fix(common): adjust MockPlatformLocation to set state to new object (#30055)

When using the `history` API, setting a new `state` and retrieving it does not pass a `===` test to the object used to set the state. In other words, `history.state` is always a copy. This change makes the `MockPlatformLocation` behave in the same way.

PR Close #30055
This commit is contained in:
Jason Aden 2019-04-23 06:42:52 -07:00 committed by Ben Lesh
parent 3a9cf3f2ba
commit 825efa8721
2 changed files with 16 additions and 11 deletions

View File

@ -12,10 +12,10 @@ import {Subject} from 'rxjs';
function parseUrl(urlStr: string, baseHref: string) {
const verifyProtocol = /^((http[s]?|ftp):\/\/)/;
let serverBase = '';
let serverBase;
// URL class requires full URL. If the URL string doesn't start with protocol, we need to add an
// arbitrary base URL which can be removed afterward.
// URL class requires full URL. If the URL string doesn't start with protocol, we need to add
// an arbitrary base URL which can be removed afterward.
if (!verifyProtocol.test(urlStr)) {
serverBase = 'http://empty.com/';
}
@ -62,7 +62,7 @@ export class MockPlatformLocation implements PlatformLocation {
this.baseHref = config.appBaseHref || '';
const parsedChanges =
this.parseChanges(null, config.startUrl || 'http://<empty>', this.baseHref);
this.parseChanges(null, config.startUrl || 'http://<empty>/', this.baseHref);
this.urlChanges[0] = {...parsedChanges};
}
}
@ -86,7 +86,9 @@ export class MockPlatformLocation implements PlatformLocation {
onHashChange(fn: LocationChangeListener): void { this.hashUpdate.subscribe(fn); }
get href(): string {
return `${this.protocol}//${this.hostname}${this.baseHref}${this.pathname === '/' ? '' : this.pathname}${this.search}${this.hash}`;
let url = `${this.protocol}//${this.hostname}${this.port ? ':' + this.port : ''}`;
url += `${this.pathname === '/' ? '' : this.pathname}${this.search}${this.hash}`
return url;
}
get url(): string { return `${this.pathname}${this.search}${this.hash}`; }
@ -104,6 +106,8 @@ export class MockPlatformLocation implements PlatformLocation {
}
private parseChanges(state: unknown, url: string, baseHref: string = '') {
// When the `history.state` value is stored, it is always copied.
state = JSON.parse(JSON.stringify(state));
return {...parseUrl(url, baseHref), state};
}

View File

@ -1,21 +1,22 @@
{
"extends": "../tsconfig-build.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "../",
"paths": {
"@angular/core": ["../../../dist/packages/core"],
"@angular/common": ["../../../dist/packages/common"]
"@angular/core": [
"../../../dist/packages/core"
],
"@angular/common": [
"../../../dist/packages/common"
]
},
"outDir": "../../../dist/packages/common"
},
"files": [
"public_api.ts",
"../../../node_modules/zone.js/dist/zone.js.d.ts"
],
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
"strictMetadataEmit": false,
@ -23,4 +24,4 @@
"flatModuleOutFile": "testing.js",
"flatModuleId": "@angular/common/testing"
}
}
}