Implement multiline comments and be more forgiving of extra whitespace
This commit is contained in:
parent
1812a76f8d
commit
0646031217
|
@ -104,16 +104,22 @@ LineTerminatorSequence
|
|||
/ "\\u2028"
|
||||
/ "\\u2029"
|
||||
|
||||
Comment "comment"
|
||||
= MultiLineComment
|
||||
|
||||
MultiLineComment
|
||||
= "/*" (!"*/" SourceCharacter)* "*/"
|
||||
|
||||
__ "skipped"
|
||||
= (WhiteSpace / LineTerminatorSequence )*
|
||||
= (WhiteSpace / LineTerminatorSequence / Comment)*
|
||||
|
||||
IdentifierPath
|
||||
= variable:Identifier accessor:("." Identifier)* {
|
||||
= variable:Identifier accessor:(__ "." __ Identifier)* {
|
||||
const path = variable.split( '.' );
|
||||
let result = path.reduce( ( nextObject, propertyName ) => nextObject[ propertyName ], options.context );
|
||||
|
||||
for ( let i = 0; i < accessor.length; i++ ) {
|
||||
result = result[ accessor[ i ][ 1 ] ];
|
||||
result = result[ accessor[ i ][ 3 ] ];
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -378,7 +384,9 @@ LogicalOrOperator
|
|||
= "||"
|
||||
|
||||
Expression
|
||||
= LogicalOrExpression
|
||||
= __ expression:LogicalOrExpression __ {
|
||||
return expression;
|
||||
}
|
||||
`;
|
||||
|
||||
export const parser = peggy.generate( grammar );
|
||||
|
|
|
@ -116,6 +116,12 @@ describe( 'evaluate', () => {
|
|||
expect( result ).toEqual( "foo \\'bar\\'" );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a literal with whitespace around it', () => {
|
||||
const result = evaluate( ' 23 ' );
|
||||
|
||||
expect( result ).toEqual( 23 );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a top-level context property', () => {
|
||||
const result = evaluate( 'foo', {
|
||||
foo: 'bar',
|
||||
|
@ -124,6 +130,14 @@ describe( 'evaluate', () => {
|
|||
expect( result ).toEqual( 'bar' );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a top-level context property with whitespace', () => {
|
||||
const result = evaluate( ' foo ', {
|
||||
foo: 'bar',
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( 'bar' );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a nested context property', () => {
|
||||
const result = evaluate( 'foo.bar', {
|
||||
foo: {
|
||||
|
@ -134,6 +148,30 @@ describe( 'evaluate', () => {
|
|||
expect( result ).toEqual( 'baz' );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a nested context property with whitespace', () => {
|
||||
const result = evaluate( 'foo. bar', {
|
||||
foo: {
|
||||
bar: 'baz',
|
||||
},
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( 'baz' );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a nested context property with multiple lines', () => {
|
||||
const result = evaluate(
|
||||
`foo.
|
||||
bar`,
|
||||
{
|
||||
foo: {
|
||||
bar: 'baz',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect( result ).toEqual( 'baz' );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a NOT expression', () => {
|
||||
const result = evaluate( '!foo', {
|
||||
foo: true,
|
||||
|
@ -158,6 +196,14 @@ describe( 'evaluate', () => {
|
|||
expect( result ).toEqual( false );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a NOT expression with parentheses and spaces', () => {
|
||||
const result = evaluate( '! ( foo ) ', {
|
||||
foo: true,
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( false );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a multiplication expression', () => {
|
||||
const result = evaluate( 'foo * 2', {
|
||||
foo: 2,
|
||||
|
@ -351,6 +397,50 @@ describe( 'evaluate', () => {
|
|||
expect( result ).toEqual( true );
|
||||
} );
|
||||
|
||||
it( 'should evaluate an expression with a multiline comment at the end', () => {
|
||||
const result = evaluate( 'foo /* + 23 */', {
|
||||
foo: 5,
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( 5 );
|
||||
} );
|
||||
|
||||
it( 'should evaluate an expression with a multiline comment at the beginning', () => {
|
||||
const result = evaluate( '/* 23 + */ foo', {
|
||||
foo: 5,
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( 5 );
|
||||
} );
|
||||
|
||||
it( 'should evaluate an expression with a multiline comment in the middle', () => {
|
||||
const result = evaluate( 'foo + /* 23 */ bar', {
|
||||
foo: 5,
|
||||
bar: 3,
|
||||
} );
|
||||
|
||||
expect( result ).toEqual( 8 );
|
||||
} );
|
||||
|
||||
it( 'should evaluate a multiline expression with a multiline comment', () => {
|
||||
const result = evaluate(
|
||||
`foo
|
||||
/*
|
||||
+ bar
|
||||
+ boo
|
||||
*/
|
||||
+ baz`,
|
||||
{
|
||||
foo: 5,
|
||||
bar: 23,
|
||||
boo: 6,
|
||||
baz: 3,
|
||||
}
|
||||
);
|
||||
|
||||
expect( result ).toEqual( 8 );
|
||||
} );
|
||||
|
||||
it( 'should throw an error if the expression is invalid', () => {
|
||||
expect( () => evaluate( '= 1' ) ).toThrow();
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue