1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4from __future__ import absolute_import, print_function, unicode_literals 5"""Tests for the FileAvoidWrite object.""" 6 7import locale 8import pytest 9import pathlib2 10from mozbuild.util import FileAvoidWrite 11from mozunit import main 12 13 14@pytest.fixture 15def tmp_path(tmpdir): 16 """Backport of the tmp_path fixture from pytest 3.9.1.""" 17 return pathlib2.Path(str(tmpdir)) 18 19 20def test_overwrite_contents(tmp_path): 21 file = tmp_path / "file.txt" 22 file.write_text("abc") 23 24 faw = FileAvoidWrite(str(file)) 25 faw.write("bazqux") 26 27 assert faw.close() == (True, True) 28 assert file.read_text() == "bazqux" 29 30 31def test_store_new_contents(tmp_path): 32 file = tmp_path / "file.txt" 33 34 faw = FileAvoidWrite(str(file)) 35 faw.write("content") 36 37 assert faw.close() == (False, True) 38 assert file.read_text() == "content" 39 40 41def test_change_binary_file_contents(tmp_path): 42 file = tmp_path / "file.dat" 43 file.write_bytes(b"\0") 44 45 faw = FileAvoidWrite(str(file), readmode="rb") 46 faw.write(b"\0\0\0") 47 48 assert faw.close() == (True, True) 49 assert file.read_bytes() == b"\0\0\0" 50 51 52def test_obj_as_context_manager(tmp_path): 53 file = tmp_path / "file.txt" 54 55 with FileAvoidWrite(str(file)) as fh: 56 fh.write("foobar") 57 58 assert file.read_text() == "foobar" 59 60 61def test_no_write_happens_if_file_contents_same(tmp_path): 62 file = tmp_path / "file.txt" 63 file.write_text("content") 64 original_write_time = file.stat().st_mtime 65 66 faw = FileAvoidWrite(str(file)) 67 faw.write("content") 68 69 assert faw.close() == (True, False) 70 assert file.stat().st_mtime == original_write_time 71 72 73def test_diff_not_created_by_default(tmp_path): 74 file = tmp_path / "file.txt" 75 faw = FileAvoidWrite(str(file)) 76 faw.write("dummy") 77 faw.close() 78 assert faw.diff is None 79 80 81def test_diff_update(tmp_path): 82 file = tmp_path / "diffable.txt" 83 file.write_text("old") 84 85 faw = FileAvoidWrite(str(file), capture_diff=True) 86 faw.write("new") 87 faw.close() 88 89 diff = "\n".join(faw.diff) 90 assert "-old" in diff 91 assert "+new" in diff 92 93 94@pytest.mark.skipif( 95 locale.getdefaultlocale()[1] == "cp1252", 96 reason="Fails on win32 terminals with cp1252 encoding", 97) 98def test_write_unicode(tmp_path): 99 # Unicode grinning face :D 100 binary_emoji = b"\xf0\x9f\x98\x80" 101 102 file = tmp_path / "file.dat" 103 faw = FileAvoidWrite(str(file)) 104 faw.write(binary_emoji) 105 faw.close() 106 107 108if __name__ == "__main__": 109 main() 110