v3: gstack-code-gen 生成

This commit is contained in:
hangshuo652
2026-05-24 12:36:44 +08:00
commit 818e81269c
50 changed files with 1343 additions and 0 deletions
View File
+39
View File
@@ -0,0 +1,39 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from comparator.aligner import align_records
def test_align_by_key():
c = [{"CUST-ID": "C001", "AMT": 100}, {"CUST-ID": "C002", "AMT": 200}]
s = [{"CUST-ID": "C002", "AMT": 200}, {"CUST-ID": "C001", "AMT": 100}]
result = align_records(c, s, key_field="CUST-ID")
assert len(result) == 2
assert all(st == "MATCHED" for _, _, st in result)
def test_missing_in_spark():
c = [{"CUST-ID": "C001"}, {"CUST-ID": "C002"}]
s = [{"CUST-ID": "C001"}]
result = align_records(c, s, key_field="CUST-ID")
assert "MISSING_IN_SPARK" in [st for _, _, st in result]
def test_extra_in_spark():
c = [{"CUST-ID": "C001"}]
s = [{"CUST-ID": "C001"}, {"CUST-ID": "C002"}]
result = align_records(c, s, key_field="CUST-ID")
assert "EXTRA_IN_SPARK" in [st for _, _, st in result]
def test_empty_inputs():
assert align_records([], [], "key") == []
def test_duplicate_keys():
c = [{"ID": "K1", "V": 1}, {"ID": "K1", "V": 2}]
s = [{"ID": "K1", "V": 1}, {"ID": "K1", "V": 2}]
assert len(align_records(c, s, key_field="ID")) == 2
def test_none_key():
assert len(align_records([{"ID": None, "V": 1}], [{"ID": None, "V": 1}], "ID")) == 1
+31
View File
@@ -0,0 +1,31 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from comparator.field_compare import compare_field, DEFAULT_TOLERANCE
def test_exact_match():
assert compare_field("F1", "1500000", "1500000", "decimal").status == "PASS"
def test_within_tolerance():
assert compare_field("F1", "1500000", "1499999.99", "decimal", DEFAULT_TOLERANCE).status == "TOLERATED"
def test_beyond_tolerance():
assert compare_field("F1", "1500000", "1000000", "decimal", DEFAULT_TOLERANCE).status == "MISMATCH"
def test_string_trim():
assert compare_field("F1", "A ", "A", "string").status == "PASS"
def test_date_normalization():
assert compare_field("F1", "20260522", "2026-05-22", "date").status == "PASS"
def test_default_zero():
assert compare_field("F1", "\x00\x00\x00\x00\x00", "0", "decimal").status in ("PASS", "TOLERATED")
def test_java_null():
assert compare_field("F1", "1500000", "None", "decimal").status in ("MISMATCH", "NOT_SET")
+30
View File
@@ -0,0 +1,30 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from comparator.normalizer import Normalizer
def test_ebcdic():
n = Normalizer()
assert n.normalize_encoding(b'\xc1\xc2', "EBCDIC") == "AB"
def test_ascii_passthrough():
assert Normalizer().normalize_encoding(b"hello", "ASCII") == "hello"
def test_comp3():
assert Normalizer().normalize_comp3(b'\x00\x15\x0C') == "150"
def test_comp3_negative():
assert Normalizer().normalize_comp3(b'\x15\x0D') == "-150"
def test_date_iso():
assert Normalizer().normalize_date("20260522") == "2026-05-22"
def test_ir_record():
n = Normalizer()
ir = n.to_ir_record("BR-AMT", "15000C", "1500", "EBCDIC", "COMP3", 5, 2, True)
assert ir.field_name == "BR-AMT"
assert ir.cobol.decoded_value == "1500"
+19
View File
@@ -0,0 +1,19 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from comparator.rounding_detect import detect_rounding
def test_truncation():
r = detect_rounding("1500000", "1499999")
assert r.mode in ("TRUNCATE", "HALF_UP")
def test_exact():
r = detect_rounding("1500000", "1500000")
assert r.mode == "EXACT"
assert r.confidence == 1.0
def test_small_diff():
r = detect_rounding("1500", "1498")
assert r.confidence < 1.0
+13
View File
@@ -0,0 +1,13 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SIMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 BILL-RECORD.
05 BR-AMT PIC S9(7)V99 COMP-3.
05 BR-STATUS PIC X.
05 BR-DATE PIC 9(8).
PROCEDURE DIVISION.
DISPLAY BR-AMT.
DISPLAY BR-STATUS.
DISPLAY BR-DATE.
STOP RUN.
+4
View File
@@ -0,0 +1,4 @@
01 BILL-RECORD.
05 BR-AMT PIC S9(7)V99 COMP-3.
05 BR-STATUS PIC X.
05 BR-DATE PIC 9(8).
+13
View File
@@ -0,0 +1,13 @@
program: "SIMPLE"
field_mapping:
- cobol_field: "BR-AMT"
java_field: "billAmount"
type: "decimal"
precision: 2
- cobol_field: "BR-STATUS"
java_field: "statusCode"
type: "string"
- cobol_field: "BR-DATE"
java_field: "billDate"
type: "date"
format: "YYYYMMDD"
+26
View File
@@ -0,0 +1,26 @@
import sys, os, json
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from pathlib import Path
from report.generator import ReportGenerator
from data.diff_result import VerificationRun, FieldResult
def test_json_output(tmp_path):
vr = VerificationRun(program="BILL-CALC", status="PASS", exit_code=0,
field_results=[FieldResult(field_name="BR-AMT", status="PASS")])
p = ReportGenerator().generate_json(vr, tmp_path / "result.json")
d = json.loads(p.read_text())
assert d["program"] == "BILL-CALC"
def test_html_output(tmp_path):
vr = VerificationRun(program="TEST", status="MISMATCH",
field_results=[FieldResult(field_name="F1", status="MISMATCH")])
p = ReportGenerator().generate_html(vr, tmp_path / "report.html")
assert "MISMATCH" in p.read_text()
def test_machine_json(tmp_path):
vr = VerificationRun(program="TEST", status="PASS", exit_code=0)
p = ReportGenerator().generate_machine_json(vr, tmp_path / "machine.json")
assert json.loads(p.read_text())["exit_code"] == 0
+30
View File
@@ -0,0 +1,30 @@
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
def test_e2e_imports():
from data.field_tree import Field, FieldTree
from data.test_case import TestCase, TestSuite, SparkConfig
from data.diff_result import FieldResult, VerificationRun
from runners.runner import Runner, BuildResult, RunResult, CoverageReport
from runners.native_java_runner import NativeJavaRunner
from runners.spark_java_runner import SparkJavaRunner
from runners.cobol_runner import CobolRunner
from runners.data_writer import DataWriter
from agents.llm import LLMClient
from agents.agent1_parser import Agent1Parser
from agents.agent2_data import Agent2Data
from agents.agent3_diagnostic import Agent3Diagnostic
from comparator.aligner import align_records
from comparator.field_compare import compare_field
from comparator.normalizer import Normalizer
from comparator.rounding_detect import detect_rounding
from comparator.cobol_binary_reader import CobolBinaryReader
from report.generator import ReportGenerator
from storage.bundle import TestDataBundle
from storage.store import ReportStore, DiskCache
from preprocessor import CopybookPreprocessor
from config.mapping import MappingConfig, FieldMapping
from quality.l1_offset_validate import L1OffsetValidator
from quality.l2_value_roundtrip import L2RoundtripValidator
assert True