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

Add pattern matches to values for Mustermann::Concat. Fixes #1332 #1333

Merged
merged 1 commit into from
Feb 6, 2018

Conversation

dometto
Copy link
Contributor

@dometto dometto commented Aug 15, 2017

This resolves #1332. Two questions:

  • should I add a regression spec for this?
  • is it possible that matches should also be added to values? for classes other than Mustermann::Regular and Mustermann:Concat?

@namusyaka
Copy link
Member

The :captures parameter is added for use in regexp route.
Also, the mustermann concat feature has been using by other routes like sinatra-namespace, so this patch makes params have the :captures params in unexpected routes.

@dometto
Copy link
Contributor Author

dometto commented Aug 20, 2017

The :captures parameter is added for use in regexp route.

Yes, but the problem seems to be exactly that :captures should also be added, in some cases at least, to concat routes (when the Mustermann::Concat consists in part of a regexp).

@namusyaka
Copy link
Member

@dometto Could you add a test?

@zzak
Copy link
Member

zzak commented Oct 29, 2017

Needs a test

@dometto
Copy link
Contributor Author

dometto commented Jan 14, 2018

Sorry for the slow response. I've added a test (which indeed fails when the fix is absent).

@namusyaka
Copy link
Member

Thanks for adding the test. I've just confirmed that.

However, I can't aggressively agree with this change.
Because the :captures parameter is required only if Mustermann::Concat consists of multiple patterns containing a Mustermann::Regular pattern.
In other words, Mustermann::Concat doesn't require captures except that case.

For example, one Mustermann::Concat may consist of Mustermann::Sinatra and Mustermann::SimpleMatch. In this case, obviously, the :captures parameter will be an empty array.

Although it seems that this change doesn't largely destroy backward compatibility (the :captures key is originally prohibited), this may confuse application developers in some cases.

@namusyaka
Copy link
Member

Additional notes:
I have grasped the problem you indicated.
We need to work on this in some way and I think that the patch you sent is also one of the solutions.
Thanks!

@dometto
Copy link
Contributor Author

dometto commented Jan 15, 2018

Is there already an easy way to test if a Mustermann::Concat contains a regexp, e.g. .include?? In that case we can just make the condition more specific.

@namusyaka
Copy link
Member

Nope, that's not the proper way.
However, you can determine by using Mustermann::Composite#patterns

concat = Mustermann.new("/prefix", type: :identity) + Mustermann.new('/foo')
p concat.patterns.any?{|pattern| pattern.is_a?(Mustermann::Regular) }
concat = Mustermann.new("/prefix", type: :regexp) + Mustermann.new('/foo')
p concat.patterns.any?{|pattern| pattern.is_a?(Mustermann::Regular) }

@dometto
Copy link
Contributor Author

dometto commented Jan 15, 2018

Fair enough. 👍 I'll put together a fix based on that!

@dometto
Copy link
Contributor Author

dometto commented Jan 15, 2018

New implementation. The check in base.rb is now more complicated, but I think it performs well and is precise enough. If you have any suggestions on how to shorten it or make it more readable, let me know.

Copy link
Member

@namusyaka namusyaka left a comment

Choose a reason for hiding this comment

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

Looks good with a few nits.
Thanks.

@@ -1024,7 +1024,9 @@ def process_route(pattern, conditions, block = nil, values = [])
params.delete("ignore") # TODO: better params handling, maybe turn it into "smart" object or detect changes
original, @params = @params, @params.merge(params) if params.any?

if pattern.is_a?(Mustermann::Regular) || pattern.is_a?(Mustermann::Concat)
has_regexp = pattern.is_a?(Mustermann::Regular) ? true :
(pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} )
Copy link
Member

Choose a reason for hiding this comment

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

prefer AND operator over conditional operator in this case.

regexp_exists = pattern.is_a?(Mustermann::Regular) || (pattern.respond_to?(:patterns) && pattern.patterns.any? {|subpattern| subpattern.is_a?(Mustermann::Regular)} )

@@ -630,17 +630,26 @@ class RoutingTest < Minitest::Test
end

it 'makes regular expression captures available in params[:captures] for concatenated routes' do
concatenated = Mustermann.new('/prefix') + Mustermann.new("/fo(.*)/ba(.*)", :type => :regexp)
with_regexp = Mustermann.new('/prefix') + Mustermann.new("/fo(.*)/ba(.*)", :type => :regexp)
without_regexp = Mustermann.new('/prefix') + Mustermann.new('/baz')
Copy link
Member

@namusyaka namusyaka Jan 15, 2018

Choose a reason for hiding this comment

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

Maybe this is not Mustermann::Concat, but pure Mustermann::Sinatra.
You should use multiple mustermann types, it will be something like:

without_regexp = Mustermann.new('/prefix', type: :identity) + Mustermann.new('/baz')

@@ -630,17 +630,26 @@ class RoutingTest < Minitest::Test
end

it 'makes regular expression captures available in params[:captures] for concatenated routes' do
concatenated = Mustermann.new('/prefix') + Mustermann.new("/fo(.*)/ba(.*)", :type => :regexp)
with_regexp = Mustermann.new('/prefix') + Mustermann.new("/fo(.*)/ba(.*)", :type => :regexp)
Copy link
Member

Choose a reason for hiding this comment

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

Please use keyword argument instead of hash-rocket.

@dometto
Copy link
Contributor Author

dometto commented Jan 15, 2018

👍

@namusyaka
Copy link
Member

Perfect! Please wait for cutting next release!

@namusyaka namusyaka mentioned this pull request Jan 15, 2018
@zzak
Copy link
Member

zzak commented Jan 16, 2018

Could you squash your commits please? 🙏

@dometto
Copy link
Contributor Author

dometto commented Jan 16, 2018

All ready!

@dometto
Copy link
Contributor Author

dometto commented Jan 31, 2018

Any idea when this will be merged/released?

@namusyaka namusyaka added this to the v2.0.1 milestone Feb 6, 2018
@namusyaka
Copy link
Member

Sorry for the late reply. Now I don't see any reason why we cannot merge this.

Thank you for your contribution!

@namusyaka namusyaka merged commit a96f144 into sinatra:master Feb 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ArgumentError with regexp route with optional capture group
3 participants