Add mock for window.location

This commit is contained in:
Tom Byers
2019-08-29 10:58:27 +01:00
parent 2fdf8161d2
commit a67d1901c0
2 changed files with 91 additions and 0 deletions

View File

@@ -1,3 +1,4 @@
const globals = require('./helpers/globals.js');
const events = require('./helpers/events.js');
const domInterfaces = require('./helpers/dom_interfaces.js');
const html = require('./helpers/html.js');
@@ -5,6 +6,7 @@ const elements = require('./helpers/elements.js');
const rendering = require('./helpers/rendering.js');
const forms = require('./helpers/forms.js');
exports.LocationMock = globals.LocationMock;
exports.triggerEvent = events.triggerEvent;
exports.clickElementWithMouse = events.clickElementWithMouse;
exports.moveSelectionToRadio = events.moveSelectionToRadio;

View File

@@ -0,0 +1,89 @@
// helpers for mocking objects attached to the global space as properties, ie. window.location
class LocationMock {
constructor (URL) {
this._location = window.location;
// setting href sets all sub-properties
this.href = URL;
// JSDOM sets window.location as non-configurable
// the only way to mock it, currently, is to replace it completely
delete window.location;
window.location = this;
}
get href () {
return `${this.protocol}://${this.host}${this.pathname}${this.search}${this.hash}`
}
set href (value) {
const partNames = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash'];
const protocol = '(https:|http:)';
const hostname = '[^\\/]+';
const port = '(:\\d)';
const pathname = '([^?]+)';
const search = '([^#])';
const hash = '(#[\\x00-\\x7F])'; // match any ASCII character
const re = new RegExp(`^${protocol}{0,1}(?:\\/\\/){0,1}(${hostname}${port}{0,1}){0,1}${pathname}{0,1}${search}{0,1}${hash}{0,1}$`);
const match = value.match(re)
if (match === null) { throw Error(`${value} is not a valid URL`); }
match.forEach((part, idx) => {
let partName;
// 0 index is whole match, we want the groups
if (idx > 0) {
partName = partNames[idx - 1];
if (part !== undefined) {
this[partName] = part;
} else if (!(partName in this)) { // only get value from window.location if property not set
this[partName] = this._location[partName];
}
}
});
}
get host () {
return `${this.hostname}:${this.port}`;
}
set host (value) {
const parts = value.split(':');
this.hostname = parts[0];
this.protocol = parts[1];
}
// origin is read-only
get origin () {
return `${this.protol}://${this.hostname}`;
}
reset () {
window.location = this._location;
}
}
exports.LocationMock = LocationMock;