|
@ -2,139 +2,147 @@ import json |
|
|
import pathlib |
|
|
import pathlib |
|
|
import pytest |
|
|
import pytest |
|
|
|
|
|
|
|
|
from transpose import Transpose |
|
|
|
|
|
|
|
|
from transpose import Transpose, TransposeConfig, TransposeEntry |
|
|
from transpose.exceptions import TransposeError |
|
|
from transpose.exceptions import TransposeError |
|
|
|
|
|
|
|
|
from .utils import ( |
|
|
from .utils import ( |
|
|
STORE_DIR, |
|
|
|
|
|
STORED_DIR, |
|
|
|
|
|
TARGET_DIR, |
|
|
|
|
|
|
|
|
ENTRY_NAME, |
|
|
|
|
|
ENTRY_STORE_PATH, |
|
|
|
|
|
STORE_PATH, |
|
|
|
|
|
TARGET_PATH, |
|
|
|
|
|
TRANSPOSE_CONFIG_PATH, |
|
|
setup_restore, |
|
|
setup_restore, |
|
|
setup_store, |
|
|
setup_store, |
|
|
setup_apply, |
|
|
setup_apply, |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
def test_init(): |
|
|
def test_init(): |
|
|
t = Transpose(target_path=TARGET_DIR) |
|
|
|
|
|
assert t.cache_filename == ".transpose.json" |
|
|
|
|
|
assert t.cache_path == pathlib.Path(TARGET_DIR).joinpath(".transpose.json") |
|
|
|
|
|
|
|
|
|
|
|
t = Transpose(target_path=TARGET_DIR, cache_filename=".transpose.txt") |
|
|
|
|
|
assert t.cache_filename == ".transpose.txt" |
|
|
|
|
|
assert t.cache_path == pathlib.Path(TARGET_DIR).joinpath(".transpose.txt") |
|
|
|
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
assert t.config.entries.get(ENTRY_NAME) |
|
|
|
|
|
assert t.config_path == TRANSPOSE_CONFIG_PATH |
|
|
|
|
|
assert t.store_path == TRANSPOSE_CONFIG_PATH.parent |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_apply() |
|
|
@setup_apply() |
|
|
def test_apply(): |
|
|
def test_apply(): |
|
|
store_path = pathlib.Path(STORE_DIR) |
|
|
|
|
|
target_path = pathlib.Path(TARGET_DIR) |
|
|
|
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
|
|
|
|
|
|
# Success |
|
|
|
|
|
t.apply(ENTRY_NAME) |
|
|
|
|
|
assert TARGET_PATH.is_symlink() |
|
|
|
|
|
assert ENTRY_STORE_PATH.is_dir() |
|
|
|
|
|
|
|
|
t = Transpose(target_path=STORE_DIR) |
|
|
|
|
|
|
|
|
with pytest.raises(TransposeError, match="Entry does not exist"): |
|
|
|
|
|
t.apply("BadName") |
|
|
|
|
|
|
|
|
with open(t.cache_path, "r") as f: |
|
|
|
|
|
cache = json.load(f) |
|
|
|
|
|
|
|
|
# Will remove the symlink created above and reapply |
|
|
|
|
|
# TODO: Check symlink path |
|
|
|
|
|
t.apply(ENTRY_NAME) |
|
|
|
|
|
assert TARGET_PATH.is_symlink() |
|
|
|
|
|
assert ENTRY_STORE_PATH.is_dir() |
|
|
|
|
|
|
|
|
# Test cache doesn't exist |
|
|
|
|
|
t.cache_path.unlink() |
|
|
|
|
|
with pytest.raises(TransposeError): |
|
|
|
|
|
t.apply() |
|
|
|
|
|
|
|
|
# Target already exists, force not set |
|
|
|
|
|
TARGET_PATH.unlink() |
|
|
|
|
|
TARGET_PATH.mkdir() |
|
|
|
|
|
with pytest.raises(TransposeError, match="Entry path already exists"): |
|
|
|
|
|
t.apply(ENTRY_NAME) |
|
|
|
|
|
|
|
|
with open(t.cache_path, "w") as f: |
|
|
|
|
|
json.dump(cache, f) |
|
|
|
|
|
|
|
|
# Target already exists, force set (Create backup of original path) |
|
|
|
|
|
t.apply(ENTRY_NAME, force=True) |
|
|
|
|
|
backup_path = TARGET_PATH.with_suffix(".backup") |
|
|
|
|
|
|
|
|
pathlib.Path(cache["original_path"]).symlink_to("bad/path") |
|
|
|
|
|
|
|
|
assert backup_path.is_dir() |
|
|
|
|
|
assert TARGET_PATH.is_symlink() |
|
|
|
|
|
assert ENTRY_STORE_PATH.is_dir() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_restore() |
|
|
|
|
|
def test_restore(): |
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
|
|
|
# Success |
|
|
# Success |
|
|
t.apply() |
|
|
|
|
|
|
|
|
t.restore(ENTRY_NAME) |
|
|
|
|
|
assert TARGET_PATH.is_dir() |
|
|
|
|
|
assert not TARGET_PATH.is_symlink() |
|
|
|
|
|
assert not ENTRY_STORE_PATH.exists() |
|
|
|
|
|
|
|
|
assert store_path.is_dir() and not store_path.is_symlink() |
|
|
|
|
|
assert target_path.is_dir() and target_path.is_symlink() |
|
|
|
|
|
|
|
|
with pytest.raises(TransposeError, match="Could not locate entry by name"): |
|
|
|
|
|
t.restore("BadName") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_restore() |
|
|
@setup_restore() |
|
|
def test_create(): |
|
|
|
|
|
target_path = pathlib.Path(TARGET_DIR) |
|
|
|
|
|
stored_path = pathlib.Path(STORE_DIR).joinpath(STORED_DIR) |
|
|
|
|
|
|
|
|
def test_restore_path_conflicts(): |
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
|
|
|
t = Transpose(target_path=str(target_path)) |
|
|
|
|
|
|
|
|
# Target already exists, force not set |
|
|
|
|
|
TARGET_PATH.mkdir() |
|
|
|
|
|
with pytest.raises(TransposeError, match="Entry path already exists"): |
|
|
|
|
|
t.restore(ENTRY_NAME) |
|
|
|
|
|
|
|
|
# Missing stored path |
|
|
|
|
|
stored_path.rename("tmp") |
|
|
|
|
|
with pytest.raises(TransposeError): |
|
|
|
|
|
t.create(stored_path=stored_path) |
|
|
|
|
|
pathlib.Path("tmp").rename(stored_path) |
|
|
|
|
|
|
|
|
t.restore(ENTRY_NAME, force=True) |
|
|
|
|
|
backup_path = TARGET_PATH.with_suffix(".backup") |
|
|
|
|
|
|
|
|
cache_path = stored_path.joinpath(t.cache_filename) |
|
|
|
|
|
|
|
|
assert backup_path.is_dir() |
|
|
|
|
|
assert TARGET_PATH.is_dir() |
|
|
|
|
|
assert not TARGET_PATH.is_symlink() |
|
|
|
|
|
assert not ENTRY_STORE_PATH.exists() |
|
|
|
|
|
assert not t.config.entries.get(ENTRY_NAME) |
|
|
|
|
|
|
|
|
# Successful Create |
|
|
|
|
|
t.create(stored_path=stored_path) |
|
|
|
|
|
assert t.cache_path == cache_path |
|
|
|
|
|
assert cache_path.exists() |
|
|
|
|
|
|
|
|
|
|
|
with open(t.cache_path, "r") as f: |
|
|
|
|
|
cache = json.load(f) |
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_store(): |
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
|
|
|
assert cache["original_path"] == str(target_path.absolute()) |
|
|
|
|
|
|
|
|
# Success |
|
|
|
|
|
t.store("TestEntry", TARGET_PATH) |
|
|
|
|
|
assert TARGET_PATH.is_symlink() |
|
|
|
|
|
assert STORE_PATH.joinpath("TestEntry").is_dir() |
|
|
|
|
|
assert t.config.entries["TestEntry"].path == str(TARGET_PATH) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
@setup_store() |
|
|
def test_store(): |
|
|
|
|
|
t = Transpose(target_path=TARGET_DIR) |
|
|
|
|
|
t.store(store_path=STORE_DIR) |
|
|
|
|
|
|
|
|
def test_store_conflicts(): |
|
|
|
|
|
t = Transpose(config_path=TRANSPOSE_CONFIG_PATH) |
|
|
|
|
|
|
|
|
|
|
|
with pytest.raises(TransposeError, match="Entry already exists"): |
|
|
|
|
|
t.store(ENTRY_NAME, TARGET_PATH) |
|
|
|
|
|
|
|
|
target_path = pathlib.Path(TARGET_DIR) |
|
|
|
|
|
store_path = pathlib.Path(STORE_DIR).joinpath(target_path.name) |
|
|
|
|
|
|
|
|
with pytest.raises(TransposeError, match="Source path does not exist"): |
|
|
|
|
|
t.store("TestEntry", "UnknownPath/") |
|
|
|
|
|
|
|
|
# Successful Store |
|
|
|
|
|
assert store_path.is_dir() and not store_path.is_symlink() |
|
|
|
|
|
assert target_path.is_dir() and target_path.is_symlink() |
|
|
|
|
|
assert t.cache_path.is_file() |
|
|
|
|
|
|
|
|
STORE_PATH.joinpath("TestEntry").mkdir() |
|
|
|
|
|
with pytest.raises(TransposeError, match="Store path already exists"): |
|
|
|
|
|
t.store("TestEntry", TARGET_PATH) |
|
|
|
|
|
STORE_PATH.joinpath("TestEntry").rmdir() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
@setup_store() |
|
|
def test_store_named(): |
|
|
|
|
|
t = Transpose(target_path=TARGET_DIR) |
|
|
|
|
|
t.store(store_path=STORE_DIR, name="TestStore") |
|
|
|
|
|
|
|
|
def test_config_add(): |
|
|
|
|
|
pass # TODO |
|
|
|
|
|
|
|
|
target_path = pathlib.Path(TARGET_DIR) |
|
|
|
|
|
store_path = pathlib.Path(STORE_DIR).joinpath("TestStore") |
|
|
|
|
|
|
|
|
|
|
|
# Successful Store |
|
|
|
|
|
assert store_path.is_dir() and not store_path.is_symlink() |
|
|
|
|
|
assert target_path.is_dir() and target_path.is_symlink() |
|
|
|
|
|
assert t.cache_path.is_file() |
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_config_get(): |
|
|
|
|
|
pass # TODO |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_restore() |
|
|
|
|
|
def test_restore(): |
|
|
|
|
|
target_path = pathlib.Path(TARGET_DIR) |
|
|
|
|
|
stored_path = pathlib.Path(STORE_DIR).joinpath(STORED_DIR) |
|
|
|
|
|
|
|
|
|
|
|
t = Transpose(target_path=str(stored_path)) |
|
|
|
|
|
|
|
|
|
|
|
# Missing Cache File |
|
|
|
|
|
cache = t.cache_path.read_text() |
|
|
|
|
|
t.cache_path.unlink() |
|
|
|
|
|
with pytest.raises(TransposeError): |
|
|
|
|
|
t.restore() |
|
|
|
|
|
t.cache_path.write_text(cache) |
|
|
|
|
|
cache = json.loads(cache) |
|
|
|
|
|
|
|
|
|
|
|
# Missing Target Path (original path) |
|
|
|
|
|
t.target_path.rename("newpath") |
|
|
|
|
|
with pytest.raises(TransposeError): |
|
|
|
|
|
t.restore() |
|
|
|
|
|
pathlib.Path("newpath").rename(t.target_path) |
|
|
|
|
|
|
|
|
|
|
|
# Original Path is a symlink - Should be removed and successfully restore |
|
|
|
|
|
original_path = pathlib.Path(cache["original_path"]) |
|
|
|
|
|
original_path.rename("newpath") |
|
|
|
|
|
original_path.symlink_to("newpath") |
|
|
|
|
|
|
|
|
|
|
|
# Successful |
|
|
|
|
|
t.restore() |
|
|
|
|
|
|
|
|
|
|
|
assert target_path.is_dir() and not target_path.is_symlink() |
|
|
|
|
|
assert not stored_path.exists() |
|
|
|
|
|
assert not t.cache_path.exists() |
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_config_list(): |
|
|
|
|
|
pass # TODO |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_config_remove(): |
|
|
|
|
|
pass # TODO |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_config_save(): |
|
|
|
|
|
pass # TODO |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@setup_store() |
|
|
|
|
|
def test_config_load(): |
|
|
|
|
|
pass # TODO |