Skip to content

Commit

Permalink
Merge pull request #595 from derbyjs/test-util-render-reset
Browse files Browse the repository at this point in the history
test-utils `.to.render` assertion - Reset page/component state between each render pass
  • Loading branch information
ericyhwang authored May 25, 2021
2 parents 4d3327b + cb1c4b8 commit 442568f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
22 changes: 20 additions & 2 deletions test-utils/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ module.exports = function(dom, Assertion) {
return el.innerHTML;
}

// Executes the parts of `Page#destroy` pertaining to the model, which get
// re-done when a new Page gets created on the same model. Normally, using
// `Page#destroy` would be fine, but the `.to.render` assertion wants to do
// 3 rendering passes on the same data, so we can't completely clear the
// model's state between the rendering passes.
function resetPageModel(page) {
page._removeModelListeners();
for (var componentId in page._components) {
var component = page._components[componentId];
component.destroy();
}
page.model.silent().destroy('$components');
}

if (Assertion) {
Assertion.addMethod('html', function(expected, options) {
var obj = this._obj;
Expand Down Expand Up @@ -76,7 +90,8 @@ module.exports = function(dom, Assertion) {
new Assertion(harness).instanceOf(ComponentHarness);

// Render to a HTML string.
var htmlString = harness.renderHtml(options).html;
var renderResult = harness.renderHtml(options);
var htmlString = renderResult.html;

// Normalize `htmlString` into the same form as the DOM would give for `element.innerHTML`.
//
Expand Down Expand Up @@ -105,6 +120,8 @@ module.exports = function(dom, Assertion) {
}
}

resetPageModel(renderResult.page);

// Check DOM rendering is also equivalent.
// This uses the harness "pageRendered" event to grab the rendered DOM *before* any component
// `create()` methods are called, as `create()` methods can do DOM mutations.
Expand All @@ -121,7 +138,8 @@ module.exports = function(dom, Assertion) {
}
}
});
harness.renderDom(options);
renderResult = harness.renderDom(options);
resetPageModel(renderResult.page);

// Try attaching. Attachment will throw an error if HTML doesn't match
var el = domDocument.createElement(parentTag);
Expand Down
25 changes: 25 additions & 0 deletions test/dom/ComponentHarness.mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,31 @@ describe('ComponentHarness', function() {
expect(harness).to.render();
expect(harness).to.render('< ">');
});

it('cleans up component state between render passes', function() {
function Box() {}
Box.view = {
is: 'box',
source: '<index:><div class="box">{{greeting}}</div>'
};
Box.prototype.init = function() {
var initialName = this.model.scope('_page.initialName').get();
expect(initialName).to.equal('Spot');
this.model.set('name', initialName);
this.model.start('greeting', ['name'], function(name) {
// This assertion ensures that the reactive function isn't called after
// the component gets destroyed.
expect(name).to.equal('Spot');
return 'Hello, ' + name;
});
};
var harness = runner.createHarness('<view is="box" />', Box);
// Have the test depend on state in `_page` to make sure it's not cleared
// between rendering passes in `.to.render`.
harness.model.set('_page.initialName', 'Spot');

expect(harness).to.render('<div class="box">Hello, Spot</div>');
});
});

describe('fake app.history implementation', function() {
Expand Down

0 comments on commit 442568f

Please sign in to comment.