-
Notifications
You must be signed in to change notification settings - Fork 3k
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
doctest allow int/line-number prefix #9430
base: master
Are you sure you want to change the base?
Conversation
CT Test Results 2 files 97 suites 1h 8m 53s ⏱️ For more details on these failures, see this check. Results for commit 9ed5b46. ♻️ This comment has been updated with latest results. To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
Here are some results of manual testing, because I'm not yet smort enough to run only doctests from the CLI;
I still be learning the ways of Erlang, and least-bad practices, so any tips towards reducing future costs to maintenance are very much appreciated! CC: @garazdawi I figured it'd be wise to nudge things specific to OTP parity from |
One of the things I like a lot about doctests is that it adds uniformity to the examples. So I think that I would like it to be very oppionionated about how you write examples. So I would like for the examples to either use Which one do you prefer and why? |
1> shell_docs:test(ModuleToTest, []). |
For compatibility with preexisting 1> State = "World".
2> Greeter = fun(State) -> "Hello " ++ State end.
3> Result = Greeter(State).
"Hello World" At the same time I prefer > true.
true
> false.
false True having both is a more overhead to maintain and parse, and I'm but one opinionated noob ;-) |
I think just the Maybe it would be nice to use @garazdawi Sorry for the off-topic question below: Is it possible for the shell to capture pasted content (
The shell would then print:
It would be nice to have this feature to experiment with copied examples from the documentation. |
Ooof, so seems to be lots of variants that could be supported, but could don't mean should... 🤔 still I'm game to be nerd-sniped for a bit ;-) TLDR Here's a synopsis of what I could find of variants;
... Double-checking dates it seems Simplicity is nice, and usually I'm all for it, but I like the idea of broader support for documentation tests too 🤷 |
Just checked and the iex(1)> a = ~s"
...(1)> foo
...(1)> "
"\nfoo\n"
iex(2)> b =
...(2)> 1 +
...(2)> 1
2
iex(3)> c = :foo
:foo The line numbers can be omitted in Elixir doctest: iex> a = ~s"
...> foo
...> "
"\nfoo\n"
iex> b =
...> 1 +
...> 1
2
iex> c = :foo
:foo In Erlang shell (OTP-28) it is: 1> A = ~"
foo
".
<<"\nfoo\n">>
2> B =
1 +
1.
2
3> C = foo.
foo Omitting line numbers in Erlang doctest: > A = ~"
foo
".
<<"\nfoo\n">>
> B =
1 +
1.
2
> C = foo.
foo Erlang should not always adhere to what's implemented in Elixir, but maybe the optional line count support is a good idea. I do not have a strong opinion of the "why", only because of the shell ;) |
Having noodled it about in my brain, and skimmed bits of doc-comments within various Erlang OTP sources, I believe the strongest argument I can think of for supporting line-numbers in doctests is reducing Git Diff churn. Here be but two examples I could find that should just work were we to support both ways;
And though glancing elsewhere I found a few instances where either would require some touch-work, ex;
... I've got a hunch it'll be less touch-work than picking but one style. |
Lets do what the shell does, so that we get a similar look and feel as the shell. That is the regexp to match a test start is
@michalmuskala it already works like this :) |
Sure thing! I'll try to get something prettier (more maintainable than my current questionable code suggestions) sorted and submitted for public comment soon™ |
TLDR update I'm blocked by something upstream of A hint, or two, would be much appreciated! Unabridged update I think I won the battle with RegExp, and by doing so also flattened that pesky Like the most recent commit message says, local/isolated testing of If we get doctest input similar to; -module(wat).
-export([woot/0]).
-doc """
```erlang
> wat:woot().
false
```
""".
woot() -> woot. ... Then I can observe the -doc """
```erlang
-> wat:woot().
+1> wat:woot().
false
```
""".
woot() -> woot. Altering the RegExp to allow for optional line-numbers, --define(RE_CAPTURE, "(?'indent'^\s*)(((?'line_number'[0-9]+)(?'prefix'>\s|\s))|(?'prefix'%))(?'content'[^%]*)(?'comment'(?:.*%.*)?)").
+-define(RE_CAPTURE, "(?'indent'^\s*)(((?'line_number'(?:[0-9]+)?)(?'prefix'>\s|\s))|(?'prefix'%))(?'content'[^%]*)(?'comment'(?:.*%.*)?)").
-define(RE_OPTIONS, [ {capture, [indent, line_number, prefix, content, comment] ,binary}, dupnames ]).
parse_tests([], []) -> ... does show things are mostly parsed as they use-to. I.E. Edit 🤦 |
Let me know when you are ready for a review! The examples in |
Thanks for being patient with me! I think I've got most of the For single line test/match blocks it seems to be mostly doing what it should... mostly... but for reasons I've yet to figure-out it ain't at all happy with mutli-line stuff and I either may need a bit of help or more time to resolve my skill issues x-) |
I think (hope) changes are ready for review!
Updated doctest comments to include line numbers and adjusted indentation too for
Please do let me know if I've broken anything, that wasn't already misbehaving, and I'll do my best to make corrections! |
We did some changes in the lists module, would you mind rebasing on latest master? I’ll have a closer look on Monday. |
⚠️ nested `case` does not spark joy and RegExp might be a better choice for this feature request! This patch aims to formally begin the discussion here about feature parity between Erlang OTP doctest, and the library of the same name maintained by [williamthome](https://github.com/williamthome/doctest/) Specifically this patch targets `>` vs `1>` syntax for declaring the start of a testable code line or set of lines, ex; **Erlang OTP doctest** ````erlang -doc """ This test is how we do with `erlang/otp` doctests ``` > true. true > totallyOkay. totallyOkay ``` """ woot() -> ok. ```` **williamthome doctest** ````erlang -doc """ This test is how we do with `williamthome/doctest` ```erlang 1> false. false 2> thisIsFine. thisIsFine ``` """ muchJoy() -> ok. ````
⚠️ Local testing of changes, in isolation, shows good behavior! But additional edits, and testing, will be necessary for me to have confidence in changes. Change summary between `c23347df2c` and here: - define RegExp capture and options - remove `parse_match/2` completely - add `parse_tests/2` RegExp pattern matching within function prams - remove `parse_tests/2` nested `case` in favor of recursion
🤦 Now I get what `Match` means in `parse_tests/2` and why for the calls to `parse_match/2` too! This _should_ now collect code lines, like it once did, and expected match line(s)... Though it seems the last line and/or empty lines now need ignored or skipped 🤔
Attempting to match in-line comments was a bad idea from my past self, as was trying to dedent 🤦⚠️ Still need to sort-out multi-line `Cmd` and `Match`
Still gotta sort-out that issue of multi-line `Code`/`Match` 🤔
⚠️ If we need to support `.. ` command continuation in the future that'll require touching the `RE_CAPTURE` pattern and adding a few more variants for `parse_tests/2` too
Spotting the following error/stack-trace popping for; ````erlang -doc """ ``` 1> Prebound. hello ``` """. ```` ... Here's some `io:format` output and resulting error; ``` run_test(Code, InitialBindings) | Code -> <<"1> Prebound.\nhello\n">> | InitialBindings -> [] | ReLines -> [ {match, [<<"1> ">>, <<"> ">>, <<"Prebound.">>]}, {match, [<<>>, <<>>, <<"hello">>]}, {match, [<<>>, <<>>, <<>>]} ] | Tests -> [{test, [<<"Prebound.">>], [<<"hello">>]}] [{match,1,{atom,1,hello},{block,1,[{var,1,'Prebound'}]}}] ** exception error: {unbound_var,'Prebound'} in function erl_eval:exprs/2 (erl_eval.erl, line 217) in call from shell_docs_test:run_tests/2 (shell_docs_test.erl, line 202) in call from lists:foldl/3 (lists.erl, line 2146) in call from shell_docs_test:test/2 (shell_docs_test.erl, line 153) in call from shell_docs_test:test/2 (shell_docs_test.erl, line 153) in call from shell_docs_test:parse_and_run/3 (shell_docs_test.erl, line 137) in call from shell_docs_test:'-parse_and_run/3-lc$^0/1-0-'/3 (shell_docs_test.erl, line 133) in call from shell_docs_test:'-module/2-lc$^0/1-0-'/3 (shell_docs_test.erl, line 122) ```
Tip, use the following command to filter out this commit's churn; ```bash git diff --ignore-space-change ```
Usually doing something like; ```bash git pull --rebase -X theirs origin master ``` ... is fine, but this time Git lost the plot in a few places. Fortunately it was only one file, so doing a selective show via; ```bash git show origin/master:lib/stdlib/src/lists.erl > lib/stdlib/src/lists.erl ``` ... And then manually going through to re-add doctest line numbers, and adjust indentation, wasn't too much of a chore.
For _reasons_ Git felt it important to (re-)introduce trailing spaces
2d96680
to
9ed5b46
Compare
I don't mind at all, and ya can consider the rebasing done :-) Looking forward to Monday's review I will, and 'ntil then I'll be wishing y'all a wonderful weekend! |
case
does not spark joy and RegExp might be a better choice for this feature request!This patch aims to formally begin the discussion here about feature parity between Erlang OTP doctest, and the library of the same name maintained by williamthome
Specifically this patch targets
>
vs1>
syntax for declaring the start of a testable code line or set of lines, ex;Erlang OTP doctest
williamthome doctest