UNPKG

@polymer/polymer

Version:

The Polymer library makes it easy to create your own web components. Give your element some markup and properties, and then use it on a site. Polymer provides features like dynamic templates and data binding to reduce the amount of boilerplate you need to

1,101 lines (1,011 loc) 191 kB
<!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="../../../webcomponentsjs/webcomponents-lite.js"></script> <script src="../../../web-component-tester/browser.js"></script> <link rel="import" href="../../polymer.html"> <link rel="import" href="dom-repeat-elements.html"> <style> /* makes painting faster when testing on IOS simulator */ x-repeat-chunked { display: none; } </style> </head> <body> <test-fixture id="simple"> <template> <x-simple-repeat></x-simple-repeat> </template> </test-fixture> <test-fixture id="primitive"> <template> <x-primitive-repeat></x-primitive-repeat> </template> </test-fixture> <test-fixture id="configured"> <template> <x-nested-repeat-configured></x-nested-repeat-configured> </template> </test-fixture> <test-fixture id="filter-and-sort-by-nested-property"> <template> <x-repeat-filter-and-sort-by-nested-property></x-repeat-filter-and-sort-by-nested-property> </template> </test-fixture> <test-fixture id="unconfigured"> <template> <dom-bind> <template> <x-nested-repeat id="el1" items="{{items}}"></x-nested-repeat> <x-nested-repeat id="el2" items="{{items}}"></x-nested-repeat> </template> </dom-bind> </template> </test-fixture> <test-fixture id="unconfigured-mutable"> <template> <dom-bind mutable-data> <template> <x-nested-repeat-mutable id="el1" items="{{items}}"></x-nested-repeat-mutable> <x-nested-repeat-mutable id="el2" items="{{items}}"></x-nested-repeat-mutable> </template> </dom-bind> </template> </test-fixture> <h4>inDocumentRepeater</h4> <div id="inDocumentContainerOrig"> <dom-repeat id="inDocumentRepeater" as="itema" index-as="indexa"> <template> <x-foo innera-prop="{{innera.prop}}" itema-prop="{{itema.prop}}" indexa="{{indexa}}"> </x-foo> <template is="dom-repeat" items="{{itema.items}}" as="itemb" index-as="indexb"> <x-foo innerb-prop="{{innerb.prop}}" itemb-prop="{{itemb.prop}}" innera-prop="{{innera.prop}}" itema-prop="{{itema.prop}}" indexa="{{indexa}}" indexb="{{indexb}}"> </x-foo> <template is="dom-repeat" items="{{itemb.items}}" as="itemc" index-as="indexc"> <x-foo innerc-prop="{{innerc.prop}}" itemc-prop="{{itemc.prop}}" innerb-prop="{{innerb.prop}}" itemb-prop="{{itemb.prop}}" innera-prop="{{innera.prop}}" itema-prop="{{itema.prop}}" indexa="{{indexa}}" indexb="{{indexb}}" indexc="{{indexc}}"> </x-foo> </template> </template> </template> </dom-repeat> </div> <test-fixture id="primitiveLarge"> <template> <x-primitive-large></x-primitive-large> </template> </test-fixture> <h4>x-repeat-limit</h4> <x-repeat-limit id="limited"></x-repeat-limit> <h4>x-repeat-chunked</h4> <x-repeat-chunked id="chunked"></x-repeat-chunked> <div id="inDocumentContainer"> </div> <script> /* force non-upgrade, to test MO-based template finding below */ </script> <div id="nonUpgrade"> <dom-repeat items='[{"prop": "stamped"}]'> <template>{{item.prop}}</template> </dom-repeat> </div> <script> (function() { 'use strict'; /* global limited inDocumentRepeater inDocumentContainer inDocumentContainerOrig chunked nonUpgrade*/ /* Expected: stamped[0] ... 1 stamped[1] ... 1-1 stamped[2] ... 1-1-1 stamped[3] ... 1-1-2 stamped[4] ... 1-1-3 stamped[5] ... 1-2 ... stamped[13] .. 2 ... stamped[36] .. 3-3-1 stamped[37] .. 3-3-2 stamped[38] .. 3-3-3 */ function arrayDelete(el, path, item) { var array = el.get(path); var idx = array.indexOf(item); el.splice(path, idx, 1); } suite('errors', function() { test('items must be array', function() { sinon.spy(console, 'warn'); inDocumentRepeater.items = {}; assert.isTrue(console.warn.calledOnce, 'should warn when items is not array'); assert.match(console.warn.firstCall.args[0], /expected array/); console.warn.restore(); }); }); suite('nested pre-configured dom-repeat', function() { let configured; setup(function() { configured = fixture('configured'); Polymer.flush(); }); test('basic rendering, downward item binding', function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(configured.$.repeater.renderedItemCount, 3, 'rendered item count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].computeda, 'prop-1+itemForComputedA'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[0].$.bar.itemaProp, 'prop-1'); assert.equal(stamped[1].itembProp, 'prop-1-1'); assert.equal(stamped[1].computedb, 'prop-1-1+itemForComputedB'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].indexb, 0); assert.equal(stamped[1].$.bar.itembProp, 'prop-1-1'); assert.equal(stamped[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped[2].computedc, 'prop-1-1-1+itemForComputedC'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].indexc, 0); assert.equal(stamped[2].$.bar.itemcProp, 'prop-1-1-1'); assert.equal(stamped[3].itemcProp, 'prop-1-1-2'); assert.equal(stamped[3].indexa, 0); assert.equal(stamped[3].indexb, 0); assert.equal(stamped[3].indexc, 1); assert.equal(stamped[3].$.bar.itemcProp, 'prop-1-1-2'); assert.equal(stamped[4].itemcProp, 'prop-1-1-3'); assert.equal(stamped[4].indexa, 0); assert.equal(stamped[4].indexb, 0); assert.equal(stamped[4].indexc, 2); assert.equal(stamped[4].$.bar.itemcProp, 'prop-1-1-3'); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[13].$.bar.itemaProp, 'prop-2'); assert.equal(stamped[36].itemcProp, 'prop-3-3-1'); assert.equal(stamped[36].indexa, 2); assert.equal(stamped[36].indexb, 2); assert.equal(stamped[36].indexc, 0); assert.equal(stamped[36].$.bar.itemcProp, 'prop-3-3-1'); assert.equal(stamped[37].itemcProp, 'prop-3-3-2'); assert.equal(stamped[37].indexa, 2); assert.equal(stamped[37].indexb, 2); assert.equal(stamped[37].indexc, 1); assert.equal(stamped[37].$.bar.itemcProp, 'prop-3-3-2'); assert.equal(stamped[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].indexc, 2); assert.equal(stamped[38].$.bar.itemcProp, 'prop-3-3-3'); }); test('parent scope binding', function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped[0].outerProp, 'outer'); assert.equal(stamped[0].outerItemProp, 'outerItem'); assert.equal(stamped[1].itemaProp, 'prop-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].outerProp, 'outer'); assert.equal(stamped[1].outerItemProp, 'outerItem'); assert.equal(stamped[2].itembProp, 'prop-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].itemaProp, 'prop-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].outerProp, 'outer'); assert.equal(stamped[2].outerItemProp, 'outerItem'); assert.equal(stamped[38].itembProp, 'prop-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].itemaProp, 'prop-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].outerProp, 'outer'); assert.equal(stamped[38].outerItemProp, 'outerItem'); }); test('parent scope downward notification', function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); configured.prop = 'yes'; assert.equal(stamped[0].outerProp, 'yes'); assert.equal(stamped[1].outerProp, 'yes'); assert.equal(stamped[2].outerProp, 'yes'); assert.equal(stamped[38].outerProp, 'yes'); configured.set('item.prop', 'yay'); assert.equal(stamped[0].outerItemProp, 'yay'); assert.equal(stamped[1].outerItemProp, 'yay'); assert.equal(stamped[2].outerItemProp, 'yay'); assert.equal(stamped[38].outerItemProp, 'yay'); }); test('parent scope upward notification', function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); stamped[38].outerProp = 'nice'; assert.equal(configured.prop, 'nice'); assert.equal(stamped[0].outerProp, 'nice'); assert.equal(stamped[1].outerProp, 'nice'); assert.equal(stamped[2].outerProp, 'nice'); assert.equal(stamped[37].outerProp, 'nice'); stamped[38].outerItemProp = 'cool'; assert.equal(configured.item.prop, 'cool'); assert.equal(stamped[0].outerItemProp, 'cool'); assert.equal(stamped[1].outerItemProp, 'cool'); assert.equal(stamped[2].outerItemProp, 'cool'); assert.equal(stamped[37].outerItemProp, 'cool'); }); // Anonymous inner scope feature removed for time being // test('anonymous scope binding', function() { // var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); // stamped[1].$.bar.inneraProp = 'changed'; // assert.equal(stamped[1].inneraProp, 'changed'); // assert.equal(stamped[2].inneraProp, 'changed'); // assert.equal(stamped[3].inneraProp, 'changed'); // assert.equal(stamped[4].inneraProp, 'changed'); // }); test('sort function by name on host', function() { // set sort fn configured.$.repeater.sort = 'sortDesc'; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-1'); assert.equal(stamped[26].indexa, 2); // reset sort fn configured.$.repeater.sort = null; configured.$.repeater.render(); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); }); test('sort function imperative', function() { // set sort fn configured.$.repeater.sort = function(a, b) { return b.prop.localeCompare(a.prop); }; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-1'); assert.equal(stamped[26].indexa, 2); // reset sort fn configured.$.repeater.sort = null; configured.$.repeater.render(); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); }); test('filter function by name on host', function() { // set filter fn configured.$.repeater.filter = 'filter2nd'; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(configured.$.repeater.renderedItemCount, 2, 'rendered item count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-3'); assert.equal(stamped[13].indexa, 1); // reset filter fn configured.$.repeater.filter = null; configured.$.repeater.render(); stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); }); test('filter function imperative', function() { // set filter fn configured.$.repeater.filter = function(o) { return o.prop.indexOf('2') < 0; }; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-3'); assert.equal(stamped[13].indexa, 1); // reset filter fn configured.$.repeater.filter = null; configured.$.repeater.render(); stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); }); test('sort and filter function by name on host', function() { // set filter fn configured.$.repeater.sort = 'sortDesc'; configured.$.repeater.filter = 'filter2nd'; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); // reset filter fn configured.$.repeater.sort = null; configured.$.repeater.filter = null; configured.$.repeater.render(); stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); }); test('observe refreshes sort and filter', function(done) { // set filter fn configured.$.repeater.sort = 'sortDesc'; configured.$.repeater.filter = 'filter2nd'; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); // Update observed prop to be in filter configured.set(['items', 1, 'prop'], 'prop-0'); // avoid imperative/synchronous refresh() since that forces a full refresh setTimeout(function() { stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-0'); assert.equal(stamped[26].indexa, 2); // Update observed prop back to be out of the filter configured.set(['items', 1, 'prop'], 'prop-2'); setTimeout(function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); // reset filter fn configured.$.repeater.sort = null; configured.$.repeater.filter = null; configured.$.repeater.render(); stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); done(); }); }); }); test('item change refreshes sort and filter', function(done) { // set filter fn configured.$.repeater.sort = 'sortDesc'; configured.$.repeater.filter = 'filter2nd'; configured.$.repeater.render(); var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); // Update observed prop to be in filter (set new object) configured.set(['items', 1], Object.assign({}, configured.items[1], {prop: 'prop-0'})); // avoid imperative/synchronous refresh() since that forces a full refresh setTimeout(function() { stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-0'); assert.equal(stamped[26].indexa, 2); // Update observed prop back to be out of the filter (set new object) configured.set(['items', 1], Object.assign({}, configured.items[1], {prop: 'prop-2'})); setTimeout(function() { var stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-3'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-1'); assert.equal(stamped[13].indexa, 1); // reset filter fn configured.$.repeater.sort = null; configured.$.repeater.filter = null; configured.$.repeater.render(); stamped = configured.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[26].itemaProp, 'prop-3'); assert.equal(stamped[26].indexa, 2); done(); }); }); }); }); suite('filter and sort by nested property', function () { let fixtureInstance; setup(function() { fixtureInstance = fixture('filter-and-sort-by-nested-property'); Polymer.flush(); }); test('change of item nested-property refreshes sort and filter', function(done) { // Original values for `item.prop.nestedProp` are numbers 0 through 4 const repeater = fixtureInstance.$.repeater; repeater.sort = (a, b) => b.prop.nestedProp - a.prop.nestedProp; // Desc order repeater.filter = (a) => a.prop.nestedProp >= 1; // => Just 1 through 4 repeater.observe = 'prop.nestedProp'; repeater.render(); const stamped = fixtureInstance.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 4, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 4); assert.equal(stamped[1].itemaProp, 3); assert.equal(stamped[2].itemaProp, 2); assert.equal(stamped[3].itemaProp, 1); // Update observed nested prop for (let i = 0; i < 5; i++) { const x = fixtureInstance.get(['items', i, 'prop', 'nestedProp']); fixtureInstance.set(['items', i, 'prop', 'nestedProp'], (x + 10) * 2); } // Wait for changes to be reflected to the DOM setTimeout(function() { const stamped = fixtureInstance.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 5, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 28); assert.equal(stamped[1].itemaProp, 26); assert.equal(stamped[2].itemaProp, 24); assert.equal(stamped[3].itemaProp, 22); assert.equal(stamped[4].itemaProp, 20); done(); }); }); }); suite('nested un-configured dom-repeat in document', function() { test('basic rendering, downward item binding', function() { inDocumentRepeater.items = window.getData(); inDocumentRepeater.render(); var stamped = inDocumentContainerOrig.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[0].$.bar.itemaProp, 'prop-1'); assert.equal(stamped[1].itembProp, 'prop-1-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].indexb, 0); assert.equal(stamped[1].$.bar.itembProp, 'prop-1-1'); assert.equal(stamped[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].indexc, 0); assert.equal(stamped[2].$.bar.itemcProp, 'prop-1-1-1'); assert.equal(stamped[3].itemcProp, 'prop-1-1-2'); assert.equal(stamped[3].indexa, 0); assert.equal(stamped[3].indexb, 0); assert.equal(stamped[3].indexc, 1); assert.equal(stamped[3].$.bar.itemcProp, 'prop-1-1-2'); assert.equal(stamped[4].itemcProp, 'prop-1-1-3'); assert.equal(stamped[4].indexa, 0); assert.equal(stamped[4].indexb, 0); assert.equal(stamped[4].indexc, 2); assert.equal(stamped[4].$.bar.itemcProp, 'prop-1-1-3'); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[13].$.bar.itemaProp, 'prop-2'); assert.equal(stamped[36].itemcProp, 'prop-3-3-1'); assert.equal(stamped[36].indexa, 2); assert.equal(stamped[36].indexb, 2); assert.equal(stamped[36].indexc, 0); assert.equal(stamped[36].$.bar.itemcProp, 'prop-3-3-1'); assert.equal(stamped[37].itemcProp, 'prop-3-3-2'); assert.equal(stamped[37].indexa, 2); assert.equal(stamped[37].indexb, 2); assert.equal(stamped[37].indexc, 1); assert.equal(stamped[37].$.bar.itemcProp, 'prop-3-3-2'); assert.equal(stamped[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].indexc, 2); assert.equal(stamped[38].$.bar.itemcProp, 'prop-3-3-3'); }); test('move to different container', function() { var repeater = inDocumentRepeater; inDocumentContainer.appendChild(repeater); var stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[0].$.bar.itemaProp, 'prop-1'); assert.equal(stamped[1].itembProp, 'prop-1-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].indexb, 0); assert.equal(stamped[1].$.bar.itembProp, 'prop-1-1'); assert.equal(stamped[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].indexc, 0); assert.equal(stamped[2].$.bar.itemcProp, 'prop-1-1-1'); assert.equal(stamped[3].itemcProp, 'prop-1-1-2'); assert.equal(stamped[3].indexa, 0); assert.equal(stamped[3].indexb, 0); assert.equal(stamped[3].indexc, 1); assert.equal(stamped[3].$.bar.itemcProp, 'prop-1-1-2'); assert.equal(stamped[4].itemcProp, 'prop-1-1-3'); assert.equal(stamped[4].indexa, 0); assert.equal(stamped[4].indexb, 0); assert.equal(stamped[4].indexc, 2); assert.equal(stamped[4].$.bar.itemcProp, 'prop-1-1-3'); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[13].$.bar.itemaProp, 'prop-2'); assert.equal(stamped[36].itemcProp, 'prop-3-3-1'); assert.equal(stamped[36].indexa, 2); assert.equal(stamped[36].indexb, 2); assert.equal(stamped[36].indexc, 0); assert.equal(stamped[36].$.bar.itemcProp, 'prop-3-3-1'); assert.equal(stamped[37].itemcProp, 'prop-3-3-2'); assert.equal(stamped[37].indexa, 2); assert.equal(stamped[37].indexb, 2); assert.equal(stamped[37].indexc, 1); assert.equal(stamped[37].$.bar.itemcProp, 'prop-3-3-2'); assert.equal(stamped[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].indexc, 2); assert.equal(stamped[38].$.bar.itemcProp, 'prop-3-3-3'); }); test('basic rendering, downward item binding', function() { var r = inDocumentRepeater; r.parentElement.removeChild(r); inDocumentContainer.appendChild(r); var stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[0].$.bar.itemaProp, 'prop-1'); assert.equal(stamped[1].itembProp, 'prop-1-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].indexb, 0); assert.equal(stamped[1].$.bar.itembProp, 'prop-1-1'); assert.equal(stamped[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].indexc, 0); assert.equal(stamped[2].$.bar.itemcProp, 'prop-1-1-1'); assert.equal(stamped[3].itemcProp, 'prop-1-1-2'); assert.equal(stamped[3].indexa, 0); assert.equal(stamped[3].indexb, 0); assert.equal(stamped[3].indexc, 1); assert.equal(stamped[3].$.bar.itemcProp, 'prop-1-1-2'); assert.equal(stamped[4].itemcProp, 'prop-1-1-3'); assert.equal(stamped[4].indexa, 0); assert.equal(stamped[4].indexb, 0); assert.equal(stamped[4].indexc, 2); assert.equal(stamped[4].$.bar.itemcProp, 'prop-1-1-3'); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[13].$.bar.itemaProp, 'prop-2'); assert.equal(stamped[36].itemcProp, 'prop-3-3-1'); assert.equal(stamped[36].indexa, 2); assert.equal(stamped[36].indexb, 2); assert.equal(stamped[36].indexc, 0); assert.equal(stamped[36].$.bar.itemcProp, 'prop-3-3-1'); assert.equal(stamped[37].itemcProp, 'prop-3-3-2'); assert.equal(stamped[37].indexa, 2); assert.equal(stamped[37].indexb, 2); assert.equal(stamped[37].indexc, 1); assert.equal(stamped[37].$.bar.itemcProp, 'prop-3-3-2'); assert.equal(stamped[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].indexc, 2); assert.equal(stamped[38].$.bar.itemcProp, 'prop-3-3-3'); }); test('parent scope binding', function() { var stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped[1].itemaProp, 'prop-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[2].itembProp, 'prop-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].itemaProp, 'prop-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[38].itembProp, 'prop-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].itemaProp, 'prop-3'); assert.equal(stamped[38].indexa, 2); }); // Anonymous inner scope feature removed for time being // test('anonymous scope binding', function() { // var stamped = inDocumentContainer.querySelectorAll('*:not(template):not(dom-repeat)'); // stamped[1].$.bar.inneraProp = 'changed'; // assert.equal(stamped[1].inneraProp, 'changed'); // assert.equal(stamped[2].inneraProp, 'changed'); // assert.equal(stamped[3].inneraProp, 'changed'); // assert.equal(stamped[4].inneraProp, 'changed'); // }); }); suite('nested un-configured dom-repeat', function() { let unconfigured; setup(function() { unconfigured = fixture('unconfigured'); unconfigured.items = window.getData(); unconfigured.$.el1.prop = 'outer'; unconfigured.$.el1.item = {prop: 'outerItem'}; Polymer.flush(); }); test('basic rendering, downward item binding', function() { var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped.length, 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped[0].itemaProp, 'prop-1'); assert.equal(stamped[0].indexa, 0); assert.equal(stamped[0].$.bar.itemaProp, 'prop-1'); assert.equal(stamped[1].itembProp, 'prop-1-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].indexb, 0); assert.equal(stamped[1].$.bar.itembProp, 'prop-1-1'); assert.equal(stamped[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].indexc, 0); assert.equal(stamped[2].$.bar.itemcProp, 'prop-1-1-1'); assert.equal(stamped[3].itemcProp, 'prop-1-1-2'); assert.equal(stamped[3].indexa, 0); assert.equal(stamped[3].indexb, 0); assert.equal(stamped[3].indexc, 1); assert.equal(stamped[3].$.bar.itemcProp, 'prop-1-1-2'); assert.equal(stamped[4].itemcProp, 'prop-1-1-3'); assert.equal(stamped[4].indexa, 0); assert.equal(stamped[4].indexb, 0); assert.equal(stamped[4].indexc, 2); assert.equal(stamped[4].$.bar.itemcProp, 'prop-1-1-3'); assert.equal(stamped[13].itemaProp, 'prop-2'); assert.equal(stamped[13].indexa, 1); assert.equal(stamped[13].$.bar.itemaProp, 'prop-2'); assert.equal(stamped[36].itemcProp, 'prop-3-3-1'); assert.equal(stamped[36].indexa, 2); assert.equal(stamped[36].indexb, 2); assert.equal(stamped[36].indexc, 0); assert.equal(stamped[36].$.bar.itemcProp, 'prop-3-3-1'); assert.equal(stamped[37].itemcProp, 'prop-3-3-2'); assert.equal(stamped[37].indexa, 2); assert.equal(stamped[37].indexb, 2); assert.equal(stamped[37].indexc, 1); assert.equal(stamped[37].$.bar.itemcProp, 'prop-3-3-2'); assert.equal(stamped[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].indexc, 2); assert.equal(stamped[38].$.bar.itemcProp, 'prop-3-3-3'); }); test('parent scope binding', function() { var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped[0].outerProp, 'outer'); assert.equal(stamped[0].outerItemProp, 'outerItem'); assert.equal(stamped[1].itemaProp, 'prop-1'); assert.equal(stamped[1].indexa, 0); assert.equal(stamped[1].outerProp, 'outer'); assert.equal(stamped[1].outerItemProp, 'outerItem'); assert.equal(stamped[2].itembProp, 'prop-1-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].indexb, 0); assert.equal(stamped[2].itemaProp, 'prop-1'); assert.equal(stamped[2].indexa, 0); assert.equal(stamped[2].outerProp, 'outer'); assert.equal(stamped[2].outerItemProp, 'outerItem'); assert.equal(stamped[38].itembProp, 'prop-3-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].indexb, 2); assert.equal(stamped[38].itemaProp, 'prop-3'); assert.equal(stamped[38].indexa, 2); assert.equal(stamped[38].outerProp, 'outer'); assert.equal(stamped[38].outerItemProp, 'outerItem'); }); test('parent scope downward notification', function() { var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); unconfigured.$.el1.prop = 'yes'; assert.equal(stamped[0].outerProp, 'yes'); assert.equal(stamped[1].outerProp, 'yes'); assert.equal(stamped[2].outerProp, 'yes'); assert.equal(stamped[38].outerProp, 'yes'); unconfigured.$.el1.set('item.prop', 'yay'); assert.equal(stamped[0].outerItemProp, 'yay'); assert.equal(stamped[1].outerItemProp, 'yay'); assert.equal(stamped[2].outerItemProp, 'yay'); assert.equal(stamped[38].outerItemProp, 'yay'); }); test('parent scope upward notification', function() { var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); stamped[38].outerProp = 'nice'; assert.equal(unconfigured.$.el1.prop, 'nice'); assert.equal(stamped[0].outerProp, 'nice'); assert.equal(stamped[1].outerProp, 'nice'); assert.equal(stamped[2].outerProp, 'nice'); assert.equal(stamped[37].outerProp, 'nice'); stamped[38].outerItemProp = 'cool'; assert.equal(unconfigured.$.el1.item.prop, 'cool'); assert.equal(stamped[0].outerItemProp, 'cool'); assert.equal(stamped[1].outerItemProp, 'cool'); assert.equal(stamped[2].outerItemProp, 'cool'); assert.equal(stamped[37].outerItemProp, 'cool'); }); // Anonymous inner scope feature removed for time being // test('anonymous scope binding', function() { // var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); // stamped[1].$.bar.inneraProp = 'changed'; // assert.equal(stamped[1].inneraProp, 'changed'); // assert.equal(stamped[2].inneraProp, 'changed'); // assert.equal(stamped[3].inneraProp, 'changed'); // assert.equal(stamped[4].inneraProp, 'changed'); // }); test('event handlers', function() { var stamped = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); stamped[0].fire('test1'); assert.equal(unconfigured.$.el1.testHandler1Count, 1); stamped[1].fire('test2'); assert.equal(unconfigured.$.el1.testHandler2Count, 1); stamped[2].fire('test3'); assert.equal(unconfigured.$.el1.testHandler3Count, 1); }); }); suite('array notification between two dom-repeats', function() { let unconfigured; setup(function() { unconfigured = fixture('unconfigured'); unconfigured.items = window.getData(); Polymer.flush(); }); test('change to item from one dom-repeat to other', function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el2.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1[0].itemaProp, 'prop-1'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped2[0].itemaProp, 'prop-1'); assert.equal(stamped2[0].indexa, 0); stamped1[0].$.bar.itemaProp = 'changed'; assert.equal(stamped2[0].itemaProp, 'changed'); stamped2[0].$.bar.itemaProp = 'prop-1'; assert.equal(stamped1[0].itemaProp, 'prop-1'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped1[1].itembProp, 'prop-1-1'); assert.equal(stamped1[1].indexa, 0); assert.equal(stamped1[1].indexb, 0); assert.equal(stamped2[1].itembProp, 'prop-1-1'); assert.equal(stamped2[1].indexa, 0); assert.equal(stamped2[1].indexb, 0); stamped1[1].$.bar.itembProp = 'changed'; assert.equal(stamped2[1].itembProp, 'changed'); stamped2[1].$.bar.itembProp = 'prop-1-1'; assert.equal(stamped1[1].itembProp, 'prop-1-1'); assert.equal(stamped1[1].indexa, 0); assert.equal(stamped1[1].indexb, 0); assert.equal(stamped1[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped1[2].indexa, 0); assert.equal(stamped1[2].indexb, 0); assert.equal(stamped1[2].indexc, 0); assert.equal(stamped2[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped2[2].indexa, 0); assert.equal(stamped2[2].indexb, 0); assert.equal(stamped2[2].indexc, 0); stamped1[2].$.bar.itemcProp = 'changed'; assert.equal(stamped2[2].itemcProp, 'changed'); stamped2[2].$.bar.itemcProp = 'prop-1-1-1'; assert.equal(stamped1[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped1[2].indexa, 0); assert.equal(stamped1[2].indexb, 0); assert.equal(stamped1[2].indexc, 0); assert.equal(stamped1[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped1[38].indexa, 2); assert.equal(stamped1[38].indexb, 2); assert.equal(stamped1[38].indexc, 2); assert.equal(stamped2[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped2[38].indexa, 2); assert.equal(stamped2[38].indexb, 2); assert.equal(stamped2[38].indexc, 2); stamped1[38].$.bar.itemcProp = 'changed'; assert.equal(stamped2[38].itemcProp, 'changed'); stamped2[38].$.bar.itemcProp = 'prop-3-3-3'; assert.equal(stamped1[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped1[38].indexa, 2); assert.equal(stamped1[38].indexb, 2); assert.equal(stamped1[38].indexc, 2); }); test('change to non-item scope doesn\'t affect other dom-repeat', function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el2.root.querySelectorAll('*:not(template):not(dom-repeat)'); unconfigured.$.el1.prop = 'foo'; unconfigured.$.el2.prop = 'bar'; assert.equal(stamped1[0].outerProp, 'foo'); assert.equal(stamped1[1].outerProp, 'foo'); assert.equal(stamped1[2].outerProp, 'foo'); assert.equal(stamped2[0].outerProp, 'bar'); assert.equal(stamped2[1].outerProp, 'bar'); assert.equal(stamped2[2].outerProp, 'bar'); stamped1[1].$.bar.inneraProp = 'bar'; }); }); suite('reacting to changes, array sort', function() { let unconfigured; setup(function() { unconfigured = fixture('unconfigured'); unconfigured.items = window.getData(); Polymer.flush(); unconfigured.$.el1.domUpdateHandlerCount = 0; }); test('push', function(done) { unconfigured.push('items', {prop: 'new-1'}, {prop: 'new-2'}); setTimeout(function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1.length, 2 + 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped2.length, 2 + 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped1[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped1[38].indexa, 2); assert.equal(stamped1[38].indexb, 2); assert.equal(stamped1[38].indexc, 2); assert.equal(stamped1[39].itemaProp, 'new-1'); assert.equal(stamped1[40].itemaProp, 'new-2'); assert.equal(stamped1[41], undefined); assert.equal(stamped2[38].itemcProp, 'prop-3-3-3'); assert.equal(stamped2[38].indexa, 2); assert.equal(stamped2[38].indexb, 2); assert.equal(stamped2[38].indexc, 2); assert.equal(stamped2[39].itemaProp, 'new-1'); assert.equal(stamped2[40].itemaProp, 'new-2'); assert.equal(stamped2[41], undefined); assert.equal(unconfigured.$.el1.domUpdateHandlerCount, 1); done(); }); }); test('pop', function(done) { unconfigured.pop('items'); setTimeout(function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped2.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped1[25].itemcProp, 'prop-2-3-3'); assert.equal(stamped1[25].indexa, 1); assert.equal(stamped1[25].indexb, 2); assert.equal(stamped1[25].indexc, 2); assert.equal(stamped1[26], undefined); assert.equal(stamped2[25].itemcProp, 'prop-2-3-3'); assert.equal(stamped2[25].indexa, 1); assert.equal(stamped2[25].indexb, 2); assert.equal(stamped2[25].indexc, 2); assert.equal(stamped2[26], undefined); done(); }); }); test('unshift', function(done) { unconfigured.unshift('items', {prop: 'new-1'}, {prop: 'new-2'}); setTimeout(function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1.length, 2 + 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped2.length, 2 + 3 + 3*3 + 3*3*3, 'total stamped count incorrect'); assert.equal(stamped1[0].itemaProp, 'new-1'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped1[1].itemaProp, 'new-2'); assert.equal(stamped1[1].indexa, 1); assert.equal(stamped1[2].itemaProp, 'prop-1'); assert.equal(stamped1[2].indexa, 2); assert.equal(stamped2[0].itemaProp, 'new-1'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped2[1].itemaProp, 'new-2'); assert.equal(stamped1[1].indexa, 1); assert.equal(stamped2[2].itemaProp, 'prop-1'); assert.equal(stamped2[2].indexa, 2); done(); }); }); test('shift', function(done) { unconfigured.shift('items'); setTimeout(function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped2.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped1[0].itemaProp, 'prop-2'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped1[1].itembProp, 'prop-2-1'); assert.equal(stamped1[1].indexa, 0); assert.equal(stamped1[1].indexb, 0); assert.equal(stamped1[2].itemcProp, 'prop-2-1-1'); assert.equal(stamped1[2].indexa, 0); assert.equal(stamped1[2].indexb, 0); assert.equal(stamped1[2].indexc, 0); assert.equal(stamped2[0].itemaProp, 'prop-2'); assert.equal(stamped2[0].indexa, 0); assert.equal(stamped2[1].itembProp, 'prop-2-1'); assert.equal(stamped2[1].indexa, 0); assert.equal(stamped2[1].indexb, 0); assert.equal(stamped2[2].itemcProp, 'prop-2-1-1'); assert.equal(stamped2[2].indexa, 0); assert.equal(stamped2[2].indexb, 0); assert.equal(stamped2[2].indexc, 0); done(); }); }); test('splice - remove from middle', function(done) { unconfigured.splice('items', 1, 1)[0]; setTimeout(function() { var stamped1 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); var stamped2 = unconfigured.$.el1.root.querySelectorAll('*:not(template):not(dom-repeat)'); assert.equal(stamped1.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped2.length, 2 + 2*3 + 2*3*3, 'total stamped count incorrect'); assert.equal(stamped1[0].itemaProp, 'prop-1'); assert.equal(stamped1[0].indexa, 0); assert.equal(stamped1[1].itembProp, 'prop-1-1'); assert.equal(stamped1[1].indexa, 0); assert.equal(stamped1[1].indexb, 0); assert.equal(stamped1[2].itemcProp, 'prop-1-1-1'); assert.equal(stamped1[2].indexa, 0); assert.equal(stamped1[2].indexb, 0); assert.equal(stamped1[2].indexc, 0); assert.equal(stamped1[13].itemaProp, 'prop-3'); assert.equal(stamped1[13].indexa, 1); assert.equal(stamped1[14].itembProp, 'prop-3-1'); assert.equal(stamped1[14].indexa, 1); assert.equal(stamped1[14].indexb, 0); assert.equal(stamped1[15].itemcProp, 'prop-3-1-1'); assert.equal(stamped1[15].indexa, 1); assert.equal(stamped1[15].indexb, 0); assert.equal(stamped1[15].indexc, 0); assert.equal(stamped2[0].itemaProp, 'prop-1'); assert.equal(stamped2[0].indexa, 0);