mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
test: update acceptance core tests to work with es2015 (#44505)
Updates the acceptance core tests to work with ES2015 devmode output. There were two issues surfacing: * The NodeJS test execution failed because Domino does not handle destructuring syntax properly. This is because `Node.children` is not an iterable. * `forwardRef` does not work with ES2015 and TypeScript's decorator downlevel emit. This is a known limitation we work around in Angular applications by either compiling tests with the Angular compiler, or by running a custom decorator downlevel transform (like in the CLI). PR Close #44505
This commit is contained in:
parent
92806ff042
commit
807c6a4e10
5 changed files with 135 additions and 64 deletions
|
|
@ -1,12 +1,17 @@
|
|||
load("//tools:defaults.bzl", "jasmine_node_test", "karma_web_test_suite", "ts_library")
|
||||
load("//tools:defaults.bzl", "jasmine_node_test", "karma_web_test_suite", "ng_module", "ts_library")
|
||||
|
||||
package(default_visibility = ["//visibility:private"])
|
||||
|
||||
SPEC_FILES_WITH_FORWARD_REFS = [
|
||||
"di_forward_ref_spec.ts",
|
||||
]
|
||||
|
||||
ts_library(
|
||||
name = "acceptance_lib",
|
||||
testonly = True,
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = SPEC_FILES_WITH_FORWARD_REFS,
|
||||
),
|
||||
# Visible to //:saucelabs_unit_tests
|
||||
visibility = ["//:__pkg__"],
|
||||
|
|
@ -35,11 +40,28 @@ ts_library(
|
|||
],
|
||||
)
|
||||
|
||||
# Note: The `forward_ref` example tests are built through this `ng_module` sub-target.
|
||||
# This is done so that DI decorator/type metadata is processed manually by the compiler
|
||||
# ahead of time. We cannot rely on the official TypeScript decorator downlevel emit (for JIT),
|
||||
# as the output is not compatible with `forwardRef` and ES2015+. More details here:
|
||||
# https://github.com/angular/angular/commit/323651bd38909b0f4226bcb6c8f5abafa91cf9d9.
|
||||
# https://github.com/microsoft/TypeScript/issues/27519.
|
||||
ng_module(
|
||||
name = "forward_ref_test_lib",
|
||||
testonly = True,
|
||||
srcs = SPEC_FILES_WITH_FORWARD_REFS,
|
||||
deps = [
|
||||
"//packages/core",
|
||||
"//packages/core/testing",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "acceptance",
|
||||
bootstrap = ["//tools/testing:node_es2015"],
|
||||
deps = [
|
||||
":acceptance_lib",
|
||||
":forward_ref_test_lib",
|
||||
"//packages/zone.js/lib:zone_d_ts",
|
||||
"@npm//base64-js",
|
||||
"@npm//source-map",
|
||||
|
|
@ -50,5 +72,6 @@ karma_web_test_suite(
|
|||
name = "acceptance_web",
|
||||
deps = [
|
||||
":acceptance_lib",
|
||||
":forward_ref_test_lib",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
67
packages/core/test/acceptance/di_forward_ref_spec.ts
Normal file
67
packages/core/test/acceptance/di_forward_ref_spec.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google LLC 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
|
||||
*/
|
||||
|
||||
import {Component, Directive, forwardRef, Host, Inject, ViewChild} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
// **NOTE**: More details on why tests relying on `forwardRef` are put into this
|
||||
// file can be found in the `BUILD.bazel` file declaring the forward ref test target.
|
||||
|
||||
describe('di with forwardRef', () => {
|
||||
describe('directive injection', () => {
|
||||
it('should throw if directives try to inject each other', () => {
|
||||
@Directive({selector: '[dirB]'})
|
||||
class DirectiveB {
|
||||
constructor(@Inject(forwardRef(() => DirectiveA)) siblingDir: DirectiveA) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dirA]'})
|
||||
class DirectiveA {
|
||||
constructor(siblingDir: DirectiveB) {}
|
||||
}
|
||||
|
||||
@Component({template: '<div dirA dirB></div>'})
|
||||
class MyComp {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [DirectiveA, DirectiveB, MyComp]});
|
||||
expect(() => TestBed.createComponent(MyComp))
|
||||
.toThrowError(
|
||||
'NG0200: Circular dependency in DI detected for DirectiveA. Find more at https://angular.io/errors/NG0200');
|
||||
});
|
||||
|
||||
describe('flags', () => {
|
||||
describe('@Host', () => {
|
||||
it('should find host component on the host itself', () => {
|
||||
@Directive({selector: '[dirComp]'})
|
||||
class DirectiveComp {
|
||||
constructor(@Inject(forwardRef(() => MyComp)) @Host() public comp: MyComp) {}
|
||||
}
|
||||
|
||||
@Component({selector: 'my-comp', template: '<div dirComp></div>'})
|
||||
class MyComp {
|
||||
@ViewChild(DirectiveComp) dirComp!: DirectiveComp;
|
||||
}
|
||||
|
||||
@Component({template: '<my-comp></my-comp>', jit: true})
|
||||
class MyApp {
|
||||
@ViewChild(MyComp) myComp!: MyComp;
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [DirectiveComp, MyComp, MyApp]});
|
||||
const fixture = TestBed.createComponent(MyApp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const myComp = fixture.componentInstance.myComp;
|
||||
const dirComp = myComp.dirComp;
|
||||
expect(dirComp.comp).toBe(myComp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -684,27 +684,6 @@ describe('di', () => {
|
|||
expect(cmp.componentInstance.testB.a).toBeNull();
|
||||
});
|
||||
|
||||
it('should throw if directives try to inject each other', () => {
|
||||
@Directive({selector: '[dirB]'})
|
||||
class DirectiveB {
|
||||
constructor(@Inject(forwardRef(() => DirectiveA)) siblingDir: DirectiveA) {}
|
||||
}
|
||||
|
||||
@Directive({selector: '[dirA]'})
|
||||
class DirectiveA {
|
||||
constructor(siblingDir: DirectiveB) {}
|
||||
}
|
||||
|
||||
@Component({template: '<div dirA dirB></div>'})
|
||||
class MyComp {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [DirectiveA, DirectiveB, MyComp]});
|
||||
expect(() => TestBed.createComponent(MyComp))
|
||||
.toThrowError(
|
||||
'NG0200: Circular dependency in DI detected for DirectiveA. Find more at https://angular.io/errors/NG0200');
|
||||
});
|
||||
|
||||
it('should throw if directive tries to inject itself', () => {
|
||||
@Directive({selector: '[dirA]'})
|
||||
class DirectiveA {
|
||||
|
|
@ -1781,31 +1760,6 @@ describe('di', () => {
|
|||
expect(dirString.s).toBe('Foo');
|
||||
});
|
||||
|
||||
it('should find host component on the host itself', () => {
|
||||
@Directive({selector: '[dirComp]'})
|
||||
class DirectiveComp {
|
||||
constructor(@Inject(forwardRef(() => MyComp)) @Host() public comp: MyComp) {}
|
||||
}
|
||||
|
||||
@Component({selector: 'my-comp', template: '<div dirComp></div>'})
|
||||
class MyComp {
|
||||
@ViewChild(DirectiveComp) dirComp!: DirectiveComp;
|
||||
}
|
||||
|
||||
@Component({template: '<my-comp></my-comp>'})
|
||||
class MyApp {
|
||||
@ViewChild(MyComp) myComp!: MyComp;
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [DirectiveComp, MyComp, MyApp]});
|
||||
const fixture = TestBed.createComponent(MyApp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const myComp = fixture.componentInstance.myComp;
|
||||
const dirComp = myComp.dirComp;
|
||||
expect(dirComp.comp).toBe(myComp);
|
||||
});
|
||||
|
||||
it('should not find providers on the host itself', () => {
|
||||
@Component({
|
||||
selector: 'my-comp',
|
||||
|
|
@ -1882,19 +1836,19 @@ describe('di', () => {
|
|||
});
|
||||
|
||||
it('should not find component above the host', () => {
|
||||
@Component({template: '<my-comp></my-comp>'})
|
||||
class MyApp {
|
||||
}
|
||||
|
||||
@Directive({selector: '[dirComp]'})
|
||||
class DirectiveComp {
|
||||
constructor(@Inject(forwardRef(() => MyApp)) @Host() public comp: MyApp) {}
|
||||
constructor(@Host() public comp: MyApp) {}
|
||||
}
|
||||
|
||||
@Component({selector: 'my-comp', template: '<div dirComp></div>'})
|
||||
class MyComp {
|
||||
}
|
||||
|
||||
@Component({template: '<my-comp></my-comp>'})
|
||||
class MyApp {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [DirectiveComp, MyComp, MyApp]});
|
||||
expect(() => TestBed.createComponent(MyApp))
|
||||
.toThrowError(
|
||||
|
|
|
|||
|
|
@ -510,7 +510,12 @@ describe('property bindings', () => {
|
|||
const fixture = TestBed.createComponent(App);
|
||||
const myDir = fixture.debugElement.query(By.directive(MyDir)).injector.get(MyDir);
|
||||
const myDirB = fixture.debugElement.query(By.directive(MyDirB)).injector.get(MyDirB);
|
||||
const [buttonEl, listboxEl] = fixture.nativeElement.children;
|
||||
const fixtureElements = fixture.nativeElement.children;
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const buttonEl = fixtureElements[0];
|
||||
const listboxEl = fixtureElements[1];
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(buttonEl.getAttribute('role')).toBe('button');
|
||||
|
|
@ -581,7 +586,11 @@ describe('property bindings', () => {
|
|||
|
||||
expect(fixture.nativeElement.children.length).toBe(2);
|
||||
|
||||
const [comp1, comp2] = fixture.nativeElement.children;
|
||||
const compElements = fixture.nativeElement.children;
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const comp1 = compElements[0];
|
||||
const comp2 = compElements[1];
|
||||
|
||||
expect(comp1.tagName).toBe('COMP');
|
||||
expect(comp2.tagName).toBe('COMP');
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ describe('styling', () => {
|
|||
|
||||
TestBed.configureTestingModule({declarations: [Cmp]});
|
||||
const fixture = TestBed.createComponent(Cmp);
|
||||
const staticDiv = fixture.nativeElement.querySelectorAll('div')[0];
|
||||
|
||||
const [staticDiv] = fixture.nativeElement.querySelectorAll('div');
|
||||
expect(getSortedClassName(staticDiv)).toEqual('STATIC');
|
||||
expect(getSortedStyle(staticDiv)).toEqual('color: blue;');
|
||||
});
|
||||
|
|
@ -335,7 +335,12 @@ describe('styling', () => {
|
|||
const fixture = TestBed.createComponent(Cmp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const [div1, div2] = fixture.nativeElement.querySelectorAll('div');
|
||||
const divs = fixture.nativeElement.querySelectorAll('div');
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const div1 = divs[0];
|
||||
const div2 = divs[1];
|
||||
|
||||
// Static value `class="s1"` is always written to the DOM.
|
||||
expect(div1.className).toEqual('s1');
|
||||
expect(div1.getAttribute('shadow-class')).toEqual('s1 d1');
|
||||
|
|
@ -367,7 +372,12 @@ describe('styling', () => {
|
|||
const fixture = TestBed.createComponent(Cmp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const [divStatic, divBinding] = fixture.nativeElement.querySelectorAll('div');
|
||||
const divs = fixture.nativeElement.querySelectorAll('div');
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const divStatic = divs[0];
|
||||
const divBinding = divs[1];
|
||||
|
||||
expectClass(divStatic).toEqual({'DIRECTIVE': true, 's1': true});
|
||||
expect(divStatic.getAttribute('shadow-class')).toEqual('s1');
|
||||
|
||||
|
|
@ -398,7 +408,12 @@ describe('styling', () => {
|
|||
const fixture = TestBed.createComponent(Cmp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const [divStatic, divBinding] = fixture.nativeElement.querySelectorAll('div');
|
||||
const divs = fixture.nativeElement.querySelectorAll('div');
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const divStatic = divs[0];
|
||||
const divBinding = divs[1];
|
||||
|
||||
expectStyle(divStatic).toEqual({'color': 'red', 'width': '1px'});
|
||||
expect(divStatic.getAttribute('shadow-style')).toEqual('width: 1px;');
|
||||
|
||||
|
|
@ -2451,11 +2466,10 @@ describe('styling', () => {
|
|||
|
||||
const items = fixture.nativeElement.querySelectorAll('.item');
|
||||
expect(items.length).toEqual(4);
|
||||
const [a, b, c, d] = items;
|
||||
expect(a.style.height).toEqual('0px');
|
||||
expect(b.style.height).toEqual('100px');
|
||||
expect(c.style.height).toEqual('200px');
|
||||
expect(d.style.height).toEqual('300px');
|
||||
expect(items[0].style.height).toEqual('0px');
|
||||
expect(items[1].style.height).toEqual('100px');
|
||||
expect(items[2].style.height).toEqual('200px');
|
||||
expect(items[3].style.height).toEqual('300px');
|
||||
|
||||
const section = fixture.nativeElement.querySelector('section');
|
||||
const p = fixture.nativeElement.querySelector('p');
|
||||
|
|
@ -3342,7 +3356,11 @@ describe('styling', () => {
|
|||
const fixture = TestBed.createComponent(MyComp);
|
||||
fixture.detectChanges();
|
||||
|
||||
const [div1, div2] = fixture.nativeElement.querySelectorAll('div') as HTMLDivElement[];
|
||||
const divs = fixture.nativeElement.querySelectorAll('div') as HTMLDivElement[];
|
||||
|
||||
// TODO: Use destructuring once Domino supports native ES2015, or when jsdom is used.
|
||||
const div1 = divs[0];
|
||||
const div2 = divs[1];
|
||||
|
||||
expect(div1.className).toBe('');
|
||||
expect(div2.className).toBe('');
|
||||
|
|
|
|||
Loading…
Reference in a new issue