Skip to content

Commit 0f505d7

Browse files
gh-93417: Improve test_mimetypes (GH-150725)
* Separate tests for module-level API and for the MimeTypes class. * Add tests for mimetypes.init() and MimeTypes() with knownfiles and with explicitly passed files. (cherry picked from commit b23646a)
1 parent 70d6c85 commit 0f505d7

2 files changed

Lines changed: 160 additions & 98 deletions

File tree

Lib/test/mime.types2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# MIME type Extensions
2+
testing/test2 test test2
3+
testing/test3 test test3

Lib/test/test_mimetypes.py

Lines changed: 157 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,166 @@ def tearDownModule():
2929
mimetypes.knownfiles = knownfiles
3030

3131

32-
class MimeTypesTestCase(unittest.TestCase):
32+
class MimeTypesModuleTestCase(unittest.TestCase):
33+
def setUp(self):
34+
mimetypes.inited = False
35+
mimetypes._default_mime_types()
36+
mimetypes._db = None
37+
38+
def test_read_mime_types(self):
39+
eq = self.assertEqual
40+
41+
# Unreadable file returns None
42+
self.assertIsNone(mimetypes.read_mime_types("non-existent"))
43+
44+
with os_helper.temp_dir() as directory:
45+
data = "x-application/x-unittest pyunit\n"
46+
file = os.path.join(directory, "sample.mimetype")
47+
with open(file, 'w', encoding="utf-8") as f:
48+
f.write(data)
49+
mime_dict = mimetypes.read_mime_types(file)
50+
eq(mime_dict[".pyunit"], "x-application/x-unittest")
51+
52+
data = "x-application/x-unittest2 pyunit2\n"
53+
file = os.path.join(directory, "sample2.mimetype")
54+
with open(file, 'w', encoding="utf-8") as f:
55+
f.write(data)
56+
mime_dict = mimetypes.read_mime_types(os_helper.FakePath(file))
57+
eq(mime_dict[".pyunit2"], "x-application/x-unittest2")
58+
59+
# bpo-41048: read_mime_types should read the rule file with 'utf-8' encoding.
60+
# Not with locale encoding. _bootlocale has been imported because io.open(...)
61+
# uses it.
62+
data = "application/no-mans-land Fran\u00E7ais"
63+
filename = "filename"
64+
fp = io.StringIO(data)
65+
with unittest.mock.patch.object(mimetypes, 'open',
66+
return_value=fp) as mock_open:
67+
mime_dict = mimetypes.read_mime_types(filename)
68+
mock_open.assert_called_with(filename, encoding='utf-8')
69+
eq(mime_dict[".Français"], "application/no-mans-land")
70+
71+
def test_init_reinitializes(self):
72+
# Issue 4936: make sure an init starts clean
73+
# First, put some poison into the types table
74+
mimetypes.add_type('foo/bar', '.foobar')
75+
self.assertEqual(mimetypes.guess_extension('foo/bar'), '.foobar')
76+
# Reinitialize
77+
mimetypes.init()
78+
# Poison should be gone.
79+
self.assertEqual(mimetypes.guess_extension('foo/bar'), None)
80+
81+
@unittest.skipIf(sys.platform.startswith("win"), "Non-Windows only")
82+
def test_guess_known_extensions(self):
83+
# Issue 37529
84+
# The test fails on Windows because Windows adds mime types from the Registry
85+
# and that creates some duplicates.
86+
from mimetypes import types_map
87+
for v in types_map.values():
88+
self.assertIsNotNone(mimetypes.guess_extension(v))
89+
90+
def test_preferred_extension(self):
91+
def check_extensions():
92+
self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin')
93+
self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps')
94+
self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u')
95+
self.assertEqual(mimetypes.guess_extension('application/vnd.ms-excel'), '.xls')
96+
self.assertEqual(mimetypes.guess_extension('application/vnd.ms-powerpoint'), '.ppt')
97+
self.assertEqual(mimetypes.guess_extension('application/x-texinfo'), '.texi')
98+
self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff')
99+
self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl')
100+
self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3')
101+
self.assertEqual(mimetypes.guess_extension('image/avif'), '.avif')
102+
self.assertEqual(mimetypes.guess_extension('image/webp'), '.webp')
103+
self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg')
104+
self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff')
105+
self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml')
106+
self.assertEqual(mimetypes.guess_extension('text/html'), '.html')
107+
self.assertEqual(mimetypes.guess_extension('text/plain'), '.txt')
108+
self.assertEqual(mimetypes.guess_extension('text/rtf'), '.rtf')
109+
self.assertEqual(mimetypes.guess_extension('text/x-rst'), '.rst')
110+
self.assertEqual(mimetypes.guess_extension('video/mpeg'), '.mpeg')
111+
self.assertEqual(mimetypes.guess_extension('video/quicktime'), '.mov')
112+
113+
check_extensions()
114+
mimetypes.init()
115+
check_extensions()
116+
117+
def test_init_stability(self):
118+
mimetypes.init()
119+
120+
suffix_map = mimetypes.suffix_map
121+
encodings_map = mimetypes.encodings_map
122+
types_map = mimetypes.types_map
123+
common_types = mimetypes.common_types
124+
125+
mimetypes.init()
126+
self.assertIsNot(suffix_map, mimetypes.suffix_map)
127+
self.assertIsNot(encodings_map, mimetypes.encodings_map)
128+
self.assertIsNot(types_map, mimetypes.types_map)
129+
self.assertIsNot(common_types, mimetypes.common_types)
130+
self.assertEqual(suffix_map, mimetypes.suffix_map)
131+
self.assertEqual(encodings_map, mimetypes.encodings_map)
132+
self.assertEqual(types_map, mimetypes.types_map)
133+
self.assertEqual(common_types, mimetypes.common_types)
134+
135+
def test_init_files(self):
136+
guess_file_type = mimetypes.guess_file_type
137+
self.assertEqual(guess_file_type("file.test2")[0], None)
138+
139+
filename = support.findfile("mime.types2")
140+
mimetypes.init([filename])
141+
self.assertEqual(guess_file_type("file.test2")[0], "testing/test2")
142+
143+
mimetypes.init()
144+
self.assertEqual(guess_file_type("file.test2")[0], None)
145+
146+
def test_init_knownfiles(self):
147+
guess_file_type = mimetypes.guess_file_type
148+
self.assertEqual(guess_file_type("file.test2")[0], None)
149+
150+
filename = support.findfile("mime.types2")
151+
mimetypes.knownfiles = [filename, "non-existent"]
152+
self.addCleanup(mimetypes.knownfiles.clear)
153+
154+
mimetypes.init()
155+
self.assertEqual(guess_file_type("file.test2")[0], "testing/test2")
156+
157+
def test_added_types_are_used(self):
158+
mimetypes.add_type('testing/default-type', '')
159+
mime_type, _ = mimetypes.guess_type('')
160+
self.assertEqual(mime_type, 'testing/default-type')
161+
162+
mime_type, _ = mimetypes.guess_type('test.myext')
163+
self.assertEqual(mime_type, None)
164+
165+
mimetypes.add_type('testing/type', '.myext')
166+
mime_type, _ = mimetypes.guess_type('test.myext')
167+
self.assertEqual(mime_type, 'testing/type')
168+
169+
170+
class MimeTypesClassTestCase(unittest.TestCase):
33171
def setUp(self):
34172
self.db = mimetypes.MimeTypes()
35173

