MEP 9. Fixture Catalogue
| Field | Value |
|---|---|
| MEP | 9 |
| Title | Fixture Catalogue |
| Author | Mochi core |
| Status | Informational |
| Type | Informational |
| Created | 2026-05-08 |
Abstract
This MEP is the live inventory of parser and type fixtures, plus a coverage matrix that maps each soundness property in MEP 7 to the fixtures that exercise it. New fixtures are added to the inventory in the same commit that introduces the file.
Motivation
Without an index, the same property is often covered three times under three different names while another property goes uncovered. The matrix makes the gaps visible.
Specification
Inventory at v0.10.82
Source counts taken at the snapshot date. Numbers are pairs of .mochi plus matching golden or err.
| Directory | Pairs |
|---|---|
| tests/parser/valid | 52 |
| tests/parser/errors | 10 |
| tests/types/valid | 31+17 (added in v0.11.0) |
| tests/types/errors | 45+4 (added in v0.11.0) |
| tests/queryplan | small |
| tests/interpreter | many |
| tests/vm | many |
tests/compiler/{rb,dart,ts} | 37+ |
| tests/mochi_in_mochi/parser | small |
The VM and interpreter directories are end-to-end suites and are not the focus of this initiative. The parser and type fixtures are.
Existing parser/valid fixtures
Sorted by name:
agent_call, agent_decl, agent_full, agent_on_event, assign_stmt,
call_expr, cast_expr, collection_literals, cross_join,
cross_join_triple, dataset, dataset_sort_take_limit, expect_stmt,
for_loop, fun_def, fun_expr, fun_expr_type_params, fun_type_params,
generate_expr, generic_type, group_by, group_expr, if_expr_then_else,
if_expr_then_else_nested, if_stmt, in_operator, index_expr, join,
left_join, let_stmt, list_assign, load_expr, load_save_stdinout,
load_with_expr, map_assign, match_expr, model_decl, negative,
nested_type_decl, on_stmt, outer_join, package_export, right_join,
save_expr, stream_decl, test_block, type_struct_equals, unary_expr,
update_stmt, user_type_literal, var_stmt, while_loop
Existing types/valid fixtures
break_continue, cast_expr, closure, doom_move, fetch_extra_options,
fetch_options, fun_return_type, generate_options, generate_struct,
join_basic, join_multi, left_join, let_basic, list_assign,
list_concat, load_with, map_assign, map_hint_literal, match_expr,
model_decl, nested_type_decl, outer_join, shadow_scope,
stream_on_emit, string_in_operator, string_index, union_alias,
update_stmt, user_type_selector, user_types_basic, var_mutable
Added in v0.11.0:
aggregate_count_list, aggregate_min_max_int, aggregate_sum_int_list,
canonical_bool_only, canonical_int_arithmetic, canonical_string_concat,
closure_inferred_return, for_in_list, for_in_range,
inversion_if_expr, match_literal_pattern, match_union_variant,
numeric_float_plus_int, numeric_int_plus_float,
preservation_let_chain, query_basic_select, query_sort_take,
struct_field_access
Existing types/errors fixtures
arg_type_mismatch, assign_to_let, assign_type_mismatch,
assign_undeclared_var, avg_non_numeric, binary_operator_type_error,
cannot_iterate, comparison_type_error, count_invalid_type,
emit_field_type, emit_unknown_stream, expect_non_boolean,
fetch_option_type, fetch_opts_map, fetch_url_type, fun_return_mismatch,
fun_wrong_return, generate_type_mismatch, index_not_int,
invalid_len_operand, invalid_range_bounds, join_on_not_bool,
join_source_not_list, json_missing_arg, len_missing_arg,
let_missing_type_or_value, map_assign_immutable, map_key_type_mismatch,
map_slice, match_pattern_mismatch, match_result_mismatch, missing_index,
not_callable, not_indexable, not_struct_selector, now_too_many_args,
on_unknown_stream, query_source_not_list, too_many_args,
undeclared_var, undefined_function, unknown_generate_type,
user_type_field_mismatch, user_unknown_field, wrong_type_assign
Added in v0.11.0:
match_variant_arity, multiple_top_level_errors, range_bound_float,
struct_unknown_field_access
Coverage matrix
The matrix is a property-to-fixture mapping. A cell value of existing means at least one fixture in the corresponding directory exercises the property. missing means we need to author one.
| Property (from MEP 7) | Valid | Error |
|---|---|---|
| Progress, primitives | existing | existing |
| Progress, list and map | existing | existing |
| Progress, function call | existing | existing |
| Preservation under let binding | existing | missing |
| Canonical forms, bool | existing | existing |
| Canonical forms, int and int64 | existing | existing |
| Canonical forms, float | partial | partial |
| Canonical forms, bigint, bigrat | missing | missing |
| Canonical forms, string | existing | existing |
| Canonical forms, void | missing | missing |
| Canonical forms, struct | existing | existing |
| Canonical forms, union variant | existing | existing |
| Inversion, every Primary shape | partial | partial |
| Substitution, let bindings | existing | missing |
| Variance, function arg and result | missing | missing |
| Variance, list element read | missing | missing |
| Variance, list element write | missing | missing |
| Variance, map key | missing | missing |
| Variance, map value | missing | missing |
| Parametricity, len | missing | missing |
| Parametricity, first | missing | missing |
| Parametricity, push, append, concat | missing | missing |
| Parametricity, range | missing | missing |
| Exhaustiveness, union | missing | missing |
| Irredundancy, union | missing | missing |
| Alpha equivalence (property) | missing | n/a |
| Numeric tower, int + float order | existing | n/a |
| Numeric tower, bigint + bigrat | missing | n/a |
| Numeric tower, int / int | missing | n/a |
| Mutability, let immutable | existing | existing |
| Mutability, var mutable | existing | n/a |
| Mutability, let xs[i] = ... | missing | missing |
| Mutability, let s.f = ... | missing | missing |
| Subtyping, record width | missing | missing |
| Subtyping, AnyType silently accepts | missing | n/a |
| Cast, int as string | missing | n/a |
| Cast, union as variant | missing | missing |
| Null assignable as any | missing | n/a |
| Closures capture | existing | missing |
| Recursive types | missing | missing |
| Generic function declared | existing | missing |
| Generic function instantiation | missing | missing |
| Query result type | existing | partial |
| Query aggregate types | existing | partial |
| Multiple top level errors accumulated | n/a | existing |
| Pure flag (future enforcement) | n/a | n/a |
partial means at least one fixture exists but the property is not fully covered.
New fixtures to author for v0.11.0
Grouped by MEP.
From MEP 4 (type system):
type_void_not_assignable(error, T009 family).type_struct_nominal_inequality(error, two anon structs).type_bigint_string(valid).type_bigrat_string(valid).
From MEP 5 (inference):
numeric_int_div_int(valid, asserts int / int : int).numeric_bigint_minus_float(valid).numeric_float_minus_bigint(valid, mirror).numeric_bigrat_dominates(valid).for_in_int_count(valid, range form).for_in_map_keys(valid).aggregate_avg_int_list(valid).aggregate_min_string_list(valid).aggregate_sum_bigint_list(valid).
From MEP 7 (soundness):
preservation_let_substitution(valid, sequence).inversion_every_primary(valid, large composite).
From MEP 11 (subtyping):
record_width_subtype(valid, when implemented).any_top_silent_widen(valid, snapshots current behaviour).any_to_int_unchecked(valid, snapshots current behaviour).cast_int_as_string(valid, snapshots current behaviour).
From MEP 12 (polymorphism):
generic_id_int_string(valid).generic_id_per_call_freshness(valid).generic_pair_swap(valid, when implemented).generic_unification_conflict(error, when implemented).
From MEP 13 (ADT):
adt_struct_field_mismatch(error).adt_union_constructor_arity(error).adt_match_exhaustive(valid, when implemented).adt_match_missing_variant(error, when implemented).adt_match_redundant_variant(error, when implemented).adt_match_wildcard_after(valid).
From MEP 14 (queries):
query_select_arbitrary_expr(valid).query_join_cardinality(valid).query_group_having_bool(error, T042).query_distinct_unique_int(valid).query_skip_take_int(valid).
From MEP 15 (effects):
mutate_through_let_index(valid today, error after fix).mutate_through_let_field(valid today, error after fix).pure_call_in_pure_context(future, no fixture yet).
How to map a fixture to a MEP
Every fixture committed under tests/types/ should be referenced in the MEP that owns the property. The MEP's "Open Questions" or "Specification" section carries a checklist that lists fixtures by name. When a fixture is added, the checklist gets a checkmark.
When this catalogue is updated, the matrix above must reflect reality. Stale matrix rows are a tech debt indicator.
Rationale
The catalogue is the single source of truth for fixture coverage. Without it, missing coverage hides behind passing tests. The matrix is uncomfortable to read on purpose: every missing cell is a debt we owe the language.
Backwards Compatibility
Informational. No backward compatibility implications.
Reference Implementation
tests/parser/valid/,tests/parser/errors/— parser fixtures.tests/types/valid/,tests/types/errors/— type fixtures.golden/golden.go— harness used by both directories.
Open Questions
- Inventory regeneration. A small Go program that walks the tree and produces this Markdown would keep the inventory honest.
- Property test fixtures. Once layer 5 is wired in, this catalogue gains a third column.
References
- See MEP 7 for the property list.
- See MEP 8 for the test layer that owns each fixture.
Copyright
This document is placed in the public domain.