angular-cn/packages/zone.js/test/browser/registerElement.spec.ts

172 lines
5.4 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/*
* check that document.registerElement(name, { prototype: proto });
* is properly patched
*/
import {ifEnvSupports} from '../test-util';
function registerElement() {
return ('registerElement' in document) && (typeof customElements === 'undefined');
}
(<any>registerElement).message = 'document.registerElement';
describe(
'document.registerElement', ifEnvSupports(registerElement, function() {
// register a custom element for each callback
const callbackNames = ['created', 'attached', 'detached', 'attributeChanged'];
const callbacks: any = {};
const testZone = Zone.current.fork({name: 'test'});
let customElements;
customElements = testZone.run(function() {
callbackNames.forEach(function(callbackName) {
const fullCallbackName = callbackName + 'Callback';
const proto = Object.create(HTMLElement.prototype);
(proto as any)[fullCallbackName] = function(arg: any) {
callbacks[callbackName](arg);
};
(<any>document).registerElement('x-' + callbackName.toLowerCase(), {prototype: proto});
});
});
it('should work with createdCallback', function(done) {
callbacks.created = function() {
expect(Zone.current).toBe(testZone);
done();
};
document.createElement('x-created');
});
it('should work with attachedCallback', function(done) {
callbacks.attached = function() {
expect(Zone.current).toBe(testZone);
done();
};
const elt = document.createElement('x-attached');
document.body.appendChild(elt);
document.body.removeChild(elt);
});
it('should work with detachedCallback', function(done) {
callbacks.detached = function() {
expect(Zone.current).toBe(testZone);
done();
};
const elt = document.createElement('x-detached');
document.body.appendChild(elt);
document.body.removeChild(elt);
});
it('should work with attributeChanged', function(done) {
callbacks.attributeChanged = function() {
expect(Zone.current).toBe(testZone);
done();
};
const elt = document.createElement('x-attributechanged');
elt.id = 'bar';
});
it('should work with non-writable, non-configurable prototypes created with defineProperty',
function(done) {
testZone.run(function() {
const proto = Object.create(HTMLElement.prototype);
Object.defineProperty(
proto, 'createdCallback',
<any>{writable: false, configurable: false, value: checkZone});
(<any>document).registerElement('x-prop-desc', {prototype: proto});
function checkZone() {
expect(Zone.current).toBe(testZone);
done();
}
});
const elt = document.createElement('x-prop-desc');
});
it('should work with non-writable, non-configurable prototypes created with defineProperties',
function(done) {
testZone.run(function() {
const proto = Object.create(HTMLElement.prototype);
Object.defineProperties(proto, {
createdCallback: <any> {
writable: false, configurable: false, value: checkZone
}
});
(<any>document).registerElement('x-props-desc', {prototype: proto});
function checkZone() {
expect(Zone.current).toBe(testZone);
done();
}
});
const elt = document.createElement('x-props-desc');
});
it('should not throw with frozen prototypes ', function() {
testZone.run(function() {
const proto = Object.create(HTMLElement.prototype, Object.freeze(<PropertyDescriptorMap>{
createdCallback: <PropertyDescriptor> {
value: () => {}, writable: true, configurable: true
}
}));
Object.defineProperty(
proto, 'createdCallback', <any>{writable: false, configurable: false});
expect(function() {
(<any>document).registerElement('x-frozen-desc', {prototype: proto});
}).not.toThrow();
});
});
it('should check bind callback if not own property', function(done) {
testZone.run(function() {
const originalProto = {createdCallback: checkZone};
const secondaryProto = Object.create(originalProto);
expect(secondaryProto.createdCallback).toBe(originalProto.createdCallback);
(<any>document).registerElement('x-inherited-callback', {prototype: secondaryProto});
expect(secondaryProto.createdCallback).not.toBe(originalProto.createdCallback);
function checkZone() {
expect(Zone.current).toBe(testZone);
done();
}
const elt = document.createElement('x-inherited-callback');
});
});
it('should not throw if no options passed to registerElement', function() {
expect(function() {
(<any>document).registerElement('x-no-opts');
}).not.toThrow();
});
}));