Comparing version 0.0.0 to 2.0.0
71
bogus.js
@@ -1,10 +0,16 @@ | ||
(function() { | ||
(function(Hogan) { | ||
// Get a hold of Underscore.js. | ||
var _ = null; | ||
if (typeof window !== 'undefined') { | ||
_ = window._; | ||
} | ||
if (!_) { | ||
_ = require('underscore'); | ||
} | ||
// Empty constructor. | ||
var ctor = function() {}; | ||
// Require Hogan.js if we need to. | ||
if (typeof require !== 'undefined') { | ||
var Hogan = require('hogan.js'); | ||
} | ||
// Create a Bogus namespace that inherits from Hogan. | ||
@@ -17,11 +23,15 @@ ctor.prototype = Hogan; | ||
else { | ||
this.Bogus = Bogus | ||
this.Bogus = Bogus; | ||
} | ||
// Override the compiler's generate method to create Bogus templates. | ||
Bogus.generate = function (code, text, options) { | ||
Bogus.generate = function (tree, text, options) { | ||
var code = Hogan.generate(tree, text, { asString: true }); | ||
if (options.asString) { | ||
return 'function(c,p,i){' + code + ';}'; | ||
return code; | ||
} | ||
// FIXME: This is hacky, but otherwise requires support from Hogan.js. | ||
code = code.slice(16, -2); | ||
return new Bogus.Template(new Function('c', 'p', 'i', code), | ||
@@ -39,10 +49,16 @@ text, Bogus, options); | ||
// Truthy includes all JS truthy values, and the empty string. | ||
var truthy = function(val) { | ||
return (val === '') || !!val; | ||
}; | ||
// Value helper. | ||
var getValue = function(obj, key) { | ||
var val; | ||
if (obj && typeof obj === 'object') { | ||
if (obj.attributes) { | ||
obj = obj.attributes; | ||
if (obj.attributes && truthy(val = obj.attributes[key])) { | ||
return { val: val, found: true }; | ||
} | ||
if (key in obj) { | ||
return { val: obj[key], found: true }; | ||
if (truthy(val = obj[key])) { | ||
return { val: val, found: true }; | ||
} | ||
@@ -55,17 +71,20 @@ } | ||
proto.rs = function(context, partials, section) { | ||
var buf = '', | ||
var _this = this, | ||
tail = context[context.length - 1]; | ||
if (typeof tail === 'object' && tail.forEach) { | ||
tail.forEach(function(model) { | ||
context.push(model); | ||
buf += section(context, partials); | ||
context.pop(); | ||
}); | ||
function iter(obj) { | ||
context.push(obj); | ||
section(context, partials, _this); | ||
context.pop(); | ||
} | ||
if (tail.forEach) { | ||
tail.forEach(iter); | ||
} | ||
else if (_.isArray(tail)) { | ||
_.each(tail, iter); | ||
} | ||
else { | ||
buf = section(context, partials); | ||
section(context, partials, this); | ||
} | ||
return buf; | ||
}; | ||
@@ -85,3 +104,3 @@ | ||
pass = (val === '') || !!val; | ||
pass = truthy(val); | ||
@@ -159,2 +178,4 @@ if (!inverted && pass && ctx) { | ||
})(); | ||
// Require Hogan.js if we need to. | ||
})(typeof require === 'function' ? require('hogan.js') : Hogan); |
{ | ||
"name": "bogus.js", | ||
"description": "Access Backbone templates from Hogan", | ||
"version": "0.0.0", | ||
"version": "2.0.0", | ||
"author": "Stéphan Kochen <stephan@angrybytes.com>", | ||
@@ -14,10 +14,12 @@ "keywords": ["mustache", "template", "hogan", "backbone"], | ||
"type": "git", | ||
"url": "https://github.com/AngryBytes/bogus.js.git" | ||
"url": "https://github.com/Two-Screen/bogus.js.git" | ||
}, | ||
"dependencies": { | ||
"hogan.js": "1.0.5-dev" | ||
"underscore": "1", | ||
"hogan.js": "2.0.0" | ||
}, | ||
"devDependencies": { | ||
"tap": "0.2" | ||
"tap": "0.2", | ||
"backbone": ">=0.5" | ||
}, | ||
@@ -24,0 +26,0 @@ |
@@ -1,2 +0,2 @@ | ||
## Bogus.js = Hogan.js + Backbone.js [![Build Status](https://secure.travis-ci.org/AngryBytes/bogus.js.png)](http://travis-ci.org/AngryBytes/bogus.js) | ||
## Bogus.js = Hogan.js + Backbone.js [![Build Status](https://secure.travis-ci.org/Two-Screen/bogus.js.png)](http://travis-ci.org/Two-Screen/bogus.js) | ||
@@ -12,23 +12,22 @@ Bogus.js extends [Hogan.js] with support for [Backbone.js] models. This means | ||
Bogus.js is tied to a specific version of Hogan.js, currently 1.0.5. You will | ||
Bogus.js is tied to a specific version of Hogan.js, currently 2.0.0. You will | ||
probably want one of the following builds: | ||
* [hogan-1.0.5.js]: Complete build. | ||
* [hogan-1.0.5.min.js]: Complete build, minified. | ||
* [template-1.0.5.js]: Just Hogan.Template. | ||
* [template-1.0.5.min.js]: Just Hogan.Template, minified. | ||
* [hogan-2.0.0.js]: Complete build. | ||
* [hogan-2.0.0.min.js]: Complete build, minified. | ||
* [template-2.0.0.js]: Just Hogan.Template. | ||
* [template-2.0.0.min.js]: Just Hogan.Template, minified. | ||
Make sure Hogan.js and Bogus.js are included in your page in order: | ||
<script src="underscore.js"></script> | ||
<script src="backbone.js"></script> | ||
<script src="hogan.js"></script> | ||
<script src="bogus.js"></script> | ||
(Of course, you also want Backbone and dependencies, but Bogus.js won't | ||
actually fail without them.) | ||
[hogan-2.0.0.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/2.0.0/hogan-2.0.0.js | ||
[hogan-2.0.0.min.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/2.0.0/hogan-2.0.0.min.js | ||
[template-2.0.0.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/2.0.0/template-2.0.0.js | ||
[template-2.0.0.min.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/2.0.0/template-2.0.0.min.js | ||
[hogan-1.0.5.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/1.0.5/hogan-1.0.5.js | ||
[hogan-1.0.5.min.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/1.0.5/hogan-1.0.5.min.js | ||
[template-1.0.5.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/1.0.5/template-1.0.5.js | ||
[template-1.0.5.min.js]: https://raw.github.com/twitter/hogan.js/gh-pages/builds/1.0.5/template-1.0.5.min.js | ||
### From Node.js | ||
@@ -35,0 +34,0 @@ |
146
test.js
@@ -1,10 +0,58 @@ | ||
// This is the Hogan.js test suite, running on node-tap. | ||
var fs = require('fs'); | ||
var tap = require('tap'); | ||
var Backbone = require('backbone'); | ||
var Bogus = require('./'); | ||
// It's actually derived from Hogan.js master (5010d991f1), whereis Bogus | ||
// requires the current NPM release 1.0.5-dev. But Hogan.js master started | ||
// using QUnit, which is a lot easier to translate to TAP. | ||
// FIXME: Tests comparing function bodies were disabled. | ||
// FIXME: Check into failing tests. | ||
// Backbone.js-specific tests. | ||
tap.test("Render With Model", function(test) { | ||
var text = "test {{foo}} test {{bar}}"; | ||
var t = Bogus.compile(text); | ||
var m = new Backbone.Model({foo:'bar'}); | ||
var s = t.render(m); | ||
test.equal(s, "test bar test ", "basic variable substitution works."); | ||
m.bar = 'baz'; | ||
var s = t.render(m); | ||
test.equal(s, "test bar test baz", "fallback to regular model attributes."); | ||
m.set({ bar: 'foo' }); | ||
var s = t.render(m); | ||
test.equal(s, "test bar test foo", "Backbone attributes shadow regular attributes."); | ||
test.end(); | ||
}); | ||
tap.test("Render With Nested Model", function(test) { | ||
var text = "test {{foo.bar}} test"; | ||
var t = Bogus.compile(text); | ||
var m = new Backbone.Model({bar:'baz'}); | ||
var s = t.render({foo:m}); | ||
test.equal(s, "test baz test", "basic traversal works."); | ||
test.end(); | ||
}); | ||
tap.test("Render With Array Of Models", function(test) { | ||
var text = "test {{#list}}{{val}}{{/list}} test"; | ||
var t = Bogus.compile(text); | ||
var m1 = new Backbone.Model({val:'foo'}); | ||
var m2 = new Backbone.Model({val:'bar'}); | ||
var s = t.render({list:[m1,m2]}); | ||
test.equal(s, "test foobar test", "basic iteration works."); | ||
test.end(); | ||
}); | ||
tap.test("Render With Collection", function(test) { | ||
var text = "test {{#list}}foo {{val}} {{/list}}test"; | ||
var t = Bogus.compile(text); | ||
var c = new Backbone.Collection([{val:'bar'}, {val:'baz'}]); | ||
var s = t.render({list:c}); | ||
test.equal(s, "test foo bar foo baz test", "basic iteration works."); | ||
test.end(); | ||
}); | ||
// The following is taken from the Hogan.js test suite. | ||
// Hogan.js uses QUnit. Perhaps we should too, but for now, this is the | ||
// entire test suite converted to use TAP. | ||
/* | ||
@@ -25,6 +73,2 @@ * Copyright 2011 Twitter, Inc. | ||
var fs = require('fs'); | ||
var tap = require('tap'); | ||
var Bogus = require('./'); | ||
tap.test("Scan Text No Tags", function(test) { | ||
@@ -307,3 +351,3 @@ var text = "<h2>hi</h2>"; | ||
// FIXME: disabled | ||
// FIXME: This test is disabled in 2.0.0. | ||
/* | ||
@@ -326,3 +370,3 @@ tap.test("Basic Output As String", function(test) { | ||
// FIXME: disabled | ||
// FIXME: This test is disabled in 2.0.0. | ||
/* | ||
@@ -526,4 +570,2 @@ tap.test("One Variable As String", function(test) { | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Undefined Return Value From Lambda", function(test) { | ||
@@ -541,3 +583,2 @@ var text = "abc{{foo}}def"; | ||
}); | ||
*/ | ||
@@ -547,7 +588,7 @@ tap.test("Section Extensions", function(test) { | ||
var options = {sectionTags:[{o:'_//|__foo', c:'foo'}]}; | ||
var tree = Bogus.parse(Bogus.scan(text), options); | ||
var tree = Bogus.parse(Bogus.scan(text), text, options); | ||
test.equal(tree[1].tag, "#", "_//|__foo node transformed to section"); | ||
test.equal(tree[1].n, "_//|__foo", "_//|__foo node transformed to section"); | ||
var t = Bogus.compile(text, options); | ||
var t = Bogus.compile(text, options ); | ||
var s = t.render({'_//|__foo':true}); | ||
@@ -562,3 +603,3 @@ test.equal(s, "Test bar", "Custom sections work"); | ||
test.throws(function() { | ||
var tree = Bogus.parse(Bogus.scan(text), options); | ||
var tree = Bogus.parse(Bogus.scan(text), text, options); | ||
}, { | ||
@@ -571,4 +612,2 @@ name: "Error", | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Section Extensions In Higher Order Sections", function(test) { | ||
@@ -587,6 +626,3 @@ var text = "Test{{_foo}}bar{{/foo}}"; | ||
}); | ||
*/ | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Section Extensions In Lambda Replace Variable", function(test) { | ||
@@ -597,4 +633,4 @@ var text = "Test{{foo}}"; | ||
var context = { | ||
"foo": function (s) { | ||
return "{{_baz}}" + s + "{{/baz}}"; | ||
"foo": function () { | ||
return function() { "{{_baz}}" + s + "{{/baz}}"; }; | ||
} | ||
@@ -606,4 +642,37 @@ } | ||
}); | ||
*/ | ||
tap.test("Mustache not reprocessed for method calls in interpolations", function(test) { | ||
var text = "text with {{foo}} inside"; | ||
var t = Bogus.compile(text); | ||
var context = { | ||
foo: function() { | ||
return "no processing of {{tags}}"; | ||
} | ||
} | ||
var s = t.render(context); | ||
test.equal(s, "text with no processing of {{tags}} inside", "method calls should not be processed as mustache."); | ||
var text = "text with {{{foo}}} inside"; | ||
var t = Bogus.compile(text); | ||
var s = t.render(context); | ||
test.equal(s, "text with no processing of {{tags}} inside", "method calls should not be processed as mustache in triple staches."); | ||
test.end(); | ||
}); | ||
tap.test("Mustache is reprocessed for lambdas in interpolations", function(test) { | ||
var text = "text with {{foo}} inside"; | ||
var t = Bogus.compile(text); | ||
var context = { | ||
bar: "42", | ||
foo: function() { | ||
return function() { | ||
return "processing of {{bar}}"; | ||
}; | ||
} | ||
}; | ||
var s = t.render(context); | ||
test.equal(s, "text with processing of 42 inside", "the return value of lambdas should be processed mustache."); | ||
test.end(); | ||
}); | ||
tap.test("Nested Section", function(test) { | ||
@@ -719,4 +788,2 @@ var text = "{{#foo}}{{#bar}}{{baz}}{{/bar}}{{/foo}}"; | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Mustache JS Undefined Triple Stache", function(test) { | ||
@@ -729,6 +796,3 @@ var text = 'foo{{{bar}}}baz'; | ||
}); | ||
*/ | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Mustache JS Null String", function(test) { | ||
@@ -741,6 +805,3 @@ var text = 'foo{{bar}}baz'; | ||
}); | ||
*/ | ||
// FIXME: This test is not in 1.0.5. | ||
/* | ||
tap.test("Mustache JS Null Triple Stache", function(test) { | ||
@@ -753,3 +814,2 @@ var text = 'foo{{{bar}}}baz'; | ||
}); | ||
*/ | ||
@@ -764,2 +824,12 @@ tap.test("Mustache JS Triple Stache Alt Delimiter", function(test) { | ||
/* Safety tests */ | ||
tap.test("Updates object state", function(test) { | ||
var text = '{{foo}} {{bar}} {{foo}}'; | ||
var t = Bogus.compile(text); | ||
var s = t.render({foo: 1, bar: function() { this.foo++; return 42; } }); | ||
test.equal(s, '1 42 2'); | ||
test.end(); | ||
}); | ||
/* shootout benchmark tests */ | ||
@@ -838,4 +908,4 @@ | ||
filter: function() { | ||
return function(text, render) { | ||
return render(text).toUpperCase(); | ||
return function(text) { | ||
return text.toUpperCase() + "{{bar}}"; | ||
} | ||
@@ -845,3 +915,3 @@ }, | ||
}); | ||
var expected = "FOO BAR" | ||
var expected = "FOO bar" | ||
test.equal(s, expected, "Shootout Filter compiled correctly"); | ||
@@ -848,0 +918,0 @@ test.end(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
50856
988
1
2
2
56
+ Addedunderscore@1
+ Addedhogan.js@2.0.0(transitive)
+ Addedunderscore@1.13.7(transitive)
- Removedhogan.js@1.0.5-dev(transitive)
Updatedhogan.js@2.0.0