222 lines
8.1 KiB
Python
222 lines
8.1 KiB
Python
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
|