1ffe3c632Sopenharmony_ci/**
2ffe3c632Sopenharmony_ci * @fileoverview Tests for writer.js.
3ffe3c632Sopenharmony_ci */
4ffe3c632Sopenharmony_cigoog.module('protobuf.binary.WriterTest');
5ffe3c632Sopenharmony_ci
6ffe3c632Sopenharmony_cigoog.setTestOnly();
7ffe3c632Sopenharmony_ci
8ffe3c632Sopenharmony_ci// Note to the reader:
9ffe3c632Sopenharmony_ci// Since the writer behavior changes with the checking level some of the tests
10ffe3c632Sopenharmony_ci// in this file have to know which checking level is enable to make correct
11ffe3c632Sopenharmony_ci// assertions.
12ffe3c632Sopenharmony_ciconst BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
13ffe3c632Sopenharmony_ciconst ByteString = goog.require('protobuf.ByteString');
14ffe3c632Sopenharmony_ciconst WireType = goog.require('protobuf.binary.WireType');
15ffe3c632Sopenharmony_ciconst Writer = goog.require('protobuf.binary.Writer');
16ffe3c632Sopenharmony_ciconst {CHECK_BOUNDS, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks');
17ffe3c632Sopenharmony_ciconst {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays');
18ffe3c632Sopenharmony_ciconst {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs');
19ffe3c632Sopenharmony_ciconst {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs');
20ffe3c632Sopenharmony_ciconst {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs');
21ffe3c632Sopenharmony_ciconst {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs');
22ffe3c632Sopenharmony_ciconst {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs');
23ffe3c632Sopenharmony_ciconst {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs');
24ffe3c632Sopenharmony_ciconst {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs');
25ffe3c632Sopenharmony_ciconst {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs');
26ffe3c632Sopenharmony_ciconst {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs');
27ffe3c632Sopenharmony_ciconst {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs');
28ffe3c632Sopenharmony_ciconst {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs');
29ffe3c632Sopenharmony_ciconst {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs');
30ffe3c632Sopenharmony_ciconst {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs');
31ffe3c632Sopenharmony_ciconst {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs');
32ffe3c632Sopenharmony_ciconst {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs');
33ffe3c632Sopenharmony_ciconst {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs');
34ffe3c632Sopenharmony_ciconst {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs');
35ffe3c632Sopenharmony_ciconst {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs');
36ffe3c632Sopenharmony_ciconst {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs');
37ffe3c632Sopenharmony_ciconst {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs');
38ffe3c632Sopenharmony_ciconst {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs');
39ffe3c632Sopenharmony_ci
40ffe3c632Sopenharmony_ci
41ffe3c632Sopenharmony_ci/**
42ffe3c632Sopenharmony_ci * @param {...number} bytes
43ffe3c632Sopenharmony_ci * @return {!ArrayBuffer}
44ffe3c632Sopenharmony_ci */
45ffe3c632Sopenharmony_cifunction createArrayBuffer(...bytes) {
46ffe3c632Sopenharmony_ci  return new Uint8Array(bytes).buffer;
47ffe3c632Sopenharmony_ci}
48ffe3c632Sopenharmony_ci
49ffe3c632Sopenharmony_ci/******************************************************************************
50ffe3c632Sopenharmony_ci *                        OPTIONAL FUNCTIONS
51ffe3c632Sopenharmony_ci ******************************************************************************/
52ffe3c632Sopenharmony_ci
53ffe3c632Sopenharmony_cidescribe('Writer does', () => {
54ffe3c632Sopenharmony_ci  it('return an empty ArrayBuffer when nothing is encoded', () => {
55ffe3c632Sopenharmony_ci    const writer = new Writer();
56ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
57ffe3c632Sopenharmony_ci  });
58ffe3c632Sopenharmony_ci
59ffe3c632Sopenharmony_ci  it('encode tag', () => {
60ffe3c632Sopenharmony_ci    const writer = new Writer();
61ffe3c632Sopenharmony_ci    writer.writeTag(1, WireType.VARINT);
62ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));
63ffe3c632Sopenharmony_ci
64ffe3c632Sopenharmony_ci    writer.writeTag(0x0FFFFFFF, WireType.VARINT);
65ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
66ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x7));
67ffe3c632Sopenharmony_ci
68ffe3c632Sopenharmony_ci    writer.writeTag(0x10000000, WireType.VARINT);
69ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
70ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(0x80, 0x80, 0x80, 0x80, 0x08));
71ffe3c632Sopenharmony_ci
72ffe3c632Sopenharmony_ci    writer.writeTag(0x1FFFFFFF, WireType.VARINT);
73ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
74ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F));
75ffe3c632Sopenharmony_ci  });
76ffe3c632Sopenharmony_ci
77ffe3c632Sopenharmony_ci  it('reset after calling getAndResetResultBuffer', () => {
78ffe3c632Sopenharmony_ci    const writer = new Writer();
79ffe3c632Sopenharmony_ci    writer.writeTag(1, WireType.VARINT);
80ffe3c632Sopenharmony_ci    writer.getAndResetResultBuffer();
81ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
82ffe3c632Sopenharmony_ci  });
83ffe3c632Sopenharmony_ci
84ffe3c632Sopenharmony_ci  it('fail when field number is too large for writeTag', () => {
85ffe3c632Sopenharmony_ci    const writer = new Writer();
86ffe3c632Sopenharmony_ci    if (CHECK_TYPE) {
87ffe3c632Sopenharmony_ci      expect(() => writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT))
88ffe3c632Sopenharmony_ci          .toThrowError('Field number is out of range: 536870912');
89ffe3c632Sopenharmony_ci    } else {
90ffe3c632Sopenharmony_ci      // Note in unchecked mode we produce invalid output for invalid inputs.
91ffe3c632Sopenharmony_ci      // This test just documents our behavior in those cases.
92ffe3c632Sopenharmony_ci      // These values might change at any point and are not considered
93ffe3c632Sopenharmony_ci      // what the implementation should be doing here.
94ffe3c632Sopenharmony_ci      writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT);
95ffe3c632Sopenharmony_ci      expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0));
96ffe3c632Sopenharmony_ci    }
97ffe3c632Sopenharmony_ci  });
98ffe3c632Sopenharmony_ci
99ffe3c632Sopenharmony_ci  it('fail when field number is negative for writeTag', () => {
100ffe3c632Sopenharmony_ci    const writer = new Writer();
101ffe3c632Sopenharmony_ci    if (CHECK_TYPE) {
102ffe3c632Sopenharmony_ci      expect(() => writer.writeTag(-1, WireType.VARINT))
103ffe3c632Sopenharmony_ci          .toThrowError('Field number is out of range: -1');
104ffe3c632Sopenharmony_ci    } else {
105ffe3c632Sopenharmony_ci      // Note in unchecked mode we produce invalid output for invalid inputs.
106ffe3c632Sopenharmony_ci      // This test just documents our behavior in those cases.
107ffe3c632Sopenharmony_ci      // These values might change at any point and are not considered
108ffe3c632Sopenharmony_ci      // what the implementation should be doing here.
109ffe3c632Sopenharmony_ci      writer.writeTag(-1, WireType.VARINT);
110ffe3c632Sopenharmony_ci      expect(writer.getAndResetResultBuffer())
111ffe3c632Sopenharmony_ci          .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0xF));
112ffe3c632Sopenharmony_ci    }
113ffe3c632Sopenharmony_ci  });
114ffe3c632Sopenharmony_ci
115ffe3c632Sopenharmony_ci  it('fail when wire type is invalid for writeTag', () => {
116ffe3c632Sopenharmony_ci    const writer = new Writer();
117ffe3c632Sopenharmony_ci    if (CHECK_TYPE) {
118ffe3c632Sopenharmony_ci      expect(() => writer.writeTag(1, /** @type {!WireType} */ (0x08)))
119ffe3c632Sopenharmony_ci          .toThrowError('Invalid wire type: 8');
120ffe3c632Sopenharmony_ci    } else {
121ffe3c632Sopenharmony_ci      // Note in unchecked mode we produce invalid output for invalid inputs.
122ffe3c632Sopenharmony_ci      // This test just documents our behavior in those cases.
123ffe3c632Sopenharmony_ci      // These values might change at any point and are not considered
124ffe3c632Sopenharmony_ci      // what the implementation should be doing here.
125ffe3c632Sopenharmony_ci      writer.writeTag(1, /** @type {!WireType} */ (0x08));
126ffe3c632Sopenharmony_ci      expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));
127ffe3c632Sopenharmony_ci    }
128ffe3c632Sopenharmony_ci  });
129ffe3c632Sopenharmony_ci
130ffe3c632Sopenharmony_ci  it('encode singular boolean value', () => {
131ffe3c632Sopenharmony_ci    const writer = new Writer();
132ffe3c632Sopenharmony_ci    writer.writeBool(1, true);
133ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
134ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(0x08, 0x01));
135ffe3c632Sopenharmony_ci  });
136ffe3c632Sopenharmony_ci
137ffe3c632Sopenharmony_ci  it('encode length delimited', () => {
138ffe3c632Sopenharmony_ci    const writer = new Writer();
139ffe3c632Sopenharmony_ci    writer.writeDelimited(1, createArrayBuffer(0x01, 0x02));
140ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
141ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(0x0A, 0x02, 0x01, 0x02));
142ffe3c632Sopenharmony_ci  });
143ffe3c632Sopenharmony_ci});
144ffe3c632Sopenharmony_ci
145ffe3c632Sopenharmony_cidescribe('Writer.writeBufferDecoder does', () => {
146ffe3c632Sopenharmony_ci  it('encode BufferDecoder containing a varint value', () => {
147ffe3c632Sopenharmony_ci    const writer = new Writer();
148ffe3c632Sopenharmony_ci    const expected = createArrayBuffer(
149ffe3c632Sopenharmony_ci        0x08, /* varint start= */ 0xFF, /* varint end= */ 0x01, 0x08, 0x01);
150ffe3c632Sopenharmony_ci    writer.writeBufferDecoder(
151ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT, 1);
152ffe3c632Sopenharmony_ci    const result = writer.getAndResetResultBuffer();
153ffe3c632Sopenharmony_ci    expect(result).toEqual(arrayBufferSlice(expected, 1, 3));
154ffe3c632Sopenharmony_ci  });
155ffe3c632Sopenharmony_ci
156ffe3c632Sopenharmony_ci  it('encode BufferDecoder containing a fixed64 value', () => {
157ffe3c632Sopenharmony_ci    const writer = new Writer();
158ffe3c632Sopenharmony_ci    const expected = createArrayBuffer(
159ffe3c632Sopenharmony_ci        0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
160ffe3c632Sopenharmony_ci        /* fixed64 end= */ 0x08, 0x08, 0x01);
161ffe3c632Sopenharmony_ci    writer.writeBufferDecoder(
162ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64, 1);
163ffe3c632Sopenharmony_ci    const result = writer.getAndResetResultBuffer();
164ffe3c632Sopenharmony_ci    expect(result).toEqual(arrayBufferSlice(expected, 1, 9));
165ffe3c632Sopenharmony_ci  });
166ffe3c632Sopenharmony_ci
167ffe3c632Sopenharmony_ci  it('encode BufferDecoder containing a length delimited value', () => {
168ffe3c632Sopenharmony_ci    const writer = new Writer();
169ffe3c632Sopenharmony_ci    const expected = createArrayBuffer(
170ffe3c632Sopenharmony_ci        0xA, /* length= */ 0x03, /* data start= */ 0x01, 0x02,
171ffe3c632Sopenharmony_ci        /* data end= */ 0x03, 0x08, 0x01);
172ffe3c632Sopenharmony_ci    writer.writeBufferDecoder(
173ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED, 1);
174ffe3c632Sopenharmony_ci    const result = writer.getAndResetResultBuffer();
175ffe3c632Sopenharmony_ci    expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
176ffe3c632Sopenharmony_ci  });
177ffe3c632Sopenharmony_ci
178ffe3c632Sopenharmony_ci  it('encode BufferDecoder containing a group', () => {
179ffe3c632Sopenharmony_ci    const writer = new Writer();
180ffe3c632Sopenharmony_ci    const expected = createArrayBuffer(
181ffe3c632Sopenharmony_ci        0xB, /* group start= */ 0x08, 0x01, /* nested group start= */ 0x0B,
182ffe3c632Sopenharmony_ci        /* nested group end= */ 0x0C, /* group end= */ 0x0C, 0x08, 0x01);
183ffe3c632Sopenharmony_ci    writer.writeBufferDecoder(
184ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP, 1);
185ffe3c632Sopenharmony_ci    const result = writer.getAndResetResultBuffer();
186ffe3c632Sopenharmony_ci    expect(result).toEqual(arrayBufferSlice(expected, 1, 6));
187ffe3c632Sopenharmony_ci  });
188ffe3c632Sopenharmony_ci
189ffe3c632Sopenharmony_ci  it('encode BufferDecoder containing a fixed32 value', () => {
190ffe3c632Sopenharmony_ci    const writer = new Writer();
191ffe3c632Sopenharmony_ci    const expected = createArrayBuffer(
192ffe3c632Sopenharmony_ci        0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, /* fixed64 end= */ 0x04,
193ffe3c632Sopenharmony_ci        0x08, 0x01);
194ffe3c632Sopenharmony_ci    writer.writeBufferDecoder(
195ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32, 1);
196ffe3c632Sopenharmony_ci    const result = writer.getAndResetResultBuffer();
197ffe3c632Sopenharmony_ci    expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
198ffe3c632Sopenharmony_ci  });
199ffe3c632Sopenharmony_ci
200ffe3c632Sopenharmony_ci  it('fail when encoding out of bound data', () => {
201ffe3c632Sopenharmony_ci    const writer = new Writer();
202ffe3c632Sopenharmony_ci    const buffer = createArrayBuffer(0x4, 0x0, 0x1, 0x2, 0x3);
203ffe3c632Sopenharmony_ci    const subBuffer = arrayBufferSlice(buffer, 0, 2);
204ffe3c632Sopenharmony_ci    expect(
205ffe3c632Sopenharmony_ci        () => writer.writeBufferDecoder(
206ffe3c632Sopenharmony_ci            BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED, 1))
207ffe3c632Sopenharmony_ci        .toThrow();
208ffe3c632Sopenharmony_ci  });
209ffe3c632Sopenharmony_ci});
210ffe3c632Sopenharmony_ci
211ffe3c632Sopenharmony_cidescribe('Writer.writeBytes does', () => {
212ffe3c632Sopenharmony_ci  let writer;
213ffe3c632Sopenharmony_ci  beforeEach(() => {
214ffe3c632Sopenharmony_ci    writer = new Writer();
215ffe3c632Sopenharmony_ci  });
216ffe3c632Sopenharmony_ci
217ffe3c632Sopenharmony_ci  it('encodes empty ByteString', () => {
218ffe3c632Sopenharmony_ci    writer.writeBytes(1, ByteString.EMPTY);
219ffe3c632Sopenharmony_ci    const buffer = writer.getAndResetResultBuffer();
220ffe3c632Sopenharmony_ci    expect(buffer.byteLength).toBe(2);
221ffe3c632Sopenharmony_ci  });
222ffe3c632Sopenharmony_ci
223ffe3c632Sopenharmony_ci  it('encodes empty array', () => {
224ffe3c632Sopenharmony_ci    writer.writeBytes(1, ByteString.fromArrayBuffer(new ArrayBuffer(0)));
225ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
226ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
227ffe3c632Sopenharmony_ci            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
228ffe3c632Sopenharmony_ci            0,              // length of the bytes
229ffe3c632Sopenharmony_ci            ));
230ffe3c632Sopenharmony_ci  });
231ffe3c632Sopenharmony_ci
232ffe3c632Sopenharmony_ci  it('encodes ByteString', () => {
233ffe3c632Sopenharmony_ci    const array = createArrayBuffer(1, 2, 3);
234ffe3c632Sopenharmony_ci    writer.writeBytes(1, ByteString.fromArrayBuffer(array));
235ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
236ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
237ffe3c632Sopenharmony_ci            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
238ffe3c632Sopenharmony_ci            3,              // length of the bytes
239ffe3c632Sopenharmony_ci            1,
240ffe3c632Sopenharmony_ci            2,
241ffe3c632Sopenharmony_ci            3,
242ffe3c632Sopenharmony_ci            ));
243ffe3c632Sopenharmony_ci  });
244ffe3c632Sopenharmony_ci});
245ffe3c632Sopenharmony_ci
246ffe3c632Sopenharmony_cidescribe('Writer.writeDouble does', () => {
247ffe3c632Sopenharmony_ci  let writer;
248ffe3c632Sopenharmony_ci  beforeEach(() => {
249ffe3c632Sopenharmony_ci    writer = new Writer();
250ffe3c632Sopenharmony_ci  });
251ffe3c632Sopenharmony_ci
252ffe3c632Sopenharmony_ci  for (const pair of getDoublePairs()) {
253ffe3c632Sopenharmony_ci    it(`encode ${pair.name}`, () => {
254ffe3c632Sopenharmony_ci        writer.writeDouble(1, pair.doubleValue);
255ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
256ffe3c632Sopenharmony_ci        expect(buffer.length).toBe(9);
257ffe3c632Sopenharmony_ci        // ensure we have a correct tag
258ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x09);
259ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
260ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, 9))
261ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
262ffe3c632Sopenharmony_ci    });
263ffe3c632Sopenharmony_ci  }
264ffe3c632Sopenharmony_ci
265ffe3c632Sopenharmony_ci  /**
266ffe3c632Sopenharmony_ci   * NaN may have different value in different browsers. Thus, we need to make
267ffe3c632Sopenharmony_ci   * the test lenient.
268ffe3c632Sopenharmony_ci   */
269ffe3c632Sopenharmony_ci  it('encode NaN', () => {
270ffe3c632Sopenharmony_ci    writer.writeDouble(1, NaN);
271ffe3c632Sopenharmony_ci    const buffer = new Uint8Array(writer.getAndResetResultBuffer());
272ffe3c632Sopenharmony_ci    expect(buffer.length).toBe(9);
273ffe3c632Sopenharmony_ci    // ensure we have a correct tag
274ffe3c632Sopenharmony_ci    expect(buffer[0]).toEqual(0x09);
275ffe3c632Sopenharmony_ci    // Encoded values are stored right after the tag
276ffe3c632Sopenharmony_ci    const float64 = new DataView(buffer.buffer);
277ffe3c632Sopenharmony_ci    expect(float64.getFloat64(1, true)).toBeNaN();
278ffe3c632Sopenharmony_ci  });
279ffe3c632Sopenharmony_ci});
280ffe3c632Sopenharmony_ci
281ffe3c632Sopenharmony_cidescribe('Writer.writeFixed32 does', () => {
282ffe3c632Sopenharmony_ci  let writer;
283ffe3c632Sopenharmony_ci  beforeEach(() => {
284ffe3c632Sopenharmony_ci    writer = new Writer();
285ffe3c632Sopenharmony_ci  });
286ffe3c632Sopenharmony_ci
287ffe3c632Sopenharmony_ci  for (const pair of getFixed32Pairs()) {
288ffe3c632Sopenharmony_ci    it(`encode ${pair.name}`, () => {
289ffe3c632Sopenharmony_ci      writer.writeFixed32(1, pair.intValue);
290ffe3c632Sopenharmony_ci      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
291ffe3c632Sopenharmony_ci      expect(buffer.length).toBe(5);
292ffe3c632Sopenharmony_ci      // ensure we have a correct tag
293ffe3c632Sopenharmony_ci      expect(buffer[0]).toEqual(0x0D);
294ffe3c632Sopenharmony_ci      // Encoded values are stored right after the tag
295ffe3c632Sopenharmony_ci      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
296ffe3c632Sopenharmony_ci    });
297ffe3c632Sopenharmony_ci  }
298ffe3c632Sopenharmony_ci});
299ffe3c632Sopenharmony_ci
300ffe3c632Sopenharmony_cidescribe('Writer.writeFloat does', () => {
301ffe3c632Sopenharmony_ci  let writer;
302ffe3c632Sopenharmony_ci  beforeEach(() => {
303ffe3c632Sopenharmony_ci    writer = new Writer();
304ffe3c632Sopenharmony_ci  });
305ffe3c632Sopenharmony_ci
306ffe3c632Sopenharmony_ci  for (const pair of getFloatPairs()) {
307ffe3c632Sopenharmony_ci    it(`encode ${pair.name}`, () => {
308ffe3c632Sopenharmony_ci      writer.writeFloat(1, pair.floatValue);
309ffe3c632Sopenharmony_ci      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
310ffe3c632Sopenharmony_ci      expect(buffer.length).toBe(5);
311ffe3c632Sopenharmony_ci      // ensure we have a correct tag
312ffe3c632Sopenharmony_ci      expect(buffer[0]).toEqual(0x0D);
313ffe3c632Sopenharmony_ci      // Encoded values are stored right after the tag
314ffe3c632Sopenharmony_ci      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
315ffe3c632Sopenharmony_ci    });
316ffe3c632Sopenharmony_ci  }
317ffe3c632Sopenharmony_ci
318ffe3c632Sopenharmony_ci  /**
319ffe3c632Sopenharmony_ci   * NaN may have different value in different browsers. Thus, we need to make
320ffe3c632Sopenharmony_ci   * the test lenient.
321ffe3c632Sopenharmony_ci   */
322ffe3c632Sopenharmony_ci  it('encode NaN', () => {
323ffe3c632Sopenharmony_ci    writer.writeFloat(1, NaN);
324ffe3c632Sopenharmony_ci    const buffer = new Uint8Array(writer.getAndResetResultBuffer());
325ffe3c632Sopenharmony_ci    expect(buffer.length).toBe(5);
326ffe3c632Sopenharmony_ci    // ensure we have a correct tag
327ffe3c632Sopenharmony_ci    expect(buffer[0]).toEqual(0x0D);
328ffe3c632Sopenharmony_ci    // Encoded values are stored right after the tag
329ffe3c632Sopenharmony_ci    const float32 = new DataView(buffer.buffer);
330ffe3c632Sopenharmony_ci    expect(float32.getFloat32(1, true)).toBeNaN();
331ffe3c632Sopenharmony_ci  });
332ffe3c632Sopenharmony_ci});
333ffe3c632Sopenharmony_ci
334ffe3c632Sopenharmony_cidescribe('Writer.writeInt32 does', () => {
335ffe3c632Sopenharmony_ci  let writer;
336ffe3c632Sopenharmony_ci  beforeEach(() => {
337ffe3c632Sopenharmony_ci    writer = new Writer();
338ffe3c632Sopenharmony_ci  });
339ffe3c632Sopenharmony_ci
340ffe3c632Sopenharmony_ci  for (const pair of getInt32Pairs()) {
341ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
342ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
343ffe3c632Sopenharmony_ci        writer.writeInt32(1, pair.intValue);
344ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
345ffe3c632Sopenharmony_ci        // ensure we have a correct tag
346ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x08);
347ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
348ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
349ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
350ffe3c632Sopenharmony_ci      });
351ffe3c632Sopenharmony_ci    }
352ffe3c632Sopenharmony_ci  }
353ffe3c632Sopenharmony_ci});
354ffe3c632Sopenharmony_ci
355ffe3c632Sopenharmony_cidescribe('Writer.writeSfixed32 does', () => {
356ffe3c632Sopenharmony_ci  let writer;
357ffe3c632Sopenharmony_ci  beforeEach(() => {
358ffe3c632Sopenharmony_ci    writer = new Writer();
359ffe3c632Sopenharmony_ci  });
360ffe3c632Sopenharmony_ci
361ffe3c632Sopenharmony_ci  it('encode empty array', () => {
362ffe3c632Sopenharmony_ci    writer.writePackedSfixed32(1, []);
363ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
364ffe3c632Sopenharmony_ci  });
365ffe3c632Sopenharmony_ci
366ffe3c632Sopenharmony_ci  for (const pair of getSfixed32Pairs()) {
367ffe3c632Sopenharmony_ci    it(`encode ${pair.name}`, () => {
368ffe3c632Sopenharmony_ci      writer.writeSfixed32(1, pair.intValue);
369ffe3c632Sopenharmony_ci      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
370ffe3c632Sopenharmony_ci      expect(buffer.length).toBe(5);
371ffe3c632Sopenharmony_ci      // ensure we have a correct tag
372ffe3c632Sopenharmony_ci      expect(buffer[0]).toEqual(0x0D);
373ffe3c632Sopenharmony_ci      // Encoded values are stored right after the tag
374ffe3c632Sopenharmony_ci      expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
375ffe3c632Sopenharmony_ci    });
376ffe3c632Sopenharmony_ci  }
377ffe3c632Sopenharmony_ci});
378ffe3c632Sopenharmony_ci
379ffe3c632Sopenharmony_cidescribe('Writer.writeSfixed64 does', () => {
380ffe3c632Sopenharmony_ci  let writer;
381ffe3c632Sopenharmony_ci  beforeEach(() => {
382ffe3c632Sopenharmony_ci    writer = new Writer();
383ffe3c632Sopenharmony_ci  });
384ffe3c632Sopenharmony_ci
385ffe3c632Sopenharmony_ci  for (const pair of getSfixed64Pairs()) {
386ffe3c632Sopenharmony_ci    it(`encode ${pair.name}`, () => {
387ffe3c632Sopenharmony_ci      writer.writeSfixed64(1, pair.longValue);
388ffe3c632Sopenharmony_ci      const buffer = new Uint8Array(writer.getAndResetResultBuffer());
389ffe3c632Sopenharmony_ci      expect(buffer.length).toBe(9);
390ffe3c632Sopenharmony_ci      // ensure we have a correct tag
391ffe3c632Sopenharmony_ci      expect(buffer[0]).toEqual(0x09);
392ffe3c632Sopenharmony_ci      // Encoded values are stored right after the tag
393ffe3c632Sopenharmony_ci      expect(buffer.subarray(1, 9)).toEqual(pair.bufferDecoder.asUint8Array());
394ffe3c632Sopenharmony_ci    });
395ffe3c632Sopenharmony_ci  }
396ffe3c632Sopenharmony_ci});
397ffe3c632Sopenharmony_ci
398ffe3c632Sopenharmony_cidescribe('Writer.writeSint32 does', () => {
399ffe3c632Sopenharmony_ci  let writer;
400ffe3c632Sopenharmony_ci  beforeEach(() => {
401ffe3c632Sopenharmony_ci    writer = new Writer();
402ffe3c632Sopenharmony_ci  });
403ffe3c632Sopenharmony_ci
404ffe3c632Sopenharmony_ci  for (const pair of getSint32Pairs()) {
405ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
406ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
407ffe3c632Sopenharmony_ci        writer.writeSint32(1, pair.intValue);
408ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
409ffe3c632Sopenharmony_ci        // ensure we have a correct tag
410ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x08);
411ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
412ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
413ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
414ffe3c632Sopenharmony_ci      });
415ffe3c632Sopenharmony_ci    }
416ffe3c632Sopenharmony_ci  }
417ffe3c632Sopenharmony_ci});
418ffe3c632Sopenharmony_ci
419ffe3c632Sopenharmony_cidescribe('Writer.writeSint64 does', () => {
420ffe3c632Sopenharmony_ci  let writer;
421ffe3c632Sopenharmony_ci  beforeEach(() => {
422ffe3c632Sopenharmony_ci    writer = new Writer();
423ffe3c632Sopenharmony_ci  });
424ffe3c632Sopenharmony_ci
425ffe3c632Sopenharmony_ci  for (const pair of getSint64Pairs()) {
426ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
427ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
428ffe3c632Sopenharmony_ci        writer.writeSint64(1, pair.longValue);
429ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
430ffe3c632Sopenharmony_ci        // ensure we have a correct tag
431ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x08);
432ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
433ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
434ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
435ffe3c632Sopenharmony_ci      });
436ffe3c632Sopenharmony_ci    }
437ffe3c632Sopenharmony_ci  }
438ffe3c632Sopenharmony_ci});
439ffe3c632Sopenharmony_ci
440ffe3c632Sopenharmony_cidescribe('Writer.writeInt64 does', () => {
441ffe3c632Sopenharmony_ci  let writer;
442ffe3c632Sopenharmony_ci  beforeEach(() => {
443ffe3c632Sopenharmony_ci    writer = new Writer();
444ffe3c632Sopenharmony_ci  });
445ffe3c632Sopenharmony_ci
446ffe3c632Sopenharmony_ci  for (const pair of getInt64Pairs()) {
447ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
448ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
449ffe3c632Sopenharmony_ci        writer.writeInt64(1, pair.longValue);
450ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
451ffe3c632Sopenharmony_ci        // ensure we have a correct tag
452ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x08);
453ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
454ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
455ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
456ffe3c632Sopenharmony_ci      });
457ffe3c632Sopenharmony_ci    }
458ffe3c632Sopenharmony_ci  }
459ffe3c632Sopenharmony_ci});
460ffe3c632Sopenharmony_ci
461ffe3c632Sopenharmony_cidescribe('Writer.writeUint32 does', () => {
462ffe3c632Sopenharmony_ci  let writer;
463ffe3c632Sopenharmony_ci  beforeEach(() => {
464ffe3c632Sopenharmony_ci    writer = new Writer();
465ffe3c632Sopenharmony_ci  });
466ffe3c632Sopenharmony_ci
467ffe3c632Sopenharmony_ci  for (const pair of getUint32Pairs()) {
468ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
469ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
470ffe3c632Sopenharmony_ci        writer.writeUint32(1, pair.intValue);
471ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
472ffe3c632Sopenharmony_ci        // ensure we have a correct tag
473ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x08);
474ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
475ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
476ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
477ffe3c632Sopenharmony_ci      });
478ffe3c632Sopenharmony_ci    }
479ffe3c632Sopenharmony_ci  }
480ffe3c632Sopenharmony_ci});
481ffe3c632Sopenharmony_ci
482ffe3c632Sopenharmony_cidescribe('Writer.writeString does', () => {
483ffe3c632Sopenharmony_ci  let writer;
484ffe3c632Sopenharmony_ci  beforeEach(() => {
485ffe3c632Sopenharmony_ci    writer = new Writer();
486ffe3c632Sopenharmony_ci  });
487ffe3c632Sopenharmony_ci
488ffe3c632Sopenharmony_ci  it('encode empty string', () => {
489ffe3c632Sopenharmony_ci    writer.writeString(1, '');
490ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
491ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
492ffe3c632Sopenharmony_ci            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
493ffe3c632Sopenharmony_ci            0,              // length of the string
494ffe3c632Sopenharmony_ci            ));
495ffe3c632Sopenharmony_ci  });
496ffe3c632Sopenharmony_ci
497ffe3c632Sopenharmony_ci  it('encode simple string', () => {
498ffe3c632Sopenharmony_ci    writer.writeString(1, 'hello');
499ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
500ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
501ffe3c632Sopenharmony_ci            1 << 3 | 0x02,  // tag (fieldnumber << 3 | (length delimited))
502ffe3c632Sopenharmony_ci            5,              // length of the string
503ffe3c632Sopenharmony_ci            'h'.charCodeAt(0),
504ffe3c632Sopenharmony_ci            'e'.charCodeAt(0),
505ffe3c632Sopenharmony_ci            'l'.charCodeAt(0),
506ffe3c632Sopenharmony_ci            'l'.charCodeAt(0),
507ffe3c632Sopenharmony_ci            'o'.charCodeAt(0),
508ffe3c632Sopenharmony_ci            ));
509ffe3c632Sopenharmony_ci  });
510ffe3c632Sopenharmony_ci
511ffe3c632Sopenharmony_ci  it('throw for invalid fieldnumber', () => {
512ffe3c632Sopenharmony_ci    if (CHECK_BOUNDS) {
513ffe3c632Sopenharmony_ci      expect(() => writer.writeString(-1, 'a'))
514ffe3c632Sopenharmony_ci          .toThrowError('Field number is out of range: -1');
515ffe3c632Sopenharmony_ci    } else {
516ffe3c632Sopenharmony_ci      writer.writeString(-1, 'a');
517ffe3c632Sopenharmony_ci      expect(new Uint8Array(writer.getAndResetResultBuffer()))
518ffe3c632Sopenharmony_ci          .toEqual(new Uint8Array(createArrayBuffer(
519ffe3c632Sopenharmony_ci              -6,  // invalid tag
520ffe3c632Sopenharmony_ci              0xff,
521ffe3c632Sopenharmony_ci              0xff,
522ffe3c632Sopenharmony_ci              0xff,
523ffe3c632Sopenharmony_ci              0x0f,
524ffe3c632Sopenharmony_ci              1,  // string length
525ffe3c632Sopenharmony_ci              'a'.charCodeAt(0),
526ffe3c632Sopenharmony_ci              )));
527ffe3c632Sopenharmony_ci    }
528ffe3c632Sopenharmony_ci  });
529ffe3c632Sopenharmony_ci
530ffe3c632Sopenharmony_ci  it('throw for null string value', () => {
531ffe3c632Sopenharmony_ci    expect(
532ffe3c632Sopenharmony_ci        () => writer.writeString(
533ffe3c632Sopenharmony_ci            1, /** @type {string} */ (/** @type {*} */ (null))))
534ffe3c632Sopenharmony_ci        .toThrow();
535ffe3c632Sopenharmony_ci  });
536ffe3c632Sopenharmony_ci});
537ffe3c632Sopenharmony_ci
538ffe3c632Sopenharmony_ci
539ffe3c632Sopenharmony_ci/******************************************************************************
540ffe3c632Sopenharmony_ci *                        REPEATED FUNCTIONS
541ffe3c632Sopenharmony_ci ******************************************************************************/
542ffe3c632Sopenharmony_ci
543ffe3c632Sopenharmony_cidescribe('Writer.writePackedBool does', () => {
544ffe3c632Sopenharmony_ci  let writer;
545ffe3c632Sopenharmony_ci  beforeEach(() => {
546ffe3c632Sopenharmony_ci    writer = new Writer();
547ffe3c632Sopenharmony_ci  });
548ffe3c632Sopenharmony_ci
549ffe3c632Sopenharmony_ci  it('encode empty array', () => {
550ffe3c632Sopenharmony_ci    writer.writePackedBool(1, []);
551ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
552ffe3c632Sopenharmony_ci  });
553ffe3c632Sopenharmony_ci
554ffe3c632Sopenharmony_ci  for (const pair of getPackedBoolPairs()) {
555ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
556ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
557ffe3c632Sopenharmony_ci        writer.writePackedBool(1, pair.boolValues);
558ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
559ffe3c632Sopenharmony_ci        // ensure we have a correct tag
560ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
561ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
562ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
563ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
564ffe3c632Sopenharmony_ci      });
565ffe3c632Sopenharmony_ci    }
566ffe3c632Sopenharmony_ci  }
567ffe3c632Sopenharmony_ci});
568ffe3c632Sopenharmony_ci
569ffe3c632Sopenharmony_cidescribe('Writer.writeRepeatedBool does', () => {
570ffe3c632Sopenharmony_ci  let writer;
571ffe3c632Sopenharmony_ci  beforeEach(() => {
572ffe3c632Sopenharmony_ci    writer = new Writer();
573ffe3c632Sopenharmony_ci  });
574ffe3c632Sopenharmony_ci
575ffe3c632Sopenharmony_ci  it('encode empty array', () => {
576ffe3c632Sopenharmony_ci    writer.writeRepeatedBool(1, []);
577ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
578ffe3c632Sopenharmony_ci  });
579ffe3c632Sopenharmony_ci
580ffe3c632Sopenharmony_ci  it('encode repeated unpacked boolean values', () => {
581ffe3c632Sopenharmony_ci    const writer = new Writer();
582ffe3c632Sopenharmony_ci    writer.writeRepeatedBool(1, [true, false]);
583ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
584ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
585ffe3c632Sopenharmony_ci            1 << 3 | 0x00,  // tag (fieldnumber << 3 | (varint))
586ffe3c632Sopenharmony_ci            0x01,           // value[0]
587ffe3c632Sopenharmony_ci            1 << 3 | 0x00,  // tag (fieldnumber << 3 | (varint))
588ffe3c632Sopenharmony_ci            0x00,           // value[1]
589ffe3c632Sopenharmony_ci            ));
590ffe3c632Sopenharmony_ci  });
591ffe3c632Sopenharmony_ci});
592ffe3c632Sopenharmony_ci
593ffe3c632Sopenharmony_cidescribe('Writer.writePackedDouble does', () => {
594ffe3c632Sopenharmony_ci  let writer;
595ffe3c632Sopenharmony_ci  beforeEach(() => {
596ffe3c632Sopenharmony_ci    writer = new Writer();
597ffe3c632Sopenharmony_ci  });
598ffe3c632Sopenharmony_ci
599ffe3c632Sopenharmony_ci  it('encode empty array', () => {
600ffe3c632Sopenharmony_ci    writer.writePackedDouble(1, []);
601ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
602ffe3c632Sopenharmony_ci  });
603ffe3c632Sopenharmony_ci
604ffe3c632Sopenharmony_ci  for (const pair of getPackedDoublePairs()) {
605ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
606ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
607ffe3c632Sopenharmony_ci        writer.writePackedDouble(1, pair.doubleValues);
608ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
609ffe3c632Sopenharmony_ci        // ensure we have a correct tag
610ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
611ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
612ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
613ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
614ffe3c632Sopenharmony_ci      });
615ffe3c632Sopenharmony_ci    }
616ffe3c632Sopenharmony_ci  }
617ffe3c632Sopenharmony_ci});
618ffe3c632Sopenharmony_ci
619ffe3c632Sopenharmony_cidescribe('Writer.writePackedFixed32 does', () => {
620ffe3c632Sopenharmony_ci  let writer;
621ffe3c632Sopenharmony_ci  beforeEach(() => {
622ffe3c632Sopenharmony_ci    writer = new Writer();
623ffe3c632Sopenharmony_ci  });
624ffe3c632Sopenharmony_ci
625ffe3c632Sopenharmony_ci  it('encode empty array', () => {
626ffe3c632Sopenharmony_ci    writer.writePackedFixed32(1, []);
627ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
628ffe3c632Sopenharmony_ci  });
629ffe3c632Sopenharmony_ci
630ffe3c632Sopenharmony_ci  for (const pair of getPackedFixed32Pairs()) {
631ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
632ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
633ffe3c632Sopenharmony_ci        writer.writePackedFixed32(1, pair.fixed32Values);
634ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
635ffe3c632Sopenharmony_ci        // ensure we have a correct tag
636ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
637ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
638ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
639ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
640ffe3c632Sopenharmony_ci      });
641ffe3c632Sopenharmony_ci    }
642ffe3c632Sopenharmony_ci  }
643ffe3c632Sopenharmony_ci});
644ffe3c632Sopenharmony_ci
645ffe3c632Sopenharmony_cidescribe('Writer.writePackedFloat does', () => {
646ffe3c632Sopenharmony_ci  let writer;
647ffe3c632Sopenharmony_ci  beforeEach(() => {
648ffe3c632Sopenharmony_ci    writer = new Writer();
649ffe3c632Sopenharmony_ci  });
650ffe3c632Sopenharmony_ci
651ffe3c632Sopenharmony_ci  it('encode empty array', () => {
652ffe3c632Sopenharmony_ci    writer.writePackedFloat(1, []);
653ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
654ffe3c632Sopenharmony_ci  });
655ffe3c632Sopenharmony_ci
656ffe3c632Sopenharmony_ci  for (const pair of getPackedFloatPairs()) {
657ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
658ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
659ffe3c632Sopenharmony_ci        writer.writePackedFloat(1, pair.floatValues);
660ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
661ffe3c632Sopenharmony_ci        // ensure we have a correct tag
662ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
663ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
664ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
665ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
666ffe3c632Sopenharmony_ci      });
667ffe3c632Sopenharmony_ci    }
668ffe3c632Sopenharmony_ci  }
669ffe3c632Sopenharmony_ci});
670ffe3c632Sopenharmony_ci
671ffe3c632Sopenharmony_cidescribe('Writer.writePackedInt32 does', () => {
672ffe3c632Sopenharmony_ci  let writer;
673ffe3c632Sopenharmony_ci  beforeEach(() => {
674ffe3c632Sopenharmony_ci    writer = new Writer();
675ffe3c632Sopenharmony_ci  });
676ffe3c632Sopenharmony_ci
677ffe3c632Sopenharmony_ci  it('encode empty array', () => {
678ffe3c632Sopenharmony_ci    writer.writePackedInt32(1, []);
679ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
680ffe3c632Sopenharmony_ci  });
681ffe3c632Sopenharmony_ci
682ffe3c632Sopenharmony_ci  for (const pair of getPackedInt32Pairs()) {
683ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
684ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
685ffe3c632Sopenharmony_ci        writer.writePackedInt32(1, pair.int32Values);
686ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
687ffe3c632Sopenharmony_ci        // ensure we have a correct tag
688ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
689ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
690ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
691ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
692ffe3c632Sopenharmony_ci      });
693ffe3c632Sopenharmony_ci    }
694ffe3c632Sopenharmony_ci  }
695ffe3c632Sopenharmony_ci});
696ffe3c632Sopenharmony_ci
697ffe3c632Sopenharmony_cidescribe('Writer.writePackedInt64 does', () => {
698ffe3c632Sopenharmony_ci  let writer;
699ffe3c632Sopenharmony_ci  beforeEach(() => {
700ffe3c632Sopenharmony_ci    writer = new Writer();
701ffe3c632Sopenharmony_ci  });
702ffe3c632Sopenharmony_ci
703ffe3c632Sopenharmony_ci  it('encode empty array', () => {
704ffe3c632Sopenharmony_ci    writer.writePackedInt64(1, []);
705ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
706ffe3c632Sopenharmony_ci  });
707ffe3c632Sopenharmony_ci
708ffe3c632Sopenharmony_ci  for (const pair of getPackedInt64Pairs()) {
709ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
710ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
711ffe3c632Sopenharmony_ci        writer.writePackedInt64(1, pair.int64Values);
712ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
713ffe3c632Sopenharmony_ci        // ensure we have a correct tag
714ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
715ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
716ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
717ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
718ffe3c632Sopenharmony_ci      });
719ffe3c632Sopenharmony_ci    }
720ffe3c632Sopenharmony_ci  }
721ffe3c632Sopenharmony_ci});
722ffe3c632Sopenharmony_ci
723ffe3c632Sopenharmony_cidescribe('Writer.writePackedSfixed32 does', () => {
724ffe3c632Sopenharmony_ci  let writer;
725ffe3c632Sopenharmony_ci  beforeEach(() => {
726ffe3c632Sopenharmony_ci    writer = new Writer();
727ffe3c632Sopenharmony_ci  });
728ffe3c632Sopenharmony_ci
729ffe3c632Sopenharmony_ci  it('encode empty array', () => {
730ffe3c632Sopenharmony_ci    writer.writePackedSfixed32(1, []);
731ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
732ffe3c632Sopenharmony_ci  });
733ffe3c632Sopenharmony_ci
734ffe3c632Sopenharmony_ci  for (const pair of getPackedSfixed32Pairs()) {
735ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
736ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
737ffe3c632Sopenharmony_ci        writer.writePackedSfixed32(1, pair.sfixed32Values);
738ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
739ffe3c632Sopenharmony_ci        // ensure we have a correct tag
740ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
741ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
742ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
743ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
744ffe3c632Sopenharmony_ci      });
745ffe3c632Sopenharmony_ci    }
746ffe3c632Sopenharmony_ci  }
747ffe3c632Sopenharmony_ci});
748ffe3c632Sopenharmony_ci
749ffe3c632Sopenharmony_cidescribe('Writer.writePackedSfixed64 does', () => {
750ffe3c632Sopenharmony_ci  let writer;
751ffe3c632Sopenharmony_ci  beforeEach(() => {
752ffe3c632Sopenharmony_ci    writer = new Writer();
753ffe3c632Sopenharmony_ci  });
754ffe3c632Sopenharmony_ci
755ffe3c632Sopenharmony_ci  it('encode empty array', () => {
756ffe3c632Sopenharmony_ci    writer.writePackedSfixed64(1, []);
757ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
758ffe3c632Sopenharmony_ci  });
759ffe3c632Sopenharmony_ci
760ffe3c632Sopenharmony_ci  for (const pair of getPackedSfixed64Pairs()) {
761ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
762ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
763ffe3c632Sopenharmony_ci        writer.writePackedSfixed64(1, pair.sfixed64Values);
764ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
765ffe3c632Sopenharmony_ci        // ensure we have a correct tag
766ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
767ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
768ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
769ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
770ffe3c632Sopenharmony_ci      });
771ffe3c632Sopenharmony_ci    }
772ffe3c632Sopenharmony_ci  }
773ffe3c632Sopenharmony_ci});
774ffe3c632Sopenharmony_ci
775ffe3c632Sopenharmony_cidescribe('Writer.writePackedSint32 does', () => {
776ffe3c632Sopenharmony_ci  let writer;
777ffe3c632Sopenharmony_ci  beforeEach(() => {
778ffe3c632Sopenharmony_ci    writer = new Writer();
779ffe3c632Sopenharmony_ci  });
780ffe3c632Sopenharmony_ci
781ffe3c632Sopenharmony_ci  it('encode empty array', () => {
782ffe3c632Sopenharmony_ci    writer.writePackedSint32(1, []);
783ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
784ffe3c632Sopenharmony_ci  });
785ffe3c632Sopenharmony_ci
786ffe3c632Sopenharmony_ci  for (const pair of getPackedSint32Pairs()) {
787ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
788ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
789ffe3c632Sopenharmony_ci        writer.writePackedSint32(1, pair.sint32Values);
790ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
791ffe3c632Sopenharmony_ci        // ensure we have a correct tag
792ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
793ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
794ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
795ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
796ffe3c632Sopenharmony_ci      });
797ffe3c632Sopenharmony_ci    }
798ffe3c632Sopenharmony_ci  }
799ffe3c632Sopenharmony_ci});
800ffe3c632Sopenharmony_ci
801ffe3c632Sopenharmony_cidescribe('Writer.writePackedSint64 does', () => {
802ffe3c632Sopenharmony_ci  let writer;
803ffe3c632Sopenharmony_ci  beforeEach(() => {
804ffe3c632Sopenharmony_ci    writer = new Writer();
805ffe3c632Sopenharmony_ci  });
806ffe3c632Sopenharmony_ci
807ffe3c632Sopenharmony_ci  it('encode empty array', () => {
808ffe3c632Sopenharmony_ci    writer.writePackedSint64(1, []);
809ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
810ffe3c632Sopenharmony_ci  });
811ffe3c632Sopenharmony_ci
812ffe3c632Sopenharmony_ci  for (const pair of getPackedSint64Pairs()) {
813ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
814ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
815ffe3c632Sopenharmony_ci        writer.writePackedSint64(1, pair.sint64Values);
816ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
817ffe3c632Sopenharmony_ci        // ensure we have a correct tag
818ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
819ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
820ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
821ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
822ffe3c632Sopenharmony_ci      });
823ffe3c632Sopenharmony_ci    }
824ffe3c632Sopenharmony_ci  }
825ffe3c632Sopenharmony_ci});
826ffe3c632Sopenharmony_ci
827ffe3c632Sopenharmony_cidescribe('Writer.writePackedUint32 does', () => {
828ffe3c632Sopenharmony_ci  let writer;
829ffe3c632Sopenharmony_ci  beforeEach(() => {
830ffe3c632Sopenharmony_ci    writer = new Writer();
831ffe3c632Sopenharmony_ci  });
832ffe3c632Sopenharmony_ci
833ffe3c632Sopenharmony_ci  it('encode empty array', () => {
834ffe3c632Sopenharmony_ci    writer.writePackedUint32(1, []);
835ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
836ffe3c632Sopenharmony_ci  });
837ffe3c632Sopenharmony_ci
838ffe3c632Sopenharmony_ci  for (const pair of getPackedUint32Pairs()) {
839ffe3c632Sopenharmony_ci    if (!pair.skip_writer) {
840ffe3c632Sopenharmony_ci      it(`encode ${pair.name}`, () => {
841ffe3c632Sopenharmony_ci        writer.writePackedUint32(1, pair.uint32Values);
842ffe3c632Sopenharmony_ci        const buffer = new Uint8Array(writer.getAndResetResultBuffer());
843ffe3c632Sopenharmony_ci        // ensure we have a correct tag
844ffe3c632Sopenharmony_ci        expect(buffer[0]).toEqual(0x0A);
845ffe3c632Sopenharmony_ci        // Encoded values are stored right after the tag
846ffe3c632Sopenharmony_ci        expect(buffer.subarray(1, buffer.length))
847ffe3c632Sopenharmony_ci            .toEqual(pair.bufferDecoder.asUint8Array());
848ffe3c632Sopenharmony_ci      });
849ffe3c632Sopenharmony_ci    }
850ffe3c632Sopenharmony_ci  }
851ffe3c632Sopenharmony_ci});
852ffe3c632Sopenharmony_ci
853ffe3c632Sopenharmony_cidescribe('Writer.writeRepeatedBytes does', () => {
854ffe3c632Sopenharmony_ci  let writer;
855ffe3c632Sopenharmony_ci  beforeEach(() => {
856ffe3c632Sopenharmony_ci    writer = new Writer();
857ffe3c632Sopenharmony_ci  });
858ffe3c632Sopenharmony_ci
859ffe3c632Sopenharmony_ci  it('encode empty array', () => {
860ffe3c632Sopenharmony_ci    writer.writeRepeatedBytes(1, []);
861ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
862ffe3c632Sopenharmony_ci  });
863ffe3c632Sopenharmony_ci
864ffe3c632Sopenharmony_ci  it('encode single value', () => {
865ffe3c632Sopenharmony_ci    const value = createArrayBuffer(0x61);
866ffe3c632Sopenharmony_ci    writer.writeRepeatedBytes(1, [ByteString.fromArrayBuffer(value)]);
867ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
868ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
869ffe3c632Sopenharmony_ci            0x0A,
870ffe3c632Sopenharmony_ci            0x01,
871ffe3c632Sopenharmony_ci            0x61,  // a
872ffe3c632Sopenharmony_ci            ));
873ffe3c632Sopenharmony_ci  });
874ffe3c632Sopenharmony_ci
875ffe3c632Sopenharmony_ci  it('encode multiple values', () => {
876ffe3c632Sopenharmony_ci    const value1 = createArrayBuffer(0x61);
877ffe3c632Sopenharmony_ci    const value2 = createArrayBuffer(0x62);
878ffe3c632Sopenharmony_ci    writer.writeRepeatedBytes(1, [
879ffe3c632Sopenharmony_ci      ByteString.fromArrayBuffer(value1),
880ffe3c632Sopenharmony_ci      ByteString.fromArrayBuffer(value2),
881ffe3c632Sopenharmony_ci    ]);
882ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
883ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
884ffe3c632Sopenharmony_ci            0x0A,
885ffe3c632Sopenharmony_ci            0x01,
886ffe3c632Sopenharmony_ci            0x61,  // a
887ffe3c632Sopenharmony_ci            0x0A,
888ffe3c632Sopenharmony_ci            0x01,
889ffe3c632Sopenharmony_ci            0x62,  // b
890ffe3c632Sopenharmony_ci            ));
891ffe3c632Sopenharmony_ci  });
892ffe3c632Sopenharmony_ci});
893ffe3c632Sopenharmony_ci
894ffe3c632Sopenharmony_cidescribe('Writer.writeRepeatedString does', () => {
895ffe3c632Sopenharmony_ci  let writer;
896ffe3c632Sopenharmony_ci  beforeEach(() => {
897ffe3c632Sopenharmony_ci    writer = new Writer();
898ffe3c632Sopenharmony_ci  });
899ffe3c632Sopenharmony_ci
900ffe3c632Sopenharmony_ci  it('encode empty array', () => {
901ffe3c632Sopenharmony_ci    writer.writeRepeatedString(1, []);
902ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
903ffe3c632Sopenharmony_ci  });
904ffe3c632Sopenharmony_ci
905ffe3c632Sopenharmony_ci  it('encode single value', () => {
906ffe3c632Sopenharmony_ci    writer.writeRepeatedString(1, ['a']);
907ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
908ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
909ffe3c632Sopenharmony_ci            0x0A,
910ffe3c632Sopenharmony_ci            0x01,
911ffe3c632Sopenharmony_ci            0x61,  // a
912ffe3c632Sopenharmony_ci            ));
913ffe3c632Sopenharmony_ci  });
914ffe3c632Sopenharmony_ci
915ffe3c632Sopenharmony_ci  it('encode multiple values', () => {
916ffe3c632Sopenharmony_ci    writer.writeRepeatedString(1, ['a', 'b']);
917ffe3c632Sopenharmony_ci    expect(writer.getAndResetResultBuffer())
918ffe3c632Sopenharmony_ci        .toEqual(createArrayBuffer(
919ffe3c632Sopenharmony_ci            0x0A,
920ffe3c632Sopenharmony_ci            0x01,
921ffe3c632Sopenharmony_ci            0x61,  // a
922ffe3c632Sopenharmony_ci            0x0A,
923ffe3c632Sopenharmony_ci            0x01,
924ffe3c632Sopenharmony_ci            0x62,  // b
925ffe3c632Sopenharmony_ci            ));
926ffe3c632Sopenharmony_ci  });
927ffe3c632Sopenharmony_ci});
928