diff options
author | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-02 00:49:04 +0000 |
---|---|---|
committer | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-02 00:49:04 +0000 |
commit | b4d4bbb9dd3efc9ea272b1cc950a407df1f1d3a7 (patch) | |
tree | d0be7e656562fc24dd1c8163b98179def3b370ba /mojo/apps | |
parent | 0a54cd50d5b4c771c637b78268787990d298ac25 (diff) | |
download | chromium_src-b4d4bbb9dd3efc9ea272b1cc950a407df1f1d3a7.zip chromium_src-b4d4bbb9dd3efc9ea272b1cc950a407df1f1d3a7.tar.gz chromium_src-b4d4bbb9dd3efc9ea272b1cc950a407df1f1d3a7.tar.bz2 |
Move existing Mojo JS <--> CPP tests out of webui test harness.
The mojo webui test in content_browsertests was not the proper place to
perform bindings-related fuzzing (though it was initially convenient). As a
first step, move the existing tests to the new "framework" sky added in
https://src.chromium.org/viewvc/chrome?revision=267208&view=revision
This also restores the webui code to something near its original purpose,
although I've kept a few of the hooks that may be useful as real webui
tests are added.
R=sky@chromium.org
Review URL: https://codereview.chromium.org/268593002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267703 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/apps')
-rw-r--r-- | mojo/apps/js/test/js_to_cpp.mojom | 37 | ||||
-rw-r--r-- | mojo/apps/js/test/js_to_cpp_unittest.cc | 237 | ||||
-rw-r--r-- | mojo/apps/js/test/js_to_cpp_unittest.js | 55 |
3 files changed, 254 insertions, 75 deletions
diff --git a/mojo/apps/js/test/js_to_cpp.mojom b/mojo/apps/js/test/js_to_cpp.mojom new file mode 100644 index 0000000..0c96335 --- /dev/null +++ b/mojo/apps/js/test/js_to_cpp.mojom @@ -0,0 +1,37 @@ +module js_to_cpp { + +// This struct encompasses all of the basic types, so that they +// may be sent from C++ to JS and back for validation. +struct EchoArgs { + int64 si64; + int32 si32; + int16 si16; + int8 si8; + uint64 ui64; + uint32 ui32; + uint16 ui16; + uint8 ui8; + float float_val; + float float_inf; + float float_nan; + double double_val; + double double_inf; + double double_nan; + string name; + string[] string_array; +}; + +[Peer=JsSide] +interface CppSide { + StartTest(); // Sent to notify that the JS side is now ready. + PingResponse(); + EchoResponse(EchoArgs arg1, EchoArgs arg2); +}; + +[Peer=CppSide] +interface JsSide { + Ping(); + Echo(EchoArgs arg); +}; + +} diff --git a/mojo/apps/js/test/js_to_cpp_unittest.cc b/mojo/apps/js/test/js_to_cpp_unittest.cc index 3b19142..d7aa875 100644 --- a/mojo/apps/js/test/js_to_cpp_unittest.cc +++ b/mojo/apps/js/test/js_to_cpp_unittest.cc @@ -9,74 +9,206 @@ #include "base/strings/utf_string_conversions.h" #include "gin/public/isolate_holder.h" #include "mojo/apps/js/mojo_runner_delegate.h" +#include "mojo/apps/js/test/js_to_cpp.mojom.h" #include "mojo/common/common_type_converters.h" #include "mojo/common/test/test_utils.h" +#include "mojo/public/cpp/bindings/allocation_scope.h" #include "mojo/public/cpp/bindings/remote_ptr.h" #include "mojo/public/cpp/environment/environment.h" #include "mojo/public/cpp/system/core.h" #include "mojo/public/cpp/system/macros.h" -#include "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { namespace js { namespace { +// Negative numbers with different values in each byte, the last of +// which can survive promotion to double and back. +const int8 kExpectedInt8Value = -65; +const int16 kExpectedInt16Value = -16961; +const int32 kExpectedInt32Value = -1145258561; +const int64 kExpectedInt64Value = -77263311946305LL; + +// Positive numbers with different values in each byte, the last of +// which can survive promotion to double and back. +const uint8 kExpectedUInt8Value = 65; +const uint16 kExpectedUInt16Value = 16961; +const uint32 kExpectedUInt32Value = 1145258561; +const uint64 kExpectedUInt64Value = 77263311946305LL; + +// Double/float values, including special case constants. +const double kExpectedDoubleVal = 3.14159265358979323846; +const double kExpectedDoubleInf = std::numeric_limits<double>::infinity(); +const double kExpectedDoubleNan = std::numeric_limits<double>::quiet_NaN(); +const float kExpectedFloatVal = static_cast<float>(kExpectedDoubleVal); +const float kExpectedFloatInf = std::numeric_limits<float>::infinity(); +const float kExpectedFloatNan = std::numeric_limits<float>::quiet_NaN(); + +// NaN has the property that it is not equal to itself. +#define EXPECT_NAN(x) EXPECT_NE(x, x) + +bool IsRunningOnIsolatedBot() { + // TODO(yzshen): Remove this check once isolated tests are supported on the + // Chromium waterfall. (http://crbug.com/351214) + const base::FilePath test_file_path( + test::GetFilePathForJSResource( + "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom")); + if (!base::PathExists(test_file_path)) { + LOG(WARNING) << "Mojom binding files don't exist. Skipping the test."; + return true; + } + return false; +} + // Base Provider implementation class. It's expected that tests subclass and // override the appropriate Provider functions. When test is done quit the // run_loop(). -class ProviderConnection : public sample::Provider { +class CppSideConnection : public js_to_cpp::CppSide { public: - ProviderConnection() : run_loop_(NULL), client_(NULL) { + CppSideConnection() : run_loop_(NULL), client_(NULL) { } - virtual ~ProviderConnection() {} + virtual ~CppSideConnection() {} void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; } base::RunLoop* run_loop() { return run_loop_; } - void set_client(sample::ProviderClient* client) { client_ = client; } - sample::ProviderClient* client() { return client_; } + void set_client(js_to_cpp::JsSide* client) { client_ = client; } + js_to_cpp::JsSide* client() { return client_; } - // sample::Provider: - virtual void EchoString(const String& a, - const Callback<void(String)>& callback) OVERRIDE { + // js_to_cpp::CppSide: + virtual void StartTest() OVERRIDE { NOTREACHED(); } - virtual void EchoStrings( - const String& a, - const String& b, - const Callback<void(String, String)>& callback) OVERRIDE { + + virtual void PingResponse() OVERRIDE { NOTREACHED(); } - virtual void EchoMessagePipeHandle( - ScopedMessagePipeHandle a, - const Callback<void(ScopedMessagePipeHandle)>& callback) OVERRIDE { + + virtual void EchoResponse(const js_to_cpp::EchoArgs& arg1, + const js_to_cpp::EchoArgs& arg2) OVERRIDE { NOTREACHED(); } - virtual void EchoEnum(sample::Enum a, - const Callback<void(sample::Enum)>& callback) - OVERRIDE { - NOTREACHED(); + + protected: + base::RunLoop* run_loop_; + js_to_cpp::JsSide* client_; + + private: + Environment environment; + DISALLOW_COPY_AND_ASSIGN(CppSideConnection); +}; + +// Trivial test to verify a message sent from JS is received. +class PingCppSideConnection : public CppSideConnection { + public: + explicit PingCppSideConnection() : got_message_(false) {} + virtual ~PingCppSideConnection() {} + + // js_to_cpp::CppSide: + virtual void StartTest() OVERRIDE { + client_->Ping(); + } + + virtual void PingResponse() OVERRIDE { + got_message_ = true; + run_loop()->Quit(); + } + + bool DidSucceed() { + return got_message_; } private: - base::RunLoop* run_loop_; - sample::ProviderClient* client_; + bool got_message_; + DISALLOW_COPY_AND_ASSIGN(PingCppSideConnection); +}; - DISALLOW_COPY_AND_ASSIGN(ProviderConnection); +// Test that parameters are passed with correct values. +class EchoCppSideConnection : public CppSideConnection { + public: + explicit EchoCppSideConnection() : message_count_(0) {} + virtual ~EchoCppSideConnection() {} + + // js_to_cpp::CppSide: + virtual void StartTest() OVERRIDE { + AllocationScope scope; + js_to_cpp::EchoArgs::Builder builder; + builder.set_si64(kExpectedInt64Value); + builder.set_si32(kExpectedInt32Value); + builder.set_si16(kExpectedInt16Value); + builder.set_si8(kExpectedInt8Value); + builder.set_ui64(kExpectedUInt64Value); + builder.set_ui32(kExpectedUInt32Value); + builder.set_ui16(kExpectedUInt16Value); + builder.set_ui8(kExpectedUInt8Value); + builder.set_float_val(kExpectedFloatVal); + builder.set_float_inf(kExpectedFloatInf); + builder.set_float_nan(kExpectedFloatNan); + builder.set_double_val(kExpectedDoubleVal); + builder.set_double_inf(kExpectedDoubleInf); + builder.set_double_nan(kExpectedDoubleNan); + builder.set_name("coming"); + mojo::Array<mojo::String>::Builder string_array(3); + string_array[0] = "one"; + string_array[1] = "two"; + string_array[2] = "three"; + builder.set_string_array(string_array.Finish()); + client_->Echo(builder.Finish()); + } + + virtual void EchoResponse(const js_to_cpp::EchoArgs& arg1, + const js_to_cpp::EchoArgs& arg2) OVERRIDE { + EXPECT_EQ(kExpectedInt64Value, arg1.si64()); + EXPECT_EQ(kExpectedInt32Value, arg1.si32()); + EXPECT_EQ(kExpectedInt16Value, arg1.si16()); + EXPECT_EQ(kExpectedInt8Value, arg1.si8()); + EXPECT_EQ(kExpectedUInt64Value, arg1.ui64()); + EXPECT_EQ(kExpectedUInt32Value, arg1.ui32()); + EXPECT_EQ(kExpectedUInt16Value, arg1.ui16()); + EXPECT_EQ(kExpectedUInt8Value, arg1.ui8()); + EXPECT_EQ(kExpectedFloatVal, arg1.float_val()); + EXPECT_EQ(kExpectedFloatInf, arg1.float_inf()); + EXPECT_NAN(arg1.float_nan()); + EXPECT_EQ(kExpectedDoubleVal, arg1.double_val()); + EXPECT_EQ(kExpectedDoubleInf, arg1.double_inf()); + EXPECT_NAN(arg1.double_nan()); + EXPECT_EQ(std::string("coming"), arg1.name().To<std::string>()); + EXPECT_EQ(std::string("one"), arg1.string_array()[0].To<std::string>()); + EXPECT_EQ(std::string("two"), arg1.string_array()[1].To<std::string>()); + EXPECT_EQ(std::string("three"), arg1.string_array()[2].To<std::string>()); + + EXPECT_EQ(-1, arg2.si64()); + EXPECT_EQ(-1, arg2.si32()); + EXPECT_EQ(-1, arg2.si16()); + EXPECT_EQ(-1, arg2.si8()); + EXPECT_EQ(std::string("going"), arg2.name().To<std::string>()); + + message_count_ += 1; + if (message_count_ == kExpectedMessageCount) + run_loop_->Quit(); + } + + bool DidSucceed() { + return message_count_ == kExpectedMessageCount; + } + + private: + static const int kExpectedMessageCount = 100; + int message_count_; + DISALLOW_COPY_AND_ASSIGN(EchoCppSideConnection); }; class JsToCppTest : public testing::Test { public: JsToCppTest() {} - void RunTest(const std::string& test, ProviderConnection* provider) { - provider->set_run_loop(&run_loop_); - InterfacePipe<sample::Provider, sample::ProviderClient> pipe; - RemotePtr<sample::ProviderClient> provider_client; - provider_client.reset(pipe.handle_to_peer.Pass(), provider); - - provider->set_client(provider_client.get()); + void RunTest(const std::string& test, CppSideConnection* cpp_side) { + cpp_side->set_run_loop(&run_loop_); + InterfacePipe<js_to_cpp::CppSide, js_to_cpp::JsSide> pipe; + RemotePtr<js_to_cpp::JsSide> js_side; + js_side.reset(pipe.handle_to_peer.Pass(), cpp_side); + cpp_side->set_client(js_side.get()); gin::IsolateHolder instance(gin::IsolateHolder::kStrictMode); apps::MojoRunnerDelegate delegate; @@ -88,49 +220,28 @@ class JsToCppTest : public testing::Test { } private: - Environment environment; base::MessageLoop loop; base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(JsToCppTest); }; -// Trivial test to verify a message sent from JS is received. -class FromJsProviderConnection : public ProviderConnection { - public: - explicit FromJsProviderConnection() {} - virtual ~FromJsProviderConnection() { - } - - const base::string16& echo_string() const { return echo_string_; } - - // Provider: - virtual void EchoString(const String& a, - const Callback<void(String)>& callback) OVERRIDE { - echo_string_ = a.To<base::string16>(); - run_loop()->Quit(); - } - - private: - base::string16 echo_string_; +TEST_F(JsToCppTest, Ping) { + if (IsRunningOnIsolatedBot()) + return; - DISALLOW_COPY_AND_ASSIGN(FromJsProviderConnection); -}; + PingCppSideConnection cpp_side_connection; + RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); +} -TEST_F(JsToCppTest, FromJS) { - // TODO(yzshen): Remove this check once isolated tests are supported on the - // Chromium waterfall. (http://crbug.com/351214) - const base::FilePath test_file_path( - test::GetFilePathForJSResource( - "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom")); - if (!base::PathExists(test_file_path)) { - LOG(WARNING) << "Mojom binding files don't exist. Skipping the test."; +TEST_F(JsToCppTest, Echo) { + if (IsRunningOnIsolatedBot()) return; - } - FromJsProviderConnection provider; - RunTest("mojo/apps/js/test/js_to_cpp_unittest", &provider); - EXPECT_EQ("message", base::UTF16ToASCII(provider.echo_string())); + EchoCppSideConnection cpp_side_connection; + RunTest("mojo/apps/js/test/js_to_cpp_unittest", &cpp_side_connection); + EXPECT_TRUE(cpp_side_connection.DidSucceed()); } } // namespace diff --git a/mojo/apps/js/test/js_to_cpp_unittest.js b/mojo/apps/js/test/js_to_cpp_unittest.js index 45bb411..8b0a99b 100644 --- a/mojo/apps/js/test/js_to_cpp_unittest.js +++ b/mojo/apps/js/test/js_to_cpp_unittest.js @@ -3,21 +3,52 @@ // found in the LICENSE file. define("mojo/apps/js/test/js_to_cpp_unittest", [ - 'mojo/public/js/bindings/connection', - "mojo/public/interfaces/bindings/tests/sample_interfaces.mojom", -], function(connector, provider) { - var connection; - - function ProviderClientConnection(provider) { - this.provider_ = provider; - provider.echoString("message"); + "mojo/apps/js/test/js_to_cpp.mojom", + "mojo/public/js/bindings/connection", +], function(jsToCpp, connector) { + var connection, kIterations = 100, kBadValue = 13; + + function JsSideConnection(cppSide) { + this.cppSide_ = cppSide; + cppSide.startTest(); } - ProviderClientConnection.prototype = - Object.create(provider.ProviderClientStub.prototype); + JsSideConnection.prototype = Object.create(jsToCpp.JsSideStub.prototype); + + JsSideConnection.prototype.ping = function (arg) { + this.cppSide_.pingResponse(); + + }; + + JsSideConnection.prototype.echo = function (arg) { + var i, arg2; + + // Ensure negative values are negative. + if (arg.si64 > 0) + arg.si64 = kBadValue; + + if (arg.si32 > 0) + arg.si32 = kBadValue; + + if (arg.si16 > 0) + arg.si16 = kBadValue; + + if (arg.si8 > 0) + arg.si8 = kBadValue; + + for (i = 0; i < kIterations; ++i) { + arg2 = new jsToCpp.EchoArgs(); + arg2.si64 = -1; + arg2.si32 = -1; + arg2.si16 = -1; + arg2.si8 = -1; + arg2.name = "going"; + this.cppSide_.echoResponse(arg, arg2); + } + }; return function(handle) { - connection = new connector.Connection(handle, ProviderClientConnection, - provider.ProviderProxy); + connection = new connector.Connection(handle, JsSideConnection, + jsToCpp.CppSideProxy); }; }); |