diff --git a/.vscode/launch.json b/.vscode/launch.json index b509da7..8a6145c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,13 +33,24 @@ } }, { - "name": "Test Scenario", - "program": "${workspaceFolder}/test/test_scenario.ts", + "runtimeExecutable": "/usr/local/bin/node", + "name": "Jest Scenario", + "program": "${workspaceFolder}/node_modules/.bin/jest", "request": "launch", - "runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"], "skipFiles": ["/**"], - "args": ["--scenario=${input:scenario}", "--index=${input:index}"], - "type": "node" + "args": [ + "scenario.test", + "--config", + "jest.config.ts", + "--scenario=${input:scenario}", + "--index=${input:index}" + ], + "type": "node", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "windows": { + "program": "${workspaceFolder}/node_modules/jest/bin/jest" + } }, { "runtimeExecutable": "/usr/local/bin/node", diff --git a/src/lexer.ts b/src/lexer.ts index e8a6881..165667e 100644 --- a/src/lexer.ts +++ b/src/lexer.ts @@ -13,7 +13,6 @@ export class JsonTemplateLexer { private readonly codeChars: string[]; private buf: Token[]; private idx = 0; - private lastParsedToken?: Token; constructor(template: string) { this.buf = []; @@ -29,6 +28,11 @@ export class JsonTemplateLexer { return this.idx; } + reset(idx: number) { + this.idx = idx; + this.buf = []; + } + getCode(start: number, end: number): string { return this.codeChars.slice(start, end).join(''); } @@ -272,12 +276,11 @@ export class JsonTemplateLexer { lex(): Token { if (this.buf[0]) { this.idx = this.buf[0].range[1]; - this.lastParsedToken = this.buf[0]; + let token = this.buf[0]; this.buf = this.buf.slice(1); - return this.lastParsedToken; + return token; } - this.lastParsedToken = this.advance(); - return this.lastParsedToken; + return this.advance(); } static isLiteralToken(token: Token) { diff --git a/src/parser.ts b/src/parser.ts index d7e4eaf..056062e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -35,7 +35,7 @@ import { LoopExpression, IncrementExpression, } from './types'; -import { JsonTemplateParserError } from './errors'; +import { JsonTemplateLexerError, JsonTemplateParserError } from './errors'; import { BINDINGS_PARAM_KEY, DATA_PARAM_KEY } from './constants'; import { JsonTemplateLexer } from './lexer'; import { CommonUtils } from './utils'; @@ -471,8 +471,16 @@ export class JsonTemplateParser { } private parseConditionalBodyExpr(): Expression { + const currentIndex = this.lexer.currentIndex(); if (this.lexer.match('{')) { - return this.parseCurlyBlockExpr({ blockEnd: '}', parentType: SyntaxType.CONDITIONAL_EXPR }); + try { + return this.parseObjectExpr(); + } catch (error: any) { + if (error instanceof JsonTemplateLexerError) { + this.lexer.reset(currentIndex); + } + return this.parseCurlyBlockExpr({ blockEnd: '}', parentType: SyntaxType.CONDITIONAL_EXPR }); + } } return this.parseBaseExpr(); } diff --git a/test/scenarios/conditions/data.ts b/test/scenarios/conditions/data.ts index ddfaa35..11e0505 100644 --- a/test/scenarios/conditions/data.ts +++ b/test/scenarios/conditions/data.ts @@ -1,14 +1,6 @@ import { Scenario } from '../../types'; export const data: Scenario[] = [ - { - templatePath: 'empty_if.jt', - error: 'Empty statements are not allowed in loop and condtional expressions', - }, - { - templatePath: 'empty_then.jt', - error: 'Empty statements are not allowed in loop and condtional expressions', - }, { templatePath: 'if_block.jt', input: { @@ -58,6 +50,20 @@ export const data: Scenario[] = [ }, output: 5, }, + { + templatePath: 'objects.jt', + input: { + a: 5, + }, + output: { message: 'a > 1' }, + }, + { + templatePath: 'objects.jt', + input: { + a: 0, + }, + output: { message: 'a <= 1' }, + }, { input: { a: 5, diff --git a/test/scenarios/conditions/empty_if.jt b/test/scenarios/conditions/empty_if.jt deleted file mode 100644 index 1fdbebc..0000000 --- a/test/scenarios/conditions/empty_if.jt +++ /dev/null @@ -1 +0,0 @@ -.num > 0 ? {} \ No newline at end of file diff --git a/test/scenarios/conditions/empty_then.jt b/test/scenarios/conditions/empty_then.jt deleted file mode 100644 index 33ed3a4..0000000 --- a/test/scenarios/conditions/empty_then.jt +++ /dev/null @@ -1 +0,0 @@ -.num > 0 ? let a = .num : {} \ No newline at end of file diff --git a/test/scenarios/conditions/objects.jt b/test/scenarios/conditions/objects.jt new file mode 100644 index 0000000..35eff0b --- /dev/null +++ b/test/scenarios/conditions/objects.jt @@ -0,0 +1 @@ +.a > 1 ? { message: "a > 1" } : { message: "a <= 1" } \ No newline at end of file diff --git a/test_engine_local1.ts b/test_engine_local1.ts new file mode 100644 index 0000000..c3ddfc7 --- /dev/null +++ b/test_engine_local1.ts @@ -0,0 +1,6 @@ +import { JsonTemplateEngine } from './src'; + +console.log( + JsonTemplateEngine.translate(` +.output ? .output : { "foo": "bar" }`), +);