diff --git a/adev/src/content/examples/resolution-modifiers/src/app/host/host.component.ts b/adev/src/content/examples/resolution-modifiers/src/app/host/host.component.ts
deleted file mode 100755
index 48bb6c25be2..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/host/host.component.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import {Component, Host, Optional} from '@angular/core';
-import {FlowerService} from '../flower.service';
-import {HostChildComponent} from '../host-child/host-child.component';
-
-// #docregion host-component
-@Component({
- selector: 'app-host',
- templateUrl: './host.component.html',
- styleUrls: ['./host.component.css'],
- // provide the service
- providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
- imports: [HostChildComponent],
-})
-export class HostComponent {
- // use @Host() in the constructor when injecting the service
- constructor(@Host() @Optional() public flower?: FlowerService) {}
-}
-// #enddocregion host-component
-
-// if you take out @Host() and the providers array, flower will be red hibiscus
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/leaf.service.ts b/adev/src/content/examples/resolution-modifiers/src/app/leaf.service.ts
deleted file mode 100755
index b4f6b2e6df0..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/leaf.service.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {Injectable} from '@angular/core';
-
-@Injectable({
- providedIn: 'root',
-})
-// #docregion leafservice
-export class LeafService {
- emoji = '🌿';
-}
-// #enddocregion leafservice
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/optional.service.ts b/adev/src/content/examples/resolution-modifiers/src/app/optional.service.ts
deleted file mode 100755
index 05f31cbee3c..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/optional.service.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {Injectable} from '@angular/core';
-
-@Injectable()
-export class OptionalService {}
-
-// This service isn't provided anywhere.
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.css b/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.css
deleted file mode 100755
index 78336a39059..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.section {
- border: 2px solid #369;
- padding: 1rem;
- margin: 1rem 0;
-}
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.html b/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.html
deleted file mode 100755
index e5017994904..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
@Optional() Component
-
- This component still works even though the OptionalService (notice @Optional() in the
- constructor isn't provided or configured anywhere. Angular goes through tree and visibility
- rules, and if it doesn't find the requested service, returns null.
-
-
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.ts b/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.ts
deleted file mode 100755
index aaf3b36f221..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/optional/optional.component.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {Component, Optional} from '@angular/core';
-import {OptionalService} from '../optional.service';
-
-@Component({
- selector: 'app-optional',
- templateUrl: './optional.component.html',
- styleUrls: ['./optional.component.css'],
-})
-
-// #docregion optional-component
-export class OptionalComponent {
- constructor(@Optional() public optional?: OptionalService) {}
-}
-// #enddocregion optional-component
-
-// The OptionalService isn't provided here, in the @Injectable()
-// providers array, or in the NgModule. If you remove @Optional()
-// from the constructor, you'll get an error.
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.css b/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.css
deleted file mode 100755
index 78336a39059..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.section {
- border: 2px solid #369;
- padding: 1rem;
- margin: 1rem 0;
-}
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.html b/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.html
deleted file mode 100755
index 84d6306da3f..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
@Self() Component (without a provider)
-
Leaf emoji: {{ leaf?.emoji }}
-
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.ts b/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.ts
deleted file mode 100755
index b6673bfa4e8..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self-no-data/self-no-data.component.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {Component, Self, Optional} from '@angular/core';
-import {LeafService} from '../leaf.service';
-
-// #docregion self-no-data-component
-@Component({
- selector: 'app-self-no-data',
- templateUrl: './self-no-data.component.html',
- styleUrls: ['./self-no-data.component.css'],
-})
-export class SelfNoDataComponent {
- constructor(@Self() @Optional() public leaf?: LeafService) {}
-}
-
-// #enddocregion self-no-data-component
-
-// The app doesn't break because the value being available at self is optional.
-// If you remove @Optional(), the app breaks.
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.css b/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.css
deleted file mode 100755
index 78336a39059..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.section {
- border: 2px solid #369;
- padding: 1rem;
- margin: 1rem 0;
-}
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.html b/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.html
deleted file mode 100755
index fba7c08ed70..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
@Self() Component
-
Flower emoji: {{ flower.emoji }}
-
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.ts b/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.ts
deleted file mode 100755
index ec0e8b3bc13..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/self/self.component.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {Component, Self} from '@angular/core';
-import {FlowerService} from '../flower.service';
-
-// #docregion self-component
-@Component({
- selector: 'app-self',
- templateUrl: './self.component.html',
- styleUrls: ['./self.component.css'],
- providers: [{provide: FlowerService, useValue: {emoji: '🌷'}}],
-})
-export class SelfComponent {
- constructor(@Self() public flower: FlowerService) {}
-}
-// #enddocregion self-component
-
-// This component provides the FlowerService so the injector
-// doesn't have to look further up the injector tree
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.css b/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.css
deleted file mode 100755
index 78336a39059..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.section {
- border: 2px solid #369;
- padding: 1rem;
- margin: 1rem 0;
-}
diff --git a/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.html b/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.html
deleted file mode 100755
index 01bc38abdeb..00000000000
--- a/adev/src/content/examples/resolution-modifiers/src/app/skipself/skipself.component.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/adev/src/content/examples/testing/src/app/hero/hero-list.component.spec.ts b/adev/src/content/examples/testing/src/app/hero/hero-list.component.spec.ts
deleted file mode 100755
index 2ba082c9ee9..00000000000
--- a/adev/src/content/examples/testing/src/app/hero/hero-list.component.spec.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import {ComponentFixture, fakeAsync, TestBed, tick, waitForAsync} from '@angular/core/testing';
-
-import {By} from '@angular/platform-browser';
-import {DebugElement} from '@angular/core';
-
-import {Router} from '@angular/router';
-
-import {addMatchers} from '../../testing';
-import {HeroService} from '../model/hero.service';
-import {getTestHeroes, TestHeroService} from '../model/testing/test-hero.service';
-
-import {HeroListComponent} from './hero-list.component';
-import {HighlightDirective} from '../shared/highlight.directive';
-import {appConfig} from '../app.config';
-
-const HEROES = getTestHeroes();
-
-let comp: HeroListComponent;
-let fixture: ComponentFixture;
-let page: Page;
-
-/////// Tests //////
-
-describe('HeroListComponent', () => {
- beforeEach(waitForAsync(() => {
- addMatchers();
- const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
-
- TestBed.configureTestingModule(
- Object.assign({}, appConfig, {
- providers: [
- {provide: HeroService, useClass: TestHeroService},
- {provide: Router, useValue: routerSpy},
- ],
- }),
- )
-
- .then(createComponent);
- }));
-
- it('should display heroes', () => {
- expect(page.heroRows.length).toBeGreaterThan(0);
- });
-
- it('1st hero should match 1st test hero', () => {
- const expectedHero = HEROES[0];
- const actualHero = page.heroRows[0].textContent;
- expect(actualHero).withContext('hero.id').toContain(expectedHero.id.toString());
- expect(actualHero).withContext('hero.name').toContain(expectedHero.name);
- });
-
- it('should select hero on click', fakeAsync(() => {
- const expectedHero = HEROES[1];
- const btn = page.heroRows[1].querySelector('button');
-
- btn!.dispatchEvent(new Event('click'));
- tick();
- // `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
- expect(comp.selectedHero).toEqual(expectedHero);
- }));
-
- it('should navigate to selected hero detail on click', fakeAsync(() => {
- const expectedHero = HEROES[1];
- const btn = page.heroRows[1].querySelector('button');
-
- btn!.dispatchEvent(new Event('click'));
- tick();
-
- // should have navigated
- expect(page.navSpy.calls.any()).withContext('navigate called').toBe(true);
-
- // composed hero detail will be URL like 'heroes/42'
- // expect link array with the route path and hero id
- // first argument to router.navigate is link array
- const navArgs = page.navSpy.calls.first().args[0];
- expect(navArgs[0]).withContext('nav to heroes detail URL').toContain('heroes');
- expect(navArgs[1]).withContext('expected hero.id').toBe(expectedHero.id);
- }));
-
- it('should find `HighlightDirective` with `By.directive', () => {
- // #docregion by
- // Can find DebugElement either by css selector or by directive
- const h2 = fixture.debugElement.query(By.css('h2'));
- const directive = fixture.debugElement.query(By.directive(HighlightDirective));
- // #enddocregion by
- expect(h2).toBe(directive);
- });
-
- it('should color header with `HighlightDirective`', () => {
- const h2 = page.highlightDe.nativeElement as HTMLElement;
- const bgColor = h2.style.backgroundColor;
-
- // different browsers report color values differently
- const isExpectedColor = bgColor === 'gold' || bgColor === 'rgb(255, 215, 0)';
- expect(isExpectedColor).withContext('backgroundColor').toBe(true);
- });
-
- it("the `HighlightDirective` is among the element's providers", () => {
- expect(page.highlightDe.providerTokens)
- .withContext('HighlightDirective')
- .toContain(HighlightDirective);
- });
-});
-
-/////////// Helpers /////
-
-/** Create the component and set the `page` test variables */
-function createComponent() {
- fixture = TestBed.createComponent(HeroListComponent);
- comp = fixture.componentInstance;
-
- // change detection triggers ngOnInit which gets a hero
- fixture.detectChanges();
-
- return fixture.whenStable().then(() => {
- // got the heroes and updated component
- // change detection updates the view
- fixture.detectChanges();
- page = new Page();
- });
-}
-
-class Page {
- /** Hero line elements */
- heroRows: HTMLLIElement[];
-
- /** Highlighted DebugElement */
- highlightDe: DebugElement;
-
- /** Spy on router navigate method */
- navSpy: jasmine.Spy;
-
- constructor() {
- const heroRowNodes = fixture.nativeElement.querySelectorAll('li');
- this.heroRows = Array.from(heroRowNodes);
-
- // Find the first element with an attached HighlightDirective
- this.highlightDe = fixture.debugElement.query(By.directive(HighlightDirective));
-
- // Get the component's injected router navigation spy
- const routerSpy = fixture.debugElement.injector.get(Router);
- this.navSpy = routerSpy.navigate as jasmine.Spy;
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/hero/hero-list.component.ts b/adev/src/content/examples/testing/src/app/hero/hero-list.component.ts
deleted file mode 100755
index 6aff874ee90..00000000000
--- a/adev/src/content/examples/testing/src/app/hero/hero-list.component.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {Component} from '@angular/core';
-import {AsyncPipe} from '@angular/common';
-import {Router} from '@angular/router';
-
-import {Observable} from 'rxjs';
-
-import {Hero} from '../model/hero';
-import {HeroService} from '../model/hero.service';
-import {sharedImports} from '../shared/shared';
-
-@Component({
- selector: 'app-heroes',
- templateUrl: './hero-list.component.html',
- styleUrls: ['./hero-list.component.css'],
- imports: [AsyncPipe, sharedImports],
-})
-export class HeroListComponent {
- heroes: Observable;
- selectedHero!: Hero;
-
- constructor(
- private router: Router,
- private heroService: HeroService,
- ) {
- this.heroes = this.heroService.getHeroes();
- }
-
- onSelect(hero: Hero) {
- this.selectedHero = hero;
- this.router.navigate(['../heroes', this.selectedHero.id]);
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/hero/hero.routes.ts b/adev/src/content/examples/testing/src/app/hero/hero.routes.ts
deleted file mode 100755
index 1668b130448..00000000000
--- a/adev/src/content/examples/testing/src/app/hero/hero.routes.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {HeroListComponent} from './hero-list.component';
-import {HeroDetailComponent} from './hero-detail.component';
-import {Routes} from '@angular/router';
-
-export default [
- {path: '', component: HeroListComponent},
- {path: ':id', component: HeroDetailComponent},
-] as Routes;
diff --git a/adev/src/content/examples/testing/src/app/in-memory-data.service.ts b/adev/src/content/examples/testing/src/app/in-memory-data.service.ts
deleted file mode 100644
index 23cf6475af6..00000000000
--- a/adev/src/content/examples/testing/src/app/in-memory-data.service.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import {InMemoryDbService} from 'angular-in-memory-web-api';
-import {QUOTES} from './twain/twain.data';
-
-// Adjust to reduce number of quotes
-const maxQuotes = Infinity; // 0;
-
-/** Create in-memory database of heroes and quotes */
-export class InMemoryDataService implements InMemoryDbService {
- createDb() {
- const heroes = [
- {id: 12, name: 'Dr. Nice'},
- {id: 13, name: 'Bombasto'},
- {id: 14, name: 'Celeritas'},
- {id: 15, name: 'Magneta'},
- {id: 16, name: 'RubberMan'},
- {id: 17, name: 'Dynama'},
- {id: 18, name: 'Dr. IQ'},
- {id: 19, name: 'Magma'},
- {id: 20, name: 'Tornado'},
- ];
-
- return {heroes, quotes: QUOTES.slice(0, maxQuotes)};
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/model/hero.service.spec.ts b/adev/src/content/examples/testing/src/app/model/hero.service.spec.ts
deleted file mode 100644
index 67cad203620..00000000000
--- a/adev/src/content/examples/testing/src/app/model/hero.service.spec.ts
+++ /dev/null
@@ -1,218 +0,0 @@
-import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
-
-// Other imports
-import {TestBed} from '@angular/core/testing';
-import {HttpClient, HttpResponse, HttpErrorResponse} from '@angular/common/http';
-
-import {asyncData, asyncError} from '../../testing/async-observable-helpers';
-
-import {Hero} from './hero';
-import {HeroService} from './hero.service';
-
-describe('HeroesService (with spies)', () => {
- // #docregion test-with-spies
- let httpClientSpy: jasmine.SpyObj;
- let heroService: HeroService;
-
- beforeEach(() => {
- // TODO: spy on other methods too
- httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
- heroService = new HeroService(httpClientSpy);
- });
-
- it('should return expected heroes (HttpClient called once)', (done: DoneFn) => {
- const expectedHeroes: Hero[] = [
- {id: 1, name: 'A'},
- {id: 2, name: 'B'},
- ];
-
- httpClientSpy.get.and.returnValue(asyncData(expectedHeroes));
-
- heroService.getHeroes().subscribe({
- next: (heroes) => {
- expect(heroes).withContext('expected heroes').toEqual(expectedHeroes);
- done();
- },
- error: done.fail,
- });
- expect(httpClientSpy.get.calls.count()).withContext('one call').toBe(1);
- });
-
- it('should return an error when the server returns a 404', (done: DoneFn) => {
- const errorResponse = new HttpErrorResponse({
- error: 'test 404 error',
- status: 404,
- statusText: 'Not Found',
- });
-
- httpClientSpy.get.and.returnValue(asyncError(errorResponse));
-
- heroService.getHeroes().subscribe({
- next: (heroes) => done.fail('expected an error, not heroes'),
- error: (error) => {
- expect(error.message).toContain('test 404 error');
- done();
- },
- });
- });
- // #enddocregion test-with-spies
-});
-
-describe('HeroesService (with mocks)', () => {
- let httpClient: HttpClient;
- let httpTestingController: HttpTestingController;
- let heroService: HeroService;
-
- beforeEach(() => {
- TestBed.configureTestingModule({
- // Import the HttpClient mocking services
- imports: [HttpClientTestingModule],
- // Provide the service-under-test
- providers: [HeroService],
- });
-
- // Inject the http, test controller, and service-under-test
- // as they will be referenced by each test.
- httpClient = TestBed.inject(HttpClient);
- httpTestingController = TestBed.inject(HttpTestingController);
- heroService = TestBed.inject(HeroService);
- });
-
- afterEach(() => {
- // After every test, assert that there are no more pending requests.
- httpTestingController.verify();
- });
-
- /// HeroService method tests begin ///
- describe('#getHeroes', () => {
- let expectedHeroes: Hero[];
-
- beforeEach(() => {
- heroService = TestBed.inject(HeroService);
- expectedHeroes = [
- {id: 1, name: 'A'},
- {id: 2, name: 'B'},
- ] as Hero[];
- });
-
- it('should return expected heroes (called once)', () => {
- heroService.getHeroes().subscribe({
- next: (heroes) =>
- expect(heroes).withContext('should return expected heroes').toEqual(expectedHeroes),
- error: fail,
- });
-
- // HeroService should have made one request to GET heroes from expected URL
- const req = httpTestingController.expectOne(heroService.heroesUrl);
- expect(req.request.method).toEqual('GET');
-
- // Respond with the mock heroes
- req.flush(expectedHeroes);
- });
-
- it('should be OK returning no heroes', () => {
- heroService.getHeroes().subscribe({
- next: (heroes) =>
- expect(heroes.length).withContext('should have empty heroes array').toEqual(0),
- error: fail,
- });
-
- const req = httpTestingController.expectOne(heroService.heroesUrl);
- req.flush([]); // Respond with no heroes
- });
-
- it('should turn 404 into a user-friendly error', () => {
- const msg = 'Deliberate 404';
- heroService.getHeroes().subscribe({
- next: (heroes) => fail('expected to fail'),
- error: (error) => expect(error.message).toContain(msg),
- });
-
- const req = httpTestingController.expectOne(heroService.heroesUrl);
-
- // respond with a 404 and the error message in the body
- req.flush(msg, {status: 404, statusText: 'Not Found'});
- });
-
- it('should return expected heroes (called multiple times)', () => {
- heroService.getHeroes().subscribe();
- heroService.getHeroes().subscribe();
- heroService.getHeroes().subscribe({
- next: (heroes) =>
- expect(heroes).withContext('should return expected heroes').toEqual(expectedHeroes),
- error: fail,
- });
-
- const requests = httpTestingController.match(heroService.heroesUrl);
- expect(requests.length).withContext('calls to getHeroes()').toEqual(3);
-
- // Respond to each request with different mock hero results
- requests[0].flush([]);
- requests[1].flush([{id: 1, name: 'bob'}]);
- requests[2].flush(expectedHeroes);
- });
- });
-
- describe('#updateHero', () => {
- // Expecting the query form of URL so should not 404 when id not found
- const makeUrl = (id: number) => `${heroService.heroesUrl}/?id=${id}`;
-
- it('should update a hero and return it', () => {
- const updateHero: Hero = {id: 1, name: 'A'};
-
- heroService.updateHero(updateHero).subscribe({
- next: (data) => expect(data).withContext('should return the hero').toEqual(updateHero),
- error: fail,
- });
-
- // HeroService should have made one request to PUT hero
- const req = httpTestingController.expectOne(heroService.heroesUrl);
- expect(req.request.method).toEqual('PUT');
- expect(req.request.body).toEqual(updateHero);
-
- // Expect server to return the hero after PUT
- const expectedResponse = new HttpResponse({
- status: 200,
- statusText: 'OK',
- body: updateHero,
- });
- req.event(expectedResponse);
- });
-
- it('should turn 404 error into user-facing error', () => {
- const msg = 'Deliberate 404';
- const updateHero: Hero = {id: 1, name: 'A'};
- heroService.updateHero(updateHero).subscribe({
- next: (heroes) => fail('expected to fail'),
- error: (error) => expect(error.message).toContain(msg),
- });
-
- const req = httpTestingController.expectOne(heroService.heroesUrl);
-
- // respond with a 404 and the error message in the body
- req.flush(msg, {status: 404, statusText: 'Not Found'});
- });
-
- it('should turn network error into user-facing error', (done) => {
- // Create mock ProgressEvent with type `error`, raised when something goes wrong at
- // the network level. Connection timeout, DNS error, offline, etc.
- const errorEvent = new ProgressEvent('error');
-
- const updateHero: Hero = {id: 1, name: 'A'};
- heroService.updateHero(updateHero).subscribe({
- next: (heroes) => fail('expected to fail'),
- error: (error) => {
- expect(error).toBe(errorEvent);
- done();
- },
- });
-
- const req = httpTestingController.expectOne(heroService.heroesUrl);
-
- // Respond with mock error
- req.error(errorEvent);
- });
- });
-
- // TODO: test other HeroService methods
-});
diff --git a/adev/src/content/examples/testing/src/app/model/hero.service.ts b/adev/src/content/examples/testing/src/app/model/hero.service.ts
deleted file mode 100644
index ecfbe462213..00000000000
--- a/adev/src/content/examples/testing/src/app/model/hero.service.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import {HttpClient, HttpErrorResponse, HttpHeaders} from '@angular/common/http';
-import {inject, Injectable} from '@angular/core';
-import {Observable} from 'rxjs';
-import {catchError, map, tap} from 'rxjs/operators';
-
-import {Hero} from './hero';
-
-const httpOptions = {
- headers: new HttpHeaders({'Content-Type': 'application/json'}),
-};
-
-@Injectable({providedIn: 'root'})
-export class HeroService {
- readonly heroesUrl = 'api/heroes'; // URL to web api
-
- private http = inject(HttpClient);
-
- /** GET heroes from the server */
- getHeroes(): Observable {
- return this.http.get(this.heroesUrl).pipe(
- tap((heroes) => this.log('fetched heroes')),
- catchError(this.handleError('getHeroes')),
- ) as Observable;
- }
-
- /** GET hero by id. Return `undefined` when id not found */
- getHero(id: number | string): Observable {
- if (typeof id === 'string') {
- id = parseInt(id, 10);
- }
- const url = `${this.heroesUrl}/?id=${id}`;
- return this.http.get(url).pipe(
- map((heroes) => heroes[0]), // returns a {0|1} element array
- tap((h) => {
- const outcome = h ? 'fetched' : 'did not find';
- this.log(`${outcome} hero id=${id}`);
- }),
- catchError(this.handleError(`getHero id=${id}`)),
- );
- }
-
- //////// Save methods //////////
-
- /** POST: add a new hero to the server */
- addHero(hero: Hero): Observable {
- return this.http.post(this.heroesUrl, hero, httpOptions).pipe(
- tap((addedHero) => this.log(`added hero w/ id=${addedHero.id}`)),
- catchError(this.handleError('addHero')),
- );
- }
- /** DELETE: delete the hero from the server */
- deleteHero(hero: Hero | number): Observable {
- const id = typeof hero === 'number' ? hero : hero.id;
- const url = `${this.heroesUrl}/${id}`;
-
- return this.http.delete(url, httpOptions).pipe(
- tap((_) => this.log(`deleted hero id=${id}`)),
- catchError(this.handleError('deleteHero')),
- );
- }
-
- /** PUT: update the hero on the server */
- updateHero(hero: Hero): Observable {
- return this.http.put(this.heroesUrl, hero, httpOptions).pipe(
- tap((_) => this.log(`updated hero id=${hero.id}`)),
- catchError(this.handleError('updateHero')),
- );
- }
- /**
- * Returns a function that handles Http operation failures.
- * This error handler lets the app continue to run as if no error occurred.
- *
- * @param operation - name of the operation that failed
- */
- private handleError(operation = 'operation') {
- return (error: HttpErrorResponse): Observable => {
- // TODO: send the error to remote logging infrastructure
- console.error(error); // log to console instead
-
- // If a native error is caught, do not transform it. We only want to
- // transform response errors that are not wrapped in an `Error`.
- if (error.error instanceof Event) {
- throw error.error;
- }
-
- const message = `server returned code ${error.status} with body "${error.error}"`;
- // TODO: better job of transforming error for user consumption
- throw new Error(`${operation} failed: ${message}`);
- };
- }
-
- private log(message: string) {
- console.log('HeroService: ' + message);
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/model/hero.ts b/adev/src/content/examples/testing/src/app/model/hero.ts
deleted file mode 100644
index a61b497759b..00000000000
--- a/adev/src/content/examples/testing/src/app/model/hero.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface Hero {
- id: number;
- name: string;
-}
diff --git a/adev/src/content/examples/testing/src/app/model/index.ts b/adev/src/content/examples/testing/src/app/model/index.ts
deleted file mode 100644
index 694c333a879..00000000000
--- a/adev/src/content/examples/testing/src/app/model/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './hero';
-export * from './hero.service';
-export * from './user.service';
diff --git a/adev/src/content/examples/testing/src/app/model/testing/http-client.spec.ts b/adev/src/content/examples/testing/src/app/model/testing/http-client.spec.ts
deleted file mode 100644
index 21dcd3143f6..00000000000
--- a/adev/src/content/examples/testing/src/app/model/testing/http-client.spec.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-// Http testing module and mocking controller
-import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
-
-// Other imports
-import {TestBed} from '@angular/core/testing';
-import {HttpClient, HttpErrorResponse} from '@angular/common/http';
-
-import {HttpHeaders} from '@angular/common/http';
-
-interface Data {
- name: string;
-}
-
-const testUrl = '/data';
-
-describe('HttpClient testing', () => {
- let httpClient: HttpClient;
- let httpTestingController: HttpTestingController;
-
- beforeEach(() => {
- TestBed.configureTestingModule({
- imports: [HttpClientTestingModule],
- });
-
- // Inject the http service and test controller for each test
- httpClient = TestBed.inject(HttpClient);
- httpTestingController = TestBed.inject(HttpTestingController);
- });
-
- afterEach(() => {
- // After every test, assert that there are no more pending requests.
- httpTestingController.verify();
- });
-
- /// Tests begin ///
- it('can test HttpClient.get', () => {
- const testData: Data = {name: 'Test Data'};
-
- // Make an HTTP GET request
- httpClient.get(testUrl).subscribe((data) =>
- // When observable resolves, result should match test data
- expect(data).toEqual(testData),
- );
-
- // The following `expectOne()` will match the request's URL.
- // If no requests or multiple requests matched that URL
- // `expectOne()` would throw.
- const req = httpTestingController.expectOne('/data');
-
- // Assert that the request is a GET.
- expect(req.request.method).toEqual('GET');
-
- // Respond with mock data, causing Observable to resolve.
- // Subscribe callback asserts that correct data was returned.
- req.flush(testData);
-
- // Finally, assert that there are no outstanding requests.
- httpTestingController.verify();
- });
-
- it('can test HttpClient.get with matching header', () => {
- const testData: Data = {name: 'Test Data'};
-
- // Make an HTTP GET request with specific header
- httpClient
- .get(testUrl, {
- headers: new HttpHeaders({Authorization: 'my-auth-token'}),
- })
- .subscribe((data) => expect(data).toEqual(testData));
-
- // Find request with a predicate function.
- // Expect one request with an authorization header
- const req = httpTestingController.expectOne((request) => request.headers.has('Authorization'));
- req.flush(testData);
- });
-
- it('can test multiple requests', () => {
- const testData: Data[] = [{name: 'bob'}, {name: 'carol'}, {name: 'ted'}, {name: 'alice'}];
-
- // Make three requests in a row
- httpClient
- .get(testUrl)
- .subscribe((d) => expect(d.length).withContext('should have no data').toEqual(0));
-
- httpClient
- .get(testUrl)
- .subscribe((d) =>
- expect(d).withContext('should be one element array').toEqual([testData[0]]),
- );
-
- httpClient
- .get(testUrl)
- .subscribe((d) => expect(d).withContext('should be expected data').toEqual(testData));
-
- // get all pending requests that match the given URL
- const requests = httpTestingController.match(testUrl);
- expect(requests.length).toEqual(3);
-
- // Respond to each request with different results
- requests[0].flush([]);
- requests[1].flush([testData[0]]);
- requests[2].flush(testData);
- });
-
- it('can test for 404 error', () => {
- const emsg = 'deliberate 404 error';
-
- httpClient.get(testUrl).subscribe({
- next: (data) => fail('should have failed with the 404 error'),
- error: (error: HttpErrorResponse) => {
- expect(error.status).withContext('status').toEqual(404);
- expect(error.error).withContext('message').toEqual(emsg);
- },
- });
-
- const req = httpTestingController.expectOne(testUrl);
-
- // Respond with mock error
- req.flush(emsg, {status: 404, statusText: 'Not Found'});
- });
-
- it('can test for network error', (done) => {
- // Create mock ProgressEvent with type `error`, raised when something goes wrong at
- // the network level. Connection timeout, DNS error, offline, etc.
- const errorEvent = new ProgressEvent('error');
-
- httpClient.get(testUrl).subscribe({
- next: (data) => fail('should have failed with the network error'),
- error: (error: HttpErrorResponse) => {
- expect(error.error).toBe(errorEvent);
- done();
- },
- });
-
- const req = httpTestingController.expectOne(testUrl);
-
- // Respond with mock error
- req.error(errorEvent);
- });
-
- it('httpTestingController.verify should fail if HTTP response not simulated', () => {
- // Sends request
- httpClient.get('some/api').subscribe();
-
- // verify() should fail because haven't handled the pending request.
- expect(() => httpTestingController.verify()).toThrow();
-
- // Now get and flush the request so that afterEach() doesn't fail
- const req = httpTestingController.expectOne('some/api');
- req.flush(null);
- });
-
- // Proves that verify in afterEach() really would catch error
- // if test doesn't simulate the HTTP response.
- //
- // Must disable this test because can't catch an error in an afterEach().
- // Uncomment if you want to confirm that afterEach() does the job.
- // it('afterEach() should fail when HTTP response not simulated',() => {
- // // Sends request which is never handled by this test
- // httpClient.get('some/api').subscribe();
- // });
-});
diff --git a/adev/src/content/examples/testing/src/app/model/testing/index.ts b/adev/src/content/examples/testing/src/app/model/testing/index.ts
deleted file mode 100644
index 898f64c2783..00000000000
--- a/adev/src/content/examples/testing/src/app/model/testing/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './test-hero.service';
diff --git a/adev/src/content/examples/testing/src/app/model/testing/test-hero.service.ts b/adev/src/content/examples/testing/src/app/model/testing/test-hero.service.ts
deleted file mode 100644
index c93a3122a8a..00000000000
--- a/adev/src/content/examples/testing/src/app/model/testing/test-hero.service.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import {Injectable} from '@angular/core';
-
-import {Observable} from 'rxjs';
-import {asyncData} from '../../../testing';
-
-import {map} from 'rxjs/operators';
-
-// re-export for tester convenience
-export {Hero} from '../hero';
-export {HeroService} from '../hero.service';
-export {getTestHeroes} from './test-heroes';
-
-import {Hero} from '../hero';
-import {HeroService} from '../hero.service';
-import {getTestHeroes} from './test-heroes';
-
-@Injectable()
-/**
- * FakeHeroService pretends to make real http requests.
- * implements only as much of HeroService as is actually consumed by the app
- */
-export class TestHeroService extends HeroService {
- constructor() {
- // This is a fake testing service that won't be making HTTP
- // requests so we can pass in `null` as the HTTP client.
- super(null!);
- }
-
- heroes = getTestHeroes();
- lastResult!: Observable; // result from last method call
-
- override addHero(hero: Hero): Observable {
- throw new Error('Method not implemented.');
- }
-
- override deleteHero(hero: number | Hero): Observable {
- throw new Error('Method not implemented.');
- }
-
- override getHeroes(): Observable {
- return (this.lastResult = asyncData(this.heroes));
- }
-
- override getHero(id: number | string): Observable {
- if (typeof id === 'string') {
- id = parseInt(id, 10);
- }
- const hero = this.heroes.find((h) => h.id === id);
- this.lastResult = asyncData(hero);
- return this.lastResult;
- }
-
- override updateHero(hero: Hero): Observable {
- return (this.lastResult = this.getHero(hero.id).pipe(
- map((h) => {
- if (h) {
- return Object.assign(h, hero);
- }
- throw new Error(`Hero ${hero.id} not found`);
- }),
- ));
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/model/testing/test-heroes.ts b/adev/src/content/examples/testing/src/app/model/testing/test-heroes.ts
deleted file mode 100644
index 709ec3212de..00000000000
--- a/adev/src/content/examples/testing/src/app/model/testing/test-heroes.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import {Hero} from '../hero';
-
-/** return fresh array of test heroes */
-export function getTestHeroes(): Hero[] {
- return [
- {id: 41, name: 'Bob'},
- {id: 42, name: 'Carol'},
- {id: 43, name: 'Ted'},
- {id: 44, name: 'Alice'},
- {id: 45, name: 'Speedy'},
- {id: 46, name: 'Stealthy'},
- ];
-}
diff --git a/adev/src/content/examples/testing/src/app/model/user.service.ts b/adev/src/content/examples/testing/src/app/model/user.service.ts
deleted file mode 100644
index d66826f7f46..00000000000
--- a/adev/src/content/examples/testing/src/app/model/user.service.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {Injectable, signal} from '@angular/core';
-
-@Injectable({providedIn: 'root'})
-export class UserService {
- isLoggedIn = signal(true);
- user = signal({name: 'Sam Spade'});
-}
diff --git a/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts b/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts
deleted file mode 100755
index 3d8f0006427..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/canvas.component.spec.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-// #docplaster
-// #docregion without-toBlob-macrotask
-import {fakeAsync, TestBed, tick} from '@angular/core/testing';
-
-import {CanvasComponent} from './canvas.component';
-
-describe('CanvasComponent', () => {
- // #enddocregion without-toBlob-macrotask
- // #docregion enable-toBlob-macrotask
- beforeEach(() => {
- (window as any).__zone_symbol__FakeAsyncTestMacroTask = [
- {
- source: 'HTMLCanvasElement.toBlob',
- callbackArgs: [{size: 200}],
- },
- ];
- });
- // #enddocregion enable-toBlob-macrotask
- // #docregion without-toBlob-macrotask
- it('should be able to generate blob data from canvas', fakeAsync(() => {
- const fixture = TestBed.createComponent(CanvasComponent);
- const canvasComp = fixture.componentInstance;
-
- fixture.detectChanges();
- expect(canvasComp.blobSize).toBe(0);
-
- tick();
- expect(canvasComp.blobSize).toBeGreaterThan(0);
- }));
-});
-// #enddocregion without-toBlob-macrotask
diff --git a/adev/src/content/examples/testing/src/app/shared/canvas.component.ts b/adev/src/content/examples/testing/src/app/shared/canvas.component.ts
deleted file mode 100755
index 90a23b7acf8..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/canvas.component.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// #docplaster
-// #docregion import-canvas-patch
-// Import patch to make async `HTMLCanvasElement` methods (such as `.toBlob()`) Zone.js-aware.
-// Either import in `polyfills.ts` (if used in more than one places in the app) or in the component
-// file using `HTMLCanvasElement` (if it is only used in a single file).
-import 'zone.js/plugins/zone-patch-canvas';
-// #enddocregion import-canvas-patch
-// #docregion main
-import {Component, AfterViewInit, ViewChild, ElementRef} from '@angular/core';
-
-@Component({
- selector: 'sample-canvas',
- template: '',
-})
-export class CanvasComponent implements AfterViewInit {
- blobSize = 0;
- @ViewChild('sampleCanvas') sampleCanvas!: ElementRef;
-
- ngAfterViewInit() {
- const canvas: HTMLCanvasElement = this.sampleCanvas.nativeElement;
- const context = canvas.getContext('2d')!;
-
- context.clearRect(0, 0, 200, 200);
- context.fillStyle = '#FF1122';
- context.fillRect(0, 0, 200, 200);
-
- canvas.toBlob((blob) => {
- this.blobSize = blob?.size ?? 0;
- });
- }
-}
-// #enddocregion main
diff --git a/adev/src/content/examples/testing/src/app/shared/highlight.directive.spec.ts b/adev/src/content/examples/testing/src/app/shared/highlight.directive.spec.ts
deleted file mode 100755
index ffc340fd347..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/highlight.directive.spec.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import {Component, DebugElement} from '@angular/core';
-import {ComponentFixture, TestBed} from '@angular/core/testing';
-import {By} from '@angular/platform-browser';
-
-import {HighlightDirective} from './highlight.directive';
-
-// #docregion test-component
-@Component({
- template: `
Something Yellow
-
The Default (Gray)
-
No Highlight
- `,
- imports: [HighlightDirective],
-})
-class TestComponent {}
-// #enddocregion test-component
-
-describe('HighlightDirective', () => {
- let fixture: ComponentFixture;
- let des: DebugElement[]; // the three elements w/ the directive
- let bareH2: DebugElement; // the
w/o the directive
-
- // #docregion selected-tests
- beforeEach(() => {
- fixture = TestBed.configureTestingModule({
- imports: [HighlightDirective, TestComponent],
- }).createComponent(TestComponent);
-
- fixture.detectChanges(); // initial binding
-
- // all elements with an attached HighlightDirective
- des = fixture.debugElement.queryAll(By.directive(HighlightDirective));
-
- // the h2 without the HighlightDirective
- bareH2 = fixture.debugElement.query(By.css('h2:not([highlight])'));
- });
-
- // color tests
- it('should have three highlighted elements', () => {
- expect(des.length).toBe(3);
- });
-
- it('should color 1st
background w/ default color', () => {
- const dir = des[1].injector.get(HighlightDirective) as HighlightDirective;
- const bgColor = des[1].nativeElement.style.backgroundColor;
- expect(bgColor).toBe(dir.defaultColor);
- });
-
- it('should bind background to value color', () => {
- // easier to work with nativeElement
- const input = des[2].nativeElement as HTMLInputElement;
- expect(input.style.backgroundColor).withContext('initial backgroundColor').toBe('cyan');
-
- input.value = 'green';
-
- // Dispatch a DOM event so that Angular responds to the input value change.
- input.dispatchEvent(new Event('input'));
- fixture.detectChanges();
-
- expect(input.style.backgroundColor).withContext('changed backgroundColor').toBe('green');
- });
-
- it('bare
should not have a customProperty', () => {
- expect(bareH2.properties['customProperty']).toBeUndefined();
- });
- // #enddocregion selected-tests
-
- // Removed on 12/02/2016 when ceased public discussion of the `Renderer`. Revive in future?
- // // customProperty tests
- // it('all highlighted elements should have a true customProperty', () => {
- // const allTrue = des.map(de => !!de.properties['customProperty']).every(v => v === true);
- // expect(allTrue).toBe(true);
- // });
-
- // injected directive
- // attached HighlightDirective can be injected
- it('can inject `HighlightDirective` in 1st
', () => {
- const dir = des[0].injector.get(HighlightDirective);
- expect(dir).toBeTruthy();
- });
-
- it('cannot inject `HighlightDirective` in 3rd
', () => {
- const dir = bareH2.injector.get(HighlightDirective, null);
- expect(dir).toBe(null);
- });
-
- // DebugElement.providerTokens
- // attached HighlightDirective should be listed in the providerTokens
- it('should have `HighlightDirective` in 1st
providerTokens', () => {
- expect(des[0].providerTokens).toContain(HighlightDirective);
- });
-
- it('should not have `HighlightDirective` in 3rd
providerTokens', () => {
- expect(bareH2.providerTokens).not.toContain(HighlightDirective);
- });
-});
diff --git a/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts b/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts
deleted file mode 100755
index 858d3843660..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/highlight.directive.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/* eslint-disable @angular-eslint/directive-selector */
-// #docregion
-import {Directive, ElementRef, inject, input, OnChanges} from '@angular/core';
-
-@Directive({selector: '[highlight]'})
-/**
- * Set backgroundColor for the attached element to highlight color
- * and set the element's customProperty to true
- */
-export class HighlightDirective implements OnChanges {
- defaultColor = 'rgb(211, 211, 211)'; // lightgray
-
- bgColor = input('', {alias: 'highlight'});
-
- private el = inject(ElementRef);
-
- constructor() {
- this.el.nativeElement.style.customProperty = true;
- }
-
- ngOnChanges() {
- this.el.nativeElement.style.backgroundColor = this.bgColor || this.defaultColor;
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/shared/shared.ts b/adev/src/content/examples/testing/src/app/shared/shared.ts
deleted file mode 100755
index 01bf42aa126..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/shared.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {FormsModule} from '@angular/forms';
-
-import {HighlightDirective} from './highlight.directive';
-import {TitleCasePipe} from './title-case.pipe';
-
-export const sharedImports = [FormsModule, HighlightDirective, TitleCasePipe];
diff --git a/adev/src/content/examples/testing/src/app/shared/title-case.pipe.spec.ts b/adev/src/content/examples/testing/src/app/shared/title-case.pipe.spec.ts
deleted file mode 100644
index a4501980cdb..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/title-case.pipe.spec.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// #docplaster
-// #docregion
-import {TitleCasePipe} from './title-case.pipe';
-
-// #docregion excerpt
-describe('TitleCasePipe', () => {
- // This pipe is a pure, stateless function so no need for BeforeEach
- const pipe = new TitleCasePipe();
-
- it('transforms "abc" to "Abc"', () => {
- expect(pipe.transform('abc')).toBe('Abc');
- });
-
- it('transforms "abc def" to "Abc Def"', () => {
- expect(pipe.transform('abc def')).toBe('Abc Def');
- });
-
- // ... more tests ...
- // #enddocregion excerpt
- it('leaves "Abc Def" unchanged', () => {
- expect(pipe.transform('Abc Def')).toBe('Abc Def');
- });
-
- it('transforms "abc-def" to "Abc-def"', () => {
- expect(pipe.transform('abc-def')).toBe('Abc-def');
- });
-
- it('transforms " abc def" to " Abc Def" (preserves spaces) ', () => {
- expect(pipe.transform(' abc def')).toBe(' Abc Def');
- });
- // #docregion excerpt
-});
-// #enddocregion excerpt
diff --git a/adev/src/content/examples/testing/src/app/shared/title-case.pipe.ts b/adev/src/content/examples/testing/src/app/shared/title-case.pipe.ts
deleted file mode 100755
index d0861444fc9..00000000000
--- a/adev/src/content/examples/testing/src/app/shared/title-case.pipe.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-// #docregion
-import {Pipe, PipeTransform} from '@angular/core';
-
-@Pipe({name: 'titlecase', pure: true})
-/** Transform to Title Case: uppercase the first letter of the words in a string. */
-export class TitleCasePipe implements PipeTransform {
- transform(input: string): string {
- return input.length === 0
- ? ''
- : input.replace(/\w\S*/g, (txt) => txt[0].toUpperCase() + txt.slice(1).toLowerCase());
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/twain/quote.ts b/adev/src/content/examples/testing/src/app/twain/quote.ts
deleted file mode 100644
index 293b1348801..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/quote.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface Quote {
- id: number;
- quote: string;
-}
diff --git a/adev/src/content/examples/testing/src/app/twain/twain.component.marbles.spec.ts b/adev/src/content/examples/testing/src/app/twain/twain.component.marbles.spec.ts
deleted file mode 100755
index d69b474d4a1..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/twain.component.marbles.spec.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-// #docplaster
-import {fakeAsync, ComponentFixture, TestBed, tick} from '@angular/core/testing';
-
-// #docregion import-marbles
-import {cold, getTestScheduler} from 'jasmine-marbles';
-// #enddocregion import-marbles
-
-import {TwainService} from './twain.service';
-import {TwainComponent} from './twain.component';
-
-describe('TwainComponent (marbles)', () => {
- let component: TwainComponent;
- let fixture: ComponentFixture;
- let getQuoteSpy: jasmine.Spy;
- let quoteEl: HTMLElement;
- let testQuote: string;
-
- // Helper function to get the error message element value
- // An *ngIf keeps it out of the DOM until there is an error
- const errorMessage = () => {
- const el = fixture.nativeElement.querySelector('.error');
- return el ? el.textContent : null;
- };
-
- beforeEach(() => {
- // Create a fake TwainService object with a `getQuote()` spy
- const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
- getQuoteSpy = twainService.getQuote;
-
- TestBed.configureTestingModule({
- imports: [TwainComponent],
- providers: [{provide: TwainService, useValue: twainService}],
- });
-
- fixture = TestBed.createComponent(TwainComponent);
- component = fixture.componentInstance;
- quoteEl = fixture.nativeElement.querySelector('.twain');
- testQuote = 'Test Quote';
- });
-
- // A synchronous test that simulates async behavior
- // #docregion get-quote-test
- it('should show quote after getQuote (marbles)', () => {
- // observable test quote value and complete(), after delay
- // #docregion test-quote-marbles
- const q$ = cold('---x|', {x: testQuote});
- // #enddocregion test-quote-marbles
- getQuoteSpy.and.returnValue(q$);
-
- fixture.detectChanges(); // ngOnInit()
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
-
- // #docregion test-scheduler-flush
- getTestScheduler().flush(); // flush the observables
- // #enddocregion test-scheduler-flush
-
- fixture.detectChanges(); // update view
-
- expect(quoteEl.textContent).withContext('should show quote').toBe(testQuote);
- expect(errorMessage()).withContext('should not show error').toBeNull();
- });
- // #enddocregion get-quote-test
-
- // Still need fakeAsync() because of component's setTimeout()
- // #docregion error-test
- it('should display error when TwainService fails', fakeAsync(() => {
- // observable error after delay
- // #docregion error-marbles
- const q$ = cold('---#|', null, new Error('TwainService test failure'));
- // #enddocregion error-marbles
- getQuoteSpy.and.returnValue(q$);
-
- fixture.detectChanges(); // ngOnInit()
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
-
- getTestScheduler().flush(); // flush the observables
- tick(); // component shows error after a setTimeout()
- fixture.detectChanges(); // update error message
-
- expect(errorMessage())
- .withContext('should display error')
- .toMatch(/test failure/);
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
- }));
- // #enddocregion error-test
-});
diff --git a/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts b/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts
deleted file mode 100755
index 874c1f67728..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/twain.component.spec.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-// #docplaster
-import {fakeAsync, ComponentFixture, TestBed, tick, waitForAsync} from '@angular/core/testing';
-
-import {asyncData, asyncError} from '../../testing';
-
-import {Subject, defer, of, throwError} from 'rxjs';
-import {last} from 'rxjs/operators';
-
-import {TwainComponent} from './twain.component';
-import {TwainService} from './twain.service';
-
-describe('TwainComponent', () => {
- let component: TwainComponent;
- let fixture: ComponentFixture;
- let getQuoteSpy: jasmine.Spy;
- let quoteEl: HTMLElement;
- let testQuote: string;
-
- // Helper function to get the error message element value
- // An *ngIf keeps it out of the DOM until there is an error
- const errorMessage = () => {
- const el = fixture.nativeElement.querySelector('.error');
- return el ? el.textContent : null;
- };
-
- // #docregion setup
- beforeEach(() => {
- TestBed.configureTestingModule({
- providers: [TwainService],
- });
- testQuote = 'Test Quote';
-
- // #docregion spy
- // Create a fake TwainService object with a `getQuote()` spy
- const twainService = TestBed.inject(TwainService);
- // Make the spy return a synchronous Observable with the test data
- getQuoteSpy = spyOn(twainService, 'getQuote').and.returnValue(of(testQuote));
- // #enddocregion spy
-
- fixture = TestBed.createComponent(TwainComponent);
- fixture.autoDetectChanges();
- component = fixture.componentInstance;
- quoteEl = fixture.nativeElement.querySelector('.twain');
- });
- // #enddocregion setup
-
- describe('when test with synchronous observable', () => {
- it('should not show quote before OnInit', () => {
- expect(quoteEl.textContent).withContext('nothing displayed').toBe('');
- expect(errorMessage()).withContext('should not show error element').toBeNull();
- expect(getQuoteSpy.calls.any()).withContext('getQuote not yet called').toBe(false);
- });
-
- // The quote would not be immediately available if the service were truly async.
- // #docregion sync-test
- it('should show quote after component initialized', async () => {
- await fixture.whenStable(); // onInit()
-
- // sync spy result shows testQuote immediately after init
- expect(quoteEl.textContent).toBe(testQuote);
- expect(getQuoteSpy.calls.any()).withContext('getQuote called').toBe(true);
- });
- // #enddocregion sync-test
-
- // The error would not be immediately available if the service were truly async.
- // Use `fakeAsync` because the component error calls `setTimeout`
- // #docregion error-test
- it('should display error when TwainService fails', fakeAsync(() => {
- // tell spy to return an error observable after a timeout
- getQuoteSpy.and.returnValue(
- defer(() => {
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- reject('TwainService test failure');
- });
- });
- }),
- );
- fixture.detectChanges(); // onInit()
- // sync spy errors immediately after init
-
- tick(); // flush the setTimeout()
-
- fixture.detectChanges(); // update errorMessage within setTimeout()
-
- expect(errorMessage())
- .withContext('should display error')
- .toMatch(/test failure/);
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
- }));
- // #enddocregion error-test
- });
-
- describe('when test with asynchronous observable', () => {
- beforeEach(() => {
- // #docregion async-setup
- // Simulate delayed observable values with the `asyncData()` helper
- getQuoteSpy.and.returnValue(asyncData(testQuote));
- // #enddocregion async-setup
- });
-
- it('should not show quote before OnInit', () => {
- expect(quoteEl.textContent).withContext('nothing displayed').toBe('');
- expect(errorMessage()).withContext('should not show error element').toBeNull();
- expect(getQuoteSpy.calls.any()).withContext('getQuote not yet called').toBe(false);
- });
-
- it('should still not show quote after component initialized', () => {
- fixture.detectChanges();
- // getQuote service is async => still has not returned with quote
- // so should show the start value, '...'
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
- expect(errorMessage()).withContext('should not show error').toBeNull();
- expect(getQuoteSpy.calls.any()).withContext('getQuote called').toBe(true);
- });
-
- // #docregion fake-async-test
- it('should show quote after getQuote (fakeAsync)', fakeAsync(() => {
- fixture.detectChanges(); // ngOnInit()
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
-
- tick(); // flush the observable to get the quote
- fixture.detectChanges(); // update view
-
- expect(quoteEl.textContent).withContext('should show quote').toBe(testQuote);
- expect(errorMessage()).withContext('should not show error').toBeNull();
- }));
- // #enddocregion fake-async-test
-
- // #docregion async-test
- it('should show quote after getQuote (async)', async () => {
- fixture.detectChanges(); // ngOnInit()
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
-
- await fixture.whenStable();
- // wait for async getQuote
- fixture.detectChanges(); // update view with quote
- expect(quoteEl.textContent).toBe(testQuote);
- expect(errorMessage()).withContext('should not show error').toBeNull();
- });
- // #enddocregion async-test
-
- it('should display error when TwainService fails', fakeAsync(() => {
- // tell spy to return an async error observable
- getQuoteSpy.and.returnValue(asyncError('TwainService test failure'));
-
- fixture.detectChanges();
- tick(); // component shows error after a setTimeout()
- fixture.detectChanges(); // update error message
-
- expect(errorMessage())
- .withContext('should display error')
- .toMatch(/test failure/);
- expect(quoteEl.textContent).withContext('should show placeholder').toBe('...');
- }));
- });
-});
diff --git a/adev/src/content/examples/testing/src/app/twain/twain.component.ts b/adev/src/content/examples/testing/src/app/twain/twain.component.ts
deleted file mode 100755
index c14e7fe466a..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/twain.component.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-// #docregion
-import {Component, inject, OnInit, signal} from '@angular/core';
-import {AsyncPipe} from '@angular/common';
-import {sharedImports} from '../shared/shared';
-
-import {Observable, of} from 'rxjs';
-import {catchError, startWith} from 'rxjs/operators';
-
-import {TwainService} from './twain.service';
-
-@Component({
- selector: 'twain-quote',
- // #docregion template
- template: `
- {{ quote | async }}
-
-
- @if (errorMessage()) {
-
{{ errorMessage() }}
- }`,
- // #enddocregion template
- styles: ['.twain { font-style: italic; } .error { color: red; }'],
- imports: [AsyncPipe, sharedImports],
-})
-export class TwainComponent {
- errorMessage = signal('');
- quote?: Observable;
-
- private twainService = inject(TwainService);
-
- constructor() {
- this.getQuote();
- }
-
- // #docregion get-quote
- getQuote() {
- this.errorMessage.set('');
- this.quote = this.twainService.getQuote().pipe(
- startWith('...'),
- catchError((err: any) => {
- this.errorMessage.set(err.message || err.toString());
- return of('...'); // reset message to placeholder
- }),
- );
- // #enddocregion get-quote
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/twain/twain.data.ts b/adev/src/content/examples/testing/src/app/twain/twain.data.ts
deleted file mode 100644
index 9b550934c03..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/twain.data.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {Quote} from './quote';
-
-export const QUOTES: Quote[] = [
- 'Always do right. This will gratify some people and astonish the rest.',
- 'I have never let my schooling interfere with my education.',
- "Don't go around saying the world owes you a living. The world owes you nothing. It was here first.",
- 'Whenever you find yourself on the side of the majority, it is time to pause and reflect.',
- "If you tell the truth, you don't have to remember anything.",
- 'Clothes make the man. Naked people have little or no influence on society.',
- "It's not the size of the dog in the fight, it's the size of the fight in the dog.",
- "Truth is stranger than fiction, but it is because Fiction is obliged to stick to possibilities; Truth isn't.",
- 'The man who does not read good books has no advantage over the man who cannot read them.',
- 'Get your facts first, and then you can distort them as much as you please.',
-].map((q, i) => ({id: i + 1, quote: q}));
diff --git a/adev/src/content/examples/testing/src/app/twain/twain.service.ts b/adev/src/content/examples/testing/src/app/twain/twain.service.ts
deleted file mode 100644
index 30d9d630373..00000000000
--- a/adev/src/content/examples/testing/src/app/twain/twain.service.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-// Mark Twain Quote service gets quotes from server
-import {inject, Injectable} from '@angular/core';
-import {HttpClient, HttpErrorResponse} from '@angular/common/http';
-
-import {Observable, of, throwError, Observer} from 'rxjs';
-import {concat, map, retryWhen, switchMap, take, tap} from 'rxjs/operators';
-
-import {Quote} from './quote';
-
-@Injectable()
-export class TwainService {
- private http = inject(HttpClient);
-
- private nextId = 1;
-
- getQuote(): Observable {
- return Observable.create((observer: Observer) => observer.next(this.nextId++)).pipe(
- // tap((id: number) => console.log(id)),
- // tap((id: number) => { throw new Error('Simulated server error'); }),
-
- switchMap((id: number) => this.http.get(`api/quotes/${id}`)),
- // tap((q : Quote) => console.log(q)),
- map((q: Quote) => q.quote),
-
- // `errors` is observable of http.get errors
- retryWhen((errors) =>
- errors.pipe(
- switchMap((error: HttpErrorResponse) => {
- if (error.status === 404) {
- // Queried for quote that doesn't exist.
- this.nextId = 1; // retry with quote id:1
- return of(null); // signal OK to retry
- }
- // Some other HTTP error.
- console.error(error);
- return throwError('Cannot get Twain quotes from the server');
- }),
- take(2),
- // If a second retry value, then didn't find id:1 and triggers the following error
- concat(throwError('There are no Twain quotes')), // didn't find id:1
- ),
- ),
- );
- }
-}
diff --git a/adev/src/content/examples/testing/src/app/welcome/welcome.component.spec.ts b/adev/src/content/examples/testing/src/app/welcome/welcome.component.spec.ts
deleted file mode 100755
index 149a6f91c9f..00000000000
--- a/adev/src/content/examples/testing/src/app/welcome/welcome.component.spec.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-// #docplaster
-import {ComponentFixture, inject, TestBed} from '@angular/core/testing';
-
-import {UserService} from '../model/user.service';
-import {WelcomeComponent} from './welcome.component';
-
-// #docregion mock-user-service
-class MockUserService {
- isLoggedIn = true;
- user = {name: 'Test User'};
-}
-// #enddocregion mock-user-service
-
-describe('WelcomeComponent', () => {
- let comp: WelcomeComponent;
- let fixture: ComponentFixture;
- let componentUserService: UserService; // the actually injected service
- let userService: UserService; // the TestBed injected service
- let el: HTMLElement; // the DOM element with the welcome message
-
- // #docregion setup
- beforeEach(() => {
- fixture = TestBed.createComponent(WelcomeComponent);
- fixture.autoDetectChanges();
- comp = fixture.componentInstance;
-
- // #docregion injected-service
- // UserService actually injected into the component
- userService = fixture.debugElement.injector.get(UserService);
- // #enddocregion injected-service
- componentUserService = userService;
- // #docregion inject-from-testbed
- // UserService from the root injector
- userService = TestBed.inject(UserService);
- // #enddocregion inject-from-testbed
-
- // get the "welcome" element by CSS selector (e.g., by class name)
- el = fixture.nativeElement.querySelector('.welcome');
- });
- // #enddocregion setup
-
- // #docregion tests
- it('should welcome the user', async () => {
- await fixture.whenStable();
- const content = el.textContent;
- expect(content).withContext('"Welcome ..."').toContain('Welcome');
- expect(content).withContext('expected name').toContain('Test User');
- });
-
- it('should welcome "Bubba"', async () => {
- userService.user.set({name: 'Bubba'}); // welcome message hasn't been shown yet
- await fixture.whenStable();
- expect(el.textContent).toContain('Bubba');
- });
-
- it('should request login if not logged in', async () => {
- userService.isLoggedIn.set(false); // welcome message hasn't been shown yet
- await fixture.whenStable();
- const content = el.textContent;
- expect(content).withContext('not welcomed').not.toContain('Welcome');
- expect(content)
- .withContext('"log in"')
- .toMatch(/log in/i);
- });
- // #enddocregion tests
-
- it("should inject the component's UserService instance", inject(
- [UserService],
- (service: UserService) => {
- expect(service).toBe(componentUserService);
- },
- ));
-
- it('TestBed and Component UserService should be the same', () => {
- expect(userService).toBe(componentUserService);
- });
-});
diff --git a/adev/src/content/examples/testing/src/app/welcome/welcome.component.ts b/adev/src/content/examples/testing/src/app/welcome/welcome.component.ts
deleted file mode 100755
index 03d5936d75d..00000000000
--- a/adev/src/content/examples/testing/src/app/welcome/welcome.component.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// #docregion
-import {Component, inject, OnInit, signal} from '@angular/core';
-import {UserService} from '../model/user.service';
-
-@Component({
- selector: 'app-welcome',
- template: '
{{welcome()}}
',
-})
-// #docregion class
-export class WelcomeComponent {
- welcome = signal('');
- private userService = inject(UserService);
-
- constructor() {
- this.welcome.set(
- this.userService.isLoggedIn() ? 'Welcome, ' + this.userService.user().name : 'Please log in.',
- );
- }
-}
-// #enddocregion class
diff --git a/adev/src/content/examples/testing/src/expected.ts b/adev/src/content/examples/testing/src/expected.ts
deleted file mode 100644
index 5339fa97259..00000000000
--- a/adev/src/content/examples/testing/src/expected.ts
+++ /dev/null
@@ -1 +0,0 @@
-/* Ignore. Satisfies static analysis of router config in app.component.router.spec.ts */
diff --git a/adev/src/content/examples/testing/src/index-specs.html b/adev/src/content/examples/testing/src/index-specs.html
deleted file mode 100644
index ca132f6cd05..00000000000
--- a/adev/src/content/examples/testing/src/index-specs.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/adev/src/content/examples/testing/src/index.html b/adev/src/content/examples/testing/src/index.html
deleted file mode 100644
index 4106cb2d82e..00000000000
--- a/adev/src/content/examples/testing/src/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
- App Under Test
-
-
-
-
-
-
-
-
diff --git a/adev/src/content/examples/testing/src/main.ts b/adev/src/content/examples/testing/src/main.ts
deleted file mode 100755
index 091b8a9b07c..00000000000
--- a/adev/src/content/examples/testing/src/main.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// main app entry point
-import {bootstrapApplication} from '@angular/platform-browser';
-import {AppComponent} from './app/app.component';
-import {appConfig} from './app/app.config';
-
-bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err));
diff --git a/adev/src/content/examples/testing/src/test.css b/adev/src/content/examples/testing/src/test.css
deleted file mode 100644
index d832553e525..00000000000
--- a/adev/src/content/examples/testing/src/test.css
+++ /dev/null
@@ -1 +0,0 @@
-@import '~jasmine-core/lib/jasmine-core/jasmine.css';
diff --git a/adev/src/content/examples/testing/src/testing/async-observable-helpers.ts b/adev/src/content/examples/testing/src/testing/async-observable-helpers.ts
deleted file mode 100644
index d2cdd657237..00000000000
--- a/adev/src/content/examples/testing/src/testing/async-observable-helpers.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Mock async observables that return asynchronously.
- * The observable either emits once and completes or errors.
- *
- * Must call `tick()` when test with `fakeAsync()`.
- *
- * THE FOLLOWING DON'T WORK
- * Using `of().delay()` triggers TestBed errors;
- * see https://github.com/angular/angular/issues/10127 .
- *
- * Using `asap` scheduler - as in `of(value, asap)` - doesn't work either.
- */
-import {defer} from 'rxjs';
-
-// #docregion async-data
-/**
- * Create async observable that emits-once and completes
- * after a JS engine turn
- */
-export function asyncData(data: T) {
- return defer(() => Promise.resolve(data));
-}
-// #enddocregion async-data
-
-// #docregion async-error
-/**
- * Create async observable error that errors
- * after a JS engine turn
- */
-export function asyncError(errorObject: any) {
- return defer(() => Promise.reject(errorObject));
-}
-// #enddocregion async-error
diff --git a/adev/src/content/examples/testing/src/testing/index.ts b/adev/src/content/examples/testing/src/testing/index.ts
deleted file mode 100644
index 0cf2d1cb81b..00000000000
--- a/adev/src/content/examples/testing/src/testing/index.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import {DebugElement} from '@angular/core';
-import {ComponentFixture, tick} from '@angular/core/testing';
-
-export * from './async-observable-helpers';
-export * from './jasmine-matchers';
-
-///// Short utilities /////
-
-/** Wait a tick, then detect changes */
-export function advance(f: ComponentFixture): void {
- tick();
- f.detectChanges();
-}
-
-// See https://developer.mozilla.org/docs/Web/API/MouseEvent/button
-// #docregion click-event
-/** Button events to pass to `DebugElement.triggerEventHandler` for RouterLink event handler */
-export const ButtonClickEvents = {
- left: {button: 0},
- right: {button: 2},
-};
-
-/** Simulate element click. Defaults to mouse left-button click event. */
-export function click(
- el: DebugElement | HTMLElement,
- eventObj: any = ButtonClickEvents.left,
-): void {
- if (el instanceof HTMLElement) {
- el.click();
- } else {
- el.triggerEventHandler('click', eventObj);
- }
-}
-// #enddocregion click-event
diff --git a/adev/src/content/examples/testing/src/testing/jasmine-matchers.d.ts b/adev/src/content/examples/testing/src/testing/jasmine-matchers.d.ts
deleted file mode 100644
index 8378ffb9bce..00000000000
--- a/adev/src/content/examples/testing/src/testing/jasmine-matchers.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-// TODO: fix
-// declare namespace jasmine {
-// interface Matchers {
-// toHaveText(actual: any, expectationFailOutput?: any): jasmine.CustomMatcher;
-// }
-// }
diff --git a/adev/src/content/examples/testing/src/testing/jasmine-matchers.ts b/adev/src/content/examples/testing/src/testing/jasmine-matchers.ts
deleted file mode 100644
index c816509e492..00000000000
--- a/adev/src/content/examples/testing/src/testing/jasmine-matchers.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-///
-
-//// Jasmine Custom Matchers ////
-// Be sure to extend jasmine-matchers.d.ts when adding matchers
-
-export function addMatchers(): void {
- jasmine.addMatchers({
- toHaveText,
- });
-}
-
-function toHaveText(): jasmine.CustomMatcher {
- return {
- compare: (
- actual: any,
- expectedText: string,
- expectationFailOutput?: any,
- ): jasmine.CustomMatcherResult => {
- const actualText = elementText(actual);
- const pass = actualText.indexOf(expectedText) > -1;
- const message = pass ? '' : composeMessage();
- return {pass, message};
-
- function composeMessage() {
- const a = actualText.length < 100 ? actualText : actualText.slice(0, 100) + '...';
- const efo = expectationFailOutput ? ` '${expectationFailOutput}'` : '';
- return `Expected element to have text content '${expectedText}' instead of '${a}'${efo}`;
- }
- },
- };
-}
-
-function elementText(n: any): string {
- if (n instanceof Array) {
- return n.map(elementText).join('');
- }
-
- if (n.nodeType === Node.COMMENT_NODE) {
- return '';
- }
-
- if (n.nodeType === Node.ELEMENT_NODE && n.hasChildNodes()) {
- return elementText(Array.prototype.slice.call(n.childNodes));
- }
-
- if (n.nativeElement) {
- n = n.nativeElement;
- }
-
- return n.textContent;
-}
diff --git a/adev/src/content/examples/testing/stackblitz.json b/adev/src/content/examples/testing/stackblitz.json
deleted file mode 100644
index c8d925daaa2..00000000000
--- a/adev/src/content/examples/testing/stackblitz.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "description": "Heroes Test App",
- "files": [
- "src/index.html",
- "src/main.ts",
- "src/test.ts",
- "src/styles.css",
- "src/test.css",
- "e2e/src/**/*.ts",
- "src/app/**/*.css",
- "src/app/**/*.html",
- "src/app/**/*.ts",
- "src/app/**/*.spec.ts",
- "src/testing/**/*.ts",
- "src/expected.ts",
- "karma.conf.js"
- ],
- "tags": [
- "testing"
- ],
- "devDependencies": [
- "jasmine-core",
- "jasmine-marbles"
- ]
-}
diff --git a/adev/src/content/guide/routing/router-reference.md b/adev/src/content/guide/routing/router-reference.md
index 29849e977a2..9df1c923412 100644
--- a/adev/src/content/guide/routing/router-reference.md
+++ b/adev/src/content/guide/routing/router-reference.md
@@ -64,7 +64,9 @@ The browser uses the `` value to prefix relative URLs when referencin
Add the `` element just after the `` tag.
If the `app` folder is the application root, as it is for this application, set the `href` value in `index.html` as shown here.
-
+```html
+
+```
### HTML5 URLs and the ``
diff --git a/adev/src/content/guide/routing/router-tutorial.md b/adev/src/content/guide/routing/router-tutorial.md
deleted file mode 100644
index d816c1e74a0..00000000000
--- a/adev/src/content/guide/routing/router-tutorial.md
+++ /dev/null
@@ -1,276 +0,0 @@
-# Using Angular routes in a single-page application
-
-This tutorial describes how to build a single-page application, SPA that uses multiple Angular routes.
-
-In a Single Page Application \(SPA\), all of your application's functions exist in a single HTML page.
-As users access your application's features, the browser needs to render only the parts that matter to the user, instead of loading a new page.
-This pattern can significantly improve your application's user experience.
-
-To define how users navigate through your application, you use routes.
-Add routes to define how users navigate from one part of your application to another.
-You can also configure routes to guard against unexpected or unauthorized behavior.
-
-## Objectives
-
-- Organize a sample application's features into modules.
-- Define how to navigate to a component.
-- Pass information to a component using a parameter.
-- Structure routes by nesting several routes.
-- Check whether users can access a route.
-- Control whether the application can discard unsaved changes.
-- Improve performance by pre-fetching route data and lazy loading feature modules.
-- Require specific criteria to load components.
-
-## Create a sample application
-
-Using the Angular CLI, create a new application, _angular-router-sample_.
-This application will have two components: _crisis-list_ and _heroes-list_.
-
-1. Create a new Angular project, _angular-router-sample_.
-
- ```shell
- ng new angular-router-sample
- ```
-
- When prompted with `Would you like to add Angular routing?`, select `N`.
-
- When prompted with `Which stylesheet format would you like to use?`, select `CSS`.
-
- After a few moments, a new project, `angular-router-sample`, is ready.
-
-1. From your terminal, navigate to the `angular-router-sample` directory.
-1. Create a component, _crisis-list_.
-
-```shell
-ng generate component crisis-list
-```
-
-1. In your code editor, locate the file, `crisis-list.component.html` and replace the placeholder content with the following HTML.
-
-
-
-1. Create a second component, _heroes-list_.
-
-```shell
-ng generate component heroes-list
-```
-
-1. In your code editor, locate the file, `heroes-list.component.html` and replace the placeholder content with the following HTML.
-
-
-
-1. In your code editor, open the file, `app.component.html` and replace its contents with the following HTML.
-
-
-
-1. Verify that your new application runs as expected by running the `ng serve` command.
-
-```shell
-ng serve
-```
-
-1. Open a browser to `http://localhost:4200`.
-
- You should see a single web page, consisting of a title and the HTML of your two components.
-
-## Define your routes
-
-In this section, you'll define two routes:
-
-- The route `/crisis-center` opens the `crisis-center` component.
-- The route `/heroes-list` opens the `heroes-list` component.
-
-A route definition is a JavaScript object.
-Each route typically has two properties.
-The first property, `path`, is a string that specifies the URL path for the route.
-The second property, `component`, is a string that specifies what component your application should display for that path.
-
-1. From your code editor, create and open the `app.routes.ts` file.
-1. Create and export a routes list for your application:
-
- ```ts
- import {Routes} from '@angular/router';
-
- export const routes = [];
- ```
-
-1. Add two routes for your first two components:
-
- ```ts
- {path: 'crisis-list', component: CrisisListComponent},
- {path: 'heroes-list', component: HeroesListComponent},
- ```
-
-This routes list is an array of JavaScript objects, with each object defining the properties of a route.
-
-## Import `provideRouter` from `@angular/router`
-
-Routing lets you display specific views of your application depending on the URL path.
-To add this functionality to your sample application, you need to update the `app.config.ts` file to use the router providers function, `provideRouter`.
-You import this provider function from `@angular/router`.
-
-1. From your code editor, open the `app.config.ts` file.
-1. Add the following import statements:
-
- ```ts
- import {provideRouter} from '@angular/router';
- import {routes} from './app.routes';
- ```
-
-1. Update the providers in the `appConfig`:
-
- ```ts
- providers: [provideRouter(routes)];
- ```
-
-For `NgModule` based applications, put the `provideRouter` in the `providers` list of the `AppModule`, or whichever module is passed to `bootstrapModule` in the application.
-
-## Update your component with `router-outlet`
-
-At this point, you have defined two routes for your application.
-However, your application still has both the `crisis-list` and `heroes-list` components hard-coded in your `app.component.html` template.
-For your routes to work, you need to update your template to dynamically load a component based on the URL path.
-
-To implement this functionality, you add the `router-outlet` directive to your template file.
-
-1. From your code editor, open the `app.component.html` file.
-1. Delete the following lines.
-
-
-
-1. Add the `router-outlet` directive.
-
-
-
-1. Add `RouterOutlet` to the imports of the `AppComponent` in `app.component.ts`
-
- ```ts
- imports: [RouterOutlet],
- ```
-
-View your updated application in your browser.
-You should see only the application title.
-To view the `crisis-list` component, add `crisis-list` to the end of the path in your browser's address bar.
-For example:
-
-
-http://localhost:4200/crisis-list
-
-
-Notice that the `crisis-list` component displays.
-Angular is using the route you defined to dynamically load the component.
-You can load the `heroes-list` component the same way:
-
-
-http://localhost:4200/heroes-list
-
-
-## Control navigation with UI elements
-
-Currently, your application supports two routes.
-However, the only way to use those routes is for the user to manually type the path in the browser's address bar.
-In this section, you'll add two links that users can click to navigate between the `heroes-list` and `crisis-list` components.
-You'll also add some CSS styles.
-While these styles are not required, they make it easier to identify the link for the currently-displayed component.
-You'll add that functionality in the next section.
-
-1. Open the `app.component.html` file and add the following HTML below the title.
-
-
-
- This HTML uses an Angular directive, `routerLink`.
- This directive connects the routes you defined to your template files.
-
-1. Add the `RouterLink` directive to the imports list of `AppComponent` in `app.component.ts`.
-
-1. Open the `app.component.css` file and add the following styles.
-
-
-
-If you view your application in the browser, you should see these two links.
-When you click on a link, the corresponding component appears.
-
-## Identify the active route
-
-While users can navigate your application using the links you added in the previous section, they don't have a straightforward way to identify what the active route is.
-Add this functionality using Angular's `routerLinkActive` directive.
-
-1. From your code editor, open the `app.component.html` file.
-1. Update the anchor tags to include the `routerLinkActive` directive.
-
-
-
-1. Add the `RouterLinkActive` directive to the `imports` list of `AppComponent` in `app.component.ts`.
-
-View your application again.
-As you click one of the buttons, the style for that button updates automatically, identifying the active component to the user.
-By adding the `routerLinkActive` directive, you inform your application to apply a specific CSS class to the active route.
-In this tutorial, that CSS class is `activebutton`, but you could use any class that you want.
-
-Note that we are also specifying a value for the `routerLinkActive`'s `ariaCurrentWhenActive`. This makes sure that visually impaired users (which may not perceive the different styling being applied) can also identify the active button. For more information see the Accessibility Best Practices [Active links identification section](/best-practices/a11y#active-links-identification).
-
-## Adding a redirect
-
-In this step of the tutorial, you add a route that redirects the user to display the `/heroes-list` component.
-
-1. From your code editor, open the `app.routes.ts` file.
-1. Update the `routes` section as follows.
-
- ```ts
- {path: '', redirectTo: '/heroes-list', pathMatch: 'full'},
- ```
-
- Notice that this new route uses an empty string as its path.
- In addition, it replaces the `component` property with two new ones:
-
- | Properties | Details |
- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
- | `redirectTo` | This property instructs Angular to redirect from an empty path to the `heroes-list` path. |
- | `pathMatch` | This property instructs Angular on how much of the URL to match. For this tutorial, you should set this property to `full`. This strategy is recommended when you have an empty string for a path. For more information about this property, see the [Route API documentation](api/router/Route). |
-
-Now when you open your application, it displays the `heroes-list` component by default.
-
-## Adding a 404 page
-
-It is possible for a user to try to access a route that you have not defined.
-To account for this behavior, the best practice is to display a 404 page.
-In this section, you'll create a 404 page and update your route configuration to show that page for any unspecified routes.
-
-1. From the terminal, create a new component, `PageNotFound`.
-
-```shell
-ng generate component page-not-found
-```
-
-1. From your code editor, open the `page-not-found.component.html` file and replace its contents with the following HTML.
-
-
-
-1. Open the `app.routes.ts` file and add the following route to the routes list:
-
- ```ts
- {path: '**', component: PageNotFoundComponent}
- ```
-
- The new route uses a path, `**`.
- This path is how Angular identifies a wildcard route.
- Any route that does not match an existing route in your configuration will use this route.
-
-IMPORTANT: Notice that the wildcard route is placed at the end of the array.
-The order of your routes is important, as Angular applies routes in order and uses the first match it finds.
-
-Try navigating to a non-existing route on your application, such as `http://localhost:4200/powers`.
-This route doesn't match anything defined in your `app.routes.ts` file.
-However, because you defined a wildcard route, the application automatically displays your `PageNotFound` component.
-
-## Next steps
-
-At this point, you have a basic application that uses Angular's routing feature to change what components the user can see based on the URL address.
-You have extended these features to include a redirect, as well as a wildcard route to display a custom 404 page.
-
-For more information about routing, see the following topics:
-
-
-
-
-
diff --git a/adev/src/context/llms-list.md b/adev/src/context/llms-list.md
index ef49ca28e4d..a379f90ffa3 100644
--- a/adev/src/context/llms-list.md
+++ b/adev/src/context/llms-list.md
@@ -74,7 +74,6 @@ adev/src/content/guide/routing/show-routes-with-outlets.md
adev/src/content/guide/routing/navigate-to-routes.md
adev/src/content/guide/routing/read-route-state.md
adev/src/content/guide/routing/common-router-tasks.md
-adev/src/content/guide/routing/router-tutorial.md
adev/src/content/guide/routing/routing-with-urlmatcher.md
## SSR
diff --git a/packages.bzl b/packages.bzl
index 8dc4f0de752..15d70cff5d7 100644
--- a/packages.bzl
+++ b/packages.bzl
@@ -72,23 +72,6 @@ DOCS_ENTRYPOINTS = [
"core/src/util",
"core/testing",
"elements",
- "examples/common",
- "examples/core",
- "examples/core/di/ts/forward_ref",
- "examples/core/testing/ts",
- "examples/forms",
- "examples/platform-browser",
- "examples/router/activated-route",
- "examples/router/testing",
- "examples/router",
- "examples/service-worker/push",
- "examples/service-worker/registration-options",
- "examples/test-utils",
- "examples/testing",
- "examples/upgrade/static/ts/full",
- "examples/upgrade/static/ts/lite",
- "examples/upgrade/static/ts/lite-multi",
- "examples/upgrade/static/ts/lite-multi-shared",
"forms",
"localize",
"localize/init",
@@ -107,8 +90,4 @@ DOCS_ENTRYPOINTS = [
"router/testing",
"router/upgrade",
"service-worker",
- "upgrade",
- "upgrade/src/common",
- "upgrade/static",
- "upgrade/static/testing",
]
diff --git a/packages/examples/injection-token/src/main.ts b/packages/examples/injection-token/src/main.ts
index 7740aac8014..0041028d6f2 100644
--- a/packages/examples/injection-token/src/main.ts
+++ b/packages/examples/injection-token/src/main.ts
@@ -6,7 +6,6 @@
* found in the LICENSE file at https://angular.dev/license
*/
-// TODO: Add unit tests for this file.
/* eslint-disable @angular-eslint/no-output-native */
// #docregion
import {Injector, InjectionToken} from '@angular/core';
diff --git a/packages/examples/platform-browser/dom/debug/ts/debug_element_view_listener/providers.ts b/packages/examples/platform-browser/dom/debug/ts/debug_element_view_listener/providers.ts
deleted file mode 100644
index 2c0498748e7..00000000000
--- a/packages/examples/platform-browser/dom/debug/ts/debug_element_view_listener/providers.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * @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.dev/license
- */
-
-import {Component, NgModule} from '@angular/core';
-import {BrowserModule, platformBrowser} from '@angular/platform-browser';
-
-@Component({
- selector: 'my-component',
- template: 'text',
- standalone: false,
-})
-class MyAppComponent {}
-@NgModule({imports: [BrowserModule], bootstrap: [MyAppComponent]})
-class AppModule {}
-platformBrowser().bootstrapModule(AppModule);