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

test(search): improve test coverage #48

Merged
merged 6 commits into from
Jan 9, 2021
Merged

test(search): improve test coverage #48

merged 6 commits into from
Jan 9, 2021

Conversation

oscard0m
Copy link
Contributor

@oscard0m oscard0m commented Dec 8, 2020

📝 Summary

  • Improve test coverage
  • ⚠️ still one line not covered:
  • L26
  • L65

⛱ Motivation and Context

To reach 100% test coverage

@jsumners
Copy link
Owner

jsumners commented Dec 8, 2020

Is this still in draft or are you okay with not covering line 65?

@oscard0m
Copy link
Contributor Author

oscard0m commented Dec 8, 2020

Is this still in draft or are you okay with not covering line 65?

I was expecting to land this since I did not find an easy way to cover that line:

const alfredItems = (names) => {
const items = []
names.forEach((name) => {
const emoji = emojilib.lib[name]
if (!emoji) return
items.push(alfredItem(emoji, name))
})
return { items }
}

It depends on emojilib and I did not find a way to inject or mock with tap so I can force that path of execution. Maybe you have more experience with it and you can provide some guidance here? 👼🏽

@jsumners
Copy link
Owner

jsumners commented Dec 8, 2020

I would use https://www.npmjs.com/package/mock-require

@oscard0m
Copy link
Contributor Author

oscard0m commented Dec 9, 2020

I would use npmjs.com/package/mock-require

@jsumners

Working with your package proposal and so far so good. With current mocked emojilib I'm facing problems giving test coverage for the following lines:

Coverage for Line 26

const addModifier = (emoji, modifier) => {
if (!modifier || !emoji.fitzpatrick_scale) return emoji.char
const zwj = new RegExp('‍', 'g')
return emoji.char.match(zwj) ? emoji.char.replace(zwj, modifier + '‍') : emoji.char + modifier
}

Checking the code and the possible values in emojisMock.json, char property will always be a string, and, consequently, the .match expression will always be truthy, right? Checking the commit adding this lines did not give to me any clue on what is this logic for. Any clue?

(strange because with previous version of my tests I made it to cover this line but I don't know exactly how 🙄)

Coverage for Line 65

const alfredItems = (names) => {
const items = []
names.forEach((name) => {
const emoji = emojilib.lib[name]
if (!emoji) return
items.push(alfredItem(emoji, name))
})
return { items }
}
const all = () => alfredItems(emojiNames)
const matches = (terms) => {
return emojiNames.filter((name) => {
return terms.every((term) => {
return name.includes(term) ||
emojilib.lib[name].keywords.some((keyword) => keyword.includes(term))
})
})
}

According to the invocation of matches() and after it, alfredItems

return alfredItems(matches(terms))

I think there is no path of execution where line 65 can be falsy so that it stops execution there. Could that be possible? If so, do you have any example where that could happen, so I can reproduce it in the mock?

Thanks for your support and help here :)

@jsumners
Copy link
Owner

jsumners commented Dec 13, 2020

Checking the code and the possible values in emojisMock.json, char property will always be a string, and, consequently, the .match expression will always be truthy, right? Checking the commit adding this lines did not give to me any clue on what is this logic for. Any clue?

Maybe @Glennmen can help answer this question. It was added by 2973921

I think there is no path of execution where line 65 can be falsy so that it stops execution there.

I believe the thinking is that if one searches for "baz" then it will short circuit and not attempt to add any search results for Alfred to display.

@Glennmen
Copy link
Contributor

The logic I got for the skintone modifier came from: https://github.com/muan/mojibar/blob/3a1dac0998202e8425a63acb37da82aa7d6385f9/app/search.js#L225

Not sure about line 65 through, can't remember if I actually checked if that is ever triggered.
Anyways this test should catch if a none valid search is passed:

test('omits "rage1"', (t) => {
t.plan(1)
const found = search('rage1')
t.ok(Object.keys(found.items).length === 0)
})

It has been a while sorry 😅 if there is something else I can help with please let me know.

@oscard0m
Copy link
Contributor Author

oscard0m commented Jan 8, 2021

Finally found the use case for L26 🥳
Here is the key commit to find it: muan/mojibar@b4c1f47
And here is the info I found about ZWJ emojis: https://emojipedia.org/emoji-zwj-sequence/

@oscard0m
Copy link
Contributor Author

oscard0m commented Jan 8, 2021

To make test to cover L65 and do not fail for the rest I had to add an extreme use case:

  • a term appearing in orderedList.json and not appearing in emojiLib.json

To avoid exploding for the rest of tests, I had to add an extra defensive programming statement:

emojilib.lib[name] &&
    emojilib.lib[name].keywords.some((keyword) => keyword.includes(term))

Copy link
Owner

@jsumners jsumners left a comment

Choose a reason for hiding this comment

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

Fantastic. Thank you for sticking with this.

@jsumners jsumners merged commit ed5eb2a into jsumners:master Jan 9, 2021
@oscard0m oscard0m deleted the improve-test-coverage branch January 9, 2021 12:45
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.

3 participants