This repository has been archived by the owner on Apr 29, 2023. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Use JSX in test * Prefer native event over emulation * Improve tests by distinguishing between integration tests and unit tests * Improve test coverage from 97% to 100% * Don't remove URI param with invalid character sequences * Add some integration tests * Fix bug around clicking an external link
- Loading branch information
1 parent
795eb9b
commit b19c91f
Showing
7 changed files
with
181 additions
and
150 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
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 |
---|---|---|
@@ -1,38 +1,124 @@ | ||
import { h, app } from "hyperapp" | ||
import { Route, location } from "../src" | ||
import { Route, Link, Redirect, location } from "../src" | ||
|
||
test("Router", done => { | ||
const state = { | ||
location: location.state | ||
} | ||
const wait = async ms => new Promise(resolve => setTimeout(resolve, ms)) | ||
const click = e => e.dispatchEvent(new MouseEvent("click", { button: 0 })) | ||
|
||
let state, actions, unsubscribe | ||
|
||
const actions = { | ||
location: location.actions | ||
beforeEach(() => { | ||
state = { location: location.state } | ||
actions = { | ||
location: location.actions, | ||
getLocation: () => state => state.location | ||
} | ||
unsubscribe = null | ||
}) | ||
|
||
afterEach(() => { | ||
unsubscribe && unsubscribe() | ||
}) | ||
|
||
const main = app( | ||
state, | ||
actions, | ||
(state, actions) => | ||
h(Route, { | ||
path: "/test", | ||
render: () => | ||
h( | ||
"h1", | ||
{ | ||
oncreate() { | ||
expect(document.body.innerHTML).toBe(`<h1>Hello</h1>`) | ||
unsubscribe() | ||
done() | ||
} | ||
}, | ||
"Hello" | ||
) | ||
}), | ||
document.body | ||
test("Transition by location.go()", async done => { | ||
const spy = jest.fn() | ||
const view = () => <Route path="/test" render={spy} /> | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
expect(spy).not.toBeCalled() | ||
main.location.go("/test") | ||
await wait(0) | ||
expect(spy).toBeCalled() | ||
done() | ||
}) | ||
|
||
test("Transition by clicking Link", async done => { | ||
const spy = jest.fn() | ||
const view = () => ( | ||
<div> | ||
<Link to="/test" /> | ||
<Route path="/test" render={spy} /> | ||
</div> | ||
) | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
expect(spy).not.toBeCalled() | ||
click(document.body.getElementsByTagName("a")[0]) | ||
await wait(0) | ||
expect(spy).toBeCalled() | ||
// Clicking the same link again doesn't cause transition. | ||
const count = spy.mock.calls.length | ||
click(document.body.getElementsByTagName("a")[0]) | ||
await wait(0) | ||
expect(spy).toHaveBeenCalledTimes(count) | ||
done() | ||
}) | ||
|
||
const unsubscribe = location.subscribe(main.location) | ||
test('Click Link with target="_blank"', async done => { | ||
const spy = jest.fn() | ||
const view = () => ( | ||
<div> | ||
<Link to="/test" target="_blank" /> | ||
<Route path="/test" render={spy} /> | ||
</div> | ||
) | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
click(document.body.getElementsByTagName("a")[0]) | ||
await wait(0) | ||
expect(spy).not.toBeCalled() | ||
done() | ||
}) | ||
|
||
test("Click external Link", async done => { | ||
const spy = jest.fn() | ||
const view = () => <Link to="http://example.com/" /> | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
expect(main.getLocation().pathname).toEqual("/") | ||
click(document.body.getElementsByTagName("a")[0]) | ||
await wait(0) | ||
expect(main.getLocation().pathname).toEqual("/") | ||
done() | ||
}) | ||
|
||
test("Transition by clicking Link including non alphanumeric characters", async done => { | ||
const spy = jest.fn() | ||
const view = () => ( | ||
<div> | ||
<Link to="/test/café" /> | ||
<Route path="/test/:id" render={spy} /> | ||
</div> | ||
) | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
expect(spy).not.toBeCalled() | ||
click(document.body.getElementsByTagName("a")[0]) | ||
await wait(0) | ||
expect(spy).toBeCalled() | ||
expect(spy.mock.calls[0][0].match.params).toEqual({ id: "café" }) | ||
expect(main.getLocation().pathname).toEqual("/test/caf%C3%A9") | ||
done() | ||
}) | ||
|
||
test("Transition by rendering Redirect", async done => { | ||
const spy = jest.fn() | ||
const view = () => ( | ||
<div> | ||
<Route path="/test" render={() => <Redirect to="/somewhere" />} /> | ||
<Route path="/somewhere" render={spy} /> | ||
</div> | ||
) | ||
const main = app(state, actions, view, document.body) | ||
unsubscribe = location.subscribe(main.location) | ||
await wait(0) | ||
expect(spy).not.toBeCalled() | ||
main.location.go("/test") | ||
await wait(0) | ||
expect(spy).toBeCalled() | ||
done() | ||
}) |
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 |
---|---|---|
@@ -1,74 +1,18 @@ | ||
import { h, app } from "hyperapp" | ||
import { Route, Link, location } from "../src" | ||
import { Link } from "../src" | ||
|
||
const fakeEvent = { | ||
button: 0, | ||
currentTarget: { origin: window.location.origin }, | ||
preventDefault: () => {} | ||
} | ||
|
||
test("Link", done => { | ||
const state = { | ||
location: location.state | ||
} | ||
|
||
const actions = { | ||
location: location.actions | ||
} | ||
|
||
const main = app( | ||
state, | ||
actions, | ||
(state, actions) => | ||
h("div", {}, [ | ||
h(Route, { | ||
path: "/test", | ||
render: () => { | ||
h(Link, { | ||
to: "/done" | ||
})(state, actions).attributes.onclick(fakeEvent) | ||
} | ||
}), | ||
h(Route, { | ||
path: "/done", | ||
render: () => | ||
h( | ||
"h1", | ||
{ | ||
oncreate() { | ||
expect(document.body.innerHTML).toBe( | ||
`<div><h1>Hello</h1></div>` | ||
) | ||
unsubscribe() | ||
done() | ||
} | ||
}, | ||
"Hello" | ||
) | ||
}) | ||
]), | ||
document.body | ||
) | ||
|
||
const unsubscribe = location.subscribe(main.location) | ||
|
||
main.location.go("/test") | ||
}) | ||
|
||
test("pass through attributes", () => { | ||
const vnode = h(Link, { to: "/path", pass: "through", location })({}, {}) | ||
test('Link passes given attributes except "to" and "location" to underlying element', () => { | ||
const vnode = Link({ to: "/path", pass: "through", location })({}, {}) | ||
expect(vnode.attributes.to).toBeUndefined() | ||
expect(vnode.attributes.location).toBeUndefined() | ||
expect(vnode.attributes.href).toEqual("/path") | ||
expect(vnode.attributes.pass).toEqual("through") | ||
}) | ||
|
||
test("custom onclick handler", () => { | ||
const event = { defaultPrevented: false } | ||
const onclick = e => { | ||
e.defaultPrevented = true | ||
} | ||
const vnode = h(Link, { to: "/path", onclick })({}, {}) | ||
test("Calling onclick of VNode transparently calls Link's onclick prop", () => { | ||
const onclickProp = jest.fn() | ||
const vnode = Link({ onclick: onclickProp })({}, {}) | ||
const event = new Object() | ||
expect(vnode.attributes.onclick).not.toBe(onclickProp) | ||
vnode.attributes.onclick(event) | ||
expect(event.defaultPrevented).toBe(true) | ||
expect(onclickProp).toBeCalledWith(event) | ||
}) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.