3939 _opm_item_for_param ,
4040 _classify_size ,
4141 _summary_size_shape ,
42+ _summary_optional_body ,
4243 NS ,
4344 SECTION_MAP ,
4445)
@@ -1146,19 +1147,22 @@ def test_field_scope_gets_size_kind_none(self, tmp_path):
11461147 assert entry ["size_kind" ] == "none"
11471148 assert "size_count" not in entry
11481149
1149- def test_well_and_group_scope_get_size_kind_fixed_one (self , tmp_path ):
1150- # Group/well/region/etc. mnemonics take a single record (a list of
1151- # names or just '/'); modelling them as 'list' would wrongly demand
1152- # a closing standalone '/'. They're 'fixed' with size_count=1.
1150+ def test_well_and_group_scope_get_size_kind_array (self , tmp_path ):
1151+ # Group/well/region/etc. mnemonics take an optional list of names
1152+ # spread across one or more lines and closed by a single '/'. That's
1153+ # ``size_kind: 'array'`` plus ``optional_body: True`` so a bare
1154+ # ``WOPR`` stacked back-to-back with another mnemonic is accepted
1155+ # but a forgotten closing '/' after listed names is still flagged.
11531156 body = self ._fgwcl_table (
11541157 _row ("Flow" , "Gas-Oil Ratio" , "GOR" ,
11551158 "" , "GGOR" , "WGOR" , "" , "" , "" ),
11561159 )
11571160 fodt = self ._write_section_fodt (tmp_path , body )
11581161 out = parse_summary_mnemonics (fodt )
11591162 for kw in ("GGOR" , "WGOR" ):
1160- assert out [kw ]["size_kind" ] == "fixed"
1161- assert out [kw ]["size_count" ] == 1
1163+ assert out [kw ]["size_kind" ] == "array"
1164+ assert "size_count" not in out [kw ]
1165+ assert out [kw ]["optional_body" ] is True
11621166
11631167 def test_skips_empty_scope_cells (self , tmp_path ):
11641168 # Only WOPT exists for this row; the empty Field/Group cells must
@@ -1218,8 +1222,9 @@ def test_picks_up_network_model_gpr(self, tmp_path):
12181222 fodt = self ._write_section_fodt (tmp_path , body )
12191223 out = parse_summary_mnemonics (fodt )
12201224 assert "GPR" in out
1221- assert out ["GPR" ]["size_kind" ] == "fixed"
1222- assert out ["GPR" ]["size_count" ] == 1
1225+ assert out ["GPR" ]["size_kind" ] == "array"
1226+ assert "size_count" not in out ["GPR" ]
1227+ assert out ["GPR" ]["optional_body" ] is True
12231228
12241229 def test_tags_tracer_rows_as_templated (self , tmp_path ):
12251230 # Tracer mnemonics (FTPR, WTPC, …) are templates — the user appends
@@ -1256,10 +1261,11 @@ def test_picks_up_field_group_control_mode_table(self, tmp_path):
12561261 out = parse_summary_mnemonics (fodt )
12571262 for kw in ("FMCTP" , "GMCTP" , "FMCTW" , "GMCTW" , "FMCTG" , "GMCTG" ):
12581263 assert kw in out
1259- # Field-scope stays bare; group-scope takes a single record .
1264+ # Field-scope stays bare; group-scope takes an optional list of names .
12601265 assert out ["FMCTP" ]["size_kind" ] == "none"
1261- assert out ["GMCTP" ]["size_kind" ] == "fixed"
1262- assert out ["GMCTP" ]["size_count" ] == 1
1266+ assert out ["GMCTP" ]["size_kind" ] == "array"
1267+ assert "size_count" not in out ["GMCTP" ]
1268+ assert out ["GMCTP" ]["optional_body" ] is True
12631269 # Description spans pair Field/Group correctly.
12641270 assert "Production Group" in out ["FMCTP" ]["summary" ]
12651271 assert "Production Group" in out ["GMCTP" ]["summary" ]
@@ -1278,11 +1284,13 @@ def test_picks_up_well_control_mode_table(self, tmp_path):
12781284 body = _table (title , groups , mnem , desc )
12791285 fodt = self ._write_section_fodt (tmp_path , body )
12801286 out = parse_summary_mnemonics (fodt )
1281- assert out ["WSTAT" ]["size_kind" ] == "fixed"
1282- assert out ["WSTAT" ]["size_count" ] == 1
1287+ assert out ["WSTAT" ]["size_kind" ] == "array"
1288+ assert "size_count" not in out ["WSTAT" ]
1289+ assert out ["WSTAT" ]["optional_body" ] is True
12831290 assert "Well Status" in out ["WSTAT" ]["summary" ]
12841291 assert "Well Mode of Control" in out ["WMCTL" ]["summary" ]
1285- assert out ["WMCTL" ]["size_kind" ] == "fixed"
1292+ assert out ["WMCTL" ]["size_kind" ] == "array"
1293+ assert out ["WMCTL" ]["optional_body" ] is True
12861294
12871295 def test_picks_up_performance_table (self , tmp_path ):
12881296 # The "OPM Flow Simulation Performance" table has a different
@@ -1328,19 +1336,22 @@ def test_handles_aquifer_and_recovery_table_titles(self, tmp_path):
13281336 for kw in ("FAQR" , "AAQR" , "ALQR" , "ANQR" , "FOE" , "ROE" ):
13291337 assert kw in out
13301338 assert out ["FAQR" ]["size_kind" ] == "none"
1331- assert out ["AAQR" ]["size_kind" ] == "fixed " and out ["AAQR" ]["size_count " ] == 1
1339+ assert out ["AAQR" ]["size_kind" ] == "array " and out ["AAQR" ]["optional_body " ] is True
13321340 assert out ["FOE" ]["size_kind" ] == "none"
1333- assert out ["ROE" ]["size_kind" ] == "fixed " and out ["ROE" ]["size_count " ] == 1
1341+ assert out ["ROE" ]["size_kind" ] == "array " and out ["ROE" ]["optional_body " ] is True
13341342
13351343
13361344class TestSummarySizeShape :
13371345 def test_field_scope_none (self ):
13381346 assert _summary_size_shape ("FOPR" ) == ("none" , None )
13391347 assert _summary_size_shape ("FWPR" ) == ("none" , None )
13401348
1341- def test_other_scopes_fixed_one (self ):
1349+ def test_other_scopes_array_optional (self ):
1350+ # W/G/R/B/A-prefixed mnemonics take an optional list of names
1351+ # spread across one or more lines and closed by a single '/'.
13421352 for kw in ("WOPR" , "WWIR" , "GGOR" , "ROE" , "BPR" , "AAQR" ):
1343- assert _summary_size_shape (kw ) == ("fixed" , 1 )
1353+ assert _summary_size_shape (kw ) == ("array" , None )
1354+ assert _summary_optional_body (kw ) is True
13441355
13451356
13461357class TestAttachStringOptions :
0 commit comments