Files
Aislo/resources/tester/test_est_text_units.py

260 lines
10 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_text_units_and_description_columns_preserve_numeric_assignments():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'units',LineData:'units'},
{LineData:' G2 = 3.14 / 4 ×0.105^2 ×1.50M × 2배 = \x120.026\x12 ㎥',Precision:3},
{LineData:' N = 2 set'},
{LineData:' 1. 재료비 : D=16mm, 1본당 4.0m'},
{LineData:' Q = D × N = \x1232\x12'},
{LineData:' V = G2 × 1000 = \x1226\x12'}
])""",
)
assert result["errors"] == []
assert result["rows"][1]["TC"] == 0.026
assert result["rows"][4]["TC"] == 32
assert result["rows"][5]["TC"] == 26
def test_text_unit_changes_propagate_without_reusing_stored_results():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'changed',LineData:'changed'},
{LineData:' N = 3 set'},
{LineData:' 1. 재료비 : D=25mm, 1본당 4.0m'},
{LineData:' Q = D × N = \x1232\x12'},
{LineData:' V = 1.5M × 3배 = \x123\x12',Precision:2}
])""",
)
assert result["errors"] == []
assert result["rows"][3]["TC"] == 75
assert result["rows"][4]["TC"] == 4.5
def test_per_set_unicode_millimetres_and_starred_weight_declarations():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'source_units',LineData:'source_units'},
{LineData:' * 본당 중량 W = 0.553톤/본*'},
{LineData:' T = 20㎜ A = 0.95 × 0.95 = \x120.9\x12㎡',Precision:1},
{LineData:' 재료비 : \x031,690\x03 × 0.005kg/set = \x128.4\x12',SCheck:-2},
{LineData:' Q = W × T = \x1211.06\x12',Precision:2}
])""",
)
assert result["errors"] == []
assert result["rows"][2]["TC"] == 0.9
assert result["rows"][3]["TC"] == 8.4
assert result["rows"][4]["TC"] == 11.06
def test_parenthesized_volume_and_count_units_recalculate_from_variables():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'volume',LineData:'volume'},
{LineData:' A = 80㎡ B = 16㎡'},
{LineData:' 새끼 : L =0.05m × 4배 × 4번 × 1줄 = \x120.8\x12m',Precision:1},
{LineData:' 노무비 : \x0358,122\x03 × 0.1 × (A+B)㎥ = 58,122 × 0.1 × (80+16) = \x12557,971.2\x12',SCheck:-1},
{LineData:' Q = L × (A+B)㎡ = \x1276.8\x12',Precision:1}
])""",
)
assert result["errors"] == []
assert result["rows"][2]["TC"] == 0.8
assert result["rows"][3]["TC"] == 557971.2
assert result["rows"][4]["TC"] == 76.8
def test_quoted_source_conversion_declaration_propagates_changed_value():
result = run(
"math",
r"""[2,3].map(quantity=>EstText.calculate([
{Index:1,Code:'quote',LineData:'quote'},
{LineData:` * 중량환산 : 사석기준 'Q1 = ${quantity}.0 톤/㎥'`},
{LineData:' 노무비 : \x03235,204\x03 ×1.04인×Q1 = 235,204 ×1.04×2 = \x12489,224.3\x12',SCheck:-1}
]))""",
)
assert all(item["errors"] == [] for item in result)
assert [item["rows"][2]["TC"] for item in result] == [489224.3, 733836.4]
def test_group_sum_accepts_assigned_price_and_refreshes_from_source():
result = run(
"math",
r"""[550,600].map(price=>{
const p=EstNative.empty();p.options.SourceRefresh=true;
p.tables.StuffcDat=[{Code:'M',ValueIndex:4,InputTC:price}];
p.tables.CostMainDat=[
{Index:1,Code:'C',LineData:'C'},
{LinkIndex:5,Code:'M',LineData:' \x0ebrick\x0e \x06A\x06\x03550\x03 : 별산'},
{LinkIndex:62,SCheck:-1,LineData:' \x07A\x07\x1a550\x1a × 5% = \x1227.5\x12'},
{SCheck:-1,LineData:' \x1a노무비:27\x1a'},
{SCheck:-5,LineData:' \x1a계:\x1a \x1227\x12'}];
p.tables.EstMainDat=[{Code:'C',LinkIndex:104,GN:10},{LinkIndex:54}];
return EstNative.calculate(p);
})""",
)
assert all(item["calculation"]["errors"] == [] for item in result)
assert [item["tables"]["CostMainDat"][2]["TC"] for item in result] == [27.5, 30]
assert [item["tables"]["EstMainDat"][0]["TC"] for item in result] == [270, 300]
def test_subtotal_includes_price_only_rows_and_updates_truncated_final_amount():
result = run(
"math",
r"""[1094,2000].map(price=>{
const p=EstNative.empty();
p.tables.StuffcDat=[{Code:'T',ValueIndex:4,InputTC:110754},{Code:'H',ValueIndex:4,InputTC:price}];
p.tables.CostMainDat=[
{Index:1,Code:'C',LineData:'transport'},
{Level:2,LineData:'1. 운반 및 하역'},
{LinkIndex:5,Code:'T',LineData:' \x0etruck\x0e (\x03110,754\x03 ÷12) ×1.5 = \x1213,844.2\x12'},
{LinkIndex:5,Code:'H',LineData:' \x0eunloading\x0e \x031,094\x03'},
{LinkIndex:61,SCheck:-3,TC:14938.2,LineData:' 경비소계 : \x0c14,938.2\x0c'},
{Level:2,LineData:'2. 합계'},
{Level:-2,SCheck:-3,LineData:' \x1a경비:14,938\x1a'},
{Level:-2,SCheck:-5,LineData:' \x1a계:\x1a \x1214,938\x12'}];
p.tables.EstMainDat=[{Code:'C',LinkIndex:104,GN:10},{LinkIndex:54}];
const first=EstNative.calculate(p),again=EstNative.calculate(first);
return {first,again};
})""",
)
assert all(item["first"]["calculation"]["errors"] == [] for item in result)
assert [item["first"]["tables"]["CostMainDat"][4]["TC"] for item in result] == [
14938.2,
15844.2,
]
for key in ["first", "again"]:
assert [item[key]["tables"]["EstMainDat"][0]["TC"] for item in result] == [
149380,
158440,
]
def test_operator_followed_by_spaces_does_not_start_a_new_assignment():
result = run(
"math",
r"""[1700,2000].map(weight=>EstText.calculate([
{Index:1,Code:'forest',LineData:'forest'},
{LineData:` N = 54.93 q = 250 W = ${weight}`},
{LineData:' Q = N × q ÷ W = 54.93 × 250 ÷ 1,700 = \x128.08\x12 ㎥/hr'},
{LineData:' V = Q × 2 = \x1216.16\x12'}
]))""",
)
assert all(item["errors"] == [] for item in result)
assert [item["rows"][2]["TC"] for item in result] == [8.08, 6.87]
assert [item["rows"][3]["TC"] for item in result] == [16.16, 13.74]
def test_curly_wrapped_results_and_explanatory_calculations_keep_their_text():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'forest',LineData:'forest'},
{LineData:' {0.91m×0.91m×0.6m = \x120.49686\x12㎥}'},
{LineData:' {0.49686 ×2.6Ton = \x121.29\x12}'},
{LineData:' ※ ㎡당 중량 1.6개 ×1,325÷1,000 = \x122.12\x12Ton/㎡'}
])""",
)
assert result["errors"] == []
assert [row["TC"] for row in result["rows"][1:]] == [0.49686, 1.29, 2.12]
assert result["rows"][1]["LineData"].strip().startswith("{")
assert result["rows"][1]["LineData"].endswith("}")
def test_won_unit_glyphs_are_units_instead_of_operators():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'money',LineData:'money'},
{LineData:' 0.0347㎥ / 2.5 × 0 \\/㎥ = \x120\x12'},
{LineData:' 0.0347㎥ / 2.5 × 2500 \\/㎥ = \x1234.7\x12'},
{LineData:' 2㎥ × 2500₩/㎥ = \x125000\x12'}
])""",
)
assert result["errors"] == []
assert [row["TC"] for row in result["rows"][1:]] == [0, 34.7, 5000]
def test_range_conditions_are_not_assigned_arbitrary_values():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'range',LineData:'range'},
{LineData:' 앙카핀 (D=13, L=450~600mm) 1.0㎡ : 별도계상'},
{LineData:' H = 0~4m : (기계80%, 인력20%)'},
{LineData:' Q = 2 × 3 = \x126\x12'},
{LineData:' V = H × 2 = \x128\x12'}
])""",
)
assert len(result["errors"]) == 1
assert "참조 항목 없음: H" in result["errors"][0]
assert result["rows"][3]["TC"] == 6
def test_quantity_subtotal_keeps_six_digits_before_pricing():
result = run(
"math",
r"""[4.4,5].map(length=>EstText.calculate([
{Index:1,Code:'sign',LineData:'sign'},
{Level:2,LineData:'각재 수량'},
{Diget:7,DigetIndex:1,LineData:` 0.09 ×0.09 ×${length}m ×2개 = \x120.07128\x12`},
{Diget:7,DigetIndex:1,LineData:' 0.06 ×0.06 ×2.28m ×5개 = \x120.04104\x12'},
{Diget:7,DigetIndex:1,LineData:' 0.06 ×0.06 ×2.28m ×7개 = \x120.057456\x12'},
{Diget:7,DigetIndex:1,LinkIndex:61,LineData:' 소 계 : Q1 = \x0c0.169776\x0c ㎥/개소'},
{SCheck:-2,LinkIndex:5,LineData:' 재료비 : \x03577,842\x03 × Q1 = 577,842 × 0.169776 = \x1298,103.7\x12'}
]))""",
)
assert all(item["errors"] == [] for item in result)
assert [item["rows"][5]["TC"] for item in result] == [0.169776, 0.179496]
assert [item["rows"][6]["TC"] for item in result] == [98103.7, 103720.3]
def test_declaration_can_follow_an_hour_unit_with_a_single_space():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'transport',LineData:'transport'},
{LineData:' L = 1.0Km{?} V1 = 5.5Km/hr V2 = 9.3Km/hr t=35분'},
{LineData:' Q = t × 2 = \x1270\x12'}
])""",
)
assert result["errors"] == []
assert result["rows"][2]["TC"] == 70
def test_fullwidth_unit_slash_and_ground_level_annotations():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'annotations',LineData:'annotations'},
{LineData:' Q = 23.32 ㎥/hr'},
{LineData:' D1 = {-}6.6m [평균지반고]'},
{LineData:' D2 = {-}18.6m [기초터파기 평균 저면 EL.]'},
{LineData:' V = Q + D1 - D2 = \x1235.32\x12',Precision:2}
])""",
)
assert result["errors"] == []
assert result["rows"][4]["TC"] == 35.32
def test_spaced_metre_unit_is_not_a_second_variable_declaration():
result = run(
"math",
r"""EstText.calculate([
{Index:1,Code:'spaced_unit',LineData:'spaced_unit'},
{LineData:' L7 = 4.5m'},
{LineData:' Q2 = L7 / 0.8 M = 4.5 / 0.8 = \x125.63\x12 개'},
{SCheck:-2,LineData:' 재료비 : \x033,000\x03 × Q2 = 3,000 × 5.63 = \x1216,890\x12'}
])""",
)
assert result["errors"] == []
assert result["rows"][2]["TC"] == 5.63
assert result["rows"][3]["TC"] == 16890