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