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