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

[WIP] Help style #164

Merged
merged 14 commits into from Nov 9, 2017
Merged

[WIP] Help style #164

merged 14 commits into from Nov 9, 2017

Conversation

K3TH3R
Copy link
Collaborator

@K3TH3R K3TH3R commented Oct 2, 2017

@kentcdodds this isn't quite ready as I'm running into some issues with tests, but I didn't want to fill up the GitHub issue with back and forth. On several of the help-related tests I'm getting the following error: TypeError: Cannot read property 'help-style' of undefined. I'll use one of the tests as an example:

test('if there is a help script in the psConfig, does not show the help', () => {
  mockBinUtils.mock.psConfig = {scripts: {help: 'hi'}}
  expect(parse('help')).not.toBe(undefined)
  expect(mockGetLogger.mock.info).toHaveBeenCalledTimes(0)
})

If I change that to this, the test stops erroring:

test('if there is a help script in the psConfig, does not show the help', () => {
  mockBinUtils.mock.psConfig = {scripts: {help: 'hi'}, options: {}}
  expect(parse('help')).not.toBe(undefined)
  expect(mockGetLogger.mock.info).toHaveBeenCalledTimes(0)
})

However, I'm under the impression that arbitrarily adding the options object to the config is probably against best testing practices?

The tests are specifically choking on this line:

const helpStyle = String(psConfig.options['help-style'] || 'all')

Is the only way to solve this by writing code checking whether the options property exists? It just seems a bit dirty/weird since I don't see anywhere else where you're checking for existence of options nor the scripts property, like maybe I'm not grok'ing something I should be?

@kentcdodds
Copy link
Collaborator

Thanks so much! I'm fine with the solution you mentioned. Could you also rebase your branch in master?

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Oct 3, 2017

@kentcdodds Okay, so I have all of the tests passing, but I have a code coverage issue that I'm not sure how to fix. The coverage tool is complaining that these lines aren't tested, but I'm not entirely sure how to write a test for that block of code. Parser doesn't expose the help function and I'm still rather new to writing tests, so any help or guidance would be much appreciated.

K3TH3R and others added 4 commits October 3, 2017 14:51
* Update concurrently => concurrent in examples

* Add myself as a contributer

* Add myself as a contributer properly, this time :)
Copy link
Collaborator

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

Looking good! Just a few comments :)

I updated your branch, so make sure to pull the latest changes.

@@ -171,25 +171,32 @@ function requireDefaultFromModule(modulePath) {
}
}

