-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbignumber-notation.spec.js
More file actions
207 lines (169 loc) · 5.82 KB
/
bignumber-notation.spec.js
File metadata and controls
207 lines (169 loc) · 5.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import { describe, it, expect } from 'vitest'
import BigNumber from 'bignumber.js'
import n from './index.js'
import { getMatchingTags, parse, calculate } from './bignumber-notation.js'
const bn = (n) => new BigNumber(n)
describe('bignumber-notation', () => {
describe('basic arithmetic', () => {
it('should add two numbers', () => {
expect(n`8 + 2`.toString()).toBe('10')
})
it('should subtract two numbers', () => {
expect(n`10 - 3`.toString()).toBe('7')
})
it('should multiply two numbers', () => {
expect(n`4 * 5`.toString()).toBe('20')
})
it('should divide two numbers', () => {
expect(n`20 / 4`.toString()).toBe('5')
})
it('should handle negative results', () => {
expect(n`5 - 10`.toString()).toBe('-5')
})
it('should handle decimal numbers', () => {
expect(n`1.5 + 2.5`.toString()).toBe('4')
})
})
describe('operator precedence', () => {
it('should respect multiplication before addition', () => {
expect(n`1 + 2 * 3`.toString()).toBe('7')
})
it('should respect division before subtraction', () => {
expect(n`10 - 8 / 2`.toString()).toBe('6')
})
it('should handle multiple operations with correct precedence', () => {
expect(n`2 + 3 * 4 - 6 / 2`.toString()).toBe('11')
})
})
describe('parentheses', () => {
it('should handle simple parentheses', () => {
expect(n`(8 + 2)`.toString()).toBe('10')
})
it('should override precedence with parentheses', () => {
expect(n`(1 + 2) * 3`.toString()).toBe('9')
})
it('should handle nested parentheses', () => {
expect(n`((2 + 3) * 4)`.toString()).toBe('20')
})
it('should handle multiple parentheses groups', () => {
expect(n`(2 + 3) * (4 + 1)`.toString()).toBe('25')
})
it('should handle deeply nested parentheses', () => {
expect(n`(((1 + 2)))`.toString()).toBe('3')
})
})
describe('template interpolation', () => {
it('should handle interpolated numbers', () => {
const num = 100
expect(n`1 + ${num} * 2`.toString()).toBe('201')
})
it('should handle interpolated BigNumber', () => {
const num = bn(100)
expect(n`1 + ${num} * 2`.toString()).toBe('201')
})
it('should handle multiple interpolations', () => {
const a = 10
const b = 20
expect(n`${a} + ${b}`.toString()).toBe('30')
})
it('should handle interpolated values in parentheses', () => {
const x = 5
expect(n`(${x} + 3) * 2`.toString()).toBe('16')
})
})
describe('scientific notation', () => {
it('should handle scientific notation', () => {
const num = bn(100)
expect(n`${num} * 10e11`.toString()).toBe(bn(10e13).toString())
})
it('should handle negative exponents', () => {
expect(n`1e-2 + 1e-2`.toString()).toBe('0.02')
})
})
describe('BigNumber precision', () => {
it('should maintain precision for large numbers', () => {
const large = '99999999999999999999999999999999'
const result = n`${large} + 1`
expect(result.isEqualTo('100000000000000000000000000000000')).toBe(true)
})
it('should maintain precision for small decimals', () => {
expect(n`0.1 + 0.2`.toString()).toBe('0.3')
})
it('should allow chaining BigNumber methods', () => {
const x = bn('1.5')
const y = x.times('2').plus(9).dividedBy('4').integerValue()
const t = n`(${x} * 2 + 9) / 4`.integerValue()
expect(y.toString()).toBe(t.toString())
})
})
describe('chained expressions', () => {
it('should handle many additions', () => {
expect(n`1+2+3+4+5`.toString()).toBe('15')
})
it('should handle mixed operators', () => {
expect(n`1 + 2 - 3 + 4`.toString()).toBe('4')
})
it('should handle expressions without spaces', () => {
expect(n`1+2*3`.toString()).toBe('7')
})
})
describe('edge cases', () => {
it('should handle single number', () => {
expect(n`42`.toString()).toBe('42')
})
it('should handle single interpolated value', () => {
const x = 42
expect(n`${x}`.toString()).toBe('42')
})
it('should handle division resulting in decimal', () => {
expect(n`1 / 3`.toString()).toBe('0.33333333333333333333')
})
it('should handle zero operations', () => {
expect(n`0 + 0`.toString()).toBe('0')
expect(n`5 * 0`.toString()).toBe('0')
expect(n`0 / 5`.toString()).toBe('0')
})
})
})
describe('helper functions', () => {
describe('getMatchingTags', () => {
it('should find matching bracket pairs', () => {
const tokens = ['(', '1', '+', '2', ')']
expect(getMatchingTags('(', ')', tokens)).toEqual([[0, 4]])
})
it('should handle nested brackets', () => {
const tokens = ['(', '(', '1', ')', ')']
const result = getMatchingTags('(', ')', tokens)
// Returns pairs as they are closed: inner bracket first, then outer
expect(result).toEqual([
[1, 3],
[0, 4],
])
})
it('should return empty when no brackets', () => {
const tokens = ['1', '+', '2']
expect(getMatchingTags('(', ')', tokens)).toEqual([])
})
})
describe('parse', () => {
it('should tokenize simple expression', () => {
const result = parse(['1 + 2'], [])
expect(result).toEqual(['1', '+', '2'])
})
it('should handle interpolated values', () => {
const result = parse(['', ' + 2'], [1])
expect(result).toEqual([1, '+', '2'])
})
})
describe('calculate', () => {
it('should calculate from token array', () => {
const tokens = ['1', '+', '2']
expect(calculate(tokens).toString()).toBe('3')
})
it('should return BigNumber for single value', () => {
const result = calculate(['42'])
expect(result instanceof BigNumber).toBe(true)
expect(result.toString()).toBe('42')
})
})
})