mime-types 2.99.3 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/{Code-of-Conduct.rdoc → Code-of-Conduct.md} +29 -30
  3. data/Contributing.md +132 -0
  4. data/History.md +269 -0
  5. data/{Licence.rdoc → Licence.md} +4 -18
  6. data/Manifest.txt +8 -25
  7. data/README.rdoc +63 -73
  8. data/Rakefile +200 -97
  9. data/lib/mime/type/columnar.rb +30 -63
  10. data/lib/mime/type.rb +294 -458
  11. data/lib/mime/types/_columnar.rb +137 -0
  12. data/lib/mime/types/cache.rb +52 -74
  13. data/lib/mime/types/columnar.rb +2 -147
  14. data/lib/mime/types/container.rb +96 -0
  15. data/lib/mime/types/deprecations.rb +17 -34
  16. data/lib/mime/types/full.rb +19 -0
  17. data/lib/mime/types/loader.rb +36 -152
  18. data/lib/mime/types/logger.rb +7 -5
  19. data/lib/mime/types/registry.rb +90 -0
  20. data/lib/mime/types.rb +55 -148
  21. data/lib/mime-types.rb +2 -2
  22. data/test/minitest_helper.rb +8 -18
  23. data/test/test_mime_type.rb +489 -464
  24. data/test/test_mime_types.rb +139 -91
  25. data/test/test_mime_types_cache.rb +85 -57
  26. data/test/test_mime_types_class.rb +120 -100
  27. data/test/test_mime_types_lazy.rb +30 -28
  28. data/test/test_mime_types_loader.rb +18 -45
  29. metadata +92 -77
  30. data/Contributing.rdoc +0 -170
  31. data/History-Types.rdoc +0 -454
  32. data/History.rdoc +0 -590
  33. data/data/mime-types.json +0 -1
  34. data/data/mime.content_type.column +0 -1980
  35. data/data/mime.docs.column +0 -1980
  36. data/data/mime.encoding.column +0 -1980
  37. data/data/mime.friendly.column +0 -1980
  38. data/data/mime.obsolete.column +0 -1980
  39. data/data/mime.registered.column +0 -1980
  40. data/data/mime.signature.column +0 -1980
  41. data/data/mime.use_instead.column +0 -1980
  42. data/data/mime.xrefs.column +0 -1980
  43. data/docs/COPYING.txt +0 -339
  44. data/docs/artistic.txt +0 -127
  45. data/lib/mime/types/loader_path.rb +0 -15
  46. data/support/apache_mime_types.rb +0 -108
  47. data/support/benchmarks/load.rb +0 -64
  48. data/support/benchmarks/load_allocations.rb +0 -83
  49. data/support/benchmarks/object_counts.rb +0 -41
  50. data/support/convert/columnar.rb +0 -88
  51. data/support/convert.rb +0 -158
  52. data/support/iana_registry.rb +0 -172
@@ -1,596 +1,621 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
- require 'mime/types'
4
- require 'minitest_helper'
3
+ require "mime/types"
4
+ require "minitest_helper"
5
5
 
6
- class TestMIMEType < Minitest::Test
7
- def make(content_type)
6
+ describe MIME::Type do
7
+ def mime_type(content_type)
8
8
  MIME::Type.new(content_type) { |mt| yield mt if block_given? }
9
9
  end
10
10
 
11
- def make_javascript
12
- make('application/javascript') do |js|
13
- js.friendly('en' => 'JavaScript')
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")
14
20
  js.xrefs = {
15
- 'rfc' => %w(rfc4239 rfc4239),
16
- 'template' => %w(application/javascript)
21
+ "rfc" => %w[rfc4239 rfc4239],
22
+ "template" => %w[application/javascript]
17
23
  }
18
- js.encoding = '8bit'
19
- js.extensions = %w(js sj)
20
- assert_deprecated('MIME::Type#references=') do
21
- js.references = :anything
22
- end
24
+ js.encoding = "8bit"
25
+ js.extensions = %w[js sj]
23
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"
39
+ end
40
+ }
41
+
42
+ describe ".simplified" do
43
+ it "leaves normal types alone" do
44
+ assert_equal "text/plain", MIME::Type.simplified("text/plain")
45
+ end
46
+
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
24
63
 
25
- yield js if block_given?
64
+ it "returns nil when the value provided is not a valid content type" do
65
+ assert_nil MIME::Type.simplified("text")
26
66
  end
27
67
  end
28
68
 
29
- def make_yaml_mime_type
30
- make('text/x-yaml') do |yaml|
31
- yaml.extensions = %w(yaml yml)
32
- yaml.encoding = '8bit'
33
- assert_deprecated('MIME::Type#system=') do
34
- yaml.system = 'd9d172f608'
35
- end
36
- yaml.friendly('en' => 'YAML Structured Document')
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")
37
85
  end
38
86
  end
39
87
 
40
- def make_yaml_mime_type_with_docs
41
- make('text/x-yaml') do |yaml|
42
- yaml.extensions = %w(yaml yml)
43
- yaml.encoding = '8bit'
44
- assert_deprecated('MIME::Type#system=') do
45
- yaml.system = 'd9d172f608'
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")
46
92
  end
47
- yaml.docs = 'Test YAML'
93
+ assert_equal 'Invalid Content-Type "apps"', exception.to_s
48
94
  end
49
- end
50
95
 
51
- def setup
52
- @applzip = MIME::Type.new('x-appl/x-zip') { |t|
53
- t.extensions = %w(zip zp)
54
- }
55
- end
96
+ it "creates a valid content type just from a string" do
97
+ type = MIME::Type.new("text/x-yaml")
56
98
 
