1ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format
2ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc.  All rights reserved.
3ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/
4ffe3c632Sopenharmony_ci//
5ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
6ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are
7ffe3c632Sopenharmony_ci// met:
8ffe3c632Sopenharmony_ci//
9ffe3c632Sopenharmony_ci//     * Redistributions of source code must retain the above copyright
10ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer.
11ffe3c632Sopenharmony_ci//     * Redistributions in binary form must reproduce the above
12ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
13ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the
14ffe3c632Sopenharmony_ci// distribution.
15ffe3c632Sopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
16ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from
17ffe3c632Sopenharmony_ci// this software without specific prior written permission.
18ffe3c632Sopenharmony_ci//
19ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30ffe3c632Sopenharmony_ci
31ffe3c632Sopenharmony_cigoog.require('goog.testing.asserts');
32ffe3c632Sopenharmony_cigoog.require('goog.userAgent');
33ffe3c632Sopenharmony_ci
34ffe3c632Sopenharmony_ci// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
35ffe3c632Sopenharmony_cigoog.require('proto.jspb.test.MapValueEnum');
36ffe3c632Sopenharmony_cigoog.require('proto.jspb.test.MapValueMessage');
37ffe3c632Sopenharmony_cigoog.require('proto.jspb.test.TestMapFields');
38ffe3c632Sopenharmony_ci
39ffe3c632Sopenharmony_ci// CommonJS-LoadFromFile: test_pb proto.jspb.test
40ffe3c632Sopenharmony_cigoog.require('proto.jspb.test.MapValueMessageNoBinary');
41ffe3c632Sopenharmony_cigoog.require('proto.jspb.test.TestMapFieldsNoBinary');
42ffe3c632Sopenharmony_ci
43ffe3c632Sopenharmony_ci/**
44ffe3c632Sopenharmony_ci * Helper: check that the given map has exactly this set of (sorted) entries.
45ffe3c632Sopenharmony_ci * @param {!jspb.Map} map
46ffe3c632Sopenharmony_ci * @param {!Array<!Array<?>>} entries
47ffe3c632Sopenharmony_ci */
48ffe3c632Sopenharmony_cifunction checkMapEquals(map, entries) {
49ffe3c632Sopenharmony_ci  var arr = map.toArray();
50ffe3c632Sopenharmony_ci  assertEquals(arr.length, entries.length);
51ffe3c632Sopenharmony_ci  for (var i = 0; i < arr.length; i++) {
52ffe3c632Sopenharmony_ci    assertElementsEquals(arr[i], entries[i]);
53ffe3c632Sopenharmony_ci  }
54ffe3c632Sopenharmony_ci}
55ffe3c632Sopenharmony_ci
56ffe3c632Sopenharmony_ci/**
57ffe3c632Sopenharmony_ci * Converts an ES6 iterator to an array.
58ffe3c632Sopenharmony_ci * @template T
59ffe3c632Sopenharmony_ci * @param {!Iterator<T>} iter an iterator
60ffe3c632Sopenharmony_ci * @return {!Array<T>}
61ffe3c632Sopenharmony_ci */
62ffe3c632Sopenharmony_cifunction toArray(iter) {
63ffe3c632Sopenharmony_ci  var arr = [];
64ffe3c632Sopenharmony_ci  while (true) {
65ffe3c632Sopenharmony_ci    var val = iter.next();
66ffe3c632Sopenharmony_ci    if (val.done) {
67ffe3c632Sopenharmony_ci      break;
68ffe3c632Sopenharmony_ci    }
69ffe3c632Sopenharmony_ci    arr.push(val.value);
70ffe3c632Sopenharmony_ci  }
71ffe3c632Sopenharmony_ci  return arr;
72ffe3c632Sopenharmony_ci}
73ffe3c632Sopenharmony_ci
74ffe3c632Sopenharmony_ci
75ffe3c632Sopenharmony_ci/**
76ffe3c632Sopenharmony_ci * Helper: generate test methods for this TestMapFields class.
77ffe3c632Sopenharmony_ci * @param {?} msgInfo
78ffe3c632Sopenharmony_ci * @param {?} submessageCtor
79ffe3c632Sopenharmony_ci * @param {!string} suffix
80ffe3c632Sopenharmony_ci */
81ffe3c632Sopenharmony_cifunction makeTests(msgInfo, submessageCtor, suffix) {
82ffe3c632Sopenharmony_ci  /**
83ffe3c632Sopenharmony_ci   * Helper: fill all maps on a TestMapFields.
84ffe3c632Sopenharmony_ci   * @param {?} msg
85ffe3c632Sopenharmony_ci   */
86ffe3c632Sopenharmony_ci  var fillMapFields = function(msg) {
87ffe3c632Sopenharmony_ci    msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world');
88ffe3c632Sopenharmony_ci    msg.getMapStringInt32Map().set('a', 1).set('b', -2);
89ffe3c632Sopenharmony_ci    msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000);
90ffe3c632Sopenharmony_ci    msg.getMapStringBoolMap().set('e', true).set('f', false);
91ffe3c632Sopenharmony_ci    msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828);
92ffe3c632Sopenharmony_ci    msg.getMapStringEnumMap()
93ffe3c632Sopenharmony_ci        .set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR)
94ffe3c632Sopenharmony_ci        .set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ);
95ffe3c632Sopenharmony_ci    msg.getMapStringMsgMap()
96ffe3c632Sopenharmony_ci        .set('k', new submessageCtor())
97ffe3c632Sopenharmony_ci        .set('l', new submessageCtor());
98ffe3c632Sopenharmony_ci    msg.getMapStringMsgMap().get('k').setFoo(42);
99ffe3c632Sopenharmony_ci    msg.getMapStringMsgMap().get('l').setFoo(84);
100ffe3c632Sopenharmony_ci    msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
101ffe3c632Sopenharmony_ci    msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
102ffe3c632Sopenharmony_ci    msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
103ffe3c632Sopenharmony_ci  };
104ffe3c632Sopenharmony_ci
105ffe3c632Sopenharmony_ci  /**
106ffe3c632Sopenharmony_ci   * Helper: check all maps on a TestMapFields.
107ffe3c632Sopenharmony_ci   * @param {?} msg
108ffe3c632Sopenharmony_ci   */
109ffe3c632Sopenharmony_ci  var checkMapFields = function(msg) {
110ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringStringMap(), [
111ffe3c632Sopenharmony_ci          ['asdf', 'jkl;'],
112ffe3c632Sopenharmony_ci          ['key 2', 'hello world']
113ffe3c632Sopenharmony_ci    ]);
114ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringInt32Map(), [
115ffe3c632Sopenharmony_ci          ['a', 1],
116ffe3c632Sopenharmony_ci          ['b', -2]
117ffe3c632Sopenharmony_ci    ]);
118ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringInt64Map(), [
119ffe3c632Sopenharmony_ci          ['c', 0x100000000],
120ffe3c632Sopenharmony_ci          ['d', 0x200000000]
121ffe3c632Sopenharmony_ci    ]);
122ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringBoolMap(), [
123ffe3c632Sopenharmony_ci          ['e', true],
124ffe3c632Sopenharmony_ci          ['f', false]
125ffe3c632Sopenharmony_ci    ]);
126ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringDoubleMap(), [
127ffe3c632Sopenharmony_ci          ['g', 3.14159],
128ffe3c632Sopenharmony_ci          ['h', 2.71828]
129ffe3c632Sopenharmony_ci    ]);
130ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapStringEnumMap(), [
131ffe3c632Sopenharmony_ci          ['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
132ffe3c632Sopenharmony_ci          ['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
133ffe3c632Sopenharmony_ci    ]);
134ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapInt32StringMap(), [
135ffe3c632Sopenharmony_ci          [-1, 'a'],
136ffe3c632Sopenharmony_ci          [42, 'b']
137ffe3c632Sopenharmony_ci    ]);
138ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapInt64StringMap(), [
139ffe3c632Sopenharmony_ci          [0x123456789abc, 'c'],
140ffe3c632Sopenharmony_ci          [0xcba987654321, 'd']
141ffe3c632Sopenharmony_ci    ]);
142ffe3c632Sopenharmony_ci    checkMapEquals(msg.getMapBoolStringMap(), [
143ffe3c632Sopenharmony_ci          [false, 'e'],
144ffe3c632Sopenharmony_ci          [true, 'f']
145ffe3c632Sopenharmony_ci    ]);
146ffe3c632Sopenharmony_ci
147ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringMsgMap().getLength(), 2);
148ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
149ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84);
150ffe3c632Sopenharmony_ci
151ffe3c632Sopenharmony_ci    var entries = toArray(msg.getMapStringMsgMap().entries());
152ffe3c632Sopenharmony_ci    assertEquals(entries.length, 2);
153ffe3c632Sopenharmony_ci    entries.forEach(function(entry) {
154ffe3c632Sopenharmony_ci      var key = entry[0];
155ffe3c632Sopenharmony_ci      var val = entry[1];
156ffe3c632Sopenharmony_ci      assert(val === msg.getMapStringMsgMap().get(key));
157ffe3c632Sopenharmony_ci    });
158ffe3c632Sopenharmony_ci
159ffe3c632Sopenharmony_ci    msg.getMapStringMsgMap().forEach(function(val, key) {
160ffe3c632Sopenharmony_ci      assert(val === msg.getMapStringMsgMap().get(key));
161ffe3c632Sopenharmony_ci    });
162ffe3c632Sopenharmony_ci  };
163ffe3c632Sopenharmony_ci
164ffe3c632Sopenharmony_ci  it('testMapStringStringField' + suffix, function() {
165ffe3c632Sopenharmony_ci    var msg = new msgInfo.constructor();
166ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringStringMap().getLength(), 0);
167ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringInt32Map().getLength(), 0);
168ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringInt64Map().getLength(), 0);
169ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringBoolMap().getLength(), 0);
170ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringDoubleMap().getLength(), 0);
171ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringEnumMap().getLength(), 0);
172ffe3c632Sopenharmony_ci    assertEquals(msg.getMapStringMsgMap().getLength(), 0);
173ffe3c632Sopenharmony_ci
174ffe3c632Sopenharmony_ci    // Re-create to clear out any internally-cached wrappers, etc.
175ffe3c632Sopenharmony_ci    msg = new msgInfo.constructor();
176ffe3c632Sopenharmony_ci    var m = msg.getMapStringStringMap();
177ffe3c632Sopenharmony_ci    assertEquals(m.has('asdf'), false);
178ffe3c632Sopenharmony_ci    assertEquals(m.get('asdf'), undefined);
179ffe3c632Sopenharmony_ci    m.set('asdf', 'hello world');
180ffe3c632Sopenharmony_ci    assertEquals(m.has('asdf'), true);
181ffe3c632Sopenharmony_ci    assertEquals(m.get('asdf'), 'hello world');
182ffe3c632Sopenharmony_ci    m.set('jkl;', 'key 2');
183ffe3c632Sopenharmony_ci    assertEquals(m.has('jkl;'), true);
184ffe3c632Sopenharmony_ci    assertEquals(m.get('jkl;'), 'key 2');
185ffe3c632Sopenharmony_ci    assertEquals(m.getLength(), 2);
186ffe3c632Sopenharmony_ci    var it = m.entries();
187ffe3c632Sopenharmony_ci    assertElementsEquals(it.next().value, ['asdf', 'hello world']);
188ffe3c632Sopenharmony_ci    assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
189ffe3c632Sopenharmony_ci    assertEquals(it.next().done, true);
190ffe3c632Sopenharmony_ci    checkMapEquals(m, [
191ffe3c632Sopenharmony_ci        ['asdf', 'hello world'],
192ffe3c632Sopenharmony_ci        ['jkl;', 'key 2']
193ffe3c632Sopenharmony_ci    ]);
194ffe3c632Sopenharmony_ci    m.del('jkl;');
195ffe3c632Sopenharmony_ci    assertEquals(m.has('jkl;'), false);
196ffe3c632Sopenharmony_ci    assertEquals(m.get('jkl;'), undefined);
197ffe3c632Sopenharmony_ci    assertEquals(m.getLength(), 1);
198ffe3c632Sopenharmony_ci    it = m.keys();
199ffe3c632Sopenharmony_ci    assertEquals(it.next().value, 'asdf');
200ffe3c632Sopenharmony_ci    assertEquals(it.next().done, true);
201ffe3c632Sopenharmony_ci    it = m.values();
202ffe3c632Sopenharmony_ci    assertEquals(it.next().value, 'hello world');
203ffe3c632Sopenharmony_ci    assertEquals(it.next().done, true);
204ffe3c632Sopenharmony_ci
205ffe3c632Sopenharmony_ci    var count = 0;
206ffe3c632Sopenharmony_ci    m.forEach(function(value, key, map) {
207ffe3c632Sopenharmony_ci      assertEquals(map, m);
208ffe3c632Sopenharmony_ci      assertEquals(key, 'asdf');
209ffe3c632Sopenharmony_ci      assertEquals(value, 'hello world');
210ffe3c632Sopenharmony_ci      count++;
211ffe3c632Sopenharmony_ci    });
212ffe3c632Sopenharmony_ci    assertEquals(count, 1);
213ffe3c632Sopenharmony_ci
214ffe3c632Sopenharmony_ci    m.clear();
215ffe3c632Sopenharmony_ci    assertEquals(m.getLength(), 0);
216ffe3c632Sopenharmony_ci  });
217ffe3c632Sopenharmony_ci
218ffe3c632Sopenharmony_ci
219ffe3c632Sopenharmony_ci  /**
220ffe3c632Sopenharmony_ci   * Tests operations on maps with all key and value types.
221ffe3c632Sopenharmony_ci   */
222ffe3c632Sopenharmony_ci  it('testAllMapTypes' + suffix, function() {
223ffe3c632Sopenharmony_ci    var msg = new msgInfo.constructor();
224ffe3c632Sopenharmony_ci    fillMapFields(msg);
225ffe3c632Sopenharmony_ci    checkMapFields(msg);
226ffe3c632Sopenharmony_ci  });
227ffe3c632Sopenharmony_ci
228ffe3c632Sopenharmony_ci
229ffe3c632Sopenharmony_ci  if (msgInfo.deserializeBinary) {
230ffe3c632Sopenharmony_ci    /**
231ffe3c632Sopenharmony_ci     * Tests serialization and deserialization in binary format.
232ffe3c632Sopenharmony_ci     */
233ffe3c632Sopenharmony_ci    it('testBinaryFormat' + suffix, function() {
234ffe3c632Sopenharmony_ci      if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
235ffe3c632Sopenharmony_ci        // IE8/9 currently doesn't support binary format because they lack
236ffe3c632Sopenharmony_ci        // TypedArray.
237ffe3c632Sopenharmony_ci        return;
238ffe3c632Sopenharmony_ci      }
239ffe3c632Sopenharmony_ci
240ffe3c632Sopenharmony_ci      // Check that the format is correct.
241ffe3c632Sopenharmony_ci      var msg = new msgInfo.constructor();
242ffe3c632Sopenharmony_ci      msg.getMapStringStringMap().set('A', 'a');
243ffe3c632Sopenharmony_ci      var serialized = msg.serializeBinary();
244ffe3c632Sopenharmony_ci      var expectedSerialized = [
245ffe3c632Sopenharmony_ci          0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
246ffe3c632Sopenharmony_ci          0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
247ffe3c632Sopenharmony_ci          0x41,      // ASCII 'A'
248ffe3c632Sopenharmony_ci          0x12, 0x1, // field 2 in submessage (value), delimited, length 1
249ffe3c632Sopenharmony_ci          0x61       // ASCII 'a'
250ffe3c632Sopenharmony_ci      ];
251ffe3c632Sopenharmony_ci      assertEquals(serialized.length, expectedSerialized.length);
252ffe3c632Sopenharmony_ci      for (var i = 0; i < serialized.length; i++) {
253ffe3c632Sopenharmony_ci        assertEquals(serialized[i], expectedSerialized[i]);
254ffe3c632Sopenharmony_ci      }
255ffe3c632Sopenharmony_ci
256ffe3c632Sopenharmony_ci      // Check that all map fields successfully round-trip.
257ffe3c632Sopenharmony_ci      msg = new msgInfo.constructor();
258ffe3c632Sopenharmony_ci      fillMapFields(msg);
259ffe3c632Sopenharmony_ci      serialized = msg.serializeBinary();
260ffe3c632Sopenharmony_ci      var decoded = msgInfo.deserializeBinary(serialized);
261ffe3c632Sopenharmony_ci      checkMapFields(decoded);
262ffe3c632Sopenharmony_ci    });
263ffe3c632Sopenharmony_ci  }
264ffe3c632Sopenharmony_ci
265ffe3c632Sopenharmony_ci  /**
266ffe3c632Sopenharmony_ci   * Exercises the lazy map<->underlying array sync.
267ffe3c632Sopenharmony_ci   */
268ffe3c632Sopenharmony_ci  it('testLazyMapSync' + suffix, function() {
269ffe3c632Sopenharmony_ci    // Start with a JSPB array containing a few map entries.
270ffe3c632Sopenharmony_ci    var entries = [
271ffe3c632Sopenharmony_ci        ['a', 'entry 1'],
272ffe3c632Sopenharmony_ci        ['c', 'entry 2'],
273ffe3c632Sopenharmony_ci        ['b', 'entry 3']
274ffe3c632Sopenharmony_ci    ];
275ffe3c632Sopenharmony_ci    var msg = new msgInfo.constructor([entries]);
276ffe3c632Sopenharmony_ci    assertEquals(entries.length, 3);
277ffe3c632Sopenharmony_ci    assertEquals(entries[0][0], 'a');
278ffe3c632Sopenharmony_ci    assertEquals(entries[1][0], 'c');
279ffe3c632Sopenharmony_ci    assertEquals(entries[2][0], 'b');
280ffe3c632Sopenharmony_ci    msg.getMapStringStringMap().del('a');
281ffe3c632Sopenharmony_ci    assertEquals(entries.length, 3);  // not yet sync'd
282ffe3c632Sopenharmony_ci    msg.toArray();                // force a sync
283ffe3c632Sopenharmony_ci    assertEquals(entries.length, 2);
284ffe3c632Sopenharmony_ci    assertEquals(entries[0][0], 'b'); // now in sorted order
285ffe3c632Sopenharmony_ci    assertEquals(entries[1][0], 'c');
286ffe3c632Sopenharmony_ci
287ffe3c632Sopenharmony_ci    var a = msg.toArray();
288ffe3c632Sopenharmony_ci    assertEquals(a[0], entries);  // retains original reference
289ffe3c632Sopenharmony_ci  });
290ffe3c632Sopenharmony_ci}
291ffe3c632Sopenharmony_ci
292ffe3c632Sopenharmony_cidescribe('mapsTest', function() {
293ffe3c632Sopenharmony_ci  makeTests({
294ffe3c632Sopenharmony_ci    constructor: proto.jspb.test.TestMapFields,
295ffe3c632Sopenharmony_ci    deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
296ffe3c632Sopenharmony_ci  }, proto.jspb.test.MapValueMessage, "_Binary");
297ffe3c632Sopenharmony_ci  makeTests({
298ffe3c632Sopenharmony_ci    constructor: proto.jspb.test.TestMapFieldsNoBinary,
299ffe3c632Sopenharmony_ci    deserializeBinary: null
300ffe3c632Sopenharmony_ci  }, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");
301ffe3c632Sopenharmony_ci});
302