testing-hashql
HashQL testing strategies including compiletest (UI tests), unit tests, and snapshot tests. Use when writing tests for HashQL code, using //~ annotations, running --bless, debugging test failures, or choosing the right testing approach.
Install
mkdir -p .claude/skills/testing-hashql && curl -L -o skill.zip "https://mcp.directory/api/skills/download/4090" && unzip -o skill.zip -d .claude/skills/testing-hashql && rm skill.zipInstalls to .claude/skills/testing-hashql
About this skill
HashQL Testing Strategies
HashQL uses three testing approaches. compiletest is the default for testing compiler behavior.
Quick Reference
| Scenario | Test Type | Location |
|---|---|---|
| Diagnostics/error messages | compiletest | tests/ui/ |
| Compiler pipeline phases | compiletest | tests/ui/ |
| MIR/HIR/AST pass integration | compiletest | tests/ui/ |
| MIR/HIR/AST pass edge cases | insta | tests/ui/<category>/ |
| MIR pass unit tests | MIR builder | src/**/tests.rs |
| Core crate (where needed) | insta | src/**/snapshots/ |
| Parser fragments (syntax-jexpr) | insta | src/*/snapshots/ |
| Internal functions/logic | Unit tests | src/*.rs |
compiletest (UI Tests)
Test parsing, type checking, and error reporting using J-Expr files with diagnostic annotations.
Structure:
package/tests/ui/
category/
.spec.toml # Suite specification (required)
test.jsonc # Test input
test.stdout # Expected output (run: pass)
test.stderr # Expected errors (run: fail)
test.aux.svg # Auxiliary output (some suites)
Commands:
cargo run -p hashql-compiletest run # Run all
cargo run -p hashql-compiletest run --filter "test(name)" # Filter
cargo run -p hashql-compiletest run --bless # Update expected
Test file example:
//@ run: fail
//@ description: Tests duplicate field detection
["type", "Bad", {"#struct": {"x": "Int", "x": "String"}}, "_"]
//~^ ERROR Field `x` first defined here
Directives (//@ at file start):
run: pass/run: fail(default) /run: skipdescription: ...(encouraged)name: custom_name
Annotations (//~ for expected diagnostics):
//~ ERROR msg- current line//~^ ERROR msg- previous line//~v ERROR msg- next line//~| ERROR msg- same as previous annotation
📖 Full Guide: references/compiletest-guide.md
Unit Tests
Standard Rust #[test] functions for testing internal logic.
Location: #[cfg(test)] modules in source files
Example from hashql-syntax-jexpr/src/parser/state.rs:
#[test]
fn peek_returns_token_without_consuming() {
bind_context!(let context = "42");
bind_state!(let mut state from context);
let token = state.peek().expect("should not fail").expect("should have token");
assert_eq!(token.kind, number("42"));
}
Commands:
cargo nextest run --package hashql-<package>
cargo test --package hashql-<package> --doc # Doc tests
insta Snapshot Tests
Use insta crate for snapshot-based output when compiletest (the preferred method) is infeasible. Three categories exist:
| Category | Crates | Snapshot Location | Rationale |
|---|---|---|---|
| Pipeline Crates | mir, hir, ast | tests/ui/<category>/*.snap | Colocate with compiletest tests |
| Core | hashql-core | Default insta (src/**/snapshots/) | Separate from pipeline; prefer unit tests |
| Syntax | syntax-jexpr | src/*/snapshots/ | Macro-based for parser fragments |
Pipeline Crates (mir, hir, ast)
Snapshots colocate with compiletest UI tests. Test code lives in src/**/tests.rs, snapshots go in the appropriate tests/ui/<category>/ directory.
// Example: hashql-mir/src/pass/transform/ssa_repair/tests.rs
let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut settings = Settings::clone_current();
settings.set_snapshot_path(dir.join("tests/ui/pass/ssa_repair")); // matches test category
settings.set_prepend_module_to_snapshot(false);
let _drop = settings.bind_to_scope();
assert_snapshot!(name, value);
Categories vary: reify/, lower/, pass/ssa_repair/, etc.
Core
hashql-core is separate from the compilation pipeline, so it uses default insta directories. Prefer unit tests; only use snapshots where necessary.
Syntax (syntax-jexpr)
Syntax crates predate compiletest and use macro-based test harnesses for testing parser fragments directly.
// hashql-syntax-jexpr/src/parser/string/test.rs
pub(crate) macro test_cases($parser:ident; $($name:ident($source:expr) => $description:expr,)*) {
$(
#[test]
fn $name() {
assert_parse!($parser, $source, $description);
}
)*
}
Snapshots: hashql-syntax-jexpr/src/parser/*/snapshots/*.snap
Commands
cargo insta test --package hashql-<package>
cargo insta review # Interactive review
cargo insta accept # Accept all pending
MIR Builder Tests
For testing MIR transformation and analysis passes directly with programmatically constructed MIR bodies.
Location: hashql-mir/src/pass/**/tests.rs
When to use:
- Testing MIR passes in isolation with precise CFG control
- Edge cases requiring specific MIR structures hard to produce from source
- Benchmarking pass performance
Key features:
- Transform passes return
Changedenum (Yes,No,Unknown) to indicate modifications - Test harness captures and includes
Changedvalue in snapshots for verification - Snapshot format: before MIR →
Changed: Yes/No/Unknownseparator → after MIR
Important: Missing Macro Features
The body! macro does not support all MIR constructs. If you need a feature that is not supported, do not work around it manually - instead, stop and request that the feature be added to the macro.
Quick Example (using body! macro)
use hashql_core::{heap::Heap, r#type::environment::Environment};
use hashql_mir::{builder::body, intern::Interner};
let heap = Heap::new();
let interner = Interner::new(&heap);
let env = Environment::new(&heap);
let body = body!(interner, env; fn@0/1 -> Int {
decl x: Int, cond: Bool;
bb0() {
cond = load true;
if cond then bb1() else bb2();
},
bb1() {
goto bb3(1);
},
bb2() {
goto bb3(2);
},
bb3(x) {
return x;
}
});
📖 Full Guide: references/mir-builder-guide.md
References
- compiletest Guide - Detailed UI test documentation
- Testing Strategies - Choosing the right approach
- MIR Builder Guide -
body!macro for MIR construction in tests - MIR Fluent Builder - Programmatic builder API (for advanced cases)
More by hashintel
View all skills by hashintel →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversUse Backlinks (Ahrefs) for detailed SEO analysis. Check website backlinks, anchor text, domain rating & more with this b
Unlock AI-powered automation for Postman for API testing. Streamline workflows, code sync, and team collaboration with f
Android Mobile MCP: control Android devices via ADB for Android automation — UI actions, screen capture, gestures, text
Bruno: API testing via Bruno CLI — execute requests, manage collections & environments, and generate automated test repo
Playwright automation for AI agents: 50+ functions for browser automation, form filling, Chrome DevTools, and web scrapi
API Tester MCP Server — secure API testing and API sandbox for AI that lets Claude make HTTP requests and act as an Open
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.