mime-types 2.99.3 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/{Code-of-Conduct.rdoc → Code-of-Conduct.md} +19 -20
  3. data/Contributing.md +139 -0
  4. data/History.md +208 -0
  5. data/{Licence.rdoc → Licence.md} +4 -18
  6. data/Manifest.txt +8 -25
  7. data/README.rdoc +63 -67
  8. data/Rakefile +144 -55
  9. data/lib/mime/type/columnar.rb +29 -62
  10. data/lib/mime/type.rb +192 -417
  11. data/lib/mime/types/_columnar.rb +137 -0
  12. data/lib/mime/types/cache.rb +51 -73
  13. data/lib/mime/types/columnar.rb +2 -147
  14. data/lib/mime/types/container.rb +94 -0
  15. data/lib/mime/types/deprecations.rb +5 -24
  16. data/lib/mime/types/full.rb +19 -0
  17. data/lib/mime/types/loader.rb +12 -141
  18. data/lib/mime/types/logger.rb +4 -0
  19. data/lib/mime/types/registry.rb +90 -0
  20. data/lib/mime/types.rb +43 -139
  21. data/lib/mime-types.rb +1 -1
  22. data/test/minitest_helper.rb +6 -12
  23. data/test/test_mime_type.rb +473 -455
  24. data/test/test_mime_types.rb +136 -86
  25. data/test/test_mime_types_cache.rb +83 -53
  26. data/test/test_mime_types_class.rb +119 -97
  27. data/test/test_mime_types_lazy.rb +27 -23
  28. data/test/test_mime_types_loader.rb +7 -32
  29. metadata +102 -62
  30. data/Contributing.rdoc +0 -170
  31. data/History-Types.rdoc +0 -454
  32. data/History.rdoc +0 -590
  33. data/data/mime-types.json +0 -1
  34. data/data/mime.content_type.column +0 -1980
  35. data/data/mime.docs.column +0 -1980
  36. data/data/mime.encoding.column +0 -1980
  37. data/data/mime.friendly.column +0 -1980
  38. data/data/mime.obsolete.column +0 -1980
  39. data/data/mime.registered.column +0 -1980
  40. data/data/mime.signature.column +0 -1980
  41. data/data/mime.use_instead.column +0 -1980
  42. data/data/mime.xrefs.column +0 -1980
  43. data/docs/COPYING.txt +0 -339
  44. data/docs/artistic.txt +0 -127
  45. data/lib/mime/types/loader_path.rb +0 -15
  46. data/support/apache_mime_types.rb +0 -108
  47. data/support/benchmarks/load.rb +0 -64
  48. data/support/benchmarks/load_allocations.rb +0 -83
  49. data/support/benchmarks/object_counts.rb +0 -41
  50. data/support/convert/columnar.rb +0 -88
  51. data/support/convert.rb +0 -158
  52. data/support/iana_registry.rb +0 -172
@@ -1,121 +1,171 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- ruby encoding: utf-8 -*-
2
4
 
3
5
  require 'mime/types'
4
6
  require 'minitest_helper'
5
7
 
6
- class TestMIMETypes < Minitest::Test
7
- def setup
8
- @mime_types = MIME::Types.new
9
- @mime_types.add(MIME::Type.new(['text/plain', %w(txt)]),
10
- MIME::Type.new(['image/jpeg', %w(jpg jpeg)]),
11
- MIME::Type.new('application/x-wordperfect6.1'),
12
- MIME::Type.new('content-type' => 'application/x-www-form-urlencoded', 'registered' => true),
13
- MIME::Type.new(['application/x-gzip', %w(gz)]),
14
- MIME::Type.new(['application/gzip', %w(gz)]))
8
+ describe MIME::Types do
9
+ def mime_types
10
+ @mime_types ||= MIME::Types.new.tap do |mt|
11
+ mt.add MIME::Type.new(['text/plain', %w(txt)]),
12
+ MIME::Type.new(['image/jpeg', %w(jpg jpeg)]),
13
+ MIME::Type.new('application/x-wordperfect6.1'),
14
+ MIME::Type.new(
15
+ 'content-type' => 'application/x-www-form-urlencoded',
16
+ 'registered' => true
17
+ ),
18
+ MIME::Type.new(['application/x-gzip', %w(gz)]),
19
+ MIME::Type.new(
20
+ 'content-type' => 'application/gzip',
21
+ 'extensions' => 'gz',
22
+ 'registered' => true
23
+ )
24
+ end
15
25
  end
