Skip to content

Commit a490a70

Browse files
committed
fix: consistent range syntax parsing, #791
1 parent a5070af commit a490a70

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/parser/tokenizer.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,11 @@ export class Tokenizer {
391391
if (this.peek() !== '(') return
392392
++this.p
393393
const lhs = this.readValueOrThrow()
394-
this.p += 2
394+
this.skipBlank()
395+
this.assert(this.read() === '.' && this.read() === '.', 'invalid range syntax')
395396
const rhs = this.readValueOrThrow()
396-
++this.p
397+
this.skipBlank()
398+
this.assert(this.read() === ')', 'invalid range syntax')
397399
return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file)
398400
}
399401

src/render/expression.spec.ts

+24-5
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ describe('Expression', function () {
2424
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
2525
expect(await toPromise(create('false').evaluate(ctx, false))).toBe(false)
2626
})
27-
it('should eval range expression', async function () {
28-
const ctx = new Context({ two: 2 })
29-
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
30-
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
31-
})
3227
it('should eval literal', async function () {
3328
expect(await toPromise(create('2.4').evaluate(ctx, false))).toBe(2.4)
3429
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
@@ -221,6 +216,30 @@ describe('Expression', function () {
221216
})
222217
})
223218

219+
describe('range', function () {
220+
const ctx = new Context({ two: 2, num: { one: 1, two: 2 } })
221+
it('should eval range expression', async function () {
222+
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
223+
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
224+
})
225+
it('should allow property access expression as variables', async function () {
226+
expect(await toPromise(create('(num.one..num.two)').evaluate(ctx))).toEqual([1, 2])
227+
expect(await toPromise(create('(num.one .. two)').evaluate(ctx))).toEqual([1, 2])
228+
})
229+
it('should allow blanks in range', async function () {
230+
expect(await toPromise(create('(3 ..5)').evaluate(ctx))).toEqual([3, 4, 5])
231+
expect(await toPromise(create('(3 .. 5)').evaluate(ctx))).toEqual([3, 4, 5])
232+
expect(await toPromise(create('( 3 .. 5 )').evaluate(ctx))).toEqual([3, 4, 5])
233+
})
234+
it('should throw if .. not matched', async function () {
235+
expect(() => create('(3.5')).toThrow('invalid range syntax')
236+
expect(() => create('(3 5')).toThrow('invalid range syntax')
237+
})
238+
it('should throw if ( not patched', async function () {
239+
expect(() => create('(3..5')).toThrow('invalid range syntax')
240+
})
241+
})
242+
224243
describe('sync', function () {
225244
it('should eval literal', function () {
226245
expect(toValueSync(create('2.4').evaluate(ctx, false))).toBe(2.4)
File renamed without changes.

0 commit comments

Comments
 (0)