Updated URI Template to follow official RFC6570

This commit is contained in:
Jocelyn Fiat
2012-05-14 18:11:12 +02:00
parent 278a71eaaf
commit 64eebd32db
18 changed files with 4631 additions and 2212 deletions
+4
View File
@@ -1,6 +1,10 @@
# URI Template # URI Template
## Overview ## Overview
Implement URI Template as described at http://tools.ietf.org/rfc/rfc6570.txt
Support for URI template string expansion
But also partial URI Template matching
## Usage ## Usage
+3 -2
View File
@@ -1,4 +1,5 @@
Most recent spec/draft/in-progress http://code.google.com/p/uri-templates/source/browse/trunk/spec/draft-gregorio-uritemplate.xml Most recent http://code.google.com/p/uri-templates/source/browse/trunk
svn cat http://uri-templates.googlecode.com/svn/trunk/spec/draft-gregorio-uritemplate.xml > uritemplate-draft-gregorio-trunk.xml wget http://tools.ietf.org/rfc/rfc6570.txt -O uritemplate-RFC6570
# Check http://code.google.com/p/uri-templates/source/browse/trunk for work in progress
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,52 +0,0 @@
note
description: "[
Summary description for {URI_TEMPLATE_CONSTANTS}.
see http://tools.ietf.org/html/draft-gregorio-uritemplate-05
]"
author: ""
date: "$Date$"
revision: "$Revision$"
class
URI_TEMPLATE_CONSTANTS
feature -- Operator
Reserved_operator: CHARACTER = '+'
Form_style_query_operator: CHARACTER = '?'
Path_style_parameters_operator: CHARACTER = ';'
Path_segment_operator: CHARACTER = '/'
Label_operator: CHARACTER = '.'
feature -- Separator
Default_delimiter: CHARACTER = '|' --| Draft 05
feature -- Explode
Explode_plus: CHARACTER = '+'
Explode_star: CHARACTER = '*'
feature -- Modified
Modifier_substring: CHARACTER = ':'
Modifier_remainder: CHARACTER = '^'
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
@@ -1,12 +1,9 @@
note note
description: "[ description: "[
Summary description for {URI_TEMPLATE}. Implementation of URI Template RFC6570.
See http://tools.ietf.org/html/draft-gregorio-uritemplate-04
note for draft 05, check {URI_TEMPLATE_CONSTANTS}.Default_delimiter
]" See http://tools.ietf.org/html/rfc6570
]"
legal: "See notice at end of class." legal: "See notice at end of class."
status: "See notice at end of class." status: "See notice at end of class."
date: "$Date$" date: "$Date$"
@@ -513,7 +510,7 @@ feature {NONE} -- Implementation
end end
note note
copyright: "2011-2012, Eiffel Software and others" copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software
@@ -2,9 +2,9 @@ note
description: "[ description: "[
Summary description for {URI_TEMPLATE_CONSTANTS}. Summary description for {URI_TEMPLATE_CONSTANTS}.
see http://tools.ietf.org/html/draft-gregorio-uritemplate-04 see http://tools.ietf.org/html/rfc6570
]" ]"
author: "" author: "Jocelyn Fiat"
date: "$Date$" date: "$Date$"
revision: "$Revision$" revision: "$Revision$"
@@ -17,15 +17,19 @@ feature -- Operator
Form_style_query_operator: CHARACTER = '?' Form_style_query_operator: CHARACTER = '?'
Form_style_query_continuation: CHARACTER = '&'
Path_style_parameters_operator: CHARACTER = ';' Path_style_parameters_operator: CHARACTER = ';'
Path_segment_operator: CHARACTER = '/' Path_segment_operator: CHARACTER = '/'
Fragment_expansion: CHARACTER = '#'
Label_operator: CHARACTER = '.' Label_operator: CHARACTER = '.'
feature -- Separator feature -- Separator
Default_delimiter: CHARACTER = '=' --| Draft 0.4 , change to '|' for Draft 0.5 Default_delimiter: CHARACTER = '=' --| Not included in the RFC, but was part of previous Draft
feature -- Explode feature -- Explode
@@ -12,7 +12,7 @@ inherit
DEBUG_OUTPUT DEBUG_OUTPUT
export {NONE} all end export {NONE} all end
URI_TEMPLATE_CONSTANTS URI_TEMPLATE_CONSTANTS
export {NONE} all end export {NONE} all end
@@ -72,6 +72,17 @@ feature -- Processing
operator := '?' operator := '?'
op_prefix := '?' op_prefix := '?'
op_delimiter := '&' op_delimiter := '&'
when form_style_query_continuation then
--| '&'
operator := '&'
op_prefix := '&'
op_delimiter := '&'
when fragment_expansion then
--| '#'
reserved := True
operator := '#'
op_prefix := '#'
op_delimiter := ','
when '|', '!', '@' then when '|', '!', '@' then
operator := exp[1] operator := exp[1]
else else
@@ -238,7 +249,7 @@ feature {NONE} -- Implementation
else else
a_buffer.append_character (delimiter_char) a_buffer.append_character (delimiter_char)
end end
if l_use_default and (operator = Form_style_query_operator) and not vi.has_explode_star then if l_use_default and (operator = Form_style_query_operator or operator = form_style_query_continuation or operator = path_style_parameters_operator) and not vi.has_explode_star then
a_buffer.append (vi.name) a_buffer.append (vi.name)
if vi.has_explode_plus then if vi.has_explode_plus then
a_buffer.append_character ('.') a_buffer.append_character ('.')
@@ -262,7 +273,7 @@ feature -- Status report
end end
;note ;note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software
@@ -45,12 +45,19 @@ feature {NONE} -- Initialization
when Form_style_query_operator then --| '?' when Form_style_query_operator then --| '?'
op_prefix := '?' op_prefix := '?'
op_separator := '&' op_separator := '&'
when form_style_query_continuation then --| '&'
op_prefix := '&'
op_separator := '&'
when Path_style_parameters_operator then --| ';' when Path_style_parameters_operator then --| ';'
op_prefix := ';' op_prefix := ';'
op_separator := ';' op_separator := ';'
when Path_segment_operator then --| '/' when Path_segment_operator then --| '/'
op_prefix := '/' op_prefix := '/'
op_separator := '/' op_separator := '/'
when fragment_expansion then --| '#'
reserved := True
op_prefix := '#'
op_separator := ','
when Label_operator then --| '.' when Label_operator then --| '.'
op_prefix := '.' op_prefix := '.'
op_separator := '.' op_separator := '.'
@@ -169,7 +176,7 @@ feature -- Report
create Result.make (20) create Result.make (20)
if attached {READABLE_STRING_GENERAL} d as l_string then if attached {READABLE_STRING_GENERAL} d as l_string then
v_enc := url_encoded_string (modified_string (l_string), not reserved) v_enc := url_encoded_string (modified_string (l_string), not reserved)
if op = Form_style_query_operator then if op = Form_style_query_operator or op = form_style_query_continuation then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
elseif op = Path_style_parameters_operator then elseif op = Path_style_parameters_operator then
@@ -183,7 +190,7 @@ feature -- Report
if l_array.is_empty then if l_array.is_empty then
if dft /= Void then if dft /= Void then
inspect op inspect op
when Form_style_query_operator, Path_style_parameters_operator then when Path_style_parameters_operator,Form_style_query_operator, form_style_query_continuation then
if not l_has_explode then if not l_has_explode then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
@@ -195,6 +202,16 @@ feature -- Report
end end
Result.append (dft.out) Result.append (dft.out)
end end
-- if not explode_is_plus then
-- Result.append (name)
-- Result.append_character ('=')
-- Result.append (dft.out)
-- else
-- Result.append (name)
-- Result.append_character ('.')
-- Result.append (dft.out)
-- end
when Path_segment_operator then when Path_segment_operator then
if explode_is_plus then if explode_is_plus then
Result.append (name) Result.append (name)
@@ -220,7 +237,7 @@ feature -- Report
else else
l_delimiter := ',' l_delimiter := ','
inspect op inspect op
when Form_style_query_operator then when Form_style_query_operator, form_style_query_continuation, path_style_parameters_operator then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
else else
@@ -242,6 +259,7 @@ feature -- Report
if explode_is_plus then if explode_is_plus then
if if
(op = Form_style_query_operator and explode_is_plus) or (op = Form_style_query_operator and explode_is_plus) or
(op = form_style_query_continuation and explode_is_plus) or
(op = Path_style_parameters_operator and l_has_explode) (op = Path_style_parameters_operator and l_has_explode)
then then
Result.append (name) Result.append (name)
@@ -250,7 +268,7 @@ feature -- Report
Result.append (name) Result.append (name)
Result.append_character ('.') Result.append_character ('.')
end end
elseif explode_is_star and op = Form_style_query_operator then elseif explode_is_star and (op = Form_style_query_operator or op = form_style_query_continuation or op = path_style_parameters_operator) then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
end end
@@ -269,7 +287,7 @@ feature -- Report
if l_table.is_empty then if l_table.is_empty then
if dft /= Void then if dft /= Void then
inspect op inspect op
when Form_style_query_operator, Path_style_parameters_operator then when Path_style_parameters_operator, Form_style_query_operator, form_style_query_continuation then
if not l_has_explode then if not l_has_explode then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
@@ -281,6 +299,15 @@ feature -- Report
end end
Result.append (dft.out) Result.append (dft.out)
end end
-- if not explode_is_plus then
-- Result.append (name)
-- Result.append_character ('=')
-- Result.append (dft.out)
-- else
-- Result.append (name)
-- Result.append_character ('.')
-- Result.append (dft.out)
-- end
when Path_segment_operator then when Path_segment_operator then
if explode_is_plus then if explode_is_plus then
Result.append (name) Result.append (name)
@@ -306,7 +333,7 @@ feature -- Report
else else
l_delimiter := ',' l_delimiter := ','
inspect op inspect op
when Form_style_query_operator then when Form_style_query_operator, form_style_query_continuation, path_style_parameters_operator then
Result.append (name) Result.append (name)
Result.append_character ('=') Result.append_character ('=')
else else
@@ -358,7 +385,7 @@ feature -- Report
else else
v_enc := default_value v_enc := default_value
end end
if op = Form_style_query_operator then if op = Form_style_query_operator or op = form_style_query_continuation then
Result.append (name) Result.append (name)
if v_enc /= Void then if v_enc /= Void then
Result.append_character ('=') Result.append_character ('=')
@@ -400,7 +427,7 @@ feature {NONE} -- Implementation
end end
;note ;note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2012, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software
@@ -57,26 +57,37 @@ feature -- Query
feature -- Query: url-decoded feature -- Query: url-decoded
url_decoded_query_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 encoded_name (n: READABLE_STRING_GENERAL): READABLE_STRING_8
-- URL encoded name `n'
-- to be used with ..._variable functions
do
if attached {READABLE_STRING_32} n as n32 then
Result := url_encoded_string (n32)
else
Result := n.as_string_8
end
end
url_decoded_query_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached query_variable (n) as v then if attached query_variable (encoded_name (n)) as v then
Result := url_decoded_string (v) Result := url_decoded_string (v)
end end
end end
url_decoded_path_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 url_decoded_path_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached path_variable (n) as v then if attached path_variable (encoded_name (n)) as v then
Result := url_decoded_string (v) Result := url_decoded_string (v)
end end
end end
url_decoded_variable (n: READABLE_STRING_8): detachable READABLE_STRING_32 url_decoded_variable (n: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- Unencoded value related to variable name `n' -- Unencoded value related to variable name `n'
do do
if attached variable (n) as v then if attached variable (encoded_name (n)) as v then
Result := url_decoded_string (v) Result := url_decoded_string (v)
end end
end end
@@ -85,7 +96,12 @@ feature {NONE} -- Implementation
url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32 url_decoded_string (s: READABLE_STRING_8): READABLE_STRING_32
do do
Result := url_encoder.decoded_string (s.as_string_8) Result := url_encoder.decoded_string (s)
end
url_encoded_string (s: READABLE_STRING_32): READABLE_STRING_8
do
Result := url_encoder.encoded_string (s)
end end
url_encoder: URL_ENCODER url_encoder: URL_ENCODER
File diff suppressed because it is too large Load Diff
@@ -8,53 +8,16 @@ note
testing: "type/manual" testing: "type/manual"
class class
TEST_URI_TEMPLATE_DRAFT_05 TEST_URI_TEMPLATE_DRAFT
inherit inherit
EQA_TEST_SET TEST_URI_TEMPLATE
feature -- Test routines feature -- Expander
test_uri_template_parser
note
testing: "uri-template-05"
do
uri_template_parse ("api/foo/{foo_id}/{?id,extra}", <<"foo_id">>, <<"id", "extra">>)
uri_template_parse ("weather/{state}/{city}?forecast={day}", <<"state", "city">>, <<"day">>)
end
test_uri_template_matcher
note
testing: "uri-template-05"
local
tpl: URI_TEMPLATE
do
create tpl.make ("{version}/{id}")
uri_template_match (tpl, "v2/123", <<["version", "v2"], ["id" , "123"]>>, <<>>)
create tpl.make ("api/{foo}{bar}/id/{id}")
uri_template_mismatch (tpl, "api/foobar/id/123")
create tpl.make ("api/foo/{foo_id}/{?id,extra}")
uri_template_match (tpl, "api/foo/bar/", <<["foo_id", "bar"]>>, <<>>)
uri_template_match (tpl, "api/foo/bar/?id=123", <<["foo_id", "bar"]>>, <<["id", "123"]>>)
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test&one=more", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
uri_template_mismatch (tpl, "")
uri_template_mismatch (tpl, "/")
uri_template_mismatch (tpl, "foo/bar/?id=123")
uri_template_mismatch (tpl, "/api/foo/bar/")
uri_template_mismatch (tpl, "api/foo/bar")
create tpl.make ("weather/{state}/{city}?forecast={day}")
uri_template_match (tpl, "weather/California/Goleta?forecast=today", <<["state", "California"], ["city", "Goleta"]>>, <<["day", "today"]>>)
end
uri_template_string_errors: detachable LIST [STRING]
test_uri_template_string_builder test_uri_template_string_builder
note note
testing: "uri-template-05" testing: "uri-template"
local local
ht: HASH_TABLE [detachable ANY, STRING] ht: HASH_TABLE [detachable ANY, STRING]
empty_keys: HASH_TABLE [STRING, STRING] empty_keys: HASH_TABLE [STRING, STRING]
@@ -115,34 +78,34 @@ feature -- Test routines
--| Simple string expansion --| Simple string expansion
uri_template_string (ht, "{var}", "value") uri_template_string (ht, "{var}", "value")
uri_template_string (ht, "{hello}", "Hello+World%%21") uri_template_string (ht, "{hello}", "Hello%%20World%%21")
uri_template_string (ht, "O{empty}X", "OX") uri_template_string (ht, "O{empty}X", "OX")
uri_template_string (ht, "O{undef}X", "OX") uri_template_string (ht, "O{undef}X", "OX")
--| String expansion with defaults --| String expansion with defaults
uri_template_string (ht, "{var|default}", "value") uri_template_string (ht, "{var=default}", "value")
uri_template_string (ht, "O{empty|default}X", "OX") uri_template_string (ht, "O{empty=default}X", "OX")
uri_template_string (ht, "O{undef|default}X", "OdefaultX") uri_template_string (ht, "O{undef=default}X", "OdefaultX")
--| Reserved expansion with defaults --| Reserved expansion with defaults
uri_template_string (ht, "{+var}", "value") uri_template_string (ht, "{+var}", "value")
uri_template_string (ht, "{+hello}", "Hello+World!") uri_template_string (ht, "{+hello}", "Hello%%20World!")
uri_template_string (ht, "{+path}/here", "/foo/bar/here") uri_template_string (ht, "{+path}/here", "/foo/bar/here")
uri_template_string (ht, "here?ref={+path}", "here?ref=/foo/bar") uri_template_string (ht, "here?ref={+path}", "here?ref=/foo/bar")
uri_template_string (ht, "up{+path}{x}/here", "up/foo/bar1024/here") uri_template_string (ht, "up{+path}{x}/here", "up/foo/bar1024/here")
uri_template_string (ht, "up{+empty|/1}/here", "up/here") uri_template_string (ht, "up{+empty=/1}/here", "up/here")
uri_template_string (ht, "up{+undef|/1}/here", "up/1/here") uri_template_string (ht, "up{+undef=/1}/here", "up/1/here")
--| String expansion with multiple variables --| String expansion with multiple variables
uri_template_string (ht, "{x,y}", "1024,768") uri_template_string (ht, "{x,y}", "1024,768")
uri_template_string (ht, "{x,hello,y}", "1024,Hello+World%%21,768") uri_template_string (ht, "{x,hello,y}", "1024,Hello%%20World%%21,768")
uri_template_string (ht, "?{x,empty}", "?1024,") uri_template_string (ht, "?{x,empty}", "?1024,")
uri_template_string (ht, "?{x,undef}", "?1024") uri_template_string (ht, "?{x,undef}", "?1024")
uri_template_string (ht, "?{undef,y}", "?768") uri_template_string (ht, "?{undef,y}", "?768")
uri_template_string (ht, "?{x,undef|0}", "?1024,0") uri_template_string (ht, "?{x,undef=0}", "?1024,0")
--| Reserved expansion with multiple variables --| Reserved expansion with multiple variables
uri_template_string (ht, "{+x,hello,y}", "1024,Hello+World!,768") uri_template_string (ht, "{+x,hello,y}", "1024,Hello%%20World!,768")
uri_template_string (ht, "{+path,x}/here", "/foo/bar,1024/here") uri_template_string (ht, "{+path,x}/here", "/foo/bar,1024/here")
--| Label expansion, dot-prefixed --| Label expansion, dot-prefixed
uri_template_string (ht, "X{.var}", "X.value") uri_template_string (ht, "X{.var}", "X.value")
@@ -200,9 +163,9 @@ feature -- Test routines
--| Path-style parameters, semicolon-prefixed --| Path-style parameters, semicolon-prefixed
uri_template_string (ht, "{;hello:5}", ";hello=Hello") uri_template_string (ht, "{;hello:5}", ";hello=Hello")
uri_template_string (ht, "{;list}", ";red,green,blue") uri_template_string (ht, "{;list}", ";list=red,green,blue")
uri_template_string (ht, "{;list*}", ";red;green;blue") uri_template_string (ht, "{;list*}", ";list=red;list=green;list=blue")
uri_template_string (ht, "{;keys}", ";semi,%%3B,dot,.,comma,%%2C") uri_template_string (ht, "{;keys}", ";keys=semi,%%3B,dot,.,comma,%%2C")
uri_template_string (ht, "{;keys*}", ";semi=%%3B;dot=.;comma=%%2C") uri_template_string (ht, "{;keys*}", ";semi=%%3B;dot=.;comma=%%2C")
--| Form-style query, ampersand-separated --| Form-style query, ampersand-separated
@@ -218,7 +181,7 @@ feature -- Test routines
test_uri_template_string_builder_extra test_uri_template_string_builder_extra
note note
testing: "uri-template-05" testing: "uri-template"
local local
ht: HASH_TABLE [detachable ANY, STRING] ht: HASH_TABLE [detachable ANY, STRING]
empty_keys: HASH_TABLE [STRING, STRING] empty_keys: HASH_TABLE [STRING, STRING]
@@ -278,162 +241,162 @@ feature -- Test routines
--| Addition to the spec --| Addition to the spec
uri_template_string (ht, "api/foo/{foo_id}/{?id,extra}", uri_template_string (ht, "api/foo/{foo_id}/{?id,extra}",
"api/foo/FooBar/?id=123&extra=That%%27s+right%%21") "api/foo/FooBar/?id=123&extra=That%%27s%%20right%%21")
uri_template_string (ht, "api/foo/{foo_id}/{?id,empty,undef,extra}", uri_template_string (ht, "api/foo/{foo_id}/{?id,empty,undef,extra}",
"api/foo/FooBar/?id=123&empty=&extra=That%%27s+right%%21") "api/foo/FooBar/?id=123&empty=&extra=That%%27s%%20right%%21")
uri_template_string (ht, "weather/{state}/{city}?forecast={day}", uri_template_string (ht, "weather/{state}/{city}?forecast={day}",
"weather/California/Goleta?forecast=today") "weather/California/Goleta?forecast=today")
uri_template_string (ht, "{var|default}", "value") uri_template_string (ht, "{var=default}", "value")
uri_template_string (ht, "{undef|default}", "default") uri_template_string (ht, "{undef=default}", "default")
uri_template_string (ht, "{undef:3|default}", "default") uri_template_string (ht, "{undef:3=default}", "default")
uri_template_string (ht, "x{empty}y", "xy") uri_template_string (ht, "x{empty}y", "xy")
uri_template_string (ht, "x{empty|_}y", "xy") uri_template_string (ht, "x{empty=_}y", "xy")
uri_template_string (ht, "x{undef}y", "xy") uri_template_string (ht, "x{undef}y", "xy")
uri_template_string (ht, "x{undef|_}y", "x_y") uri_template_string (ht, "x{undef=_}y", "x_y")
uri_template_string (ht, "x{.name|none}", "x.Fred,Wilma,Pebbles") uri_template_string (ht, "x{.name=none}", "x.Fred,Wilma,Pebbles")
uri_template_string (ht, "x{.name*|none}", "x.Fred.Wilma.Pebbles") uri_template_string (ht, "x{.name*=none}", "x.Fred.Wilma.Pebbles")
uri_template_string (ht, "x{.empty}", "x.") uri_template_string (ht, "x{.empty}", "x.")
uri_template_string (ht, "x{.empty|none}", "x.") uri_template_string (ht, "x{.empty=none}", "x.")
uri_template_string (ht, "x{.undef}", "x") uri_template_string (ht, "x{.undef}", "x")
uri_template_string (ht, "x{.undef|none}", "x.none") uri_template_string (ht, "x{.undef=none}", "x.none")
uri_template_string (ht, "x{/name|none}", "x/Fred,Wilma,Pebbles") uri_template_string (ht, "x{/name=none}", "x/Fred,Wilma,Pebbles")
uri_template_string (ht, "x{/name*|none}", "x/Fred/Wilma/Pebbles") uri_template_string (ht, "x{/name*=none}", "x/Fred/Wilma/Pebbles")
uri_template_string (ht, "x{/undef}", "x") uri_template_string (ht, "x{/undef}", "x")
uri_template_string (ht, "x{/undef|none}", "x/none") uri_template_string (ht, "x{/undef=none}", "x/none")
uri_template_string (ht, "x{/empty}", "x/") uri_template_string (ht, "x{/empty}", "x/")
uri_template_string (ht, "x{/empty|none}", "x/") uri_template_string (ht, "x{/empty=none}", "x/")
uri_template_string (ht, "x{/empty_keys}", "x") uri_template_string (ht, "x{/empty_keys}", "x")
uri_template_string (ht, "x{/empty_keys|none}", "x/none") uri_template_string (ht, "x{/empty_keys=none}", "x/none")
uri_template_string (ht, "x{/empty_keys*}", "x") uri_template_string (ht, "x{/empty_keys*}", "x")
uri_template_string (ht, "x{/empty_keys*|none}", "x/none") uri_template_string (ht, "x{/empty_keys*=none}", "x/none")
uri_template_string (ht, "x{;name|none}", "x;name=Fred,Wilma,Pebbles") uri_template_string (ht, "x{;name=none}", "x;name=Fred,Wilma,Pebbles")
uri_template_string (ht, "x{;favs|none}", "x;favs=color,red,volume,high") uri_template_string (ht, "x{;favs=none}", "x;favs=color,red,volume,high")
uri_template_string (ht, "x{;favs*|none}", "x;color=red;volume=high") uri_template_string (ht, "x{;favs*=none}", "x;color=red;volume=high")
uri_template_string (ht, "x{;empty}", "x;empty") uri_template_string (ht, "x{;empty}", "x;empty")
uri_template_string (ht, "x{;empty|none}", "x;empty") uri_template_string (ht, "x{;empty=none}", "x;empty")
uri_template_string (ht, "x{;undef}", "x") uri_template_string (ht, "x{;undef}", "x")
uri_template_string (ht, "x{;undef|none}", "x;none") uri_template_string (ht, "x{;undef=none}", "x;none")
uri_template_string (ht, "x{;undef|foo=y}", "x;foo=y") uri_template_string (ht, "x{;undef=foo=y}", "x;foo=y")
uri_template_string (ht, "x{?var|none}", "x?var=value") uri_template_string (ht, "x{?var=none}", "x?var=value")
uri_template_string (ht, "x{?favs|none}", "x?favs=color,red,volume,high") uri_template_string (ht, "x{?favs=none}", "x?favs=color,red,volume,high")
uri_template_string (ht, "x{?favs*|none}", "x?color=red&volume=high") uri_template_string (ht, "x{?favs*=none}", "x?color=red&volume=high")
uri_template_string (ht, "x{?empty}", "x?empty=") uri_template_string (ht, "x{?empty}", "x?empty=")
uri_template_string (ht, "x{?empty|foo=none}", "x?empty=") uri_template_string (ht, "x{?empty=foo=none}", "x?empty=")
uri_template_string (ht, "x{?undef}", "x") uri_template_string (ht, "x{?undef}", "x")
uri_template_string (ht, "x{?undef|foo=none}", "x?foo=none") uri_template_string (ht, "x{?undef=foo=none}", "x?foo=none")
uri_template_string (ht, "x{?empty_keys}", "x") uri_template_string (ht, "x{?empty_keys}", "x")
uri_template_string (ht, "x{?empty_keys|none}", "x?none") uri_template_string (ht, "x{?empty_keys=none}", "x?none")
uri_template_string (ht, "x{?empty_keys|y=z}", "x?y=z") uri_template_string (ht, "x{?empty_keys=y=z}", "x?y=z")
uri_template_string (ht, "x{?empty_keys*|y=z}", "x?y=z") uri_template_string (ht, "x{?empty_keys*=y=z}", "x?y=z")
------ ------
uri_template_string (ht, "x{empty_list}y", "xy") uri_template_string (ht, "x{empty_list}y", "xy")
uri_template_string (ht, "x{empty_list|_}y", "xy") uri_template_string (ht, "x{empty_list=_}y", "xy")
uri_template_string (ht, "x{empty_list*}y", "xy") uri_template_string (ht, "x{empty_list*}y", "xy")
uri_template_string (ht, "x{empty_list*|_}y", "x_y") uri_template_string (ht, "x{empty_list*=_}y", "x_y")
uri_template_string (ht, "x{empty_list+}y", "xy") uri_template_string (ht, "x{empty_list+}y", "xy")
uri_template_string (ht, "x{empty_list+|_}y", "xempty_list._y") uri_template_string (ht, "x{empty_list+=_}y", "xempty_list._y")
uri_template_string (ht, "x{empty_keys}y", "xy") uri_template_string (ht, "x{empty_keys}y", "xy")
uri_template_string (ht, "x{empty_keys|_}y", "xy") uri_template_string (ht, "x{empty_keys=_}y", "xy")
uri_template_string (ht, "x{empty_keys*}y", "xy") uri_template_string (ht, "x{empty_keys*}y", "xy")
uri_template_string (ht, "x{empty_keys*|_}y", "x_y") uri_template_string (ht, "x{empty_keys*=_}y", "x_y")
uri_template_string (ht, "x{empty_keys+}y", "xy") uri_template_string (ht, "x{empty_keys+}y", "xy")
uri_template_string (ht, "x{empty_keys+|_}y", "xempty_keys._y") uri_template_string (ht, "x{empty_keys+=_}y", "xempty_keys._y")
uri_template_string (ht, "x{?name|none}", "x?name=Fred,Wilma,Pebbles") uri_template_string (ht, "x{?name=none}", "x?name=Fred,Wilma,Pebbles")
uri_template_string (ht, "x{?favs|none}", "x?favs=color,red,volume,high") uri_template_string (ht, "x{?favs=none}", "x?favs=color,red,volume,high")
uri_template_string (ht, "x{?favs*|none}", "x?color=red&volume=high") uri_template_string (ht, "x{?favs*=none}", "x?color=red&volume=high")
uri_template_string (ht, "x{?favs+|none}", "x?favs.color=red&favs.volume=high") uri_template_string (ht, "x{?favs+=none}", "x?favs.color=red&favs.volume=high")
uri_template_string (ht, "x{?undef}", "x") uri_template_string (ht, "x{?undef}", "x")
uri_template_string (ht, "x{?undef|none}", "x?undef=none") uri_template_string (ht, "x{?undef=none}", "x?undef=none")
uri_template_string (ht, "x{?empty}", "x?empty=") uri_template_string (ht, "x{?empty}", "x?empty=")
uri_template_string (ht, "x{?empty|none}", "x?empty=") uri_template_string (ht, "x{?empty=none}", "x?empty=")
uri_template_string (ht, "x{?empty_list}", "x") uri_template_string (ht, "x{?empty_list}", "x")
uri_template_string (ht, "x{?empty_list|none}", "x?empty_list=none") uri_template_string (ht, "x{?empty_list=none}", "x?empty_list=none")
uri_template_string (ht, "x{?empty_list*}", "x") uri_template_string (ht, "x{?empty_list*}", "x")
uri_template_string (ht, "x{?empty_list*|none}", "x?none") uri_template_string (ht, "x{?empty_list*=none}", "x?none")
uri_template_string (ht, "x{?empty_list+}", "x") uri_template_string (ht, "x{?empty_list+}", "x")
uri_template_string (ht, "x{?empty_list+|none}", "x?empty_list.none") uri_template_string (ht, "x{?empty_list+=none}", "x?empty_list.none")
uri_template_string (ht, "x{?empty_keys}", "x") uri_template_string (ht, "x{?empty_keys}", "x")
uri_template_string (ht, "x{?empty_keys|none}", "x?empty_keys=none") uri_template_string (ht, "x{?empty_keys=none}", "x?empty_keys=none")
uri_template_string (ht, "x{?empty_keys*}", "x") uri_template_string (ht, "x{?empty_keys*}", "x")
uri_template_string (ht, "x{?empty_keys*|none}", "x?none") uri_template_string (ht, "x{?empty_keys*=none}", "x?none")
uri_template_string (ht, "x{?empty_keys+}", "x") uri_template_string (ht, "x{?empty_keys+}", "x")
uri_template_string (ht, "x{?empty_keys+|none}", "x?empty_keys.none") uri_template_string (ht, "x{?empty_keys+=none}", "x?empty_keys.none")
uri_template_string (ht, "x{;name|none}", "x;name=Fred,Wilma,Pebbles") uri_template_string (ht, "x{;name=none}", "x;name=Fred,Wilma,Pebbles")
uri_template_string (ht, "x{;favs|none}", "x;favs=color,red,volume,high") uri_template_string (ht, "x{;favs=none}", "x;favs=color,red,volume,high")
uri_template_string (ht, "x{;favs*|none}", "x;color=red;volume=high") uri_template_string (ht, "x{;favs*=none}", "x;color=red;volume=high")
uri_template_string (ht, "x{;favs+|none}", "x;favs.color=red;favs.volume=high") uri_template_string (ht, "x{;favs+=none}", "x;favs.color=red;favs.volume=high")
uri_template_string (ht, "x{;undef}", "x") uri_template_string (ht, "x{;undef}", "x")
uri_template_string (ht, "x{;undef|none}", "x;undef=none") uri_template_string (ht, "x{;undef=none}", "x;undef=none")
uri_template_string (ht, "x{;undef|none}", "x;none") uri_template_string (ht, "x{;undef=none}", "x;none")
uri_template_string (ht, "x{;empty}", "x;empty") uri_template_string (ht, "x{;empty}", "x;empty")
uri_template_string (ht, "x{;empty|none}", "x;empty") uri_template_string (ht, "x{;empty=none}", "x;empty")
uri_template_string (ht, "x{;empty_list}", "x") uri_template_string (ht, "x{;empty_list}", "x")
uri_template_string (ht, "x{;empty_list|none}", "x;empty_list=none") uri_template_string (ht, "x{;empty_list=none}", "x;empty_list=none")
uri_template_string (ht, "x{;empty_list*}", "x") uri_template_string (ht, "x{;empty_list*}", "x")
uri_template_string (ht, "x{;empty_list*|none}", "x;none") uri_template_string (ht, "x{;empty_list*=none}", "x;none")
uri_template_string (ht, "x{;empty_list+}", "x") uri_template_string (ht, "x{;empty_list+}", "x")
uri_template_string (ht, "x{;empty_list+|none}", "x;empty_list.none") uri_template_string (ht, "x{;empty_list+=none}", "x;empty_list.none")
uri_template_string (ht, "x{;empty_keys}", "x") uri_template_string (ht, "x{;empty_keys}", "x")
uri_template_string (ht, "x{;empty_keys|none}", "x;empty_keys=none") uri_template_string (ht, "x{;empty_keys=none}", "x;empty_keys=none")
uri_template_string (ht, "x{;empty_keys*}", "x") uri_template_string (ht, "x{;empty_keys*}", "x")
uri_template_string (ht, "x{;empty_keys*|none}", "x;none") uri_template_string (ht, "x{;empty_keys*=none}", "x;none")
uri_template_string (ht, "x{;empty_keys+}", "x") uri_template_string (ht, "x{;empty_keys+}", "x")
uri_template_string (ht, "x{;empty_keys+|none}", "x;empty_keys.none") uri_template_string (ht, "x{;empty_keys+=none}", "x;empty_keys.none")
uri_template_string (ht, "x{/name|none}", "x/Fred,Wilma,Pebbles") uri_template_string (ht, "x{/name=none}", "x/Fred,Wilma,Pebbles")
uri_template_string (ht, "x{/name*|none}", "x/Fred/Wilma/Pebbles") uri_template_string (ht, "x{/name*=none}", "x/Fred/Wilma/Pebbles")
uri_template_string (ht, "x{/name+|none}", "x/name.Fred/name.Wilma/name.Pebbles") uri_template_string (ht, "x{/name+=none}", "x/name.Fred/name.Wilma/name.Pebbles")
uri_template_string (ht, "x{/favs|none}", "x/color,red,volume,high") uri_template_string (ht, "x{/favs=none}", "x/color,red,volume,high")
uri_template_string (ht, "x{/favs*|none}", "x/color/red/volume/high") uri_template_string (ht, "x{/favs*=none}", "x/color/red/volume/high")
uri_template_string (ht, "x{/favs+|none}", "x/favs.color/red/favs.volume/high") uri_template_string (ht, "x{/favs+=none}", "x/favs.color/red/favs.volume/high")
uri_template_string (ht, "x{/undef}", "x") uri_template_string (ht, "x{/undef}", "x")
uri_template_string (ht, "x{/undef|none}", "x/none") uri_template_string (ht, "x{/undef=none}", "x/none")
uri_template_string (ht, "x{/empty}", "x/") uri_template_string (ht, "x{/empty}", "x/")
uri_template_string (ht, "x{/empty|none}", "x/") uri_template_string (ht, "x{/empty=none}", "x/")
uri_template_string (ht, "x{/empty_list}", "x") uri_template_string (ht, "x{/empty_list}", "x")
uri_template_string (ht, "x{/empty_list|none}", "x/none") uri_template_string (ht, "x{/empty_list=none}", "x/none")
uri_template_string (ht, "x{/empty_list*}", "x") uri_template_string (ht, "x{/empty_list*}", "x")
uri_template_string (ht, "x{/empty_list*|none}", "x/none") uri_template_string (ht, "x{/empty_list*=none}", "x/none")
uri_template_string (ht, "x{/empty_list+}", "x") uri_template_string (ht, "x{/empty_list+}", "x")
uri_template_string (ht, "x{/empty_list+|none}", "x/empty_list.none") uri_template_string (ht, "x{/empty_list+=none}", "x/empty_list.none")
uri_template_string (ht, "x{/empty_keys}", "x") uri_template_string (ht, "x{/empty_keys}", "x")
uri_template_string (ht, "x{/empty_keys|none}", "x/none") uri_template_string (ht, "x{/empty_keys=none}", "x/none")
uri_template_string (ht, "x{/empty_keys*}", "x") uri_template_string (ht, "x{/empty_keys*}", "x")
uri_template_string (ht, "x{/empty_keys*|none}", "x/none") uri_template_string (ht, "x{/empty_keys*=none}", "x/none")
uri_template_string (ht, "x{/empty_keys+}", "x") uri_template_string (ht, "x{/empty_keys+}", "x")
uri_template_string (ht, "x{/empty_keys+|none}", "x/empty_keys.none") uri_template_string (ht, "x{/empty_keys+=none}", "x/empty_keys.none")
--| Simple expansion with comma-separated values --| Simple expansion with comma-separated values
uri_template_string (ht, "{var}", "value") uri_template_string (ht, "{var}", "value")
uri_template_string (ht, "{hello}", "Hello+World%%21") uri_template_string (ht, "{hello}", "Hello%%20World%%21")
uri_template_string (ht, "{path}/here", "%%2Ffoo%%2Fbar/here") uri_template_string (ht, "{path}/here", "%%2Ffoo%%2Fbar/here")
uri_template_string (ht, "{x,y}", "1024,768") uri_template_string (ht, "{x,y}", "1024,768")
uri_template_string (ht, "{var|default}", "value") uri_template_string (ht, "{var=default}", "value")
uri_template_string (ht, "{undef|default}", "default") uri_template_string (ht, "{undef=default}", "default")
uri_template_string (ht, "{list}", "val1,val2,val3") uri_template_string (ht, "{list}", "val1,val2,val3")
uri_template_string (ht, "{list*}", "val1,val2,val3") uri_template_string (ht, "{list*}", "val1,val2,val3")
uri_template_string (ht, "{list+}", "list.val1,list.val2,list.val3") uri_template_string (ht, "{list+}", "list.val1,list.val2,list.val3")
@@ -443,7 +406,7 @@ feature -- Test routines
--| Reserved expansion with comma-separated values --| Reserved expansion with comma-separated values
uri_template_string (ht, "{+var}", "value") uri_template_string (ht, "{+var}", "value")
uri_template_string (ht, "{+hello}", "Hello+World!") uri_template_string (ht, "{+hello}", "Hello%%20World!")
uri_template_string (ht, "{+path}/here", "/foo/bar/here") uri_template_string (ht, "{+path}/here", "/foo/bar/here")
uri_template_string (ht, "{+path,x}/here", "/foo/bar,1024/here") uri_template_string (ht, "{+path,x}/here", "/foo/bar,1024/here")
uri_template_string (ht, "{+path}{x}/here", "/foo/bar1024/here") uri_template_string (ht, "{+path}{x}/here", "/foo/bar1024/here")
@@ -463,16 +426,16 @@ feature -- Test routines
uri_template_string (ht, "{;list}", ";list=val1,val2,val3") -- DIFF uri_template_string (ht, "{;list}", ";list=val1,val2,val3") -- DIFF
uri_template_string (ht, "{;list*}", ";val1;val2;val3") uri_template_string (ht, "{;list*}", ";val1;val2;val3")
uri_template_string (ht, "{;list+}", ";list=val1;list=val2;list=val3") uri_template_string (ht, "{;list+}", ";list=val1;list=val2;list=val3")
uri_template_string (ht, "{;keys}", ";key1,val1,key2,val2") uri_template_string (ht, "{;keys}", ";keys=key1,val1,key2,val2")
uri_template_string (ht, "{;keys*}", ";key1=val1;key2=val2") uri_template_string (ht, "{;keys*}", ";key1=val1;key2=val2")
uri_template_string (ht, "{;keys+}", ";keys.key1=val1;keys.key2=val2") uri_template_string (ht, "{;keys+}", ";key1=val1;key2=val2")
--| Form-style parameters, ampersand-separated --| Form-style parameters, ampersand-separated
uri_template_string (ht, "{?x,y}", "?x=1024&y=768") uri_template_string (ht, "{?x,y}", "?x=1024&y=768")
uri_template_string (ht, "{?x,y,empty}", "?x=1024&y=768&empty=") uri_template_string (ht, "{?x,y,empty}", "?x=1024&y=768&empty=")
uri_template_string (ht, "{?x,y,undef}", "?x=1024&y=768") uri_template_string (ht, "{?x,y,undef}", "?x=1024&y=768")
uri_template_string (ht, "{?list}", "?list=val1,val2,val3") uri_template_string (ht, "{?list}", "?list=val1,val2,val3")
uri_template_string (ht, "{?list*}", "?val1&val2&val3") uri_template_string (ht, "{?list*}", "?list=val1&list=val2&list=val3")
uri_template_string (ht, "{?list+}", "?list=val1&list=val2&list=val3") uri_template_string (ht, "{?list+}", "?list=val1&list=val2&list=val3")
uri_template_string (ht, "{?keys}", "?keys=key1,val1,key2,val2") uri_template_string (ht, "{?keys}", "?keys=key1,val1,key2,val2")
uri_template_string (ht, "{?keys*}", "?key1=val1&key2=val2") uri_template_string (ht, "{?keys*}", "?key1=val1&key2=val2")
@@ -487,8 +450,8 @@ feature -- Test routines
uri_template_string (ht, "{/list*,x}", "/val1/val2/val3/1024") uri_template_string (ht, "{/list*,x}", "/val1/val2/val3/1024")
uri_template_string (ht, "{/list+}", "/list.val1/list.val2/list.val3") uri_template_string (ht, "{/list+}", "/list.val1/list.val2/list.val3")
uri_template_string (ht, "{/keys}", "/key1,val1,key2,val2") uri_template_string (ht, "{/keys}", "/key1,val1,key2,val2")
uri_template_string (ht, "{/keys*}", "/key1/val1/key2/val2") uri_template_string (ht, "{/keys*}", "/key1=val1/key2=val2")
uri_template_string (ht, "{/keys+}", "/keys.key1/val1/keys.key2/val2") uri_template_string (ht, "{/keys+}", "/keys.key1=val1/keys.key2=val2")
--| Label expansion, dot-prefixed --| Label expansion, dot-prefixed
uri_template_string (ht, "X{.var}", "X.value") uri_template_string (ht, "X{.var}", "X.value")
@@ -506,123 +469,17 @@ feature -- Test routines
uri_template_string (ht, "{foo}", "fred") uri_template_string (ht, "{foo}", "fred")
uri_template_string (ht, "{foo,foo}", "fred,fred") uri_template_string (ht, "{foo,foo}", "fred,fred")
uri_template_string (ht, "{bar,foo}", "fred") uri_template_string (ht, "{bar,foo}", "fred")
uri_template_string (ht, "{bar|wilma}", "wilma") uri_template_string (ht, "{bar=wilma}", "wilma")
--| Reserved Expansion --| Reserved Expansion
uri_template_string (ht, "{foo2}", "That%%27s+right%%21") uri_template_string (ht, "{foo2}", "That%%27s%%20right%%21")
uri_template_string (ht, "{+foo2}", "That%%27s+right!") uri_template_string (ht, "{+foo2}", "That%%27s%%20right!")
uri_template_string (ht, "{base}index", "http%%3A%%2F%%2Fexample.com%%2Fhome%%2Findex") uri_template_string (ht, "{base}index", "http%%3A%%2F%%2Fexample.com%%2Fhome%%2Findex")
uri_template_string (ht, "{+base}index", "http://example.com/home/index") uri_template_string (ht, "{+base}index", "http://example.com/home/index")
assert ("all strings built", uri_template_string_errors = Void or (attached uri_template_string_errors as err and then err.is_empty)) assert ("all strings built", uri_template_string_errors = Void or (attached uri_template_string_errors as err and then err.is_empty))
end end
uri_template_string (a_ht: HASH_TABLE [detachable ANY, STRING]; a_expression: STRING; a_expected: STRING)
local
tpl: URI_TEMPLATE
s: STRING
m: STRING
do
create tpl.make (a_expression)
s := tpl.expanded_string (a_ht)
if not s.same_string (a_expected) then
m := "Expected string for %"" + a_expression + "%" expected=%""+ a_expected +"%" but got %"" + s + "%"%N"
if attached uri_template_string_errors as err then
print (m)
err.force (m)
else
assert (m, False)
end
end
end
uri_template_parse (s: STRING_8; path_vars: ARRAY [STRING]; query_vars: ARRAY [STRING])
local
u: URI_TEMPLATE
matched: BOOLEAN
i: INTEGER
do
create u.make (s)
if attached u.path_variable_names as vars then
matched := vars.count = path_vars.count
from
i := path_vars.lower
vars.start
until
not matched or i > path_vars.upper
loop
matched := vars.item.same_string (path_vars[i])
vars.forth
i := i + 1
end
else
matched := path_vars.is_empty
end
assert ("path variables matched", matched)
if attached u.query_variable_names as vars then
matched := vars.count = query_vars.count
from
i := query_vars.lower
vars.start
until
not matched or i > query_vars.upper
loop
matched := vars.item.same_string (query_vars[i])
vars.forth
i := i + 1
end
else
matched := query_vars.is_empty
end
assert ("query variables matched", matched)
end
uri_template_mismatch (a_uri_template: URI_TEMPLATE; a_uri: STRING)
local
l_match: detachable URI_TEMPLATE_MATCH_RESULT
do
l_match := a_uri_template.match (a_uri)
assert ("uri %"" + a_uri + "%" does not match template %"" + a_uri_template.template + "%"", l_match = Void)
end
uri_template_match (a_uri_template: URI_TEMPLATE; a_uri: STRING; path_res: ARRAY [TUPLE [name: STRING; value: STRING]]; query_res: ARRAY [TUPLE [name: STRING; value: STRING]])
local
b: BOOLEAN
i: INTEGER
l_match: detachable URI_TEMPLATE_MATCH_RESULT
do
l_match := a_uri_template.match (a_uri)
if l_match /= Void then
if attached l_match.path_variables as path_ht then
b := path_ht.count = path_res.count
from
i := path_res.lower
until
not b or i > path_res.upper
loop
b := attached path_ht.item (path_res[i].name) as s and then s.same_string (path_res[i].value)
i := i + 1
end
assert ("uri matched path variables", b)
end
if attached l_match.query_variables as query_ht then
b := query_ht.count >= query_res.count
from
i := query_res.lower
until
not b or i > query_res.upper
loop
b := attached query_ht.item (query_res[i].name) as s and then s.same_string (query_res[i].value)
i := i + 1
end
assert ("uri matched query variables", b)
end
else
assert ("uri matched", False)
end
end
note note
copyright: "2011-2011, Eiffel Software and others" copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
@@ -0,0 +1,142 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date$"
revision: "$Revision$"
testing: "type/manual"
class
TEST_URI_TEMPLATE_MATCHER
inherit
TEST_URI_TEMPLATE
feature -- Matcher
test_uri_template_matcher
note
testing: "uri-template"
local
tpl: URI_TEMPLATE
do
create tpl.make ("/hello.{format}{/vars}")
uri_template_match (tpl, "/hello.json/foo/bar", <<["format", "json"], ["vars", "/foo/bar"], ["vars[1]", "foo"], ["vars[2]", "bar"]>>, <<>>)
create tpl.make ("/hello.{format}{?op}")
uri_template_match (tpl, "/hello.json?op=foobar", <<["format", "json"]>>, << ["op", "foobar"]>>)
create tpl.make ("{version}/{id}")
uri_template_match (tpl, "v2/123", <<["version", "v2"], ["id" , "123"]>>, <<>>)
create tpl.make ("api/{foo}{bar}/id/{id}")
uri_template_mismatch (tpl, "api/foobar/id/123")
create tpl.make ("api/foo/{foo_id}/{?id,extra}")
uri_template_match (tpl, "api/foo/bar/", <<["foo_id", "bar"]>>, <<>>)
uri_template_match (tpl, "api/foo/bar/?id=123", <<["foo_id", "bar"]>>, <<["id", "123"]>>)
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
uri_template_match (tpl, "api/foo/bar/?id=123&extra=test&one=more", <<["foo_id", "bar"]>>, <<["id", "123"], ["extra", "test"]>>)
uri_template_mismatch (tpl, "")
uri_template_mismatch (tpl, "/")
uri_template_mismatch (tpl, "foo/bar/?id=123")
uri_template_mismatch (tpl, "/api/foo/bar/")
uri_template_mismatch (tpl, "api/foo/bar")
create tpl.make ("weather/{state}/{city}?forecast={day}")
uri_template_match (tpl, "weather/California/Goleta?forecast=today", <<["state", "California"], ["city", "Goleta"]>>, <<["day", "today"]>>)
create tpl.make ("/hello")
uri_template_match (tpl, "/hello", <<>>, <<>>)
uri_template_mismatch (tpl, "/hello/Foo2") -- longer
uri_template_mismatch (tpl, "/hell") -- shorter
create tpl.make ("/hello.{format}")
uri_template_match (tpl, "/hello.xml", <<["format", "xml"]>>, <<>>)
uri_template_mismatch (tpl, "/hello.xml/Bar")
create tpl.make ("/hello.{format}/{name}")
uri_template_match (tpl, "/hello.xml/Joce", <<["format", "xml"], ["name", "Joce"]>>, <<>>)
create tpl.make ("/hello/{name}.{format}")
uri_template_match (tpl, "/hello/Joce.json", <<["name", "Joce"], ["format", "json"]>>, <<>>)
create tpl.make ("/hello/{name}.{format}/foo")
uri_template_match (tpl, "/hello/Joce.xml/foo", <<["name", "Joce"], ["format", "xml"]>>, <<>>)
uri_template_mismatch (tpl, "/hello/Joce.xml/fooBAR")
create tpl.make ("/hello{/vars}")
uri_template_match (tpl, "/hello/foo/bar", <<["vars", "/foo/bar"], ["vars[1]", "foo"], ["vars[2]", "bar"]>>, <<>>)
-- create tpl.make ("/hello/{name}.{format}/foo{?foo};crazy={idea}")
---- uri_template_match (tpl, "/hello/Joce.xml/foo", <<["name", "Joce"], ["format", "xml"]>>, <<>>)
-- uri_template_match (tpl, "/hello/Joce.xml/foo?foo=FOO", <<["name", "Joce"], ["format", "xml"]>>, <<["foo", "FOO"]>>)
-- uri_template_match (tpl, "/hello/Joce.xml/foo;crazy=IDEA", <<["name", "Joce"], ["format", "xml"]>>, <<["idea", "IDEA"], ["crazy", "IDEA"]>>)
end
feature {NONE} -- Implementations
uri_template_mismatch (a_uri_template: URI_TEMPLATE; a_uri: STRING)
local
l_match: detachable URI_TEMPLATE_MATCH_RESULT
do
l_match := a_uri_template.match (a_uri)
assert ("uri %"" + a_uri + "%" does not match template %"" + a_uri_template.template + "%"", l_match = Void)
end
uri_template_match (a_uri_template: URI_TEMPLATE; a_uri: STRING; path_res: ARRAY [TUPLE [name: STRING; value: STRING]]; query_res: ARRAY [TUPLE [name: STRING; value: STRING]])
local
b: BOOLEAN
i: INTEGER
l_match: detachable URI_TEMPLATE_MATCH_RESULT
do
l_match := a_uri_template.match (a_uri)
if l_match /= Void then
if attached l_match.path_variables as path_ht then
b := path_ht.count = path_res.count
from
i := path_res.lower
until
not b or i > path_res.upper
loop
b := attached path_ht.item (path_res[i].name) as s and then s.same_string (path_res[i].value)
i := i + 1
end
assert ("uri %"" + a_uri + "%" matched path variables", b)
end
if attached l_match.query_variables as query_ht then
b := query_ht.count >= query_res.count
from
i := query_res.lower
until
not b or i > query_res.upper
loop
b := attached query_ht.item (query_res[i].name) as s and then s.same_string (query_res[i].value)
i := i + 1
end
assert ("uri %"" + a_uri + "%" matched query variables", b)
end
else
assert ("uri %"" + a_uri + "%" matched", False)
end
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
@@ -0,0 +1,87 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date$"
revision: "$Revision$"
testing: "type/manual"
class
TEST_URI_TEMPLATE_PARSER
inherit
TEST_URI_TEMPLATE
feature -- Parser
test_uri_template_parser
note
testing: "uri-template"
do
uri_template_parse ("api/foo/{foo_id}/{?id,extra}", <<"foo_id">>, <<"id", "extra">>)
uri_template_parse ("weather/{state}/{city}?forecast={day}", <<"state", "city">>, <<"day">>)
uri_template_parse ("/hello/{name}.{format}", <<"name", "format">>, <<>>)
uri_template_parse ("/hello.{format}/{name}", <<"format", "name">>, <<>>)
-- uri_template_parse ("/hello/{name}.{format}/foo{?foobar};crazy=IDEA", <<"name", "format">>, <<"foobar">>)
end
feature {NONE} -- Implementation
uri_template_parse (s: STRING_8; path_vars: ARRAY [STRING]; query_vars: ARRAY [STRING])
local
u: URI_TEMPLATE
matched: BOOLEAN
i: INTEGER
do
create u.make (s)
u.parse
assert ("Template %""+ s +"%" is valid", u.is_valid)
if attached u.path_variable_names as vars then
matched := vars.count = path_vars.count
from
i := path_vars.lower
vars.start
until
not matched or i > path_vars.upper
loop
matched := vars.item.same_string (path_vars[i])
vars.forth
i := i + 1
end
else
matched := path_vars.is_empty
end
assert ("path variables matched for %""+ s +"%"", matched)
if attached u.query_variable_names as vars then
matched := vars.count = query_vars.count
from
i := query_vars.lower
vars.start
until
not matched or i > query_vars.upper
loop
matched := vars.item.same_string (query_vars[i])
vars.forth
i := i + 1
end
else
matched := query_vars.is_empty
end
assert ("query variables matched %""+ s +"%"", matched)
end
note
copyright: "2011-2011, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-8-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-8-0 http://www.eiffel.com/developers/xml/configuration-1-8-0.xsd" name="test_uri_template_draft_05" uuid="6309455F-E0C7-4DCB-BF34-9C750EE4AC79" library_target="tests"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="test_uri_template_draft_05" uuid="C995E97E-BE7F-44BB-A38D-FE884CF837F5" library_target="tests">
<target name="tests"> <target name="tests">
<root class="ANY" feature="default_create"/> <root class="ANY" feature="default_create"/>
<file_rule> <file_rule>
@@ -7,32 +7,12 @@
<exclude>/EIFGENs$</exclude> <exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all"> <option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true"/> <assertions precondition="true"/>
</option> </option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/> <library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<library name="uri_template" location="../uri_template-safe.ecf"/> <library name="uri_template" location="..\uri_template-safe.ecf" readonly="false"/>
<tests name="tests" location="." recursive="false"/> <tests name="tests" location=".\"/>
</target>
<target name="tests_draft_05">
<root class="ANY" feature="default_create"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all">
<assertions precondition="true"/>
</option>
<variable name="uri_template" value="draft_05"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<library name="uri_template" location="../uri_template-safe.ecf"/>
<tests name="tests" location="." recursive="true">
<file_rule>
<exclude>/test_uri_template.e$</exclude>
</file_rule>
</tests>
</target> </target>
</system> </system>
@@ -13,21 +13,6 @@
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/> <library name="encoder" location="..\..\text\encoder\encoder-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<cluster name="src" location="src\" recursive="true"> <cluster name="src" location="src\" recursive="true"/>
<file_rule>
<exclude>/draft_05$</exclude>
</file_rule>
<file_rule>
<exclude>/uri_template_constants.e</exclude>
<condition>
<custom name="uri_template" value="draft_05"/>
</condition>
</file_rule>
</cluster>
<cluster name="draft_05" location=".\src\draft_05\">
<condition>
<custom name="uri_template" value="draft_05"/>
</condition>
</cluster>
</target> </target>
</system> </system>
+1 -16
View File
@@ -16,21 +16,6 @@
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="encoder" location="..\..\text\encoder\encoder.ecf"/> <library name="encoder" location="..\..\text\encoder\encoder.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<cluster name="src" location="src\" recursive="true"> <cluster name="src" location="src\" recursive="true"/>
<file_rule>
<exclude>/draft_05$</exclude>
</file_rule>
<file_rule>
<exclude>/uri_template_constants.e</exclude>
<condition>
<custom name="uri_template" value="draft_05"/>
</condition>
</file_rule>
</cluster>
<cluster name="draft_05" location=".\src\draft_05\">
<condition>
<custom name="uri_template" value="draft_05"/>
</condition>
</cluster>
</target> </target>
</system> </system>