Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Achieve 100% test coverage #349

Merged
merged 22 commits into from
Mar 5, 2024

Conversation

jean-michelet
Copy link
Contributor

Hi, first time contributor here 👋

Will fixes #330

So far, I've only worked on one test file, but I think I should try to improve existing tests or create new isolated test files.

I don't have much confidence in the tests I've written, so I'd like to get some initial feedback to make sure I'm on the right track.

Although all filenames are green now, yellow has gradually appeared...
I'm not familiar with test coverage tools but this seems to be related to conditional statements and logical expressions, right?
How important is it for you to cover these cases? To what extent?

get-100-coverage

test: findMyWay.findRoute should also trows an error when wildcard is not the last character

test: does not find the route if maxParamLength is exceeded

refactor: make integration test more compliant with the existing code base

test: cover uncovered constrainer.js test cases

test: safeDecodeURIComponent should replace %3x to null for every x that is not a valid lowchar

test: SemVerStore version should be a string

test: httpMethodStrategy storage handles set and get operations correctly

test: case insensitive static routes of level 1 for FindMyWay.findRoute

test: findRoute normalizes wildcard patterns to require leading slash

refactor: make tests more consistants with the existing

test: should return null if no wildchar child

Date:      Tue Feb 20 14:10:18 2024 +0100
Achieves 100% test coverage
@mcollina
Copy link
Collaborator

Although all filenames are green now, yellow has gradually appeared...
I'm not familiar with test coverage tools but this seems to be related to conditional statements and logical expressions, right?
How important is it for you to cover these cases? To what extent?

You should make them all green. They are yellow because the lines are covered, but the branches of those conditions are not.
Take a look at https://en.wikipedia.org/wiki/Code_coverage.

@jean-michelet
Copy link
Contributor Author

jean-michelet commented Feb 23, 2024

Still have some work to do... But maybe someone can answers these questions.

  1. Is it ok to test directly internal components?
test('throws error if pass an undefined constraint value', (t) => {
  t.plan(1)

  const constrainer = new Constrainer()
  const error = new Error('Can\'t pass an undefined constraint value, must pass null or no key at all')
  t.throws(() => constrainer.validateConstraints({ key: undefined }), error)
})

Or do I have to test through apis?

  1. It seems that there are many preventive conditions that can't be evaluated trough the apis, but can be triggered by modifying the internal state. Here, I'm struggling to find a reason why a route with a wildcard path would have a pattern without a leading slash... Is the condition relevant if there is no way to trigger it through apis?
test('findRoute normalizes wildcard patterns with leading slash', (t) => {
  t.plan(4)

  const findMyWay = FindMyWay()
  findMyWay.get('*', () => {})

  t.equal(findMyWay.routes.length, 1)
  // will match with leading slash
  t.equal(findMyWay.routes[0].pattern, '/*')

  t.ok(findMyWay.findRoute('GET', '*'))

  // will fail if we remove it
  findMyWay.routes[0].pattern = '*'

  t.equal(findMyWay.findRoute('GET', '*'), null)
})
  1. Should I keep the tests in the current test file issue-330.test.js or should I try to distribute them in a relevant way in the existing tests?

@mcollina
Copy link
Collaborator

  1. better through public APIs, but still ok to call internal methods to achieve code coverage

  2. it really depends on a case-by-case basis. If something can't be evaluated, you might be able to remove it.

  3. ideally keep the tests where they are, but it's ok to refactor things around.

Copy link
Contributor Author

@jean-michelet jean-michelet left a comment

Choose a reason for hiding this comment

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

100-percent

I feel I can test better via the APIs, I'll look at that on Monday.

This PR is a lot of fun, although technical...

@@ -742,8 +733,6 @@ for (const i in httpMethods) {
const m = httpMethods[i]
const methodName = m.toLowerCase()

if (Router.prototype[methodName]) throw new Error('Method already exists: ' + methodName)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uncovered branch.

I think httpMethods should be a trusted source: if it contains duplicates, the tests will fail in one way or another.

} else {
throw new Error('unknown non-custom strategy for compiling constraint derivation function')
lines.push(' host: req.headers.host || req.headers[\':authority\'],')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uncovered branch.

How can we accidentally inject a builtin strategy or forget to manage it?

@@ -407,9 +406,7 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
// add the wildcard parameter
params.push('*')
currentNode = currentNode.getWildcardChild()
if (currentNode === null) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uncovered branch.

Can't find a good reason why this could be null using apis.

@@ -422,10 +419,6 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
pattern = pattern.toLowerCase()
}

