decojs
Version:
Scalable frontend architecture
171 lines (126 loc) • 4.83 kB
JavaScript
describe("when applying nested viewmodels", [
"deco/spa/applyViewModels",
"Given/an_element",
"knockout"
], function(
applyViewModels,
an_element,
ko
){
var dummyVM,
nestedVM,
subscribe,
model = {a: true},
nestedPromise,
parentContext,
subWhenContext,
originalRequire,
DummyVM;
beforeEach(function(){
originalRequire = require;
require = sinon.stub();
subWhenContext = sinon.spy();
parentContext = sinon.stub().returns(subWhenContext);
parentContext.destroyChildContexts = sinon.spy();
subscribe = sinon.stub().returns(sinon.stub().returns(parentContext));
DummyVM = function DummyVM(){
dummyVM.apply(this, arguments);
this.value = "dummyText";
}
dummyVM = sinon.spy();
nestedVM = sinon.spy();
require.withArgs(['dummyVM']).callsArgWith(1, DummyVM);
});
afterEach(function(){
require = originalRequire;
});
describe("before the nested view model has loaded", function(){
because(function(done){
require.withArgs(['nestedVM']).callsArgWith(1, function(){});
var elm = an_element.withNestedViewModel("dummyVM", "nestedVM");
applyViewModels(elm, subscribe).then(done);
});
it("should find only the top level viewmodels in the dom tree", function(){
expect(dummyVM).toHaveBeenCalled();
});
it("should not find the nested viewmodels", function(){
expect(nestedVM).not.toHaveBeenCalled();
});
it("should have called require twice", function(){
expect(require).toHaveBeenCalledThrice();
});
it("should have first requested dummyVM", function(){
expect(require.firstCall.args[0]).toEqual(['dummyVM']);
});
it("should have second requested nestedVM", function(){
expect(require.secondCall.args[0]).toEqual(['nestedVM']);
});
it("should have third requested nestedVM again", function(){
expect(require.thirdCall.args[0]).toEqual(['nestedVM']);
});
});
describe("and the nested viewmodel has been loaded with a model", function(){
var elm;
beforeEach(function(done){
function NestedVM(){
nestedVM.apply(this, arguments);
setTimeout(done,1);
}
require.withArgs(['nestedVM']).callsArgWith(1, NestedVM);
elm = an_element.withNestedViewModel("dummyVM", "nestedVM", model);
applyViewModels(elm, subscribe);
});
it("should now have found the nested viewmodels", function(){
expect(nestedVM).toHaveBeenCalled();
});
it("should call the nested viewmodel with the model as the first argument", function(){
expect(nestedVM.firstCall.args[0]).toEqual(model);
});
it("should call the nested viewmodel with the subWhenContext function as the second argument", function(){
expect(nestedVM.firstCall.args[1]).toEqual(subWhenContext);
});
it("should have access to the parent context", function(){
expect(elm.firstChild.firstChild.textContent).toBe("dummyText");
});
describe("when the nested element is destroyed", function(){
beforeEach(function(){
ko.cleanNode(elm.firstChild.firstChild);
});
it("should destroy the when context", function(){
expect(parentContext.destroyChildContexts).toHaveBeenCalledOnce();
});
});
});
describe("and the nested viewmodel has been loaded with params", function(){
var elm;
beforeEach(function(done){
function NestedVM(){
nestedVM.apply(this, arguments);
setTimeout(done, 1);
}
require.withArgs(['nestedVM']).callsArgWith(1, NestedVM);
elm = an_element.withNestedViewModelAndParams("dummyVM", "nestedVM", "something: value");
applyViewModels(elm, subscribe);
});
it("should now have found the nested viewmodels", function(){
expect(nestedVM).toHaveBeenCalled();
});
it("should call the nested viewmodel with the model as the first argument", function(){
expect(nestedVM.firstCall.args[0].something).toBe("dummyText");
});
it("should call the nested viewmodel with the subWhenContext function as the second argument", function(){
expect(nestedVM.firstCall.args[1]).toEqual(subWhenContext);
});
it("should have access to the parent context", function(){
expect(elm.firstChild.firstChild.textContent).toBe("dummyText");
});
describe("when the nested element is destroyed", function(){
beforeEach(function(){
ko.cleanNode(elm.firstChild.firstChild);
});
it("should destroy the when context", function(){
expect(parentContext.destroyChildContexts).toHaveBeenCalledOnce();
});
});
});
});