function scriptObjectToChalk({name, description, script}) {
function scriptObjectToChalk(options, {name, description, script}) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You could save a fair amount of logic below by changing this to:

function scriptObjectToChalk(options = {'help-style': 'all'}, {name, description, script}) {

@@ -117,6 +123,7 @@ function parse(rawArgv) {
log.info(help(psConfig))
return true
}
const helpStyle = String(psConfig.options['help-style'] || 'all')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this || 'all' necessary considering the parser has default: 'all'? I'm pretty sure that psConfig.options['help-style'] should always be defined.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I might've put that in because I had been running into some edge cases from the existing tests... but that also may have been because I was mis-understanding the test feedback. I'll give it a shot without it in there 👍

README.md Outdated
--require, -r Module to preload
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
--help-style, -hs Style of help to use
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think that -hs should be -y based on the alias in the parser.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup, good catch.

README.md Outdated
@@ -310,6 +312,25 @@ And you can pass arguments to scripts by putting the scripts in quotes:
nps "test --cover" check-coverage
```

##### -hs, --help-style
Copy link
Collaborator

Choose a reason for hiding this comment

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

-hs should be -y?

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Oct 11, 2017

@kentcdodds Thank you for taking the time to provide your feedback. I did your requested updates and added myself as a contributor. All of the tests are passing, but I'm still unsure how to fix the code coverage issues?

@kentcdodds
Copy link
Collaborator

Hi @iamkether! Yeah, code coverage is tricky. I normally require 100% code coverage on my open source projects because they're pretty small and often have many dependents, so it's worth the effort. If you run npm test then you should have a coverage directory. Open coverage/lcov-report/index.html and that'll show you where you're missing coverage (looks like it's the src/bin-utils/parser.js file). Just add a test or two to cover the missing lines and you should be good :)

Let me know if you need help with that :)

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 1, 2017

Hey @kentcdodds, I've taken a look and I could definitely use your help on this. The first line in the code coverage report uncovered is the updated function signature on line 174 of bin-utils/index.js:

function scriptObjectToChalk(
  options = {'help-style': 'all'}, // this line specifically
  {name, description, script},
)

I haven't done much testing previously, so I'm not sure how to test this? The whole point of doing the line like this is so that we set a default and don't really have to test conditions where the value isn't provided, no? How would one even go about testing whether the default assignment has been assigned? Wouldn't I need to peek inside of the function post-call and check the values?

And the second line it's choking on is the following one on line 139-141 of bin-utils/parser.js:

if (helpStyle === 'all') {
  parser.showHelp('log')
}

I expect that I have to fire the showHelp function this is contained within, but I'm not seeing anything on the mockBinUtils object that would allow me to do that? But again, I'm fairly new to testing so there's probably something I'm not understanding quite right here...

@kentcdodds
Copy link
Collaborator

Thanks @iamkether. So if you cannot reproduce it in tests then the code probably doesn't need to be there at all. Meaning if there's no way for you to have that function called without arguments provided, then we don't need a default argument. Does that make sense? I'm really sorry, but it's very hard for me to find time to help with this :-/

@mikecann
Copy link

mikecann commented Nov 2, 2017

@iamkether ill try to take a look at it for you today, see if I can help..

Ughh or not.. sorry I overcommitted :(

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 3, 2017

@kentcdodds @mikecann I did a little bit of refactoring based on Kent's last message and I'm much closer now. I have 100% coverage for all statements and functions, but it's telling me I'm at 97.67% for branch... not sure what that is? It's still identifying the same line as the problem though.

[edit]
I feel this is probably more due to my lack of experience/knowledge with writing tests more than anything... but it's hard to problem-solve something you don't have much knowledge or experience with.

@@ -129,7 +136,9 @@ function parse(rawArgv) {
log.info(specificHelpScript(psConfig, specifiedScripts[1]))
return true
} else if (commandIsHelp || noScriptSpecifiedAndNoDefault) {
parser.showHelp('log')
if (helpStyle === 'all' || helpStyle === 'undefined') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would change this to: helpStyle === 'all' || !helpStyle

Unless someone explicitly sets helpStyle to the string of 'undefined' then that second branch will never be true.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@kentcdodds okay, so the undefined check was because of the value coming back from the tests. Where I think I might be getting confused and what might be happening is that, I'm expecting the baseOptions to be setting a default everytime the script is run. However, I don't think that's happening when the tests are run, so I'm getting an undefined value for my helpStyle variable.

For example, if I change it back to this:

if (helpStyle === 'all') {
    parser.showHelp('log')
}

and change the helpStyle var to have a default as I had it before:

const helpStyle = String(psConfig.options['help-style'] || 'all')

I will get 100% function/statement/line coverage again, but still 97.67% on the branch stats for that same if (helpStyle === 'all') line. Now, I've read up some more on "branches" and I understand that Jest is calculating multiple different potential branches from this line:

  • helpStyle === 'all'
  • helpStyle === 'scripts'
  • helpStyle === 'basic'
  • helpStyle === undefined (in the case of aforementioned defaults during tests not being set)

But the way that I've written this is that scripts and basic values are not relevant at this point of the code, because they're analyzed inside of the scriptObjectToChalk() function from index.js. As far as I can tell, it seems to me like I'm going to need to do a bunch of refactoring to move showHelp into index.js and export it to be used in parser.js, because it's not currently exposed as a publically accessible method of the parse object exported from parser.js.

It ultimately makes sense for all of the "help"-related functions/screen output to be within the same file, but I want to check if you see another way before I dive into this because it's going to be a decent-sized refactoring.

@kentcdodds
Copy link
Collaborator

If you're confident that it works as-is, then you can also just use the comment /* istanbul ignore next */. No worries :)

Thank you so much for working so hard on this. I know it's not been easy and I've not been the best helper.

@kentcdodds
Copy link
Collaborator

I hope you've learned a lot from the time you've put in :)

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 9, 2017

@kentcdodds it definitely works as is, so I've implemented the istanbul ignore for that if statement. And yes, I've definitely learned some things, thank you :)

@kentcdodds
Copy link
Collaborator

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 9, 2017

npm test vs. nps validate 😣

On it.

@codecov
Copy link

codecov bot commented Nov 9, 2017

Codecov Report

Merging #164 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #164   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files          12     12           
  Lines         376    382    +6     
  Branches       90     92    +2     
=====================================
+ Hits          376    382    +6
Impacted Files Coverage Δ
src/bin-utils/parser.js 100% <100%> (ø) ⬆️
src/bin-utils/index.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 fc7e660...250f7c6. Read the comment docs.

@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 9, 2017

@kentcdodds realized that I was setting the help-style default in the wrong place. I implemented a small "default" config object and merged it with the config that was getting returned so everything is passing now.

Copy link
Collaborator

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

Thank you so much for working so tirelessly on this! 🎉 Very well done!

@kentcdodds kentcdodds merged commit 9338d72 into sezna:master Nov 9, 2017
@kentcdodds
Copy link
Collaborator

Thanks so much for your help! I've added you as a collaborator on the project. Please make sure that you review the other/MAINTAINING.md and CONTRIBUTING.md files (specifically the bit about the commit messages and the git hooks) and familiarize yourself with the code of conduct (we're using the contributor covenant). You might also want to watch the repo to be notified when someone files an issue/PR. Please continue to make PRs as you feel the need (you can make your branches directly on the repo rather than your fork if you want). Thanks! And welcome to the team :)

@K3TH3R K3TH3R deleted the help-style branch November 9, 2017 05:53
@K3TH3R
Copy link
Collaborator Author

K3TH3R commented Nov 9, 2017

Sounds good @kentcdodds, and thank you for making me part of the team :)

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.

None yet

4 participants