accept_headers 0.0.6 → 0.0.7
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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +6 -0
- data/README.md +22 -8
- data/lib/accept_headers/language.rb +1 -1
- data/lib/accept_headers/media_type/negotiator.rb +15 -15
- data/lib/accept_headers/media_type.rb +12 -12
- data/lib/accept_headers/version.rb +1 -1
- data/spec/encoding_spec.rb +108 -102
- data/spec/language_spec.rb +161 -153
- data/spec/media_type/negotiator_spec.rb +9 -9
- data/spec/media_type_spec.rb +162 -156
- data/spec/spec_helper.rb +2 -0
- metadata +2 -2
data/spec/language_spec.rb
CHANGED
@@ -1,201 +1,204 @@
|
|
1
1
|
require_relative "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
3
|
+
describe AcceptHeaders::Language do
|
4
|
+
subject do
|
5
|
+
AcceptHeaders::Language
|
6
|
+
end
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
it "defaults primary tag to *" do
|
9
|
+
subject.new.primary_tag.must_equal '*'
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
it "defaults subtag to *" do
|
13
|
+
subject.new('en').subtag.must_equal '*'
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
it "strips and downcases the primary tag" do
|
17
|
+
subject.new("\t\nEN\s\r", '*').primary_tag.must_equal "en"
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
it "strips and downcases the subtag" do
|
21
|
+
subject.new("en", "\s\nUS\r\t").subtag.must_equal "us"
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
it "sets subtag to * if value passed in is nil and primary tag is *" do
|
25
|
+
subject.new('*', nil).subtag.must_equal '*'
|
26
|
+
end
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
it "optionally supports a q argument" do
|
29
|
+
subject.new('en', 'us', q: 0.8).q.must_equal 0.8
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
it "compares on q value all other values remaining equal" do
|
33
|
+
subject.new(q: 0.514).must_be :>, subject.new(q: 0.1)
|
34
|
+
subject.new(q: 0).must_be :<, subject.new(q: 1)
|
35
|
+
subject.new(q: 0.9).must_equal subject.new(q: 0.9)
|
36
|
+
end
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
it "compares on subtag then primary tag all other values remaining equal" do
|
39
|
+
subject.new('en', 'us').must_be :>, subject.new('en', '*')
|
40
|
+
subject.new('*', '*').must_be :<, subject.new('en', '*')
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
it "raises an InvalidQError if q can't be converted to a float" do
|
44
|
+
e = -> do
|
45
|
+
subject.new('en', 'us', q: 'a')
|
46
|
+
end.must_raise AcceptHeaders::Language::InvalidQError
|
47
|
+
|
48
|
+
e.message.must_match INVALID_FLOAT_PATTERN
|
49
|
+
|
50
|
+
subject.new('en', 'us', q: '1')
|
51
|
+
end
|
48
52
|
|
49
|
-
|
53
|
+
it "raises an InvalidQError unless q value is between 0 and 1" do
|
54
|
+
[-1.0, -0.1, 1.1].each do |q|
|
55
|
+
e = -> do
|
56
|
+
subject.new('en', 'us', q: q)
|
57
|
+
end.must_raise AcceptHeaders::Language::InvalidQError
|
50
58
|
|
51
|
-
|
59
|
+
e.message.must_equal "q must be between 0 and 1"
|
52
60
|
end
|
53
61
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
subject.new('en', 'us', q: q)
|
58
|
-
end.must_raise Language::InvalidQError
|
62
|
+
subject.new('en', 'us', q: 1)
|
63
|
+
subject.new('en', 'gb', q: 0)
|
64
|
+
end
|
59
65
|
|
60
|
-
|
61
|
-
|
66
|
+
it "raises an InvalidQError if q has more than a precision of 3" do
|
67
|
+
e = -> do
|
68
|
+
subject.new('en', 'us', q: 0.1234)
|
69
|
+
end.must_raise AcceptHeaders::Language::InvalidQError
|
62
70
|
|
63
|
-
|
64
|
-
|
71
|
+
e.message.must_equal "q must be at most 3 decimal places"
|
72
|
+
|
73
|
+
subject.new('en', 'us', q: 0.123)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "converts to hash" do
|
77
|
+
subject.new('en', 'us').to_h.must_equal({
|
78
|
+
primary_tag: 'en',
|
79
|
+
subtag: 'us',
|
80
|
+
q: 1.0
|
81
|
+
})
|
82
|
+
end
|
83
|
+
|
84
|
+
it "converts to string" do
|
85
|
+
s = subject.new('en', 'us', q: 0.9).to_s
|
86
|
+
s.must_equal "en-us;q=0.9"
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#language_tag" do
|
90
|
+
it "outputs the language tag" do
|
91
|
+
subject.new('en', 'us', q: 0.9).language_tag.must_equal "en-us"
|
65
92
|
end
|
66
93
|
|
67
|
-
it "
|
68
|
-
|
69
|
-
|
70
|
-
|
94
|
+
it "if primary tag is * and subtag is * or nil, outputs *" do
|
95
|
+
subject.new('*', nil).language_tag.must_equal '*'
|
96
|
+
subject.new('*', '*').language_tag.must_equal '*'
|
97
|
+
end
|
98
|
+
end
|
71
99
|
|
72
|
-
|
100
|
+
describe "#accept?" do
|
101
|
+
it "accepted if the primary_tag and subtag are the same" do
|
102
|
+
a = subject.new('en', 'us')
|
103
|
+
a.accept?('en-us').must_equal true
|
104
|
+
b = subject.new('en', 'us', q: 0.001)
|
105
|
+
b.accept?('en-us').must_equal true
|
106
|
+
end
|
73
107
|
|
74
|
-
|
108
|
+
it "accepted if the primary_tag is the same and the other subtag is *" do
|
109
|
+
a = subject.new('en', '*')
|
110
|
+
a.accept?('en-us').must_equal true
|
111
|
+
b = subject.new('en', '*', q: 0.9)
|
112
|
+
b.accept?('en-us').must_equal true
|
75
113
|
end
|
76
114
|
|
77
|
-
it "
|
78
|
-
subject.new('
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
})
|
115
|
+
it "accepted if the primary_tag and subtag are *" do
|
116
|
+
a = subject.new('*')
|
117
|
+
a.accept?('en-us').must_equal true
|
118
|
+
b = subject.new('*', q: 0.1)
|
119
|
+
b.accept?('en-us').must_equal true
|
83
120
|
end
|
84
121
|
|
85
|
-
it "
|
86
|
-
|
87
|
-
|
122
|
+
it "not accepted if the primary_tag and subtag don't match" do
|
123
|
+
a = subject.new('en', 'us')
|
124
|
+
a.accept?('en-gb').must_equal false
|
125
|
+
b = subject.new('en', 'us', q: 0.2)
|
126
|
+
b.accept?('en-gb').must_equal false
|
88
127
|
end
|
89
128
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
129
|
+
it "not accepted if the primary_tag doesn't match" do
|
130
|
+
a = subject.new('en', 'us')
|
131
|
+
a.accept?('zh-us').must_equal false
|
132
|
+
b = subject.new('en', 'us', q: 0.4)
|
133
|
+
b.accept?('zh-us').must_equal false
|
134
|
+
end
|
94
135
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
136
|
+
it "not accepted if the subtag doesn't match" do
|
137
|
+
a = subject.new('en', 'us')
|
138
|
+
a.accept?('en-gb').must_equal false
|
139
|
+
b = subject.new('en', 'us', q: 0.6)
|
140
|
+
b.accept?('en-gb').must_equal false
|
99
141
|
end
|
100
142
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
143
|
+
it "not accepted if q is 0" do
|
144
|
+
a = subject.new('en', 'us', q: 0)
|
145
|
+
a.accept?('en-us').must_equal false
|
146
|
+
a.accept?('en-gb').must_equal false
|
147
|
+
a.accept?('zh-us').must_equal false
|
148
|
+
b = subject.new('en', '*', q: 0)
|
149
|
+
b.accept?('en-us').must_equal false
|
150
|
+
c = subject.new('*', q: 0)
|
151
|
+
c.accept?('en-us').must_equal false
|
152
|
+
end
|
108
153
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
b.accept?('en-us').must_equal true
|
114
|
-
end
|
154
|
+
it "not accepted compared against nil" do
|
155
|
+
a = subject.new('en', 'us')
|
156
|
+
a.accept?(nil).must_equal false
|
157
|
+
end
|
115
158
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
159
|
+
# TODO: test *
|
160
|
+
it "not accepted if..." do
|
161
|
+
a = subject.new('en', 'us')
|
162
|
+
a.accept?('*').must_equal false
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#reject?" do
|
167
|
+
describe "given q is 0" do
|
168
|
+
it "rejected if the primary_tag and subtag are the same" do
|
169
|
+
a = subject.new('en', 'us', q: 0)
|
170
|
+
a.reject?('en-us').must_equal true
|
121
171
|
end
|
122
172
|
|
123
|
-
it "
|
124
|
-
a = subject.new('en', '
|
125
|
-
a.
|
126
|
-
b = subject.new('en', 'us', q: 0.2)
|
127
|
-
b.accept?('en-gb').must_equal false
|
173
|
+
it "rejected if the primary_tag is the same and the other subtag is *" do
|
174
|
+
a = subject.new('en', '*', q: 0)
|
175
|
+
a.reject?('en-us').must_equal true
|
128
176
|
end
|
129
177
|
|
130
|
-
it "
|
131
|
-
a = subject.new('
|
132
|
-
a.
|
133
|
-
b = subject.new('en', 'us', q: 0.4)
|
134
|
-
b.accept?('zh-us').must_equal false
|
178
|
+
it "rejected if the primary_tag and subtag are *" do
|
179
|
+
a = subject.new('*', q: 0)
|
180
|
+
a.reject?('en-us').must_equal true
|
135
181
|
end
|
136
182
|
|
137
|
-
it "not
|
138
|
-
a = subject.new('en', 'us')
|
139
|
-
a.
|
140
|
-
b = subject.new('en', 'us', q: 0.6)
|
141
|
-
b.accept?('en-gb').must_equal false
|
183
|
+
it "not rejected if the primary_tag and subtag don't match" do
|
184
|
+
a = subject.new('en', 'us', q: 0)
|
185
|
+
a.reject?('en-gb').must_equal false
|
142
186
|
end
|
143
187
|
|
144
|
-
it "not
|
188
|
+
it "not rejected if the primary_tag doesn't match" do
|
145
189
|
a = subject.new('en', 'us', q: 0)
|
146
|
-
a.
|
147
|
-
a.accept?('en-gb').must_equal false
|
148
|
-
a.accept?('zh-us').must_equal false
|
149
|
-
b = subject.new('en', '*', q: 0)
|
150
|
-
b.accept?('en-us').must_equal false
|
151
|
-
c = subject.new('*', q: 0)
|
152
|
-
c.accept?('en-us').must_equal false
|
190
|
+
a.reject?('zh-us').must_equal false
|
153
191
|
end
|
154
192
|
|
155
|
-
|
156
|
-
|
157
|
-
a
|
158
|
-
a.accept?('*').must_equal false
|
193
|
+
it "not rejected if the subtag doesn't match" do
|
194
|
+
a = subject.new('en', 'us', q: 0)
|
195
|
+
a.reject?('en-gb').must_equal false
|
159
196
|
end
|
160
|
-
end
|
161
197
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
a.reject?('en-us').must_equal true
|
167
|
-
end
|
168
|
-
|
169
|
-
it "rejected if the primary_tag is the same and the other subtag is *" do
|
170
|
-
a = subject.new('en', '*', q: 0)
|
171
|
-
a.reject?('en-us').must_equal true
|
172
|
-
end
|
173
|
-
|
174
|
-
it "rejected if the primary_tag and subtag are *" do
|
175
|
-
a = subject.new('*', q: 0)
|
176
|
-
a.reject?('en-us').must_equal true
|
177
|
-
end
|
178
|
-
|
179
|
-
it "not rejected if the primary_tag and subtag don't match" do
|
180
|
-
a = subject.new('en', 'us', q: 0)
|
181
|
-
a.reject?('en-gb').must_equal false
|
182
|
-
end
|
183
|
-
|
184
|
-
it "not rejected if the primary_tag doesn't match" do
|
185
|
-
a = subject.new('en', 'us', q: 0)
|
186
|
-
a.reject?('zh-us').must_equal false
|
187
|
-
end
|
188
|
-
|
189
|
-
it "not rejected if the subtag doesn't match" do
|
190
|
-
a = subject.new('en', 'us', q: 0)
|
191
|
-
a.reject?('en-gb').must_equal false
|
192
|
-
end
|
193
|
-
|
194
|
-
# TODO: test *
|
195
|
-
it "not rejected if..." do
|
196
|
-
a = subject.new('en', 'us', q: 0)
|
197
|
-
a.reject?('*').must_equal false
|
198
|
-
end
|
198
|
+
# TODO: test *
|
199
|
+
it "not rejected if..." do
|
200
|
+
a = subject.new('en', 'us', q: 0)
|
201
|
+
a.reject?('*').must_equal false
|
199
202
|
end
|
200
203
|
|
201
204
|
it "not rejected if q > 0" do
|
@@ -208,6 +211,11 @@ module AcceptHeaders
|
|
208
211
|
c = subject.new('*', q: 1)
|
209
212
|
c.reject?('en-us').must_equal false
|
210
213
|
end
|
214
|
+
|
215
|
+
it "not rejected compared against nil" do
|
216
|
+
a = subject.new('en', 'us')
|
217
|
+
a.reject?(nil).must_equal false
|
218
|
+
end
|
211
219
|
end
|
212
220
|
end
|
213
221
|
end
|
@@ -18,17 +18,17 @@ describe AcceptHeaders::MediaType::Negotiator do
|
|
18
18
|
]
|
19
19
|
|
20
20
|
subject.new("text/*, text/html, text/html;level=1, */*").list.must_equal [
|
21
|
-
media_type.new('text', 'html',
|
21
|
+
media_type.new('text', 'html', extensions: { 'level' => '1' }),
|
22
22
|
media_type.new('text', 'html'),
|
23
23
|
media_type.new('text', '*'),
|
24
24
|
media_type.new('*', '*')
|
25
25
|
]
|
26
26
|
|
27
27
|
subject.new("text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5").list.must_equal [
|
28
|
-
media_type.new('text', 'html',
|
28
|
+
media_type.new('text', 'html', extensions: { 'level' => '1' }),
|
29
29
|
media_type.new('text', 'html', q: 0.7),
|
30
30
|
media_type.new('*', '*', q: 0.5),
|
31
|
-
media_type.new('text', 'html', q: 0.4,
|
31
|
+
media_type.new('text', 'html', q: 0.4, extensions: { 'level' => '2' }),
|
32
32
|
media_type.new('text', '*', q: 0.3)
|
33
33
|
]
|
34
34
|
end
|
@@ -79,10 +79,10 @@ describe AcceptHeaders::MediaType::Negotiator do
|
|
79
79
|
]
|
80
80
|
end
|
81
81
|
|
82
|
-
it "strips whitespace around q and
|
82
|
+
it "strips whitespace around q and extensions" do
|
83
83
|
subject.new("text/plain;\tq\r=\n1, application/json;q=0.8;\slevel\t\t=\r\n1\n").list.must_equal [
|
84
84
|
media_type.new('text', 'plain'),
|
85
|
-
media_type.new('application', 'json', q: 0.8,
|
85
|
+
media_type.new('application', 'json', q: 0.8, extensions: { "level" => "1" })
|
86
86
|
]
|
87
87
|
end
|
88
88
|
|
@@ -92,10 +92,10 @@ describe AcceptHeaders::MediaType::Negotiator do
|
|
92
92
|
]
|
93
93
|
end
|
94
94
|
|
95
|
-
it "parses
|
95
|
+
it "parses extensions with quoted values" do
|
96
96
|
subject.new('text/html;q=1;version="2";level="a;b;cc\'cd", text/html;version=\'1\';level=\'\blah;x;1;;\'').list.must_equal [
|
97
|
-
media_type.new('text', 'html',
|
98
|
-
media_type.new('text', 'html',
|
97
|
+
media_type.new('text', 'html', extensions: { 'version' => '2', 'level' => 'a;b;cc\'cd'}),
|
98
|
+
media_type.new('text', 'html', extensions: { 'version' => '1', 'level' => '\'\blah;x;1;;\''})
|
99
99
|
]
|
100
100
|
end
|
101
101
|
|
@@ -146,7 +146,7 @@ describe AcceptHeaders::MediaType::Negotiator do
|
|
146
146
|
api.negotiate('application/xml').must_be_nil
|
147
147
|
api.negotiate(['application/xml', 'application/json']).must_equal({
|
148
148
|
supported: 'application/json',
|
149
|
-
matched: media_type.new('application', 'json',
|
149
|
+
matched: media_type.new('application', 'json', extensions: { 'version' => '2' })
|
150
150
|
})
|
151
151
|
|
152
152
|
q0 = subject.new('application/json,application/xml;q=0')
|