Skip to content

Commit

Permalink
Match data for level 3
Browse files Browse the repository at this point in the history
  • Loading branch information
therabidbanana committed May 18, 2012
1 parent 519dbc9 commit 05ad1e6
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 25 deletions.
92 changes: 67 additions & 25 deletions lib/addressable/uri_template.rb
Expand Up @@ -39,6 +39,10 @@ class UriTemplate < Template
"(?:(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)"
RESERVED =
"(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])"
UNRESERVED =
"(?:[#{
Addressable::URI::CharacterClasses::UNRESERVED
}]|%[a-fA-F0-9][a-fA-F0-9])"
variable =
"(?:#{var_char}(?:\\.?#{var_char})*)"
varspec =
Expand Down Expand Up @@ -137,21 +141,39 @@ def match(uri, processor=nil)

if uri.to_str == pattern
return Addressable::Template::MatchData.new(uri, self, mapping)
elsif expansions.size > 0 && expansions.size == unparsed_values.size
expansions.each_with_index do |expansion, index|
unparsed_value = unparsed_values[index]
elsif expansions.size > 0
index = 0
expansions.each do |expansion|
_, operator, varlist = *expansion.match(EXPRESSION)
case operator
when nil, ?+, ?#
name = varlist[VARSPEC, 1]
value = unparsed_value
if processor != nil && processor.respond_to?(:restore)
value = processor.restore(name, value)
when nil, ?+, ?#, ?/, ?.
varlist.split(',').each do |varspec|
unparsed_value = unparsed_values[index]
name = varspec[VARSPEC, 1]
value = unparsed_value
if processor != nil && processor.respond_to?(:restore)
value = processor.restore(name, value)
end
if mapping[name] == nil || mapping[name] == value
mapping[name] = value
else
return nil
end
index = index + 1
end
if mapping[name] == nil || mapping[name] == value
mapping[name] = value
else
return nil
when ?;, ??, ?&
varlist.split(',').each do |varspec|
name, value = unparsed_values[index].split('=')
value = "" if value.nil?
if processor != nil && processor.respond_to?(:restore)
value = processor.restore(name, value)
end
if mapping[name] == nil || mapping[name] == value
mapping[name] = value
else
return nil
end
index = index + 1
end
end
# if expansion =~ OPERATOR_EXPANSION
Expand Down Expand Up @@ -328,8 +350,10 @@ def ordered_variable_defaults
expansions, expansion_regexp = parse_template_pattern(pattern)
expansions.map do |capture|
_, operator, varlist = *capture.match(EXPRESSION)
name = varlist[VARSPEC, 1]
end
varlist.split(',').map do |varspec|
name = varspec[VARSPEC, 1]
end
end.flatten
)
end

Expand Down Expand Up @@ -497,24 +521,42 @@ def parse_template_pattern(pattern, processor=nil)
_, operator, varlist = *expansion.match(EXPRESSION)
case operator
when ?+
capture_group = "(#{ RESERVED }*?)"
varlist.split(',').map do |varspec|
"(#{ RESERVED }*?)"
end.join(',')
when ?#
capture_group = "#(#{ RESERVED }*?)"
?# + varlist.split(',').map do |varspec|
"(#{ RESERVED }*?)"
end.join(',')
when ?/
varlist.split(',').map do |varspec|
"(#{ UNRESERVED }*?)"
end.join('/?')
when ?.
'\.' + varlist.split(',').map do |varspec|
"(#{ UNRESERVED.gsub('\.', '') }*?)"
end.join('\.?')
when ?;
?; + varlist.split(',').map do |varspec|
"(#{ UNRESERVED }*=?#{ UNRESERVED }*?)"
end.join(';?')
when ??
'\?' + varlist.split(',').map do |varspec|
"(#{ UNRESERVED }*=#{ UNRESERVED }*?)"
end.join('&')
when ?&
'&' + varlist.split(',').map do |varspec|
"(#{ UNRESERVED }*=#{ UNRESERVED }*?)"
end.join('&')
else
capture_group = "([#{
Addressable::URI::CharacterClasses::UNRESERVED
}]*?)"
varlist.split(',').map do |varspec|
"(#{ UNRESERVED }*?)"
end.join(',')
end
if processor != nil && processor.respond_to?(:match)
name = expansion[VARSPEC, 1]
capture_group = "(#{processor.match(name)})"
end
capture_group
end

# Ensure that the regular expression matches the whole URI.
regexp_string = "^#{regexp_string}$"

return expansions, Regexp.new(regexp_string)
end

Expand Down
81 changes: 81 additions & 0 deletions spec/addressable/uri_template_spec.rb
Expand Up @@ -130,6 +130,87 @@
end
end

describe "Level 3:" do
context "no operator" do
subject { Addressable::UriTemplate.new("foo{foo,bar}baz") }
it "can match" do
data = subject.match("foofoo,barbaz")
data.mapping["foo"].should == "foo"
data.mapping["bar"].should == "bar"
end
it "lists vars" do
subject.variables.should == ["foo", "bar"]
end
end
context "+ operator" do
subject { Addressable::UriTemplate.new("foo{+foo,bar}baz") }
it "can match" do
data = subject.match("foofoo/bar,barbaz")
data.mapping["foo"].should == "foo/bar"
data.mapping["bar"].should == "bar"
end
it "lists vars" do
subject.variables.should == ["foo", "bar"]
end
end
context ". operator" do
subject { Addressable::UriTemplate.new("foo{.foo,bar}baz") }
it "can match" do
data = subject.match("foo.foo.barbaz")
data.mapping["foo"].should == "foo"
data.mapping["bar"].should == "bar"
end
it "lists vars" do
subject.variables.should == ["foo", "bar"]
end
end
context "/ operator" do
subject { Addressable::UriTemplate.new("foo{/foo,bar}baz") }
it "can match" do
data = subject.match("foofoo/barbaz")
data.mapping["foo"].should == "foo"
data.mapping["bar"].should == "bar"
end
it "lists vars" do
subject.variables.should == ["foo", "bar"]
end
end
context "; operator" do
subject { Addressable::UriTemplate.new("foo{;foo,bar,baz}baz") }
it "can match" do
data = subject.match("foo;foo=bar%20baz;bar=foo;bazbaz")
data.mapping["foo"].should == "bar%20baz"
data.mapping["bar"].should == "foo"
data.mapping["baz"].should == ""
end
it "lists vars" do
subject.variables.should == %w(foo bar baz)
end
end
context "? operator" do
subject { Addressable::UriTemplate.new("foo{?foo,bar}baz") }
it "can match" do
data = subject.match("foo?foo=bar%20baz&bar=foobaz")
data.mapping["foo"].should == "bar%20baz"
data.mapping["bar"].should == "foo"
end
it "lists vars" do
subject.variables.should == %w(foo bar)
end
end
context "& operator" do
subject { Addressable::UriTemplate.new("foo{&foo,bar}baz") }
it "can match" do
data = subject.match("foo&foo=bar%20baz&bar=foobaz")
data.mapping["foo"].should == "bar%20baz"
data.mapping["bar"].should == "foo"
end
it "lists vars" do
subject.variables.should == %w(foo bar)
end
end
end

context "support regexes:" do
context "EXPRESSION" do
subject { Addressable::UriTemplate::EXPRESSION }
Expand Down

0 comments on commit 05ad1e6

Please sign in to comment.