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

[WIP] Add nested get query parameter expandation #84

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 44 additions & 2 deletions mustermann/lib/mustermann/expander.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'mustermann/ast/expander'
require 'mustermann/caster'
require 'mustermann'
require 'addressable/uri'
Copy link
Member

Choose a reason for hiding this comment

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

What is this?
I would not like to use the addressable gem. Mustermann has not been depended on external gems.
Is there a clear reason to add this gem?
If so, why do not you add this to gemspec.


module Mustermann
# Allows fine-grained control over pattern expansion.
Expand Down Expand Up @@ -194,8 +195,9 @@ def slice(hash, keys)

def append(uri, values)
return uri unless values and values.any?
entries = values.map { |pair| pair.map { |e| @api_expander.escape(e, also_escape: /[\/\?#\&\=%]/) }.join(?=) }
"#{ uri }#{ uri[??]??&:?? }#{ entries.join(?&) }"
Copy link
Member

Choose a reason for hiding this comment

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

Why did you delete these lines? Your patch doesn't cover these feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed 2addf75

Addressable::URI.encode(
[uri, uri.include?('?') ? '&' : '?', QueryStringBuilder.new(values).build].join
)
end

def map_values(values)
Expand All @@ -205,5 +207,45 @@ def map_values(values)
end

private :with_rest, :slice, :append, :caster, :map_values, :split_values

class QueryStringBuilder # :nodoc:
attr_reader :query

def initialize(query = {})
@query = query
end

def build
query.map { |key, value|
if value.is_a?(Array)
build_array_query(key, value)
elsif value.is_a?(Hash)
build_hash_query(key, value)
else
"#{key}=#{value}"
end
}.join('&')
end

private

def build_array_query(key, values)
query_key = "#{key}[]"
values.map { |v| [query_key, v].join('=') }.join('&')
end

def build_hash_query(key, values)
values.map { |h_key, h_value|
query_key = "#{key}[#{h_key}]"
if h_value.is_a?(Hash)
build_hash_query(query_key, h_value)
elsif h_value.is_a?(Array)
build_array_query(query_key, h_value)
else
[query_key, h_value].join('=')
end
}.join('&')
end
end
end
end
3 changes: 3 additions & 0 deletions mustermann/spec/expander_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
subject(:expander) { Mustermann::Expander.new('/:a', additional_values: :append) }
example { expander.expand(a: ?a).should be == '/a' }
example { expander.expand(a: ?a, b: ?b).should be == '/a?b=b' }
example { expander.expand(a: ?a, b: [?b]).should be == '/a?b%5B%5D=b' }
example { expander.expand(a: ?a, b: {c: ?c}).should be == '/a?b%5Bc%5D=c' }
example { expander.expand(a: ?a, b: {c: [1, 2]}).should be == '/a?b%5Bc%5D%5B%5D=1&b%5Bc%5D%5B%5D=2' }
example { expect { expander.expand(b: ?b) }.to raise_error(Mustermann::ExpandError) }
end
end
Expand Down