McRogueFace/tests/regression
John McCardle a46667df6f test(snippets): the docs site's 130 code samples are now part of the test suite
The samples published on mcrogueface.github.io were executed by nothing at all.
Each carried a machine-readable header -- objects=[...] verified=0.2.8@b6720f6
status=ok -- and every one of those fields was hand-typed. 130 snippets asserted
"status=ok" while no run had ever confirmed it. This is the same failure mode as
the 82 rotted tests in 112f357, at a larger scale and with no gate whatsoever.

The samples now live here, in the engine repo, so that breaking the API breaks the
build. The site pulls them from tests/snippets/ rather than keeping a copy to rot
in parallel (build_library.py, site-side).

They are display scripts: each builds a scene and stops. They deliberately do NOT
call sys.exit(), because they must stay copy-pasteable -- a reader who pastes one
into their game should get a running scene, not an interpreter that quits. Since
#350 that also makes them un-runnable on their own, so _harness.py is chained as a
second --exec to supply the ending the snippet must not have. Chaining rather than
exec()-ing the source is deliberate: the snippet travels the same path a real
user's script travels, and nothing has to read the file -- which is how the first
draft of this harness tripped over #378 and mistook three healthy snippets for
broken ones.

A snippet passes only if it runs clean AND leaves a scene with something in it.
Not raising is not enough: a sample whose body silently no-ops still renders as
code on the docs site, and would still be wrong.

tools/stamp_snippets.py makes the header a measurement instead of a claim: status
comes from an actual run, verified from the engine that ran it, and objects is
derived from the source intersected with what the engine exports -- so a snippet
that starts using a new type gets tagged for it without anyone remembering to. It
immediately found tags the humans had missed (062 uses Transition, Key and
InputState; the hand-written header listed none of them). --check is the CI gate.

The gate earned its keep on the first run, catching #379 (fixed here): configuring
default_transition before the first scene activation made the engine transition
FROM the internal "uitest" bootstrap scene, which is not a PyScene and has no
Python wrapper -- so mcrfpy.current_scene reported None for the transition's full
duration, immediately after the user had assigned it. A transition with nothing
meaningful to transition from now changes scene immediately. Scene-to-scene
transitions still report the outgoing scene until they complete.

Suite: 468/468 (336 + 130 snippets + 2 regressions).

