summaryrefslogtreecommitdiffstats
path: root/mojo/public
diff options
context:
space:
mode:
authorabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-19 04:33:15 +0000
committerabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-19 04:33:15 +0000
commitbe12cc446c38f5d149318e8282dd32b726c02640 (patch)
treec14985510a4a8e5aad43f6a9c4e77e0c8455a9d7 /mojo/public
parent1e70007669ac9740a0b80ba9b337be657c518328 (diff)
downloadchromium_src-be12cc446c38f5d149318e8282dd32b726c02640.zip
chromium_src-be12cc446c38f5d149318e8282dd32b726c02640.tar.gz
chromium_src-be12cc446c38f5d149318e8282dd32b726c02640.tar.bz2
Port Mojo's sample_service.cc to JavaScript
This CL completes the manual implementation of sample_service.js and tests it using sample_test.js, which exactly mirrors the testing of sample_service.cc by sample_service.cc. (I've also moved sample_service.js into mojo/public/bindings/sample/mojom to better mirror the C++ implementation.) BUG=317398 Review URL: https://codereview.chromium.org/68323004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235917 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/public')
-rw-r--r--mojo/public/bindings/js/codec.js8
-rw-r--r--mojo/public/bindings/js/codec_unittests.js33
-rw-r--r--mojo/public/bindings/js/core.cc3
-rw-r--r--mojo/public/bindings/js/test/run_js_tests.cc12
-rw-r--r--mojo/public/bindings/js/test/sample_service.js99
-rw-r--r--mojo/public/bindings/sample/mojom/sample_service.js229
-rw-r--r--mojo/public/bindings/sample/sample_test.js123
7 files changed, 406 insertions, 101 deletions
diff --git a/mojo/public/bindings/js/codec.js b/mojo/public/bindings/js/codec.js
index b7dcbee..2df9c46 100644
--- a/mojo/public/bindings/js/codec.js
+++ b/mojo/public/bindings/js/codec.js
@@ -50,6 +50,12 @@ define(function() {
return low + high * 0x10000;
}
+ var kAlignment = 8;
+
+ function align(size) {
+ return size + (kAlignment - (size % kAlignment)) % kAlignment;
+ }
+
// Buffer -------------------------------------------------------------------
function Buffer(size) {
@@ -391,7 +397,7 @@ define(function() {
};
var exports = {};
- exports.load32 = load32;
+ exports.align = align;
exports.MessageBuilder = MessageBuilder;
exports.MessageReader = MessageReader;
exports.kArrayHeaderSize = kArrayHeaderSize;
diff --git a/mojo/public/bindings/js/codec_unittests.js b/mojo/public/bindings/js/codec_unittests.js
index 7fd23f6..f22791d 100644
--- a/mojo/public/bindings/js/codec_unittests.js
+++ b/mojo/public/bindings/js/codec_unittests.js
@@ -5,10 +5,11 @@
define([
"gtest",
"mojo/public/bindings/js/codec",
- "mojo/public/bindings/js/test/sample_service"
+ "mojo/public/bindings/sample/mojom/sample_service"
], function(gtest, codec, sample) {
testBar();
testFoo();
+ testAlign();
this.result = "PASS";
function barMatches(bar, expected) {
@@ -161,4 +162,34 @@ define([
equalsArray(foo2.files, foo.files, "foo2.files");
}
+
+ function testAlign() {
+ var aligned = [
+ 0, // 0
+ 8, // 1
+ 8, // 2
+ 8, // 3
+ 8, // 4
+ 8, // 5
+ 8, // 6
+ 8, // 7
+ 8, // 8
+ 16, // 9
+ 16, // 10
+ 16, // 11
+ 16, // 12
+ 16, // 13
+ 16, // 14
+ 16, // 15
+ 16, // 16
+ 24, // 17
+ 24, // 18
+ 24, // 19
+ 24, // 20
+ ];
+ for (var i = 0; i < aligned.length; ++i) {
+ gtest.expectEqual(codec.align(i), aligned[i],
+ "codec.align(" + i + ") is " + codec.align(i));
+ }
+ }
});
diff --git a/mojo/public/bindings/js/core.cc b/mojo/public/bindings/js/core.cc
index 9760ca0..6a048cf 100644
--- a/mojo/public/bindings/js/core.cc
+++ b/mojo/public/bindings/js/core.cc
@@ -156,6 +156,9 @@ v8::Local<v8::ObjectTemplate> Core::GetTemplate(v8::Isolate* isolate) {
templ->Set(gin::StringToSymbol(isolate, "readMessage"),
v8::FunctionTemplate::New(ReadMessage));
+ templ->Set(gin::StringToSymbol(isolate, "kInvalidHandle"),
+ gin::ConvertToV8(isolate, mojo::kInvalidHandle));
+
templ->Set(gin::StringToSymbol(isolate, "RESULT_OK"),
gin::ConvertToV8(isolate, MOJO_RESULT_OK));
templ->Set(gin::StringToSymbol(isolate, "RESULT_CANCELLED"),
diff --git a/mojo/public/bindings/js/test/run_js_tests.cc b/mojo/public/bindings/js/test/run_js_tests.cc
index 00f7574..c558547 100644
--- a/mojo/public/bindings/js/test/run_js_tests.cc
+++ b/mojo/public/bindings/js/test/run_js_tests.cc
@@ -45,6 +45,18 @@ TEST(JSTest, codec) {
RunTest("codec_unittests.js");
}
+TEST(JSTest, sample_test) {
+ base::FilePath path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &path);
+ path = path.AppendASCII("mojo")
+ .AppendASCII("public")
+ .AppendASCII("bindings")
+ .AppendASCII("sample")
+ .AppendASCII("sample_test.js");
+ TestRunnerDelegate delegate;
+ gin::RunTestFromFile(path, &delegate);
+}
+
} // namespace
} // namespace js
} // namespace mojo
diff --git a/mojo/public/bindings/js/test/sample_service.js b/mojo/public/bindings/js/test/sample_service.js
deleted file mode 100644
index 1885f7a..0000000
--- a/mojo/public/bindings/js/test/sample_service.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 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.
-
-// "Generated" code for sample_service.mojom
-define([
- "mojo/public/bindings/js/codec",
- ], function(codec) {
-
- // Bar ----------------------------------------------------------------------
-
- function Bar() {
- this.alpha = 0;
- this.beta = 0;
- this.gamma = 0;
- }
-
- Bar.encodedSize = codec.kStructHeaderSize + 8;
-
- Bar.decode = function(decoder) {
- var val = new Bar();
- var numberOfBytes = decoder.read32();
- var numberOfFields = decoder.read32();
- // TODO(abarth): We need to support optional fields.
- val.alpha = decoder.read8();
- val.beta = decoder.read8();
- val.gamma = decoder.read8();
- decoder.skip(5);
- return val;
- };
-
- Bar.encode = function(encoder, val) {
- encoder.write32(Bar.encodedSize);
- encoder.write32(3);
- encoder.write8(val.alpha);
- encoder.write8(val.beta);
- encoder.write8(val.gamma);
- encoder.skip(5);
- };
-
- // Foo ----------------------------------------------------------------------
-
- function Foo() {
- this.x = 0;
- this.y = 0;
- this.a = 0;
- this.b = 0;
- this.c = 0;
- this.bar = null;
- this.data = [];
- this.extra_bars = [];
- this.name = "";
- this.files = [];
- }
-
- Foo.encodedSize = codec.kStructHeaderSize + 64;
-
- Foo.decode = function(decoder) {
- var val = new Foo();
- var numberOfBytes = decoder.read32();
- var numberofFields = decoder.read32();
- // TODO(abarth): We need to support optional fields.
- val.x = decoder.read32();
- val.y = decoder.read32();
- var packed = decoder.read8();
- val.a = (packed >> 0) & 1;
- val.b = (packed >> 1) & 1;
- val.c = (packed >> 2) & 1;
- decoder.skip(7);
- val.bar = decoder.decodeStructPointer(Bar);
- val.data = decoder.decodeArrayPointer(codec.Uint8);
- val.extra_bars = decoder.decodeArrayPointer(new codec.PointerTo(Bar));
- val.name = decoder.decodeStringPointer();
- val.files = decoder.decodeArrayPointer(codec.Handle);
- return val;
- }
-
- Foo.encode = function(encoder, val) {
- encoder.write32(Foo.encodedSize);
- encoder.write32(10);
- encoder.write32(val.x);
- encoder.write32(val.y);
- var packed = (val.a & 1) << 0 |
- (val.b & 1) << 1 |
- (val.c & 1) << 2;
- encoder.write8(packed);
- encoder.skip(7);
- encoder.encodeStructPointer(Bar, val.bar);
- encoder.encodeArrayPointer(codec.Uint8, val.data);
- encoder.encodeArrayPointer(new codec.PointerTo(Bar), val.extra_bars);
- encoder.encodeStringPointer(val.name);
- encoder.encodeArrayPointer(codec.Handle, val.files);
- };
-
- var exports = {};
- exports.Bar = Bar;
- exports.Foo = Foo;
- return exports;
-});
diff --git a/mojo/public/bindings/sample/mojom/sample_service.js b/mojo/public/bindings/sample/mojom/sample_service.js
new file mode 100644
index 0000000..081ed99
--- /dev/null
+++ b/mojo/public/bindings/sample/mojom/sample_service.js
@@ -0,0 +1,229 @@
+// Copyright 2013 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.
+
+// "Generated" code for sample_service.mojom
+define([
+ "mojo/public/bindings/js/core",
+ "mojo/public/bindings/js/codec",
+ ], function(core, codec) {
+
+ // Bar ----------------------------------------------------------------------
+
+ function Bar() {
+ this.alpha = 0;
+ this.beta = 0;
+ this.gamma = 0;
+ }
+
+ Bar.encodedSize = codec.kStructHeaderSize + 8;
+
+ Bar.decode = function(decoder) {
+ var val = new Bar();
+ var numberOfBytes = decoder.read32();
+ var numberOfFields = decoder.read32();
+ // TODO(abarth): We need to support optional fields.
+ val.alpha = decoder.read8();
+ val.beta = decoder.read8();
+ val.gamma = decoder.read8();
+ decoder.skip(5);
+ return val;
+ };
+
+ Bar.encode = function(encoder, val) {
+ encoder.write32(Bar.encodedSize);
+ encoder.write32(3);
+ encoder.write8(val.alpha);
+ encoder.write8(val.beta);
+ encoder.write8(val.gamma);
+ encoder.skip(5);
+ };
+
+ // Foo ----------------------------------------------------------------------
+
+ function Foo() {
+ this.x = 0;
+ this.y = 0;
+ this.a = 0;
+ this.b = 0;
+ this.c = 0;
+ this.bar = null;
+ this.data = [];
+ this.extra_bars = [];
+ this.name = "";
+ this.files = [];
+ }
+
+ Foo.encodedSize = codec.kStructHeaderSize + 64;
+
+ Foo.decode = function(decoder) {
+ var val = new Foo();
+ var numberOfBytes = decoder.read32();
+ var numberOfFields = decoder.read32();
+ // TODO(abarth): We need to support optional fields.
+ val.x = decoder.read32();
+ val.y = decoder.read32();
+ var packed = decoder.read8();
+ val.a = (packed >> 0) & 1;
+ val.b = (packed >> 1) & 1;
+ val.c = (packed >> 2) & 1;
+ decoder.skip(7);
+ val.bar = decoder.decodeStructPointer(Bar);
+ val.data = decoder.decodeArrayPointer(codec.Uint8);
+ val.extra_bars = decoder.decodeArrayPointer(new codec.PointerTo(Bar));
+ val.name = decoder.decodeStringPointer();
+ val.files = decoder.decodeArrayPointer(codec.Handle);
+ return val;
+ };
+
+ Foo.encode = function(encoder, val) {
+ encoder.write32(Foo.encodedSize);
+ encoder.write32(10);
+ encoder.write32(val.x);
+ encoder.write32(val.y);
+ var packed = (val.a & 1) << 0 |
+ (val.b & 1) << 1 |
+ (val.c & 1) << 2;
+ encoder.write8(packed);
+ encoder.skip(7);
+ encoder.encodeStructPointer(Bar, val.bar);
+ encoder.encodeArrayPointer(codec.Uint8, val.data);
+ encoder.encodeArrayPointer(new codec.PointerTo(Bar), val.extra_bars);
+ encoder.encodeStringPointer(val.name);
+ encoder.encodeArrayPointer(codec.Handle, val.files);
+ };
+
+ // Service ------------------------------------------------------------------
+
+ var kService_Frobinate_Name = 1;
+
+ function Service_Frobinate_Params() {
+ this.foo = null;
+ this.baz = false;
+ this.port = core.kInvalidHandle;
+ }
+
+ Service_Frobinate_Params.encodedSize = codec.kStructHeaderSize + 16;
+
+ Service_Frobinate_Params.decode = function(decoder) {
+ var val = new Service_Frobinate_Params();
+ var numberOfBytes = decoder.read32();
+ var numberOfFields = decoder.read32();
+ val.foo = decoder.decodeStructPointer(Foo);
+ val.baz = decoder.read8() & 1;
+ decoder.skip(3);
+ val.port = decoder.decodeHandle();
+ return val;
+ };
+
+ Service_Frobinate_Params.encode = function(encoder, val) {
+ encoder.write32(Service_Frobinate_Params.encodedSize);
+ encoder.write32(3);
+ encoder.encodeStructPointer(Foo, val.foo);
+ encoder.write8(val.baz & 1);
+ encoder.skip(3);
+ encoder.encodeHandle(val.port);
+ };
+
+ function ServiceProxy(receiver) {
+ this.receiver_ = receiver;
+ }
+
+ ServiceProxy.prototype.frobinate = function(foo, baz, port) {
+ var params = new Service_Frobinate_Params();
+ params.foo = foo;
+ params.baz = baz;
+ params.port = port;
+
+ var payloadSize = codec.align(Service_Frobinate_Params.encodedSize);
+ var builder = new codec.MessageBuilder(kService_Frobinate_Name,
+ payloadSize);
+ builder.encodeStruct(Service_Frobinate_Params, params);
+ var message = builder.finish();
+ this.receiver_.accept(message);
+ };
+
+ function ServiceStub() {
+ }
+
+ ServiceStub.prototype.accept = function(message) {
+ var reader = new codec.MessageReader(message);
+ switch (reader.messageName) {
+ case kService_Frobinate_Name:
+ var params = reader.decodeStruct(Service_Frobinate_Params);
+ this.frobinate(params.foo, params.baz, params.port);
+ return true;
+ default:
+ return false;
+ }
+ };
+
+ // ServiceClient ------------------------------------------------------------
+
+ var kServiceClient_DidFrobinate_Name = 0;
+
+ function ServiceClient_DidFrobinate_Params() {
+ this.result = 0;
+ }
+
+ ServiceClient_DidFrobinate_Params.encodedSize = codec.kStructHeaderSize + 8;
+
+ ServiceClient_DidFrobinate_Params.decode = function(decoder) {
+ var val = new ServiceClient_DidFrobinate_Params();
+ var numberOfBytes = decoder.read32();
+ var numberOfFields = decoder.read32();
+ val.result = decoder.read32();
+ decoder.skip(4);
+ return val;
+ };
+
+ ServiceClient_DidFrobinate_Params.encode = function(encoder, val) {
+ encoder.write32(ServiceClient_DidFrobinate_Params.encodedSize);
+ encoder.write32(1);
+ encoder.write32(val.result);
+ encoder.skip(4);
+ };
+
+ function ServiceClientProxy(receiver) {
+ this.receiver_ = receiver;
+ }
+
+ ServiceClientProxy.prototype.didFrobinate = function(result) {
+ var params = new ServiceClient_DidFrobinate_Params();
+ params.result = result;
+
+ var payloadSize = codec.align(
+ ServiceClient_DidFrobinate_Params.encodedSize);
+ var builder = new codec.MessageBuilder(kServiceClient_DidFrobinate_Name,
+ payloadSize);
+ builder.encodeStruct(ServiceClient_DidFrobinate_Params, params);
+ var message = builder.finish();
+ this.receiver_.accept(message);
+ };
+
+ function ServiceClientStub() {
+ }
+
+ ServiceClientStub.prototype.accept = function(message) {
+ var reader = new codec.MessageReader(message);
+ switch (reader.messageName) {
+ case kServiceClient_DidFrobinate_Name:
+ var params = reader.decodeStruct(kServiceClient_DidFrobinate_Name);
+ this.didFrobinate(params.result);
+ return true;
+ default:
+ return false;
+ }
+ };
+
+ // Exports ------------------------------------------------------------------
+
+ var exports = {};
+ exports.Bar = Bar;
+ exports.Foo = Foo;
+ exports.ServiceProxy = ServiceProxy;
+ exports.ServiceStub = ServiceStub;
+ exports.ServiceClientProxy = ServiceClientProxy;
+ exports.ServiceClientStub = ServiceClientStub;
+ return exports;
+});
diff --git a/mojo/public/bindings/sample/sample_test.js b/mojo/public/bindings/sample/sample_test.js
new file mode 100644
index 0000000..230f4df
--- /dev/null
+++ b/mojo/public/bindings/sample/sample_test.js
@@ -0,0 +1,123 @@
+// Copyright 2013 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.
+
+define([
+ "gtest",
+ // TODO(abarth): We shouldn't need to depend on codec, but there seems to
+ // be a bug in the module loading system whereby this test doesn't run if
+ // we don't import codec here.
+ "mojo/public/bindings/js/codec",
+ "mojo/public/bindings/sample/mojom/sample_service"
+ ], function(gtest, codec, sample) {
+
+ var global = this;
+
+ function makeFoo() {
+ var bar = new sample.Bar();
+ bar.alpha = 20;
+ bar.beta = 40;
+ bar.gamma = 60;
+
+ var extra_bars = new Array(3);
+ for (var i = 0; i < extra_bars.length; ++i) {
+ var base = i * 100;
+ extra_bars[i] = new sample.Bar();
+ extra_bars[i].alpha = base;
+ extra_bars[i].beta = base + 20;
+ extra_bars[i].gamma = base + 40;
+ }
+
+ var data = new Array(10);
+ for (var i = 0; i < data.length; ++i) {
+ data[i] = data.length - i;
+ }
+
+ var files = new Array(4);
+ for (var i = 0; i < files.length; ++i) {
+ files[i] = 0xFFFF - i;
+ }
+
+ var foo = new sample.Foo();
+ foo.name = "foopy";
+ foo.x = 1;
+ foo.y = 2;
+ foo.a = false;
+ foo.b = true;
+ foo.c = false;
+ foo.bar = bar;
+ foo.extra_bars = extra_bars;
+ foo.data = data;
+ foo.files = files;
+ return foo;
+ }
+
+ // Check that the given |Foo| is identical to the one made by |MakeFoo()|.
+ function checkFoo(foo) {
+ gtest.expectEqual(foo.name, "foopy", "foo.name is " + foo.name);
+ gtest.expectEqual(foo.x, 1, "foo.x is " + foo.x);
+ gtest.expectEqual(foo.y, 2, "foo.y is " + foo.y);
+ gtest.expectFalse(foo.a, "foo.a is " + foo.a);
+ gtest.expectTrue(foo.b, "foo.b is " + foo.b);
+ gtest.expectFalse(foo.c, "foo.c is " + foo.c);
+ gtest.expectEqual(foo.bar.alpha, 20, "foo.bar.alpha is " + foo.bar.alpha);
+ gtest.expectEqual(foo.bar.beta, 40, "foo.bar.beta is " + foo.bar.beta);
+ gtest.expectEqual(foo.bar.gamma, 60, "foo.bar.gamma is " + foo.bar.gamma);
+
+ gtest.expectEqual(foo.extra_bars.length, 3,
+ "foo.extra_bars.length is " + foo.extra_bars.length);
+ for (var i = 0; i < foo.extra_bars.length; ++i) {
+ var base = i * 100;
+ gtest.expectEqual(foo.extra_bars[i].alpha, base,
+ "foo.extra_bars[" + i + "].alpha is " + foo.extra_bars[i].alpha);
+ gtest.expectEqual(foo.extra_bars[i].beta, base + 20,
+ "foo.extra_bars[" + i + "].beta is " + foo.extra_bars[i].beta);
+ gtest.expectEqual(foo.extra_bars[i].gamma, base + 40,
+ "foo.extra_bars[" + i + "].gamma is " + foo.extra_bars[i].gamma);
+ }
+
+ gtest.expectEqual(foo.data.length, 10,
+ "foo.data.length is " + foo.data.length);
+ for (var i = 0; i < foo.data.length; ++i) {
+ gtest.expectEqual(foo.data[i], foo.data.length - i,
+ "foo.data[" + i + "] is " + foo.data[i]);
+ }
+
+ gtest.expectEqual(foo.files.length, 4,
+ "foo.files.length " + foo.files.length);
+ for (var i = 0; i < foo.files.length; ++i) {
+ gtest.expectEqual(foo.files[i], 0xFFFF - i,
+ "foo.files[" + i + "] is " + foo.files[i]);
+ }
+ }
+
+ function ServiceImpl() {
+ }
+
+ ServiceImpl.prototype = Object.create(sample.ServiceStub.prototype);
+
+ ServiceImpl.prototype.frobinate = function(foo, baz, port) {
+ checkFoo(foo);
+ gtest.expectTrue(baz, "baz is " + baz);
+ gtest.expectEqual(port, 10, "port is " + port);
+ global.result = "PASS";
+ };
+
+ function SimpleMessageReceiver() {
+ }
+
+ SimpleMessageReceiver.prototype.accept = function(message) {
+ // Imagine some IPC happened here.
+ var serviceImpl = new ServiceImpl();
+ serviceImpl.accept(message);
+ };
+
+ var receiver = new SimpleMessageReceiver();
+ var serviceProxy = new sample.ServiceProxy(receiver);
+
+ var foo = makeFoo();
+ checkFoo(foo);
+
+ var port = 10;
+ serviceProxy.frobinate(foo, true, port);
+});