UnifyWeaver

UnifyWeaver Testing Guide

This document lists all tests that should be run when making changes to the UnifyWeaver codebase. As features are added, this list will grow to cover new test scenarios.

Quick Test Suite

Run these tests after any significant change:

cd /path/to/UnifyWeaver

# 1. Core constraint system
swipl -q -g "use_module('src/unifyweaver/core/constraint_analyzer'), test_constraint_analyzer, halt."

# 2. Stream compiler (non-recursive predicates)
swipl -q -g "use_module('src/unifyweaver/core/stream_compiler'), test_stream_compiler, halt."

# 3. Recursive compiler (transitive closure, tail recursion)
swipl -q -g "use_module('src/unifyweaver/core/recursive_compiler'), test_recursive_compiler, halt."

# 4. Advanced recursion (linear, mutual, tail with accumulators)
swipl -q -g "use_module('src/unifyweaver/core/advanced/test_advanced'), test_all_advanced, halt."

# 5. Constraint integration tests
swipl -q -g "use_module('src/unifyweaver/core/test_constraints'), test_constraints, halt."

# 6. Generate and run inferred test runner (validates generated bash scripts)
swipl -g "use_module('src/unifyweaver/core/advanced/test_runner_inference'), \
         generate_test_runner_inferred('output/advanced/inferred_test_runner.sh'), halt."
bash output/advanced/inferred_test_runner.sh

Test Categories

1. Constraint System Tests

Module: src/unifyweaver/core/constraint_analyzer.pl

What it tests:

Run:

swipl -q -g "use_module('src/unifyweaver/core/constraint_analyzer'), test_constraint_analyzer, halt."

Expected output: All 6 tests pass with ✓ marks


2. Stream Compiler Tests

Module: src/unifyweaver/core/stream_compiler.pl

What it tests:

Run:

swipl -q -g "use_module('src/unifyweaver/core/stream_compiler'), test_stream_compiler, halt."

Expected output:

Verify generated code:

bash output/test.sh  # Run the generated test script

3. Recursive Compiler Tests

Module: src/unifyweaver/core/recursive_compiler.pl

What it tests:

Run:

swipl -q -g "use_module('src/unifyweaver/core/recursive_compiler'), test_recursive_compiler, halt."

Expected output:

Verify generated code:

bash output/test_recursive.sh  # Run the generated test script

4. Advanced Recursion Tests

Module: src/unifyweaver/core/advanced/test_advanced.pl

What it tests:

4.1 Call Graph Analysis

4.2 SCC Detection (Tarjan’s Algorithm)

4.3 Pattern Matching

4.4 Tail Recursion Compilation

4.5 Linear Recursion Compilation

4.6 Mutual Recursion Compilation

Run:

swipl -q -g "use_module('src/unifyweaver/core/advanced/test_advanced'), test_all_advanced, halt."

Expected output:

Total: 24/24 tests passing (100%)

Verify generated code:

ls -lh output/advanced/
head -30 output/advanced/list_length.sh
bash output/advanced/test_runner.sh  # Run all generated scripts

4.7 Automatic Test Runner Generation

Module: src/unifyweaver/core/advanced/test_runner_inference.pl

What it does: Automatically generates comprehensive test runners by analyzing compiled bash scripts - no manual configuration required!

Features:

How to use:

# Generate inferred test runner
swipl -g "use_module('src/unifyweaver/core/advanced/test_runner_inference'), \
         generate_test_runner_inferred('output/advanced/inferred_test_runner.sh'), \
         halt."

# Run the generated test runner
bash output/advanced/inferred_test_runner.sh

Generated Output Modes:

  1. Explicit Mode (default)
    • One test case per line
    • Easy to read and debug
    • Clear error messages with line numbers
  2. Concise Mode
    • Compact test definitions
    • Loops for multiple test cases
    • Smaller file size
  3. Hybrid Mode
    • Mix of explicit and concise styles
    • Balances readability and size

Example Generated Test:

