/* tslint:disable:no-unused-expression */ import { expect } from 'chai'; import 'mocha'; import { createLexerFromText, lexAssert } from '../util.test'; import { Token } from '../../src/lexer/Token'; describe('lexer/Lexer', () => { describe('peek', () => { it('should return eof token when provider is empty', () => { const lexer = createLexerFromText(''); expect(lexer.peek().type).eq('eof'); }); it('should return next token without moving', () => { const lexer = createLexerFromText('Hello World'); expect(lexer.peek() === lexer.peek()).true; }); }); describe('next', () => { it('should return eof token when provider is empty', () => { const lexer = createLexerFromText(''); for (let i = 0; i < 100; ++i) { expect(lexer.peek().type).eq('eof'); } }); it('should move thru tokens', () => { const lexer = createLexerFromText(` Hello World @section('a', 'b') `.trim()); let tok: Token; tok = lexer.next(); expect(tok.type).eq('text'); if (tok.type === 'text') { expect(tok.value).eq('Hello World\n'); } tok = lexer.next(); expect(tok.type).eq('function'); if (tok.type === 'function') { expect(tok.name).eq('section'); expect(tok.args).deep.eq([`'a'`, `'b'`]); } }); it('should return first token even if peek was called before', () => { const lexer = createLexerFromText(` @for(let i = 0; i < 10; ++i) @endfor `.trim()); expect(lexer.peek()).deep.eq(lexer.next()); }); }); describe('samples', () => { it('sample-1 (complex input)', () => { lexAssert(` {{-- this example is taken from https://laravel.com/docs/5.8/blade#template-inheritance --}} App Name - @yield('title') @section('sidebar') This is the master sidebar. @show
@yield('content')
`.trim(), [ { type: 'comment', value: ' this example is taken from https://laravel.com/docs/5.8/blade#template-inheritance ', }, { type: 'text', value: '\n\n' + '\n\n\n \n App Name - ' , }, { type: 'function', name: 'yield', args: [ `'title'`, ], }, { type: 'text', value: '\n \n \n ', }, { type: 'function', name: 'section', args: [ `'sidebar'`, ], }, { type: 'text', value: '\n This is the master sidebar.\n ', }, { type: 'function', name: 'show', }, { type: 'text', value: '\n\n
\n ', }, { type: 'function', name: 'yield', args: [ `'content'`, ], }, { type: 'text', value: '\n
\n \n', }, ]); }); it('sample-2 (function arguments with nested braces and quotes)', () => { lexAssert(` @include('view.name', { 'foo': ['hello )))', '(( world'], 'bar': 5 * (3 + 4 * (5 - 2)), }) `.trim(), [ { type: 'function', name: 'include', args: [ `'view.name'`, `{ 'foo': ['hello )))', '(( world'], 'bar': 5 * (3 + 4 * (5 - 2)), }`, ], }, ]); }); it('sample-3 (\'{{ }}\' and \'{!! !!}\')', () => { lexAssert(`
Username: {{ user.name }} Status: {{ user.status }} Badge: {!! user.badge !!}
`.trim(), [ { type: 'text', value: '
\n Username: ', }, { type: 'data', escaped: true, value: 'user.name', }, { type: 'text', value: '\n Status: ', }, { type: 'data', escaped: true, value: 'user.status', }, { type: 'text', value: '\n Badge: ', }, { type: 'data', escaped: false, value: 'user.badge', }, { type: 'text', value: '\n
', }, ]); }); it('sample-4 (escape with \'@\')', () => { lexAssert(`
Username: @{{ user.name }} Status: @{{ user.status }} Badge: @{!! user.badge !!}
`.trim(), [ { type: 'text', value: '
\n Username: {{ user.name }}\n Status: {{ user.status }}\n Badge: {!! user.badge !!}\n
', }, ]); }); it('sample-5 (verbatim and js)', () => { lexAssert(` @verbatim Hello World @endverbatim @js for (let i = 0; i < 10; ++i) { print(i); } @endjs @markdown('default') Profile info: - Name: Bill - Number: *+1234567890* - Email: example@example.com @endmarkdown `.trim(), [ { type: 'text', value: '\nHello World\n', }, { type: 'text', value: '\n\n', }, { type: 'raw-function', name: 'js', content: '\nfor (let i = 0; i < 10; ++i) {\n print(i);\n}\n', }, { type: 'text', value: '\n\n', }, { type: 'raw-function', name: 'markdown', args: [`'default'`], content: '\n\nProfile info:\n- Name: Bill\n- Number: *+1234567890*\n- Email: example@example.com\n\n', }, ], { rawFunctions: ['verbatim', 'js', 'markdown'], }); }); it('sample-6 (filters)', () => { lexAssert(` {{ 'test' | ucfirst }} {{ 'hello' | ucfirst | uclast }} {{ ' HeLlO ' | trim }} {{ name | ucfirst | substr:0,1 }} {!! time | format-time:'Y-m-d H:i:s' !!} `.trim(), [ { type: 'data', escaped: true, value: '\'test\'', filters: [ { name: 'ucfirst', args: [] }, ], }, { type: 'text', value: '\n', }, { type: 'data', escaped: true, value: '\'hello\'', filters: [ { name: 'ucfirst', args: [] }, { name: 'uclast', args: [] }, ], }, { type: 'text', value: '\n', }, { type: 'data', escaped: true, value: '\' HeLlO \'', filters: [ { name: 'trim', args: [] }, ], }, { type: 'text', value: '\n', }, { type: 'data', escaped: true, value: 'name', filters: [ { name: 'ucfirst', args: [] }, { name: 'substr', args: ['0', '1'] }, ], }, { type: 'text', value: '\n', }, { type: 'data', escaped: false, value: 'time', filters: [ { name: 'format-time', args: ['\'Y-m-d H:i:s\''] }, ], }, ]); }); }); });