-
-
Notifications
You must be signed in to change notification settings - Fork 389
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: hmr reload with invalid link url
- Loading branch information
1 parent
ee9df43
commit 998494a
Showing
3 changed files
with
331 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
/* eslint-env browser */ | ||
/* eslint-disable no-console */ | ||
|
||
import hotModuleReplacement from '../src/hmr/hotModuleReplacement'; | ||
|
||
function getLoadEvent() { | ||
const event = document.createEvent('Event'); | ||
|
||
event.initEvent('load', false, false); | ||
|
||
return event; | ||
} | ||
|
||
function getErrorEvent() { | ||
const event = document.createEvent('Event'); | ||
|
||
event.initEvent('error', false, false); | ||
|
||
return event; | ||
} | ||
|
||
describe('HMR', () => { | ||
let consoleMock = null; | ||
|
||
beforeEach(() => { | ||
consoleMock = jest.spyOn(console, 'log').mockImplementation(() => () => {}); | ||
|
||
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200000); | ||
|
||
document.head.innerHTML = '<link rel="stylesheet" href="/dist/main.css" />'; | ||
document.body.innerHTML = '<script src="/dist/main.js"></script>'; | ||
}); | ||
|
||
afterEach(() => { | ||
consoleMock.mockClear(); | ||
}); | ||
|
||
it('should works', (done) => { | ||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should works with multiple updates', (done) => { | ||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
|
||
jest.spyOn(Date, 'now').mockImplementation(() => 1479427200001); | ||
|
||
const update2 = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update2(); | ||
|
||
setTimeout(() => { | ||
const links2 = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links2[0].visited).toBe(true); | ||
expect(links2[0].isLoaded).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links2[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links2[1].isLoaded).toBe(true); | ||
|
||
done(); | ||
}, 100); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with locals', (done) => { | ||
const update = hotModuleReplacement('./src/style.css', { | ||
locals: { foo: 'bar' }, | ||
}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with reloadAll option', (done) => { | ||
const update = hotModuleReplacement('./src/style.css', { | ||
reloadAll: true, | ||
}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with non http/https link href', (done) => { | ||
document.head.innerHTML = | ||
'<link rel="stylesheet" href="/dist/main.css" /><link rel="shortcut icon" href="data:;base64,=" />'; | ||
|
||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
expect(links[2].visited).toBeUndefined(); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with # link href', (done) => { | ||
document.head.innerHTML = | ||
'<link rel="stylesheet" href="/dist/main.css" /><link rel="shortcut icon" href="#href" />'; | ||
|
||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
expect(links[2].visited).toBeUndefined(); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with link without href', (done) => { | ||
document.head.innerHTML = | ||
'<link rel="stylesheet" href="/dist/main.css" /><link rel="shortcut icon" />'; | ||
|
||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
expect(links[2].visited).toBeUndefined(); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should reloads with absolute remove url', (done) => { | ||
document.head.innerHTML = | ||
'<link rel="stylesheet" href="/dist/main.css" /><link rel="stylesheet" href="http://dev.com/dist/main.css" />'; | ||
|
||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getLoadEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
expect(links[2].visited).toBeUndefined(); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
|
||
it('should handle error event', (done) => { | ||
const update = hotModuleReplacement('./src/style.css', {}); | ||
|
||
update(); | ||
|
||
setTimeout(() => { | ||
expect(console.log.mock.calls[0][0]).toMatchSnapshot(); | ||
|
||
const links = Array.prototype.slice.call( | ||
document.querySelectorAll('link') | ||
); | ||
|
||
expect(links[0].visited).toBe(true); | ||
expect(document.head.innerHTML).toMatchSnapshot(); | ||
|
||
links[1].dispatchEvent(getErrorEvent()); | ||
|
||
expect(links[1].isLoaded).toBe(true); | ||
|
||
done(); | ||
}, 100); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`HMR should handle error event 1`] = `"[HMR] css reload %s"`; | ||
|
||
exports[`HMR should handle error event 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`; | ||
exports[`HMR should reloads with # link href 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should reloads with # link href 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"shortcut icon\\" href=\\"#href\\">"`; | ||
exports[`HMR should reloads with absolute remove url 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should reloads with absolute remove url 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"stylesheet\\" href=\\"http://dev.com/dist/main.css\\">"`; | ||
exports[`HMR should reloads with link without href 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should reloads with link without href 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"shortcut icon\\">"`; | ||
exports[`HMR should reloads with locals 1`] = `"[HMR] Detected local css modules. Reload all css"`; | ||
exports[`HMR should reloads with locals 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`; | ||
exports[`HMR should reloads with non http/https link href 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should reloads with non http/https link href 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"shortcut icon\\" href=\\"data:;base64,=\\">"`; | ||
exports[`HMR should reloads with reloadAll option 1`] = `"[HMR] Reload all css"`; | ||
exports[`HMR should reloads with reloadAll option 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`; | ||
exports[`HMR should works 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should works 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`; | ||
exports[`HMR should works with multiple updates 1`] = `"[HMR] css reload %s"`; | ||
exports[`HMR should works with multiple updates 2`] = `"<link rel=\\"stylesheet\\" href=\\"/dist/main.css\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\">"`; | ||
exports[`HMR should works with multiple updates 3`] = `"<link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200000\\"><link rel=\\"stylesheet\\" href=\\"http://localhost/dist/main.css?1479427200001\\">"`; |