1// 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'); 37 38// CommonJS-LoadFromFile: google-protobuf jspb 39goog.require('jspb.Message'); 40 41// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta 42goog.require('proto.jspb.exttest.beta.floatingStrField'); 43 44// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest 45goog.require('proto.jspb.exttest.floatingMsgField'); 46 47// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest 48goog.require('proto.jspb.exttest.floatingMsgFieldTwo'); 49 50// CommonJS-LoadFromFile: test_pb proto.jspb.test 51goog.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'); 56goog.require('proto.jspb.test.floatingMsgField'); 57goog.require('proto.jspb.test.FloatingPointFields'); 58goog.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'); 64goog.require('proto.jspb.test.OuterMessage.Complex'); 65goog.require('proto.jspb.test.Simple1'); 66goog.require('proto.jspb.test.Simple2'); 67goog.require('proto.jspb.test.SpecialCases'); 68goog.require('proto.jspb.test.TestClone'); 69goog.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 75// CommonJS-LoadFromFile: test2_pb proto.jspb.test 76goog.require('proto.jspb.test.ExtensionMessage'); 77goog.require('proto.jspb.test.TestExtensionsMessage'); 78 79 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 158 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 165 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 549 550 // 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 = 906 new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890)); 907 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( 935 new Array(11).concat(567, 890)); 936 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 988 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 1010}); 1011