Skip to content

Commit bb89d13

Browse files
committed
WIP
1 parent 2b8ae86 commit bb89d13

File tree

5 files changed

+54
-43
lines changed

5 files changed

+54
-43
lines changed

Diff for: lib/mime/type.rb

+15-11
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def initialize(content_type) # :yields: self
131131
@friendly = {}
132132
@obsolete = @registered = @provisional = false
133133
@preferred_extension = @docs = @use_instead = @__sort_priority = nil
134-
self.__extension_priorities
134+
__extension_priorities
135135

136136
self.extensions = []
137137

@@ -176,6 +176,8 @@ def like?(other)
176176
#
177177
# Note that this implementation of #<=> is deprecated and will be changed
178178
# in the next major version to be the same as #priority_compare.
179+
#
180+
# Note that MIME::Types no longer compare against nil.
179181
def <=>(other)
180182
return priority_compare(other) if other.is_a?(MIME::Type)
181183
simplified <=> other
@@ -230,7 +232,8 @@ def hash
230232
# The computed sort priority value. This is _not_ intended to be used by most
231233
# callers.
232234
def __sort_priority # :nodoc:
233-
@__sort_priority || update_sort_priority
235+
update_sort_priority if !instance_variable_defined?(:@__sort_priority) || @__sort_priority.nil?
236+
@__sort_priority
234237
end
235238

236239
# Returns the whole MIME content-type string.
@@ -317,7 +320,7 @@ def preferred_extension=(value) # :nodoc:
317320
if value
318321
add_extensions(value)
319322
set_preferred_extension_priority(value)
320-
else
323+
elsif instance_variable_defined?(:@preferred_extension)
321324
clear_extension_priority(@preferred_extension)
322325
end
323326
@preferred_extension = value
@@ -566,7 +569,7 @@ def encode_with(coder)
566569
coder["registered"] = registered?
567570
coder["provisional"] = provisional? if provisional?
568571
coder["signature"] = signature? if signature?
569-
coder["sort-priority"] = __sort_priority
572+
coder["sort-priority"] = __sort_priority || 0b11111111
570573
coder["extension-priorities"] = __extension_priorities unless __extension_priorities.empty?
571574
coder
572575
end
@@ -646,12 +649,12 @@ def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
646649
end
647650
end
648651

649-
private
650-
651-
def __extension_priorities
652+
def __extension_priorities # :nodoc:
652653
@extension_priorities ||= {}
653654
end
654655

656+
private
657+
655658
def clear_extension_priority(ext)
656659
__extension_priorities.delete(ext) if ext
657660
end
@@ -686,14 +689,15 @@ def clear_sort_priority
686689
# 16, to a minimum of 0.
687690
def update_sort_priority
688691
extension_count = @extensions.length
689-
obsolete = @obsolete ? 1 << 7 : 0
690-
provisional = @provisional ? 1 << 6 : 0
691-
registered = @registered ? 0 : 1 << 5
692+
obsolete = instance_variable_defined?(:@obsolete) && @obsolete ? 1 << 7 : 0
693+
provisional = instance_variable_defined?(:@provisional) && @provisional ? 1 << 6 : 0
694+
registered = instance_variable_defined?(:@registered) && @registered ? 0 : 1 << 5
692695
complete = extension_count.nonzero? ? 0 : 1 << 4
693696
extension_count = [0, 16 - extension_count].max
694697

695698
@__sort_priority = obsolete | registered | provisional | complete | extension_count
696-
@__priority_penalty = (@obsolete ? 3 : 0) + (@registered ? 0 : 2)
699+
@__priority_penalty = (instance_variable_defined?(:@obsolete) && @obsolete ? 3 : 0) +
700+
(instance_variable_defined?(:@registered) && @registered ? 0 : 2)
697701
end
698702

699703
def __priority_penalty

Diff for: lib/mime/type/columnar.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
class MIME::Type::Columnar < MIME::Type
1616
def initialize(container, content_type, extensions) # :nodoc:
1717
@container = container
18+
@__priority_penalty = nil
1819
self.content_type = content_type
19-
self.extensions = extensions
20+
@extensions = Set[*Array(extensions).flatten.compact].freeze
21+
clear_sort_priority
2022
end
2123

2224
def self.column(*methods, file: nil) # :nodoc:
@@ -60,7 +62,7 @@ def update_sort_priority
6062
obsolete = (@__sort_priority & (1 << 7)) != 0
6163
registered = (@__sort_priority & (1 << 5)) == 0
6264

63-
@__priority_penalty = (@obsolete ? 3 : 0) + (@registered ? 0 : 2)
65+
@__priority_penalty = (obsolete ? 3 : 0) + (registered ? 0 : 2)
6466
end
6567
end
6668

Diff for: lib/mime/types/_columnar.rb

+3-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ def load_base_data(path) # :nodoc:
3030
line = line.split
3131
content_type = line.shift
3232
extensions = line
33-
# content_type, *extensions = line.split
3433

3534
type = MIME::Type::Columnar.new(self, content_type, extensions)
3635
@__mime_data__ << type
@@ -162,9 +161,9 @@ def dict(line, transform: nil)
162161
def dict_extension_priority(h, k, v)
163162
return if v.nil?
164163

165-
v = v.to_i if v.kind_of?(String)
166-
v = v.trunc if v.kind_of?(Float)
167-
v = [[-20, v].max, 20].min
164+
v = v.to_i if v.is_a?(String)
165+
v = v.trunc if v.is_a?(Float)
166+
v = [[-20, v].max, 20].min
168167

