@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
357 lines (307 loc) • 13.4 kB
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="attributes-elements.html">
<body>
<test-fixture id="basic">
<template>
<x-basic attr3="instance"></x-basic>
</template>
</test-fixture>
<test-fixture id="compose">
<template>
<x-compose></x-compose>
</template>
</test-fixture>
<test-fixture id="basic-with-attributes">
<template>
<x-basic
object='{"foo": "bar", "nested": {"meaning": 42}, "arr": [0, "foo", true]}'
array='[0, "foo", true, {"foo": "bar"}]'
number="42"
string="The quick brown fox"
bool
date="Wed Mar 04 2015 10:46:05 GMT-0800 (PST)"
-u-p-c-a-s-e="The quick brown fox"
dash-case="The quick brown fox"
no-type="Should be String"
read-only="Should not change"
class="Should not deserialize"
nard="Should not deserialize"
behavior-bool
behavior-number="77"
shorthand-bool
shorthand-number="88"
behavior-shorthand-bool
behavior-shorthand-number="99"
foreign-type-object-prop="The quick brown fox">
</x-basic>
</template>
</test-fixture>
<test-fixture id="reflect-to-attribute">
<template>
<x-reflect></x-reflect>
</template>
</test-fixture>
<test-fixture id="reflect-to-attribute-and-attributes">
<template>
<x-reflect
object='{"foo": "bar", "nested": {"meaning": 42}, "arr": [0, "foo", true]}'
array='[0, "foo", true, {"foo": "bar"}]'
number="42"
string="The quick brown fox"
bool
date="Wed Mar 04 2015 10:46:05 GMT-0800 (PST)"
dash-case="The quick brown fox"
-u-p-c-a-s-e="The quick brown fox"
no-type="Should be String"
read-only="Should not change"
class="Should not deserialize"
nard="Should not deserialize"
behavior-bool
behavior-number="77"
shorthand-bool
shorthand-number="88"
behavior-shorthand-bool
behavior-shorthand-number="99"
foreign-type-object-prop="The quick brown fox">
</x-reflect>
</template>
</test-fixture>
<script>
suite('create-time deserialization', function() {
function testAttributesMatchDefaults(element) {
assert.deepEqual(element.object, {});
assert.deepEqual(element.array, []);
assert.strictEqual(element.number, 0);
assert.strictEqual(element.string, 'none');
assert.strictEqual(element.bool, true);
assert.strictEqual(element.negBool, false);
assert.strictEqual(element.date.getTime(), 0);
assert.strictEqual(element.dashCase, 'none');
assert.strictEqual(element.UPCASE, 'none');
assert.strictEqual(element.noType, 'none');
assert.strictEqual(element.readOnly, 'default');
assert.strictEqual(element.behaviorNumber, 11);
assert.strictEqual(element.behaviorBool, false);
assert.strictEqual(element.shorthandNumber, undefined);
assert.strictEqual(element.shorthandBool, undefined);
assert.strictEqual(element.behaviorShorthandNumber, undefined);
assert.strictEqual(element.behaviorShorthandBool, undefined);
assert.strictEqual(element.foreignTypeObjectProp, 'none');
}
function testAttributesMatchCustomConfiguration(element) {
var configuredObject = {foo: 'bar', nested: {'meaning': 42}, arr: [0, 'foo', true]};
var configuredArray = [0, 'foo', true, {foo: 'bar'}];
var configuredString = "The quick brown fox";
var configuredTime = 1425494765000;
assert.deepEqual(element.object, configuredObject);
assert.deepEqual(element.array, configuredArray);
assert.strictEqual(element.number, 42);
assert.strictEqual(element.string, 'The quick brown fox');
assert.strictEqual(element.bool, true);
assert.strictEqual(element.negBool, false);
assert.strictEqual(element.date.getTime(), configuredTime);
assert.strictEqual(element.dashCase, configuredString);
assert.strictEqual(element.UPCASE, configuredString);
assert.strictEqual(element.noType, 'Should be String');
assert.strictEqual(element.readOnly, 'default');
assert.strictEqual(element.class, undefined);
assert.strictEqual(element.nard, undefined);
assert.strictEqual(element.behaviorNumber, 77);
assert.strictEqual(element.behaviorBool, true);
assert.strictEqual(element.shorthandNumber, 88);
assert.strictEqual(element.shorthandBool, true);
assert.strictEqual(element.behaviorShorthandNumber, 99);
assert.strictEqual(element.behaviorShorthandBool, true);
assert.strictEqual(element.foreignTypeObjectProp, configuredString);
}
test('basic default values', function() {
var element = fixture('basic');
testAttributesMatchDefaults(element);
});
test('basic deserialize attributes', function() {
var element = fixture('basic-with-attributes');
testAttributesMatchCustomConfiguration(element);
});
test('reflected default values', function() {
var element = fixture('reflect-to-attribute');
testAttributesMatchDefaults(element);
});
test('reflected deserialize attributes', function() {
var element = fixture('reflect-to-attribute-and-attributes');
testAttributesMatchCustomConfiguration(element);
});
test('reflected warned about reflection for UPCASE', function() {
var element = fixture('reflect-to-attribute');
assert.isTrue(element.__warnedAboutUPCASE = true);
});
});
suite('imperative attribute change (no-reflect)', function() {
var element, configuredObject, configuredArray;
setup(function() {
element = fixture('basic');
configuredObject = {foo: 'bar', nested: {'meaning': 42}, arr: [0, 'foo', true]};
configuredArray = [0, 'foo', true, {foo: 'bar'}];
});
test('change object attribute', function() {
element.setAttribute('object', '{"foo": "bar", "nested": {"meaning": 42}, "arr": [0, "foo", true]}');
assert.deepEqual(element.object, configuredObject);
});
test('change object attribute to foreign type', function() {
element.setAttribute('object', 'The quick brown fox');
assert.strictEqual(element.object, 'The quick brown fox');
});
test('change array attribute', function() {
element.setAttribute('array', '[0, "foo", true, {"foo": "bar"}]');
assert.deepEqual(element.array, configuredArray);
});
test('change number attribute', function() {
element.setAttribute('number', 42);
assert.strictEqual(element.number, 42);
});
test('change string attribute', function() {
element.setAttribute('string', 'howdy');
assert.strictEqual(element.string, 'howdy');
});
test('change boolean attribute true', function() {
element.setAttribute('bool', '');
assert.strictEqual(element.bool, true);
});
test('change boolean attribute truthy', function() {
element.setAttribute('bool', 'sure!');
assert.strictEqual(element.bool, true);
});
test('change boolean attribute false', function() {
element.setAttribute('bool', '');
assert.strictEqual(element.bool, true);
element.removeAttribute('bool');
assert.strictEqual(element.bool, false);
});
test('change dashCase attribute', function() {
element.setAttribute('dash-case', 'Changed');
assert.strictEqual(element.dashCase, 'Changed');
});
test('value that cannot deserialize from JSON warns', function() {
sinon.spy(console, 'warn');
var badAttr = '[foo, bar]';
element.setAttribute('array', badAttr);
assert.isTrue(console.warn.calledOnce);
assert.include(console.warn.firstCall.args[0], badAttr);
console.warn.restore();
});
});
suite('imperative attribute change (reflect)', function() {
var element, configuredObject, configuredArray;
setup(function() {
element = fixture('reflect-to-attribute');
configuredObject = {foo: 'bar', nested: {'meaning': 42}, arr: [0, 'foo', true]};
configuredArray = [0, 'foo', true, {foo: 'bar'}];
});
test('change object attribute', function() {
element.setAttribute('object', '{"foo": "bar", "nested": {"meaning": 42}, "arr": [0, "foo", true]}');
assert.deepEqual(element.object, configuredObject);
});
test('change object attribute to foreign type', function() {
element.setAttribute('object', 'The quick brown fox');
assert.strictEqual(element.object, 'The quick brown fox');
});
test('change array attribute', function() {
element.setAttribute('array', '[0, "foo", true, {"foo": "bar"}]');
assert.deepEqual(element.array, configuredArray);
});
test('change number attribute', function() {
element.setAttribute('number', 42);
assert.strictEqual(element.number, 42);
});
test('change string attribute', function() {
element.setAttribute('string', 'howdy');
assert.strictEqual(element.string, 'howdy');
});
test('change boolean attribute true', function() {
element.setAttribute('bool', '');
assert.strictEqual(element.bool, true);
});
test('change boolean attribute truthy', function() {
element.setAttribute('bool', 'sure!');
assert.strictEqual(element.bool, true);
});
test('change boolean attribute false', function() {
element.setAttribute('bool', '');
assert.strictEqual(element.bool, true);
element.removeAttribute('bool');
assert.strictEqual(element.bool, false);
});
test('change dashCase attribute', function() {
element.setAttribute('dash-case', 'Changed');
assert.strictEqual(element.dashCase, 'Changed');
});
test('change non-`properties` property that natively reflects', function() {
element.title = 'awesome';
assert.strictEqual(element.title, 'awesome');
element.title = '';
assert.strictEqual(element.title, '');
element.setAttribute('title', 'super');
assert.strictEqual(element.title, 'super');
element.removeAttribute('title');
assert.strictEqual(element.title, '');
});
});
suite('hostAttributes', function() {
var configuredObject;
setup(function() {
configuredObject = {foo: 'bar', nested: {'meaning': 42}, arr: [0, 'foo', true]};
});
test('hostAttributes set correctly', function() {
var element = fixture('basic');
assert.strictEqual(element.getAttribute('attr1'), 'this is attr 1');
assert.strictEqual(element.getAttribute('attr2'), '42');
assert.strictEqual(element.getAttribute('attr3'), 'instance', 'host attribute overrode instance attribute and should not');
assert.strictEqual(element.getAttribute('aria-role'), 'button');
assert.strictEqual(element.getAttribute('title'), 'awesome');
assert.strictEqual(element.title, 'awesome');
assert.equal(element.getAttribute('attr-object'), JSON.stringify(configuredObject));
assert.equal(element.hasAttribute('attr-stupid'), false);
// class *is* serialized
// BREAKME(sorvell): document breaking change.
assert.ok(element.classList.contains('foo'));
assert.ok(element.classList.contains('bar'));
assert.ok(element.classList.contains('baz'));
});
test('hostAttributes set correctly in composed element', function() {
var element = fixture('compose');
assert.strictEqual(element.$.basic.getAttribute('attr1'), 'compose');
assert.strictEqual(element.$.basic.getAttribute('attr2'), '42');
assert.strictEqual(element.$.basic.getAttribute('aria-role'), 'button');
assert.strictEqual(element.$.basic.getAttribute('title'), 'awesome');
assert.strictEqual(element.$.basic.title, 'awesome');
assert.equal(element.$.basic.getAttribute('attr-object'), JSON.stringify(configuredObject));
assert.equal(element.$.basic.hasAttribute('attr-stupid'), false);
// class does not overwrite user setting
assert.notOk(element.$.basic.classList.contains('foo'));
assert.notOk(element.$.basic.classList.contains('bar'));
assert.notOk(element.$.basic.classList.contains('baz'));
assert(element.$.basic.classList.contains('should-not-override'));
// applied to property with effect
assert.strictEqual(element.$.basic.prop, 'compose');
assert.equal(element.$.basic.propChangedCount, 1);
assert.equal(element.$.basic.attr1ChangedCount, 1);
assert.equal(element.prop2, 'hi');
});
});
</script>
</body>
</html>