Skip to content

Commit

Permalink
Merge pull request #1766 from pygy/fix-ie10-11-hash-routes
Browse files Browse the repository at this point in the history
[mocks] make location.onhashchange debounced async
  • Loading branch information
pygy authored Apr 1, 2017
2 parents cc5d7c4 + d0ee256 commit 30edf36
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 52 deletions.
19 changes: 17 additions & 2 deletions test-utils/pushStateMock.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
"use strict"

var parseURL = require("../test-utils/parseURL")
var callAsync = require("../test-utils/callAsync.js")

function debouncedAsync(f) {
var ref
return function() {
if (ref != null) return
ref = callAsync(function(){
ref = null
f()
})
}
}

module.exports = function(options) {
if (options == null) options = {}
Expand Down Expand Up @@ -29,7 +41,9 @@ module.exports = function(options) {
if (data.search != null && data.search !== search) search = data.search, isNew = true
if (data.hash != null && data.hash !== hash) {
hash = data.hash
if (!isNew) hashchange()
if (!isNew) {
hashchange()
}
}
return isNew
}
Expand All @@ -38,9 +52,10 @@ module.exports = function(options) {
if (value === "") return ""
return (value.charAt(0) !== prefix ? prefix : "") + value
}
function hashchange() {
function _hashchange() {
if (typeof $window.onhashchange === "function") $window.onhashchange({type: "hashchange"})
}
var hashchange = debouncedAsync(_hashchange)
function popstate() {
if (typeof $window.onpopstate === "function") $window.onpopstate({type: "popstate", state: $window.history.state})
}
Expand Down
167 changes: 117 additions & 50 deletions test-utils/tests/test-pushStateMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var o = require("../../ospec/ospec")
var pushStateMock = require("../../test-utils/pushStateMock")

var callAsync = require("../../test-utils/callAsync")
o.spec("pushStateMock", function() {

var $window
Expand Down Expand Up @@ -478,93 +478,160 @@ o.spec("pushStateMock", function() {
})
})
o.spec("onhashchance", function() {
o("onhashchange triggers on location.href change", function() {
o("onhashchange triggers on location.href change", function(done) {
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/#a"

o($window.onhashchange.callCount).equals(1)
o($window.onhashchange.args[0].type).equals("hashchange")
callAsync(function(){
o($window.onhashchange.callCount).equals(1)
o($window.onhashchange.args[0].type).equals("hashchange")
done()
})
})
o("onhashchange triggers on relative location.href change", function() {
o("onhashchange triggers on relative location.href change", function(done) {
$window.onhashchange = o.spy()
$window.location.href = "#a"

o($window.onhashchange.callCount).equals(1)
callAsync(function(){
o($window.onhashchange.callCount).equals(1)
done()
})
})
o("onhashchange triggers on location.hash change", function() {
o("onhashchange triggers on location.hash change", function(done) {
$window.onhashchange = o.spy()
$window.location.hash = "#a"

o($window.onhashchange.callCount).equals(1)
callAsync(function(){
o($window.onhashchange.callCount).equals(1)
done()
})
})
o("onhashchange does not trigger on page change", function() {
o("onhashchange does not trigger on page change", function(done) {
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/a"

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
o("onhashchange does not trigger on page change with different hash", function() {
o("onhashchange does not trigger on page change with different hash", function(done) {
$window.location.href = "http://localhost/#a"
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/a#b"
callAsync(function(){
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/a#b"

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
o("onhashchange does not trigger on page change with same hash", function() {
o("onhashchange does not trigger on page change with same hash", function(done) {
$window.location.href = "http://localhost/#b"
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/a#b"
callAsync(function(){
$window.onhashchange = o.spy()
$window.location.href = "http://localhost/a#b"

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
o("onhashchange triggers on history.back()", function() {
o("onhashchange triggers on history.back()", function(done) {
$window.location.href = "#a"
$window.onhashchange = o.spy()
$window.history.back()
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()

o($window.onhashchange.callCount).equals(1)
callAsync(function(){
o($window.onhashchange.callCount).equals(1)
done()
})
})
})
o("onhashchange triggers on history.forward()", function() {
o("onhashchange triggers on history.forward()", function(done) {
$window.location.href = "#a"
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

o($window.onhashchange.callCount).equals(2)
})
o("onhashchange does not trigger on history.back() that causes page change with different hash", function() {
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()
callAsync(function(){
$window.history.forward()

callAsync(function(){
o($window.onhashchange.callCount).equals(2)
done()
})
})
})
})
o("onhashchange triggers once when the hash changes twice in a single tick", function(done) {
$window.location.href = "#a"
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

callAsync(function(){
o($window.onhashchange.callCount).equals(1)
done()
})
})
})
o("onhashchange does not trigger on history.back() that causes page change with different hash", function(done) {
$window.location.href = "#a"
$window.location.href = "a#b"
$window.onhashchange = o.spy()
$window.history.back()
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
o("onhashchange does not trigger on history.back() that causes page change with same hash", function() {
o("onhashchange does not trigger on history.back() that causes page change with same hash", function(done) {
$window.location.href = "#a"
$window.location.href = "a#a"
$window.onhashchange = o.spy()
$window.history.back()
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
o("onhashchange does not trigger on history.forward() that causes page change with different hash", function() {
o("onhashchange does not trigger on history.forward() that causes page change with different hash", function(done) {
$window.location.href = "#a"
$window.location.href = "a#b"
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

o($window.onhashchange.callCount).equals(0)
})
o("onhashchange does not trigger on history.forward() that causes page change with same hash", function() {
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
o("onhashchange does not trigger on history.forward() that causes page change with same hash", function(done) {
$window.location.href = "#a"
$window.location.href = "a#b"
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

o($window.onhashchange.callCount).equals(0)
callAsync(function(){
$window.onhashchange = o.spy()
$window.history.back()
$window.history.forward()

callAsync(function(){
o($window.onhashchange.callCount).equals(0)
done()
})
})
})
})
o.spec("onunload", function() {
Expand Down

0 comments on commit 30edf36

Please sign in to comment.