Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: extensions/renderer/api_last_error_unittest.cc

Issue 2819683002: [Extenisons Bindings] Don't throw unchecked errors; add console errors (Closed)
Patch Set: jbroman's Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/api_last_error.h" 5 #include "extensions/renderer/api_last_error.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/optional.h"
9 #include "extensions/renderer/api_binding_test.h" 10 #include "extensions/renderer/api_binding_test.h"
10 #include "extensions/renderer/api_binding_test_util.h" 11 #include "extensions/renderer/api_binding_test_util.h"
11 #include "gin/converter.h" 12 #include "gin/converter.h"
12 #include "gin/public/context_holder.h" 13 #include "gin/public/context_holder.h"
13 14
14 namespace extensions { 15 namespace extensions {
15 16
16 namespace { 17 namespace {
17 18
19 void DoNothingWithError(v8::Local<v8::Context> context,
20 const std::string& error) {}
21
18 std::string GetLastError(v8::Local<v8::Object> parent, 22 std::string GetLastError(v8::Local<v8::Object> parent,
19 v8::Local<v8::Context> context) { 23 v8::Local<v8::Context> context) {
20 v8::Local<v8::Value> last_error = 24 v8::Local<v8::Value> last_error =
21 GetPropertyFromObject(parent, context, "lastError"); 25 GetPropertyFromObject(parent, context, "lastError");
22 if (last_error.IsEmpty() || !last_error->IsObject()) 26 if (last_error.IsEmpty() || !last_error->IsObject())
23 return V8ToString(last_error, context); 27 return V8ToString(last_error, context);
24 v8::Local<v8::Value> message = 28 v8::Local<v8::Value> message =
25 GetPropertyFromObject(last_error.As<v8::Object>(), context, "message"); 29 GetPropertyFromObject(last_error.As<v8::Object>(), context, "message");
26 return V8ToString(message, context); 30 return V8ToString(message, context);
27 } 31 }
(...skipping 15 matching lines...) Expand all
43 47
44 using APILastErrorTest = APIBindingTest; 48 using APILastErrorTest = APIBindingTest;
45 49
46 // Test basic functionality of the lastError object. 50 // Test basic functionality of the lastError object.
47 TEST_F(APILastErrorTest, TestLastError) { 51 TEST_F(APILastErrorTest, TestLastError) {
48 v8::HandleScope handle_scope(isolate()); 52 v8::HandleScope handle_scope(isolate());
49 v8::Local<v8::Context> context = MainContext(); 53 v8::Local<v8::Context> context = MainContext();
50 v8::Local<v8::Object> parent_object = v8::Object::New(isolate()); 54 v8::Local<v8::Object> parent_object = v8::Object::New(isolate());
51 55
52 ParentList parents = {{context, parent_object}}; 56 ParentList parents = {{context, parent_object}};
53 APILastError last_error(base::Bind(&GetParent, parents)); 57 APILastError last_error(base::Bind(&GetParent, parents),
58 base::Bind(&DoNothingWithError));
54 59
55 EXPECT_EQ("undefined", GetLastError(parent_object, context)); 60 EXPECT_EQ("undefined", GetLastError(parent_object, context));
56 // Check that the key isn't present on the object (as opposed to simply being 61 // Check that the key isn't present on the object (as opposed to simply being
57 // undefined). 62 // undefined).
58 EXPECT_FALSE( 63 EXPECT_FALSE(
59 parent_object->Has(context, gin::StringToV8(isolate(), "lastError")) 64 parent_object->Has(context, gin::StringToV8(isolate(), "lastError"))
60 .ToChecked()); 65 .ToChecked());
61 66
62 last_error.SetError(context, "Some last error"); 67 last_error.SetError(context, "Some last error");
63 EXPECT_EQ("\"Some last error\"", GetLastError(parent_object, context)); 68 EXPECT_EQ("\"Some last error\"", GetLastError(parent_object, context));
64 69
65 last_error.ClearError(context, false); 70 last_error.ClearError(context, false);
66 EXPECT_EQ("undefined", GetLastError(parent_object, context)); 71 EXPECT_EQ("undefined", GetLastError(parent_object, context));
67 EXPECT_FALSE( 72 EXPECT_FALSE(
68 parent_object->Has(context, gin::StringToV8(isolate(), "lastError")) 73 parent_object->Has(context, gin::StringToV8(isolate(), "lastError"))
69 .ToChecked()); 74 .ToChecked());
70 } 75 }
71 76
72 // Test throwing an error if the last error wasn't checked. 77 // Test throwing an error if the last error wasn't checked.
73 TEST_F(APILastErrorTest, ReportIfUnchecked) { 78 TEST_F(APILastErrorTest, ReportIfUnchecked) {
74 v8::HandleScope handle_scope(isolate()); 79 v8::HandleScope handle_scope(isolate());
75 v8::Local<v8::Context> context = MainContext(); 80 v8::Local<v8::Context> context = MainContext();
76 v8::Local<v8::Object> parent_object = v8::Object::New(isolate()); 81 v8::Local<v8::Object> parent_object = v8::Object::New(isolate());
77 82
83 base::Optional<std::string> console_error;
84 auto log_error = [](base::Optional<std::string>* console_error,
85 v8::Local<v8::Context> context,
86 const std::string& error) { *console_error = error; };
87
78 ParentList parents = {{context, parent_object}}; 88 ParentList parents = {{context, parent_object}};
79 APILastError last_error(base::Bind(&GetParent, parents)); 89 APILastError last_error(base::Bind(&GetParent, parents),
90 base::Bind(log_error, &console_error));
80 91
81 { 92 {
82 v8::TryCatch try_catch(isolate()); 93 v8::TryCatch try_catch(isolate());
83 last_error.SetError(context, "foo"); 94 last_error.SetError(context, "foo");
84 // GetLastError() will count as accessing the error property, so we 95 // GetLastError() will count as accessing the error property, so we
85 // shouldn't throw an exception. 96 // shouldn't log an error.
86 EXPECT_EQ("\"foo\"", GetLastError(parent_object, context)); 97 EXPECT_EQ("\"foo\"", GetLastError(parent_object, context));
87 last_error.ClearError(context, true); 98 last_error.ClearError(context, true);
99 EXPECT_FALSE(console_error);
88 EXPECT_FALSE(try_catch.HasCaught()); 100 EXPECT_FALSE(try_catch.HasCaught());
89 } 101 }
90 102
91 { 103 {
92 v8::TryCatch try_catch(isolate()); 104 v8::TryCatch try_catch(isolate());
93 // This time, we should throw an exception. 105 // This time, we should log an error.
94 last_error.SetError(context, "A last error"); 106 last_error.SetError(context, "A last error");
95 last_error.ClearError(context, true); 107 last_error.ClearError(context, true);
96 ASSERT_TRUE(try_catch.HasCaught()); 108 ASSERT_TRUE(console_error);
97 EXPECT_EQ("Uncaught Error: A last error", 109 EXPECT_EQ("Unchecked runtime.lastError: A last error", *console_error);
98 gin::V8ToString(try_catch.Message()->Get())); 110 // We shouldn't have thrown an exception in order to prevent disrupting
111 // JS execution.
112 EXPECT_FALSE(try_catch.HasCaught());
99 } 113 }
100 } 114 }
101 115
102 // Test behavior when something else sets a lastError property on the parent 116 // Test behavior when something else sets a lastError property on the parent
103 // object. 117 // object.
104 TEST_F(APILastErrorTest, NonLastErrorObject) { 118 TEST_F(APILastErrorTest, NonLastErrorObject) {
105 v8::HandleScope handle_scope(isolate()); 119 v8::HandleScope handle_scope(isolate());
106 v8::Local<v8::Context> context = MainContext(); 120 v8::Local<v8::Context> context = MainContext();
107 v8::Local<v8::Object> parent_object = v8::Object::New(isolate()); 121 v8::Local<v8::Object> parent_object = v8::Object::New(isolate());
108 122
109 ParentList parents = {{context, parent_object}}; 123 ParentList parents = {{context, parent_object}};
110 APILastError last_error(base::Bind(&GetParent, parents)); 124 APILastError last_error(base::Bind(&GetParent, parents),
125 base::Bind(&DoNothingWithError));
111 126
112 auto checked_set = [context](v8::Local<v8::Object> object, 127 auto checked_set = [context](v8::Local<v8::Object> object,
113 base::StringPiece key, 128 base::StringPiece key,
114 v8::Local<v8::Value> value) { 129 v8::Local<v8::Value> value) {
115 v8::Maybe<bool> success = object->Set( 130 v8::Maybe<bool> success = object->Set(
116 context, gin::StringToSymbol(context->GetIsolate(), key), value); 131 context, gin::StringToSymbol(context->GetIsolate(), key), value);
117 ASSERT_TRUE(success.IsJust()); 132 ASSERT_TRUE(success.IsJust());
118 ASSERT_TRUE(success.FromJust()); 133 ASSERT_TRUE(success.FromJust());
119 }; 134 };
120 135
(...skipping 15 matching lines...) Expand all
136 151
137 // Test lastError in multiple different contexts. 152 // Test lastError in multiple different contexts.
138 TEST_F(APILastErrorTest, MultipleContexts) { 153 TEST_F(APILastErrorTest, MultipleContexts) {
139 v8::HandleScope handle_scope(isolate()); 154 v8::HandleScope handle_scope(isolate());
140 v8::Local<v8::Context> context_a = MainContext(); 155 v8::Local<v8::Context> context_a = MainContext();
141 v8::Local<v8::Context> context_b = AddContext(); 156 v8::Local<v8::Context> context_b = AddContext();
142 157
143 v8::Local<v8::Object> parent_a = v8::Object::New(isolate()); 158 v8::Local<v8::Object> parent_a = v8::Object::New(isolate());
144 v8::Local<v8::Object> parent_b = v8::Object::New(isolate()); 159 v8::Local<v8::Object> parent_b = v8::Object::New(isolate());
145 ParentList parents = {{context_a, parent_a}, {context_b, parent_b}}; 160 ParentList parents = {{context_a, parent_a}, {context_b, parent_b}};
146 APILastError last_error(base::Bind(&GetParent, parents)); 161 APILastError last_error(base::Bind(&GetParent, parents),
162 base::Bind(&DoNothingWithError));
147 163
148 last_error.SetError(context_a, "Last error a"); 164 last_error.SetError(context_a, "Last error a");
149 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a)); 165 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a));
150 EXPECT_EQ("undefined", GetLastError(parent_b, context_b)); 166 EXPECT_EQ("undefined", GetLastError(parent_b, context_b));
151 167
152 last_error.SetError(context_b, "Last error b"); 168 last_error.SetError(context_b, "Last error b");
153 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a)); 169 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a));
154 EXPECT_EQ("\"Last error b\"", GetLastError(parent_b, context_b)); 170 EXPECT_EQ("\"Last error b\"", GetLastError(parent_b, context_b));
155 171
156 last_error.ClearError(context_b, false); 172 last_error.ClearError(context_b, false);
157 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a)); 173 EXPECT_EQ("\"Last error a\"", GetLastError(parent_a, context_a));
158 EXPECT_EQ("undefined", GetLastError(parent_b, context_b)); 174 EXPECT_EQ("undefined", GetLastError(parent_b, context_b));
159 175
160 last_error.ClearError(context_a, false); 176 last_error.ClearError(context_a, false);
161 EXPECT_EQ("undefined", GetLastError(parent_a, context_a)); 177 EXPECT_EQ("undefined", GetLastError(parent_a, context_a));
162 EXPECT_EQ("undefined", GetLastError(parent_b, context_b)); 178 EXPECT_EQ("undefined", GetLastError(parent_b, context_b));
163 } 179 }
164 180
165 } // namespace extensions 181 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/api_last_error.cc ('k') | extensions/renderer/api_request_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698