16
26
 
17
- def test_enumerable
18
- assert(@mime_types.any? { |type| type.content_type == 'text/plain' })
19
- assert_kind_of(Enumerator, @mime_types.each)
20
- assert_equal(6, @mime_types.each.count)
21
- end
27
+ describe 'is enumerable' do
28
+ it 'correctly uses an Enumerable method like #any?' do
29
+ assert mime_types.any? { |type| type.content_type == 'text/plain' }
30
+ end
22
31
 
23
- def test_index_with_mime_type
24
- xtxp = MIME::Type.new('x-text/x-plain')
25
- assert_includes(@mime_types[xtxp], 'text/plain')
26
- assert_equal(1, @mime_types[xtxp].size)
27
- end
32
+ it 'implements each with no parameters to return an Enumerator' do
33
+ assert_kind_of Enumerator, mime_types.each
34
+ assert_kind_of Enumerator, mime_types.map
35
+ end
28
36
 
29
- def test_index_with_regex
30
- assert_includes(@mime_types[/plain/], 'text/plain')
31
- assert_equal(1, @mime_types[/plain/].size)
32
- end
37
+ it 'will create a lazy enumerator' do
38
+ assert_kind_of Enumerator::Lazy, mime_types.lazy
39
+ assert_kind_of Enumerator::Lazy, mime_types.map.lazy
40
+ end
33
41
 
34
- def test_index_with_string
35
- assert_includes(@mime_types['text/plain'], 'text/plain')
36
- assert_equal(1, @mime_types['text/plain'].size)
42
+ it 'is countable with an enumerator' do
43
+ assert_equal 6, mime_types.each.count
44
+ assert_equal 6, mime_types.lazy.count
45
+ end
37
46
  end
38
47
 
39
- def test_index_with_complete_flag
40
- assert_empty(@mime_types['text/vnd.fly', complete: true])
41
- refute_empty(@mime_types['text/plain', complete: true])
42
- end
48
+ describe '#[]' do
49
+ it 'can be searched with a MIME::Type' do
50
+ text_plain = MIME::Type.new('text/plain')
51
+ assert_includes mime_types[text_plain], 'text/plain'
52
+ assert_equal 1, mime_types[text_plain].size
53
+ end
43
54
 
44
- def test_index_with_registered_flag
45
- assert_empty(@mime_types['application/x-wordperfect6.1',
46
- registered: true])
47
- refute_empty(@mime_types['application/x-www-form-urlencoded',
48
- registered: true])
49
- refute_empty(@mime_types['application/gzip', registered: true])
50
- refute_equal(@mime_types['application/gzip'].size,
51
- @mime_types['application/gzip', registered: true])
52
- end
55
+ it 'can be searched with a regular expression' do
56
+ assert_includes mime_types[/plain$/], 'text/plain'
57
+ assert_equal 1, mime_types[/plain$/].size
58
+ end
53
59
 
54
- def test_index_with_platform_flag
55
- assert_deprecated('MIME::Types#[]', 'using the :platform flag') do
56
- refute_empty MIME::Types['text/plain', platform: true]
60
+ it 'sorts by priority with multiple matches' do
61
+ assert_equal %w(application/gzip application/x-gzip), mime_types[/gzip$/]
62
+ assert_equal 2, mime_types[/gzip$/].size
57
63
  end
58
- end
59
64
 
60
- def test_add
61
- eruby = MIME::Type.new('application/x-eruby') do |t|
62
- t.extensions = 'rhtml'
63
- t.encoding = '8bit'
65
+ it 'can be searched with a string' do
66
+ assert_includes mime_types['text/plain'], 'text/plain'
67
+ assert_equal 1, mime_types['text/plain'].size
64
68
  end
65
69
 
66
- @mime_types.add(eruby)
70
+ it 'can be searched with the complete flag' do
71
+ assert_empty mime_types[
72
+ 'application/x-www-form-urlencoded',
73
+ complete: true
74
+ ]
75
+ assert_includes mime_types['text/plain', complete: true], 'text/plain'
76
+ assert_equal 1, mime_types['text/plain', complete: true].size
77
+ end
78
+
79
+ it 'can be searched with the registered flag' do
80
+ assert_empty mime_types['application/x-wordperfect6.1', registered: true]
81
+ refute_empty mime_types[
82
+ 'application/x-www-form-urlencoded',
83
+ registered: true
84
+ ]
85
+ refute_empty mime_types[/gzip/, registered: true]
86
+ refute_equal mime_types[/gzip/], mime_types[/gzip/, registered: true]
87
+ end
67
88
 
