-
Notifications
You must be signed in to change notification settings - Fork 123
/
Copy pathinterpreter.spec.ts
180 lines (143 loc) · 6.16 KB
/
interpreter.spec.ts
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
import {HyperFormula} from '../src'
import {ErrorType} from '../src/Cell'
import {ErrorMessage} from '../src/error-message'
import {adr, detailedError} from './testUtils'
describe('Interpreter', () => {
it('relative addressing formula', () => {
const engine = HyperFormula.buildFromArray([['42', '=A1']])
expect(engine.getCellValue(adr('B1'))).toBe(42)
})
it('number literal', () => {
const engine = HyperFormula.buildFromArray([['3']])
expect(engine.getCellValue(adr('A1'))).toBe(3)
})
it('negative number literal', () => {
const engine = HyperFormula.buildFromArray([['=-3']])
expect(engine.getCellValue(adr('A1'))).toBe(-3)
})
it('negative number literal - non numeric value', () => {
const engine = HyperFormula.buildFromArray([['=-"foo"']])
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.VALUE, ErrorMessage.NumberCoercion))
})
it('string literals - faulty tests', () => {
const engine = HyperFormula.buildFromArray([
['www', '1www', 'www1'],
])
expect(engine.getCellValue(adr('A1'))).toBe('www')
expect(engine.getCellValue(adr('B1'))).toBe('1www')
expect(engine.getCellValue(adr('C1'))).toBe('www1')
})
it('string literals in formula - faulty tests', () => {
const engine = HyperFormula.buildFromArray([
['="www"', '="1www"', '="www1"'],
])
expect(engine.getCellValue(adr('A1'))).toBe('www')
expect(engine.getCellValue(adr('B1'))).toBe('1www')
expect(engine.getCellValue(adr('C1'))).toBe('www1')
})
it('ranges - VALUE error when evaluating without context', () => {
const engine = HyperFormula.buildFromArray([['1'], ['2'], ['=A1:A2']])
expect(engine.getCellValue(adr('A3'))).toEqualError(detailedError(ErrorType.VALUE, ErrorMessage.ScalarExpected))
})
it('procedures - SUM with bad args', () => {
const engine = HyperFormula.buildFromArray([['=SUM(B1)', 'asdf']])
expect(engine.getCellValue(adr('A1'))).toEqual(0)
})
it('procedures - not known procedure', () => {
const engine = HyperFormula.buildFromArray([['=FOO()']])
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.NAME, ErrorMessage.FunctionName('FOO')))
})
it('errors - parsing errors', () => {
const engine = HyperFormula.buildFromArray([['=1A1', '=foo(', '=)(asdf']])
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.ERROR, ErrorMessage.ParseError))
expect(engine.getCellValue(adr('B1'))).toEqualError(detailedError(ErrorType.ERROR, ErrorMessage.ParseError))
expect(engine.getCellValue(adr('C1'))).toEqualError(detailedError(ErrorType.ERROR, ErrorMessage.ParseError))
})
it('function OFFSET basic use', () => {
const engine = HyperFormula.buildFromArray([['5', '=OFFSET(B1, 0, -1)', '=OFFSET(A1, 0, 0)']])
expect(engine.getCellValue(adr('B1'))).toEqual(5)
expect(engine.getCellValue(adr('C1'))).toEqual(5)
})
it('function OFFSET out of range', () => {
const engine = HyperFormula.buildFromArray([['=OFFSET(A1, -1, 0)', '=OFFSET(A1, 0, -1)']])
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.OutOfSheet))
expect(engine.getCellValue(adr('B1'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.OutOfSheet))
})
it('function OFFSET returns bigger range', () => {
const engine = HyperFormula.buildFromArray([
['=SUM(OFFSET(A1, 0, 1,2,1))', '5', '6'],
['2', '3', '4'],
])
expect(engine.getCellValue(adr('A1'))).toEqual(8)
})
it('function OFFSET returns rectangular range and fails', () => {
const engine = HyperFormula.buildFromArray([
['=OFFSET(A1, 0, 1,2,1))'],
])
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.ERROR, ErrorMessage.ParseError))
})
it('function OFFSET used twice in a range', () => {
const engine = HyperFormula.buildFromArray([
['5', '6', '=SUM(OFFSET(A2,-1,0):OFFSET(A2,0,1))'],
['2', '3', '4'],
])
expect(engine.getCellValue(adr('C1'))).toEqual(16)
})
it('function OFFSET as a reference inside SUM', () => {
const engine = HyperFormula.buildFromArray([
['0', '0', '10'],
['5', '6', '=SUM(SUM(OFFSET(C2,-1,0),A2),-B2)'],
])
expect(engine.getCellValue(adr('C2'))).toEqual(9)
})
it('initializing engine with multiple sheets', () => {
const engine = HyperFormula.buildFromSheets({
Sheet1: [
['0', '1'],
['2', '3'],
],
Sheet2: [
['=SUM(Sheet1!A1:Sheet1!B2)'],
],
})
expect(engine.getCellValue(adr('A1', 1))).toEqual(6)
})
it('using bad range reference', () => {
const engine = HyperFormula.buildFromSheets({
Sheet1: [
['0', '1'],
['2', '3'],
],
Sheet2: [
['=SUM(Sheet1!A1:Sheet2!A2)'],
[''],
],
})
expect(engine.getCellValue(adr('A1', 1))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
})
it('expression with parenthesis', () => {
const engine = HyperFormula.buildFromArray([
['=(1+2)*3'],
])
expect(engine.getCellValue(adr('A1'))).toEqual(9)
})
it('should return #REF when range is pointing to multiple sheets', () => {
const engine = HyperFormula.buildFromSheets({
'Sheet1': [
['=SUM(Sheet1!A2:Sheet2!B3)'],
['=SUM(Sheet1!A:Sheet2!B)'],
['=SUM(Sheet1!2:Sheet2!3)'],
['=Sheet1!A2:Sheet2!B3'],
['=Sheet1!A:Sheet2!B'],
['=Sheet1!2:Sheet2!3'],
],
'Sheet2': []
})
expect(engine.getCellValue(adr('A1'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
expect(engine.getCellValue(adr('A2'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
expect(engine.getCellValue(adr('A3'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
expect(engine.getCellValue(adr('A4'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
expect(engine.getCellValue(adr('A5'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
expect(engine.getCellValue(adr('A6'))).toEqualError(detailedError(ErrorType.REF, ErrorMessage.RangeManySheets))
})
})