refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
15
packages/common/testing/src/index.ts
Normal file
15
packages/common/testing/src/index.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point for all public APIs of the common/testing package.
|
||||
*/
|
||||
export {SpyLocation} from './location_mock';
|
||||
export {MockLocationStrategy} from './mock_location_strategy';
|
124
packages/common/testing/src/location_mock.ts
Normal file
124
packages/common/testing/src/location_mock.ts
Normal file
@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Location, LocationStrategy} from '@angular/common';
|
||||
import {EventEmitter, Injectable} from '@angular/core';
|
||||
|
||||
|
||||
/**
|
||||
* A spy for {@link Location} that allows tests to fire simulated location events.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@Injectable()
|
||||
export class SpyLocation implements Location {
|
||||
urlChanges: string[] = [];
|
||||
private _history: LocationState[] = [new LocationState('', '')];
|
||||
private _historyIndex: number = 0;
|
||||
/** @internal */
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
/** @internal */
|
||||
_baseHref: string = '';
|
||||
/** @internal */
|
||||
_platformStrategy: LocationStrategy = null;
|
||||
|
||||
setInitialPath(url: string) { this._history[this._historyIndex].path = url; }
|
||||
|
||||
setBaseHref(url: string) { this._baseHref = url; }
|
||||
|
||||
path(): string { return this._history[this._historyIndex].path; }
|
||||
|
||||
isCurrentPathEqualTo(path: string, query: string = ''): boolean {
|
||||
const givenPath = path.endsWith('/') ? path.substring(0, path.length - 1) : path;
|
||||
const currPath =
|
||||
this.path().endsWith('/') ? this.path().substring(0, this.path().length - 1) : this.path();
|
||||
|
||||
return currPath == givenPath + (query.length > 0 ? ('?' + query) : '');
|
||||
}
|
||||
|
||||
simulateUrlPop(pathname: string) { this._subject.emit({'url': pathname, 'pop': true}); }
|
||||
|
||||
simulateHashChange(pathname: string) {
|
||||
// Because we don't prevent the native event, the browser will independently update the path
|
||||
this.setInitialPath(pathname);
|
||||
this.urlChanges.push('hash: ' + pathname);
|
||||
this._subject.emit({'url': pathname, 'pop': true, 'type': 'hashchange'});
|
||||
}
|
||||
|
||||
prepareExternalUrl(url: string): string {
|
||||
if (url.length > 0 && !url.startsWith('/')) {
|
||||
url = '/' + url;
|
||||
}
|
||||
return this._baseHref + url;
|
||||
}
|
||||
|
||||
go(path: string, query: string = '') {
|
||||
path = this.prepareExternalUrl(path);
|
||||
|
||||
if (this._historyIndex > 0) {
|
||||
this._history.splice(this._historyIndex + 1);
|
||||
}
|
||||
this._history.push(new LocationState(path, query));
|
||||
this._historyIndex = this._history.length - 1;
|
||||
|
||||
const locationState = this._history[this._historyIndex - 1];
|
||||
if (locationState.path == path && locationState.query == query) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = path + (query.length > 0 ? ('?' + query) : '');
|
||||
this.urlChanges.push(url);
|
||||
this._subject.emit({'url': url, 'pop': false});
|
||||
}
|
||||
|
||||
replaceState(path: string, query: string = '') {
|
||||
path = this.prepareExternalUrl(path);
|
||||
|
||||
const history = this._history[this._historyIndex];
|
||||
if (history.path == path && history.query == query) {
|
||||
return;
|
||||
}
|
||||
|
||||
history.path = path;
|
||||
history.query = query;
|
||||
|
||||
const url = path + (query.length > 0 ? ('?' + query) : '');
|
||||
this.urlChanges.push('replace: ' + url);
|
||||
}
|
||||
|
||||
forward() {
|
||||
if (this._historyIndex < (this._history.length - 1)) {
|
||||
this._historyIndex++;
|
||||
this._subject.emit({'url': this.path(), 'pop': true});
|
||||
}
|
||||
}
|
||||
|
||||
back() {
|
||||
if (this._historyIndex > 0) {
|
||||
this._historyIndex--;
|
||||
this._subject.emit({'url': this.path(), 'pop': true});
|
||||
}
|
||||
}
|
||||
|
||||
subscribe(
|
||||
onNext: (value: any) => void, onThrow: (error: any) => void = null,
|
||||
onReturn: () => void = null): Object {
|
||||
return this._subject.subscribe({next: onNext, error: onThrow, complete: onReturn});
|
||||
}
|
||||
|
||||
normalize(url: string): string { return null; }
|
||||
}
|
||||
|
||||
class LocationState {
|
||||
path: string;
|
||||
query: string;
|
||||
constructor(path: string, query: string) {
|
||||
this.path = path;
|
||||
this.query = query;
|
||||
}
|
||||
}
|
83
packages/common/testing/src/mock_location_strategy.ts
Normal file
83
packages/common/testing/src/mock_location_strategy.ts
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {LocationStrategy} from '@angular/common';
|
||||
import {EventEmitter, Injectable} from '@angular/core';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A mock implementation of {@link LocationStrategy} that allows tests to fire simulated
|
||||
* location events.
|
||||
*
|
||||
* @stable
|
||||
*/
|
||||
@Injectable()
|
||||
export class MockLocationStrategy extends LocationStrategy {
|
||||
internalBaseHref: string = '/';
|
||||
internalPath: string = '/';
|
||||
internalTitle: string = '';
|
||||
urlChanges: string[] = [];
|
||||
/** @internal */
|
||||
_subject: EventEmitter<any> = new EventEmitter();
|
||||
constructor() { super(); }
|
||||
|
||||
simulatePopState(url: string): void {
|
||||
this.internalPath = url;
|
||||
this._subject.emit(new _MockPopStateEvent(this.path()));
|
||||
}
|
||||
|
||||
path(includeHash: boolean = false): string { return this.internalPath; }
|
||||
|
||||
prepareExternalUrl(internal: string): string {
|
||||
if (internal.startsWith('/') && this.internalBaseHref.endsWith('/')) {
|
||||
return this.internalBaseHref + internal.substring(1);
|
||||
}
|
||||
return this.internalBaseHref + internal;
|
||||
}
|
||||
|
||||
pushState(ctx: any, title: string, path: string, query: string): void {
|
||||
this.internalTitle = title;
|
||||
|
||||
const url = path + (query.length > 0 ? ('?' + query) : '');
|
||||
this.internalPath = url;
|
||||
|
||||
const externalUrl = this.prepareExternalUrl(url);
|
||||
this.urlChanges.push(externalUrl);
|
||||
}
|
||||
|
||||
replaceState(ctx: any, title: string, path: string, query: string): void {
|
||||
this.internalTitle = title;
|
||||
|
||||
const url = path + (query.length > 0 ? ('?' + query) : '');
|
||||
this.internalPath = url;
|
||||
|
||||
const externalUrl = this.prepareExternalUrl(url);
|
||||
this.urlChanges.push('replace: ' + externalUrl);
|
||||
}
|
||||
|
||||
onPopState(fn: (value: any) => void): void { this._subject.subscribe({next: fn}); }
|
||||
|
||||
getBaseHref(): string { return this.internalBaseHref; }
|
||||
|
||||
back(): void {
|
||||
if (this.urlChanges.length > 0) {
|
||||
this.urlChanges.pop();
|
||||
const nextUrl = this.urlChanges.length > 0 ? this.urlChanges[this.urlChanges.length - 1] : '';
|
||||
this.simulatePopState(nextUrl);
|
||||
}
|
||||
}
|
||||
|
||||
forward(): void { throw 'not implemented'; }
|
||||
}
|
||||
|
||||
class _MockPopStateEvent {
|
||||
pop: boolean = true;
|
||||
type: string = 'popstate';
|
||||
constructor(public newUrl: string) {}
|
||||
}
|
17
packages/common/testing/tsconfig-build.json
Normal file
17
packages/common/testing/tsconfig-build.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./tsconfig-build",
|
||||
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@angular/core": ["../../../dist/packages-dist/core/"],
|
||||
"@angular/common": ["../../../dist/packages-dist/common"]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"testing/index.ts",
|
||||
"../../../node_modules/zone.js/dist/zone.js.d.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"strictMetadataEmit": true
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user