Files
Aislo/resources/tester/helper_est_native.cjs

161 lines
7.2 KiB
JavaScript

const fs = require("node:fs");
const path = require("node:path");
const vm = require("node:vm");
const base = path.resolve(__dirname, "../../tools/est-test");
const context = vm.createContext({ structuredClone, console });
for (const file of [
"native-math.js",
"native-formula.js",
"native-machine.js",
"native-rows.js",
"native-text.js",
"native-quantity.cjs",
"native-wonga.js",
"native-engine.js",
"native-escalation.js",
"native-progress.js",
"native-business.js",
"native-resources.js",
"native-schedule.js",
"native-model.js",
"native-c3r.js",
"native-exchange.js",
"native-verify.js",
]) {
vm.runInContext(fs.readFileSync(path.join(base, file), "utf8"), context, { filename: file });
}
const project = JSON.parse(fs.readFileSync(path.join(base, "sample.json"), "utf8"));
context.project = project;
const command = process.argv[2];
let result;
if (command === "machine")
result = vm.runInContext(
"EstMachine.calculate(project.tables.MachMainDat, project.tables.MachGijunDat, project.options)",
context,
);
else if (command === "head")
result = vm.runInContext("EstRows.head(project.tables.HeadMainDat, project.options)", context);
else if (command === "estimate")
result = vm.runInContext("EstRows.estimate(project.tables.EstMainDat, project.options)", context);
else if (command === "text")
result = vm.runInContext(
"EstText.calculate(project.tables.CostMainDat, project.options)",
context,
);
else if (command === "wonga")
result = vm.runInContext("EstWonga.calculate(project.tables.Wonga, project.options)", context);
else if (command === "all") result = vm.runInContext("EstNative.calculate(project)", context);
else if (command === "text-layout") {
context.cases = JSON.parse(
fs.readFileSync(path.join(__dirname, "fixtures/est_text_layout_cases.json"), "utf8"),
);
result = vm.runInContext(
"cases.map(item=>({code:item.code,...EstText.calculate(item.rows)}))",
context,
);
} else if (command === "manual") {
project.options.AutoCalc = false;
project.tables.EstMainDat[1].GN += 100;
result = require(path.join(base, "server.cjs")).calculate(project);
} else if (command === "refresh")
result = vm.runInContext(
"project.options.SourceRefresh=true; EstNative.calculate(project)",
context,
);
else if (command === "repeat")
result = vm.runInContext(
'project.options.SourceRefresh=true; project.tables.LaborcDat.forEach(row=>{for(const key of ["Cost1","Cost2","Cost3","Cost4","Cost5","Cost6"]) row[key] = Number(row[key] || 0)*1.1}); const a=EstNative.calculate(project); [a,EstNative.calculate(a)]',
context,
);
else if (command === "import")
result = require(path.join(base, "import-estx.cjs")).importEstx(fs.readFileSync(process.argv[3]));
else if (command === "baseline-size") {
context.input = require(path.join(base, "import-estx.cjs")).importEstx(
fs.readFileSync(process.argv[3]),
);
const baseline = vm.runInContext("EstBusiness.baseline(input)", context);
result = {
bytes: Buffer.byteLength(JSON.stringify(baseline), "utf8"),
archivePreserved: baseline.originalArchive === context.input.originalArchive,
};
} else if (command === "blob-tail") {
const { blob } = require(path.join(base, "import-estx.cjs")),
bytes = Buffer.alloc(1536);
bytes.writeUInt32LE(2, 516);
bytes.writeUInt16LE(3, 520);
bytes.writeUInt32LE(7, 522);
bytes.writeUInt32LE(3, 526);
bytes.write("abc", 530);
bytes.writeUInt32LE(1, 1024);
bytes.writeUInt16LE(3, 1032);
bytes.write("xyz", 1042);
const value = blob(bytes, 1, 7).toString();
bytes.writeUInt32LE(4, 526);
bytes.writeUInt32LE(0, 516);
let truncated = "";
try {
blob(bytes, 1, 7);
} catch (error) {
truncated = error.message;
}
result = { value, truncated };
} else if (command === "extended") {
context.extended = JSON.parse(
fs.readFileSync(path.join(__dirname, "fixtures/est_native_extended.json"), "utf8"),
);
result = vm.runInContext(
`({
head: EstRows.head(extended.tables.HeadMainDat, extended.options),
text: EstText.calculate(extended.tables.CostMainDat, extended.options),
machine: EstMachine.calculate(extended.tables.MachMainDat, extended.tables.MachGijunDat, extended.options)
})`,
context,
);
} else if (command === "quantity") {
context.sheets = JSON.parse(
fs.readFileSync(path.join(__dirname, "fixtures/est_quantity_sheets.json"), "utf8"),
);
result = vm.runInContext(
"sheets.map(sheet=>({Code:sheet.Code,original:sheet.items,...EstQuantity.calculate(sheet)}))",
context,
);
} else if (command === "business")
result = vm.runInContext(
`
const p=EstNative.empty();
p.tables.StuffcDat=[{Code:'M',Name:'material',Cost1:100,ValueIndex:0}];
p.tables.HeadMainDat=[{Index:1,Code:'H',Name:'head'},{Index:0,Code:'M',LinkIndex:5,GN:2}];
p.tables.HeadTitleDat=[{Code:'H',Name:'head'}];
p.tables.EstMainDat=[{PkID:1,Code:'H',Name:'item',GN:10,LinkIndex:103},{PkID:2,Name:'direct',LinkIndex:54}];
p.tables.EstMainDat.push({PkID:4,Name:'부가세',LinkIndex:58},{PkID:5,Name:'total',LinkIndex:55});
p.tables.Wonga=[{Gubun:'G',Name:'material',BaseField:'GC',Cost:0},{Gubun:'V',Name:'부가세',VSusic:'G*0.1',Youl:'10%'},{Gubun:'T',Name:'total',VSusic:'G+V',LinkIndex:55}];
let q=EstNative.calculate(p);q=EstBusiness.baseline(q);
q.progress=[{id:'one',inputs:{'1':{Gum:25,GumMode:'ratio',Sa:1.5}},approved:true,locked:false}];
const first=EstBusiness.progress(q,'one');q.progress[0].result=first;q.progress[0].locked=true;
q.progress.push({id:'two',inputs:{'1':{Gum:500,GumMode:'amount',Sa:1}},approved:false,locked:false});
const second=EstBusiness.progress(q,'two');
q.annual=[{name:'1차',formula:'[계약수량]*0.4'},{name:'2차',formula:'[계약수량]-[1차]'}];
const years=EstBusiness.annual(q);const resources=EstResources.calculate(q);
const esc=structuredClone(q);esc.options.SourceRefresh=false;
Object.assign(esc.tables.EstMainDat[0],{AGU:180,GU:240,EscPlanned:2,EscActual:3,EscProgress:1});
const escalation=EstBusiness.escalation(esc);
const changed=structuredClone(q);changed.tables.StuffcDat[0].Cost1=120;
changed.tables.EstMainDat.splice(1,0,{PkID:3,Code:'M',Name:'new',GN:1,LinkIndex:5,NewItem:true});
const originals=[0,1,2].map(method=>EstBusiness.original(changed,method));
const bid=EstBusiness.bid(q,[90]);const bidAgain=EstBusiness.bid(bid,[90]);
const bidResources=EstResources.calculate(bid);
const converted=structuredClone(q);converted.tables.HeadMainDat.push({Index:0,GN:0.5,LinkIndex:68,Size:'unit conversion'});
const convertedResources=EstResources.calculate(converted);
const equipment=EstNative.empty();
equipment.tables.MachMainDat=[{Index:1,Code:'E',Name:'equipment',Unite:'hr'},{Index:-2,Name:'주연료',GN:1,TU:100}];
equipment.tables.HeadMainDat=[{Index:1,Code:'H',Name:'head'},{Index:0,LinkIndex:105,Code:'E',GN:2}];
equipment.tables.HeadTitleDat=[{Code:'H'}];equipment.tables.EstMainDat=[{PkID:1,LinkIndex:103,Code:'H',GN:10},{LinkIndex:54}];
const equipmentResources=EstResources.calculate(equipment);
({first,second,years,resources,escalation,originals,bid,bidAgain,bidResources,convertedResources,equipmentResources,project:q});
`,
context,
);
else if (command === "math") result = vm.runInContext(process.argv[3], context);
else throw Error("unknown command");
process.stdout.write(JSON.stringify(result));