# Test count_items.sh (multi-function: 2 functions)
if [[ -f count_items.sh ]]; then
    echo "--- Testing count_items.sh ---"
    source count_items.sh

    # Function: count_items_eval
    echo "Test 1: Generic test"
    count_items_eval

    # Function: count_items
    echo "Test 1: Empty list with accumulator 0"
    count_items "[]" "0" ""

    echo "Test 2: List with elements"
    count_items "[a,b,c]" "0" ""
fi

What gets tested:

What gets skipped:

Implementation Details:

Three-phase implementation:

Phase 1: Classification & Deduplication (Commit 0fbf0a0)

% Classify scripts by type
classify_script_type(Content, Type) :-
    % Returns: function_library, demo, test_wrapper, or standalone

% Skip duplicates
is_test_wrapper_duplicate(FileName) :-
    atom_concat('test_', _BaseName, FileName).

Phase 2: Multi-Function Extraction (Commit ebac072)

% Extract ALL functions from a script
extract_all_functions(Content, Functions) :-
    re_foldl(collect_function, "^(\w+)\(\)\s*\{", Content, [], Functions, [...]).

% Get arity for each function
extract_function_arity(Content, FuncName, Arity) :-
    % Count "local var=\"$N\"" patterns in function body

Phase 3: File Grouping (Commit c1c5e64)

% Group test configs by source file
group_configs_by_file(Configs, GroupedConfigs) :-
    % Source each file only once, test all its functions

% Write tests for multi-function files
write_file_tests(Stream, FilePath, FunctionConfigs) :-
    format(Stream, '# Test ~w (multi-function: ~w functions)~n', [...])

Advantages over manual configuration:

When to use:

Troubleshooting:


5. Constraint Integration Tests

Module: src/unifyweaver/core/test_constraints.pl

What it tests:

Run:

swipl -q -g "use_module('src/unifyweaver/core/test_constraints'), test_constraints, halt."

Expected output: All 4 integration tests pass with ✓ marks

Constraint Support in Advanced Compilers:


6. Constraint Demo (Visual Verification)

Module: examples/constraints_demo.pl

What it demonstrates:

Run:

swipl -q -g "['examples/constraints_demo.pl'], demo, halt."

Verify generated files:

ls -lh output/demo_*.sh
head -20 output/demo_default.sh   # Should show: sort -u
head -20 output/demo_ordered.sh   # Should show: declare -A seen
head -20 output/demo_no_dedup.sh  # Should show: no deduplication

Testing Checklist

After making changes, verify:

Test Organization

Unit Tests

Individual module functionality:

Integration Tests

Cross-module functionality:

Regression Tests

Ensure no breaking changes:


Adding New Tests

When adding a new feature, update this document with:

  1. New test module - Add to appropriate category
  2. Run command - Show how to execute the test
  3. Expected output - Describe what success looks like
  4. Verification steps - How to verify generated code
  5. Known issues - Document any expected failures

Example Template

### X. New Feature Tests

**Module:** `src/unifyweaver/core/new_feature.pl`

**What it tests:**
- Feature aspect 1
- Feature aspect 2

**Run:**
```bash
swipl -q -g "use_module('src/unifyweaver/core/new_feature'), test_new_feature, halt."

Expected output: Description of success

Verify:

# Commands to verify functionality

---


## Test Environment (test_env)

UnifyWeaver provides test environment setup scripts that create standalone test directories with auto-discovery:

### Setup

**Bash/Linux:**
```bash
cd scripts/testing
./init_testing.sh           # Creates test_env/ in scripts/testing/
./init_testing.sh -d /tmp   # Creates /tmp/test_env/

PowerShell/Windows:

cd scripts\testing
.\Init-TestEnvironment.ps1  # Creates test_env/ in scripts\testing\

Test Environment Features

Hybrid Test Discovery:

Available Commands:

% Core loaders
?- load_stream.         # Load stream compiler
?- load_recursive.      # Load recursive compiler
?- load_all_core.       # Load all core modules

% Manual tests (reliable fallback)
?- test_stream.         # Test stream compiler
?- test_recursive.      # Test recursive compiler
?- test_advanced.       # Test advanced recursion (24 tests)
?- test_constraints.    # Test constraint system

% Auto-discovered tests (if available)
?- test_auto.           # Run all auto-discovered tests

% Run everything
?- test_all.            # Run ALL tests (manual + auto)

