From c631cfc2fd24eac8e9fc72d0c6d92702d6f28104 Mon Sep 17 00:00:00 2001 From: Victor Savkin Date: Fri, 19 Aug 2016 16:05:34 -0700 Subject: [PATCH] feat(core): add NO_ERRORS_SCHEMA that allows any properties to be set on any element (#10956) Often it is useful to test a component without rendering certain directives/components in its template because these directives require some complicated setup. You can do that by using NO_ERRORS_SCHEMA. TestBed.configureTestingModule({ schemas: [NO_ERRORS_SCHEMA] }); This would disable all schema checks in your tests. --- .../compiler/src/schema/dom_element_schema_registry.ts | 7 ++++++- .../test/schema/dom_element_schema_registry_spec.ts | 7 ++++++- modules/@angular/core/src/metadata.ts | 2 +- modules/@angular/core/src/metadata/ng_module.ts | 9 +++++++++ tools/public_api_guard/core/index.d.ts | 3 +++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/modules/@angular/compiler/src/schema/dom_element_schema_registry.ts b/modules/@angular/compiler/src/schema/dom_element_schema_registry.ts index 99d3199a32..97982ead63 100644 --- a/modules/@angular/compiler/src/schema/dom_element_schema_registry.ts +++ b/modules/@angular/compiler/src/schema/dom_element_schema_registry.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {CUSTOM_ELEMENTS_SCHEMA, Injectable, SchemaMetadata, SecurityContext} from '@angular/core'; +import {CUSTOM_ELEMENTS_SCHEMA, Injectable, NO_ERRORS_SCHEMA, SchemaMetadata, SecurityContext} from '@angular/core'; import {StringMapWrapper} from '../facade/collection'; import {isPresent} from '../facade/lang'; @@ -270,6 +270,10 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { } hasProperty(tagName: string, propName: string, schemaMetas: SchemaMetadata[]): boolean { + if (schemaMetas.some((schema) => schema.name === NO_ERRORS_SCHEMA.name)) { + return true; + } + if (tagName.indexOf('-') !== -1) { if (tagName === 'ng-container' || tagName === 'ng-content') { return false; @@ -280,6 +284,7 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry { return true; } } + var elementProperties = this.schema[tagName.toLowerCase()]; if (!isPresent(elementProperties)) { elementProperties = this.schema['unknown']; diff --git a/modules/@angular/compiler/test/schema/dom_element_schema_registry_spec.ts b/modules/@angular/compiler/test/schema/dom_element_schema_registry_spec.ts index d3a68f47cd..968a391d06 100644 --- a/modules/@angular/compiler/test/schema/dom_element_schema_registry_spec.ts +++ b/modules/@angular/compiler/test/schema/dom_element_schema_registry_spec.ts @@ -7,7 +7,7 @@ */ import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry'; -import {CUSTOM_ELEMENTS_SCHEMA, SecurityContext} from '@angular/core'; +import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, SecurityContext} from '@angular/core'; import {beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {browserDetection} from '@angular/platform-browser/testing/browser_util'; @@ -59,6 +59,11 @@ export function main() { expect(registry.hasProperty('custom-like', 'unknown', [CUSTOM_ELEMENTS_SCHEMA])).toBeTruthy(); }); + it('should return true for all elements if the NO_ERRORS_SCHEMA was used', () => { + expect(registry.hasProperty('custom-like', 'unknown', [NO_ERRORS_SCHEMA])).toBeTruthy(); + expect(registry.hasProperty('a', 'unknown', [NO_ERRORS_SCHEMA])).toBeTruthy(); + }); + it('should re-map property names that are specified in DOM facade', () => { expect(registry.getMappedPropName('readonly')).toEqual('readOnly'); }); diff --git a/modules/@angular/core/src/metadata.ts b/modules/@angular/core/src/metadata.ts index d50cdca297..43dc88b449 100644 --- a/modules/@angular/core/src/metadata.ts +++ b/modules/@angular/core/src/metadata.ts @@ -21,7 +21,7 @@ import {TypeDecorator, makeDecorator, makeParamDecorator, makePropDecorator} fro export {ANALYZE_FOR_ENTRY_COMPONENTS, AttributeMetadata, ContentChildMetadata, ContentChildrenMetadata, QueryMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata} from './metadata/di'; export {ComponentMetadata, ComponentMetadataType, DirectiveMetadata, DirectiveMetadataType, HostBindingMetadata, HostListenerMetadata, InputMetadata, OutputMetadata, PipeMetadata, PipeMetadataType} from './metadata/directives'; export {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnDestroy, OnInit} from './metadata/lifecycle_hooks'; -export {CUSTOM_ELEMENTS_SCHEMA, ModuleWithProviders, NgModuleMetadata, NgModuleMetadataType, SchemaMetadata} from './metadata/ng_module'; +export {CUSTOM_ELEMENTS_SCHEMA, ModuleWithProviders, NO_ERRORS_SCHEMA, NgModuleMetadata, NgModuleMetadataType, SchemaMetadata} from './metadata/ng_module'; export {ViewEncapsulation} from './metadata/view'; diff --git a/modules/@angular/core/src/metadata/ng_module.ts b/modules/@angular/core/src/metadata/ng_module.ts index 321ea0a3f1..fbf163b5fa 100644 --- a/modules/@angular/core/src/metadata/ng_module.ts +++ b/modules/@angular/core/src/metadata/ng_module.ts @@ -36,6 +36,15 @@ export const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = { name: 'custom-elements' }; +/** + * Defines a schema that will allow any property on any element. + * + * @experimental + */ +export const NO_ERRORS_SCHEMA: SchemaMetadata = { + name: 'no-errors-schema' +}; + /** * Interface for creating {@link NgModuleMetadata} * @experimental diff --git a/tools/public_api_guard/core/index.d.ts b/tools/public_api_guard/core/index.d.ts index a55ab9f16e..f5e43719bd 100644 --- a/tools/public_api_guard/core/index.d.ts +++ b/tools/public_api_guard/core/index.d.ts @@ -840,6 +840,9 @@ export declare class NgZone { static isInAngularZone(): boolean; } +/** @experimental */ +export declare const NO_ERRORS_SCHEMA: SchemaMetadata; + /** @stable */ export declare class NoAnnotationError extends BaseException { constructor(typeOrFunc: Type | Function, params: any[][]);