http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6aed8542/tests/javascript/codec.js ---------------------------------------------------------------------- diff --git a/tests/javascript/codec.js b/tests/javascript/codec.js new file mode 100644 index 0000000..95e36e4 --- /dev/null +++ b/tests/javascript/codec.js @@ -0,0 +1,544 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/** + * This is a fairly literal JavaScript port of codec.py used to unit test the + * proton.Data wrapper class. + */ + +// Check if the environment is Node.js and if so import the required libraries. +if (typeof exports !== "undefined" && exports !== null) { + unittest = require("./unittest.js"); + assert = require("assert"); + proton = require("qpid-proton"); +} + +// We extend TestCase by creating an instance and adding test methods as properties. +var DataTest = new unittest.TestCase(); + +DataTest.setUp = function() { + this.data = new proton.Data(); +}; + +DataTest.tearDown = function() { + this.data.free(); + this.data = null; +}; + +DataTest.testTopLevelNext = function() { + console.log("testTopLevelNext"); + assert(this.data.next() === null); + this.data.putNULL(); + this.data.putBOOL(false); + this.data.putINT(0); + assert(this.data.next() === null); + this.data.rewind(); + assert(this.data.next() === proton.Data.NULL); + assert(this.data.next() === proton.Data.BOOL); + assert(this.data.next() === proton.Data.INT); + assert(this.data.next() === null); + console.log("OK\n"); +}; + +DataTest.testNestedNext = function() { + console.log("testNestedNext"); + assert(this.data.next() === null); + this.data.putNULL(); + assert(this.data.next() === null); + this.data.putLISTNODE(); + assert(this.data.next() === null); + this.data.putBOOL(false); + assert(this.data.next() === null); + this.data.rewind(); + assert(this.data.next() === proton.Data.NULL); + assert(this.data.next() === proton.Data.LIST); + this.data.enter(); + assert(this.data.next() === null); + this.data.putUBYTE(0); + assert(this.data.next() === null); + this.data.putUINT(0); + assert(this.data.next() === null); + this.data.putINT(0); + assert(this.data.next() === null); + this.data.exit(); + assert(this.data.next() === proton.Data.BOOL); + assert(this.data.next() === null); + + this.data.rewind(); + assert(this.data.next() === proton.Data.NULL); + assert(this.data.next() === proton.Data.LIST); + assert(this.data.enter()); + assert(this.data.next() === proton.Data.UBYTE); + assert(this.data.next() === proton.Data.UINT); + assert(this.data.next() === proton.Data.INT); + assert(this.data.next() === null); + assert(this.data.exit()); + assert(this.data.next() === proton.Data.BOOL); + assert(this.data.next() === null); + console.log("OK\n"); +}; + +DataTest.testEnterExit = function() { + console.log("testEnterExit"); + assert(this.data.next() === null); + assert(!this.data.enter()); + this.data.putLISTNODE(); + assert(this.data.enter()); + assert(this.data.next() === null); + this.data.putLISTNODE(); + assert(this.data.enter()); + this.data.putLISTNODE(); + assert(this.data.enter()); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 0); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 1); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 1); + assert(!this.data.exit()); + assert(this.data.getLISTNODE() === 1); + assert(this.data.next() === null); + + this.data.rewind(); + assert(this.data.next() === proton.Data.LIST); + assert(this.data.getLISTNODE() === 1); + assert(this.data.enter()); + assert(this.data.next() === proton.Data.LIST); + assert(this.data.getLISTNODE() === 1); + assert(this.data.enter()); + assert(this.data.next() === proton.Data.LIST); + assert(this.data.getLISTNODE() === 0); + assert(this.data.enter()); + assert(this.data.next() === null); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 0); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 1); + assert(this.data.exit()); + assert(this.data.getLISTNODE() === 1); + assert(!this.data.exit()); + console.log("OK\n"); +}; + +/** + * This tests the "low level" putARRAYNODE/getARRAYNODE methods. + * In general though applications would create a proton.Data.Array and use the + * higher level putARRAY/getARRAY + */ +DataTest._testArray = function(dtype, descriptor, atype, values) { + var values = Array.prototype.slice.apply(arguments, [3]); + dtype = (dtype == null) ? null : dtype.toUpperCase(); + atype = atype.toUpperCase(); + + // Create an array node, enter it and put the descriptor (if present) and values. + this.data.putARRAYNODE(dtype != null, proton.Data[atype]); + this.data.enter(); + if (dtype != null) { + var putter = 'put' + dtype; + this.data[putter](descriptor); + } + var putter = 'put' + atype; + for (var i = 0; i < values.length; i++) { + this.data[putter](values[i]); + } + this.data.exit(); + + // Check that we did indeed add an Array node + this.data.rewind(); + assert(this.data.next() === proton.Data.ARRAY); + + // Get the count, described and type metadata from the array node and compare + // with the values we passed to putARRAYNODE. + var metadata = this.data.getARRAYNODE(); + var count = metadata.count; + var described = metadata.described; + var type = metadata.type; + + assert(count === values.length); + if (dtype == null) { + assert(described === false); + } else { + assert(described === true); + } + assert(type === proton.Data[atype]); + + // Enter the array node and compare the descriptor and values with those that + // we put into the array. + assert(this.data.enter()); + if (described) { + assert(this.data.next() === proton.Data[dtype]); + var getter = 'get' + dtype; + var gotten = this.data[getter](); + assert(gotten.toString() === descriptor.toString()); + } + var getter = 'get' + atype; + for (var i = 0; i < values.length; i++) { + assert(this.data.next() === proton.Data[atype]); + var gotten = this.data[getter](); + assert(gotten.toString() === values[i].toString()); + } + assert(this.data.next() === null); + assert(this.data.exit()); +}; + +DataTest.testStringArray = function() { + console.log("testStringArray"); + this._testArray(null, null, "string", "one", "two", "three"); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array("STRING", ["four", "five", "six"]); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest.testDescribedStringArray = function() { + console.log("testDescribedStringArray"); + this._testArray("symbol", "url", "string", "one", "two", "three"); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array("STRING", ["four", "five", "six"], new proton.Data.Symbol("url")); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest.testIntArray = function() { + console.log("testIntArray"); + this._testArray(null, null, "int", 1, 2, 3); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array("INT", [4, 5, 6]); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest.testUUIDArray = function() { + console.log("testUUIDArray"); + this._testArray(null, null, "uuid", new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array("UUID", [new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()]); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest.testEmptyArray = function() { + console.log("testEmptyArray"); + this._testArray(null, null, "null"); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array(); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest.testDescribedEmptyArray = function() { + console.log("testDescribedEmptyArray"); + this._testArray("long", 0, "null"); + + // Now try using the proton.Data.Array class. + this.data.clear(); + var put = new proton.Data.Array((0).long()); + this.data.putARRAY(put); + var get = this.data.getARRAY(); + assert(get.equals(put)); + console.log("OK\n"); +}; + +DataTest._test = function(dtype, values) { + var values = Array.prototype.slice.apply(arguments, [1]); + var lastValue = values[values.length - 1]; + + // Default equality function. Note that we use valueOf because some of the + // types we are trying to compare (Symbol, Timestamp, Uuid etc.) are object + // types and we want to compare their value not whether they are the same object. + var eq = function(x, y) {return x.valueOf() === y.valueOf();}; + + if (typeof lastValue === 'function') { + eq = values.pop(); + } + + dtype = dtype.toUpperCase(); + var ntype = proton.Data[dtype]; + var putter = 'put' + dtype; + var getter = 'get' + dtype; + + for (var i = 0; i < values.length; i++) { + var v = values[i]; + /* + * Replace the array element with its value. We do this to make testing + * simpler for Binary elements. In the case of Binary putBINARY "consumes" + * the data, in other words ownership of the underlying raw data transfers + * to the Data object so the v object becomes "empty" after calling the + * putter. Calling its valueOf() happens to call its toString() which + * provides a stringified version of the Binary whilst also working for + * the other data types we want to test too. + */ + values[i] = v.valueOf(); + this.data[putter](v); + var gotten = this.data[getter](); + assert(eq(gotten, values[i])); + } + + this.data.rewind(); + + for (var i = 0; i < values.length; i++) { + var v = values[i]; + var vtype = this.data.next(); + assert(vtype === ntype); + var gotten = this.data[getter](); + assert(eq(gotten, v)); + } + + // Test encode and decode methods. + var encoded = this.data.encode(); + var copy = new proton.Data(); + while (encoded) { + encoded = copy.decode(encoded); + } + copy.rewind(); + + for (var i = 0; i < values.length; i++) { + var v = values[i]; + var vtype = copy.next(); + assert(vtype === ntype); + var gotten = copy[getter](); + assert(eq(gotten, v)); + } + copy.free(); +}; + +DataTest.testInt = function() { + console.log("testInt"); + this._test("int", 1, 2, 3, -1, -2, -3); + console.log("OK\n"); + +}; + +DataTest.testString = function() { + console.log("testString"); + this._test("string", "one", "two", "three", "this is a test", ""); + console.log("OK\n"); +}; + +DataTest.testBigString = function() { + // Try a 2MB string, this is about as big as we can cope with using the default + // emscripten heap size. + console.log("testBigString"); + var data = ""; + for (var i = 0; i < 2000000; i++) { + data += "*"; + } + var string = "start\n" + data + "\nfinish\n"; + this._test("string", string); + console.log("OK\n"); +}; + +DataTest.testFloat = function() { + console.log("testFloat"); + // We have to use a special comparison here because JavaScript internally + // only uses doubles and converting between floats and doubles is imprecise. + this._test("float", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3, + function(x, y) {return (x - y < 0.000001);}); + console.log("OK\n"); +}; + +DataTest.testDouble = function() { + console.log("testDouble"); + this._test("double", 0, 1, 2, 3, 0.1, 0.2, 0.3, -1, -2, -3, -0.1, -0.2, -0.3); + console.log("OK\n"); +}; + +DataTest.testBinary = function() { + console.log("testBinary"); + this._test("binary", new proton.Data.Binary(["t".char(), "h".char(), "i".char(), "s".char()]), + new proton.Data.Binary("is"), new proton.Data.Binary("a"), new proton.Data.Binary("test"), + new proton.Data.Binary("of"), new proton.Data.Binary("ÐÐÐÐРЫ")); + console.log("OK\n"); +}; + +DataTest.testSymbol = function() { + console.log("testSymbol"); + this._test("symbol", new proton.Data.Symbol("this is a symbol test"), + new proton.Data.Symbol("bleh"), new proton.Data.Symbol("blah")); + console.log("OK\n"); +}; + +DataTest.testTimestamp = function() { + console.log("testTimestamp"); + this._test("timestamp", new Date(0), new Date(12345), new Date(1000000)); + console.log("OK\n"); +}; + +DataTest.testChar = function() { + console.log("testChar"); + this._test("char", 'a', 'b', 'c', '\u1234'); + console.log("OK\n"); +}; + +DataTest.testUUID = function() { + console.log("testUUID"); + this._test("uuid", new proton.Data.Uuid(), new proton.Data.Uuid(), new proton.Data.Uuid()); + console.log("OK\n"); +}; + +/* TODO +DataTest.testDecimal32 = function() { + console.log("testDecimal32"); + //this._test("decimal32", 0, 1, 2, 3, 4, Math.pow(2, 30)); +}; + +DataTest.testDecimal64 = function() { + console.log("testDecimal64"); + //this._test("decimal64", 0, 1, 2, 3, 4, Math.pow(2, 60)); +}; + +DataTest.testDecimal128 = function() { + console.log("testDecimal128"); + // TODO +}; +*/ + +DataTest.testCopy = function() { + console.log("testCopy"); + this.data.putDESCRIBEDNODE(); + this.data.enter(); + this.data.putULONG(123); + this.data.putMAPNODE(); + this.data.enter(); + this.data.putSTRING("pi"); + this.data.putDOUBLE(3.14159265359); + this.data.exit(); + this.data.exit(); + + var dst = this.data.copy(); + var copy = dst.format(); + var orig = this.data.format(); + assert(copy === orig); + dst.free(); + console.log("OK\n"); +}; + +DataTest.testCopyNested = function() { + console.log("testCopyNested"); + var nested = [1, 2, 3, [4, 5, 6], 7, 8, 9]; + this.data.putObject(nested); + var dst = this.data.copy(); + assert(dst.format() === this.data.format()); + dst.free(); + console.log("OK\n"); +}; + +DataTest.testCopyNestedArray = function() { + console.log("testCopyNestedArray"); + var nested = [new proton.Data.Array("LIST", [ + ["first", [new proton.Data.Array("INT", [1, 2, 3]), "this"]], + ["second", [new proton.Data.Array("INT", [1, 2, 3]), "is"]], + ["third", [new proton.Data.Array("INT", [1, 2, 3]), "fun"]] + ]), + "end"]; + this.data.putObject(nested); + var dst = this.data.copy(); + assert(dst.format() === this.data.format()); + dst.free(); + console.log("OK\n"); +}; + +DataTest.testRoundTrip = function() { + console.log("testRoundTrip"); + var obj = {key: new Date(1234), + 123: "blah", + c: "bleh", + desc: new proton.Data.Described("http://example.org", new proton.Data.Symbol("url")), + array: new proton.Data.Array("INT", [1, 2, 3]), + list: [1, 2, 3, null, 4], + boolean: true}; + // Serialise obj into this.data. + this.data.putObject(obj); + + // Encode this.data into a Binary representation. + var enc = this.data.encode(); + + // Create a new Data instance and decode from the Binary representation + // consuming the Binary contents in the process. + var data = new proton.Data(); + data.decode(enc); + + assert(data.format() === this.data.format()); + + // Deserialise from the copied Data instance into a new JavaScript Object. + data.rewind(); + assert(data.next()); + var copy = data.getObject(); + + // Create yet another Data instance and serialise the new Object into that. + var data1 = new proton.Data(); + data1.putObject(copy); + + // Compare the round tripped Data with the original one. + assert(data1.format() === this.data.format()); + + data.free(); + data1.free(); + console.log("OK\n"); +}; + +DataTest.testLookup = function() { + console.log("testLookup"); + var obj = {key: "value", + pi: 3.14159, + list: [1, 2, 3, 4]}; + // Serialise obj into this.data. + this.data.putObject(obj); + this.data.rewind(); + this.data.next(); + this.data.enter(); + this.data.narrow(); + assert(this.data.lookup("pi")); + assert(this.data.getObject() === 3.14159); + this.data.rewind(); + assert(this.data.lookup("key")); + assert(this.data.getObject() === "value"); + this.data.rewind(); + assert(this.data.lookup("list")); + assert(this.data.getObject().toString() === "1,2,3,4"); + this.data.widen(); + this.data.rewind(); + assert(!this.data.lookup("pi")); + console.log("OK\n"); +}; + +DataTest.run(); + +
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6aed8542/tests/javascript/unittest.js ---------------------------------------------------------------------- diff --git a/tests/javascript/unittest.js b/tests/javascript/unittest.js new file mode 100644 index 0000000..bc1567c --- /dev/null +++ b/tests/javascript/unittest.js @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/** + * The TestCase class provides a simple dependency-free Unit Test framework to + * automagically invoke methods that start with "test" on classes that extend it. + */ + +// TestCase Constructor +var TestCase = function() {}; + +// Enumerate all functions of the class and invoke those beginning with "test". +TestCase.prototype.run = function() { + for (var property in this) { + if ((typeof this[property] === 'function') && + property.lastIndexOf('test', 0) === 0) { + this.setUp(); + this[property](); + this.tearDown(); + } + } +}; + +TestCase.prototype.setUp = function() {}; +TestCase.prototype.tearDown = function() {}; + +module.exports.TestCase = TestCase; + --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
