diff --git a/goldens/public-api/core/testing/index.md b/goldens/public-api/core/testing/index.md index 9f0a46ddf6f..8c992385608 100644 --- a/goldens/public-api/core/testing/index.md +++ b/goldens/public-api/core/testing/index.md @@ -215,7 +215,6 @@ export class TestComponentRenderer { // @public (undocumented) export interface TestEnvironmentOptions { - errorOnUnknownElements?: boolean; teardown?: ModuleTeardownOptions; } @@ -226,7 +225,6 @@ export type TestModuleMetadata = { imports?: any[]; schemas?: Array; teardown?: ModuleTeardownOptions; - errorOnUnknownElements?: boolean; }; // @public diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 8785f48e49e..88d9f3ec85f 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -209,8 +209,6 @@ export { ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵviewQuery, - ɵgetUnknownElementStrictMode, - ɵsetUnknownElementStrictMode } from './render3/index'; export { LContext as ɵLContext, diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 26bcc889974..9e9a39e0ce0 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -129,8 +129,6 @@ export { ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, - ɵgetUnknownElementStrictMode, - ɵsetUnknownElementStrictMode } from './instructions/all'; export {ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp,ɵɵi18nPostprocess, ɵɵi18nStart} from './instructions/i18n'; export {RenderFlags} from './interfaces/definition'; diff --git a/packages/core/src/render3/instructions/element.ts b/packages/core/src/render3/instructions/element.ts index 79fdc1b32a8..e3da2ec4c42 100644 --- a/packages/core/src/render3/instructions/element.ts +++ b/packages/core/src/render3/instructions/element.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {formatRuntimeError, RuntimeError, RuntimeErrorCode} from '../../errors'; +import {formatRuntimeError, RuntimeErrorCode} from '../../errors'; import {SchemaMetadata} from '../../metadata/schema'; import {assertDefined, assertEqual, assertIndexInRange} from '../../util/assert'; import {assertFirstCreatePass, assertHasParent} from '../assert'; @@ -26,23 +26,7 @@ import {getConstant} from '../util/view_utils'; import {setDirectiveInputsWhichShadowsStyling} from './property'; import {createDirectivesInstances, executeContentQueries, getOrCreateTNode, matchingSchemas, resolveDirectives, saveResolvedLocalsInData} from './shared'; -let shouldThrowErrorOnUnknownElement = false; -/** - * Sets a strict mode for JIT-compiled components to throw an error on unknown elements, - * instead of just logging the error. - * (for AOT-compiled ones this check happens at build time). - */ -export function ɵsetUnknownElementStrictMode(shouldThrow: boolean) { - shouldThrowErrorOnUnknownElement = shouldThrow; -} - -/** - * Gets the current value of the strict mode. - */ -export function ɵgetUnknownElementStrictMode() { - return shouldThrowErrorOnUnknownElement; -} function elementStartFirstCreatePass( index: number, tView: TView, lView: LView, native: RElement, name: string, @@ -257,11 +241,7 @@ function validateElementIsKnown( message += `2. To allow any element add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.`; } - if (shouldThrowErrorOnUnknownElement) { - throw new RuntimeError(RuntimeErrorCode.UNKNOWN_ELEMENT, message); - } else { - console.error(formatRuntimeError(RuntimeErrorCode.UNKNOWN_ELEMENT, message)); - } + console.error(formatRuntimeError(RuntimeErrorCode.UNKNOWN_ELEMENT, message)); } } } diff --git a/packages/core/test/acceptance/ng_module_spec.ts b/packages/core/test/acceptance/ng_module_spec.ts index 1710f323129..ad2f3bbca7b 100644 --- a/packages/core/test/acceptance/ng_module_spec.ts +++ b/packages/core/test/acceptance/ng_module_spec.ts @@ -331,19 +331,6 @@ describe('NgModule', () => { expect(spy).not.toHaveBeenCalled(); }); - it('should throw an error about unknown element without CUSTOM_ELEMENTS_SCHEMA for element with dash in tag name', - () => { - @Component({template: ``}) - class MyComp { - } - - TestBed.configureTestingModule({declarations: [MyComp], errorOnUnknownElements: true}); - expect(() => { - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - }).toThrowError(/NG0304: 'custom-el' is not a known element/g); - }); - it('should log an error about unknown element without CUSTOM_ELEMENTS_SCHEMA for element without dash in tag name', () => { @Component({template: ``}) @@ -357,19 +344,6 @@ describe('NgModule', () => { expect(spy.calls.mostRecent().args[0]).toMatch(/'custom' is not a known element/); }); - it('should throw an error about unknown element without CUSTOM_ELEMENTS_SCHEMA for element without dash in tag name', - () => { - @Component({template: ``}) - class MyComp { - } - - TestBed.configureTestingModule({declarations: [MyComp], errorOnUnknownElements: true}); - expect(() => { - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - }).toThrowError(/NG0304: 'custom' is not a known element/g); - }); - it('should report unknown property bindings on ng-content', () => { @Component({template: ``}) class App { @@ -531,25 +505,6 @@ describe('NgModule', () => { expect(spy).not.toHaveBeenCalled(); }); - it('should not throw an error about unknown elements with CUSTOM_ELEMENTS_SCHEMA', () => { - @Component({template: ``}) - class MyComp { - } - - const spy = spyOn(console, 'error'); - TestBed.configureTestingModule({ - declarations: [MyComp], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - errorOnUnknownElements: true - }); - - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - // We do not expect any errors being thrown or logged in a console, - // since the `CUSTOM_ELEMENTS_SCHEMA` is applied. - expect(spy).not.toHaveBeenCalled(); - }); - it('should not log an error about unknown elements with NO_ERRORS_SCHEMA', () => { @Component({template: ``}) class MyComp { @@ -566,22 +521,6 @@ describe('NgModule', () => { expect(spy).not.toHaveBeenCalled(); }); - it('should not throw an error about unknown elements with NO_ERRORS_SCHEMA', () => { - @Component({template: ``}) - class MyComp { - } - - const spy = spyOn(console, 'error'); - TestBed.configureTestingModule( - {declarations: [MyComp], schemas: [NO_ERRORS_SCHEMA], errorOnUnknownElements: true}); - - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - // We do not expect any errors being thrown or logged in a console, - // since the `NO_ERRORS_SCHEMA` is applied. - expect(spy).not.toHaveBeenCalled(); - }); - it('should not log an error about unknown elements if element matches a directive', () => { @Component({ selector: 'custom-el', @@ -602,29 +541,6 @@ describe('NgModule', () => { expect(spy).not.toHaveBeenCalled(); }); - it('should not throw an error about unknown elements if element matches a directive', () => { - @Component({ - selector: 'custom-el', - template: '', - }) - class CustomEl { - } - - @Component({template: ``}) - class MyComp { - } - - const spy = spyOn(console, 'error'); - TestBed.configureTestingModule( - {declarations: [MyComp, CustomEl], errorOnUnknownElements: true}); - - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - // We do not expect any errors being thrown or logged in a console, - // since the element matches a directive. - expect(spy).not.toHaveBeenCalled(); - }); - it('should not log an error for HTML elements inside an SVG foreignObject', () => { @Component({ template: ` @@ -649,33 +565,6 @@ describe('NgModule', () => { fixture.detectChanges(); expect(spy).not.toHaveBeenCalled(); }); - - it('should not throw an error for HTML elements inside an SVG foreignObject', () => { - @Component({ - template: ` - - - Hello - - - `, - }) - class MyComp { - } - - @NgModule({declarations: [MyComp]}) - class MyModule { - } - - const spy = spyOn(console, 'error'); - TestBed.configureTestingModule({imports: [MyModule], errorOnUnknownElements: true}); - - const fixture = TestBed.createComponent(MyComp); - fixture.detectChanges(); - // We do not expect any errors being thrown or logged in a console, - // since the element is inside an SVG foreignObject. - expect(spy).not.toHaveBeenCalled(); - }); }); describe('createNgModuleRef function', () => { diff --git a/packages/core/test/test_bed_spec.ts b/packages/core/test/test_bed_spec.ts index d47991a2883..7320b05bfdc 100644 --- a/packages/core/test/test_bed_spec.ts +++ b/packages/core/test/test_bed_spec.ts @@ -13,7 +13,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; import {getNgModuleById} from '../public_api'; import {TestBedRender3} from '../testing/src/r3_test_bed'; -import {TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT, THROW_ON_UNKNOWN_ELEMENTS_DEFAULT} from '../testing/src/test_bed_common'; +import {TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT} from '../testing/src/test_bed_common'; const NAME = new InjectionToken('name'); @@ -1714,34 +1714,3 @@ describe('TestBed module teardown', () => { expect(TestBed.shouldRethrowTeardownErrors()).toBe(false); }); }); - -describe('TestBed module `errorOnUnknownElements`', () => { - // Cast the `TestBed` to the internal data type since we're testing private APIs. - let TestBed: TestBedRender3; - - beforeEach(() => { - TestBed = getTestBed() as unknown as TestBedRender3; - TestBed.resetTestingModule(); - }); - - it('should not throw based on the default behavior', () => { - expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(THROW_ON_UNKNOWN_ELEMENTS_DEFAULT); - }); - - it('should not throw if the option is omitted', () => { - TestBed.configureTestingModule({}); - expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(false); - }); - - it('should be able to configure the option', () => { - TestBed.configureTestingModule({errorOnUnknownElements: true}); - expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(true); - }); - - it('should reset the option back to the default when TestBed is reset', () => { - TestBed.configureTestingModule({errorOnUnknownElements: true}); - expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(true); - TestBed.resetTestingModule(); - expect(TestBed.shouldThrowErrorOnUnknownElements()).toBe(false); - }); -}); diff --git a/packages/core/testing/src/r3_test_bed.ts b/packages/core/testing/src/r3_test_bed.ts index 77176c2146b..36f6c4b2554 100644 --- a/packages/core/testing/src/r3_test_bed.ts +++ b/packages/core/testing/src/r3_test_bed.ts @@ -24,12 +24,10 @@ import { ProviderToken, Type, ɵflushModuleScopingQueueAsMuchAsPossible as flushModuleScopingQueueAsMuchAsPossible, - ɵgetUnknownElementStrictMode as getUnknownElementStrictMode, ɵRender3ComponentFactory as ComponentFactory, ɵRender3NgModuleRef as NgModuleRef, ɵresetCompiledComponents as resetCompiledComponents, ɵsetAllowDuplicateNgModuleIdsForTest as setAllowDuplicateNgModuleIdsForTest, - ɵsetUnknownElementStrictMode as setUnknownElementStrictMode, ɵstringify as stringify, } from '@angular/core'; @@ -39,7 +37,7 @@ import {ComponentFixture} from './component_fixture'; import {MetadataOverride} from './metadata_override'; import {R3TestBedCompiler} from './r3_test_bed_compiler'; import {TestBed} from './test_bed'; -import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, ModuleTeardownOptions, TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT, TestBedStatic, TestComponentRenderer, TestEnvironmentOptions, TestModuleMetadata, THROW_ON_UNKNOWN_ELEMENTS_DEFAULT} from './test_bed_common'; +import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, ModuleTeardownOptions, TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT, TestBedStatic, TestComponentRenderer, TestEnvironmentOptions, TestModuleMetadata} from './test_bed_common'; let _nextRootElementId = 0; @@ -61,30 +59,12 @@ export class TestBedRender3 implements TestBed { */ private static _environmentTeardownOptions: ModuleTeardownOptions|undefined; - /** - * "Error on unknown elements" option that has been configured at the environment level. - * Used as a fallback if no instance-level option has been provided. - */ - private static _environmentErrorOnUnknownElementsOption: boolean|undefined; - /** * Teardown options that have been configured at the `TestBed` instance level. - * These options take precedence over the environment-level ones. + * These options take precedence over the environemnt-level ones. */ private _instanceTeardownOptions: ModuleTeardownOptions|undefined; - /** - * "Error on unknown elements" option that has been configured at the `TestBed` instance level. - * This option takes precedence over the environment-level one. - */ - private _instanceErrorOnUnknownElementsOption: boolean|undefined; - - /** - * Stores the previous "Error on unknown elements" option value, - * allowing to restore it in the reset testing module logic. - */ - private _previousErrorOnUnknownElementsOption: boolean|undefined; - /** * Initialize the environment for testing with a compiler factory, a PlatformRef, and an * angular module. These are common to every test in the suite. @@ -257,8 +237,6 @@ export class TestBedRender3 implements TestBed { TestBedRender3._environmentTeardownOptions = options?.teardown; - TestBedRender3._environmentErrorOnUnknownElementsOption = options?.errorOnUnknownElements; - this.platform = platform; this.ngModule = ngModule; this._compiler = new R3TestBedCompiler(this.platform, this.ngModule); @@ -291,9 +269,6 @@ export class TestBedRender3 implements TestBed { this.compiler.restoreOriginalState(); } this._compiler = new R3TestBedCompiler(this.platform, this.ngModule); - // Restore the previous value of the "error on unknown elements" option - setUnknownElementStrictMode( - this._previousErrorOnUnknownElementsOption ?? THROW_ON_UNKNOWN_ELEMENTS_DEFAULT); // We have to chain a couple of try/finally blocks, because each step can // throw errors and we don't want it to interrupt the next step and we also @@ -308,7 +283,6 @@ export class TestBedRender3 implements TestBed { } finally { this._testModuleRef = null; this._instanceTeardownOptions = undefined; - this._instanceErrorOnUnknownElementsOption = undefined; } } } @@ -332,14 +306,9 @@ export class TestBedRender3 implements TestBed { // description for additional info. this.checkGlobalCompilationFinished(); - // Always re-assign the options, even if they're undefined. - // This ensures that we don't carry them between tests. + // Always re-assign the teardown options, even if they're undefined. + // This ensures that we don't carry the options between tests. this._instanceTeardownOptions = moduleDef.teardown; - this._instanceErrorOnUnknownElementsOption = moduleDef.errorOnUnknownElements; - // Store the current value of the strict mode option, - // so we can restore it later - this._previousErrorOnUnknownElementsOption = getUnknownElementStrictMode(); - setUnknownElementStrictMode(this.shouldThrowErrorOnUnknownElements()); this.compiler.configureTestingModule(moduleDef); } @@ -512,7 +481,7 @@ export class TestBedRender3 implements TestBed { } } - shouldRethrowTeardownErrors(): boolean { + shouldRethrowTeardownErrors() { const instanceOptions = this._instanceTeardownOptions; const environmentOptions = TestBedRender3._environmentTeardownOptions; @@ -526,13 +495,6 @@ export class TestBedRender3 implements TestBed { this.shouldTearDownTestingModule(); } - shouldThrowErrorOnUnknownElements(): boolean { - // Check if a configuration has been provided to throw when an unknown element is found - return this._instanceErrorOnUnknownElementsOption ?? - TestBedRender3._environmentErrorOnUnknownElementsOption ?? - THROW_ON_UNKNOWN_ELEMENTS_DEFAULT; - } - shouldTearDownTestingModule(): boolean { return this._instanceTeardownOptions?.destroyAfterEach ?? TestBedRender3._environmentTeardownOptions?.destroyAfterEach ?? diff --git a/packages/core/testing/src/test_bed_common.ts b/packages/core/testing/src/test_bed_common.ts index dd4c692ac34..fe17568a713 100644 --- a/packages/core/testing/src/test_bed_common.ts +++ b/packages/core/testing/src/test_bed_common.ts @@ -15,9 +15,6 @@ import {TestBed} from './test_bed'; /** Whether test modules should be torn down by default. */ export const TEARDOWN_TESTING_MODULE_ON_DESTROY_DEFAULT = true; -/** Whether unknown elements in templates should throw by default. */ -export const THROW_ON_UNKNOWN_ELEMENTS_DEFAULT = false; - /** * An abstract class for inserting the root test component element in a platform independent way. * @@ -48,13 +45,6 @@ export type TestModuleMetadata = { imports?: any[], schemas?: Array, teardown?: ModuleTeardownOptions; - /** - * Whether NG0304 runtime errors should be thrown on unknown elements. - * Defaults to `false`, where the error is simply logged. - * If sets to `true`, the error is thrown. - * @see https://angular.io/errors/NG8001 for the description of the problem and how to fix it - */ - errorOnUnknownElements?: boolean; }; /** @@ -65,13 +55,6 @@ export interface TestEnvironmentOptions { * Configures the test module teardown behavior in `TestBed`. */ teardown?: ModuleTeardownOptions; - /** - * Whether errors should be thrown on unknown elements. - * Defaults to `false`, where the error is simply logged. - * If sets to `true`, the error is thrown. - * @see https://angular.io/errors/NG8001 for the description of the error and how to fix it - */ - errorOnUnknownElements?: boolean; } /**