Skip to content

Commit

Permalink
fix: issue with loop variable access inside nested foreach statements
Browse files Browse the repository at this point in the history
close #135
  • Loading branch information
shepherdwind committed Dec 2, 2020
1 parent f32057a commit 58d9066
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
17 changes: 17 additions & 0 deletions .vscode/launch.json
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Mocha Current File",
"program": "${workspaceRoot}/node_modules/.bin/_mocha",
"args": ["${file}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
19 changes: 9 additions & 10 deletions src/compile/set.js
Expand Up @@ -6,29 +6,28 @@ module.exports = function(Velocity, utils) {
/**
* get variable from context, if run in block, return local context, else return global context
*/
getContext: function() {
var condition = this.condition;
getContext: function(idName) {
var local = this.local;
if (condition) {
return local[condition];
} else {
return this.context;
// context find, from the conditions stack top to end
for (var condition of this.conditions) {
if (local[condition].hasOwnProperty(idName)) {
return local[condition];
}
}
// not find local variable, return global context
return this.context;
},
/**
* parse #set
*/
setValue: function(ast) {
var ref = ast.equal[0];
var context = this.getContext();
var context = this.getContext(ref.id);

// @see #25
if (this.condition && this.condition.indexOf('macro:') === 0) {
context = this.context;
// fix #129
} else if (!context.hasOwnProperty(ref.id)) {
// set var to global context, see #100
context = this.context;
}

var valAst = ast.equal[1];
Expand Down
38 changes: 38 additions & 0 deletions test/set.test.js
Expand Up @@ -216,4 +216,42 @@ describe('Set && Expression', function() {
const html = render(tpl).replace(/\n\s.|\s{2}/g, '').trim();
html.should.eql('<h1>test1 test3</h1><h1>test1 test2 test3</h1><h1>test1 test3</h1><h1>test1 test2 test3</h1>');
})

it('nested foreach subprop', function() {
var tpl = `
#set($list = [{"prop": "a"}])
#set($list2 = ["a", "b", "c"])
#foreach($i in $list)
#set($fc = $velocityCount - 1)
#foreach($j in $list2)
#set($i.prop = "$i.prop$j")
#end
#end
$list
`
var ret = render(tpl).trim()
assert.strictEqual('[{prop=aabc}]', ret);
})

it('nested foreach set', function() {
var tpl = `
#set($obj = [{
"SubProp": [
{ "SubSubProp": "a" }
]
}])
#set($subSubPropRealValue = "b")
#foreach($sub in $obj)
#set($fc = $velocityCount - 1)
#foreach($subsub in $sub.SubProp)
#set($fcc = $velocityCount - 1)
#set($sub.SubProp[$fcc].SubSubProp = $subSubPropRealValue)
#end
#set($obj[$fc] = $sub)
#end
$obj
`
var ret = render(tpl).trim()
assert.strictEqual('[{SubProp=[{SubSubProp=b}]}]', ret);
});
})

0 comments on commit 58d9066

Please sign in to comment.