Skip to content

Commit

Permalink
feat(tags): implement if,elseif and else tags
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jul 3, 2018
1 parent e4935eb commit f7647b5
Show file tree
Hide file tree
Showing 27 changed files with 290 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ indent_style = tab

[*.md]
trim_trailing_whitespace = false

[fixtures/**/*]
insert_final_newline = ignore
15 changes: 15 additions & 0 deletions fixtures/else-if-tag/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(function (template, ctx) {
let out = ''
if(ctx.resolve('username') === 'virk') {
out += ' Hello VK'
out += '\n'
} else if(ctx.resolve('username')) {
out += ' Hello '
out += `${ctx.escape(ctx.resolve('username'))}`
out += '\n'
} else {
out += ' Hello Guest!'
}
out += '\n'
return out
})(template, ctx)
7 changes: 7 additions & 0 deletions fixtures/else-if-tag/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@if(username === 'virk')
Hello VK
@elseif(username)
Hello {{ username }}
@else
Hello Guest!
@endif
3 changes: 3 additions & 0 deletions fixtures/else-if-tag/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"username": "nikk"
}
1 change: 1 addition & 0 deletions fixtures/else-if-tag/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello nikk
12 changes: 12 additions & 0 deletions fixtures/else-tag/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(function (template, ctx) {
let out = ''
if(ctx.resolve('username')) {
out += ' Hello '
out += `${ctx.escape(ctx.resolve('username'))}`
out += '\n'
} else {
out += ' Hello guest!'
}
out += '\n'
return out
})(template, ctx)
9 changes: 9 additions & 0 deletions fixtures/else-tag/if-tag/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(function (template, ctx) {
let out = ''
if(ctx.resolve('username')) {
out += ' Hello '
out += `${ctx.escape(ctx.resolve('username'))}`
}
out += '\n'
return out
})(template, ctx)
3 changes: 3 additions & 0 deletions fixtures/else-tag/if-tag/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@if(username)
Hello {{ username }}
@endif
3 changes: 3 additions & 0 deletions fixtures/else-tag/if-tag/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"username": "virk"
}
1 change: 1 addition & 0 deletions fixtures/else-tag/if-tag/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello virk
5 changes: 5 additions & 0 deletions fixtures/else-tag/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@if(username)
Hello {{ username }}
@else
Hello guest!
@endif
2 changes: 2 additions & 0 deletions fixtures/else-tag/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions fixtures/else-tag/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello guest!
9 changes: 9 additions & 0 deletions fixtures/if-tag/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(function (template, ctx) {
let out = ''
if(ctx.resolve('username')) {
out += ' Hello '
out += `${ctx.escape(ctx.resolve('username'))}`
}
out += '\n'
return out
})(template, ctx)
3 changes: 3 additions & 0 deletions fixtures/if-tag/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@if(username)
Hello {{ username }}
@endif
3 changes: 3 additions & 0 deletions fixtures/if-tag/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"username": "virk"
}
1 change: 1 addition & 0 deletions fixtures/if-tag/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello virk
11 changes: 11 additions & 0 deletions fixtures/nested-if-tag/compiled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(function (template, ctx) {
let out = ''
if(ctx.resolve('username')) {
if(ctx.resolve('age') > 18) {
out += ' Hello '
out += `${ctx.escape(ctx.resolve('username'))}`
}
}
out += '\n'
return out
})(template, ctx)
5 changes: 5 additions & 0 deletions fixtures/nested-if-tag/index.edge
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@if(username)
@if(age > 18)
Hello {{ username }}
@endif
@endif
4 changes: 4 additions & 0 deletions fixtures/nested-if-tag/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"username": "virk",
"age": 20
}
1 change: 1 addition & 0 deletions fixtures/nested-if-tag/index.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello virk
9 changes: 9 additions & 0 deletions japaFile.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
require('ts-node/register')

const cli = require('japa/cli')
const Assertion = require('japa/api').Assertion
const os = require('os')

Assertion.use((chai, utils) => {
chai.assert.stringEqual = function (val, exp, msg) {
new chai.Assertion(val.split(/\r\n|\n/), msg).to.deep.equal(exp.split(/\r\n|\n/))
}
})

cli.run('test/**/*.spec.ts')
27 changes: 27 additions & 0 deletions src/Tags/Else.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Parser } from 'edge-parser'
import { EdgeBuffer } from 'edge-parser/build/src/EdgeBuffer'
import { IBlockNode } from 'edge-lexer/build/src/Contracts'

