1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests for CppBoundClass, in conjunction with CppBindingExample. Binds 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a CppBindingExample class into JavaScript in a custom test shell and tests 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the binding from the outside by loading JS into the shell. 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/string_util.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebData.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/cpp_binding_example.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/tools/test_shell/test_shell_test.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebFrame; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CppBindingExampleSubObject : public CppBindingExample { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CppBindingExampleSubObject() { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sub_value_.Set("sub!"); 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BindProperty("sub_value", &sub_value_); 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CppVariant sub_value_; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CppBindingExampleWithOptionalFallback : public CppBindingExample { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CppBindingExampleWithOptionalFallback() { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BindProperty("sub_object", sub_object_.GetAsCppVariant()); 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void set_fallback_method_enabled(bool state) { 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BindFallbackMethod(state ? 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CppBindingExampleWithOptionalFallback::fallbackMethod 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : NULL); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The fallback method does nothing, but because of it the JavaScript keeps 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // running when a nonexistent method is called on an object. 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void fallbackMethod(const CppArgumentList& args, CppVariant* result) { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CppBindingExampleSubObject sub_object_; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExampleTestShell : public TestShell { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExampleTestShell(bool use_fallback_method) { 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch example_bound_class_.set_fallback_method_enabled(use_fallback_method); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When called by WebViewDelegate::WindowObjectCleared method, this binds a 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // CppExampleObject to window.example. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BindJSObjectsToWindow(WebFrame* frame) { 6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen example_bound_class_.BindToJavascript(frame, "example"); 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use the layoutTestController binding for notifyDone. 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestShell::BindJSObjectsToWindow(frame); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a public interface to TestShell's protected method, so it 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // can be called by our CreateEmptyWindow. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool PublicInitialize(const std::string& starting_url) { 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Initialize(GURL(starting_url)); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CppBindingExampleWithOptionalFallback example_bound_class_; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CppBoundClassTest : public TestShellTest { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Adapted from TestShell::CreateNewWindow, this creates an 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ExampleTestShellWindow rather than a regular TestShell. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void CreateEmptyWindow() { 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExampleTestShell* host = new ExampleTestShell(useFallback()); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(host != NULL); 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool rv = host->PublicInitialize("about:blank"); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_shell_ = host; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestShell::windowList()->push_back(host->mainWnd()); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webframe_ = test_shell_->webView()->mainFrame(); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(webframe_ != NULL); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete host; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Wraps the given JavaScript snippet in <html><body><script> tags, then 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // loads it into a webframe so it is executed. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ExecuteJavaScript(const std::string& javascript) { 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string html = "<html><body>"; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch html.append(TestShellTest::kJavascriptDelayExitScript); 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch html.append("<script>"); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch html.append(javascript); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch html.append("</script></body></html>"); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The base URL doesn't matter. 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch webframe_->loadHTMLString(html, GURL("about:blank")); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch test_shell_->WaitTestFinished(); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Executes the specified JavaScript and checks to be sure that the resulting 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // document text is exactly "SUCCESS". 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CheckJavaScriptSuccess(const std::string& javascript) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExecuteJavaScript(javascript); 11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("SUCCESS", 11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_))); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Executes the specified JavaScript and checks that the resulting document 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // text is empty. 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CheckJavaScriptFailure(const std::string& javascript) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExecuteJavaScript(javascript); 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen EXPECT_EQ("", UTF16ToASCII(webkit_glue::DumpDocumentText(webframe_))); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Constructs a JavaScript snippet that evaluates and compares the left and 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // right expressions, printing "SUCCESS" to the page if they are equal and 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // printing their actual values if they are not. Any strings in the 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // expressions should be enclosed in single quotes, and no double quotes 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // should appear in either expression (even if escaped). (If a test case 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is added that needs fancier quoting, Json::valueToQuotedString could be 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // used here. For now, it's not worth adding the dependency.) 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string BuildJSCondition(std::string left, std::string right) { 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "var leftval = " + left + ";" + 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "var rightval = " + right + ";" + 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "if (leftval == rightval) {" + 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " document.writeln('SUCCESS');" + 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "} else {" + 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " document.writeln(\"" + 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left + " [\" + leftval + \"] != " + 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right + " [\" + rightval + \"]\");" + 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "}"; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochprotected: 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool useFallback() { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochprivate: 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebFrame* webframe_; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CppBoundClassWithFallbackMethodTest : public CppBoundClassTest { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochprotected: 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual bool useFallback() { 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Ensures that the example object has been bound to JS. 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, ObjectExists) { 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = BuildJSCondition("typeof window.example", "'object'"); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // An additional check to test our test. 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js = BuildJSCondition("typeof window.invalid_object", "'undefined'"); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, PropertiesAreInitialized) { 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = BuildJSCondition("example.my_value", "10"); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js = BuildJSCondition("example.my_other_value", "'Reinitialized!'"); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, SubOject) { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = BuildJSCondition("typeof window.example.sub_object", 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "'object'"); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js = BuildJSCondition("example.sub_object.sub_value", "'sub!'"); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, SetAndGetProperties) { 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The property on the left will be set to the value on the right, then 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // checked to make sure it holds that same value. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const std::string tests[] = { 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_value", "7", 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_value", "'test'", 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_other_value", "3.14", 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_other_value", "false", 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "" // Array end marker: insert additional test pairs before this. 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; tests[i] != ""; i += 2) { 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string left = tests[i]; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string right = tests[i + 1]; 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // left = right; 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = left; 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js.append(" = "); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js.append(right); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js.append(";"); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js.append(BuildJSCondition(left, right)); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, SetAndGetPropertiesWithCallbacks) { 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(dglazkov): fix NPObject issues around failing property setters and 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // getters and add tests for situations when GetProperty or SetProperty fail. 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = "var result = 'SUCCESS';\n" 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_value_with_callback = 10;\n" 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "if (example.my_value_with_callback != 10)\n" 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " result = 'FAIL: unable to set property.';\n" 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.my_value_with_callback = 11;\n" 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "if (example.my_value_with_callback != 11)\n" 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " result = 'FAIL: unable to set property again';\n" 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "if (example.same != 42)\n" 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " result = 'FAIL: same property should always be 42';\n" 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.same = 24;\n" 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "if (example.same != 42)\n" 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " result = 'FAIL: same property should always be 42';\n" 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "document.writeln(result);\n"; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(CppBoundClassTest, InvokeMethods) { 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The expression on the left is expected to return the value on the right. 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const std::string tests[] = { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoValue(true)", "true", 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoValue(13)", "13", 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoValue(2.718)", "2.718", 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoValue('yes')", "'yes'", 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoValue()", "null", // Too few arguments 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoType(false)", "true", 24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "example.echoType(19)", "3.14159", 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoType(9.876)", "3.14159", 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoType('test string')", "'Success!'", 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.echoType()", "null", // Too few arguments 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Comparing floats that aren't integer-valued is usually problematic due 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to rounding, but exact powers of 2 should also be safe. 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(2.5, 18.0)", "20.5", 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(2, 3.25)", "5.25", 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(2, 3)", "5", 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus()", "null", // Too few arguments 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(1)", "null", // Too few arguments 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(1, 'test')", "null", // Wrong argument type 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus('test', 2)", "null", // Wrong argument type 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus('one', 'two')", "null", // Wrong argument type 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "" // Array end marker: insert additional test pairs before this. 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; tests[i] != ""; i+= 2) { 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string left = tests[i]; 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string right = tests[i + 1]; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = BuildJSCondition(left, right); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = "example.my_value = 3.25; example.my_other_value = 1.25;"; 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch js.append(BuildJSCondition( 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "example.plus(example.my_value, example.my_other_value)", "4.5")); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that invoking a nonexistent method with no fallback method stops the 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// script's execution 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassTest, 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InvokeNonexistentMethodNoFallback) { 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = "example.nonExistentMethod();document.writeln('SUCCESS');"; 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptFailure(js); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Ensures existent methods can be invoked successfully when the fallback method 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is used 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(CppBoundClassWithFallbackMethodTest, 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InvokeExistentMethodsWithFallback) { 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string js = BuildJSCondition("example.echoValue(34)", "34"); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CheckJavaScriptSuccess(js); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 291