mime-types 2.99.3 → 3.2.2

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