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