bcbd1bdb22
Test (Python) / test-python-gate (push) Blocked by required conditions
Test (TypeScript) / test-typescript-gate (push) Blocked by required conditions
CLI exit codes / cli-gate (push) Blocked by required conditions
Test (Install) / test-install-gate (push) Blocked by required conditions
Integ / integ-gate (push) Blocked by required conditions
CLI exit codes / Python CLI (push) Waiting to run
Integ / changes (push) Has been skipped
Test (Install) / python-minimal (3.11) (push) Waiting to run
Test (Install) / python-minimal (3.12) (push) Waiting to run
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Waiting to run
Integ / integ-ts (push) Waiting to run
Integ / integ (push) Waiting to run
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Waiting to run
Integ / integ-database (push) Waiting to run
Test (Install) / python-extra (email, mirage.resource.email) (push) Waiting to run
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Waiting to run
Integ / integ-ssh (push) Waiting to run
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
CLI exit codes / TypeScript CLI (push) Waiting to run
CLI exit codes / Cross-language snapshot interop (push) Waiting to run
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Waiting to run
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Waiting to run
Test (Python) / changes (push) Has been skipped
Integ / integ-database-ts (push) Waiting to run
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Waiting to run
Integ / integ-data (push) Waiting to run
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Waiting to run
Test (Python) / test (push) Waiting to run
Integ / integ-fuse (push) Waiting to run
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Waiting to run
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Waiting to run
Test (Python) / audit (push) Waiting to run
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Waiting to run
Integ / integ-ssh-ts (push) Waiting to run
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Waiting to run
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Waiting to run
Test (TypeScript) / changes (push) Has been skipped
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Waiting to run
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Waiting to run
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Waiting to run
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Waiting to run
Test (TypeScript) / test (push) Waiting to run
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Waiting to run
Test (TypeScript) / python-fs-shim (push) Waiting to run
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Waiting to run
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Waiting to run
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Waiting to run
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Waiting to run
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Waiting to run
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Waiting to run
Test (Install) / ts-minimal (push) Waiting to run
169 lines
4.4 KiB
Python
169 lines
4.4 KiB
Python
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
|
|
from mirage.utils.path import (expand_tilde, gnu_basename, gnu_dirname, norm,
|
|
parent, resolve_path)
|
|
|
|
|
|
def test_norm_strips_and_adds_leading_slash():
|
|
assert norm("a/b") == "/a/b"
|
|
assert norm("/a/b/") == "/a/b"
|
|
assert norm("///a///") == "/a"
|
|
assert norm("") == "/"
|
|
assert norm("/") == "/"
|
|
|
|
|
|
def test_parent_of_normalized_key():
|
|
assert parent("/a/b") == "/a"
|
|
assert parent("/a") == "/"
|
|
assert parent("/") == "/"
|
|
assert parent("/a/b/c") == "/a/b"
|
|
|
|
|
|
def test_basename_simple():
|
|
assert gnu_basename("/a/b/c.txt") == "c.txt"
|
|
|
|
|
|
def test_basename_no_slash():
|
|
assert gnu_basename("c.txt") == "c.txt"
|
|
|
|
|
|
def test_basename_trailing_slash():
|
|
assert gnu_basename("/a/b/") == "b"
|
|
|
|
|
|
def test_basename_multiple_trailing_slashes():
|
|
assert gnu_basename("/a/b///") == "b"
|
|
|
|
|
|
def test_basename_root():
|
|
assert gnu_basename("/") == "/"
|
|
|
|
|
|
def test_basename_empty():
|
|
assert gnu_basename("") == ""
|
|
|
|
|
|
def test_basename_strip_suffix():
|
|
assert gnu_basename("/a/b/c.txt", ".txt") == "c"
|
|
|
|
|
|
def test_basename_suffix_equal_to_base_not_stripped():
|
|
assert gnu_basename("/a/.txt", ".txt") == ".txt"
|
|
|
|
|
|
def test_basename_suffix_not_matching():
|
|
assert gnu_basename("/a/c.txt", ".md") == "c.txt"
|
|
|
|
|
|
def test_dirname_simple():
|
|
assert gnu_dirname("/a/b/c.txt") == "/a/b"
|
|
|
|
|
|
def test_dirname_relative_nested():
|
|
assert gnu_dirname("a/b") == "a"
|
|
|
|
|
|
def test_dirname_trailing_slash():
|
|
assert gnu_dirname("/a/b/") == "/a"
|
|
|
|
|
|
def test_dirname_single_absolute():
|
|
assert gnu_dirname("/a") == "/"
|
|
|
|
|
|
def test_dirname_single_relative():
|
|
assert gnu_dirname("a") == "."
|
|
|
|
|
|
def test_dirname_root():
|
|
assert gnu_dirname("/") == "/"
|
|
|
|
|
|
def test_dirname_empty():
|
|
assert gnu_dirname("") == "."
|
|
|
|
|
|
def test_resolve_relative_against_cwd():
|
|
assert resolve_path("file.txt", "/data/") == "/data/file.txt"
|
|
|
|
|
|
def test_resolve_parent_traversal():
|
|
assert resolve_path("../file.txt", "/data/sub/") == "/data/file.txt"
|
|
|
|
|
|
def test_resolve_absolute_ignores_cwd():
|
|
assert resolve_path("/abs/path", "/ignored") == "/abs/path"
|
|
|
|
|
|
def test_resolve_current_dir_segment():
|
|
assert resolve_path("./x", "/a/b") == "/a/b/x"
|
|
|
|
|
|
def test_expand_tilde_alone():
|
|
assert expand_tilde("~", "/home/u") == "/home/u"
|
|
|
|
|
|
def test_expand_tilde_with_subpath():
|
|
assert expand_tilde("~/file.txt", "/home/u") == "/home/u/file.txt"
|
|
|
|
|
|
def test_expand_tilde_root_home():
|
|
assert expand_tilde("~/file.txt", "/") == "/file.txt"
|
|
|
|
|
|
def test_expand_tilde_user_unchanged():
|
|
assert expand_tilde("~other/x", "/home/u") == "~other/x"
|
|
|
|
|
|
def test_expand_tilde_non_leading_unchanged():
|
|
assert expand_tilde("a~b", "/home/u") == "a~b"
|
|
|
|
|
|
def test_expand_tilde_plain_word_unchanged():
|
|
assert expand_tilde("file.txt", "/home/u") == "file.txt"
|
|
|
|
|
|
def test_resolve_symlinks_prefix_substitution():
|
|
from mirage.utils.path import resolve_symlinks
|
|
links = {"/a/link": "/a/real"}
|
|
assert resolve_symlinks("/a/link/f.txt", links) == "/a/real/f.txt"
|
|
assert resolve_symlinks("/a/link", links) == "/a/real"
|
|
|
|
|
|
def test_resolve_symlinks_relative_target_resolved_against_link_dir():
|
|
from mirage.utils.path import resolve_symlinks
|
|
links = {"/a/link": "real"}
|
|
assert resolve_symlinks("/a/link", links) == "/a/real"
|
|
|
|
|
|
def test_resolve_symlinks_respects_path_boundary():
|
|
from mirage.utils.path import resolve_symlinks
|
|
links = {"/a/b": "/x"}
|
|
assert resolve_symlinks("/a/bc", links) == "/a/bc"
|
|
|
|
|
|
def test_resolve_symlinks_no_links_is_identity():
|
|
from mirage.utils.path import resolve_symlinks
|
|
assert resolve_symlinks("/a/b", {}) == "/a/b"
|
|
|
|
|
|
def test_resolve_symlinks_cycle_raises():
|
|
import pytest
|
|
|
|
from mirage.utils.path import CycleError, resolve_symlinks
|
|
links = {"/a": "/b", "/b": "/a"}
|
|
with pytest.raises(CycleError):
|
|
resolve_symlinks("/a", links)
|