From f5b5390113524dc8043d9d8c703616c5d7c3f3ce Mon Sep 17 00:00:00 2001 From: Tomek Wytrebowicz Date: Thu, 30 Mar 2017 13:27:14 +0200 Subject: [PATCH] Fix attaching the model to new partial with same URL, Fix race condition between dom-bind and imported-template in tests https://github.com/Starcounter/starcounter-include/issues/25 https://github.com/Starcounter/RebelsLounge/issues/97 --- starcounter-include.html | 2 ++ test/partialAttribute/given_in_HTML.html | 22 ++++++++++++ test/partialAttribute/given_in_JS.html | 26 +++++++++++++- .../nested-html/given_in_HTML.html | 16 +++++++++ .../nested-html/given_in_JS.html | 19 +++++++++++ .../stamped_from_polymer_template.html | 34 ++++++++++++++++++- .../stamped_from_polymer_template.html | 23 +++++++++++++ 7 files changed, 140 insertions(+), 2 deletions(-) diff --git a/starcounter-include.html b/starcounter-include.html index f9da930..540bf6c 100644 --- a/starcounter-include.html +++ b/starcounter-include.html @@ -170,6 +170,8 @@ } this._forceLayoutChange = true; this._lastHtml = html; + } else if (this.template.model != this.partial) { + this.template.model = this.partial } }; LauncherPartialPrototype._compositionChanged = function(composition) { diff --git a/test/partialAttribute/given_in_HTML.html b/test/partialAttribute/given_in_HTML.html index 2e391d1..8ce2af4 100644 --- a/test/partialAttribute/given_in_HTML.html +++ b/test/partialAttribute/given_in_HTML.html @@ -108,6 +108,28 @@ testAllAttributes(); }); + describe('changed after element was attached and stamped to the new object, with the same Html, model should be attached immediately', function (done) { + beforeEach(function(done){ + scInclude = fixture('full'); + importedTemplate = scInclude.querySelector_template_for_buggy_polyfill(); + + importedTemplate.addEventListener('stamping', function afterAttached(){ + importedTemplate.removeEventListener('stamping', afterAttached); + setTimeout(function(){ + let oldModel = scInclude.partial; + scInclude.setAttribute('partial', JSON.stringify(oldModel)); + done(); + }); + }); + }); + it('should attach `.Html` property as content attribute for `imported-template`', function () { + expect(importedTemplate.getAttribute("content")).to.equal(scInclude.partial.Html); + }); + it('should attach partial model to `imported-template` immediately', function () { + expect(importedTemplate.model).to.equal(scInclude.partial); + }); + }); + describe('set after element was detached', function(){ beforeEach(function(){ scInclude = fixture('nothing'); diff --git a/test/partialAttribute/given_in_JS.html b/test/partialAttribute/given_in_JS.html index 1ba2bfa..ce8277a 100644 --- a/test/partialAttribute/given_in_JS.html +++ b/test/partialAttribute/given_in_JS.html @@ -106,6 +106,30 @@ testAllAttributes(); }); + describe('changed after element was attached and stamped to the new object, with the same Html, model should be attached immediately', function (done) { + beforeEach(function(done){ + scInclude = fixture('full'); + importedTemplate = scInclude.querySelector_template_for_buggy_polyfill(); + + importedTemplate.addEventListener('stamping', function afterAttached(){ + importedTemplate.removeEventListener('stamping', afterAttached); + setTimeout(function(){ + let oldModel = scInclude.partial; + let newModel = clone(oldModel); + newModel.doesItWork = 'still works!'; + scInclude.partial = newModel; + done(); + }); + }); + }); + it('should attach `.Html` property as content attribute for `imported-template`', function () { + expect(importedTemplate.getAttribute("content")).to.equal(scInclude.partial.Html); + }); + it('should attach partial model to `imported-template` immediately', function () { + expect(importedTemplate.model).to.equal(scInclude.partial); + }); + }); + describe('set after element was detached', function(){ beforeEach(function(){ scInclude = fixture('nothing'); @@ -115,7 +139,7 @@ }); testAllAttributes(); }); - describe('chnaged after element was detached', function(){ + describe('changed after element was detached', function(){ beforeEach(function(done){ scInclude = fixture('old'); previousModel = scInclude.partial; diff --git a/test/partialAttribute/nested-html/given_in_HTML.html b/test/partialAttribute/nested-html/given_in_HTML.html index bef04bb..4f30afa 100644 --- a/test/partialAttribute/nested-html/given_in_HTML.html +++ b/test/partialAttribute/nested-html/given_in_HTML.html @@ -172,6 +172,22 @@ }); }); + it('if value was changed after element was attached and stamped to the new object, with the same Html, model should be attached immediately', function (done) { + scInclude = fixture('nested-html'); + let importedTemplate = scInclude.querySelector_template_for_buggy_polyfill(); + + importedTemplate.addEventListener('stamping', function afterAttached(){ + importedTemplate.removeEventListener('stamping', afterAttached); + setTimeout(function(){ + let oldModel = scInclude.partial; + scInclude.setAttribute('partial', JSON.stringify(oldModel)); + + expect(importedTemplate.getAttribute("content")).to.equal('/sc/htmlmerger?scope1=scope1Html&scope2=scope2Html%3B%2C%2F%3F%3A%40%26%3D%2B%24&scope3='); + expect(importedTemplate.model).to.equal(scInclude.partial); + done(); + }); + }); + }); it('if value was set after element was detached (model not yet attached)', function () { scInclude = fixture('nothing'); diff --git a/test/partialAttribute/nested-html/given_in_JS.html b/test/partialAttribute/nested-html/given_in_JS.html index 44f5e9e..791e889 100644 --- a/test/partialAttribute/nested-html/given_in_JS.html +++ b/test/partialAttribute/nested-html/given_in_JS.html @@ -139,6 +139,25 @@ }); }); + it('if value was changed after element was attached and stamped to the new object, with the same Html, model should be attached immediately', function (done) { + scInclude = fixture('nested-html'); + let importedTemplate = scInclude.querySelector_template_for_buggy_polyfill(); + + importedTemplate.addEventListener('stamping', function afterAttached(){ + importedTemplate.removeEventListener('stamping', afterAttached); + setTimeout(function(){ + let oldModel = scInclude.partial; + let newModel = clone(oldModel); + newModel.scope1.doesItWork = 'still works!'; + scInclude.partial = newModel; + + expect(importedTemplate.getAttribute("content")).to.equal('/sc/htmlmerger?scope1=scope1Html&scope2=scope2Html&scope3='); + expect(importedTemplate.model).to.equal(scInclude.partial); + done(); + }); + }); + }); + it('if value was set after element was detached (model not yet attached)', function () { scInclude = fixture('nothing'); scInclude.parentElement.removeChild(scInclude); diff --git a/test/partialAttribute/nested-html/stamped_from_polymer_template.html b/test/partialAttribute/nested-html/stamped_from_polymer_template.html index fa06f8e..5e28c34 100644 --- a/test/partialAttribute/nested-html/stamped_from_polymer_template.html +++ b/test/partialAttribute/nested-html/stamped_from_polymer_template.html @@ -107,7 +107,7 @@ }); }); - xit('should attach new `.Html` property as content attribute for ``', function () { + it('should attach new `.Html` property as content attribute for ``', function () { expect(importedTemplate.getAttribute("content")).to.equal('/sc/htmlmerger?scopeA=scopeAHtml&scopeB=scopeBHtml'); }); it('should NOT attach new partial model to `imported-template` immediately', function () { @@ -121,6 +121,38 @@ }); }); + describe('after `dom-bind`` changed the partial property to new one with the same Html', function () { + var changedPartialWithSameHtml; + beforeEach(function(done) { + // IDEA: promisify juicy-html + importedTemplate.addEventListener('stamping', function onceStamped(){ + importedTemplate.removeEventListener('stamping', onceStamped); + changedPartialWithSameHtml = { + 'scope1': { + 'Html': 'scope1Html', + 'doesItWork': 'still works!' + }, + 'scope2': { + 'Html': 'scope2Html;,/?:@&=+$', + 'doesItWork': 'still works!' + }, + 'scope3': { + 'doesItWork': 'still works!' + } + }; + domBind.set('model.Page', changedPartialWithSameHtml); + done(); + }); + }); + + it('should attach new `.Html` property as content attribute for ``', function () { + expect(importedTemplate.getAttribute("content")).to.equal('/sc/htmlmerger?scope1=scope1Html&scope2=scope2Html%3B%2C%2F%3F%3A%40%26%3D%2B%24&scope3='); + }); + it('should attach new partial model to `imported-template` immediately', function () { + expect(importedTemplate.model).to.equal(changedPartialWithSameHtml); + }); + }); + describe('after `dom-bind`` changed the inner `Html` property', function () { beforeEach(function() { domBind.set('model.Page.scope1.Html', 'changedHtml'); diff --git a/test/partialAttribute/stamped_from_polymer_template.html b/test/partialAttribute/stamped_from_polymer_template.html index 76906ee..f6894a9 100644 --- a/test/partialAttribute/stamped_from_polymer_template.html +++ b/test/partialAttribute/stamped_from_polymer_template.html @@ -102,6 +102,29 @@ }); }); + describe('after `dom-bind`` changed the partial property to new one with the same Html', function () { + var changedPartialWithSameHtml; + beforeEach(function(done) { + // IDEA: promisify juicy-html + importedTemplate.addEventListener('stamping', function onceStamped(){ + importedTemplate.removeEventListener('stamping', onceStamped); + changedPartialWithSameHtml = { + Html: "../old_templateToInclude.html", + doesItWork: "works!" + }; + domBind.set('model.Page', changedPartialWithSameHtml); + done(); + }); + }); + + it('should attach new `.Html` property as content attribute for ``', function () { + expect(importedTemplate.getAttribute("content")).to.equal('../old_templateToInclude.html'); + }); + it('should attach new partial model to `imported-template` immediately', function () { + expect(importedTemplate.model).to.equal(changedPartialWithSameHtml); + }); + }); + describe('after `dom-bind`` changed the partial.Html property', function() { beforeEach(function(done) { importedTemplate.addEventListener('stamping', function onceStamped(){