septima-lang 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main.js +1 -0
- package/package.json +3 -3
- package/dist/src/ast-node.d.ts +0 -98
- package/dist/src/ast-node.js +0 -139
- package/dist/src/extract-message.d.ts +0 -1
- package/dist/src/extract-message.js +0 -10
- package/dist/src/fail-me.d.ts +0 -1
- package/dist/src/fail-me.js +0 -11
- package/dist/src/find-array-method.d.ts +0 -15
- package/dist/src/find-array-method.js +0 -104
- package/dist/src/find-string-method.d.ts +0 -2
- package/dist/src/find-string-method.js +0 -88
- package/dist/src/index.d.ts +0 -1
- package/dist/src/index.js +0 -18
- package/dist/src/location.d.ts +0 -11
- package/dist/src/location.js +0 -3
- package/dist/src/parser.d.ts +0 -44
- package/dist/src/parser.js +0 -462
- package/dist/src/result.d.ts +0 -24
- package/dist/src/result.js +0 -29
- package/dist/src/runtime.d.ts +0 -28
- package/dist/src/runtime.js +0 -347
- package/dist/src/scanner.d.ts +0 -23
- package/dist/src/scanner.js +0 -88
- package/dist/src/septima.d.ts +0 -32
- package/dist/src/septima.js +0 -91
- package/dist/src/should-never-happen.d.ts +0 -1
- package/dist/src/should-never-happen.js +0 -9
- package/dist/src/source-code.d.ts +0 -19
- package/dist/src/source-code.js +0 -90
- package/dist/src/stack.d.ts +0 -11
- package/dist/src/stack.js +0 -19
- package/dist/src/switch-on.d.ts +0 -1
- package/dist/src/switch-on.js +0 -9
- package/dist/src/symbol-table.d.ts +0 -6
- package/dist/src/symbol-table.js +0 -3
- package/dist/src/value.d.ts +0 -128
- package/dist/src/value.js +0 -634
- package/dist/tests/parser.spec.d.ts +0 -1
- package/dist/tests/parser.spec.js +0 -31
- package/dist/tests/septima-compute-module.spec.d.ts +0 -1
- package/dist/tests/septima-compute-module.spec.js +0 -36
- package/dist/tests/septima.spec.d.ts +0 -1
- package/dist/tests/septima.spec.js +0 -807
- package/dist/tests/value.spec.d.ts +0 -1
- package/dist/tests/value.spec.js +0 -355
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/jest-output.json +0 -1
- package/src/a.js +0 -66
- package/src/ast-node.ts +0 -249
- package/src/extract-message.ts +0 -5
- package/src/fail-me.ts +0 -7
- package/src/find-array-method.ts +0 -115
- package/src/find-string-method.ts +0 -84
- package/src/index.ts +0 -1
- package/src/location.ts +0 -13
- package/src/parser.ts +0 -530
- package/src/result.ts +0 -45
- package/src/runtime.ts +0 -365
- package/src/scanner.ts +0 -106
- package/src/septima.ts +0 -121
- package/src/should-never-happen.ts +0 -4
- package/src/source-code.ts +0 -101
- package/src/stack.ts +0 -18
- package/src/switch-on.ts +0 -4
- package/src/symbol-table.ts +0 -7
- package/src/value.ts +0 -742
- package/tests/parser.spec.ts +0 -30
- package/tests/septima-compute-module.spec.ts +0 -41
- package/tests/septima.spec.ts +0 -880
- package/tests/value.spec.ts +0 -387
- package/tsconfig.json +0 -11
package/tests/value.spec.ts
DELETED
|
@@ -1,387 +0,0 @@
|
|
|
1
|
-
import { Value } from '../src/value'
|
|
2
|
-
|
|
3
|
-
const err = () => {
|
|
4
|
-
throw new Error(`should not run`)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const fixed = (u: unknown) => () => Value.from(u)
|
|
8
|
-
|
|
9
|
-
const notFromHere = () => {
|
|
10
|
-
throw new Error('should not be called from this test')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
describe('value', () => {
|
|
14
|
-
test('arithmetics', () => {
|
|
15
|
-
expect(Value.num(5).plus(Value.num(3)).export()).toEqual(8)
|
|
16
|
-
expect(Value.num(5).minus(Value.num(3)).export()).toEqual(2)
|
|
17
|
-
expect(Value.num(5).times(Value.num(3)).export()).toEqual(15)
|
|
18
|
-
expect(Value.num(14).over(Value.num(4)).export()).toEqual(3.5)
|
|
19
|
-
expect(Value.num(5).negate().export()).toEqual(-5)
|
|
20
|
-
expect(Value.num(-12).negate().export()).toEqual(12)
|
|
21
|
-
expect(Value.num(3).power(Value.num(4)).export()).toEqual(81)
|
|
22
|
-
expect(Value.num(2).power(Value.num(8)).export()).toEqual(256)
|
|
23
|
-
})
|
|
24
|
-
test('comparisons of numbers', () => {
|
|
25
|
-
expect(Value.num(5).order(Value.num(3)).export()).toEqual(1)
|
|
26
|
-
expect(Value.num(5).order(Value.num(4)).export()).toEqual(1)
|
|
27
|
-
expect(Value.num(5).order(Value.num(5)).export()).toEqual(0)
|
|
28
|
-
expect(Value.num(5).order(Value.num(6)).export()).toEqual(-1)
|
|
29
|
-
expect(Value.num(5).order(Value.num(7)).export()).toEqual(-1)
|
|
30
|
-
})
|
|
31
|
-
test('booleans', () => {
|
|
32
|
-
expect(Value.bool(true).export()).toEqual(true)
|
|
33
|
-
expect(Value.bool(false).export()).toEqual(false)
|
|
34
|
-
expect(Value.bool(false).not().export()).toEqual(true)
|
|
35
|
-
expect(Value.bool(true).not().export()).toEqual(false)
|
|
36
|
-
})
|
|
37
|
-
describe('boolean operators', () => {
|
|
38
|
-
test('or', () => {
|
|
39
|
-
expect(
|
|
40
|
-
Value.bool(false)
|
|
41
|
-
.or(() => Value.bool(false))
|
|
42
|
-
.export(),
|
|
43
|
-
).toEqual(false)
|
|
44
|
-
expect(
|
|
45
|
-
Value.bool(false)
|
|
46
|
-
.or(() => Value.bool(true))
|
|
47
|
-
.export(),
|
|
48
|
-
).toEqual(true)
|
|
49
|
-
expect(
|
|
50
|
-
Value.bool(true)
|
|
51
|
-
.or(() => Value.bool(false))
|
|
52
|
-
.export(),
|
|
53
|
-
).toEqual(true)
|
|
54
|
-
expect(
|
|
55
|
-
Value.bool(true)
|
|
56
|
-
.or(() => Value.bool(true))
|
|
57
|
-
.export(),
|
|
58
|
-
).toEqual(true)
|
|
59
|
-
})
|
|
60
|
-
test('and', () => {
|
|
61
|
-
expect(
|
|
62
|
-
Value.bool(false)
|
|
63
|
-
.and(() => Value.bool(false))
|
|
64
|
-
.export(),
|
|
65
|
-
).toEqual(false)
|
|
66
|
-
expect(
|
|
67
|
-
Value.bool(false)
|
|
68
|
-
.and(() => Value.bool(true))
|
|
69
|
-
.export(),
|
|
70
|
-
).toEqual(false)
|
|
71
|
-
expect(
|
|
72
|
-
Value.bool(true)
|
|
73
|
-
.and(() => Value.bool(false))
|
|
74
|
-
.export(),
|
|
75
|
-
).toEqual(false)
|
|
76
|
-
expect(
|
|
77
|
-
Value.bool(true)
|
|
78
|
-
.and(() => Value.bool(true))
|
|
79
|
-
.export(),
|
|
80
|
-
).toEqual(true)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
test('comparisons of booleans', () => {
|
|
84
|
-
expect(Value.bool(false).order(Value.bool(false)).export()).toEqual(0)
|
|
85
|
-
expect(Value.bool(false).order(Value.bool(true)).export()).toEqual(-1)
|
|
86
|
-
expect(Value.bool(true).order(Value.bool(false)).export()).toEqual(1)
|
|
87
|
-
expect(Value.bool(true).order(Value.bool(true)).export()).toEqual(0)
|
|
88
|
-
})
|
|
89
|
-
test('strings', () => {
|
|
90
|
-
expect(Value.str('abc').export()).toEqual('abc')
|
|
91
|
-
expect(Value.str('').export()).toEqual('')
|
|
92
|
-
expect(Value.str('a').plus(Value.str('b')).export()).toEqual('ab')
|
|
93
|
-
expect(Value.str('').plus(Value.str('')).export()).toEqual('')
|
|
94
|
-
expect(Value.str('').plus(Value.str('xyz')).export()).toEqual('xyz')
|
|
95
|
-
expect(Value.str('pqr').plus(Value.str('')).export()).toEqual('pqr')
|
|
96
|
-
expect(Value.str('zxcvb').plus(Value.str('nm')).export()).toEqual('zxcvbnm')
|
|
97
|
-
})
|
|
98
|
-
test('comparisons of strings', () => {
|
|
99
|
-
expect(Value.str('e').order(Value.str('c')).export()).toEqual(1)
|
|
100
|
-
expect(Value.str('e').order(Value.str('d')).export()).toEqual(1)
|
|
101
|
-
expect(Value.str('e').order(Value.str('e')).export()).toEqual(0)
|
|
102
|
-
expect(Value.str('e').order(Value.str('f')).export()).toEqual(-1)
|
|
103
|
-
expect(Value.str('e').order(Value.str('g')).export()).toEqual(-1)
|
|
104
|
-
})
|
|
105
|
-
test('arrays', () => {
|
|
106
|
-
expect(Value.arr([Value.num(10), Value.num(20)]).export()).toEqual([10, 20])
|
|
107
|
-
expect(Value.arr([]).export()).toEqual([])
|
|
108
|
-
expect(Value.arr([Value.str('ab'), Value.num(500), Value.bool(true)]).export()).toEqual(['ab', 500, true])
|
|
109
|
-
})
|
|
110
|
-
test('objects', () => {
|
|
111
|
-
expect(Value.obj({ x: Value.num(10), y: Value.num(20) }).export()).toEqual({ x: 10, y: 20 })
|
|
112
|
-
expect(Value.obj({}).export()).toEqual({})
|
|
113
|
-
expect(Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) }).export()).toEqual({
|
|
114
|
-
the: 'ab',
|
|
115
|
-
quick: 500,
|
|
116
|
-
brown: true,
|
|
117
|
-
})
|
|
118
|
-
const o = Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) })
|
|
119
|
-
expect(o.access('the', notFromHere).export()).toEqual('ab')
|
|
120
|
-
expect(o.access('quick', notFromHere).export()).toEqual(500)
|
|
121
|
-
expect(o.access('brown', notFromHere).export()).toEqual(true)
|
|
122
|
-
expect(o.access(Value.str('quick'), notFromHere).export()).toEqual(500)
|
|
123
|
-
})
|
|
124
|
-
test('yells if access() is called with value which is neither string or num', () => {
|
|
125
|
-
const o = Value.obj({ the: Value.str('ab'), quick: Value.num(500), brown: Value.bool(true) })
|
|
126
|
-
expect(() => o.access(Value.arr([]), notFromHere).export()).toThrowError(
|
|
127
|
-
'value type error: expected either num or str but found []',
|
|
128
|
-
)
|
|
129
|
-
expect(() => o.access(Value.bool(false), notFromHere).export()).toThrowError(
|
|
130
|
-
'value type error: expected either num or str but found false',
|
|
131
|
-
)
|
|
132
|
-
expect(() => o.access(Value.obj({ x: Value.num(1) }), notFromHere).export()).toThrowError(
|
|
133
|
-
'value type error: expected either num or str but found {"x":1}',
|
|
134
|
-
)
|
|
135
|
-
})
|
|
136
|
-
test('json', () => {
|
|
137
|
-
const v = Value.obj({ x: Value.num(1) })
|
|
138
|
-
expect(JSON.stringify(v)).toEqual('{"x":1}')
|
|
139
|
-
})
|
|
140
|
-
describe('ifElse', () => {
|
|
141
|
-
test('when applied to true evaluates the positive branch', () => {
|
|
142
|
-
expect(Value.bool(true).ifElse(fixed('yes'), fixed('no')).export()).toEqual('yes')
|
|
143
|
-
})
|
|
144
|
-
test('when applied to false evaluates the positive branch', () => {
|
|
145
|
-
expect(Value.bool(false).ifElse(fixed('yes'), fixed('no')).export()).toEqual('no')
|
|
146
|
-
})
|
|
147
|
-
test('errors if applied to a non-boolean', () => {
|
|
148
|
-
expect(() => Value.num(1).ifElse(fixed('yes'), fixed('no')).export()).toThrowError('expected bool but found 1')
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
describe('sink', () => {
|
|
152
|
-
const sink = Value.sink()
|
|
153
|
-
test('exported as undefined', () => {
|
|
154
|
-
expect(sink.export()).toEqual(undefined)
|
|
155
|
-
})
|
|
156
|
-
test('arithmetic operations on sink evaluate to sink', () => {
|
|
157
|
-
expect(sink.plus(Value.num(5)).export()).toEqual(undefined)
|
|
158
|
-
expect(sink.minus(Value.num(5)).export()).toEqual(undefined)
|
|
159
|
-
expect(sink.times(Value.num(5)).export()).toEqual(undefined)
|
|
160
|
-
expect(sink.over(Value.num(5)).export()).toEqual(undefined)
|
|
161
|
-
expect(sink.power(Value.num(5)).export()).toEqual(undefined)
|
|
162
|
-
expect(sink.modulo(Value.num(5)).export()).toEqual(undefined)
|
|
163
|
-
expect(sink.negate().export()).toEqual(undefined)
|
|
164
|
-
|
|
165
|
-
expect(Value.num(5).plus(sink).export()).toEqual(undefined)
|
|
166
|
-
expect(Value.num(5).minus(sink).export()).toEqual(undefined)
|
|
167
|
-
expect(Value.num(5).times(sink).export()).toEqual(undefined)
|
|
168
|
-
expect(Value.num(5).over(sink).export()).toEqual(undefined)
|
|
169
|
-
expect(Value.num(5).power(sink).export()).toEqual(undefined)
|
|
170
|
-
expect(Value.num(5).modulo(sink).export()).toEqual(undefined)
|
|
171
|
-
})
|
|
172
|
-
test('boolean operations on sink evaluate to sink', () => {
|
|
173
|
-
expect(sink.and(fixed(true)).export()).toEqual(undefined)
|
|
174
|
-
expect(sink.or(fixed(true)).export()).toEqual(undefined)
|
|
175
|
-
expect(sink.not().export()).toEqual(undefined)
|
|
176
|
-
})
|
|
177
|
-
test('when sink is the right-hand-side of a boolean expression, the result is sink only if the left-hand-side dictates so', () => {
|
|
178
|
-
expect(Value.bool(true).and(fixed(sink)).export()).toEqual(undefined)
|
|
179
|
-
expect(Value.bool(false).and(fixed(sink)).export()).toEqual(false)
|
|
180
|
-
expect(Value.bool(true).or(fixed(sink)).export()).toEqual(true)
|
|
181
|
-
expect(Value.bool(false).or(fixed(sink)).export()).toEqual(undefined)
|
|
182
|
-
})
|
|
183
|
-
test('ifElse with sink condition evaluates to sink', () => {
|
|
184
|
-
expect(sink.ifElse(fixed('y'), fixed('n')).export()).toEqual(undefined)
|
|
185
|
-
})
|
|
186
|
-
test('ifElse with sink positive expression evaluates to sink only if the condition is true', () => {
|
|
187
|
-
expect(Value.bool(true).ifElse(fixed(sink), fixed(-200)).export()).toEqual(undefined)
|
|
188
|
-
expect(Value.bool(false).ifElse(fixed(sink), fixed(-200)).export()).toEqual(-200)
|
|
189
|
-
})
|
|
190
|
-
test('ifElse with sink negative expression evaluates to sink only if the condition is false', () => {
|
|
191
|
-
expect(Value.bool(true).ifElse(fixed(-300), fixed(sink)).export()).toEqual(-300)
|
|
192
|
-
expect(Value.bool(false).ifElse(fixed(-300), fixed(sink)).export()).toEqual(undefined)
|
|
193
|
-
})
|
|
194
|
-
test('access to an attribute of a sink evaluates to sink', () => {
|
|
195
|
-
expect(sink.access('foo', notFromHere).export()).toEqual(undefined)
|
|
196
|
-
})
|
|
197
|
-
test('calling a sink evaluates to sink', () => {
|
|
198
|
-
expect(sink.call([], err).export()).toEqual(undefined)
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
test('applying .keys() to sink evaluates to sink', () => {
|
|
202
|
-
expect(sink.keys().export()).toEqual(undefined)
|
|
203
|
-
})
|
|
204
|
-
test('applying .entries() to sink evaluates to sink', () => {
|
|
205
|
-
expect(sink.entries().export()).toEqual(undefined)
|
|
206
|
-
})
|
|
207
|
-
test('applying .fromEntries() to sink evaluates to sink', () => {
|
|
208
|
-
expect(sink.fromEntries().export()).toEqual(undefined)
|
|
209
|
-
})
|
|
210
|
-
describe('unsink()', () => {
|
|
211
|
-
test('when applied to a non-sink value evaluates to it', () => {
|
|
212
|
-
expect(Value.num(5).unsink(fixed('x')).export()).toEqual(5)
|
|
213
|
-
})
|
|
214
|
-
test('when applied to a sink value evaluates to its argument', () => {
|
|
215
|
-
expect(Value.num(5).unsink(fixed('x')).export()).toEqual(5)
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
describe('comparisons', () => {
|
|
219
|
-
test('comparing a sink with itself evaluates to true', () => {
|
|
220
|
-
expect(sink.equalsTo(sink).export()).toEqual(true)
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
test('comparing a sink with other types evaluates to false', () => {
|
|
224
|
-
expect(sink.equalsTo(Value.arr([])).export()).toEqual(false)
|
|
225
|
-
expect(sink.equalsTo(Value.bool(false)).export()).toEqual(false)
|
|
226
|
-
expect(sink.equalsTo(Value.bool(true)).export()).toEqual(false)
|
|
227
|
-
expect(sink.equalsTo(Value.num(0)).export()).toEqual(false)
|
|
228
|
-
expect(sink.equalsTo(Value.num(5)).export()).toEqual(false)
|
|
229
|
-
expect(sink.equalsTo(Value.obj({})).export()).toEqual(false)
|
|
230
|
-
expect(sink.equalsTo(Value.str('')).export()).toEqual(false)
|
|
231
|
-
expect(sink.equalsTo(Value.str('s')).export()).toEqual(false)
|
|
232
|
-
})
|
|
233
|
-
test('erros when trying to order a sink with a non-sink', () => {
|
|
234
|
-
expect(() => sink.order(Value.arr([])).export()).toThrowError('Cannot compare a')
|
|
235
|
-
expect(() => sink.order(Value.bool(false)).export()).toThrowError('Cannot compare a')
|
|
236
|
-
expect(() => sink.order(Value.bool(true)).export()).toThrowError('Cannot compare a')
|
|
237
|
-
expect(() => sink.order(Value.num(0)).export()).toThrowError('Cannot compare a')
|
|
238
|
-
expect(() => sink.order(Value.num(5)).export()).toThrowError('Cannot compare a')
|
|
239
|
-
expect(() => sink.order(Value.obj({})).export()).toThrowError('Cannot compare a')
|
|
240
|
-
expect(() => sink.order(Value.str('')).export()).toThrowError('Cannot compare a')
|
|
241
|
-
expect(() => sink.order(Value.str('a')).export()).toThrowError('Cannot compare a')
|
|
242
|
-
|
|
243
|
-
expect(() => Value.arr([]).order(sink).export()).toThrowError('Cannot compare a')
|
|
244
|
-
expect(() => Value.bool(false).order(sink).export()).toThrowError('Cannot compare a')
|
|
245
|
-
expect(() => Value.bool(true).order(sink).export()).toThrowError('Cannot compare a')
|
|
246
|
-
expect(() => Value.num(0).order(sink).export()).toThrowError('Cannot compare a')
|
|
247
|
-
expect(() => Value.num(5).order(sink).export()).toThrowError('Cannot compare a')
|
|
248
|
-
expect(() => Value.obj({}).order(sink).export()).toThrowError('Cannot compare a')
|
|
249
|
-
expect(() => Value.str('').order(sink).export()).toThrowError('Cannot compare a')
|
|
250
|
-
expect(() => Value.str('a').order(sink).export()).toThrowError('Cannot compare a')
|
|
251
|
-
})
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
describe('type erros', () => {
|
|
255
|
-
const five = Value.num(1)
|
|
256
|
-
const t = Value.bool(true)
|
|
257
|
-
const f = Value.bool(false)
|
|
258
|
-
|
|
259
|
-
const check = (a: Value, b: Value | Value[], f: (lhs: Value, rhs: Value) => void) => {
|
|
260
|
-
const arr = Array.isArray(b) ? b : [b]
|
|
261
|
-
const r = /(^value type error: expected)|(^Cannot compare a )/
|
|
262
|
-
// /(^value type error: expected)|(^Type error: operator cannot be applied to operands of type)|(^Cannot compare when the left-hand-side value is of type)|(^Not a)/
|
|
263
|
-
for (const curr of arr) {
|
|
264
|
-
expect(() => f(a, curr)).toThrowError(r)
|
|
265
|
-
expect(() => f(curr, a)).toThrowError(r)
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
test('emits erros when numeric operations are applied to a boolean (either lhs or rhs)', () => {
|
|
270
|
-
check(five, t, (x, y) => x.plus(y))
|
|
271
|
-
check(five, t, (x, y) => x.minus(y))
|
|
272
|
-
check(five, t, (x, y) => x.times(y))
|
|
273
|
-
check(five, t, (x, y) => x.over(y))
|
|
274
|
-
check(five, t, (x, y) => x.power(y))
|
|
275
|
-
check(five, t, (x, y) => x.modulo(y))
|
|
276
|
-
check(five, t, (x, y) => x.order(y))
|
|
277
|
-
check(t, t, x => x.negate())
|
|
278
|
-
expect(1).toEqual(1) // make the linter happy
|
|
279
|
-
})
|
|
280
|
-
test('emits erros when boolean operations are applied to a number (either lhs or rhs)', () => {
|
|
281
|
-
check(five, f, (x, y) => x.or(() => y))
|
|
282
|
-
check(five, t, (x, y) => x.and(() => y))
|
|
283
|
-
check(five, five, x => x.not())
|
|
284
|
-
expect(1).toEqual(1) // make the linter happy
|
|
285
|
-
})
|
|
286
|
-
})
|
|
287
|
-
describe('foreign code calls', () => {
|
|
288
|
-
test('invokes the given function', () => {
|
|
289
|
-
const indexOf = Value.foreign(s => 'the quick brown fox jumps over the lazy dog'.indexOf(s.assertStr()))
|
|
290
|
-
expect(indexOf.call([Value.str('quick')], err).export()).toEqual(4)
|
|
291
|
-
})
|
|
292
|
-
})
|
|
293
|
-
describe('string operatios', () => {
|
|
294
|
-
test('.length', () => {
|
|
295
|
-
expect(Value.str('four scores AND seven').access('length', notFromHere).export()).toEqual(21)
|
|
296
|
-
})
|
|
297
|
-
test.each([
|
|
298
|
-
['at', [Value.num(10)], 'e'],
|
|
299
|
-
['at', [Value.num(-4)], 'v'],
|
|
300
|
-
['charAt', [Value.num(10)], 'e'],
|
|
301
|
-
['concat', [Value.str('years')], ' four scores AND seven years'],
|
|
302
|
-
['endsWith', [Value.str('seven ')], true],
|
|
303
|
-
['endsWith', [Value.str('years')], false],
|
|
304
|
-
['includes', [Value.str('scores')], true],
|
|
305
|
-
['includes', [Value.str('years')], false],
|
|
306
|
-
['indexOf', [Value.str('e')], 10],
|
|
307
|
-
['lastIndexOf', [Value.str('e')], 20],
|
|
308
|
-
['match', [Value.str('r|f')], ['f']],
|
|
309
|
-
['matchAll', [Value.str('r|f')], [['f'], ['r'], ['r']]],
|
|
310
|
-
['padEnd', [Value.num(25), Value.str('#')], ' four scores AND seven ##'],
|
|
311
|
-
['padStart', [Value.num(25), Value.str('#')], '## four scores AND seven '],
|
|
312
|
-
['repeat', [Value.num(3)], ' four scores AND seven four scores AND seven four scores AND seven '],
|
|
313
|
-
['replace', [Value.str('o'), Value.str('#')], ' f#ur scores AND seven '],
|
|
314
|
-
['replaceAll', [Value.str('o'), Value.str('#')], ' f#ur sc#res AND seven '],
|
|
315
|
-
['search', [Value.str('sco..s')], 6],
|
|
316
|
-
['slice', [Value.num(13), Value.num(-7)], 'AND'],
|
|
317
|
-
['split', [Value.str(' ')], ['', 'four', 'scores', 'AND', 'seven', '']],
|
|
318
|
-
['startsWith', [Value.str(' four')], true],
|
|
319
|
-
['startsWith', [Value.str('seven')], false],
|
|
320
|
-
['substring', [Value.num(6), Value.num(12)], 'scores'],
|
|
321
|
-
['substring', [Value.num(13), Value.num(-7)], ' four scores '],
|
|
322
|
-
['toLowerCase', [], ' four scores and seven '],
|
|
323
|
-
['toUpperCase', [], ' FOUR SCORES AND SEVEN '],
|
|
324
|
-
['trim', [], 'four scores AND seven'],
|
|
325
|
-
['trimEnd', [], ' four scores AND seven'],
|
|
326
|
-
['trimStart', [], 'four scores AND seven '],
|
|
327
|
-
])('provides the .%s() method', (name, args, expected) => {
|
|
328
|
-
const callee = Value.str(' four scores AND seven ').access(name, notFromHere)
|
|
329
|
-
const actual = callee.call(args, err)
|
|
330
|
-
expect(actual.export()).toEqual(expected)
|
|
331
|
-
})
|
|
332
|
-
})
|
|
333
|
-
describe('array operations', () => {
|
|
334
|
-
test('.length', () => {
|
|
335
|
-
expect(
|
|
336
|
-
Value.arr([Value.str('foo'), Value.str('bar'), Value.str('foo'), Value.str('goo')])
|
|
337
|
-
.access('length', notFromHere)
|
|
338
|
-
.export(),
|
|
339
|
-
).toEqual(4)
|
|
340
|
-
})
|
|
341
|
-
test.each([
|
|
342
|
-
['at', [Value.num(-1)], 'goo'],
|
|
343
|
-
['at', [Value.num(4)], undefined],
|
|
344
|
-
['concat', [Value.arr([Value.str('boo'), Value.str('poo')])], ['foo', 'bar', 'foo', 'goo', 'boo', 'poo']],
|
|
345
|
-
[
|
|
346
|
-
'entries',
|
|
347
|
-
[],
|
|
348
|
-
[
|
|
349
|
-
[0, 'foo'],
|
|
350
|
-
[1, 'bar'],
|
|
351
|
-
[2, 'foo'],
|
|
352
|
-
[3, 'goo'],
|
|
353
|
-
],
|
|
354
|
-
],
|
|
355
|
-
// TODO(imaman): ['find', [Value.foreign(v => v.assertStr() === 'lorem ipsum')], ??]"",
|
|
356
|
-
['includes', [Value.str('bar')], true],
|
|
357
|
-
['includes', [Value.str('lorem-ipsum')], false],
|
|
358
|
-
['indexOf', [Value.str('goo')], 3],
|
|
359
|
-
['join', [Value.str('; ')], 'foo; bar; foo; goo'],
|
|
360
|
-
['lastIndexOf', [Value.str('foo')], 2],
|
|
361
|
-
['lastIndexOf', [Value.str('lorem ipsum')], -1],
|
|
362
|
-
['reverse', [], ['goo', 'foo', 'bar', 'foo']],
|
|
363
|
-
['slice', [Value.num(1), Value.num(2)], ['bar']],
|
|
364
|
-
['slice', [Value.num(1), Value.num(3)], ['bar', 'foo']],
|
|
365
|
-
['slice', [Value.num(2), Value.num(4)], ['foo', 'goo']],
|
|
366
|
-
])('provides the .%s() method', (name, args, expected) => {
|
|
367
|
-
const input = Value.arr([Value.str('foo'), Value.str('bar'), Value.str('foo'), Value.str('goo')])
|
|
368
|
-
const before = JSON.parse(JSON.stringify(input))
|
|
369
|
-
const callee = input.access(name, notFromHere)
|
|
370
|
-
const actual = callee.call(args, err)
|
|
371
|
-
expect(actual.export()).toEqual(expected)
|
|
372
|
-
// Make sure the input array was not accidentally mutated.
|
|
373
|
-
expect(JSON.parse(JSON.stringify(input))).toEqual(before)
|
|
374
|
-
})
|
|
375
|
-
test('.flat() flattens', () => {
|
|
376
|
-
const input = Value.arr([Value.arr([Value.str('a'), Value.str('b')]), Value.str('c')])
|
|
377
|
-
const callee = input.access('flat', notFromHere)
|
|
378
|
-
const actual = callee.call([], err)
|
|
379
|
-
expect(actual.export()).toEqual(['a', 'b', 'c'])
|
|
380
|
-
})
|
|
381
|
-
})
|
|
382
|
-
|
|
383
|
-
test.todo('array.sort()')
|
|
384
|
-
test.todo('what happens when we get an undefined from a foreign call (like Array.get())')
|
|
385
|
-
test.todo('access to non-existing string method (a sad path test)')
|
|
386
|
-
test.todo('access to non-existing array method (a sad path test)')
|
|
387
|
-
})
|