Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make $idx/$len work for all array objects and not leave old values in contexts #113

Merged
merged 6 commits into from
Aug 21, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions dist/dust-core-1.0.0.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ Context.prototype.getPath = function(cur, down) {
};

Context.prototype.push = function(head, idx, len) {
if( head ){
// loop index for a block section
head['$idx'] = idx;
// loop size for a block section
head['$len'] = len;
}
return new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
};

Expand Down Expand Up @@ -373,7 +367,8 @@ Chunk.prototype.render = function(body, context) {
Chunk.prototype.reference = function(elem, context, auto, filters) {
if (typeof elem === "function") {
elem.isReference = true;
elem = elem(this, context, null, {auto: auto, filters: filters});
// Changed the function calling to use apply with the current context to make sure that "this" is wat we expect it to be inside the function
elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -387,7 +382,7 @@ Chunk.prototype.reference = function(elem, context, auto, filters) {

Chunk.prototype.section = function(elem, context, bodies, params) {
if (typeof elem === "function") {
elem = elem(this, context, bodies, params);
elem = elem.apply(context.current(), [this, context, bodies, params]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -403,15 +398,26 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
if (dust.isArray(elem)) {
if (body) {
var len = elem.length, chunk = this;
context.stack.head['$len'] = len;
for (var i=0; i<len; i++) {
context.stack.head['$idx'] = i;
chunk = body(chunk, context.push(elem[i], i, len));
}
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (elem === true) {
if (body) return body(this, context);
} else if (elem || elem === 0) {
if (body) return body(this, context.push(elem));
if (body) {
context.stack.head['$idx'] = 0;
context.stack.head['$len'] = 1;
chunk = body(this, context.push(elem));
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (skip) {
return skip(this, context);
}
Expand Down
24 changes: 15 additions & 9 deletions dist/dust-full-1.0.0.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,6 @@ Context.prototype.getPath = function(cur, down) {
};

Context.prototype.push = function(head, idx, len) {
if( head ){
// loop index for a block section
head['$idx'] = idx;
// loop size for a block section
head['$len'] = len;
}
return new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
};

Expand Down Expand Up @@ -373,7 +367,8 @@ Chunk.prototype.render = function(body, context) {
Chunk.prototype.reference = function(elem, context, auto, filters) {
if (typeof elem === "function") {
elem.isReference = true;
elem = elem(this, context, null, {auto: auto, filters: filters});
// Changed the function calling to use apply with the current context to make sure that "this" is wat we expect it to be inside the function
elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -387,7 +382,7 @@ Chunk.prototype.reference = function(elem, context, auto, filters) {

Chunk.prototype.section = function(elem, context, bodies, params) {
if (typeof elem === "function") {
elem = elem(this, context, bodies, params);
elem = elem.apply(context.current(), [this, context, bodies, params]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -403,15 +398,26 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
if (dust.isArray(elem)) {
if (body) {
var len = elem.length, chunk = this;
context.stack.head['$len'] = len;
for (var i=0; i<len; i++) {
context.stack.head['$idx'] = i;
chunk = body(chunk, context.push(elem[i], i, len));
}
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (elem === true) {
if (body) return body(this, context);
} else if (elem || elem === 0) {
if (body) return body(this, context.push(elem));
if (body) {
context.stack.head['$idx'] = 0;
context.stack.head['$len'] = 1;
chunk = body(this, context.push(elem));
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (skip) {
return skip(this, context);
}
Expand Down
4 changes: 2 additions & 2 deletions dustjs-helpers/test/jasmine-test/server/specRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var jasmine = require('jasmine-node'),

/* this should be declared global in order to access them in the spec*/
dust = require('dustjs-linkedin'),
dust.helpers = require("../../../lib/dust-helpers").helpers,
dust.helpers = require('../../../lib/dust-helpers').helpers,
helpersTests = require('../spec/helpersTests');

//Add the tapper helper to test the Tap helper.
Expand Down Expand Up @@ -41,4 +41,4 @@ jasmine.executeSpecsInFolder(path.dirname(__dirname) + '/spec', (function(runner
} else {
return process.exit(1);
}
}), isVerbose, showColors);
}), isVerbose, showColors);
58 changes: 57 additions & 1 deletion dustjs-helpers/test/jasmine-test/spec/helpersTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,67 @@ var helpersTests = [
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: "array: reference $idx in iteration on objects",
source: "{#names}({$idx}).{title} {name}{~n}{/names}",
context: { title: "Sir", names: [ { name: "Moe" }, { name: "Larry" }, { name: "Curly" } ] },
expected: "(0).Sir Moe\n(1).Sir Larry\n(2).Sir Curly\n",
message: "array: reference $idx in iteration on objects"
},
{
name: "array: reference $len in iteration on objects",
source: "{#names}Size=({$len}).{title} {name}{~n}{/names}",
context: { title: "Sir", names: [ { name: "Moe" }, { name: "Larry" }, { name: "Curly" } ] },
expected: "Size=(3).Sir Moe\nSize=(3).Sir Larry\nSize=(3).Sir Curly\n",
message: "test array: reference $len in iteration on objects"
},
{
name: "array reference $idx in iteration on simple type",
source: "{#names}({$idx}).{title} {.}{~n}{/names}",
context: { title: "Sir", names: [ "Moe", "Larry", "Curly" ] },
expected: "(0).Sir Moe\n(1).Sir Larry\n(2).Sir Curly\n",
message: "test array reference $idx in iteration on simple types"
},
{
name: "array reference $len in iteration on simple type",
source: "{#names}Size=({$len}).{title} {.}{~n}{/names}",
context: { title: "Sir", names: [ "Moe", "Larry", "Curly" ] },
expected: "Size=(3).Sir Moe\nSize=(3).Sir Larry\nSize=(3).Sir Curly\n",
message: "test array reference $len in iteration on simple types"
},
{
name: "array reference $idx/$len on empty array case",
source: "{#names}Idx={$idx} Size=({$len}).{title} {.}{~n}{/names}",
context: { title: "Sir", names: [ ] },
expected: "",
message: "test array reference $idx/$len on empty array case"
},
{
name: "array reference $idx/$len on single element case",
source: "{#names}Idx={$idx} Size={$len} {.}{/names}",
context: { names: "Just one name" },
expected: "Idx=0 Size=1 Just one name",
message: "test array reference $idx/$len on single element case"
},
{
name: "array reference $idx/$len {#.} section case",
source: "{#names}{#.}{$idx}{.} {/.}{/names}",
context: { names: ["Moe", "Larry", "Curly"] },
expected: "0Moe 1Larry 2Curly ",
message: "test array reference $idx/$len {#.} section case"
},
{
name: "array reference $idx/$len nested loops",
source: "{#A}A loop:{$idx}-{$len},{#B}B loop:{$idx}-{$len}C[0]={.C[0]} {/B}A loop trailing: {$idx}-{$len}{/A}",
context: {"A": [ {"B": [ {"C": ["Ca1", "C2"]}, {"C": ["Ca2", "Ca22"]} ] }, {"B": [ {"C": ["Cb1", "C2"]}, {"C": ["Cb2", "Ca2"]} ] } ] },
expected: "A loop:0-2,B loop:0-2C[0]=Ca1 B loop:1-2C[0]=Ca2 A loop trailing: 0-2A loop:1-2,B loop:0-2C[0]=Cb1 B loop:1-2C[0]=Cb2 A loop trailing: 1-2",
message: "test array reference $idx/$len nested loops"
}
];

if (typeof module !== "undefined" && typeof require !== "undefined") {
module.exports = helpersTests; // We're on node.js
} else {
window.helpersTests = helpersTests; // We're on the browser
}
}
24 changes: 15 additions & 9 deletions lib/dust.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ Context.prototype.getPath = function(cur, down) {
};

Context.prototype.push = function(head, idx, len) {
if( head ){
// loop index for a block section
head['$idx'] = idx;
// loop size for a block section
head['$len'] = len;
}
return new Context(new Stack(head, this.stack, idx, len), this.global, this.blocks);
};

Expand Down Expand Up @@ -365,7 +359,8 @@ Chunk.prototype.render = function(body, context) {
Chunk.prototype.reference = function(elem, context, auto, filters) {
if (typeof elem === "function") {
elem.isReference = true;
elem = elem(this, context, null, {auto: auto, filters: filters});
// Changed the function calling to use apply with the current context to make sure that "this" is wat we expect it to be inside the function
elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -379,7 +374,7 @@ Chunk.prototype.reference = function(elem, context, auto, filters) {

Chunk.prototype.section = function(elem, context, bodies, params) {
if (typeof elem === "function") {
elem = elem(this, context, bodies, params);
elem = elem.apply(context.current(), [this, context, bodies, params]);
if (elem instanceof Chunk) {
return elem;
}
Expand All @@ -395,15 +390,26 @@ Chunk.prototype.section = function(elem, context, bodies, params) {
if (dust.isArray(elem)) {
if (body) {
var len = elem.length, chunk = this;
context.stack.head['$len'] = len;
for (var i=0; i<len; i++) {
context.stack.head['$idx'] = i;
chunk = body(chunk, context.push(elem[i], i, len));
}
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (elem === true) {
if (body) return body(this, context);
} else if (elem || elem === 0) {
if (body) return body(this, context.push(elem));
if (body) {
context.stack.head['$idx'] = 0;
context.stack.head['$len'] = 1;
chunk = body(this, context.push(elem));
context.stack.head['$idx'] = undefined;
context.stack.head['$len'] = undefined;
return chunk;
}
} else if (skip) {
return skip(this, context);
}
Expand Down
14 changes: 0 additions & 14 deletions test/jasmine-test/spec/grammarTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,6 @@ var grammarTests = [
expected: "Sir Moe\nSir Larry\nSir Curly\n",
message: "should test an array"
},
{
name: "array",
source: "{#names}({$idx}).{title} {name}{~n}{/names}",
context: { title: "Sir", names: [ { name: "Moe" }, { name: "Larry" }, { name: "Curly" } ] },
expected: "(0).Sir Moe\n(1).Sir Larry\n(2).Sir Curly\n",
message: "should test an array"
},
{
name: "array",
source: "{#names}Size=({$len}).{title} {name}{~n}{/names}",
context: { title: "Sir", names: [ { name: "Moe" }, { name: "Larry" }, { name: "Curly" } ] },
expected: "Size=(3).Sir Moe\nSize=(3).Sir Larry\nSize=(3).Sir Curly\n",
message: "should test an array"
},
{
name: "empty_array",
source: "{#names}{title} {name}{~n}{/names}",
Expand Down