Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion OpenDSS/13Bus/IEEE13Nodeckt.dss
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ New Transformer.XFM1 Phases=3 Windings=2 XHL=2


!LINE CODES
redirect IEEELineCodes.dss
redirect IEEELineCodes.DSS

// these are local matrix line codes
// corrected 9-14-2011
Expand Down
2 changes: 1 addition & 1 deletion OpenDSS/13Bus/IEEE13Nodeckt_com_loadshape.dss
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ New Transformer.XFM1 Phases=3 Windings=2 XHL=2


!LINE CODES
redirect IEEELineCodes.dss
redirect IEEELineCodes.DSS

// these are local matrix line codes
// corrected 9-14-2011
Expand Down
49 changes: 49 additions & 0 deletions tests/test_opendss_case_files.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""The shipped OpenDSS cases must compile on case-sensitive filesystems.

Windows and macOS resolve ``redirect IEEELineCodes.dss`` against a file named
``IEEELineCodes.DSS``; Linux does not, and OpenDSS then leaves a circuit with
no line codes. Compare names exactly so the check fails on every platform.
"""

from __future__ import annotations

import re
from pathlib import Path

import pytest

OPENDSS_DIR = Path(__file__).resolve().parents[1] / "OpenDSS"
_FILE_COMMAND = re.compile(r"^\s*(redirect|compile|buscoords)\s+(\S+)", re.IGNORECASE)


def _dss_files():
return sorted(p for p in OPENDSS_DIR.rglob("*") if p.suffix.lower() == ".dss")


def _referenced_files(dss_file: Path):
for line in dss_file.read_text(errors="replace").splitlines():
match = _FILE_COMMAND.match(line)
if match:
yield match.group(2).strip("\"'()[]")


def _exists_with_exact_case(base: Path, relative: str) -> bool:
current = base
for part in Path(relative.replace("\\", "/")).parts:
if part in (".", ".."):
current = current / part
continue
if not current.is_dir() or part not in {entry.name for entry in current.iterdir()}:
return False
current = current / part
return current.is_file()


@pytest.mark.parametrize("dss_file", _dss_files(), ids=lambda p: str(p.relative_to(OPENDSS_DIR)))
def test_referenced_files_match_case_exactly(dss_file):
missing = [
target
for target in _referenced_files(dss_file)
if not _exists_with_exact_case(dss_file.parent, target)
]
assert not missing, f"{dss_file.name} references files that do not exist with this exact case: {missing}"
Loading