68
- assert_equal(@mime_types['application/x-eruby'], [eruby])
89
+ it 'properly returns an empty result on a regular expression miss' do
90
+ assert_empty mime_types[/^foo/]
91
+ assert_empty mime_types[/^foo/, registered: true]
92
+ assert_empty mime_types[/^foo/, complete: true]
93
+ end
69
94
  end
70
95
 
71
- def test_type_for
72
- assert_equal(%w(application/gzip application/x-gzip),
73
- @mime_types.type_for('gz'))
74
- assert_equal(%w(image/jpeg), MIME::Types.of('foo.jpeg'))
75
- assert_equal(%w(image/jpeg text/plain),
76
- MIME::Types.type_for(%w(foo.txt foo.jpeg)))
77
- assert_deprecated('MIME::Types#type_for', 'using the platform parameter') do
78
- assert_equal(@mime_types.of('gif', true), @mime_types['image/gif'])
96
+ describe '#add' do
97
+ let(:eruby) { MIME::Type.new('application/x-eruby') }
98
+ let(:jinja) { MIME::Type.new('application/jinja2' )}
99
+
100
+ it 'successfully adds a new type' do
101
+ mime_types.add(eruby)
102
+ assert_equal mime_types['application/x-eruby'], [ eruby ]
79
103
  end
80
- assert_empty(MIME::Types.type_for('coverallsjson'))
81
- assert_deprecated('MIME::Types#type_for', 'using the platform parameter') do
82
- assert_equal @mime_types.type_for('jpeg', true), @mime_types['image/jpeg']
104
+
105
+ it 'complains about adding a duplicate type' do
106
+ mime_types.add(eruby)
107
+ assert_output '', /is already registered as a variant/ do
108
+ mime_types.add(eruby)
109
+ end
110
+ assert_equal mime_types['application/x-eruby'], [eruby]
83
111
  end
84
- assert_empty(@mime_types.type_for('zzz'))
85
- end
86
112
 
87
- def test_count
88
- assert_equal(6, @mime_types.count)
89
- end
113
+ it 'does not complain about adding a duplicate type when quiet' do
114
+ mime_types.add(eruby)
115
+ assert_output '', '' do
116
+ mime_types.add(eruby, :silent)
117
+ end
118
+ assert_equal mime_types['application/x-eruby'], [ eruby ]
119
+ end
90
120
 
91
- # This tests the instance implementation through the class implementation.
92
- def test_add_type_variant
93
- xtxp = MIME::Type.new('x-text/x-plain')
94
- assert_deprecated('MIME::Types#add_type_variant', 'and will be private') do
95
- @mime_types.add_type_variant(xtxp)
121
+ it 'successfully adds from an array' do
122
+ mime_types.add([ eruby, jinja ])
123
+ assert_equal mime_types['application/x-eruby'], [ eruby ]
124
+ assert_equal mime_types['application/jinja2'], [ jinja ]
96
125
  end
97
- assert_includes(@mime_types['text/plain'], xtxp)
98
- end
99
126
 
100
- def test_data_version
101
- assert_equal(MIME::Type::VERSION, @mime_types.data_version)
102
- end
127
+ it 'successfully adds from another MIME::Types' do
128
+ mt = MIME::Types.new
129
+ mt.add(mime_types)
130
+ assert_equal mime_types.count, mt.count
103
131
 
104
- # This tests the instance implementation through the class implementation.
105
- def test_index_extensions
106
- xtxp = MIME::Type.new(['x-text/x-plain', %w(tzt)])
107
- assert_deprecated('MIME::Types#index_extensions', 'and will be private') do
108
- @mime_types.index_extensions(xtxp)
132
+ mime_types.each do |type|
133
+ assert_equal mt[type.content_type], [ type ]
134
+ end
109
135
  end
110
- assert_includes(@mime_types.of('tzt'), xtxp)
111
136
  end
112
137
 
