first commit
This commit is contained in:
7
node_modules/@n8n_io/riot-tmpl/test/.eslintrc.yml
generated
vendored
Normal file
7
node_modules/@n8n_io/riot-tmpl/test/.eslintrc.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
env:
|
||||
mocha: true
|
||||
|
||||
globals:
|
||||
tmpl: true
|
||||
brackets: true
|
||||
expect: true
|
||||
71
node_modules/@n8n_io/riot-tmpl/test/browsers.js
generated
vendored
Normal file
71
node_modules/@n8n_io/riot-tmpl/test/browsers.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable */
|
||||
module.exports = {
|
||||
// Windows
|
||||
bs_ie_9: {
|
||||
'browser' : 'ie',
|
||||
'browser_version' : '9.0',
|
||||
'os' : 'Windows',
|
||||
'os_version' : '7'
|
||||
},
|
||||
bs_ie_10: {
|
||||
'browser' : 'ie',
|
||||
'browser_version' : '10.0',
|
||||
'os' : 'Windows',
|
||||
'os_version' : '7'
|
||||
},
|
||||
bs_ie_11: {
|
||||
'browser' : 'ie',
|
||||
'browser_version' : '11.0',
|
||||
'os' : 'Windows',
|
||||
'os_version' : '7'
|
||||
},
|
||||
bs_edge: {
|
||||
'browser' : 'edge',
|
||||
'browser_version' : '12.0',
|
||||
'os' : 'Windows',
|
||||
'os_version' : '10'
|
||||
},
|
||||
// Mac
|
||||
bs_safari_6: {
|
||||
'browser' : 'safari',
|
||||
'browser_version' : '6.2',
|
||||
'os' : 'OS X',
|
||||
'os_version' : 'Mountain Lion'
|
||||
},
|
||||
bs_safari_7: {
|
||||
'browser' : 'safari',
|
||||
'browser_version' : '7.1',
|
||||
'os' : 'OS X',
|
||||
'os_version' : 'Mavericks'
|
||||
},
|
||||
bs_safari_8: {
|
||||
'browser' : 'safari',
|
||||
'browser_version' : '8.0',
|
||||
'os' : 'OS X',
|
||||
'os_version' : 'Yosemite'
|
||||
},
|
||||
bs_firefox: {
|
||||
'browser' : 'firefox',
|
||||
'os' : 'OS X',
|
||||
'os_version' : 'Yosemite'
|
||||
},
|
||||
bs_iphone_5: {
|
||||
'browserName' : 'iPhone',
|
||||
'device' : 'iPhone 5',
|
||||
'os_version': '6.0',
|
||||
'os': 'ios'
|
||||
},
|
||||
bs_iphone_6: {
|
||||
'browserName' : 'iPhone',
|
||||
'device' : 'iPhone 6',
|
||||
'os_version': '8.0',
|
||||
'os': 'ios'
|
||||
},
|
||||
// Android
|
||||
bs_android_4: {
|
||||
'browserName' : 'android',
|
||||
'device' : 'Samsung Galaxy S5',
|
||||
'os_version': '4.4',
|
||||
'os': 'android'
|
||||
}
|
||||
}
|
||||
48
node_modules/@n8n_io/riot-tmpl/test/karma.conf.js
generated
vendored
Normal file
48
node_modules/@n8n_io/riot-tmpl/test/karma.conf.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
module.exports = function (config) {
|
||||
|
||||
var browsers,
|
||||
customLaunchers = []
|
||||
|
||||
if (process.env.BROWSERSTACK) {
|
||||
customLaunchers = require('./browsers')
|
||||
browsers = Object.keys(customLaunchers)
|
||||
browsers.forEach(function (browser) { customLaunchers[browser].base = 'BrowserStack' })
|
||||
} else {
|
||||
browsers = ['PhantomJS']
|
||||
}
|
||||
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['mocha'],
|
||||
plugins: [
|
||||
'karma-mocha',
|
||||
'karma-coverage',
|
||||
'karma-browserstack-launcher',
|
||||
'karma-phantomjs-launcher'
|
||||
],
|
||||
|
||||
files: [
|
||||
'../node_modules/expect.js/index.js',
|
||||
'../dist/tmpl.js',
|
||||
'specs/core.specs.js',
|
||||
'specs/brackets.specs.js'
|
||||
],
|
||||
|
||||
browsers: browsers,
|
||||
|
||||
customLaunchers: customLaunchers,
|
||||
|
||||
reporters: ['progress', 'coverage'],
|
||||
preprocessors: {
|
||||
'../dist/tmpl.js': ['coverage']
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: '../coverage/',
|
||||
reporters: [{
|
||||
type: 'lcov',
|
||||
subdir: 'report-lcov'
|
||||
}]
|
||||
},
|
||||
singleRun: true
|
||||
})
|
||||
}
|
||||
139
node_modules/@n8n_io/riot-tmpl/test/perf.js
generated
vendored
Normal file
139
node_modules/@n8n_io/riot-tmpl/test/perf.js
generated
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
/* eslint no-console: 0, max-len: 0 */
|
||||
'use strict' // eslint-disable-line
|
||||
|
||||
var
|
||||
version = require('../package.json').version,
|
||||
tmplNew = require('../dist/tmpl').tmpl,
|
||||
tmpl22 = require('./v223/tmpl223.js').tmpl
|
||||
|
||||
var
|
||||
data = { num: 1, str: 'string', date: new Date(), bool: true, item: null },
|
||||
tmplList = [
|
||||
[' { date }', ' ' + data.date],
|
||||
[' { num === 0 ? 0 : num } ', ' ' + data.num + ' '],
|
||||
['<p>\n{str + num}\n</p>', '<p>\nstring1\n</p>'],
|
||||
[' "{ str.slice(0, 3).replace(/t/, \'T\') }" ', ' "sTr" '],
|
||||
[' "{this.num}" ', ' "1" '],
|
||||
['{ !bool } ', ' '],
|
||||
['{} ', ' ']
|
||||
],
|
||||
exprList = [
|
||||
['{ date }', data.date],
|
||||
['{ num === 0 ? 0 : num }', data.num],
|
||||
['<p>{str + num}</p>', '<p>string1</p>'],
|
||||
['{ "-" + str.slice(0, 3).replace(/t/, \'T\') + "-" }', '-sTr-'],
|
||||
['{this.num}', 1],
|
||||
['{ !bool }', false],
|
||||
['{}', undefined]
|
||||
],
|
||||
csList = [
|
||||
['{ foo: num }', 'foo'],
|
||||
['{ foo: num, bar: item }', 'foo'],
|
||||
['{ foo: date.getFullYear() > 2000, bar: str==this.str }', 'foo bar'],
|
||||
['{ foo: str + num }', 'foo']
|
||||
],
|
||||
ex22a, ex22b, ex22c, mem22, tt22 = [],
|
||||
exNewa, exNewb, exNewc, memNew, tt23 = []
|
||||
|
||||
var LOOP = 50000, TMAX = 12, CPAD = 12, NPAD = 11
|
||||
|
||||
console.log()
|
||||
console.log('Testing %d expressions %d times each.', exprList.length + csList.length, LOOP)
|
||||
|
||||
console.log('tmpl v2.2.4 ...')
|
||||
mem22 = [0, 0, 0]
|
||||
testExpr(tmpl22, data, tt22, exprList, mem22)
|
||||
ex22a = tt22.reduce(numsum)
|
||||
testExpr(tmpl22, data, tt22, csList, mem22)
|
||||
ex22b = tt22.reduce(numsum)
|
||||
testExpr(tmpl22, data, tt22, tmplList, mem22)
|
||||
ex22c = tt22.reduce(numsum)
|
||||
|
||||
console.log('tmpl v' + version + ' ...')
|
||||
memNew = [0, 0, 0]
|
||||
testExpr(tmplNew, data, tt23, exprList, memNew, 1)
|
||||
exNewa = tt23.reduce(numsum)
|
||||
testExpr(tmplNew, data, tt23, csList, memNew, 1)
|
||||
exNewb = tt23.reduce(numsum)
|
||||
testExpr(tmplNew, data, tt23, tmplList, memNew, 1)
|
||||
exNewc = tt23.reduce(numsum)
|
||||
|
||||
console.log()
|
||||
console.log('%s tmpl 2.2.4 new v' + version, padr('Results', CPAD))
|
||||
console.log('%s ---------- ----------', replicate('-', CPAD))
|
||||
console.log('%s: %s %s', padr('Expressions', CPAD), padl(ex22a, NPAD), padl(exNewa, NPAD))
|
||||
console.log('%s: %s %s', padr('Shorthands', CPAD), padl(ex22b, NPAD), padl(exNewb, NPAD))
|
||||
console.log('%s: %s %s', padr('Templates', CPAD), padl(ex22c, NPAD), padl(exNewc, NPAD))
|
||||
console.log('%s: %s %s', padr('TOTAL', CPAD), padl(ex22a + ex22b + ex22c, NPAD), padl(exNewa + exNewb + exNewc, NPAD))
|
||||
console.log()
|
||||
console.log('Memory')
|
||||
//console.log('%s: %s %s', padr('Res set size', CPAD), padl(mem22[0], NPAD), padl(memNew[0], NPAD))
|
||||
console.log('%s: %s %s', padr('Heap total', CPAD), padl(mem22[1], NPAD), padl(memNew[1], NPAD))
|
||||
console.log('%s: %s %s', padr('Heap used', CPAD), padl(mem22[2], NPAD), padl(memNew[2], NPAD))
|
||||
console.log()
|
||||
|
||||
console.log('NOTES:')
|
||||
console.log('- Memory used is the difference during the test of the heapTotal info')
|
||||
console.log(' provided by the node process.memoryUsage() function.')
|
||||
console.log('- Execution time in both versions excludes expression compilation.')
|
||||
console.log('- Minimum & maximum times are removed.')
|
||||
|
||||
function testExpr (tmpl, data, times, list, agc) {
|
||||
var ogc, gc1, gc2, gc3
|
||||
times.length = 0
|
||||
global.gc()
|
||||
global.gc()
|
||||
ogc = process.memoryUsage()
|
||||
gc1 = ogc.rss
|
||||
gc2 = ogc.heapTotal
|
||||
gc3 = ogc.heapUsed
|
||||
|
||||
list.forEach(function (pair, idx) {
|
||||
var
|
||||
tt = new Array(TMAX),
|
||||
s, i, j,
|
||||
expr = pair[0]
|
||||
|
||||
s = tmpl(expr, data)
|
||||
//assert(s === pair[1])
|
||||
if (s !== pair[1]) {
|
||||
throw new Error('`' + s + '` in #' + idx + ' is not `' + pair[1] + '`')
|
||||
}
|
||||
|
||||
for (i = 0; i < tt.length; ++i) {
|
||||
tt[i] = Date.now()
|
||||
for (j = 0; j < LOOP; ++j) {
|
||||
s = tmpl(expr, data)
|
||||
}
|
||||
tt[i] = Date.now() - tt[i]
|
||||
}
|
||||
|
||||
// discard min & max times
|
||||
tt.sort(numsort).pop()
|
||||
tt.shift()
|
||||
times[idx] = tt.reduce(numsum)
|
||||
})
|
||||
|
||||
ogc = process.memoryUsage()
|
||||
agc[0] += ogc.rss - gc1
|
||||
agc[1] += ogc.heapTotal - gc2
|
||||
agc[2] += ogc.heapUsed - gc3
|
||||
}
|
||||
|
||||
function numsort (a, b) {
|
||||
return a - b
|
||||
}
|
||||
function numsum (a, b) {
|
||||
return a + b
|
||||
}
|
||||
function replicate (s, n) {
|
||||
return n < 1 ? '' : (new Array(n + 1)).join(s)
|
||||
}
|
||||
function padr (s, n) {
|
||||
s = '' + s
|
||||
return s + replicate(' ', n - s.length)
|
||||
}
|
||||
function padl (s, n) {
|
||||
s = '' + s
|
||||
return replicate(' ', n - s.length) + s
|
||||
}
|
||||
7
node_modules/@n8n_io/riot-tmpl/test/runner.js
generated
vendored
Normal file
7
node_modules/@n8n_io/riot-tmpl/test/runner.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
expect = require('expect.js')
|
||||
tmpl = require('../dist/tmpl').tmpl
|
||||
brackets = require('../dist/tmpl').brackets
|
||||
|
||||
require('./specs/core.specs.js')
|
||||
require('./specs/brackets.specs.js')
|
||||
446
node_modules/@n8n_io/riot-tmpl/test/specs/brackets.specs.js
generated
vendored
Normal file
446
node_modules/@n8n_io/riot-tmpl/test/specs/brackets.specs.js
generated
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
/* eslint max-len: 0 */
|
||||
|
||||
describe('brackets', function () {
|
||||
|
||||
var data = { x: 2, str: 'x', JSON: JSON }
|
||||
|
||||
// send 1 or 2 in 'err' to enable internal information
|
||||
function render (str, dbg) {
|
||||
if (dbg) data._debug_ = 1
|
||||
return tmpl(str, data)
|
||||
}
|
||||
function setBrackets (s) {
|
||||
brackets.set(s)
|
||||
}
|
||||
function resetBrackets () {
|
||||
brackets.set('{ }')
|
||||
}
|
||||
function bracketsPair () {
|
||||
return brackets(0) + ' ' + brackets(1)
|
||||
}
|
||||
|
||||
// reset brackets to defaults
|
||||
after(resetBrackets)
|
||||
beforeEach(resetBrackets)
|
||||
resetBrackets()
|
||||
|
||||
it('default to { } if setting to undefined, null, or an empty string', function () {
|
||||
var ab = [null, '']
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
setBrackets(ab[i])
|
||||
expect(bracketsPair()).to.equal('{ }')
|
||||
expect(render('{ x }')).to.equal(2)
|
||||
}
|
||||
})
|
||||
|
||||
//// custom brackets
|
||||
it('single and multi character custom brackets', function () {
|
||||
|
||||
// single character brackets
|
||||
brackets.set('[ ]')
|
||||
expect(bracketsPair()).to.equal('[ ]')
|
||||
expect(render('[ x ]')).to.equal(2)
|
||||
expect(render('[ str\\[0\\] ]')).to.equal('x')
|
||||
|
||||
// multi character brackets
|
||||
setBrackets('{{ }}')
|
||||
expect(bracketsPair()).to.equal('{{ }}')
|
||||
expect(render('{{ x }}')).to.equal(2)
|
||||
|
||||
// asymmetric brackets
|
||||
setBrackets('${ }')
|
||||
expect(bracketsPair()).to.equal('${ }')
|
||||
expect(render('${ x }')).to.equal(2)
|
||||
})
|
||||
|
||||
describe('using brackets inside expressions', function () {
|
||||
|
||||
it('brackets in expressions can always be escaped', function () {
|
||||
expect(render('{ "\\{ 1 \\}" }')).to.equal('{ 1 }')
|
||||
expect(render('\\{ 1 }')).to.equal('{ 1 }')
|
||||
expect(render('{ "\\}" }')).to.equal('}')
|
||||
expect(render('{ "\\{" }')).to.equal('{')
|
||||
expect(render('{ \\{\\} }')).to.eql({})
|
||||
})
|
||||
|
||||
it('though escaping is optional', function () {
|
||||
expect(render('{ JSON.stringify({ x: 5 }) }')).to.equal('{"x":5}')
|
||||
expect(render('a{ "b{c}d" }e { "{f{f}}" } g')).to.equal('ab{c}de {f{f}} g')
|
||||
|
||||
// for custom brackets as well
|
||||
setBrackets('[ ]')
|
||||
expect(render('a[ "b[c]d" ]e [ "[f[f]]" ] g')).to.equal('ab[c]de [f[f]] g')
|
||||
|
||||
setBrackets('{{ }}')
|
||||
expect(render('a{{ "b{{c}}d" }}e {{ "{f{{f}}}" }} g')).to.equal('ab{{c}}de {f{{f}}} g')
|
||||
expect(render('{{{}}}')).to.eql({})
|
||||
|
||||
setBrackets('{^ ^}')
|
||||
expect(render('{^ "x" ^}')).to.equal('x')
|
||||
expect(render('{^ /{^}/ ^}').source).to.equal(/{^}/.source)
|
||||
|
||||
setBrackets('[[ ]]')
|
||||
expect(render('a[[ "b[[c]]d" ]]e [["[[f[f]]]"]]g[[]]')).to.equal('ab[[c]]de [[f[f]]]g')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('2.2.3', function () {
|
||||
|
||||
it('escaped brackets, some 8 bit, iso-8859-1 characters', function () {
|
||||
var vals = [
|
||||
// source brackets(2) + brackets(3)
|
||||
//['<% %>', '<% %>' ], // angle brackets unsupported from 2.4
|
||||
['{# #}', '{# #}'],
|
||||
['[! !]', '\\[! !\\]'],
|
||||
['·ʃ ʃ', '·ʃ ʃ'],
|
||||
['{$ $}', '{\\$ \\$}'],
|
||||
['_( )_', '_\\( \\)_']
|
||||
]
|
||||
var rs, bb, i
|
||||
|
||||
rs = new RegExp('{x}')
|
||||
setBrackets('{ }') // same as defaults
|
||||
expect(brackets(rs)).to.be(rs) // must returns the same object (to.be)
|
||||
expect(brackets(0)).to.equal('{')
|
||||
expect(brackets(1)).to.equal('}')
|
||||
expect(brackets(2)).to.equal('{')
|
||||
expect(brackets(3)).to.equal('}')
|
||||
|
||||
for (i = 0; i < vals.length; i++) {
|
||||
// set the new brackets pair
|
||||
rs = vals[i]
|
||||
setBrackets(rs[0])
|
||||
bb = rs[0].split(' ')
|
||||
rs = rs[1]
|
||||
expect(brackets(/{ }/g).source).to.equal(rs)
|
||||
expect(brackets(0)).to.equal(bb[0])
|
||||
expect(brackets(1)).to.equal(bb[1]); bb = rs.split(' ')
|
||||
expect(brackets(2)).to.equal(bb[0])
|
||||
expect(brackets(3)).to.equal(bb[1])
|
||||
}
|
||||
})
|
||||
|
||||
//// Better recognition of nested brackets, escaping is almost unnecessary.
|
||||
//// (include escaped version for compatibility)
|
||||
|
||||
describe('escaping is almost unnecessary', function () {
|
||||
|
||||
// ...unless you're doing something very special?
|
||||
it('no problem with brackets inside strings', function () {
|
||||
//, e.g. { "{" } or { "}" }
|
||||
expect(render('a{ "b{" }c')).to.equal('ab{c')
|
||||
expect(render('a{ "b\\{" }c')).to.equal('ab{c')
|
||||
expect(render('a{ "{b" }c')).to.equal('a{bc')
|
||||
expect(render('a{ "\\{b" }c')).to.equal('a{bc')
|
||||
|
||||
expect(render('a{ "b}" }c')).to.equal('ab}c')
|
||||
expect(render('a{ "b\\}" }c')).to.equal('ab}c')
|
||||
expect(render('a{ "}b" }c')).to.equal('a}bc')
|
||||
expect(render('a{ "\\}b" }c')).to.equal('a}bc')
|
||||
|
||||
expect(render('{"{"}')).to.equal('{')
|
||||
expect(render('{"\\{"}')).to.equal('{')
|
||||
expect(render('{"}"}')).to.equal('}')
|
||||
expect(render('{"\\}"}')).to.equal('}')
|
||||
|
||||
expect(render('{{a:"{}}"}}')).to.eql({ a: '{}}' })
|
||||
expect(render('{{a:"{\\}\\}"}}')).to.eql({ a: '{}}' })
|
||||
})
|
||||
|
||||
it('with custom brackets to "[ ]" (bad idea)', function () {
|
||||
setBrackets('[ ]')
|
||||
expect(render('[ str[0] ]')).to.be('x')
|
||||
expect(render('\\[[ str[0] ]]')).to.be('[x]')
|
||||
expect(render('[ [1].pop() ]')).to.be(1)
|
||||
expect(render('a,[["b", "c"]],d')).to.be('a,b,c,d')
|
||||
})
|
||||
|
||||
it('with custom brackets to "( )" (another bad idea)', function () {
|
||||
setBrackets('( )')
|
||||
expect(render('(str.charAt(0))')).to.be('x')
|
||||
expect(render('\\((str.charAt(0)))')).to.be('(x)')
|
||||
expect(render('((1 + 1))')).to.be(2)
|
||||
expect(render('a,(("b"),("c")),d')).to.be('a,c,d')
|
||||
})
|
||||
|
||||
it('with multi character brackets {{ }}, e.g. on "{{{a:1}}}"', function () {
|
||||
setBrackets('{{ }}')
|
||||
// note: '{{{\\}}}' generate Parse error, this equals to '{{ {\\} }}'
|
||||
expect(render('{{{ a:1 }}}')).to.eql({ a: 1 })
|
||||
expect(render('{{{a: {}}}}')).to.eql({ a: {} })
|
||||
expect(render('{{{a: {\\}}}}')).to.eql({ a: {} })
|
||||
expect(render(' {{{}}}')).to.eql(' [object Object]')
|
||||
})
|
||||
|
||||
it('with multi character brackets (( ))', function () {
|
||||
setBrackets('(( ))')
|
||||
expect(render('((({})))')).to.eql({})
|
||||
expect(render('(((("o"))))="o"')).to.be('o="o"')
|
||||
expect(render('((( ("o") )))="o"')).to.be('o="o"')
|
||||
})
|
||||
|
||||
// - you're using asymmetric custom brackets, e.g.: ${ } instead of { }, [ ], {{ }}, <% %>
|
||||
it('with asymmetric brackets, e.g. ${ {a:1} } instead of ${ {a:1\\} }',
|
||||
function () {
|
||||
setBrackets('${ }')
|
||||
expect(render('${ {a:1} }')).to.eql({ a: 1 })
|
||||
expect(render('${ {a:1\\} }')).to.eql({ a: 1 })
|
||||
})
|
||||
|
||||
it('silly brackets? good luck', function () {
|
||||
setBrackets('[ ]]')
|
||||
expect(render('a[ "[]]"]]b')).to.be('a[]]b')
|
||||
expect(render('[[[]]]]')).to.eql([[]])
|
||||
|
||||
setBrackets('( ))')
|
||||
expect(render('a( "b))" ))c')).to.be('ab))c')
|
||||
expect(render('a( (("bc))")) ))')).to.be('abc))')
|
||||
expect(render('a( ("(((b))") ))c')).to.be('a(((b))c')
|
||||
expect(render('a( ("b" + (")c" ))))')).to.be('ab)c') // test skipBracketedPart()
|
||||
})
|
||||
|
||||
it('please find a case when escaping is still needed!', function () {
|
||||
//expect(render).withArgs('{ "}" }').to.throwError()
|
||||
expect(render('{ "}" }')).to.equal('}')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
// end of brackets 2.2.3
|
||||
|
||||
|
||||
describe('2.3.x', function () {
|
||||
|
||||
it('don\'t use characters in the set [\\x00-\\x1F<>a-zA-Z0-9\'",;\\]',
|
||||
function () {
|
||||
expect(setBrackets).withArgs(', ,').to.throwError()
|
||||
expect(setBrackets).withArgs('" "').to.throwError()
|
||||
expect(setBrackets).withArgs('a[ ]a').to.throwError()
|
||||
expect(bracketsPair()).to.be('{ }')
|
||||
})
|
||||
|
||||
it('you can\'t use the pretty <% %> anymore', function () {
|
||||
expect(setBrackets).withArgs('<% %>').to.throwError()
|
||||
})
|
||||
|
||||
it('brackets.array in sync with riot.settings.brackets', function () {
|
||||
var
|
||||
settings = typeof riot === 'undefined' ? {} : riot.settings,
|
||||
str
|
||||
brackets.settings = settings
|
||||
|
||||
settings.brackets = '{{ }}'
|
||||
str = render('{{ x }} and { x }')
|
||||
expect(str).to.be('2 and { x }')
|
||||
|
||||
// restore using riot.settings
|
||||
settings.brackets = '{ }'
|
||||
str = render('\\{{ x }} and { x }')
|
||||
expect(str).to.be('{2} and 2')
|
||||
|
||||
// change again, now with riot.settings
|
||||
settings.brackets = '{{ }}'
|
||||
str = render('{{ x }} and { x }')
|
||||
expect(str).to.be('2 and { x }')
|
||||
|
||||
settings.brackets = undefined
|
||||
str = render('\\{{ x }} and { x } ')
|
||||
expect(str).to.be('{2} and 2 ')
|
||||
|
||||
resetBrackets()
|
||||
})
|
||||
|
||||
it('riot.settings.brackets has immediate effect', function () {
|
||||
var
|
||||
settings,
|
||||
haveRiot
|
||||
resetBrackets()
|
||||
|
||||
brackets.settings.brackets = '$ $'
|
||||
expect(bracketsPair()).to.be('$ $')
|
||||
|
||||
if (typeof riot !== 'undefined' && riot.settings) {
|
||||
expect(riot.settings.brackets).to.be('^ ^')
|
||||
riot.settings.brackets = '^ ^'
|
||||
expect(brackets.settings.brackets).to.be('^ ^')
|
||||
expect(bracketsPair()).to.be('^ ^')
|
||||
haveRiot = true
|
||||
}
|
||||
|
||||
// reasign brackets.settings
|
||||
|
||||
resetBrackets()
|
||||
brackets.settings = settings = {}
|
||||
|
||||
settings.brackets = '^ ^'
|
||||
expect(brackets.settings.brackets).to.be('^ ^')
|
||||
expect(bracketsPair()).to.be('^ ^')
|
||||
|
||||
brackets.settings.brackets = '$ $'
|
||||
expect(settings.brackets).to.be('$ $')
|
||||
expect(bracketsPair()).to.be('$ $')
|
||||
|
||||
brackets.settings = null // reset to {brackets: DEFAULT}
|
||||
|
||||
expect(brackets.settings.brackets).to.be('{ }')
|
||||
expect(bracketsPair()).to.be('{ }')
|
||||
|
||||
if (haveRiot)
|
||||
brackets.settings = riot.settings
|
||||
resetBrackets()
|
||||
})
|
||||
|
||||
it('don\'t use internal functions', function () {
|
||||
var bp
|
||||
setBrackets(null) //to default
|
||||
|
||||
bp = brackets.array(null)
|
||||
expect(bp[0] + bp[1]).to.be('{}')
|
||||
expect(bracketsPair()).to.be('{ }')
|
||||
|
||||
bp = brackets.array('~ ~')
|
||||
expect(bp[0] + bp[1]).to.be('~~')
|
||||
expect(bracketsPair()).to.be('{ }') // must no change
|
||||
})
|
||||
|
||||
describe('brackets.split', function () {
|
||||
|
||||
it('the new kid in the town is a key function', function () {
|
||||
var
|
||||
str = '<tag att="{ a }" expr1={a<1} expr2={a>2}>\n\\{{body}}\r\n</tag>\n'
|
||||
|
||||
resetBrackets() // set brackets to default
|
||||
var a = brackets.split(str)
|
||||
|
||||
expect(a).to.have.length(9)
|
||||
expect(a[1]).to.be(' a ')
|
||||
expect(a[3]).to.be('a<1')
|
||||
expect(a[5]).to.be('a>2')
|
||||
expect(a[6]).to.be('>\n\\{')
|
||||
expect(a[7]).to.be('body')
|
||||
expect(a[8]).to.be('}\r\n</tag>\n')
|
||||
})
|
||||
|
||||
it('serve unescaped template to the tmpl module', function () {
|
||||
var
|
||||
str = '<tag att="{ a }" expr1={a<1} expr2={a>2}>\n\\{{body}}\r\n</tag>\n'
|
||||
|
||||
resetBrackets()
|
||||
var a = brackets.split(str, true)
|
||||
|
||||
expect(a).to.have.length(9)
|
||||
expect(a[6]).to.be('>\n{')
|
||||
})
|
||||
|
||||
it('handle single or double quotes inside quoted expressions', function () {
|
||||
var
|
||||
str = '<tag att1="{"a"}" att2={"a"} att3={\'a\'}>\'{\'a\'}\'</tag>'
|
||||
|
||||
resetBrackets()
|
||||
var a = brackets.split(str, true)
|
||||
var b = a.qblocks
|
||||
|
||||
expect(a).to.have.length(9)
|
||||
expect(a[0]).to.be('<tag att1="')
|
||||
expect(a[8]).to.be('\'</tag>')
|
||||
|
||||
expect(b).to.have.length(4)
|
||||
expect(b[0]).to.be('"a"')
|
||||
expect(b[1]).to.be('"a"')
|
||||
expect(b[2]).to.be("'a'")
|
||||
expect(b[3]).to.be("'a'")
|
||||
})
|
||||
|
||||
it('recognizes difficult literal regexes', function () {
|
||||
var n, p1 = '<p a="', p2 = '">'
|
||||
var atest = [
|
||||
[p1, '{5+3/ /}/}', p2], // <p a="{a+5/ /}/}"> : regex: /}/ (ok, `5+3/ re` == NaN)
|
||||
[p1, '{/[///[]}/}', p2], // <p a="{/[///[]}/}"> : regex: /[///[]}/
|
||||
[p1, '{/\\/[}\\]]/}', p2], // <p a="{/\/[}\]]/}"> : regex: /\/[}\]]/
|
||||
[p1, '{x/y}', '', '{x/g}', p2], // <p a="{x/y}{x/g}"> : NOT regex: /y}{x/g
|
||||
[p1, '{a++/b}', '', '{/i}', p2], // <p a="{a++/b}{/i}"> : NOT regex: /b}{/i
|
||||
[p1, "{''+/b}{/i}", p2], // <p a="{''+/b}{/i}"> : regex: /b}{/i
|
||||
[p1, '{a==/b}{/i}', p2], // <p a="{a==/b}{/i"> : regex: /b}{/i
|
||||
[p1, '{a=/{}}}}/}', p2] // <p a="{a=/{}}}}/"> : regex: /{}}}}/
|
||||
]
|
||||
var qblocks = [
|
||||
'/}/',
|
||||
'/[///[]}/',
|
||||
'/\\/[}\\]]/',
|
||||
undefined,
|
||||
undefined,
|
||||
'/b}{/i',
|
||||
'/b}{/i',
|
||||
'/{}}}}/',
|
||||
]
|
||||
resetBrackets()
|
||||
|
||||
for (n = 0; n < atest.length; ++n) {
|
||||
var a, t = atest[n]
|
||||
a = brackets.split(t.join(''), 1)
|
||||
expect(a).to.have.length(t.length)
|
||||
expect(a[0]).to.be(unq(t[0]))
|
||||
expect(a.qblocks[0]).to.be(qblocks[n])
|
||||
expect(a[2]).to.be(unq(t[2]))
|
||||
}
|
||||
|
||||
function unq (s) { return /^{.*}$/.test(s) ? s.slice(1, -1) : s }
|
||||
})
|
||||
|
||||
})
|
||||
// end of brackets.split
|
||||
|
||||
})
|
||||
// end of brackets 2.4 suite
|
||||
|
||||
})
|
||||
|
||||
describe('regexes', function () {
|
||||
|
||||
it('literal strings with escaped quotes inside (double quotes)', function () {
|
||||
var match = ' """\\"" "x" "a\\" "'.match(brackets.R_STRINGS) // R_STRINGS has global flag
|
||||
|
||||
expect(match).to.have.length(4)
|
||||
expect(match[0]).to.be('""')
|
||||
expect(match[1]).to.be('"\\""')
|
||||
expect(match[2]).to.be('"x"')
|
||||
expect(match[3]).to.be('"a\\" "')
|
||||
})
|
||||
|
||||
it('literal strings with escaped quotes inside (single quotes)', function () {
|
||||
var match = " '''\\'' 'x' 'a\\' '".match(brackets.R_STRINGS) // R_STRINGS has global flag
|
||||
|
||||
expect(match).to.have.length(4)
|
||||
expect(match[0]).to.be("''")
|
||||
expect(match[1]).to.be("'\\''")
|
||||
expect(match[2]).to.be("'x'")
|
||||
expect(match[3]).to.be("'a\\' '")
|
||||
})
|
||||
|
||||
it('multiline javascript comments in almost all forms', function () {
|
||||
var match = ' /* a *//**/ /*/**/ /*//\n*/ /\\*/**/'.match(brackets.R_MLCOMMS)
|
||||
|
||||
expect(match).to.have.length(5)
|
||||
expect(match[0]).to.be('/* a */')
|
||||
expect(match[1]).to.be('/**/')
|
||||
expect(match[2]).to.be('/*/**/')
|
||||
expect(match[3]).to.be('/*//\n*/')
|
||||
expect(match[4]).to.be('/**/')
|
||||
})
|
||||
|
||||
it('no problema with mixed quoted strings and comments', function () {
|
||||
var
|
||||
re = new RegExp(brackets.S_QBLOCKS + '|' + brackets.R_MLCOMMS.source, 'g'),
|
||||
match = ' /* a */"" /*""*/ "/*\\"*/" \\\'/*2*/\\\'\'\''.match(re)
|
||||
|
||||
expect(match).to.have.length(5)
|
||||
expect(match[0]).to.be('/* a */')
|
||||
expect(match[1]).to.be('""')
|
||||
expect(match[2]).to.be('/*""*/')
|
||||
expect(match[3]).to.be('"/*\\"*/"')
|
||||
expect(match[4]).to.be("'/*2*/\\\''") // yes, the match is correct :)
|
||||
})
|
||||
|
||||
})
|
||||
559
node_modules/@n8n_io/riot-tmpl/test/specs/core.specs.js
generated
vendored
Normal file
559
node_modules/@n8n_io/riot-tmpl/test/specs/core.specs.js
generated
vendored
Normal file
@@ -0,0 +1,559 @@
|
||||
/*eslint camelcase: 0, max-len: 0 */
|
||||
/*global globalVar:true */
|
||||
|
||||
globalVar = 5
|
||||
|
||||
var data = {
|
||||
yes: true,
|
||||
no: false,
|
||||
str: 'x',
|
||||
obj: { val: 2 },
|
||||
arr: [2],
|
||||
x: 2,
|
||||
$a: 0,
|
||||
$b: 1,
|
||||
esc: '\'\n\\',
|
||||
abc: { def: 'abc' },
|
||||
fn: function (s) { return ['hi', s].join(' ') },
|
||||
_debug_: 0
|
||||
}
|
||||
|
||||
// avoid to output the console errors
|
||||
function noop() { /* noop */ }
|
||||
|
||||
// send 1 or 2 in 'err' to enable internal information
|
||||
function render (str, dbg) {
|
||||
if (dbg) data._debug_ = 1
|
||||
return tmpl(str, data)
|
||||
}
|
||||
|
||||
describe('riot-tmpl', function () {
|
||||
|
||||
describe('compiles specs', function () {
|
||||
|
||||
//// return values
|
||||
|
||||
it('expressions always return a raw value', function () {
|
||||
expect(render('{ 1 }')).to.equal(1)
|
||||
expect(render('{ x }')).to.equal(2)
|
||||
expect(render('{ str }')).to.equal(data.str)
|
||||
expect(render('{ obj }')).to.equal(data.obj)
|
||||
expect(render('{ arr }')).to.equal(data.arr)
|
||||
expect(render('{ fn }')).to.equal(data.fn)
|
||||
expect(render('{ null }')).to.equal(null)
|
||||
expect(render('{ no }')).to.equal(false)
|
||||
expect(render('{ yes }')).to.equal(true)
|
||||
expect(render('{ $a }')).to.equal(0)
|
||||
})
|
||||
|
||||
it('templates always return a string value', function () {
|
||||
expect(render('{ 1 } ')).to.equal('1 ')
|
||||
expect(render('{ obj } ')).to.equal('[object Object] ')
|
||||
expect(render(' { yes }')).to.equal(' true')
|
||||
})
|
||||
|
||||
//// empty arguments
|
||||
|
||||
it('empty expressions equal to undefined', function () {
|
||||
expect(render()).to.be(undefined)
|
||||
expect(render('{}')).to.be(undefined)
|
||||
expect(render('{ }')).to.be(undefined)
|
||||
})
|
||||
|
||||
it('empty templates equal to empty string', function () {
|
||||
expect(render('')).to.equal('')
|
||||
expect(render('{ } ')).to.equal(' ')
|
||||
})
|
||||
|
||||
//// undefined values
|
||||
|
||||
it('undefined vars are catched in expressions and returns undefined', function () {
|
||||
expect(render('{ nonExistingVar }')).to.be(undefined)
|
||||
data.parent = undefined
|
||||
tmpl.errorHandler = noop
|
||||
expect(render('{ parent.some.thing }')).to.be(undefined)
|
||||
expect(render('{ !nonExistingVar }')).to.equal(true)
|
||||
expect(render('{ nonExistingVar ? "yes" : "no" }')).to.equal('no')
|
||||
expect(render('{ !nonExistingVar ? "yes" : "no" }')).to.equal('yes')
|
||||
tmpl.errorHandler = null
|
||||
delete data.parent
|
||||
})
|
||||
|
||||
it('in templates, falsy values result in empty string, except zero and false', function () {
|
||||
expect(render(' { nonExistingVar }')).to.equal(' ')
|
||||
expect(render(' { no }')).to.equal(' false')
|
||||
expect(render(' { $a }')).to.equal(' 0')
|
||||
expect(render('{false}')).to.equal(false)
|
||||
expect(render(' {false}')).to.equal(' false')
|
||||
})
|
||||
|
||||
//// expressions
|
||||
|
||||
it('expressions are just regular JavaScript', function () {
|
||||
expect(render('{ obj.val }')).to.be(2)
|
||||
expect(render('{ obj["val"] }')).to.be(2)
|
||||
expect(render('{ arr[0] }')).to.be(2)
|
||||
expect(render('{ arr[0]; }')).to.be(2)
|
||||
expect(render('{ arr.pop() }')).to.be(2)
|
||||
expect(render('{ fn(str) }')).to.be('hi x')
|
||||
expect(render('{ yes && "ok" }')).to.be('ok')
|
||||
expect(render('{ no && "ok" }')).to.be(false)
|
||||
expect(render('{ false || null || !no && yes }')).to.be(true)
|
||||
expect(render('{ !no ? "yes" : "no" }')).to.be('yes')
|
||||
expect(render('{ !yes ? "yes" : "no" }')).to.be('no')
|
||||
// expect(render('{ /^14/.test(+new Date()) }')).to.be(true)
|
||||
expect(render('{ typeof Math.random() }')).to.be('number')
|
||||
expect(render('{ fn("there") }')).to.be('hi there')
|
||||
expect(render('{ str == "x" }')).to.be(true)
|
||||
// debugger
|
||||
expect(render('{ /x/.test(str) }')).to.be(true)
|
||||
expect(render('{ true ? "a b c" : "foo" }')).to.be('a b c')
|
||||
expect(render('{ true ? "a \\"b\\" c" : "foo" }')).to.be('a "b" c')
|
||||
expect(render('{ str + " y" + \' z\'}')).to.be('x y z')
|
||||
expect(render('{ esc }')).to.be(data.esc)
|
||||
expect(render('{ $a }')).to.be(0)
|
||||
expect(render('{ $a + $b }')).to.be(1)
|
||||
expect(render('{ this.str }')).to.be('x')
|
||||
})
|
||||
|
||||
it('global variables are not supported in expressions', function () {
|
||||
expect(render('{ globalVar }')).to.be(undefined)
|
||||
})
|
||||
|
||||
it('all comments in expressions are stripped from the output (not anymore)', function () {
|
||||
expect(render('{ /* comment */ /* as*/ }')).to.be(undefined)
|
||||
expect(render('{ 1 /* comment */ + 1 }')).to.equal(2)
|
||||
expect(render('{ 1 /* comment */ + 1 } ')).to.equal('2 ')
|
||||
})
|
||||
|
||||
//// templates
|
||||
|
||||
it('all expressions are evaluted in template', function () {
|
||||
expect(render('{ 1 }{ 1 }')).to.equal('11')
|
||||
expect(render('{ 1 }{ 1 } ')).to.equal('11 ')
|
||||
expect(render(' { 1 }{ 1 }')).to.equal(' 11')
|
||||
expect(render('{ 1 } { 1 }')).to.equal('1 1')
|
||||
})
|
||||
|
||||
it('both templates and expressions are new-line-friendly', function () {
|
||||
expect(render('\n { yes \n ? 2 \n : 4} \n')).to.equal('\n 2 \n')
|
||||
})
|
||||
|
||||
//// class shorthands
|
||||
|
||||
describe('class shorthands', function () {
|
||||
|
||||
it('names can be single-quoted, double-quoted, unquoted', function () {
|
||||
expect(render('{ ok : yes }')).to.equal('ok')
|
||||
expect(render('{ "a" : yes, \'b\': yes, c: yes }')).to.equal('a b c')
|
||||
expect(render('{ a_b-c3: yes }')).to.equal('a_b-c3')
|
||||
})
|
||||
|
||||
it('set multiple cases, test trim', function () {
|
||||
expect(render('{ c0: 0, c1: "x", "c2 c2b": str, c3: "", c4: obj }')).to.be('c1 c2 c2b c4')
|
||||
expect(render('{ c0: 0, c1: false, "c2 c2b": "", c3: null, c4: undefined }')).to.be('')
|
||||
})
|
||||
|
||||
it('set two classes with one expression', function () {
|
||||
expect(render('{ "a b": yes }')).to.equal('a b')
|
||||
})
|
||||
|
||||
it('errors in expressions are catched silently', function () {
|
||||
tmpl.errorHandler = noop
|
||||
expect(render('{ loading: !nonExistingVar.length }')).to.equal('')
|
||||
tmpl.errorHandler = null
|
||||
})
|
||||
|
||||
it('expressions are just regular JavaScript', function () {
|
||||
expect(render('{ a: !no, b: yes }')).to.equal('a b')
|
||||
expect(render('{ y: false || null || !no && yes }')).to.equal('y')
|
||||
expect(render('{ y: 4 > 2 }')).to.equal('y')
|
||||
expect(render('{ y: fn() }')).to.equal('y')
|
||||
expect(render('{ y: str == "x" }')).to.equal('y')
|
||||
expect(render('{ y: new Date() }')).to.equal('y')
|
||||
expect(render('{ y: str[0] }')).to.equal('y')
|
||||
expect(render('<div>{ (2+3)/2 }</div>')).to.equal('<div>2.5</div>')
|
||||
})
|
||||
|
||||
it('even function calls, objects and arrays are no problem', function () {
|
||||
expect(render('{ ok: fn(1, 2) }')).to.equal('ok')
|
||||
expect(render('{ ok: fn([1, 2]) }')).to.equal('ok')
|
||||
expect(render('{ ok: fn({a: 1, b: 1}) }')).to.equal('ok')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
//// new in tmpl 2.2.3
|
||||
|
||||
describe('2.2.3', function () {
|
||||
|
||||
it('few errors in recognizing complex expressions', function () {
|
||||
data.$a = 0
|
||||
data.$b = 0
|
||||
data.parent = { selectedId: 0 }
|
||||
|
||||
//eslint-disable-next-line no-unused-vars
|
||||
data.translate = function (k, v) { return v.value }
|
||||
|
||||
// FIX #784 - The shorthand syntax for class names doesn't support parentheses
|
||||
expect(render('{ primary: (parent.selectedId === $a) }')).to.be('primary')
|
||||
// a bit more of complexity. note: using the comma operator requires parentheses
|
||||
expect(render('{ ok: ($b++, ($a > 0) || ($b & 1)) }')).to.be('ok')
|
||||
// FIX #1916 - Can't access variable without this in riot 2.5
|
||||
expect(render("{translate('key', {value: abc.def})}", 1)).to.be('abc')
|
||||
|
||||
delete data.translate
|
||||
})
|
||||
|
||||
it('unwrapped keywords void, window and global, in addition to `this`', function () {
|
||||
data.$a = 5
|
||||
expect(render('{ ' + (typeof window === 'object' ? 'window' : 'global') + ' }')).to.be.a('object')
|
||||
expect(Object.keys(render('{ ' + (typeof window === 'object' ? 'window' : 'global') + ' }')).length).to.be(0)
|
||||
|
||||
expect(render('{' + (typeof window === 'object' ? 'window' : 'global') + '.globalVar }')).to.be(undefined)
|
||||
expect(render('{ this.$a }')).to.be(5)
|
||||
expect(render('{ void 0 }')).to.be(undefined)
|
||||
data.Date = Date
|
||||
expect(render('{ new Date() }')).to.be.a('object')
|
||||
delete data.Date
|
||||
})
|
||||
|
||||
//// Better recognition of literal regexps inside template and expressions.
|
||||
it('better recognition of literal regexes', function () {
|
||||
expect(render('{ /{}\\/\\n/.source }')).to.be('{}\\/\\n')
|
||||
expect(render('{ ok: /{}\\/\\n/.test("{}\\/\\n") }')).to.be('ok')
|
||||
// handling quotes in regexp is not so complicated :)
|
||||
expect(render('{ /"\'/.source }')).to.be('"\'')
|
||||
expect(render('{ ok: /"\'/.test("\\"\'") }')).to.be('ok') // ok: /"'/.test("\"'")
|
||||
// html template don't have escape
|
||||
expect(render('rex = /"\'/')).to.be('rex = /"\'/') // rex = /\"\'/
|
||||
// no confusion with operators
|
||||
data.x = 2
|
||||
expect(render('{ 10 /x+10/ 1 }')).to.be(15)
|
||||
expect(render('{ x /2+x/ 1 }')).to.be(3)
|
||||
expect(render('{ x /2+"abc".search(/c/) }')).to.be(3)
|
||||
// in expressions, there's no ASI
|
||||
expect(render('{ x\n /2+x/ 1 }')).to.be(3)
|
||||
})
|
||||
|
||||
it('in quoted text, only openning riot brackets need to be escaped!', function () {
|
||||
expect(render('str = "/\\{}\\/\\n/"')).to.be('str = "/{}\\/\\n/"')
|
||||
expect(render('<p str2="\\{foo}">\\{ message }</p>')).to.be('<p str2="{foo}">{ message }</p>')
|
||||
expect(render('str="\\\\{foo}"')).to.be('str="\\{foo}"')
|
||||
})
|
||||
|
||||
//// Better recognition of comments, including empty ones.
|
||||
//// (moved to 2.4, now tmpl does not support comments)
|
||||
|
||||
it('you can include almost anything in quoted shorhand names', function () {
|
||||
expect(render('{ "_\u221A": 1 }')).to.be('_\u221A')
|
||||
expect(render('{ (this["\u221A"] = 1, this["\u221A"]) }')).to.be(1)
|
||||
})
|
||||
|
||||
//// Extra tests
|
||||
|
||||
it('correct handling of quotes', function () {
|
||||
expect(render("{filterState==''?'empty':'notempty'}")).to.be('notempty')
|
||||
expect(render('{ "House \\"Atrides\\" wins" }')).to.be('House "Atrides" wins')
|
||||
expect(render('{ "Leto\'s house" }')).to.be("Leto's house")
|
||||
expect(render("In '{ \"Leto\\\\\\\'s house\" }'")).to.be("In 'Leto\\\'s house'") //« In '{ "Leto\\\'s house" }' » --> In 'Leto\'s house'
|
||||
expect(render('In "{ "Leto\'s house" }"')).to.be('In "Leto\'s house"') //« In "{ "Leto's house" }" » --> In "Leto's house"
|
||||
expect(render('In "{ \'Leto\\\'s house\' }"')).to.be('In "Leto\'s house"') //« In "{ 'Leto\'s house' }" » --> In "Leto's house"
|
||||
})
|
||||
|
||||
//// Consistency?
|
||||
|
||||
it('main inconsistence between expressions and class shorthands are gone', function () {
|
||||
tmpl.errorHandler = noop
|
||||
expect(render('{ !nonExistingVar.foo ? "ok" : "" }')).to.equal(undefined) // ok
|
||||
expect(render('{ !nonExistingVar.foo ? "ok" : "" } ')).to.equal(' ') // ok
|
||||
expect(render('{ ok: !nonExistingVar.foo }')).to.equal('') // ok ;)
|
||||
tmpl.errorHandler = null
|
||||
})
|
||||
|
||||
//// Mac/Win EOL's normalization avoids unexpected results with some editors.
|
||||
//// (moved to 2.4, now tmpl don't touch non-expression parts)
|
||||
|
||||
describe('whitespace', function () {
|
||||
|
||||
it('is compacted to a space in expressions', function () {
|
||||
// you need see at generated code
|
||||
expect(render(' { yes ?\n\t2 : 4} ')).to.be(' 2 ')
|
||||
expect(render('{ \t \nyes !== no\r\n }')).to.be(true)
|
||||
})
|
||||
|
||||
it('is compacted and trimmed in quoted shorthand names', function () {
|
||||
expect(render('{ " \ta\n \r \r\nb\n ": yes }')).to.be('a b')
|
||||
})
|
||||
|
||||
it('is preserved in literal javascript strings', function () {
|
||||
expect(render('{ "\r\n \n \r" }')).to.be('\r\n \n \r')
|
||||
expect(render('{ ok: "\r\n".charCodeAt(0) === 13 }')).to.be('ok')
|
||||
})
|
||||
|
||||
it('eols (mac/win) are normalized to unix in html text', function () {
|
||||
expect(render('\r\n \n \r \n\r')).to.be('\n \n \n \n\n')
|
||||
expect(render('\r\n { \r"\n" } \r\n')).to.be('\n \n \n')
|
||||
// ...even in their quoted parts
|
||||
expect(render('foo="\r\n \n \r"')).to.be('foo="\n \n \n"')
|
||||
expect(render('style="\rtop:0\r\n"')).to.be('style="\ntop:0\n"')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
// end of tmpl 2.2.3
|
||||
|
||||
//// new in tmpl 2.3.0
|
||||
|
||||
describe('2.3.0', function () {
|
||||
|
||||
it('support for 8 bit, ISO-8859-1 charset in shorthand names', function () {
|
||||
expect(render('{ neón: 1 }')).to.be('neón')
|
||||
expect(render('{ -ä: 1 }')).to.be('-ä') // '-ä' is a valid class name
|
||||
expect(render('{ ä: 1 }')).to.be('ä')
|
||||
})
|
||||
|
||||
it('does not wrap global and window object names', function () {
|
||||
var gw = typeof window === 'object' ? 'window' : 'global'
|
||||
|
||||
expect(render('{ ' + gw + '.globalVar }')).to.be(undefined)
|
||||
data.Date = '{}'
|
||||
expect(render('{ +new ' + gw + '.Date() }')).to.be(undefined)
|
||||
delete data.Date
|
||||
})
|
||||
|
||||
it('unwrapped keywords: Infinity, isFinite, isNaN, Date, RegExp and Math', function () {
|
||||
var i, a = ['isFinite', 'isNaN', 'Date', 'RegExp', 'Math']
|
||||
|
||||
data.Infinity = Infinity
|
||||
data.isFinite = isFinite
|
||||
data.isNaN = isNaN
|
||||
data.Date = Date
|
||||
data.RegExp = RegExp
|
||||
data.Math = Math
|
||||
|
||||
expect(render('{ Infinity }')).to.be.a('number')
|
||||
expect(render('{ isFinite(1) }')).to.be(true)
|
||||
expect(render('{ isNaN({}) }')).to.be(true)
|
||||
expect(render('{ Date.parse }')).to.be.a('function')
|
||||
expect(render('{ RegExp.$1 }')).to.be.a('string')
|
||||
expect(render('{ Math.floor(0) }')).to.be.a('number')
|
||||
|
||||
for (i = 0; i < a.length; ++i) {
|
||||
delete data[a[i]]
|
||||
}
|
||||
})
|
||||
|
||||
it('Fix riot#2002 issue with the `JS_VARNAME` regex failing in iOS 9.3.0', function () {
|
||||
data.t = function (s, o) { return s.replace('__storeCount__', o.storeCount) }
|
||||
data.storeCount = 1
|
||||
var result = render("{ t('Please choose from the __storeCount__ stores available', {storeCount: this.storeCount}) }", 1)
|
||||
|
||||
expect(result).to.be('Please choose from the 1 stores available')
|
||||
delete data.t
|
||||
delete data.storeCount
|
||||
})
|
||||
|
||||
describe('support for comments has been dropped', function () {
|
||||
// comments within expresions are converted to spaces, in concordance with js specs
|
||||
it('if included, the expression may work, but...', function () {
|
||||
expect(render('{ typeof/**/str === "string" }')).to.be(true)
|
||||
expect(render('{ 1+/* */+2 }')).to.be(3)
|
||||
|
||||
// comments in template text is preserved
|
||||
expect(render(' /*/* *\/ /**/ ')).to.be(' /*/* *\/ /**/ ')
|
||||
expect(render('/*/* "note" /**/')).to.be('/*/* "note" /**/')
|
||||
|
||||
// riot parse correctamente empty and exotic comments
|
||||
expect(render('{ /**/ }')).to.be(undefined) // empty comment
|
||||
expect(render('{ /*/* *\/ /**/ }')).to.be(undefined) // nested comment sequences
|
||||
expect(render('{ /*dummy*/ }')).to.be(undefined)
|
||||
|
||||
// there's no problem in shorthands
|
||||
expect(render('{ ok: 0+ /*{no: 1}*/ 1 }')).to.be('ok')
|
||||
|
||||
// nor in the template text, comments inside strings are preserved
|
||||
expect(render('{ "/* ok */" }')).to.be('/* ok */')
|
||||
expect(render('{ "/*/* *\/ /**/" }')).to.be('/*/* *\/ /**/')
|
||||
expect(render('{ "/* \\"comment\\" */" }')).to.be('/* "comment" */')
|
||||
})
|
||||
|
||||
it('something like `{ ok:1 /*,no:1*/ } give incorrect result ("no")', function () {
|
||||
expect(render('{ ok: 1 /*, no: 1*/ }')).to.be('no')
|
||||
})
|
||||
|
||||
it('others can break your application, e.g. { ok/**/: 1 }', function () {
|
||||
expect(render).withArgs('{ ok/**/: 1 }').to.throwError()
|
||||
expect(render).withArgs(' { /* comment */ }').to.throwError()
|
||||
})
|
||||
})
|
||||
|
||||
//// error handler
|
||||
|
||||
describe('catch errors in expressions with tmpl.errorHandler', function () {
|
||||
var clearHandler = function () { tmpl.errorHandler = null }
|
||||
|
||||
beforeEach(clearHandler)
|
||||
afterEach(clearHandler)
|
||||
after(clearHandler)
|
||||
|
||||
it('using a custom function', function () {
|
||||
var err
|
||||
|
||||
tmpl.errorHandler = function (e) { err = e }
|
||||
// je, tmpl({x}, NaN) does not generate error... bug or danling var?
|
||||
//console.error('========== >>>> x: ' + x) // error here
|
||||
//console.error('========== >>>> x: ' + global.x) // undefined here
|
||||
err = 0
|
||||
expect(tmpl('{x[0]}'), {}).to.be(undefined) // empty data
|
||||
expect(err instanceof Error).to.be(true)
|
||||
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
|
||||
// undefined as parameter for Function.call(`this`) defaults to global
|
||||
err = 0
|
||||
expect(tmpl('{x[0]}')).to.be(undefined)
|
||||
expect(err instanceof Error).to.be(true)
|
||||
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
|
||||
})
|
||||
|
||||
it('GOTCHA: null as param for call([this]) defaults to global too', function () {
|
||||
var err
|
||||
|
||||
tmpl.errorHandler = function (e) { err = e }
|
||||
err = 0
|
||||
expect(tmpl('{x[0]}', null)).to.be(undefined)
|
||||
expect(err instanceof Error).to.be(true)
|
||||
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
|
||||
})
|
||||
|
||||
it('catching reading property of an undefined variable', function () {
|
||||
var result, err
|
||||
|
||||
tmpl.errorHandler = function (e) { err = e }
|
||||
data.__ = { tagName: 'DIV' }
|
||||
data._riot_id = 1
|
||||
result = render('{ undefinedVar.property }') // render as normal
|
||||
delete data._riot_id
|
||||
delete data.root
|
||||
|
||||
expect(result).to.be(undefined)
|
||||
expect(err instanceof Error).to.be(true)
|
||||
expect(err.riotData).to.eql({ tagName: 'DIV', _riot_id: 1 })
|
||||
})
|
||||
|
||||
it('top level undefined variables (properties) can\'t be catched', function () {
|
||||
var result, err = 0
|
||||
|
||||
tmpl.errorHandler = function (e) { err = e }
|
||||
result = render('{ undefinedVar }') // render as normal
|
||||
expect(result).to.be(undefined)
|
||||
expect(err).to.be.a('number')
|
||||
})
|
||||
|
||||
it('errors only in the user defined error handler (riot/2108)', function () {
|
||||
var result, userErrOutput, defaultErrOutput
|
||||
|
||||
tmpl.errorHandler = function (e) { userErrOutput = e }
|
||||
console.error = function (e) { defaultErrOutput = e }
|
||||
|
||||
data.__ = { tagName: 'DIV' }
|
||||
data._riot_id = 1
|
||||
result = render('{ undefinedVar.property }') // render as normal
|
||||
delete data._riot_id
|
||||
delete data.root
|
||||
|
||||
console.error = function () { /* noop */ } // eslint-disable-line
|
||||
expect(result).to.be(undefined)
|
||||
expect(userErrOutput instanceof Error).to.be(true)
|
||||
expect(userErrOutput.riotData).to.eql({ tagName: 'DIV', _riot_id: 1 })
|
||||
expect(defaultErrOutput).to.be(undefined)
|
||||
})
|
||||
|
||||
it('errors on instantiation of the getter always throws', function () {
|
||||
expect(render).withArgs('{ a: } }').to.throwError() // SintaxError
|
||||
expect(render).withArgs('{ d c:1 }').to.throwError()
|
||||
})
|
||||
|
||||
it('syntax errors on expressions throws exception', function () {
|
||||
expect(render).withArgs('{ a:(1 }').to.throwError() // SintaxError
|
||||
expect(render).withArgs('{ c[0) }').to.throwError()
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
//// helper functions
|
||||
|
||||
describe('new helper functions', function () {
|
||||
|
||||
it('tmpl.loopKeys: extract keys from the value (for `each`)', function () {
|
||||
var i,
|
||||
atest = [
|
||||
'{ studio in studios["Nearby Locations"] }', { key: 'studio', pos: undefined, val: '{studios["Nearby Locations"]}' },
|
||||
'{k,i in item}', { key: 'k', pos: 'i', val: '{item}' },
|
||||
'{ k in i }', { key: 'k', pos: undefined, val: '{i}' },
|
||||
'{^ item in i }', { key: 'item', pos: undefined, val: '{i}' },
|
||||
'{^item,idx in items } ', { key: 'item', pos: 'idx', val: '{items}' },
|
||||
'{ item} ', { val: '{ item}' },
|
||||
'{item', { val: '{item' }, // val is expected
|
||||
'{}', { val: '{}' },
|
||||
'0', { val: '0' }
|
||||
]
|
||||
|
||||
for (i = 0; i < atest.length; i += 2) {
|
||||
expect(tmpl.loopKeys(atest[i])).to.eql(atest[i + 1])
|
||||
}
|
||||
})
|
||||
|
||||
it('tmpl.loopKeys with custom brackets', function () {
|
||||
brackets.set('{{ }}')
|
||||
var i,
|
||||
atest = [
|
||||
'{{k,i in item}}', { key: 'k', pos: 'i', val: '{{item}}' },
|
||||
'{{ k in i }}', { key: 'k', pos: undefined, val: '{{i}}' },
|
||||
'{{^ item in i }}', { key: 'item', pos: undefined, val: '{{i}}' },
|
||||
'{{^item,idx in items }} ', { key: 'item', pos: 'idx', val: '{{items}}' },
|
||||
'{{ item}} ', { val: '{{ item}}' },
|
||||
'{{item', { val: '{{item' }, // val is expected
|
||||
'{{}}', { val: '{{}}' },
|
||||
'0', { val: '0' }
|
||||
]
|
||||
|
||||
for (i = 0; i < atest.length; i += 2) {
|
||||
expect(tmpl.loopKeys(atest[i])).to.eql(atest[i + 1])
|
||||
}
|
||||
brackets.set(null)
|
||||
})
|
||||
|
||||
it('tmpl.hasExpr: test for expression (brackets) existence', function () {
|
||||
expect(tmpl.hasExpr('{}')).to.be(true)
|
||||
expect(tmpl.hasExpr(' {} ')).to.be(true)
|
||||
expect(tmpl.hasExpr('{ 123 } ')).to.be(true)
|
||||
expect(tmpl.hasExpr('"{ "#" }"')).to.be(true)
|
||||
expect(tmpl.hasExpr('"{ " }')).to.be(true)
|
||||
expect(tmpl.hasExpr('\\{ 123 } ')).to.be(true)
|
||||
expect(tmpl.hasExpr(' \\{}')).to.be(true)
|
||||
expect(tmpl.hasExpr(' }{ ')).to.be(false)
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
// end of tmpl 2.3.0
|
||||
|
||||
describe('tmpl 3.x', function () {
|
||||
|
||||
it('has beter support for regexes', function () {
|
||||
data.i = { x: 1 }
|
||||
expect(render('<a>{ typeof /5/ }</a>')).to.be('<a>object</a>')
|
||||
expect(render('<a>{ 5*5 /i.x }</a>')).to.be('<a>25</a>')
|
||||
expect(render('<a>{ 5*5 /i.x/1 }</a>')).to.be('<a>25</a>')
|
||||
expect(render('{ 5+/./.lastIndex }')).to.be(5)
|
||||
})
|
||||
|
||||
it('fixes riot#2361', function () {
|
||||
expect(render('<div>{ (2+3)/2 }</div>')).to.be('<div>2.5</div>')
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
215
node_modules/@n8n_io/riot-tmpl/test/v223/tmpl223.js
generated
vendored
Normal file
215
node_modules/@n8n_io/riot-tmpl/test/v223/tmpl223.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
Code from v2.2.3, riot master branch (sep 18, 2015)
|
||||
*/
|
||||
var riot = { settings: {} }
|
||||
|
||||
if (typeof window === 'undefined')
|
||||
window = false
|
||||
|
||||
var brackets = (function(orig) {
|
||||
|
||||
var cachedBrackets,
|
||||
r,
|
||||
b,
|
||||
re = /[{}]/g
|
||||
|
||||
return function(x) {
|
||||
|
||||
// make sure we use the current setting
|
||||
var s = riot.settings.brackets || orig
|
||||
|
||||
// recreate cached vars if needed
|
||||
if (cachedBrackets !== s) {
|
||||
cachedBrackets = s
|
||||
b = s.split(' ')
|
||||
r = b.map(function (e) { return e.replace(/(?=.)/g, '\\') })
|
||||
}
|
||||
|
||||
// if regexp given, rewrite it with current brackets (only if differ from default)
|
||||
return x instanceof RegExp ? (
|
||||
s === orig ? x :
|
||||
new RegExp(x.source.replace(re, function(b) { return r[~~(b === '}')] }), x.global ? 'g' : '')
|
||||
) :
|
||||
// else, get specific bracket
|
||||
b[x]
|
||||
}
|
||||
})('{ }')
|
||||
|
||||
|
||||
var tmpl = (function() {
|
||||
|
||||
var cache = {},
|
||||
OGLOB = '"in d?d:' + (window ? 'window).' : 'global).'),
|
||||
reVars =
|
||||
/(['"\/])(?:[^\\]*?|\\.|.)*?\1|\.\w*|\w*:|\b(?:(?:new|typeof|in|instanceof) |(?:this|true|false|null|undefined)\b|function\s*\()|([A-Za-z_$]\w*)/g
|
||||
|
||||
// build a template (or get it from cache), render with data
|
||||
return function(str, data) {
|
||||
return str && (cache[str] || (cache[str] = tmpl(str)))(data)
|
||||
}
|
||||
|
||||
|
||||
// create a template instance
|
||||
|
||||
function tmpl(s, p) {
|
||||
|
||||
if (s.indexOf(brackets(0)) < 0) {
|
||||
// return raw text
|
||||
s = s.replace(/\n|\r\n?/g, '\n')
|
||||
return function () { return s }
|
||||
}
|
||||
|
||||
// temporarily convert \{ and \} to a non-character
|
||||
s = s
|
||||
.replace(brackets(/\\{/g), '\uFFF0')
|
||||
.replace(brackets(/\\}/g), '\uFFF1')
|
||||
|
||||
// split string to expression and non-expresion parts
|
||||
p = split(s, extract(s, brackets(/{/), brackets(/}/)))
|
||||
|
||||
// is it a single expression or a template? i.e. {x} or <b>{x}</b>
|
||||
s = (p.length === 2 && !p[0]) ?
|
||||
|
||||
// if expression, evaluate it
|
||||
expr(p[1]) :
|
||||
|
||||
// if template, evaluate all expressions in it
|
||||
'[' + p.map(function(s, i) {
|
||||
|
||||
// is it an expression or a string (every second part is an expression)
|
||||
return i % 2 ?
|
||||
|
||||
// evaluate the expressions
|
||||
expr(s, true) :
|
||||
|
||||
// process string parts of the template:
|
||||
'"' + s
|
||||
|
||||
// preserve new lines
|
||||
.replace(/\n|\r\n?/g, '\\n')
|
||||
|
||||
// escape quotes
|
||||
.replace(/"/g, '\\"') +
|
||||
|
||||
'"'
|
||||
|
||||
}).join(',') + '].join("")'
|
||||
|
||||
return new Function('d', 'return ' + s
|
||||
// bring escaped { and } back
|
||||
.replace(/\uFFF0/g, brackets(0))
|
||||
.replace(/\uFFF1/g, brackets(1)) + ';')
|
||||
|
||||
}
|
||||
|
||||
|
||||
// parse { ... } expression
|
||||
|
||||
function expr(s, n) {
|
||||
s = s
|
||||
|
||||
// convert new lines to spaces
|
||||
.replace(/\n|\r\n?/g, ' ')
|
||||
|
||||
// trim whitespace, brackets, strip comments
|
||||
.replace(brackets(/^[{ ]+|[ }]+$|\/\*.+?\*\//g), '')
|
||||
|
||||
// is it an object literal? i.e. { key : value }
|
||||
return /^\s*[\w- "']+ *:/.test(s) ?
|
||||
|
||||
// if object literal, return trueish keys
|
||||
// e.g.: { show: isOpen(), done: item.done } -> "show done"
|
||||
'[' +
|
||||
|
||||
// extract key:val pairs, ignoring any nested objects
|
||||
extract(s,
|
||||
|
||||
// name part: name:, "name":, 'name':, name :
|
||||
/["' ]*[\w- ]+["' ]*:/,
|
||||
|
||||
// expression part: everything upto a comma followed by a name (see above) or end of line
|
||||
/,(?=["' ]*[\w- ]+["' ]*:)|}|$/
|
||||
).map(function(pair) {
|
||||
|
||||
// get key, val parts
|
||||
return pair.replace(/^[ "']*(.+?)[ "']*: *(.+?),? *$/, function(_, k, v) {
|
||||
|
||||
// wrap all conditional parts to ignore errors
|
||||
return v.replace(/[^&|=!><]+/g, wrap) + '?"' + k + '":"",'
|
||||
|
||||
})
|
||||
|
||||
}).join('') +
|
||||
|
||||
'].join(" ").trim()' :
|
||||
|
||||
// if js expression, evaluate as javascript
|
||||
wrap(s, n)
|
||||
|
||||
}
|
||||
|
||||
|
||||
// execute js w/o breaking on errors or undefined vars
|
||||
|
||||
function wrap(s, nonull) {
|
||||
s = s.trim()
|
||||
return !s ? '' : '(function(v){try{v=' +
|
||||
|
||||
// prefix vars (name => data.name)
|
||||
s.replace(reVars, function(s, _, v) { return v ? '(("' + v + OGLOB + v + ')' : s }) +
|
||||
|
||||
// default to empty string for falsy values except zero
|
||||
'}catch(e){}return ' + (nonull === true ? '!v&&v!==0?"":v' : 'v') + '}).call(d)'
|
||||
}
|
||||
|
||||
|
||||
// split string by an array of substrings
|
||||
|
||||
function split(str, substrings) {
|
||||
var parts = []
|
||||
substrings.map(function(sub, i) {
|
||||
|
||||
// push matched expression and part before it
|
||||
i = str.indexOf(sub)
|
||||
parts.push(str.slice(0, i), sub)
|
||||
str = str.slice(i + sub.length)
|
||||
})
|
||||
if (str) parts.push(str)
|
||||
|
||||
// push the remaining part
|
||||
return parts
|
||||
}
|
||||
|
||||
|
||||
// match strings between opening and closing regexp, skipping any inner/nested matches
|
||||
|
||||
function extract(str, open, close) {
|
||||
|
||||
var start,
|
||||
level = 0,
|
||||
matches = [],
|
||||
re = new RegExp('(' + open.source + ')|(' + close.source + ')', 'g')
|
||||
|
||||
str.replace(re, function(_, open, close, pos) {
|
||||
|
||||
// if outer inner bracket, mark position
|
||||
if (!level && open) start = pos
|
||||
|
||||
// in(de)crease bracket level
|
||||
level += open ? 1 : -1
|
||||
|
||||
// if outer closing bracket, grab the match
|
||||
if (!level && close != null) matches.push(str.slice(start, pos + close.length))
|
||||
|
||||
})
|
||||
|
||||
return matches
|
||||
}
|
||||
|
||||
})()
|
||||
|
||||
module.exports = {
|
||||
brackets: brackets,
|
||||
tmpl: tmpl
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user