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.
- checksums.yaml +7 -0
- data/.autotest +35 -0
- data/.gitignore +17 -0
- data/.hoerc +20 -12
- data/Code-of-Conduct.rdoc +41 -0
- data/Contributing.rdoc +169 -0
- data/History.rdoc +531 -30
- data/Licence.rdoc +25 -0
- data/Manifest.txt +32 -34
- data/README.rdoc +198 -13
- data/Rakefile +181 -159
- data/lib/mime/type/columnar.rb +55 -0
- data/lib/mime/type.rb +566 -0
- data/lib/mime/types/cache.rb +56 -0
- data/lib/mime/types/columnar.rb +142 -0
- data/lib/mime/types/container.rb +30 -0
- data/lib/mime/types/deprecations.rb +32 -0
- data/lib/mime/types/full.rb +17 -0
- data/lib/mime/types/loader.rb +148 -0
- data/lib/mime/types/logger.rb +37 -0
- data/lib/mime/types/registry.rb +81 -0
- data/lib/mime/types.rb +199 -819
- data/lib/mime-types.rb +1 -0
- data/support/benchmarks/load.rb +65 -0
- data/support/benchmarks/load_allocations.rb +90 -0
- data/support/benchmarks/object_counts.rb +43 -0
- data/support/profile/columnar.rb +5 -0
- data/support/profile/columnar_full.rb +5 -0
- data/support/profile/full.rb +5 -0
- data/test/bad-fixtures/malformed +9 -0
- data/test/fixture/json.json +1 -0
- data/test/fixture/old-data +9 -0
- data/test/fixture/yaml.yaml +55 -0
- data/test/minitest_helper.rb +12 -0
- data/test/test_mime_type.rb +527 -242
- data/test/test_mime_types.rb +130 -68
- data/test/test_mime_types_cache.rb +100 -0
- data/test/test_mime_types_class.rb +155 -0
- data/test/test_mime_types_lazy.rb +43 -0
- data/test/test_mime_types_loader.rb +32 -0
- metadata +286 -229
- data/License.rdoc +0 -10
- data/lib/mime/types/application +0 -940
- data/lib/mime/types/application.mac +0 -2
- data/lib/mime/types/application.nonstandard +0 -114
- data/lib/mime/types/application.obsolete +0 -40
- data/lib/mime/types/audio +0 -131
- data/lib/mime/types/audio.nonstandard +0 -10
- data/lib/mime/types/audio.obsolete +0 -1
- data/lib/mime/types/image +0 -43
- data/lib/mime/types/image.nonstandard +0 -17
- data/lib/mime/types/image.obsolete +0 -5
- data/lib/mime/types/message +0 -19
- data/lib/mime/types/message.obsolete +0 -1
- data/lib/mime/types/model +0 -15
- data/lib/mime/types/multipart +0 -14
- data/lib/mime/types/multipart.nonstandard +0 -1
- data/lib/mime/types/multipart.obsolete +0 -7
- data/lib/mime/types/other.nonstandard +0 -8
- data/lib/mime/types/text +0 -54
- data/lib/mime/types/text.nonstandard +0 -5
- data/lib/mime/types/text.obsolete +0 -7
- data/lib/mime/types/text.vms +0 -1
- data/lib/mime/types/video +0 -68
- data/lib/mime/types/video.nonstandard +0 -11
- data/lib/mime/types/video.obsolete +0 -3
- data/mime-types.gemspec +0 -57
- data/type-lists/application.txt +0 -951
- data/type-lists/audio.txt +0 -132
- data/type-lists/image.txt +0 -43
- data/type-lists/message.txt +0 -20
- data/type-lists/model.txt +0 -15
- data/type-lists/multipart.txt +0 -14
- data/type-lists/text.txt +0 -57
- data/type-lists/video.txt +0 -67
data/test/test_mime_type.rb
CHANGED
@@ -1,318 +1,603 @@
|
|
1
|
-
|
1
|
+
# -*- ruby encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'mime/types'
|
4
|
-
require '
|
5
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
-
|
88
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
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
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
133
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
142
|
+
describe '#<=>' do
|
143
|
+
it 'correctly compares identical types' do
|
144
|
+
assert_equal text_plain, text_plain
|
145
|
+
end
|
139
146
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
150
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
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
|
-
|
173
|
-
|
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
|
-
|
177
|
-
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
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
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
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
|
-
|
197
|
-
|
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
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
219
|
-
|
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
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
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
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
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
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
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
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
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
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
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
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
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
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
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
|
-
|
284
|
-
|
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
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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
|
-
|
300
|
-
|
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
|
-
|
304
|
-
|
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
|
-
|
308
|
-
|
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
|
-
|
312
|
-
|
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
|
-
|
316
|
-
|
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
|