closes #379
2026-07-14 18:29:37 -04:00
..
frame_children_mutation_test.py Add regression tests for Frame.children mutation and parent=None removal 2026-04-01 11:27:47 -04:00
grid_backward_compat_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_9_rendertexture_resize_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_37_simple_test.py update tests: new scene API 2026-01-03 10:59:52 -05:00
issue_76_test.py Test suite modernization 2026-02-09 08:15:18 -05:00
issue_79_color_properties_test.py Test suite modernization 2026-02-09 08:15:18 -05:00
issue_99_texture_font_properties_test.py Test suite modernization 2026-02-09 08:15:18 -05:00
issue_123_chunk_system_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_146_fov_returns_none.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_147_grid_layers.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_148_layer_dirty_flags.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_176_entity_position_test.py Phase 2: Entity data model extensions for behavior system 2026-03-15 22:05:06 -04:00
issue_177_gridpoint_grid_pos_test.py Test suite modernization 2026-02-09 08:15:18 -05:00
issue_179_181_grid_vectors_test.py Remove redundant Grid.position alias, keep only Grid.pos, closes #308 2026-04-09 22:18:30 -04:00
issue_180_timer_orphan_test.py Organize test suite: add README, move loose tests to proper directories 2026-01-21 21:34:22 -05:00
issue_180_timer_stopped_test.py Organize test suite: add README, move loose tests to proper directories 2026-01-21 21:34:22 -05:00
issue_182_caption_size_test.py Organize test suite: add README, move loose tests to proper directories 2026-01-21 21:34:22 -05:00
issue_183_parent_quirks_test.py tests for the last few issues (these test scripts should work with recent APIs, while the rest of the test suite needs an overhaul) 2026-01-08 10:31:21 -05:00
issue_184_189_module_test.py Organize test suite: add README, move loose tests to proper directories 2026-01-21 21:34:22 -05:00
issue_185_188_bounds_test.py Organize test suite: add README, move loose tests to proper directories 2026-01-21 21:34:22 -05:00
issue_190_layer_docs_test.py Test suite modernization 2026-02-09 08:15:18 -05:00
issue_212_to_217_test.py Add input validation and fix Entity repr 2026-01-16 19:18:27 -05:00
issue_223_clip_children_test.py Fix UIFrame RenderTexture positioning and toggling issues 2026-01-22 22:54:50 -05:00
issue_251_callback_gc_test.py Fix callback/timer GC: prevent premature destruction of Python callbacks 2026-02-19 20:53:50 -05:00
issue_251_timer_gc_test.py Fix callback/timer GC: prevent premature destruction of Python callbacks 2026-02-19 20:53:50 -05:00
issue_253_spatial_hash_test.py Phase 1: Safety & performance foundation for Grid/Entity overhaul 2026-03-15 21:48:24 -04:00
issue_254_tilelayer_texture_test.py Phase 1: Safety & performance foundation for Grid/Entity overhaul 2026-03-15 21:48:24 -04:00
issue_256_animation_spatial_hash_test.py Update spatial hash in animation setProperty for entity position, closes #256 2026-04-10 01:40:29 -04:00
issue_258_gridstate_resize_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_264_gridpoint_dangle_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_266_entity_lifecycle_test.py Remove entity self-reference cycle 2026-03-07 23:22:58 -05:00
issue_266_subclass_identity_test.py Preserve Python subclass identity for entities in grids (reopens #266) 2026-03-09 00:24:26 -04:00
issue_267_275_refcount_test.py Add regression tests for GridPointState dangle and refcount leaks, refs #287 2026-04-10 02:06:10 -04:00
issue_268_vector_null_test.py Add regression tests for vector NULL safety and uniform owner validity, closes #287 2026-04-10 02:57:32 -04:00
issue_270_277_parent_grid_dangle_test.py Null parent_grid pointers in GridData destructor, closes #270, closes #271, closes #277 2026-04-10 01:34:33 -04:00
issue_272_uniform_owner_test.py Add regression tests for vector NULL safety and uniform owner validity, closes #287 2026-04-10 02:57:32 -04:00
issue_273_die_during_iteration_test.py Add regression test for entity.die() during iteration, refs #273 2026-04-10 01:45:23 -04:00
issue_274_set_grid_spatial_hash_test.py Add missing spatial_hash.insert() in set_grid() grid transfer, closes #274 2026-04-10 01:45:18 -04:00
issue_288_291_dirty_flags_test.py Add missing markDirty()/markCompositeDirty() to all Python property setters 2026-04-10 01:01:41 -04:00
issue_292_fov_dedup_test.py Phase 1: Safety & performance foundation for Grid/Entity overhaul 2026-03-15 21:48:24 -04:00
issue_294_perspective_map_test.py Replace UIEntity gridstate with DiscreteMap perspective_map; closes #294 2026-04-17 23:04:27 -04:00
issue_295_cell_pos_test.py Phase 2: Entity data model extensions for behavior system 2026-03-15 22:05:06 -04:00
issue_307_color_eq_test.py Fix audit type count (44->46) and add regression test for Color __eq__, refs #307 2026-04-09 21:45:12 -04:00
issue_309_caption_numeric_setter_test.py Clamp Caption numeric setters to prevent UBSan float->uint UB 2026-04-16 23:31:58 -04:00
issue_310_compute_fov_enum_test.py Route Grid.compute_fov algorithm through PyFOV::from_arg 2026-04-16 23:32:09 -04:00
issue_311_dijkstra_bounds_test.py Bounds-check DijkstraMap coordinates at the Python boundary 2026-04-16 23:32:19 -04:00
issue_313_entity_grid_data_test.py refactor(grid): GridData is a map, not a widget -- delete UIGrid's drawable half 2026-07-13 07:14:43 -04:00
issue_315_path_provider_test.py Refactor EntityBehavior SEEK/FLEE to use PathProvider strategy; refs #315 2026-04-18 09:19:05 -04:00
issue_316_sparse_perspective_test.py Windowed perspective writeback in UIEntity::updateVisibility; closes #316 2026-06-21 09:40:05 -04:00
issue_317_scroll_position_test.py Fix verify-pass code bugs #317/#318/#319 2026-06-21 10:12:41 -04:00
issue_318_gridview_texture_test.py Fix verify-pass code bugs #317/#318/#319 2026-06-21 10:12:41 -04:00
issue_319_visible_entities_radius_none_test.py Fix verify-pass code bugs #317/#318/#319 2026-06-21 10:12:41 -04:00
issue_320_caption_positional_font_test.py Add read-only Caption.font getter; addresses #320 2026-06-21 12:18:53 -04:00
issue_322_terrain_enum_bad_utf8_test.py Check Python C-API returns in terrain_enum builders; closes #322 2026-06-26 23:52:38 -04:00
issue_323_pitch_shift_nonfinite_test.py Reject non-finite floats before int casts; closes #323, closes #324, closes #325 2026-06-26 23:53:02 -04:00
issue_324_hsl_shift_nonfinite_test.py Reject non-finite floats before int casts; closes #323, closes #324, closes #325 2026-06-26 23:53:02 -04:00
issue_325_vector_int_nonfinite_test.py Reject non-finite floats before int casts; closes #323, closes #324, closes #325 2026-06-26 23:53:02 -04:00
issue_329_entity_index_perf_test.py Add tests pinning EntityCollection semantics and O(1) indexing (#329) 2026-07-02 20:13:18 -04:00
issue_332_soa_storage_test.py refactor(grid): GridData SoA -- dense uint8 planes for walkable/transparent; closes #332 2026-07-11 01:43:30 -04:00
issue_334_discretemap_buffer_test.py feat(discretemap): buffer protocol for zero-copy numpy views; closes #334 2026-07-11 01:00:53 -04:00
issue_335_layer_edit_test.py feat(grid): numpy buffer views for ColorLayer/TileLayer via layer.edit(); closes #335 2026-07-11 02:04:42 -04:00
issue_338_drawable_footprint_test.py perf(grid): lazily allocate rotationTexture; footprint measurement; addresses #338 2026-07-11 01:31:18 -04:00
issue_341_metrics_counters_test.py fix(metrics): report counters Python can actually observe 2026-07-14 06:37:33 -04:00
issue_342_animation_float_fastpath_test.py perf(animation): scalar-float fast path skipping variant visits; closes #342 2026-07-10 22:59:28 -04:00
issue_344_key_enum_cache_test.py perf(input): cache Key/InputState enum members per event; closes #344 2026-07-10 22:59:47 -04:00
issue_348_gridview_wrapper_identity_test.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
issue_350_step_frame_parity_test.py fix(engine): headless step() is a full simulation frame; --exec can no longer hang 2026-07-14 06:37:52 -04:00
issue_351_gridview_early_out_test.py perf(grid): clean-state render early-out for UIGridView; closes #351 2026-07-11 00:55:32 -04:00
issue_351_step_movement_render_test.py fix(grid): turn manager invalidates view render cache on entity move; addresses #351 2026-07-11 10:15:36 -04:00
issue_355_camera_rotation_hit_test.py fix(grid): revive Grid input — move cell callbacks and hit-testing to GridView; N-view registry 2026-07-12 18:01:40 -04:00
issue_355_grid_cell_dispatch_test.py fix(grid): revive Grid input — move cell callbacks and hit-testing to GridView; N-view registry 2026-07-12 18:01:40 -04:00
issue_355_grid_input_test.py fix(grid): revive Grid input — move cell callbacks and hit-testing to GridView; N-view registry 2026-07-12 18:01:40 -04:00
issue_355_gridview_position_sync_test.py fix(grid): revive Grid input — move cell callbacks and hit-testing to GridView; N-view registry 2026-07-12 18:01:40 -04:00
issue_355_perspective_overlay_test.py fix(grid): revive Grid input — move cell callbacks and hit-testing to GridView; N-view registry 2026-07-12 18:01:40 -04:00
issue_356_module_attrs_discoverable_test.py fix(bindings): make dynamic module attributes dir()-discoverable 2026-07-13 23:47:04 -04:00
issue_357_find_in_grid_test.py fix(grid): find()/findAll() descend into grids again 2026-07-12 18:02:04 -04:00
issue_359_shared_griddata_test.py refactor(grid): GridData is a map, not a widget -- delete UIGrid's drawable half 2026-07-13 07:14:43 -04:00
issue_361_griddata_is_not_a_widget_test.py refactor(grid): GridData is a map, not a widget -- delete UIGrid's drawable half 2026-07-13 07:14:43 -04:00
issue_363_hover_exit_on_window_leave_test.py fix(input): dispatch hover-exit when the cursor leaves the window 2026-07-12 21:12:58 -04:00
issue_364_grid_children_on_view_test.py fix(bindings): route every drawable wrapper through PythonObjectCache 2026-07-13 23:37:01 -04:00
issue_365_stale_clicked_cell_test.py fix(grid): never dispatch a stale cell from UIGridView::click_at 2026-07-12 20:26:59 -04:00
issue_366_collection_repr_grid_test.py fix(grid): UICollection.repr names Grids again instead of "UIDrawable" 2026-07-12 20:26:32 -04:00
issue_367_hover_exit_on_focus_loss_test.py fix(render): content invalidation propagates again; clear hover on focus loss 2026-07-13 07:40:20 -04:00
issue_368_cache_subtree_content_dirty_test.py fix(render): content invalidation propagates again; clear hover on focus loss 2026-07-13 07:40:20 -04:00
issue_369_parent_identity_test.py fix(bindings): route every drawable wrapper through PythonObjectCache 2026-07-13 23:37:01 -04:00
issue_373_subclass_identity_survives_gc_test.py fix(bindings): pin a subclassed drawable's wrapper while a collection owns it 2026-07-14 07:53:42 -04:00
issue_377_collection_parent_link_test.py fix(ui): maintain the parent link in every collection mutator 2026-07-14 07:53:21 -04:00
issue_378_utf8_source_test.py fix(engine): UTF-8 filesystem encoding, --run-forever in --help, honest step() docs 2026-07-14 18:21:19 -04:00
issue_379_first_scene_transition_test.py test(snippets): the docs site's 130 code samples are now part of the test suite 2026-07-14 18:29:37 -04:00
issue_callback_refcount_test.py Simplify on_enter/on_exit callbacks to position-only signature 2026-01-28 17:36:02 -05:00
parent_none_removal_test.py Add regression tests for Frame.children mutation and parent=None removal 2026-04-01 11:27:47 -04:00
recursive_animation_callback_segfault.py test(suite): unrot 82 tests that were passing without ever running 2026-07-14 07:29:23 -04:00
subclass_callback_segfault_test.py Remove legacy string enum comparisons from InputState/Key/MouseButton, closes #306 2026-04-09 22:19:02 -04:00
test_type_preservation_solution.py Test suite modernization 2026-02-09 08:15:18 -05:00