"""EST 테스트 앱 조달청 표준공사코드 적용(원본 TfrmCodeChange — 코드변경·변경취소·적용·일괄변경·자동변경·다산정리·사용자정의코드).""" import json import subprocess from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] JODAL = Path("C:/Dasansoft/Est Plus 2/System/MainSys/JodalCodeDB.estx") PPS = Path("C:/Dasansoft/Est Plus 2/System/MainSys/PPS_STUFFC.dat") def run_js(code: str, *args: str): runner = f""" const fs = require('fs'), vm = require('vm'); const ctx = vm.createContext({{ structuredClone, console, require, process }}); for (const f of ['native-autolink.js', 'native-code-change.js']) vm.runInContext(fs.readFileSync('tools/est-test/' + f, 'utf8'), ctx, {{ filename: f }}); process.stdout.write(JSON.stringify(vm.runInContext({json.dumps(code)}, ctx))); """ return json.loads( subprocess.check_output(["node", "-e", runner, *args], cwd=ROOT).decode("utf-8") ) def test_input_check_cancel_apply(): out = run_js( r"""(() => { const C = EstCodeChange; const p = { tables: { StuffcDat: [{ Index: 1, Code: 'M0000000001', Name: '휘발유', Size: '', Unite: 'ℓ' }, { Index: 2, Code: '1510150620282202', Name: '경유', Size: '', Unite: 'ℓ' }], LaborcDat: [{ Index: 7, Code: 'L001010101000001', Name: '작업반장', Size: '' }], EstMainDat: [{ LinkIndex: 5, Code: 'M0000000001', Index: 0 }, { LinkIndex: 6, Code: 'M0000000001' }], CostMainDat: [{ LinkIndex: 5, Code: 'M0000000001', Index: 1 }, { LinkIndex: 5, Code: 'M0000000001', Index: 0 }], MachTitleDat: [], MachMainDat: [{ TitleCode: 'E0000000001', Code: 'E0000000001' }] } }; const rows = C.load(p, 5); const bad = C.validate(p, 5, rows); const err = (code) => { try { C.input(p, 5, rows, 0, code); return ''; } catch (e) { return e.message; } }; const out = { bad, flags: rows.map((r) => r.Flag), dup: err('1510150620282202'), other: err('L001010101000001'), short: err('123'), est: err('M0000000009') }; C.input(p, 5, rows, 0, '1510150620282999'); C.cancel(rows, 0); out.cancel = rows[0].Code; C.input(p, 5, rows, 0, '1510150620282999'); out.applied = C.apply(p, 5, rows); out.codes = [p.tables.StuffcDat[0].Code, p.tables.EstMainDat.map((r) => r.Code), p.tables.CostMainDat.map((r) => r.Code)]; const m = [{ Code: 'E0000000001', Name: '불도저' }]; p.tables.MachTitleDat = m; const mr = C.load(p, 105); C.input(p, 105, mr, 0, '0000010100070000'); C.apply(p, 105, mr); out.mach = [m[0].Code, p.tables.MachMainDat[0]]; const s = [{ Code: 'OB010.11001' }, { Code: 'OB010.11001' }, { Code: '' }]; C.auto(s); out.auto = s.map((r) => r.Code); const d = [{ Code: 'x' }, { Code: '' }]; C.dasan(d, 5); out.dasan = d.map((r) => r.Code); out.user = [C.userCode(p, 6, C.load(p, 6), 'L001010101000001'), C.userCode(p, 103, [], 'CAA16123000S'), C.userCode(p, 105, [], '00000101000700000')]; out.search = C.search([{ Name: '강관 지주', Size: '6m' }, { Name: '강관', Size: '' }], '강관&6 m').length; return out; })()""" ) assert out["bad"] == 1 and out["flags"] == [1, 0] assert out["dup"] == "같은 코드가 있습니다. 확인하세요." assert out["other"].startswith('노임"7.작업반장()" ') assert out["short"].startswith("코드자리수가 틀립니다") assert out["est"] == "조달청 코드가 아닙니다." assert out["cancel"] == "M0000000001" assert out["applied"] == 3 assert out["codes"] == [ "1510150620282999", ["1510150620282999", "M0000000001"], ["M0000000001", "1510150620282999"], ] assert out["mach"] == [ "00000101000700000", {"TitleCode": "00000101000700000", "Code": "00000101000700000"}, ] assert out["auto"] == ["OB01011001", "COB010110010", ""] assert out["dasan"] == ["M0000000000", "M0000000001"] assert out["user"] == ["L0010101010Z0000", "CAA16123Z000", "00000101000Z00000"] assert out["search"] == 1 def test_bulk_from_installed_jodal_db_and_pps_list(): if not JODAL.exists() or not PPS.exists(): pytest.skip("installed EST code DB unavailable") out = run_js( r"""(() => { const { importEstx, table } = require(process.cwd() + '/tools/est-test/import-estx.cjs'); const fs = require('fs'); const source = importEstx(fs.readFileSync(process.argv[1])); const p = { tables: { LaborcDat: [ { Index: 1, Code: 'L0000000001', Name: '작업반장', Size: '', Unite: '인' }, { Index: 2, Code: 'L0000000002', Name: '없는직종', Size: '', Unite: '인' }, { Index: 3, Code: 'L001010101000001', Name: '작업반장', Size: '', Unite: '인' } ] } }; const rows = EstCodeChange.load(p, 6); rows.splice(2, 1); const n = EstCodeChange.bulk(p, 6, rows, source); const pps = table(fs.readFileSync(process.argv[2]), null, []); return { n, codes: rows.map((r) => r.Code), checked: rows.map((r) => r.Checked), pps: pps.length, found: EstCodeChange.search(pps, '작업반장').some((r) => r.Code === 'L001010101000001') }; })()""", str(JODAL), str(PPS), ) assert out["n"] == 1 and out["checked"] == [True, False] assert out["codes"][0] == "L001010101000001" assert out["codes"][1] == "L0000000002" assert out["pps"] > 50000 and out["found"]