57
- def test_class_from_array
58
- yaml = nil
59
- assert_deprecated('MIME::Type.from_array') do
60
- yaml = MIME::Type.from_array(
61
- 'text/x-yaml',
62
- %w(yaml yml),
63
- '8bit',
64
- 'd9d172f608'
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
107
+ end
108
+ end
109
+
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
65
114
  )
115
+ assert_instance_of MIME::Type, type
116
+ assert_equal "text/x-yaml", type.content_type
117
+ assert type.obsolete?
66
118
  end
67
- assert_instance_of(MIME::Type, yaml)
68
- assert_equal('text/yaml', yaml.simplified)
69
- assert_deprecated('MIME::Type.from_array') do
70
- assert_raises(ArgumentError) { MIME::Type.from_array }
119
+
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
71
125
  end
72
126
  end
73
127
 
74
- def test_class_from_hash
75
- yaml = nil
76
- assert_deprecated('MIME::Type.from_hash') do
77
- yaml = MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
78
- 'Content-Transfer-Encoding' => '8bit',
79
- 'System' => 'd9d172f608',
80
- 'Extensions' => %w(yaml yml))
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)
81
132
  end
82
- assert_instance_of(MIME::Type, yaml)
83
- assert_equal('text/yaml', yaml.simplified)
84
- end
85
133
 
86
- def test_class_from_mime_type
87
- zip2 = nil
88
- assert_deprecated('MIME::Type.from_mime_type') do
89
- zip2 = MIME::Type.from_mime_type(@applzip)
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)
90
137
  end
91
- assert_instance_of(MIME::Type, @applzip)
92
- assert_equal('appl/zip', @applzip.simplified)
93
- refute_equal(@applzip.object_id, zip2.object_id)
94
138
  end
95
139
 
96
- def test_class_simplified
97
- assert_equal('text/plain', MIME::Type.simplified('text/plain'))
98
- assert_equal('image/jpeg', MIME::Type.simplified('image/jpeg'))
99
- assert_equal('application/msword', MIME::Type.simplified('application/x-msword'))
100
- assert_equal('text/vcard', MIME::Type.simplified('text/vCard'))
101
- assert_equal('application/pkcs7-mime', MIME::Type.simplified('application/pkcs7-mime'))
102
- assert_equal('xyz/abc', MIME::Type.simplified('x-xyz/abc'))
103
- assert_nil(MIME::Type.simplified('text'))
104
- end
140
+ describe "#<=>" do
141
+ it "correctly compares identical types" do
142
+ assert_equal text_plain, text_plain
143
+ end
105
144
 
106
- def test_class_i18n_key
107
- assert_equal('text.plain', MIME::Type.i18n_key('text/plain'))
108
- assert_equal('image.jpeg', MIME::Type.i18n_key('image/jpeg'))
109
- assert_equal('application.msword', MIME::Type.i18n_key('application/x-msword'))
110
- assert_equal('text.vcard', MIME::Type.i18n_key('text/vCard'))
111
- assert_equal('application.pkcs7-mime', MIME::Type.i18n_key('application/pkcs7-mime'))
112
- assert_equal('xyz.abc', MIME::Type.i18n_key('x-xyz/abc'))
113
- assert_nil(MIME::Type.i18n_key('text'))
114
- end
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
149
+ end
115
150
 
116
- def test_spaceship_compare # '<=>'
117
- assert(MIME::Type.new('text/plain') == MIME::Type.new('text/plain')) # rubocop:disable Lint/UselessComparison
118
- assert(MIME::Type.new('text/plain') != MIME::Type.new('image/jpeg'))
119
- assert(MIME::Type.new('text/plain') == 'text/plain')
120
- assert(MIME::Type.new('text/plain') != 'image/jpeg')
121
- assert(MIME::Type.new('text/plain') > MIME::Type.new('text/html'))
122
- assert(MIME::Type.new('text/plain') > 'text/html')
123
- assert(MIME::Type.new('text/html') < MIME::Type.new('text/plain'))
124
- assert(MIME::Type.new('text/html') < 'text/plain')
125
- assert('text/html' == MIME::Type.new('text/html'))
126
- assert('text/html' < MIME::Type.new('text/plain'))
127
- assert('text/plain' > MIME::Type.new('text/html'))
128
- end
151
+ it "correctly compares types that sort earlier" do
152
+ refute_equal text_html, text_plain
153
+ assert_operator text_html, :<, text_plain
154
+ end
129
155
 
130
- def test_ascii_eh
131
- assert(MIME::Type.new('text/plain').ascii?)
132
- refute(MIME::Type.new('image/jpeg').ascii?)
133
- refute(MIME::Type.new('application/x-msword').ascii?)
134
- assert(MIME::Type.new('text/vCard').ascii?)
135
- refute(MIME::Type.new('application/pkcs7-mime').ascii?)
136
- refute(@applzip.ascii?)
137
- end
156
+ it "correctly compares types that sort later" do
157
+ refute_equal text_plain, text_html
158
+ assert_operator text_plain, :>, text_html
159
+ end
138
160
 
139
- def test_binary_eh
140
- refute(MIME::Type.new('text/plain').binary?)
141
- assert(MIME::Type.new('image/jpeg').binary?)
142
- assert(MIME::Type.new('application/x-msword').binary?)
143
- refute(MIME::Type.new('text/vCard').binary?)
144
- assert(MIME::Type.new('application/pkcs7-mime').binary?)
145
- assert(@applzip.binary?)
146
- end
161
+ it "correctly compares types against equivalent strings" do
162
+ assert_equal text_plain, "text/plain"
163
+ end
147
164
 
