Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / tests / suite.js
1 /*\r
2  Copyright 2013 Daniel Wirtz <dcode@dcode.io>\r
3 \r
4  Licensed under the Apache License, Version 2.0 (the "License");\r
5  you may not use this file except in compliance with the License.\r
6  You may obtain a copy of the License at\r
7 \r
8  http://www.apache.org/licenses/LICENSE-2.0\r
9 \r
10  Unless required by applicable law or agreed to in writing, software\r
11  distributed under the License is distributed on an "AS IS" BASIS,\r
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  See the License for the specific language governing permissions and\r
14  limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * ProtoBuf.js Test Suite.\r
19  * @author Daniel Wirtz <dcode@dcode.io>\r
20  */\r
21 (function(global) {\r
22 \r
23     var FILE = "protobuf.js";\r
24     var BROWSER = !!global.window;\r
25     var StdOutFixture = require('fixture-stdout');\r
26     var fixture = new StdOutFixture();\r
27 \r
28     var ProtoBuf = BROWSER ? global.dcodeIO.ProtoBuf : require(__dirname+"/../dist/"+FILE),\r
29         ByteBuffer = BROWSER ? global.dcodeIO.ByteBuffer : ByteBuffer || require("bytebuffer"),\r
30         util = BROWSER ? null : require("util"),\r
31         fs = BROWSER ? null : require("fs");\r
32 \r
33         if (typeof __dirname == 'undefined') {\r
34             __dirname = document.location.href.replace(/[\/\\][^\/\\]*$/, "");\r
35         }\r
36 \r
37     /**\r
38      * Constructs a new Sandbox for module loaders and shim testing.\r
39      * @param {Object.<string,*>} properties Additional properties to set\r
40      * @constructor\r
41      */\r
42     var Sandbox = function(properties) {\r
43         this.ByteBuffer = function() {};\r
44         for (var i in properties) {\r
45             this[i] = properties[i];\r
46         }\r
47         this.console = {\r
48             log: function(s) {\r
49                 console.log(s);\r
50             }\r
51         };\r
52     };\r
53 \r
54     function fail(e) {\r
55         throw(e);\r
56     }\r
57 \r
58     /**\r
59      * Validates the complexDotProto and complexInline tests.\r
60      * @param {*} test Nodeunit test\r
61      * @param {Object} Game Game namespace\r
62      */\r
63     function validateComplex(test, Game) {\r
64         var Car = Game.Cars.Car,\r
65             Vendor = Car.Vendor,\r
66             Speed = Car.Speed;\r
67 \r
68         var vendor;\r
69         // Car from class with argument list properties\r
70         var car = new Car(\r
71             "Rusty",\r
72             // Vendor from class with object properties\r
73             vendor = new Vendor({\r
74                 "name": "Iron Inc.",\r
75                 // Address from object\r
76                 "address": {\r
77                     "country": "US"\r
78                 },\r
79                 "models": ["m1"]\r
80             }),\r
81             // Speed from enum object\r
82             Speed.SUPERFAST\r
83         );\r
84         test.equal(car.model, "Rusty");\r
85         test.equal(car.vendor.name, "Iron Inc.");\r
86         test.equal(car.vendor.address.country, "US");\r
87         test.equal(car.vendor.address.country, car.getVendor().get_address().country);\r
88         var bb = new ByteBuffer(32);\r
89         car.encode(bb);\r
90         test.equal(bb.flip().toString("debug"), "<0A 05 52 75 73 74 79 12 15 0A 09 49 72 6F 6E 20 49 6E 63 2E 12 04 0A 02 55 53 1A 02 6D 31 18 02>");\r
91         var carDec = Car.decode(bb);\r
92         test.equal(carDec.model, "Rusty");\r
93         test.equal(carDec.vendor.name, "Iron Inc.");\r
94         test.equal(carDec.vendor.address.country, "US");\r
95         test.equal(carDec.vendor.address.country, carDec.getVendor().get_address().country);\r
96         test.equal(carDec.vendor.models[0], "m1");\r
97     }\r
98 \r
99     /**\r
100      * Test suite.\r
101      * @type {Object.<string,function>}\r
102      */\r
103     var suite = {\r
104 \r
105         "init": function(test) {\r
106             test.ok(typeof ProtoBuf == "object");\r
107             test.ok(typeof ProtoBuf.Reflect == 'object');\r
108             test.ok(typeof ProtoBuf.loadProto == "function");\r
109             test.ok(typeof ProtoBuf.loadProtoFile == "function");\r
110             test.strictEqual(ProtoBuf.loadProto, ProtoBuf.protoFromString);\r
111             test.strictEqual(ProtoBuf.loadProtoFile, ProtoBuf.protoFromFile);\r
112             test.ok(ProtoBuf.ByteBuffer);\r
113             test.done();\r
114         },\r
115 \r
116         "IS_NODE": function(test) {\r
117             test.ok(ProtoBuf.Util.IS_NODE);\r
118             test.done();\r
119         },\r
120 \r
121         // Example "A Simple Message" from the protobuf docs\r
122         // https://developers.google.com/protocol-buffers/docs/encoding#simple\r
123         "example1": function(test) {\r
124             try{\r
125                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example1.proto");\r
126                 var Test1 = builder.build("Test1");\r
127                 test.ok(typeof Test1 == 'function');\r
128                 var inst = new Test1(150);\r
129                 test.ok(inst instanceof ProtoBuf.Builder.Message);\r
130                 test.equal(inst.a, 150);\r
131                 test.equal(inst.getA(), 150);\r
132                 test.equal(inst.get_a(), 150);\r
133                 inst.setA(151);\r
134                 test.equal(inst.a, 151);\r
135                 test.equal(inst.getA(), 151);\r
136                 test.equal(inst.get_a(), 151);\r
137                 inst.set_a(152);\r
138                 test.equal(inst.a, 152);\r
139                 test.equal(inst.toString(), ".Test1");\r
140                 test.throws(function() {\r
141                     inst.setA(null); // required\r
142                 });\r
143                 test.throws(function() {\r
144                     inst.setA([]);\r
145                 });\r
146                 var size = inst.calculate();\r
147                 var bb = new ByteBuffer(3);\r
148                 inst.encode(bb);\r
149                 test.strictEqual(bb.offset, size);\r
150                 test.equal(bb.flip().toString("debug"), "<08 98 01>");\r
151                 var instDec = Test1.decode(bb);\r
152                 test.equal(instDec.a, 152);\r
153 \r
154             } catch (e) {\r
155                 fail(e);\r
156             }\r
157             test.done();\r
158         },\r
159 \r
160         // Basically the same as example1, but with an unsigned value.\r
161         "example1u": function(test) {\r
162             try{\r
163                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example1u.proto");\r
164                 var Test1u = builder.build("Test1u");\r
165                 test.ok(typeof Test1u == 'function');\r
166                 var inst = new Test1u(-1);\r
167                 test.strictEqual(inst.a, 4294967295);\r
168                 var bb = new ByteBuffer(6);\r
169                 var size = inst.calculate();\r
170                 inst.encode(bb);\r
171                 test.strictEqual(bb.offset, size);\r
172                 test.equal(bb.flip().toString("debug"), "<08 FF FF FF FF 0F>");\r
173                 var instDec = Test1u.decode(bb);\r
174                 test.strictEqual(instDec.a, 4294967295);\r
175 \r
176             } catch (e) {\r
177                 fail(e);\r
178             }\r
179             test.done();\r
180         },\r
181 \r
182         // Example "Strings" from the protobuf docs\r
183         // https://developers.google.com/protocol-buffers/docs/encoding#types\r
184         "example2": function(test) {\r
185             try {\r
186                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example2.proto");\r
187                 var Test2 = builder.build("Test2");\r
188                 var inst = new Test2("testing");\r
189                 var bb = new ByteBuffer(9);\r
190                 var size = inst.calculate();\r
191                 inst.encode(bb);\r
192                 test.strictEqual(bb.offset, size);\r
193                 test.equal(bb.flip().toString("debug"), "<12 07 74 65 73 74 69 6E 67>");\r
194                 var instDec = Test2.decode(bb);\r
195                 test.equal(instDec.b, "testing");\r
196             } catch (e) {\r
197                 fail(e);\r
198             }\r
199             test.done();\r
200         },\r
201 \r
202         // Example "Embedded Messages" from the protobuf docs\r
203         // https://developers.google.com/protocol-buffers/docs/encoding#embedded\r
204         "example3": function(test) {\r
205             try {\r
206                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example3.proto");\r
207                 var root = builder.build();\r
208                 var Test1 = root.Test1;\r
209                 var Test3 = root.Test3;\r
210                 var inst = new Test3(new Test1(150));\r
211                 var bb = new ByteBuffer(5);\r
212                 test.equal(inst.c.a, 150);\r
213                 var size = inst.calculate();\r
214                 inst.encode(bb);\r
215                 test.strictEqual(bb.offset, size);\r
216                 test.equal(bb.flip().toString("debug"), "<1A 03 08 96 01>");\r
217                 var instDec = Test3.decode(bb);\r
218                 test.equal(instDec.c.a, 150);\r
219             } catch(e) {\r
220                 fail(e);\r
221             }\r
222             test.done();\r
223         },\r
224 \r
225         "example4": function(test) {\r
226             try {\r
227                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example4.proto");\r
228                 var Test4 = builder.build("Test4");\r
229                 var inst = new Test4([3, 270, 86942]);\r
230                 var bb = new ByteBuffer(8);\r
231                 test.equal(inst.d.length, 3);\r
232                 var size = inst.calculate();\r
233                 inst.encode(bb);\r
234                 test.strictEqual(bb.offset, size);\r
235                 test.equal(bb.flip().toString("debug"), "<22 06 03 8E 02 9E A7 05>");\r
236                 var instDec = Test4.decode(bb);\r
237                 test.equal(bb.toString("debug"), "22 06 03 8E 02 9E A7 05|");\r
238                 test.equal(instDec.d.length, 3);\r
239                 test.equal(instDec.d[2], 86942);\r
240             } catch(e) {\r
241                 fail(e);\r
242             }\r
243             test.done();\r
244         },\r
245 \r
246         "example5": function(test) {\r
247             try {\r
248                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example5.proto");\r
249                 builder.build();\r
250             } catch(e) {\r
251                 fail(e);\r
252             }\r
253             test.done();\r
254         },\r
255 \r
256         "constructor": function(test) {\r
257             var builder = ProtoBuf.loadProtoFile(__dirname+"/example1.proto");\r
258             var Test1 = builder.build("Test1");\r
259             var t1 = new Test1(123),\r
260                 t2 = new Test1({a: 123}),\r
261                 t3 = new Test1(t1);\r
262             test.deepEqual(t1, t2);\r
263             test.deepEqual(t2, t3);\r
264             test.done();\r
265         },\r
266         \r
267         "constructorWithOneofs": function(test) {\r
268             try {\r
269                 var builder = ProtoBuf.loadProtoFile(__dirname+"/oneof.proto"),\r
270                     MyOneOf = builder.build("MyOneOf"),\r
271                     TOneOf = builder.lookup(".MyOneOf");\r
272                 test.ok(TOneOf.getChild("my_oneof"));\r
273                 \r
274                 var myOneOf = new MyOneOf();\r
275                 test.strictEqual(myOneOf.my_oneof, null);\r
276                 myOneOf.set("id", 1);\r
277                 test.strictEqual(myOneOf.my_oneof, "id");\r
278                 myOneOf.set("name", "me");\r
279                 test.strictEqual(myOneOf.my_oneof, "name");\r
280                 test.strictEqual(myOneOf.id, null);\r
281                 \r
282                 var copy = new MyOneOf(myOneOf); // this line is what was failing\r
283                 // Error: .MyOneOf#my_oneof is not a field: undefined\r
284                 \r
285                 test.deepEqual(myOneOf, copy);\r
286                 \r
287                 // Test same things are there\r
288                 test.strictEqual(copy.my_oneof, "name");\r
289                 test.strictEqual(copy.name, "me");\r
290                 test.strictEqual(copy.id, null);\r
291             } catch (e) {\r
292                 fail(e);\r
293             }\r
294             test.done();\r
295         },\r
296 \r
297         "numberFormats": function(test) {\r
298             try {\r
299                 var builder = ProtoBuf.loadProtoFile(__dirname+"/numberformats.proto");\r
300                 var Formats = builder.build("Formats");\r
301                 test.strictEqual(Formats.DEC, 1);\r
302                 test.strictEqual(Formats.HEX, 31);\r
303                 test.strictEqual(Formats.OCT, 15);\r
304                 var Msg = builder.build("Msg");\r
305                 var msg = new Msg();\r
306                 test.strictEqual(msg.dec, -1);\r
307                 test.strictEqual(msg.hex, -31);\r
308                 test.strictEqual(msg.hexUC, 521);\r
309                 test.strictEqual(msg.oct, -15);\r
310                 test.strictEqual(msg.exp, 0.1e5);\r
311                 test.strictEqual(msg.nod, 1.);\r
312                 test.strictEqual(msg.exn, 1e8);\r
313                 test.strictEqual(msg.sp1, Infinity);\r
314                 test.strictEqual(msg.sp2, -Infinity);\r
315                 test.ok(isNaN(msg.sp3));\r
316             } catch (e) {\r
317                 fail(e);\r
318             }\r
319             test.done();\r
320         },\r
321 \r
322         // Check encode/decode against a table of known correct pairs.\r
323         // Note that javascript ArrayBuffer does not support signed Zero or NaN\r
324         // bertdouglas (https://github.com/bertdouglas)\r
325         "float": function(test) {\r
326             try {\r
327                 var str_proto = "message Float {"\r
328                     + " required float f = 1;"\r
329                     + "}";\r
330                 var builder = ProtoBuf.loadProto(str_proto);\r
331                 var root = builder.build();\r
332                 var Float = root.Float;\r
333 \r
334                 var in_tolerance = function (reference,actual) {\r
335                     var tol = 1e-6;\r
336                     var scale = 1.0;\r
337                     if (reference != 0.0 ) {\r
338                         scale = reference;\r
339                     };\r
340                     var err = Math.abs(reference - actual)/scale;\r
341                     return err < tol;\r
342                 };\r
343 \r
344                 var f_vals = [\r
345                     // hex values are shown here in big-endian following IEEE754 notation\r
346                     // protobuf is little-endian\r
347                     // { f: -0.0 , b: "80 00 00 00" },\r
348                     { f: +0.0 , b: "00 00 00 00" },\r
349                     { f: -1e-10 , b: "AE DB E6 FF" },\r
350                     { f: +1e-10 , b: "2E DB E6 FF" },\r
351                     { f: -2e+10 , b: "D0 95 02 F9" },\r
352                     { f: +2e+10 , b: "50 95 02 F9" },\r
353                     { f: -3e-30 , b: "8E 73 63 90" },\r
354                     { f: +3e-30 , b: "0E 73 63 90" },\r
355                     { f: -4e+30 , b: "F2 49 F2 CA" },\r
356                     { f: +4e+30 , b: "72 49 F2 CA" },\r
357                     { f: -123456789.0 , b: "CC EB 79 A3" },\r
358                     { f: +123456789.0 , b: "4C EB 79 A3" },\r
359                     { f: -0.987654321 , b: "BF 7C D6 EA" },\r
360                     { f: +0.987654321 , b: "3F 7C D6 EA" },\r
361                     { f: -Infinity , b: "FF 80 00 00" },\r
362                     { f: +Infinity , b: "7F 80 00 00" }\r
363                     // { f: -NaN , b: "FF C0 00 00>" },\r
364                     // { f: +NaN , b: "7F C0 00 00" }\r
365                 ];\r
366 \r
367                 f_vals.map( function(x) {\r
368                     // check encode\r
369                     var m1 = new Float();\r
370                     var b1 = new ByteBuffer();\r
371                     m1.f = x.f;\r
372                     m1.encode(b1);\r
373                     var q1 = b1.slice(1,5).compact().reverse();\r
374                     test.strictEqual('<' + x.b + '>', q1.toString("debug"));\r
375 \r
376                     // check decode\r
377                     var b2 = new ByteBuffer();\r
378                     var s1 = x.b + ' 0D';\r
379                     var s2 = s1.split(" ");\r
380                     var s3 = s2.reverse();\r
381                     var i1 = s3.map(function(y) { return parseInt(y,16) } );\r
382                     i1.map(function(y) { b2.writeUint8(y) });\r
383                     b2.limit = b2.offset;\r
384                     b2.offset = 0;\r
385                     var m2 = Float.decode(b2);\r
386 \r
387                     var s4 = "" + x.f +" " + m2.f;\r
388                     if ( isNaN(x.f) ) {\r
389                         test.ok( isNaN(m2.f), s4 );\r
390                     }\r
391                     else if ( ! isFinite( x.f) ) {\r
392                         test.ok( x.f === m2.f, s4 );\r
393                     }\r
394                     else {\r
395                         test.ok( in_tolerance(x.f, m2.f), s4 );\r
396                     }\r
397                 });\r
398             } catch(e) {\r
399                 fail(e);\r
400             }\r
401             test.done();\r
402         },\r
403 \r
404         "bytes": function(test) {\r
405             try {\r
406                 var str_proto = "message Test { required bytes b = 1; }";\r
407                 var builder = ProtoBuf.loadProto(str_proto);\r
408                 var Test = builder.build("Test");\r
409                 var bb = new ByteBuffer(4).writeUint32(0x12345678).flip();\r
410                 var myTest = new Test(bb);\r
411                 test.strictEqual(myTest.b.array, bb.array);\r
412                 var bb2 = new ByteBuffer(6);\r
413                 var size = myTest.calculate();\r
414                 myTest.encode(bb2);\r
415                 test.strictEqual(bb2.offset, size);\r
416                 test.equal(bb2.flip().toString("debug"), "<0A 04 12 34 56 78>");\r
417                 myTest = Test.decode(bb2);\r
418                 test.equal(myTest.b.BE().readUint32(), 0x12345678);\r
419             } catch (e) {\r
420                 fail(e);\r
421             }\r
422             test.done();\r
423         },\r
424 \r
425         "bytesFromFile": function(test) {\r
426             try {\r
427                 var builder = ProtoBuf.loadProto("message Image { required bytes data = 1; }"),\r
428                     Image = builder.build("Image"),\r
429                     data = fs.readFileSync(__dirname+"/../protobuf.png"),\r
430                     image = new Image({ data: data }),\r
431                     bb = image.encode(),\r
432                     imageDec = Image.decode(bb),\r
433                     dataDec = imageDec.data.toBuffer();\r
434                 test.strictEqual(data.length, dataDec.length);\r
435                 test.deepEqual(data, dataDec);\r
436             } catch (e) {\r
437                 fail(e);\r
438             }\r
439             test.done();\r
440         },\r
441 \r
442         "notEnoughBytes": function(test) {\r
443             var builder = ProtoBuf.loadProto("message Test { required bytes b = 1; }");\r
444             var Test = builder.build("Test");\r
445             var bb = new ByteBuffer().writeUint32(0x12345678).flip();\r
446             var encoded = new ByteBuffer(6);\r
447             new Test(bb).encode(encoded);\r
448             test.equal(encoded.flip().toString("debug"), "<0A 04 12 34 56 78>");\r
449             encoded = encoded.slice(0, 5); // chop off the last byte\r
450             var err = null;\r
451             try {\r
452                 Test.decode(encoded);\r
453             } catch (caught) {\r
454                 err = caught;\r
455             }\r
456             test.ok(err && err.message && err.message.indexOf(": 4 required but got only 3") >= 0);\r
457             test.done();\r
458         },\r
459 \r
460         "bool": function(test) {\r
461             try {\r
462                 var builder = ProtoBuf.loadProto("message Test { optional bool ok = 1 [ default = false ]; }"),\r
463                     Test = builder.build("Test"),\r
464                     t =  new Test();\r
465                 test.strictEqual(t.ok, null); // Not set as it is optional\r
466                 t.setOk(true);\r
467                 test.strictEqual(t.ok, true);\r
468                 test.strictEqual(Test.decode(t.encode()).ok, true);\r
469                 t.setOk(false);\r
470                 test.strictEqual(t.ok, false);\r
471                 t.setOk(null); // Not set\r
472                 test.strictEqual(Test.decode(t.encode()).ok, false); // = default when missing\r
473             } catch (err) {\r
474                 fail(err);\r
475             }\r
476             test.done();\r
477         },\r
478 \r
479         // As mentioned by Bill Katz\r
480         "T139": function(test) {\r
481             try{\r
482                 var builder = ProtoBuf.loadProtoFile(__dirname+"/T139.proto");\r
483                 var T139 = builder.build("T139");\r
484                 test.ok(typeof T139 == 'function');\r
485                 var inst = new T139(139,139);\r
486                 test.equal(inst.a, 139);\r
487                 test.equal(inst.b, 139);\r
488                 inst.setA(139);\r
489                 inst.setB(139);\r
490                 test.equal(inst.a, 139);\r
491                 test.equal(inst.b, 139);\r
492                 var bb = new ByteBuffer(3);\r
493                 inst.encode(bb);\r
494                 test.equal(bb.flip().toString("debug"), "<08 8B 01 10 8B 01>");\r
495                 var instDec = T139.decode(bb);\r
496                 test.equal(instDec.a, 139);\r
497                 test.equal(instDec.b, 139);\r
498             } catch (e) {\r
499                 fail(e);\r
500             }\r
501             test.done();\r
502         },\r
503 \r
504         "emptyDefaultString": function(test) {\r
505             try {\r
506                 var builder = ProtoBuf.loadProto("message Test1 { required string test = 1 [default = \"\"]; }");\r
507                 var Test1;\r
508                 test.doesNotThrow(function() {\r
509                     Test1 = builder.build("Test1");\r
510                 });\r
511                 var test1 = new Test1();\r
512                 test.strictEqual(test1.test, "");\r
513             } catch (e) {\r
514                 fail(e);\r
515             }\r
516             test.done();\r
517         },\r
518 \r
519         "trailingSemicolon": function(test) {\r
520             try {\r
521                 var builder = ProtoBuf.loadProto("message Test1 { optional string test = 1; };");\r
522                 test.doesNotThrow(function() {\r
523                     var Test1 = builder.build("Test1");\r
524                 });\r
525             } catch (e) {\r
526                 fail(e);\r
527             }\r
528             test.done();\r
529         },\r
530 \r
531         "inner": {\r
532 \r
533             "longstr": function(test) {\r
534                 try {\r
535                     var builder = ProtoBuf.loadProto("message Test { required Inner a = 1; message Inner { required string b = 1; } }");\r
536                     var Test = builder.build("Test");\r
537                     var t = new Test();\r
538                     var data = "0123456789"; // 10: 20, 40, 80, 160, 320 bytes\r
539                     for (var i=0; i<5; i++) data += data;\r
540                     test.equal(data.length, 320);\r
541                     t.a = new Test.Inner(data);\r
542                     var bb = t.encode();\r
543                     var t2 = Test.decode(bb);\r
544                     test.equal(t2.a.b.length, 320);\r
545                     test.equal(data, t2.a.b);\r
546                 } catch (e) {\r
547                     fail(e);\r
548                 }\r
549                 test.done();\r
550             },\r
551 \r
552             "multiple": function(test) {\r
553                 try {\r
554                     var str = "";\r
555                     for (var i=0; i<200; i++) str += 'a';\r
556                     var builder = ProtoBuf.loadProtoFile(__dirname+"/inner.proto");\r
557                     var fooCls = builder.build("Foo");\r
558                     var barCls = builder.build("Bar");\r
559                     var bazCls = builder.build("Baz");\r
560                     var foo = new fooCls(new barCls(str), new bazCls(str));\r
561                     var fooEncoded = foo.encode();\r
562                     test.doesNotThrow(function() {\r
563                         fooCls.decode(fooEncoded);\r
564                     });\r
565                 } catch (e) {\r
566                     fail(e);\r
567                 }\r
568                 test.done();\r
569             },\r
570 \r
571             "float": function(test) {\r
572                 try {\r
573                     var builder = ProtoBuf.loadProto("message Foo { required Bar bar = 1; } message Bar { required float baz = 1; }");\r
574                     var root = builder.build();\r
575                     var foo = new root.Foo(new root.Bar(4));\r
576                     var bb = foo.encode();\r
577                     var foo2 = root.Foo.decode(bb);\r
578                     test.equal(foo.bar.baz, 4);\r
579                     test.equal(foo2.bar.baz, foo.bar.baz);\r
580                 } catch (e) {\r
581                     fail(e);\r
582                 }\r
583                 test.done();\r
584             }\r
585 \r
586         },\r
587 \r
588         "truncated": function(test) {\r
589             try {\r
590                 var builder = ProtoBuf.loadProto("message Test { required int32 a = 1; required int32 b = 2; }");\r
591                 var Test = builder.build("Test");\r
592                 var t = new Test(), bb = new ByteBuffer(2);\r
593                 t.setA(1);\r
594                 try {\r
595                     bb = t.encode(bb).flip();\r
596                     test.ok(false);\r
597                 } catch (e) {\r
598                     test.ok(e.encoded);\r
599                     bb = e.encoded.flip();\r
600                     test.equal(bb.toString("debug"), "<08 01>");\r
601                 }\r
602                 var t2;\r
603                 try /* to decode truncated message */ {\r
604                     t2 = Test.decode(bb);\r
605                     test.ok(false); // ^ throws\r
606                 } catch (e) {\r
607                     // But still be able to access the rest\r
608                     var t3 = e.decoded;\r
609                     test.strictEqual(t3.a, 1);\r
610                     test.strictEqual(t3.b, null);\r
611                 }\r
612                 test.strictEqual(t2, undefined);\r
613             } catch (e) {\r
614                 fail(e);\r
615             }\r
616             test.done();\r
617         },\r
618 \r
619         // Options on all levels\r
620         "options": {\r
621 \r
622             "parse": function(test) {\r
623                 try {\r
624                     var parser = new ProtoBuf.DotProto.Parser(ProtoBuf.Util.fetch(__dirname+"/options.proto"));\r
625                     var root = parser.parse();\r
626                     test.equal(root["package"], "My");\r
627                     test.strictEqual(root["options"]["(toplevel_1)"], 10);\r
628                     test.equal(root["options"]["(toplevel_2)"], "Hello world!");\r
629                     var opt = root["messages"][0]["fields"][0]["options"];\r
630                     test.equal(opt["default"], "Max");\r
631                     opt = root["messages"][0]["options"];\r
632                     test.strictEqual(opt["(inmessage)"], "My.Test");\r
633                     test.strictEqual(opt["(foo.my_option).bar"], false);\r
634                     opt = root["messages"][0]["fields"][1]["options"];\r
635                     test.strictEqual(opt["default"], "Shouldn't mix quotes");\r
636                     opt = root["messages"][0]["fields"][2]["options"];\r
637                     test.strictEqual(opt["default"], 'Shouldn"t mix quotes');\r
638                     opt = root["messages"][0]["fields"][3]["options"];\r
639                     test.strictEqual(opt["(foo_options).opt1"], 123);\r
640                     test.strictEqual(opt["(foo_options).opt2"], "baz");\r
641                 } catch (e) {\r
642                     fail(e);\r
643                 }\r
644                 test.done();\r
645             },\r
646 \r
647             "export": function(test) {\r
648                 try {\r
649                     var builder = ProtoBuf.loadProtoFile(__dirname+"/options.proto");\r
650                     var My = builder.build("My");\r
651                     test.deepEqual(My.$options, {\r
652                         "(toplevel_1)": 10,\r
653                         "(toplevel_2)": "Hello world!"\r
654                     });\r
655                     test.strictEqual(My.$options['(toplevel_1)'], 10);\r
656                     test.deepEqual(My.Test.$options, {\r
657                         "(inmessage)": "My.Test",\r
658                         "(foo.my_option).bar": false\r
659                     });\r
660                 } catch (e) {\r
661                     fail(e);\r
662                 }\r
663                 test.done();\r
664             }\r
665         },\r
666 \r
667         // Comments\r
668         "comments": function(test) {\r
669             try {\r
670                 var tn = new ProtoBuf.DotProto.Tokenizer(ProtoBuf.Util.fetch(__dirname+'/comments.proto'));\r
671                 var token, tokens = [];\r
672                 do {\r
673                     token = tn.next();\r
674                     tokens.push(token);\r
675                 } while (token !== null);\r
676                 test.deepEqual(tokens, ['message', 'TestC', '{', 'required', 'int32', 'a', '=', '1', ';', '}', null]);\r
677             } catch (e) {\r
678                 fail(e);\r
679             }\r
680             test.done();\r
681         },\r
682 \r
683         // A more or less complex proto with type references\r
684         "complexProto": function(test) {\r
685             try {\r
686                 var builder = ProtoBuf.loadProtoFile(__dirname+"/complex.proto");\r
687                 validateComplex(test, builder.build("Game"));\r
688                 var TCars = builder.lookup("Game.Cars");\r
689                 test.strictEqual(TCars.fqn(), ".Game.Cars");\r
690             } catch(e) {\r
691                 fail(e);\r
692             }\r
693             test.done();\r
694         },\r
695 \r
696         // The same created without calling upon the parser to do so\r
697         "complexJSON": function(test) {\r
698             try {\r
699                 var builder = ProtoBuf.loadJsonFile(__dirname+"/complex.json");\r
700                 validateComplex(test, builder.build("Game"));\r
701             } catch (e) {\r
702                 fail(e);\r
703             }\r
704             test.done();\r
705         },\r
706 \r
707         // Test error messages\r
708         "errorMessage": function(test) {\r
709             test.throws(function() {\r
710                 var builder = ProtoBuf.loadJsonFile(__dirname+"/complex.json");\r
711                 var Game = builder.build("Game");\r
712                 var car = new Game.Cars.Car();\r
713                 car.speed = "hello";\r
714                 car.encode();\r
715             }, /Illegal value for speed/);\r
716             test.done();\r
717         },\r
718 \r
719         // Builder reused to add definitions from multiple sources\r
720         "multiBuilder": function(test) {\r
721             try {\r
722                 var builder = ProtoBuf.loadProtoFile(__dirname+"/example1.proto");\r
723                 ProtoBuf.loadProtoFile(__dirname+"/example2.proto", builder);\r
724                 var ns = builder.build();\r
725                 test.ok(!!ns.Test1);\r
726                 test.ok(!!ns.Test2);\r
727             } catch (e) {\r
728                 fail(e);\r
729             }\r
730             test.done();\r
731         },\r
732 \r
733         // Inner messages test\r
734         "inner": function(test) {\r
735             try {\r
736                 var builder = ProtoBuf.loadProtoFile(__dirname+"/repeated.proto");\r
737                 var root = builder.build(),\r
738                     Outer = root.Outer,\r
739                     Inner = root.Inner;\r
740                 // Empty\r
741                 var outer = new Outer();\r
742                 var bb = new ByteBuffer(1).fill(0).flip();\r
743                 outer.encode(bb);\r
744                 test.equal(bb.flip().toString("debug"), "|00");\r
745                 var douter = Outer.decode(bb);\r
746                 test.ok(douter.inner instanceof Array);\r
747                 test.equal(douter.inner.length, 0);\r
748                 // Multiple\r
749                 outer = new Outer({ inner: [new Inner(1), new Inner(2)] });\r
750                 bb = new ByteBuffer(8);\r
751                 var size = outer.calculate();\r
752                 outer.encode(bb);\r
753                 test.strictEqual(bb.offset, size);\r
754                 test.equal(bb.flip().toString("debug"), "<0A 02 08 01 0A 02 08 02>");\r
755                 douter = Outer.decode(bb);\r
756                 test.ok(douter.inner instanceof Array);\r
757                 test.equal(douter.inner.length, 2);\r
758                 test.equal(douter.inner[0].inner_value, 1);\r
759                 test.equal(douter.inner[1].inner_value, 2);\r
760             } catch (e) {\r
761                 fail(e);\r
762             }\r
763             test.done();\r
764         },\r
765 \r
766         // Packed vs. not packed repeated fields test\r
767         "packed": function(test) {\r
768             try {\r
769                 var builder = ProtoBuf.loadProtoFile(__dirname+"/packed.proto");\r
770                 var Message = builder.build("Message");\r
771                 // Both empty\r
772                 var message = new Message();\r
773                 var bb = new ByteBuffer(1).fill(0).flip();\r
774                 var size = message.calculate();\r
775                 message.encode(bb);\r
776                 test.strictEqual(bb.offset, size);\r
777                 test.equal(bb.flip().toString("debug"), "|00");\r
778                 message = Message.decode(bb);\r
779                 test.ok(message.a instanceof Array);\r
780                 test.equal(message.a.length, 0);\r
781                 test.ok(message.b instanceof Array);\r
782                 test.equal(message.b.length, 0);\r
783                 // Both non-empty\r
784                 message = new Message([1,2,3], [1,2,3]);\r
785                 size = message.calculate();\r
786                 message.encode(bb.resize(11));\r
787                 test.strictEqual(bb.offset, size);\r
788                 test.equal(bb.flip().toString("debug"), "<0A 03 01 02 03 10 01 10 02 10 03>");\r
789                 message = Message.decode(bb);\r
790                 test.ok(message.a instanceof Array);\r
791                 test.equal(message.a.length, 3);\r
792                 test.deepEqual(message.a, [1,2,3]);\r
793                 test.ok(message.b instanceof Array);\r
794                 test.equal(message.b.length, 3);\r
795                 test.deepEqual(message.b, [1,2,3]);\r
796             } catch (e) {\r
797                 fail(e);\r
798             }\r
799             test.done();\r
800         },\r
801 \r
802         // Legacy groups test\r
803         "groups": function(test) {\r
804             try {\r
805                 var builder = ProtoBuf.loadProtoFile(__dirname+"/groups.proto");\r
806                 var root = builder.build();\r
807                 var Outer = root.Outer;\r
808                 var TOuter = builder.ns.getChild("Outer");\r
809                 var TInner = TOuter.getChild("MyInner");\r
810                 test.ok(TInner instanceof ProtoBuf.Reflect.Message);\r
811                 test.strictEqual(TInner.isGroup, true);\r
812                 var Tinner = TOuter.getChild("myinner");\r
813                 test.ok(Tinner instanceof ProtoBuf.Reflect.Message.Field);\r
814                 test.strictEqual(Tinner.id, 2);\r
815                 test.deepEqual(Tinner.options, { "deprecated": true });\r
816                 var Inner = root.Outer.MyInner;\r
817                 var outer = new Outer("a", [new Inner("hello")], "b", new Inner("world"));\r
818                 var bb = new ByteBuffer();\r
819                 var size = outer.calculate();\r
820                 outer.encode(bb);\r
821                 test.strictEqual(bb.offset, size);\r
822                 bb.flip().compact();\r
823                 var wiredMsg = [\r
824                     "0A", // 1|010 = id 1, wire type 2 (ldelim)\r
825                     "01", // length 1\r
826                     "61", // "a"\r
827                     "13", // 10|011 = id 2, wire type 3 (start group)\r
828                     "1A", // 11|010 = id 3, wire type 2 (ldelim)\r
829                     "05", // length 5\r
830                     "68 65 6C 6C 6F", // "hello"\r
831                     "14", // 10|100 = id 2, wire type 4 (end group)\r
832                     "22", // 100|010 = id 4, wire type 2 (ldelim)\r
833                     "01", // length 1\r
834                     "62", // "b"\r
835                     "2B", // 101|011 = id 5, wire type = 3 (start group)\r
836                     "1A", // 11|010 = id 3, wire type = 2 (ldelim)\r
837                     "05", // length 5\r
838                     "77 6F 72 6C 64", // "world"\r
839                     "2C" // 101|100 = id 5, wire type = 4 (end group)\r
840                 ];\r
841                 test.equal(bb.toString("debug"), "<" +wiredMsg.join(" ") + ">");\r
842                 var douter = Outer.decode(bb);\r
843                 test.strictEqual(douter.before, "a");\r
844                 test.strictEqual(douter.myinner.length, 1);\r
845                 test.strictEqual(douter.myinner[0].a, "hello");\r
846                 test.strictEqual(douter.after, "b");\r
847                 bb.offset = 0;\r
848                 douter = root.OuterSparse.decode(bb);\r
849                 test.strictEqual(bb.offset, bb.limit);\r
850                 test.strictEqual(douter.before, "a");\r
851                 test.strictEqual(douter.after, "b");\r
852             } catch (e) {\r
853                 fail(e);\r
854             }\r
855             test.done();\r
856         },\r
857 \r
858         "x64Fixed": function(test) {\r
859             try {\r
860                 var builder = ProtoBuf.loadProtoFile(__dirname+"/x64.proto");\r
861                 var Test = builder.build("Test");\r
862                 var myTest = new Test();\r
863                 test.ok(myTest.val instanceof ByteBuffer.Long);\r
864                 test.equal(myTest.val.unsigned, false);\r
865                 test.equal(myTest.val.toNumber(), -1);\r
866                 test.ok(myTest.uval instanceof ByteBuffer.Long);\r
867                 test.equal(myTest.uval.unsigned, true);\r
868                 test.equal(myTest.uval.toNumber(), 1);\r
869                 myTest.setVal(-2);\r
870                 myTest.setUval(2);\r
871                 var bb = new ByteBuffer(18); // 2x tag + 2x 64bit\r
872                 var size = myTest.calculate();\r
873                 myTest.encode(bb);\r
874                 test.strictEqual(bb.offset, size);\r
875                 test.equal(bb.flip().toString("debug"), "<09 FE FF FF FF FF FF FF FF 11 02 00 00 00 00 00 00 00>");\r
876                 //                         ^ wireType=1, id=1         ^ wireType=1, id=2\r
877                 myTest = Test.decode(bb);\r
878                 test.ok(myTest.val instanceof ByteBuffer.Long);\r
879                 test.equal(myTest.val.unsigned, false);\r
880                 test.equal(myTest.val.toNumber(), -2);\r
881                 test.ok(myTest.uval instanceof ByteBuffer.Long);\r
882                 test.equal(myTest.uval.unsigned, true);\r
883                 test.equal(myTest.uval.toNumber(), 2);\r
884             } catch (e) {\r
885                 fail(e);\r
886             }\r
887             test.done();\r
888         },\r
889 \r
890         "x64Varint": function(test) {\r
891             try {\r
892                 var builder = ProtoBuf.loadProtoFile(__dirname+"/x64.proto");\r
893                 var Test = builder.build("Test2");\r
894                 var Test = builder.build("Test2");\r
895                 var myTest = new Test();\r
896                 test.ok(myTest.val instanceof ByteBuffer.Long);\r
897                 test.equal(myTest.val.unsigned, false);\r
898                 test.equal(myTest.val.toNumber(), -1);\r
899                 test.ok(myTest.uval instanceof ByteBuffer.Long);\r
900                 test.equal(myTest.uval.unsigned, true);\r
901                 test.equal(myTest.uval.toNumber(), 1);\r
902                 test.ok(myTest.sval instanceof ByteBuffer.Long);\r
903                 test.equal(myTest.sval.unsigned, false);\r
904                 test.equal(myTest.sval.toNumber(), -2);\r
905 \r
906                 myTest.setVal(-2);\r
907                 myTest.setUval(2);\r
908                 myTest.setSval(-3);\r
909                 var bb = new ByteBuffer(3+10+2); // 3x tag + 1x varint 10byte + 2x varint 1byte\r
910                 var size = myTest.calculate();\r
911                 myTest.encode(bb);\r
912                 test.strictEqual(bb.offset, size);\r
913                 test.equal(bb.flip().toString("debug"), "<08 FE FF FF FF FF FF FF FF FF 01 10 02 18 05>");\r
914                 // 08: wireType=0, id=1, 18: wireType=0, id=2, ?: wireType=0, id=3\r
915                 myTest = Test.decode(bb);\r
916                 test.ok(myTest.val instanceof ByteBuffer.Long);\r
917                 test.equal(myTest.val.unsigned, false);\r
918                 test.equal(myTest.val.toNumber(), -2);\r
919                 test.ok(myTest.uval instanceof ByteBuffer.Long);\r
920                 test.equal(myTest.uval.unsigned, true);\r
921                 test.equal(myTest.uval.toNumber(), 2);\r
922                 test.ok(myTest.sval instanceof ByteBuffer.Long);\r
923                 test.equal(myTest.sval.unsigned, false);\r
924                 test.equal(myTest.sval.toNumber(), -3);\r
925             } catch (e) {\r
926                 fail(e);\r
927             }\r
928             test.done();\r
929         },\r
930 \r
931         "keywords": function(test) {\r
932             try {\r
933                 var builder = ProtoBuf.loadProto("message Reserved { optional string get = 1; }");\r
934                 var My = builder.build();\r
935                 var myTest = new My.Reserved("a");\r
936                 test.doesNotThrow(function() {\r
937                     myTest.encode();\r
938                 });\r
939             } catch (e) {\r
940                 fail(e);\r
941             }\r
942             test.done();\r
943         },\r
944 \r
945         "imports": function(test) {\r
946             try {\r
947                 var builder = ProtoBuf.loadProtoFile(__dirname+"/imports.proto");\r
948                 var root = builder.build();\r
949                 test.ok(!!root.Test1);\r
950                 test.ok(!!root.Test2);\r
951                 test.ok(!!root.My.Test3);\r
952                 test.notEqual(root.Test2, root.My.Test2);\r
953             } catch (e) {\r
954                 fail(e);\r
955             }\r
956             test.done();\r
957         },\r
958 \r
959         "weakImports": function(test) {\r
960             try {\r
961                 var builder = ProtoBuf.loadProtoFile(__dirname+"/imports-weak.proto");\r
962                 var root = builder.build();\r
963             } catch (e) {\r
964                 test.ok(e.message.indexOf("unresolvable type reference") >= 0);\r
965                 test.done();\r
966                 return;\r
967             }\r
968             var e = new Error("Weak import was imported.");\r
969             fail(e);\r
970         },\r
971 \r
972         "importExtensions": function(test) {\r
973             var x = "package x; \\r
974             message Test { \\r
975                 extensions 1 to 10; \\r
976             } \\r
977             extend Test { \\r
978                 optional int32 first_val = 1; \\r
979             }";\r
980             var y = "package y; \\r
981             extend x.Test { \\r
982                 optional int32 second_val = 2; \\r
983             }";\r
984             var builder = ProtoBuf.newBuilder();\r
985             ProtoBuf.loadProto(x, builder);\r
986             ProtoBuf.loadProto(y, builder);\r
987             var Test = builder.build('x.Test');\r
988             var inst = new Test();\r
989             test.strictEqual(inst[".x.first_val"], null);\r
990             test.strictEqual(inst[".y.second_val"], null);\r
991             test.done();\r
992         },\r
993 \r
994         "toplevel": function(test) {\r
995             try {\r
996                 var builder = ProtoBuf.loadProtoFile(__dirname+"/toplevel.proto");\r
997                 var My = builder.build("My");\r
998                 test.ok(!!My.MyEnum);\r
999                 test.equal(My.MyEnum.ONE, 1);\r
1000                 test.equal(My.MyEnum.TWO, 2);\r
1001                 test.ok(!!My.Test);\r
1002                 var myTest = new My.Test();\r
1003                 test.equal(myTest.num, My.MyEnum.ONE);\r
1004             } catch (e) {\r
1005                 fail(e);\r
1006             }\r
1007             test.done();\r
1008         },\r
1009 \r
1010         "importsToplevel": function(test) {\r
1011             try {\r
1012                 var builder = ProtoBuf.loadProtoFile(__dirname+"/imports-toplevel.proto");\r
1013                 var My = builder.build("My");\r
1014                 test.ok(!!My.MyEnum);\r
1015                 test.equal(My.MyEnum1.ONE, 1);\r
1016                 test.equal(My.MyEnum1.TWO, 2);\r
1017                 test.ok(!!My.Test1);\r
1018                 var myTest = new My.Test1();\r
1019                 test.equal(myTest.num, My.MyEnum.ONE);\r
1020                 test.equal(myTest.num1, My.MyEnum1.ONE);\r
1021             } catch (e) {\r
1022                 fail(e);\r
1023             }\r
1024             test.done();\r
1025         },\r
1026 \r
1027         "importDuplicate": function(test) {\r
1028             try {\r
1029                 var builder = ProtoBuf.loadProtoFile(__dirname+"/import_a.proto");\r
1030                 test.doesNotThrow(function() {\r
1031                     ProtoBuf.loadProtoFile(__dirname+"/import_b.proto", builder);\r
1032                 });\r
1033                 var root = builder.build();\r
1034                 test.ok(root.A);\r
1035                 test.ok(root.B);\r
1036                 test.ok(root.Common);\r
1037             } catch (e) {\r
1038                 fail(e);\r
1039             }\r
1040             test.done();\r
1041         },\r
1042 \r
1043         "importDuplicateDifferentBuilder": function(test) {\r
1044             try {\r
1045                 var builderA = ProtoBuf.loadProtoFile(__dirname+"/import_a.proto");\r
1046                 var builderB;\r
1047                 test.doesNotThrow(function() {\r
1048                     builderB = ProtoBuf.loadProtoFile(__dirname+"/import_b.proto");\r
1049                 });\r
1050                 var rootA = builderA.build();\r
1051                 var rootB = builderB.build();\r
1052                 test.ok(rootA.A);\r
1053                 test.ok(rootB.B);\r
1054                 test.ok(rootA.Common);\r
1055                 test.ok(rootB.Common);\r
1056             } catch (e) {\r
1057                 fail(e);\r
1058             }\r
1059             test.done();\r
1060         },\r
1061 \r
1062         "dupimport": function(test) {\r
1063             try {\r
1064                 // Suppress logging result to stdout\r
1065                 fixture.capture(function() { return false;});\r
1066                 require(__dirname+"/../cli/pbjs.js").main(["node", "bin/pbjs", __dirname+"/dupimport/main.proto", "--quiet"]);\r
1067                 fixture.release();\r
1068             } catch (e) {\r
1069                 fixture.release();\r
1070                 fail(e);\r
1071             }\r
1072             test.done();\r
1073         },\r
1074 \r
1075         "field_name_same_as_package": function(test) {\r
1076             try {\r
1077                 fixture.capture(function() { return false;});\r
1078                 require(__dirname+"/../cli/pbjs.js").main(["node", "bin/pbjs", __dirname+"/field_name_same_as_package/main.proto", "--quiet"]);\r
1079                 fixture.release();\r
1080             } catch (e) {\r
1081                 fixture.release();\r
1082                 fail(e);\r
1083             }\r
1084             test.done();\r
1085         },\r
1086 \r
1087         "importRoot": function(test) {\r
1088             try {\r
1089                 var builder = ProtoBuf.loadProtoFile({\r
1090                     root: __dirname,\r
1091                     file: "importRoot/file1.proto"\r
1092                 });\r
1093                 var Test = builder.build("Test");\r
1094                 test.ok(new Test() instanceof ProtoBuf.Builder.Message);\r
1095             } catch (e) {\r
1096                 fail(e);\r
1097             }\r
1098             test.done();\r
1099         },\r
1100 \r
1101         "extend": function(test) {\r
1102             try {\r
1103                 var ast = new ProtoBuf.DotProto.Parser(fs.readFileSync(__dirname+"/extend.proto")).parse();\r
1104                 test.deepEqual(ast, { package: null,\r
1105                     messages:\r
1106                         [ { ref: 'google.protobuf.MessageOptions',\r
1107                             fields:\r
1108                                 [ { rule: 'optional',\r
1109                                     type: 'int32',\r
1110                                     name: 'foo',\r
1111                                     options: {},\r
1112                                     id: 1001 } ] },\r
1113                             { name: 'Foo',\r
1114                                 fields: [],\r
1115                                 enums: [],\r
1116                                 messages: [],\r
1117                                 options: {},\r
1118                                 services: [],\r
1119                                 oneofs: {},\r
1120                                 extensions: [ [ 2, 536870911 ] ] },\r
1121                             { ref: 'Foo',\r
1122                                 fields:\r
1123                                     [ { rule: 'optional',\r
1124                                         type: 'string',\r
1125                                         name: 'bar',\r
1126                                         options: {},\r
1127                                         id: 2 } ] },\r
1128                             { name: 'Bar',\r
1129                                 fields: [],\r
1130                                 enums: [],\r
1131                                 messages:\r
1132                                     [ { name: 'Foo',\r
1133                                         fields: [],\r
1134                                         enums: [],\r
1135                                         messages: [],\r
1136                                         options: {},\r
1137                                         services: [],\r
1138                                         oneofs: {} },\r
1139                                         { ref: '.Foo',\r
1140                                             fields: [ { rule: 'optional', type: 'Foo', name: 'foo', options: {}, id: 3 } ] } ],\r
1141                                 options: {},\r
1142                                 services: [],\r
1143                                 oneofs: {} } ],\r
1144                     enums: [],\r
1145                     imports: [ 'google/protobuf/descriptor.proto' ],\r
1146                     options: {},\r
1147                     services: [] }\r
1148                 );\r
1149 \r
1150                 var builder = ProtoBuf.loadProtoFile(__dirname+"/extend.proto");\r
1151                 var TFoo = builder.lookup(".Foo"),\r
1152                     TBar = builder.lookup(".Bar"),\r
1153                     TBarFoo = builder.lookup(".Bar.Foo"),\r
1154                     fields = TFoo.getChildren(ProtoBuf.Reflect.Message.Field);\r
1155                 test.strictEqual(fields.length, 2);\r
1156                 test.strictEqual(fields[0].name, ".bar");\r
1157                 test.strictEqual(fields[0].id, 2);\r
1158                 test.strictEqual(fields[1].name, ".Bar.foo");\r
1159                 test.strictEqual(fields[1].id, 3);\r
1160                 test.deepEqual(TFoo.extensions, [[2, ProtoBuf.ID_MAX]]); // explicitly defined\r
1161                 test.strictEqual(TBar.extensions, undefined); // none defined\r
1162                 test.deepEqual(TBar.getChild("foo"), { builder: builder, parent: TBar, name: "foo", field: TFoo.getChild('.Bar.foo') });\r
1163                 test.strictEqual(TBar.getChildren(ProtoBuf.Reflect.Message.Field).length, 0);\r
1164                 var root = builder.build();\r
1165                 test.strictEqual(TFoo.getChild(".Bar.foo").resolvedType, TBarFoo); // .Bar.Foo, not .Foo\r
1166                 var foo = new root.Foo(),\r
1167                     bar = new root.Bar();\r
1168                 foo['.bar'] = "123";\r
1169                 foo['.Bar.foo'] = bar;\r
1170                 test.equal(foo.encode().compact().toString("debug"), "<12 03 31 32 33 1A 00>");\r
1171             } catch (e) {\r
1172                 fail(e);\r
1173             }\r
1174             test.done();\r
1175         },\r
1176 \r
1177         // Custom options on all levels\r
1178         // victorr (https://github.com/victorr)\r
1179         "customOptions": function(test) {\r
1180             try {\r
1181                 var parser = new ProtoBuf.DotProto.Parser(ProtoBuf.Util.fetch(__dirname+"/custom-options.proto"));\r
1182                 var root = parser.parse();\r
1183                 test.equal(root["options"]["(my_file_option)"], "Hello world!");\r
1184                 test.equal(root["messages"][7]["options"]["(my_message_option)"], 1234);\r
1185                 test.equal(root["messages"][7]["fields"][0]["options"]["(my_field_option)"], 4.5);\r
1186                 // test.equal(root["services"]["MyService"]["options"]["my_service_option"], "FOO");\r
1187                 // TODO: add tests for my_enum_option, my_enum_value_option\r
1188             } catch (e) {\r
1189                 fail(e);\r
1190             }\r
1191             test.done();\r
1192         },\r
1193 \r
1194         "oneofs": function(test) {\r
1195             try {\r
1196                 var builder = ProtoBuf.loadProtoFile(__dirname+"/oneof.proto"),\r
1197                     MyOneOf = builder.build("MyOneOf"),\r
1198                     TOneOf = builder.lookup(".MyOneOf");\r
1199                 test.ok(TOneOf.getChild("my_oneof"));\r
1200                 var myOneOf = new MyOneOf();\r
1201                 test.strictEqual(myOneOf.my_oneof, null);\r
1202                 myOneOf.set("id", 1);\r
1203                 test.strictEqual(myOneOf.my_oneof, "id");\r
1204                 myOneOf.set("name", "me");\r
1205                 test.strictEqual(myOneOf.my_oneof, "name");\r
1206                 test.strictEqual(myOneOf.id, null);\r
1207                 var bb = myOneOf.encode().compact();\r
1208                 test.strictEqual(bb.toString("debug"), "<12 02 6D 65>"); // id 2, wt 2, len 2\r
1209                 myOneOf = MyOneOf.decode(bb);\r
1210                 test.strictEqual(myOneOf.my_oneof, "name");\r
1211                 test.strictEqual(myOneOf.name, "me");\r
1212                 test.strictEqual(myOneOf.id, null);\r
1213             } catch (e) {\r
1214                 fail(e);\r
1215             }\r
1216             test.done();\r
1217         },\r
1218 \r
1219         "services": function(test) {\r
1220             try {\r
1221                 var parser = new ProtoBuf.DotProto.Parser(ProtoBuf.Util.fetch(__dirname+"/custom-options.proto"));\r
1222                 var root = parser.parse();\r
1223                 test.deepEqual(root["services"], [{\r
1224                     "name": "MyService",\r
1225                     "rpc": {\r
1226                         "MyMethod": {\r
1227                             "request": "RequestType",\r
1228                             "response": "ResponseType",\r
1229                             "request_stream": false,\r
1230                             "response_stream": false,\r
1231                             "options": {\r
1232                                 "(my_method_option).foo": 567,\r
1233                                 "(my_method_option).bar": "Some string"\r
1234                             }\r
1235                         }\r
1236                     },\r
1237                     "options": {\r
1238                         "(my_service_option)": "FOO"\r
1239                     }\r
1240                 }]);\r
1241 \r
1242                 var builder = ProtoBuf.loadProtoFile(__dirname+"/custom-options.proto");\r
1243                 var root = builder.build(),\r
1244                     MyService = root.MyService,\r
1245                     RequestType = root.RequestType,\r
1246                     ResponseType = root.ResponseType,\r
1247                     called = false;\r
1248 \r
1249                 test.deepEqual(MyService.$options, {\r
1250                     "(my_service_option)": "FOO"\r
1251                 });\r
1252                 test.deepEqual(MyService.MyMethod.$options, {\r
1253                     "(my_method_option).foo": 567,\r
1254                     "(my_method_option).bar": "Some string"\r
1255                 });\r
1256 \r
1257                 // Provide the service with your actual RPC implementation based on whatever framework you like most.\r
1258                 var myService = new MyService(function(method, req, callback) {\r
1259                     test.strictEqual(method, ".MyService.MyMethod");\r
1260                     test.ok(req instanceof RequestType);\r
1261                     called = true;\r
1262 \r
1263                     // In this case we just return no error and our pre-built response. This must be properly async!\r
1264                     setTimeout(callback.bind(this, null, (new ResponseType()).encode() /* as raw bytes for debugging */ ));\r
1265                 });\r
1266 \r
1267                 test.deepEqual(myService.$options, MyService.$options);\r
1268                 test.deepEqual(myService.MyMethod.$options, MyService.MyMethod.$options);\r
1269 \r
1270                 // Call the service with your request message and provide a callback. This will call your actual service\r
1271                 // implementation to perform the request and gather a response before calling the callback. If the\r
1272                 // request or response type is invalid i.e. not an instance of RequestType or ResponseType, your\r
1273                 // implementation will not be called as ProtoBuf.js handles this case internally and directly hands the\r
1274                 // error to your callback below.\r
1275                 myService.MyMethod(new RequestType(), function(err, res) {\r
1276                     // We get: err = null, res = our prebuilt response. And that's it.\r
1277                     if (err !== null) {\r
1278                         fail(err);\r
1279                     }\r
1280                     test.strictEqual(called, true);\r
1281                     test.ok(res instanceof ResponseType);\r
1282                     test.done();\r
1283                 });\r
1284                 myService.MyMethod(new RequestType().encode(), function(err, res) {\r
1285                     // We get: err = null, res = our prebuilt response. And that's it.\r
1286                     if (err !== null) {\r
1287                         fail(err);\r
1288                     }\r
1289                     test.strictEqual(called, true);\r
1290                     test.ok(res instanceof ResponseType);\r
1291                     test.done();\r
1292                 });\r
1293             } catch (e) {\r
1294                 fail(e);\r
1295             }\r
1296         },\r
1297 \r
1298         // Properly ignore "syntax" and "extensions" keywords\r
1299         // The corresponding .proto file has been removed upon request\r
1300         /* "gtfs-realtime": function(test) {\r
1301             try {\r
1302                 test.doesNotThrow(function() {\r
1303                     ProtoBuf.loadProtoFile(__dirname+"/gtfs-realtime.proto");\r
1304                 });\r
1305             } catch (e) {\r
1306                 fail(e);\r
1307             }\r
1308             test.done();\r
1309         }, */\r
1310 \r
1311         "delimited": function(test) {\r
1312             try {\r
1313                 var builder = ProtoBuf.loadProto("message Position { required int32 x = 1; required int32 y = 2; }");\r
1314                 var Position = builder.build("Position");\r
1315                 var bb = new ByteBuffer();\r
1316                 for (var i=0; i<2; i++) {\r
1317                     var position = new Position(10,10);\r
1318                     position.encodeDelimited(bb);\r
1319                 }\r
1320                 bb.flip();\r
1321                 for (i=0; i<2; i++) {\r
1322                     position = Position.decodeDelimited(bb);\r
1323                     test.strictEqual(position.x, 10);\r
1324                     test.strictEqual(position.y, 10);\r
1325                 }\r
1326             } catch (e) {\r
1327                 fail(e);\r
1328             }\r
1329             test.done();\r
1330         },\r
1331 \r
1332         "stringify": function(test) {\r
1333             try {\r
1334                 var builder = ProtoBuf.loadProto("message Position { required int32 x = 1; required int64 y = 2; }");\r
1335                 var Position = builder.build("Position");\r
1336                 var position = new Position(1, ProtoBuf.Long.fromNumber(2));\r
1337                 var json = JSON.stringify(position);\r
1338                 test.strictEqual(json, '{"x":1,"y":{"low":2,"high":0,"unsigned":false}}');\r
1339                 position = new Position(JSON.parse(json));\r
1340                 test.strictEqual(position.x, 1);\r
1341                 test.ok(position.y instanceof ProtoBuf.Long);\r
1342                 test.deepEqual(position.y, {"low":2,"high":0,"unsigned":false});\r
1343                 // Also test if this encodes and decodes properly\r
1344                 position = Position.decode(position.encode());\r
1345                 test.ok(position.y instanceof ProtoBuf.Long);\r
1346                 test.deepEqual(position.y, {"low": 2, "high": 0, "unsigned": false });\r
1347             } catch (e) {\r
1348                 fail(e);\r
1349             }\r
1350             test.done();\r
1351         },\r
1352 \r
1353         "fields": function(test) {\r
1354             try {\r
1355                 var builder = ProtoBuf.loadProtoFile(__dirname+"/optional.proto");\r
1356                 var Test1 = builder.build("Test1");\r
1357                 var test1 = new Test1();\r
1358                 test.strictEqual(test1.a, null);\r
1359                 test.deepEqual(Object.keys(test1), ['a','b']);\r
1360                 var bb = test1.encode();\r
1361                 test1 = Test1.decode(bb);\r
1362                 test.strictEqual(test1.a, null);\r
1363                 test.deepEqual(Object.keys(test1), ['a','b']);\r
1364             } catch (e) {\r
1365                 fail(e);\r
1366             }\r
1367             test.done();\r
1368         },\r
1369 \r
1370         "fieldsToCamelCase": function(test) {\r
1371             try {\r
1372                 ProtoBuf.convertFieldsToCamelCase = true;\r
1373                 var builder = ProtoBuf.loadProtoFile(__dirname+"/camelcase.proto");\r
1374                 var Test = builder.build("Test"),\r
1375                     TTest = builder.lookup("Test");\r
1376                 var msg = new Test();\r
1377 \r
1378                 // Reverted collision on 1st\r
1379                 test.strictEqual(msg.some_field, null);\r
1380                 test.strictEqual(msg.someField, null);\r
1381                 test.equal(TTest.getChild("some_field").id, 1);\r
1382                 test.equal(TTest.getChild("someField").id, 2);\r
1383 \r
1384 \r
1385                 // Reverted collision on 2nd\r
1386                 test.strictEqual(msg.aField, null);\r
1387                 test.strictEqual(msg.a_field, null);\r
1388                 test.equal(TTest.getChild("aField").id, 3);\r
1389                 test.equal(TTest.getChild("a_field").id, 4);\r
1390 \r
1391                 // No collision\r
1392                 test.strictEqual(msg.itsAField, null);\r
1393                 test.equal(TTest.getChild("itsAField").id, 5);\r
1394 \r
1395                 test.ok(typeof msg.set_its_a_field === "function");\r
1396                 test.ok(typeof msg.setItsAField === "function");\r
1397 \r
1398                 ProtoBuf.convertFieldsToCamelCase = false;\r
1399             } catch (e) {\r
1400                 ProtoBuf.convertFieldsToCamelCase = false;\r
1401                 fail(e);\r
1402             }\r
1403             test.done();\r
1404         },\r
1405 \r
1406         "setarray": function(test) {\r
1407             try {\r
1408                 var builder = ProtoBuf.loadProtoFile(__dirname+"/setarray.proto");\r
1409                 var root = builder.build(),\r
1410                     Outer = root.Outer,\r
1411                     Inner = root.Inner,\r
1412                     inners = [];\r
1413 \r
1414                 // Array of repeated messages\r
1415                 inners.push(new Inner("a"), new Inner("b"), new Inner("c"));\r
1416                 var outer = new Outer();\r
1417                 outer.setInners(inners);\r
1418                 test.deepEqual(outer.inners, inners);\r
1419 \r
1420                 // Array of repeated message objects\r
1421                 inners = [];\r
1422                 inners.push({ str: 'a' }, { str: 'b' }, { str: 'c' });\r
1423                 outer.setInners(inners); // Converts\r
1424                 test.ok(outer.inners[0] instanceof Inner);\r
1425                 test.deepEqual(outer.inners, inners);\r
1426             } catch (e) {\r
1427                 fail(e);\r
1428             }\r
1429             test.done();\r
1430         },\r
1431 \r
1432 \r
1433         // Make sure that our example at https://github.com/dcodeIO/ProtoBuf.js/wiki is not nonsense\r
1434         "pingexample": function(test) {\r
1435             try {\r
1436                 var builder = ProtoBuf.loadProtoFile(__dirname+"/PingExample.proto");\r
1437                 var Message = builder.build("Message");\r
1438                 var msg = new Message();\r
1439                 msg.ping = new Message.Ping(123456789);\r
1440                 var bb = msg.encode();\r
1441                 test.strictEqual(bb.limit, 7);\r
1442                 msg = Message.decode(bb);\r
1443                 test.ok(msg.ping);\r
1444                 test.notOk(msg.pong);\r
1445                 test.strictEqual(msg.ping.time, 123456789);\r
1446             } catch (e) {\r
1447                 fail(e);\r
1448             }\r
1449             test.done();\r
1450         },\r
1451 \r
1452         "negInt32": function(test) {\r
1453             try {\r
1454                 var builder = ProtoBuf.loadProto("message Test { required int32 value = 2; }");\r
1455                 var Test = builder.build("Test");\r
1456                 var t = new Test(-1);\r
1457                 var size = t.calculate();\r
1458                 var bb = t.encode(); // flips\r
1459                 test.strictEqual(bb.remaining(), size);\r
1460                 test.strictEqual(bb.toBase64(), "EP///////////wE=");\r
1461                 t = Test.decode(bb);\r
1462                 test.strictEqual(t.value, -1);\r
1463             } catch (e) {\r
1464                 fail(e);\r
1465             }\r
1466             test.done();\r
1467         },\r
1468 \r
1469         "negEnumId": function(test) {\r
1470             try {\r
1471                 test.doesNotThrow(function() {\r
1472                     var builder = ProtoBuf.loadProtoFile(__dirname+"/negid.proto");\r
1473                     var Test = builder.build("Test");\r
1474                     test.strictEqual(Test.LobbyType.INVALID, -1);\r
1475                     var t = new Test(Test.LobbyType.INVALID);\r
1476                     test.strictEqual(t.type, -1);\r
1477                     var size = t.calculate();\r
1478                     var bb = t.encode(); // flips\r
1479                     test.strictEqual(bb.remaining(), size);\r
1480                     t = Test.decode(bb);\r
1481                     test.strictEqual(t.type, -1);\r
1482                 });\r
1483             } catch (e) {\r
1484                 fail(e);\r
1485             }\r
1486             test.done();\r
1487         },\r
1488 \r
1489         "base64": function(test) {\r
1490             try {\r
1491                 var Message = ProtoBuf.loadProto("message Message { required string s = 1; }").build("Message");\r
1492                 var msg = new Message("ProtoBuf.js");\r
1493                 var b64 = msg.toBase64();\r
1494                 test.strictEqual(b64, "CgtQcm90b0J1Zi5qcw==");\r
1495                 var msg2 = Message.decode64(b64);\r
1496                 test.deepEqual(msg, msg2);\r
1497                 msg2 = Message.decode(b64, "base64");\r
1498                 test.deepEqual(msg, msg2);\r
1499             } catch (e) {\r
1500                 fail(e);\r
1501             }\r
1502             test.done();\r
1503         },\r
1504 \r
1505         "hex": function(test) {\r
1506             try {\r
1507                 var Message = ProtoBuf.loadProto("message Message { required string s = 1; }").build("Message");\r
1508                 var msg = new Message("ProtoBuf.js");\r
1509                 var hex = msg.toHex();\r
1510                 test.strictEqual(hex, "0a0b50726f746f4275662e6a73");\r
1511                 var msg2 = Message.decodeHex(hex);\r
1512                 test.deepEqual(msg, msg2);\r
1513                 msg2 = Message.decode(hex, "hex");\r
1514                 test.deepEqual(msg, msg2);\r
1515             } catch (e) {\r
1516                 fail(e);\r
1517             }\r
1518             test.done();\r
1519         },\r
1520 \r
1521         "forwardComp": function(test) {\r
1522             try {\r
1523                 var Message = ProtoBuf.loadProto("message Message { required int32 a = 1; required string b = 2; required float c = 3; }").build("Message");\r
1524                 var msg = new Message(123, "abc", 0.123);\r
1525                 var bb = msg.encode();\r
1526                 Message = ProtoBuf.loadProto("message Message {}").build("Message");\r
1527                 test.doesNotThrow(function() {\r
1528                     Message.decode(bb);\r
1529                 });\r
1530                 test.strictEqual(bb.offset, bb.limit);\r
1531             } catch (e) {\r
1532                 fail(e);\r
1533             }\r
1534             test.done();\r
1535         },\r
1536 \r
1537         "tokenizerLine": function(test) {\r
1538             try {\r
1539                 var parser = new ProtoBuf.DotProto.Parser("package test;\n\nmessage Message {\n\trequired string invalid = 1;}ERROR\n"),\r
1540                     ast = null, err = null;\r
1541                 try {\r
1542                     ast = parser.parse();\r
1543                 } catch (caught) {\r
1544                     err = caught;\r
1545                 }\r
1546                 test.ok(err);\r
1547                 test.notOk(ast);\r
1548                 test.ok(err.message.indexOf("line 4:") >= 0);\r
1549             } catch (e) {\r
1550                 fail(e);\r
1551             }\r
1552             test.done();\r
1553         },\r
1554 \r
1555         "excludeFields": function(test) {\r
1556             try {\r
1557                 var builder = ProtoBuf.loadProto("message A { required int32 i = 1; } message B { required A A = 1; }");\r
1558                 builder.build();\r
1559             } catch (e) {\r
1560                 fail(e);\r
1561             }\r
1562             test.done();\r
1563         },\r
1564 \r
1565         "proto2jsExtend": function(test) {\r
1566             try {\r
1567                 var builder = ProtoBuf.loadJsonFile(__dirname+"/proto2js/Bar.json");\r
1568                 builder.build();\r
1569             } catch (e) {\r
1570                 fail(e);\r
1571             }\r
1572             test.done();\r
1573         },\r
1574 \r
1575         "emptyMessage": function(test) {\r
1576             try {\r
1577                 var builder = ProtoBuf.loadProto("message EmptyMessage {}"),\r
1578                     EmptyMessage = builder.build("EmptyMessage");\r
1579 \r
1580                 var msg = new EmptyMessage(),\r
1581                     ab = msg.toArrayBuffer();\r
1582                 test.strictEqual(ab.byteLength, 0);\r
1583             } catch (e) {\r
1584                 fail(e);\r
1585             }\r
1586             test.done();\r
1587         },\r
1588 \r
1589         "toRaw": function(test) {\r
1590             try {\r
1591                 var builder = ProtoBuf.loadProto("message MyMessage { required int32 a = 1; required int32 b = 2; required bytes c = 3; }"),\r
1592                     MyMessage = builder.build("MyMessage");\r
1593                 var raw = { a: 1, b: 2, c: "YWJj" },\r
1594                     myMessage = new MyMessage(raw);\r
1595                 test.deepEqual(myMessage.c.toBase64(), raw.c);\r
1596                 test.deepEqual(myMessage.toRaw(true), raw);\r
1597             } catch (e) {\r
1598                 fail(e);\r
1599             }\r
1600             test.done();\r
1601         },\r
1602 \r
1603         "singleQuotedString": function(test) {\r
1604             try{\r
1605                 var builder = ProtoBuf.loadProtoFile(__dirname+"/string_single_quote.proto");\r
1606                 var TestSingleQuoteString = builder.build("TestSingleQuoteString");\r
1607                 test.ok(typeof TestSingleQuoteString == 'function');\r
1608             } catch (e) {\r
1609                 fail(e);\r
1610             }\r
1611             test.done();\r
1612         },\r
1613 \r
1614         "importDuplicateSingleQuote": function(test) {\r
1615             try {\r
1616                 var builder = ProtoBuf.loadProtoFile(__dirname+"/import_a_single_quote.proto");\r
1617                 test.doesNotThrow(function() {\r
1618                     ProtoBuf.loadProtoFile(__dirname+"/import_b.proto", builder);\r
1619                 });\r
1620                 var root = builder.build();\r
1621                 test.ok(root.A);\r
1622                 test.ok(root.B);\r
1623                 test.ok(root.Common);\r
1624             } catch (e) {\r
1625                 fail(e);\r
1626             }\r
1627             test.done();\r
1628         },\r
1629 \r
1630         "importStringSuccessively": function(test) {\r
1631             try {\r
1632                 var proto1 = "message A { required string a = 1; };";\r
1633                 var proto2 = "import \"proto1.proto\"; message B { required A a = 1; };";\r
1634                 var builder = ProtoBuf.loadProto(proto1, "proto1.proto");\r
1635                 ProtoBuf.loadProto(proto2, builder, "proto2.proto");\r
1636                 var root = builder.build();\r
1637                 test.ok(root.A);\r
1638                 test.ok(root.B);\r
1639             } catch (e) {\r
1640                 fail(e);\r
1641             }\r
1642             test.done();\r
1643         },\r
1644 \r
1645         "multilineString": function(test) {\r
1646             try {\r
1647                 var proto = "message TestMessage { required string test = 1 [default = \"1\"   \"2\"\n\"3\"];}";\r
1648                 var builder = ProtoBuf.loadProto(proto, "multilineString.proto");\r
1649                 var TestMessage = builder.build("TestMessage"),\r
1650                     testMessage = new TestMessage();\r
1651                 test.strictEqual(testMessage.test, "123");\r
1652                 test.done();\r
1653             } catch (e) {\r
1654                 fail(e);\r
1655             }\r
1656             test.done();\r
1657         },\r
1658 \r
1659         "packable": function(test) {\r
1660             try {\r
1661                 var proto = 'message Inner { required int32 id=2; }\nmessage Outer { repeated Inner inner = 1 [packed=true]; }';\r
1662                 var builder = ProtoBuf.loadProto(proto);\r
1663                 var root = builder.build();\r
1664                 var inner = new root.Inner(1),\r
1665                     outer = new root.Outer(inner);\r
1666                 var bb = outer.encode().compact();\r
1667                 test.strictEqual(bb.toDebug(), "<0A 02 10 01>");\r
1668                 // 0A: wt 2, id 1\r
1669                 // 02: len 2\r
1670                 // 10: wt 0, id 2\r
1671                 // 01: 1\r
1672                 var outer2 = root.Outer.decode(bb);\r
1673                 test.strictEqual(outer2.inner.id, 1);\r
1674             } catch (e) {\r
1675                 fail(e);\r
1676             }\r
1677             test.done();\r
1678         },\r
1679 \r
1680         "$type": function(test) {\r
1681             var builder = ProtoBuf.loadProto("message Test {}");\r
1682             var Test = builder.build("Test"),\r
1683                 TTest = builder.lookup("Test");\r
1684             test.strictEqual(new Test().$type, TTest);\r
1685             test.done();\r
1686         },\r
1687 \r
1688         "descriptor": function(test) {\r
1689             try {\r
1690                 var proto = 'import "./google/protobuf/descriptor.proto";';\r
1691                 var builder = ProtoBuf.loadProto(proto, "tests/proto.proto");\r
1692                 var root = builder.build("google.protobuf");\r
1693                 test.ok(root.FileDescriptorSet);\r
1694             } catch (e) {\r
1695                 fail(e);\r
1696             }\r
1697             test.done();\r
1698         },\r
1699 \r
1700         "mismatchedNesting": function(test) {\r
1701             try {\r
1702                 var proto = "message Child { optional uint32 foo = 1; } message FakeChild { optional uint32 foo = 1; } message Parent { optional Child child = 1; }";\r
1703                 var builder = ProtoBuf.loadProto(proto, "tests/mismatchedNesting.proto");\r
1704                 var root = builder.build();\r
1705                 var foo = new root.Parent({ child: new root.FakeChild({ foo: 1 })});\r
1706             } catch (e) {\r
1707                 fail(e);\r
1708             }\r
1709             test.done();\r
1710         },\r
1711 \r
1712         /* "mismatchedType": function(test) {\r
1713             try {\r
1714                 var proto  = "message Test1 { optional string foo = 1; }";\r
1715                     proto += "message Test2 { optional int32 foo = 1; }";\r
1716                 var builder = ProtoBuf.loadProto(proto, "tests/mistmatchedType.proto");\r
1717                 var root = builder.build();\r
1718                 var test1 = new root.Test1({ foo: 'bar' });\r
1719                 var test2 = root.Test2.decode(test1.encode());\r
1720             } catch (e) {\r
1721                 fail(e);\r
1722             }\r
1723             test.done();\r
1724         }, */\r
1725 \r
1726         "builderOptions": function(test) {\r
1727             try {\r
1728                 var proto = "message Foo { optional uint32 foo_bar = 1; }";\r
1729                 var builder = ProtoBuf.newBuilder({\r
1730                     convertFieldsToCamelCase: true\r
1731                 });\r
1732                 ProtoBuf.loadProto(proto, builder, "tests/builderOptions.proto");\r
1733                 var Foo = builder.build("Foo");\r
1734                 test.strictEqual(ProtoBuf.convertFieldsToCamelCase, false);\r
1735                 test.strictEqual(builder.options.convertFieldsToCamelCase, true);\r
1736                 var foo = new Foo();\r
1737                 test.ok(typeof foo.fooBar !== 'undefined');\r
1738                 test.ok(typeof foo.foo_bar === 'undefined');\r
1739                 test.done();\r
1740             } catch (e) {\r
1741                 fail(e);\r
1742             }\r
1743             test.done();\r
1744         },\r
1745 \r
1746         "proto3": function(test) {\r
1747             try {\r
1748                 var builder = ProtoBuf.loadProtoFile(__dirname+"/proto3.proto");\r
1749                 test.doesNotThrow(function() {\r
1750                     ProtoBuf.loadProtoFile(__dirname+"/proto3.proto", builder);\r
1751                 });\r
1752                 var root = builder.build();\r
1753                 test.ok(root.test.Foo.$type.syntax === 'proto3');\r
1754             } catch (e) {\r
1755                 fail(e);\r
1756             }\r
1757             test.done();\r
1758         },\r
1759 \r
1760         // FIXME: This test relied on some bloated builder functionality that has been removed.\r
1761         // Is it even mandatory to strictly disallow proto2/3 mixing, even if that would be illegal in the official\r
1762         // implementation?\r
1763         /* "proto3DisallowedFeatures": function(test) {\r
1764             try {\r
1765                 // Required field\r
1766                 var proto = "syntax = \"proto3\"; message Foo { required int32 field = 1; }";\r
1767                 var builder = ProtoBuf.newBuilder();\r
1768                 ProtoBuf.loadProto(proto, builder, "tests/proto3DisallowedFeatures.proto");\r
1769                 test.ok(false);  // ^ should throw\r
1770             } catch (e) {\r
1771                 test.ok(/^Not a valid definition/.test(e.message));\r
1772             }\r
1773 \r
1774             try {\r
1775                 // Field with default value\r
1776                 var proto = "syntax = \"proto3\"; message Foo { int32 field = 1 [default=42]; }";\r
1777                 var builder = ProtoBuf.newBuilder();\r
1778                 ProtoBuf.loadProto(proto, builder, "tests/proto3DisallowedFeatures.proto");\r
1779                 test.ok(false);  // ^ should throw\r
1780             } catch (e) {\r
1781                 test.ok(/^Not a valid definition/.test(e.message));\r
1782             }\r
1783 \r
1784             try {\r
1785                 // Message with extension range\r
1786                 var proto = "syntax = \"proto3\"; message Foo { extensions 100 to max; } ";\r
1787                 var builder = ProtoBuf.newBuilder();\r
1788                 ProtoBuf.loadProto(proto, builder, "tests/proto3DisallowedFeatures.proto");\r
1789                 test.ok(false);  // ^ should throw\r
1790             } catch (e) {\r
1791                 test.ok(/^Not a valid definition/.test(e.message));\r
1792             }\r
1793 \r
1794             try {\r
1795                 // Message with extension\r
1796                 var proto = "syntax = \"proto3\"; message Foo { extensions 100 to max; } " +\r
1797                             "message Bar { extend Foo { optional Bar bar = 100; } }";\r
1798                 var builder = ProtoBuf.newBuilder();\r
1799                 ProtoBuf.loadProto(proto, builder, "tests/proto3DisallowedFeatures.proto");\r
1800                 test.ok(false);  // ^ should throw\r
1801             } catch (e) {\r
1802                 test.ok(/^Not a valid definition/.test(e.message));\r
1803             }\r
1804 \r
1805             try {\r
1806                 // Enum with non-zero first entry.\r
1807                 var proto = "syntax = \"proto3\"; enum E { A = 1; B = 2; }";\r
1808                 var builder = ProtoBuf.newBuilder();\r
1809                 ProtoBuf.loadProto(proto, builder, "tests/proto3DisallowedFeatures.proto");\r
1810                 test.ok(false);  // ^ should throw\r
1811             } catch (e) {\r
1812                 test.ok(/^Not a valid definition/.test(e.message));\r
1813             }\r
1814 \r
1815             try {\r
1816                 // Proto3 message referring to proto2 enum.\r
1817                 var proto2 = "syntax = \"proto2\"; enum E { A = 1; B = 2; }";\r
1818                 var proto3 = "syntax = \"proto3\"; message Test { E enum_field = 1; }";\r
1819                 var builder = ProtoBuf.newBuilder();\r
1820                 ProtoBuf.loadProto(proto2, builder, "tests/proto3DisallowedFeatures1.proto");\r
1821                 ProtoBuf.loadProto(proto3, builder, "tests/proto3DisallowedFeatures3.proto");\r
1822                 test.ok(false);  // ^ should throw\r
1823             } catch (e) {\r
1824                 test.ok(/^Proto3 message refers to proto2 enum/.test(e.message));\r
1825             }\r
1826 \r
1827             test.done();\r
1828         }, */\r
1829 \r
1830         "proto3FieldPresence": function(test) {\r
1831             var proto =\r
1832                 "syntax = \"proto3\";\n" +\r
1833                 "message Test {\n" +\r
1834                 "  int32 field_int32 = 1;\n" +\r
1835                 "  int64 field_int64 = 2;\n" +\r
1836                 "  string field_str = 3;\n" +\r
1837                 "  bytes field_bytes = 4;\n" +\r
1838                 "  Test field_msg = 5;\n" +\r
1839                 "  Enum field_enum = 6;\n" +\r
1840                 "  repeated int32 rpt_int32 = 11;\n" +\r
1841                 "  repeated int64 rpt_int64 = 12;\n" +\r
1842                 "  repeated string rpt_str = 13;\n" +\r
1843                 "  repeated bytes rpt_bytes = 14;\n" +\r
1844                 "  repeated Test rpt_msg = 15;\n" +\r
1845                 "  repeated Enum rpt_enum = 16;\n" +\r
1846                 "  oneof oneof_type { bool oneof_bool = 17; };\n" +\r
1847                 "}\n" +\r
1848                 "enum Enum { Default = 0; A = 1; B = 2; }\n";\r
1849             var builder = ProtoBuf.newBuilder();\r
1850             ProtoBuf.loadProto(proto, builder, "test/proto3FieldPresence.proto");\r
1851             var Test = builder.build('Test'),\r
1852                 Enum = builder.build('Enum');\r
1853 \r
1854             var testMsg = new Test();\r
1855             test.strictEqual(testMsg.field_int32, 0);\r
1856             test.strictEqual(testMsg.field_int64.low, 0);\r
1857             test.strictEqual(testMsg.field_int64.high, 0);\r
1858             test.strictEqual(testMsg.field_str, "");\r
1859             test.strictEqual(testMsg.field_msg, null);\r
1860             test.ok(testMsg.field_bytes instanceof ByteBuffer);\r
1861             test.strictEqual(testMsg.field_bytes.remaining(), 0);\r
1862             test.strictEqual(testMsg.rpt_int32.length, 0);\r
1863             test.strictEqual(testMsg.oneof_type, null);\r
1864             test.strictEqual(testMsg.oneof_bool, false);\r
1865 \r
1866             // No fields should go on the wire, even though they're set\r
1867             var encoded = testMsg.encode();\r
1868             test.strictEqual(encoded.remaining(), 0);\r
1869             testMsg.field_int32 = 42;\r
1870             encoded = testMsg.encode();\r
1871             test.strictEqual(encoded.remaining(), 2);\r
1872             testMsg.field_int32 = 0;\r
1873             encoded = testMsg.encode();\r
1874             test.strictEqual(encoded.remaining(), 0);\r
1875 \r
1876             // Enum fields should be able to carry arbitrary values.\r
1877             testMsg.field_enum = 42;\r
1878             test.strictEqual(testMsg.field_enum, 42);\r
1879             encoded = testMsg.encode();\r
1880             testMsg = Test.decode(encoded);\r
1881             test.strictEqual(testMsg.field_enum, 42);\r
1882 \r
1883             // Explicitly set fields that are part of an oneof should\r
1884             // be encoded even if set to their default value\r
1885             testMsg = new Test();\r
1886             testMsg.set("oneof_bool", false);\r
1887             test.strictEqual(testMsg.oneof_type, "oneof_bool");\r
1888             encoded = testMsg.encode().compact();\r
1889             test.strictEqual(encoded.toString("debug"), "<88 01 00>"); // 17|varint (0term) + varint 0\r
1890             var decoded = Test.decode(encoded);\r
1891             test.strictEqual(decoded.oneof_type, "oneof_bool");\r
1892             test.strictEqual(decoded.oneof_bool, false);\r
1893 \r
1894             test.done();\r
1895         },\r
1896 \r
1897         "mapContainer": function(test) {\r
1898             var proto =\r
1899                 "message Test {\n" +\r
1900                 "  map<string, int32> map_string_int32 = 1;\n" +\r
1901                 "  map<string, int64> map_string_int64 = 2;\n" +\r
1902                 "  map<string, string> map_string_string = 3;\n" +\r
1903                 "  map<string, Test> map_string_msg = 4;\n" +\r
1904                 "  map<string, Enum> map_string_enum = 5;\n" +\r
1905                 "  map<int32, string> map_int32_string = 6;\n" +\r
1906                 "  map<int64, string> map_int64_string = 7;\n" +\r
1907                 "  map<bool, string> map_bool_string = 9;\n" +\r
1908                 "}\n" +\r
1909                 "enum Enum { Default = 0; A = 1; B = 2; }\n";\r
1910             var builder = ProtoBuf.newBuilder();\r
1911             ProtoBuf.loadProto(proto, builder, "test/mapContainer.proto");\r
1912 \r
1913             var map_string_int32 =\r
1914                 new ProtoBuf.Map(builder.lookup("Test.map_string_int32"));\r
1915             test.strictEqual(map_string_int32.size, 0);\r
1916             test.strictEqual(map_string_int32.has("asdf"), false);\r
1917             test.strictEqual(map_string_int32.get("asdf"), undefined);\r
1918             map_string_int32.set("asdf", 42);\r
1919             test.strictEqual(map_string_int32.has("asdf"), true);\r
1920             test.strictEqual(map_string_int32.get("asdf"), 42);\r
1921 \r
1922             var it = map_string_int32.keys();\r
1923             var itVal = it.next();\r
1924             test.strictEqual(itVal.done, false);\r
1925             test.strictEqual(itVal.value, "asdf");\r
1926             itVal = it.next();\r
1927             test.strictEqual(itVal.done, true);\r
1928 \r
1929             it = map_string_int32.values();\r
1930             itVal = it.next();\r
1931             test.strictEqual(itVal.done, false);\r
1932             test.strictEqual(itVal.value, 42);\r
1933             itVal = it.next();\r
1934             test.strictEqual(itVal.done, true);\r
1935 \r
1936             it = map_string_int32.entries();\r
1937             itVal = it.next();\r
1938             test.strictEqual(itVal.done, false);\r
1939             test.deepEqual(itVal.value, ["asdf", 42]);\r
1940             itVal = it.next();\r
1941             test.strictEqual(itVal.done, true);\r
1942 \r
1943             map_string_int32.set("jkl;", 84);\r
1944             test.strictEqual(map_string_int32.has("jkl;"), true);\r
1945             test.strictEqual(map_string_int32.has("asdf"), true);\r
1946             test.strictEqual(map_string_int32.size, 2);\r
1947             map_string_int32.delete("jkl;");\r
1948             test.strictEqual(map_string_int32.has("jkl;"), false);\r
1949             test.strictEqual(map_string_int32.get("jkl;"), undefined);\r
1950             test.strictEqual(map_string_int32.size, 1);\r
1951 \r
1952             map_string_int32.clear();\r
1953             test.strictEqual(map_string_int32.size, 0);\r
1954 \r
1955             try {\r
1956                 map_string_int32.set("asdf", 42.1);\r
1957                 test.ok(false); // ^ should throw\r
1958             } catch(e) {\r
1959                 test.ok(e.message.match(/not an integer/));\r
1960             }\r
1961 \r
1962             try {\r
1963                 map_string_int32.set(42, 42);\r
1964                 test.ok(false); // ^ should throw\r
1965             } catch(e) {\r
1966                 test.ok(e.message.match(/not a string/));\r
1967             }\r
1968 \r
1969             // Test various key types to ensure that value->string->value\r
1970             // conversion works.\r
1971             var map_int32_string =\r
1972                 new ProtoBuf.Map(builder.lookup("Test.map_int32_string"));\r
1973             test.strictEqual(map_int32_string.size, 0);\r
1974             map_int32_string.set(12345678, "asdf");\r
1975             test.strictEqual(map_int32_string.size, 1);\r
1976             test.strictEqual(map_int32_string.has(12345678), true);\r
1977             test.strictEqual(map_int32_string.get(12345678), "asdf");\r
1978 \r
1979             var map_int64_string =\r
1980                 new ProtoBuf.Map(builder.lookup("Test.map_int64_string"));\r
1981             test.strictEqual(map_int64_string.size, 0);\r
1982             map_int64_string.set("9223372036854775807", "asdf");\r
1983             test.strictEqual(map_int64_string.size, 1);\r
1984             test.strictEqual(map_int64_string.has("9223372036854775807"), true);\r
1985             test.strictEqual(map_int64_string.get("9223372036854775807"), "asdf");\r
1986 \r
1987             // Ensure that initialization from a raw object works.\r
1988             var map_int32_string =\r
1989                 new ProtoBuf.Map(builder.lookup("Test.map_int32_string"),\r
1990                                  { 42: "asdf" });\r
1991             test.strictEqual(map_int32_string.size, 1);\r
1992             test.strictEqual(map_int32_string.keys().next().value, 42);\r
1993 \r
1994             var map_int64_string =\r
1995                 new ProtoBuf.Map(builder.lookup("Test.map_int64_string"),\r
1996                                  { "9223372036854775807": "asdf" });\r
1997             test.strictEqual(map_int64_string.size, 1);\r
1998             var i64 = map_int64_string.keys().next().value;\r
1999             test.ok(i64 instanceof ProtoBuf.Long);\r
2000             test.strictEqual(i64.toString(), "9223372036854775807");\r
2001 \r
2002             test.done();\r
2003         },\r
2004 \r
2005         "mapField": function(test) {\r
2006             var proto =\r
2007                 "message Test {\n" +\r
2008                 "  map<string, int32> map_string_int32 = 1;\n" +\r
2009                 "  map<string, int64> map_string_int64 = 2;\n" +\r
2010                 "  map<string, string> map_string_string = 3;\n" +\r
2011                 "  map<string, Test> map_string_msg = 4;\n" +\r
2012                 "  map<string, Enum> map_string_enum = 5;\n" +\r
2013                 "  map<int32, string> map_int32_string = 6;\n" +\r
2014                 "  map<int64, string> map_int64_string = 7;\n" +\r
2015                 "  map<bool, string> map_bool_string = 9;\n" +\r
2016                 "}\n" +\r
2017                 "enum Enum { Default = 0; A = 1; B = 2; }\n";\r
2018             var builder = ProtoBuf.newBuilder();\r
2019             ProtoBuf.loadProto(proto, builder, "test/mapField.proto");\r
2020             var Test = builder.build('Test'),\r
2021                 Enum = builder.build('Enum');\r
2022 \r
2023             var testMsg = new Test();\r
2024             test.strictEqual(testMsg.map_string_int32.size, 0);\r
2025             test.strictEqual(testMsg.map_string_int64.size, 0);\r
2026             test.strictEqual(testMsg.map_string_string.size, 0);\r
2027             test.strictEqual(testMsg.map_string_msg.size, 0);\r
2028             test.strictEqual(testMsg.map_string_enum.size, 0);\r
2029             test.strictEqual(testMsg.map_int32_string.size, 0);\r
2030             test.strictEqual(testMsg.map_int64_string.size, 0);\r
2031             test.strictEqual(testMsg.map_bool_string.size, 0);\r
2032 \r
2033             testMsg.$set('map_string_int32', { 'asdf': 42 });\r
2034 \r
2035             try {\r
2036                 testMsg.$set('map_string_int32', { 'asdf': 42.1 });\r
2037                 test.ok(false); // ^ should throw\r
2038             } catch (e) {\r
2039                 test.ok(e.message.match(/Illegal/));\r
2040             }\r
2041 \r
2042             test.done();\r
2043         },\r
2044 \r
2045         "mapEncodeDecode": function(test) {\r
2046             var proto =\r
2047                 "message Test {\n" +\r
2048                 "  map<string, int32> map_string_int32 = 1;\n" +\r
2049                 "  map<string, int64> map_string_int64 = 2;\n" +\r
2050                 "  map<string, string> map_string_string = 3;\n" +\r
2051                 "  map<string, Test> map_string_msg = 4;\n" +\r
2052                 "  map<string, Enum> map_string_enum = 5;\n" +\r
2053                 "  map<int32, string> map_int32_string = 6;\n" +\r
2054                 "  map<int64, string> map_int64_string = 7;\n" +\r
2055                 "  map<bool, string> map_bool_string = 9;\n" +\r
2056                 "}\n" +\r
2057                 "enum Enum { Default = 0; A = 1; B = 2; }\n";\r
2058             var builder = ProtoBuf.newBuilder();\r
2059             ProtoBuf.loadProto(proto, builder, "test/mapField.proto");\r
2060             var Test = builder.build('Test'),\r
2061                 Enum = builder.build('Enum');\r
2062 \r
2063             var testMsg = new Test();\r
2064             testMsg.map_string_int32.set("a", 1);\r
2065             testMsg.map_string_int32.set("b", 2);\r
2066             testMsg.map_string_int64.set("c", "12345678901234");\r
2067             testMsg.map_string_int64.set("d", "98765432109876");\r
2068             testMsg.map_string_string.set("e", "asdf");\r
2069             testMsg.map_string_string.set("f", "jkl;");\r
2070             testMsg.map_string_enum.set("g", Enum.A);\r
2071             testMsg.map_string_enum.set("h", Enum.B);\r
2072             testMsg.map_int32_string.set(9, "a");\r
2073             testMsg.map_int32_string.set(10, "b");\r
2074             testMsg.map_int64_string.set("12345678901234", "a");\r
2075             testMsg.map_int64_string.set("98765432109876", "b");\r
2076             testMsg.map_bool_string.set(false, "a");\r
2077             testMsg.map_bool_string.set(true, "b");\r
2078 \r
2079             var encoded = testMsg.encode();\r
2080             testMsg = Test.decode(encoded);\r
2081 \r
2082             test.strictEqual(testMsg.map_string_int32.get("a"), 1);\r
2083             test.strictEqual(testMsg.map_string_int32.get("b"), 2);\r
2084             test.strictEqual(testMsg.map_string_int64.get("c").toString(), "12345678901234");\r
2085             test.strictEqual(testMsg.map_string_int64.get("d").toString(), "98765432109876");\r
2086             test.strictEqual(testMsg.map_string_string.get("e"), "asdf");\r
2087             test.strictEqual(testMsg.map_string_string.get("f"), "jkl;");\r
2088             test.strictEqual(testMsg.map_string_enum.get("g"), Enum.A);\r
2089             test.strictEqual(testMsg.map_string_enum.get("h"), Enum.B);\r
2090             test.strictEqual(testMsg.map_int32_string.get(9), "a");\r
2091             test.strictEqual(testMsg.map_int32_string.get(10), "b");\r
2092             test.strictEqual(testMsg.map_int64_string.get("12345678901234"), "a");\r
2093             test.strictEqual(testMsg.map_int64_string.get("98765432109876"), "b");\r
2094             test.strictEqual(testMsg.map_bool_string.get(false), "a");\r
2095             test.strictEqual(testMsg.map_bool_string.get(true), "b");\r
2096 \r
2097             test.done();\r
2098         },\r
2099 \r
2100         "proto3Json": function(test) {\r
2101             var proto =\r
2102                 "syntax = \"proto3\";\n" +\r
2103                 "message Test {\n" +\r
2104                 "  int32 optional_int32 = 1;\n" +\r
2105                 "  int64 optional_int64 = 2;\n" +\r
2106                 "  string optional_string = 3;\n" +\r
2107                 "  bytes optional_bytes = 4;\n" +\r
2108                 "  bool optional_bool = 5;\n" +\r
2109                 "  Enum optional_enum = 6;\n" +\r
2110                 "  repeated int32 repeated_int32 = 11;\n" +\r
2111                 "  repeated int64 repeated_int64 = 12;\n" +\r
2112                 "  repeated string repeated_string = 13;\n" +\r
2113                 "  repeated bytes repeated_bytes = 14;\n" +\r
2114                 "  repeated bool repeated_bool = 15;\n" +\r
2115                 "  repeated Enum repeated_enum = 16;\n" +\r
2116                 "  map<string, int32> map_string_int32 = 20;\n" +\r
2117                 "  map<string, int64> map_string_int64 = 21;\n" +\r
2118                 "  map<string, string> map_string_string = 22;\n" +\r
2119                 "  map<string, Enum> map_string_enum = 24;\n" +\r
2120                 "  map<int32, string> map_int32_string = 25;\n" +\r
2121                 "  map<int64, string> map_int64_string = 26;\n" +\r
2122                 "  map<bool, string> map_bool_string = 27;\n" +\r
2123                 "}\n" +\r
2124                 "enum Enum { Default = 0; A = 1; B = 2; }\n";\r
2125             var builder = ProtoBuf.newBuilder();\r
2126             ProtoBuf.loadProto(proto, builder, "test/mapField.proto");\r
2127             var Test = builder.build('Test'),\r
2128                 Enum = builder.build('Enum');\r
2129 \r
2130             var testMsg = new Test();\r
2131             testMsg.optional_int32 = 1;\r
2132             testMsg.optional_int64 = "12345678901234";\r
2133             testMsg.optional_string = "hello";\r
2134             testMsg.optional_bytes = ProtoBuf.ByteBuffer.fromBinary("\x00\xFF\x80");\r
2135             testMsg.optional_bool = true;\r
2136             testMsg.optional_enum = Enum.A;\r
2137             testMsg.repeated_int32.push(1);\r
2138             testMsg.repeated_int64.push("12345678901234");\r
2139             testMsg.repeated_string.push("hello");\r
2140             testMsg.repeated_bytes.push(ProtoBuf.ByteBuffer.fromBinary("\x00\xFF\x80"));\r
2141             testMsg.repeated_bool.push(true);\r
2142             testMsg.repeated_enum.push(Enum.A);\r
2143             testMsg.map_string_int32.set("a", 1);\r
2144             testMsg.map_string_int32.set("b", 2);\r
2145             testMsg.map_string_int64.set("c", "12345678901234");\r
2146             testMsg.map_string_int64.set("d", "98765432109876");\r
2147             testMsg.map_string_string.set("e", "asdf");\r
2148             testMsg.map_string_string.set("f", "jkl;");\r
2149             testMsg.map_string_enum.set("g", Enum.A);\r
2150             testMsg.map_string_enum.set("h", Enum.B);\r
2151             testMsg.map_int32_string.set(9, "a");\r
2152             testMsg.map_int32_string.set(10, "b");\r
2153             testMsg.map_int64_string.set("12345678901234", "a");\r
2154             testMsg.map_int64_string.set("98765432109876", "b");\r
2155             testMsg.map_bool_string.set(false, "a");\r
2156             testMsg.map_bool_string.set(true, "b");\r
2157 \r
2158             var jsonObj = JSON.parse(testMsg.encodeJSON());\r
2159             test.deepEqual(jsonObj,\r
2160                 {\r
2161                     optional_int32: 1,\r
2162                     optional_int64: "12345678901234",\r
2163                     optional_string: "hello",\r
2164                     optional_bytes: "AP+A",  // base64\r
2165                     optional_bool: true,\r
2166                     optional_enum: "A",\r
2167                     repeated_int32: [1],\r
2168                     repeated_int64: ["12345678901234"],\r
2169                     repeated_string: ["hello"],\r
2170                     repeated_bytes: ["AP+A"],  // base64\r
2171                     repeated_bool: [true],\r
2172                     repeated_enum: ["A"],\r
2173                     map_string_int32: { "a": 1, "b": 2 },\r
2174                     map_string_int64: { "c": "12345678901234", "d": "98765432109876" },\r
2175                     map_string_string: { "e": "asdf", "f": "jkl;" },\r
2176                     map_string_enum: { "g": "A", "h": "B" },\r
2177                     map_int32_string: { "9": "a", "10": "b" },\r
2178                     map_int64_string: { "12345678901234": "a", "98765432109876": "b" },\r
2179                     map_bool_string: { "false": "a", "true": "b" },\r
2180                 });\r
2181 \r
2182             var testMsg2 = Test.decodeJSON(testMsg.encodeJSON());\r
2183             test.strictEqual(testMsg2.encodeJSON(), testMsg.encodeJSON());\r
2184 \r
2185             test.done();\r
2186         },\r
2187 \r
2188         // Node.js only\r
2189         "loaders": BROWSER ? {} : {\r
2190 \r
2191             "commonjs": function(test) {\r
2192                 var fs = require("fs")\r
2193                   , vm = require("vm")\r
2194                   , util = require('util');\r
2195 \r
2196                 var code = fs.readFileSync(__dirname+"/../dist/"+FILE);\r
2197                 var exports = {};\r
2198                 var sandbox = new Sandbox({\r
2199                     module: {\r
2200                         exports: exports,\r
2201                         id: "protobufjs"\r
2202                     },\r
2203                     exports: exports,\r
2204                     require: (function() {\r
2205                         function require(mod) {\r
2206                             if (mod == 'bytebuffer') require.called = true;\r
2207                             return ByteBuffer;\r
2208                         }\r
2209                         require.called = false;\r
2210                         return require;\r
2211                     })()\r
2212                 });\r
2213                 vm.runInNewContext(code, sandbox, "ProtoBuf.js in CommonJS-VM");\r
2214                 // console.log(util.inspect(sandbox));\r
2215                 test.ok(typeof sandbox.module.exports == 'object');\r
2216                 test.ok(typeof sandbox.require != 'undefined' && sandbox.require.called);\r
2217                 test.done();\r
2218             },\r
2219 \r
2220             "amd": function(test) {\r
2221                 var fs = require("fs")\r
2222                   , vm = require("vm")\r
2223                   , util = require('util');\r
2224 \r
2225                 var code = fs.readFileSync(__dirname+"/../dist/"+FILE);\r
2226                 var sandbox = new Sandbox({\r
2227                     define: (function() {\r
2228                         function define() {\r
2229                             define.called = true;\r
2230                         }\r
2231                         define.amd = true;\r
2232                         define.called = false;\r
2233                         return define;\r
2234                     })()\r
2235                 });\r
2236                 vm.runInNewContext(code, sandbox, "ProtoBuf.js in AMD-VM");\r
2237                 // console.log(util.inspect(sandbox));\r
2238                 test.ok(sandbox.define.called == true);\r
2239                 test.done();\r
2240             },\r
2241 \r
2242             "shim": function(test) {\r
2243                 var fs = require("fs")\r
2244                   , vm = require("vm")\r
2245                   , util = require('util');\r
2246 \r
2247                 var code = fs.readFileSync(__dirname+"/../dist/"+FILE);\r
2248                 var sandbox = new Sandbox({\r
2249                     dcodeIO: {\r
2250                         ByteBuffer: ByteBuffer\r
2251                     }\r
2252                 });\r
2253                 vm.runInNewContext(code, sandbox, "ProtoBuf.js in shim-VM");\r
2254                 // console.log(util.inspect(sandbox));\r
2255                 test.ok(typeof sandbox.dcodeIO != 'undefined' && typeof sandbox.dcodeIO.ProtoBuf != 'undefined');\r
2256                 test.done();\r
2257             }\r
2258         }\r
2259     };\r
2260 \r
2261     if (typeof module != 'undefined' && module.exports) {\r
2262         module.exports = suite;\r
2263     } else {\r
2264         global["suite"] = suite;\r
2265     }\r
2266 \r
2267 })(this);\r