WillTools 2026-09-09 -- clean snapshot of the development repo for review
ci / test (push) Successful in 6m18s
ci / test (push) Successful in 6m18s
History-free snapshot of the private development repository at cbe45c5 (2026-09-09). Code, docs and public catalogue only; no plant or job knowledge layers, no client or job names (tools/scrub.py clean). The intro deck is left out of this snapshot because its slide images could not be checked for job drawings.
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Host-side guard for issue #23's `live` kv contract.
|
||||
|
||||
The issue (owner, 2026-09-07: "啥叫JS活儿?html写不了?" -- the front end is
|
||||
ours, so write it): a kv row that sums a row table -- the Reinforcement
|
||||
page's Strand count, Total IP and Aps -- must follow the table's rows IN
|
||||
THE BROWSER as they are edited, not only on the next page build / Run.
|
||||
The page is plain ES2017 in a static file with no JS test runner, so this
|
||||
suite checks the CONTRACT by reading the source, the same way
|
||||
`test_button_tooltips.py` reads `bundle.yaml` / `script.py`: the three
|
||||
pieces that wire the feature together must all exist and stay connected --
|
||||
`renderKv` records the spec into `state.liveKv`, `recomputeLiveKv` rewrites
|
||||
the value cells, and `updateValue` (plus the row add/remove handlers) calls
|
||||
it whenever a key of the table changes. And the spec document must still
|
||||
describe the row shape (docs/pa-web-spec.md, "kv").
|
||||
"""
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
|
||||
_EXT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
_REPO = os.path.dirname(_EXT)
|
||||
|
||||
APP_JS = os.path.join(_REPO, 'tools', 'pa_web', 'static', 'app.js')
|
||||
SPEC_MD = os.path.join(_REPO, 'docs', 'pa-web-spec.md')
|
||||
|
||||
|
||||
def _read(path):
|
||||
with io.open(path, encoding='utf-8') as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def test_the_files_this_guards_still_exist():
|
||||
"""If the page moves, this suite must fail loudly rather than pass by
|
||||
reading nothing -- the test_button_tooltips.py discipline."""
|
||||
assert os.path.isfile(APP_JS), 'missing {0}'.format(APP_JS)
|
||||
assert os.path.isfile(SPEC_MD), 'missing {0}'.format(SPEC_MD)
|
||||
|
||||
|
||||
def test_app_js_declares_the_live_kv_mechanism():
|
||||
src = _read(APP_JS)
|
||||
# renderKv records rows into state.liveKv, keyed by the spec's table...
|
||||
assert 'state.liveKv' in src
|
||||
assert 'function recomputeLiveKv' in src
|
||||
# ...the value formatting helper exists, and row discovery is the SAME
|
||||
# helper the editable table itself uses (one idea of "present row").
|
||||
assert 'function fmtLive' in src
|
||||
assert 'rowIds(live.table)' in src
|
||||
|
||||
|
||||
def test_update_value_recomputes_live_kv_rows():
|
||||
"""`updateValue` -- every cell edit's one funnel -- must call
|
||||
`recomputeLiveKv`, not just `recomputeDerived`. Sliced to updateValue's
|
||||
own body so a stray later call elsewhere cannot satisfy the guard."""
|
||||
src = _read(APP_JS)
|
||||
start = src.index('function updateValue')
|
||||
end = src.find('\n\n // ---', start)
|
||||
assert end != -1, 'could not find the end of updateValue\'s body'
|
||||
body = src[start:end]
|
||||
assert 'recomputeLiveKv(' in body, \
|
||||
'updateValue no longer calls recomputeLiveKv after recomputeDerived'
|
||||
|
||||
|
||||
def test_spec_documents_live_under_kv():
|
||||
md = _read(SPEC_MD)
|
||||
start = md.index('### `kv`')
|
||||
nxt = md.find('\n### ', start + 1)
|
||||
assert nxt != -1, 'no section follows kv in pa-web-spec.md'
|
||||
section = md[start:nxt]
|
||||
assert re.search(r'\[label, value, live\]', section)
|
||||
assert '"live"' in section
|
||||
assert '"terms"' in section and '"format"' in section
|
||||
assert '"unknown"' in section
|
||||
# the contract names the trigger: any key of the table, add/remove row
|
||||
# included, and JS-off correctness (server value is the first paint).
|
||||
assert '.present' in section
|
||||
assert 'JS off' in section
|
||||
Reference in New Issue
Block a user