Skip to content

Commit

Permalink
Merge pull request #71 from kate2753/master
Browse files Browse the repository at this point in the history
dustjs-linkedin#423 fix dust.helpers.tap to work with dust body functions. Fix tap helper to not rely on isFunction flag set in dust core. Using helper.tap on Context functions (function in your JSON context) will now get chunk and context as arguments.
  • Loading branch information
jimmyhchan committed Feb 20, 2014
2 parents 87d949e + c9fdb38 commit c383b44
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 c383b44

Please sign in to comment.