summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html')
-rw-r--r--chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html351
1 files changed, 351 insertions, 0 deletions
diff --git a/chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html b/chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html
new file mode 100644
index 00000000000..2194e147904
--- /dev/null
+++ b/chromium/third_party/catapult/third_party/polymer2/bower_components/test-fixture/test-fixture.html
@@ -0,0 +1,351 @@
+<!--
+@license
+Copyright (c) 2015 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
+-->
+
+<!--
+
+The `<test-fixture>` element can simplify the exercise of consistently
+resetting a test suite's DOM. To use it, wrap the test suite's DOM as a template:
+
+```html
+<test-fixture id="SomeElementFixture">
+ <template>
+ <some-element id="SomeElementForTesting"></some-element>
+ </template>
+</test-fixture>
+```
+
+Now, the `<test-fixture>` element can be used to generate a copy of its
+template:
+
+```html
+<script>
+describe('<some-element>', function () {
+ var someElement;
+
+ beforeEach(function () {
+ document.getElementById('SomeElementFixture').create();
+ someElement = document.getElementById('SomeElementForTesting');
+ });
+});
+</script>
+```
+
+Fixtured elements can be cleaned up by calling `restore` on the `<test-fixture>`:
+
+```javascript
+ afterEach(function () {
+ document.getElementById('SomeElementFixture').restore();
+ // <some-element id='SomeElementForTesting'> has been removed
+ });
+```
+
+`<test-fixture>` will create fixtures from all of its immediate `<template>`
+children. The DOM structure of fixture templates can be as simple or as complex
+as the situation calls for.
+
+## Even simpler usage in Mocha
+
+In Mocha, usage can be simplified even further. Include `test-fixture-mocha.js`
+after Mocha in the `<head>` of your document and then fixture elements like so:
+
+```html
+<script>
+describe('<some-element>', function () {
+ var someElement;
+
+ beforeEach(function () {
+ someElement = fixture('SomeElementFixture');
+ });
+});
+</script>
+```
+
+Fixtured elements will be automatically restored in the `afterEach` phase of the
+current Mocha `Suite`.
+
+## Data-bound templates
+
+Data-binding systems are also supported, as long as your (custom) template
+elements define a `stamp(model)` method that returns a document fragment. This
+allows you to stamp out templates w/ custom models for your fixtures.
+
+For example, using Polymer 0.8's `dom-template`:
+
+```html
+<test-fixture id="bound">
+ <template is="dom-template">
+ <span>{{greeting}}</span>
+ </template>
+</test-fixture>
+```
+
+You can pass an optional context argument to `create()` or `fixture()` to pass
+the model:
+
+```js
+var bound = fixture('bound', {greeting: 'ohai thurr'});
+```
+
+## The problem being addressed
+
+Consider the following `web-component-tester` test suite:
+
+```html
+<!doctype html>
+<html>
+<head>
+ <title>some-element test suite</title>
+
+ <link rel="import" href="../some-element.html">
+</head>
+<body>
+ <some-element id="SomeElementForTesting"></some-element>
+ <script>
+describe('<some-element>', function () {
+ var someElement;
+
+ beforeEach(function () {
+ someElement = document.getElementById('SomeElementForTesting');
+ });
+
+ it('can receive property `foo`', function () {
+ someElement.foo = 'bar';
+ expect(someElement.foo).to.be.equal('bar');
+ });
+
+ it('has a default `foo` value of `undefined`', function () {
+ expect(someElement.foo).to.be.equal(undefined);
+ });
+});
+ </script>
+</body>
+</html>
+```
+
+In this contrived example, the suite will pass or fail depending on which order
+the tests are run in. It is non-deterministic because `someElement` has
+internal state that is not properly reset at the end of each test.
+
+It would be trivial in the above example to simply reset `someElement.foo` to
+the expected default value of `undefined` in an `afterEach` hook. However, for
+non-contrived test suites that target complex elements, this can result in a
+large quantity of ever-growing set-up and tear-down boilerplate.
+
+@pseudoElement test-fixture
+ -->
+
+<script>
+
+(function () {
+ var TestFixturePrototype = Object.create(HTMLElement.prototype);
+ var TestFixtureExtension = {
+ _fixtureTemplates: null,
+
+ _elementsFixtured: false,
+
+ get elementsFixtured () {
+ return this._elementsFixtured;
+ },
+
+ get fixtureTemplates () {
+ if (!this._fixtureTemplates) {
+ // Copy fixtures to a true Array for Safari 7. This prevents their
+ // `content` property from being improperly garbage collected.
+ this._fixtureTemplates = Array.prototype.slice.apply(this.querySelectorAll('template'));
+ }
+
+ return this._fixtureTemplates;
+ },
+
+ create: function (model) {
+ var generatedDoms = [];
+
+ this.restore();
+
+ this.removeElements(this.fixtureTemplates);
+
+ this.forElements(this.fixtureTemplates, function (fixtureTemplate) {
+ generatedDoms.push(
+ this.createFrom(fixtureTemplate, model)
+ );
+ }, this);
+
+ this.forcePolyfillAttachedStateSynchrony();
+
+ if (generatedDoms.length < 2) {
+ return generatedDoms[0];
+ }
+
+ return generatedDoms;
+ },
+
+ createFrom: function (fixtureTemplate, model) {
+ var fixturedFragment;
+ var fixturedElements;
+ var fixturedElement;
+
+ if (!(fixtureTemplate &&
+ fixtureTemplate.tagName === 'TEMPLATE')) {
+ return;
+ }
+
+ try {
+ fixturedFragment = this.stamp(fixtureTemplate, model);
+ } catch (error) {
+ console.error('Error stamping', fixtureTemplate, error);
+ throw error;
+ }
+
+ fixturedElements = this.collectElementChildren(fixturedFragment);
+
+ this.appendChild(fixturedFragment);
+ this._elementsFixtured = true;
+
+ if (fixturedElements.length < 2) {
+ return fixturedElements[0];
+ }
+
+ return fixturedElements;
+ },
+
+ restore: function () {
+ if (!this._elementsFixtured) {
+ return;
+ }
+
+ this.removeElements(this.children);
+
+ this.forElements(this.fixtureTemplates, function (fixtureTemplate) {
+ this.appendChild(fixtureTemplate);
+ }, this);
+
+ this.generatedDomStack = [];
+
+ this._elementsFixtured = false;
+
+ this.forcePolyfillAttachedStateSynchrony();
+ },
+
+ forcePolyfillAttachedStateSynchrony: function () {
+ // Force synchrony in attachedCallback and detachedCallback where
+ // implemented, in the event that we are dealing with one of these async
+ // polyfills:
+ // 1. Web Components CustomElements polyfill (v1 or v0).
+ if (window.customElements && window.customElements.flush) {
+ window.customElements.flush();
+ } else if (window.CustomElements && window.CustomElements.takeRecords) {
+ window.CustomElements.takeRecords();
+ }
+ // 2. ShadyDOM polyfill.
+ if (window.ShadyDOM && window.ShadyDOM.flush) {
+ window.ShadyDOM.flush();
+ }
+ },
+
+ collectElementChildren: function (parent) {
+ // Note: Safari 7.1 does not support `firstElementChild` or
+ // `nextElementSibling`, so we do things the old-fashioned way:
+ var elements = [];
+ var child = parent.firstChild;
+
+ while (child) {
+ if (child.nodeType === Node.ELEMENT_NODE) {
+ elements.push(child);
+ }
+
+ child = child.nextSibling;
+ }
+
+ return elements;
+ },
+
+ removeElements: function (elements) {
+ this.forElements(elements, function (element) {
+ this.removeChild(element);
+ }, this);
+ },
+
+ forElements: function (elements, iterator, context) {
+ Array.prototype.slice.call(elements)
+ .forEach(iterator, context);
+ },
+
+ stamp: function (fixtureTemplate, model) {
+ var stamped;
+ // Check if we are dealing with a "stampable" `<template>`. This is a
+ // vaguely defined special case of a `<template>` that is a custom
+ // element with a public `stamp` method that implements some manner of
+ // data binding.
+ if (fixtureTemplate.stamp) {
+ stamped = fixtureTemplate.stamp(model);
+ // We leak Polymer specifics a little; if there is an element `root`, we
+ // want that to be returned.
+ stamped = stamped.root || stamped;
+
+ // Otherwise, we fall back to standard HTML templates, which do not have
+ // any sort of binding support.
+ } else {
+ if (model) {
+ console.warn(this, 'was given a model to stamp, but the template is not of a bindable type');
+ }
+
+ stamped = document.importNode(fixtureTemplate.content, true);
+
+ // Immediately upgrade the subtree if we are dealing with async
+ // Web Components polyfill.
+ // https://github.com/Polymer/polymer/blob/0.8-preview/src/features/mini/template.html#L52
+ if (window.CustomElements && window.CustomElements.upgradeSubtree) {
+ window.CustomElements.upgradeSubtree(stamped);
+ }
+ }
+
+ return stamped;
+ }
+ };
+
+ Object.getOwnPropertyNames(TestFixtureExtension)
+ .forEach(function (property) {
+ Object.defineProperty(
+ TestFixturePrototype,
+ property,
+ Object.getOwnPropertyDescriptor(TestFixtureExtension, property)
+ );
+ });
+
+ try {
+ if (window.customElements) {
+ function TestFixture() {
+ return ((window.Reflect && Reflect.construct) ?
+ Reflect.construct(HTMLElement, [], TestFixture)
+ : HTMLElement.call(this)) || this;
+ }
+ TestFixture.prototype = TestFixturePrototype;
+ // `constructor` is not writable on Safari 9, but is configurable.
+ Object.defineProperty(TestFixture.prototype, 'constructor', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: TestFixture,
+ });
+ window.customElements.define('test-fixture', TestFixture);
+ } else {
+ document.registerElement('test-fixture', {
+ prototype: TestFixturePrototype
+ });
+ }
+ } catch (e) {
+ if (window.WCT) {
+ console.warn('if you are using WCT, you do not need to manually import test-fixture.html');
+ } else {
+ console.warn('test-fixture has already been registered!');
+ }
+ }
+})();
+</script>