148
- def test_complete_eh
149
- yaml = make_yaml_mime_type
150
- assert(yaml.complete?)
151
- yaml.extensions = nil
152
- refute(yaml.complete?)
153
- end
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"
168
+ end
154
169
 
155
- def test_content_type
156
- assert_equal('text/plain', MIME::Type.new('text/plain').content_type)
157
- assert_equal('image/jpeg', MIME::Type.new('image/jpeg').content_type)
158
- assert_equal('application/x-msword',
159
- MIME::Type.new('application/x-msword').content_type)
160
- assert_equal('text/vCard', MIME::Type.new('text/vCard').content_type)
161
- assert_equal('application/pkcs7-mime',
162
- MIME::Type.new('application/pkcs7-mime').content_type)
163
- assert_equal('x-appl/x-zip', @applzip.content_type)
164
- assert_equal('base64', @applzip.encoding)
165
- end
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"
173
+ end
166
174
 
167
- def test_encoding
168
- assert_equal('quoted-printable', MIME::Type.new('text/plain').encoding)
169
- assert_equal('base64', MIME::Type.new('image/jpeg').encoding)
170
- assert_equal('base64', MIME::Type.new('application/x-msword').encoding)
171
- assert_equal('quoted-printable', MIME::Type.new('text/vCard').encoding)
172
- assert_equal('base64', MIME::Type.new('application/pkcs7-mime').encoding)
175
+ it "correctly compares against nil" do
176
+ refute_equal text_html, nil
177
+ assert_operator text_plain, :<, nil
178
+ end
173
179
  end
174
180
 
175
- def test_encoding_equals
176
- yaml = make_yaml_mime_type
177
- assert_equal('8bit', yaml.encoding)
178
- yaml.encoding = 'base64'
179
- assert_equal('base64', yaml.encoding)
180
- yaml.encoding = :default
181
- assert_equal('quoted-printable', yaml.encoding)
182
- assert_raises(MIME::Type::InvalidEncoding) {
183
- yaml.encoding = 'binary'
184
- }
185
- end
181
+ describe "#ascii?" do
182
+ it "defaults to true for text/* types" do
183
+ assert text_plain.ascii?
184
+ end
186
185
 
187
- def test_default_encoding
188
- %w(text/plain text/html).each { |mt|
189
- assert_equal('quoted-printable', MIME::Type.new(mt).default_encoding)
190
- }
191
- %w(image/jpeg applicatoin/pkcs7-mime).each { |mt|
192
- assert_equal('base64', MIME::Type.new(mt).default_encoding)
193
- }
186
+ it "defaults to false for non-text/* types" do
187
+ refute image_jpeg.ascii?
188
+ end
194
189
  end
195
190
 
196
- def test_docs
197
- yaml = make_yaml_mime_type_with_docs
198
- assert_equal('Test YAML', yaml.docs)
199
- end
191
+ describe "#binary?" do
192
+ it "defaults to false for text/* types" do
193
+ refute text_plain.binary?
194
+ end
200
195
 
201
- def test_docs_equals
202
- yaml = make_yaml_mime_type
203
- assert_equal [], yaml.docs
204
- yaml.docs = 'YAML docs'
205
- assert_equal('YAML docs', yaml.docs)
196
+ it "defaults to true for non-text/* types" do
197
+ assert image_jpeg.binary?
198
+ end
206
199
  end
207
200
 
208
- def test_eql?
209
- assert(MIME::Type.new('text/plain').eql?(MIME::Type.new('text/plain')))
210
- refute(MIME::Type.new('text/plain').eql?(MIME::Type.new('image/jpeg')))
211
- refute(MIME::Type.new('text/plain').eql?('text/plain'))
212
- refute(MIME::Type.new('text/plain').eql?('image/jpeg'))
201
+ describe "#complete?" do
202
+ it "is true when there are extensions" do
203
+ assert text_x_yaml.complete?
204
+ end
205
+
206
+ it "is false when there are no extensions" do
207
+ refute mime_type("text/plain").complete?
208
+ end
213
209
  end
214
210
 
215
- def test_extensions
216
- yaml = make_yaml_mime_type
217
- assert_equal(%w(yaml yml), yaml.extensions)
218
- assert_equal(2, @applzip.extensions.size)
219
- assert_equal(%w(zip zp), @applzip.extensions)
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
215
+ end
216
+
217
+ it "does not remove x- prefixes" do
218
+ assert_equal "x-appl/x-zip", x_appl_x_zip.content_type
219
+ end
220
220
  end
221
221
 
222
- def test_add_extensions
223
- expected = make_yaml_mime_type
224
- test_doc = make_yaml_mime_type
225
- test_doc.add_extensions(nil)
226
- assert_equal(expected.extensions, test_doc.extensions)
227
- test_doc.add_extensions('yaml')
228
- assert_equal(expected.extensions, test_doc.extensions)
229
- test_doc.add_extensions(%w(yaml))
230
- assert_equal(expected.extensions, test_doc.extensions)
231
- test_doc.add_extensions('yz')
232
- assert_equal(%w(yaml yml yz), test_doc.extensions)
222
+ describe "#default_encoding" do
223
+ it "is quoted-printable for text/* types" do
224
+ assert_equal "quoted-printable", text_plain.default_encoding
225
+ end
226
+
227
+ it "is base64 for non-text/* types" do
228
+ assert_equal "base64", image_jpeg.default_encoding
229
+ end
233
230
  end
234
231
 
235
- def test_extensions_equals
236
- yaml = make_yaml_mime_type
237
- yaml.extensions = 'yaml'
238
- assert_equal(%w(yaml), yaml.extensions)
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
236
+ end
237
+
238
+ it "returns the set value when set" do
239
+ text_plain.encoding = "8bit"
240
+ assert_equal "8bit", text_plain.encoding
241
+ end
239
242
 
