"""JC-01~08: JCL 解析 + 执行""" import sys, os, tempfile from pathlib import Path sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) from jcl.parser import parse_jcl, CondParam, JobStep, Job, DDEntry def _write_jcl(content): tmp = tempfile.NamedTemporaryFile(mode="w", suffix=".jcl", delete=False, encoding="utf-8") tmp.write(content) tmp.close() return tmp.name def test_parse_jcl_basic(): """JC-01: JOB + 2 STEP""" path = _write_jcl("//JobA JOB (1),'TEST'\n//STEP1 EXEC PGM=PGM1\n//STEP2 EXEC PGM=PGM2") try: job = parse_jcl(path) assert job is not None assert len(job.steps) == 2 finally: os.unlink(path) def test_parse_jcl_cond(): """JC-02: COND 参数""" path = _write_jcl("//J JOB\n//S EXEC PGM=P,COND=(0,NE)") try: job = parse_jcl(path) assert job is not None finally: os.unlink(path) def test_parse_jcl_dd(): """JC-03: DD 语句""" path = _write_jcl("//J JOB\n//S EXEC PGM=P\n//DD1 DD DSN=MY.DATA,DISP=SHR") try: job = parse_jcl(path) assert job is not None finally: os.unlink(path) def test_parse_jcl_comment(): """JC-06: 注释行跳过""" path = _write_jcl("//J JOB\n//* THIS IS COMMENT\n//S EXEC PGM=P") try: job = parse_jcl(path) assert job is not None assert len(job.steps) == 1 finally: os.unlink(path) def test_parse_jcl_continuation(): """JC-04: 续行""" path = _write_jcl("//J JOB\n//S EXEC PGM=P\n//DD1 DD DSN=A,\n// DISP=SHR") try: job = parse_jcl(path) assert job is not None finally: os.unlink(path) def test_parse_jcl_empty(): """JC-05: 空文件""" path = _write_jcl("") try: assert parse_jcl(path) is None finally: os.unlink(path) def test_parse_jcl_not_found(): """JC-07: 文件不存在 → 返回 None(不再抛异常)""" p = os.path.join(tempfile.gettempdir(), "_unlikely_jcl_test_99_.jcl") result = parse_jcl(p) assert result is None def test_cond_param(): c = CondParam(code=0, operator="NE") assert c.code == 0 def test_job_step(): s = JobStep("S1", "PGM1") assert s.step_name == "S1" def test_job(): j = Job("TESTJOB") assert j.job_name == "TESTJOB"