| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 // Tests for CppBoundClass, in conjunction with CppBindingExample. Binds | |
| 6 // a CppBindingExample class into JavaScript in a custom test shell and tests | |
| 7 // the binding from the outside by loading JS into the shell. | |
| 8 | |
| 9 #include "base/strings/utf_string_conversions.h" | |
| 10 #include "content/public/common/url_constants.h" | |
| 11 #include "content/public/renderer/render_view_observer.h" | |
| 12 #include "content/public/test/render_view_test.h" | |
| 13 #include "content/test/cpp_binding_example.h" | |
| 14 #include "third_party/WebKit/public/platform/WebURLRequest.h" | |
| 15 #include "third_party/WebKit/public/web/WebDocument.h" | |
| 16 #include "third_party/WebKit/public/web/WebElement.h" | |
| 17 | |
| 18 using webkit_glue::CppArgumentList; | |
| 19 using webkit_glue::CppVariant; | |
| 20 | |
| 21 namespace content { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 class CppBindingExampleSubObject : public CppBindingExample { | |
| 26 public: | |
| 27 CppBindingExampleSubObject() { | |
| 28 sub_value_.Set("sub!"); | |
| 29 BindProperty("sub_value", &sub_value_); | |
| 30 } | |
| 31 private: | |
| 32 CppVariant sub_value_; | |
| 33 }; | |
| 34 | |
| 35 | |
| 36 class CppBindingExampleWithOptionalFallback : public CppBindingExample { | |
| 37 public: | |
| 38 CppBindingExampleWithOptionalFallback() { | |
| 39 BindProperty("sub_object", sub_object_.GetAsCppVariant()); | |
| 40 } | |
| 41 | |
| 42 void set_fallback_method_enabled(bool state) { | |
| 43 BindFallbackCallback(state ? | |
| 44 base::Bind(&CppBindingExampleWithOptionalFallback::fallbackMethod, | |
| 45 base::Unretained(this)) | |
| 46 : CppBoundClass::Callback()); | |
| 47 } | |
| 48 | |
| 49 // The fallback method does nothing, but because of it the JavaScript keeps | |
| 50 // running when a nonexistent method is called on an object. | |
| 51 void fallbackMethod(const CppArgumentList& args, CppVariant* result) { | |
| 52 } | |
| 53 | |
| 54 private: | |
| 55 CppBindingExampleSubObject sub_object_; | |
| 56 }; | |
| 57 | |
| 58 class TestObserver : public RenderViewObserver { | |
| 59 public: | |
| 60 explicit TestObserver(RenderView* render_view) | |
| 61 : RenderViewObserver(render_view) {} | |
| 62 virtual void DidClearWindowObject(blink::WebFrame* frame) OVERRIDE { | |
| 63 example_bound_class_.BindToJavascript(frame, "example"); | |
| 64 } | |
| 65 void set_fallback_method_enabled(bool use_fallback) { | |
| 66 example_bound_class_.set_fallback_method_enabled(use_fallback); | |
| 67 } | |
| 68 private: | |
| 69 CppBindingExampleWithOptionalFallback example_bound_class_; | |
| 70 }; | |
| 71 | |
| 72 } // namespace | |
| 73 | |
| 74 class CppBoundClassTest : public RenderViewTest { | |
| 75 public: | |
| 76 CppBoundClassTest() {} | |
| 77 | |
| 78 virtual void SetUp() OVERRIDE { | |
| 79 RenderViewTest::SetUp(); | |
| 80 observer_.reset(new TestObserver(view_)); | |
| 81 observer_->set_fallback_method_enabled(useFallback()); | |
| 82 | |
| 83 blink::WebURLRequest url_request; | |
| 84 url_request.initialize(); | |
| 85 url_request.setURL(GURL(kAboutBlankURL)); | |
| 86 | |
| 87 GetMainFrame()->loadRequest(url_request); | |
| 88 ProcessPendingMessages(); | |
| 89 } | |
| 90 | |
| 91 virtual void TearDown() OVERRIDE { | |
| 92 observer_.reset(); | |
| 93 RenderViewTest::TearDown(); | |
| 94 } | |
| 95 | |
| 96 // Executes the specified JavaScript and checks that the resulting document | |
| 97 // text is empty. | |
| 98 void CheckJavaScriptFailure(const std::string& javascript) { | |
| 99 ExecuteJavaScript(javascript.c_str()); | |
| 100 EXPECT_EQ( | |
| 101 "", | |
| 102 UTF16ToASCII(GetMainFrame()->document().documentElement().innerText())); | |
| 103 } | |
| 104 | |
| 105 void CheckTrue(const std::string& expression) { | |
| 106 int was_page_a = -1; | |
| 107 base::string16 check_page_a = | |
| 108 base::ASCIIToUTF16(std::string("Number(") + expression + ")"); | |
| 109 EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a)); | |
| 110 EXPECT_EQ(1, was_page_a); | |
| 111 } | |
| 112 | |
| 113 protected: | |
| 114 virtual bool useFallback() { | |
| 115 return false; | |
| 116 } | |
| 117 | |
| 118 private: | |
| 119 scoped_ptr<TestObserver> observer_; | |
| 120 }; | |
| 121 | |
| 122 class CppBoundClassWithFallbackMethodTest : public CppBoundClassTest { | |
| 123 protected: | |
| 124 virtual bool useFallback() OVERRIDE { | |
| 125 return true; | |
| 126 } | |
| 127 }; | |
| 128 | |
| 129 // Ensures that the example object has been bound to JS. | |
| 130 TEST_F(CppBoundClassTest, ObjectExists) { | |
| 131 CheckTrue("typeof window.example == 'object'"); | |
| 132 | |
| 133 // An additional check to test our test. | |
| 134 CheckTrue("typeof window.invalid_object == 'undefined'"); | |
| 135 } | |
| 136 | |
| 137 TEST_F(CppBoundClassTest, PropertiesAreInitialized) { | |
| 138 CheckTrue("example.my_value == 10"); | |
| 139 | |
| 140 CheckTrue("example.my_other_value == 'Reinitialized!'"); | |
| 141 } | |
| 142 | |
| 143 TEST_F(CppBoundClassTest, SubOject) { | |
| 144 CheckTrue("typeof window.example.sub_object == 'object'"); | |
| 145 | |
| 146 CheckTrue("example.sub_object.sub_value == 'sub!'"); | |
| 147 } | |
| 148 | |
| 149 TEST_F(CppBoundClassTest, SetAndGetProperties) { | |
| 150 // The property on the left will be set to the value on the right, then | |
| 151 // checked to make sure it holds that same value. | |
| 152 static const std::string tests[] = { | |
| 153 "example.my_value", "7", | |
| 154 "example.my_value", "'test'", | |
| 155 "example.my_other_value", "3.14", | |
| 156 "example.my_other_value", "false", | |
| 157 "" // Array end marker: insert additional test pairs before this. | |
| 158 }; | |
| 159 | |
| 160 for (int i = 0; tests[i] != ""; i += 2) { | |
| 161 std::string left = tests[i]; | |
| 162 std::string right = tests[i + 1]; | |
| 163 // left = right; | |
| 164 std::string js = left; | |
| 165 js.append(" = "); | |
| 166 js.append(right); | |
| 167 js.append(";"); | |
| 168 ExecuteJavaScript(js.c_str()); | |
| 169 std::string expression = left; | |
| 170 expression += " == "; | |
| 171 expression += right; | |
| 172 CheckTrue(expression); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 TEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) { | |
| 177 // TODO(dglazkov): fix NPObject issues around failing property setters and | |
| 178 // getters and add tests for situations when GetProperty or SetProperty fail. | |
| 179 ExecuteJavaScript("example.my_value_with_callback = 10;"); | |
| 180 CheckTrue("example.my_value_with_callback == 10"); | |
| 181 | |
| 182 ExecuteJavaScript("example.my_value_with_callback = 11;"); | |
| 183 CheckTrue("example.my_value_with_callback == 11"); | |
| 184 | |
| 185 CheckTrue("example.same == 42"); | |
| 186 | |
| 187 ExecuteJavaScript("example.same = 24;"); | |
| 188 CheckTrue("example.same == 42"); | |
| 189 } | |
| 190 | |
| 191 TEST_F(CppBoundClassTest, InvokeMethods) { | |
| 192 // The expression on the left is expected to return the value on the right. | |
| 193 static const std::string tests[] = { | |
| 194 "example.echoValue(true) == true", | |
| 195 "example.echoValue(13) == 13", | |
| 196 "example.echoValue(2.718) == 2.718", | |
| 197 "example.echoValue('yes') == 'yes'", | |
| 198 "example.echoValue() == null", // Too few arguments | |
| 199 | |
| 200 "example.echoType(false) == true", | |
| 201 "example.echoType(19) == 3.14159", | |
| 202 "example.echoType(9.876) == 3.14159", | |
| 203 "example.echoType('test string') == 'Success!'", | |
| 204 "example.echoType() == null", // Too few arguments | |
| 205 | |
| 206 // Comparing floats that aren't integer-valued is usually problematic due | |
| 207 // to rounding, but exact powers of 2 should also be safe. | |
| 208 "example.plus(2.5, 18.0) == 20.5", | |
| 209 "example.plus(2, 3.25) == 5.25", | |
| 210 "example.plus(2, 3) == 5", | |
| 211 "example.plus() == null", // Too few arguments | |
| 212 "example.plus(1) == null", // Too few arguments | |
| 213 "example.plus(1, 'test') == null", // Wrong argument type | |
| 214 "example.plus('test', 2) == null", // Wrong argument type | |
| 215 "example.plus('one', 'two') == null", // Wrong argument type | |
| 216 "" // Array end marker: insert additional test pairs before this. | |
| 217 }; | |
| 218 | |
| 219 for (int i = 0; tests[i] != ""; i++) | |
| 220 CheckTrue(tests[i]); | |
| 221 | |
| 222 ExecuteJavaScript("example.my_value = 3.25; example.my_other_value = 1.25;"); | |
| 223 CheckTrue("example.plus(example.my_value, example.my_other_value) == 4.5"); | |
| 224 } | |
| 225 | |
| 226 // Tests that invoking a nonexistent method with no fallback method stops the | |
| 227 // script's execution | |
| 228 TEST_F(CppBoundClassTest, | |
| 229 InvokeNonexistentMethodNoFallback) { | |
| 230 std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');"; | |
| 231 CheckJavaScriptFailure(js); | |
| 232 } | |
| 233 | |
| 234 // Ensures existent methods can be invoked successfully when the fallback method | |
| 235 // is used | |
| 236 TEST_F(CppBoundClassWithFallbackMethodTest, | |
| 237 InvokeExistentMethodsWithFallback) { | |
| 238 CheckTrue("example.echoValue(34) == 34"); | |
| 239 } | |
| 240 | |
| 241 } // namespace content | |
| OLD | NEW |