mime-types 1.17.2 → 3.0

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