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

fix(#20): Add params option to the mustermann grape pattern for taking into account the parameter type #21

Merged
merged 3 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format documentation
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
### 1.0.3 (Next)
jcagarcia marked this conversation as resolved.
Show resolved Hide resolved

#### Features

* Your contribution here.

#### Fixes

* [#21](https://github.com/ruby-grape/mustermann-grape/pull/21): Introducing the `params` option to `Mustermann::Grape` to enhance matching by offering detailed information regarding the parameter types. - [@jcagarcia](https://github.com/jcagarcia).
* Your contribution here.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ This gem implements the `grape` pattern type for Mustermann.
## Overview

**Supported options:**
`capture`, `except`, `greedy`, `space_matches_plus`, `uri_decode`, `converters` and `ignore_unknown_options`
`capture`, `converters`, `except`, `greedy`, `ignore_unknown_options`, `params`, `space_matches_plus` and `uri_decode`

``` ruby
require 'mustermann/grape'

Mustermann.new('/:id', type: :grape).params('/foo') # => { id: 'foo' }

# Providing params option
Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"Integer"}}).params('/1') # => { id: '1'}
Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"Integer"}}).params('/foo') # => nil
Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"String"}}).params('/foo') # => { id: 'foo'}
```

## Syntax
Expand Down
19 changes: 18 additions & 1 deletion lib/mustermann/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,28 @@ module Mustermann
# @see file:README.md#grape Syntax description in the README
class Grape < AST::Pattern
register :grape
supported_options :params

on(nil, '?', ')') { |c| unexpected(c) }

on('*') { |_c| scan(/\w+/) ? node(:named_splat, buffer.matched) : node(:splat) }
on(':') { |_c| node(:capture, constraint: "[^/\\?#\.]") { scan(/\w+/) } }
on(':') do |_c|
param_name = scan(/\w+/)
return node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) } unless pattern

params_opt = pattern.options[:params]
if params_opt && params_opt[param_name] && params_opt[param_name][:type]
param_type = params_opt[param_name][:type]
case(param_type)
when "Integer"
node(:capture, param_name, constraint: /\d/) { scan(/\w+/) }
else
node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) }
end
else
node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) }
end
end
on('\\') { |_c| node(:char, expect(/./)) }
on('(') { |_c| node(:optional, node(:group) { read unless scan(')') }) }
on('|') { |_c| node(:or) }
Expand Down
29 changes: 29 additions & 0 deletions spec/grape_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -751,4 +751,33 @@
example { pattern.peek_params('/foo bar') .should be_nil }
end
end

context 'when params option is provided' do
context 'and they contain parameters information' do
pattern '/foo/:id', params: {"id"=>{:type=>"Integer"}} do
it { should match('/foo/1') }
it { should_not match('/foo/bar') }
end

context 'and inherit routes are present' do
pattern '/foo/:id/bar/:reference', params: {"id"=>{:type=>"Integer"}, "reference"=>{:type=>"String"}} do
it { should match('/foo/1/bar/wadus') }
it { should_not match('/foo/bar/bar/wadus') }
end

pattern '/foo/:id/bar/:reference', params: {"id"=>{:type=>"Integer"}, "reference"=>{:type=>"Integer"}} do
it { should match('/foo/1/bar/1') }
it { should_not match('/foo/1/bar/wadus') }
it { should_not match('/foo/bar/bar/1') }
end
end
end

context 'and they do NOT contain parameters information' do
pattern '/foo/:id' do
it { should match('/foo/1') }
it { should match('/foo/bar') }
end
end
end
end
Loading