240
- yaml.extensions = %w(yaml yaml)
241
- assert_equal(%w(yaml), yaml.extensions)
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
242
250
 
243
- yaml.extensions = %w(yz yaml yz yml)
244
- assert_equal(%w(yz yaml yml), yaml.extensions)
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"
254
+ end
255
+ assert_equal 'Invalid Encoding "binary"', exception.to_s
256
+ end
245
257
  end
246
258
 
247
- def test_like_eh
248
- assert(MIME::Type.new('text/plain').like?(MIME::Type.new('text/plain')))
249
- assert(MIME::Type.new('text/plain').like?(MIME::Type.new('text/x-plain')))
250
- refute(MIME::Type.new('text/plain').like?(MIME::Type.new('image/jpeg')))
251
- assert(MIME::Type.new('text/plain').like?('text/plain'))
252
- assert(MIME::Type.new('text/plain').like?('text/x-plain'))
253
- refute(MIME::Type.new('text/plain').like?('image/jpeg'))
254
- end
259
+ describe "#eql?" do
260
+ it "is not true for a non-MIME::Type" do
261
+ refute text_plain.eql?("text/plain")
262
+ end
255
263
 
256
- def test_media_type
257
- assert_equal('text', MIME::Type.new('text/plain').media_type)
258
- assert_equal('image', MIME::Type.new('image/jpeg').media_type)
259
- assert_equal('application', MIME::Type.new('application/x-msword').media_type)
260
- assert_equal('text', MIME::Type.new('text/vCard').media_type)
261
- assert_equal('application', MIME::Type.new('application/pkcs7-mime').media_type)
262
- assert_equal('chemical', MIME::Type.new('x-chemical/x-pdb').media_type)
263
- assert_equal('appl', @applzip.media_type)
264
- end
264
+ it "is not true for a different MIME::Type" do
265
+ refute text_plain.eql?(image_jpeg)
266
+ end
265
267
 
266
- def test_obsolete_eh
267
- type = MIME::Type.new('content-type' => 'test/type',
268
- 'obsolete' => true)
269
- assert(type.obsolete?)
270
- refute(make_yaml_mime_type.obsolete?)
268
+ it "is true for an equivalent MIME::Type" do
269
+ assert text_plain, mime_type("text/Plain")
270
+ end
271
271
  end
272
272
 
273
- def test_obsolete_equals
274
- yaml = make_yaml_mime_type
275
- refute(yaml.obsolete?)
276
- yaml.obsolete = true
277
- assert(yaml.obsolete?)
278
- end
273
+ describe "#extensions, #extensions=" do
274
+ it "returns an array of extensions" do
275
+ assert_equal %w[yaml yml], text_x_yaml.extensions
276
+ assert_equal %w[zip zp], x_appl_x_zip.extensions
277
+ end
279
278
 
280
- def test_platform_eh
281
- assert_deprecated('MIME::Type#platform?') do
282
- refute make_yaml_mime_type.platform?
279
+ it "sets a single extension when provided a single value" do
280
+ text_x_yaml.extensions = "yaml"
281
+ assert_equal %w[yaml], text_x_yaml.extensions
282
+ end
283
+
284
+ it "deduplicates extensions" do
285
+ text_x_yaml.extensions = %w[yaml yaml]
286
+ assert_equal %w[yaml], text_x_yaml.extensions
283
287
  end
284
288
  end
285
289
 
286
- def assert_priority(l, e, r)
287
- assert_equal(-1, l.first.priority_compare(l.last))
288
- assert_equal(0, e.first.priority_compare(e.last))
289
- assert_equal(1, r.first.priority_compare(r.last))
290
+ describe "#add_extensions" do
291
+ it "does not modify extensions when provided nil" do
292
+ text_x_yaml.add_extensions(nil)
293
+ assert_equal %w[yaml yml], text_x_yaml.extensions
294
+ end
295
+
296
+ it "remains deduplicated with duplicate values" do
297
+ text_x_yaml.add_extensions("yaml")
298
+ assert_equal %w[yaml yml], text_x_yaml.extensions
299
+ text_x_yaml.add_extensions(%w[yaml yz])
300
+ assert_equal %w[yaml yml yz], text_x_yaml.extensions
301
+ end
290
302
  end
291
303
 
292
- def test_priority_compare
293
- tl, te, tr = make('text/1'), make('text/1'), make('text/2')
294
- assert_priority([tl, tr], [tl, te], [tr, tl])
304
+ describe "#priority_compare" do
305
+ def assert_priority_less(left, right)
306
+ assert_equal(-1, left.priority_compare(right))
307
+ end
295
308
 
296
- tl.registered = te.registered = true
297
- tr = make(tl) { |t| t.registered = false }
298
- assert_priority([tl, tr], [tl, te], [tr, tl])
309
+ def assert_priority_same(left, right)
310
+ assert_equal 0, left.priority_compare(right)
311
+ end
299
312
 
300
- tl.extensions = te.extensions = %w(1)
301
- tr = make(tl) { |t| t.extensions = nil }
302
- assert_priority([tl, tr], [tl, te], [tr, tl])
313
+ def assert_priority_more(left, right)
314
+ assert_equal 1, left.priority_compare(right)
315
+ end
303
316
 
304
- tl.obsolete = te.obsolete = false
305
- tr = make(tl) { |t| t.obsolete = true }
306
- assert_priority([tl, tr], [tl, te], [tr, tl])
317
+ def assert_priority(left, middle, right)
318
+ assert_priority_less left, right
319
+ assert_priority_same left, middle
320
+ assert_priority_more right, left
321
+ end
307
322
 
