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