-
-
Notifications
You must be signed in to change notification settings - Fork 761
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
Example ids #1884
Example ids #1884
Conversation
(...continued...) What do people think about the semantics and syntax of the example id filtering? /cc @rspec/rspec @JoshCheek |
e4e9bd0
to
376fc2a
Compare
This exact spec is duplicated on line 775. I suspect this was written for the old `--line-number` CLI flag and got updated to the `file_path:line_num` form when we dropped support for `--line-number`, creating the duplication.
This allows us to uniquely identify any example or group.
0b542a4
to
a22d0b4
Compare
OK, the build is green and this is ready for a review. /cc @rspec/rspec @JoshCheek |
…and add a spec enforcing that it is always up-to-date.
a22d0b4
to
b77d5bd
Compare
@@ -1613,6 +1613,9 @@ def extract_location(path) | |||
captures = match.captures | |||
path, lines = captures[0], captures[1][1..-1].split(":").map { |n| n.to_i } | |||
filter_manager.add_location path, lines | |||
else | |||
path, scoped_ids = path.split(/[\[\]]/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This group is hard to read with all the slashes and square brackets, do you think it'd be easier to understand if it was path.split(/[#{Regexp.escape("[]")}]/)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally find that to be less readable than what's there now, and it's almost certainly going to perform slower (it has the extra Regexp.escape
method call plus the string interpolation, plus the extra objects created by "[]"
and Regexp.escape
...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps the regex needs a name? split(match_square_brackets)
not convinced that's better, just throwing the idea out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps the regex needs a name?
split(match_square_brackets)
not convinced that's better, just throwing the idea out?
I'm not convinced it needs a name but am happy to assign it to a local if you find that easier to read. I could name the local on_square_brackets
and then it would read split(on_square_brackets)
-- do you like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems fine to me :)
I did a partial review, I'll give more feedback when I get more time. |
@@ -173,6 +181,12 @@ def build_description_from(parent_description=nil, my_description=nil) | |||
(parent_description.to_s + separator) << my_description.to_s | |||
end | |||
|
|||
def build_scoped_id_for(file_path) | |||
index = @index_provider.call(file_path).to_s | |||
parent_scoped_id = metadata.fetch(:scoped_id) { return index } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return keyword is unnecessary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's very much necessary. It's an early return of index
from build_scoped_id_for
. Remember that return
is relative to the enclosing method definition since this is a block, not a lambda.
OK, I'm done. Let me know what you think :) |
Today and tomorrow are pretty packed full, but I'll try and take a look sometime in the several days. |
..as per @samphipppen’s request.
..as per @samphippen’s review request.
Thanks for the review! Any ideas what we can do about the zsh square bracket problem? |
Thanks, @JoshCheek...more 👀 on a PR is always nice :). |
I had a scan, looks good too me |
Any ideas for what to do about zsh complaining about |
I'm not a zsh user either :/ |
OK, so looks like
I'm thinking we should go with the second option. We can test the common shells (zsh, bash, csh, any others?) and for anything unknown have it escape to be on the safe side. Question is, which of these forms do we prefer? rspec ./path/to/spec.rb\[2:2\]
# or
rspec './path/to/spec.rb[2:2]' I think I prefer the latter...the |
I agree on the later, and on escaping unless we know we're good. |
zsh users can also run the command with noglob e.g. See: https://github.com/sorin-ionescu/prezto/blob/b41f4855286cd9ec2b00f7c8d91a6e2778009d51/modules/utility/init.zsh#L43 |
Right. I'm aware of that, but the re-run command should "just work" and not require users to do something special like that. Good to know, though. |
cab546a
to
b3f8ca5
Compare
- Clarify location filtering. - Add info about id filtering.
b3f8ca5
to
16bb9a7
Compare
OK, I implemented the quoting for non-bash shells as discussed. Anyone know what other shells (if any) support the id syntax w/o quoting? I tested it on:
We can add more to the list later but if anyone knows of others we can add them now. |
I use fish, it doesn't need quoting: $ ruby -e 'p ARGV' ./path/to/spec.rb[2:2]
# ["./path/to/spec.rb[2:2]"]
$ fish -c 'ls [lt][im][bp]'
# ls: [lt][im][bp]: No such file or directory
$ bash -c 'ls [lt][im][bp]'
# lib:
# rspec
#
# tmp:
# aruba |
…according to @JoshCheek’s comment: #1884 (comment)
Thanks, @JoshCheek, I added fish to the list of shells that allow unquoted ids. |
# Returns the location-based argument that can be passed to the `rspec` command to rerun this example. | ||
def location_rerun_argument | ||
@location_rerun_argument ||= begin | ||
loaded_spec_files = RSpec.configuration.loaded_spec_files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm generally apprehensive of singletons like RSpec.configuration
, and find my code is most flexible if internally I always inject such a value from the highest level of the caller. e.g. global state leads to the need to do things like https://github.com/rspec/rspec-core/blob/43b464b6bfa3117e6c91d0028d272954229f8b00/spec/support/sandboxing.rb Obviously my sense of danger tingles wherever a stateful method is called on a global object like a class, and probably it's been this way since its inception, so I'll just mention it out on this one and leave it alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm apprehensive, too, and would love to find a way to do away with the global state, but it's definitely not an easy change. Many, many call sites would have to change to accept RSpec.configuration
and/or RSpec.world
in order to pass them on. I looked into a bit at one point and concluded it wasn't worth the ROI, but you can certainly take a stab at it :).
@JonRowe / @samphippen is this good to merge? |
LGTM |
…according to @JoshCheek’s comment: rspec#1884 (comment)
Example ids
:rerun_file_path
. This is usually the same as:file_path
but can be different for situations such as an abstract example defined in a shared example group. In that situation:file_path
would be file the shared example group is defined in (e.g.spec/support/model_shared_examples.rb
), whereas:rerun_file_path
would be the file would be something likespec/models/my_model_spec.rb
-- a particular spec file that includes the shared example group. The:rerun_file_path
is the file arg you would have to pass torspec
to cause the example to be re-run.--bisect
flag #1767 (e.g../spec/rspec/core/example_spec.rb[1:14]
). You can also specify multiple examples or groups:./spec/rspec/core/example_spec.rb[1:14,1:15]
. I thought the brackets make a nice syntax for separating the id part from the file part, and it makes it clear that you are passing an example id, whereas in the syntax suggested in Feature idea: new--bisect
flag #1767, it's harder to differentiate between an id filter and a location filter --file_name:1
would be ambiguous about whether it's a line number or id filter. This allows us to support passing ids simply as the main args torspec
, e.g.rspec ./spec/rspec/core/example_spec.rb[1:1] ./spec/rspec/core/example_group_spec.rb[1:1]
, which I think is better than a specific--ids
flag. One downside to this syntax is that zsh makes you wrap it in quotes due to the use of[...]
. Bash doesn't, though. I'm not sure about Windows, but it's the syntax Rake uses for task arguments so I figured it's already been vetted and proved out by rake and I have to assume rake works fine on windows.[]
characters. It'd be nice to do something about that but I'm not sure what.TODOs: