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