1
1
"""Utilities for testing."""
2
2
3
3
import textwrap
4
- from pathlib import PurePath
4
+ from pathlib import PureWindowsPath , PurePosixPath
5
5
from unittest import mock
6
6
from io import StringIO
7
7
import functools
@@ -11,16 +11,21 @@ def dedent_ftl(text):
11
11
return textwrap .dedent (f"{ text .rstrip ()} \n " )
12
12
13
13
14
- # Unify path separator, default path separator on Windows is \ not /
15
- # Supports only relative paths
16
14
# Needed in test_falllback.py because it uses dict + string compare to make a virtual file structure
17
- def _normalize_path (path ):
15
+ def _normalize_file_path (path ):
18
16
"""Note: Does not support absolute paths or paths that
19
17
contain '.' or '..' parts."""
20
- path = PurePath (path )
21
- if path .is_absolute () or "." in path .parts or ".." in path .parts :
18
+ # Cannot use os.path or PurePath, because they only recognize
19
+ # one kind of path separator
20
+ if PureWindowsPath (path ).is_absolute () or PurePosixPath (path ).is_absolute ():
22
21
raise ValueError (f"Unsupported path: { path } " )
23
- return "/" .join (path .parts )
22
+ parts = path .replace ("\\ " , "/" ).split ("/" )
23
+ if "." in parts or ".." in parts :
24
+ raise ValueError (f"Unsupported path: { path } " )
25
+ if parts and parts [- 1 ] == "" :
26
+ # path ends with a trailing pathsep
27
+ raise ValueError (f"Path appears to be a directory, not a file: { path } " )
28
+ return "/" .join (parts )
24
29
25
30
26
31
def patch_files (files : dict ):
@@ -32,12 +37,12 @@ def patch_files(files: dict):
32
37
33
38
The implementation may be changed to match the mechanism used.
34
39
"""
35
- if files is None :
36
- files = {}
40
+
41
+ # Here it is possible to validate file names, but skipped
37
42
38
43
def then (func ):
39
- @mock .patch ("os.path.isfile" , side_effect = lambda p : _normalize_path (p ) in files )
40
- @mock .patch ("codecs.open" , side_effect = lambda p , _ , __ : StringIO (files [_normalize_path (p )]))
44
+ @mock .patch ("os.path.isfile" , side_effect = lambda p : _normalize_file_path (p ) in files )
45
+ @mock .patch ("codecs.open" , side_effect = lambda p , _ , __ : StringIO (files [_normalize_file_path (p )]))
41
46
@functools .wraps (func ) # Make ret look like func to later decorators
42
47
def ret (* args , ** kwargs ):
43
48
func (* args [:- 2 ], ** kwargs )
0 commit comments