hedl-test
Shared test fixtures and utilities for HEDL -comprehensive test data, builders, and error cases for consistent testing across all crates.
Testing format converters requires representative documents. Building test cases by hand is tedious and error-prone. Common test scenarios should be reusable across crates. Edge cases need systematic coverage. Error conditions must be validated consistently.
hedl-test provides 15 pre-built fixtures covering all HEDL features, 4 builder types for programmatic document construction, comprehensive error fixtures (15 invalid HEDL, 15 invalid expressions, 8 semantic violations), and edge case generators (deep nesting, wide documents, long strings, many references).
What's Implemented
Comprehensive test infrastructure:
- 15 Pre-Built Fixtures: Scalars, special strings, references, expressions, tensors, named values, user list, mixed type list, with references, with nest, deep nest, edge cases, comprehensive, blog, empty
- 4 Builder Types: DocumentBuilder, MatrixListBuilder, NodeBuilder, ValueBuilder
- Error Fixtures: 15 invalid HEDL samples, 15 invalid expressions, 8 semantically invalid documents
- Edge Case Generators: deeply_nested_document, wide_document, long_string_document, many_references_document
- Counting Utilities: count_nodes, count_references
- Expression Helpers: expr, try_expr, expr_value, try_expr_value with ExprError type
Installation
[]
= { = true }
Or specify version directly:
[]
= "2.0"
Pre-Built Fixtures
Basic Fixtures
use fixtures;
// Scalar types (all primitives)
let doc = scalars;
// Contains: int, float, bool, null, string examples
// Special strings (escapes, Unicode, etc.)
let doc = special_strings;
// Contains: quotes, escapes, newlines, Unicode
// References (qualified and local)
let doc = references;
// Contains: local references (@id) and typed references (@Type:id)
// Tensors (matrix literals)
let doc = tensors;
// Contains: 1D, 2D, 3D tensors and empty tensor
Complex Fixtures
use fixtures;
// User list (simple matrix)
let doc = user_list;
// 3 users: alice, bob, charlie with id, name, email
// Mixed type list
let doc = mixed_type_list;
// Items with int, float, bool, null, and string fields
// With references
let doc = with_references;
// Users and Posts with author references
// With NEST hierarchy
let doc = with_nest;
// Users with nested posts (parent-child via NEST)
// Deep NEST hierarchy
let doc = deep_nest;
// Organization → Department → Employee (3 levels)
// Blog (nested structure)
let doc = blog;
// Complex blog platform: users, categories, tags, posts, comments, reactions, post_tags, followers
Comprehensive Fixture
All HEDL features in one document:
use fixtures;
let doc = comprehensive;
// Contains:
// - Scalar values (bool, string, int, float)
// - Expressions (function calls, identifiers, literals)
// - Tensors
// - Users list with nested posts (via NEST)
// - Comments and Tags lists
// - References between entities
// - Multiple STRUCT definitions
// - NEST directive
Builder Types
DocumentBuilder
Programmatically construct documents:
use DocumentBuilder;
use Value;
let doc = new
.version
.struct_def
.alias
.nest
.scalar
.scalar
.build;
Methods:
version(major, minor)- Set document versionstruct_def(name, fields)- Add struct definitionalias(alias, target)- Add aliasnest(parent, child)- Add NEST relationshipscalar(name, value)- Add scalar value to rootlist(name, list)- Add MatrixList to rootitem(name, item)- Add Item to rootbuild()- Build the Document
MatrixListBuilder
Build typed entity lists:
use MatrixListBuilder;
use ;
let list = new
.schema
.row
.row
.build;
Methods:
schema(fields)- Set schema (all field names)field(field)- Add single field to schemarow(node)- Add a row (node)rows(nodes)- Add multiple rowscount_hint(count)- Set count hintbuild()- Build the MatrixList
NodeBuilder
Build individual entities:
use NodeBuilder;
use Value;
let node = new
.field
.field
.field
.build;
Methods:
field(value)- Add a field valuefields(values)- Add multiple field valueschildren(rel_name, nodes)- Add child nodes under a relationshipchild(rel_name, node)- Add single child nodechild_count(count)- Set child count hintbuild()- Build the Node
ValueBuilder
Static helper methods for creating values:
use ValueBuilder;
// Scalar values
let v = null;
let v = bool_val;
let v = int;
let v = float;
let v = string;
// References
let v = reference; // Qualified reference
let v = local_ref; // Local reference
// Tensors
let v = tensor_1d;
let v = tensor_2d;
Methods:
null()- Create null valuebool_val(value)- Create boolean valueint(value)- Create integer valuefloat(value)- Create float valuestring(value)- Create string valuereference(type_name, id)- Create qualified referencelocal_ref(id)- Create local referencetensor_1d(values)- Create 1D tensortensor_2d(rows)- Create 2D tensor
Error Fixtures
Invalid HEDL Syntax
use errors;
// Get all invalid HEDL samples as (name, hedl_text) pairs
let samples = invalid_hedl_samples;
for in samples
Available samples (15 total):
empty- Empty documentwhitespace_only- Only whitespaceinvalid_directive- Invalid directive namemissing_separator- Missing --- separatorinvalid_version- Invalid version numbermalformed_struct- Malformed STRUCT directiveunclosed_string- Unclosed string literalinvalid_escape- Invalid escape sequencemalformed_reference- Malformed referenceinvalid_tensor- Malformed tensor syntaxmismatched_brackets- Mismatched bracketsinvalid_number- Invalid number formatmalformed_expression- Malformed expressioninvalid_identifier- Invalid identifierduplicate_directive- Duplicate directive
Invalid Expressions
use errors;
// Get all invalid expression samples as (description, expr_string) pairs
let samples = invalid_expression_samples;
for in samples
Available samples (15 total):
empty- Empty expressionwhitespace_only- Only whitespaceunclosed_paren- Unclosed parenthesisunclosed_string- Unclosed string literalinvalid_chars- Invalid charactersdouble_dot- Double dot in pathtrailing_dot- Trailing dotleading_dot- Leading dotmismatched_parens- Mismatched parenthesesempty_call- Empty function callinvalid_identifier- Invalid identifierspecial_chars_only- Only special charactersnested_unclosed- Nested unclosed parenthesescomma_without_args- Comma without argumentstrailing_comma- Trailing comma
Semantic Errors
Valid syntax but semantic violations:
use errors;
// Get all semantically invalid documents as (name, document) pairs
let docs = semantically_invalid_docs;
for in docs
Available documents (8 total):
undefined_struct- MatrixList references undefined structundefined_nest- NEST directive references non-existent child typecircular_nest- Circular NEST references (TypeA → TypeB → TypeA)dangling_reference- Reference points to non-existent nodemismatched_schema- MatrixList schema doesn't match struct definitionempty_type_name- MatrixList has empty type nameduplicate_ids- Multiple nodes with same ID in a listinvalid_alias- Alias references non-existent item
Edge Case Generators
Deeply Nested Document
Test parser depth limits:
use errors;
let doc = deeply_nested_document;
// Creates 1000 levels of nested children via NEST
Use Case: Verify recursion depth limits and stack safety
Wide Document
Test handling of many entities:
use errors;
let doc = wide_document;
// Creates a MatrixList with 1000 rows
Use Case: Verify large list handling and memory efficiency
Long Strings
Test string length limits:
use errors;
let doc = long_string_document;
// Creates a document with a 1 MB string value
Use Case: Verify string buffer limits and allocation safety
Many References
Test reference resolution performance:
use errors;
let doc = many_references_document;
// Creates 10K target nodes and 10K references
Use Case: Verify reference resolution performance and correctness
Test Utilities
Counting Utilities
use ;
// Count total nodes (entities) in document
let count = count_nodes;
// Count total references in document
let ref_count = count_references;
Available functions:
count_nodes(&doc)- Count all nodes in the document (including nested children)count_references(&doc)- Count all reference values in the document
Expression Utilities
use ;
// Create Expression from string (panics on error)
let e = expr;
let e = expr;
let e = expr;
// Create Expression safely (returns Result)
let result = try_expr;
match result
// Create Value::Expression from string
let v = expr_value; // Panics on error
let v = try_expr_value?; // Returns Result
Available functions:
expr(s)- Parse expression string, panic on errortry_expr(s)- Parse expression string, return Resultexpr_value(s)- Create Value::Expression, panic on errortry_expr_value(s)- Create Value::Expression, return Result
Error type:
ExprError::EmptyInput- Expression string is emptyExprError::ParseFailed { source, input }- Parse failed with lexical errorExprError::Missing- Expression is missing or null
Quick Builder Helpers
The fixtures::builders::quick module provides convenient helper functions for common patterns:
use quick;
// Create document with simple scalar fields
let doc = simple_scalars;
// Create document with simple user list
let doc = simple_user_list;
// Create document with references
let doc = with_references;
Usage Patterns
Testing Parsers
use fixtures;
Testing Format Converters
use fixtures;
Testing Error Handling
use errors;
Testing Edge Cases
use errors;
use count_nodes;
What This Crate Doesn't Do
Property-Based Testing: Fixtures are hand-crafted examples. For property-based testing, use proptest or quickcheck with custom generators.
Performance Testing: Fixtures designed for correctness testing. For performance, use hedl-bench with realistic workloads.
Fuzz Testing: No fuzzing infrastructure. For fuzz testing, use cargo-fuzz with custom fuzz targets.
Test Data Generation: Fixtures are static. For dynamic test data, write custom generators using builders.
Dependencies
hedl-core- Core HEDL types and parsinghedl-c14n- Canonicalization for HEDL documentssmallvec- Optimized small vector implementation
License
Apache-2.0