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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
- **A refusal or a declared difference** found in the code (`not modelled`, `Unsupported`, `UnsupportedOption`) has
an entry here.
- **A change of status** (a z/OS run, a new flag) edits the entry and its date. The summary table follows (it is generated from the entries' front matter).
- **An entry that claims a match** (ASSUMED, MATCHED, or no status) names an IBM document number (`SC27-8713-03`) or an
`ibm.com/docs` link, declares the difference, or states that IBM is silent (#4702). `python tests/tools/register.py
audit --ci` fails on one that does not; `STRICT_BASELINE` lists those that still name a document only by name, and
only shrinks.
- **How.** This page is generated; do not edit it. Each entry is one file, `docs/language_status/register/<ID>.md`
(front matter: id, family, status, title, area, summary, reached; then the entry text). Take a new ID with
`python tests/tools/register.py next <family>` when the issue is filed, so parallel PRs never pick the same number
Expand Down
35 changes: 34 additions & 1 deletion tests/tools/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ def check() -> list[str]:
re.I,
)
DECLARED_DIFF = re.compile(r"declared (oracle-vs-IBM )?difference|DIFFERS|Where they differ", re.I)
# The strict tier: a document NUMBER or an ibm.com/docs link (a bare document name is not a quote), a declared
# difference, or an explicit statement that IBM is silent. Entries that still name a document only by name are listed
# here; the list only shrinks (#4702).
STRICT_CITE = re.compile(r"[SGA][CHA]\d\d-\d{4}|ibm\.com/docs", re.I)
IBM_SILENT = re.compile(
r"IBM (is|stays|says nothing|does not (define|document))[^.]{0,30}(silent|undefined|nothing)"
r"|undefined (on|in|by) IBM|not documented",
re.I,
)
STRICT_BASELINE: frozenset[str] = frozenset(
{"F1", "F2", "I1", "I3", "I4", "Q1a", "Q1b", "X1", "X9", "X13", "X14", "X15", "X16", "X23", "X24"}
)


def audit() -> list[tuple[str, str, str]]:
Expand All @@ -146,13 +158,34 @@ def audit() -> list[tuple[str, str, str]]:
return out


def audit_strict() -> list[str]:
"""Ids of the entries that claim a match without a document number, a link, a declared difference or a stated IBM
silence."""
out = []
for meta, body in load_entries():
status = meta["status"]
claims = "ASSUMED" in status or "MATCHED" in status or not status
if claims and not (STRICT_CITE.search(body) or DECLARED_DIFF.search(body) or IBM_SILENT.search(body)):
out.append(meta["id"])
return out


def audit_problems(found: list[tuple[str, str, str]]) -> list[str]:
ids = {i for i, _, _ in found}
new = sorted(ids - UNCITED_BASELINE, key=id_key)
fixed = sorted(UNCITED_BASELINE - ids, key=id_key)
return [f"{i}: no IBM citation or declared difference (quote IBM, or declare the difference)" for i in new] + [
problems = [f"{i}: no IBM citation or declared difference (quote IBM, or declare the difference)" for i in new] + [
f"{i}: now cited; remove it from UNCITED_BASELINE" for i in fixed
]
strict = set(audit_strict())
problems += [
f"{i}: no IBM document number or link (cite it, declare the difference, or state IBM is silent)"
for i in sorted(strict - STRICT_BASELINE, key=id_key)
]
problems += [
f"{i}: now strictly cited; remove it from STRICT_BASELINE" for i in sorted(STRICT_BASELINE - strict, key=id_key)
]
return problems


def _git(*args: str) -> str:
Expand Down
23 changes: 23 additions & 0 deletions tests/tools/test_register_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,28 @@ def test_the_real_register_matches_the_baseline():
assert register.audit_problems(register.audit()) == []


def test_strict_tier_needs_a_number_a_difference_or_stated_silence(monkeypatch, tmp_path):
_audit_with(
monkeypatch,
tmp_path,
{
"C1": ("ASSUMED", "- see the Language Reference"),
"C2": ("MATCHED", "- Enterprise COBOL 6.4 Language Reference, SC27-8713-03, says so"),
"C3": ("ASSUMED", "- **Where they differ.** the oracle pads"),
"C4": ("ASSUMED", "- IBM is silent here"),
"C5": ("REFUSED", "- nothing"),
},
)
assert register.audit_strict() == ["C1"]


def test_strict_problems_name_new_and_fixed(monkeypatch, tmp_path):
_audit_with(monkeypatch, tmp_path, {"C1": ("ASSUMED", "- Language Reference"), "C2": ("MATCHED", "- SC27-8713-03")})
monkeypatch.setattr(register, "STRICT_BASELINE", frozenset({"C2"}))
problems = register.audit_problems([])
assert any(p.startswith("C1:") for p in problems)
assert any(p.startswith("C2:") and "STRICT_BASELINE" in p for p in problems)


def test_the_baseline_is_empty():
assert not register.UNCITED_BASELINE
Loading