if (pattern === '*') {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uncovered branch.

Can't find a good reason why pattern could be * using apis.

@@ -436,7 +429,7 @@ Router.prototype.findRoute = function findNode (method, path, constraints = {})
return {
handler: existRoute.handler,
store: existRoute.store,
params: existRoute.params || []
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uncovered branch.

route.params is assigned as an array and never reassigned, do I miss something?

lib/node.js Show resolved Hide resolved
@@ -38,7 +42,7 @@ SemVerStore.prototype.set = function (version, store) {
this.store[`${major}.x.x`] = store
}

if (patch >= (this.store[`${major}.${minor}`] || 0)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's an error here, but curiously no one seems to have noticed, right?

@@ -40,6 +40,7 @@
"chalk": "^4.1.2",
"inquirer": "^8.2.4",
"pre-commit": "^1.2.2",
"proxyquire": "^2.1.3",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I saw it has a dependency of Fastify, so I tough it could be welcome here.
https://github.com/fastify/fastify/blob/7e50e5307c9a6593a2e43171912630033aa1aacb/package.json#L189

const customHeaderConstraint2 = rfdc(customHeaderConstraint)
customHeaderConstraint2.name = 'requestedBy2'

const router = FindMyWay({ constraints: { requestedBy: customHeaderConstraint, requestedBy2: customHeaderConstraint2 } })
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To evaluate this branch:

if (--asyncConstraintsCount === 0) {

lib/strategies/accept-version.js Show resolved Hide resolved
@mcollina
Copy link
Collaborator

once you are done, remove the last 4 lines from https://github.com/delvedor/find-my-way/blob/main/.taprc. In that way it will fail the test suit if the coverage falls again.

@jean-michelet
Copy link
Contributor Author

jean-michelet commented Feb 25, 2024

100% reached, minimal limits removed.

Copy link
Collaborator

@ivan-tymoshenko ivan-tymoshenko left a comment

Choose a reason for hiding this comment

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

Thanks. I'm a bit worried about the changes in the router's behaviour. I will take a deep look into them next week.

@jean-michelet
Copy link
Contributor Author

jean-michelet commented Feb 25, 2024

Thanks. I'm a bit worried about the changes in the router's behaviour. I will take a deep look into them next week.

I'd also appreciate feedback on how you'd test these lines if you prefer I reintroduce them.

Copy link
Collaborator

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm with a nit

index.js Outdated Show resolved Hide resolved
@mcollina mcollina merged commit e117960 into delvedor:main Mar 5, 2024
12 checks passed
Josh-Walker-GM pushed a commit to redwoodjs/redwood that referenced this pull request May 16, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [find-my-way](https://togithub.com/delvedor/find-my-way) | [`8.1.0` ->
`8.2.0`](https://renovatebot.com/diffs/npm/find-my-way/8.1.0/8.2.0) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/find-my-way/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/find-my-way/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/find-my-way/8.1.0/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/find-my-way/8.1.0/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>delvedor/find-my-way (find-my-way)</summary>

###
[`v8.2.0`](https://togithub.com/delvedor/find-my-way/releases/tag/v8.2.0)

[Compare
Source](https://togithub.com/delvedor/find-my-way/compare/v8.1.0...v8.2.0)

#### What's Changed

- Update contraint check to throw with 32 handlers by
[@&#8203;valeneiko](https://togithub.com/valeneiko) in
[delvedor/find-my-way#344
- feat: add node: prefix for assert by
[@&#8203;SavaCool122](https://togithub.com/SavaCool122) in
[delvedor/find-my-way#347
- add dependabot.yml by [@&#8203;Uzlopak](https://togithub.com/Uzlopak)
in
[delvedor/find-my-way#350
- chore: bump actions/setup-node from 3 to 4 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[delvedor/find-my-way#351
- chore: bump actions/checkout from 3 to 4 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[delvedor/find-my-way#352
- Achieve 100% test coverage by
[@&#8203;jean-michelet](https://togithub.com/jean-michelet) in
[delvedor/find-my-way#349
- chore: bump the dependencies-major group with 1 update by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[delvedor/find-my-way#353
- Fix header in README by [@&#8203;selimb](https://togithub.com/selimb)
in
[delvedor/find-my-way#345
- Exclude Node v14 and v16 on macos by
[@&#8203;mcollina](https://togithub.com/mcollina) in
[delvedor/find-my-way#364
- add node v22. Skip old nodes on mac by
[@&#8203;mcollina](https://togithub.com/mcollina) in
[delvedor/find-my-way#363
- Support optional params on root by
[@&#8203;mcollina](https://togithub.com/mcollina) in
[delvedor/find-my-way#367

#### New Contributors

- [@&#8203;valeneiko](https://togithub.com/valeneiko) made their first
contribution in
[delvedor/find-my-way#344
- [@&#8203;SavaCool122](https://togithub.com/SavaCool122) made their
first contribution in
[delvedor/find-my-way#347
- [@&#8203;dependabot](https://togithub.com/dependabot) made their first
contribution in
[delvedor/find-my-way#351
- [@&#8203;jean-michelet](https://togithub.com/jean-michelet) made their
first contribution in
[delvedor/find-my-way#349
- [@&#8203;selimb](https://togithub.com/selimb) made their first
contribution in
[delvedor/find-my-way#345

**Full Changelog**:
delvedor/find-my-way@v8.1.0...v8.2.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/redwoodjs/redwood).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNjMuNSIsInVwZGF0ZWRJblZlciI6IjM3LjM2My41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Get Test Coverage to 100%
3 participants