MLF Language Tests (mlf-lang crate)#
This directory contains crate-specific integration tests for the mlf-lang crate only. These tests verify parsing, validation, and workspace resolution using real MLF files.
For workspace-level integration tests that span multiple crates (codegen, CLI, etc.), see /tests/README.md at the workspace root.
Test Structure#
tests/
├── integration_test.rs # Test runner that discovers and executes tests
└── lang/ # Language-level tests
├── namespace_imports/ # Import statement behavior
├── namespace_exports/ # Export and main resolution
└── constraints/ # Type constraint validation
Writing Tests#
Each test is a directory containing:
- One or more
.mlffiles - The MLF code to test expected.json- Expected test outcome
Expected Result Format#
{
"status": "success" // or "error"
}
For error tests:
{
"status": "error",
"errors": [
{
"type": "UndefinedReference", // Error variant name
"name": "foo" // Optional: specific error details
}
]
}
Test Categories#
Namespace Imports#
Tests various import syntaxes:
- namespace_alias -
use com.example;creates aliasexample→com.example - namespace_alias_nested - Multi-level namespace aliasing
- implicit_main_import -
use place.stream.profile;importsprofiletype - undefined_namespace - Error when importing non-existent namespace
Namespace Exports#
Tests how types are exported from modules:
- implicit_main - Type matching namespace suffix becomes main export
Constraints#
Tests constraint validation and refinement:
- refinement_valid - Valid constraint narrowing (maxLength: 100 → 50)
- refinement_invalid - Invalid constraint widening (maxLength: 50 → 100)
- type_mismatch - Wrong constraint types (string constraints on integers)
- enum_refinement - Enum subset validation
Running Tests#
# Run all integration tests
cargo test -p mlf-lang --test integration_test
# Run with output
cargo test -p mlf-lang --test integration_test -- --nocapture
# Run specific test (not directly supported, but you can filter by removing tests)
Test Output#
The test runner outputs:
- ✓ for passing tests
- ✗ for failing tests with error details
- Summary:
X passed, Y failed
Example:
✓ namespace_imports/namespace_alias
✓ namespace_imports/namespace_alias_nested
✓ constraints/refinement_valid
✗ constraints/bad_test: Test expected success but got errors: ...
Results: 8 passed, 1 failed
Scope: mlf-lang Only#
These tests use only the mlf-lang crate (parsing, validation, workspace resolution). They do not test:
- Code generation (mlf-codegen, mlf-codegen-*)
- CLI commands (mlf-cli)
- Error formatting (mlf-diagnostics)
- Multi-crate workflows
For those, see workspace-level tests in /tests/ at the project root.
Future Lang-Specific Tests#
More tests to add here (still mlf-lang only):
- raw_identifiers - Keyword escaping and edge cases
- lenient_parsing - Error recovery and multiple errors
- esoteric - Edge cases like circular references, empty unions
- annotations - @main, @key, @encoding parsing
- unions - Open vs closed unions
- circular_references - A refs B refs A
Adding New Tests#
-
Create a new directory under the appropriate category:
mkdir -p tests/lang/your_category/your_test -
Add MLF files:
echo 'record foo { bar!: string; }' > tests/lang/your_category/your_test/test.mlf -
Add expected result:
echo '{"status": "success"}' > tests/lang/your_category/your_test/expected.json -
Update
derive_namespace_from_path()inintegration_test.rsif needed -
Run tests:
cargo test -p mlf-lang --test integration_test
Namespace Derivation#
The test runner automatically derives namespaces from file paths:
test.mlf→ Uses test directory namedefs.mlfinnamespace_alias/→com.example.defsactor_defs.mlfinnamespace_alias_nested/→app.bsky.actor.defs
Update derive_namespace_from_path() for custom namespace logic.
Notes#
- Tests run against
Workspace::with_std()so prelude types are available - Multiple
.mlffiles in a test directory are loaded in sorted order (test.mlf last) - Error tests check for error type presence, not exact messages
- Warnings don't cause test failures