mime-types 1.16 → 3.5.2
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 +7 -0
- data/.standard.yml +4 -0
- data/Code-of-Conduct.md +73 -0
- data/Contributing.md +133 -0
- data/History.md +335 -0
- data/Licence.md +25 -0
- data/Manifest.txt +27 -7
- data/README.rdoc +194 -0
- data/Rakefile +191 -278
- data/lib/mime/type/columnar.rb +57 -0
- data/lib/mime/type.rb +660 -0
- data/lib/mime/types/_columnar.rb +137 -0
- data/lib/mime/types/cache.rb +54 -0
- data/lib/mime/types/columnar.rb +3 -0
- data/lib/mime/types/container.rb +96 -0
- data/lib/mime/types/deprecations.rb +36 -0
- data/lib/mime/types/full.rb +19 -0
- data/lib/mime/types/loader.rb +159 -0
- data/lib/mime/types/logger.rb +37 -0
- data/lib/mime/types/registry.rb +90 -0
- data/lib/mime/types.rb +197 -715
- data/lib/mime-types.rb +3 -0
- data/test/bad-fixtures/malformed +9 -0
- data/test/fixture/json.json +1 -0
- data/test/fixture/old-data +9 -0
- data/test/fixture/yaml.yaml +55 -0
- data/test/minitest_helper.rb +10 -0
- data/test/test_mime_type.rb +585 -284
- data/test/test_mime_types.rb +134 -83
- data/test/test_mime_types_cache.rb +118 -0
- data/test/test_mime_types_class.rb +164 -0
- data/test/test_mime_types_lazy.rb +49 -0
- data/test/test_mime_types_loader.rb +32 -0
- metadata +295 -110
- data/History.txt +0 -107
- data/Install.txt +0 -17
- data/Licence.txt +0 -15
- data/README.txt +0 -28
- data/lib/mime/types.rb.data +0 -1324
- data/mime-types.gemspec +0 -43
- data/setup.rb +0 -1585
- data.tar.gz.sig +0 -2
- metadata.gz.sig +0 -0
data/test/test_mime_type.rb
CHANGED
@@ -1,356 +1,657 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mime/types"
|
4
|
+
require "minitest_helper"
|
5
|
+
|
6
|
+
describe MIME::Type do
|
7
|
+
def mime_type(content_type)
|
8
|
+
MIME::Type.new(content_type) { |mt| yield mt if block_given? }
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:x_appl_x_zip) {
|
12
|
+
mime_type("x-appl/x-zip") { |t| t.extensions = %w[zip zp] }
|
13
|
+
}
|
14
|
+
let(:text_plain) { mime_type("text/plain") }
|
15
|
+
let(:text_html) { mime_type("text/html") }
|
16
|
+
let(:image_jpeg) { mime_type("image/jpeg") }
|
17
|
+
let(:application_javascript) {
|
18
|
+
mime_type("application/javascript") do |js|
|
19
|
+
js.friendly("en" => "JavaScript")
|
20
|
+
js.xrefs = {
|
21
|
+
"rfc" => %w[rfc4239 rfc4239],
|
22
|
+
"template" => %w[application/javascript]
|
23
|
+
}
|
24
|
+
js.encoding = "8bit"
|
25
|
+
js.extensions = %w[js sj]
|
26
|
+
js.registered = true
|
27
|
+
end
|
28
|
+
}
|
29
|
+
let(:text_x_yaml) {
|
30
|
+
mime_type("text/x-yaml") do |yaml|
|
31
|
+
yaml.extensions = %w[yaml yml]
|
32
|
+
yaml.encoding = "8bit"
|
33
|
+
yaml.friendly("en" => "YAML Structured Document")
|
34
|
+
end
|
35
|
+
}
|
36
|
+
let(:text_x_yaml_with_docs) {
|
37
|
+
text_x_yaml.dup.tap do |yaml|
|
38
|
+
yaml.docs = "Test YAML"
|
30
39
|
end
|
40
|
+
}
|
31
41
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
'Content-Transfer-Encoding' => '8bit',
|
36
|
-
'System' => 'linux',
|
37
|
-
'Extensions' => %w(yaml yml))
|
38
|
-
end
|
39
|
-
assert_instance_of(MIME::Type, @yaml)
|
40
|
-
assert_equal('text/yaml', @yaml.simplified)
|
42
|
+
describe ".simplified" do
|
43
|
+
it "leaves normal types alone" do
|
44
|
+
assert_equal "text/plain", MIME::Type.simplified("text/plain")
|
41
45
|
end
|
42
46
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
assert_equal
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
assert(MIME::Type.new('application/x-msword').binary?)
|
89
|
-
assert(!MIME::Type.new('text/vCard').binary?)
|
90
|
-
assert(MIME::Type.new('application/pkcs7-mime').binary?)
|
91
|
-
assert(@zip.binary?)
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_complete_eh
|
95
|
-
assert_nothing_raised do
|
96
|
-
@yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
|
97
|
-
'linux')
|
47
|
+
it "does not remove x- prefixes by default" do
|
48
|
+
assert_equal "application/x-msword",
|
49
|
+
MIME::Type.simplified("application/x-msword")
|
50
|
+
assert_equal "x-xyz/abc", MIME::Type.simplified("x-xyz/abc")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "removes x- prefixes when requested" do
|
54
|
+
assert_equal "application/msword",
|
55
|
+
MIME::Type.simplified("application/x-msword", remove_x_prefix: true)
|
56
|
+
assert_equal "xyz/abc",
|
57
|
+
MIME::Type.simplified("x-xyz/abc", remove_x_prefix: true)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "lowercases mixed-case types" do
|
61
|
+
assert_equal "text/vcard", MIME::Type.simplified("text/vCard")
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns nil when the value provided is not a valid content type" do
|
65
|
+
assert_nil MIME::Type.simplified("text")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe ".i18n_key" do
|
70
|
+
it "converts text/plain to text.plain" do
|
71
|
+
assert_equal "text.plain", MIME::Type.i18n_key("text/plain")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "does not remove x-prefixes" do
|
75
|
+
assert_equal "application.x-msword",
|
76
|
+
MIME::Type.i18n_key("application/x-msword")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "converts text/vCard to text.vcard" do
|
80
|
+
assert_equal "text.vcard", MIME::Type.i18n_key("text/vCard")
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns nil when the value provided is not a valid content type" do
|
84
|
+
assert_nil MIME::Type.i18n_key("text")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe ".new" do
|
89
|
+
it "fails if an invalid content type is provided" do
|
90
|
+
exception = assert_raises MIME::Type::InvalidContentType do
|
91
|
+
MIME::Type.new("apps")
|
98
92
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
assert_equal
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
def test_encoding
|
114
|
-
assert_equal(MIME::Type.new('text/plain').encoding, 'quoted-printable')
|
115
|
-
assert_equal(MIME::Type.new('image/jpeg').encoding, 'base64')
|
116
|
-
assert_equal(MIME::Type.new('application/x-msword').encoding, 'base64')
|
117
|
-
assert_equal(MIME::Type.new('text/vCard').encoding, 'quoted-printable')
|
118
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').encoding, 'base64')
|
119
|
-
assert_nothing_raised do
|
120
|
-
@yaml = MIME::Type.from_array('text/x-yaml', %w(yaml yml), '8bit',
|
121
|
-
'linux')
|
93
|
+
assert_equal 'Invalid Content-Type "apps"', exception.to_s
|
94
|
+
end
|
95
|
+
|
96
|
+
it "creates a valid content type just from a string" do
|
97
|
+
type = MIME::Type.new("text/x-yaml")
|
98
|
+
|
99
|
+
assert_instance_of MIME::Type, type
|
100
|
+
assert_equal "text/x-yaml", type.content_type
|
101
|
+
end
|
102
|
+
|
103
|
+
it "yields the content type in a block" do
|
104
|
+
MIME::Type.new("text/x-yaml") do |type|
|
105
|
+
assert_instance_of MIME::Type, type
|
106
|
+
assert_equal "text/x-yaml", type.content_type
|
122
107
|
end
|
123
|
-
assert_equal(@yaml.encoding, '8bit')
|
124
|
-
assert_nothing_raised { @yaml.encoding = 'base64' }
|
125
|
-
assert_equal(@yaml.encoding, 'base64')
|
126
|
-
assert_nothing_raised { @yaml.encoding = :default }
|
127
|
-
assert_equal(@yaml.encoding, 'quoted-printable')
|
128
|
-
assert_raises(ArgumentError) { @yaml.encoding = 'binary' }
|
129
|
-
assert_equal(@zip.encoding, 'base64')
|
130
108
|
end
|
131
109
|
|
132
|
-
|
133
|
-
|
110
|
+
it "creates a valid content type from a hash" do
|
111
|
+
type = MIME::Type.new(
|
112
|
+
"content-type" => "text/x-yaml",
|
113
|
+
"obsolete" => true
|
114
|
+
)
|
115
|
+
assert_instance_of MIME::Type, type
|
116
|
+
assert_equal "text/x-yaml", type.content_type
|
117
|
+
assert type.obsolete?
|
134
118
|
end
|
135
119
|
|
136
|
-
|
137
|
-
|
120
|
+
it "creates a valid content type from an array" do
|
121
|
+
type = MIME::Type.new(%w[text/x-yaml yaml yml yz])
|
122
|
+
assert_instance_of MIME::Type, type
|
123
|
+
assert_equal "text/x-yaml", type.content_type
|
124
|
+
assert_equal %w[yaml yml yz], type.extensions
|
138
125
|
end
|
126
|
+
end
|
139
127
|
|
140
|
-
|
141
|
-
|
128
|
+
describe "#like?" do
|
129
|
+
it "compares two MIME::Types on #simplified values without x- prefixes" do
|
130
|
+
assert text_plain.like?(text_plain)
|
131
|
+
refute text_plain.like?(text_html)
|
142
132
|
end
|
143
133
|
|
144
|
-
|
145
|
-
assert
|
146
|
-
|
147
|
-
assert(!MIME::Type.new('text/plain').eql?('text/plain'))
|
148
|
-
assert(!MIME::Type.new('text/plain').eql?('image/jpeg'))
|
134
|
+
it "compares MIME::Type against string without x- prefixes" do
|
135
|
+
assert text_plain.like?(text_plain.to_s)
|
136
|
+
refute text_plain.like?(text_html.to_s)
|
149
137
|
end
|
138
|
+
end
|
150
139
|
|
151
|
-
|
152
|
-
|
140
|
+
describe "#<=>" do
|
141
|
+
it "correctly compares identical types" do
|
142
|
+
assert_equal text_plain, text_plain
|
153
143
|
end
|
154
144
|
|
155
|
-
|
156
|
-
|
145
|
+
it "correctly compares equivalent types" do
|
146
|
+
right = mime_type("text/Plain")
|
147
|
+
refute_same text_plain, right
|
148
|
+
assert_equal text_plain, right
|
157
149
|
end
|
158
150
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
'linux')
|
163
|
-
end
|
164
|
-
assert_equal(@yaml.extensions, %w(yaml yml))
|
165
|
-
assert_nothing_raised { @yaml.extensions = 'yaml' }
|
166
|
-
assert_equal(@yaml.extensions, ['yaml'])
|
167
|
-
assert_equal(@zip.extensions.size, 2)
|
168
|
-
assert_equal(@zip.extensions, ['zip', 'zp'])
|
151
|
+
it "correctly compares types that sort earlier" do
|
152
|
+
refute_equal text_html, text_plain
|
153
|
+
assert_operator text_html, :<, text_plain
|
169
154
|
end
|
170
155
|
|
171
|
-
|
172
|
-
|
156
|
+
it "correctly compares types that sort later" do
|
157
|
+
refute_equal text_plain, text_html
|
158
|
+
assert_operator text_plain, :>, text_html
|
173
159
|
end
|
174
160
|
|
175
|
-
|
176
|
-
|
177
|
-
assert(MIME::Type.new('text/plain').like?(MIME::Type.new('text/x-plain')))
|
178
|
-
assert(!MIME::Type.new('text/plain').like?(MIME::Type.new('image/jpeg')))
|
179
|
-
assert(MIME::Type.new('text/plain').like?('text/plain'))
|
180
|
-
assert(MIME::Type.new('text/plain').like?('text/x-plain'))
|
181
|
-
assert(!MIME::Type.new('text/plain').like?('image/jpeg'))
|
161
|
+
it "correctly compares types against equivalent strings" do
|
162
|
+
assert_equal text_plain, "text/plain"
|
182
163
|
end
|
183
164
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
assert_equal(MIME::Type.new('application/x-msword').media_type, 'application')
|
188
|
-
assert_equal(MIME::Type.new('text/vCard').media_type, 'text')
|
189
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').media_type, 'application')
|
190
|
-
assert_equal(MIME::Type.new('x-chemical/x-pdb').media_type, 'chemical')
|
191
|
-
assert_equal(@zip.media_type, 'appl')
|
165
|
+
it "correctly compares types against strings that sort earlier" do
|
166
|
+
refute_equal text_html, "text/plain"
|
167
|
+
assert_operator text_html, :<, "text/plain"
|
192
168
|
end
|
193
169
|
|
194
|
-
|
195
|
-
|
170
|
+
it "correctly compares types against strings that sort later" do
|
171
|
+
refute_equal text_plain, "text/html"
|
172
|
+
assert_operator text_plain, :>, "text/html"
|
196
173
|
end
|
197
174
|
|
198
|
-
|
199
|
-
|
175
|
+
it "correctly compares against nil" do
|
176
|
+
refute_equal text_html, nil
|
177
|
+
assert_operator text_plain, :<, nil
|
200
178
|
end
|
179
|
+
end
|
201
180
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
'oddbox')
|
206
|
-
end
|
207
|
-
assert(!@yaml.platform?)
|
208
|
-
assert_nothing_raised { @yaml.system = nil }
|
209
|
-
assert(!@yaml.platform?)
|
210
|
-
assert_nothing_raised { @yaml.system = /#{RUBY_PLATFORM}/ }
|
211
|
-
assert(@yaml.platform?)
|
181
|
+
describe "#ascii?" do
|
182
|
+
it "defaults to true for text/* types" do
|
183
|
+
assert text_plain.ascii?
|
212
184
|
end
|
213
185
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
assert_equal(MIME::Type.new('text/vCard').raw_media_type, 'text')
|
219
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').raw_media_type, 'application')
|
186
|
+
it "defaults to false for non-text/* types" do
|
187
|
+
refute image_jpeg.ascii?
|
188
|
+
end
|
189
|
+
end
|
220
190
|
|
221
|
-
|
222
|
-
|
191
|
+
describe "#binary?" do
|
192
|
+
it "defaults to false for text/* types" do
|
193
|
+
refute text_plain.binary?
|
223
194
|
end
|
224
195
|
|
225
|
-
|
226
|
-
|
227
|
-
assert_equal(MIME::Type.new('image/jpeg').raw_sub_type, 'jpeg')
|
228
|
-
assert_equal(MIME::Type.new('application/x-msword').raw_sub_type, 'x-msword')
|
229
|
-
assert_equal(MIME::Type.new('text/vCard').raw_sub_type, 'vCard')
|
230
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').raw_sub_type, 'pkcs7-mime')
|
231
|
-
assert_equal(@zip.raw_sub_type, 'x-zip')
|
196
|
+
it "defaults to true for non-text/* types" do
|
197
|
+
assert image_jpeg.binary?
|
232
198
|
end
|
199
|
+
end
|
233
200
|
|
234
|
-
|
235
|
-
|
236
|
-
assert
|
237
|
-
assert(!MIME::Type.new('application/x-msword').registered?)
|
238
|
-
assert(MIME::Type.new('text/vCard').registered?)
|
239
|
-
assert(MIME::Type.new('application/pkcs7-mime').registered?)
|
240
|
-
assert(!@zip.registered?)
|
201
|
+
describe "#complete?" do
|
202
|
+
it "is true when there are extensions" do
|
203
|
+
assert text_x_yaml.complete?
|
241
204
|
end
|
242
205
|
|
243
|
-
|
244
|
-
|
206
|
+
it "is false when there are no extensions" do
|
207
|
+
refute mime_type("text/plain").complete?
|
245
208
|
end
|
209
|
+
end
|
246
210
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
assert(MIME::Type.new('text/vCard').signature?)
|
252
|
-
assert(MIME::Type.new('application/pkcs7-mime').signature?)
|
211
|
+
describe "#content_type" do
|
212
|
+
it "preserves the original case" do
|
213
|
+
assert_equal "text/plain", text_plain.content_type
|
214
|
+
assert_equal "text/vCard", mime_type("text/vCard").content_type
|
253
215
|
end
|
254
216
|
|
255
|
-
|
256
|
-
assert_equal
|
257
|
-
assert_equal(MIME::Type.new('image/jpeg').simplified, 'image/jpeg')
|
258
|
-
assert_equal(MIME::Type.new('application/x-msword').simplified, 'application/msword')
|
259
|
-
assert_equal(MIME::Type.new('text/vCard').simplified, 'text/vcard')
|
260
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').simplified, 'application/pkcs7-mime')
|
261
|
-
assert_equal(MIME::Type.new('x-chemical/x-pdb').simplified, 'chemical/pdb')
|
217
|
+
it "does not remove x- prefixes" do
|
218
|
+
assert_equal "x-appl/x-zip", x_appl_x_zip.content_type
|
262
219
|
end
|
220
|
+
end
|
263
221
|
|
264
|
-
|
265
|
-
|
266
|
-
assert_equal
|
267
|
-
assert_equal(MIME::Type.new('application/x-msword').sub_type, 'msword')
|
268
|
-
assert_equal(MIME::Type.new('text/vCard').sub_type, 'vcard')
|
269
|
-
assert_equal(MIME::Type.new('application/pkcs7-mime').sub_type, 'pkcs7-mime')
|
270
|
-
assert_equal(@zip.sub_type, 'zip')
|
222
|
+
describe "#default_encoding" do
|
223
|
+
it "is quoted-printable for text/* types" do
|
224
|
+
assert_equal "quoted-printable", text_plain.default_encoding
|
271
225
|
end
|
272
226
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
assert_equal
|
281
|
-
|
282
|
-
assert_nil(@yaml.system)
|
227
|
+
it "is base64 for non-text/* types" do
|
228
|
+
assert_equal "base64", image_jpeg.default_encoding
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "#encoding, #encoding=" do
|
233
|
+
it "returns #default_encoding if not set explicitly" do
|
234
|
+
assert_equal "quoted-printable", text_plain.encoding
|
235
|
+
assert_equal "base64", image_jpeg.encoding
|
283
236
|
end
|
284
237
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
238
|
+
it "returns the set value when set" do
|
239
|
+
text_plain.encoding = "8bit"
|
240
|
+
assert_equal "8bit", text_plain.encoding
|
241
|
+
end
|
242
|
+
|
243
|
+
it "resets to the default encoding when set to nil or :default" do
|
244
|
+
text_plain.encoding = "8bit"
|
245
|
+
text_plain.encoding = nil
|
246
|
+
assert_equal text_plain.default_encoding, text_plain.encoding
|
247
|
+
text_plain.encoding = :default
|
248
|
+
assert_equal text_plain.default_encoding, text_plain.encoding
|
249
|
+
end
|
250
|
+
|
251
|
+
it "raises a MIME::Type::InvalidEncoding for an invalid encoding" do
|
252
|
+
exception = assert_raises MIME::Type::InvalidEncoding do
|
253
|
+
text_plain.encoding = "binary"
|
289
254
|
end
|
290
|
-
|
291
|
-
|
292
|
-
|
255
|
+
assert_equal 'Invalid Encoding "binary"', exception.to_s
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe "#eql?" do
|
260
|
+
it "is not true for a non-MIME::Type" do
|
261
|
+
refute text_plain.eql?("text/plain")
|
262
|
+
end
|
263
|
+
|
264
|
+
it "is not true for a different MIME::Type" do
|
265
|
+
refute text_plain.eql?(image_jpeg)
|
266
|
+
end
|
267
|
+
|
268
|
+
it "is true for an equivalent MIME::Type" do
|
269
|
+
assert text_plain.eql?(mime_type("text/Plain"))
|
270
|
+
end
|
271
|
+
|
272
|
+
it "is true for an equivalent subclass of MIME::Type" do
|
273
|
+
subclass = Class.new(MIME::Type)
|
274
|
+
assert text_plain.eql?(subclass.new("text/plain"))
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "#hash" do
|
279
|
+
it "is the same between #eql? MIME::Type instances" do
|
280
|
+
assert_equal text_plain.hash, mime_type("text/plain").hash
|
281
|
+
end
|
282
|
+
|
283
|
+
it "is the same between #eql? MIME::Type instances of different classes" do
|
284
|
+
subclass = Class.new(MIME::Type)
|
285
|
+
assert_equal text_plain.hash, subclass.new("text/plain").hash
|
286
|
+
end
|
287
|
+
|
288
|
+
it "uses the #simplified value" do
|
289
|
+
assert_equal text_plain.hash, mime_type("text/Plain").hash
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "#extensions, #extensions=" do
|
294
|
+
it "returns an array of extensions" do
|
295
|
+
assert_equal %w[yaml yml], text_x_yaml.extensions
|
296
|
+
assert_equal %w[zip zp], x_appl_x_zip.extensions
|
297
|
+
end
|
298
|
+
|
299
|
+
it "sets a single extension when provided a single value" do
|
300
|
+
text_x_yaml.extensions = "yaml"
|
301
|
+
assert_equal %w[yaml], text_x_yaml.extensions
|
302
|
+
end
|
303
|
+
|
304
|
+
it "deduplicates extensions" do
|
305
|
+
text_x_yaml.extensions = %w[yaml yaml]
|
306
|
+
assert_equal %w[yaml], text_x_yaml.extensions
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "#add_extensions" do
|
311
|
+
it "does not modify extensions when provided nil" do
|
312
|
+
text_x_yaml.add_extensions(nil)
|
313
|
+
assert_equal %w[yaml yml], text_x_yaml.extensions
|
314
|
+
end
|
315
|
+
|
316
|
+
it "remains deduplicated with duplicate values" do
|
317
|
+
text_x_yaml.add_extensions("yaml")
|
318
|
+
assert_equal %w[yaml yml], text_x_yaml.extensions
|
319
|
+
text_x_yaml.add_extensions(%w[yaml yz])
|
320
|
+
assert_equal %w[yaml yml yz], text_x_yaml.extensions
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "#priority_compare" do
|
325
|
+
def assert_priority_less(left, right)
|
326
|
+
assert_equal(-1, left.priority_compare(right))
|
327
|
+
end
|
328
|
+
|
329
|
+
def assert_priority_same(left, right)
|
330
|
+
assert_equal 0, left.priority_compare(right)
|
331
|
+
end
|
332
|
+
|
333
|
+
def assert_priority_more(left, right)
|
334
|
+
assert_equal 1, left.priority_compare(right)
|
335
|
+
end
|
336
|
+
|
337
|
+
def assert_priority(left, middle, right)
|
338
|
+
assert_priority_less left, right
|
339
|
+
assert_priority_same left, middle
|
340
|
+
assert_priority_more right, left
|
341
|
+
end
|
342
|
+
|
343
|
+
let(:text_1) { mime_type("text/1") }
|
344
|
+
let(:text_1p) { mime_type("text/1") }
|
345
|
+
let(:text_2) { mime_type("text/2") }
|
346
|
+
|
347
|
+
it "sorts (1) based on the simplified type" do
|
348
|
+
assert_priority text_1, text_1p, text_2
|
349
|
+
end
|
350
|
+
|
351
|
+
it "sorts (2) based on extensions" do
|
352
|
+
text_1.extensions = ["foo", "bar"]
|
353
|
+
text_2.extensions = ["foo"]
|
354
|
+
|
355
|
+
assert_priority_same text_1, text_2
|
356
|
+
|
357
|
+
text_2.registered = true
|
358
|
+
|
359
|
+
assert_priority_more text_1, text_2
|
360
|
+
end
|
361
|
+
|
362
|
+
it "sorts (3) based on the registration state" do
|
363
|
+
text_1.registered = text_1p.registered = true
|
364
|
+
text_1b = mime_type(text_1) { |t| t.registered = false }
|
365
|
+
|
366
|
+
assert_priority text_1, text_1p, text_1b
|
367
|
+
end
|
368
|
+
|
369
|
+
it "sorts (4) based on the completeness" do
|
370
|
+
text_1.extensions = text_1p.extensions = "1"
|
371
|
+
text_1b = mime_type(text_1) { |t| t.extensions = nil }
|
372
|
+
|
373
|
+
assert_priority text_1, text_1p, text_1b
|
374
|
+
end
|
375
|
+
|
376
|
+
it "sorts (5) based on obsolete status" do
|
377
|
+
text_1.obsolete = text_1p.obsolete = false
|
378
|
+
text_1b = mime_type(text_1) { |t| t.obsolete = true }
|
379
|
+
|
380
|
+
assert_priority text_1, text_1p, text_1b
|
381
|
+
end
|
382
|
+
|
383
|
+
it "sorts (5) based on the use-instead value" do
|
384
|
+
text_1.obsolete = text_1p.obsolete = true
|
385
|
+
text_1.use_instead = text_1p.use_instead = "abc/xyz"
|
386
|
+
text_1b = mime_type(text_1) { |t| t.use_instead = nil }
|
387
|
+
|
388
|
+
assert_priority text_1, text_1p, text_1b
|
389
|
+
|
390
|
+
text_1b.use_instead = "abc/zzz"
|
391
|
+
|
392
|
+
assert_priority text_1, text_1p, text_1b
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
describe "#raw_media_type" do
|
397
|
+
it "extracts the media type as case-preserved" do
|
398
|
+
assert_equal "Text", mime_type("Text/plain").raw_media_type
|
399
|
+
end
|
400
|
+
|
401
|
+
it "does not remove x- prefixes" do
|
402
|
+
assert_equal("x-appl", x_appl_x_zip.raw_media_type)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
describe "#media_type" do
|
407
|
+
it "extracts the media type as lowercase" do
|
408
|
+
assert_equal "text", text_plain.media_type
|
409
|
+
end
|
410
|
+
|
411
|
+
it "does not remove x- prefixes" do
|
412
|
+
assert_equal("x-appl", x_appl_x_zip.media_type)
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
describe "#raw_media_type" do
|
417
|
+
it "extracts the media type as case-preserved" do
|
418
|
+
assert_equal "Text", mime_type("Text/plain").raw_media_type
|
293
419
|
end
|
294
420
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
421
|
+
it "does not remove x- prefixes" do
|
422
|
+
assert_equal("x-appl", x_appl_x_zip.raw_media_type)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
describe "#sub_type" do
|
427
|
+
it "extracts the sub type as lowercase" do
|
428
|
+
assert_equal "plain", text_plain.sub_type
|
429
|
+
end
|
430
|
+
|
431
|
+
it "does not remove x- prefixes" do
|
432
|
+
assert_equal("x-zip", x_appl_x_zip.sub_type)
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
describe "#raw_sub_type" do
|
437
|
+
it "extracts the sub type as case-preserved" do
|
438
|
+
assert_equal "Plain", mime_type("text/Plain").raw_sub_type
|
439
|
+
end
|
440
|
+
|
441
|
+
it "does not remove x- prefixes" do
|
442
|
+
assert_equal("x-zip", x_appl_x_zip.raw_sub_type)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
describe "#to_h" do
|
447
|
+
let(:t) { mime_type("a/b") }
|
448
|
+
|
449
|
+
def assert_has_keys(wanted_keys, actual, msg = nil)
|
450
|
+
wanted_keys = Array(wanted_keys).uniq.sort
|
451
|
+
actual_keys = if actual.is_a?(Hash)
|
452
|
+
actual.keys
|
453
|
+
else
|
454
|
+
actual.to_h.keys
|
299
455
|
end
|
300
|
-
|
301
|
-
|
456
|
+
|
457
|
+
missing = wanted_keys - actual_keys
|
458
|
+
pretty_wanted_keys = (wanted_keys + actual_keys).uniq.sort
|
459
|
+
|
460
|
+
msg = message(msg) {
|
461
|
+
"#{mu_pp(actual)} is missing attribute values\n#{diff(pretty_wanted_keys, actual_keys)}"
|
462
|
+
}
|
463
|
+
|
464
|
+
assert missing.empty?, msg
|
465
|
+
end
|
466
|
+
|
467
|
+
it "has the required keys (content-type, registered, encoding)" do
|
468
|
+
assert_has_keys %w[content-type registered encoding], t
|
469
|
+
end
|
470
|
+
|
471
|
+
it "has the docs key if there are documents" do
|
472
|
+
assert_has_keys "docs", mime_type(t) { |v| v.docs = "a" }
|
302
473
|
end
|
303
474
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
475
|
+
it "has the extensions key if set" do
|
476
|
+
assert_has_keys "extensions", mime_type(t) { |v| v.extensions = "a" }
|
477
|
+
end
|
478
|
+
|
479
|
+
it "has the preferred-extension key if set" do
|
480
|
+
assert_has_keys "preferred-extension", mime_type(t) { |v| v.preferred_extension = "a" }
|
481
|
+
end
|
482
|
+
|
483
|
+
it "has the obsolete key if set" do
|
484
|
+
assert_has_keys "obsolete", mime_type(t) { |v| v.obsolete = true }
|
485
|
+
end
|
486
|
+
|
487
|
+
it "has the obsolete and use-instead keys if set" do
|
488
|
+
assert_has_keys %w[obsolete use-instead], mime_type(t) { |v|
|
489
|
+
v.obsolete = true
|
490
|
+
v.use_instead = "c/d"
|
491
|
+
}
|
492
|
+
end
|
493
|
+
|
494
|
+
it "has the signature key if set" do
|
495
|
+
assert_has_keys "signature", mime_type(t) { |v| v.signature = true }
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe "#to_json" do
|
500
|
+
let(:expected_1) {
|
501
|
+
'{"content-type":"a/b","encoding":"base64","registered":false}'
|
502
|
+
}
|
503
|
+
let(:expected_2) {
|
504
|
+
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
|
505
|
+
}
|
506
|
+
|
507
|
+
it "converts to JSON when requested" do
|
508
|
+
assert_equal expected_1, mime_type("a/b").to_json
|
509
|
+
end
|
510
|
+
|
511
|
+
it "converts to JSON with provisional when requested" do
|
512
|
+
type = mime_type("a/b") do |t|
|
513
|
+
t.registered = true
|
514
|
+
t.provisional = true
|
308
515
|
end
|
309
|
-
assert_equal
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
516
|
+
assert_equal expected_2, type.to_json
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
describe "#to_s, #to_str" do
|
521
|
+
it "represents itself as a string of the canonical content_type" do
|
522
|
+
assert_equal "text/plain", text_plain.to_s
|
523
|
+
end
|
524
|
+
|
525
|
+
it "acts like a string of the canonical content_type for comparison" do
|
526
|
+
assert_equal text_plain, "text/plain"
|
527
|
+
end
|
528
|
+
|
529
|
+
it "acts like a string for other purposes" do
|
530
|
+
assert_equal "stringy", "text/plain".sub(text_plain, "stringy")
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
describe "#xrefs, #xrefs=" do
|
535
|
+
let(:expected) {
|
536
|
+
MIME::Types::Container.new("rfc" => Set["rfc1234", "rfc5678"])
|
537
|
+
}
|
538
|
+
|
539
|
+
it "returns the expected results" do
|
540
|
+
application_javascript.xrefs = {
|
541
|
+
"rfc" => %w[rfc5678 rfc1234 rfc1234]
|
542
|
+
}
|
543
|
+
|
544
|
+
assert_equal expected, application_javascript.xrefs
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
describe "#xref_urls" do
|
549
|
+
let(:expected) {
|
550
|
+
[
|
551
|
+
"http://www.iana.org/go/draft1",
|
552
|
+
"http://www.iana.org/assignments/media-types/a/b",
|
553
|
+
"http://www.iana.org/assignments/media-types/media-types.xhtml#p-1",
|
554
|
+
"http://www.iana.org/go/rfc-1",
|
555
|
+
"http://www.rfc-editor.org/errata_search.php?eid=err-1",
|
556
|
+
"http://example.org",
|
557
|
+
"text"
|
558
|
+
]
|
559
|
+
}
|
560
|
+
|
561
|
+
let(:type) {
|
562
|
+
mime_type("a/b").tap do |t|
|
563
|
+
t.xrefs = {
|
564
|
+
"draft" => ["RFC1"],
|
565
|
+
"template" => ["a/b"],
|
566
|
+
"person" => ["p-1"],
|
567
|
+
"rfc" => ["rfc-1"],
|
568
|
+
"rfc-errata" => ["err-1"],
|
569
|
+
"uri" => ["http://example.org"],
|
570
|
+
"text" => ["text"]
|
571
|
+
}
|
330
572
|
end
|
331
|
-
|
332
|
-
|
333
|
-
|
573
|
+
}
|
574
|
+
|
575
|
+
it "translates according to given rules" do
|
576
|
+
assert_equal expected, type.xref_urls
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
describe "#use_instead" do
|
581
|
+
it "is nil unless the type is obsolete" do
|
582
|
+
assert_nil text_plain.use_instead
|
583
|
+
end
|
584
|
+
|
585
|
+
it "is nil if not set and the type is obsolete" do
|
586
|
+
text_plain.obsolete = true
|
587
|
+
assert_nil text_plain.use_instead
|
588
|
+
end
|
589
|
+
|
590
|
+
it "is a different type if set and the type is obsolete" do
|
591
|
+
text_plain.obsolete = true
|
592
|
+
text_plain.use_instead = "text/html"
|
593
|
+
assert_equal "text/html", text_plain.use_instead
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
describe "#preferred_extension, #preferred_extension=" do
|
598
|
+
it "is nil when not set and there are no extensions" do
|
599
|
+
assert_nil text_plain.preferred_extension
|
600
|
+
end
|
601
|
+
|
602
|
+
it "is the first extension when not set but there are extensions" do
|
603
|
+
assert_equal "yaml", text_x_yaml.preferred_extension
|
604
|
+
end
|
605
|
+
|
606
|
+
it "is the extension provided when set" do
|
607
|
+
text_x_yaml.preferred_extension = "yml"
|
608
|
+
assert_equal "yml", text_x_yaml.preferred_extension
|
609
|
+
end
|
610
|
+
|
611
|
+
it "is adds the preferred extension if it does not exist" do
|
612
|
+
text_x_yaml.preferred_extension = "yz"
|
613
|
+
assert_equal "yz", text_x_yaml.preferred_extension
|
614
|
+
assert_includes text_x_yaml.extensions, "yz"
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
describe "#friendly" do
|
619
|
+
it "returns English by default" do
|
620
|
+
assert_equal "YAML Structured Document", text_x_yaml.friendly
|
334
621
|
end
|
335
622
|
|
336
|
-
|
337
|
-
|
623
|
+
it "returns English when requested" do
|
624
|
+
assert_equal "YAML Structured Document", text_x_yaml.friendly("en")
|
625
|
+
assert_equal "YAML Structured Document", text_x_yaml.friendly(:en)
|
338
626
|
end
|
339
627
|
|
340
|
-
|
341
|
-
|
628
|
+
it "returns nothing for an unknown language" do
|
629
|
+
assert_nil text_x_yaml.friendly("zz")
|
342
630
|
end
|
343
631
|
|
344
|
-
|
345
|
-
|
632
|
+
it "merges new values from an array parameter" do
|
633
|
+
expected = {"en" => "Text files"}
|
634
|
+
assert_equal expected, text_plain.friendly(["en", "Text files"])
|
635
|
+
expected.update("fr" => "des fichiers texte")
|
636
|
+
assert_equal expected,
|
637
|
+
text_plain.friendly(["fr", "des fichiers texte"])
|
346
638
|
end
|
347
639
|
|
348
|
-
|
349
|
-
|
640
|
+
it "merges new values from a hash parameter" do
|
641
|
+
expected = {"en" => "Text files"}
|
642
|
+
assert_equal expected, text_plain.friendly(expected)
|
643
|
+
french = {"fr" => "des fichiers texte"}
|
644
|
+
expected.update(french)
|
645
|
+
assert_equal expected, text_plain.friendly(french)
|
350
646
|
end
|
351
647
|
|
352
|
-
|
353
|
-
|
648
|
+
it "raises an ArgumentError if an unknown value is provided" do
|
649
|
+
exception = assert_raises ArgumentError do
|
650
|
+
text_plain.friendly(1)
|
651
|
+
end
|
652
|
+
|
653
|
+
assert_equal "Expected a language or translation set, not 1",
|
654
|
+
exception.message
|
354
655
|
end
|
355
656
|
end
|
356
657
|
end
|