Skip to content

Commit

Permalink
Allow calling dust.helpers.tap on interpolated parameters (dust body …
Browse files Browse the repository at this point in the history
…functions)
  • Loading branch information
kate2753 committed Feb 20, 2014
1 parent 87d949e commit c9fdb38
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 23 deletions.
44 changes: 26 additions & 18 deletions lib/dust-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,34 @@ var helpers = {
dust render emits < and we return the partial output
*/
"tap": function( input, chunk, context ){
"tap": function(input, chunk, context) {
// return given input if there is no dust reference to resolve
var output = input;
// dust compiles a string/reference such as {foo} to function,
if( typeof input === "function"){
// just a plain function (a.k.a anonymous functions) in the context, not a dust `body` function created by the dust compiler
if( input.isFunction === true ){
output = input();
} else {
output = '';
chunk.tap(function(data){
output += data;
return '';
}).render(input, context).untap();
if( output === '' ){
output = false;
}
}
// dust compiles a string/reference such as {foo} to a function
if (typeof input !== "function") {
return input;
}

var dustBodyOutput = '',
returnValue;

//use chunk render to evaluate output. For simple functions result will be returned from render call,
//for dust body functions result will be output via callback function
returnValue = chunk.tap(function(data) {
dustBodyOutput += data;
return '';
}).render(input, context);

chunk.untap();

//assume it's a simple function call if return result is not a chunk
if (returnValue.constructor !== chunk.constructor) {
//use returnValue as a result of tap
return returnValue;
} else if (dustBodyOutput === '') {
return false;
} else {
return dustBodyOutput;
}
return output;
},

"sep": function(chunk, context, bodies) {
Expand Down
99 changes: 94 additions & 5 deletions test/jasmine-test/spec/helpersTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1093,35 +1093,124 @@ var helpersTests = [
source: '{b}. {@tapper value=b/}',
context: { "b" : function() { return "beta"; } },
expected: "beta. beta",
message: "should test if tap helper is working properly when it makes reference to a a string-valued {context function}"
message: "should test if tap helper is working properly when it makes reference to a a string-valued {context function}"
},
{
name: "tap helper: string literal that includes an object-valued {context variable}",
source: 'a.foo is {a.foo}. {@tapper value="a.foo is {a.foo}"/}',
context: { "a" : {"foo":"bar"} },
expected: "a.foo is bar. a.foo is bar",
message: "should test if tap helper is working properly when the value is a string literal that includes an object-valued {context variable}"
message: "should test if tap helper is working properly when the value is a string literal that includes an object-valued {context variable}"
},
{
name: "tap helper: reference to an object-valued {context variable}",
source: '{a.foo}. {@tapper value=a.foo/}',
context: { "a" : {"foo":"bar"} },
expected: "bar. bar",
message: "should test if tap helper is working properly when it makes reference to an object-valued {context variable}"
message: "should test if tap helper is working properly when it makes reference to an object-valued {context variable}"
},
{
name: "tap helper: string literal that calls a function within an object-valued {context variable}",
source: 'a.foo is {a.foo}. {@tapper value="a.foo is {a.foo}"/}',
context: { "a" : {"foo" : function() { return "bar"; } } },
expected: "a.foo is bar. a.foo is bar",
message: "should test if tap helper is working properly when the value is string literal that calls a function within an object-valued {context variable}"
message: "should test if tap helper is working properly when the value is string literal that calls a function within an object-valued {context variable}"
},
{
name: "tap helper: reference to a function within an object-valued {context variable}",
source: '{a.foo} {@tapper value=a.foo/}',
context: { "a" : {"foo" : function() { return "bar"; } } },
expected: "bar bar",
message: "should test if tap helper is working properly when it makes reference to a function within an object-valued {context variable}"
message: "should test if tap helper is working properly when it makes reference to a function within an object-valued {context variable}"
},
{
name: "tap on a function",
source: '{#callTap val=foo}{/callTap}',
context: {
callTap: function(chunk, context, bodies, params) {
return chunk.write(dust.helpers.tap(params.val, chunk, context));
},
foo: function() {
return 'foo';
}
},
expected: "foo",
message: "should call tap on a normal function and use it's return value to write to chunk"
},
{
name: "tap literals",
source: '{#callTap p1=valStr p2=valNum p3=valBool p4=valArray p5=valObj}{/callTap}',
context: {
callTap: function(chunk, context, bodies, params) {
for (var i = 1; i < 6; i ++) {
if (params['p' + i]) {
chunk.write(dust.helpers.tap(params['p' + i], chunk, context));
}
}
return chunk;
},
valStr: "this is string literal",
valNum: 54321,
valBool: true,
valArray: [1,2,3,4,5],
valObj: { whoAmI: "I'm an object" }
},
expected: "this is string literal54321true1,2,3,4,5[object Object]",
message: "should call tap on literals and output them as is to chunk"
},
{
name: "tap interpolated literals",
source: '{#callTap p1="{valStr}" p2="{valNum}" p3="{valBool}" p4="{valArray}" p5="{valObj}"}{/callTap}',
context: {
callTap: function(chunk, context, bodies, params) {
for (var i = 1; i < 6; i ++) {
if (params['p' + i]) {
chunk.write(dust.helpers.tap(params['p' + i], chunk, context));
}
}
return chunk;
},
valStr: "this is string literal",
valNum: 54321,
valBool: true,
valArray: [1,2,3,4,5],
valObj: { whoAmI: "I'm an object" }
},
expected: "this is string literal54321true1,2,3,4,5[object Object]",
message: "should call tap on interpolated literals and output them as is to chunk"
},
{
name: "tap on a function that is using context and chunk",
source: '{#callTap val=foo}{/callTap}',
context: {
callTap: function(chunk, context, bodies, params) {
return chunk.write(dust.helpers.tap(params.val, chunk, context));
},
foo: function(chunk, context) {
return chunk.write(context.get('myVar'));
},
myVar: 'foo'
},
expected: "foo",
message: "testing tap on a normal function returning chunk"
},
{
name: "tap on a section param",
source: '{#foo p1="{baz}"}{#bar}{#callTap val=p1}{/callTap}{/bar}{/foo}',
context: {
baz : "baz",
foo :
{
bar :
{
callTap: function(chunk, context, bodies, params) {
return chunk.write(dust.helpers.tap(params.val, chunk, context));
}
}
}
},
expected: "baz",
message: "testing tap on a dust body function"
}
]
},
Expand Down

0 comments on commit c9fdb38

Please sign in to comment.