feature: browser side support, close #6

This commit is contained in:
harttle
2016-09-27 02:28:20 +08:00
parent 937d213a2d
commit 16a66f2b18
20 changed files with 4108 additions and 107 deletions
+30 -2
View File
@@ -86,7 +86,35 @@ app.set('views', './views'); // specify the views directory
app.set('view engine', 'liquid'); // set to default
```
There's an Express demo in [the demo folder](demo/).
There's an Express demo [here](demo/express/).
## Use in Browser
[Download][releases] the dist files and import into your HTML.
And `window.Liquid` is what you want.
```html
<html lang="en">
<head>
<script src="shopify-liquid.min.js"></script>
</head>
<body>
<script>
var engine = window.Liquid();
var src = '{{ name | capitalize}}';
var ctx = {
name: 'welcome to Shopify Liquid'
};
engine.parseAndRender(src, ctx)
.then(function(html) {
// html === Welcome to Shopify Liquid
});
</script>
</body>
</html>
```
There's also a [demo](demo/browser/).
## Includes
@@ -248,4 +276,4 @@ Documentation: <https://shopify.github.io/liquid/basics/operators/>
[shopify-liquid]: https://shopify.github.io/liquid/
[jekyll]: http://jekyllrb.com/
[gh]: https://pages.github.com/
(test/filters.js): https://github.com/harttle/shopify-liquid/blob/master/test/filters.js
[releases]: https://github.com/harttle/shopify-liquid/releases
+26
View File
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="../../dist/shopify-liquid.min.js"></script>
</head>
<body>
<h2 id="header"></h2>
<script>
var engine = window.Liquid();
var src = '{{ name | capitalize}}';
var ctx = {
name: 'welcome to Shopify Liquid'
};
engine.parseAndRender(src, ctx)
.then(function(html) {
document.getElementById('header').innerHTML = html;
});
</script>
</body>
</html>
+3858
View File
File diff suppressed because it is too large Load Diff
+4
View File
File diff suppressed because one or more lines are too long
+66 -25
View File
@@ -1,23 +1,49 @@
const _ = require('lodash');
const strftime = require('strftime').timezone(-(new Date()).getTimezoneOffset());
module.exports = function(liquid) {
liquid.registerFilter('abs', v => Math.abs(v));
liquid.registerFilter('append', (v, arg) => v + arg);
liquid.registerFilter('capitalize', v => _.capitalize(v));
liquid.registerFilter('capitalize', str =>
(str || '').charAt(0).toUpperCase() + str.slice(1));
liquid.registerFilter('ceil', v => Math.ceil(v));
liquid.registerFilter('date', (v, arg) => strftime(arg, v));
liquid.registerFilter('default', (v, arg) => arg || v);
liquid.registerFilter('divided_by', (v, arg) => Math.floor(v / arg));
liquid.registerFilter('downcase', v => v.toLowerCase());
liquid.registerFilter('escape', v => _.escape(v));
liquid.registerFilter('escape_once', v => _.escape(_.unescape(v)));
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&#34;',
"'": '&#39;',
};
function escape(str) {
return (str || '').replace(/&|<|>|"|'/g, m => escapeMap[m]);
}
liquid.registerFilter('escape', escape);
var unescapeMap = {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&#34;': '"',
'&#39;': "'",
};
function unescape(str) {
return (str || '').replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m]);
}
liquid.registerFilter('escape_once', str => escape(unescape(str)));
liquid.registerFilter('first', v => v[0]);
liquid.registerFilter('floor', v => Math.floor(v));
liquid.registerFilter('join', _.join);
liquid.registerFilter('join', (v, arg) => v.join(arg));
liquid.registerFilter('last', v => v[v.length - 1]);
liquid.registerFilter('lstrip', v => _.trimStart(v));
liquid.registerFilter('map', (v, arg) => _.map(v, arg));
liquid.registerFilter('lstrip', v => (v || '').replace(/^\s+/, ''));
liquid.registerFilter('map', (arr, arg) => arr.map(v => v[arg]));
liquid.registerFilter('minus', bindFixed((v, arg) => v - arg));
liquid.registerFilter('modulo', bindFixed((v, arg) => v % arg));
liquid.registerFilter('newline_to_br', v => v.replace(/\n/g, '<br />'));
@@ -25,25 +51,31 @@ module.exports = function(liquid) {
liquid.registerFilter('prepend', (v, arg) => arg + v);
liquid.registerFilter('remove', (v, arg) => v.split(arg).join(''));
liquid.registerFilter('remove_first', (v, l) => v.replace(l, ''));
liquid.registerFilter('replace', (v, pattern, replacement) =>
_.replace(v, new RegExp(_.escapeRegExp(pattern), 'g'), replacement));
liquid.registerFilter('replace_first', _.replace);
liquid.registerFilter('reverse', _.reverse);
liquid.registerFilter('round', _.round);
liquid.registerFilter('rstrip', _.trimEnd);
liquid.registerFilter('size', _.size);
liquid.registerFilter('replace', (v, pattern, replacement) =>
(v || '').split(pattern).join(replacement));
liquid.registerFilter('replace_first', (v, arg1, arg2) => (v || '').replace(arg1, arg2));
liquid.registerFilter('reverse', v => (v || '').reverse());
liquid.registerFilter('round', (v, arg) => {
var amp = Math.pow(10, arg || 0);
return Math.round(v * amp, arg) / amp;
});
liquid.registerFilter('rstrip', str => (str || '').replace(/\s+$/, ''));
liquid.registerFilter('size', v => v.length);
liquid.registerFilter('slice', (v, begin, length) =>
v.substr(begin, length === undefined ? 1 : length));
liquid.registerFilter('sort', _.sortBy);
liquid.registerFilter('split', _.split);
liquid.registerFilter('strip', _.trim);
liquid.registerFilter('strip_html', v => _.replace(v, /<\/?\s*\w+\s*\/?>/g, ''));
liquid.registerFilter('strip_newlines', v => _.replace(v, /\n/g, ''));
liquid.registerFilter('sort', (v, arg) => (v || '').sort(arg));
liquid.registerFilter('split', (v, arg) => (v || '').split(arg));
liquid.registerFilter('strip', (v) => (v || '').trim());
liquid.registerFilter('strip_html', v => (v || '').replace(/<\/?\s*\w+\s*\/?>/g, ''));
liquid.registerFilter('strip_newlines', v => (v || '').replace(/\n/g, ''));
liquid.registerFilter('times', (v, arg) => v * arg);
liquid.registerFilter('truncate', (v, l, o) => _.truncate(v, {
length: l,
omission: o === undefined ? '...' : o
}));
liquid.registerFilter('truncate', (v, l, o) => {
v = v || '';
o = (o === undefined) ? '...' : o;
l = l || 16;
if (v.length <= l) return v;
return v.substr(0, l - o.length) + o;
});
liquid.registerFilter('truncatewords', (v, l, o) => {
if (o === undefined) o = '...';
var arr = v.split(' ');
@@ -51,8 +83,17 @@ module.exports = function(liquid) {
if (arr.length > l) ret += o;
return ret;
});
liquid.registerFilter('uniq', _.uniq);
liquid.registerFilter('upcase', _.toUpper);
liquid.registerFilter('uniq', function(arr) {
var u = {};
return (arr || []).filter(val => {
if (u.hasOwnProperty(val)) {
return false;
}
u[val] = true;
return true;
});
});
liquid.registerFilter('upcase', str => (str || '').toUpperCase());
liquid.registerFilter('url_encode', encodeURIComponent);
};
+8 -9
View File
@@ -1,6 +1,5 @@
const Scope = require('./src/scope');
const assert = require('assert');
const _ = require('lodash');
const tokenizer = require('./src/tokenizer.js');
const Render = require('./src/render.js');
const lexical = require('./src/lexical.js');
@@ -35,10 +34,10 @@ var _engine = {
return this.parser.parse(tokens);
},
render: function(tpl, ctx, opts) {
opts = _.defaults(opts, {
strict_variables: false,
strict_filters: false
});
opts = opts || {};
opts.strict_variables = opts.strict_variables || false;
opts.strict_filters = opts.strict_filters || false;
this.renderer.resetRegisters();
var scope = Scope.factory(ctx, {
strict: opts.strict_variables,
@@ -105,10 +104,10 @@ var _engine = {
};
function factory(options) {
options = _.defaults(options || {
root: '',
extname: '.liquid'
});
options = options || {};
options.root = options.root || '';
options.extname = options.extname || '.liquid';
var engine = Object.create(_engine);
engine.init(Tag(), Filter(), options);
+17
View File
@@ -0,0 +1,17 @@
MINIFY = ./node_modules/.bin/uglifyjs
BROWSERIFY = ./node_modules/.bin/browserify
.PHONY: dist default clean
default:
dist:
[ -d dist/ ] || mkdir dist/
$(BROWSERIFY) index.js -s Liquid \
-t [ babelify --global true --presets [ es2015 ] ] \
> dist/shopify-liquid.js
$(MINIFY) dist/shopify-liquid.js --output dist/shopify-liquid.min.js
ls -lh dist/
clean:
rm -rf dist/
+8 -4
View File
@@ -1,10 +1,11 @@
{
"name": "shopify-liquid",
"version": "1.1.15",
"version": "1.2.0",
"description": "Liquid template engine in Node.js (Shopify compliant)",
"main": "index.js",
"scripts": {
"test": "mocha --recursive"
"test": "mocha --recursive",
"dist": "make dist"
},
"repository": {
"type": "git",
@@ -24,10 +25,12 @@
"homepage": "https://github.com/harttle/shopify-liquid#readme",
"dependencies": {
"any-promise": "^1.3.0",
"lodash": "^4.13.1",
"strftime": "^0.9.2"
},
"devDependencies": {
"babel-preset-es2015": "^6.14.0",
"babelify": "^7.3.0",
"browserify": "^13.1.0",
"chai": "^3.5.0",
"chai-as-promised": "^5.3.0",
"coveralls": "^2.11.9",
@@ -37,6 +40,7 @@
"mock-fs": "^3.9.0",
"sinon": "^1.17.4",
"sinon-chai": "^2.8.0",
"supertest": "^1.2.0"
"supertest": "^1.2.0",
"uglifyjs": "^2.4.10"
}
}
+6 -3
View File
@@ -1,7 +1,6 @@
const syntax = require('./syntax.js');
const Exp = require('./expression.js');
const lexical = require('./lexical.js');
const _ = require('lodash');
function evalExp(exp, scope) {
if (!scope) throw new Error('unable to evalExp: scope undefined');
@@ -20,8 +19,12 @@ function evalExp(exp, scope) {
if (match = exp.match(lexical.rangeLine)) {
var low = evalValue(match[1], scope),
high = evalValue(match[2], scope) + 1;
return _.range(low, high);
high = evalValue(match[2], scope);
var range = [];
for (var j = low; j <= high; j++) {
range.push(j);
}
return range;
}
return evalValue(exp, scope);
-1
View File
@@ -1,5 +1,4 @@
const lexical = require('./lexical.js');
const _ = require('lodash');
const Exp = require('./expression.js');
var valueRE = new RegExp(`${lexical.value.source}`, 'g');
-2
View File
@@ -1,5 +1,3 @@
const _ = require('lodash');
// quote related
var singleQuoted = /'[^']*'/;
var doubleQuoted = /"[^"]*"/;
+2 -4
View File
@@ -2,15 +2,13 @@ const error = require('./error.js');
const Exp = require('./expression.js');
const assert = require('assert');
const Promise = require('any-promise');
const _ = require('lodash');
var render = {
renderTemplates: function(templates, scope, opts) {
assert(scope, 'unable to evalTemplates: scope undefined');
opts = _.defaults(opts, {
strict_filters: false
});
opts = opts || {};
opts.strict_filters = opts.strict_filters || false;
var html = '';
+37 -8
View File
@@ -1,4 +1,3 @@
const _ = require('lodash');
const lexical = require('./lexical.js');
var Scope = {
@@ -8,17 +7,22 @@ var Scope = {
if (str === undefined) {
var ctx = {};
for (i = this.scopes.length - 1; i >= 0; i--) {
_.merge(ctx, this.scopes[i]);
var scp = this.scopes[i];
for (var k in scp) {
if (scp.hasOwnProperty(k)) {
ctx[k] = scp[k];
}
}
}
return ctx;
}
// get one path
for (i = this.scopes.length - 1; i >= 0; i--) {
var v = _.get(this.scopes[i], str);
var v = getPropertyByPath(this.scopes[i], str);
if (v !== undefined) return v;
}
},
get: function(str){
get: function(str) {
var val = this.safeGet(str);
if (val === undefined && this.opts.strict) {
throw new Error(`[strict_variables] undefined variable: ${str}`);
@@ -26,7 +30,7 @@ var Scope = {
return val;
},
set: function(k, v) {
_.set(this.scopes[this.scopes.length - 1], k, v);
setPropertyByPath(this.scopes[this.scopes.length - 1], k, v);
return this;
},
push: function(ctx) {
@@ -38,10 +42,35 @@ var Scope = {
}
};
function setPropertyByPath(obj, path, val) {
if (path instanceof String || typeof path === 'string') {
var paths = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');
for (var i = 0; i < paths.length; i++) {
var key = paths[i];
if (i === paths.length - 1) {
return obj[key] = val;
}
if (undefined === obj[key]) obj[key] = {};
// case for readonly objects
obj = obj[key] || {};
}
return obj;
}
return obj[path] = val;
}
function getPropertyByPath(obj, path) {
if (path instanceof String || typeof path === 'string') {
var paths = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');
paths.forEach(p => obj = obj && obj[p]);
return obj;
}
return obj[path];
}
exports.factory = function(_ctx, opts) {
opts = _.defaults(opts, {
strict: false
});
opts = opts || {};
opts.strict = opts.strict || false;
var scope = Object.create(Scope);
scope.opts = opts;
-1
View File
@@ -1,6 +1,5 @@
var Liquid = require('..');
var Promise = require('any-promise');
var _ = require('lodash');
var lexical = Liquid.lexical;
var re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` +
`(${lexical.value.source})` +
+44 -46
View File
@@ -24,32 +24,32 @@ function test(src, dst) {
}
describe('filters', function() {
it('should support abs 1', function() { return test('{{ -3 | abs }}', '3'); });
it('should support abs 2', function() { return test('{{ arr[0] | abs }}', '2'); });
it('should support abs 1', () => test('{{ -3 | abs }}', '3'));
it('should support abs 2', () => test('{{ arr[0] | abs }}', '2'));
it('should support append 1', function() { return test('{{ -3 | append: "abc" }}', '-3abc'); });
it('should support append 2', function() { return test('{{ "a" | append: foo }}', 'abar');; });
it('should support append 1', () => test('{{ -3 | append: "abc" }}', '-3abc'));
it('should support append 2', () => test('{{ "a" | append: foo }}', 'abar'));
it('should support capitalize', function() { return test('{{ "i am good" | capitalize }}', 'I am good'); });
it('should support capitalize', () => test('{{ "i am good" | capitalize }}', 'I am good'));
it('should support ceil 1', function() { return test('{{ 1.2 | ceil }}', '2'); });
it('should support ceil 2', function() { return test('{{ 2.0 | ceil }}', '2'); });
it('should support ceil 3', function() { return test('{{ "3.5" | ceil }}', '4'); });
it('should support ceil 4', function() { return test('{{ 183.357 | ceil }}', '184'); });
it('should support ceil 1', () => test('{{ 1.2 | ceil }}', '2'));
it('should support ceil 2', () => test('{{ 2.0 | ceil }}', '2'));
it('should support ceil 3', () => test('{{ "3.5" | ceil }}', '4'));
it('should support ceil 4', () => test('{{ 183.357 | ceil }}', '184'));
it('should support date', function() {
str = ctx.date.toDateString();
return test('{{ date | date:"%a %b %d %Y"}}', str);
});
it('should support default', function() { return test('{{false |default: "a"}}', 'a'); });
it('should support default', () => test('{{false |default: "a"}}', 'a'));
it('should support divided_by 1', function() { return test('{{4 | divided_by: 2}}', '2'); });
it('should support divided_by 2', function() { return test('{{16 | divided_by: 4}}', '4'); });
it('should support divided_by 3', function() { return test('{{5 | divided_by: 3}}', '1'); });
it('should support divided_by 1', () => test('{{4 | divided_by: 2}}', '2'));
it('should support divided_by 2', () => test('{{16 | divided_by: 4}}', '4'));
it('should support divided_by 3', () => test('{{5 | divided_by: 3}}', '1'));
it('should support downcase 1', function() { return test('{{ "Parker Moore" | downcase }}', 'parker moore'); });
it('should support downcase 2', function() { return test('{{ "apple" | downcase }}', 'apple'); });
it('should support downcase 1', () => test('{{ "Parker Moore" | downcase }}', 'parker moore'));
it('should support downcase 2', () => test('{{ "apple" | downcase }}', 'apple'));
it('should support escape 1', function() {
return test('{{ "Have you read \'James & the Giant Peach\'?" | escape }}',
@@ -59,8 +59,8 @@ describe('filters', function() {
return test('{{ "Tetsuro Takara" | escape }}', 'Tetsuro Takara');
});
it('should support escape_once 1', function() { return test('{{ "1 < 2 & 3" | escape_once }}', '1 &lt; 2 &amp; 3'); });
it('should support escape_once 2', function() { return test('{{ "1 &lt; 2 &amp; 3" | escape_once }}', '1 &lt; 2 &amp; 3'); });
it('should support escape_once 1', () => test('{{ "1 < 2 & 3" | escape_once }}', '1 &lt; 2 &amp; 3'));
it('should support escape_once 2', () => test('{{ "1 &lt; 2 &amp; 3" | escape_once }}', '1 &lt; 2 &amp; 3'));
it('should support split/first', function() {
src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' +
@@ -68,10 +68,10 @@ describe('filters', function() {
return test(src, 'apples');
});
it('should support floor 1', function() { return test('{{ 1.2 | floor }}', '1'); });
it('should support floor 2', function() { return test('{{ 2.0 | floor }}', '2'); });
it('should support floor 3', function() { return test('{{ 183.357 | floor }}', '183'); });
it('should support floor 4', function() { return test('{{ "3.5" | floor }}', '3'); });
it('should support floor 1', () => test('{{ 1.2 | floor }}', '1'));
it('should support floor 2', () => test('{{ 2.0 | floor }}', '2'));
it('should support floor 3', () => test('{{ 183.357 | floor }}', '183'));
it('should support floor 4', () => test('{{ "3.5" | floor }}', '3'));
it('should support join', function() {
src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' +
@@ -94,13 +94,13 @@ describe('filters', function() {
return test('{{posts | map: "category"}}', '["foo","bar"]');
});
it('should support minus 1', function() { return test('{{ 4 | minus: 2 }}', '2'); });
it('should support minus 2', function() { return test('{{ 16 | minus: 4 }}', '12'); });
it('should support minus 3', function() { return test('{{ 183.357 | minus: 12 }}', '171.357'); });
it('should support minus 1', () => test('{{ 4 | minus: 2 }}', '2'));
it('should support minus 2', () => test('{{ 16 | minus: 4 }}', '12'));
it('should support minus 3', () => test('{{ 183.357 | minus: 12 }}', '171.357'));
it('should support modulo 1', function() { return test('{{ 3 | modulo: 2 }}', '1'); });
it('should support modulo 2', function() { return test('{{ 24 | modulo: 7 }}', '3'); });
it('should support modulo 3', function() { return test('{{ 183.357 | modulo: 12 }}', '3.357'); });
it('should support modulo 1', () => test('{{ 3 | modulo: 2 }}', '1'));
it('should support modulo 2', () => test('{{ 24 | modulo: 7 }}', '3'));
it('should support modulo 3', () => test('{{ 183.357 | modulo: 12 }}', '3.357'));
it('should support string_with_newlines', function() {
src = '{% capture string_with_newlines %}\n' +
@@ -114,9 +114,9 @@ describe('filters', function() {
return test(src, dst);
});
it('should support plus 1', function() { return test('{{ 4 | plus: 2 }}', '6'); });
it('should support plus 2', function() { return test('{{ 16 | plus: 4 }}', '20'); });
it('should support plus 3', function() { return test('{{ 183.357 | plus: 12 }}', '195.357'); });
it('should support plus 1', () => test('{{ 4 | plus: 2 }}', '6'));
it('should support plus 2', () => test('{{ 16 | plus: 4 }}', '20'));
it('should support plus 3', () => test('{{ 183.357 | plus: 12 }}', '195.357'));
it('should support prepend', function() {
return test('{% assign url = "liquidmarkup.com" %}' +
@@ -150,26 +150,26 @@ describe('filters', function() {
'.moT rojaM ot lortnoc dnuorG');
});
it('should support round 1', function() { return test('{{1.2|round}}', '1'); });
it('should support round 2', function() { return test('{{2.7|round}}', '3'); });
it('should support round 3', function() { return test('{{183.357|round: 2}}', '183.36'); });
it('should support round 1', () => test('{{1.2|round}}', '1'));
it('should support round 2', () => test('{{2.7|round}}', '3'));
it('should support round 3', () => test('{{183.357|round: 2}}', '183.36'));
it('should support rstrip', function() {
return test('{{ " So much room for activities! " | rstrip }}',
' So much room for activities!');
});
it('should support size 1', function() { return test('{{ "Ground control to Major Tom." | size }}', '28'); });
it('should support size 1', () => test('{{ "Ground control to Major Tom." | size }}', '28'));
it('should support size 2', function() {
return test('{% assign my_array = "apples, oranges, peaches, plums"' +
' | split: ", " %}{{ my_array | size }}',
'4');
});
it('should support slice 1', function() { return test('{{ "Liquid" | slice: 0 }}', 'L'); });
it('should support slice 2', function() { return test('{{ "Liquid" | slice: 2 }}', 'q'); });
it('should support slice 3', function() { return test('{{ "Liquid" | slice: 2, 5 }}', 'quid'); });
it('should support slice 4', function() { return test('{{ "Liquid" | slice: -3, 2 }}', 'ui'); });
it('should support slice 1', () => test('{{ "Liquid" | slice: 0 }}', 'L'));
it('should support slice 2', () => test('{{ "Liquid" | slice: 2 }}', 'q'));
it('should support slice 3', () => test('{{ "Liquid" | slice: 2, 5 }}', 'quid'));
it('should support slice 4', () => test('{{ "Liquid" | slice: -3, 2 }}', 'ui'));
it('should support sort', function() {
return test('{% assign my_array = "zebra, octopus, giraffe, Sally Snake"' +
@@ -206,9 +206,9 @@ describe('filters', function() {
'Hellothere');
});
it('should support times 1', function() { return test('{{ 3 | times: 2 }}', '6'); });
it('should support times 2', function() { return test('{{ 24 | times: 7 }}', '168'); });
it('should support times 3', function() { return test('{{ 183.357 | times: 12 }}', '2200.284'); });
it('should support times 1', () => test('{{ 3 | times: 2 }}', '6'));
it('should support times 2', () => test('{{ 24 | times: 7 }}', '168'));
it('should support times 3', () => test('{{ 183.357 | times: 12 }}', '2200.284'));
it('should support truncate 1', function() {
return test('{{ "Ground control to Major Tom." | truncate: 20 }}',
@@ -250,10 +250,8 @@ describe('filters', function() {
'ants, bugs, bees');
});
it('should support upcase', function() {
return test('{{ "Parker Moore" | upcase }}', 'PARKER MOORE');
});
it('should support upcase', () => test('{{ "Parker Moore" | upcase }}', 'PARKER MOORE'));
it('should support url_encode 1', function() { return test('{{ "[email protected]" | url_encode }}', 'john%40liquid.com'); });
it('should support url_encode 2', function() { return test('{{ "Tetsuro Takara" | url_encode }}', 'Tetsuro%20Takara'); });
it('should support url_encode 1', () => test('{{ "[email protected]" | url_encode }}', 'john%40liquid.com'));
it('should support url_encode 2', () => test('{{ "Tetsuro Takara" | url_encode }}', 'Tetsuro%20Takara'));
});
+2 -2
View File
@@ -24,6 +24,8 @@ describe('scope', function() {
}
expect(fn).to.not.throw();
expect(scope.get('notdefined')).to.equal(undefined);
expect(scope.get('')).to.equal(undefined);
expect(scope.get(false)).to.equal(undefined);
});
it('should throw undefined in strict mode', function() {
@@ -38,8 +40,6 @@ describe('scope', function() {
it('should get all property', function() {
scope.get().should.deep.equal(ctx);
expect(scope.get('')).to.equal(undefined);
expect(scope.get(false)).to.equal(undefined);
});
it('should set property', function() {