Skip to content
Skills Library
Programming · Testing

testing-hashql

/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.

Repository
hash ↗
Licence
MIT
Last repository change
24.10.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
5
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 24.10.2026, without references to retired models or APIs.

Licence

MIT, open: use and modify while retaining author attribution.

What it does and when to use it

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.

Original author description

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.

How it works

  1. Quick Reference
  2. compiletest (UI Tests)
  3. Unit Tests
  4. insta Snapshot Tests
  5. MIR Builder Tests
  6. References
Original SKILL.md headings · 209 lines, 810 words
SKILL.md preview
---
name: testing-hashql
description: 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.
license: AGPL-3.0
---

# 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:**

```text
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:**

```bash
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:**

```jsonc
//@ 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: skip`
- `description: ...` (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](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`:

```rust
#[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:**

```bash
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.

```rust
// 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.

```rust
// 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

```bash
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 `Changed` enum (`Yes`, `No`, `Unknown`) to indicate modifications
- Test harness captures and includes `Changed` value in snapshots for verification
- Snapshot format: before MIR → `Changed: Yes/No/Unknown` separator → 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)

```rust
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/mir-builder-guide.md)

## References

- [compiletest Guide](references/compiletest-guide.md) - Detailed UI test documentation
- [Testing Strategies](references/testing-strategies.md) - Choosing the right approach
- [MIR Builder Guide](references/mir-builder-guide.md) - `body!` macro for MIR construction in tests
- [MIR Fluent Builder](references/mir-fluent-builder.md) - Programmatic builder API (for advanced cases)
Files in this package (5)
  • SKILL.md 7 KB
  • references/compiletest-guide.md 11 KB
  • references/mir-builder-guide.md 16 KB
  • references/mir-fluent-builder.md 5 KB
  • references/testing-strategies.md 10 KB

Versions

The database has no other skills named testing-hashql.

Database snapshot: 13.11.2026 · package version cbaa3f6bb28f (SHA-256 digest of the entire package)

Downloads in the last 30 days: 0 · ranking

Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.

Similar skills

  • 100writing-hashql-diagnostics
    HashQL diagnostic writing patterns using hashql-diagnostics crate. Use when creating error messages, warnings, Labels, Messages, Severity levels, Patches, Suggestions, or improving diagnostic quality in HashQL code.
  • 100writing-hashql-jexpr
    HashQL J-Expr syntax for writing queries. Use when writing J-Expr code, using #literal/#struct/#list constructs, understanding function call syntax, or working with HashQL query files (.jsonc).
  • 100unit-testing
    Write and review unit tests for Gather V2. Use when writing tests, reviewing test code, debugging test failures, or asking about testing patterns.
  • 100mobiai-ios-testing
    Use when writing or running tests in an iOS project — unit tests, UI tests, snapshot tests, choosing the right framework.
  • 100testing
    Write and run tests for Frappe apps including unit tests, integration tests, and UI tests. Use when adding test coverage, debugging test failures, or setting up CI for Frappe projects.
  • 90mobile-testing
    Use this skill when the user asks about mobile testing strategies, unit tests, widget tests, component tests, integration tests, E2E, golden/snapshot tests, mocking, or CI test integration.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.