uri-component 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in stringglob.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new
5
+
@@ -0,0 +1,122 @@
1
+ ## Ruby URI::Component::Path: Class to handle a path component in an URI
2
+ ##
3
+ ## Author:: SATOH Fumiyasu
4
+ ## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
5
+ ## License:: You can redistribute it and/or modify it under the same term as Ruby.
6
+ ##
7
+
8
+ require 'uri'
9
+
10
+ module URI
11
+ module Component
12
+ ## Handle a path component in an URI as an object
13
+ class Path
14
+ #:stopdoc:
15
+ ## Same as URI::UNSAFE, plus ';' (separator for path nodes)
16
+ ## and '?' (separator for path and query)
17
+ RE_UNSAFE = /
18
+ [^#{URI::REGEXP::PATTERN::UNRESERVED}#{URI::REGEXP::PATTERN::RESERVED}]|
19
+ [\/?]
20
+ /x
21
+ RE_COMPONENT = /^(?:#{URI::REGEXP::PATTERN::ABS_PATH})?$/
22
+ #:startdoc:
23
+
24
+ def self.mixin(klass) #:nodoc:
25
+ PathMixin.__send__(:append_features, klass)
26
+ PathMixin.__send__(:included, klass)
27
+ end
28
+
29
+ def initialize(path_str='')
30
+ unless path_str =~ RE_COMPONENT
31
+ raise InvalidURIError, "bad Path component for URI: #{path_str}"
32
+ end
33
+
34
+ if path_str
35
+ @nodes = path_str.split('/', -1).map do |node|
36
+ URI.unescape(node)
37
+ end
38
+ @nodes.shift
39
+ else
40
+ @nodes = []
41
+ end
42
+ end
43
+
44
+ def to_uri
45
+ return '' if @nodes.empty?
46
+ return '/' + @nodes.map do |node|
47
+ URI.escape(node, RE_UNSAFE)
48
+ end.join('/')
49
+ end
50
+ alias to_s to_uri
51
+
52
+ def nodes
53
+ return @nodes
54
+ end
55
+
56
+ def nodes=(v)
57
+ @nodes = v
58
+ end
59
+
60
+ def normalize!
61
+ nodes = []
62
+ @nodes.each do |node|
63
+ case node
64
+ when ''
65
+ next
66
+ when '.'
67
+ next
68
+ when '..'
69
+ nodes.pop
70
+ next
71
+ end
72
+ nodes << node
73
+ end
74
+
75
+ @nodes = nodes
76
+ end
77
+ end
78
+
79
+ module PathMixin
80
+ def initialize_copy(uri)
81
+ if (path = uri.instance_variable_get('@path_component'))
82
+ @path_component = path.dup
83
+ end
84
+
85
+ super(uri)
86
+ end
87
+
88
+ def path
89
+ return @path_component ? @path_component.to_uri : @path
90
+ end
91
+
92
+ def path=(path_str)
93
+ super(path_str)
94
+
95
+ parse_path!
96
+ return self.path
97
+ end
98
+
99
+ def path_component
100
+ parse_path! unless @path_component
101
+ return @path_component
102
+ end
103
+ alias path_c path_component
104
+
105
+ def path_query
106
+ str = self.path
107
+ if query = self.query
108
+ str += '?' + query
109
+ end
110
+ return str
111
+ end
112
+ private :path_query
113
+
114
+ protected
115
+
116
+ def parse_path!
117
+ @path_component = URI::Component::Path.new(@path)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,115 @@
1
+ ## Ruby URI::Component::Query: Class to handle a query component in an URI
2
+ ##
3
+ ## Author:: SATOH Fumiyasu
4
+ ## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
5
+ ## License:: You can redistribute it and/or modify it under the same term as Ruby.
6
+ ##
7
+
8
+ require 'uri'
9
+ require 'cgi'
10
+
11
+ module URI
12
+ module Component
13
+ ## Handle a query component in an URI as an object
14
+ class Query
15
+ #:stopdoc:
16
+ RE_COMPONENT = /^#{URI::REGEXP::PATTERN::QUERY}?$/
17
+ #:startdoc:
18
+
19
+ def self.mixin(klass) #:nodoc:
20
+ QueryMixin.__send__(:append_features, klass)
21
+ QueryMixin.__send__(:included, klass)
22
+ end
23
+
24
+ def initialize(query_str='')
25
+ unless query_str =~ RE_COMPONENT
26
+ raise InvalidURIError, "bad Query component for URI: #{query_str}"
27
+ end
28
+
29
+ @params = {}
30
+ @params.default_proc = Proc.new {|hash, key|
31
+ hash[key] = [] unless hash.key?(key)
32
+ }
33
+ @param_separator = '&'
34
+
35
+ query_str.split(/[&;]/).each do |param|
36
+ next if param.empty?
37
+ name, value = param.split('=', 2).map do |v|
38
+ CGI.unescape(v)
39
+ end
40
+ @params[name] ||= []
41
+ @params[name] << value ? value : nil
42
+ end
43
+ end
44
+
45
+ def params
46
+ return @params
47
+ end
48
+
49
+ def param_separator
50
+ return @param_separator
51
+ end
52
+
53
+ def param_separator=(v)
54
+ @param_separator = v
55
+ end
56
+
57
+ def to_uri(separator=@param_separator)
58
+ query = []
59
+
60
+ @params.each do |name, values|
61
+ name = CGI.escape(name)
62
+ values.each do |value|
63
+ query << "#{name}#{'=' + CGI.escape(value.to_s) if value}"
64
+ end
65
+ end
66
+
67
+ return query.join(separator)
68
+ end
69
+ alias to_s to_uri
70
+ end
71
+
72
+ module QueryMixin
73
+ def initialize_copy(uri)
74
+ if (query = uri.instance_variable_get('@query_component'))
75
+ @query_component = query.dup
76
+ end
77
+
78
+ super(uri)
79
+ end
80
+
81
+ def query
82
+ return @query_component ? @query_component.to_uri : @query
83
+ end
84
+
85
+ def query=(query_str)
86
+ super(query_str)
87
+
88
+ parse_query!
89
+ return self.query
90
+ end
91
+
92
+ def query_component
93
+ parse_query! unless @query_component
94
+ return @query_component
95
+ end
96
+ alias query_c query_component
97
+
98
+ def path_query
99
+ str = self.path
100
+ if query = self.query
101
+ str += '?' + query
102
+ end
103
+ return str
104
+ end
105
+ private :path_query
106
+
107
+ protected
108
+
109
+ def parse_query!
110
+ @query_component = URI::Component::Query.new(@query)
111
+ end
112
+ end
113
+ end
114
+ end
115
+
@@ -0,0 +1,156 @@
1
+ ## Ruby URI::Component::UserInfo: Class to handle an userinfo component in an URI
2
+ ##
3
+ ## Author:: SATOH Fumiyasu
4
+ ## Copyright:: (c) 2007-2011 SATOH Fumiyasu @ OSS Technology, Corp.
5
+ ## License:: You can redistribute it and/or modify it under the same term as Ruby.
6
+ ##
7
+
8
+ require 'uri'
9
+
10
+ module URI
11
+ module Component
12
+ ## Handle an userinfo component in an URI as an object
13
+ class UserInfo
14
+ #:stopdoc:
15
+ RE_UNSAFE = /[^#{URI::REGEXP::PATTERN::UNRESERVED}]/
16
+ ## Same as URI::USERINFO, except ';' and ':'
17
+ RE_PART = /(?:
18
+ [#{URI::REGEXP::PATTERN::UNRESERVED}&=+$,]|
19
+ #{URI::REGEXP::PATTERN::ESCAPED})*
20
+ /x
21
+ RE_COMPONENT = /^(?:(#{RE_PART});)?(#{RE_PART})(?::(#{RE_PART}))?$/
22
+ #:startdoc:
23
+
24
+ def self.mixin(klass) #:nodoc:
25
+ UserInfoMixin.__send__(:append_features, klass)
26
+ UserInfoMixin.__send__(:included, klass)
27
+ end
28
+
29
+ def self.escape(v)
30
+ return URI.escape(v, RE_UNSAFE)
31
+ end
32
+
33
+ def initialize(info_str=nil)
34
+ if info_str
35
+ unless m = info_str.match(RE_COMPONENT)
36
+ raise InvalidURIError, "bad UserInfo component for URI: #{info_str}"
37
+ end
38
+ @domain = m[1] ? URI.unescape(m[1]) : nil
39
+ @user = URI.unescape(m[2])
40
+ @password = m[3] ? URI.unescape(m[3]) : nil
41
+ else
42
+ @domain = @user = @password = nil
43
+ end
44
+ end
45
+
46
+ def domain
47
+ return @domain
48
+ end
49
+
50
+ def domain=(v)
51
+ if v && !@user
52
+ raise InvalidURIError, "domain component depends user component"
53
+ end
54
+ @domain = v
55
+ end
56
+
57
+ def user
58
+ return @user
59
+ end
60
+
61
+ def user=(v)
62
+ if !v
63
+ @domain = @password = nil
64
+ end
65
+ @user = v
66
+ end
67
+
68
+ def password
69
+ return @password
70
+ end
71
+
72
+ def password=(v)
73
+ if v && !@user
74
+ raise InvalidURIError, "password component depends user component"
75
+ end
76
+ @password = v
77
+ end
78
+
79
+ def to_uri
80
+ return nil unless @user
81
+
82
+ info_str = ''
83
+ info_str += self.class.escape(@domain) + ';' if @domain
84
+ info_str += @user ? self.class.escape(@user) : '';
85
+ info_str += ':' + self.class.escape(@password) if @password
86
+ return info_str
87
+ end
88
+ alias to_s to_uri
89
+ end
90
+
91
+ module UserInfoMixin
92
+ def initialize_copy(uri)
93
+ if (userinfo = uri.instance_variable_get('@userinfo_component'))
94
+ @userinfo_component = userinfo.dup
95
+ end
96
+
97
+ super(uri)
98
+ end
99
+
100
+ def userinfo
101
+ @userinfo_component.to_uri
102
+ end
103
+
104
+ def userinfo=(info_str)
105
+ super(info_str)
106
+
107
+ parse_userinfo!
108
+ return self.userinfo
109
+ end
110
+
111
+ def user
112
+ user = @userinfo_component.user
113
+ return nil unless user
114
+
115
+ domain = @userinfo_component.domain
116
+ user_uri = domain ? URI::Component::UserInfo.escape(domain) + ';' : ''
117
+ user_uri += URI::Component::UserInfo.escape(user)
118
+ return user_uri
119
+ end
120
+
121
+ def user=(user_uri)
122
+ if user_uri
123
+ m = user_uri.match(/^(?:(.*);)?(.*)$/)
124
+ @userinfo_component.domain = m[1] ? URI.unescape(m[1]) : nil
125
+ @userinfo_component.user = URI.unescape(m[2])
126
+ else
127
+ @userinfo_component.user = nil
128
+ end
129
+ end
130
+
131
+ def password
132
+ pass = @userinfo_component.password
133
+ return pass ? URI::Component::UserInfo.escape(pass) : nil
134
+ end
135
+
136
+ def password=(pass_uri)
137
+ @userinfo_component.password = pass_uri ? URI.unescape(pass_uri) : nil
138
+ end
139
+
140
+ def userinfo_component
141
+ parse_userinfo! unless @userinfo_component
142
+ return @userinfo_component
143
+ end
144
+ alias userinfo_c userinfo_component
145
+
146
+ protected
147
+
148
+ def parse_userinfo!
149
+ info_str = @user
150
+ info_str += ':' + @password if @password
151
+ @userinfo_component = URI::Component::UserInfo.new(info_str)
152
+ end
153
+ end
154
+ end
155
+ end
156
+
@@ -0,0 +1,6 @@
1
+ module URI
2
+ module Component
3
+ VERSION = "0.0.1" ## :nodoc:
4
+ end
5
+ end
6
+
@@ -0,0 +1,174 @@
1
+ require 'test/unit'
2
+ require 'uri/component/path'
3
+
4
+ UCP = URI::Component::Path
5
+
6
+ module URI
7
+ module Component
8
+
9
+ class TestPathClass < Test::Unit::TestCase
10
+ def setup
11
+ end
12
+
13
+ def teardown
14
+ end
15
+
16
+ def test_parse
17
+ p_uri = ''
18
+ p = UCP.new(p_uri)
19
+ assert_equal(p_uri, p.to_uri)
20
+ assert_empty(p.nodes)
21
+
22
+ p_uri = '/'
23
+ p = UCP.new(p_uri)
24
+ assert_equal(p_uri, p.to_uri)
25
+ assert_equal(1, p.nodes.size)
26
+ assert_equal('', p.nodes[0])
27
+
28
+ p_uri = '/foo'
29
+ p = UCP.new(p_uri)
30
+ assert_equal(p_uri, p.to_uri)
31
+ assert_equal(1, p.nodes.size)
32
+ assert_equal('foo', p.nodes[0])
33
+
34
+ p_uri = '/foo/'
35
+ p = UCP.new(p_uri)
36
+ assert_equal(p_uri, p.to_uri)
37
+ assert_equal(2, p.nodes.size)
38
+ assert_equal('foo', p.nodes[0])
39
+
40
+ p_uri = '/123%20abc'
41
+ p = UCP.new(p_uri)
42
+ assert_equal('/123%20abc', p.to_uri)
43
+ assert_equal(1, p.nodes.size)
44
+ assert_equal('123 abc', p.nodes[0])
45
+
46
+ p_uri = '/123+abc%2BABC'
47
+ p = UCP.new(p_uri)
48
+ assert_equal('/123+abc+ABC', p.to_uri)
49
+ assert_equal(1, p.nodes.size)
50
+ assert_equal('123+abc+ABC', p.nodes[0])
51
+
52
+ p_uri = '/foo-1/bar-abc%40xyz/baz-123%20%00%2B789%25ff'
53
+ p = UCP.new(p_uri)
54
+ assert_equal('/foo-1/bar-abc@xyz/baz-123%20%00+789%25ff', p.to_uri)
55
+ assert_equal(3, p.nodes.size)
56
+ assert_equal('foo-1', p.nodes[0])
57
+ assert_equal('bar-abc@xyz', p.nodes[1])
58
+ assert_equal("baz-123 \x00+789%ff", p.nodes[2])
59
+
60
+ p_uri = '/foo//bar'
61
+ p = UCP.new(p_uri)
62
+ assert_equal(p_uri, p.to_uri)
63
+ assert_equal(3, p.nodes.size)
64
+ assert_equal('foo', p.nodes[0])
65
+ assert_equal('', p.nodes[1])
66
+ assert_equal('bar', p.nodes[2])
67
+
68
+ %w(foo1 /foo?bar2 /foo\bar3).concat(['/foo bar4']).each do |path_str|
69
+ assert_raise(URI::InvalidURIError) do
70
+ UCP.new(path_str)
71
+ raise path_str
72
+ end
73
+ end
74
+ end
75
+
76
+ def test_set
77
+ p = UCP.new('')
78
+ assert_equal('', p.to_uri)
79
+
80
+ p = UCP.new('')
81
+ p.nodes << 'foo'
82
+ assert_equal('/foo', p.to_uri)
83
+
84
+ p = UCP.new('')
85
+ p.nodes << 'foo?bar'
86
+ assert_equal('/foo%3Fbar', p.to_uri)
87
+
88
+ p = UCP.new('')
89
+ p.nodes << 'foo/bar'
90
+ assert_equal('/foo%2Fbar', p.to_uri)
91
+
92
+ p = UCP.new('')
93
+ p.nodes << '123 abc'
94
+ assert_equal('/123%20abc', p.to_uri)
95
+
96
+ p = UCP.new('')
97
+ p.nodes << '123+abc'
98
+ assert_equal('/123+abc', p.to_uri)
99
+
100
+ p = UCP.new('')
101
+ p.nodes << 'abc@xyz'
102
+ p.nodes << "123 \x00+789%ff"
103
+ assert_equal('/abc@xyz/123%20%00+789%25ff', p.to_uri)
104
+ end
105
+
106
+ def test_normalize
107
+ p = UCP.new('/foo/')
108
+ p.normalize!
109
+ assert_equal('/foo', p.to_uri)
110
+
111
+ p = UCP.new('/foo/./bar')
112
+ p.normalize!
113
+ assert_equal('/foo/bar', p.to_uri)
114
+
115
+ p = UCP.new('/foo/./bar/baz/.')
116
+ p.normalize!
117
+ assert_equal('/foo/bar/baz', p.to_uri)
118
+
119
+ p = UCP.new('/foo/../bar')
120
+ p.normalize!
121
+ assert_equal('/bar', p.to_uri)
122
+
123
+ p = UCP.new('/foo/../../../bar')
124
+ p.normalize!
125
+ assert_equal('/bar', p.to_uri)
126
+
127
+ p = UCP.new('/foo/./../bar')
128
+ p.normalize!
129
+ assert_equal('/bar', p.to_uri)
130
+
131
+ p = UCP.new('/foo//bar')
132
+ p.normalize!
133
+ assert_equal('/foo/bar', p.to_uri)
134
+ end
135
+
136
+ def test_mixin
137
+ UCP.mixin(URI::HTTPS)
138
+
139
+ u_uri = 'https://example.jp/abc%40xyz/123+%00%2B789%25ff'
140
+ u_uri_x = u_uri.gsub('%40','@').gsub('%2B', '+')
141
+ u = URI.parse(u_uri)
142
+ p = u.path_component
143
+ assert_kind_of(URI::HTTPS, u)
144
+ assert_kind_of(UCP, p)
145
+ assert_equal(u_uri_x, u.to_s)
146
+ assert_equal('/abc@xyz/123+%00+789%25ff', u.path)
147
+ assert_equal('/abc@xyz/123+%00+789%25ff', p.to_s)
148
+
149
+ p.nodes << 'xxx'
150
+ assert_equal(u_uri_x + '/xxx', u.to_s)
151
+ assert_equal('/abc@xyz/123+%00+789%25ff/xxx', u.path)
152
+ assert_equal('/abc@xyz/123+%00+789%25ff/xxx', p.to_s)
153
+
154
+ u_uri.sub!(/^https:/, 'http:')
155
+ u_uri_x = u_uri.gsub('%40','@').gsub('%2B', '+')
156
+ u = URI.parse(u_uri)
157
+ assert_raise(NoMethodError) do
158
+ u.path_component
159
+ end
160
+
161
+ UCP.mixin(URI::HTTP)
162
+ u = URI.parse(u_uri)
163
+ p = u.path_component
164
+ assert_kind_of(URI::HTTP, u)
165
+ assert_kind_of(UCP, u.path_component)
166
+ assert_equal(u_uri_x, u.to_s)
167
+ assert_equal('/abc@xyz/123+%00+789%25ff', u.path)
168
+ assert_equal('/abc@xyz/123+%00+789%25ff', p.to_s)
169
+ end
170
+ end
171
+
172
+ end
173
+ end
174
+
@@ -0,0 +1,179 @@
1
+ require 'test/unit'
2
+ require 'uri/component/query'
3
+
4
+ UCQ = URI::Component::Query
5
+
6
+ module URI
7
+ module Component
8
+
9
+ class TestQueryClass < Test::Unit::TestCase
10
+ def setup
11
+ end
12
+
13
+ def teardown
14
+ end
15
+
16
+ def test_parse
17
+ q_uri = ''
18
+ q = UCQ.new(q_uri)
19
+ assert_equal(q_uri, q.to_uri)
20
+ assert_empty(q.params)
21
+
22
+ q_uri = 'foo=1'
23
+ q = UCQ.new(q_uri)
24
+ assert_equal(q_uri, q.to_uri)
25
+ assert_equal(1, q.params.size)
26
+ assert_equal(1, q.params['foo'].size)
27
+ assert_equal('1', q.params['foo'][0])
28
+
29
+ q_uri = 'foo'
30
+ q = UCQ.new(q_uri)
31
+ assert_equal(q_uri, q.to_uri)
32
+ assert_equal(1, q.params.size)
33
+ assert_equal(1, q.params['foo'].size)
34
+ assert_nil(q.params['foo'][0])
35
+
36
+ q_uri = 'foo=123%20abc'
37
+ q = UCQ.new(q_uri)
38
+ assert_equal(q_uri.gsub('%20', '+'), q.to_uri)
39
+ assert_equal(1, q.params.size)
40
+ assert_equal(1, q.params['foo'].size)
41
+ assert_equal('123 abc', q.params['foo'][0])
42
+
43
+ q_uri = 'foo=123+abc%2BABC'
44
+ q = UCQ.new(q_uri)
45
+ assert_equal(q_uri, q.to_uri)
46
+ assert_equal(1, q.params.size)
47
+ assert_equal(1, q.params['foo'].size)
48
+ assert_equal('123 abc+ABC', q.params['foo'][0])
49
+
50
+ q_uri = 'foo=1&bar=abc%40xyz&baz=123%20%00%2B789'
51
+ q = UCQ.new(q_uri)
52
+ assert_equal(q_uri.gsub('%20', '+'), q.to_uri)
53
+ assert_equal(3, q.params.size)
54
+ assert_equal(1, q.params['foo'].size)
55
+ assert_equal('1', q.params['foo'][0])
56
+ assert_equal(1, q.params['bar'].size)
57
+ assert_equal('abc@xyz', q.params['bar'][0])
58
+ assert_equal(1, q.params['baz'].size)
59
+ assert_equal("123 \x00+789", q.params['baz'][0])
60
+
61
+ q_uri = 'foo=1&bar=a&foo=2&bar=bb&bar=ccc'
62
+ q = UCQ.new(q_uri)
63
+ assert_equal('foo=1&foo=2&bar=a&bar=bb&bar=ccc', q.to_uri)
64
+ assert_equal(2, q.params.size)
65
+ assert_equal(2, q.params['foo'].size)
66
+ assert_equal('1', q.params['foo'][0])
67
+ assert_equal('2', q.params['foo'][1])
68
+ assert_equal(3, q.params['bar'].size)
69
+ assert_equal('a', q.params['bar'][0])
70
+ assert_equal('bb', q.params['bar'][1])
71
+ assert_equal('ccc', q.params['bar'][2])
72
+
73
+ q_uri = 'foo=1&foo&bar&baz=a'
74
+ q = UCQ.new(q_uri)
75
+ assert_equal(q_uri, q.to_uri)
76
+ assert_equal(3, q.params.size)
77
+ assert_equal(2, q.params['foo'].size)
78
+ assert_equal('1', q.params['foo'][0])
79
+ assert_nil(q.params['foo'][1])
80
+ assert_equal(1, q.params['bar'].size)
81
+ assert_nil(q.params['bar'][0])
82
+ assert_equal(1, q.params['baz'].size)
83
+ assert_equal('a', q.params['baz'][0])
84
+
85
+ q_uri = 'foo=1;bar=abc;baz=ABC'
86
+ q = UCQ.new(q_uri)
87
+ assert_equal(q_uri.gsub(';', '&'), q.to_uri)
88
+ assert_equal(q_uri, q.to_uri(';'))
89
+ assert_equal(3, q.params.size)
90
+ assert_equal(1, q.params['foo'].size)
91
+ assert_equal('1', q.params['foo'][0])
92
+ assert_equal(1, q.params['bar'].size)
93
+ assert_equal('abc', q.params['bar'][0])
94
+ assert_equal(1, q.params['baz'].size)
95
+ assert_equal('ABC', q.params['baz'][0])
96
+
97
+ assert_raise(URI::InvalidURIError) do
98
+ UCQ.new('foo bar')
99
+ end
100
+ end
101
+
102
+ def test_set
103
+ q = UCQ.new('')
104
+ q.params['foo'] = [1]
105
+ assert_equal('foo=1', q.to_uri)
106
+
107
+ q = UCQ.new('')
108
+ q.params['foo'] = [nil]
109
+ assert_equal('foo', q.to_uri)
110
+
111
+ q = UCQ.new('')
112
+ q.params['foo'] = ['123 abc']
113
+ assert_equal('foo=123+abc', q.to_uri)
114
+
115
+ q = UCQ.new('')
116
+ q.params['foo'] = ['123+abc']
117
+ assert_equal('foo=123%2Babc', q.to_uri)
118
+
119
+ q = UCQ.new('')
120
+ q.params['foo'] = [1]
121
+ q.params['bar'] = ['abc@xyz']
122
+ q.params['baz'] = ["123 \x00+789"]
123
+ assert_equal('foo=1&bar=abc%40xyz&baz=123+%00%2B789', q.to_uri)
124
+
125
+ q = UCQ.new('')
126
+ q.params['foo'] = [1, 2]
127
+ q.params['bar'] = ['a', 'bb', 'ccc']
128
+ assert_equal('foo=1&foo=2&bar=a&bar=bb&bar=ccc', q.to_uri)
129
+
130
+ q = UCQ.new('')
131
+ q.params['foo'] = [1, nil]
132
+ q.params['bar'] = [nil]
133
+ q.params['baz'] = ['a']
134
+ assert_equal('foo=1&foo&bar&baz=a', q.to_uri)
135
+
136
+ q = UCQ.new('')
137
+ q.params['foo'] = [1]
138
+ q.params['bar'] = ['abc']
139
+ q.params['baz'] = ['ABC']
140
+ assert_equal('foo=1;bar=abc;baz=ABC', q.to_uri(';'))
141
+ end
142
+
143
+ def test_mixin
144
+ UCQ.mixin(URI::HTTPS)
145
+
146
+ u_uri = 'https://example.jp/?foo=123%40example&bar=abc%20xyz'
147
+ u_uri_x = u_uri.gsub('+', '%2B').gsub('%20', '+')
148
+ u = URI.parse(u_uri)
149
+ q = u.query_component
150
+ assert_kind_of(UCQ, q)
151
+ assert_equal(u_uri_x, u.to_s)
152
+ assert_equal('foo=123%40example&bar=abc+xyz', u.query)
153
+ assert_equal('foo=123%40example&bar=abc+xyz', q.to_s)
154
+
155
+ q.params['baz'] = ['xxx']
156
+ assert_equal(u_uri_x + '&baz=xxx', u.to_s)
157
+ assert_equal('foo=123%40example&bar=abc+xyz&baz=xxx', u.query)
158
+ assert_equal('foo=123%40example&bar=abc+xyz&baz=xxx', q.to_s)
159
+
160
+ u_uri.sub!(/^https:/, 'http:')
161
+ u_uri_x = u_uri.gsub('+', '%2B').gsub('%20', '+')
162
+ u = URI.parse(u_uri)
163
+ assert_raise(NoMethodError) do
164
+ u.query_component
165
+ end
166
+
167
+ UCQ.mixin(URI::HTTP)
168
+ u = URI.parse(u_uri)
169
+ q = u.query_component
170
+ assert_kind_of(UCQ, q)
171
+ assert_equal(u_uri_x, u.to_s)
172
+ assert_equal('foo=123%40example&bar=abc+xyz', u.query)
173
+ assert_equal('foo=123%40example&bar=abc+xyz', q.to_s)
174
+ end
175
+ end
176
+
177
+ end
178
+ end
179
+
@@ -0,0 +1,158 @@
1
+ require 'test/unit'
2
+ require 'uri/component/userinfo'
3
+
4
+ UCUI = URI::Component::UserInfo
5
+
6
+ module URI
7
+ module Component
8
+
9
+ class TestUserInfoClass < Test::Unit::TestCase
10
+ def setup
11
+ end
12
+
13
+ def teardown
14
+ end
15
+
16
+ def test_parse
17
+ i = UCUI.new()
18
+ assert_nil(i.to_uri)
19
+ assert_nil(i.domain)
20
+ assert_nil(i.user)
21
+ assert_nil(i.password)
22
+
23
+ i_uri = 'user%20name'
24
+ i = UCUI.new(i_uri)
25
+ assert_equal(i_uri, i.to_uri)
26
+ assert_nil(i.domain)
27
+ assert_equal('user name', i.user)
28
+ assert_nil(i.password)
29
+
30
+ i_uri = 'user%20name:p%40ssword'
31
+ i = UCUI.new(i_uri)
32
+ assert_equal(i_uri, i.to_uri)
33
+ assert_nil(i.domain)
34
+ assert_equal('user name', i.user)
35
+ assert_equal('p@ssword', i.password)
36
+
37
+ i_uri = 'domain%20name;user%20name'
38
+ i = UCUI.new(i_uri)
39
+ assert_equal(i_uri, i.to_uri)
40
+ assert_equal('domain name', i.domain)
41
+ assert_equal('user name', i.user)
42
+ assert_nil(i.password)
43
+
44
+ i_uri = 'domain%20name;user%20name:p%40ssword'
45
+ i = UCUI.new(i_uri)
46
+ assert_equal(i_uri, i.to_uri)
47
+ assert_equal('domain name', i.domain)
48
+ assert_equal('user name', i.user)
49
+ assert_equal('p@ssword', i.password)
50
+
51
+ %w(foo/bar1 foo@bar2 foo?bar3 foo:bar:baz4 foo;bar;baz5).each do |info_str|
52
+ assert_raise(URI::InvalidURIError) do
53
+ UCUI.new(info_str)
54
+ raise info_str
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_modify
60
+ i = UCUI.new('domain%5Fname;user%20name:p%40ssword')
61
+
62
+ i.domain = 'domain2'
63
+ assert_equal('domain2', i.domain)
64
+ assert_equal('domain2;user%20name:p%40ssword', i.to_uri)
65
+ i.domain = nil
66
+ assert_nil(i.domain)
67
+ assert_equal('user%20name:p%40ssword', i.to_uri)
68
+
69
+ i.password = 'password2'
70
+ assert_equal('password2', i.password)
71
+ assert_equal('user%20name:password2', i.to_uri)
72
+ i.password = nil
73
+ assert_nil(i.password)
74
+ assert_equal('user%20name', i.to_uri)
75
+
76
+ i.domain = 'domain %20_3'
77
+ assert_equal('domain %20_3', i.domain)
78
+ assert_equal('domain%20%2520_3;user%20name', i.to_uri)
79
+
80
+ i.password = 'password %20_3'
81
+ assert_equal('password %20_3', i.password)
82
+ assert_equal('domain%20%2520_3;user%20name:password%20%2520_3', i.to_uri)
83
+
84
+ i.user = 'user2'
85
+ assert_equal('user2', i.user)
86
+ assert_equal('domain%20%2520_3;user2:password%20%2520_3', i.to_uri)
87
+ i.user = nil
88
+ assert_nil(i.user)
89
+ assert_nil(i.to_uri)
90
+
91
+ assert_raise(URI::InvalidURIError) do
92
+ i.domain = 'domain4'
93
+ end
94
+ assert_raise(URI::InvalidURIError) do
95
+ i.password = 'password4'
96
+ end
97
+
98
+ i.user = 'user %20_3'
99
+ assert_equal('user %20_3', i.user)
100
+ assert_equal('user%20%2520_3', i.to_uri)
101
+ end
102
+
103
+ def test_mixin
104
+ UCUI.mixin(URI::HTTPS)
105
+
106
+ u_uri = 'https://user%20name:p%40ssword@example.jp/'
107
+ u = URI.parse(u_uri)
108
+ i = u.userinfo_component
109
+ assert_kind_of(UCUI, i)
110
+ assert_equal('user%20name:p%40ssword', u.userinfo)
111
+ assert_equal('user%20name', u.user)
112
+ assert_equal('user name', i.user)
113
+ assert_equal('p%40ssword', u.password)
114
+ assert_equal('p@ssword', i.password)
115
+ assert_nil(i.domain)
116
+
117
+ u.user = 'user%2Fname'
118
+ assert_equal('user%2Fname:p%40ssword', u.userinfo)
119
+ assert_equal('user%2Fname', u.user)
120
+ assert_equal('user/name', i.user)
121
+ assert_nil(i.domain)
122
+
123
+ u.password = 'pass%2Fword'
124
+ assert_equal('user%2Fname:pass%2Fword', u.userinfo)
125
+ assert_equal('pass%2Fword', u.password)
126
+ assert_equal('pass/word', i.password)
127
+ assert_nil(i.domain)
128
+
129
+ u.user = 'domain;user%3Bname'
130
+ assert_equal('domain;user%3Bname:pass%2Fword', u.userinfo)
131
+ assert_equal('domain;user%3Bname', u.user)
132
+ assert_equal('domain', i.domain)
133
+ assert_equal('user;name', i.user)
134
+
135
+ assert_equal('https://domain;user%3Bname:pass%2Fword@example.jp/', u.to_s)
136
+
137
+ u_uri.sub!(/^https:/, 'http:')
138
+ u = URI.parse(u_uri)
139
+ assert_raise(NoMethodError) do
140
+ u.userinfo_component
141
+ end
142
+
143
+ UCUI.mixin(URI::HTTP)
144
+ u = URI.parse(u_uri)
145
+ i = u.userinfo_component
146
+ assert_kind_of(UCUI, i)
147
+ assert_equal('user%20name:p%40ssword', u.userinfo)
148
+ assert_equal('user%20name', u.user)
149
+ assert_equal('user name', i.user)
150
+ assert_equal('p%40ssword', u.password)
151
+ assert_equal('p@ssword', i.password)
152
+ assert_nil(i.domain)
153
+ end
154
+ end
155
+
156
+ end
157
+ end
158
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "uri/component/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "uri-component"
7
+ s.version = URI::Component::VERSION
8
+ s.authors = ["SATOH Fumiyasu"]
9
+ s.email = ["fumiyas@osstech.co.jp"]
10
+ s.homepage = "https://github.com/fumiyas/ruby-uri-component"
11
+ s.summary = %q{URI::Component::* classes}
12
+ s.description = %q{Handle URI components as an object}
13
+
14
+ s.rubyforge_project = "uri-component"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
21
+
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uri-component
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - SATOH Fumiyasu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-04 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Handle URI components as an object
15
+ email:
16
+ - fumiyas@osstech.co.jp
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - Gemfile
22
+ - Rakefile
23
+ - lib/uri/component/path.rb
24
+ - lib/uri/component/query.rb
25
+ - lib/uri/component/userinfo.rb
26
+ - lib/uri/component/version.rb
27
+ - test/test_component_path.rb
28
+ - test/test_component_query.rb
29
+ - test/test_component_userinfo.rb
30
+ - uri-compoment.gemspec
31
+ homepage: https://github.com/fumiyas/ruby-uri-component
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project: uri-component
51
+ rubygems_version: 1.8.11
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: URI::Component::* classes
55
+ test_files:
56
+ - test/test_component_path.rb
57
+ - test/test_component_query.rb
58
+ - test/test_component_userinfo.rb