Files
2026-09-30 13:58:39 +08:00

57 lines
2.9 KiB
Python

"""Synthetic interface and fail-closed schedule checks, no scientific records."""
import ast
from pathlib import Path
import unittest
import numpy as np
from run_audit import compare_results
from summarize import metrics, primary_rows
class IntegrationTests(unittest.TestCase):
def test_per_neuron_count_difference_not_cancelled_by_equal_total(self):
a = dict(step=np.array([0, 1], np.int32), neuron_idx=np.array([1, 1], np.int32),
counts=np.array([2, 0], np.int32), first_spike=np.array([0, -1], np.int32),
v=np.array([-.052, -.052], np.float64), g=np.zeros(2, np.float64))
b = {k: v.copy() for k, v in a.items()}
b['neuron_idx'][:] = 2; b['counts'][:] = [0, 2]; b['first_spike'][:] = [-1, 0]
h = dict(history_v=np.zeros((2, 2)), history_g=np.zeros((2, 2)))
result = compare_results(a, b, h, h)
self.assertEqual(result['spike_count_L1'], 4)
self.assertEqual(result['neurons_with_count_change'], 2)
self.assertTrue(result['functional_count_or_first_latency_change'])
def test_event_difference_with_same_counts_and_first_is_retained(self):
a = dict(step=np.array([0, 3], np.int32), neuron_idx=np.array([1, 1], np.int32),
counts=np.array([2], np.int32), first_spike=np.array([0], np.int32),
v=np.zeros(1), g=np.zeros(1))
b = {k: v.copy() for k, v in a.items()}; b['step'][1] = 4
h = dict(history_v=np.zeros((5, 1)), history_g=np.zeros((5, 1)))
result = compare_results(a, b, h, h)
self.assertTrue(result['event_sequence_changed'])
self.assertFalse(result['functional_count_or_first_latency_change'])
def test_undefined_denominator_is_not_silently_zero(self):
self.assertIsNone(metrics([])['mean'])
def test_repeat_not_an_independent_primary_trial(self):
rows = [dict(name=str(i), repeat=0) for i in range(120)] + [dict(name=str(i), repeat=1) for i in range(24)]
self.assertEqual(len(primary_rows(dict(planned=rows))), 120)
rows[1]['name'] = '0'
with self.assertRaises(AssertionError):
primary_rows(dict(planned=rows))
def test_all_baseline_gate_precedes_conditional_schedule(self):
tree = ast.parse((Path(__file__).parent / 'run_audit.py').read_text())
main = next(n for n in tree.body if isinstance(n, ast.FunctionDef) and n.name == 'main')
loops = [n for n in ast.walk(main) if isinstance(n, ast.For) and isinstance(n.target, ast.Name) and n.target.id == 'stage']
self.assertEqual(len(loops), 1)
self.assertEqual(ast.literal_eval(loops[0].iter), ('baseline', 'conditional25'))
audit = next(n for n in tree.body if isinstance(n, ast.FunctionDef) and n.name == 'audit_trial')
source = ast.unparse(audit)
self.assertIn("baselines-complete.json", source)
self.assertLess(source.index("baselines-complete.json"), source.index('core.replay'))
if __name__ == '__main__':
unittest.main()