| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 | // Protocol Buffers - Google's data interchange format// Copyright 2008 Google Inc.  All rights reserved.// https://developers.google.com/protocol-buffers///// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.//     * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.goog.require('goog.testing.asserts');goog.require('goog.userAgent');// CommonJS-LoadFromFile: testbinary_pb proto.jspb.testgoog.require('proto.jspb.test.MapValueEnum');goog.require('proto.jspb.test.MapValueMessage');goog.require('proto.jspb.test.TestMapFields');// CommonJS-LoadFromFile: test_pb proto.jspb.testgoog.require('proto.jspb.test.MapValueMessageNoBinary');goog.require('proto.jspb.test.TestMapFieldsNoBinary');/** * Helper: check that the given map has exactly this set of (sorted) entries. * @param {!jspb.Map} map * @param {!Array<!Array<?>>} entries */function checkMapEquals(map, entries) {  var arr = map.toArray();  assertEquals(arr.length, entries.length);  for (var i = 0; i < arr.length; i++) {    assertElementsEquals(arr[i], entries[i]);  }}/** * Converts an ES6 iterator to an array. * @template T * @param {!Iterator<T>} iter an iterator * @return {!Array<T>} */function toArray(iter) {  var arr = [];  while (true) {    var val = iter.next();    if (val.done) {      break;    }    arr.push(val.value);  }  return arr;}/** * Helper: generate test methods for this TestMapFields class. * @param {?} msgInfo * @param {?} submessageCtor * @param {!string} suffix */function makeTests(msgInfo, submessageCtor, suffix) {  /**   * Helper: fill all maps on a TestMapFields.   * @param {?} msg   */  var fillMapFields = function(msg) {    msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world');    msg.getMapStringInt32Map().set('a', 1).set('b', -2);    msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000);    msg.getMapStringBoolMap().set('e', true).set('f', false);    msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828);    msg.getMapStringEnumMap()        .set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR)        .set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ);    msg.getMapStringMsgMap()        .set('k', new submessageCtor())        .set('l', new submessageCtor());    msg.getMapStringMsgMap().get('k').setFoo(42);    msg.getMapStringMsgMap().get('l').setFoo(84);    msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');    msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');    msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');  };  /**   * Helper: check all maps on a TestMapFields.   * @param {?} msg   */  var checkMapFields = function(msg) {    checkMapEquals(msg.getMapStringStringMap(), [          ['asdf', 'jkl;'],          ['key 2', 'hello world']    ]);    checkMapEquals(msg.getMapStringInt32Map(), [          ['a', 1],          ['b', -2]    ]);    checkMapEquals(msg.getMapStringInt64Map(), [          ['c', 0x100000000],          ['d', 0x200000000]    ]);    checkMapEquals(msg.getMapStringBoolMap(), [          ['e', true],          ['f', false]    ]);    checkMapEquals(msg.getMapStringDoubleMap(), [          ['g', 3.14159],          ['h', 2.71828]    ]);    checkMapEquals(msg.getMapStringEnumMap(), [          ['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],          ['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]    ]);    checkMapEquals(msg.getMapInt32StringMap(), [          [-1, 'a'],          [42, 'b']    ]);    checkMapEquals(msg.getMapInt64StringMap(), [          [0x123456789abc, 'c'],          [0xcba987654321, 'd']    ]);    checkMapEquals(msg.getMapBoolStringMap(), [          [false, 'e'],          [true, 'f']    ]);    assertEquals(msg.getMapStringMsgMap().getLength(), 2);    assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);    assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84);    var entries = toArray(msg.getMapStringMsgMap().entries());    assertEquals(entries.length, 2);    entries.forEach(function(entry) {      var key = entry[0];      var val = entry[1];      assert(val === msg.getMapStringMsgMap().get(key));    });    msg.getMapStringMsgMap().forEach(function(val, key) {      assert(val === msg.getMapStringMsgMap().get(key));    });  };  it('testMapStringStringField' + suffix, function() {    var msg = new msgInfo.constructor();    assertEquals(msg.getMapStringStringMap().getLength(), 0);    assertEquals(msg.getMapStringInt32Map().getLength(), 0);    assertEquals(msg.getMapStringInt64Map().getLength(), 0);    assertEquals(msg.getMapStringBoolMap().getLength(), 0);    assertEquals(msg.getMapStringDoubleMap().getLength(), 0);    assertEquals(msg.getMapStringEnumMap().getLength(), 0);    assertEquals(msg.getMapStringMsgMap().getLength(), 0);    // Re-create to clear out any internally-cached wrappers, etc.    msg = new msgInfo.constructor();    var m = msg.getMapStringStringMap();    assertEquals(m.has('asdf'), false);    assertEquals(m.get('asdf'), undefined);    m.set('asdf', 'hello world');    assertEquals(m.has('asdf'), true);    assertEquals(m.get('asdf'), 'hello world');    m.set('jkl;', 'key 2');    assertEquals(m.has('jkl;'), true);    assertEquals(m.get('jkl;'), 'key 2');    assertEquals(m.getLength(), 2);    var it = m.entries();    assertElementsEquals(it.next().value, ['asdf', 'hello world']);    assertElementsEquals(it.next().value, ['jkl;', 'key 2']);    assertEquals(it.next().done, true);    checkMapEquals(m, [        ['asdf', 'hello world'],        ['jkl;', 'key 2']    ]);    m.del('jkl;');    assertEquals(m.has('jkl;'), false);    assertEquals(m.get('jkl;'), undefined);    assertEquals(m.getLength(), 1);    it = m.keys();    assertEquals(it.next().value, 'asdf');    assertEquals(it.next().done, true);    it = m.values();    assertEquals(it.next().value, 'hello world');    assertEquals(it.next().done, true);    var count = 0;    m.forEach(function(value, key, map) {      assertEquals(map, m);      assertEquals(key, 'asdf');      assertEquals(value, 'hello world');      count++;    });    assertEquals(count, 1);    m.clear();    assertEquals(m.getLength(), 0);  });  /**   * Tests operations on maps with all key and value types.   */  it('testAllMapTypes' + suffix, function() {    var msg = new msgInfo.constructor();    fillMapFields(msg);    checkMapFields(msg);  });  if (msgInfo.deserializeBinary) {    /**     * Tests serialization and deserialization in binary format.     */    it('testBinaryFormat' + suffix, function() {      if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {        // IE8/9 currently doesn't support binary format because they lack        // TypedArray.        return;      }      // Check that the format is correct.      var msg = new msgInfo.constructor();      msg.getMapStringStringMap().set('A', 'a');      var serialized = msg.serializeBinary();      var expectedSerialized = [          0x0a, 0x6, // field 1 (map_string_string), delimited, length 6          0x0a, 0x1, // field 1 in submessage (key), delimited, length 1          0x41,      // ASCII 'A'          0x12, 0x1, // field 2 in submessage (value), delimited, length 1          0x61       // ASCII 'a'      ];      assertEquals(serialized.length, expectedSerialized.length);      for (var i = 0; i < serialized.length; i++) {        assertEquals(serialized[i], expectedSerialized[i]);      }      // Check that all map fields successfully round-trip.      msg = new msgInfo.constructor();      fillMapFields(msg);      serialized = msg.serializeBinary();      var decoded = msgInfo.deserializeBinary(serialized);      checkMapFields(decoded);    });  }  /**   * Exercises the lazy map<->underlying array sync.   */  it('testLazyMapSync' + suffix, function() {    // Start with a JSPB array containing a few map entries.    var entries = [        ['a', 'entry 1'],        ['c', 'entry 2'],        ['b', 'entry 3']    ];    var msg = new msgInfo.constructor([entries]);    assertEquals(entries.length, 3);    assertEquals(entries[0][0], 'a');    assertEquals(entries[1][0], 'c');    assertEquals(entries[2][0], 'b');    msg.getMapStringStringMap().del('a');    assertEquals(entries.length, 3);  // not yet sync'd    msg.toArray();                // force a sync    assertEquals(entries.length, 2);    assertEquals(entries[0][0], 'b'); // now in sorted order    assertEquals(entries[1][0], 'c');    var a = msg.toArray();    assertEquals(a[0], entries);  // retains original reference  });}describe('mapsTest', function() {  makeTests({    constructor: proto.jspb.test.TestMapFields,    deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary  }, proto.jspb.test.MapValueMessage, "_Binary");  makeTests({    constructor: proto.jspb.test.TestMapFieldsNoBinary,    deserializeBinary: null  }, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");});
 |