Files
willtools-demo/WillTools.extension/tests/test_pyrevit_yaml_fake.py
T
will 52d94303bc
ci / test (push) Has been cancelled
WillTools: precast shop-ticket QC and panel handling tools
Public demo snapshot of an in-house pyRevit extension for precast concrete
shop-ticket QC (37 checks / 46 checklist rows) and a standalone panel
handling solver (PCI Chapter 8).

- No client, job, plant or product data: knowledge layers ship as
  structural templates only.
- Ticket QC's model-read escalation targets a LAN model server endpoint
  (configurable), not a cloud provider.
- Built from the private development repo via tools/make_dist.py.
2026-09-03 16:33:47 -05:00

108 lines
4.5 KiB
Python

# -*- coding: utf-8 -*-
"""Tests for the double itself -- because a kind double is a blindfold.
`pyrevit_yaml_fake` stands in for pyRevit's YAML reader, and every guard in
this repository that reads YAML is tested through it. Twice now the double
has been KINDER than the thing it doubles and the suite was green while the
button was broken:
* it TYPED its scalars while YamlDotNet returns every one as a string --
the master checklist reached the button with the word 'null' in 37 of 39
reason slots, on the owner's screen;
* it took the LAST of two duplicate keys while YamlDotNet raises
`Duplicate key` and returns nothing -- one nested duplicate discarded a
whole 255KB plant layer inside Revit on 2026-09-01, and nothing on the
host could reproduce it.
Both properties are the double's PRODUCT, so they are tested here rather than
assumed by the files that use it.
"""
import os
import sys
import pytest
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
pytest.importorskip('yaml')
from pyrevit_yaml_fake import ( # noqa: E402
DuplicateKeyError, raise_on_duplicate_keys, stringify_like_yamldotnet,
strings_only_yaml_reader)
def _write(tmp_path, text):
path = tmp_path / 'layer.yaml'
path.write_text(text, encoding='utf-8')
return str(path)
# ------------------------------------------------------------- duplicate keys
def test_a_duplicate_key_at_the_top_level_raises(tmp_path):
path = _write(tmp_path, u'a: 1\nb: 2\na: 3\n')
with pytest.raises(DuplicateKeyError) as caught:
strings_only_yaml_reader()(path)
assert 'Duplicate key' in str(caught.value)
def test_a_duplicate_key_NESTED_raises_too(tmp_path):
"""The shape the incident actually had. A top-level-only check would have
read that file happily and thrown the layer away in production."""
path = _write(tmp_path, u'checks:\n'
u' rules:\n'
u' cap_label_mismatch_is_view_specific: true\n'
u' other: 1\n'
u' cap_label_mismatch_is_view_specific: false\n')
with pytest.raises(DuplicateKeyError) as caught:
strings_only_yaml_reader()(path)
said = str(caught.value)
assert 'cap_label_mismatch_is_view_specific' in said
assert 'line 5' in said # the SECOND statement: the one to delete
def test_a_duplicate_inside_a_list_item_raises(tmp_path):
path = _write(tmp_path, u'items:\n - name: a\n size: 1\n name: b\n')
with pytest.raises(DuplicateKeyError):
strings_only_yaml_reader()(path)
def test_the_same_key_in_two_different_mappings_is_fine(tmp_path):
"""Not a duplicate. A checker that called this one would be unusable --
every knowledge file names `note:` under a dozen different parents."""
path = _write(tmp_path, u'a:\n note: x\nb:\n note: y\n')
assert strings_only_yaml_reader()(path) == {'a': {'note': 'x'},
'b': {'note': 'y'}}
def test_a_clean_file_still_reads_and_still_comes_back_as_strings(tmp_path):
path = _write(tmp_path, u'n: 1.5\nflag: true\nempty: null\n')
assert strings_only_yaml_reader()(path) == {'n': '1.5', 'flag': 'true',
'empty': 'null'}
def test_a_document_pyyaml_cannot_parse_is_not_judged_for_duplicates():
"""Stated out loud rather than left to be discovered: this detector has
exactly one question, and it answers `no duplicate found` for a document
it could not read at all. `tools/knowledgelint.py` is the check that does
refuse those, and it is the one the landing agents run."""
raise_on_duplicate_keys(u'a:\n - [1, 2\n') # does not raise
def test_the_message_leads_with_the_words_pyrevit_uses():
"""The string in the message is what a person sees in Self Check and in
`config_problems()`, and what they will search for."""
with pytest.raises(DuplicateKeyError) as caught:
raise_on_duplicate_keys(u'a: 1\na: 2\n', path='C:/plant/k.yaml')
said = str(caught.value)
assert said.startswith('Duplicate key')
assert 'C:/plant/k.yaml' in said
# ---------------------------------------------------------------- the strings
def test_every_scalar_comes_back_as_text():
"""The other way this double was once kinder than production."""
assert stringify_like_yamldotnet(
{'a': 1.5, 'b': True, 'c': None, 'd': [1, {'e': False}]}) == \
{'a': '1.5', 'b': 'true', 'c': 'null', 'd': ['1', {'e': 'false'}]}