Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dustjs-helpers

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dustjs-helpers - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

.npmignore

131

dist/dust-helpers-1.0.0.js

@@ -8,7 +8,12 @@ //

(function(dust){
(function(){
if (typeof exports !== "undefined")
{
dust = require("dustjs-linkedin");
}
/* make a safe version of console if it is not available
* currently supporting:
* _console.log
* _console.log
* */

@@ -23,3 +28,3 @@ var _console = (typeof console !== 'undefined')? console: {

var value = context.current();
return typeof value === "object" && value.isSelect === true;
return typeof value === "object" && value.isSelect === true;
}

@@ -29,3 +34,3 @@

var params = params || {},
actual,
actual,
expected;

@@ -83,3 +88,3 @@ if (params.key) {

contextDump: function(chunk, context, bodies) {
_console.log(JSON.stringify(context.stack));
_console.log(JSON.stringify(context.stack.head));
return chunk;

@@ -94,11 +99,15 @@ },

if( typeof input === "function"){
output = '';
chunk.tap(function(data){
output += data;
return '';
}).render(input, context).untap();
if( output === '' ){
output = false;
if( ( typeof input.isReference !== "undefined" ) && ( input.isReference === true ) ){ // just a plain function, not a dust `body` function
output = input();
} else {
output = '';
chunk.tap(function(data){
output += data;
return '';
}).render(input, context).untap();
if( output === '' ){
output = false;
}
}
}
}
return output;

@@ -108,3 +117,3 @@ },

/**
if helper
if helper
@param cond, either a string literal value or a dust reference

@@ -135,4 +144,68 @@ a string literal value, is enclosed in double quotes, e.g. cond="2>3"

/**
* math helper
* @param key is the value to perform math against
* @param eq is the value to test for equality with key
* @param method is the math method we will employ
* in the absence of an equality test
* @param operand is the second value needed for
* operations like mod, add, subtract, etc.
*/
"math": function ( chunk, context, bodies, params ) {
//make sure we have key and eq or method params before continuing
if( params && params.key && (params.eq || params.method) ){
var key = params.key;
key = this.tap(key, chunk, context);
if (params.eq) {
var eq = params.eq;
eq = this.tap(eq, chunk, context);
return chunk.write(key === eq);
}
//we are going to operate with math methods if not equals
else {
var method = params.method;
var operand = params.operand || null;
var operError = function(){_console.log("operand is required for this math method")};
var returnExpression = function(exp){chunk.write( exp )};
if (operand) {
operand = this.tap(operand, chunk, context);
}
switch(method) {
case "mod":
(operand) ? returnExpression( parseFloat(key) % parseFloat(operand) ) : operError();
break;
case "add":
(operand) ? returnExpression( parseFloat(key) + parseFloat(operand) ) : operError();
break;
case "subtract":
(operand) ? returnExpression( parseFloat(key) - parseFloat(operand) ) : operError();
break;
case "multiply":
(operand) ? returnExpression( parseFloat(key) * parseFloat(operand) ) : operError();
break;
case "divide":
(operand) ? returnExpression( parseFloat(key) / parseFloat(operand) ) : operError();
break;
case "ceil":
returnExpression( Math.ceil(parseFloat(key)) );
break;
case "floor":
returnExpression( Math.floor(parseFloat(key)) );
break;
case "abs":
returnExpression( Math.abs(parseFloat(key)) );
break;
default:
_console.log( "method passed is not supported" );
}
}
}
// no key parameter and no method or eq passed
else {
_console.log( "Key is a required parameter along with eq or method/operand!" );
}
return chunk;
},
/**
select/eq/lt/lte/gt/gte/default helper
select/eq/lt/lte/gt/gte/default helper
@param key, either a string literal value or a dust reference

@@ -178,2 +251,24 @@ a string literal value, is enclosed in double quotes, e.g. key="foo"

return filter(chunk, context, bodies, params, function(expected, actual) { return true; });
},
"size": function( chunk, context, bodies, params ) {
var subject = params.subject;
var value = 0;
if (!subject) { //undefined, "", 0
value = 0;
}
else if(dust.isArray(subject)) { //array
value = subject.length;
}
else if (!isNaN(subject)) { //numeric values
value = subject;
}
else if (Object(subject) === subject) { //object test
var nr = 0;
for(var k in subject)
if(Object.hasOwnProperty.call(subject,k)) nr++;
value = nr;
} else {
value = (subject + '').length; //any other value (strings etc.)
}
return chunk.write(value);
}

@@ -184,2 +279,6 @@ };

})(typeof exports !== 'undefined' ? exports : getGlobal());
if (typeof exports !== "undefined")
{
module.exports = dust;
}
})();

@@ -7,6 +7,7 @@ (function(){

}
// Note: all error conditions are logged to console and failed silently
/* make a safe version of console if it is not available
* currently supporting:
* _console.log
* _console.log
* */

@@ -21,30 +22,54 @@ var _console = (typeof console !== 'undefined')? console: {

var value = context.current();
return typeof value === "object" && value.isSelect === true;
return typeof value === "object" && value.isSelect === true;
}
function filter(chunk, context, bodies, params, filter) {
var params = params || {},
actual,
expected;
if (params.key) {
actual = helpers.tap(params.key, chunk, context);
} else if (isSelect(context)) {
actual = context.current().selectKey;
// Utility method : toString() equivalent for functions
function jsonFilter(key, value) {
if (typeof value === "function") {
return value.toString();
}
return value;
}
// Utility method: to invoke the given filter operation such as eq/gt etc
function filter(chunk, context, bodies, params, filterOp) {
params = params || {};
var body = bodies.block,
actualKey,
expectedValue,
filterOpType = params.filterOpType || '';
// when @eq, @lt etc are used as standalone helpers, key is required and hence check for defined
if ( typeof params.key !== "undefined") {
actualKey = dust.helpers.tap(params.key, chunk, context);
}
else if (isSelect(context)) {
actualKey = context.current().selectKey;
// supports only one of the blocks in the select to be selected
if (context.current().isResolved) {
filter = function() { return false; };
filterOp = function() { return false; };
}
} else {
throw "No key specified for filter and no key found in context from select statement";
}
expected = helpers.tap(params.value, chunk, context);
if (filter(expected, coerce(actual, params.type, context))) {
else {
_console.log ("No key specified for filter in:" + filterOpType + " helper ");
return chunk;
}
expectedValue = dust.helpers.tap(params.value, chunk, context);
// coerce both the actualKey and expectedValue to the same type for equality and non-equality compares
if (filterOp(coerce(expectedValue, params.type, context), coerce(actualKey, params.type, context))) {
if (isSelect(context)) {
context.current().isResolved = true;
}
return chunk.render(bodies.block, context);
} else if (bodies['else']) {
// we want helpers without bodies to fail gracefully so check it first
if(body) {
return chunk.render(body, context);
}
else {
_console.log( "Missing body block in the " + filterOpType + " helper ");
return chunk;
}
}
else if (bodies['else']) {
return chunk.render(bodies['else'], context);
}
return chunk.write('');
return chunk;
}

@@ -57,3 +82,6 @@

case 'string': return String(value);
case 'boolean': return Boolean(value);
case 'boolean': {
value = (value === 'false' ? false : value);
return Boolean(value);
}
case 'date': return new Date(value);

@@ -68,39 +96,103 @@ case 'context': return context.get(value);

var helpers = {
sep: function(chunk, context, bodies) {
if (context.stack.index === context.stack.of - 1) {
return chunk;
}
return bodies.block(chunk, context);
},
idx: function(chunk, context, bodies) {
return bodies.block(chunk, context.push(context.stack.index));
},
contextDump: function(chunk, context, bodies) {
_console.log(JSON.stringify(context.stack));
return chunk;
},
// Utility helping to resolve dust references in the given chunk
tap: function( input, chunk, context ){
// uses the Chunk.render method to resolve value
/*
Reference resolution rules:
if value exists in JSON:
"" or '' will evaluate to false, boolean false, null, or undefined will evaluate to false,
numeric 0 evaluates to true, so does, string "0", string "null", string "undefined" and string "false".
Also note that empty array -> [] is evaluated to false and empty object -> {} and non-empty object are evaluated to true
The type of the return value is string ( since we concatenate to support interpolated references
if value does not exist in JSON and the input is a single reference: {x}
dust render emits empty string, and we then return false
if values does not exist in JSON and the input is interpolated references : {x} < {y}
dust render emits < and we return the partial output
*/
"tap": function( input, chunk, context ){
// return given input if there is no dust reference to resolve
var output = input;
// dust compiles a string to function, if there are references
// dust compiles a string/reference such as {foo} to function,
if( typeof input === "function"){
output = '';
chunk.tap(function(data){
output += data;
return '';
}).render(input, context).untap();
if( output === '' ){
output = false;
// 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;
}
}
}
return output;
}
return output;
},
"sep": function(chunk, context, bodies) {
var body = bodies.block;
if (context.stack.index === context.stack.of - 1) {
return chunk;
}
if(body) {
return bodies.block(chunk, context);
}
else {
return chunk;
}
},
"idx": function(chunk, context, bodies) {
var body = bodies.block;
if(body) {
return bodies.block(chunk, context.push(context.stack.index));
}
else {
return chunk;
}
},
/**
if helper
* contextDump helper
* @param key specifies how much to dump.
* "current" dumps current context. "full" dumps the full context stack.
* @param to specifies where to write dump output.
* Values can be "console" or "output". Default is output.
*/
"contextDump": function(chunk, context, bodies, params) {
var p = params || {},
to = p.to || 'output',
key = p.key || 'current',
dump;
to = dust.helpers.tap(to, chunk, context),
key = dust.helpers.tap(key, chunk, context);
if (key === 'full') {
dump = JSON.stringify(context.stack, jsonFilter, 2);
}
else {
dump = JSON.stringify(context.stack.head, jsonFilter, 2);
}
if (to === 'console') {
_console.log(dump);
return chunk;
}
else {
return chunk.write(dump);
}
},
/**
if helper for complex evaluation complex logic expressions.
Note : #1 if helper fails gracefully when there is no body block nor else block
#2 Undefined values and false values in the JSON need to be handled specially with .length check
for e.g @if cond=" '{a}'.length && '{b}'.length" is advised when there are chances of the a and b been
undefined or false in the context
#3 Use only when the default ? and ^ dust operators and the select fall short in addressing the given logic,
since eval executes in the global scope
#4 All dust references are default escaped as they are resolved, hence eval will block malicious scripts in the context
Be mindful of evaluating a expression that is passed through the unescape filter -> |s
@param cond, either a string literal value or a dust reference

@@ -113,10 +205,18 @@ a string literal value, is enclosed in double quotes, e.g. cond="2>3"

"if": function( chunk, context, bodies, params ){
if( params && params.cond ){
var body = bodies.block,
skip = bodies['else'];
if( params && params.cond){
var cond = params.cond;
cond = this.tap(cond, chunk, context);
cond = dust.helpers.tap(cond, chunk, context);
// eval expressions with given dust references
if( eval( cond ) ){
return chunk.render( bodies.block, context );
if(eval(cond)){
if(body) {
return chunk.render( bodies.block, context );
}
else {
_console.log( "Missing body block in the if helper!" );
return chunk;
}
}
if( bodies['else'] ){
if(skip){
return chunk.render( bodies['else'], context );

@@ -131,15 +231,97 @@ }

},
/**
* math helper
* @param key is the value to perform math against
* @param method is the math method, is a valid string supported by math helper like mod, add, subtract
* @param operand is the second value needed for operations like mod, add, subtract, etc.
*/
"math": function ( chunk, context, bodies, params ) {
//key and method are required for further processing
if( params && typeof params.key !== "undefined" && params.method ){
var key = params.key,
method = params.method,
// operand can be null for "abs", ceil and floor
operand = params.operand,
mathOut = null,
operError = function(){_console.log("operand is required for this math method"); return null;};
key = dust.helpers.tap(key, chunk, context);
operand = dust.helpers.tap(operand, chunk, context);
// TODO: handle and tests for negatives and floats in all math operations
switch(method) {
case "mod":
if(operand === 0 || operand === -0) {
_console.log("operand for divide operation is 0/-0: expect Nan!");
}
mathOut = parseFloat(key) % parseFloat(operand);
break;
case "add":
mathOut = parseFloat(key) + parseFloat(operand);
break;
case "subtract":
mathOut = parseFloat(key) - parseFloat(operand);
break;
case "multiply":
mathOut = parseFloat(key) * parseFloat(operand);
break;
case "divide":
if(operand === 0 || operand === -0) {
_console.log("operand for divide operation is 0/-0: expect Nan/Infinity!");
}
mathOut = parseFloat(key) / parseFloat(operand);
break;
case "ceil":
mathOut = Math.ceil(parseFloat(key));
break;
case "floor":
mathOut = Math.floor(parseFloat(key));
break;
case "abs":
mathOut = Math.abs(parseFloat(key));
break;
default:
_console.log( "method passed is not supported" );
}
if (mathOut !== null){
if (bodies && bodies.block) {
// with bodies act like the select helper with mathOut as the key
// like the select helper bodies['else'] is meaningless and is ignored
return chunk.render(bodies.block, context.push({ isSelect: true, isResolved: false, selectKey: mathOut }));
} else {
// self closing math helper will return the calculated output
return chunk.write(mathOut);
}
} else {
return chunk;
}
}
// no key parameter and no method
else {
_console.log( "Key is a required parameter for math helper along with method/operand!" );
}
return chunk;
},
/**
select/eq/lt/lte/gt/gte/default helper
@param key, either a string literal value or a dust reference
select helperworks with one of the eq/gt/gte/lt/lte/default providing the functionality
of branching conditions
@param key, ( required ) either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param type (optiona), supported types are number, boolean, string, date, context, defaults to string
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
**/
select: function(chunk, context, bodies, params) {
if( params && params.key){
"select": function(chunk, context, bodies, params) {
var body = bodies.block;
// key is required for processing, hence check for defined
if( params && typeof params.key !== "undefined"){
// returns given input as output, if the input is not a dust reference, else does a context lookup
var key = this.tap(params.key, chunk, context);
return chunk.render(bodies.block, context.push({ isSelect: true, isResolved: false, selectKey: key }));
var key = dust.helpers.tap(params.key, chunk, context);
// bodies['else'] is meaningless and is ignored
if( body ) {
return chunk.render(bodies.block, context.push({ isSelect: true, isResolved: false, selectKey: key }));
}
else {
_console.log( "Missing body block in the select helper ");
return chunk;
}
}

@@ -153,25 +335,161 @@ // no key

eq: function(chunk, context, bodies, params) {
/**
eq helper compares the given key is same as the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"eq": function(chunk, context, bodies, params) {
if(params) {
params.filterOpType = "eq";
}
return filter(chunk, context, bodies, params, function(expected, actual) { return actual === expected; });
},
lt: function(chunk, context, bodies, params) {
return filter(chunk, context, bodies, params, function(expected, actual) { return actual < expected; });
/**
ne helper compares the given key is not the same as the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"ne": function(chunk, context, bodies, params) {
if(params) {
params.filterOpType = "ne";
return filter(chunk, context, bodies, params, function(expected, actual) { return actual !== expected; });
}
return chunk;
},
lte: function(chunk, context, bodies, params) {
return filter(chunk, context, bodies, params, function(expected, actual) { return actual <= expected; });
/**
lt helper compares the given key is less than the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"lt": function(chunk, context, bodies, params) {
if(params) {
params.filterOpType = "lt";
return filter(chunk, context, bodies, params, function(expected, actual) { return actual < expected; });
}
},
gt: function(chunk, context, bodies, params) {
return filter(chunk, context, bodies, params, function(expected, actual) { return actual > expected; });
/**
lte helper compares the given key is less or equal to the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"lte": function(chunk, context, bodies, params) {
if(params) {
params.filterOpType = "lte";
return filter(chunk, context, bodies, params, function(expected, actual) { return actual <= expected; });
}
return chunk;
},
gte: function(chunk, context, bodies, params) {
return filter(chunk, context, bodies, params, function(expected, actual) { return actual >= expected; });
/**
gt helper compares the given key is greater than the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"gt": function(chunk, context, bodies, params) {
// if no params do no go further
if(params) {
params.filterOpType = "gt";
return filter(chunk, context, bodies, params, function(expected, actual) { return actual > expected; });
}
return chunk;
},
/**
gte helper, compares the given key is greater than or equal to the expected value
It can be used standalone or in conjunction with select for multiple branching
@param key, The actual key to be compared ( optional when helper used in conjunction with select)
either a string literal value or a dust reference
a string literal value, is enclosed in double quotes, e.g. key="foo"
a dust reference may or may not be enclosed in double quotes, e.g. key="{val}" and key=val are both valid
@param value, The expected value to compare to, when helper is used standalone or in conjunction with select
@param type (optional), supported types are number, boolean, string, date, context, defaults to string
Note : use type="number" when comparing numeric
**/
"gte": function(chunk, context, bodies, params) {
if(params) {
params.filterOpType = "gte";
return filter(chunk, context, bodies, params, function(expected, actual) { return actual >= expected; });
}
return chunk;
},
// to be used in conjunction with the select helper
// TODO: fix the helper to do nothing when used standalone
"default": function(chunk, context, bodies, params) {
return filter(chunk, context, bodies, params, function(expected, actual) { return true; });
// does not require any params
if(params) {
params.filterOpType = "default";
}
return filter(chunk, context, bodies, params, function(expected, actual) { return true; });
},
/**
* size helper prints the size of the given key
* Note : size helper is self closing and does not support bodies
* @param key, the element whose size is returned
*/
"size": function( chunk, context, bodies, params ) {
var key, value=0, nr, k;
params = params || {};
key = params.key;
if (!key || key === true) { //undefined, null, "", 0
value = 0;
}
else if(dust.isArray(key)) { //array
value = key.length;
}
else if (!isNaN(parseFloat(key)) && isFinite(key)) { //numeric values
value = key;
}
else if (typeof key === "object") { //object test
//objects, null and array all have typeof ojbect...
//null and array are already tested so typeof is sufficient http://jsperf.com/isobject-tests
nr = 0;
for(k in key){
if(Object.hasOwnProperty.call(key,k)){
nr++;
}
}
value = nr;
} else {
value = (key + '').length; //any other value (strings etc.)
}
return chunk.write(value);
}
};

@@ -181,2 +499,6 @@

})(typeof exports !== 'undefined' ? exports : getGlobal());
if (typeof exports !== "undefined")
{
module.exports = dust;
}
})();
{
"name": "dustjs-helpers",
"version": "1.0.0",
"author": "Jairo de Morais",
"description": "Helpers for dustjs-LinkedIn package",
"version": "1.1.0",
"author": "Aleksander Williams",
"description": "Helpers for dustjs-linkedin package",
"contributors": [

@@ -12,2 +12,6 @@ {

{
"name": "Yevgeniy Brikman",
"email":"jbrikman@linkedin.com"
},
{
"name": "Veena Basavaraj",

@@ -19,2 +23,14 @@ "email":"vbasavaraj@linkedin.com"

"email":"jleppert@linkedin.com"
},
{
"name": "Jimmy Chan",
"email":"jchan@linkedin.com"
},
{
"name": "Richard Ragan",
"email":"rragan@ebay.com"
},
{
"name": "Sarah Clatterbuck",
"email": "sclatter@linkedin.com"
}

@@ -29,3 +45,3 @@ ],

"type": "git",
"url": "https://jairodemorais@github.com/linkedin/dustjs.git"
"url": "https://github.com/linkedin/dustjs-helpers.git"
},

@@ -36,3 +52,3 @@ "keywords": ["templates", "views", "helpers"],

"cover" : "0.2.x",
"dustjs-linkedin": "1.0.0"
"dustjs-linkedin": "1.1.x"
},

@@ -39,0 +55,0 @@ "license": "MIT",

@@ -83,2 +83,182 @@ (function(exports){

});
suite.test("tap (plain text string literal)", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { };
dust.renderSource("plain text. {@tapper value=\"plain text\"/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "plain text. plain text");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (string literal that includes a string-valued {context variable})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { a:"Alpha" };
dust.renderSource("a is {a}. {@tapper value=\"a is {a}\"/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "a is Alpha. a is Alpha");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (reference to string-valued context variable)", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { a:"Alpha" };
dust.renderSource("{a}. {@tapper value=a/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "Alpha. Alpha");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (string literal that includes a string-valued {context function})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "b":function() { return "beta"; } };
dust.renderSource("b is {b}. {@tapper value=\"b is {b}\"/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "b is beta. b is beta");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (reference to a a string-valued {context function})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "b":function() { return "beta"; } };
dust.renderSource("{b}. {@tapper value=b/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "beta. beta");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (string literal that includes an object-valued {context variable})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "a":{"foo":"bar"} };
dust.renderSource("a.foo is {a.foo}. {@tapper value=\"a.foo is {a.foo}\"/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "a.foo is bar. a.foo is bar");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (reference to an object-valued {context variable})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "a":{"foo":"bar"} };
dust.renderSource("{a.foo}. {@tapper value=a.foo/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "bar. bar");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (string literal that calls a function within an object-valued {context variable})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "a": {"foo":function() { return "bar"; } } };
dust.renderSource("a.foo is {a.foo}. {@tapper value=\"a.foo is {a.foo}\"/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "a.foo is bar. a.foo is bar");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
suite.test("tap (reference to a function within an object-valued {context variable})", function() {
var unit = this;
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
var base_context = { "a": {"foo":function() { return "bar"; } } };
dust.renderSource("{a.foo} {@tapper value=a.foo/}", base_context, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "bar bar");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});
}

@@ -85,0 +265,0 @@

@@ -8,5 +8,18 @@ var jasmine = require('jasmine-node'),

dust.helpers = require("../../../lib/dust-helpers").helpers,
helpersTests = require('../spec/helpersTests');
//Add the tapper helper to test the Tap helper.
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
//Add the tapper helper to test the Tap helper.
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};
for(key in jasmine)

@@ -13,0 +26,0 @@ global[key] = jasmine[key];

var helpersTests = [
{
name: "hello_there",
source: "Hello {name}! You have {count} new messages.",
context: { name: "Mick", count: 30 },
expected: "Hello Mick! You have 30 new messages.",
message: "should test a basic replace"
},
{
name: "replace",
source: "Hello {name}! You have {count} new messages.",
context: { name: "Mick", count: 30 },
expected: "Hello Mick! You have 30 new messages.",
message: "should test a basic replace"
name: "if helper with no body",
source: '{@if cond="{x}<{y}"/}',
context: { x: 2, y: 3 },
expected: "",
message: "should test if helper with no body and fail gracefully"
},
{
{
name: "if helper without else",
source: '{@if cond="{x}<{y}"}<div> X < Y </div>{/if}',
source: '{@if cond="{x}<{y}"}<div> X < Y </div>{/if}',
context: { x: 2, y: 3 },

@@ -18,3 +25,3 @@ expected: "<div> X < Y </div>",

name: "if helper with else block",
source: '{@if cond=" \'{x}\'.length && \'{y}\'.length "}<div> X and Y exists </div>{:else}<div> X and Y does not exists </div>{/if}',
source: '{@if cond=" \'{x}\'.length && \'{y}\'.length "}<div> X and Y exists </div>{:else}<div> X and Y does not exists </div>{/if}',
context: {},

@@ -26,3 +33,3 @@ expected: "<div> X and Y does not exists </div>",

name: "if helper with else using the or condition",
source: '{@if cond=" \'{x}\'.length || \'{y}\'.length "}<div> X or Y exists </div>{:else}<div> X or Y does not exists </div>{/if}',
source: '{@if cond=" \'{x}\'.length || \'{y}\'.length "}<div> X or Y exists </div>{:else}<div> X or Y does not exists </div>{/if}',
context: { x: 1},

@@ -34,3 +41,3 @@ expected: "<div> X or Y exists </div>",

name: "if helper with else using the and conditon",
source: '{@if cond="( \'{x}\'.length ) && ({x}<3)"}<div> X exists and is 1 </div>{:else}<div> x is not there </div>{/if}',
source: '{@if cond="( \'{x}\'.length ) && ({x}<3)"}<div> X exists and is 1 </div>{:else}<div> x is not there </div>{/if}',
context: { x : 1},

@@ -42,3 +49,3 @@ expected: "<div> X exists and is 1 </div>",

name: "if helper using $idx",
source: '{#list}{@if cond="( {$idx} == 1 )"}<div>{y}</div>{/if}{/list}',
source: '{#list}{@if cond="( {$idx} == 1 )"}<div>{y}</div>{/if}{/list}',
context: { x : 1, list: [ { y: 'foo' }, { y: 'bar'} ]},

@@ -49,2 +56,584 @@ expected: "<div>bar</div>",

{
name: "math/mod helper with zero as key value",
source: '<div>{@math key="0" method="mod" operand="16"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math/mod helper with zero as key value"
},
{
name: "math/mod helper with zero as key value",
source: '<div>{@math key="0" method="mod" operand="-16"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math/mod helper with zero as key value"
},
{
name: "math/mod helper with zero as key value and operand as variable as variable without quotes",
source: '<div>{@math key="0" method="mod" operand=y/}</div>',
context: { y: 4},
expected: "<div>0</div>",
message: "testing math/mod helper with zero as key value and operand as variable without quotes"
},
{
name: "math/mod helper with zero as key value and operand as variable with quotes",
source: '<div>{@math key="0" method="mod" operand="{y}"/}</div>',
context: { y: 4},
expected: "<div>0</div>",
message: "testing math/mod helper with zero as key value and operand as variable with quotes"
},
{
name: "math/mod helper with zero as operand value",
source: '<div>{@math key="0" method="mod" operand="0"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math/mod helper with zero as operand value"
},
{
name: "math/mod helper with negative zero as operand value",
source: '<div>{@math key="0" method="mod" operand="-0"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math/mod helper with negative zero as operand value"
},
{
name: "math/divide helper with zero as key value",
source: '<div>{@math key="0" method="divide" operand="16"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math/divide helper with zero as key value"
},
{
name: "math/divide helper with zero as operand value",
source: '<div>{@math key="0" method="divide" operand="0"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math/divide helper with zero as operand value"
},
{
name: "math helper mod numbers",
source: '<div>{@math key="16" method="mod" operand="4"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math/mod helper with two numbers"
},
{
name: "math helper mod using $idx",
source: '{#list}<div>{@math key="{$idx}" method="mod" operand="5"/}</div>{/list}',
context: { list: [ { y: 'foo' } ]},
expected: "<div>0</div>",
message: "should test the math/mod helper using $idx"
},
{
name: "math helper mod using $idx without quotes with lizt size = 2",
source: '{#list}<div>{@math key="{$idx}" method="mod" operand="2"/}</div>{/list}',
context: { list: [ { y: 'foo' }, { y: "bar"} ]},
expected: "<div>0</div><div>1</div>",
message: "should test the math/mod helper using $idx without quotes with lizt size = 2"
},
{
name: "math helper mod using $idx without quotes",
source: '{#list}<div>{@math key=$idx method="mod" operand="5"/}</div>{/list}',
context: { list: [ { y: 'foo' } ]},
expected: "<div>0</div>",
message: "should test the math/mod helper using $idx without quotes"
},
{
name: "math helper mod using $idx without quotes with lizt size = 2",
source: '{#list}<div>{@math key=$idx method="mod" operand="2"/}</div>{/list}',
context: { list: [ { y: 'foo' }, { y: "bar"} ]},
expected: "<div>0</div><div>1</div>",
message: "should test the math/mod helper using $idx without quotes with lizt size = 2"
},
{
name: "math helper mod using $len",
source: '{#list}<div>{@math key="{$len}" method="mod" operand="5"/}</div>{/list}',
context: { list: [ { y: 'foo' } ]},
expected: "<div>1</div>",
message: "should test the math/mod helper using $len"
},
{
name: "math helper mod using $len without quotes",
source: '{#list}<div>{@math key=$len method="mod" operand="5"/}</div>{/list}',
context: { list: [ { y: 'foo' } ]},
expected: "<div>1</div>",
message: "should test the math/mod helper using $len without quotes"
},
{
name: "math helper subtract numbers",
source: '<div>{@math key="16" method="subtract" operand="4"/}</div>',
context: {},
expected: "<div>12</div>",
message: "testing math/subtract helper with two numbers"
},
{
name: "math helper add with key as negative number",
source: '<div>{@math key="-16" method="add" operand="4"/}</div>',
context: {},
expected: "<div>-12</div>",
message: "testing math/add helper with key as negative number"
},
{
name: "math helper subtract with key as negative number",
source: '<div>{@math key="-16" method="subtract" operand="4"/}</div>',
context: {},
expected: "<div>-20</div>",
message: "testing math/subtract helper with key as negative number"
},
{
name: "math helper multiply with key as negative number",
source: '<div>{@math key="-2" method="multiply" operand="4"/}</div>',
context: {},
expected: "<div>-8</div>",
message: "testing math/multiply helper with key as negative number"
},
{
name: "math helper multiply with key as negative number and variable operand without quotes",
source: '<div>{@math key="-2" method="multiply" operand=y/}</div>',
context: { y: 4},
expected: "<div>-8</div>",
message: "testing math/multiply helper with key as negative number and variable operand without quotes"
},
{
name: "math helper multiply with key as negative number and variable operand with quotes",
source: '<div>{@math key="-2" method="multiply" operand="{y}"/}</div>',
context: { y: 4},
expected: "<div>-8</div>",
message: "testing math/multiply helper with key as negative number and variable operand with quotes"
},
{
name: "math helper add negative numbers",
source: '<div>{@math key="-16" method="add" operand="-4"/}</div>',
context: {},
expected: "<div>-20</div>",
message: "testing math/add helper with negative numbers"
},
{
name: "math helper subtract negative numbers",
source: '<div>{@math key="-16" method="subtract" operand="-4"/}</div>',
context: {},
expected: "<div>-12</div>",
message: "testing math/subtract helper with negative numbers"
},
{
name: "math helper multiply negative numbers",
source: '<div>{@math key="-0" method="multiply" operand="-4"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math/multiply helper with negative numbers"
},
{
name: "math helper blah operation",
source: '{@math key="-0" method="blah" operand="-4"/}',
context: {},
expected: "",
message: "math helper blah operation"
},
{
name: "math helper key as zero",
source: '<div>{@math key="0" method="subtract" operand="0"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math helper with zero as the operand"
},
{
name: "math helper zero key",
source: '<div>{@math key="0" method="multiply" operand="0"/}</div>',
context: {},
expected: "<div>0</div>",
message: "testing math helper with zero key"
},
{
name: "math helper zero key and operand for divide",
source: '<div>{@math key="0" method="divide" operand="0"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math helper with zero key and operand for divide"
},
{
name: "math helper zero operand",
source: '<div>{@math key="16" method="subtract" operand="0"/}</div>',
context: {},
expected: "<div>16</div>",
message: "testing math helper with zero as the operand"
},
{
name: "math helper subtract number and string",
source: '<div>{@math key="16" method="subtract" operand="doh"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math/subtract helper with a number and a string"
},
{
name: "math helper add numbers",
source: '<div>{@math key="5" method="add" operand="4"/}</div>',
context: {},
expected: "<div>9</div>",
message: "testing math/add helper with two numbers"
},
{
name: "math helper multiply numbers",
source: '<div>{@math key="5" method="multiply" operand="4"/}</div>',
context: {},
expected: "<div>20</div>",
message: "testing math/multiply helper with two numbers"
},
{
name: "math helper divide using variable",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : 4 },
expected: "<div>4</div>",
message: "testing math/divide helper with variable as operand"
},
{
name: "math helper divide with null as key and operand value",
source: '<div>{@math key="{y}" method="divide" operand="{y}"/}</div>',
context: { y : null},
expected: "<div>NaN</div>",
message: "testing math/divide helper with null as key and operand value"
},
{
name: "math helper divide with null as operand value",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : null},
expected: "<div>NaN</div>",
message: "testing math/divide helper with null as operand value"
},
{
name: "math helper divide with null as undefined value",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : undefined},
expected: "<div>NaN</div>",
message: "testing math/divide helper with null as undefined value"
},
{
name: "math helper mod with negative 0 as operand",
source: '<div>{@math key="16" method="mod" operand="{y}"/}</div>',
context: { y : -0 },
expected: "<div>NaN</div>",
message: "testing math/mod helper with negative 0 as operand"
},
{
name: "math helper mod with null as key and operand",
source: '<div>{@math key="{y}" method="mod" operand="{y}"/}</div>',
context: { y : null },
expected: "<div>NaN</div>",
message: "testing math helper mod with null as key and operand"
},
{
name: "math helper divide using negative value for variable",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : -4 },
expected: "<div>-4</div>",
message: "testing math/divide helper using negative value for variable as operand"
},
{
name: "math helper divide using key as non numeric",
source: '<div>{@math key="doh" method="divide" operand="{y}"/}</div>',
context: { y : 0 },
expected: "<div>NaN</div>",
message: "testing math/divide helper using key as non numeric"
},
{
name: "math helper divide using 0 for variable",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : 0 },
expected: "<div>Infinity</div>",
message: "testing math/divide helper using 0 for variable as operand"
},
{
name: "math helper divide using negative 0 for variable",
source: '<div>{@math key="16" method="divide" operand="{y}"/}</div>',
context: { y : -0 },
expected: "<div>Infinity</div>",
message: "testing math/divide helper using negative 0 for variable as operand"
},
{
name: "math helper floor numbers",
source: '<div>{@math key="16.5" method="floor"/}</div>',
context: {},
expected: "<div>16</div>",
message: "testing math/floor helper with two numbers"
},
{
name: "math helper ceil numbers",
source: '<div>{@math key="16.5" method="ceil"/}</div>',
context: {},
expected: "<div>17</div>",
message: "testing math/ceil helper with two numbers"
},
{
name: "math helper abs numbers with missing key",
source: '<div>{@math key="{key}" method="abs"/}</div>',
context: {},
expected: "<div>NaN</div>",
message: "testing math/abs helper with missing key"
},
{
name: "math helper abs numbers",
source: '<div>{@math key="-16" method="abs"/}</div>',
context: {},
expected: "<div>16</div>",
message: "testing math/abs helper with two numbers"
},
{
name: "math helper abs numbers with null key",
source: '<div>{@math key="{key}" method="abs"/}</div>',
context: {key : null},
expected: "<div>NaN</div>",
message: "testing math/abs helper with null key"
},
{
name: "math helper eq filter",
source: '<div>{@math key="-13" method="abs"}{@eq value=13}Test is true{/eq}{/math}</div>',
context: {},
expected: "<div>Test is true</div>",
message: "testing math with body helper with abs and eq"
},
{
name: "math helper with body gt test else",
source: '<div>{@math key="13" method="add" operand="12"}{@gt value=123}13 + 12 > 123{:else}Math is fun{/gt}{/math}</div>',
context: {},
expected: "<div>Math is fun</div>",
message: "testing math with body else helper with add and gt"
},
{
name: "math helper with body gt default",
source: '<div>{@math key="13" method="add" operand="12"}{@gt value=123}13 + 12 > 123{/gt}{@default}Math is fun{/default}{/math}</div>',
context: {},
expected: "<div>Math is fun</div>",
message: "testing math with body else helper with add and gt and default"
},
{
name: "math helper with body acts like the select helper",
source: '<div>{@math key="1" method="add" operand="1"}math with body is truthy{:else}else is meaningless{/math}</div>',
context: {},
expected: "<div>math with body is truthy</div>",
message: "testing math with body ignores the else"
},
{
name: "math helper with body acts like the select helper",
source: '<div>{@math key="1" method="subtract" operand="1"}math with body is truthy even if mathout is falsy{:else}else is meaningless{/math}</div>',
context: {},
expected: "<div>math with body is truthy even if mathout is falsy</div>",
message: "testing math with body ignores the else"
},
{
name: "math helper empty body",
source: '<div>{@math key="1" method="add" operand="2"}{/math}</div>',
context: {},
expected: "<div></div>",
message: "testing math with an empty body will show what is inside empty"
},
{
name: "select helper with no body",
source: "{@select key=\"foo\"/}",
context: {},
expected: "",
message: "select helper with no body silently fails with console log"
},
{
name: "eq helper with no body",
source: "{@eq key=\"foo\" value=\"foo\"/}",
context: {},
expected: "",
message: "eq helper with no body silently fails with console log"
},
{
name: "eq helper matching string case",
source: "{@eq key=\"foo\" value=\"foo\"}equal{/eq}",
context: {},
expected: "equal",
message: "eq helper matching string case"
},
{
name: "eq helper non matching string case",
source: "{@eq key=\"foo\" value=\"bar\"}equal{:else}bar{/eq}",
context: {},
expected: "bar",
message: "eq helper non matching string case"
},
{
name: "eq helper non matching string case missing else block",
source: "{@eq key=\"foo\" value=\"bar\"}equal{/eq}",
context: {},
expected: "",
message: "eq helper non matching string case missing else block"
},
{
name: "eq helper equal boolean case",
source: "{@eq key=\"true\" value=\"true\" type=\"boolean\"}equal{/eq}",
context: {},
expected: "equal",
message: "eq helper equal boolean case"
},
{
name: "eq helper non equal/false boolean case",
source: "{@eq key=\"false\" value=\"true\" type=\"boolean\"}equal{/eq}",
context: {},
expected: "",
message: "eq helper non equal boolean case"
},
{
name: "not eq helper true/notequal boolean case",
source: "{@ne key=\"true\" value=\"false\" type=\"boolean\"}not equal{/ne}",
context: {},
expected: "not equal",
message: "not eq helper true/notequal boolean case"
},
{
name: "not eq helper alse/equal boolean case",
source: "{@ne key=\"false\" value=\"false\" type=\"boolean\"}equal{/ne}",
context: {},
expected: "",
message: "not eq helper alse/equal boolean case"
},
{
name: "ne helper with no body",
source: "{@ne key=\"foo\" value=\"foo\"/}",
context: {},
expected: "",
message: "ne helper with no body silently fails with console log"
},
{
name: "ne helper matching string case",
source: "{@ne key=\"foo\" value=\"foo\"}not equal{/ne}",
context: {},
expected: "",
message: "ne helper matching string case"
},
{
name: "ne helper non matching string case",
source: "{@ne key=\"foo\" value=\"bar\"}not equal{:else}bar{/ne}",
context: {},
expected: "not equal",
message: "ne helper non matching string case"
},
{
name: "ne helper non matching string case missing else block",
source: "{@ne key=\"foo\" value=\"bar\"}not equal{/ne}",
context: {},
expected: "not equal",
message: "ne helper non matching string case missing else block"
},
{
name: "ne helper non equal numbers case",
source: "{@ne key=\"3\" value=\"5\" type=\"number\"}not equal{/ne}",
context: {},
expected: "not equal",
message: "ne helper non equal numbers case"
},
{
name: "ne helper equal numbers case",
source: "{@ne key=\"3\" value=\"3\" type=\"number\"}not equal{/ne}",
context: {},
expected: "",
message: "ne helper equal numbers case"
},
{
name: "ne helper non equal boolean case",
source: "{@ne key=\"false\" value=\"true\" type=\"boolean\"}not equal{/ne}",
context: {},
expected: "not equal",
message: "ne helper non equal boolean case"
},
{
name: "ne helper equal boolean case",
source: "{@ne key=\"true\" value=\"true\" type=\"boolean\"}not equal{/ne}",
context: {},
expected: "",
message: "ne helper equal boolean case"
},
{
name: "lt helper with no body",
source: "{@lt key=\"2\" value=\"3\" type=\"number\"/}",
context: {},
expected: "",
message: "lt helper with no body silently fails with console log"
},
{
name: "lt helper defaults to type number",
source: "{@lt key=\"22\" value=\"33\"}22 less than 33{/lt}",
context: {},
expected: "22 less than 33",
message: "lt helper will default to type number"
},
{
name: "lt helper with a variable with explicit type number",
source: "{@lt key=\"{a}\" value=\"33\" type=\"number\"}22 less than 33{/lt}",
context: {a: 22},
expected: "22 less than 33",
message: "lt helper with a variable with explicit type number"
},
{
name: "lt helper with a variable defaults to type number ( type is not mandatory)",
source: "{@lt key=\"{a}\" value=\"33\"}22 less than 33{/lt}",
context: {a: 22},
expected: "22 less than 33",
message: "lt helper with a variable will default to type number"
},
{
name: "lt helper with a variable defaults to type number",
source: "{@lt key=a value=\"33\"}22 less than 33{/lt}",
context: {a: 22},
expected: "22 less than 33",
message: "lt helper with a variable will default to type number"
},
{
name: "lt helper with a variable type returned as string from tap",
source: "{@lt key=\"{a}\" value=\"3\"}22 less than 3, since it is string compare{/lt}",
context: {a: 22},
expected: "22 less than 3, since it is string compare",
message: "lt helper with a variable type returned as string from tap"
},
{
name: "lt helper with a variable type returned as int from tap",
source: "{@lt key=a value=\"3\"}22 less than 3{/lt}",
context: {a: 22},
expected: "",
message: "lt helper with a with a variable type returned as int from tap"
},
{
name: "lt helper with a variable with type string representing int",
source: "{@lt key=a value=\"33\"}22 less than 33{/lt}",
context: {a:"22"},
expected: "22 less than 33",
message: "lt helper with a variable with type string representing int"
},
{
name: "lt helper with a variable with type string representing float",
source: "{@lt key=a value=\"33\"}22 less than 33{/lt}",
context: {a:"22.33"},
expected: "22 less than 33",
message: "lt helper with a variable with type string representing float"
},
{
name: "gt helper with type string not valid case",
source: "{@gt key=\"22\" value=\"3\" type=\"string\"}22 greater than 3 with type string {:else}22 not greater than 3 with type string{/gt}",
context: {},
expected: "22 not greater than 3 with type string",
message: "gt helper with type string not valid case"
},
{
name: "lte helper with no body",
source: "{@lte key=\"2\" value=\"3\" type=\"number\"/}",
context: {},
expected: "",
message: "lte helper with no body silently fails with console log"
},
{
name: "gt helper with no body",
source: "{@gt key=\"5\" value=\"3\" type=\"number\"/}",
context: {},
expected: "",
message: "gt helper with no body silently fails with console log"
},
{
name: "gte helper with no body",
source: "{@gte key=\"5\" value=\"3\" type=\"number\"/}",
context: {},
expected: "",
message: "gte helper with no body silently fails with console log"
},
{
name: "select helper with a constant string and condition eq",

@@ -58,4 +647,4 @@ source: ["{@select key=\"foo\"}",

message: "should test select helper with a constant string and condition eq"
},
{
},
{
name: "select helper with a variable string and condition eq",

@@ -90,3 +679,3 @@ source: ["{@select key=\"{foo}\"}",

},
{

@@ -152,4 +741,13 @@ name: "select helper with variable and one condition lt",

},
{
name: "select helper with a zero variable and one condition gte",
source: ["{@select key=foo}",
"{@gte value=0}foobar{/gte}",
"{/select}"
].join("\n"),
context: { foo: 0 },
expected: "foobar",
message: "should test select helper with variable and one condition gte"
},
{
name: "select helper with variable of type string and eq condition",

@@ -204,3 +802,3 @@ source: ["{@select key=\"{foo}\"}",

'{@eq value="{x}"}<div>BAR</div>{/eq}',
'{/select}'].join("\n"),
'{/select}'].join("\n"),
context: { "test":"foo", "y": "foo", "x": "bar" },

@@ -224,3 +822,3 @@ expected: "<div>FOO</div>",

},
{

@@ -238,3 +836,3 @@ name: "select helper with missing key in the context and hence no output",

{
name: "select helper wih key matching the else condition",
name: "select helper wih key matching the default condition",
source: ["{#b}{@select key=\"{x}\"}",

@@ -247,3 +845,3 @@ " {@eq value=\"{y}\"}<div>BAR</div>{/eq}",

expected: "foofoo",
message: "should test select helper with key matching the else condition"
message: "should test select helper with key matching the default condition"
},

@@ -273,24 +871,241 @@ {

{
name: "partial within a array",
source: '{#n}{>replace name=. count="30"/}{@sep} {/sep}{/n}',
context: { n: ["Mick", "Tom", "Bob"] },
expected: "Hello Mick! You have 30 new messages. Hello Tom! You have 30 new messages. Hello Bob! You have 30 new messages.",
message: "should test partial within an array"
name: "eq helper without a body",
source: "{@eq key=\"abc\" value=\"java\"/}",
context: {},
expected: "",
message: "eq helper without a body should fail gracefully and return nothing"
},
{
name: "async_iterator",
source: "{#numbers}{#delay}{.}{/delay}{@sep}, {/sep}{/numbers}",
context: {
numbers: [3, 2, 1],
delay: function(chunk, context, bodies) {
return chunk.map(function(chunk) {
setTimeout(function() {
chunk.render(bodies.block, context).end();
}, Math.ceil(Math.random()*10));
});
}
},
expected: "3, 2, 1",
message: "should test async iterator"
name: "size helper does not support body",
source: 'you have {@size key=list}{body}{/size} new messages',
context: { list: [ 'msg1', 'msg2', 'msg3' ], "body" : "body block" },
expected: "you have 3 new messages",
message: "should test size helper not supporting body"
},
{
name: "size helper 3 items",
source: 'you have {@size key=list/} new messages',
context: { list: [ 'msg1', 'msg2', 'msg3' ] },
expected: "you have 3 new messages",
message: "should test if size helper is working properly with array"
},
{
name: "size helper string",
source: "'{mystring}' has {@size key=mystring/} letters",
context: { mystring: 'hello' },
expected: "'hello' has 5 letters",
message: "should test if size helper is working properly with strings"
},
{
name: "size helper string (empty)",
source: "'{mystring}' has {@size key=mystring/} letters",
context: { mystring: '' },
expected: "'' has 0 letters",
message: "should test if size helper is working properly with strings"
},
{
name: "size helper for newline",
source: "{@size key=mystring/} letters",
context: { mystring: '\n' },
expected: "1 letters",
message: "should test if size is working for newline"
},
{
name: "size helper string with newline",
source: "{@size key=mystring/} letters",
context: { mystring: 'test\n' },
expected: "5 letters",
message: "should test if size for string with newline"
},
{
name: "size helper string with newline, tab, carriage return and bakspace",
source: "{@size key=mystring/} letters",
context: { mystring: 'test\n\t\r\b' },
expected: "8 letters",
message: "should test if size helper is working for string with newline, tab, carriage return and bakspace"
},
{
name: "size helper number",
source: 'you have {@size key=mynumber/} new messages',
context: { mynumber: 0 },
expected: "you have 0 new messages",
message: "should test if size helper is working properly with numeric 0"
},
{
name: "size helper number",
source: 'you have {@size key=mynumber/} new messages',
context: { mynumber: 10 },
expected: "you have 10 new messages",
message: "should test if size helper is working properly with numeric 10"
},
{
name: "size helper floating numeric",
source: 'you have {@size key=mynumber/} new messages',
context: { mynumber: 0.4 },
expected: "you have 0.4 new messages",
message: "should test if size helper is working properly with floating numeric"
},
{
name: "size helper with boolean false",
source: 'you have {@size key=myboolean/} new messages',
context: { myboolean: false },
expected: "you have 0 new messages",
message: "should test if size helper is working properly with boolean false"
},
{
name: "size helper with boolean true",
source: 'you have {@size key=myboolean/} new messages',
context: { myboolean: true },
expected: "you have 0 new messages",
message: "should test if size helper is working properly with boolean true"
},
{
name: "size helper with object",
source: 'you have {@size key=myValue/} new messages',
context: { myValue: { foo:'bar', baz:'bax' } },
expected: "you have 2 new messages",
message: "should test if size helper is working properly when the value is an object "
},
{
name: "size helper with object",
source: 'you have {@size key=myValue/} new messages',
context: { myValue: {} },
expected: "you have 0 new messages",
message: "should test if size helper is working properly when the value is an object that is zero"
},
{
name: "size helper value not set",
source: 'you have {@size key=myNumber/} new messages',
context: {},
expected: "you have 0 new messages",
message: "should test if size helper is working properly when the value is not present in context"
},
{
name: "tap helper: Plain text string literal",
source: 'plain text. {@tapper value="plain text"/}',
context: {},
expected: "plain text. plain text",
message: "should test if tap helper is working properly when the value is plain text"
},
{
name: "tap helper: string literal that includes a string-valued {context variable}",
source: 'a is {a}. {@tapper value="a is {a}"/}',
context: { a : "Alpha" },
expected: "a is Alpha. a is Alpha",
message: "should test if tap helper is working properly when the value is a text that inclues a string-valued {context variable}"
},
{
name: "tap helper: reference to string-valued context variable",
source: '{a}. {@tapper value=a/}',
context: { a : "Alpha" },
expected: "Alpha. Alpha",
message: "should test if tap helper is working properly when it makes referece to string-valued context variable"
},
{
name: "tap helper: string literal that includes a string-valued {context function}",
source: 'b is {b}. {@tapper value="b is {b}"/}',
context: { "b" : function() { return "beta"; } },
expected: "b is beta. b is beta",
message: "should test if tap helper is working properly when the value is a string literal that includes a string-valued {context function}"
},
{
name: "tap helper: reference to a a string-valued {context function}",
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}"
},
{
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}"
},
{
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}"
},
{
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}"
},
{
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}"
},
{
name: "contextDump simple test does not support body",
source: "{@contextDump}{body}{/contextDump}",
context: { "A" : 2, "B": 3},
expected: "{\n \"A\": 2,\n \"B\": 3\n}",
message: "contextDump simple test does not support body"
},
{
name: "contextDump simple test",
source: "{@contextDump/}",
context: { "A": 2, "B": 3},
expected: "{\n \"A\": 2,\n \"B\": 3\n}",
message: "contextDump simple test"
},
{
name: "contextDump simple test dump to console",
source: "{@contextDump to=\"console\"/}",
context: { "A": 2, "B": 3},
expected: "",
message: "contextDump simple test"
},
{
name: "contextDump full test",
source: "{@contextDump key=\"full\"/}",
context: { aa: { "A": 2, "B": 3} },
expected: "{\n \"isObject\": true,\n \"head\": {\n \"aa\": {\n \"A\": 2,\n \"B\": 3\n }\n }\n}",
message: "contextDump full test"
},
{
name: "contextDump function dump test",
source: "{#aa param=\"{p}\"}{@contextDump key=\"full\"/}{/aa}",
context: { "aa": ["a"], "p" : 42},
expected: "{\n \"tail\": {\n \"tail\": {\n \"isObject\": true,\n \"head\": {\n \"aa\": [\n \"a\"\n ],\n \"p\": 42\n }\n },\n \"isObject\": true,\n \"head\": {\n \"param\": \"function body_2(chk,ctx){return chk.reference(ctx.get(\\\"p\\\"),ctx,\\\"h\\\");}\",\n \"$len\": 1,\n \"$idx\": 0\n }\n },\n \"isObject\": false,\n \"head\": \"a\",\n \"index\": 0,\n \"of\": 1\n}",
message: "contextDump function dump test"
},
{
name: "idx helper within partial included in a array",
source: '{#n}{@idx}{.}>>{/idx}{>hello_there name=. count="30"/}{/n}',
context: { n: ["Mick", "Tom", "Bob"] },
expected: "0>>Hello Mick! You have 30 new messages.1>>Hello Tom! You have 30 new messages.2>>Hello Bob! You have 30 new messages.",
message: "should test idx helper within partial included in a array"
},
{
name: "sep helper within partial included in a array",
source: '{#n}{>hello_there name=. count="30"/}{@sep} {/sep}{/n}',
context: { n: ["Mick", "Tom", "Bob"] },
expected: "Hello Mick! You have 30 new messages. Hello Tom! You have 30 new messages. Hello Bob! You have 30 new messages.",
message: "should test sep helper within partial included in a array"
},
{
name: "sep helper in a async_iterator",
source: "{#numbers}{#delay}{.}{/delay}{@sep}, {/sep}{/numbers}",
context: {
numbers: [3, 2, 1],
delay: function(chunk, context, bodies) {
return chunk.map(function(chunk) {
setTimeout(function() {
chunk.render(bodies.block, context).end();
}, Math.ceil(Math.random()*10));
});
}
},
expected: "3, 2, 1",
message: "should sep helper in a async_iterator"
},
];

@@ -302,2 +1117,2 @@

window.helpersTests = helpersTests; // We're on the browser
}
}

6

test/README.md

@@ -17,6 +17,8 @@ Dust helpers unit-tests

----------------------------------
* install nodejs 0.6 or greater
* install nodejs 0.6 or greater
* install npm
* install jasmine test framework : npm install -g jasmine-node
* install testing dependencies by running in the package directory:
npm install
In order to run the node.js version of dust, run this command in the terminal

@@ -23,0 +25,0 @@

@@ -1,7 +0,12 @@

var uutest = require('../../test/uutest'),
dust = require('dustjs-linkedin'),
var uutest = require('./uutest'),
dust = require('../lib/dust-helpers'),
tests = require('./jasmine-test/spec/helpersTests'),
coreSetup = require('../../test/core').coreSetup;
coreSetup = require('./core').coreSetup;
dust.helpers = require('../lib/dust-helpers').helpers;
//Add the tapper helper to test the Tap helper.
dust.helpers.tapper = function(chunk, context, bodies, params) {
var result = dust.helpers.tap(params.value,chunk,context);
chunk.write(result);
return chunk;
};

@@ -8,0 +13,0 @@ function dumpError(err) {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc