Permalink
Browse files

Merge pull request #152 from jimmyhchan/scalarTruthyTest

Really undo 2760048: removing scalar block support
  • Loading branch information...
vybs committed Sep 20, 2012
2 parents fb7df55 + eb70850 commit ba47236a21be25ea1686187d556fb57b6fefe24e
Showing with 84 additions and 17 deletions.
  1. +18 −15 lib/dust.js
  2. +66 −2 test/jasmine-test/spec/coreTests.js
View
@@ -378,17 +378,19 @@ Chunk.prototype.reference = function(elem, context, auto, filters) {
};
Chunk.prototype.section = function(elem, context, bodies, params) {
- // anonymous functions
+ // anonymous functions
if (typeof elem === "function") {
elem = elem.apply(context.current(), [this, context, bodies, params]);
+ // functions that return chunks are assumed to have handled the body and/or have modified the chunk
+ // use that return value as the current chunk and go to the next method in the chain
if (elem instanceof Chunk) {
return elem;
}
}
var body = bodies.block,
skip = bodies['else'];
- // a.k.a Inline parameters in the dust documentations
+ // a.k.a Inline parameters in the Dust documentations
if (params) {
context = context.push(params);
}
@@ -398,7 +400,7 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
When elem resolves to a value or object instead of an array, Dust sets the current context to the value
and renders the block one time.
*/
- //non empty array is truthy, empty array or nonexistent is falsy
+ //non empty array is truthy, empty array is falsy
if (dust.isArray(elem)) {
if (body) {
var len = elem.length, chunk = this;
@@ -425,31 +427,32 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
}
}
}
- // any object ,including {} is truthy
- else if (elem && typeof elem == 'object') {
+ // true is truthy but does not change context
+ else if (elem === true) {
if (body) {
- if(context.stack.head) {
+ return body(this, context);
+ }
+ }
+ // everything that evaluates to true are truthy ( e.g. Non-empty strings and Empty objects are truthy. )
+ // zero is truthy
+ // for anonymous functions that did not returns a chunk, truthiness is evaluated based on the return value
+ //
+ else if (elem || elem === 0) {
+ if (body) {
+ if(context.stack.head && typeof elem === 'object') {
context.stack.head['$idx'] = 0;
context.stack.head['$len'] = 1;
}
chunk = body(this, context.push(elem));
- if(context.stack.head) {
+ if(context.stack.head && typeof elem === 'object') {
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
}
return chunk;
}
- }
- // scalar true and scalar 0 are truthy
- // do not support $idx and $len for scalar
- else if (elem === true || elem === 0) {
- if (body) {
- return body(this, context);
- }
}
// nonexistent, scalar false value, scalar empty string, null,
// undefined are all falsy
- // do not support $idx and $len for scalar
else if (skip) {
return skip(this, context);
}
@@ -139,13 +139,41 @@ var coreTests = [
expected: "true",
message: "should test for a scalar numeric 0 in a # section"
},
+ {
+ name: "scalar numeric non-zero in a # section",
+ source: "{#scalar}true{:else}false{/scalar}",
+ context: {"scalar": 42},
+ expected: "true",
+ message: "should test for a scalar numeric non-zero in a # section"
+ },
+ {
+ name: "scalar non empty string in a # section",
+ source: "{#scalar}true{:else}false{/scalar}",
+ context: {"scalar": 'abcde'},
+ expected: "true",
+ message: "should test for a scalar string in a # section"
+ },
+ {
+ name: "scalar non empty string in a # section",
+ source: "{#scalar}{.}{:else}false{/scalar}",
+ context: {"scalar": 'abcde'},
+ expected: "abcde",
+ message: "should test for a scalar string in a # section"
+ },
{
name: "missing scalar value",
source: "{#scalar}true{:else}false{/scalar}",
context: {"foo": 0},
expected: "false",
message: "should test a missing/undefined scalar value"
},
+ {
+ name: "scalar true value in the # section",
+ source: "{#scalar}true{:else}false{/scalar}",
+ context: {"scalar": true},
+ expected: "true",
+ message: "shoud test for scalar true value in the # section"
+ },
{
name: "scalar false value in the # section",
source: "{#scalar}true{:else}false{/scalar}",
@@ -287,7 +315,7 @@ var coreTests = [
context: { foo: true, bar: false },
expected: "foo, not bar!",
message:"should test scalar values true and false are supported in # nor else blocks"
- },
+ },
{
name: ". creating a block and use it to set aliases",
source: "{#. test=\"you\"}{name} {test}{/.}",
@@ -759,6 +787,42 @@ var coreTests = [
expected: "Hello Foo Bar World!",
message: "should test scope of context function"
},
+ {
+ name: "test that the scope of the function is correct and that a non-chunk return value is used for truthiness checks",
+ source: "Hello {#foo}{#bar}{.}{/bar}{/foo} World!",
+ context: {
+ foo: {
+ foobar: 'Foo Bar',
+ bar: function () {
+ return this.foobar;
+ }
+ }
+ },
+ expected: "Hello Foo Bar World!",
+ message: "should test scope of context function"
+ },
+ {
+ name: "test that function that do not return chunk and return falsy are treated as falsy",
+ source: "{#bar}{.}{:else}false{/bar}",
+ context: {
+ bar: function () {
+ return false;
+ }
+ },
+ expected: "false",
+ message: "should functions that return false are falsy"
+ },
+ {
+ name: "test that function that do not return chunk and return 0 are treated as truthy (in the Dust sense)",
+ source: "{#bar}{.}{:else}false{/bar}",
+ context: {
+ bar: function () {
+ return 0;
+ }
+ },
+ expected: "0",
+ message: "should functions that return 0 are truthy"
+ },
{
name: "Use dash in key",
source: 'Hello {first-name}, {last-name}! You have {count} new messages.',
@@ -822,4 +886,4 @@ if (typeof module !== "undefined" && typeof require !== "undefined") {
module.exports = coreTests; // We're on node.js
} else {
window.coreTests = coreTests; // We're on the browser
-}
+}

0 comments on commit ba47236

Please sign in to comment.