test(browser): change mock location definition to use defineProperty

The original fix for which this mock location logic was written fixes
a bug in master which also exists in 1.2.x. Cherry-picking the fix
to the 1.2.x branch was difficult because the mock location object
used ES5 get/set syntax, which is not supported in IE8.

This fix changes the implementation to work with IE8 and modern
browsers.

IE8's defineProperty only works on certain types of objects, such as
DOM elements. So the mock location is a div element in this
implementation.
This commit is contained in:
Jeff Cross
2014-12-16 23:05:12 -08:00
parent 9845cee63e
commit 97a91199ad
+24 -14
View File
@@ -45,26 +45,37 @@ function MockWindow(options) {
});
};
this.location = {
get href() {
return locationHref;
},
set href(value) {
//IE8 hack. defineProperty doesn't work with POJS, just with certain DOM elements
this.location = document.createElement('div');
this.location.href = {};
this.location.hash = {};
this.location.replace = function(url) {
locationHref = url;
mockWindow.history.state = null;
};
Object.defineProperty(this.location, 'href', {
enumerable: false,
configurable: true,
set: function(value) {
locationHref = value;
mockWindow.history.state = null;
historyEntriesLength++;
},
get hash() {
return getHash(locationHref);
},
set hash(value) {
get: function() {
return locationHref;
}
});
Object.defineProperty(this.location, 'hash', {
enumerable: false,
configurable: true,
set: function(value) {
locationHref = stripHash(locationHref) + '#' + value;
},
replace: function(url) {
locationHref = url;
mockWindow.history.state = null;
get: function() {
return getHash(locationHref);
}
};
});
this.history = {
replaceState: noop,
@@ -115,7 +126,6 @@ describe('browser', function() {
warn: function() { logs.warn.push(slice.call(arguments)); },
info: function() { logs.info.push(slice.call(arguments)); },
error: function() { logs.error.push(slice.call(arguments)); }};
browser = new Browser(fakeWindow, fakeDocument, fakeLog, sniffer);
});