Skip to content

Commit a90abaf

Browse files
committed
# This is a combination of 2 commits.
# This is the 1st commit message: WIP # This is the commit message #2: More WIP, still does not work
1 parent 7c40396 commit a90abaf

File tree

6 files changed

+58
-52
lines changed

6 files changed

+58
-52
lines changed

lib/mime/type.rb

+17-13
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,13 @@ def like?(other)
184184

185185
# Compares the +other+ MIME::Type against the exact content type or the
186186
# simplified type (the simplified type will be used if comparing against
187-
# something that can be treated as a String with #to_s). In comparisons,
188-
# this is done against the lowercase version of the MIME::Type.
187+
# something that can be treated as a String with #to_s). In comparisons, this
188+
# is done against the lowercase version of the MIME::Type.
189189
#
190190
# Note that this implementation of #<=> is deprecated and will be changed
191191
# in the next major version to be the same as #priority_compare.
192+
#
193+
# Note that MIME::Types no longer compare against nil.
192194
def <=>(other)
193195
return priority_compare(other) if other.is_a?(MIME::Type)
194196
simplified <=> other
@@ -201,7 +203,7 @@ def <=>(other)
201203
# consumers of mime-types. For the next major version of MIME::Types, this
202204
# method will become #<=> and #priority_compare will be removed.
203205
def priority_compare(other)
204-
if (cmp = __sort_priority <=> other.__sort_priority).zero?
206+
if (cmp = __sort_priority <=> other.__sort_priority) == 0
205207
simplified <=> other.simplified
206208
else
207209
cmp
@@ -243,7 +245,8 @@ def hash
243245
# The computed sort priority value. This is _not_ intended to be used by most
244246
# callers.
245247
def __sort_priority # :nodoc:
246-
@__sort_priority || update_sort_priority
248+
update_sort_priority if !instance_variable_defined?(:@__sort_priority) || @__sort_priority.nil?
249+
@__sort_priority
247250
end
248251

249252
# Returns the whole MIME content-type string.
@@ -330,7 +333,7 @@ def preferred_extension=(value) # :nodoc:
330333
if value
331334
add_extensions(value)
332335
set_preferred_extension_priority(value)
333-
else
336+
elsif instance_variable_defined?(:@preferred_extension)
334337
clear_extension_priority(@preferred_extension)
335338
end
336339
@preferred_extension = value
@@ -579,7 +582,7 @@ def encode_with(coder)
579582
coder["registered"] = registered?
580583
coder["provisional"] = provisional? if provisional?
581584
coder["signature"] = signature? if signature?
582-
coder["sort-priority"] = __sort_priority
585+
coder["sort-priority"] = __sort_priority || 0b11111111
583586
coder["extension-priorities"] = __extension_priorities unless __extension_priorities.empty?
584587
coder
585588
end
@@ -659,12 +662,12 @@ def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
659662
end
660663
end
661664

662-
private
663-
664-
def __extension_priorities
665+
def __extension_priorities # :nodoc:
665666
@extension_priorities ||= {}
666667
end
667668

669+
private
670+
668671
def clear_extension_priority(ext)
669672
__extension_priorities.delete(ext) if ext
670673
end
@@ -699,14 +702,15 @@ def clear_sort_priority
699702
# 16, to a minimum of 0.
700703
def update_sort_priority
701704
extension_count = @extensions.length
702-
obsolete = @obsolete ? 1 << 7 : 0
703-
provisional = @provisional ? 1 << 6 : 0
704-
registered = @registered ? 0 : 1 << 5
705+
obsolete = (instance_variable_defined?(:@obsolete) && @obsolete) ? 1 << 7 : 0
706+
provisional = (instance_variable_defined?(:@provisional) && @provisional) ? 1 << 6 : 0
707+
registered = (instance_variable_defined?(:@registered) && @registered) ? 0 : 1 << 5
705708
complete = extension_count.nonzero? ? 0 : 1 << 4
706709
extension_count = [0, 16 - extension_count].max
707710

708711
@__sort_priority = obsolete | registered | provisional | complete | extension_count
709-
@__priority_penalty = (@obsolete ? 3 : 0) + (@registered ? 0 : 2)
712+
@__priority_penalty = ((instance_variable_defined?(:@obsolete) && @obsolete) ? 3 : 0) +
713+
((instance_variable_defined?(:@registered) && @registered) ? 0 : 2)
710714
end
711715

712716
def __priority_penalty

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

lib/mime/types.rb

+3-5
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,10 @@ def [](type_id, complete: false, registered: false)
148148
# puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
149149
# => [application/xml, image/gif, text/xml]
150150
def type_for(filename)
151-
extensions = Array(filename).map { |fn| fn.chomp.downcase[/\.?([^.]*?)$/, 1] }
152-
153-
extensions.flat_map { |ext|
154-
@extension_index[ext]
151+
Array(filename).flat_map { |fn|
152+
@extension_index[fn.chomp.downcase[/\.?([^.]*?)\z/m, 1]]
155153
}.compact.inject(Set.new, :+).sort { |a, b|
156-
by_ext = a.extension_priority(*extensions) <=> b.extension_priority(*extensions)
154+
by_ext = a.extension_priority(*a.extensions) <=> b.extension_priority(*b.extensions)
157155

158156
if by_ext.zero?
159157
a.priority_compare(b)

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

test/test_mime_type.rb

+28-24
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).chars.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,19 +347,24 @@ 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

366370
it "sorts (3) based on the registration state" do
@@ -377,13 +381,6 @@ def assert_priority(left, middle, right)
377381
assert_priority text_1, text_1p, text_1b
378382
end
379383

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
386-
387384
it "sorts (5) based on the use-instead value" do
388385
text_1.obsolete = text_1p.obsolete = true
389386
text_1.use_instead = text_1p.use_instead = "abc/xyz"
@@ -395,6 +392,13 @@ def assert_priority(left, middle, right)
395392

396393
assert_priority text_1, text_1p, text_1b
397394
end
395+
396+
it "sorts based on extensions (more extensions sort lower)" do
397+
text_1.extensions = ["foo", "bar"]
398+
text_2.extensions = ["foo"]
399+
400+
assert_priority_less text_1, text_2
401+
end
398402
end
399403

400404
describe "#raw_media_type" do
@@ -502,10 +506,10 @@ def assert_has_keys(wanted_keys, actual, msg = nil)
502506

503507
describe "#to_json" do
504508
let(:expected_1) {
505-
'{"content-type":"a/b","encoding":"base64","registered":false}'
509+
'{"content-type":"a/b","encoding":"base64","registered":false,"sort-priority":48}'
506510
}
507511
let(:expected_2) {
508-
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
512+
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true,"sort-priority":80}'
509513
}
510514

511515
it "converts to JSON when requested" do

test/test_mime_types_class.rb

+3-4
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

@@ -86,9 +86,8 @@ def setup
8686
assert_equal %w[image/jpeg], MIME::Types.of(["foo.jpeg", "bar.jpeg"])
8787
end
8888

89-
it "finds multiple extensions" do
90-
assert_equal %w[image/jpeg text/plain],
91-
MIME::Types.type_for(%w[foo.txt foo.jpeg])
89+
it "finds multiple extensions ordered by the filename list" do
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)