Files
will 25592fa6c2
ci / test (push) Successful in 6m14s
WillTools 2026-09-09 -- clean snapshot of the development repo for review
History-free snapshot of the private development repository at 77a82eb.
Code, docs and the public catalogue only: no plant or job knowledge
layers, no client, job or producer names (tools/scrub.py clean against
the widened term list; a second word-level grep clean). The intro deck is
left out because its slide images cannot be checked for job drawings.
2026-09-09 08:35:15 -05:00

369 lines
14 KiB
Python

# -*- coding: utf-8 -*-
"""Host tests for `vibe.pa_defaults` -- the aggressive Panel Analysis
defaults pass. See that module's docstring for the owner's instruction this
implements (2026-09-04: press the button, type the loading, everything else
already has a number) and for what deliberately stays blank.
Runs on plain CPython via `tests/conftest.py`'s `vibe` stub -- no Revit, no
WPF. `pa_defaults` imports `panelanalysisform` / `pa_criteria` /
`pa_structural` lazily and defensively, so these tests exercise the real
field tables those modules carry today, not a copy of them.
"""
from vibe import pa_defaults as D
# --------------------------------------------------------------- unknown_keys
def test_unknown_keys_is_empty():
"""Every key this module defaults must already exist somewhere in the
live form (panelanalysisform.FIELDS, the stage matrix, pa_criteria._F,
or a real pa_structural.page() field block). A non-empty list here is
the sibling field-model agents' punch list, printed so it is actionable
rather than just "some test failed".
"""
unknown = D.unknown_keys()
assert unknown == [], (
'pa_defaults knows how to default {0} key(s) the form does not '
'recognise yet: {1}'.format(len(unknown), unknown))
def test_known_keys_is_a_real_nonempty_set():
# Sanity: the live import chain actually worked in this environment,
# so unknown_keys()==[] above is not vacuously true because every
# lookup silently failed.
known = D.known_keys()
assert len(known) > 50
assert 'fc_psi' in known
assert 'stage.stripping.include' in known
assert 'design_criteria.phi_compression' in known
# ------------------------------------------------------------------ blanks
def test_apply_defaults_fills_blanks_and_never_overwrites():
values = {
'fc_psi': '6000', # already filled -- must survive
'design_spec': '',
'phi_shear': '0.8', # already filled, non-default value
}
applied = D.apply_defaults(values)
assert values['fc_psi'] == '6000'
assert values['phi_shear'] == '0.8'
applied_keys = dict((k, v) for k, v, _w in applied)
assert applied_keys.get('design_spec') == 'ACI 318-19'
assert values['design_spec'] == 'ACI 318-19'
# phi_shear was never blank, so it must not appear in what was applied.
assert 'phi_shear' not in applied_keys
def test_defaults_for_does_not_mutate_values():
values = {'fc_psi': ''}
before = dict(values)
D.defaults_for(values)
assert values == before
def test_apply_defaults_is_idempotent():
# Two fresh, independently-blank dicts get the same defaults...
values_a = {}
values_b = {}
first = D.apply_defaults(values_a)
second = D.apply_defaults(values_b)
assert sorted(first) == sorted(second)
# ...and a second pass over an already-filled dict finds nothing left
# to do among the keys the first pass just filled.
filled_keys = set(k for k, _v, _w in first)
third = D.apply_defaults(values_a)
assert not (set(k for k, _v, _w in third) & filled_keys)
# ------------------------------------------------------------ plant knowledge
def test_stage_multiplier_falls_back_to_1_4_with_no_plant_data():
values = {}
applied = dict((k, (v, w)) for k, v, w in D.apply_defaults(values, {}))
value, why = applied['stage.stripping.load_multiplier']
assert value == '1.4'
assert 'Eriksson' in why
def test_plant_stage_multiplier_wins_over_the_1_4_fallback():
know = {
'handling': {
'stages': [
{'name': 'stripping', 'multiplier': 1.6, 'strength': 'fci'},
],
},
}
values = {}
applied = dict((k, (v, w)) for k, v, w in D.apply_defaults(values, know))
value, why = applied['stage.stripping.load_multiplier']
assert value == '1.6'
assert 'plant knowledge' in why
assert values['stage.stripping.load_multiplier'] == '1.6'
def test_transportation_and_erection_fallback_multipliers():
values = {}
D.apply_defaults(values, {})
assert values['stage.transportation.load_multiplier'] == '1.5'
assert values['stage.primary_erection.load_multiplier'] == '1.4'
assert values['stage.primary_erection.max_tilt_deg'] == '90'
assert values['stage.stripping.max_tilt_deg'] == '0'
assert values['stage.transportation.max_tilt_deg'] == '0'
def test_secondary_erection_only_fills_include_no():
values = {}
D.apply_defaults(values, {})
assert values['stage.secondary_erection.include'] == 'No'
for opt in ('load_multiplier', 'lift_type', 'concrete_strength',
'stress_limits', 'rigging', 'sling_angle',
'ground_reaction', 'min_tilt_deg', 'max_tilt_deg',
'top_crane_carries'):
key = 'stage.secondary_erection.{0}'.format(opt)
assert key not in values or values.get(key) in (None, ''), key
def test_strength_mapping_fci_to_initial_and_fc_to_in_place():
know = {
'handling': {
'stages': [
{'name': 'stripping', 'multiplier': None, 'strength': 'fci'},
{'name': 'transportation', 'multiplier': None,
'strength': 'fc'},
],
},
}
values = {}
D.apply_defaults(values, know)
assert values['stage.stripping.concrete_strength'] == 'Initial'
assert values['stage.transportation.concrete_strength'] == 'In-Place'
# Primary Erection has no matching plant stage in this `know` -> fallback.
assert values['stage.primary_erection.concrete_strength'] == 'In-Place'
def test_sling_angle_from_plant_else_60():
values = {}
D.apply_defaults(values, {})
assert values['stage.stripping.sling_angle'] == '60'
values2 = {}
know = {'handling': {'sling_angle_deg': 45}}
D.apply_defaults(values2, know)
assert values2['stage.stripping.sling_angle'] == '45'
assert values2['stage.transportation.sling_angle'] == '45'
assert values2['stage.primary_erection.sling_angle'] == '45'
def test_rails_strand_datum_mapping():
for datum, expected in (('left_rail', 'Left edge'),
('right_rail', 'Right edge'),
('centerline', 'Centerline')):
values = {}
know = {'rails': {'strand_datum': datum}}
D.apply_defaults(values, know)
assert values['strand_rail_location'] == expected
# No plant value -> the Eriksson-sample fallback.
values = {}
D.apply_defaults(values, {})
assert values['strand_rail_location'] == 'Left edge'
# An unrecognised token degrades to the fallback rather than a raw
# unmapped string leaking into the form.
values = {}
D.apply_defaults(values, {'rails': {'strand_datum': 'mystery_rail'}})
assert values['strand_rail_location'] == 'Left edge'
def test_engineer_initials_only_filled_when_plant_names_one():
values = {}
applied = D.apply_defaults(values, {})
assert 'engineer_initials' not in dict((k, v) for k, v, _w in applied)
assert values.get('engineer_initials', '') == ''
values2 = {}
D.apply_defaults(values2, {'panelanalysis': {'engineer_initials': 'WS'}})
assert values2['engineer_initials'] == 'WS'
def test_stress_ignore_lateral_ecc_plant_override():
values = {}
D.apply_defaults(values, {})
assert values['design_criteria.stress_ignore_lateral_ecc'] == 'No'
values2 = {}
know = {'panelanalysis': {'settings':
{'stress_ignore_lateral_ecc': 'yes'}}}
D.apply_defaults(values2, know)
assert values2['design_criteria.stress_ignore_lateral_ecc'] == 'Yes'
def test_top_in_form_plant_override_and_fallback():
values = {}
D.apply_defaults(values, {})
assert values['top_in_form'] == 'Interior'
values2 = {}
D.apply_defaults(values2, {'panelanalysis': {'top_in_form': 'exterior'}})
assert values2['top_in_form'] == 'Exterior'
# ---------------------------------------------------------------- geometry
def test_wind_fields_are_no_longer_defaulted_2026_09_04():
"""ASCE site data (Vult, risk/exposure/enclosure, code version, C&C/
MWFRS chapter, mean roof height, effective wind area) moved out of this
form entirely, into project config -- this module no longer defaults
any of it (`panelanalysisform`'s module docstring, Wind section)."""
values = {'length_ft': '40', 'width_ft': '8', 'top_elevation_ft': '22.5'}
applied_keys = set(k for k, _v, _w in D.apply_defaults(values, {}))
for gone in ('wind_speed_vult', 'wind_risk_category', 'wind_exposure',
'wind_enclosure', 'wind_asce_version', 'wind_cc_chapter',
'wind_mwfrs_chapter', 'wind_mean_roof_height_ft',
'wind_effective_wind_area_ft2', 'wind_pressure_psf',
'wind_suction_psf'):
assert gone not in applied_keys, gone
assert gone not in values, gone
def test_temp_alpha_t_is_the_mantissa_the_field_asks_for():
"""The field's own label is 'alphaT x 10^-6' (pa_structural.py), and
nothing consumes this value yet -- so the default is the mantissa the
box expects (5.5), not the raw coefficient (0.0000055)."""
values = {}
applied = dict((k, (v, w)) for k, v, w in D.apply_defaults(values))
assert values['temp_alpha_t'] == '5.5'
value, why = applied['temp_alpha_t']
assert value == '5.5'
assert '10' in why and '/' in why # names the x10^-6 mantissa framing
assert D.why_of('temp_alpha_t') == why
def test_project_date_is_todays_iso_date():
import datetime
values = {}
D.apply_defaults(values)
assert values['project_date'] == datetime.date.today().isoformat()
# ---------------------------------------------------------- choice vocab
def test_every_default_with_choices_is_a_valid_choice():
"""Where the form declares a choice list for a key (FIELD_CHOICES,
pa_criteria._F's own choices column, a pa_structural.page() `choice`
field, or the Handling stage matrix's per-column choices), the value
this module picks must be a member of it.
"""
values = {'length_ft': '10', 'width_ft': '10',
'top_elevation_ft': '10'}
applied = D.apply_defaults(values, {
'handling': {'sling_angle_deg': 45,
'stages': [{'name': 'stripping', 'multiplier': 1.6,
'strength': 'fci'}]},
'rails': {'strand_datum': 'left_rail'},
'panelanalysis': {'engineer_initials': 'WS', 'top_in_form': 'Interior',
'settings': {'stress_ignore_lateral_ecc': 'no'}},
})
bad = []
for key, value_text, _why in applied:
choices = D.choices_for(key)
if choices is None:
continue
if value_text not in choices:
bad.append((key, value_text, choices))
assert bad == [], 'default not in the editor\'s own choice list: {0}'.format(bad)
def test_specific_choice_defaults():
values = {}
D.apply_defaults(values, {})
# restraints are an editable row table since 2026-09-04 -- no scalar
# foundation / floor-tie defaults any more
assert 'restraint_foundation_connection' not in values
assert values['left_miter'] == 'No'
assert values['right_miter'] == 'No'
assert values['second_order'] == 'Yes'
choices = D.choices_for('load_opt_offset_from')
assert choices is not None and values['load_opt_offset_from'] in choices
beta_choices = D.choices_for('design_criteria.analysis_beta_d')
assert beta_choices is not None and \
values['design_criteria.analysis_beta_d'] in beta_choices
# --------------------------------------------------------------------- why_of
def test_why_of_returns_a_sentence_for_every_filled_key():
values = {'length_ft': '10', 'width_ft': '10'}
applied = D.apply_defaults(values, {
'handling': {'sling_angle_deg': 45,
'stages': [{'name': 'erection', 'multiplier': 1.7,
'strength': 'fc'}]},
})
missing = []
for key, _value_text, _why in applied:
sentence = D.why_of(key)
if not sentence:
missing.append(key)
assert missing == [], 'why_of() has nothing for: {0}'.format(missing)
def test_why_of_unknown_key_is_none():
assert D.why_of('this_key_does_not_exist_anywhere') is None
# -------------------------------------------------------------- robustness
def test_robust_to_values_none():
assert D.defaults_for(None) == []
assert D.apply_defaults(None) == []
def test_robust_to_know_garbage():
values = {}
applied = D.apply_defaults(values, 'garbage')
# Should still fill the plant-independent defaults without raising.
assert values.get('design_spec') == 'ACI 318-19'
assert isinstance(applied, list) and applied
def test_robust_to_garbage_values_type():
assert D.defaults_for('garbage') == []
assert D.defaults_for(['a', 'list']) == []
assert D.apply_defaults(42) == []
def test_robust_to_malformed_plant_stage_shapes():
values = {}
know = {'handling': {'stages': 'not a list'}}
applied = D.apply_defaults(values, know)
assert values['stage.stripping.load_multiplier'] == '1.4'
values2 = {}
know2 = {'handling': {'stages': [{'name': 'stripping'},
'not a dict', 42, None]}}
applied2 = D.apply_defaults(values2, know2)
assert values2['stage.stripping.load_multiplier'] == '1.4'
assert isinstance(applied2, list)
def test_choices_for_unknown_key_is_none():
assert D.choices_for('this_key_does_not_exist_anywhere') is None
# ------------------------------------------------------------- never blank
def test_loading_keys_are_never_defaulted():
"""The owner's one hard exclusion: real loading stays blank for the
user, no matter what."""
values = {}
applied_keys = set(k for k, _v, _w in D.apply_defaults(values, {
'handling': {'sling_angle_deg': 60}}))
for key in ('wind_speed_vult', 'wind_pressure_psf', 'wind_suction_psf',
'seismic_cs', 'seismic_zone_location', 'ps_loss_pct',
'ext_soil_loads', 'int_soil_loads', 'conc_loads'):
assert key not in applied_keys, key
assert values.get(key, '') == ''