blob: 01add5f1dd279d9b1a6c4fa7f29eccca4980770a [file] [log] [blame]
Feng Xiaoe841bac2015-12-11 17:09:20 -08001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Test suite is written using Jasmine -- see http://jasmine.github.io/
32
33goog.setTestOnly();
34
35goog.require('goog.json');
36goog.require('goog.testing.asserts');
Josh Habermane9f31ee2016-02-04 10:29:27 -080037
Josh Haberman77af5d02016-02-04 16:11:07 -080038// CommonJS-LoadFromFile: google-protobuf jspb
Feng Xiaoe841bac2015-12-11 17:09:20 -080039goog.require('jspb.Message');
Josh Habermane9f31ee2016-02-04 10:29:27 -080040
Josh Haberman77af5d02016-02-04 16:11:07 -080041// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta
Feng Xiaoe841bac2015-12-11 17:09:20 -080042goog.require('proto.jspb.exttest.beta.floatingStrField');
Josh Habermane9f31ee2016-02-04 10:29:27 -080043
Josh Haberman77af5d02016-02-04 16:11:07 -080044// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest
Feng Xiaoe841bac2015-12-11 17:09:20 -080045goog.require('proto.jspb.exttest.floatingMsgField');
Josh Habermane9f31ee2016-02-04 10:29:27 -080046
Josh Haberman77af5d02016-02-04 16:11:07 -080047// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest
Feng Xiaoe841bac2015-12-11 17:09:20 -080048goog.require('proto.jspb.exttest.floatingMsgFieldTwo');
Josh Habermane9f31ee2016-02-04 10:29:27 -080049
Josh Haberman77af5d02016-02-04 16:11:07 -080050// CommonJS-LoadFromFile: test_pb proto.jspb.test
Feng Xiaoe841bac2015-12-11 17:09:20 -080051goog.require('proto.jspb.test.CloneExtension');
52goog.require('proto.jspb.test.Complex');
53goog.require('proto.jspb.test.DefaultValues');
54goog.require('proto.jspb.test.Empty');
55goog.require('proto.jspb.test.EnumContainer');
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070056goog.require('proto.jspb.test.floatingMsgField');
57goog.require('proto.jspb.test.FloatingPointFields');
Feng Xiaoe841bac2015-12-11 17:09:20 -080058goog.require('proto.jspb.test.floatingStrField');
59goog.require('proto.jspb.test.HasExtensions');
60goog.require('proto.jspb.test.IndirectExtension');
61goog.require('proto.jspb.test.IsExtension');
62goog.require('proto.jspb.test.OptionalFields');
63goog.require('proto.jspb.test.OuterEnum');
Josh Haberman77af5d02016-02-04 16:11:07 -080064goog.require('proto.jspb.test.OuterMessage.Complex');
Feng Xiaoe841bac2015-12-11 17:09:20 -080065goog.require('proto.jspb.test.Simple1');
66goog.require('proto.jspb.test.Simple2');
67goog.require('proto.jspb.test.SpecialCases');
68goog.require('proto.jspb.test.TestClone');
Feng Xiaoe841bac2015-12-11 17:09:20 -080069goog.require('proto.jspb.test.TestGroup');
70goog.require('proto.jspb.test.TestGroup1');
71goog.require('proto.jspb.test.TestMessageWithOneof');
72goog.require('proto.jspb.test.TestReservedNames');
73goog.require('proto.jspb.test.TestReservedNamesExtension');
74
Josh Haberman77af5d02016-02-04 16:11:07 -080075// CommonJS-LoadFromFile: test2_pb proto.jspb.test
Josh Habermane9f31ee2016-02-04 10:29:27 -080076goog.require('proto.jspb.test.ExtensionMessage');
77goog.require('proto.jspb.test.TestExtensionsMessage');
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070078
Feng Xiaoe841bac2015-12-11 17:09:20 -080079
80
81
82describe('Message test suite', function() {
83 it('testEmptyProto', function() {
84 var empty1 = new proto.jspb.test.Empty([]);
85 var empty2 = new proto.jspb.test.Empty([]);
86 assertObjectEquals({}, empty1.toObject());
87 assertObjectEquals('Message should not be corrupted:', empty2, empty1);
88 });
89
90 it('testTopLevelEnum', function() {
91 var response = new proto.jspb.test.EnumContainer([]);
92 response.setOuterEnum(proto.jspb.test.OuterEnum.FOO);
93 assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum());
94 });
95
96 it('testByteStrings', function() {
97 var data = new proto.jspb.test.DefaultValues([]);
98 data.setBytesField('some_bytes');
99 assertEquals('some_bytes', data.getBytesField());
100 });
101
102 it('testComplexConversion', function() {
103 var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
104 var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
105 var foo = new proto.jspb.test.Complex(data1);
106 var bar = new proto.jspb.test.Complex(data2);
107 var result = foo.toObject();
108 assertObjectEquals({
109 aString: 'a',
110 anOutOfOrderBool: 1,
111 aNestedMessage: {
112 anInt: 11
113 },
114 aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
115 aRepeatedStringList: ['s1', 's2']
116 }, result);
117
118 // Now test with the jspb instances included.
119 result = foo.toObject(true /* opt_includeInstance */);
120 assertObjectEquals({
121 aString: 'a',
122 anOutOfOrderBool: 1,
123 aNestedMessage: {
124 anInt: 11,
125 $jspbMessageInstance: foo.getANestedMessage()
126 },
127 aRepeatedMessageList: [
128 {anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
129 {anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
130 ],
131 aRepeatedStringList: ['s1', 's2'],
132 $jspbMessageInstance: foo
133 }, result);
134
135 });
136
137 it('testMissingFields', function() {
138 var foo = new proto.jspb.test.Complex([
139 undefined, undefined, undefined, [],
140 undefined, undefined, undefined, undefined]);
141 var bar = new proto.jspb.test.Complex([
142 undefined, undefined, undefined, [],
143 undefined, undefined, undefined, undefined]);
144 var result = foo.toObject();
145 assertObjectEquals({
146 aString: undefined,
147 anOutOfOrderBool: undefined,
148 aNestedMessage: {
149 anInt: undefined
150 },
151 // Note: JsPb converts undefined repeated fields to empty arrays.
152 aRepeatedMessageList: [],
153 aRepeatedStringList: []
154 }, result);
155
156 });
157
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700158 it('testNestedComplexMessage', function() {
159 // Instantiate the message and set a unique field, just to ensure that we
160 // are not getting jspb.test.Complex instead.
161 var msg = new proto.jspb.test.OuterMessage.Complex();
162 msg.setInnerComplexField(5);
163 });
164
Feng Xiaoe841bac2015-12-11 17:09:20 -0800165 it('testSpecialCases', function() {
166 // Note: Some property names are reserved in JavaScript.
167 // These names are converted to the Js property named pb_<reserved_name>.
168 var special =
169 new proto.jspb.test.SpecialCases(['normal', 'default', 'function',
170 'var']);
171 var result = special.toObject();
172 assertObjectEquals({
173 normal: 'normal',
174 pb_default: 'default',
175 pb_function: 'function',
176 pb_var: 'var'
177 }, result);
178 });
179
180 it('testDefaultValues', function() {
181 var defaultString = "default<>\'\"abc";
182 var response = new proto.jspb.test.DefaultValues();
183
184 // Test toObject
185 var expectedObject = {
186 stringField: defaultString,
187 boolField: true,
188 intField: 11,
189 enumField: 13,
190 emptyField: '',
191 bytesField: 'bW9v'
192 };
193 assertObjectEquals(expectedObject, response.toObject());
194
195
196 // Test getters
197 response = new proto.jspb.test.DefaultValues();
198 assertEquals(defaultString, response.getStringField());
199 assertEquals(true, response.getBoolField());
200 assertEquals(11, response.getIntField());
201 assertEquals(13, response.getEnumField());
202 assertEquals('', response.getEmptyField());
203 assertEquals('bW9v', response.getBytesField());
204
205 function makeDefault(values) {
206 return new proto.jspb.test.DefaultValues(values);
207 }
208
209 // Test with undefined values,
210 // Use push to workaround IE treating undefined array elements as holes.
211 response = makeDefault([undefined, undefined, undefined, undefined]);
212 assertEquals(defaultString, response.getStringField());
213 assertEquals(true, response.getBoolField());
214 assertEquals(11, response.getIntField());
215 assertEquals(13, response.getEnumField());
216
217 // Test with null values, as would be returned by a JSON serializer.
218 response = makeDefault([null, null, null, null]);
219 assertEquals(defaultString, response.getStringField());
220 assertEquals(true, response.getBoolField());
221 assertEquals(11, response.getIntField());
222 assertEquals(13, response.getEnumField());
223
224 // Test with false-like values.
225 response = makeDefault(['', false, 0, 0]);
226 assertEquals('', response.getStringField());
227 assertEquals(false, response.getBoolField());
228 assertEquals(true, response.getIntField() == 0);
229 assertEquals(true, response.getEnumField() == 0);
230
231 // Test that clearing the values reverts them to the default state.
232 response = makeDefault(['blah', false, 111, 77]);
233 response.clearStringField(); response.clearBoolField();
234 response.clearIntField(); response.clearEnumField();
235 assertEquals(defaultString, response.getStringField());
236 assertEquals(true, response.getBoolField());
237 assertEquals(11, response.getIntField());
238 assertEquals(13, response.getEnumField());
239
240 // Test that setFoo(null) clears the values.
241 response = makeDefault(['blah', false, 111, 77]);
242 response.setStringField(null); response.setBoolField(null);
243 response.setIntField(undefined); response.setEnumField(undefined);
244 assertEquals(defaultString, response.getStringField());
245 assertEquals(true, response.getBoolField());
246 assertEquals(11, response.getIntField());
247 assertEquals(13, response.getEnumField());
248 });
249
250 it('testMessageRegistration', function() {
251 // goog.require(SomeResponse) will include its library, which will in
252 // turn add SomeResponse to the message registry.
253 assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse);
254 });
255
256 it('testClearFields', function() {
257 // We don't set 'proper' defaults, rather, bools, strings,
258 // etc, are cleared to undefined or null and take on the Javascript
259 // meaning for that value. Repeated fields are set to [] when cleared.
260 var data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
261 var foo = new proto.jspb.test.OptionalFields(data);
262 foo.clearAString();
263 foo.clearABool();
264 foo.clearANestedMessage();
265 foo.clearARepeatedMessageList();
266 foo.clearARepeatedStringList();
267 assertUndefined(foo.getAString());
268 assertUndefined(foo.getABool());
269 assertUndefined(foo.getANestedMessage());
270 assertObjectEquals([], foo.getARepeatedMessageList());
271 assertObjectEquals([], foo.getARepeatedStringList());
272 // NOTE: We want the missing fields in 'expected' to be undefined,
273 // but we actually get a sparse array instead. We could use something
274 // like [1,undefined,2] to avoid this, except that this is still
275 // sparse on IE. No comment...
276 var expected = [,,, [], []];
277 expected[0] = expected[1] = expected[2] = undefined;
278 assertObjectEquals(expected, foo.toArray());
279
280 // Test set(null). We could deprecated this in favor of clear(), but
281 // it's also convenient to have.
282 data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
283 foo = new proto.jspb.test.OptionalFields(data);
284 foo.setAString(null);
285 foo.setABool(null);
286 foo.setANestedMessage(null);
287 foo.setARepeatedMessageList(null);
288 foo.setARepeatedStringList(null);
289 assertNull(foo.getAString());
290 assertNull(foo.getABool());
291 assertNull(foo.getANestedMessage());
292 assertObjectEquals([], foo.getARepeatedMessageList());
293 assertObjectEquals([], foo.getARepeatedStringList());
294 assertObjectEquals([null, null, null, [], []], foo.toArray());
295
296 // Test set(undefined). Again, not something we really need, and not
297 // supported directly by our typing, but it should 'do the right thing'.
298 data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
299 foo = new proto.jspb.test.OptionalFields(data);
300 foo.setAString(undefined);
301 foo.setABool(undefined);
302 foo.setANestedMessage(undefined);
303 foo.setARepeatedMessageList(undefined);
304 foo.setARepeatedStringList(undefined);
305 assertUndefined(foo.getAString());
306 assertUndefined(foo.getABool());
307 assertUndefined(foo.getANestedMessage());
308 assertObjectEquals([], foo.getARepeatedMessageList());
309 assertObjectEquals([], foo.getARepeatedStringList());
310 expected = [,,, [], []];
311 expected[0] = expected[1] = expected[2] = undefined;
312 assertObjectEquals(expected, foo.toArray());
313 });
314
315 it('testDifferenceRawObject', function() {
316 var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]);
317 var p2 = new proto.jspb.test.HasExtensions(['hi', 'what',
318 {1000: 'unique'}]);
319 var diff = /** @type {proto.jspb.test.HasExtensions} */
320 (jspb.Message.difference(p1, p2));
321 assertUndefined(diff.getStr1());
322 assertEquals('what', diff.getStr2());
323 assertUndefined(diff.getStr3());
324 assertEquals('unique', diff.extensionObject_[1000]);
325 });
326
327 it('testEqualsSimple', function() {
328 var s1 = new proto.jspb.test.Simple1(['hi']);
329 assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi'])));
330 assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye'])));
331 var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]);
332 assertTrue(jspb.Message.equals(s1b,
333 new proto.jspb.test.Simple1(['hi', ['hello']])));
334 assertTrue(jspb.Message.equals(s1b,
335 new proto.jspb.test.Simple1(['hi', ['hello', undefined,
336 undefined, undefined]])));
337 assertFalse(jspb.Message.equals(s1b,
338 new proto.jspb.test.Simple1(['no', ['hello']])));
339 // Test with messages of different types
340 var s2 = new proto.jspb.test.Simple2(['hi']);
341 assertFalse(jspb.Message.equals(s1, s2));
342 });
343
344 it('testEquals_softComparison', function() {
345 var s1 = new proto.jspb.test.Simple1(['hi', [], null]);
346 assertTrue(jspb.Message.equals(s1,
347 new proto.jspb.test.Simple1(['hi', []])));
348
349 var s1b = new proto.jspb.test.Simple1(['hi', [], true]);
350 assertTrue(jspb.Message.equals(s1b,
351 new proto.jspb.test.Simple1(['hi', [], 1])));
352 });
353
354 it('testEqualsComplex', function() {
355 var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
356 var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1];
357 var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1];
358 var data4 = ['hi'];
359 var c1a = new proto.jspb.test.Complex(data1);
360 var c1b = new proto.jspb.test.Complex(data1);
361 var c2 = new proto.jspb.test.Complex(data2);
362 var c3 = new proto.jspb.test.Complex(data3);
363 var s1 = new proto.jspb.test.Simple1(data4);
364
365 assertTrue(jspb.Message.equals(c1a, c1b));
366 assertFalse(jspb.Message.equals(c1a, c2));
367 assertFalse(jspb.Message.equals(c2, c3));
368 assertFalse(jspb.Message.equals(c1a, s1));
369 });
370
371 it('testEqualsExtensionsConstructed', function() {
372 assertTrue(jspb.Message.equals(
373 new proto.jspb.test.HasExtensions([]),
374 new proto.jspb.test.HasExtensions([{}])
375 ));
376 assertTrue(jspb.Message.equals(
377 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
378 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
379 ));
380 assertFalse(jspb.Message.equals(
381 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
382 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])
383 ));
384 assertTrue(jspb.Message.equals(
385 new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
386 new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
387 ));
388 assertTrue(jspb.Message.equals(
389 new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
390 new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}])
391 ));
392 assertTrue(jspb.Message.equals(
393 new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]),
394 new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
395 ));
396 assertTrue(jspb.Message.equals(
397 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
398 new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}])
399 ));
400 assertTrue(jspb.Message.equals(
401 new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]),
402 new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
403 ));
404 });
405
406 it('testEqualsExtensionsUnconstructed', function() {
407 assertTrue(jspb.Message.compareFields([], [{}]));
408 assertTrue(jspb.Message.compareFields([,,, {}], []));
409 assertTrue(jspb.Message.compareFields([,,, {}], [,, {}]));
410 assertTrue(jspb.Message.compareFields(
411 ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
412 assertFalse(jspb.Message.compareFields(
413 ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}]));
414 assertTrue(jspb.Message.compareFields(
415 [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
416 assertTrue(jspb.Message.compareFields(
417 [{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}]));
418 assertTrue(jspb.Message.compareFields(
419 [,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
420 assertTrue(jspb.Message.compareFields(
421 ['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}]));
422 assertTrue(jspb.Message.compareFields(
423 ['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
424 });
425
426 it('testToMap', function() {
427 var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
428 var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
429 var soymap = jspb.Message.toMap([p1, p2],
430 proto.jspb.test.Simple1.prototype.getAString,
431 proto.jspb.test.Simple1.prototype.toObject);
432 assertEquals('k', soymap['k'].aString);
433 assertArrayEquals(['v'], soymap['k'].aRepeatedStringList);
434 var protomap = jspb.Message.toMap([p1, p2],
435 proto.jspb.test.Simple1.prototype.getAString);
436 assertEquals('k', protomap['k'].getAString());
437 assertArrayEquals(['v'], protomap['k'].getARepeatedStringList());
438 });
439
440 it('testClone', function() {
441 var original = new proto.jspb.test.TestClone();
442 original.setStr('v1');
443 var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
444 var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
445 var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
446 original.setSimple1(simple1);
447 original.setSimple2List([simple2, simple3]);
448 var extension = new proto.jspb.test.CloneExtension();
449 extension.setExt('e1');
450 original.setExtension(proto.jspb.test.IsExtension.extField, extension);
451 var clone = original.cloneMessage();
452 assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
453 [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]],,, { 100: [, 'e1'] }],
454 clone.toArray());
455 clone.setStr('v2');
456 var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]);
457 var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]);
458 var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]);
459 clone.setSimple1(simple4);
460 clone.setSimple2List([simple5, simple6]);
461 var newExtension = new proto.jspb.test.CloneExtension();
462 newExtension.setExt('e2');
463 clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension);
464 assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],,
465 [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]],,, { 100: [, 'e2'] }],
466 clone.toArray());
467 assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
468 [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]],,, { 100: [, 'e1'] }],
469 original.toArray());
470 });
471
472 it('testCopyInto', function() {
473 var original = new proto.jspb.test.TestClone();
474 original.setStr('v1');
475 var dest = new proto.jspb.test.TestClone();
476 dest.setStr('override');
477 var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
478 var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
479 var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
480 var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]);
481 var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]);
482 var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]);
483 original.setSimple1(simple1);
484 original.setSimple2List([simple2, simple3]);
485 dest.setSimple1(destSimple1);
486 dest.setSimple2List([destSimple2, destSimple3]);
487 var extension = new proto.jspb.test.CloneExtension();
488 extension.setExt('e1');
489 original.setExtension(proto.jspb.test.CloneExtension.extField, extension);
490
491 jspb.Message.copyInto(original, dest);
492 assertArrayEquals(original.toArray(), dest.toArray());
493 assertEquals('x1', dest.getSimple1().getAString());
494 assertEquals('e1',
495 dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt());
496 dest.getSimple1().setAString('new value');
497 assertNotEquals(dest.getSimple1().getAString(),
498 original.getSimple1().getAString());
499 dest.getExtension(proto.jspb.test.CloneExtension.extField).
500 setExt('new value');
501 assertNotEquals(
502 dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(),
503 original.getExtension(
504 proto.jspb.test.CloneExtension.extField).getExt());
505 });
506
507 it('testCopyInto_notSameType', function() {
508 var a = new proto.jspb.test.TestClone();
509 var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
510
511 var e = assertThrows(function() {
512 jspb.Message.copyInto(a, b);
513 });
514 assertContains('should have the same type', e.message);
515 });
516
517 it('testExtensions', function() {
518 var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
519 var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
520 var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
521 extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
522 extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
523 extension2);
524 extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
525 extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
526 ['a', 'b']);
527 var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
528 var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]);
529 extendable.setExtension(
530 proto.jspb.test.IndirectExtension.repeatedSimpleList,
531 [s1, s2]);
532 assertObjectEquals(extension1,
533 extendable.getExtension(proto.jspb.test.IsExtension.extField));
534 assertObjectEquals(extension2,
535 extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
536 assertObjectEquals('xyzzy',
537 extendable.getExtension(proto.jspb.test.IndirectExtension.str));
538 assertObjectEquals(['a', 'b'], extendable.getExtension(
539 proto.jspb.test.IndirectExtension.repeatedStrList));
540 assertObjectEquals([s1, s2], extendable.getExtension(
541 proto.jspb.test.IndirectExtension.repeatedSimpleList));
542 // Not supported yet, but it should work...
543 extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null);
544 assertNull(
545 extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
546 extendable.setExtension(proto.jspb.test.IndirectExtension.str, null);
547 assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str));
548
Josh Habermane9cf31e2015-12-21 15:18:17 -0800549
Feng Xiaoe841bac2015-12-11 17:09:20 -0800550 // Extension fields with jspb.ignore = true are ignored.
551 assertUndefined(proto.jspb.test.IndirectExtension['ignored']);
552 assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']);
553 });
554
555 it('testFloatingExtensions', function() {
556 // From an autogenerated container.
557 var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
558 var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
559 extendable.setExtension(proto.jspb.test.simple1, extension);
560 assertObjectEquals(extension,
561 extendable.getExtension(proto.jspb.test.simple1));
562
563 // From _lib mode.
564 extension = new proto.jspb.test.ExtensionMessage(['s1']);
565 extendable = new proto.jspb.test.TestExtensionsMessage([16]);
566 extendable.setExtension(proto.jspb.test.floatingMsgField, extension);
567 extendable.setExtension(proto.jspb.test.floatingStrField, 's2');
568 assertObjectEquals(extension,
569 extendable.getExtension(proto.jspb.test.floatingMsgField));
570 assertObjectEquals('s2',
571 extendable.getExtension(proto.jspb.test.floatingStrField));
572 assertNotUndefined(proto.jspb.exttest.floatingMsgField);
573 assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo);
574 assertNotUndefined(proto.jspb.exttest.beta.floatingStrField);
575 });
576
577 it('testToObject_extendedObject', function() {
578 var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
579 var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]);
580 var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
581 extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
582 extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
583 extension2);
584 extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
585 extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
586 ['a', 'b']);
587 var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]);
588 var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]);
589 extendable.setExtension(
590 proto.jspb.test.IndirectExtension.repeatedSimpleList,
591 [s1, s2]);
592 assertObjectEquals({
593 str1: 'v1', str2: 'v2', str3: 'v3',
594 extField: { ext1: 'ext1field' },
595 simple: {
596 aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true
597 },
598 str: 'xyzzy',
599 repeatedStrList: ['a', 'b'],
600 repeatedSimpleList: [
601 { aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
602 { aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
603 ]
604 }, extendable.toObject());
605
606 // Now, with instances included.
607 assertObjectEquals({
608 str1: 'v1', str2: 'v2', str3: 'v3',
609 extField: {
610 ext1: 'ext1field',
611 $jspbMessageInstance:
612 extendable.getExtension(proto.jspb.test.IsExtension.extField)
613 },
614 simple: {
615 aString: 'str',
616 aRepeatedStringList: ['s1', 's2'],
617 aBoolean: true,
618 $jspbMessageInstance:
619 extendable.getExtension(proto.jspb.test.IndirectExtension.simple)
620 },
621 str: 'xyzzy',
622 repeatedStrList: ['a', 'b'],
623 repeatedSimpleList: [{
624 aString: 'foo',
625 aRepeatedStringList: ['s1', 's2'],
626 aBoolean: true,
627 $jspbMessageInstance: s1
628 }, {
629 aString: 'bar',
630 aRepeatedStringList: ['t1', 't2'],
631 aBoolean: false,
632 $jspbMessageInstance: s2
633 }],
634 $jspbMessageInstance: extendable
635 }, extendable.toObject(true /* opt_includeInstance */));
636 });
637
638 it('testInitialization_emptyArray', function() {
639 var msg = new proto.jspb.test.HasExtensions([]);
640 if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
641 assertArrayEquals([], msg.toArray());
642 } else {
643 // Extension object is created past all regular fields.
644 assertArrayEquals([,,, {}], msg.toArray());
645 }
646 });
647
648 it('testInitialization_justExtensionObject', function() {
649 var msg = new proto.jspb.test.Empty([{1: 'hi'}]);
650 // The extensionObject is not moved from its original location.
651 assertArrayEquals([{1: 'hi'}], msg.toArray());
652 });
653
654 it('testInitialization_incompleteList', function() {
655 var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]);
656 // The extensionObject is not moved from its original location.
657 assertArrayEquals([1, {4: 'hi'}], msg.toArray());
658 });
659
660 it('testInitialization_forwardCompatible', function() {
661 var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]);
662 assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray());
663 });
664
665 it('testExtendedMessageEnsureObject', function() {
666 var data = new proto.jspb.test.HasExtensions(['str1',
667 {'a_key': 'an_object'}]);
668 assertEquals('an_object', data.extensionObject_['a_key']);
669 });
670
671 it('testToObject_hasExtensionField', function() {
672 var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
673 var obj = data.toObject();
674 assertEquals('str1', obj.str1);
675 assertEquals('ext1', obj.extField.ext1);
676 });
677
678 it('testGetExtension', function() {
679 var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
680 assertEquals('str1', data.getStr1());
681 var extension = data.getExtension(proto.jspb.test.IsExtension.extField);
682 assertNotNull(extension);
683 assertEquals('ext1', extension.getExt1());
684 });
685
686 it('testSetExtension', function() {
687 var data = new proto.jspb.test.HasExtensions();
688 var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']);
689 data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage);
690 var obj = data.toObject();
691 assertNotNull(
692 data.getExtension(proto.jspb.test.IsExtension.extField));
693 assertEquals('is_extension', obj.extField.ext1);
694 });
695
696 /**
697 * Note that group is long deprecated, we only support it because JsPb has
698 * a goal of being able to generate JS classes for all proto descriptors.
699 */
700 it('testGroups', function() {
701 var group = new proto.jspb.test.TestGroup();
702 var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup();
703 someGroup.setId('g1');
704 someGroup.setSomeBoolList([true, false]);
705 group.setRepeatedGroupList([someGroup]);
706 var groups = group.getRepeatedGroupList();
707 assertEquals('g1', groups[0].getId());
708 assertObjectEquals([true, false], groups[0].getSomeBoolList());
709 assertObjectEquals({id: 'g1', someBoolList: [true, false]},
710 groups[0].toObject());
711 assertObjectEquals({
712 repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
713 requiredGroup: {id: undefined},
714 optionalGroup: undefined,
715 requiredSimple: {aRepeatedStringList: [], aString: undefined},
716 optionalSimple: undefined,
717 id: undefined
718 }, group.toObject());
719 var group1 = new proto.jspb.test.TestGroup1();
720 group1.setGroup(someGroup);
721 assertEquals(someGroup, group1.getGroup());
722 });
723
724 it('testNonExtensionFieldsAfterExtensionRange', function() {
725 var data = [{'1': 'a_string'}];
726 var message = new proto.jspb.test.Complex(data);
727 assertArrayEquals([], message.getARepeatedStringList());
728 });
729
730 it('testReservedGetterNames', function() {
731 var message = new proto.jspb.test.TestReservedNames();
732 message.setExtension$(11);
733 message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12);
734 assertEquals(11, message.getExtension$());
735 assertEquals(12, message.getExtension(
736 proto.jspb.test.TestReservedNamesExtension.foo));
737 assertObjectEquals({extension: 11, foo: 12}, message.toObject());
738 });
739
740 it('testInitializeMessageWithUnsetOneof', function() {
741 var message = new proto.jspb.test.TestMessageWithOneof([]);
742 assertEquals(
743 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
744 PARTIAL_ONEOF_NOT_SET,
745 message.getPartialOneofCase());
746 assertEquals(
747 proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
748 RECURSIVE_ONEOF_NOT_SET,
749 message.getRecursiveOneofCase());
750 });
751
752 it('testInitializeMessageWithSingleValueSetInOneof', function() {
753 var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
754
755 assertEquals('x', message.getPone());
756 assertUndefined(message.getPthree());
757 assertEquals(
758 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
759 message.getPartialOneofCase());
760 });
761
762 it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
763 var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
764
765 assertUndefined('x', message.getPone());
766 assertEquals('y', message.getPthree());
767 assertEquals(
768 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
769 message.getPartialOneofCase());
770 });
771
772 it('testSettingOneofFieldClearsOthers', function() {
773 var message = new proto.jspb.test.TestMessageWithOneof;
774 assertUndefined(message.getPone());
775 assertUndefined(message.getPthree());
776
777 message.setPone('hi');
778 assertEquals('hi', message.getPone());
779 assertUndefined(message.getPthree());
780
781 message.setPthree('bye');
782 assertUndefined(message.getPone());
783 assertEquals('bye', message.getPthree());
784 });
785
786 it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() {
787 var other = new proto.jspb.test.TestMessageWithOneof;
788 var message = new proto.jspb.test.TestMessageWithOneof;
789 assertUndefined(message.getPone());
790 assertUndefined(message.getPthree());
791 assertUndefined(message.getRone());
792
793 message.setPone('hi');
794 message.setRone(other);
795 assertEquals('hi', message.getPone());
796 assertUndefined(message.getPthree());
797 assertEquals(other, message.getRone());
798
799 message.setPthree('bye');
800 assertUndefined(message.getPone());
801 assertEquals('bye', message.getPthree());
802 assertEquals(other, message.getRone());
803 });
804
805 it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
806 var message = new proto.jspb.test.TestMessageWithOneof;
807 assertEquals(
808 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
809 PARTIAL_ONEOF_NOT_SET,
810 message.getPartialOneofCase());
811
812 message.setPone('hi');
813 assertEquals(
814 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
815 message.getPartialOneofCase());
816
817 message.clearPone();
818 assertEquals(
819 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
820 PARTIAL_ONEOF_NOT_SET,
821 message.getPartialOneofCase());
822 });
823
824 it('testMessageWithDefaultOneofValues', function() {
825 var message = new proto.jspb.test.TestMessageWithOneof;
826 assertEquals(1234, message.getAone());
827 assertUndefined(message.getAtwo());
828 assertEquals(
829 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
830 .DEFAULT_ONEOF_A_NOT_SET,
831 message.getDefaultOneofACase());
832
833 message.setAone(567);
834 assertEquals(567, message.getAone());
835 assertUndefined(message.getAtwo());
836 assertEquals(
837 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
838 message.getDefaultOneofACase());
839
840 message.setAtwo(890);
841 assertEquals(1234, message.getAone());
842 assertEquals(890, message.getAtwo());
843 assertEquals(
844 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
845 message.getDefaultOneofACase());
846
847 message.clearAtwo();
848 assertEquals(1234, message.getAone());
849 assertUndefined(message.getAtwo());
850 assertEquals(
851 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
852 .DEFAULT_ONEOF_A_NOT_SET,
853 message.getDefaultOneofACase());
854 });
855
856 it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() {
857 var message = new proto.jspb.test.TestMessageWithOneof;
858 assertUndefined(message.getBone());
859 assertEquals(1234, message.getBtwo());
860 assertEquals(
861 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
862 .DEFAULT_ONEOF_B_NOT_SET,
863 message.getDefaultOneofBCase());
864
865 message.setBone(2);
866 assertEquals(2, message.getBone());
867 assertEquals(1234, message.getBtwo());
868 assertEquals(
869 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
870 message.getDefaultOneofBCase());
871
872 message.setBtwo(3);
873 assertUndefined(message.getBone());
874 assertEquals(3, message.getBtwo());
875 assertEquals(
876 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
877 message.getDefaultOneofBCase());
878
879 message.clearBtwo();
880 assertUndefined(message.getBone());
881 assertEquals(1234, message.getBtwo());
882 assertEquals(
883 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
884 .DEFAULT_ONEOF_B_NOT_SET,
885 message.getDefaultOneofBCase());
886 });
887
888 it('testInitializeMessageWithOneofDefaults', function() {
889 var message =
890 new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567));
891 assertEquals(567, message.getAone());
892 assertUndefined(message.getAtwo());
893 assertEquals(
894 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
895 message.getDefaultOneofACase());
896
897 message =
898 new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890));
899 assertEquals(1234, message.getAone());
900 assertEquals(890, message.getAtwo());
901 assertEquals(
902 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
903 message.getDefaultOneofACase());
904
905 message =
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700906 new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890));
Feng Xiaoe841bac2015-12-11 17:09:20 -0800907 assertEquals(1234, message.getAone());
908 assertEquals(890, message.getAtwo());
909 assertEquals(
910 proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
911 message.getDefaultOneofACase());
912 });
913
914 it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField',
915 function() {
916 var message;
917
918 message =
919 new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
920 assertEquals(567, message.getBone());
921 assertEquals(1234, message.getBtwo());
922 assertEquals(
923 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
924 message.getDefaultOneofBCase());
925
926 message =
927 new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
928 assertUndefined(message.getBone());
929 assertEquals(890, message.getBtwo());
930 assertEquals(
931 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
932 message.getDefaultOneofBCase());
933
934 message = new proto.jspb.test.TestMessageWithOneof(
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700935 new Array(11).concat(567, 890));
Feng Xiaoe841bac2015-12-11 17:09:20 -0800936 assertUndefined(message.getBone());
937 assertEquals(890, message.getBtwo());
938 assertEquals(
939 proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
940 message.getDefaultOneofBCase());
941 });
942
943 it('testOneofContainingAnotherMessage', function() {
944 var message = new proto.jspb.test.TestMessageWithOneof;
945 assertEquals(
946 proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
947 RECURSIVE_ONEOF_NOT_SET,
948 message.getRecursiveOneofCase());
949
950 var other = new proto.jspb.test.TestMessageWithOneof;
951 message.setRone(other);
952 assertEquals(other, message.getRone());
953 assertUndefined(message.getRtwo());
954 assertEquals(
955 proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE,
956 message.getRecursiveOneofCase());
957
958 message.setRtwo('hi');
959 assertUndefined(message.getRone());
960 assertEquals('hi', message.getRtwo());
961 assertEquals(
962 proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO,
963 message.getRecursiveOneofCase());
964 });
965
966 it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray',
967 function() {
968 var message = new proto.jspb.test.TestMessageWithOneof;
969 message.setPone('x');
970 assertEquals('x', message.getPone());
971 assertUndefined(message.getPthree());
972 assertEquals(
973 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
974 message.getPartialOneofCase());
975
976 var array = message.toArray();
977 assertEquals('x', array[2]);
978 assertUndefined(array[4]);
979 array[4] = 'y';
980
981 assertEquals(
982 proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
983 message.getPartialOneofCase());
984 assertUndefined(array[2]);
985 assertEquals('y', array[4]);
986 });
987
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700988 it('testFloatingPointFieldsSupportNan', function() {
989 var assertNan = function(x) {
990 assertTrue('Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.',
991 goog.isNumber(x) && isNaN(x));
992 };
993
994 var message = new proto.jspb.test.FloatingPointFields([
995 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN',
996 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
997 ]);
998 assertNan(message.getOptionalFloatField());
999 assertNan(message.getRequiredFloatField());
1000 assertNan(message.getRepeatedFloatFieldList()[0]);
1001 assertNan(message.getRepeatedFloatFieldList()[1]);
1002 assertNan(message.getDefaultFloatField());
1003 assertNan(message.getOptionalDoubleField());
1004 assertNan(message.getRequiredDoubleField());
1005 assertNan(message.getRepeatedDoubleFieldList()[0]);
1006 assertNan(message.getRepeatedDoubleFieldList()[1]);
1007 assertNan(message.getDefaultDoubleField());
1008 });
1009
Feng Xiaoe841bac2015-12-11 17:09:20 -08001010});