-
Notifications
You must be signed in to change notification settings - Fork 480
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
Improve support for multiline help text #456
Improve support for multiline help text #456
Conversation
Hmm , I notice that the tests are failing on the automated test system, and from the log it appears that the newline detection is not working. That is odd since the tests all pass on my (windows) PC and I've used Environment.NewLine rather than hardcoding assumption about linefeeds. My guess would be that the tests are being compiled in a way that that the implicit line-feeds in HelpTextWithLineBreaks_Options are not being inserted as Environment.NewLine. Are the tests running under Linux? |
Tests now passing. I have added an extra test to ensure correctness when cross-compiling or when editor line-endings are not consistent with the target machine |
@moh-hassan any chance of a review/merge on this? I can't see that it's at all controversial though I suppose there's a small chance it might annoy people who have been inserting \n into their help text then manually trying to adjust the indentation. |
I start reviewing the PR. |
To overcome the problem of line-break in test, the library break the help text into lines like:
for example |
@moh-hassan Thanks for looking at this. The line-break situation is more subtle than you might think (indeed, it took me a couple of rounds of broken tests to work out what was going on).
It will be compiled to "abc\r\ndef" when
There is also a set of scenarios that lead to the string being compiled as "abc\ndef" Furthermore, the user might choose to write
even though the code ends up being compiled on a linux machine. With .net core , we have cross-platform executables so there is no guarantee that the executable was compiled on a machine where Environment.NewLine matches the line-breaks embedded in the string. Hence the code has to take special care to ensure that line-breaks in compile-time strings are treated flexibly while being rigorous about using Environment.NewLine for strings that are output to the user at runtime. That is why you see the processing of '\r', '\n' in the TextWrapper on input (constructor) and use of Environment.NewLine on output (ToText)
I'm not sure that's really relevant here. The main reason for breaking the output string in most of the tests appears to be because 1) it's easier to look at individual lines when asserting relevant content, 2) those tests aren't really concerned with the stuff at the end of the lines! |
The problem of line-break in Cross-Platform is solvable in GIT and CI like Appveyor by properly handling the line endings.
This core.autocrlf setting tells git to convert newlines to LF when checking out files. As, you use Environment.NewLine all-the time for Cross-Platform compatibility for a line-break in the library, in test, if you want to exclude line-break from string comparison: instead of:
use:
|
@moh-hassan Please could you reread my post. Environment.NewLine is a runtime variable and hence should not be used when processing compile-time strings. If you want a concrete example you might think about what the output of
when compiled on Linux and run on Windows vs compiled on Windows and run on Linux. Even if Environment.NewLine was not likely to change at runtime, it is possible for users of the library to embed the 'wrong' style of line-endings in a string based on (false) assumptions about the target platform....
Again, it's a useful experiment to consider what happens when you consider the output when compiled/run on each platform.
You are misunderstanding the purpose of those tests. The intention is to ensure that the line-breaks are present in the expected positions, but to be agnostic about what style they are. |
From MS Documentation: Environment.NewLine Property A string containing "\r\n" for non-Unix platforms, or a string containing "\n" for Unix platforms. What about this compile-time variable (NOT run-time):
when compiled on Linux and Windows and then run on Linux and windows. |
That is not a compile time constant. It is an expression which is evaluated at run-time by appending the run-time value of Environment.Newline to the constant "File-specific line" and then appending the constant "break". If you're doubtful about that then I suggest you try compiling this.... And if it was truly defined at compile-time, then how do you suppose a cross-platform .Net core application would produce the correct line-endings when you run the following?
This just means it is a constant for the platform you happen to be running on (as opposed to the platform you are compiling on). BTW, I don't have visibility of your build system to say how it is misconfigured but I can assure you that this whole issue started because a unit test like this was failing....
|
When I meant Compile-time on the following statement: I mean, $ string interpolation - is evaluated at compile-time not at run-time My suggestions of the Environment.NewLine was based on the guideline from NetCore team when building NetCore application. |
Ah - but that is exactly the wrong way round ! If string-interpolation was conducted at compile-time, then it couldn't possibly produce the right result for
:-)
Indeed, this is generally very good guidance! But you need to be aware that it applies to strings produced or consumed at runtime (ie. supplied by or displayed to the user) not constant things! If you've ever worked with different dates or cultures then you can see this analogous to using int.Parse(..., InvariantCulture) for strings that are internal to the code and int.Parse(...,localCulture) for strings that are supplied by the user. :-) |
I added two extra test cases with the attached file: 1- For Hidden option But they fail |
…Width. Also fix up old broken tests
Thanks! The first test failure is actually not a bug. The original indenter had a flaw/bug where it would add a space to every line except the last. The new indenter doesn't suffer from this problem. That's why you'll see I've modified some of the original tests to remove the check for the trailing space. The second test really was a bug so thanks for catching this! I've modified the TextWrapper to always use a minimum width of 1 even if there is no space left on the display. Probably worth noting that the visual effect will be horrible in this case but it would also have been horrible using the old indenter! If you want to display helptext using 10 columns it's never going to look good ;-) I noticed your "hidden option" test was actually present in the original test set but had been commented out (not by me) some time in the past. That led to find a load of other tests that seem to have been ignored at some point by someone who couldn't get them to run under .net core. I have now restored these tests by simply avoiding the breaking bit of the test - i.e. the assumption that the copyright line will include some specific text. |
You are correct. 18 test case was dropped in moving from v2.3.0 to v2.4.3
Setting a minimum width is a good choice. The Refactoring done in your PR is nice. |
I did an integration test in my local machine in QA branch that merge your PR and Pr #462 and Passed: 374 and only 1 Failed (good news that hidden options passed)
It seems the two space prefix I can modify this test case and remove the extra spaces. Can I do? |
yes agreed - I think that test is so old it precedes the change that added indentation for errors and other items. Adding a couple of spaces or, better, using
resolves it. |
BTW - this PR is really just a precursor to adding a fix for #337 After you have merged it I would like to add a "Detail" parameter for HelpText which will be shown if you explicitly call "help" on a verb. The TextWrapper class is a useful building block for that. |
Now, the test case is resolved and test pass. Can you have a look to the layout of the help for the test case of "hidden option" in the attached file that I sent before. I find an extra empty line for the option "input-file" and no line between options. The layout of the help is:
|
I expect so. |
I believe this is an artefact of the fact that test uses AddOptions directly instead of HelpText.AutoBuild. Options are only separated with blank-lines when the HelpText.AdditionalNewLineAfterOption property is set to true and this is only done in one place - one of the HelpText.AutoBuild variants. So in other words, I don't think it is an error that I have caused - just another indication that the current HelpText configuration is too complicated and confusing! ;-) |
I just pushed in another couple of tests to prove that blank lines are added by default between verbs on the main help screen and between options on a specific "help verb" screen. |
An integrated branch is recreated QA with merging this PR and merging fix/missed-test #462 and find 5 test cases Fail. It seems that the extra spaces is the problem. |
I have resolved 3 test cases by removing one trailing space because it has no effect on logic of wrapping. Also removing the trailing one space cause the success of test with this PR in the integration branch, it can't be applied to PR #462 because it cause test fail. |
The test fails you are seeing are due to bugs in the original indent/wrap code which the new version does not share.
The other test failures are variants of these.
Normally I would agree that changing unit tests is undesirable and the goal should be to maintain existing behaviour. However, in this case the refactoring exposed bugs in the original design and the tests had not only ignored those bugs, but baked them into the expected behaviour! I believe the new behavior is correct (though if you can find examples where it isn't I'll be happy to fix them) and therefore the tests should be corrected. From a practical perspective, why not just treat 'develop' as the integration branch and start by merging #462? As I said, I'm quite happy to rebase to the new develop. |
I agree that adding space when wrapping lines isn't necessary, failure of these tests due that extra space can be corrected by modifying these tests.
I prefer to keep the history of develop as clean as possible and merge when the PR is final and no more iteration of change. As you see there were more iterations of change in both Pr(s). I'll merge PR #462 in develop. |
Test maintainance: add missed tests and removing xUnit1013 warning (#…
Pr #462 is merged in develop. |
…ing across tests
Thanks - have now rebased from develop so this should include tests from #462 |
+1 |
Thanks! :-) |
This PR improves support for multiline and semi-formatted HelpText. For example, it is now possible to write
and have the help text output in the expected fashion. Sub-indentation is correctly preserved even when long lines are supplied. E.g.
will be output as
for a narrow screen.
There are a couple of unit tests supplied to ensure correct operation (I'm not sure these adhere to the current naming convention - happy to change if you want).
As well as the main functionality there are a few 'drive-by' changes in the HelpText and test code.
Any questions, drop me a line. This is great library I've been using for a couple of years and it's good to see it back under active maintenance :-)