308
- tl.obsolete = te.obsolete = true
309
- tl.use_instead = te.use_instead = 'abc/xyz'
310
- tr = make(tl) { |t| t.use_instead = nil }
311
- assert_priority([tl, tr], [tl, te], [tr, tl])
312
- tr.use_instead = 'abc/zzz'
313
- assert_priority([tl, tr], [tl, te], [tr, tl])
314
- end
323
+ let(:text_1) { mime_type("text/1") }
324
+ let(:text_1p) { mime_type("text/1") }
325
+ let(:text_2) { mime_type("text/2") }
315
326
 
316
- def test_raw_media_type
317
- assert_equal('text', MIME::Type.new('text/plain').raw_media_type)
318
- assert_equal('image', MIME::Type.new('image/jpeg').raw_media_type)
319
- assert_equal('application', MIME::Type.new('application/x-msword').raw_media_type)
320
- assert_equal('text', MIME::Type.new('text/vCard').raw_media_type)
321
- assert_equal('application', MIME::Type.new('application/pkcs7-mime').raw_media_type)
322
- assert_equal('x-chemical', MIME::Type.new('x-chemical/x-pdb').raw_media_type)
323
- assert_equal('x-appl', @applzip.raw_media_type)
324
- end
327
+ it "sorts (1) based on the simplified type" do
328
+ assert_priority text_1, text_1p, text_2
329
+ end
325
330
 
326
- def test_raw_sub_type
327
- assert_equal('plain', MIME::Type.new('text/plain').raw_sub_type)
328
- assert_equal('jpeg', MIME::Type.new('image/jpeg').raw_sub_type)
329
- assert_equal('x-msword', MIME::Type.new('application/x-msword').raw_sub_type)
330
- assert_equal('vCard', MIME::Type.new('text/vCard').raw_sub_type)
331
- assert_equal('pkcs7-mime', MIME::Type.new('application/pkcs7-mime').raw_sub_type)
332
- assert_equal('x-zip', @applzip.raw_sub_type)
333
- end
331
+ it "sorts (2) based on extensions" do
332
+ text_1.extensions = ["foo", "bar"]
333
+ text_2.extensions = ["foo"]
334
334
 
335
- def test_registered_eh
336
- assert(MIME::Type.new('text/plain').registered?)
337
- assert(MIME::Type.new('image/jpeg').registered?)
338
- refute(MIME::Type.new('application/x-msword').registered?)
339
- assert(MIME::Type.new('text/vCard').registered?)
340
- assert(MIME::Type.new('application/pkcs7-mime').registered?)
341
- refute(@applzip.registered?)
342
- refute(MIME::Types['image/webp'].first.registered?)
343
- # Temporarily broken: requires the new data format to be enabled.
344
- assert(MIME::Types['application/x-www-form-urlencoded'].first.registered?)
345
- end
335
+ assert_priority_same text_1, text_2
346
336
 
347
- def test_registered_equals
348
- [ nil, false, true ].each { |v|
349
- @applzip.registered = v
350
- assert_equal(v, @applzip.instance_variable_get(:@registered))
351
- }
352
- @applzip.registered = 1
353
- assert_equal(true, @applzip.instance_variable_get(:@registered))
354
- end
337
+ text_2.registered = true
355
338
 
356
- def test_signature_eh
357
- refute(MIME::Type.new('text/plain').signature?)
358
- refute(MIME::Type.new('image/jpeg').signature?)
359
- refute(MIME::Type.new('application/x-msword').signature?)
360
- end
339
+ assert_priority_more text_1, text_2
340
+ end
361
341
 
362
- def test_signature_equals
363
- sig = MIME::Type.new('text/vCard') { |t| t.signature = true }
364
- assert(sig.signature?)
365
- end
342
+ it "sorts (3) based on the registration state" do
343
+ text_1.registered = text_1p.registered = true
344
+ text_1b = mime_type(text_1) { |t| t.registered = false }
366
345
 
367
- def test_simplified
368
- assert_equal('text/plain', MIME::Type.new('text/plain').simplified)
369
- assert_equal('image/jpeg', MIME::Type.new('image/jpeg').simplified)
370
- assert_equal('application/msword', MIME::Type.new('application/x-msword').simplified)
371
- assert_equal('text/vcard', MIME::Type.new('text/vCard').simplified)
372
- assert_equal('application/pkcs7-mime', MIME::Type.new('application/pkcs7-mime').simplified)
373
- assert_equal('chemical/pdb', MIME::Type.new('x-chemical/x-pdb').simplified)
374
- end
346
+ assert_priority text_1, text_1p, text_1b
347
+ end
375
348
 
376
- def test_sub_type
377
- assert_equal('plain', MIME::Type.new('text/plain').sub_type)
378
- assert_equal('jpeg', MIME::Type.new('image/jpeg').sub_type)
379
- assert_equal('msword', MIME::Type.new('application/x-msword').sub_type)
380
- assert_equal('vcard', MIME::Type.new('text/vCard').sub_type)
381
- assert_equal('pkcs7-mime', MIME::Type.new('application/pkcs7-mime').sub_type)
382
- assert_equal('zip', @applzip.sub_type)
383
- end
349
+ it "sorts (4) based on the completeness" do
350
+ text_1.extensions = text_1p.extensions = "1"
351
+ text_1b = mime_type(text_1) { |t| t.extensions = nil }
384
352
 
385
- def test_system
386
- assert_deprecated('MIME::Type#system') do
387
- assert_nil make_yaml_mime_type.system
353
+ assert_priority text_1, text_1p, text_1b
388
354
  end
389
- end
390
355
 
