mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
512 lines
12 KiB
HTML
512 lines
12 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-bundle.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>
|
|
<body>
|
|
|
|
<dom-module id="behavior-registered">
|
|
<template>
|
|
<div id="content"></div>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
window.BehaviorA = {
|
|
properties: {
|
|
|
|
label: {
|
|
type: String,
|
|
observer: '_labelChanged'
|
|
},
|
|
|
|
hasOptionsA: {
|
|
readOnly: true,
|
|
notify: true
|
|
},
|
|
|
|
overridableProperty: {
|
|
value: false
|
|
},
|
|
|
|
overridablePropertyB: {
|
|
value: false
|
|
},
|
|
|
|
hasBehaviorA: {
|
|
value: true
|
|
},
|
|
|
|
computeADependency: {
|
|
value: true
|
|
},
|
|
|
|
computeA: {
|
|
computed: '_computeProp(computeADependency)'
|
|
}
|
|
},
|
|
|
|
_simpleProperty: 'A',
|
|
|
|
hostAttributes: {
|
|
behavior: 'A',
|
|
element: 'A',
|
|
user: 'A'
|
|
},
|
|
|
|
listeners: {
|
|
change: '_changeHandler'
|
|
},
|
|
|
|
ready: function() {
|
|
this.__readyA = true;
|
|
},
|
|
|
|
_labelChanged: function(label) {
|
|
this.__label = label;
|
|
},
|
|
|
|
_changeHandler: function(e) {
|
|
this.__change = e.detail.value;
|
|
},
|
|
|
|
_computeProp: function(a) {
|
|
return a;
|
|
}
|
|
};
|
|
|
|
window.BehaviorB = {
|
|
properties: {
|
|
|
|
disabled: {
|
|
type: Boolean,
|
|
value: false,
|
|
observer: '_disabledChanged'
|
|
},
|
|
|
|
hasOptionsB: {
|
|
readOnly: true,
|
|
notify: true
|
|
},
|
|
|
|
hasBehaviorB: {
|
|
value: true
|
|
},
|
|
|
|
overridablePropertyB: {
|
|
value: true
|
|
},
|
|
|
|
computeADependencyDependency: {
|
|
value: 'hi'
|
|
},
|
|
|
|
computeADependency: {
|
|
computed: '_computeProp(computeADependencyDependency)'
|
|
}
|
|
|
|
},
|
|
|
|
hostAttributes: {
|
|
behavior: 'B',
|
|
element: 'B',
|
|
user: 'B'
|
|
},
|
|
|
|
_simpleProperty: 'B',
|
|
|
|
_disabledChanged: function(disabled) {
|
|
this.__disabled = disabled;
|
|
},
|
|
|
|
ready: function() {
|
|
this.__readyB = true;
|
|
},
|
|
};
|
|
|
|
window.BehaviorC = {
|
|
|
|
properties: {
|
|
|
|
hasBehaviorC: {
|
|
value: true
|
|
}
|
|
|
|
},
|
|
|
|
_simpleProperty: 'C'
|
|
};
|
|
|
|
window.BehaviorD = {
|
|
|
|
properties: {
|
|
|
|
hasBehaviorD: {
|
|
value: true
|
|
}
|
|
|
|
},
|
|
_simpleProperty: 'D'
|
|
|
|
};
|
|
|
|
Polymer({
|
|
is: 'single-behavior',
|
|
|
|
behaviors: [
|
|
window.BehaviorA
|
|
],
|
|
|
|
properties: {},
|
|
observers: [],
|
|
hostAttributes: {},
|
|
listeners: {}
|
|
});
|
|
|
|
Polymer({
|
|
is: 'multi-behaviors',
|
|
|
|
behaviors: [
|
|
window.BehaviorA,
|
|
window.BehaviorB
|
|
],
|
|
|
|
hostAttributes: {
|
|
element: 'element'
|
|
},
|
|
|
|
properties: {
|
|
|
|
foo: {
|
|
type: String,
|
|
reflectToAttribute: true,
|
|
readOnly: true,
|
|
observer: '_fooChanged'
|
|
},
|
|
|
|
overridableProperty: {
|
|
value: true
|
|
}
|
|
|
|
},
|
|
|
|
_fooChanged: function(foo) {
|
|
this.__foo = foo;
|
|
},
|
|
});
|
|
|
|
Polymer({
|
|
is: 'nested-behaviors',
|
|
|
|
behaviors: [
|
|
[window.BehaviorB, [window.BehaviorC, window.BehaviorB], window.BehaviorA],
|
|
[window.BehaviorD]
|
|
]
|
|
});
|
|
|
|
window.registerBehavior1 ={
|
|
beforeRegister: function() {
|
|
this._createPropertyObserver('beforeProp', 'beforePropChanged1');
|
|
this.beforeRegisterCount++;
|
|
this.beforeRegisterBehaviors = this.behaviors;
|
|
},
|
|
registered: function() {
|
|
this._createPropertyObserver('prop', 'propChanged1');
|
|
this._createMethodObserver('propChanged2(prop)');
|
|
this.registeredCount++;
|
|
this.registeredProps = [this.prop1, this.prop2, this.prop3, this.prop4];
|
|
this.registeredBehaviors = this.behaviors;
|
|
},
|
|
prop1: true,
|
|
ready: function() {
|
|
this._ensureAttribute('attr', true);
|
|
},
|
|
beforePropChanged1: function() {
|
|
this.beforePropChangedCalled = true;
|
|
},
|
|
propChanged1: function() {
|
|
this.propChanged1Called = true;
|
|
},
|
|
propChanged2: function() {
|
|
this.propChanged2Called = true;
|
|
}
|
|
};
|
|
|
|
window.registerBehavior2 ={
|
|
prop2: true,
|
|
beforeRegister: function() {
|
|
this.beforeRegisterCount++;
|
|
},
|
|
registered: function() {
|
|
this.registeredCount++;
|
|
}
|
|
};
|
|
|
|
window.registerBehavior3 ={
|
|
prop3: true,
|
|
beforeRegister: function() {
|
|
this.beforeRegisterCount++;
|
|
},
|
|
registered: function() {
|
|
this.registeredCount++;
|
|
}
|
|
};
|
|
|
|
Polymer({
|
|
behaviors: [
|
|
window.registerBehavior1,
|
|
window.registerBehavior2,
|
|
window.registerBehavior3
|
|
],
|
|
prop4: true,
|
|
beforeRegister: function() {
|
|
this.beforeRegisterCount++;
|
|
},
|
|
registered: function() {
|
|
this.registeredCount++;
|
|
},
|
|
|
|
beforeRegisterCount: 0,
|
|
registeredCount: 0,
|
|
|
|
is: 'behavior-registered'
|
|
});
|
|
</script>
|
|
|
|
<test-fixture id="single">
|
|
<template>
|
|
<single-behavior></single-behavior>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<test-fixture id="multi">
|
|
<template>
|
|
<multi-behaviors user="user"></multi-behaviors>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<test-fixture id="nested">
|
|
<template>
|
|
<nested-behaviors></nested-behaviors>
|
|
</template>
|
|
</test-fixture>
|
|
|
|
<test-fixture id="registered">
|
|
<template>
|
|
<behavior-registered></behavior-registered>
|
|
</template>
|
|
</test-fixture>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
|
|
suite('single behavior element', function() {
|
|
var el;
|
|
|
|
setup(function() {
|
|
el = fixture('single');
|
|
});
|
|
|
|
test('is on prototype', function() {
|
|
assert.equal(el.is, 'single-behavior');
|
|
});
|
|
|
|
test('instance behaviors, properties, observers, hostAttributes, listeners', function() {
|
|
assert.isOk(el.behaviors);
|
|
assert.isOk(el.properties);
|
|
assert.isOk(el.observers);
|
|
assert.isOk(el.hostAttributes);
|
|
assert.isOk(el.listeners);
|
|
});
|
|
|
|
test('ready from behavior', function() {
|
|
assert.equal(el.__readyA, true);
|
|
});
|
|
|
|
test('properties from behavior', function() {
|
|
el.label = 'foo';
|
|
assert.equal(el.__label, 'foo');
|
|
});
|
|
|
|
test('listener from behavior', function() {
|
|
el.fire('change', {value: 'bar'});
|
|
assert.equal(el.__change, 'bar');
|
|
});
|
|
|
|
test('property info from behavior', function() {
|
|
assert.equal(el._hasNotifyEffect('hasOptionsA'), true);
|
|
assert.equal(el._hasReadOnlyEffect('hasOptionsA'), true);
|
|
assert.equal(typeof el._setHasOptionsA, 'function');
|
|
});
|
|
|
|
test('compute property from behavior', function() {
|
|
assert.equal(el.computeA, true);
|
|
});
|
|
|
|
});
|
|
|
|
suite('behavior.registered', function() {
|
|
test('can install dynamic properties', function() {
|
|
var el = fixture('registered');
|
|
assert.ok(el.$.content);
|
|
el.prop = 42;
|
|
assert.isTrue(el.propChanged1Called);
|
|
assert.isTrue(el.propChanged2Called);
|
|
assert.isTrue(el.hasAttribute('attr'));
|
|
});
|
|
|
|
test('called once for each behavior with access to element prototype', function() {
|
|
var el = fixture('registered');
|
|
assert.equal(el.registeredCount, 4);
|
|
assert.equal(el.registeredBehaviors.length, 3);
|
|
assert.equal(el.registeredBehaviors, el.behaviors);
|
|
assert.deepEqual(el.registeredProps, [true, true, true, true]);
|
|
});
|
|
|
|
});
|
|
|
|
suite('behavior.beforeRegister', function() {
|
|
test('can install dynamic properties', function() {
|
|
var el = fixture('registered');
|
|
assert.ok(el.$.content);
|
|
el.beforeProp = 43;
|
|
assert.isTrue(el.beforePropChangedCalled);
|
|
});
|
|
|
|
test('called once for each behavior with access to element prototype', function() {
|
|
var el = fixture('registered');
|
|
assert.equal(el.beforeRegisterCount, 4);
|
|
assert.equal(el.beforeRegisterBehaviors.length, 3);
|
|
assert.equal(el.beforeRegisterBehaviors, el.behaviors);
|
|
});
|
|
|
|
});
|
|
|
|
|
|
suite('multi-behaviors element', function() {
|
|
var el;
|
|
|
|
setup(function() {
|
|
el = fixture('multi');
|
|
});
|
|
|
|
test('ready from behaviors', function() {
|
|
assert.equal(el.__readyA, true);
|
|
assert.equal(el.__readyB, true);
|
|
});
|
|
|
|
test('properties from behaviors', function() {
|
|
el.label = 'foo';
|
|
assert.equal(el.__label, 'foo');
|
|
el.disabled = true;
|
|
assert.equal(el.__disabled, true);
|
|
});
|
|
|
|
test('properties from itself', function() {
|
|
assert.isDefined(el._setFoo, 'readOnly setter not available');
|
|
el._setFoo('bar');
|
|
assert.equal(el.__foo, 'bar', 'observer not getting called');
|
|
assert.equal(el.getAttribute('foo'), 'bar', 'not getting reflected');
|
|
});
|
|
|
|
test('listener from behaviors', function() {
|
|
el.fire('change', {value: 'bar'});
|
|
assert.equal(el.__change, 'bar');
|
|
});
|
|
|
|
test('property info from behavior A', function() {
|
|
assert.equal(el._hasNotifyEffect('hasOptionsA'), true);
|
|
assert.equal(el._hasReadOnlyEffect('hasOptionsA'), true);
|
|
assert.equal(typeof el._setHasOptionsA, 'function');
|
|
});
|
|
|
|
test('property info from behavior B', function() {
|
|
assert.equal(el._hasReadOnlyEffect('hasOptionsB'), true);
|
|
assert.equal(el._hasNotifyEffect('hasOptionsB'), true);
|
|
assert.equal(typeof el._setHasOptionsB, 'function');
|
|
});
|
|
|
|
test('computed property dependency can become a computed property', function() {
|
|
assert.equal(el.computeA, 'hi');
|
|
});
|
|
|
|
test('multi-behavior overrides ordering', function() {
|
|
assert(el.overridableProperty, 'Behavior property was not overridden by prototype');
|
|
assert(el.overridablePropertyB, 'Behavior config-property was not overridden by sub-behavior');
|
|
});
|
|
|
|
test('hostAttributes ordering', function() {
|
|
assert.equal(el.attributes.behavior.value, 'B', 'Behavior hostAttribute not overridden by younger behavior');
|
|
assert.equal(el.attributes.element.value, 'element', 'Behavior hostAttribute overridden by behavior');
|
|
assert.equal(el.attributes.user.value, 'user', 'Behavior hostAttribute overrode user attribute');
|
|
});
|
|
|
|
test('behavior is null generates warning', function() {
|
|
sinon.spy(console, 'warn');
|
|
Polymer({
|
|
is: 'behavior-null',
|
|
behaviors: [
|
|
null
|
|
]
|
|
});
|
|
document.createElement('behavior-null');
|
|
assert.equal(console.warn.callCount, 1, 'Null behaviour should generate warning');
|
|
console.warn.restore();
|
|
});
|
|
|
|
test('behavior array is unique', function() {
|
|
Polymer({
|
|
is: 'behavior-unique',
|
|
behaviors: [window.BehaviorA, window.BehaviorA]
|
|
});
|
|
assert.equal(document.createElement('behavior-unique').behaviors.length, 1);
|
|
});
|
|
|
|
test('duplicate behaviors keep first behavior', function() {
|
|
Polymer({
|
|
is: 'behavior-unique-last-behavior',
|
|
behaviors: [window.BehaviorA, window.BehaviorB, window.BehaviorC, window.BehaviorA, window.BehaviorB]
|
|
});
|
|
var behaviors = document.createElement('behavior-unique-last-behavior').behaviors;
|
|
assert.deepEqual(behaviors, [window.BehaviorC, window.BehaviorA, window.BehaviorB]);
|
|
});
|
|
|
|
});
|
|
|
|
suite('nested-behaviors element', function() {
|
|
var el;
|
|
|
|
setup(function() {
|
|
el = fixture('nested');
|
|
});
|
|
|
|
test('nested-behavior dedups', function() {
|
|
assert.equal(el.behaviors.length, 4);
|
|
});
|
|
|
|
test('nested-behavior overrides ordering', function() {
|
|
assert.ok(el.hasBehaviorA, "missing BehaviorA");
|
|
assert.ok(el.hasBehaviorB, "missing BehaviorB");
|
|
assert.ok(el.hasBehaviorC, "missing BehaviorC");
|
|
assert.ok(el.hasBehaviorD, "missing BehaviorD");
|
|
assert.equal(el._simpleProperty, 'D', 'Behavior simple property was not overridden by sub-behavior');
|
|
});
|
|
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|