summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/cpp_bound_class_unittest.cc
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/content/renderer/cpp_bound_class_unittest.cc
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/content/renderer/cpp_bound_class_unittest.cc')
-rw-r--r--chromium/content/renderer/cpp_bound_class_unittest.cc241
1 files changed, 241 insertions, 0 deletions
diff --git a/chromium/content/renderer/cpp_bound_class_unittest.cc b/chromium/content/renderer/cpp_bound_class_unittest.cc
new file mode 100644
index 00000000000..2c0f75f881c
--- /dev/null
+++ b/chromium/content/renderer/cpp_bound_class_unittest.cc
@@ -0,0 +1,241 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests for CppBoundClass, in conjunction with CppBindingExample. Binds
+// a CppBindingExample class into JavaScript in a custom test shell and tests
+// the binding from the outside by loading JS into the shell.
+
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/common/url_constants.h"
+#include "content/public/renderer/render_view_observer.h"
+#include "content/public/test/render_view_test.h"
+#include "content/test/cpp_binding_example.h"
+#include "third_party/WebKit/public/platform/WebURLRequest.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebElement.h"
+
+using webkit_glue::CppArgumentList;
+using webkit_glue::CppVariant;
+
+namespace content {
+
+namespace {
+
+class CppBindingExampleSubObject : public CppBindingExample {
+ public:
+ CppBindingExampleSubObject() {
+ sub_value_.Set("sub!");
+ BindProperty("sub_value", &sub_value_);
+ }
+ private:
+ CppVariant sub_value_;
+};
+
+
+class CppBindingExampleWithOptionalFallback : public CppBindingExample {
+ public:
+ CppBindingExampleWithOptionalFallback() {
+ BindProperty("sub_object", sub_object_.GetAsCppVariant());
+ }
+
+ void set_fallback_method_enabled(bool state) {
+ BindFallbackCallback(state ?
+ base::Bind(&CppBindingExampleWithOptionalFallback::fallbackMethod,
+ base::Unretained(this))
+ : CppBoundClass::Callback());
+ }
+
+ // The fallback method does nothing, but because of it the JavaScript keeps
+ // running when a nonexistent method is called on an object.
+ void fallbackMethod(const CppArgumentList& args, CppVariant* result) {
+ }
+
+ private:
+ CppBindingExampleSubObject sub_object_;
+};
+
+class TestObserver : public RenderViewObserver {
+ public:
+ explicit TestObserver(RenderView* render_view)
+ : RenderViewObserver(render_view) {}
+ virtual void DidClearWindowObject(WebKit::WebFrame* frame) OVERRIDE {
+ example_bound_class_.BindToJavascript(frame, "example");
+ }
+ void set_fallback_method_enabled(bool use_fallback) {
+ example_bound_class_.set_fallback_method_enabled(use_fallback);
+ }
+ private:
+ CppBindingExampleWithOptionalFallback example_bound_class_;
+};
+
+} // namespace
+
+class CppBoundClassTest : public RenderViewTest {
+ public:
+ CppBoundClassTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ RenderViewTest::SetUp();
+ observer_.reset(new TestObserver(view_));
+ observer_->set_fallback_method_enabled(useFallback());
+
+ WebKit::WebURLRequest url_request;
+ url_request.initialize();
+ url_request.setURL(GURL(kAboutBlankURL));
+
+ GetMainFrame()->loadRequest(url_request);
+ ProcessPendingMessages();
+ }
+
+ virtual void TearDown() OVERRIDE {
+ observer_.reset();
+ RenderViewTest::TearDown();
+ }
+
+ // Executes the specified JavaScript and checks that the resulting document
+ // text is empty.
+ void CheckJavaScriptFailure(const std::string& javascript) {
+ ExecuteJavaScript(javascript.c_str());
+ EXPECT_EQ(
+ "",
+ UTF16ToASCII(GetMainFrame()->document().documentElement().innerText()));
+ }
+
+ void CheckTrue(const std::string& expression) {
+ int was_page_a = -1;
+ string16 check_page_a =
+ ASCIIToUTF16(std::string("Number(") + expression + ")");
+ EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
+ EXPECT_EQ(1, was_page_a);
+ }
+
+ protected:
+ virtual bool useFallback() {
+ return false;
+ }
+
+ private:
+ scoped_ptr<TestObserver> observer_;
+};
+
+class CppBoundClassWithFallbackMethodTest : public CppBoundClassTest {
+ protected:
+ virtual bool useFallback() OVERRIDE {
+ return true;
+ }
+};
+
+// Ensures that the example object has been bound to JS.
+TEST_F(CppBoundClassTest, ObjectExists) {
+ CheckTrue("typeof window.example == 'object'");
+
+ // An additional check to test our test.
+ CheckTrue("typeof window.invalid_object == 'undefined'");
+}
+
+TEST_F(CppBoundClassTest, PropertiesAreInitialized) {
+ CheckTrue("example.my_value == 10");
+
+ CheckTrue("example.my_other_value == 'Reinitialized!'");
+}
+
+TEST_F(CppBoundClassTest, SubOject) {
+ CheckTrue("typeof window.example.sub_object == 'object'");
+
+ CheckTrue("example.sub_object.sub_value == 'sub!'");
+}
+
+TEST_F(CppBoundClassTest, SetAndGetProperties) {
+ // The property on the left will be set to the value on the right, then
+ // checked to make sure it holds that same value.
+ static const std::string tests[] = {
+ "example.my_value", "7",
+ "example.my_value", "'test'",
+ "example.my_other_value", "3.14",
+ "example.my_other_value", "false",
+ "" // Array end marker: insert additional test pairs before this.
+ };
+
+ for (int i = 0; tests[i] != ""; i += 2) {
+ std::string left = tests[i];
+ std::string right = tests[i + 1];
+ // left = right;
+ std::string js = left;
+ js.append(" = ");
+ js.append(right);
+ js.append(";");
+ ExecuteJavaScript(js.c_str());
+ std::string expression = left;
+ expression += " == ";
+ expression += right;
+ CheckTrue(expression);
+ }
+}
+
+TEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) {
+ // TODO(dglazkov): fix NPObject issues around failing property setters and
+ // getters and add tests for situations when GetProperty or SetProperty fail.
+ ExecuteJavaScript("example.my_value_with_callback = 10;");
+ CheckTrue("example.my_value_with_callback == 10");
+
+ ExecuteJavaScript("example.my_value_with_callback = 11;");
+ CheckTrue("example.my_value_with_callback == 11");
+
+ CheckTrue("example.same == 42");
+
+ ExecuteJavaScript("example.same = 24;");
+ CheckTrue("example.same == 42");
+}
+
+TEST_F(CppBoundClassTest, InvokeMethods) {
+ // The expression on the left is expected to return the value on the right.
+ static const std::string tests[] = {
+ "example.echoValue(true) == true",
+ "example.echoValue(13) == 13",
+ "example.echoValue(2.718) == 2.718",
+ "example.echoValue('yes') == 'yes'",
+ "example.echoValue() == null", // Too few arguments
+
+ "example.echoType(false) == true",
+ "example.echoType(19) == 3.14159",
+ "example.echoType(9.876) == 3.14159",
+ "example.echoType('test string') == 'Success!'",
+ "example.echoType() == null", // Too few arguments
+
+ // Comparing floats that aren't integer-valued is usually problematic due
+ // to rounding, but exact powers of 2 should also be safe.
+ "example.plus(2.5, 18.0) == 20.5",
+ "example.plus(2, 3.25) == 5.25",
+ "example.plus(2, 3) == 5",
+ "example.plus() == null", // Too few arguments
+ "example.plus(1) == null", // Too few arguments
+ "example.plus(1, 'test') == null", // Wrong argument type
+ "example.plus('test', 2) == null", // Wrong argument type
+ "example.plus('one', 'two') == null", // Wrong argument type
+ "" // Array end marker: insert additional test pairs before this.
+ };
+
+ for (int i = 0; tests[i] != ""; i++)
+ CheckTrue(tests[i]);
+
+ ExecuteJavaScript("example.my_value = 3.25; example.my_other_value = 1.25;");
+ CheckTrue("example.plus(example.my_value, example.my_other_value) == 4.5");
+}
+
+// Tests that invoking a nonexistent method with no fallback method stops the
+// script's execution
+TEST_F(CppBoundClassTest,
+ InvokeNonexistentMethodNoFallback) {
+ std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');";
+ CheckJavaScriptFailure(js);
+}
+
+// Ensures existent methods can be invoked successfully when the fallback method
+// is used
+TEST_F(CppBoundClassWithFallbackMethodTest,
+ InvokeExistentMethodsWithFallback) {
+ CheckTrue("example.echoValue(34) == 34");
+}
+
+} // namespace content