Navigation Menu

Skip to content
This repository has been archived by the owner on Apr 29, 2023. It is now read-only.

Improve tests #65

Merged
merged 7 commits into from Apr 3, 2018
Merged

Improve tests #65

merged 7 commits into from Apr 3, 2018

Conversation

yuku
Copy link
Contributor

@yuku yuku commented Apr 2, 2018

  • Use JSX for better code readability.
  • Dispatch a native MouseEvent instead of calling vnode.attributes.onclick.
  • Move all integration tests (which contain app() in their test code) to test/index.test.js.
    • In previous, test/link.test.js imported Route, Link and location.
    • Now, it imports Link only. It concentrates on unit testing.
  • 💯 test coverage.
  • Fix potential bug around external links.

const state = { location: { pathname: `/foo/${invalidChars}/bar/baz` } }
const actions = {}
const render = jest.fn(({ match }) => {
expect(match.params).toEqual({ bar: "baz" })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jorgebucaran Is this intended behavior? In my opinion, a malformed URI should not match to any routes. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not toEqual({ foo: "%E0%A4%A", bar: "baz" })

Copy link
Contributor Author

@yuku yuku Apr 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing decodeURI from ↓ changes match.params from { bar: "baz" } to { foo: "%E0%A4%A", bar: "baz" }. I'm not sure why decodeURI is used here.

https://github.com/hyperapp/router/blob/795eb9b81ad9a6027d74dc65b0fe9548b0470095/src/parseRoute.js#L30-L34

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decoding is make sense because you usually expect { name: "café" } instead of { name: "caf%C3%A9" } in the params object.

but probably the code above should looks like this:

function decodeParam(val) {
  try {
    return decodeURIComponent(val)
  } catch (err) {
    return val
  }
}

params[paths[i].slice(1)] = urls[i] = decodeParam(urls[i])

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuku-t In my opinion, a malformed URI should not match to any routes. What do you think?

A lot of code was golfed to make the router as small as possible. It was fun, but probably a waste of time. I am not too obsessed about trading bytes for preciseness anymore and I think it's time to revisit a lot of the implementation code.

@codecov
Copy link

codecov bot commented Apr 2, 2018

Codecov Report

Merging #65 into master will increase coverage by 3.07%.
The diff coverage is 100%.

Impacted file tree graph

@@           Coverage Diff            @@
##           master    #65      +/-   ##
========================================
+ Coverage   96.92%   100%   +3.07%     
========================================
  Files           6      6              
  Lines          65     68       +3     
  Branches       10     11       +1     
========================================
+ Hits           63     68       +5     
+ Misses          2      0       -2
Impacted Files Coverage Δ
src/parseRoute.js 100% <100%> (+10.52%) ⬆️
src/Link.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 795eb9b...e91405a. Read the comment docs.

[
"transform-react-jsx",
{
"pragma": "h"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

const state = { location: { pathname: `/foo/${invalidChars}/bar/baz` } }
const actions = {}
const render = jest.fn(({ match }) => {
expect(match.params).toEqual({ bar: "baz" })
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuku-t In my opinion, a malformed URI should not match to any routes. What do you think?

A lot of code was golfed to make the router as small as possible. It was fun, but probably a waste of time. I am not too obsessed about trading bytes for preciseness anymore and I think it's time to revisit a lot of the implementation code.

},
"jest": {
"testURL": "http://localhost"
},
"devDependencies": {
"babel-jest": "^22.4.3",
"babel-plugin-transform-react-jsx": "^6.24.1",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuku-t I don't expect you to write all tests to use JSX, but could you use JSX in these tests? 🙏

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 })({}, {})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSX

Copy link
Contributor Author

@yuku yuku Apr 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is intentional design. There are two reasons:

  1. Because of lazy component, the mentioned line equals to the following. Don't you feel strange?

    const vnode = (<Link onclick={onclickProp} />)({}, {})
  2. test/link.test.js is for unit testing. Link could be used as a component, but it is just a pure function.

    • On the other hand, test/index.test.js is for integration testing, so I used JSX there.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, makes sense. That would be weird indeed.

expect(match.params).toEqual({ bar: "baz" })
})
expect(() =>
Route({ path: "/foo/:foo/bar/:bar", render }, [])(state, actions)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSX here too. 🙏

@yuku
Copy link
Contributor Author

yuku commented Apr 3, 2018

Pushed some commits:

  • Fix <Link> as Improve tests #65 (comment)
  • Add test scenario
  • Fix potential bug around external links 🐛
    • In previous, clicking an external link caused SecurityError: pushState cannot update history to a URL which differs in components other than in path, query, or fragment. exception in IE and Safari.

const wait = async ms => new Promise(resolve => setTimeout(resolve, ms))
const click = e => e.dispatchEvent(new MouseEvent("click", { button: 0 }))

let state, actions, unsubscribe
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I try to avoid using var and let when writing pure ES6, but I can fix this later!

@jorgebucaran jorgebucaran merged commit b19c91f into jorgebucaran:master Apr 3, 2018
@yuku yuku deleted the improve-tests branch April 3, 2018 06:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
3 participants