From 8c09cc1afcad119e11fb59f3cc91b3ca1e12fd5f Mon Sep 17 00:00:00 2001 From: Austin Ziegler Date: Sat, 21 Nov 2020 16:22:24 -0500 Subject: [PATCH 1/2] Add a stable sort MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - This probably has a negative performance impact, so I’m not sure I’m going to merge this. --- lib/mime/types.rb | 21 +++++++++++++-------- test/test_mime_types.rb | 13 +++++++++---- test/test_mime_types_class.rb | 6 ++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/lib/mime/types.rb b/lib/mime/types.rb index 026be34..05d7974 100644 --- a/lib/mime/types.rb +++ b/lib/mime/types.rb @@ -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 @@ -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 @@ -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" diff --git a/test/test_mime_types.rb b/test/test_mime_types.rb index a0812a8..e0e19c5 100644 --- a/test/test_mime_types.rb +++ b/test/test_mime_types.rb @@ -18,7 +18,8 @@ def mime_types "content-type" => "application/gzip", "extensions" => "gz", "registered" => true - ) + ), + *MIME::Types.type_for("foo.webm") } end @@ -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 @@ -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 diff --git a/test/test_mime_types_class.rb b/test/test_mime_types_class.rb index 08e9556..fa689ec 100644 --- a/test/test_mime_types_class.rb +++ b/test/test_mime_types_class.rb @@ -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 From 650047ee5f954ef5488b54ff1ddb5d651e5b5e24 Mon Sep 17 00:00:00 2001 From: Austin Ziegler Date: Mon, 15 Nov 2021 13:41:25 -0500 Subject: [PATCH 2/2] Standardrb fixup --- test/test_mime_types_class.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/test_mime_types_class.rb b/test/test_mime_types_class.rb index fa689ec..f219cb5 100644 --- a/test/test_mime_types_class.rb +++ b/test/test_mime_types_class.rb @@ -101,15 +101,13 @@ 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 + + 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