Skip to content

Commit 50e63b7

Browse files
committed
Add a stable sort
- This probably has a negative performance impact, so I’m not sure I’m going to merge this.
1 parent 156aba6 commit 50e63b7

File tree

4 files changed

+31
-17
lines changed

4 files changed

+31
-17
lines changed

lib/mime/types.rb

+12-7
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@ def [](type_id, complete: false, registered: false)
131131
@type_variants[MIME::Type.simplified(type_id)]
132132
end
133133

134-
prune_matches(matches, complete, registered).sort { |a, b|
135-
a.priority_compare(b)
136-
}
134+
stable_sort(prune_matches(matches, complete, registered))
137135
end
138136

139137
# Return the list of MIME::Types which belongs to the file based on its
@@ -149,11 +147,12 @@ def [](type_id, complete: false, registered: false)
149147
# puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
150148
# => [application/xml, image/gif, text/xml]
151149
def type_for(filename)
152-
Array(filename).flat_map { |fn|
150+
results =
151+
Array(filename).flat_map { |fn|
153152
@extension_index[fn.chomp.downcase[/\.?([^.]*?)$/, 1]]
154-
}.compact.inject(Set.new, :+).sort { |a, b|
155-
a.priority_compare(b)
156-
}
153+
}.compact.inject(Set.new, :+)
154+
155+
stable_sort(results)
157156
end
158157
alias of type_for
159158

@@ -221,6 +220,12 @@ def match(pattern)
221220
k =~ pattern
222221
}.values.inject(Set.new, :+)
223222
end
223+
224+
def stable_sort(list)
225+
list.lazy.each_with_index.sort { |(a, ai), (b, bi)|
226+
a.priority_compare(b).nonzero? || ai <=> bi
227+
}.map(&:first)
228+
end
224229
end
225230

226231
require 'mime/types/cache'

mime-types.gemspec

+6-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
2626

2727
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
2828
s.add_runtime_dependency(%q<mime-types-data>.freeze, ["~> 3.2015"])
29-
s.add_development_dependency(%q<minitest>.freeze, ["~> 5.13"])
29+
s.add_development_dependency(%q<minitest>.freeze, ["~> 5.14"])
3030
s.add_development_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
3131
s.add_development_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
3232
s.add_development_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
@@ -38,10 +38,10 @@ Gem::Specification.new do |s|
3838
s.add_development_dependency(%q<rake>.freeze, [">= 10.0", "< 14.0"])
3939
s.add_development_dependency(%q<simplecov>.freeze, ["~> 0.7"])
4040
s.add_development_dependency(%q<rdoc>.freeze, [">= 4.0", "< 7"])
41-
s.add_development_dependency(%q<hoe>.freeze, ["~> 3.20"])
41+
s.add_development_dependency(%q<hoe>.freeze, ["~> 3.22"])
4242
else
4343
s.add_dependency(%q<mime-types-data>.freeze, ["~> 3.2015"])
44-
s.add_dependency(%q<minitest>.freeze, ["~> 5.13"])
44+
s.add_dependency(%q<minitest>.freeze, ["~> 5.14"])
4545
s.add_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
4646
s.add_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
4747
s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
@@ -53,11 +53,11 @@ Gem::Specification.new do |s|
5353
s.add_dependency(%q<rake>.freeze, [">= 10.0", "< 14.0"])
5454
s.add_dependency(%q<simplecov>.freeze, ["~> 0.7"])
5555
s.add_dependency(%q<rdoc>.freeze, [">= 4.0", "< 7"])
56-
s.add_dependency(%q<hoe>.freeze, ["~> 3.20"])
56+
s.add_dependency(%q<hoe>.freeze, ["~> 3.22"])
5757
end
5858
else
5959
s.add_dependency(%q<mime-types-data>.freeze, ["~> 3.2015"])
60-
s.add_dependency(%q<minitest>.freeze, ["~> 5.13"])
60+
s.add_dependency(%q<minitest>.freeze, ["~> 5.14"])
6161
s.add_dependency(%q<hoe-doofus>.freeze, ["~> 1.0"])
6262
s.add_dependency(%q<hoe-gemspec2>.freeze, ["~> 1.1"])
6363
s.add_dependency(%q<hoe-git>.freeze, ["~> 1.6"])
@@ -69,6 +69,6 @@ Gem::Specification.new do |s|
6969
s.add_dependency(%q<rake>.freeze, [">= 10.0", "< 14.0"])
7070
s.add_dependency(%q<simplecov>.freeze, ["~> 0.7"])
7171
s.add_dependency(%q<rdoc>.freeze, [">= 4.0", "< 7"])
72-
s.add_dependency(%q<hoe>.freeze, ["~> 3.20"])
72+
s.add_dependency(%q<hoe>.freeze, ["~> 3.22"])
7373
end
7474
end

test/test_mime_types.rb

+9-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ def mime_types
1818
'content-type' => 'application/gzip',
1919
'extensions' => 'gz',
2020
'registered' => true
21-
)
21+
),
22+
*MIME::Types.type_for('foo.webm')
2223
}
2324
end
2425

@@ -38,8 +39,8 @@ def mime_types
3839
end
3940

4041
it 'is countable with an enumerator' do
41-
assert_equal 6, mime_types.each.count
42-
assert_equal 6, mime_types.lazy.count
42+
assert_equal 8, mime_types.each.count
43+
assert_equal 8, mime_types.lazy.count
4344
end
4445
end
4546

@@ -159,11 +160,15 @@ def mime_types
159160
plain_text.add_extensions('xtxt')
160161
assert_includes mime_types.type_for('xtxt'), 'text/plain'
161162
end
163+
164+
it 'returns a stable order for types with equal priority' do
165+
assert_equal %w(audio/webm video/webm), mime_types.type_for('foo.webm')
166+
end
162167
end
163168

164169
describe '#count' do
165170
it 'can count the number of types inside' do
166-
assert_equal 6, mime_types.count
171+
assert_equal 8, mime_types.count
167172
end
168173
end
169174
end

test/test_mime_types_class.rb

+4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ def setup
100100
plain_text.add_extensions('xtxt')
101101
assert_includes MIME::Types.type_for('xtxt'), 'text/plain'
102102
end
103+
104+
it 'returns a stable order for types with equal priority' do
105+
assert_equal %w(audio/webm video/webm), MIME::Types.type_for('foo.webm')
106+
end
103107
end
104108

105109
describe '.count' do

0 commit comments

Comments
 (0)