mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
374 lines
13 KiB
HTML
374 lines
13 KiB
HTML
<!doctype html>
|
|
<!--
|
|
@license
|
|
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
|
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
|
Code distributed by Google as part of the polymer project is also
|
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
|
-->
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<script src="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
|
|
<script src="wct-browser-config.js"></script>
|
|
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
|
|
<script type="module" src="../../polymer-legacy.js"></script>
|
|
<script type="module" src="./templatize-elements.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<template id="standalone"><div prop="[[prop]]">[[text]]</div></template>
|
|
|
|
<script type="module">
|
|
import './templatize-elements.js';
|
|
import { templatize } from '../../lib/utils/templatize.js';
|
|
|
|
suite('templatize basic', function() {
|
|
|
|
let host;
|
|
let childA;
|
|
|
|
setup(function() {
|
|
host = document.createElement('x-host');
|
|
document.body.appendChild(host);
|
|
host.$.templatizeA.go(true);
|
|
childA = host.shadowRoot.querySelector('#childA');
|
|
assert.ok(childA);
|
|
});
|
|
|
|
teardown(function() {
|
|
document.body.removeChild(host);
|
|
});
|
|
|
|
test('stamped with initial data', function() {
|
|
assert.equal(childA.outerProp, 'outerProp');
|
|
assert.equal(childA.outerObj, host.outerObj);
|
|
assert.equal(childA.outerObjProp, 'outerObj.prop');
|
|
assert.equal(childA.prop, 'prop-a');
|
|
assert.equal(childA.obj, host.objA);
|
|
assert.equal(childA.objProp, 'objA.prop');
|
|
});
|
|
|
|
test('host properties propagated in', function() {
|
|
host.outerProp = 'outerProp++';
|
|
assert.equal(childA.outerProp, 'outerProp++');
|
|
host.outerObj = { prop: 'outerObj++.prop' };
|
|
assert.equal(childA.outerObj, host.outerObj);
|
|
assert.equal(childA.outerObjProp, 'outerObj++.prop');
|
|
});
|
|
|
|
test('host paths propagated in', function() {
|
|
sinon.spy(childA, 'outerObjChanged');
|
|
host.set('outerObj.prop', 'outerObj.prop++');
|
|
assert.equal(childA.outerObjProp, 'outerObj.prop++');
|
|
assert.isTrue(childA.outerObjChanged.calledOnce);
|
|
assert.equal(childA.outerObjChanged.getCall(0).args[0].path, 'outerObj.prop');
|
|
assert.equal(childA.outerObjChanged.getCall(0).args[0].value, 'outerObj.prop++');
|
|
});
|
|
|
|
test('host properties propagated out', function() {
|
|
childA.outerProp = 'outerProp++';
|
|
assert.equal(host.outerProp, 'outerProp++');
|
|
childA.outerObj = { prop: 'outerObj++.prop' };
|
|
assert.equal(host.outerObj.prop, 'outerObj++.prop');
|
|
});
|
|
|
|
test('host paths propagated out', function() {
|
|
sinon.spy(host, 'outerObjChanged');
|
|
childA.set('outerObj.prop', 'outerObj.prop++');
|
|
assert.equal(host.outerObj.prop, 'outerObj.prop++');
|
|
assert.isTrue(host.outerObjChanged.calledOnce);
|
|
assert.equal(host.outerObjChanged.getCall(0).args[0].path, 'outerObj.prop');
|
|
assert.equal(host.outerObjChanged.getCall(0).args[0].value, 'outerObj.prop++');
|
|
});
|
|
|
|
test('instance properties propagated in', function() {
|
|
host.propA = 'prop-a++';
|
|
assert.equal(childA.prop, 'prop-a++');
|
|
host.objA = { prop: 'objA++.prop' };
|
|
assert.equal(childA.obj, host.objA);
|
|
assert.equal(childA.objProp, 'objA++.prop');
|
|
});
|
|
|
|
test('instance paths propagated in', function() {
|
|
sinon.spy(childA, 'objChanged');
|
|
host.set('objA.prop', 'objA.prop++');
|
|
assert.equal(childA.obj.prop, 'objA.prop++');
|
|
assert.isTrue(childA.objChanged.calledOnce);
|
|
assert.equal(childA.objChanged.getCall(0).args[0].path, 'obj.prop');
|
|
assert.equal(childA.objChanged.getCall(0).args[0].value, 'objA.prop++');
|
|
});
|
|
|
|
test('instance properties propagated out', function() {
|
|
childA.prop = 'prop-a++';
|
|
assert.equal(host.propA, 'prop-a++');
|
|
childA.obj = { prop: 'objA++.prop' };
|
|
assert.equal(host.objA.prop, 'objA++.prop');
|
|
});
|
|
|
|
test('instance paths propagated out', function() {
|
|
sinon.spy(host, 'objAChanged');
|
|
childA.set('obj.prop', 'objA.prop++');
|
|
assert.equal(host.objA.prop, 'objA.prop++');
|
|
assert.isTrue(host.objAChanged.calledOnce);
|
|
assert.equal(host.objAChanged.getCall(0).args[0].path, 'objA.prop');
|
|
assert.equal(host.objAChanged.getCall(0).args[0].value, 'objA.prop++');
|
|
});
|
|
|
|
test('outer & inner props conflict', function() {
|
|
assert.equal(childA.conflict, 'bar');
|
|
host.set('outerInnerConflict.prop', 'foo');
|
|
assert.equal(childA.conflict, 'bar');
|
|
});
|
|
|
|
test('inline computed functions', function() {
|
|
assert.equal(childA.computedFromLiteral, '33-prop-a');
|
|
});
|
|
|
|
test('ensure literals are not forwarded to templates', function() {
|
|
assert.notOk(host._hasAccessor(33));
|
|
assert.notOk(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(host), 33));
|
|
});
|
|
|
|
test('ensure undefined is not set on templatizee', function() {
|
|
assert.equal(host.$.templatizeA[undefined], undefined);
|
|
});
|
|
|
|
test('able to add gesture listeners', function() {
|
|
assert.equal(host.handleTap.callCount, 0);
|
|
childA.click();
|
|
assert.equal(host.handleTap.callCount, 1);
|
|
});
|
|
|
|
test('listener event decorated with model', function() {
|
|
host.outerProp = 'foo';
|
|
childA.click();
|
|
assert.equal(host.handleTap.callCount, 1);
|
|
let event = host.handleTap.firstCall.args[0];
|
|
assert.instanceOf(event, Event);
|
|
assert.ok(event.model);
|
|
assert.equal(event.model.outerProp, 'foo');
|
|
host.outerProp = 'bar';
|
|
assert.equal(event.model.outerProp, 'bar');
|
|
assert.equal(event.model.parentModel, host);
|
|
});
|
|
|
|
});
|
|
|
|
|
|
suite('templatize client with/without props', function() {
|
|
|
|
let host;
|
|
let childB;
|
|
|
|
setup(function() {
|
|
host = document.createElement('x-host');
|
|
document.body.appendChild(host);
|
|
});
|
|
|
|
teardown(function() {
|
|
document.body.removeChild(host);
|
|
});
|
|
|
|
test('templatize with no dataHost', function() {
|
|
host.shadowRoot.querySelector('[name=templatizeB]').go(true);
|
|
childB = host.shadowRoot.querySelector('#childB');
|
|
assert.ok(childB);
|
|
assert.equal(childB.computedFromLiteral, '33-prop-a');
|
|
});
|
|
|
|
test('templatize with no props', function() {
|
|
host.shadowRoot.querySelector('[name=templatizeB]').go(false);
|
|
childB = host.shadowRoot.querySelector('#childB');
|
|
assert.ok(childB);
|
|
assert.isUndefined(childB.computedFromLiteral);
|
|
});
|
|
|
|
test('templatize with no props, instance manually flushes', function() {
|
|
let templatizeA = host.shadowRoot.querySelector('[id=templatizeA]');
|
|
templatizeA.go(false);
|
|
let childA = host.shadowRoot.querySelector('#childA');
|
|
assert.ok(childA);
|
|
sinon.spy(childA, 'objChanged');
|
|
assert.isUndefined(childA.obj);
|
|
let o = {foo: true};
|
|
templatizeA.instance._setPendingProperty('obj', o);
|
|
templatizeA.instance._flushProperties();
|
|
assert.equal(childA.obj, o);
|
|
assert.isTrue(childA.objChanged.calledOnce);
|
|
});
|
|
|
|
});
|
|
|
|
suite('templatizer behavior', function() {
|
|
|
|
let host;
|
|
let childC;
|
|
|
|
setup(function() {
|
|
host = document.createElement('x-host');
|
|
document.body.appendChild(host);
|
|
host.$.templatizeC.go(true);
|
|
childC = host.shadowRoot.querySelector('#childC');
|
|
assert.ok(childC);
|
|
});
|
|
|
|
teardown(function() {
|
|
document.body.removeChild(host);
|
|
});
|
|
|
|
test('stamped with initial data', function() {
|
|
assert.equal(childC.outerProp, 'outerProp');
|
|
assert.equal(childC.outerObj, host.outerObj);
|
|
assert.equal(childC.outerObjProp, 'outerObj.prop');
|
|
assert.equal(childC.prop, 'prop-a');
|
|
assert.equal(childC.obj, host.objA);
|
|
assert.equal(childC.objProp, 'objA.prop');
|
|
});
|
|
|
|
test('host properties propagated in', function() {
|
|
host.outerProp = 'outerProp++';
|
|
assert.equal(childC.outerProp, 'outerProp++');
|
|
host.outerObj = { prop: 'outerObj++.prop' };
|
|
assert.equal(childC.outerObj, host.outerObj);
|
|
assert.equal(childC.outerObjProp, 'outerObj++.prop');
|
|
});
|
|
|
|
test('host paths propagated in', function() {
|
|
sinon.spy(childC, 'outerObjChanged');
|
|
host.set('outerObj.prop', 'outerObj.prop++');
|
|
assert.equal(childC.outerObjProp, 'outerObj.prop++');
|
|
assert.isTrue(childC.outerObjChanged.calledOnce);
|
|
assert.equal(childC.outerObjChanged.getCall(0).args[0].path, 'outerObj.prop');
|
|
assert.equal(childC.outerObjChanged.getCall(0).args[0].value, 'outerObj.prop++');
|
|
});
|
|
|
|
test('host properties propagated out', function() {
|
|
childC.outerProp = 'outerProp++';
|
|
assert.equal(host.outerProp, 'outerProp++');
|
|
childC.outerObj = { prop: 'outerObj++.prop' };
|
|
assert.equal(host.outerObj.prop, 'outerObj++.prop');
|
|
});
|
|
|
|
test('host paths propagated out', function() {
|
|
sinon.spy(host, 'outerObjChanged');
|
|
childC.set('outerObj.prop', 'outerObj.prop++');
|
|
assert.equal(host.outerObj.prop, 'outerObj.prop++');
|
|
assert.isTrue(host.outerObjChanged.calledOnce);
|
|
assert.equal(host.outerObjChanged.getCall(0).args[0].path, 'outerObj.prop');
|
|
assert.equal(host.outerObjChanged.getCall(0).args[0].value, 'outerObj.prop++');
|
|
});
|
|
|
|
test('instance properties propagated in', function() {
|
|
host.propA = 'prop-a++';
|
|
assert.equal(childC.prop, 'prop-a++');
|
|
host.objA = { prop: 'objA++.prop' };
|
|
assert.equal(childC.obj, host.objA);
|
|
assert.equal(childC.objProp, 'objA++.prop');
|
|
});
|
|
|
|
test('instance paths propagated in', function() {
|
|
sinon.spy(childC, 'objChanged');
|
|
host.set('objA.prop', 'objA.prop++');
|
|
assert.equal(childC.obj.prop, 'objA.prop++');
|
|
assert.isTrue(childC.objChanged.calledOnce);
|
|
assert.equal(childC.objChanged.getCall(0).args[0].path, 'obj.prop');
|
|
assert.equal(childC.objChanged.getCall(0).args[0].value, 'objA.prop++');
|
|
});
|
|
|
|
test('instance properties propagated out', function() {
|
|
childC.prop = 'prop-a++';
|
|
assert.equal(host.propA, 'prop-a++');
|
|
childC.obj = { prop: 'objA++.prop' };
|
|
assert.equal(host.objA.prop, 'objA++.prop');
|
|
});
|
|
|
|
test('instance paths propagated out', function() {
|
|
sinon.spy(host, 'objAChanged');
|
|
childC.set('obj.prop', 'objA.prop++');
|
|
assert.equal(host.objA.prop, 'objA.prop++');
|
|
assert.isTrue(host.objAChanged.calledOnce);
|
|
assert.equal(host.objAChanged.getCall(0).args[0].path, 'objA.prop');
|
|
assert.equal(host.objAChanged.getCall(0).args[0].value, 'objA.prop++');
|
|
});
|
|
|
|
test('outer & inner props conflict', function() {
|
|
assert.equal(childC.conflict, 'bar');
|
|
host.set('outerInnerConflict.prop', 'foo');
|
|
assert.equal(childC.conflict, 'bar');
|
|
});
|
|
|
|
test('inline computed functions', function() {
|
|
assert.equal(childC.computedFromLiteral, '33-prop-a');
|
|
});
|
|
|
|
test('ensure literals are not forwarded to templates', function() {
|
|
assert.notOk(host._hasAccessor(33));
|
|
assert.notOk(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(host), 33));
|
|
});
|
|
|
|
test('ensure undefined is not set on templatizee', function() {
|
|
assert.equal(host.$.templatizeA[undefined], undefined);
|
|
});
|
|
|
|
test('able to add gesture listeners', function() {
|
|
assert.equal(host.handleTap.callCount, 0);
|
|
childC.click();
|
|
assert.equal(host.handleTap.callCount, 1);
|
|
});
|
|
|
|
test('listener event decorated with model', function() {
|
|
host.outerProp = 'foo';
|
|
childC.click();
|
|
assert.equal(host.handleTap.callCount, 1);
|
|
let event = host.handleTap.firstCall.args[0];
|
|
assert.instanceOf(event, Event);
|
|
assert.ok(event.model);
|
|
assert.equal(event.model.outerProp, 'foo');
|
|
host.outerProp = 'bar';
|
|
assert.equal(event.model.outerProp, 'bar');
|
|
});
|
|
|
|
});
|
|
|
|
suite('templatize with no host', function() {
|
|
|
|
test('stamped with initial data', function() {
|
|
const template = document.getElementById('standalone').cloneNode(true);
|
|
const Template = templatize(template);
|
|
const inst = new Template({prop: 'prop', text: 'text'});
|
|
const div = inst.root.firstChild;
|
|
assert.equal(div.prop, 'prop');
|
|
assert.equal(div.textContent, 'text');
|
|
});
|
|
|
|
test('stamped with no initial data', function() {
|
|
const template = document.getElementById('standalone').cloneNode(true);
|
|
const Template = templatize(template);
|
|
const inst = new Template();
|
|
const div = inst.root.firstChild;
|
|
assert.equal(div.prop, undefined);
|
|
assert.equal(div.textContent.trim(), '');
|
|
inst.setProperties({prop: 'prop', text: 'text'});
|
|
assert.equal(div.prop, 'prop');
|
|
assert.equal(div.textContent, 'text');
|
|
});
|
|
|
|
test('notifies path data changes', function() {
|
|
const template = document.getElementById('standalone').cloneNode(true);
|
|
const Template = templatize(template);
|
|
const inst = new Template();
|
|
const div = inst.root.firstChild;
|
|
inst.setProperties({prop: {foo: true}});
|
|
assert.equal(div.prop.foo, true);
|
|
inst.set('prop.foo', false);
|
|
assert.equal(div.prop.foo, false);
|
|
});
|
|
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|