THRIFT-3122 Javascript struct constructor should properly initialize struct and container members from plain js arguments
Patch: Igor Tkach
This closes #519
diff --git a/lib/js/test/deep-constructor.test.js b/lib/js/test/deep-constructor.test.js
new file mode 100644
index 0000000..9a19809
--- /dev/null
+++ b/lib/js/test/deep-constructor.test.js
@@ -0,0 +1,195 @@
+function serialize(data) {
+ var transport = new Thrift.Transport("/service");
+ var protocol = new Thrift.Protocol(transport);
+ protocol.writeMessageBegin("", 0, 0);
+ data.write(protocol);
+ protocol.writeMessageEnd();
+ return transport.send_buf;
+}
+
+function deserialize(serialized, type) {
+ var transport = new Thrift.Transport("/service");
+ transport.setRecvBuffer(serialized);
+ var protocol = new Thrift.Protocol(transport);
+ protocol.readMessageBegin();
+ var data = new type();
+ data.read(protocol);
+ protocol.readMessageEnd();
+ return data;
+}
+
+
+function createThriftObj() {
+
+ return new Complex({
+
+ struct_field: new Simple({value: 'a'}),
+
+ struct_list_field: [
+ new Simple({value: 'b'}),
+ new Simple({value: 'c'}),
+ ],
+
+ struct_set_field: [
+ new Simple({value: 'd'}),
+ new Simple({value: 'e'}),
+ ],
+
+ struct_map_field: {
+ A: new Simple({value: 'f'}),
+ B: new Simple({value: 'g'})
+ },
+
+ struct_nested_containers_field: [
+ [
+ {
+ C: [
+ new Simple({value: 'h'}),
+ new Simple({value: 'i'})
+ ]
+ }
+ ]
+ ],
+
+
+ struct_nested_containers_field2: {
+ D: [
+ {
+ DA: new Simple({value: 'j'})
+ },
+ {
+ DB: new Simple({value: 'k'})
+ }
+ ]
+ }
+ }
+ );
+}
+
+
+function createJsObj() {
+
+ return {
+
+ struct_field: {value: 'a'},
+
+ struct_list_field: [
+ {value: 'b'},
+ {value: 'c'},
+ ],
+
+ struct_set_field: [
+ {value: 'd'},
+ {value: 'e'},
+ ],
+
+ struct_map_field: {
+ A: {value: 'f'},
+ B: {value: 'g'}
+ },
+
+ struct_nested_containers_field: [
+ [
+ {
+ C: [
+ {value: 'h'},
+ {value: 'i'}
+ ]
+ }
+ ]
+ ],
+
+ struct_nested_containers_field2: {
+ D: [
+ {
+ DA: {value: 'j'}
+ },
+ {
+ DB: {value: 'k'}
+ }
+ ]
+ }
+ };
+}
+
+
+function assertValues(obj, assert) {
+ assert.equal(obj.struct_field.value, 'a');
+ assert.equal(obj.struct_list_field[0].value, 'b');
+ assert.equal(obj.struct_list_field[1].value, 'c');
+ assert.equal(obj.struct_set_field[0].value, 'd');
+ assert.equal(obj.struct_set_field[1].value, 'e');
+ assert.equal(obj.struct_map_field.A.value, 'f');
+ assert.equal(obj.struct_map_field.B.value, 'g');
+ assert.equal(obj.struct_nested_containers_field[0][0].C[0].value, 'h');
+ assert.equal(obj.struct_nested_containers_field[0][0].C[1].value, 'i');
+ assert.equal(obj.struct_nested_containers_field2.D[0].DA.value, 'j');
+ assert.equal(obj.struct_nested_containers_field2.D[1].DB.value, 'k');
+}
+
+var cases = {
+
+ "Serialize/deserialize simple struct should return equal object": function(assert){
+ var tObj = new Simple({value: 'a'});
+ var received = deserialize(serialize(tObj), Simple);
+ assert.ok(tObj !== received);
+ assert.deepEqual(received, tObj);
+ },
+
+
+ "Serialize/deserialize should return equal object": function(assert){
+ var tObj = createThriftObj();
+ var received = deserialize(serialize(tObj), Complex);
+ assert.ok(tObj !== received);
+ assert.deepEqual(received, tObj);
+ },
+
+ "Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": function(assert) {
+ var tObj1 = createThriftObj();
+ var tObj2 = new Complex(createJsObj());
+ assertValues(tObj2, assert);
+ assert.equal(serialize(tObj2), serialize(tObj1));
+ },
+
+ "Modifications to args object should not affect constructed Thrift object": function (assert) {
+
+ var args = createJsObj();
+ assertValues(args, assert);
+
+ var tObj = new Complex(args);
+ assertValues(tObj, assert);
+
+ args.struct_field.value = 'ZZZ';
+ args.struct_list_field[0].value = 'ZZZ';
+ args.struct_list_field[1].value = 'ZZZ';
+ args.struct_set_field[0].value = 'ZZZ';
+ args.struct_set_field[1].value = 'ZZZ';
+ args.struct_map_field.A.value = 'ZZZ';
+ args.struct_map_field.B.value = 'ZZZ';
+ args.struct_nested_containers_field[0][0].C[0] = 'ZZZ';
+ args.struct_nested_containers_field[0][0].C[1] = 'ZZZ';
+ args.struct_nested_containers_field2.D[0].DA = 'ZZZ';
+ args.struct_nested_containers_field2.D[0].DB = 'ZZZ';
+
+ assertValues(tObj, assert);
+ },
+
+ "nulls are ok": function(assert) {
+ var tObj = new Complex({
+ struct_field: null,
+ struct_list_field: null,
+ struct_set_field: null,
+ struct_map_field: null,
+ struct_nested_containers_field: null,
+ struct_nested_containers_field2: null
+ });
+ var received = deserialize(serialize(tObj), Complex);
+ assert.ok(tObj !== received);
+ assert.deepEqual(tObj, received);
+ }
+
+};
+
+Object.keys(cases).forEach(function(caseName) {
+ test(caseName, cases[caseName]);
+});
diff --git a/lib/js/test/test-deep-constructor.html b/lib/js/test/test-deep-constructor.html
new file mode 100755
index 0000000..5835dc8
--- /dev/null
+++ b/lib/js/test/test-deep-constructor.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Thrift Javascript Bindings: Unit Test</title>
+
+ <script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
+ <script src="gen-js/JsDeepConstructorTest_types.js" type="text/javascript" charset="utf-8"></script>
+ <!-- jQuery -->
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js" charset="utf-8"></script>
+
+ <!-- QUnit Test framework-->
+ <script type="text/javascript" src="http://code.jquery.com/qunit/qunit-1.14.0.js" charset="utf-8"></script>
+ <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" media="screen" />
+
+ <!-- the Test Suite-->
+ <script type="text/javascript" src="deep-constructor.test.js" charset="utf-8"></script>
+</head>
+<body>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Deep Constructor Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/JsDeepConstructorTest.thrift;hb=HEAD">JsDeepConstructorTest.thrift</a>)</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+ <p>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ </p>
+</body>
+</html>