]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | const ttypes = require("./gen-nodejs/JsDeepConstructorTest_types"); | |
21 | const thrift = require("thrift"); | |
22 | const test = require("tape"); | |
23 | const bufferEquals = require("buffer-equals"); | |
24 | ||
25 | function serializeBinary(data) { | |
26 | let buff; | |
27 | const transport = new thrift.TBufferedTransport(null, function(msg) { | |
28 | buff = msg; | |
29 | }); | |
30 | const prot = new thrift.TBinaryProtocol(transport); | |
31 | data.write(prot); | |
32 | prot.flush(); | |
33 | return buff; | |
34 | } | |
35 | ||
36 | function deserializeBinary(serialized, type) { | |
37 | const t = new thrift.TFramedTransport(serialized); | |
38 | const p = new thrift.TBinaryProtocol(t); | |
39 | const data = new type(); | |
40 | data.read(p); | |
41 | return data; | |
42 | } | |
43 | ||
44 | function serializeJSON(data) { | |
45 | let buff; | |
46 | const transport = new thrift.TBufferedTransport(null, function(msg) { | |
47 | buff = msg; | |
48 | }); | |
49 | const protocol = new thrift.TJSONProtocol(transport); | |
50 | protocol.writeMessageBegin("", 0, 0); | |
51 | data.write(protocol); | |
52 | protocol.writeMessageEnd(); | |
53 | protocol.flush(); | |
54 | return buff; | |
55 | } | |
56 | ||
57 | function deserializeJSON(serialized, type) { | |
58 | const transport = new thrift.TFramedTransport(serialized); | |
59 | const protocol = new thrift.TJSONProtocol(transport); | |
60 | protocol.readMessageBegin(); | |
61 | const data = new type(); | |
62 | data.read(protocol); | |
63 | protocol.readMessageEnd(); | |
64 | return data; | |
65 | } | |
66 | ||
67 | function createThriftObj() { | |
68 | return new ttypes.Complex({ | |
69 | struct_field: new ttypes.Simple({ value: "a" }), | |
70 | ||
71 | struct_list_field: [ | |
72 | new ttypes.Simple({ value: "b" }), | |
73 | new ttypes.Simple({ value: "c" }) | |
74 | ], | |
75 | ||
76 | struct_set_field: [ | |
77 | new ttypes.Simple({ value: "d" }), | |
78 | new ttypes.Simple({ value: "e" }) | |
79 | ], | |
80 | ||
81 | struct_map_field: { | |
82 | A: new ttypes.Simple({ value: "f" }), | |
83 | B: new ttypes.Simple({ value: "g" }) | |
84 | }, | |
85 | ||
86 | struct_nested_containers_field: [ | |
87 | [ | |
88 | { | |
89 | C: [ | |
90 | new ttypes.Simple({ value: "h" }), | |
91 | new ttypes.Simple({ value: "i" }) | |
92 | ] | |
93 | } | |
94 | ] | |
95 | ], | |
96 | ||
97 | struct_nested_containers_field2: { | |
98 | D: [ | |
99 | { | |
100 | DA: new ttypes.Simple({ value: "j" }) | |
101 | }, | |
102 | { | |
103 | DB: new ttypes.Simple({ value: "k" }) | |
104 | } | |
105 | ] | |
106 | }, | |
107 | ||
108 | list_of_list_field: [ | |
109 | ["l00", "l01", "l02"], | |
110 | ["l10", "l11", "l12"], | |
111 | ["l20", "l21", "l22"] | |
112 | ], | |
113 | ||
114 | list_of_list_of_list_field: [ | |
115 | [ | |
116 | ["m000", "m001", "m002"], | |
117 | ["m010", "m011", "m012"], | |
118 | ["m020", "m021", "m022"] | |
119 | ], | |
120 | [ | |
121 | ["m100", "m101", "m102"], | |
122 | ["m110", "m111", "m112"], | |
123 | ["m120", "m121", "m122"] | |
124 | ], | |
125 | [ | |
126 | ["m200", "m201", "m202"], | |
127 | ["m210", "m211", "m212"], | |
128 | ["m220", "m221", "m222"] | |
129 | ] | |
130 | ] | |
131 | }); | |
132 | } | |
133 | ||
134 | function createJsObj() { | |
135 | return { | |
136 | struct_field: { value: "a" }, | |
137 | ||
138 | struct_list_field: [{ value: "b" }, { value: "c" }], | |
139 | ||
140 | struct_set_field: [{ value: "d" }, { value: "e" }], | |
141 | ||
142 | struct_map_field: { | |
143 | A: { value: "f" }, | |
144 | B: { value: "g" } | |
145 | }, | |
146 | ||
147 | struct_nested_containers_field: [ | |
148 | [ | |
149 | { | |
150 | C: [{ value: "h" }, { value: "i" }] | |
151 | } | |
152 | ] | |
153 | ], | |
154 | ||
155 | struct_nested_containers_field2: { | |
156 | D: [ | |
157 | { | |
158 | DA: { value: "j" } | |
159 | }, | |
160 | { | |
161 | DB: { value: "k" } | |
162 | } | |
163 | ] | |
164 | }, | |
165 | ||
166 | list_of_list_field: [ | |
167 | ["l00", "l01", "l02"], | |
168 | ["l10", "l11", "l12"], | |
169 | ["l20", "l21", "l22"] | |
170 | ], | |
171 | ||
172 | list_of_list_of_list_field: [ | |
173 | [ | |
174 | ["m000", "m001", "m002"], | |
175 | ["m010", "m011", "m012"], | |
176 | ["m020", "m021", "m022"] | |
177 | ], | |
178 | [ | |
179 | ["m100", "m101", "m102"], | |
180 | ["m110", "m111", "m112"], | |
181 | ["m120", "m121", "m122"] | |
182 | ], | |
183 | [ | |
184 | ["m200", "m201", "m202"], | |
185 | ["m210", "m211", "m212"], | |
186 | ["m220", "m221", "m222"] | |
187 | ] | |
188 | ] | |
189 | }; | |
190 | } | |
191 | ||
192 | function assertValues(obj, assert) { | |
193 | assert.equals(obj.struct_field.value, "a"); | |
194 | assert.equals(obj.struct_list_field[0].value, "b"); | |
195 | assert.equals(obj.struct_list_field[1].value, "c"); | |
196 | assert.equals(obj.struct_set_field[0].value, "d"); | |
197 | assert.equals(obj.struct_set_field[1].value, "e"); | |
198 | assert.equals(obj.struct_map_field.A.value, "f"); | |
199 | assert.equals(obj.struct_map_field.B.value, "g"); | |
200 | assert.equals(obj.struct_nested_containers_field[0][0].C[0].value, "h"); | |
201 | assert.equals(obj.struct_nested_containers_field[0][0].C[1].value, "i"); | |
202 | assert.equals(obj.struct_nested_containers_field2.D[0].DA.value, "j"); | |
203 | assert.equals(obj.struct_nested_containers_field2.D[1].DB.value, "k"); | |
204 | assert.equals(obj.list_of_list_field[0][0], "l00"); | |
205 | assert.equals(obj.list_of_list_field[0][1], "l01"); | |
206 | assert.equals(obj.list_of_list_field[0][2], "l02"); | |
207 | assert.equals(obj.list_of_list_field[1][0], "l10"); | |
208 | assert.equals(obj.list_of_list_field[1][1], "l11"); | |
209 | assert.equals(obj.list_of_list_field[1][2], "l12"); | |
210 | assert.equals(obj.list_of_list_field[2][0], "l20"); | |
211 | assert.equals(obj.list_of_list_field[2][1], "l21"); | |
212 | assert.equals(obj.list_of_list_field[2][2], "l22"); | |
213 | ||
214 | assert.equals(obj.list_of_list_of_list_field[0][0][0], "m000"); | |
215 | assert.equals(obj.list_of_list_of_list_field[0][0][1], "m001"); | |
216 | assert.equals(obj.list_of_list_of_list_field[0][0][2], "m002"); | |
217 | assert.equals(obj.list_of_list_of_list_field[0][1][0], "m010"); | |
218 | assert.equals(obj.list_of_list_of_list_field[0][1][1], "m011"); | |
219 | assert.equals(obj.list_of_list_of_list_field[0][1][2], "m012"); | |
220 | assert.equals(obj.list_of_list_of_list_field[0][2][0], "m020"); | |
221 | assert.equals(obj.list_of_list_of_list_field[0][2][1], "m021"); | |
222 | assert.equals(obj.list_of_list_of_list_field[0][2][2], "m022"); | |
223 | ||
224 | assert.equals(obj.list_of_list_of_list_field[1][0][0], "m100"); | |
225 | assert.equals(obj.list_of_list_of_list_field[1][0][1], "m101"); | |
226 | assert.equals(obj.list_of_list_of_list_field[1][0][2], "m102"); | |
227 | assert.equals(obj.list_of_list_of_list_field[1][1][0], "m110"); | |
228 | assert.equals(obj.list_of_list_of_list_field[1][1][1], "m111"); | |
229 | assert.equals(obj.list_of_list_of_list_field[1][1][2], "m112"); | |
230 | assert.equals(obj.list_of_list_of_list_field[1][2][0], "m120"); | |
231 | assert.equals(obj.list_of_list_of_list_field[1][2][1], "m121"); | |
232 | assert.equals(obj.list_of_list_of_list_field[1][2][2], "m122"); | |
233 | ||
234 | assert.equals(obj.list_of_list_of_list_field[2][0][0], "m200"); | |
235 | assert.equals(obj.list_of_list_of_list_field[2][0][1], "m201"); | |
236 | assert.equals(obj.list_of_list_of_list_field[2][0][2], "m202"); | |
237 | assert.equals(obj.list_of_list_of_list_field[2][1][0], "m210"); | |
238 | assert.equals(obj.list_of_list_of_list_field[2][1][1], "m211"); | |
239 | assert.equals(obj.list_of_list_of_list_field[2][1][2], "m212"); | |
240 | assert.equals(obj.list_of_list_of_list_field[2][2][0], "m220"); | |
241 | assert.equals(obj.list_of_list_of_list_field[2][2][1], "m221"); | |
242 | assert.equals(obj.list_of_list_of_list_field[2][2][2], "m222"); | |
243 | } | |
244 | ||
245 | function createTestCases(serialize, deserialize) { | |
246 | const cases = { | |
247 | "Serialize/deserialize should return equal object": function(assert) { | |
248 | const tObj = createThriftObj(); | |
249 | const received = deserialize(serialize(tObj), ttypes.Complex); | |
250 | assert.ok(tObj !== received, "not the same object"); | |
251 | assert.deepEqual(tObj, received); | |
252 | assert.end(); | |
253 | }, | |
254 | ||
255 | "Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": function( | |
256 | assert | |
257 | ) { | |
258 | const tObj1 = createThriftObj(); | |
259 | const tObj2 = new ttypes.Complex(createJsObj()); | |
260 | assertValues(tObj2, assert); | |
261 | const s1 = serialize(tObj1); | |
262 | const s2 = serialize(tObj2); | |
263 | assert.ok(bufferEquals(s1, s2)); | |
264 | assert.end(); | |
265 | }, | |
266 | ||
267 | "Modifications to args object should not affect constructed Thrift object": function( | |
268 | assert | |
269 | ) { | |
270 | const args = createJsObj(); | |
271 | assertValues(args, assert); | |
272 | ||
273 | const tObj = new ttypes.Complex(args); | |
274 | assertValues(tObj, assert); | |
275 | ||
276 | args.struct_field.value = "ZZZ"; | |
277 | args.struct_list_field[0].value = "ZZZ"; | |
278 | args.struct_list_field[1].value = "ZZZ"; | |
279 | args.struct_set_field[0].value = "ZZZ"; | |
280 | args.struct_set_field[1].value = "ZZZ"; | |
281 | args.struct_map_field.A.value = "ZZZ"; | |
282 | args.struct_map_field.B.value = "ZZZ"; | |
283 | args.struct_nested_containers_field[0][0].C[0] = "ZZZ"; | |
284 | args.struct_nested_containers_field[0][0].C[1] = "ZZZ"; | |
285 | args.struct_nested_containers_field2.D[0].DA = "ZZZ"; | |
286 | args.struct_nested_containers_field2.D[0].DB = "ZZZ"; | |
287 | ||
288 | assertValues(tObj, assert); | |
289 | assert.end(); | |
290 | }, | |
291 | ||
292 | "nulls are ok": function(assert) { | |
293 | const tObj = new ttypes.Complex({ | |
294 | struct_field: null, | |
295 | struct_list_field: null, | |
296 | struct_set_field: null, | |
297 | struct_map_field: null, | |
298 | struct_nested_containers_field: null, | |
299 | struct_nested_containers_field2: null | |
300 | }); | |
301 | const received = deserialize(serialize(tObj), ttypes.Complex); | |
302 | assert.strictEqual(tObj.struct_field, null); | |
303 | assert.ok(tObj !== received); | |
304 | assert.deepEqual(tObj, received); | |
305 | assert.end(); | |
306 | }, | |
307 | ||
308 | "Can make list with objects": function(assert) { | |
309 | const tObj = new ttypes.ComplexList({ | |
310 | struct_list_field: [new ttypes.Complex({})] | |
311 | }); | |
312 | const innerObj = tObj.struct_list_field[0]; | |
313 | assert.ok(innerObj instanceof ttypes.Complex); | |
314 | assert.strictEqual(innerObj.struct_field, null); | |
315 | assert.strictEqual(innerObj.struct_list_field, null); | |
316 | assert.strictEqual(innerObj.struct_set_field, null); | |
317 | assert.strictEqual(innerObj.struct_map_field, null); | |
318 | assert.strictEqual(innerObj.struct_nested_containers_field, null); | |
319 | assert.strictEqual(innerObj.struct_nested_containers_field2, null); | |
320 | assert.end(); | |
321 | } | |
322 | }; | |
323 | return cases; | |
324 | } | |
325 | ||
326 | function run(name, cases) { | |
327 | Object.keys(cases).forEach(function(caseName) { | |
328 | test(name + ": " + caseName, cases[caseName]); | |
329 | }); | |
330 | } | |
331 | ||
332 | run("binary", createTestCases(serializeBinary, deserializeBinary)); | |
333 | run("json", createTestCases(serializeJSON, deserializeJSON)); |