174+
def test_init_files(self):
175+
guess_file_type = self.db.guess_file_type
176+
self.assertEqual(guess_file_type("file.test2")[0], None)
177+
178+
filename = support.findfile("mime.types2")
179+
db = mimetypes.MimeTypes([filename])
180+
guess_file_type = db.guess_file_type
181+
self.assertEqual(guess_file_type("file.test2")[0], "testing/test2")
182+
183+
def test_init_knownfiles(self):
184+
filename = support.findfile("mime.types2")
185+
mimetypes.knownfiles = [filename, "non-existent"]
186+
self.addCleanup(mimetypes.knownfiles.clear)
187+
188+
db = mimetypes.MimeTypes()
189+
guess_file_type = db.guess_file_type
190+
self.assertEqual(guess_file_type("file.test2")[0], None)
191+
36192
def test_case_sensitivity(self):
37193
eq = self.assertEqual
38194
eq(self.db.guess_file_type("foobar.html"), ("text/html", None))
@@ -74,39 +230,6 @@ def test_file_parsing(self):
74230
("x-application/x-unittest", None))
75231
eq(self.db.guess_extension("x-application/x-unittest"), ".pyunit")
76232

77-
def test_read_mime_types(self):
78-
eq = self.assertEqual
79-
80-
# Unreadable file returns None
81-
self.assertIsNone(mimetypes.read_mime_types("non-existent"))
82-
83-
with os_helper.temp_dir() as directory:
84-
data = "x-application/x-unittest pyunit\n"
85-
file = os.path.join(directory, "sample.mimetype")
86-
with open(file, 'w', encoding="utf-8") as f:
87-
f.write(data)
88-
mime_dict = mimetypes.read_mime_types(file)
89-
eq(mime_dict[".pyunit"], "x-application/x-unittest")
90-
91-
data = "x-application/x-unittest2 pyunit2\n"
92-
file = os.path.join(directory, "sample2.mimetype")
93-
with open(file, 'w', encoding="utf-8") as f:
94-
f.write(data)
95-
mime_dict = mimetypes.read_mime_types(os_helper.FakePath(file))
96-
eq(mime_dict[".pyunit2"], "x-application/x-unittest2")
97-
98-
# bpo-41048: read_mime_types should read the rule file with 'utf-8' encoding.
99-
# Not with locale encoding. _bootlocale has been imported because io.open(...)
100-
# uses it.
101-
data = "application/no-mans-land Fran\u00E7ais"
102-
filename = "filename"
103-
fp = io.StringIO(data)
104-
with unittest.mock.patch.object(mimetypes, 'open',
105-
return_value=fp) as mock_open:
106-
mime_dict = mimetypes.read_mime_types(filename)
107-
mock_open.assert_called_with(filename, encoding='utf-8')
108-
eq(mime_dict[".Français"], "application/no-mans-land")
109-
110233
def test_non_standard_types(self):
111234
eq = self.assertEqual
112235
# First try strict
@@ -202,70 +325,6 @@ def test_encoding(self):
202325
strict=True)
203326
self.assertEqual(exts, ['.g3', '.g\xb3'])
204327

