252 lines
10 KiB
Python
252 lines
10 KiB
Python
import pytest
|
|
from pathlib import Path
|
|
from utils.path_utils import sanitize_filename, generate_path_from_pattern
|
|
|
|
# Tests for sanitize_filename
|
|
def test_sanitize_filename_valid():
|
|
assert sanitize_filename("valid_filename.txt") == "valid_filename.txt"
|
|
|
|
def test_sanitize_filename_with_spaces():
|
|
assert sanitize_filename("file name with spaces.txt") == "file_name_with_spaces.txt"
|
|
|
|
def test_sanitize_filename_with_special_characters():
|
|
assert sanitize_filename("file!@#$%^&*()[]{};:'\",.<>/?\\|.txt") == "file____________________.txt"
|
|
|
|
def test_sanitize_filename_with_leading_trailing_whitespace():
|
|
assert sanitize_filename(" filename_with_spaces .txt") == "filename_with_spaces.txt"
|
|
|
|
def test_sanitize_filename_empty_string():
|
|
assert sanitize_filename("") == ""
|
|
|
|
def test_sanitize_filename_with_none():
|
|
with pytest.raises(TypeError):
|
|
sanitize_filename(None)
|
|
|
|
def test_sanitize_filename_mixed_case():
|
|
assert sanitize_filename("MixedCaseFileName.PNG") == "MixedCaseFileName.PNG"
|
|
|
|
def test_sanitize_filename_long_filename():
|
|
long_name = "a" * 255 + ".txt"
|
|
# Assuming the function doesn't truncate, but sanitizes.
|
|
# If it's meant to handle OS limits, this test might need adjustment
|
|
# based on the function's specific behavior for long names.
|
|
assert sanitize_filename(long_name) == long_name
|
|
|
|
def test_sanitize_filename_unicode_characters():
|
|
assert sanitize_filename("文件名前缀_文件名_后缀.jpg") == "文件名前缀_文件名_后缀.jpg"
|
|
|
|
def test_sanitize_filename_multiple_extensions():
|
|
assert sanitize_filename("archive.tar.gz") == "archive.tar.gz"
|
|
|
|
def test_sanitize_filename_no_extension():
|
|
assert sanitize_filename("filename") == "filename"
|
|
|
|
def test_sanitize_filename_only_special_chars():
|
|
assert sanitize_filename("!@#$%^") == "______"
|
|
|
|
def test_sanitize_filename_with_hyphens_and_underscores():
|
|
assert sanitize_filename("file-name_with-hyphens_and_underscores.zip") == "file-name_with-hyphens_and_underscores.zip"
|
|
|
|
# Tests for generate_path_from_pattern
|
|
def test_generate_path_basic():
|
|
result = generate_path_from_pattern(
|
|
base_path="output",
|
|
pattern="{asset_name}/{map_type}/{filename}",
|
|
asset_name="MyAsset",
|
|
map_type="Diffuse",
|
|
filename="MyAsset_Diffuse.png",
|
|
source_rule_name="TestRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("output/MyAsset/Diffuse/MyAsset_Diffuse.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_all_placeholders():
|
|
result = generate_path_from_pattern(
|
|
base_path="project_files",
|
|
pattern="{source_rule_name}/{asset_name}/{map_type}_{incrementing_value}_{sha5_value}/{filename}",
|
|
asset_name="AnotherAsset",
|
|
map_type="Normal",
|
|
filename="NormalMap.tif",
|
|
source_rule_name="ComplexRule",
|
|
incrementing_value="001",
|
|
sha5_value="abcde"
|
|
)
|
|
expected = Path("project_files/ComplexRule/AnotherAsset/Normal_001_abcde/NormalMap.tif")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_optional_placeholders_none():
|
|
result = generate_path_from_pattern(
|
|
base_path="data",
|
|
pattern="{asset_name}/{filename}",
|
|
asset_name="SimpleAsset",
|
|
map_type="Albedo", # map_type is in pattern but not used if not in string
|
|
filename="texture.jpg",
|
|
source_rule_name="Basic",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("data/SimpleAsset/texture.jpg")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_optional_incrementing_value_present():
|
|
result = generate_path_from_pattern(
|
|
base_path="assets",
|
|
pattern="{asset_name}/{map_type}/v{incrementing_value}/{filename}",
|
|
asset_name="VersionedAsset",
|
|
map_type="Specular",
|
|
filename="spec.png",
|
|
source_rule_name="VersioningRule",
|
|
incrementing_value="3",
|
|
sha5_value=None
|
|
)
|
|
expected = Path("assets/VersionedAsset/Specular/v3/spec.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_optional_sha5_value_present():
|
|
result = generate_path_from_pattern(
|
|
base_path="cache",
|
|
pattern="{asset_name}/{sha5_value}/{filename}",
|
|
asset_name="HashedAsset",
|
|
map_type="Roughness",
|
|
filename="rough.exr",
|
|
source_rule_name="HashingRule",
|
|
incrementing_value=None,
|
|
sha5_value="f1234"
|
|
)
|
|
expected = Path("cache/HashedAsset/f1234/rough.exr")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_base_path_is_path_object():
|
|
result = generate_path_from_pattern(
|
|
base_path=Path("output_path"),
|
|
pattern="{asset_name}/{filename}",
|
|
asset_name="ObjectAsset",
|
|
map_type="AO",
|
|
filename="ao.png",
|
|
source_rule_name="PathObjectRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("output_path/ObjectAsset/ao.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_empty_pattern():
|
|
result = generate_path_from_pattern(
|
|
base_path="output",
|
|
pattern="", # Empty pattern should just use base_path and filename
|
|
asset_name="MyAsset",
|
|
map_type="Diffuse",
|
|
filename="MyAsset_Diffuse.png",
|
|
source_rule_name="TestRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("output/MyAsset_Diffuse.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_pattern_with_no_placeholders():
|
|
result = generate_path_from_pattern(
|
|
base_path="fixed_output",
|
|
pattern="some/static/path", # Pattern has no placeholders
|
|
asset_name="MyAsset",
|
|
map_type="Diffuse",
|
|
filename="MyAsset_Diffuse.png",
|
|
source_rule_name="TestRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("fixed_output/some/static/path/MyAsset_Diffuse.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_filename_with_subdirs_in_pattern():
|
|
result = generate_path_from_pattern(
|
|
base_path="output",
|
|
pattern="{asset_name}", # Filename itself will be appended
|
|
asset_name="AssetWithSubdirFile",
|
|
map_type="Color",
|
|
filename="textures/variant1/color.png", # Filename contains subdirectories
|
|
source_rule_name="SubdirRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
# The function is expected to join pattern result with filename
|
|
expected = Path("output/AssetWithSubdirFile/textures/variant1/color.png")
|
|
assert Path(result) == expected
|
|
|
|
def test_generate_path_no_filename_provided():
|
|
# This test assumes that if filename is None or empty, it might raise an error
|
|
# or behave in a specific way, e.g. not append anything or use a default.
|
|
# Adjust based on actual function behavior for missing filename.
|
|
# For now, let's assume it might raise TypeError if filename is critical.
|
|
with pytest.raises(TypeError): # Or ValueError, depending on implementation
|
|
generate_path_from_pattern(
|
|
base_path="output",
|
|
pattern="{asset_name}/{map_type}",
|
|
asset_name="MyAsset",
|
|
map_type="Diffuse",
|
|
filename=None, # No filename
|
|
source_rule_name="TestRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
|
|
def test_generate_path_all_values_are_empty_strings_or_none_where_applicable():
|
|
result = generate_path_from_pattern(
|
|
base_path="", # Empty base_path
|
|
pattern="{asset_name}/{map_type}/{incrementing_value}/{sha5_value}",
|
|
asset_name="", # Empty asset_name
|
|
map_type="", # Empty map_type
|
|
filename="empty_test.file",
|
|
source_rule_name="", # Empty source_rule_name
|
|
incrementing_value="", # Empty incrementing_value
|
|
sha5_value="" # Empty sha5_value
|
|
)
|
|
# Behavior with empty strings might vary. Assuming they are treated as literal empty segments.
|
|
# Path("///empty_test.file") might resolve to "/empty_test.file" on POSIX
|
|
# or just "empty_test.file" if base_path is current dir.
|
|
# Let's assume Path() handles normalization.
|
|
# If base_path is "", it means current directory.
|
|
# So, "//empty_test.file" relative to current dir.
|
|
# Path objects normalize this. e.g. Path('//a') -> Path('/a') on POSIX
|
|
# Path('a//b') -> Path('a/b')
|
|
# Path('/a//b') -> Path('/a/b')
|
|
# Path('//a//b') -> Path('/a/b')
|
|
# If base_path is empty, it's like Path('.////empty_test.file')
|
|
expected = Path("empty_test.file") # Simplified, actual result might be OS dependent or Path lib norm.
|
|
# More robust check:
|
|
# result_path = Path(result)
|
|
# expected_path = Path.cwd() / "" / "" / "" / "" / "empty_test.file" # This is not quite right
|
|
# Let's assume the function joins them: "" + "/" + "" + "/" + "" + "/" + "" + "/" + "empty_test.file"
|
|
# which becomes "////empty_test.file"
|
|
# Path("////empty_test.file") on Windows becomes "\\empty_test.file" (network path attempt)
|
|
# Path("////empty_test.file") on Linux becomes "/empty_test.file"
|
|
# Given the function likely uses os.path.join or Path.joinpath,
|
|
# and base_path="", asset_name="", map_type="", inc_val="", sha5_val=""
|
|
# pattern = "{asset_name}/{map_type}/{incrementing_value}/{sha5_value}" -> "///"
|
|
# result = base_path / pattern_result / filename
|
|
# result = "" / "///" / "empty_test.file"
|
|
# Path("") / "///" / "empty_test.file" -> Path("///empty_test.file")
|
|
# This is tricky. Let's assume the function is robust.
|
|
# If all path segments are empty, it should ideally resolve to just the filename relative to base_path.
|
|
# If base_path is also empty, then filename relative to CWD.
|
|
# Let's test the expected output based on typical os.path.join behavior:
|
|
# os.path.join("", "", "", "", "", "empty_test.file") -> "empty_test.file" on Windows
|
|
# os.path.join("", "", "", "", "", "empty_test.file") -> "empty_test.file" on Linux
|
|
assert Path(result) == Path("empty_test.file")
|
|
|
|
|
|
def test_generate_path_with_dots_in_placeholders():
|
|
result = generate_path_from_pattern(
|
|
base_path="output",
|
|
pattern="{asset_name}/{map_type}",
|
|
asset_name="My.Asset.V1",
|
|
map_type="Diffuse.Main",
|
|
filename="texture.png",
|
|
source_rule_name="DotsRule",
|
|
incrementing_value=None,
|
|
sha5_value=None
|
|
)
|
|
expected = Path("output/My.Asset.V1/Diffuse.Main/texture.png")
|
|
assert Path(result) == expected |