% Help
?- help.                # Show all available commands

test_all Command

The test_all command runs all tests in sequence:

?- test_all.

╔════════════════════════════════════════╗
  Running All UnifyWeaver Tests        
╚════════════════════════════════════════╝

═══ Manual Tests (Core) ═══

┌─ Stream Compiler ────────────────────┐
=== STREAM COMPILER TESTS ===
... tests run ...
└─ Stream Compiler Complete ──────────┘

┌─ Recursive Compiler ─────────────────┐
... tests run ...
└─ Recursive Compiler Complete ───────┘

┌─ Advanced Recursion ─────────────────┐
... 24 tests run ...
└─ Advanced Recursion Complete ───────┘

┌─ Constraint System ──────────────────┐
... tests run ...
└─ Constraint System Complete ────────┘

═══ Auto-Discovered Tests ═══
(runs any additional test modules found)

╔════════════════════════════════════════╗
  All Tests Complete                    
╚════════════════════════════════════════╝

Adding New Tests

No configuration needed! Just create your test file:

  1. Create src/unifyweaver/core/test_myfeature.pl
  2. Export test_myfeature/0 predicate
  3. Regenerate test environment or copy to existing one
  4. New test is automatically discovered

Example:

:- module(test_myfeature, [test_myfeature/0]).

test_myfeature :-
    writeln('=== MY FEATURE TESTS ==='),
    % ... your tests ...
    writeln('=== TESTS COMPLETE ===').

Then in test environment:

?- help.
% Shows: test_myfeature.  - Test myfeature module

?- test_myfeature.
% Runs your tests

?- test_all.
% Includes your tests automatically

Continuous Integration Notes

For CI/CD integration, all tests can be run in sequence:

#!/bin/bash
# run_all_tests.sh

set -e  # Exit on first failure

echo "Running UnifyWeaver test suite..."

# Core tests
echo "1. Constraint analyzer..."
swipl -q -g "use_module('src/unifyweaver/core/constraint_analyzer'), test_constraint_analyzer, halt."

echo "2. Stream compiler..."
swipl -q -g "use_module('src/unifyweaver/core/stream_compiler'), test_stream_compiler, halt."

echo "3. Recursive compiler..."
swipl -q -g "use_module('src/unifyweaver/core/recursive_compiler'), test_recursive_compiler, halt."

echo "4. Advanced recursion..."
swipl -q -g "use_module('src/unifyweaver/core/advanced/test_advanced'), test_all_advanced, halt."

echo "5. Constraint integration..."
swipl -q -g "use_module('src/unifyweaver/core/test_constraints'), test_constraints, halt."

echo ""
echo "✓ All tests passed!"

Test Coverage Goals


5. C# Query Runtime Tests

See the dedicated plan at docs/development/testing/v0_1_csharp_test_plan.md for full details.

5.1 Automated regression (skip dotnet execution)

SKIP_CSHARP_EXECUTION=1 \
swipl -q \
     -f tests/core/test_csharp_query_target.pl \
     -g test_csharp_query_target:test_csharp_query_target \
     -t halt

5.2 Optional full-suite check

SKIP_CSHARP_EXECUTION=1 swipl -q -f run_all_tests.pl -g main -t halt

5.3 Manual runtime validation (optional)

Follow the “Manual Runtime Validation” section in the plan to:

  1. Generate a C# project under output/csharp/<uuid>/.
  2. Run dotnet build --no-restore.
  3. Execute the compiled binary or DLL (dotnet bin/Debug/net9.0/<module>.dll or the self-contained executable) and verify outputs (alice,charlie, 0, 2, 4).

Troubleshooting Tests

Common Issues

Module not found:

ERROR: source_sink `...` does not exist

Solution: Ensure you’re running from the UnifyWeaver root directory

Test predicates not exported:

ERROR: Unknown procedure: test_foo/0

Solution: Check module declaration exports the test predicate

Output directory missing:

ERROR: existence_error(directory,output)

Solution: Create directory: mkdir -p output/advanced

Bash script errors:

bash: output/test.sh: No such file or directory

Solution: Run the Prolog test first to generate the files


Future Test Additions

As features are added, tests should be created for:


Last updated: 2025-10-06