391
- def test_system_equals
392
- assert_deprecated('MIME::Type#system') do
393
- yaml = make_yaml_mime_type
394
- yaml.system = /win32/
395
- assert_nil yaml.system
356
+ it "sorts (5) based on obsolete status" do
357
+ text_1.obsolete = text_1p.obsolete = false
358
+ text_1b = mime_type(text_1) { |t| t.obsolete = true }
359
+
360
+ assert_priority text_1, text_1p, text_1b
396
361
  end
397
- end
398
362
 
399
- def test_system_eh
400
- assert_deprecated('MIME::Type#system?') do
401
- refute make_yaml_mime_type.system?
363
+ it "sorts (5) based on the use-instead value" do
364
+ text_1.obsolete = text_1p.obsolete = true
365
+ text_1.use_instead = text_1p.use_instead = "abc/xyz"
366
+ text_1b = mime_type(text_1) { |t| t.use_instead = nil }
367
+
368
+ assert_priority text_1, text_1p, text_1b
369
+
370
+ text_1b.use_instead = "abc/zzz"
371
+
372
+ assert_priority text_1, text_1p, text_1b
402
373
  end
403
374
  end
404
375
 
405
- def test_to_a
406
- yaml = make_yaml_mime_type
407
- assert_deprecated('MIME::Type#to_a') do
408
- assert_equal [ 'text/x-yaml', %w(yaml yml), '8bit', nil, false, [], [],
409
- false ], yaml.to_a
376
+ describe "#raw_media_type" do
377
+ it "extracts the media type as case-preserved" do
378
+ assert_equal "Text", mime_type("Text/plain").raw_media_type
410
379
  end
411
- end
412
380
 
413
- def test_to_hash
414
- yaml = make_yaml_mime_type
415
- assert_deprecated('MIME::Type#to_hash') do
416
- assert_equal(
417
- {
418
- 'Content-Type' => 'text/x-yaml',
419
- 'Content-Transfer-Encoding' => '8bit',
420
- 'Extensions' => %w(yaml yml),
421
- 'System' => nil,
422
- 'Registered' => false,
423
- 'URL' => [],
424
- 'Obsolete' => false,
425
- 'Docs' => []
426
- },
427
- yaml.to_hash)
381
+ it "does not remove x- prefixes" do
382
+ assert_equal("x-appl", x_appl_x_zip.raw_media_type)
428
383
  end
429
384
  end
430
385
 
431
- def assert_type_has_keys(type, *keys)
432
- hash = type.to_h
433
- keys.flatten.each { |key| assert(hash.key?(key)) }
434
- end
386
+ describe "#media_type" do
387
+ it "extracts the media type as lowercase" do
388
+ assert_equal "text", text_plain.media_type
389
+ end
435
390
 
436
- def test_to_h
437
- t = make('a/b')
438
- assert_type_has_keys(t, %w(content-type registered encoding))
439
- assert_type_has_keys(make(t) { |v| v.docs = 'Something' }, 'docs')
440
- assert_type_has_keys(make(t) { |v| v.extensions = %w(b) }, 'extensions')
441
- assert_type_has_keys(make(t) { |v| v.obsolete = true }, 'obsolete')
442
- assert_type_has_keys(make(t) { |v|
443
- v.obsolete = true
444
- v.use_instead = 'c/d'
445
- }, 'obsolete', 'use-instead')
446
- assert_type_has_keys(make(t) { |v| v.signature = true }, 'signature')
391
+ it "does not remove x- prefixes" do
392
+ assert_equal("x-appl", x_appl_x_zip.media_type)
393
+ end
447
394
  end
448
395
 
449
- def test_to_json
450
- assert_equal('{"content-type":"a/b","encoding":"base64","registered":true}',
451
- make('a/b').to_json)
452
- end
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
453
400
 
454
- def test_to_s
455
- assert_equal('text/plain', "#{MIME::Type.new('text/plain')}")
401
+ it "does not remove x- prefixes" do
402
+ assert_equal("x-appl", x_appl_x_zip.raw_media_type)
403
+ end
456
404
  end
457
405
 
458
- def test_class_constructors
459
- assert_instance_of(MIME::Type, MIME::Type.new('text/x-yaml'))
460
- assert_instance_of(MIME::Type, MIME::Type.new('text/x-yaml') { |y|
461
- assert_instance_of(MIME::Type, y)
462
- })
463
- assert_instance_of(MIME::Type, MIME::Type.new('content-type' => 'text/x-yaml'))
464
- assert_instance_of(MIME::Type, MIME::Type.new(['text/x-yaml', %w(yaml)]))
465
- assert_raises(MIME::Type::InvalidContentType) { MIME::Type.new('apps') }
466
- begin
467
- MIME::Type.new(nil)
468
- rescue MIME::Type::InvalidContentType => ex
469
- assert_equal('Invalid Content-Type nil', ex.message)
406
+ describe "#sub_type" do
407
+ it "extracts the sub type as lowercase" do
408
+ assert_equal "plain", text_plain.sub_type
470
409
  end
471
- end
472
410
 
473
- def test_to_str
474
- assert_equal('stringy', 'text/plain'.sub(MIME::Type.new('text/plain'), 'stringy'))
411
+ it "does not remove x- prefixes" do
412
+ assert_equal("x-zip", x_appl_x_zip.sub_type)
413
+ end
475
414
  end
476
415
 
477
- def test_references
478
- assert_deprecated('MIME::Type#references') do
479
- assert_empty make_yaml_mime_type.references
416
+ describe "#raw_sub_type" do
417
+ it "extracts the sub type as case-preserved" do
418
+ assert_equal "Plain", mime_type("text/Plain").raw_sub_type
419
+ end
420
+
421
+ it "does not remove x- prefixes" do
422
+ assert_equal("x-zip", x_appl_x_zip.raw_sub_type)
480
423
  end
