%% tzaraat_test.pl — Tests for the Tzara'at diagnostic protocol. %% %% Phase 3, Step 19: Multi-stage input validation. :- use_module(library(plunit)). :- use_module('../src/diagnostic/tzaraat'). :- use_module('../src/diagnostic/diagnosis'). :- use_module('../src/diagnostic/inspection'). :- use_module('../src/diagnostic/quarantine'). %% ============================================================ %% DIAGNOSIS STATE TESTS %% ============================================================ :- begin_tests(diagnosis_states). %% All 8 states exist test(all_states_exist) :- findall(S, diagnosis_state(S), States), length(States, 8). %% Terminal states test(tamei_is_terminal) :- terminal_state(confirmed_tamei). test(tahor_is_terminal) :- terminal_state(declared_tahor). test(fully_visible_is_terminal) :- terminal_state(fully_visible_tahor). %% Initial state test(initial_state_is_inspection) :- initial_state(initial_inspection). %% Valid transitions test(initial_to_quarantine) :- valid_transition(initial_inspection, quarantine_1). test(initial_to_tamei) :- valid_transition(initial_inspection, confirmed_tamei). test(initial_to_tahor) :- valid_transition(initial_inspection, declared_tahor). test(initial_to_fully_visible) :- valid_transition(initial_inspection, fully_visible_tahor). test(quarantine_1_to_reinspection) :- valid_transition(quarantine_1, reinspection_1). test(quarantine_2_to_final_reinspection) :- valid_transition(quarantine_2, reinspection_2). %% Transition reasons exist test(transition_has_reason) :- transition_reason(initial_inspection, quarantine_1, Reason), Reason \= ''. :- end_tests(diagnosis_states). %% ============================================================ %% INSPECTION TESTS %% ============================================================ :- begin_tests(inspection_tests). %% Clean input → declared tahor test(clean_input_tahor) :- Input = input(declared, [visible, visible], within_bounds, []), inspect(Input, declared_tahor). %% Undeclared source → confirmed tamei (high severity) test(undeclared_source_tamei) :- Input = input(undeclared, [visible], within_bounds, []), inspect(Input, confirmed_tamei). %% Hidden dependency only → quarantine (moderate severity) test(hidden_dep_quarantine) :- Input = input(declared, [hidden], within_bounds, []), inspect(Input, quarantine_1). %% Scope creep → quarantine (moderate severity) test(scope_creep_quarantine) :- Input = input(declared, [visible], exceeds_bounds, []), inspect(Input, quarantine_1). %% The paradox: ALL signs present → fully visible tahor test(fully_visible_paradox) :- Input = input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), inspect(Input, fully_visible_tahor). %% Low severity only → declared tahor test(low_severity_tahor) :- Input = input(declared, [visible], within_bounds, [leaks_implementation]), inspect(Input, declared_tahor). %% Sign detection test(detect_undeclared_source) :- has_sign(input(undeclared, [], within_bounds, []), undeclared_source). test(detect_hidden_dependency) :- has_sign(input(declared, [hidden], within_bounds, []), hidden_dependency). test(detect_scope_creep) :- has_sign(input(declared, [], exceeds_bounds, []), scope_creep). test(detect_exposed_internals) :- has_sign(input(declared, [], within_bounds, [leaks_implementation]), exposed_internals). %% Sign count test(clean_has_zero_signs) :- count_signs(input(declared, [visible], within_bounds, []), 0). test(all_signs_count_four) :- count_signs(input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), 4). :- end_tests(inspection_tests). %% ============================================================ %% QUARANTINE TESTS %% ============================================================ :- begin_tests(quarantine_tests). %% Can quarantine an input test(quarantine_creates_record, [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- retractall(quarantine:quarantine_record(_, _, _, _)), Input = input(declared, [hidden], within_bounds, []), quarantine_input(test_q1, Input, quarantine_1), quarantine:quarantine_record(test_q1, quarantine_1, Signs, 1), member(hidden_dependency, Signs). %% Reinspection: signs cleared → tahor test(reinspect_cleared_tahor, [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- retractall(quarantine:quarantine_record(_, _, _, _)), Input1 = input(declared, [hidden], within_bounds, []), quarantine_input(test_r1, Input1, quarantine_1), %% After quarantine, input is clean Input2 = input(declared, [visible], within_bounds, []), reinspect(test_r1, Input2, declared_tahor). %% Reinspection: signs spread → tamei test(reinspect_spread_tamei, [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- retractall(quarantine:quarantine_record(_, _, _, _)), Input1 = input(declared, [hidden], within_bounds, []), quarantine_input(test_r2, Input1, quarantine_1), %% After quarantine, more problems appeared Input2 = input(declared, [hidden], exceeds_bounds, [leaks_implementation]), reinspect(test_r2, Input2, confirmed_tamei). :- end_tests(quarantine_tests). %% ============================================================ %% TZARA'AT MASTER MODULE TESTS %% ============================================================ :- begin_tests(tzaraat_master). %% Clean input diagnosed immediately test(diagnose_clean) :- Input = input(declared, [visible], within_bounds, []), diagnose(Input, declared_tahor). %% Impure input diagnosed immediately test(diagnose_impure) :- Input = input(undeclared, [visible], within_bounds, []), diagnose(Input, confirmed_tamei). %% Ambiguous input requires quarantine test(diagnose_ambiguous) :- Input = input(declared, [hidden], within_bounds, []), diagnose(Input, requires_quarantine(quarantine_1)). %% Full diagnostic flow: clean input test(full_flow_clean) :- Input = input(declared, [visible], within_bounds, []), full_diagnostic_flow(flow_clean, [Input], declared_tahor). %% Full diagnostic flow: immediate tamei test(full_flow_tamei) :- Input = input(undeclared, [visible], within_bounds, []), full_diagnostic_flow(flow_tamei, [Input], confirmed_tamei). %% Full diagnostic flow: fully visible paradox test(full_flow_paradox) :- Input = input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), full_diagnostic_flow(flow_paradox, [Input], fully_visible_tahor). %% Full diagnostic flow: quarantine then cleared test(full_flow_quarantine_cleared, [cleanup(retractall(quarantine_record(_, _, _, _)))]) :- Input1 = input(declared, [hidden], within_bounds, []), Input2 = input(declared, [visible], within_bounds, []), full_diagnostic_flow(flow_q_clear, [Input1, Input2], declared_tahor). :- end_tests(tzaraat_master).