113
- def test_defined_types
114
- assert_deprecated('MIME::Types#defined_types') do
115
- assert_empty(MIME::Types.new.defined_types)
138
+ describe '#type_for' do
139
+ it 'finds all types for a given extension' do
140
+ assert_equal %w(application/gzip application/x-gzip),
141
+ mime_types.type_for('gz')
142
+ end
143
+
144
+ it 'separates the extension from filenames' do
145
+ assert_equal %w(image/jpeg), mime_types.of(['foo.jpeg', 'bar.jpeg'])
116
146
  end
117
- assert_deprecated('MIME::Types#defined_types') do
118
- refute_empty(@mime_types.defined_types)
147
+
148
+ it 'finds multiple extensions' do
149
+ assert_equal %w(image/jpeg text/plain),
150
+ mime_types.type_for(%w(foo.txt foo.jpeg))
151
+ end
152
+
153
+ it 'does not find unknown extensions' do
154
+ keys = mime_types.instance_variable_get(:@extension_index).keys
155
+ assert_empty mime_types.type_for('zzz')
156
+ assert_equal keys, mime_types.instance_variable_get(:@extension_index).keys
157
+ end
158
+
159
+ it 'modifying type extensions causes reindexing' do
160
+ plain_text = mime_types['text/plain'].first
161
+ plain_text.add_extensions('xtxt')
162
+ assert_includes mime_types.type_for('xtxt'), 'text/plain'
163
+ end
164
+ end
165
+
166
+ describe '#count' do
167
+ it 'can count the number of types inside' do
168
+ assert_equal 6, mime_types.count
119
169
  end
120
170
  end
121
171
  end
@@ -1,19 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- ruby encoding: utf-8 -*-
2
4
 
3
5
  require 'mime/types'
4
6
  require 'minitest_helper'
5
7
 
6
- class TestMIMETypesCache < Minitest::Test
7
- def setup
8
+ describe MIME::Types::Cache do
9
+ include Minitest::Hooks
10
+
11
+ MUTEX = Mutex.new
12
+
13
+ def around
8
14
  require 'fileutils'
9
- @cache_file = File.expand_path('../cache.tst', __FILE__)
10
- ENV['RUBY_MIME_TYPES_CACHE'] = @cache_file
11
- clear_cache_file
12
- end
13
15
 
14
- def teardown
15
- clear_cache_file
16
- ENV.delete('RUBY_MIME_TYPES_CACHE')
16
+ MUTEX.synchronize do
17
+ @cache_file = File.expand_path('../cache.tst', __FILE__)
18
+ ENV['RUBY_MIME_TYPES_CACHE'] = @cache_file
19
+ clear_cache_file
20
+
21
+ super
22
+
23
+ clear_cache_file
24
+ ENV.delete('RUBY_MIME_TYPES_CACHE')
25
+ end
17
26
  end
18
27
 
19
28
  def reset_mime_types
@@ -25,66 +34,87 @@ class TestMIMETypesCache < Minitest::Test
25
34
  FileUtils.rm @cache_file if File.exist? @cache_file
26
35
  end
27
36
 
28
- def test_does_not_use_cache_when_unset
29
- ENV.delete('RUBY_MIME_TYPES_CACHE')
30
- assert_equal(nil, MIME::Types::Cache.load)
31
- end
37
+ describe '.load' do
38
+ it 'does not use cache when RUBY_MIME_TYPES_CACHE is unset' do
39
+ ENV.delete('RUBY_MIME_TYPES_CACHE')
40
+ assert_nil MIME::Types::Cache.load
41
+ end
32
42
 
33
- def test_does_not_use_cache_when_missing
34
- assert_equal(nil, MIME::Types::Cache.load)
35
- end
43
+ it 'does not use cache when missing' do
44
+ assert_nil MIME::Types::Cache.load
45
+ end
36
46
 
37
- def test_does_not_create_cache_when_unset
38
- ENV.delete('RUBY_MIME_TYPES_CACHE')
39
- assert_equal(nil, MIME::Types::Cache.save)
40
- end
47
+ it 'registers the data to be updated by #add_extensions' do
48
+ MIME::Types::Cache.save
49
+ reset_mime_types
50
+ assert_equal([], MIME::Types.type_for('foo.additional'))
51
+ html = MIME::Types['text/html'][0]
52
+ html.add_extensions('additional')
53
+ assert_equal([html], MIME::Types.type_for('foo.additional'))
54
+ end
41
55
 
