1"""Test suite for prance.util.fs .""" 2 3__author__ = 'Jens Finkhaeuser' 4__copyright__ = 'Copyright (c) 2016-2021 Jens Finkhaeuser' 5__license__ = 'MIT' 6__all__ = () 7 8 9import os 10import sys 11 12import pytest 13 14from prance.util import fs 15 16from . import sandbox, platform 17 18@pytest.fixture 19def create_symlink(): 20 # Defined as a fixture so we can selectively use it for tests." 21 testname = 'tests/specs/symlink_test' 22 import os, os.path 23 if os.path.islink(testname): 24 return testname 25 26 if os.path.exists(testname): 27 os.unlink(testname) 28 29 target = 'with_externals.yaml' 30 os.symlink(target, testname) 31 32 return testname 33 34 35@pytest.mark.skipif(platform('win32'), reason = 'Skip on win32') 36def test_canonical(create_symlink): 37 res = fs.canonical_filename(create_symlink) 38 expected = os.path.join(os.getcwd(), 'tests/specs/with_externals.yaml') 39 assert res == expected 40 41 42def test_to_posix_rel(): 43 test = "tests/specs/with_externals.yaml" 44 assert fs.to_posix(os.path.normpath(test)) == test 45 46 47@pytest.mark.skipif(platform('win32'), reason = 'Skip on win32') 48def test_to_posix_abs_posix(): 49 test = "/etc/passwd" 50 expected = test 51 assert fs.to_posix(test) == expected 52 53 54@pytest.mark.skipif(platform('!win32'), reason = 'Skip on !win32') 55def test_to_posix_abs_win32(): 56 test = "c:\\windows\\notepad.exe" 57 expected = "/c:/windows/notepad.exe" 58 assert fs.to_posix(test) == expected 59 60 61def test_from_posix_rel(): 62 test = "tests/specs/with_externals.yaml" 63 assert fs.from_posix(test) == os.path.normpath(test) 64 65 66@pytest.mark.skipif(platform('win32'), reason = 'Skip on win32') 67def test_from_posix_abs_posix(): 68 test = "/etc/passwd" 69 expected = test 70 assert fs.from_posix(test) == expected 71 72 73@pytest.mark.skipif(platform('!win32'), reason = 'Skip on !win32') 74def test_from_posix_abs_win32(): 75 test = "/c:/windows/notepad.exe" 76 expected = "c:\\windows\\notepad.exe" 77 assert fs.from_posix(test) == expected 78 79 80def test_abspath_basics(): 81 testname = os.path.normpath('tests/specs/with_externals.yaml') 82 res = fs.abspath(testname) 83 expected = fs.to_posix(os.path.join(os.getcwd(), testname)) 84 assert res == expected 85 86 87def test_abspath_relative(): 88 testname = 'error.json' 89 relative = os.path.join(os.getcwd(), 'tests/specs/with_externals.yaml') 90 res = fs.abspath(testname, relative) 91 expected = fs.to_posix(os.path.join(os.getcwd(), 'tests', 'specs', testname)) 92 assert res == expected 93 94 95def test_abspath_relative_dir(): 96 testname = 'error.json' 97 relative = os.path.join(os.getcwd(), 'tests', 'specs') 98 res = fs.abspath(testname, relative) 99 expected = fs.to_posix(os.path.join(os.getcwd(), 'tests', 'specs', testname)) 100 assert res == expected 101 102 103def test_detect_encoding(): 104 # Quick detection should yield utf-8 for the petstore file. 105 assert fs.detect_encoding('tests/specs/petstore.yaml') == 'utf-8' 106 107 # Without defaulting to utf-8, it should also work. 108 assert fs.detect_encoding('tests/specs/petstore.yaml', 109 default_to_utf8 = False) == 'utf-8' 110 111 # Deep inspection should not change anything because the file size is 112 # too small. 113 assert fs.detect_encoding('tests/specs/petstore.yaml', 114 default_to_utf8 = False, 115 read_all = True) == 'utf-8' 116 117 # The UTF-8 file with BOM should be detected properly 118 assert fs.detect_encoding('tests/specs/utf8bom.yaml') == 'utf-8-sig' 119 120 121def test_issue_51_detect_encoding(): 122 # This should be UTF-8, but in issue 51 it was reported that it comes back 123 # as iso-8859-2 124 125 # Detection should be ok if the entire file is read 126 assert fs.detect_encoding('tests/specs/issue_51/openapi-part.yaml', read_all = True) == 'utf-8' 127 128 # After the heuristic change, it reads the whole file anyway. 129 assert fs.detect_encoding('tests/specs/issue_51/openapi-part.yaml') == 'utf-8' 130 131 # Specifically re-encoded as iso-8859-2 should fail - but not as 132 # a call to the detect_encoding() function. Instead, we can only return 133 # a badly detected encoding. Chardet sends iso-8859-1 here. 134 assert fs.detect_encoding('tests/specs/issue_51/openapi-part-iso-8859-2.yaml') == 'iso-8859-1' 135 136 137def test_load_nobom(): 138 contents = fs.read_file('tests/specs/petstore.yaml') 139 assert contents.index('Swagger Petstore') >= 0, 'File reading failed!' 140 141 142def test_load_utf8bom(): 143 contents = fs.read_file('tests/specs/utf8bom.yaml') 144 assert contents.index('söme välüe') >= 0, 'UTF-8 BOM handling failed!' 145 146 147def test_load_utf8bom_override(): 148 with pytest.raises(UnicodeDecodeError): 149 fs.read_file('tests/specs/utf8bom.yaml', 'ascii') 150 151 152def test_write_file(tmpdir): 153 with sandbox.sandbox(tmpdir): 154 test_text = 'söme täxt' 155 fs.write_file('test.out', test_text) 156 157 # File must have been written 158 files = [f for f in os.listdir('.') if os.path.isfile(f)] 159 assert 'test.out' in files 160 161 # File contents must work 162 contents = fs.read_file('test.out') 163 assert test_text == contents 164 165 166def test_write_file_bom(tmpdir): 167 with sandbox.sandbox(tmpdir): 168 test_text = 'söme täxt' 169 fs.write_file('test.out', test_text, 'utf-8-sig') 170 171 # File must have been written 172 files = [f for f in os.listdir('.') if os.path.isfile(f)] 173 assert 'test.out' in files 174 175 # Encoding must match the one we've given 176 encoding = fs.detect_encoding('test.out') 177 assert encoding == 'utf-8-sig' 178 179 # File contents must work 180 contents = fs.read_file('test.out') 181 assert test_text == contents 182 183 184def test_valid_pathname(): 185 # A URL should not be valid 186 from prance.util.fs import is_pathname_valid 187 assert False == is_pathname_valid('\x00o.bar.org') 188 189 # However, the current path should be. 190 import os 191 assert True == is_pathname_valid(os.getcwd()) 192 193 # Can't put non-strings into this function 194 assert True == is_pathname_valid('foo') 195 assert False == is_pathname_valid(123) 196 197 # Can't accept too long components 198 assert False == is_pathname_valid('a'*256) 199