169168
return if v.zero?
170169

Diff for: test/test_mime_type.rb

+30-23
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,6 @@ def mime_type(content_type)
175175
refute_equal text_plain, "text/html"
176176
assert_operator text_plain, :>, "text/html"
177177
end
178-
179-
it "correctly compares against nil" do
180-
refute_equal text_html, nil
181-
assert_operator text_plain, :<, nil
182-
end
183178
end
184179

185180
describe "#ascii?" do
@@ -326,16 +321,20 @@ def mime_type(content_type)
326321
end
327322

328323
describe "#priority_compare" do
324+
def priority(type)
325+
"#{type} (#{("%08b" % type.__sort_priority).split(//).join(" ")})"
326+
end
327+
329328
def assert_priority_less(left, right)
330-
assert_equal(-1, left.priority_compare(right))
329+
assert_equal -1, left.priority_compare(right), "#{priority(left)} is not less than #{priority(right)}"
331330
end
332331

333332
def assert_priority_same(left, right)
334-
assert_equal 0, left.priority_compare(right)
333+
assert_equal 0, left.priority_compare(right), "#{priority(left)} is not equal to #{priority(right)}"
335334
end
336335

337336
def assert_priority_more(left, right)
338-
assert_equal 1, left.priority_compare(right)
337+
assert_equal 1, left.priority_compare(right), "#{priority(left)} is not more than #{priority(right)}"
339338
end
340339

341340
def assert_priority(left, middle, right)
@@ -348,21 +347,27 @@ def assert_priority(left, middle, right)
348347
let(:text_1p) { mime_type("content-type" => "text/1") }
349348
let(:text_2) { mime_type("content-type" => "text/2") }
350349

351-
it "sorts (1) based on the simplified type" do
350+
it "sorts based on the simplified type when the sort priorities are the same" do
352351
assert_priority text_1, text_1p, text_2
353352
end
354353

355-
it "sorts (2) based on extensions" do
356-
text_1.extensions = ["foo", "bar"]
357-
text_2.extensions = ["foo"]
354+
it "sorts obsolete types higher than non-obsolete types" do
355+
text_1.obsolete = text_1p.obsolete = false
356+
text_1b = mime_type(text_1) { |t| t.obsolete = true }
357+
358+
assert_priority_less text_1, text_1b
358359

359-
assert_priority_same text_1, text_2
360+
assert_priority text_1, text_1p, text_1b
361+
end
360362

361-
text_2.registered = true
363+
it "sorts provisional types higher than non-provisional types" do
364+
text_1.provisional = text_1p.provisional = true
365+
text_1b = mime_type(text_1) { |t| t.provisional = false }
362366

363-
assert_priority_more text_1, text_2
367+
assert_priority text_1, text_1p, text_1b
364368
end
365369

370+
366371
it "sorts (3) based on the registration state" do
367372
text_1.registered = text_1p.registered = true
368373
text_1b = mime_type(text_1) { |t| t.registered = false }
@@ -377,12 +382,6 @@ def assert_priority(left, middle, right)
377382
assert_priority text_1, text_1p, text_1b
378383
end
379384

380-
it "sorts (5) based on obsolete status" do
381-
text_1.obsolete = text_1p.obsolete = false
382-
text_1b = mime_type(text_1) { |t| t.obsolete = true }
383-
384-
assert_priority text_1, text_1p, text_1b
385-
end
386385

387386
it "sorts (5) based on the use-instead value" do
388387
text_1.obsolete = text_1p.obsolete = true
@@ -395,6 +394,14 @@ def assert_priority(left, middle, right)
395394

396395
assert_priority text_1, text_1p, text_1b
397396
end
397+
398+
it "sorts based on extensions (more extensions sort lower)" do
399+
text_1.extensions = ["foo", "bar"]
400+
text_2.extensions = ["foo"]
401+
402+
assert_priority_less text_1, text_2
403+
end
404+
398405
end
399406

400407
describe "#raw_media_type" do
@@ -486,10 +493,10 @@ def assert_priority(left, middle, right)
486493

487494
describe "#to_json" do
488495
let(:expected_1) {
489-
'{"content-type":"a/b","encoding":"base64","registered":false}'
496+
'{"content-type":"a/b","encoding":"base64","registered":false,"sort-priority":48}'
490497
}
491498
let(:expected_2) {
492-
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
499+
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true,"sort-priority":80}'
493500
}
494501

495502
it "converts to JSON when requested" do

Diff for: test/test_mime_types_class.rb

+2-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def setup
4747
}
4848
# This is this way because of a new type ending with gzip that only
4949
# appears in some data files.
50-
assert_equal %w[application/gzip application/x-gzip multipart/x-gzip], types
50+
assert_equal %w[application/gzip multipart/x-gzip application/x-gzip], types
5151
assert_equal 3, types.size
5252
end
5353

@@ -87,8 +87,7 @@ def setup
8787
end
8888

8989
it "finds multiple extensions" do
90-
assert_equal %w[image/jpeg text/plain],
91-
MIME::Types.type_for(%w[foo.txt foo.jpeg])
90+
assert_equal %w[text/plain image/jpeg], MIME::Types.type_for(%w[foo.txt foo.jpeg])
9291
end
9392

9493
it "does not find unknown extensions" do

0 commit comments

Comments
 (0)