42
- def test_creates_cache
43
- assert_equal(false, File.exist?(@cache_file))
44
- MIME::Types::Cache.save
45
- assert_equal(true, File.exist?(@cache_file))
56
+ it 'outputs an error when there is an invalid version' do
57
+ v = MIME::Types::Data::VERSION
58
+ MIME::Types::Data.send(:remove_const, :VERSION)
59
+ MIME::Types::Data.const_set(:VERSION, '0.0')
60
+ MIME::Types::Cache.save
61
+ MIME::Types::Data.send(:remove_const, :VERSION)
62
+ MIME::Types::Data.const_set(:VERSION, v)
63
+ MIME::Types.instance_variable_set(:@__types__, nil)
64
+ assert_output '', /MIME::Types cache: invalid version/ do
65
+ MIME::Types['text/html']
66
+ end
67
+ end
68
+
69
+ it 'outputs an error when there is a marshal file incompatibility' do
70
+ MIME::Types::Cache.save
71
+ data = File.binread(@cache_file).reverse
72
+ File.open(@cache_file, 'wb') { |f| f.write(data) }
73
+ MIME::Types.instance_variable_set(:@__types__, nil)
74
+ assert_output '', /incompatible marshal file format/ do
75
+ MIME::Types['text/html']
76
+ end
77
+ end
46
78
  end
47
79
 
48
- def test_uses_cache
49
- MIME::Types['text/html'].first.extensions << 'hex'
50
- MIME::Types::Cache.save
51
- MIME::Types.instance_variable_set(:@__types__, nil)
80
+ describe '.save' do
81
+ it 'does not create cache when RUBY_MIME_TYPES_CACHE is unset' do
82
+ ENV.delete('RUBY_MIME_TYPES_CACHE')
83
+ assert_nil MIME::Types::Cache.save
84
+ end
52
85
 
53
- assert_includes(MIME::Types['text/html'].first.extensions, 'hex')
86
+ it 'creates the cache ' do
87
+ assert_equal(false, File.exist?(@cache_file))
88
+ MIME::Types::Cache.save
89
+ assert_equal(true, File.exist?(@cache_file))
90
+ end
54
91
 
55
- reset_mime_types
56
- end
92
+ it 'uses the cache' do
93
+ MIME::Types['text/html'].first.add_extensions('hex')
94
+ MIME::Types::Cache.save
95
+ MIME::Types.instance_variable_set(:@__types__, nil)
57
96
 
58
- def test_load_different_version
59
- v = MIME::Types::VERSION.dup
60
- MIME::Types::VERSION.gsub!(/.*/, '0.0')
61
- MIME::Types::Cache.save
62
- MIME::Types::VERSION.gsub!(/.*/, v)
63
- MIME::Types.instance_variable_set(:@__types__, nil)
64
- assert_output(nil, /MIME::Types cache: invalid version/) do
65
- MIME::Types['text/html']
66
- end
67
- end
97
+ assert_includes MIME::Types['text/html'].first.extensions, 'hex'
68
98
 
69
- def test_cache_load_failure
70
- MIME::Types::Cache.save
71
- data = File.binread(@cache_file).reverse
72
- File.open(@cache_file, 'wb') { |f| f.write(data) }
73
- MIME::Types.instance_variable_set(:@__types__, nil)
74
- assert_output(nil, /Could not load MIME::Types cache: incompatible marshal file format/) do
75
- MIME::Types['text/html']
99
+ reset_mime_types
76
100
  end
77
101
  end
102
+ end
78
103
 
79
- def test_container_marshalling
104
+ describe MIME::Types::Container do
105
+ it 'marshals and unmarshals correctly' do
80
106
  container = MIME::Types::Container.new
81
- # default proc should return []
82
- assert_equal([], container['abc'])
107
+ container.add('xyz', 'abc')
108
+
109
+ # default proc should return Set[]
110
+ assert_equal(Set[], container['abc'])
111
+ assert_equal(Set['abc'], container['xyz'])
83
112
 
84
113
  marshalled = Marshal.dump(container)
85
114
  loaded_container = Marshal.load(marshalled)
86
115
 
87
- # default proc should still return []
88
- assert_equal([], loaded_container['abcd'])
116
+ # default proc should still return Set[]
117
+ assert_equal(Set[], loaded_container['abc'])
118
+ assert_equal(Set['abc'], container['xyz'])
89
119
  end
90
120
  end