# -*- coding: utf-8 -*- """`pa_elevation` -- Top/Bottom Elevation and in-place Restraints, PURE. No Revit, no live model: `elevations_from_bbox` and `restraints_from_supports` are plain arithmetic over numbers a caller already measured. The live half (reading a framing element's own bounding box) is exercised only through a bridge dry-run, not here. """ from vibe import knowledge # noqa: F401 (registers the vibe stub) from vibe import pa_elevation as E # ------------------------------------------------------- elevations_from_bbox def test_bottom_is_the_smaller_z_regardless_of_argument_order(): top, bottom, height, basis = E.elevations_from_bbox(-2.0, 35.6667) assert bottom == -2.0 assert top == 35.6667 assert height == 37.6667 assert 'bounding box' in basis # swapped -- min/max is decided by VALUE, not by which argument carried # the larger one. top2, bottom2, height2, _basis2 = E.elevations_from_bbox(35.6667, -2.0) assert (top2, bottom2, height2) == (top, bottom, height) def test_missing_either_z_is_could_not_read_not_zero(): assert E.elevations_from_bbox(None, 10.0) == ( None, None, None, 'could not read a world-space bounding box on ' 'this piece') assert E.elevations_from_bbox(0.0, None)[0] is None def test_height_matching_length_says_nothing_extra(): _top, _bottom, _height, basis = E.elevations_from_bbox( 0.0, 20.0, length_ft=20.0) assert 'differs' not in basis def test_height_gap_beyond_tolerance_is_named_in_the_basis(): _top, _bottom, height, basis = E.elevations_from_bbox( 0.0, 20.0, length_ft=18.0) assert height == 20.0 assert 'differs' in basis assert 'may not be modelled fully upright' in basis def test_height_gap_within_tolerance_is_not_named(): _top, _bottom, _height, basis = E.elevations_from_bbox( 0.0, 20.05, length_ft=20.0) assert 'differs' not in basis # --------------------------------------------------- restraints_from_supports def test_converts_support_positions_to_elevations(): text, basis = E.restraints_from_supports('6.21, 15.21, 18.88', -2.0) assert text == '4.21, 13.21, 16.88' assert 'bottom_elevation_ft' in basis assert '-2.00' in basis def test_sorts_the_output_even_if_supports_ft_was_not_sorted(): text, _basis = E.restraints_from_supports('18.88, 6.21', 0.0) assert text == '6.21, 18.88' def test_blank_supports_ft_is_nothing_to_convert(): text, why = E.restraints_from_supports('', 5.0) assert text is None assert 'supports_ft' in why def test_none_bottom_elevation_is_nothing_to_convert(): text, why = E.restraints_from_supports('1.0, 2.0', None) assert text is None assert 'bottom_elevation_ft' in why def test_both_missing_names_both(): text, why = E.restraints_from_supports(None, None) assert text is None assert 'supports_ft' in why and 'bottom_elevation_ft' in why def test_non_numeric_token_refuses_the_whole_field(): text, why = E.restraints_from_supports('6.21, oops, 18.88', 0.0) assert text is None assert 'oops' in why def test_whitespace_separated_positions_also_parse(): text, _basis = E.restraints_from_supports('6.21 15.21', -1.0) assert text == '5.21, 14.21' def test_flat_piece_skips_the_conversion_rather_than_mixing_axes(): # A slab's bounding-box height is its THICKNESS (0.83 ft), nothing like # its length (23.96 ft) -- supports_ft is measured along the length, so # adding it to bottom_elevation_ft here would not be an elevation. text, why = E.restraints_from_supports( '0.25, 1.98, 11.98', 13.5, height_ft=0.8333, length_ft=23.9583) assert text is None assert 'does not appear to stand with its length vertical' in why def test_upright_piece_within_tolerance_still_converts(): text, _why = E.restraints_from_supports( '6.21, 15.21', -2.0, height_ft=37.6667, length_ft=37.5833) assert text == '4.21, 13.21'