feature: get nyc, babel and coveralls working

This commit is contained in:
harttle
2018-08-26 21:54:35 +08:00
parent d828c4021e
commit 31c39561c9
50 changed files with 361 additions and 482 deletions
+6
View File
@@ -0,0 +1,6 @@
{
"rules": {
"no-var": 0,
"prefer-const": 0
}
}
+97
View File
@@ -0,0 +1,97 @@
const chai = require('chai')
const request = require('supertest')
const express = require('express')
const mock = require('mock-fs')
const Liquid = require('../..')
const chaiAsPromised = require('chai-as-promised')
const expect = chai.expect
chai.use(chaiAsPromised)
describe('engine#express()', function () {
var app, engine
beforeEach(function () {
app = express()
engine = Liquid({
root: '/root',
extname: '.html'
})
app.set('view engine', 'html')
app.engine('html', engine.express())
app.get('/name', (req, res) => res.render('name', {
name: 'harttle'
}))
app.get('/include/:file', (req, res) => res.render('include', {
file: req.params.file
}))
})
after(function () {
mock.restore()
})
it('should render express views', function (done) {
mock({ '/views/name.html': 'My name is {{name}}.' })
app.set('views', ['/views'])
request(app).get('/name')
.expect('My name is harttle.')
.expect(200, done)
})
it('should pass error when file not found', function (done) {
const view = {
root: []
}
const file = '/not-exist.html'
const ctx = {}
engine.express().call(view, file, ctx, function (err) {
try {
expect(err.code).to.equal('ENOENT')
expect(err.message).to.match(/Failed to lookup/)
done()
} catch (e) {
done(e)
}
})
})
it('should respect root option when lookup', function (done) {
mock({
'/root/foo.html': 'foo',
'/views/include.html': '{% include file %}'
})
app.set('views', ['/views'])
request(app).get('/include/foo')
.expect('foo')
.expect(200, done)
})
it('should respect express views (Array) when lookup', function (done) {
mock({
'/views/include.html': '{% include file %}',
'/partials/bar.html': 'bar'
})
app.set('views', ['/views', '/partials'])
request(app).get('/include/bar')
.expect('bar')
.expect(200, done)
})
it('should respect express views (String) when lookup', function (done) {
mock({
'/views/include.html': '{% include file %}',
'/views/bar.html': 'bar'
})
app.set('views', '/views')
request(app).get('/include/bar')
.expect('bar')
.expect(200, done)
})
it('should respect express views (Undefined) when lookup', function (done) {
const files = {}
files[process.cwd() + '/views/include.html'] = '{% include file %}'
files[process.cwd() + '/views/bar.html'] = 'bar'
mock(files)
request(app).get('/include/bar')
.expect('bar')
.expect(200, done)
})
})
+59
View File
@@ -0,0 +1,59 @@
var chai = require('chai')
var Liquid = require('../..')
var expect = chai.expect
chai.use(require('chai-as-promised'))
describe('.parseAndRender()', function () {
var engine, strictEngine
beforeEach(function () {
engine = Liquid()
strictEngine = Liquid({
strict_filters: true
})
})
it('should value object', function () {
var ctx = { obj: {foo: 'bar'} }
return expect(engine.parseAndRender('{{obj}}', ctx)).to.eventually.equal('{"foo":"bar"}')
})
it('should value array', function () {
var ctx = { arr: [-2, 'a'] }
return expect(engine.parseAndRender('{{arr}}', ctx)).to.eventually.equal('[-2,"a"]')
})
it('should value undefined to empty', function () {
return expect(engine.parseAndRender('foo{{zzz}}bar', {})).to.eventually.equal('foobar')
})
it('should render as null when filter undefined', function () {
return expect(engine.parseAndRender('{{"foo" | filter1}}', {})).to.eventually.equal('foo')
})
it('should throw upon undefined filter when strict_filters set', function () {
return expect(strictEngine.parseAndRender('{{"foo" | filter1}}', {})).to
.be.rejectedWith(/undefined filter: filter1/)
})
it('should parse html', function () {
expect(function () {
engine.parse('{{obj}}')
}).to.not.throw()
expect(function () {
engine.parse('<html><head>{{obj}}</head></html>')
}).to.not.throw()
})
it('should render template multiple times', function () {
var ctx = {obj: {foo: 'bar'}}
var template = engine.parse('{{obj}}')
return engine.render(template, ctx)
.then(result => expect(result).to.equal('{"foo":"bar"}'))
.then(() => engine.render(template, ctx))
.then((result) => expect(result).to.equal('{"foo":"bar"}'))
})
it('should render filters', function () {
var ctx = {names: ['alice', 'bob']}
var template = engine.parse('<p>{{names | join: ","}}</p>')
return expect(engine.render(template, ctx)).to.eventually.equal('<p>alice,bob</p>')
})
it('should render accessive filters', function () {
var src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
'{{ my_array | first }}'
return expect(engine.parseAndRender(src)).to.eventually.equal('apples')
})
})
+82
View File
@@ -0,0 +1,82 @@
var chai = require('chai')
var mock = require('mock-fs')
var Liquid = require('../..')
var expect = chai.expect
chai.use(require('chai-as-promised'))
describe('#renderFile()', function () {
var engine
beforeEach(function () {
engine = Liquid({
root: '/root/',
extname: '.html'
})
mock({
'/root/files/bar': 'bar',
'/root/files/foo.html': 'foo',
'/root/files/name.html': 'My name is {{name}}.',
'/un-readable.html': mock.file({
mode: '0000'
})
})
})
afterEach(function () {
mock.restore()
})
it('should ignore invalid root option', function () {
var liquid = Liquid({ root: /regex/ })
expect(liquid.options.root).to.deep.equal([])
})
it('should render file', function () {
return expect(engine.renderFile('/root/files/foo.html', {}))
.to.eventually.equal('foo')
})
it('should find files without extname', function () {
var engine = Liquid({root: '/root'})
return expect(engine.renderFile('/root/files/bar', {}))
.to.eventually.equal('bar')
})
it('should accept relative path', function () {
return expect(engine.renderFile('files/foo.html'))
.to.eventually.equal('foo')
})
it('should resolve array as root', function () {
engine = Liquid({
root: ['/boo', '/root/'],
extname: '.html'
})
return expect(engine.renderFile('files/foo.html'))
.to.eventually.equal('foo')
})
it('should default root to cwd', function () {
var files = {}
files[process.cwd() + '/foo.html'] = 'FOO'
mock(files)
engine = Liquid({
extname: '.html'
})
return expect(engine.renderFile('foo.html'))
.to.eventually.equal('FOO')
})
it('should render file with context', function () {
return expect(engine.renderFile('/root/files/name.html', {name: 'harttle'}))
.to.eventually.equal('My name is harttle.')
})
it('should use default extname', function () {
return expect(engine.renderFile('files/name', {name: 'harttle'})).to.eventually.equal('My name is harttle.')
})
it('should throw with lookup list when file not exist', function () {
engine = Liquid({
root: ['/boo', '/root/'],
extname: '.html'
})
return expect(engine.renderFile('/not/exist.html')).to
.be.rejectedWith(/failed to lookup \/not\/exist.html in: \/boo,\/root\//i)
})
it('should throw when file not readable', function () {
return expect(engine.renderFile('/un-readable.html')).to
.be.rejectedWith(/EACCES/)
})
})
+448
View File
@@ -0,0 +1,448 @@
const chai = require('chai')
const Liquid = require('../..')
const liquid = new Liquid()
const expect = chai.expect
chai.use(require('chai-as-promised'))
const cases = [
{
text: `
<div>
<p>
{{ 'John' }}
</p>
</div>
`,
expected: `
<div>
<p>
John
</p>
</div>
`
}, {
text: `
<div>
<p>
{{- 'John' -}}
</p>
</div>
`,
expected: `
<div>
<p>John</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if true -%}
yes
{%- endif -%}
</p>
</div>
`,
expected: `
<div>
<p>yes</p>
</div>
`
}, {
text: `
<div>
<p>
{% if true %}
yes
{% endif %}
</p>
</div>
`,
expected: `
<div>
<p>
yes
</p>
</div>
`
}, {
text: `
<div>
<p>
{% if false %}
no
{% endif %}
</p>
</div>
`,
expected: `
<div>
<p>
</p>
</div>
`
}, {
text: '<p>{{- \'John\' -}}</p>',
expected: '<p>John</p>'
}, {
text: '<p>{%- if true -%}yes{%- endif -%}</p>',
expected: '<p>yes</p>'
}, {
text: '<p>{%- if false -%}no{%- endif -%}</p>',
expected: '<p></p>'
}, {
text: '<p> {%- if true %} yes {% endif -%} </p>',
expected: '<p> yes </p>'
}, {
text: '<p> {%- if false %} no {% endif -%} </p>',
expected: '<p></p>'
}, {
text: '<p> {% if true -%} yes {%- endif %} </p>',
expected: '<p> yes </p>'
}, {
text: '<p> {% if false -%} no {%- endif %} </p>',
expected: '<p> </p>'
}, {
text: '<p> {% if true -%} yes {% endif -%} </p>',
expected: '<p> yes </p>'
}, {
text: '<p> {% if false -%} no {% endif -%} </p>',
expected: '<p> </p>'
}, {
text: '<p> {%- if true %} yes {%- endif %} </p>',
expected: '<p> yes </p>'
}, {
text: '<p> {%- if false %} no {%- endif %} </p>',
expected: '<p> </p>'
}, {
text: `
<div>
<p>
{{- 'John' }}
</p>
</div>
`,
expected: `
<div>
<p>John
</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if true %}
yes
{%- endif %}
</p>
</div>
`,
expected: `
<div>
<p>
yes
</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if false %}
no
{%- endif %}
</p>
</div>
`,
expected: `
<div>
<p>
</p>
</div>
`
}, {
text: `
<div>
<p>
{{ 'John' -}}
</p>
</div>
`,
expected: `
<div>
<p>
John</p>
</div>
`
}, {
text: `
<div>
<p>
{% if true -%}
yes
{% endif -%}
</p>
</div>
`,
expected: `
<div>
<p>
yes
</p>
</div>
`
}, {
text: `
<div>
<p>
{% if false -%}
no
{% endif -%}
</p>
</div>
`,
expected: `
<div>
<p>
</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if true %}
yes
{% endif -%}
</p>
</div>
`,
expected: `
<div>
<p>
yes
</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if false %}
no
{% endif -%}
</p>
</div>
`,
expected: `
<div>
<p></p>
</div>
`
}, {
text: `
<div>
<p>
{% if true -%}
yes
{%- endif %}
</p>
</div>
`,
expected: `
<div>
<p>
yes
</p>
</div>
`
}, {
text: `
<div>
<p>
{% if false -%}
no
{%- endif %}
</p>
</div>
`,
expected: `
<div>
<p>
</p>
</div>
`
}, {
text: `
<div>
<p>
{{- 'John' -}}
</p>
</div>
`,
expected: `
<div>
<p>John</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if true -%}
yes
{%- endif -%}
</p>
</div>
`,
expected: `
<div>
<p>yes</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if false -%}
no
{%- endif -%}
</p>
</div>
`,
expected: `
<div>
<p></p>
</div>
`
}, {
text: `
<div>
<p>
{{- 'John' -}},
{{- '30' -}}
</p>
</div>
`,
expected: `
<div>
<p>John,30</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if true -%}
yes
{%- endif -%}
</p>
</div>
`,
expected: `
<div>
<p>yes</p>
</div>
`
}, {
text: `
<div>
<p>
{%- if false -%}
no
{%- endif -%}
</p>
</div>
`,
expected: `
<div>
<p></p>
</div>
`
}, {
text: `
<div>
<p>
{{- 'John' -}}
{{- '30' -}}
</p>
<b>
{{ 'John' -}}
{{- '30' }}
</b>
<i>
{{- 'John' }}
{{ '30' -}}
</i>
</div>
`,
expected: `
<div>
<p>John30</p>
<b>
John30
</b>
<i>John
30</i>
</div>
`
}, {
text: `
<div>
{%- if true -%}
{%- if true -%}
<p>
{{- 'John' -}}
</p>
{%- endif -%}
{%- endif -%}
</div>
`,
expected: `
<div><p>John</p></div>
`
}, {
text: `
<div>
{% raw %}
{%- if true -%}
<p>
{{- 'John' -}}
</p>
{%- endif -%}
{% endraw %}
</div>
`,
expected: `
<div>
{%- if true -%}
<p>
{{- 'John' -}}
</p>
{%- endif -%}
</div>
`
}
]
describe('Whitespace Control', function () {
cases.forEach(item => it(
item.text,
() => expect(liquid.parseAndRender(item.text)).to.eventually.equal(item.expected)
))
})
+157
View File
@@ -0,0 +1,157 @@
var Liquid = require('../..')
var sinon = require('sinon')
var chai = require('chai')
var expect = chai.expect
chai.use(require('chai-as-promised'))
describe('xhr', () => {
if (process.version.match(/^v(\d+)/)[1] < 8) {
return
}
var JSDOM = require('jsdom').JSDOM
var server, engine, dom
beforeEach(() => {
server = sinon.createFakeServer()
server.autoRespond = true
server.respondWith('GET', 'https://example.com/views/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
dom = new JSDOM('', {
url: 'https://example.com/foo/bar.html',
contentType: 'text/html',
includeNodeLocations: true
})
global.XMLHttpRequest = sinon.useFakeXMLHttpRequest()
global.document = dom.window.document
engine = Liquid({
root: 'https://example.com/views/',
extname: '.html'
})
})
afterEach(() => {
server.restore()
delete global.XMLHttpRequest
delete global.document
})
describe('#renderFile()', () => {
it('should support without extname', () => {
return expect(engine.renderFile('hello', {name: 'alice1'}))
.to.eventually.equal('hello alice1')
})
it('should support with extname', () => {
return expect(engine.renderFile('hello.html', {name: 'alice2'}))
.to.eventually.equal('hello alice2')
})
it('should support with absolute path', () => {
server.respondWith('GET', 'https://example.com/foo.html',
[200, {'Content-Type': 'text/plain'}, 'foo'])
return expect(engine.renderFile('/foo.html'))
.to.eventually.equal('foo')
})
it('should support with url', () => {
return expect(engine.renderFile('https://example.com/views/hello.html', {name: 'alice4'}))
.to.eventually.equal('hello alice4')
})
it('should support include', () => {
server.respondWith('GET', 'https://example.com/views/hello.html',
[200, {'Content-Type': 'text/plain'}, "hello {% include 'name.html' %}"])
server.respondWith('GET', 'https://example.com/views/name.html',
[200, {'Content-Type': 'text/plain'}, '{{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should throw 404', () => {
return expect(engine.renderFile('/not/exist.html'))
.to.be.rejectedWith('Not Found')
})
it('should throw error', function (done) {
engine.renderFile('hello.html')
.catch(function (e) {
expect(e.message).to.equal('An error occurred whilst sending the response.')
done()
})
server.requests[0].error()
})
})
describe('root', () => {
it('should support with null', () => {
engine = Liquid({
extname: '.html'
})
server.respondWith('GET', 'https://example.com/foo/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should support with empty', () => {
engine = Liquid({
root: '',
extname: '.html'
})
server.respondWith('GET', 'https://example.com/foo/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should support with relative path', () => {
engine = Liquid({
root: './views/',
extname: '.html'
})
server.respondWith('GET', 'https://example.com/foo/views/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should support with absolute path', () => {
engine = Liquid({
root: '/views/',
extname: '.html'
})
server.respondWith('GET', 'https://example.com/views/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
it('should support with url', () => {
engine = Liquid({
root: 'https://foo.com/bar/',
extname: '.html'
})
server.respondWith('GET', 'https://foo.com/bar/hello.html',
[200, {'Content-Type': 'text/plain'}, 'hello {{name}}'])
return expect(engine.renderFile('hello.html', {name: 'alice5'}))
.to.eventually.equal('hello alice5')
})
})
describe('cache options', () => {
it('should be disabled by default', () => {
server.respondWith('GET', 'https://example.com/views/foo.html',
[200, {'Content-Type': 'text/plain'}, 'foo1'])
return engine.renderFile('foo.html')
.then((html) => {
expect(html).to.equal('foo1')
server.respondWith('GET', 'https://example.com/views/foo.html',
[200, {'Content-Type': 'text/plain'}, 'foo2'])
return engine.renderFile('foo.html')
})
.then(html => expect(html).to.equal('foo2'))
})
it('should respect cache=true option', () => {
engine = Liquid({
root: '/views/',
extname: '.html',
cache: true
})
server.respondWith('GET', 'https://example.com/views/foo.html',
[200, {'Content-Type': 'text/plain'}, 'foo1'])
return engine.renderFile('foo.html')
.then((html) => {
expect(html).to.equal('foo1')
server.respondWith('GET', 'https://example.com/views/foo.html',
[200, {'Content-Type': 'text/plain'}, 'foo2'])
return engine.renderFile('foo.html')
})
.then(html => expect(html).to.equal('foo1'))
})
})
})