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
35 changes: 34 additions & 1 deletion tests/cobol_mainframe/test_det_bytes_4690.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import shutil

import pytest
from test_det_programs import _cobol, _java, _java_run, program
from test_det_programs import ROOT, _cobol, _java, _java_run, _java_run_batch, program # noqa: F401

E2E = pytest.mark.skipif(os.environ.get("EQUIVALENCE_E2E") != "1" or not shutil.which("docker") or _java() is None,
reason="needs Docker and a JDK 17 (JAVA_HOME / JDK_17)") # fmt: skip
Expand Down Expand Up @@ -53,3 +53,36 @@
assert isinstance(want, bytes) and want
assert b"\xc3\xbf" not in got
assert got == want


def high_byte_program(name: str) -> str:
"""One MOVE X'hh' TO R and DISPLAY per byte 0x80-0xFF (all above X'7F')."""
proc: list[str] = []
for b in range(0x80, 0x100):
proc += [f"MOVE X'{b:02X}' TO R", "DISPLAY R"]
return program(name, ["01 R PIC X."], proc)


@E2E
@pytest.mark.parametrize(
"charset",
[
"ISO-8859-1",
*(
pytest.param(c, marks=pytest.mark.xfail(strict=True, reason="#4698: hex-literal bytes do not round-trip"))
for c in ("IBM037", "IBM1047", "windows-1252")
),
],
)
@pytest.mark.parametrize("mode", ["bytes", "typed", "groups"])
def test_batch_sysout_high_bytes_equal_gnucobols(charset, mode, tmp_path):
"""#4697: the batch Sysout (not the standalone one) writes the record charset's bytes for DISPLAY of X'80'..X'FF',
byte for byte as cobc does, under latin-1 and under single-byte EBCDIC record charsets."""
pytest.importorskip("tree_sitter_language_pack")
src = high_byte_program("HIBATCH")
cob = tmp_path / "cobol"
cob.mkdir()
want = _cobol(src, cob, raw=True)
got = _java_run_batch("HIBATCH", src, tmp_path, [], mode != "bytes", mode == "groups", raw=True, charset=charset)
assert isinstance(got, bytes) and want
assert got == want, f"{charset}: java {got[:40]!r} != cobol {want[:40]!r}"
21 changes: 15 additions & 6 deletions tests/cobol_mainframe/test_det_programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1301,21 +1301,30 @@ def _java_run(
check=True).stdout # fmt: skip


def _batch_package(srcdir: Path) -> None:
def _batch_package(srcdir: Path, charset: str = "ISO-8859-1") -> None:
"""The generated project's batch package (CobolFiles, DatasetResolver, Dd, MainframeClock, Sysout, CobolAbend)
from the batch forge's own templates, without Spring: what a det port with files runs on."""
from gitgalaxy.tools.cobol_to_java.cobol_to_java_batch_forge import _RUNTIME

for cls in ("CobolFiles", "DatasetResolver", "Dd", "MainframeClock", "Sysout", "CobolAbend"):
text = _RUNTIME[cls].replace("{pkg}", f"{PKG}.batch").replace("{zone}", "UTC")
text = text.replace("{record_charset}", "ISO-8859-1")
text = text.replace("{record_charset}", charset)
text = re.sub(r"^import org\.springframework\..*\n|^@Component\n", "", text, flags=re.M)
text = re.sub(r'@Value\("(?:[^"\\]|\\.)*"\)\s*', "", text)
(srcdir / PKG / "batch" / f"{cls}.java").parent.mkdir(parents=True, exist_ok=True)
(srcdir / PKG / "batch" / f"{cls}.java").write_text(text)


def _java_run_batch(name: str, src: str, work: Path, dds: list[str], typed: bool = False, groups: bool = False) -> str:
def _java_run_batch(
name: str,
src: str,
work: Path,
dds: list[str],
typed: bool = False,
groups: bool = False,
raw: bool = False,
charset: str = "ISO-8859-1",
) -> str:
"""As _java_run, on the batch runtime (DetFiles): runBatch with one DD per dataset, each a file of its name in
a datasets directory."""
from gitgalaxy.tools.cobol_to_java.det import program as P
Expand All @@ -1333,11 +1342,11 @@ def _java_run_batch(name: str, src: str, work: Path, dds: list[str], typed: bool
for rel, text in [(f"service/{r.service}.java", java), *runtime.items()]:
(srcdir / PKG / rel).parent.mkdir(parents=True, exist_ok=True)
(srcdir / PKG / rel).write_text(text)
_batch_package(srcdir)
_batch_package(srcdir, charset)
rec = srcdir / PKG / "entity/vsam/CobolRecords.java"
rec.parent.mkdir(parents=True, exist_ok=True)
rec.write_text(f"package {PKG}.entity.vsam;\npublic final class CobolRecords {{\n public static java.nio.charset."
"Charset charset() {\n return java.nio.charset.StandardCharsets.ISO_8859_1;\n }\n}\n") # fmt: skip
"Charset charset() {\n return java.nio.charset.Charset.forName(\"" + charset + "\");\n }\n}\n") # fmt: skip
data = work / "datasets"
data.mkdir()
b = f"{PKG}.batch"
Expand All @@ -1350,7 +1359,7 @@ def _java_run_batch(name: str, src: str, work: Path, dds: list[str], typed: bool
jdk = _java()
files = [str(f) for f in srcdir.rglob("*.java")]
subprocess.run([str(jdk / "javac"), "-nowarn", "-d", str(work / "classes"), *files], check=True) # noqa: S603
return subprocess.run([str(jdk / "java"), "-cp", str(work / "classes"), "Main"], capture_output=True, text=True, # noqa: S603
return subprocess.run([str(jdk / "java"), "-cp", str(work / "classes"), "Main"], capture_output=True, text=not raw, # noqa: S603
check=True).stdout # fmt: skip


Expand Down
Loading