1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "extensions/common/stack_frame.h"
6
7#include "base/logging.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/strings/string16.h"
10#include "base/strings/utf_string_conversions.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using base::UTF8ToUTF16;
14
15namespace extensions {
16
17namespace {
18
19void AssertStackFrameValid(const std::string& text,
20                           size_t line,
21                           size_t column,
22                           const std::string& source,
23                           const std::string& function) {
24  base::string16 utf16_text = base::UTF8ToUTF16(text);
25  scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(utf16_text);
26
27  ASSERT_TRUE(frame.get()) << "Failed to create frame from '" << text << "'";
28  EXPECT_EQ(line, frame->line_number);
29  EXPECT_EQ(column, frame->column_number);
30  EXPECT_EQ(base::UTF8ToUTF16(source), frame->source);
31  EXPECT_EQ(base::UTF8ToUTF16(function), frame->function);
32}
33
34void AssertStackFrameInvalid(const std::string& text) {
35  base::string16 utf16_text = base::UTF8ToUTF16(text);
36  scoped_ptr<StackFrame> frame = StackFrame::CreateFromText(utf16_text);
37  ASSERT_FALSE(frame.get()) << "Errantly created frame from '" << text << "'";
38}
39
40}  // namespace
41
42TEST(StackFrameUnitTest, ParseStackFramesFromText) {
43  AssertStackFrameValid(
44      "function_name (https://www.url.com/foo.html:100:201)",
45      100u, 201u, "https://www.url.com/foo.html", "function_name");
46  AssertStackFrameValid(
47      "(anonymous function) (https://www.url.com/foo.html:100:201)",
48      100u, 201u, "https://www.url.com/foo.html", "(anonymous function)");
49  AssertStackFrameValid(
50      "Function.target.(anonymous function) (internals::SafeBuiltins:19:14)",
51      19u, 14u, "internals::SafeBuiltins",
52      "Function.target.(anonymous function)");
53  AssertStackFrameValid(
54      "internal-item:://fpgohbggpmcpeedljibghijiclejiklo/script.js:6:12",
55      6u, 12u, "internal-item:://fpgohbggpmcpeedljibghijiclejiklo/script.js",
56      "(anonymous function)");
57
58  // No delimiting ':' between line/column numbers.
59  AssertStackFrameInvalid(
60      "function_name (https://www.url.com/foo.html:100201)");
61  // No line number.
62  AssertStackFrameInvalid("function_name (https://www.url.com/foo.html::201)");
63  // No line number or delimiting ':'.
64  AssertStackFrameInvalid("function_name (https://www.url.com/foo.html201)");
65  // No leading '(' around url, line, column.
66  AssertStackFrameInvalid(
67      "function_name https://www.url.com/foo.html:100:201)");
68  // No trailing ')'.
69  AssertStackFrameInvalid(
70      "function_name (https://www.url.com/foo.html:100:201");
71  // Trailing ' '.
72  AssertStackFrameInvalid(
73      "function_name (https://www.url.com/foo.html:100:201) ");
74  // Invalid column number.
75  AssertStackFrameInvalid(
76      "function_name (https://www.url.com/foo.html:100:201a)");
77  // Negative column number.
78  AssertStackFrameInvalid(
79      "function_name (https://www.url.com/foo.html:100:-201)");
80  // Extra trailing ')'
81  AssertStackFrameInvalid(
82      "function_name (https://www.url.com/foo.html:100:201))");
83}
84
85}  // namespace extensions
86