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 Jan 2, 2024
1 parent 7cf621f commit 8c09cc1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
21 changes: 13 additions & 8 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|
@extension_index[fn.chomp.downcase[/\.?([^.]*?)\z/m, 1]]
}.compact.inject(Set.new, :+).sort { |a, b|
a.priority_compare(b)
}
results =
Array(filename).flat_map { |fn|
@extension_index[fn.chomp.downcase[/\.?([^.]*?)\z/m, 1]]
}.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
13 changes: 9 additions & 4 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 @@ -38,8 +39,8 @@ def mime_types
end

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

Expand Down Expand Up @@ -163,11 +164,15 @@ def mime_types
it "handles newline characters correctly" do
assert_includes mime_types.type_for("test.pdf\n.txt"), "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
assert_equal 8, mime_types.count
end
end
end
6 changes: 6 additions & 0 deletions test/test_mime_types_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,15 @@ def setup
assert_includes MIME::Types.type_for("xtxt"), "text/plain"
end

<<<<<<< HEAD
it "handles newline characters correctly" do
assert_includes MIME::Types.type_for("test.pdf\n.txt"), "text/plain"
assert_includes MIME::Types.type_for("test.txt\n.pdf"), "application/pdf"
||||||| parent of 32714bc5f1ae (Add a stable sort)
=======
it 'returns a stable order for types with equal priority' do
assert_equal %w(audio/webm video/webm), MIME::Types.type_for('foo.webm')
>>>>>>> 32714bc5f1ae (Add a stable sort)
end
end

Expand Down

0 comments on commit 8c09cc1

Please sign in to comment.