205-
def test_init_reinitializes(self):
206-
# Issue 4936: make sure an init starts clean
207-
# First, put some poison into the types table
208-
mimetypes.add_type('foo/bar', '.foobar')
209-
self.assertEqual(mimetypes.guess_extension('foo/bar'), '.foobar')
210-
# Reinitialize
211-
mimetypes.init()
212-
# Poison should be gone.
213-
self.assertEqual(mimetypes.guess_extension('foo/bar'), None)
214-
215-
@unittest.skipIf(sys.platform.startswith("win"), "Non-Windows only")
216-
def test_guess_known_extensions(self):
217-
# Issue 37529
218-
# The test fails on Windows because Windows adds mime types from the Registry
219-
# and that creates some duplicates.
220-
from mimetypes import types_map
221-
for v in types_map.values():
222-
self.assertIsNotNone(mimetypes.guess_extension(v))
223-
224-
def test_preferred_extension(self):
225-
def check_extensions():
226-
self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin')
227-
self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps')
228-
self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u')
229-
self.assertEqual(mimetypes.guess_extension('application/vnd.ms-excel'), '.xls')
230-
self.assertEqual(mimetypes.guess_extension('application/vnd.ms-powerpoint'), '.ppt')
231-
self.assertEqual(mimetypes.guess_extension('application/x-texinfo'), '.texi')
232-
self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff')
233-
self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl')
234-
self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3')
235-
self.assertEqual(mimetypes.guess_extension('image/avif'), '.avif')
236-
self.assertEqual(mimetypes.guess_extension('image/webp'), '.webp')
237-
self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg')
238-
self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff')
239-
self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml')
240-
self.assertEqual(mimetypes.guess_extension('text/html'), '.html')
241-
self.assertEqual(mimetypes.guess_extension('text/plain'), '.txt')
242-
self.assertEqual(mimetypes.guess_extension('text/rtf'), '.rtf')
243-
self.assertEqual(mimetypes.guess_extension('text/x-rst'), '.rst')
244-
self.assertEqual(mimetypes.guess_extension('video/mpeg'), '.mpeg')
245-
self.assertEqual(mimetypes.guess_extension('video/quicktime'), '.mov')
246-
247-
check_extensions()
248-
mimetypes.init()
249-
check_extensions()
250-
251-
def test_init_stability(self):
252-
mimetypes.init()
253-
254-
suffix_map = mimetypes.suffix_map
255-
encodings_map = mimetypes.encodings_map
256-
types_map = mimetypes.types_map
257-
common_types = mimetypes.common_types
258-
259-
mimetypes.init()
260-
self.assertIsNot(suffix_map, mimetypes.suffix_map)
261-
self.assertIsNot(encodings_map, mimetypes.encodings_map)
262-
self.assertIsNot(types_map, mimetypes.types_map)
263-
self.assertIsNot(common_types, mimetypes.common_types)
264-
self.assertEqual(suffix_map, mimetypes.suffix_map)
265-
self.assertEqual(encodings_map, mimetypes.encodings_map)
266-
self.assertEqual(types_map, mimetypes.types_map)
267-
self.assertEqual(common_types, mimetypes.common_types)
268-
269328
def test_path_like_ob(self):
270329
filename = "LICENSE.txt"
271330
filepath = os_helper.FakePath(filename)

0 commit comments

Comments
 (0)