fix: consistent range syntax parsing, #791

This commit is contained in:
Harttle
2025-01-19 17:58:00 +08:00
committed by Jun Yang
parent a5070af3e4
commit a490a70da1
3 changed files with 28 additions and 7 deletions
+4 -2
View File
@@ -391,9 +391,11 @@ export class Tokenizer {
if (this.peek() !== '(') return
++this.p
const lhs = this.readValueOrThrow()
this.p += 2
this.skipBlank()
this.assert(this.read() === '.' && this.read() === '.', 'invalid range syntax')
const rhs = this.readValueOrThrow()
++this.p
this.skipBlank()
this.assert(this.read() === ')', 'invalid range syntax')
return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file)
}
+24 -5
View File
@@ -24,11 +24,6 @@ describe('Expression', function () {
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
expect(await toPromise(create('false').evaluate(ctx, false))).toBe(false)
})
it('should eval range expression', async function () {
const ctx = new Context({ two: 2 })
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
})
it('should eval literal', async function () {
expect(await toPromise(create('2.4').evaluate(ctx, false))).toBe(2.4)
expect(await toPromise(create('"foo"').evaluate(ctx, false))).toBe('foo')
@@ -221,6 +216,30 @@ describe('Expression', function () {
})
})
describe('range', function () {
const ctx = new Context({ two: 2, num: { one: 1, two: 2 } })
it('should eval range expression', async function () {
expect(await toPromise(create('(2..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
expect(await toPromise(create('(two..4)').evaluate(ctx, false))).toEqual([2, 3, 4])
})
it('should allow property access expression as variables', async function () {
expect(await toPromise(create('(num.one..num.two)').evaluate(ctx))).toEqual([1, 2])
expect(await toPromise(create('(num.one .. two)').evaluate(ctx))).toEqual([1, 2])
})
it('should allow blanks in range', async function () {
expect(await toPromise(create('(3 ..5)').evaluate(ctx))).toEqual([3, 4, 5])
expect(await toPromise(create('(3 .. 5)').evaluate(ctx))).toEqual([3, 4, 5])
expect(await toPromise(create('( 3 .. 5 )').evaluate(ctx))).toEqual([3, 4, 5])
})
it('should throw if .. not matched', async function () {
expect(() => create('(3.5')).toThrow('invalid range syntax')
expect(() => create('(3 5')).toThrow('invalid range syntax')
})
it('should throw if ( not patched', async function () {
expect(() => create('(3..5')).toThrow('invalid range syntax')
})
})
describe('sync', function () {
it('should eval literal', function () {
expect(toValueSync(create('2.4').evaluate(ctx, false))).toBe(2.4)