1/*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16function test_create_empty_bigint(): void {
17    let a = new BigInt()
18    assert a.positive()
19    assert a == 0n
20
21    let b = new BigInt()
22    assert b.positive()
23    assert b == 0n
24}
25
26function test_invalid_bigint(): void {
27    // NOTE(kkonsw): implement validation
28}
29
30function test_bigint_as_string(): void {
31    assert new BigInt("10").toString() == "10"
32    assert new BigInt("1000").toString() == "1000"
33    assert new BigInt("-1000").toString() == "-1000"
34    assert new BigInt("-1").toString() == "-1"
35    assert new BigInt("-10").toString() == "-10"
36    assert new BigInt("-100").toString() == "-100"
37    assert new BigInt("-100000000000000").toString() == "-100000000000000"
38    assert new BigInt("0").toString() == "0"
39}
40
41function test_type(): void {
42    let num0 = 0n;
43    let num1 = 100_100_100_100_100_100n
44    let num2 = -57896044618658097711785492504343953926634992332820282019728792003956564819967n
45
46    assert (num0 instanceof bigint)
47    assert (num1 instanceof bigint)
48    assert (num2 instanceof bigint)
49}
50
51function test_assignment(): void {
52    let a = -24059059045444224545405903904190343043049209420234290480n
53    let b = a
54    assert (a instanceof bigint)
55    assert (b instanceof bigint)
56    assert (a == b);
57
58    a = 123n;
59    assert (a instanceof bigint)
60    assert (a.toString() == "123");
61    assert (a == 123n);
62
63    const zero = 0n;
64    let c = zero;
65    assert (zero instanceof bigint)
66    assert (c instanceof bigint)
67    assert (zero == c);
68}
69
70function test_compare(): void {
71    const a = 24400569094091093912039019089543850580328542852805043n
72    const b = 34034240244909504590902901119302940942904944029040950n
73
74    assert 44493059209094029409209402940924902n < 140044940590459049067274048929058908989042385n
75    assert 44493059209094029409209402940924902n < a
76    assert a < 34034240244909504590902901119302940942904944029040950n
77    assert a < b
78
79    assert 44493059209094029409209402940924902n <= 140044940590459049067274048929058908989042385n
80    assert 44493059209094029409209402940924902n <= a
81    assert a <= 34034240244909504590902901119302940942904944029040950n
82    assert a <= b
83
84    assert 44493059209094029409209402940924902n <= 44493059209094029409209402940924902n
85    assert 24400569094091093912039019089543850580328542852805043n <= a
86    assert a <= 24400569094091093912039019089543850580328542852805043n
87    assert a <= a
88
89    assert 40044940590459049067274048929058908989042385n > 44493059209094029409209402940924902n
90    assert 34034240244909504590902901119302940942904944029040950n > a
91    assert a > 140044940590459049067274048929058908989042385n
92    assert b > a
93
94    assert 40044940590459049067274048929058908989042385n >= 44493059209094029409209402940924902n
95    assert 34034240244909504590902901119302940942904944029040950n >= a
96    assert a >= 140044940590459049067274048929058908989042385n
97    assert b >= a
98
99    assert 44493059209094029409209402940924902n <= 44493059209094029409209402940924902n
100    assert 24400569094091093912039019089543850580328542852805043n <= a
101    assert a <= 24400569094091093912039019089543850580328542852805043n
102    assert a <= a
103}
104
105function test_literals() : void {
106    let num0 = 0n
107    assert (num0.toString() == "0")
108
109    let num1 = 127n
110    assert (num1.toString() == "127")
111
112    let num2 = 32767n
113    assert (num2.toString() == "32767")
114
115    let num3 = 2147483647n
116    assert (num3.toString() == "2147483647")
117
118    let num4 = 9223372036854775807n
119    assert (num4.toString() == "9223372036854775807")
120
121    let num5 = 170141183460469231731687303715884105727n
122    assert (num5.toString() == "170141183460469231731687303715884105727")
123
124    let num6 = 57896044618658097711785492504343953926634992332820282019728792003956564819967n
125    assert (num6.toString() == "57896044618658097711785492504343953926634992332820282019728792003956564819967")
126
127    let num1_n = -128n
128    assert (num1_n.toString() == "-128")
129
130    let num2_n = -32768n
131    assert (num2_n.toString() == "-32768")
132
133    let num3_n = -2147483648n
134    assert (num3_n.toString() == "-2147483648")
135
136    let num4_n = -9223372036854775808n
137    assert (num4_n.toString() == "-9223372036854775808")
138
139    let num5_n = -170141183460469231731687303715884105728n
140    assert (num5_n.toString() == "-170141183460469231731687303715884105728")
141
142    let num6_n = -57896044618658097711785492504343953926634992332820282019728792003956564819968n
143    assert (num6_n.toString() == "-57896044618658097711785492504343953926634992332820282019728792003956564819968")
144
145    let num1_sep = 1_991_653_125_841_217_555_434419_9091_123000000_3_3313_5775_3282_29n
146    assert (num1_sep.toString() == "19916531258412175554344199091123000000333135775328229")
147
148    let num2_sep = -422_12_3333_9844_3333_3443_34111_43434_1111_11_1_3_3_411909_990081n
149    assert (num2_sep.toString() == "-4221233339844333334433411143434111111133411909990081")
150
151    let num0_t: bigint = 0n
152    assert (num0_t.toString() == "0")
153
154    let num1_t: bigint = 57896044618658097711785492504343953926634992332820282019728792003956564819967n
155    assert (num1_t.toString() == "57896044618658097711785492504343953926634992332820282019728792003956564819967")
156
157    let num2_t: bigint = -9223372036854775808n
158    assert (num2_t.toString() == "-9223372036854775808")
159
160    let num3_t: bigint = 1_991_653_125_841_217_555_434419_9091_123000000_3_3313_5775_3282_29n
161    assert (num3_t.toString() == "19916531258412175554344199091123000000333135775328229")
162
163    let num4_t: bigint = -422_12_3333_9844_3333_3443_34111_43434_1111_11_1_3_3_411909_990081n
164    assert (num4_t.toString() == "-4221233339844333334433411143434111111133411909990081")
165
166    const num0_c = 0n
167    assert (num0_c.toString() == "0")
168
169    const num1_c = 1267650600228229401496703205376n
170    assert (num1_c.toString() == "1267650600228229401496703205376")
171
172    const num2_c = -1427247692705959881058285969449495136382746624n
173    assert (num2_c.toString() == "-1427247692705959881058285969449495136382746624")
174
175    const num3_c = 4_000_000_000_000_000_000_000_100n
176    assert (num3_c.toString() == "4000000000000000000000100")
177
178    const num4_c: bigint = -7777777_666666_55555_4444_333_22_1n
179    assert (num4_c.toString() == "-7777777666666555554444333221")
180}
181
182function test_cast(): void {
183    const v = 1559053
184    const b: byte = 44
185    const s: short = -17600
186    const i: int = 1150483640
187    const l: long = -8223372036854775808
188
189    // NOTE(kkonsw): casts currently do not work
190}
191
192function test_bigint_methods(): void {
193    const b: byte = 44
194    const s: short = -17600
195    const i: int = 1150483640
196    const l: long = -8223372036854775808
197
198    /* Testing BigInt constructor */
199    let n0 = new BigInt(0)
200    assert n0 == 0n
201    assert(n0.toString() == "0")
202
203    let n1 = new BigInt(654093)
204    assert(n1.toString() == "654093")
205    assert n1 == 654093n
206
207    let n2 = new BigInt(b)
208    assert(n2.toString() == "44")
209    assert n2 == 44n
210
211    let n3 = new BigInt(s)
212    assert(n3.toString() == "-17600")
213    assert n3 == -17600n
214
215    let n4 = new BigInt(i)
216    assert(n4.toString() == "1150483640")
217    assert n4 == 1150483640n
218
219    let n5 = new BigInt(l)
220    assert(n5.toString() == "-8223372036854775808")
221    assert n5 == -8223372036854775808n
222
223    let dec = new BigInt("-12392320390239294724747283477947923471101032")
224    assert dec == -12392320390239294724747283477947923471101032n
225
226    const n7 = 12392320390239294724747283477947923471101032n
227
228    /* Testing asIntN() static method */
229    assert BigInt.asIntN(0, n7) == 0n
230    assert BigInt.asIntN(8, n7) == 104n
231    assert BigInt.asIntN(16, n7) == 27752n
232    assert BigInt.asIntN(32, n7) == -737317784n
233    assert BigInt.asIntN(64, n7) == -7098331616643290008n
234
235    /* Testing asUintN() static method */
236    assert BigInt.asUintN(0, n7) == 0n
237    assert BigInt.asUintN(8, n7) == 104n
238    assert BigInt.asUintN(16, n7) == 27752n
239    assert BigInt.asUintN(32, n7) == 3557649512n
240    assert BigInt.asUintN(64, n7) == 11348412457066261608n
241}
242
243function test_shift(): void {
244    const a = 245599210405555256299145n
245    /* Testing left shift (<<) */
246    assert a << 100n == 311333986486181324779687697000809288883015536628203520n
247    assert a << 0n == a
248
249    /* Testing right shift (>>) */
250    assert a >> 60n == 213023n
251    assert a >> 0n == a
252}
253
254function test_scientific(): void {
255    assert new BigInt(0.0e0).toString() == "0" : "BigInt(0.0e0)"
256    assert new BigInt(0.0e+0).toString() == "0" : "BigInt(0.0e+0)"
257    assert new BigInt(0.0e-0).toString() == "0" : "BigInt(0.0e-0).toString()"
258    assert new BigInt(-0.0e0).toString() == "0" : "BigInt(-0.0e0).toString()"
259    assert new BigInt(1e23).toString() == "100000000000000000000000" : "BigInt(1e22)"
260    assert new BigInt(1e+23).toString() == "100000000000000000000000" : "BigInt(1e+22)"
261    assert new BigInt(-1e23).toString() == "-100000000000000000000000" : "BigInt(-1e22)"
262    assert new BigInt(-1e+23).toString() == "-100000000000000000000000" : "BigInt(-1e+22)"
263
264    assert new BigInt(1.234567e10).toString() == "12345670000" : "BigInt(1.234567e10).toString()"
265    assert new BigInt(1.234567e20).toString() == "123456700000000000000" : "BigInt(1.234567e20).toString()"
266
267    assert new BigInt(1.2345678912e21).toString() == "1234567891200000000000" : "BigInt(1.2345678912e21)"
268    assert new BigInt(1.2345678912e+21).toString() == "1234567891200000000000" : "BigInt(1.2345678912e+21)"
269    assert new BigInt(-1.2345678912e21).toString() == "-1234567891200000000000" : "BigInt(-1.2345678912e21)"
270}
271
272function test_double(): void {
273    let bigIntFromDouble = (x: number): boolean => {
274        try {
275            let b = new BigInt(x);
276        } catch (e) {
277            return e instanceof Error;
278        }
279        return false
280    };
281
282    assert bigIntFromDouble(0.1) : "BigInt(0.1)"
283    assert bigIntFromDouble(-0.1) : "BigInt(-0.1)"
284    assert bigIntFromDouble(42.1234567) : "BigInt(42.1234567)"
285    assert bigIntFromDouble(1.234567e2) : "BigInt(1.234567e2)"
286    assert bigIntFromDouble(1e-22) : "BigInt(1e-22)"
287    assert bigIntFromDouble(-1e-22) : "BigInt(-1e-22)"
288    assert bigIntFromDouble(1.88e-20) : "BigInt(1.88e-20)"
289    assert bigIntFromDouble(1.2345678848e-21) : "BigInt(1.2345678484e-21)"
290}
291
292function main() : void {
293    test_create_empty_bigint();
294    test_bigint_as_string();
295    test_invalid_bigint();
296    test_type();
297    test_assignment();
298    test_compare();
299    test_literals();
300    test_cast();
301    test_bigint_methods();
302    test_shift();
303    test_double();
304    // NOTE(aakmaev): Enable after fix #17683.
305    // test_scientific();
306}
307