summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhansmuller@chromium.org <hansmuller@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 18:48:57 +0000
committerhansmuller@chromium.org <hansmuller@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 18:48:57 +0000
commit32c5a54e596d25d904a545df5787abeb5736ca5e (patch)
tree9cbb078039f24f063da477cc75ce7df3f1e931b0
parent5264305d2205771fc7622ce831ee70f18611b770 (diff)
downloadchromium_src-32c5a54e596d25d904a545df5787abeb5736ca5e.zip
chromium_src-32c5a54e596d25d904a545df5787abeb5736ca5e.tar.gz
chromium_src-32c5a54e596d25d904a545df5787abeb5736ca5e.tar.bz2
Validate incoming JS Message Headers: test message parser
This is the first part of the "Validate incoming JS Message Headers" CL - https://codereview.chromium.org/406993002/ It's just the test message file parser and its sanity check. TBR=jochen@chromium.org BUG=395801 Review URL: https://codereview.chromium.org/411553003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285632 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/webui/web_ui_data_source_impl.cc1
-rw-r--r--content/browser/webui/web_ui_mojo_browsertest.cc3
-rw-r--r--content/content_resources.grd1
-rw-r--r--mojo/apps/js/test/js_to_cpp_unittest.js4
-rw-r--r--mojo/apps/js/test/run_apps_js_tests.cc22
-rw-r--r--mojo/mojo.gyp14
-rw-r--r--mojo/mojo_public_tests.gypi14
-rw-r--r--mojo/public/js/bindings/buffer.js156
-rw-r--r--mojo/public/js/bindings/codec.js155
-rw-r--r--mojo/public/js/bindings/codec_unittests.js (renamed from mojo/bindings/js/codec_unittests.js)2
-rw-r--r--mojo/public/js/bindings/connector.js7
-rw-r--r--mojo/public/js/bindings/constants.cc1
-rw-r--r--mojo/public/js/bindings/constants.h1
-rw-r--r--mojo/public/js/bindings/core_unittests.js (renamed from mojo/bindings/js/core_unittests.js)2
-rw-r--r--mojo/public/js/bindings/tests/DEPS6
-rw-r--r--mojo/public/js/bindings/tests/run_js_tests.cc (renamed from mojo/bindings/js/run_js_tests.cc)19
-rw-r--r--mojo/public/js/bindings/tests/validation_test_input_parser.js299
-rw-r--r--mojo/public/js/bindings/validation_unittests.js163
18 files changed, 686 insertions, 184 deletions
diff --git a/content/browser/webui/web_ui_data_source_impl.cc b/content/browser/webui/web_ui_data_source_impl.cc
index 0523967..fb995e0 100644
--- a/content/browser/webui/web_ui_data_source_impl.cc
+++ b/content/browser/webui/web_ui_data_source_impl.cc
@@ -31,6 +31,7 @@ WebUIDataSource* WebUIDataSource::AddMojoDataSource(
const char* path;
int id;
} resources[] = {
+ { mojo::kBufferModuleName, IDR_MOJO_BUFFER_JS },
{ mojo::kCodecModuleName, IDR_MOJO_CODEC_JS },
{ mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS },
{ mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS },
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc
index 6261316..17b1bc8 100644
--- a/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -40,7 +40,8 @@ bool got_message = false;
bool GetResource(const std::string& id,
const WebUIDataSource::GotDataCallback& callback) {
// These are handled by the WebUIDataSource that AddMojoDataSource() creates.
- if (id == mojo::kCodecModuleName ||
+ if (id == mojo::kBufferModuleName ||
+ id == mojo::kCodecModuleName ||
id == mojo::kConnectionModuleName ||
id == mojo::kConnectorModuleName ||
id == mojo::kUnicodeModuleName ||
diff --git a/content/content_resources.grd b/content/content_resources.grd
index cdb7855..32a2862 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -39,6 +39,7 @@
<include name="IDR_UTILITY_SANDBOX_PROFILE" file="utility/utility.sb" type="BINDATA" />
</if>
<if expr="not is_ios">
+ <include name="IDR_MOJO_BUFFER_JS" file="../mojo/public/js/bindings/buffer.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_MOJO_CODEC_JS" file="../mojo/public/js/bindings/codec.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_MOJO_CONNECTION_JS" file="../mojo/public/js/bindings/connection.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_MOJO_CONNECTOR_JS" file="../mojo/public/js/bindings/connector.js" flattenhtml="true" type="BINDATA" />
diff --git a/mojo/apps/js/test/js_to_cpp_unittest.js b/mojo/apps/js/test/js_to_cpp_unittest.js
index 63b5f8b..b1073c8 100644
--- a/mojo/apps/js/test/js_to_cpp_unittest.js
+++ b/mojo/apps/js/test/js_to_cpp_unittest.js
@@ -98,8 +98,8 @@ define('mojo/apps/js/test/js_to_cpp_unittest', [
var value;
if (offset < message.buffer.arrayBuffer.byteLength) {
mask = 1 << (iteration % 8);
- value = message.buffer.dataView.getUint8(offset) ^ mask;
- message.buffer.dataView.setUint8(offset, value);
+ value = message.buffer.getUint8(offset) ^ mask;
+ message.buffer.setUint8(offset, value);
return this.realAccept(message);
}
stopSignalled = true;
diff --git a/mojo/apps/js/test/run_apps_js_tests.cc b/mojo/apps/js/test/run_apps_js_tests.cc
index f01ecc8..36b185b 100644
--- a/mojo/apps/js/test/run_apps_js_tests.cc
+++ b/mojo/apps/js/test/run_apps_js_tests.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "gin/modules/console.h"
@@ -13,7 +12,6 @@
#include "mojo/apps/js/bindings/monotonic_clock.h"
#include "mojo/apps/js/bindings/threading.h"
#include "mojo/bindings/js/core.h"
-#include "mojo/common/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -50,30 +48,10 @@ void RunTest(std::string test, bool run_until_idle) {
// TODO(abarth): Should we autogenerate these stubs from GYP?
TEST(JSTest, sample_test) {
- // 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_service.mojom"));
- if (!base::PathExists(test_file_path)) {
- LOG(WARNING) << "Mojom binding files don't exist. Skipping the test.";
- return;
- }
-
RunTest("sample_service_unittests.js", true);
}
TEST(JSTest, connection) {
- // 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_service.mojom"));
- if (!base::PathExists(test_file_path)) {
- LOG(WARNING) << "Mojom binding files don't exist. Skipping the test.";
- return;
- }
-
RunTest("connection_unittests.js", false);
}
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index aa34809..1e60ea0 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -751,20 +751,6 @@
],
},
{
- 'target_name': 'mojo_js_unittests',
- 'type': 'executable',
- 'dependencies': [
- '../gin/gin.gyp:gin_test',
- 'mojo_common_test_support',
- 'mojo_js_bindings_lib',
- 'mojo_run_all_unittests',
- 'mojo_public_test_interfaces',
- ],
- 'sources': [
- 'bindings/js/run_js_tests.cc',
- ],
- },
- {
'target_name': 'mojo_message_generator',
'type': 'executable',
'dependencies': [
diff --git a/mojo/mojo_public_tests.gypi b/mojo/mojo_public_tests.gypi
index 658d594..bbd1959 100644
--- a/mojo/mojo_public_tests.gypi
+++ b/mojo/mojo_public_tests.gypi
@@ -189,5 +189,19 @@
'mojo_cpp_bindings',
],
},
+ {
+ 'target_name': 'mojo_js_unittests',
+ 'type': 'executable',
+ 'dependencies': [
+ '../gin/gin.gyp:gin_test',
+ 'mojo_common_test_support',
+ 'mojo_js_bindings_lib',
+ 'mojo_public_test_interfaces',
+ 'mojo_run_all_unittests',
+ ],
+ 'sources': [
+ 'public/js/bindings/tests/run_js_tests.cc',
+ ],
+ },
],
}
diff --git a/mojo/public/js/bindings/buffer.js b/mojo/public/js/bindings/buffer.js
new file mode 100644
index 0000000..d74fef6
--- /dev/null
+++ b/mojo/public/js/bindings/buffer.js
@@ -0,0 +1,156 @@
+// Copyright 2014 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("mojo/public/js/bindings/buffer", function() {
+
+ var kHostIsLittleEndian = (function () {
+ var endianArrayBuffer = new ArrayBuffer(2);
+ var endianUint8Array = new Uint8Array(endianArrayBuffer);
+ var endianUint16Array = new Uint16Array(endianArrayBuffer);
+ endianUint16Array[0] = 1;
+ return endianUint8Array[0] == 1;
+ })();
+
+ var kHighWordMultiplier = 0x100000000;
+
+ function Buffer(sizeOrArrayBuffer) {
+ if (sizeOrArrayBuffer instanceof ArrayBuffer)
+ this.arrayBuffer = sizeOrArrayBuffer;
+ else
+ this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer);
+
+ this.dataView = new DataView(this.arrayBuffer);
+ this.next = 0;
+ }
+
+ Object.defineProperty(Buffer.prototype, "byteLength", {
+ get: function() { return this.arrayBuffer.byteLength; }
+ });
+
+ Buffer.prototype.alloc = function(size) {
+ var pointer = this.next;
+ this.next += size;
+ if (this.next > this.byteLength) {
+ var newSize = (1.5 * (this.byteLength + size)) | 0;
+ this.grow(newSize);
+ }
+ return pointer;
+ };
+
+ function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) {
+ (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer));
+ }
+
+ Buffer.prototype.grow = function(size) {
+ var newArrayBuffer = new ArrayBuffer(size);
+ copyArrayBuffer(newArrayBuffer, this.arrayBuffer);
+ this.arrayBuffer = newArrayBuffer;
+ this.dataView = new DataView(this.arrayBuffer);
+ };
+
+ Buffer.prototype.trim = function() {
+ this.arrayBuffer = this.arrayBuffer.slice(0, this.next);
+ this.dataView = new DataView(this.arrayBuffer);
+ };
+
+ Buffer.prototype.getUint8 = function(offset) {
+ return this.dataView.getUint8(offset);
+ }
+ Buffer.prototype.getUint16 = function(offset) {
+ return this.dataView.getUint16(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getUint32 = function(offset) {
+ return this.dataView.getUint32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getUint64 = function(offset) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ hi = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ } else {
+ hi = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
+ }
+
+ Buffer.prototype.getInt8 = function(offset) {
+ return this.dataView.getInt8(offset);
+ }
+ Buffer.prototype.getInt16 = function(offset) {
+ return this.dataView.getInt16(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getInt32 = function(offset) {
+ return this.dataView.getInt32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getInt64 = function(offset) {
+ var lo, hi;
+ if (kHostIsLittleEndian) {
+ lo = this.dataView.getUint32(offset, kHostIsLittleEndian);
+ hi = this.dataView.getInt32(offset + 4, kHostIsLittleEndian);
+ } else {
+ hi = this.dataView.getInt32(offset, kHostIsLittleEndian);
+ lo = this.dataView.getUint32(offset + 4, kHostIsLittleEndian);
+ }
+ return lo + hi * kHighWordMultiplier;
+ }
+
+ Buffer.prototype.getFloat32 = function(offset) {
+ return this.dataView.getFloat32(offset, kHostIsLittleEndian);
+ }
+ Buffer.prototype.getFloat64 = function(offset) {
+ return this.dataView.getFloat64(offset, kHostIsLittleEndian);
+ }
+
+ Buffer.prototype.setUint8 = function(offset, value) {
+ this.dataView.setUint8(offset, value);
+ }
+ Buffer.prototype.setUint16 = function(offset, value) {
+ this.dataView.setUint16(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setUint32 = function(offset, value) {
+ this.dataView.setUint32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setUint64 = function(offset, value) {
+ var hi = (value / kHighWordMultiplier) | 0;
+ if (kHostIsLittleEndian) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
+ } else {
+ this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
+ }
+ }
+
+ Buffer.prototype.setInt8 = function(offset, value) {
+ this.dataView.setInt8(offset, value);
+ }
+ Buffer.prototype.setInt16 = function(offset, value) {
+ this.dataView.setInt16(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setInt32 = function(offset, value) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setInt64 = function(offset, value) {
+ var hi = Math.floor(value / kHighWordMultiplier);
+ if (kHostIsLittleEndian) {
+ this.dataView.setInt32(offset, value, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, hi, kHostIsLittleEndian);
+ } else {
+ this.dataView.setInt32(offset, hi, kHostIsLittleEndian);
+ this.dataView.setInt32(offset + 4, value, kHostIsLittleEndian);
+ }
+ }
+
+ Buffer.prototype.setFloat32 = function(offset, value) {
+ this.dataView.setFloat32(offset, value, kHostIsLittleEndian);
+ }
+ Buffer.prototype.setFloat64 = function(offset, value) {
+ this.dataView.setFloat64(offset, value, kHostIsLittleEndian);
+ }
+
+ var exports = {};
+ exports.Buffer = Buffer;
+ return exports;
+});
diff --git a/mojo/public/js/bindings/codec.js b/mojo/public/js/bindings/codec.js
index 9756f4a..dca6009 100644
--- a/mojo/public/js/bindings/codec.js
+++ b/mojo/public/js/bindings/codec.js
@@ -3,112 +3,20 @@
// found in the LICENSE file.
define("mojo/public/js/bindings/codec", [
- "mojo/public/js/bindings/unicode"
-], function(unicode) {
+ "mojo/public/js/bindings/unicode",
+ "mojo/public/js/bindings/buffer"
+ ], function(unicode, buffer) {
var kErrorUnsigned = "Passing negative value to unsigned";
// Memory -------------------------------------------------------------------
var kAlignment = 8;
- var kHighWordMultiplier = 0x100000000;
- var kHostIsLittleEndian = (function () {
- var endianArrayBuffer = new ArrayBuffer(2);
- var endianUint8Array = new Uint8Array(endianArrayBuffer);
- var endianUint16Array = new Uint16Array(endianArrayBuffer);
- endianUint16Array[0] = 1;
- return endianUint8Array[0] == 1;
- })();
function align(size) {
return size + (kAlignment - (size % kAlignment)) % kAlignment;
}
- function getInt64(dataView, byteOffset, value) {
- var lo, hi;
- if (kHostIsLittleEndian) {
- lo = dataView.getUint32(byteOffset, kHostIsLittleEndian);
- hi = dataView.getInt32(byteOffset + 4, kHostIsLittleEndian);
- } else {
- hi = dataView.getInt32(byteOffset, kHostIsLittleEndian);
- lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
- }
- return lo + hi * kHighWordMultiplier;
- }
-
- function getUint64(dataView, byteOffset, value) {
- var lo, hi;
- if (kHostIsLittleEndian) {
- lo = dataView.getUint32(byteOffset, kHostIsLittleEndian);
- hi = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
- } else {
- hi = dataView.getUint32(byteOffset, kHostIsLittleEndian);
- lo = dataView.getUint32(byteOffset + 4, kHostIsLittleEndian);
- }
- return lo + hi * kHighWordMultiplier;
- }
-
- function setInt64(dataView, byteOffset, value) {
- var hi = Math.floor(value / kHighWordMultiplier);
- if (kHostIsLittleEndian) {
- dataView.setInt32(byteOffset, value, kHostIsLittleEndian);
- dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian);
- } else {
- dataView.setInt32(byteOffset, hi, kHostIsLittleEndian);
- dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian);
- }
- }
-
- function setUint64(dataView, byteOffset, value) {
- var hi = (value / kHighWordMultiplier) | 0;
- if (kHostIsLittleEndian) {
- dataView.setInt32(byteOffset, value, kHostIsLittleEndian);
- dataView.setInt32(byteOffset + 4, hi, kHostIsLittleEndian);
- } else {
- dataView.setInt32(byteOffset, hi, kHostIsLittleEndian);
- dataView.setInt32(byteOffset + 4, value, kHostIsLittleEndian);
- }
- }
-
- function copyArrayBuffer(dstArrayBuffer, srcArrayBuffer) {
- (new Uint8Array(dstArrayBuffer)).set(new Uint8Array(srcArrayBuffer));
- }
-
- // Buffer -------------------------------------------------------------------
-
- function Buffer(sizeOrArrayBuffer) {
- if (sizeOrArrayBuffer instanceof ArrayBuffer) {
- this.arrayBuffer = sizeOrArrayBuffer;
- } else {
- this.arrayBuffer = new ArrayBuffer(sizeOrArrayBuffer);
- };
-
- this.dataView = new DataView(this.arrayBuffer);
- this.next = 0;
- }
-
- Buffer.prototype.alloc = function(size) {
- var pointer = this.next;
- this.next += size;
- if (this.next > this.arrayBuffer.byteLength) {
- var newSize = (1.5 * (this.arrayBuffer.byteLength + size)) | 0;
- this.grow(newSize);
- }
- return pointer;
- };
-
- Buffer.prototype.grow = function(size) {
- var newArrayBuffer = new ArrayBuffer(size);
- copyArrayBuffer(newArrayBuffer, this.arrayBuffer);
- this.arrayBuffer = newArrayBuffer;
- this.dataView = new DataView(this.arrayBuffer);
- };
-
- Buffer.prototype.trim = function() {
- this.arrayBuffer = this.arrayBuffer.slice(0, this.next);
- this.dataView = new DataView(this.arrayBuffer);
- };
-
// Constants ----------------------------------------------------------------
var kArrayHeaderSize = 8;
@@ -130,64 +38,61 @@ define("mojo/public/js/bindings/codec", [
};
Decoder.prototype.readInt8 = function() {
- var result = this.buffer.dataView.getInt8(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getInt8(this.next);
this.next += 1;
return result;
};
Decoder.prototype.readUint8 = function() {
- var result = this.buffer.dataView.getUint8(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getUint8(this.next);
this.next += 1;
return result;
};
Decoder.prototype.readInt16 = function() {
- var result = this.buffer.dataView.getInt16(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getInt16(this.next);
this.next += 2;
return result;
};
Decoder.prototype.readUint16 = function() {
- var result = this.buffer.dataView.getUint16(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getUint16(this.next);
this.next += 2;
return result;
};
Decoder.prototype.readInt32 = function() {
- var result = this.buffer.dataView.getInt32(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getInt32(this.next);
this.next += 4;
return result;
};
Decoder.prototype.readUint32 = function() {
- var result = this.buffer.dataView.getUint32(this.next, kHostIsLittleEndian);
+ var result = this.buffer.getUint32(this.next);
this.next += 4;
return result;
};
Decoder.prototype.readInt64 = function() {
- var result = getInt64(this.buffer.dataView, this.next, kHostIsLittleEndian);
+ var result = this.buffer.getInt64(this.next);
this.next += 8;
return result;
};
Decoder.prototype.readUint64 = function() {
- var result = getUint64(
- this.buffer.dataView, this.next, kHostIsLittleEndian);
+ var result = this.buffer.getUint64(this.next);
this.next += 8;
return result;
};
Decoder.prototype.readFloat = function() {
- var result = this.buffer.dataView.getFloat32(
- this.next, kHostIsLittleEndian);
+ var result = this.buffer.getFloat32(this.next);
this.next += 4;
return result;
};
Decoder.prototype.readDouble = function() {
- var result = this.buffer.dataView.getFloat64(
- this.next, kHostIsLittleEndian);
+ var result = this.buffer.getFloat64(this.next);
this.next += 8;
return result;
};
@@ -293,8 +198,7 @@ define("mojo/public/js/bindings/codec", [
};
Encoder.prototype.writeInt8 = function(val) {
- // NOTE: Endianness doesn't come into play for single bytes.
- this.buffer.dataView.setInt8(this.next, val);
+ this.buffer.setInt8(this.next, val);
this.next += 1;
};
@@ -302,13 +206,12 @@ define("mojo/public/js/bindings/codec", [
if (val < 0) {
throw new Error(kErrorUnsigned);
}
- // NOTE: Endianness doesn't come into play for single bytes.
- this.buffer.dataView.setUint8(this.next, val);
+ this.buffer.setUint8(this.next, val);
this.next += 1;
};
Encoder.prototype.writeInt16 = function(val) {
- this.buffer.dataView.setInt16(this.next, val, kHostIsLittleEndian);
+ this.buffer.setInt16(this.next, val);
this.next += 2;
};
@@ -316,12 +219,12 @@ define("mojo/public/js/bindings/codec", [
if (val < 0) {
throw new Error(kErrorUnsigned);
}
- this.buffer.dataView.setUint16(this.next, val, kHostIsLittleEndian);
+ this.buffer.setUint16(this.next, val);
this.next += 2;
};
Encoder.prototype.writeInt32 = function(val) {
- this.buffer.dataView.setInt32(this.next, val, kHostIsLittleEndian);
+ this.buffer.setInt32(this.next, val);
this.next += 4;
};
@@ -329,12 +232,12 @@ define("mojo/public/js/bindings/codec", [
if (val < 0) {
throw new Error(kErrorUnsigned);
}
- this.buffer.dataView.setUint32(this.next, val, kHostIsLittleEndian);
+ this.buffer.setUint32(this.next, val);
this.next += 4;
};
Encoder.prototype.writeInt64 = function(val) {
- setInt64(this.buffer.dataView, this.next, val);
+ this.buffer.setInt64(this.next, val);
this.next += 8;
};
@@ -342,17 +245,17 @@ define("mojo/public/js/bindings/codec", [
if (val < 0) {
throw new Error(kErrorUnsigned);
}
- setUint64(this.buffer.dataView, this.next, val);
+ this.buffer.setUint64(this.next, val);
this.next += 8;
};
Encoder.prototype.writeFloat = function(val) {
- this.buffer.dataView.setFloat32(this.next, val, kHostIsLittleEndian);
+ this.buffer.setFloat32(this.next, val);
this.next += 4;
};
Encoder.prototype.writeDouble = function(val) {
- this.buffer.dataView.setFloat64(this.next, val, kHostIsLittleEndian);
+ this.buffer.setFloat64(this.next, val);
this.next += 8;
};
@@ -465,11 +368,11 @@ define("mojo/public/js/bindings/codec", [
Message.prototype.setRequestID = function(requestID) {
// TODO(darin): Verify that space was reserved for this field!
- setUint64(this.buffer.dataView, kRequestIDOffset, requestID);
+ this.buffer.setUint64(kRequestIDOffset, requestID);
};
Message.prototype.getFlags = function() {
- return this.buffer.dataView.getUint32(kFlagsOffset, kHostIsLittleEndian);
+ return this.buffer.getUint32(kFlagsOffset);
};
// MessageBuilder -----------------------------------------------------------
@@ -478,7 +381,7 @@ define("mojo/public/js/bindings/codec", [
// Currently, we don't compute the payload size correctly ahead of time.
// Instead, we resize the buffer at the end.
var numberOfBytes = kMessageHeaderSize + payloadSize;
- this.buffer = new Buffer(numberOfBytes);
+ this.buffer = new buffer.Buffer(numberOfBytes);
this.handles = [];
var encoder = this.createEncoder(kMessageHeaderSize);
encoder.writeUint32(kMessageHeaderSize);
@@ -514,7 +417,7 @@ define("mojo/public/js/bindings/codec", [
// Currently, we don't compute the payload size correctly ahead of time.
// Instead, we resize the buffer at the end.
var numberOfBytes = kMessageWithRequestIDHeaderSize + payloadSize;
- this.buffer = new Buffer(numberOfBytes);
+ this.buffer = new buffer.Buffer(numberOfBytes);
this.handles = [];
var encoder = this.createEncoder(kMessageWithRequestIDHeaderSize);
encoder.writeUint32(kMessageWithRequestIDHeaderSize);
@@ -535,8 +438,7 @@ define("mojo/public/js/bindings/codec", [
function MessageReader(message) {
this.decoder = new Decoder(message.buffer, message.handles, 0);
var messageHeaderSize = this.decoder.readUint32();
- this.payloadSize =
- message.buffer.arrayBuffer.byteLength - messageHeaderSize;
+ this.payloadSize = message.buffer.byteLength - messageHeaderSize;
var numFields = this.decoder.readUint32();
this.messageName = this.decoder.readUint32();
this.flags = this.decoder.readUint32();
@@ -764,7 +666,6 @@ define("mojo/public/js/bindings/codec", [
var exports = {};
exports.align = align;
- exports.Buffer = Buffer;
exports.Message = Message;
exports.MessageBuilder = MessageBuilder;
exports.MessageWithRequestIDBuilder = MessageWithRequestIDBuilder;
diff --git a/mojo/bindings/js/codec_unittests.js b/mojo/public/js/bindings/codec_unittests.js
index e30acb5..14cd96a 100644
--- a/mojo/bindings/js/codec_unittests.js
+++ b/mojo/public/js/bindings/codec_unittests.js
@@ -1,4 +1,4 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright 2014 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.
diff --git a/mojo/public/js/bindings/connector.js b/mojo/public/js/bindings/connector.js
index 51022b0..cf7c93b 100644
--- a/mojo/public/js/bindings/connector.js
+++ b/mojo/public/js/bindings/connector.js
@@ -3,10 +3,11 @@
// found in the LICENSE file.
define("mojo/public/js/bindings/connector", [
+ "mojo/public/js/bindings/buffer",
"mojo/public/js/bindings/codec",
"mojo/public/js/bindings/core",
"mojo/public/js/bindings/support",
-], function(codec, core, support) {
+], function(buffer, codec, core, support) {
function Connector(handle) {
this.handle_ = handle;
@@ -95,8 +96,8 @@ define("mojo/public/js/bindings/connector", [
this.errorHandler_.onError(read.result);
return;
}
- var buffer = new codec.Buffer(read.buffer);
- var message = new codec.Message(buffer, read.handles);
+ var messageBuffer = new buffer.Buffer(read.buffer);
+ var message = new codec.Message(messageBuffer, read.handles);
if (this.incomingReceiver_) {
this.incomingReceiver_.accept(message);
}
diff --git a/mojo/public/js/bindings/constants.cc b/mojo/public/js/bindings/constants.cc
index 239b67d..246bd36 100644
--- a/mojo/public/js/bindings/constants.cc
+++ b/mojo/public/js/bindings/constants.cc
@@ -6,6 +6,7 @@
namespace mojo {
+const char kBufferModuleName[] = "mojo/public/js/bindings/buffer";
const char kCodecModuleName[] = "mojo/public/js/bindings/codec";
const char kConnectionModuleName[] = "mojo/public/js/bindings/connection";
const char kConnectorModuleName[] = "mojo/public/js/bindings/connector";
diff --git a/mojo/public/js/bindings/constants.h b/mojo/public/js/bindings/constants.h
index 50e5d7c..c048cb2 100644
--- a/mojo/public/js/bindings/constants.h
+++ b/mojo/public/js/bindings/constants.h
@@ -8,6 +8,7 @@
namespace mojo {
// JavaScript module names:
+extern const char kBufferModuleName[];
extern const char kCodecModuleName[];
extern const char kConnectionModuleName[];
extern const char kConnectorModuleName[];
diff --git a/mojo/bindings/js/core_unittests.js b/mojo/public/js/bindings/core_unittests.js
index fa6cb4f..b115cc0 100644
--- a/mojo/bindings/js/core_unittests.js
+++ b/mojo/public/js/bindings/core_unittests.js
@@ -1,4 +1,4 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright 2014 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.
diff --git a/mojo/public/js/bindings/tests/DEPS b/mojo/public/js/bindings/tests/DEPS
new file mode 100644
index 0000000..37eb10c
--- /dev/null
+++ b/mojo/public/js/bindings/tests/DEPS
@@ -0,0 +1,6 @@
+include_rules = [
+ "+base",
+ "+gin",
+ "+v8",
+ "+mojo/bindings/js/core.h",
+]
diff --git a/mojo/bindings/js/run_js_tests.cc b/mojo/public/js/bindings/tests/run_js_tests.cc
index 976a0b1..d791e0b 100644
--- a/mojo/bindings/js/run_js_tests.cc
+++ b/mojo/public/js/bindings/tests/run_js_tests.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "gin/modules/console.h"
@@ -11,7 +10,6 @@
#include "gin/test/file_runner.h"
#include "gin/test/gtest.h"
#include "mojo/bindings/js/core.h"
-#include "mojo/common/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
@@ -33,8 +31,9 @@ void RunTest(std::string test, bool run_until_idle) {
base::FilePath path;
PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("mojo")
- .AppendASCII("bindings")
+ .AppendASCII("public")
.AppendASCII("js")
+ .AppendASCII("bindings")
.AppendASCII(test);
TestRunnerDelegate delegate;
gin::RunTestFromFile(path, &delegate, run_until_idle);
@@ -46,19 +45,13 @@ TEST(JSTest, core) {
}
TEST(JSTest, codec) {
- // 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_service.mojom"));
- if (!base::PathExists(test_file_path)) {
- LOG(WARNING) << "Mojom binding files don't exist. Skipping the test.";
- return;
- }
-
RunTest("codec_unittests.js", true);
}
+TEST(JSTest, validation) {
+ RunTest("validation_unittests.js", true);
+}
+
} // namespace
} // namespace js
} // namespace mojo
diff --git a/mojo/public/js/bindings/tests/validation_test_input_parser.js b/mojo/public/js/bindings/tests/validation_test_input_parser.js
new file mode 100644
index 0000000..98b1c19
--- /dev/null
+++ b/mojo/public/js/bindings/tests/validation_test_input_parser.js
@@ -0,0 +1,299 @@
+// Copyright 2014 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.
+
+// Support for parsing binary sequences encoded as readable strings
+// or ".data" files. The input format is described here:
+// mojo/public/cpp/bindings/tests/validation_test_input_parser.h
+
+define([
+ "mojo/public/js/bindings/buffer"
+ ], function(buffer) {
+
+ // Files and Lines represent the raw text from an input string
+ // or ".data" file.
+
+ function InputError(message, line) {
+ this.message = message;
+ this.line = line;
+ }
+
+ InputError.prototype.toString = function() {
+ var s = 'Error: ' + this.message;
+ if (this.line)
+ s += ', at line ' +
+ (this.line.number + 1) + ': "' + this.line.contents + '"';
+ return s;
+ }
+
+ function File(contents) {
+ this.contents = contents;
+ this.index = 0;
+ this.lineNumber = 0;
+ }
+
+ File.prototype.endReached = function() {
+ return this.index >= this.contents.length;
+ }
+
+ File.prototype.nextLine = function() {
+ if (this.endReached())
+ return null;
+ var start = this.index;
+ var end = this.contents.indexOf('\n', start);
+ if (end == -1)
+ end = this.contents.length;
+ this.index = end + 1;
+ return new Line(this.contents.substring(start, end), this.lineNumber++);
+ }
+
+ function Line(contents, number) {
+ var i = contents.indexOf('//');
+ var s = (i == -1) ? contents.trim() : contents.substring(0, i).trim();
+ this.contents = contents;
+ this.items = (s.length > 0) ? s.split(/\s+/) : [];
+ this.index = 0;
+ this.number = number;
+ }
+
+ Line.prototype.endReached = function() {
+ return this.index >= this.items.length;
+ }
+
+ var ITEM_TYPE_SIZES = {
+ u1: 1, u2: 2, u4: 4, u8: 8, s1: 1, s2: 2, s4: 4, s8: 8, b: 1, f: 4, d: 8,
+ dist4: 4, dist8: 8, anchr: 0, handles: 0
+ };
+
+ function isValidItemType(type) {
+ return ITEM_TYPE_SIZES[type] !== undefined;
+ }
+
+ Line.prototype.nextItem = function() {
+ if (this.endReached())
+ return null;
+
+ var itemString = this.items[this.index++];
+ var type = 'u1';
+ var value = itemString;
+
+ if (itemString.charAt(0) == '[') {
+ var i = itemString.indexOf(']');
+ if (i != -1 && i + 1 < itemString.length) {
+ type = itemString.substring(1, i);
+ value = itemString.substring(i + 1);
+ } else {
+ throw new InputError('invalid item', this);
+ }
+ }
+ if (!isValidItemType(type))
+ throw new InputError('invalid item type', this);
+
+ return new Item(this, type, value);
+ }
+
+ // The text for each whitespace delimited binary data "item" is represented
+ // by an Item.
+
+ function Item(line, type, value) {
+ this.line = line;
+ this.type = type;
+ this.value = value;
+ this.size = ITEM_TYPE_SIZES[type];
+ }
+
+ Item.prototype.isFloat = function() {
+ return this.type == 'f' || this.type == 'd';
+ }
+
+ Item.prototype.isInteger = function() {
+ return ['u1', 'u2', 'u4', 'u8',
+ 's1', 's2', 's4', 's8'].indexOf(this.type) != -1;
+ }
+
+ Item.prototype.isNumber = function() {
+ return this.isFloat() || this.isInteger();
+ }
+
+ Item.prototype.isByte = function() {
+ return this.type == 'b';
+ }
+
+ Item.prototype.isDistance = function() {
+ return this.type == 'dist4' || this.type == 'dist8';
+ }
+
+ Item.prototype.isAnchor = function() {
+ return this.type == 'anchr';
+ }
+
+ Item.prototype.isHandles = function() {
+ return this.type == 'handles';
+ }
+
+ // A TestMessage represents the complete binary message loaded from an input
+ // string or ".data" file. The parseTestMessage() function below constructs
+ // a TestMessage from a File.
+
+ function TestMessage(byteLength) {
+ this.index = 0;
+ this.buffer = new buffer.Buffer(byteLength);
+ this.distances = {};
+ this.handleCount = 0;
+ }
+
+ function checkItemNumberValue(item, n, min, max) {
+ if (n < min || n > max)
+ throw new InputError('invalid item value', item.line);
+ }
+
+ TestMessage.prototype.addNumber = function(item) {
+ var n = item.isInteger() ? parseInt(item.value) : parseFloat(item.value);
+ if (Number.isNaN(n))
+ throw new InputError("can't parse item value", item.line);
+
+ switch(item.type) {
+ case 'u1':
+ checkItemNumberValue(item, n, 0, 0xFF);
+ this.buffer.setUint8(this.index, n);
+ break;
+ case 'u2':
+ checkItemNumberValue(item, n, 0, 0xFFFF);
+ this.buffer.setUint16(this.index, n);
+ break;
+ case 'u4':
+ checkItemNumberValue(item, n, 0, 0xFFFFFFFF);
+ this.buffer.setUint32(this.index, n);
+ break;
+ case 'u8':
+ checkItemNumberValue(item, n, 0, Number.MAX_SAFE_INTEGER);
+ this.buffer.setUint64(this.index, n);
+ break;
+ case 's1':
+ checkItemNumberValue(item, n, -128, 127);
+ this.buffer.setInt8(this.index, n);
+ break;
+ case 's2':
+ checkItemNumberValue(item, n, -32768, 32767);
+ this.buffer.setInt16(this.index, n);
+ break;
+ case 's4':
+ checkItemNumberValue(item, n, -2147483648, 2147483647);
+ this.buffer.setInt32(this.index, n);
+ break;
+ case 's8':
+ checkItemNumberValue(item, n,
+ Number.MIN_SAFE_INTEGER,
+ Number.MAX_SAFE_INTEGER);
+ this.buffer.setInt64(this.index, n);
+ break;
+ case 'f':
+ this.buffer.setFloat32(this.index, n);
+ break;
+ case 'd':
+ this.buffer.setFloat64(this.index, n);
+ break;
+
+ default:
+ throw new InputError('unrecognized item type', item.line);
+ }
+ }
+
+ TestMessage.prototype.addByte = function(item) {
+ if (!/^[01]{8}$/.test(item.value))
+ throw new InputError('invalid byte item value', item.line);
+ function b(i) {
+ return (item.value.charAt(7 - i) == '1') ? 1 << i : 0;
+ }
+ var n = b(0) | b(1) | b(2) | b(3) | b(4) | b(5) | b(6) | b(7);
+ this.buffer.setUint8(this.index, n);
+ }
+
+ TestMessage.prototype.addDistance = function(item) {
+ if (this.distances[item.value])
+ throw new InputError('duplicate distance item', item.line);
+ this.distances[item.value] = {index: this.index, item: item};
+ }
+
+ TestMessage.prototype.addAnchor = function(item) {
+ var dist = this.distances[item.value];
+ if (!dist)
+ throw new InputError('unmatched anchor item', item.line);
+ delete this.distances[item.value];
+
+ var n = this.index - dist.index;
+ // TODO(hansmuller): validate n
+
+ if (dist.item.type == 'dist4')
+ this.buffer.setUint32(dist.index, n);
+ else if (dist.item.type == 'dist8')
+ this.buffer.setUint64(dist.index, n);
+ else
+ throw new InputError('unrecognzed distance item type', dist.item.line);
+ }
+
+ TestMessage.prototype.addHandles = function(item) {
+ this.handleCount = parseInt(item.value);
+ if (Number.isNaN(this.handleCount))
+ throw new InputError("can't parse handleCount", item.line);
+ }
+
+ TestMessage.prototype.addItem = function(item) {
+ if (item.isNumber())
+ this.addNumber(item);
+ else if (item.isByte())
+ this.addByte(item);
+ else if (item.isDistance())
+ this.addDistance(item);
+ else if (item.isAnchor())
+ this.addAnchor(item);
+ else if (item.isHandles())
+ this.addHandles(item);
+ else
+ throw new InputError('unrecognized item type', item.line);
+
+ this.index += item.size;
+ }
+
+ TestMessage.prototype.unanchoredDistances = function() {
+ var names = null;
+ for (var name in this.distances) {
+ if (this.distances.hasOwnProperty(name))
+ names = (names === null) ? name : names + ' ' + name;
+ }
+ return names;
+ }
+
+ function parseTestMessage(text) {
+ var file = new File(text);
+ var items = [];
+ var messageLength = 0;
+ while(!file.endReached()) {
+ var line = file.nextLine();
+ while (!line.endReached()) {
+ var item = line.nextItem();
+ if (item.isHandles() && items.length > 0)
+ throw new InputError('handles item is not first');
+ messageLength += item.size;
+ items.push(item);
+ }
+ }
+
+ var msg = new TestMessage(messageLength);
+ for (var i = 0; i < items.length; i++)
+ msg.addItem(items[i]);
+
+ if (messageLength != msg.index)
+ throw new InputError('failed to compute message length');
+ var names = msg.unanchoredDistances();
+ if (names)
+ throw new InputError('no anchors for ' + names, 0);
+
+ return msg;
+ }
+
+ var exports = {};
+ exports.parseTestMessage = parseTestMessage;
+ exports.InputError = InputError;
+ return exports;
+});
diff --git a/mojo/public/js/bindings/validation_unittests.js b/mojo/public/js/bindings/validation_unittests.js
new file mode 100644
index 0000000..6931777
--- /dev/null
+++ b/mojo/public/js/bindings/validation_unittests.js
@@ -0,0 +1,163 @@
+// Copyright 2014 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([
+ "gin/test/expect",
+ "mojo/public/js/bindings/buffer",
+ "mojo/public/js/bindings/tests/validation_test_input_parser"
+ ], function(expect, buffer, parser) {
+
+ function checkTestMessageParser() {
+ function TestMessageParserFailure(message, input) {
+ this.message = message;
+ this.input = input;
+ }
+
+ TestMessageParserFailure.prototype.toString = function() {
+ return 'Error: ' + this.message + ' for "' + this.input + '"';
+ }
+
+ function checkData(data, expectedData, input) {
+ if (data.byteLength != expectedData.byteLength) {
+ var s = "message length (" + data.byteLength + ") doesn't match " +
+ "expected length: " + expectedData.byteLength;
+ throw new TestMessageParserFailure(s, input);
+ }
+
+ for (var i = 0; i < data.byteLength; i++) {
+ if (data.getUint8(i) != expectedData.getUint8(i)) {
+ var s = 'message data mismatch at byte offset ' + i;
+ throw new TestMessageParserFailure(s, input);
+ }
+ }
+ }
+
+ function testFloatItems() {
+ var input = '[f]+.3e9 [d]-10.03';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(12);
+ expectedData.setFloat32(0, +.3e9);
+ expectedData.setFloat64(4, -10.03);
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testUnsignedIntegerItems() {
+ var input = '[u1]0x10// hello world !! \n\r \t [u2]65535 \n' +
+ '[u4]65536 [u8]0xFFFFFFFFFFFFF 0 0Xff';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(17);
+ expectedData.setUint8(0, 0x10);
+ expectedData.setUint16(1, 65535);
+ expectedData.setUint32(3, 65536);
+ expectedData.setUint64(7, 0xFFFFFFFFFFFFF);
+ expectedData.setUint8(15, 0);
+ expectedData.setUint8(16, 0xff);
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testSignedIntegerItems() {
+ var input = '[s8]-0x800 [s1]-128\t[s2]+0 [s4]-40';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(15);
+ expectedData.setInt64(0, -0x800);
+ expectedData.setInt8(8, -128);
+ expectedData.setInt16(9, 0);
+ expectedData.setInt32(11, -40);
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testByteItems() {
+ var input = '[b]00001011 [b]10000000 // hello world\n [b]00000000';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(3);
+ expectedData.setUint8(0, 11);
+ expectedData.setUint8(1, 128);
+ expectedData.setUint8(2, 0);
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testAnchors() {
+ var input = '[dist4]foo 0 [dist8]bar 0 [anchr]foo [anchr]bar';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(14);
+ expectedData.setUint32(0, 14);
+ expectedData.setUint8(4, 0);
+ expectedData.setUint64(5, 9);
+ expectedData.setUint8(13, 0);
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testHandles() {
+ var input = '// This message has handles! \n[handles]50 [u8]2';
+ var msg = parser.parseTestMessage(input);
+ var expectedData = new buffer.Buffer(8);
+ expectedData.setUint64(0, 2);
+
+ if (msg.handleCount != 50) {
+ var s = 'wrong handle count (' + msg.handleCount + ')';
+ throw new TestMessageParserFailure(s, input);
+ }
+ checkData(msg.buffer, expectedData, input);
+ }
+
+ function testEmptyInput() {
+ var msg = parser.parseTestMessage('');
+ if (msg.buffer.byteLength != 0)
+ throw new TestMessageParserFailure('expected empty message', '');
+ }
+
+ function testBlankInput() {
+ var input = ' \t // hello world \n\r \t// the answer is 42 ';
+ var msg = parser.parseTestMessage(input);
+ if (msg.buffer.byteLength != 0)
+ throw new TestMessageParserFailure('expected empty message', input);
+ }
+
+ function testInvalidInput() {
+ function parserShouldFail(input) {
+ try {
+ parser.parseTestMessage(input);
+ } catch (e) {
+ if (e instanceof parser.InputError)
+ return;
+ throw new TestMessageParserFailure(
+ 'unexpected exception ' + e.toString(), input);
+ }
+ throw new TestMessageParserFailure("didn't detect invalid input", file);
+ }
+
+ ['/ hello world',
+ '[u1]x',
+ '[u2]-1000',
+ '[u1]0x100',
+ '[s2]-0x8001',
+ '[b]1',
+ '[b]1111111k',
+ '[dist4]unmatched',
+ '[anchr]hello [dist8]hello',
+ '[dist4]a [dist4]a [anchr]a',
+ // '[dist4]a [anchr]a [dist4]a [anchr]a',
+ '0 [handles]50'
+ ].forEach(parserShouldFail);
+ }
+
+ try {
+ testFloatItems();
+ testUnsignedIntegerItems();
+ testSignedIntegerItems();
+ testByteItems();
+ testInvalidInput();
+ testEmptyInput();
+ testBlankInput();
+ testHandles();
+ testAnchors();
+ } catch (e) {
+ return e.toString();
+ }
+ return null;
+ }
+
+ expect(checkTestMessageParser()).toBeNull();
+ this.result = "PASS";
+});