mime-types 3.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +413 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +93 -0
- data/CONTRIBUTORS.md +52 -0
- data/{Licence.md → LICENCE.md} +9 -10
- data/Manifest.txt +8 -6
- data/README.md +200 -0
- data/Rakefile +66 -95
- data/SECURITY.md +7 -0
- data/lib/mime/type/columnar.rb +14 -1
- data/lib/mime/type.rb +178 -92
- data/lib/mime/types/_columnar.rb +52 -5
- data/lib/mime/types/container.rb +45 -15
- data/lib/mime/types/deprecations.rb +39 -19
- data/lib/mime/types/loader.rb +2 -2
- data/lib/mime/types/logger.rb +35 -4
- data/lib/mime/types/registry.rb +6 -4
- data/lib/mime/types/version.rb +14 -0
- data/lib/mime/types.rb +21 -11
- data/test/minitest_helper.rb +3 -4
- data/test/test_mime_type.rb +95 -77
- data/test/test_mime_types.rb +20 -20
- data/test/test_mime_types_class.rb +13 -7
- metadata +54 -102
- data/.standard.yml +0 -4
- data/Code-of-Conduct.md +0 -73
- data/Contributing.md +0 -132
- data/History.md +0 -319
- data/README.rdoc +0 -194
|
@@ -2,35 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
require "mime/types/logger"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
class << MIME::Types
|
|
6
|
+
# Used to mark a method as deprecated in the mime-types interface.
|
|
7
|
+
def deprecated(options = {}, &block) # :nodoc:
|
|
8
|
+
message =
|
|
9
|
+
if options[:message]
|
|
10
|
+
options[:message]
|
|
11
|
+
else
|
|
12
|
+
klass = options.fetch(:class)
|
|
13
|
+
|
|
14
|
+
msep = case klass
|
|
13
15
|
when Class, Module
|
|
14
16
|
"."
|
|
15
17
|
else
|
|
16
18
|
klass = klass.class
|
|
17
19
|
"#"
|
|
18
20
|
end
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
|
|
22
|
+
method = "#{klass}#{msep}#{options.fetch(:method)}"
|
|
23
|
+
pre = " #{options[:pre]}" if options[:pre]
|
|
24
|
+
post = case options[:next]
|
|
21
25
|
when :private, :protected
|
|
22
|
-
"and will be #{
|
|
23
|
-
when
|
|
24
|
-
"and will be removed"
|
|
26
|
+
" and will be made #{options[:next]}"
|
|
27
|
+
when :removed
|
|
28
|
+
" and will be removed"
|
|
29
|
+
when nil, ""
|
|
30
|
+
nil
|
|
25
31
|
else
|
|
26
|
-
|
|
32
|
+
" #{options[:next]}"
|
|
27
33
|
end
|
|
28
|
-
MIME::Types.logger.debug <<-WARNING.chomp.strip
|
|
29
|
-
#{caller(2..2).first}: #{klass}#{level}#{sym} is deprecated #{message}.
|
|
30
|
-
WARNING
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
<<-WARNING.chomp.strip
|
|
36
|
+
#{caller(2..2).first}: #{klass}#{msep}#{method}#{pre} is deprecated#{post}.
|
|
37
|
+
WARNING
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if !__deprecation_logged?(message, options[:once])
|
|
41
|
+
MIME::Types.logger.__send__(options[:level] || :debug, message)
|
|
34
42
|
end
|
|
43
|
+
|
|
44
|
+
return unless block
|
|
45
|
+
block.call
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def __deprecation_logged?(message, once)
|
|
51
|
+
return false unless once
|
|
52
|
+
|
|
53
|
+
@__deprecations_logged = {} unless defined?(@__deprecations_logged)
|
|
54
|
+
@__deprecations_logged.key?(message)
|
|
35
55
|
end
|
|
36
56
|
end
|
data/lib/mime/types/loader.rb
CHANGED
|
@@ -13,7 +13,7 @@ require "mime/types/data"
|
|
|
13
13
|
#
|
|
14
14
|
# The Loader will use one of the following paths:
|
|
15
15
|
# 1. The +path+ provided in its constructor argument;
|
|
16
|
-
# 2. The value of ENV[
|
|
16
|
+
# 2. The value of ENV["RUBY_MIME_TYPES_DATA"]; or
|
|
17
17
|
# 3. The value of MIME::Types::Data::PATH.
|
|
18
18
|
#
|
|
19
19
|
# When #load is called, the +path+ will be searched recursively for all YAML
|
|
@@ -79,7 +79,7 @@ class MIME::Types::Loader
|
|
|
79
79
|
#
|
|
80
80
|
# This will load from columnar files (#load_columnar) if <tt>columnar:
|
|
81
81
|
# true</tt> is provided in +options+ and there are columnar files in +path+.
|
|
82
|
-
def load(options = {columnar:
|
|
82
|
+
def load(options = {columnar: true})
|
|
83
83
|
if options[:columnar] && !Dir[columnar_path].empty?
|
|
84
84
|
load_columnar
|
|
85
85
|
else
|
data/lib/mime/types/logger.rb
CHANGED
|
@@ -9,7 +9,18 @@ module MIME
|
|
|
9
9
|
class << self
|
|
10
10
|
# Configure the MIME::Types logger. This defaults to an instance of a
|
|
11
11
|
# logger that passes messages (unformatted) through to Kernel#warn.
|
|
12
|
-
attr_accessor
|
|
12
|
+
# :attr_accessor: logger
|
|
13
|
+
attr_reader :logger
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
def logger=(logger) # :nodoc
|
|
17
|
+
@logger =
|
|
18
|
+
if logger.nil?
|
|
19
|
+
NullLogger.new
|
|
20
|
+
else
|
|
21
|
+
logger
|
|
22
|
+
end
|
|
23
|
+
end
|
|
13
24
|
end
|
|
14
25
|
|
|
15
26
|
class WarnLogger < ::Logger # :nodoc:
|
|
@@ -25,13 +36,33 @@ module MIME
|
|
|
25
36
|
end
|
|
26
37
|
end
|
|
27
38
|
|
|
28
|
-
def initialize(
|
|
29
|
-
super
|
|
39
|
+
def initialize(*)
|
|
40
|
+
super(nil)
|
|
30
41
|
@logdev = WarnLogDevice.new
|
|
31
42
|
@formatter = ->(_s, _d, _p, m) { m }
|
|
32
43
|
end
|
|
33
44
|
end
|
|
34
45
|
|
|
35
|
-
|
|
46
|
+
class NullLogger < ::Logger
|
|
47
|
+
def initialize(*)
|
|
48
|
+
super(nil)
|
|
49
|
+
@logdev = nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def reopen(_)
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def <<(_)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def close
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def add(_severity, _message = nil, _progname = nil)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
self.logger = WarnLogger.new
|
|
36
67
|
end
|
|
37
68
|
end
|
data/lib/mime/types/registry.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "mime/types/deprecations"
|
|
4
|
+
|
|
3
5
|
class << MIME::Types
|
|
4
6
|
include Enumerable
|
|
5
7
|
|
|
@@ -45,11 +47,11 @@ class << MIME::Types
|
|
|
45
47
|
def lazy_load?
|
|
46
48
|
return unless ENV.key?("RUBY_MIME_TYPES_LAZY_LOAD")
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed.
|
|
50
|
-
|
|
50
|
+
deprecated(
|
|
51
|
+
message: "Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed."
|
|
52
|
+
)
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] != "false"
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
def __types__
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
module MIME
|
|
5
|
+
class Types
|
|
6
|
+
# The released version of the mime-types library.
|
|
7
|
+
VERSION = "3.7.0"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Type
|
|
11
|
+
# The released version of the mime-types library.
|
|
12
|
+
VERSION = MIME::Types::VERSION
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/mime/types.rb
CHANGED
|
@@ -66,9 +66,6 @@ require "mime/type"
|
|
|
66
66
|
# puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
|
|
67
67
|
#
|
|
68
68
|
class MIME::Types
|
|
69
|
-
# The release version of Ruby MIME::Types
|
|
70
|
-
VERSION = MIME::Type::VERSION
|
|
71
|
-
|
|
72
69
|
include Enumerable
|
|
73
70
|
|
|
74
71
|
# Creates a new MIME::Types registry.
|
|
@@ -133,9 +130,7 @@ class MIME::Types
|
|
|
133
130
|
@type_variants[MIME::Type.simplified(type_id)]
|
|
134
131
|
end
|
|
135
132
|
|
|
136
|
-
prune_matches(matches, complete, registered).sort
|
|
137
|
-
a.priority_compare(b)
|
|
138
|
-
}
|
|
133
|
+
prune_matches(matches, complete, registered).sort
|
|
139
134
|
end
|
|
140
135
|
|
|
141
136
|
# Return the list of MIME::Types which belongs to the file based on its
|
|
@@ -151,10 +146,14 @@ class MIME::Types
|
|
|
151
146
|
# puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
|
|
152
147
|
# => [application/xml, image/gif, text/xml]
|
|
153
148
|
def type_for(filename)
|
|
154
|
-
Array(filename).
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
149
|
+
wanted = Array(filename).map { |fn| fn.chomp.downcase[/\.?([^.]*?)\z/m, 1] }
|
|
150
|
+
|
|
151
|
+
wanted
|
|
152
|
+
.flat_map { |ext| @extension_index[ext] }
|
|
153
|
+
.compact
|
|
154
|
+
.reduce(Set.new, :+)
|
|
155
|
+
.sort { |a, b|
|
|
156
|
+
a.__extension_priority_compare(b, wanted)
|
|
158
157
|
}
|
|
159
158
|
end
|
|
160
159
|
alias_method :of, :type_for
|
|
@@ -165,7 +164,7 @@ class MIME::Types
|
|
|
165
164
|
# The last parameter may be the value <tt>:silent</tt> or +true+ which
|
|
166
165
|
# will suppress duplicate MIME type warnings.
|
|
167
166
|
def add(*types)
|
|
168
|
-
quiet = (
|
|
167
|
+
quiet = (types.last == :silent) || (types.last == true)
|
|
169
168
|
|
|
170
169
|
types.each do |mime_type|
|
|
171
170
|
case mime_type
|
|
@@ -196,6 +195,10 @@ class MIME::Types
|
|
|
196
195
|
index_extensions!(type)
|
|
197
196
|
end
|
|
198
197
|
|
|
198
|
+
def __fully_loaded? # :nodoc:
|
|
199
|
+
true
|
|
200
|
+
end
|
|
201
|
+
|
|
199
202
|
private
|
|
200
203
|
|
|
201
204
|
def add_type_variant!(mime_type)
|
|
@@ -223,6 +226,12 @@ class MIME::Types
|
|
|
223
226
|
k =~ pattern
|
|
224
227
|
}.values.inject(Set.new, :+)
|
|
225
228
|
end
|
|
229
|
+
|
|
230
|
+
# def stable_sort(list)
|
|
231
|
+
# list.lazy.each_with_index.sort { |(a, ai), (b, bi)|
|
|
232
|
+
# a.priority_compare(b).nonzero? || ai <=> bi
|
|
233
|
+
# }.map(&:first)
|
|
234
|
+
# end
|
|
226
235
|
end
|
|
227
236
|
|
|
228
237
|
require "mime/types/cache"
|
|
@@ -231,3 +240,4 @@ require "mime/types/loader"
|
|
|
231
240
|
require "mime/types/logger"
|
|
232
241
|
require "mime/types/_columnar"
|
|
233
242
|
require "mime/types/registry"
|
|
243
|
+
require "mime/types/version"
|
data/test/minitest_helper.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "mime/type"
|
|
4
|
-
require "fileutils"
|
|
5
|
-
|
|
6
3
|
gem "minitest"
|
|
7
4
|
require "minitest/focus"
|
|
8
|
-
require "minitest-bonus-assertions"
|
|
9
5
|
require "minitest/hooks"
|
|
10
6
|
|
|
7
|
+
require "fileutils"
|
|
8
|
+
|
|
9
|
+
require "mime/type"
|
|
11
10
|
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] = "yes"
|
data/test/test_mime_type.rb
CHANGED
|
@@ -9,13 +9,13 @@ 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|
|
|
18
|
+
mime_type("content-type" => "application/javascript") do |js|
|
|
19
19
|
js.friendly("en" => "JavaScript")
|
|
20
20
|
js.xrefs = {
|
|
21
21
|
"rfc" => %w[rfc4239 rfc4239],
|
|
@@ -27,7 +27,7 @@ describe MIME::Type do
|
|
|
27
27
|
end
|
|
28
28
|
}
|
|
29
29
|
let(:text_x_yaml) {
|
|
30
|
-
mime_type("text/x-yaml") do |yaml|
|
|
30
|
+
mime_type("content-type" => "text/x-yaml") do |yaml|
|
|
31
31
|
yaml.extensions = %w[yaml yml]
|
|
32
32
|
yaml.encoding = "8bit"
|
|
33
33
|
yaml.friendly("en" => "YAML Structured Document")
|
|
@@ -88,20 +88,22 @@ describe MIME::Type do
|
|
|
88
88
|
describe ".new" do
|
|
89
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
96
|
it "creates a valid content type just from a string" do
|
|
97
|
-
|
|
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
|
-
|
|
100
|
-
|
|
100
|
+
assert_instance_of MIME::Type, type
|
|
101
|
+
assert_equal "text/x-yaml", type.content_type
|
|
102
|
+
end
|
|
101
103
|
end
|
|
102
104
|
|
|
103
105
|
it "yields the content type in a block" do
|
|
104
|
-
MIME::Type.new("text/x-yaml") do |type|
|
|
106
|
+
MIME::Type.new("content-type" => "text/x-yaml") do |type|
|
|
105
107
|
assert_instance_of MIME::Type, type
|
|
106
108
|
assert_equal "text/x-yaml", type.content_type
|
|
107
109
|
end
|
|
@@ -118,10 +120,12 @@ describe MIME::Type do
|
|
|
118
120
|
end
|
|
119
121
|
|
|
120
122
|
it "creates a valid content type from an array" do
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
|
@@ -143,7 +147,7 @@ describe MIME::Type do
|
|
|
143
147
|
end
|
|
144
148
|
|
|
145
149
|
it "correctly compares equivalent types" do
|
|
146
|
-
right = mime_type("text/Plain")
|
|
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
|
|
@@ -171,11 +175,6 @@ describe MIME::Type do
|
|
|
171
175
|
refute_equal text_plain, "text/html"
|
|
172
176
|
assert_operator text_plain, :>, "text/html"
|
|
173
177
|
end
|
|
174
|
-
|
|
175
|
-
it "correctly compares against nil" do
|
|
176
|
-
refute_equal text_html, nil
|
|
177
|
-
assert_operator text_plain, :<, nil
|
|
178
|
-
end
|
|
179
178
|
end
|
|
180
179
|
|
|
181
180
|
describe "#ascii?" do
|
|
@@ -204,14 +203,14 @@ describe MIME::Type do
|
|
|
204
203
|
end
|
|
205
204
|
|
|
206
205
|
it "is false when there are no extensions" do
|
|
207
|
-
refute mime_type("text/plain").complete?
|
|
206
|
+
refute mime_type("content-type" => "text/plain").complete?
|
|
208
207
|
end
|
|
209
208
|
end
|
|
210
209
|
|
|
211
210
|
describe "#content_type" do
|
|
212
211
|
it "preserves the original case" do
|
|
213
212
|
assert_equal "text/plain", text_plain.content_type
|
|
214
|
-
assert_equal "text/vCard", mime_type("text/vCard").content_type
|
|
213
|
+
assert_equal "text/vCard", mime_type("content-type" => "text/vCard").content_type
|
|
215
214
|
end
|
|
216
215
|
|
|
217
216
|
it "does not remove x- prefixes" do
|
|
@@ -266,27 +265,27 @@ describe MIME::Type do
|
|
|
266
265
|
end
|
|
267
266
|
|
|
268
267
|
it "is true for an equivalent MIME::Type" do
|
|
269
|
-
assert text_plain.eql?(mime_type("text/Plain"))
|
|
268
|
+
assert text_plain.eql?(mime_type("content-type" => "text/Plain"))
|
|
270
269
|
end
|
|
271
270
|
|
|
272
271
|
it "is true for an equivalent subclass of MIME::Type" do
|
|
273
272
|
subclass = Class.new(MIME::Type)
|
|
274
|
-
assert text_plain.eql?(subclass.new("text/plain"))
|
|
273
|
+
assert text_plain.eql?(subclass.new("content-type" => "text/plain"))
|
|
275
274
|
end
|
|
276
275
|
end
|
|
277
276
|
|
|
278
277
|
describe "#hash" do
|
|
279
278
|
it "is the same between #eql? MIME::Type instances" do
|
|
280
|
-
assert_equal text_plain.hash, mime_type("text/plain").hash
|
|
279
|
+
assert_equal text_plain.hash, mime_type("content-type" => "text/plain").hash
|
|
281
280
|
end
|
|
282
281
|
|
|
283
282
|
it "is the same between #eql? MIME::Type instances of different classes" do
|
|
284
283
|
subclass = Class.new(MIME::Type)
|
|
285
|
-
assert_equal text_plain.hash, subclass.new("text/plain").hash
|
|
284
|
+
assert_equal text_plain.hash, subclass.new("content-type" => "text/plain").hash
|
|
286
285
|
end
|
|
287
286
|
|
|
288
287
|
it "uses the #simplified value" do
|
|
289
|
-
assert_equal text_plain.hash, mime_type("text/Plain").hash
|
|
288
|
+
assert_equal text_plain.hash, mime_type("content-type" => "text/Plain").hash
|
|
290
289
|
end
|
|
291
290
|
end
|
|
292
291
|
|
|
@@ -322,41 +321,56 @@ describe MIME::Type do
|
|
|
322
321
|
end
|
|
323
322
|
|
|
324
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
|
+
|
|
325
334
|
def assert_priority_less(left, right)
|
|
326
|
-
assert_equal(-1, left.priority_compare(right))
|
|
335
|
+
assert_equal(-1, left.priority_compare(right), "#{priority(left)} is not less than #{priority(right)}")
|
|
327
336
|
end
|
|
328
337
|
|
|
329
338
|
def assert_priority_same(left, right)
|
|
330
|
-
assert_equal 0, left.priority_compare(right)
|
|
339
|
+
assert_equal 0, left.priority_compare(right), "#{priority(left)} is not equal to #{priority(right)}"
|
|
331
340
|
end
|
|
332
341
|
|
|
333
342
|
def assert_priority_more(left, right)
|
|
334
|
-
assert_equal 1, left.priority_compare(right)
|
|
343
|
+
assert_equal 1, left.priority_compare(right), "#{priority(left)} is not more than #{priority(right)}"
|
|
335
344
|
end
|
|
336
345
|
|
|
337
346
|
def assert_priority(left, middle, right)
|
|
338
347
|
assert_priority_less left, right
|
|
339
348
|
assert_priority_same left, middle
|
|
340
|
-
assert_priority_more right,
|
|
349
|
+
assert_priority_more right, middle
|
|
341
350
|
end
|
|
342
351
|
|
|
343
|
-
let(:text_1) { mime_type("text/1") }
|
|
344
|
-
let(:text_1p) { mime_type("text/1") }
|
|
345
|
-
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") }
|
|
346
355
|
|
|
347
|
-
it "sorts
|
|
356
|
+
it "sorts based on the simplified type when the sort priorities are the same" do
|
|
348
357
|
assert_priority text_1, text_1p, text_2
|
|
349
358
|
end
|
|
350
359
|
|
|
351
|
-
it "sorts
|
|
352
|
-
text_1.
|
|
353
|
-
|
|
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 }
|
|
354
363
|
|
|
355
|
-
|
|
364
|
+
assert_priority_less text_1, text_1b
|
|
365
|
+
|
|
366
|
+
assert_priority text_1, text_1p, text_1b
|
|
367
|
+
end
|
|
356
368
|
|
|
357
|
-
|
|
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 }
|
|
358
372
|
|
|
359
|
-
|
|
373
|
+
assert_priority text_1, text_1p, text_1b
|
|
360
374
|
end
|
|
361
375
|
|
|
362
376
|
it "sorts (3) based on the registration state" do
|
|
@@ -373,29 +387,17 @@ describe MIME::Type do
|
|
|
373
387
|
assert_priority text_1, text_1p, text_1b
|
|
374
388
|
end
|
|
375
389
|
|
|
376
|
-
it "sorts
|
|
377
|
-
text_1.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
assert_priority text_1, text_1p, text_1b
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
it "sorts (5) based on the use-instead value" do
|
|
384
|
-
text_1.obsolete = text_1p.obsolete = true
|
|
385
|
-
text_1.use_instead = text_1p.use_instead = "abc/xyz"
|
|
386
|
-
text_1b = mime_type(text_1) { |t| t.use_instead = nil }
|
|
387
|
-
|
|
388
|
-
assert_priority text_1, text_1p, text_1b
|
|
389
|
-
|
|
390
|
-
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"]
|
|
391
393
|
|
|
392
|
-
|
|
394
|
+
assert_priority_less text_1, text_2
|
|
393
395
|
end
|
|
394
396
|
end
|
|
395
397
|
|
|
396
398
|
describe "#raw_media_type" do
|
|
397
399
|
it "extracts the media type as case-preserved" do
|
|
398
|
-
assert_equal "Text", mime_type("Text/plain").raw_media_type
|
|
400
|
+
assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type
|
|
399
401
|
end
|
|
400
402
|
|
|
401
403
|
it "does not remove x- prefixes" do
|
|
@@ -415,7 +417,7 @@ describe MIME::Type do
|
|
|
415
417
|
|
|
416
418
|
describe "#raw_media_type" do
|
|
417
419
|
it "extracts the media type as case-preserved" do
|
|
418
|
-
assert_equal "Text", mime_type("Text/plain").raw_media_type
|
|
420
|
+
assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type
|
|
419
421
|
end
|
|
420
422
|
|
|
421
423
|
it "does not remove x- prefixes" do
|
|
@@ -435,7 +437,7 @@ describe MIME::Type do
|
|
|
435
437
|
|
|
436
438
|
describe "#raw_sub_type" do
|
|
437
439
|
it "extracts the sub type as case-preserved" do
|
|
438
|
-
assert_equal "Plain", mime_type("text/Plain").raw_sub_type
|
|
440
|
+
assert_equal "Plain", mime_type("content-type" => "text/Plain").raw_sub_type
|
|
439
441
|
end
|
|
440
442
|
|
|
441
443
|
it "does not remove x- prefixes" do
|
|
@@ -444,56 +446,72 @@ describe MIME::Type do
|
|
|
444
446
|
end
|
|
445
447
|
|
|
446
448
|
describe "#to_h" do
|
|
447
|
-
let(:t) { mime_type("a/b") }
|
|
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
|
|
448
468
|
|
|
449
469
|
it "has the required keys (content-type, registered, encoding)" do
|
|
450
|
-
assert_has_keys
|
|
470
|
+
assert_has_keys %w[content-type registered encoding], t
|
|
451
471
|
end
|
|
452
472
|
|
|
453
473
|
it "has the docs key if there are documents" do
|
|
454
|
-
assert_has_keys mime_type(t) { |v| v.docs = "a" }
|
|
474
|
+
assert_has_keys "docs", mime_type(t) { |v| v.docs = "a" }
|
|
455
475
|
end
|
|
456
476
|
|
|
457
477
|
it "has the extensions key if set" do
|
|
458
|
-
assert_has_keys mime_type(t) { |v| v.extensions = "a" }
|
|
459
|
-
"extensions"
|
|
478
|
+
assert_has_keys "extensions", mime_type(t) { |v| v.extensions = "a" }
|
|
460
479
|
end
|
|
461
480
|
|
|
462
481
|
it "has the preferred-extension key if set" do
|
|
463
|
-
assert_has_keys mime_type(t) { |v| v.preferred_extension = "a" }
|
|
464
|
-
"preferred-extension"
|
|
482
|
+
assert_has_keys "preferred-extension", mime_type(t) { |v| v.preferred_extension = "a" }
|
|
465
483
|
end
|
|
466
484
|
|
|
467
485
|
it "has the obsolete key if set" do
|
|
468
|
-
assert_has_keys mime_type(t) { |v| v.obsolete = true }
|
|
486
|
+
assert_has_keys "obsolete", mime_type(t) { |v| v.obsolete = true }
|
|
469
487
|
end
|
|
470
488
|
|
|
471
489
|
it "has the obsolete and use-instead keys if set" do
|
|
472
|
-
assert_has_keys mime_type(t) { |v|
|
|
490
|
+
assert_has_keys %w[obsolete use-instead], mime_type(t) { |v|
|
|
473
491
|
v.obsolete = true
|
|
474
492
|
v.use_instead = "c/d"
|
|
475
|
-
}
|
|
493
|
+
}
|
|
476
494
|
end
|
|
477
495
|
|
|
478
496
|
it "has the signature key if set" do
|
|
479
|
-
assert_has_keys mime_type(t) { |v| v.signature = true }
|
|
497
|
+
assert_has_keys "signature", mime_type(t) { |v| v.signature = true }
|
|
480
498
|
end
|
|
481
499
|
end
|
|
482
500
|
|
|
483
501
|
describe "#to_json" do
|
|
484
502
|
let(:expected_1) {
|
|
485
|
-
'{"content-type":"a/b","encoding":"base64","registered":false}'
|
|
503
|
+
'{"content-type":"a/b","encoding":"base64","registered":false,"sort-priority":48}'
|
|
486
504
|
}
|
|
487
505
|
let(:expected_2) {
|
|
488
|
-
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
|
|
506
|
+
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true,"sort-priority":80}'
|
|
489
507
|
}
|
|
490
508
|
|
|
491
509
|
it "converts to JSON when requested" do
|
|
492
|
-
assert_equal expected_1, mime_type("a/b").to_json
|
|
510
|
+
assert_equal expected_1, mime_type("content-type" => "a/b").to_json
|
|
493
511
|
end
|
|
494
512
|
|
|
495
513
|
it "converts to JSON with provisional when requested" do
|
|
496
|
-
type = mime_type("a/b") do |t|
|
|
514
|
+
type = mime_type("content-type" => "a/b") do |t|
|
|
497
515
|
t.registered = true
|
|
498
516
|
t.provisional = true
|
|
499
517
|
end
|
|
@@ -543,7 +561,7 @@ describe MIME::Type do
|
|
|
543
561
|
}
|
|
544
562
|
|
|
545
563
|
let(:type) {
|
|
546
|
-
mime_type("a/b").tap do |t|
|
|
564
|
+
mime_type("content-type" => "a/b").tap do |t|
|
|
547
565
|
t.xrefs = {
|
|
548
566
|
"draft" => ["RFC1"],
|
|
549
567
|
"template" => ["a/b"],
|