spec/addressable/uri_spec.rb in honkster-addressable-2.1.2 vs spec/addressable/uri_spec.rb in honkster-addressable-2.2.3

- old
+ new

@@ -162,23 +162,34 @@ describe Addressable::URI, "when created from nil components" do before do @uri = Addressable::URI.new end + it "should have a nil site value" do + @uri.site.should == nil + end + it "should have an empty path" do @uri.path.should == "" end it "should be an empty uri" do @uri.to_s.should == "" end - it "should still be an empty uri if the scheme is set to whitespace" do - @uri.scheme = "\t \n" - @uri.to_s.should == "" + it "should raise an error if the scheme is set to whitespace" do + (lambda do + @uri.scheme = "\t \n" + end).should raise_error(Addressable::URI::InvalidURIError) end + it "should raise an error if the scheme is set to all digits" do + (lambda do + @uri.scheme = "123" + end).should raise_error(Addressable::URI::InvalidURIError) + end + it "should raise an error if set into an invalid state" do (lambda do @uri.user = "user" end).should raise_error(Addressable::URI::InvalidURIError) end @@ -209,10 +220,14 @@ @uri = Addressable::URI.new( :scheme => "http", :host => "example.com" ) end + it "should have a site value of 'http://example.com'" do + @uri.site.should == "http://example.com" + end + it "should be equal to the equivalent parsed URI" do @uri.should == Addressable::URI.parse("http://example.com") end it "should raise an error if invalid components omitted" do @@ -251,10 +266,18 @@ it "should not infer a port" do @uri.port.should == nil @uri.inferred_port.should == nil end + + it "should have a site value of '//user@example.com'" do + @uri.site.should == "//user@example.com" + end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when created with both a userinfo and a user" do it "should raise an error" do (lambda do @@ -263,39 +286,69 @@ end end describe Addressable::URI, "when created with a path that hasn't been " + "prefixed with a '/' but a host specified" do - it "should prefix a '/' to the path" do - Addressable::URI.new( + before do + @uri = Addressable::URI.new( :scheme => "http", :host => "example.com", :path => "path" - ).should == Addressable::URI.parse("http://example.com/path") + ) end + + it "should prefix a '/' to the path" do + @uri.should == Addressable::URI.parse("http://example.com/path") + end + + it "should have a site value of 'http://example.com'" do + @uri.site.should == "http://example.com" + end + + it "should have an origin of 'http://example.com" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when created with a path that hasn't been " + "prefixed with a '/' but no host specified" do - it "should prefix a '/' to the path" do - Addressable::URI.new( + before do + @uri = Addressable::URI.new( :scheme => "http", :path => "path" - ).should == Addressable::URI.parse("http:path") + ) end + + it "should not prefix a '/' to the path" do + @uri.should == Addressable::URI.parse("http:path") + end + + it "should have a site value of 'http:'" do + @uri.site.should == "http:" + end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from an Addressable::URI object" do - it "should return the object" do - uri = Addressable::URI.parse("http://example.com/") - (lambda do - Addressable::URI.parse(uri).object_id.should == uri.object_id - end).should_not raise_error + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.parse(original_uri) + new_uri.host = 'www.example.com' + new_uri.host.should == 'www.example.com' + new_uri.to_s.should == 'http://www.example.com/' + original_uri.host.should == 'example.com' + original_uri.to_s.should == 'http://example.com/' end - it "should return the object" do - uri = Addressable::URI.parse("http://example.com/") - (lambda do - Addressable::URI.heuristic_parse(uri).object_id.should == uri.object_id - end).should_not raise_error + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.heuristic_parse(original_uri) + new_uri.host = 'www.example.com' + new_uri.host.should == 'www.example.com' + new_uri.to_s.should == 'http://www.example.com/' + original_uri.host.should == 'example.com' + original_uri.to_s.should == 'http://example.com/' end end describe Addressable::URI, "when parsed from something that looks " + "like a URI object" do @@ -333,10 +386,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'ftp://ftp.is.co.za/rfc/rfc1808.txt'" do @@ -365,10 +422,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have an origin of 'ftp://ftp.is.co.za'" do + @uri.origin.should == 'ftp://ftp.is.co.za' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'http://www.ietf.org/rfc/rfc2396.txt'" do @@ -407,10 +468,14 @@ it "should correctly omit components destructively" do @uri.omit!(:scheme) @uri.to_s.should == "//www.ietf.org/rfc/rfc2396.txt" end + + it "should have an origin of 'http://www.ietf.org'" do + @uri.origin.should == 'http://www.ietf.org' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'ldap://[2001:db8::7]/c=GB?objectClass?one'" do @@ -465,10 +530,14 @@ it "should raise an error if omission would create an invalid URI" do (lambda do @uri.omit(:authority, :path) end).should raise_error(Addressable::URI::InvalidURIError) end + + it "should have an origin of 'ldap://[2001:db8::7]'" do + @uri.origin.should == 'ldap://[2001:db8::7]' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'mailto:John.Doe@example.com'" do @@ -493,10 +562,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'news:comp.infosystems.www.servers.unix'" do @@ -521,10 +594,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'tel:+1-816-555-1212'" do @@ -549,10 +626,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'telnet://192.0.2.16:80/'" do @@ -585,10 +666,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have an origin of 'telnet://192.0.2.16:80'" do + @uri.origin.should == 'telnet://192.0.2.16:80' + end end # Section 1.1.2 of RFC 3986 describe Addressable::URI, "when parsed from " + "'urn:oasis:names:specification:docbook:dtd:xml:4.1.2'" do @@ -615,10 +700,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'http://example.com'" do before do @@ -732,10 +821,31 @@ it "should result in itself when joined with itself" do @uri.join(@uri).to_s.should == "http://example.com" @uri.join!(@uri).to_s.should == "http://example.com" end + it "should be equivalent to http://EXAMPLE.com" do + @uri.should == Addressable::URI.parse("http://EXAMPLE.com") + end + + it "should be equivalent to http://EXAMPLE.com:80/" do + @uri.should == Addressable::URI.parse("http://EXAMPLE.com:80/") + end + + it "should have the same hash as http://example.com" do + @uri.hash.should == Addressable::URI.parse("http://example.com").hash + end + + it "should have the same hash as http://EXAMPLE.com after assignment" do + @uri.host = "EXAMPLE.com" + @uri.hash.should == Addressable::URI.parse("http://EXAMPLE.com").hash + end + + it "should have a different hash from http://EXAMPLE.com" do + @uri.hash.should_not == Addressable::URI.parse("http://EXAMPLE.com").hash + end + # Section 6.2.3 of RFC 3986 it "should be equivalent to http://example.com/" do @uri.should == Addressable::URI.parse("http://example.com/") end @@ -869,10 +979,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end # Section 5.1.2 of RFC 2616 describe Addressable::URI, "when parsed from " + "'http://www.w3.org/pub/WWW/TheProject.html'" do @@ -896,10 +1010,16 @@ @uri.request_uri.should == "/?x=y" @uri.path.should == "/" @uri.query.should == "x=y" end + it "should raise an error if the site value is set to something bogus" do + (lambda do + @uri.site = 42 + end).should raise_error(TypeError) + end + it "should raise an error if the request URI is set to something bogus" do (lambda do @uri.request_uri = 42 end).should raise_error(TypeError) end @@ -914,10 +1034,14 @@ :path => "/pub/WWW/TheProject.html", :query => nil, :fragment => nil } end + + it "should have an origin of 'http://www.w3.org'" do + @uri.origin.should == 'http://www.w3.org' + end end describe Addressable::URI, "when parsed from " + "'http://example.com/'" do before do @@ -993,10 +1117,50 @@ end it "should have the same hash as an equal URI" do @uri.hash.should == Addressable::URI.parse("http://example.com/").hash end + + it "should be equivalent to http://EXAMPLE.com" do + @uri.should == Addressable::URI.parse("http://EXAMPLE.com") + end + + it "should be equivalent to http://EXAMPLE.com:80/" do + @uri.should == Addressable::URI.parse("http://EXAMPLE.com:80/") + end + + it "should have the same hash as http://example.com/" do + @uri.hash.should == Addressable::URI.parse("http://example.com/").hash + end + + it "should have the same hash as http://example.com after assignment" do + @uri.path = "" + @uri.hash.should == Addressable::URI.parse("http://example.com").hash + end + + it "should have the same hash as http://example.com/? after assignment" do + @uri.query = "" + @uri.hash.should == Addressable::URI.parse("http://example.com/?").hash + end + + it "should have the same hash as http://example.com/? after assignment" do + @uri.query_values = {} + @uri.hash.should == Addressable::URI.parse("http://example.com/?").hash + end + + it "should have the same hash as http://example.com/# after assignment" do + @uri.fragment = "" + @uri.hash.should == Addressable::URI.parse("http://example.com/#").hash + end + + it "should have a different hash from http://example.com" do + @uri.hash.should_not == Addressable::URI.parse("http://example.com").hash + end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + "'http://@example.com/'" do before do @@ -1021,10 +1185,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + "'http://example.com./'" do before do @@ -1040,10 +1208,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + "'http://:@example.com/'" do before do @@ -1068,10 +1240,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + "'http://example.com/~smith/'" do before do @@ -1477,10 +1653,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + "'http://example.com:8080/'" do before do @@ -1574,10 +1754,14 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com:8080'" do + @uri.origin.should == 'http://example.com:8080' + end end describe Addressable::URI, "when parsed from " + "'http://example.com:%38%30/'" do before do @@ -1593,13 +1777,55 @@ end it "should normalize to 'http://example.com/'" do @uri.normalize.should === "http://example.com/" end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + + "'http://example.com/..'" do + before do + @uri = Addressable::URI.parse("http://example.com/..") + end + + it "should have the correct port" do + @uri.inferred_port.should == 80 + end + + it "should not be considered to be in normal form" do + @uri.normalize.should_not be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + @uri.normalize.should === "http://example.com/" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/../..'" do + before do + @uri = Addressable::URI.parse("http://example.com/../..") + end + + it "should have the correct port" do + @uri.inferred_port.should == 80 + end + + it "should not be considered to be in normal form" do + @uri.normalize.should_not be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + @uri.normalize.should === "http://example.com/" + end +end + +describe Addressable::URI, "when parsed from " + "'http://example.com/path/to/resource/'" do before do @uri = Addressable::URI.parse("http://example.com/path/to/resource/") end @@ -2024,14 +2250,14 @@ @uri.normalize.should be_eql(@uri) end end describe Addressable::URI, "when parsed from " + - "'ssh+svn://developername@rubyforge.org/var/svn/project'" do + "'ssh+svn://developername@RUBYFORGE.ORG/var/svn/project'" do before do @uri = Addressable::URI.parse( - "ssh+svn://developername@rubyforge.org/var/svn/project" + "ssh+svn://developername@RUBYFORGE.ORG/var/svn/project" ) end it "should have a scheme of 'ssh+svn'" do @uri.scheme.should == "ssh+svn" @@ -2039,10 +2265,14 @@ it "should have a normalized scheme of 'svn+ssh'" do @uri.normalized_scheme.should == "svn+ssh" end + it "should have a normalized site of 'svn+ssh'" do + @uri.normalized_site.should == "svn+ssh://developername@rubyforge.org" + end + it "should not be considered to be ip-based" do @uri.should_not be_ip_based end it "should have a path of '/var/svn/project'" do @@ -2114,10 +2344,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'http://example.com/x;y/'" do before do @@ -2155,10 +2389,14 @@ end it "should be considered to be in normal form" do @uri.normalize.should be_eql(@uri) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do before do @@ -2266,10 +2504,26 @@ "bogus%21://user:pass@example.com/path/to/resource?query=x#fragment" @uri.normalize.to_str.should == "bogus%21://user:pass@example.com/path/to/resource?query=x#fragment" end + it "should have the correct site segment after assignment" do + @uri.site = "https://newuser:newpass@example.com:443" + @uri.scheme.should == "https" + @uri.authority.should == "newuser:newpass@example.com:443" + @uri.user.should == "newuser" + @uri.password.should == "newpass" + @uri.userinfo.should == "newuser:newpass" + @uri.normalized_userinfo.should == "newuser:newpass" + @uri.host.should == "example.com" + @uri.port.should == 443 + @uri.inferred_port.should == 443 + @uri.to_s.should == + "https://newuser:newpass@example.com:443" + + "/path/to/resource?query=x#fragment" + end + it "should have the correct authority segment after assignment" do @uri.authority = "newuser:newpass@example.com:80" @uri.authority.should == "newuser:newpass@example.com:80" @uri.user.should == "newuser" @uri.password.should == "newpass" @@ -2326,10 +2580,24 @@ @uri.path.should == "/newpath/to/resource" @uri.to_s.should == "http://user:pass@example.com/newpath/to/resource?query=x#fragment" end + it "should have the correct scheme and authority after nil assignment" do + @uri.site = nil + @uri.scheme.should == nil + @uri.authority.should == nil + @uri.to_s.should == "/path/to/resource?query=x#fragment" + end + + it "should have the correct scheme and authority after assignment" do + @uri.site = "file://" + @uri.scheme.should == "file" + @uri.authority.should == "" + @uri.to_s.should == "file:///path/to/resource?query=x#fragment" + end + it "should have the correct path after nil assignment" do @uri.path = nil @uri.path.should == "" @uri.to_s.should == "http://user:pass@example.com?query=x#fragment" @@ -2414,26 +2682,34 @@ end it "should have the correct values after a merge" do @uri.merge(:authority => "foo:bar@baz:42").to_s.should == "http://foo:bar@baz:42/path/to/resource?query=x#fragment" + # Ensure the operation was not destructive @uri.to_s.should == "http://user:pass@example.com/path/to/resource?query=x#fragment" end it "should have the correct values after a destructive merge" do @uri.merge!(:authority => "foo:bar@baz:42") + # Ensure the operation was destructive @uri.to_s.should == "http://foo:bar@baz:42/path/to/resource?query=x#fragment" end it "should fail to merge with bogus values" do (lambda do @uri.merge(:port => "bogus") end).should raise_error(Addressable::URI::InvalidURIError) end + it "should fail to merge with bogus values" do + (lambda do + @uri.merge(:authority => "bar@baz:bogus") + end).should raise_error(Addressable::URI::InvalidURIError) + end + it "should fail to merge with bogus parameters" do (lambda do @uri.merge(42) end).should raise_error(TypeError) end @@ -2457,13 +2733,77 @@ end it "should be identical to its duplicate" do @uri.should == @uri.dup end + + it "should have an origin of 'http://example.com'" do + @uri.origin.should == 'http://example.com' + end end describe Addressable::URI, "when parsed from " + + "'http://example.com/?q&&x=b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q&&x=b") + end + + it "should have a query of 'q&&x=b'" do + @uri.query.should == "q&&x=b" + end + + it "should have query_values of {'q' => true, 'x' => 'b'}" do + @uri.query_values.should == {'q' => true, 'x' => 'b'} + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=a+b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=a+b") + end + + it "should have a query of 'q=a+b'" do + @uri.query.should == "q=a+b" + end + + it "should have query_values of {'q' => 'a b'}" do + @uri.query_values.should == {'q' => 'a b'} + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=a%2bb'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=a%2bb") + end + + it "should have a query of 'q=a+b'" do + @uri.query.should == "q=a%2bb" + end + + it "should have query_values of {'q' => 'a+b'}" do + @uri.query_values.should == {'q' => 'a+b'} + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q='" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=") + end + + it "should have a query of 'q='" do + @uri.query.should == "q=" + end + + it "should have query_values of {'q' => ''}" do + @uri.query_values.should == {'q' => ''} + end +end + +describe Addressable::URI, "when parsed from " + "'http://user@example.com'" do before do @uri = Addressable::URI.parse("http://user@example.com") end @@ -2732,10 +3072,18 @@ it "should have a host of nil" do @uri.host.should == nil end + it "should have a site of nil" do + @uri.site.should == nil + end + + it "should have a normalized_site of nil" do + @uri.normalized_site.should == nil + end + it "should have a path of ''" do @uri.path.should == "" end it "should have a query string of nil" do @@ -2771,10 +3119,14 @@ end).should raise_error(ArgumentError, /\/\/example.com\//) (lambda do @uri.route_from("http://example.com/") end).should raise_error(ArgumentError, /\/\/example.com\//) end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'feed://http://example.com/'" do before do @@ -2802,10 +3154,14 @@ it "should normalize to 'http://example.com/'" do @uri.normalize.to_s.should == "http://example.com/" @uri.normalize!.to_s.should == "http://example.com/" end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'example://a/b/c/%7Bfoo%7D'" do before do @@ -2815,10 +3171,14 @@ # Section 6.2.2 of RFC 3986 it "should be equivalent to eXAMPLE://a/./b/../b/%63/%7bfoo%7d" do @uri.should == Addressable::URI.parse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d") end + + it "should have an origin of 'example://a'" do + @uri.origin.should == 'example://a' + end end describe Addressable::URI, "when parsed from " + "'http://example.com/indirect/path/./to/../resource/'" do before do @@ -2869,10 +3229,14 @@ end it "should have no scheme" do @uri.scheme.should == nil end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from " + "'this:that'" do before do @@ -2884,10 +3248,14 @@ end it "should have a scheme of 'this'" do @uri.scheme.should == "this" end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from '?'" do before do @uri = Addressable::URI.parse("?") @@ -2903,10 +3271,14 @@ end it "should have the correct flat notation query values" do @uri.query_values(:notation => :flat).should == {} end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do before do @uri = Addressable::URI.parse("?one=1&two=2&three=3") @@ -2919,12 +3291,38 @@ it "should raise an error for invalid query value notations" do (lambda do @uri.query_values(:notation => :bogus) end).should raise_error(ArgumentError) end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one", "1"], ["two", "2"], ["three", "3"] + ] + end + + it "should have a 'null' origin" do + @uri.origin.should == 'null' + end end +describe Addressable::URI, "when parsed from '?one=1=uno&two=2=dos'" do + before do + @uri = Addressable::URI.parse("?one=1=uno&two=2=dos") + end + + it "should have the correct query values" do + @uri.query_values.should == {"one" => "1=uno", "two" => "2=dos"} + end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one", "1=uno"], ["two", "2=dos"] + ] + end +end + describe Addressable::URI, "when parsed from '?one[two][three]=four'" do before do @uri = Addressable::URI.parse("?one[two][three]=four") end @@ -2935,10 +3333,16 @@ it "should have the correct flat notation query values" do @uri.query_values(:notation => :flat).should == { "one[two][three]" => "four" } end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one[two][three]", "four"] + ] + end end describe Addressable::URI, "when parsed from '?one.two.three=four'" do before do @uri = Addressable::URI.parse("?one.two.three=four") @@ -2953,10 +3357,16 @@ it "should have the correct flat notation query values" do @uri.query_values(:notation => :flat).should == { "one.two.three" => "four" } end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one.two.three", "four"] + ] + end end describe Addressable::URI, "when parsed from " + "'?one[two][three]=four&one[two][five]=six'" do before do @@ -2973,10 +3383,16 @@ @uri.query_values(:notation => :flat).should == { "one[two][three]" => "four", "one[two][five]" => "six" } end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one[two][three]", "four"], ["one[two][five]", "six"] + ] + end end describe Addressable::URI, "when parsed from " + "'?one.two.three=four&one.two.five=six'" do before do @@ -2993,13 +3409,33 @@ @uri.query_values(:notation => :flat).should == { "one.two.three" => "four", "one.two.five" => "six" } end + + it "should have the correct flat array notation query values" do + @uri.query_values(:notation => :flat_array).should == [ + ["one.two.three", "four"], ["one.two.five", "six"] + ] + end end describe Addressable::URI, "when parsed from " + + "'?one=two&one=three'" do + before do + @uri = Addressable::URI.parse( + "?one=two&one=three" + ) + end + + it "should have correct flat_array notation query values" do + @uri.query_values(:notation => :flat_array).should == + [['one', 'two'], ['one', 'three']] + end +end + +describe Addressable::URI, "when parsed from " + "'?one[two][three][]=four&one[two][three][]=five'" do before do @uri = Addressable::URI.parse( "?one[two][three][]=four&one[two][three][]=five" ) @@ -3014,10 +3450,17 @@ it "should raise an error if a key is repeated in the flat notation" do (lambda do @uri.query_values(:notation => :flat) end).should raise_error(ArgumentError) end + + it "should not raise an error if a key is " + + "repeated in the flat array notation" do + (lambda do + @uri.query_values(:notation => :flat_array) + end).should_not raise_error + end end describe Addressable::URI, "when parsed from " + "'?one[two][three][0]=four&one[two][three][1]=five'" do before do @@ -3032,10 +3475,40 @@ } end end describe Addressable::URI, "when parsed from " + + "'?one[two][three][1]=four&one[two][three][0]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][1]=four&one[two][three][0]=five" + ) + end + + it "should have the correct subscript notation query values" do + @uri.query_values(:notation => :subscript).should == { + "one" => {"two" => {"three" => ["five", "four"]}} + } + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three][2]=four&one[two][three][1]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][2]=four&one[two][three][1]=five" + ) + end + + it "should have the correct subscript notation query values" do + @uri.query_values(:notation => :subscript).should == { + "one" => {"two" => {"three" => ["five", "four"]}} + } + end +end + +describe Addressable::URI, "when parsed from " + "'http://www.詹姆斯.com/'" do before do @uri = Addressable::URI.parse("http://www.詹姆斯.com/") end @@ -3046,10 +3519,14 @@ it "should not have domain name encoded during normalization" do Addressable::URI.normalized_encode(@uri.to_s).should == "http://www.詹姆斯.com/" end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + @uri.origin.should == 'http://www.xn--8ws00zhy3a.com' + end end describe Addressable::URI, "when parsed from " + "'http://www.詹姆斯.com/ some spaces /'" do before do @@ -3065,10 +3542,14 @@ it "should not have domain name encoded during normalization" do Addressable::URI.normalized_encode(@uri.to_s).should == "http://www.詹姆斯.com/%20some%20spaces%20/" end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + @uri.origin.should == 'http://www.xn--8ws00zhy3a.com' + end end describe Addressable::URI, "when parsed from " + "'http://www.xn--8ws00zhy3a.com/'" do before do @@ -3084,10 +3565,14 @@ display_string.should == "http://www.詹姆斯.com/" if display_string.respond_to?(:encoding) display_string.encoding.to_s.should == Encoding::UTF_8.to_s end end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + @uri.origin.should == 'http://www.xn--8ws00zhy3a.com' + end end describe Addressable::URI, "when parsed from " + "'http://www.詹姆斯.com/atomtests/iri/詹.html'" do before do @@ -3121,10 +3606,17 @@ "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" @uri.normalize!.to_s.should == "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" end + + it "should have the correct origin" do + @uri.origin.should == ( + "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + + "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" + ) + end end describe Addressable::URI, "with a base uri of 'http://a/b/c/d;p?q'" do before do @uri = Addressable::URI.parse("http://a/b/c/d;p?q") @@ -3453,10 +3945,15 @@ it "should convert to \'file:///\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given a Windows root directory" do before do @path = "C:\\" @@ -3464,10 +3961,15 @@ it "should convert to \'file:///c:/\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path '/home/user/'" do before do @path = '/home/user/' @@ -3476,10 +3978,15 @@ it "should convert to " + "\'file:///home/user/\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///home/user/" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path " + "'c:\\windows\\My Documents 100%20\\foo.txt'" do before do @@ -3489,10 +3996,15 @@ it "should convert to " + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path " + "'file://c:\\windows\\My Documents 100%20\\foo.txt'" do before do @@ -3502,10 +4014,15 @@ it "should convert to " + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path " + "'file:c:\\windows\\My Documents 100%20\\foo.txt'" do before do @@ -3515,10 +4032,15 @@ it "should convert to " + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path " + "'file:/c:\\windows\\My Documents 100%20\\foo.txt'" do before do @@ -3528,10 +4050,15 @@ it "should convert to " + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given the path " + "'file:///c|/windows/My%20Documents%20100%20/foo.txt'" do before do @@ -3541,10 +4068,15 @@ it "should convert to " + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do @uri = Addressable::URI.convert_path(@path) @uri.to_str.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt" end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + @uri.origin.should == 'file://' + end end describe Addressable::URI, "when given an http protocol URI" do before do @path = "http://example.com/" @@ -3586,10 +4118,99 @@ Addressable::URI.heuristic_parse(42) end).should raise_error(TypeError, "Can't convert Fixnum into String.") end end +describe Addressable::URI, "when form encoding a hash" do + it "should result in correct percent encoded sequence" do + Addressable::URI.form_encode( + {"&one" => "/1", "=two" => "?2", ":three" => "#3"} + ).should == "%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233" + end + + it "should result in correct percent encoded sequence" do + Addressable::URI.form_encode( + {"q" => "one two three"} + ).should == "q=one+two+three" + end + + it "should result in correct percent encoded sequence" do + Addressable::URI.form_encode( + {"key" => nil} + ).should == "key=" + end + + it "should result in correctly encoded newlines" do + Addressable::URI.form_encode( + {"text" => "one\ntwo\rthree\r\nfour\n\r"} + ).should == "text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A" + end + + it "should result in a sorted percent encoded sequence" do + Addressable::URI.form_encode( + [["a", "1"], ["dup", "3"], ["dup", "2"]], true + ).should == "a=1&dup=2&dup=3" + end +end + +describe Addressable::URI, "when form encoding a non-Array object" do + it "should raise a TypeError for objects than cannot be converted" do + (lambda do + Addressable::URI.form_encode(42) + end).should raise_error(TypeError, "Can't convert Fixnum into Array.") + end +end + +describe Addressable::URI, "when form unencoding a string" do + it "should result in correct values" do + Addressable::URI.form_unencode( + "%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233" + ).should == [["&one", "/1"], ["=two", "?2"], [":three", "#3"]] + end + + it "should result in correct values" do + Addressable::URI.form_unencode( + "q=one+two+three" + ).should == [["q", "one two three"]] + end + + it "should result in correct values" do + Addressable::URI.form_unencode( + "text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A" + ).should == [["text", "one\ntwo\nthree\nfour\n\n"]] + end + + it "should result in correct values" do + Addressable::URI.form_unencode( + "a=1&dup=2&dup=3" + ).should == [["a", "1"], ["dup", "2"], ["dup", "3"]] + end + + it "should result in correct values" do + Addressable::URI.form_unencode( + "key" + ).should == [["key", nil]] + end + + it "should result in correct values" do + Addressable::URI.form_unencode("GivenName=Ren%C3%A9").should == + [["GivenName", "René"]] + end +end + +describe Addressable::URI, "when form unencoding a non-String object" do + it "should correctly parse anything with a 'to_str' method" do + Addressable::URI.form_unencode(SuperString.new(42)) + end + + it "should raise a TypeError for objects than cannot be converted" do + (lambda do + Addressable::URI.form_unencode(42) + end).should raise_error(TypeError, "Can't convert Fixnum into String.") + end +end + describe Addressable::URI, "when normalizing a non-String object" do it "should correctly parse anything with a 'to_str' method" do Addressable::URI.normalize_component(SuperString.new(42)) end @@ -3663,10 +4284,17 @@ "günther", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/ ).should == "g%C3%BCnther" end end +describe Addressable::URI, "when form encoding a multibyte string" do + it "should result in correct percent encoded sequence" do + Addressable::URI.form_encode({"GivenName" => "René"}).should == + "GivenName=Ren%C3%A9" + end +end + describe Addressable::URI, "when encoding a string with ASCII chars 0-15" do it "should result in correct percent encoded sequence" do Addressable::URI.encode_component("one\ntwo").should == "one%0Atwo" end @@ -3934,7 +4562,84 @@ "{:a => 'a', :b => {:c => true, :d => 'd'}, :e => []}" do @uri.query_values = { :a => 'a', :b => {:c => true, :d => 'd'} } @uri.query.should == "a=a&b[c]&b[d]=d" + end + + it "should correctly assign {}" do + @uri.query_values = {} + @uri.query.should == '' + end + + it "should correctly assign nil" do + @uri.query_values = nil + @uri.query.should == nil + end + + it "should correctly sort {'ab' => 'c', :ab => 'a', :a => 'x'}" do + @uri.query_values = {'ab' => 'c', :ab => 'a', :a => 'x'} + @uri.query.should == "a=x&ab=a&ab=c" + end + + it "should correctly assign " + + "[['b', 'c'], ['b', 'a'], ['a', 'a']]" do + # Order can be guaranteed in this format, so preserve it. + @uri.query_values = [['b', 'c'], ['b', 'a'], ['a', 'a']] + @uri.query.should == "b=c&b=a&a=a" + end + + it "should preserve query string order" do + query_string = (('a'..'z').to_a.shuffle.map { |e| "#{e}=#{e}" }).join("&") + @uri.query = query_string + original_uri = @uri.to_s + @uri.query_values = @uri.query_values(:notation => :flat_array) + @uri.to_s.should == original_uri + end +end + +describe Addressable::URI, "when assigning path values" do + before do + @uri = Addressable::URI.new + end + + it "should correctly assign paths containing colons" do + @uri.path = "acct:bob@sporkmonger.com" + Addressable::URI.parse(@uri.normalize.to_str).path.should == @uri.path + @uri.normalize.to_str.should == "acct%2Fbob@sporkmonger.com" + end + + it "should correctly assign paths containing colons" do + @uri.path = "/acct:bob@sporkmonger.com" + @uri.authority = "example.com" + @uri.normalize.to_str.should == "//example.com/acct:bob@sporkmonger.com" + end + + it "should correctly assign paths containing colons" do + @uri.path = "acct:bob@sporkmonger.com" + @uri.scheme = "something" + @uri.normalize.to_str.should == "something:acct:bob@sporkmonger.com" + end + + it "should not allow relative paths to be assigned on absolute URIs" do + (lambda do + @uri.scheme = "http" + @uri.host = "example.com" + @uri.path = "acct:bob@sporkmonger.com" + end).should raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow relative paths to be assigned on absolute URIs" do + (lambda do + @uri.path = "acct:bob@sporkmonger.com" + @uri.scheme = "http" + @uri.host = "example.com" + end).should raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow relative paths to be assigned on absolute URIs" do + (lambda do + @uri.path = "uuid:0b3ecf60-3f93-11df-a9c3-001f5bfffe12" + @uri.scheme = "urn" + end).should_not raise_error(Addressable::URI::InvalidURIError) end end