Files
Aislo/resources/tester/test_est_text_parser.py

222 lines
8.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from test_est_rea_parity import run
def test_mean_sea_level_labels_do_not_break_variable_declarations():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'D3 = {+}1.9m [ M.S.L ]'},
{Index:0, LineData:'1개소당 50㎥ q = 1.53 M.S.L h1 = 3.841'},
{Index:0, LineData:'Q = D3 + q + h1 = \\x127.27\\x12'}
];
return EstText.calculate(rows);
})()""",
)
assert result["errors"] == []
assert result["checks"][0]["calculated"] == 7.27
def test_redundant_price_caption_keeps_quantity_and_source_updates():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'Q = 7.35'},
{Index:0, SCheck:-2, LinkIndex:5,
LineData:'\\x0e황동주물\\x0e \\x0324,200\\x03C × Q = 24,200 × 7.35 = \\x12177,870\\x12'}
];
const initial=EstText.calculate(rows);
rows[1].LineData='Q = 4';
const changed=EstText.calculate(rows,{},()=>({GC:30000,TC:30000,Code:'M1',SourceKind:5}));
const repeat=EstText.calculate(changed.rows,{},()=>({GC:30000,TC:30000,Code:'M1',SourceKind:5}));
const conflict=structuredClone(rows);conflict.splice(1,0,{Index:0,LineData:'C = 2'});
const declared=EstText.calculate(conflict);
const mismatch=structuredClone(rows);mismatch[2].LineData=mismatch[2].LineData.replace('= 24,200','= 24,201');
return {initial,changed,repeat,declared,mismatch:EstText.calculate(mismatch)};
})()""",
)
assert result["initial"]["errors"] == []
assert result["initial"]["rows"][2]["TC"] == 177870
assert result["changed"]["errors"] == []
assert result["changed"]["rows"][2]["TC"] == 120000
assert result["changed"]["rows"][2]["ResourceFactor"] == 4
assert result["repeat"]["errors"] == []
assert result["repeat"]["rows"][2]["TC"] == 120000
assert result["declared"]["errors"]
assert result["mismatch"]["errors"]
def test_equals_in_description_is_not_a_formula_separator():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'강판{T=22} 67.659kg × 317.40 = \\x1221474.97\\x12'}
];
return EstText.calculate(rows);
})()""",
)
assert result["errors"] == []
assert result["checks"][0]["calculated"] == 21474.97
def test_korean_length_unit_ja_is_not_a_variable():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, SCheck:-1, LineData:'\\x0e목형원(제조)\\x0e : \\x03115706\\x03 × 0.16인 ×80자 = \\x061\\x06\\x121481036.8\\x12'}
];
return EstText.calculate(rows);
})()""",
)
assert result["errors"] == []
assert result["checks"][0]["calculated"] == 1481036.8
def test_selected_group_can_be_assigned_to_a_variable():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'0.15 = \\x06A\\x06\\x120.15\\x12'},
{Index:0, LineData:'0.87 = \\x06A\\x06\\x120.87\\x12'},
{Index:0, LinkIndex:62, LineData:'Q = (\\x07A\\x07\\x1a0.15 + 0.87\\x1a) = \\x121\\x12'},
{Index:0, LineData:'Q × 2 = \\x122\\x12'}
];
return EstText.calculate(rows);
})()""",
)
assert result["errors"] == []
assert result["checks"][-1]["calculated"] == 2.04
def test_independent_results_on_one_line_do_not_replace_the_declared_variable():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'Q = 3.43'},
{Index:0, LineData:'L = 2인×2조÷(Q×8hr) = \\x120.15\\x12 2×2÷(1×8) = \\x120.5\\x12'},
{Index:0, SCheck:-1, LineData:'노무비 : 226122 × L = \\x1233918.3\\x12'}
];
const initial = EstText.calculate(rows);
rows[1].LineData = 'Q = 4';
const changed = EstText.calculate(rows);
return {initial, changed};
})()""",
)
assert result["initial"]["errors"] == []
assert [check["calculated"] for check in result["initial"]["checks"][:2]] == [0.5, 0.15]
assert result["initial"]["rows"][3]["TC"] == 33918.3
assert [check["calculated"] for check in result["changed"]["checks"][:2]] == [0.5, 0.13]
assert result["changed"]["rows"][3]["TC"] == 29395.8
def test_unmarked_cost_component_declaration_is_available_to_later_formulas():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, SCheck:-3, LineData:'D = 1,466원'},
{Index:0, SCheck:-3, LineData:'E = D ×0.075 = 1,466 ×0.075 = \\x12109.9\\x12'}
];
const first = EstText.calculate(rows);
rows[1].LineData = 'D = 2,000원';
const second = EstText.calculate(rows);
return {first, second};
})()""",
)
assert result["first"]["errors"] == []
assert result["first"]["rows"][2]["TC"] == 109.9
assert result["second"]["rows"][2]["TC"] == 150
def test_repeated_saved_subtotal_tracks_the_preceding_subtotal():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, SCheck:-1, LineData:'100 = \\x12100\\x12'},
{Index:0, SCheck:-3, LineData:'50 = \\x1250\\x12'},
{Index:0, SCheck:-5, LineData:'소계 : \\x12150\\x12'},
{Index:0, SCheck:-5, LineData:'소계 : \\x12150\\x12'}
];
const first=EstText.calculate(rows);
rows[1].LineData='110 = \\x12100\\x12';
const second=EstText.calculate(rows);
return {first, second};
})()""",
)
assert [row["TC"] for row in result["first"]["rows"][-2:]] == [150, 150]
assert [row["TC"] for row in result["second"]["rows"][-2:]] == [160, 160]
def test_comment_only_declaration_waits_for_a_later_numeric_value():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'L = {공사구간 1/4}'},
{Index:0, LineData:'L = 1.213 km'},
{Index:0, LineData:'Q = L × 2 = \\x122.43\\x12'}
];
const normal=EstText.calculate(rows);
rows[1].LineData='L =';
const invalid=EstText.calculate(rows);
return {normal, invalid};
})()""",
)
assert result["normal"]["errors"] == []
assert result["normal"]["rows"][3]["TC"] == 2.43
assert result["invalid"]["errors"]
def test_unmarked_linked_price_declaration_excludes_name_and_specification_tags():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, SCheck:-3, LinkIndex:5,
LineData:'C = \\x0e구역화물\\x0e\\x13(10.5톤,230km)\\x13 \\x03293,690\\x03'},
{Index:0, LineData:'Q = C × 0.1 = \\x1229369\\x12'}
];
const original = EstText.calculate(rows);
const refreshed = EstText.calculate(rows, {}, () => ({JC: 400000}));
return {original, refreshed};
})()""",
)
assert result["original"]["errors"] == []
assert result["original"]["rows"][2]["TC"] == 29369
assert result["refreshed"]["rows"][2]["TC"] == 40000
def test_tonnes_per_area_is_a_unit_in_a_numeric_formula():
result = run(
"math",
"""(() => {
const rows = [
{Index:1, Code:'D1'},
{Index:0, LineData:'0.1 ㎥/㎡ × 2.10 t/㎡ = \\x120.21\\x12'}
];
const first=EstText.calculate(rows);
rows[1].LineData='0.1 ㎥/㎡ × 2.50 t/㎡ = \\x120.21\\x12';
const second=EstText.calculate(rows);
return {first, second};
})()""",
)
assert result["first"]["errors"] == []
assert result["first"]["rows"][1]["TC"] == 0.21
assert result["second"]["rows"][1]["TC"] == 0.25