Skip to content

Commit

Permalink
Add a stable sort
Browse files Browse the repository at this point in the history
- This probably has a negative performance impact, so I’m not sure I’m going to
  merge this.
  • Loading branch information
halostatue committed Feb 17, 2023
1 parent 0bf7805 commit 32714bc
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
19 changes: 12 additions & 7 deletions lib/mime/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ def [](type_id, complete: false, registered: false)
@type_variants[MIME::Type.simplified(type_id)]
end

prune_matches(matches, complete, registered).sort { |a, b|
a.priority_compare(b)
}
stable_sort(prune_matches(matches, complete, registered))
end

# Return the list of MIME::Types which belongs to the file based on its
Expand All @@ -151,11 +149,12 @@ def [](type_id, complete: false, registered: false)
# puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
# => [application/xml, image/gif, text/xml]
def type_for(filename)
Array(filename).flat_map { |fn|
results =
Array(filename).flat_map { |fn|
@extension_index[fn.chomp.downcase[/\.?([^.]*?)$/, 1]]
}.compact.inject(Set.new, :+).sort { |a, b|
a.priority_compare(b)
}
}.compact.inject(Set.new, :+)

stable_sort(results)
end
alias_method :of, :type_for

Expand Down Expand Up @@ -223,6 +222,12 @@ def match(pattern)
k =~ pattern
}.values.inject(Set.new, :+)
end

def stable_sort(list)
list.lazy.each_with_index.sort { |(a, ai), (b, bi)|
a.priority_compare(b).nonzero? || ai <=> bi
}.map(&:first)
end
end

require "mime/types/cache"
Expand Down
19 changes: 12 additions & 7 deletions test/test_mime_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def mime_types
"content-type" => "application/gzip",
"extensions" => "gz",
"registered" => true
)
),
*MIME::Types.type_for("foo.webm")
}
end

Expand All @@ -37,9 +38,9 @@ def mime_types
assert_kind_of Enumerator::Lazy, mime_types.map.lazy
end

it "is countable with an enumerator" do
assert_equal 6, mime_types.each.count
assert_equal 6, mime_types.lazy.count
it 'is countable with an enumerator' do
assert_equal 8, mime_types.each.count
assert_equal 8, mime_types.lazy.count
end
end

Expand Down Expand Up @@ -159,11 +160,15 @@ def mime_types
plain_text.add_extensions("xtxt")
assert_includes mime_types.type_for("xtxt"), "text/plain"
end

it 'returns a stable order for types with equal priority' do
assert_equal %w(audio/webm video/webm), mime_types.type_for('foo.webm')
end
end

describe "#count" do
it "can count the number of types inside" do
assert_equal 6, mime_types.count
describe '#count' do
it 'can count the number of types inside' do
assert_equal 8, mime_types.count
end
end
end
4 changes: 4 additions & 0 deletions test/test_mime_types_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ def setup
plain_text.add_extensions("xtxt")
assert_includes MIME::Types.type_for("xtxt"), "text/plain"
end

it 'returns a stable order for types with equal priority' do
assert_equal %w(audio/webm video/webm), MIME::Types.type_for('foo.webm')
end
end

describe ".count" do
Expand Down

0 comments on commit 32714bc

Please sign in to comment.