Home | History | Annotate | Download | only in js
      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 goog.require('goog.crypt.base64');
     32 goog.require('goog.testing.asserts');
     33 
     34 // CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
     35 goog.require('proto.jspb.test.ForeignMessage');
     36 
     37 // CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test
     38 goog.require('proto.jspb.test.Proto3Enum');
     39 goog.require('proto.jspb.test.TestProto3');
     40 
     41 
     42 var BYTES = new Uint8Array([1, 2, 8, 9]);
     43 var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
     44 
     45 
     46 /**
     47  * Helper: compare a bytes field to an expected value
     48  * @param {Uint8Array|string} arr
     49  * @param {Uint8Array} expected
     50  * @return {boolean}
     51  */
     52 function bytesCompare(arr, expected) {
     53   if (goog.isString(arr)) {
     54     arr = goog.crypt.base64.decodeStringToUint8Array(arr);
     55   }
     56   if (arr.length != expected.length) {
     57     return false;
     58   }
     59   for (var i = 0; i < arr.length; i++) {
     60     if (arr[i] != expected[i]) {
     61       return false;
     62     }
     63   }
     64   return true;
     65 }
     66 
     67 
     68 describe('proto3Test', function() {
     69   /**
     70    * Test defaults for proto3 message fields.
     71    */
     72   it('testProto3FieldDefaults', function() {
     73     var msg = new proto.jspb.test.TestProto3();
     74 
     75     assertEquals(msg.getOptionalInt32(), 0);
     76     assertEquals(msg.getOptionalInt64(), 0);
     77     assertEquals(msg.getOptionalUint32(), 0);
     78     assertEquals(msg.getOptionalUint64(), 0);
     79     assertEquals(msg.getOptionalSint32(), 0);
     80     assertEquals(msg.getOptionalSint64(), 0);
     81     assertEquals(msg.getOptionalFixed32(), 0);
     82     assertEquals(msg.getOptionalFixed64(), 0);
     83     assertEquals(msg.getOptionalSfixed32(), 0);
     84     assertEquals(msg.getOptionalSfixed64(), 0);
     85     assertEquals(msg.getOptionalFloat(), 0);
     86     assertEquals(msg.getOptionalDouble(), 0);
     87     assertEquals(msg.getOptionalString(), '');
     88 
     89     // TODO(b/26173701): when we change bytes fields default getter to return
     90     // Uint8Array, we'll want to switch this assertion to match the u8 case.
     91     assertEquals(typeof msg.getOptionalBytes(), 'string');
     92     assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true);
     93     assertEquals(typeof msg.getOptionalBytes_asB64(), 'string');
     94     assertEquals(msg.getOptionalBytes().length, 0);
     95     assertEquals(msg.getOptionalBytes_asU8().length, 0);
     96     assertEquals(msg.getOptionalBytes_asB64(), '');
     97 
     98     assertEquals(msg.getOptionalForeignEnum(),
     99                  proto.jspb.test.Proto3Enum.PROTO3_FOO);
    100     assertEquals(msg.getOptionalForeignMessage(), undefined);
    101     assertEquals(msg.getOptionalForeignMessage(), undefined);
    102 
    103     assertEquals(msg.getRepeatedInt32List().length, 0);
    104     assertEquals(msg.getRepeatedInt64List().length, 0);
    105     assertEquals(msg.getRepeatedUint32List().length, 0);
    106     assertEquals(msg.getRepeatedUint64List().length, 0);
    107     assertEquals(msg.getRepeatedSint32List().length, 0);
    108     assertEquals(msg.getRepeatedSint64List().length, 0);
    109     assertEquals(msg.getRepeatedFixed32List().length, 0);
    110     assertEquals(msg.getRepeatedFixed64List().length, 0);
    111     assertEquals(msg.getRepeatedSfixed32List().length, 0);
    112     assertEquals(msg.getRepeatedSfixed64List().length, 0);
    113     assertEquals(msg.getRepeatedFloatList().length, 0);
    114     assertEquals(msg.getRepeatedDoubleList().length, 0);
    115     assertEquals(msg.getRepeatedStringList().length, 0);
    116     assertEquals(msg.getRepeatedBytesList().length, 0);
    117     assertEquals(msg.getRepeatedForeignEnumList().length, 0);
    118     assertEquals(msg.getRepeatedForeignMessageList().length, 0);
    119 
    120   });
    121 
    122 
    123   /**
    124    * Test that all fields can be set and read via a serialization roundtrip.
    125    */
    126   it('testProto3FieldSetGet', function() {
    127     var msg = new proto.jspb.test.TestProto3();
    128 
    129     msg.setOptionalInt32(-42);
    130     msg.setOptionalInt64(-0x7fffffff00000000);
    131     msg.setOptionalUint32(0x80000000);
    132     msg.setOptionalUint64(0xf000000000000000);
    133     msg.setOptionalSint32(-100);
    134     msg.setOptionalSint64(-0x8000000000000000);
    135     msg.setOptionalFixed32(1234);
    136     msg.setOptionalFixed64(0x1234567800000000);
    137     msg.setOptionalSfixed32(-1234);
    138     msg.setOptionalSfixed64(-0x1234567800000000);
    139     msg.setOptionalFloat(1.5);
    140     msg.setOptionalDouble(-1.5);
    141     msg.setOptionalBool(true);
    142     msg.setOptionalString('hello world');
    143     msg.setOptionalBytes(BYTES);
    144     var submsg = new proto.jspb.test.ForeignMessage();
    145     submsg.setC(16);
    146     msg.setOptionalForeignMessage(submsg);
    147     msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
    148 
    149     msg.setRepeatedInt32List([-42]);
    150     msg.setRepeatedInt64List([-0x7fffffff00000000]);
    151     msg.setRepeatedUint32List([0x80000000]);
    152     msg.setRepeatedUint64List([0xf000000000000000]);
    153     msg.setRepeatedSint32List([-100]);
    154     msg.setRepeatedSint64List([-0x8000000000000000]);
    155     msg.setRepeatedFixed32List([1234]);
    156     msg.setRepeatedFixed64List([0x1234567800000000]);
    157     msg.setRepeatedSfixed32List([-1234]);
    158     msg.setRepeatedSfixed64List([-0x1234567800000000]);
    159     msg.setRepeatedFloatList([1.5]);
    160     msg.setRepeatedDoubleList([-1.5]);
    161     msg.setRepeatedBoolList([true]);
    162     msg.setRepeatedStringList(['hello world']);
    163     msg.setRepeatedBytesList([BYTES]);
    164     submsg = new proto.jspb.test.ForeignMessage();
    165     submsg.setC(1000);
    166     msg.setRepeatedForeignMessageList([submsg]);
    167     msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]);
    168 
    169     msg.setOneofString('asdf');
    170 
    171     var serialized = msg.serializeBinary();
    172     msg = proto.jspb.test.TestProto3.deserializeBinary(serialized);
    173 
    174     assertEquals(msg.getOptionalInt32(), -42);
    175     assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
    176     assertEquals(msg.getOptionalUint32(), 0x80000000);
    177     assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
    178     assertEquals(msg.getOptionalSint32(), -100);
    179     assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
    180     assertEquals(msg.getOptionalFixed32(), 1234);
    181     assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
    182     assertEquals(msg.getOptionalSfixed32(), -1234);
    183     assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
    184     assertEquals(msg.getOptionalFloat(), 1.5);
    185     assertEquals(msg.getOptionalDouble(), -1.5);
    186     assertEquals(msg.getOptionalBool(), true);
    187     assertEquals(msg.getOptionalString(), 'hello world');
    188     assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES));
    189     assertEquals(msg.getOptionalForeignMessage().getC(), 16);
    190     assertEquals(msg.getOptionalForeignEnum(),
    191         proto.jspb.test.Proto3Enum.PROTO3_BAR);
    192 
    193     assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
    194     assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
    195     assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
    196     assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
    197     assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
    198     assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
    199     assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
    200     assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
    201     assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
    202     assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
    203     assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
    204     assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
    205     assertElementsEquals(msg.getRepeatedBoolList(), [true]);
    206     assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
    207     assertEquals(msg.getRepeatedBytesList().length, 1);
    208     assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
    209     assertEquals(msg.getRepeatedForeignMessageList().length, 1);
    210     assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
    211     assertElementsEquals(msg.getRepeatedForeignEnumList(),
    212         [proto.jspb.test.Proto3Enum.PROTO3_BAR]);
    213 
    214     assertEquals(msg.getOneofString(), 'asdf');
    215   });
    216 
    217 
    218   /**
    219    * Test that oneofs continue to have a notion of field presence.
    220    */
    221   it('testOneofs', function() {
    222     var msg = new proto.jspb.test.TestProto3();
    223 
    224     assertEquals(msg.getOneofUint32(), undefined);
    225     assertEquals(msg.getOneofForeignMessage(), undefined);
    226     assertEquals(msg.getOneofString(), undefined);
    227     assertEquals(msg.getOneofBytes(), undefined);
    228 
    229     msg.setOneofUint32(42);
    230     assertEquals(msg.getOneofUint32(), 42);
    231     assertEquals(msg.getOneofForeignMessage(), undefined);
    232     assertEquals(msg.getOneofString(), undefined);
    233     assertEquals(msg.getOneofBytes(), undefined);
    234 
    235 
    236     var submsg = new proto.jspb.test.ForeignMessage();
    237     msg.setOneofForeignMessage(submsg);
    238     assertEquals(msg.getOneofUint32(), undefined);
    239     assertEquals(msg.getOneofForeignMessage(), submsg);
    240     assertEquals(msg.getOneofString(), undefined);
    241     assertEquals(msg.getOneofBytes(), undefined);
    242 
    243     msg.setOneofString('hello');
    244     assertEquals(msg.getOneofUint32(), undefined);
    245     assertEquals(msg.getOneofForeignMessage(), undefined);
    246     assertEquals(msg.getOneofString(), 'hello');
    247     assertEquals(msg.getOneofBytes(), undefined);
    248 
    249     msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
    250     assertEquals(msg.getOneofUint32(), undefined);
    251     assertEquals(msg.getOneofForeignMessage(), undefined);
    252     assertEquals(msg.getOneofString(), undefined);
    253     assertEquals(msg.getOneofBytes_asB64(),
    254         goog.crypt.base64.encodeString('\u00FF\u00FF'));
    255   });
    256 
    257 
    258   /**
    259    * Test that "default"-valued primitive fields are not emitted on the wire.
    260    */
    261   it('testNoSerializeDefaults', function() {
    262     var msg = new proto.jspb.test.TestProto3();
    263 
    264     // Set each primitive to a non-default value, then back to its default, to
    265     // ensure that the serialization is actually checking the value and not just
    266     // whether it has ever been set.
    267     msg.setOptionalInt32(42);
    268     msg.setOptionalInt32(0);
    269     msg.setOptionalDouble(3.14);
    270     msg.setOptionalDouble(0.0);
    271     msg.setOptionalBool(true);
    272     msg.setOptionalBool(false);
    273     msg.setOptionalString('hello world');
    274     msg.setOptionalString('');
    275     msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
    276     msg.setOptionalBytes('');
    277     msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage());
    278     msg.setOptionalForeignMessage(null);
    279     msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
    280     msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO);
    281     msg.setOneofUint32(32);
    282     msg.setOneofUint32(null);
    283 
    284 
    285     var serialized = msg.serializeBinary();
    286     assertEquals(0, serialized.length);
    287   });
    288 
    289   /**
    290    * Test that base64 string and Uint8Array are interchangeable in bytes fields.
    291    */
    292   it('testBytesFieldsInterop', function() {
    293     var msg = new proto.jspb.test.TestProto3();
    294     // Set as a base64 string and check all the getters work.
    295     msg.setOptionalBytes(BYTES_B64);
    296     assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
    297     assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
    298     assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
    299 
    300     // Test binary serialize round trip doesn't break it.
    301     msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary());
    302     assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
    303     assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
    304     assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
    305 
    306     msg = new proto.jspb.test.TestProto3();
    307     // Set as a Uint8Array and check all the getters work.
    308     msg.setOptionalBytes(BYTES);
    309     assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
    310     assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
    311     assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
    312 
    313   });
    314 });
    315