1ffe3c632Sopenharmony_ci/**
2ffe3c632Sopenharmony_ci * @fileoverview Tests for BufferDecoder.
3ffe3c632Sopenharmony_ci */
4ffe3c632Sopenharmony_ci
5ffe3c632Sopenharmony_cigoog.module('protobuf.binary.varintsTest');
6ffe3c632Sopenharmony_ci
7ffe3c632Sopenharmony_ciconst BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
8ffe3c632Sopenharmony_ciconst {CHECK_CRITICAL_STATE, CHECK_STATE} = goog.require('protobuf.internal.checks');
9ffe3c632Sopenharmony_ci
10ffe3c632Sopenharmony_cigoog.setTestOnly();
11ffe3c632Sopenharmony_ci
12ffe3c632Sopenharmony_ci/**
13ffe3c632Sopenharmony_ci * @param {...number} bytes
14ffe3c632Sopenharmony_ci * @return {!ArrayBuffer}
15ffe3c632Sopenharmony_ci */
16ffe3c632Sopenharmony_cifunction createArrayBuffer(...bytes) {
17ffe3c632Sopenharmony_ci  return new Uint8Array(bytes).buffer;
18ffe3c632Sopenharmony_ci}
19ffe3c632Sopenharmony_ci
20ffe3c632Sopenharmony_cidescribe('setCursor does', () => {
21ffe3c632Sopenharmony_ci  it('set the cursor at the position specified', () => {
22ffe3c632Sopenharmony_ci    const bufferDecoder =
23ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1));
24ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(0);
25ffe3c632Sopenharmony_ci    bufferDecoder.setCursor(1);
26ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
27ffe3c632Sopenharmony_ci  });
28ffe3c632Sopenharmony_ci});
29ffe3c632Sopenharmony_ci
30ffe3c632Sopenharmony_cidescribe('skip does', () => {
31ffe3c632Sopenharmony_ci  it('advance the cursor', () => {
32ffe3c632Sopenharmony_ci    const bufferDecoder =
33ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1, 0x2));
34ffe3c632Sopenharmony_ci    bufferDecoder.setCursor(1);
35ffe3c632Sopenharmony_ci    bufferDecoder.skip(1);
36ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(2);
37ffe3c632Sopenharmony_ci  });
38ffe3c632Sopenharmony_ci});
39ffe3c632Sopenharmony_ci
40ffe3c632Sopenharmony_cidescribe('Skip varint does', () => {
41ffe3c632Sopenharmony_ci  it('skip a varint', () => {
42ffe3c632Sopenharmony_ci    const bufferDecoder =
43ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
44ffe3c632Sopenharmony_ci    bufferDecoder.skipVarint();
45ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
46ffe3c632Sopenharmony_ci  });
47ffe3c632Sopenharmony_ci
48ffe3c632Sopenharmony_ci  it('fail when varint is larger than 10 bytes', () => {
49ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
50ffe3c632Sopenharmony_ci        0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00));
51ffe3c632Sopenharmony_ci
52ffe3c632Sopenharmony_ci    if (CHECK_CRITICAL_STATE) {
53ffe3c632Sopenharmony_ci      expect(() => bufferDecoder.skipVarint()).toThrow();
54ffe3c632Sopenharmony_ci    } else {
55ffe3c632Sopenharmony_ci      // Note in unchecked mode we produce invalid output for invalid inputs.
56ffe3c632Sopenharmony_ci      // This test just documents our behavior in those cases.
57ffe3c632Sopenharmony_ci      // These values might change at any point and are not considered
58ffe3c632Sopenharmony_ci      // what the implementation should be doing here.
59ffe3c632Sopenharmony_ci      bufferDecoder.skipVarint();
60ffe3c632Sopenharmony_ci      expect(bufferDecoder.cursor()).toBe(11);
61ffe3c632Sopenharmony_ci    }
62ffe3c632Sopenharmony_ci  });
63ffe3c632Sopenharmony_ci
64ffe3c632Sopenharmony_ci  it('fail when varint is beyond end of underlying array', () => {
65ffe3c632Sopenharmony_ci    const bufferDecoder =
66ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x80));
67ffe3c632Sopenharmony_ci    expect(() => bufferDecoder.skipVarint()).toThrow();
68ffe3c632Sopenharmony_ci  });
69ffe3c632Sopenharmony_ci});
70ffe3c632Sopenharmony_ci
71ffe3c632Sopenharmony_cidescribe('readVarint64 does', () => {
72ffe3c632Sopenharmony_ci  it('read zero', () => {
73ffe3c632Sopenharmony_ci    const bufferDecoder =
74ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00));
75ffe3c632Sopenharmony_ci    const {lowBits, highBits} = bufferDecoder.getVarint(0);
76ffe3c632Sopenharmony_ci    expect(lowBits).toBe(0);
77ffe3c632Sopenharmony_ci    expect(highBits).toBe(0);
78ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
79ffe3c632Sopenharmony_ci  });
80ffe3c632Sopenharmony_ci
81ffe3c632Sopenharmony_ci  it('read one', () => {
82ffe3c632Sopenharmony_ci    const bufferDecoder =
83ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
84ffe3c632Sopenharmony_ci    const {lowBits, highBits} = bufferDecoder.getVarint(0);
85ffe3c632Sopenharmony_ci    expect(lowBits).toBe(1);
86ffe3c632Sopenharmony_ci    expect(highBits).toBe(0);
87ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
88ffe3c632Sopenharmony_ci  });
89ffe3c632Sopenharmony_ci
90ffe3c632Sopenharmony_ci  it('read max value', () => {
91ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
92ffe3c632Sopenharmony_ci        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
93ffe3c632Sopenharmony_ci    const {lowBits, highBits} = bufferDecoder.getVarint(0);
94ffe3c632Sopenharmony_ci    expect(lowBits).toBe(-1);
95ffe3c632Sopenharmony_ci    expect(highBits).toBe(-1);
96ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(10);
97ffe3c632Sopenharmony_ci  });
98ffe3c632Sopenharmony_ci});
99ffe3c632Sopenharmony_ci
100ffe3c632Sopenharmony_cidescribe('readUnsignedVarint32 does', () => {
101ffe3c632Sopenharmony_ci  it('read zero', () => {
102ffe3c632Sopenharmony_ci    const bufferDecoder =
103ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00));
104ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUnsignedVarint32();
105ffe3c632Sopenharmony_ci    expect(result).toBe(0);
106ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
107ffe3c632Sopenharmony_ci  });
108ffe3c632Sopenharmony_ci
109ffe3c632Sopenharmony_ci  it('read one', () => {
110ffe3c632Sopenharmony_ci    const bufferDecoder =
111ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
112ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUnsignedVarint32();
113ffe3c632Sopenharmony_ci    expect(result).toBe(1);
114ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(1);
115ffe3c632Sopenharmony_ci  });
116ffe3c632Sopenharmony_ci
117ffe3c632Sopenharmony_ci  it('read max int32', () => {
118ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
119ffe3c632Sopenharmony_ci        createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF, 0x0F));
120ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUnsignedVarint32();
121ffe3c632Sopenharmony_ci    expect(result).toBe(4294967295);
122ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(5);
123ffe3c632Sopenharmony_ci  });
124ffe3c632Sopenharmony_ci
125ffe3c632Sopenharmony_ci  it('read max value', () => {
126ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
127ffe3c632Sopenharmony_ci        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
128ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUnsignedVarint32();
129ffe3c632Sopenharmony_ci    expect(result).toBe(4294967295);
130ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(10);
131ffe3c632Sopenharmony_ci  });
132ffe3c632Sopenharmony_ci
133ffe3c632Sopenharmony_ci  it('fail if data is longer than 10 bytes', () => {
134ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
135ffe3c632Sopenharmony_ci        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
136ffe3c632Sopenharmony_ci    if (CHECK_CRITICAL_STATE) {
137ffe3c632Sopenharmony_ci      expect(() => bufferDecoder.getUnsignedVarint32()).toThrow();
138ffe3c632Sopenharmony_ci    } else {
139ffe3c632Sopenharmony_ci      // Note in unchecked mode we produce invalid output for invalid inputs.
140ffe3c632Sopenharmony_ci      // This test just documents our behavior in those cases.
141ffe3c632Sopenharmony_ci      // These values might change at any point and are not considered
142ffe3c632Sopenharmony_ci      // what the implementation should be doing here.
143ffe3c632Sopenharmony_ci      const result = bufferDecoder.getUnsignedVarint32();
144ffe3c632Sopenharmony_ci      expect(result).toBe(4294967295);
145ffe3c632Sopenharmony_ci      expect(bufferDecoder.cursor()).toBe(10);
146ffe3c632Sopenharmony_ci    }
147ffe3c632Sopenharmony_ci  });
148ffe3c632Sopenharmony_ci});
149ffe3c632Sopenharmony_ci
150ffe3c632Sopenharmony_cidescribe('readUnsignedVarint32At does', () => {
151ffe3c632Sopenharmony_ci  it('reads from a specific index', () => {
152ffe3c632Sopenharmony_ci    const bufferDecoder =
153ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x1, 0x2));
154ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUnsignedVarint32At(1);
155ffe3c632Sopenharmony_ci    expect(result).toBe(2);
156ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(2);
157ffe3c632Sopenharmony_ci  });
158ffe3c632Sopenharmony_ci});
159ffe3c632Sopenharmony_ci
160ffe3c632Sopenharmony_cidescribe('getFloat32 does', () => {
161ffe3c632Sopenharmony_ci  it('read one', () => {
162ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
163ffe3c632Sopenharmony_ci        createArrayBuffer(0x00, 0x00, 0x80, 0x3F));
164ffe3c632Sopenharmony_ci    const result = bufferDecoder.getFloat32(0);
165ffe3c632Sopenharmony_ci    expect(result).toBe(1);
166ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(4);
167ffe3c632Sopenharmony_ci  });
168ffe3c632Sopenharmony_ci});
169ffe3c632Sopenharmony_ci
170ffe3c632Sopenharmony_cidescribe('getFloat64 does', () => {
171ffe3c632Sopenharmony_ci  it('read one', () => {
172ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
173ffe3c632Sopenharmony_ci        createArrayBuffer(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F));
174ffe3c632Sopenharmony_ci    const result = bufferDecoder.getFloat64(0);
175ffe3c632Sopenharmony_ci    expect(result).toBe(1);
176ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(8);
177ffe3c632Sopenharmony_ci  });
178ffe3c632Sopenharmony_ci});
179ffe3c632Sopenharmony_ci
180ffe3c632Sopenharmony_cidescribe('getInt32 does', () => {
181ffe3c632Sopenharmony_ci  it('read one', () => {
182ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
183ffe3c632Sopenharmony_ci        createArrayBuffer(0x01, 0x00, 0x00, 0x00));
184ffe3c632Sopenharmony_ci    const result = bufferDecoder.getInt32(0);
185ffe3c632Sopenharmony_ci    expect(result).toBe(1);
186ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(4);
187ffe3c632Sopenharmony_ci  });
188ffe3c632Sopenharmony_ci
189ffe3c632Sopenharmony_ci  it('read minus one', () => {
190ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
191ffe3c632Sopenharmony_ci        createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF));
192ffe3c632Sopenharmony_ci    const result = bufferDecoder.getInt32(0);
193ffe3c632Sopenharmony_ci    expect(result).toBe(-1);
194ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(4);
195ffe3c632Sopenharmony_ci  });
196ffe3c632Sopenharmony_ci});
197ffe3c632Sopenharmony_ci
198ffe3c632Sopenharmony_cidescribe('getUint32 does', () => {
199ffe3c632Sopenharmony_ci  it('read one', () => {
200ffe3c632Sopenharmony_ci    const bufferDecoder =
201ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x00, 0x00, 0x0));
202ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUint32(0);
203ffe3c632Sopenharmony_ci    expect(result).toBe(1);
204ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(4);
205ffe3c632Sopenharmony_ci  });
206ffe3c632Sopenharmony_ci
207ffe3c632Sopenharmony_ci  it('read max uint32', () => {
208ffe3c632Sopenharmony_ci    const bufferDecoder = BufferDecoder.fromArrayBuffer(
209ffe3c632Sopenharmony_ci        createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF));
210ffe3c632Sopenharmony_ci    const result = bufferDecoder.getUint32(0);
211ffe3c632Sopenharmony_ci    expect(result).toBe(4294967295);
212ffe3c632Sopenharmony_ci    expect(bufferDecoder.cursor()).toBe(4);
213ffe3c632Sopenharmony_ci  });
214ffe3c632Sopenharmony_ci});
215ffe3c632Sopenharmony_ci
216ffe3c632Sopenharmony_cidescribe('subBufferDecoder does', () => {
217ffe3c632Sopenharmony_ci  it('can create valid sub buffers', () => {
218ffe3c632Sopenharmony_ci    const bufferDecoder =
219ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02));
220ffe3c632Sopenharmony_ci
221ffe3c632Sopenharmony_ci    expect(bufferDecoder.subBufferDecoder(0, 0))
222ffe3c632Sopenharmony_ci        .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer()));
223ffe3c632Sopenharmony_ci    expect(bufferDecoder.subBufferDecoder(0, 1))
224ffe3c632Sopenharmony_ci        .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)));
225ffe3c632Sopenharmony_ci    expect(bufferDecoder.subBufferDecoder(1, 0))
226ffe3c632Sopenharmony_ci        .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer()));
227ffe3c632Sopenharmony_ci    expect(bufferDecoder.subBufferDecoder(1, 1))
228ffe3c632Sopenharmony_ci        .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)));
229ffe3c632Sopenharmony_ci    expect(bufferDecoder.subBufferDecoder(1, 2))
230ffe3c632Sopenharmony_ci        .toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x02)));
231ffe3c632Sopenharmony_ci  });
232ffe3c632Sopenharmony_ci
233ffe3c632Sopenharmony_ci  it('can not create invalid', () => {
234ffe3c632Sopenharmony_ci    const bufferDecoder =
235ffe3c632Sopenharmony_ci        BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02));
236ffe3c632Sopenharmony_ci    if (CHECK_STATE) {
237ffe3c632Sopenharmony_ci      expect(() => bufferDecoder.subBufferDecoder(-1, 1)).toThrow();
238ffe3c632Sopenharmony_ci      expect(() => bufferDecoder.subBufferDecoder(0, -4)).toThrow();
239ffe3c632Sopenharmony_ci      expect(() => bufferDecoder.subBufferDecoder(0, 4)).toThrow();
240ffe3c632Sopenharmony_ci    }
241ffe3c632Sopenharmony_ci  });
242ffe3c632Sopenharmony_ci});
243