export class ElseTag {
public static block = false
public static seekable = false
public static selfclosed = false

/**
* Compiles else block node to Javascript else statement
*/
public compile (parser: Parser, buffer: EdgeBuffer, token: IBlockNode) {
buffer.dedent()
buffer.writeStatement(`} else {`)
buffer.indent()
}
}
29 changes: 29 additions & 0 deletions src/Tags/ElseIf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Parser } from 'edge-parser'
import { EdgeBuffer } from 'edge-parser/build/src/EdgeBuffer'
import { IBlockNode } from 'edge-lexer/build/src/Contracts'

export class ElseIfTag {
public static block = false
public static seekable = true
public static selfclosed = false

/**
* Compiles the else if block node to a Javascript if statement
*/
public compile (parser: Parser, buffer: EdgeBuffer, token: IBlockNode) {
const parsed = parser.parseJsArg(token.properties.jsArg, token.lineno)

buffer.dedent()
buffer.writeStatement(`} else if(${parser.statementToString(parsed)}) {`)
buffer.indent()
}
}
66 changes: 66 additions & 0 deletions src/Tags/If.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Parser } from 'edge-parser'
import { EdgeBuffer } from 'edge-parser/build/src/EdgeBuffer'
import { IBlockNode, INode } from 'edge-lexer/build/src/Contracts'

export class IfTag {
public static block = true
public static seekable = true
public static selfclosed = false

/**
* Returns a boolean telling whether the node with newline has a parent
* of else or elseif.
*/
private _childOfElse (children: (IBlockNode | INode)[], index: number): boolean {
const node = children[index - 1]
if (!node || node.type !== 'block') {
return false
}

return ['else', 'elseif'].indexOf((node as IBlockNode).properties.name) > -1
}

/**
* Compiles the if block node to a Javascript if statement
*/
public compile (parser: Parser, buffer: EdgeBuffer, token: IBlockNode) {
const parsed = parser.parseJsArg(token.properties.jsArg, token.lineno)

buffer.writeStatement(`if(${parser.statementToString(parsed)}) {`)
buffer.indent()

/**
* Removing first and last newlines, they are redudant and will hurt
* when not using HTML as the markup language
*/
token.children.shift()
token.children.pop()

/**
* Process of all kids recursively
*/
token.children.forEach((child, index) => {
/**
* Ignoring newlines right after the else tag, since else itself
* doesn't have children and if has to handle it
*/
if (child.type === 'newline' && this._childOfElse(token.children, index)) {
return
}

parser.processToken(child, buffer)
})

buffer.dedent()
buffer.writeStatement('}')
}
}
12 changes: 12 additions & 0 deletions src/Tags/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* edge
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

export { IfTag as if } from './If'
export { ElseTag as else } from './Else'
export { ElseIfTag as elseif } from './ElseIf'
45 changes: 45 additions & 0 deletions test/fixtures.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* edge-parser
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import * as test from 'japa'
import { readdirSync, readFileSync, statSync } from 'fs'
import { join } from 'path'
import { Template } from '../src/Template'
import { Compiler } from '../src/Compiler'
import { Loader } from '../src/Loader'
import { Presenter } from '../src/Presenter'
import * as tags from '../src/Tags'

const basePath = join(__dirname, '../fixtures')
const loader = new Loader()
loader.mount('default', basePath)
const compiler = new Compiler(loader, tags)

test.group('Fixtures', () => {
const dirs = readdirSync(basePath).filter((file) => {
return statSync(join(basePath, file)).isDirectory()
})

dirs.forEach((dir) => {
const dirBasePath = join(basePath, dir)

test(dir, (assert) => {
const template = new Template(compiler, {})
const presenter = new Presenter(JSON.parse(readFileSync(join(dirBasePath, 'index.json'), 'utf-8')))

const compiled = compiler.compile(`${dir}/index.edge`)
const expectedCompiled = readFileSync(join(dirBasePath, 'compiled.js'), 'utf-8')
assert.stringEqual(compiled, expectedCompiled)

const out = readFileSync(join(dirBasePath, 'index.txt'), 'utf-8')
const output = template.render(`${dir}/index.edge`, presenter)
assert.equal(output.trim(), out)
})
})
})

0 comments on commit f7647b5

Please sign in to comment.