Skip to content

Commit eb49d4d

Browse files
authored
Merge 5e131e3 into ab3f16c
2 parents ab3f16c + 5e131e3 commit eb49d4d

File tree

3 files changed

+294
-0
lines changed

3 files changed

+294
-0
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/**
2+
* @license
3+
* Copyright 2022 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
// Add some unit tests for classes exported from @firebase/webchannel-wrapper.
19+
// These tests are mostly to ensure that the exported classes correctly map to
20+
// underlying functionality from google-closure-library.
21+
22+
import { Integer } from '@firebase/webchannel-wrapper';
23+
import { expect } from 'chai';
24+
25+
describe('Integer', () => {
26+
it('constructor should create distinct instances', () => {
27+
const instance1 = new Integer([1], 0);
28+
const instance2 = new Integer([1], 0);
29+
expect(instance1).is.instanceof(Integer);
30+
expect(instance2).is.instanceof(Integer);
31+
expect(instance1).is.not.equal(instance2);
32+
});
33+
34+
it('constructor should construct 1 and -1, 2 and -2', () => {
35+
const positiveOne = new Integer([1], 0);
36+
expect(positiveOne.toNumber()).equals(1);
37+
const negativeOne = new Integer([-1], -1);
38+
expect(negativeOne.toNumber()).equals(-1);
39+
const positiveTwo = new Integer([2], 0);
40+
expect(positiveTwo.toNumber()).equals(2);
41+
const negativeTwo = new Integer([-2], -1);
42+
expect(negativeTwo.toNumber()).equals(-2);
43+
});
44+
45+
it('constructor should construct big positive values', () => {
46+
expect(new Integer([0xff], 0).toNumber()).equals(255);
47+
expect(new Integer([0xffff], 0).toNumber()).equals(65535);
48+
expect(new Integer([0xffffff], 0).toNumber()).equals(16777215);
49+
expect(new Integer([0xffffffff], 0).toNumber()).equals(4294967295);
50+
expect(new Integer([0, 1], 0).toNumber()).equals(4294967296);
51+
expect(new Integer([1, 1], 0).toNumber()).equals(4294967297);
52+
expect(new Integer([0xfffffffe, 1], 0).toNumber()).equals(8589934590);
53+
expect(new Integer([0xffffffff, 1], 0).toNumber()).equals(8589934591);
54+
expect(new Integer([0, 2], 0).toNumber()).equals(8589934592);
55+
expect(new Integer([1, 2], 0).toNumber()).equals(8589934593);
56+
expect(
57+
new Integer(
58+
[0x992ce530, 0xbc1f3bbb, 0x2080e2ee, 0xe53c0595],
59+
0
60+
).toString()
61+
).equals('304704862073361391914321619654827369776');
62+
});
63+
64+
it('constructor should construct big negative values', () => {
65+
expect(new Integer([0xffffffff], -1).toNumber()).equals(-1);
66+
expect(new Integer([0xfffffffe], -1).toNumber()).equals(-2);
67+
expect(new Integer([0xfffffffd], -1).toNumber()).equals(-3);
68+
expect(new Integer([0xfffffff0], -1).toNumber()).equals(-16);
69+
expect(new Integer([0xffffff00], -1).toNumber()).equals(-256);
70+
expect(new Integer([0xfffff000], -1).toNumber()).equals(-4096);
71+
expect(new Integer([0xffff0000], -1).toNumber()).equals(-65536);
72+
expect(new Integer([0xfff00000], -1).toNumber()).equals(-1048576);
73+
expect(new Integer([0xff000000], -1).toNumber()).equals(-16777216);
74+
expect(new Integer([0xf0000000], -1).toNumber()).equals(-268435456);
75+
expect(new Integer([0x00000001], -1).toNumber()).equals(-4294967295);
76+
expect(new Integer([0x00000000], -1).toNumber()).equals(-4294967296);
77+
expect(new Integer([0x00000000, 0xffffffff], -1).toNumber()).equals(
78+
-4294967296
79+
);
80+
expect(new Integer([0xffffffff, 0xfffffffe], -1).toNumber()).equals(
81+
-4294967297
82+
);
83+
expect(new Integer([0xfffffffe, 0xfffffffe], -1).toNumber()).equals(
84+
-4294967298
85+
);
86+
});
87+
88+
it('add() should produce the sum of the two numbers', () => {
89+
expect(Integer.fromNumber(0).add(Integer.fromNumber(0)).toNumber()).equals(
90+
0
91+
);
92+
expect(Integer.fromNumber(1).add(Integer.fromNumber(1)).toNumber()).equals(
93+
2
94+
);
95+
expect(
96+
Integer.fromNumber(0xffffffff).add(Integer.fromNumber(1)).toNumber()
97+
).equals(4294967296);
98+
expect(
99+
Integer.fromString('304704862073361391914321619654827369776')
100+
.add(Integer.fromString('77393247566944052149773810817307943505'))
101+
.toString()
102+
).equals('382098109640305444064095430472135313281');
103+
expect(Integer.fromNumber(0).add(Integer.fromNumber(-1)).toNumber()).equals(
104+
-1
105+
);
106+
});
107+
108+
it('multiply() should produce the product of the two numbers', () => {
109+
expect(
110+
Integer.fromNumber(0).multiply(Integer.fromNumber(0)).toNumber()
111+
).equals(0);
112+
expect(
113+
Integer.fromNumber(1).multiply(Integer.fromNumber(0)).toNumber()
114+
).equals(0);
115+
expect(
116+
Integer.fromNumber(1).multiply(Integer.fromNumber(1)).toNumber()
117+
).equals(1);
118+
expect(
119+
Integer.fromNumber(9).multiply(Integer.fromNumber(3)).toNumber()
120+
).equals(27);
121+
expect(
122+
Integer.fromNumber(0xffffffff)
123+
.multiply(Integer.fromNumber(0xca11ba11))
124+
.toString()
125+
).equals('14560623649052575215');
126+
expect(
127+
Integer.fromString('304704862073361391914321619654827369776')
128+
.multiply(Integer.fromString('77393247566944052149773810817307943505'))
129+
.toString()
130+
).equals(
131+
'23582098825295199538298333106941184620809785262540690532878112097410752504880'
132+
);
133+
expect(
134+
Integer.fromNumber(5).multiply(Integer.fromNumber(-1)).toNumber()
135+
).equals(-5);
136+
});
137+
138+
it('modulo() should produce the division remainder of the two numbers', () => {
139+
expect(() => Integer.fromNumber(0).modulo(Integer.fromNumber(0))).to.throw(
140+
'division by zero'
141+
);
142+
expect(() => Integer.fromNumber(42).modulo(Integer.fromNumber(0))).to.throw(
143+
'division by zero'
144+
);
145+
expect(
146+
Integer.fromNumber(20).modulo(Integer.fromNumber(1)).toNumber()
147+
).equals(0);
148+
expect(
149+
Integer.fromNumber(2).modulo(Integer.fromNumber(2)).toNumber()
150+
).equals(0);
151+
expect(
152+
Integer.fromNumber(3).modulo(Integer.fromNumber(2)).toNumber()
153+
).equals(1);
154+
expect(
155+
Integer.fromNumber(4).modulo(Integer.fromNumber(2)).toNumber()
156+
).equals(0);
157+
expect(
158+
Integer.fromNumber(0xffffffff)
159+
.modulo(Integer.fromNumber(0xca11ba11))
160+
.toNumber()
161+
).equals(904807918);
162+
expect(
163+
Integer.fromString('304704862073361391914321619654827369776')
164+
.modulo(Integer.fromString('77393247566944052149773810817307943505'))
165+
.toString()
166+
).equals('72525119372529235465000187202903539261');
167+
expect(
168+
Integer.fromString('304704862073361391914321619654827369776')
169+
.modulo(Integer.fromNumber(313))
170+
.toNumber()
171+
).equals(167);
172+
});
173+
174+
it('compare() should correctly compare two numbers for order', () => {
175+
const numbers = Object.freeze([
176+
Integer.fromNumber(-4294967298),
177+
Integer.fromNumber(-2),
178+
Integer.fromNumber(-1),
179+
Integer.fromNumber(0),
180+
Integer.fromNumber(1),
181+
Integer.fromNumber(2),
182+
Integer.fromNumber(0xffffffff),
183+
Integer.fromString('77393247566944052149773810817307943505'),
184+
Integer.fromString('304704862073361391914321619654827369776')
185+
]);
186+
for (let i1 = 0; i1 < numbers.length; i1++) {
187+
for (let i2 = 0; i2 < numbers.length; i2++) {
188+
const num1 = numbers[i1];
189+
const num2 = numbers[i2];
190+
const expected = i1 === i2 ? 0 : i1 < i2 ? -1 : 1;
191+
expect(num1.compare(num2)).equals(expected);
192+
}
193+
}
194+
});
195+
196+
it('toNumber() should return the correct number', () => {
197+
const one = Integer.fromNumber(1);
198+
const two = Integer.fromNumber(2);
199+
expect(Integer.fromNumber(0).toNumber()).equals(0);
200+
expect(Integer.fromNumber(1).toNumber()).equals(1);
201+
expect(Integer.fromNumber(-1).toNumber()).equals(-1);
202+
expect(Integer.fromNumber(Number.MAX_SAFE_INTEGER).toNumber()).equals(
203+
Number.MAX_SAFE_INTEGER
204+
);
205+
expect(Integer.fromNumber(Number.MIN_SAFE_INTEGER).toNumber()).equals(
206+
Number.MIN_SAFE_INTEGER
207+
);
208+
expect(
209+
Integer.fromNumber(Number.MAX_SAFE_INTEGER).add(one).toNumber()
210+
).equals(Number.MAX_SAFE_INTEGER + 1);
211+
expect(
212+
Integer.fromNumber(Number.MAX_SAFE_INTEGER).add(two).toNumber()
213+
).equals(Number.MAX_SAFE_INTEGER + 1);
214+
});
215+
216+
it('toString() should return the correct number', () => {
217+
const one = Integer.fromNumber(1);
218+
const two = Integer.fromNumber(2);
219+
expect(Integer.fromNumber(0).toString()).equals('0');
220+
expect(Integer.fromNumber(1).toString()).equals('1');
221+
expect(Integer.fromNumber(-1).toString()).equals('-1');
222+
expect(Integer.fromNumber(Number.MAX_SAFE_INTEGER).toString()).equals(
223+
'9007199254740991'
224+
);
225+
expect(Integer.fromNumber(Number.MIN_SAFE_INTEGER).toString()).equals(
226+
'-9007199254740991'
227+
);
228+
expect(
229+
Integer.fromNumber(Number.MAX_SAFE_INTEGER).add(one).toString()
230+
).equals('9007199254740992');
231+
expect(
232+
Integer.fromNumber(Number.MAX_SAFE_INTEGER).add(two).toString()
233+
).equals('9007199254740993');
234+
expect(
235+
Integer.fromString('304704862073361391914321619654827369776').toString()
236+
).equals('304704862073361391914321619654827369776');
237+
238+
expect(Integer.fromNumber(0).toString(2)).equals('0');
239+
expect(Integer.fromNumber(43981).toString(2)).equals('1010101111001101');
240+
expect(Integer.fromNumber(43981).toString(8)).equals('125715');
241+
expect(Integer.fromNumber(43981).toString(10)).equals('43981');
242+
expect(Integer.fromNumber(43981).toString(16)).equals('abcd');
243+
});
244+
245+
it('fromNumber() create a new Integer with the given value', () => {
246+
// The tests for toString() and toNumber() cover this method.
247+
});
248+
249+
it('fromString() create a new Integer with the given value', () => {
250+
expect(Integer.fromString('0').toNumber()).equals(0);
251+
expect(Integer.fromString('1').toNumber()).equals(1);
252+
expect(Integer.fromString('-1').toNumber()).equals(-1);
253+
expect(Integer.fromString('42').toNumber()).equals(42);
254+
expect(Integer.fromString('9007199254740991').toNumber()).equals(
255+
Number.MAX_SAFE_INTEGER
256+
);
257+
expect(Integer.fromString('-9007199254740991').toNumber()).equals(
258+
Number.MIN_SAFE_INTEGER
259+
);
260+
expect(
261+
Integer.fromString('304704862073361391914321619654827369776').toString()
262+
).equals('304704862073361391914321619654827369776');
263+
264+
expect(Integer.fromString('abcd', 16).toNumber()).equals(43981);
265+
expect(Integer.fromString('125715', 8).toNumber()).equals(43981);
266+
expect(Integer.fromString('1010101111001101', 2).toNumber()).equals(43981);
267+
});
268+
});

packages/webchannel-wrapper/src/index.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,18 @@ export function getStatEventTarget(): EventTarget;
136136
export class FetchXmlHttpFactory {
137137
constructor(options: {});
138138
}
139+
140+
// See https://google.github.io/closure-library/api/goog.math.Integer.html
141+
// Unit test are written in
142+
// packages/firestore/test/unit/core/webchannel_wrapper.test.ts
143+
export class Integer {
144+
constructor(bits: Array<number>, sign: number);
145+
add(other: Integer): Integer;
146+
multiply(other: Integer): Integer;
147+
modulo(other: Integer): Integer;
148+
compare(other: Integer): number;
149+
toNumber(): number;
150+
toString(opt_radix?: number): string;
151+
static fromNumber(value: number): Integer;
152+
static fromString(str: string, opt_radix?: number): Integer;
153+
}

packages/webchannel-wrapper/src/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ goog.net.XhrIo.prototype['send'] = goog.net.XhrIo.prototype.send;
7878
goog.net.XhrIo.prototype['setWithCredentials'] =
7979
goog.net.XhrIo.prototype.setWithCredentials;
8080

81+
goog.require('goog.math.Integer');
82+
goog.math.Integer.prototype['add'] = goog.math.Integer.prototype.add;
83+
goog.math.Integer.prototype['multiply'] = goog.math.Integer.prototype.multiply;
84+
goog.math.Integer.prototype['modulo'] = goog.math.Integer.prototype.modulo;
85+
goog.math.Integer.prototype['compare'] = goog.math.Integer.prototype.compare;
86+
goog.math.Integer.prototype['toNumber'] = goog.math.Integer.prototype.toNumber;
87+
goog.math.Integer.prototype['toString'] = goog.math.Integer.prototype.toString;
88+
goog.math.Integer['fromNumber'] = goog.math.Integer.fromNumber;
89+
goog.math.Integer['fromString'] = goog.math.Integer.fromString;
90+
8191
module['exports']['createWebChannelTransport'] =
8292
goog.net.createWebChannelTransport;
8393
module['exports']['getStatEventTarget'] =
@@ -89,3 +99,4 @@ module['exports']['Stat'] = goog.labs.net.webChannel.requestStats.Stat;
8999
module['exports']['FetchXmlHttpFactory'] = goog.net.FetchXmlHttpFactory;
90100
module['exports']['WebChannel'] = goog.net.WebChannel;
91101
module['exports']['XhrIo'] = goog.net.XhrIo;
102+
module['exports']['Integer'] = goog.math.Integer;

0 commit comments

Comments
 (0)