481
424
  end
482
425
 
483
- def test_references_equals
484
- yaml = make_yaml_mime_type
485
- assert_deprecated('MIME::Type#references=') do
486
- yaml.references = :anything
426
+ describe "#to_h" do
427
+ let(:t) { mime_type("a/b") }
428
+
429
+ it "has the required keys (content-type, registered, encoding)" do
430
+ assert_has_keys t.to_h, %w[content-type registered encoding]
487
431
  end
488
- assert_deprecated('MIME::Type#references') do
489
- assert_empty yaml.references
432
+
433
+ it "has the docs key if there are documents" do
434
+ assert_has_keys mime_type(t) { |v| v.docs = "a" }.to_h, %w[docs]
490
435
  end
491
- end
492
436
 
493
- def test_xrefs
494
- assert_equal(
495
- {
496
- 'rfc' => %w(rfc4239),
497
- 'template' => %w(application/javascript)
498
- },
499
- make_javascript.xrefs
500
- )
501
- end
437
+ it "has the extensions key if set" do
438
+ assert_has_keys mime_type(t) { |v| v.extensions = "a" }.to_h,
439
+ "extensions"
440
+ end
502
441
 
503
- def test_xref_urls
504
- js = make_javascript do |j|
505
- j.xrefs = j.xrefs.merge(
506
- 'draft' => [ 'RFC-ietf-appsawg-json-merge-patch-07' ],
507
- 'person' => [ 'David_Singer' ],
508
- 'rfc-errata' => [ '3245' ],
509
- 'uri' => [ 'http://exmple.org' ],
510
- 'text' => [ 'text' ]
511
- )
442
+ it "has the preferred-extension key if set" do
443
+ assert_has_keys mime_type(t) { |v| v.preferred_extension = "a" }.to_h,
444
+ "preferred-extension"
512
445
  end
513
- assert_equal(
514
- [
515
- 'http://www.iana.org/go/rfc4239',
516
- 'http://www.iana.org/assignments/media-types/application/javascript',
517
- 'http://www.iana.org/go/draft-ietf-appsawg-json-merge-patch-07',
518
- 'http://www.iana.org/assignments/media-types/media-types.xhtml#David_Singer',
519
- 'http://www.rfc-editor.org/errata_search.php?eid=3245',
520
- 'http://exmple.org',
521
- 'text'
522
- ],
523
- js.xref_urls
524
- )
525
- end
526
446
 
527
- def test_url
528
- assert_deprecated('MIME::Type#url') do
529
- assert_empty(make_yaml_mime_type.url)
447
+ it "has the obsolete key if set" do
448
+ assert_has_keys mime_type(t) { |v| v.obsolete = true }.to_h, "obsolete"
530
449
  end
531
- end
532
450
 
533
- def test_url_equals
534
- yaml = make_yaml_mime_type
535
- assert_deprecated('MIME::Type#url=') do
536
- yaml.url = 'IANA'
451
+ it "has the obsolete and use-instead keys if set" do
452
+ assert_has_keys mime_type(t) { |v|
453
+ v.obsolete = true
454
+ v.use_instead = "c/d"
455
+ }.to_h, %w[obsolete use-instead]
537
456
  end
538
- assert_deprecated('MIME::Type#url') do
539
- assert_equal [], yaml.url
457
+
458
+ it "has the signature key if set" do
459
+ assert_has_keys mime_type(t) { |v| v.signature = true }.to_h, "signature"
540
460
  end
541
461
  end
542
462
 
543
- def test_urls
544
- yaml = make_yaml_mime_type
545
- assert_deprecated('MIME::Type#urls') do
546
- assert_empty yaml.urls
463
+ describe "#to_json" do
464
+ let(:expected_1) {
465
+ '{"content-type":"a/b","encoding":"base64","registered":false}'
466
+ }
467
+ let(:expected_2) {
468
+ '{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
469
+ }
470
+
471
+ it "converts to JSON when requested" do
472
+ assert_equal expected_1, mime_type("a/b").to_json
547
473
  end
548
- end
549
474
 
550
- def test_use_instead
551
- t = make('t/1') { |v| v.use_instead = 't/2' }
552
- assert_nil(t.use_instead)
553
- t.obsolete = true
554
- assert_equal('t/2', t.use_instead)
475
+ it "converts to JSON with provisional when requested" do
476
+ type = mime_type("a/b") do |t|
477
+ t.registered = true
478
+ t.provisional = true
479
+ end
480
+ assert_equal expected_2, type.to_json
481
+ end
555
482
  end
556
483
 
557
- def test_use_instead_equals
558
- t = make('t/1') { |v| v.obsolete = true }
559
- assert_nil(t.use_instead)
560
- t.use_instead = 't/2'
561
- assert_equal('t/2', t.use_instead)
484
+ describe "#to_s, #to_str" do
485
+ it "represents itself as a string of the canonical content_type" do
486
+ assert_equal "text/plain", text_plain.to_s
487
+ end
488
+
489
+ it "acts like a string of the canonical content_type for comparison" do
490
+ assert_equal text_plain, "text/plain"
491
+ end
492
+
493
+ it "acts like a string for other purposes" do
494
+ assert_equal "stringy", "text/plain".sub(text_plain, "stringy")
495
+ end
562
496
  end
563
497
 
564
- def test_preferred_extension
565
- assert_equal('zip', @applzip.preferred_extension)
498
+ describe "#xrefs, #xrefs=" do
499
+ let(:expected) {
500
+ MIME::Types::Container.new("rfc" => Set["rfc1234", "rfc5678"])
501
+ }
502
+
503
+ it "returns the expected results" do
504
+ application_javascript.xrefs = {
505
+ "rfc" => %w[rfc5678 rfc1234 rfc1234]
506
+ }
507
+
508
+ assert_equal expected, application_javascript.xrefs
509
+ end
566
510
  end
