Skip to content

Commit

Permalink
docEngine->callHierarchy: Remove redundant tree-branches
Browse files Browse the repository at this point in the history
- `{{>p1}} {{>p1}}` will now only create one tree-node
- Better cycle detection for this kind of template (e.g.
  templates that call themselves twice
  • Loading branch information
nknapp committed Jun 20, 2017
1 parent 2763196 commit 1ea2db7
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 5 deletions.
19 changes: 14 additions & 5 deletions lib/partial-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ function hierarchy (config) {
type: 'template',
path: template.path,
comments: template.comments,
children: template.callsPartial.map((callee) => partialForCallTree(callee.name, partials))
children: template.callsPartial
.map((callee) => callee.name)
// Remove redundant names (only take the first one)
.filter((name, index, array) => array.indexOf(name) === index)
.map((name) => partialForCallTree(name, partials, {}))
}
})
}
Expand All @@ -64,17 +68,20 @@ function hierarchy (config) {
* @returns {{name: *, type: string, comment}}
*/
function partialForCallTree (name, partials, visitedNodes) {
visitedNodes = visitedNodes || {}
const cycleFound = visitedNodes[name]
try {
const cycleFound = visitedNodes[name]
visitedNodes[name] = true
const partial = partials[name]
if (!partial) {
throw new Error(`Missing partial "${name}"`)
}
let children
if (!cycleFound) {
children = partial.callsPartial.map((callee) => partialForCallTree(callee.name, partials, visitedNodes))
children = partial.callsPartial
.map((callee) => callee.name)
// Remove redundant names (only take the first one)
.filter((name, index, array) => array.indexOf(name) === index)
.map((name) => partialForCallTree(name, partials, visitedNodes))
}
return {
name,
Expand All @@ -85,7 +92,9 @@ function partialForCallTree (name, partials, visitedNodes) {
cycleFound
}
} finally {
delete visitedNodes[name]
if (!cycleFound) {
delete visitedNodes[name]
}
}
}

Expand Down
107 changes: 107 additions & 0 deletions test/partial-details-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,114 @@ describe('partial-details:', function () {
'children': undefined
}]
}]
}]
}
]
})
})

it('should break cycles when a partial is called twice in the cycle', function () {
expect(hierarchy({
templates: {
'dir/a.txt': {
path: 'src/dir/a.txt.hbs',
contents: 'a {{>p1}} a'
}
},
partials: {
'p1': {
path: 'src/prt/p1.hbs',
contents: 'p1 {{>p1}} {{>p1}} p1'
}
}
})).to.deep.equal({
children: [
{
'name': 'dir/a.txt',
'path': 'src/dir/a.txt.hbs',
'type': 'template',
'comments': [],
'children': [{
'name': 'p1',
'path': 'src/prt/p1.hbs',
'type': 'partial',
'comments': [],
'cycleFound': undefined,
'children': [{
'name': 'p1',
'path': 'src/prt/p1.hbs',
'type': 'partial',
'comments': [],
'cycleFound': true,
'children': undefined
}]
}]
}
]
})
})

it('should allow calling the same partial twice', function () {
expect(hierarchy({
templates: {
'dir/a.txt': {
path: 'src/dir/a.txt.hbs',
contents: 'a {{>p1}} {{>p1}} a'
}
},
partials: {
'p1': {
path: 'src/prt/p1.hbs',
contents: 'p1'
}
}
})).to.deep.equal({
children: [
{
'name': 'dir/a.txt',
'path': 'src/dir/a.txt.hbs',
'type': 'template',
'comments': [],
'children': [{
'name': 'p1',
'path': 'src/prt/p1.hbs',
'type': 'partial',
'comments': [],
'cycleFound': undefined,
'children': []
}]
}
]
})
})
it('should allow calling the same partial twice', function () {
expect(hierarchy({
templates: {
'dir/a.txt': {
path: 'src/dir/a.txt.hbs',
contents: 'a {{>p1}} {{>p1}} a'
}
},
partials: {
'p1': {
path: 'src/prt/p1.hbs',
contents: 'p1'
}
}
})).to.deep.equal({
children: [
{
'name': 'dir/a.txt',
'path': 'src/dir/a.txt.hbs',
'type': 'template',
'comments': [],
'children': [{
'name': 'p1',
'path': 'src/prt/p1.hbs',
'type': 'partial',
'comments': [],
'cycleFound': undefined,
'children': []
}]
}
]
Expand Down

0 comments on commit 1ea2db7

Please sign in to comment.