567
511
 
568
- def test_friendly_read
569
- yaml = make_yaml_mime_type
570
- assert_equal('YAML Structured Document', yaml.friendly)
571
- assert_equal('YAML Structured Document', yaml.friendly('en'))
572
- assert_equal(nil, yaml.friendly('fr'))
512
+ describe "#xref_urls" do
513
+ let(:expected) {
514
+ [
515
+ "http://www.iana.org/go/draft1",
516
+ "http://www.iana.org/assignments/media-types/a/b",
517
+ "http://www.iana.org/assignments/media-types/media-types.xhtml#p-1",
518
+ "http://www.iana.org/go/rfc-1",
519
+ "http://www.rfc-editor.org/errata_search.php?eid=err-1",
520
+ "http://example.org",
521
+ "text"
522
+ ]
523
+ }
524
+
525
+ let(:type) {
526
+ mime_type("a/b").tap do |t|
527
+ t.xrefs = {
528
+ "draft" => ["RFC1"],
529
+ "template" => ["a/b"],
530
+ "person" => ["p-1"],
531
+ "rfc" => ["rfc-1"],
532
+ "rfc-errata" => ["err-1"],
533
+ "uri" => ["http://example.org"],
534
+ "text" => ["text"]
535
+ }
536
+ end
537
+ }
538
+
539
+ it "translates according to given rules" do
540
+ assert_equal expected, type.xref_urls
541
+ end
573
542
  end
574
543
 
575
- def test_friendly_set
576
- assert_equal({ 'en' => 'Zip' }, @applzip.friendly(%w(en Zip)))
577
- assert_equal({ 'en' => 'Zip Archive' }, @applzip.friendly('en' => 'Zip Archive'))
544
+ describe "#use_instead" do
545
+ it "is nil unless the type is obsolete" do
546
+ assert_nil text_plain.use_instead
547
+ end
548
+
549
+ it "is nil if not set and the type is obsolete" do
550
+ text_plain.obsolete = true
551
+ assert_nil text_plain.use_instead
552
+ end
553
+
554
+ it "is a different type if set and the type is obsolete" do
555
+ text_plain.obsolete = true
556
+ text_plain.use_instead = "text/html"
557
+ assert_equal "text/html", text_plain.use_instead
558
+ end
578
559
  end
579
560
 
580
- def test_i18n_key
581
- assert_equal('text.plain', make('text/plain').i18n_key)
582
- assert_equal('application.vnd-3gpp-bsf-xml',
583
- make('application/vnd.3gpp.bsf+xml').i18n_key)
584
- assert_equal('application.msword', make('application/x-msword').i18n_key)
561
+ describe "#preferred_extension, #preferred_extension=" do
562
+ it "is nil when not set and there are no extensions" do
563
+ assert_nil text_plain.preferred_extension
564
+ end
565
+
566
+ it "is the first extension when not set but there are extensions" do
567
+ assert_equal "yaml", text_x_yaml.preferred_extension
568
+ end
569
+
570
+ it "is the extension provided when set" do
571
+ text_x_yaml.preferred_extension = "yml"
572
+ assert_equal "yml", text_x_yaml.preferred_extension
573
+ end
574
+
575
+ it "is adds the preferred extension if it does not exist" do
576
+ text_x_yaml.preferred_extension = "yz"
577
+ assert_equal "yz", text_x_yaml.preferred_extension
578
+ assert_includes text_x_yaml.extensions, "yz"
579
+ end
585
580
  end
586
581
 
587
- def test_deprecated_constant
588
- assert_output(nil, /MIME::InvalidContentType/) do
589
- assert_same(MIME::InvalidContentType, MIME::Type::InvalidContentType)
582
+ describe "#friendly" do
583
+ it "returns English by default" do
584
+ assert_equal "YAML Structured Document", text_x_yaml.friendly
590
585
  end
591
- assert_output(nil, /MIME::InvalidContentType/) do
592
- assert_same(MIME::InvalidContentType, MIME::Type::InvalidContentType)
586
+
587
+ it "returns English when requested" do
588
+ assert_equal "YAML Structured Document", text_x_yaml.friendly("en")
589
+ assert_equal "YAML Structured Document", text_x_yaml.friendly(:en)
590
+ end
591
+
592
+ it "returns nothing for an unknown language" do
593
+ assert_nil text_x_yaml.friendly("zz")
594
+ end
595
+
596
+ it "merges new values from an array parameter" do
597
+ expected = {"en" => "Text files"}
598
+ assert_equal expected, text_plain.friendly(["en", "Text files"])
599
+ expected.update("fr" => "des fichiers texte")
600
+ assert_equal expected,
601
+ text_plain.friendly(["fr", "des fichiers texte"])
602
+ end
603
+
604
+ it "merges new values from a hash parameter" do
605
+ expected = {"en" => "Text files"}
606
+ assert_equal expected, text_plain.friendly(expected)
607
+ french = {"fr" => "des fichiers texte"}
608
+ expected.update(french)
609
+ assert_equal expected, text_plain.friendly(french)
610
+ end
611
+
612
+ it "raises an ArgumentError if an unknown value is provided" do
613
+ exception = assert_raises ArgumentError do
614
+ text_plain.friendly(1)
615
+ end
616
+
617
+ assert_equal "Expected a language or translation set, not 1",
618
+ exception.message
593
619
  end
594
- assert_raises(NameError) { MIME::Foo }
595
620
  end
596
621
  end