npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@veridtools/dmn-fixtures

v0.3.5

Published

DMN test fixtures covering DMN 1.0 to 1.5

Downloads

1,563

Readme

@veridtools/dmn-fixtures

version license dependencies

A comprehensive library of DMN/FEEL fixture files for JavaScript and TypeScript tooling. Covers 100% of the OMG DMN 1.1–1.5 and FEEL specification — every feature a FEEL runner or DMN runner needs to implement correctly.

At a glance

  • 784 DMN/XML fixture files across 5 categories
  • 416 companion JSON files with typed inputs and expected outputs
  • ~100% coverage of OMG DMN/FEEL spec features (every function, operator, expression type, and boxed expression)
  • DMN 1.1 → 1.5 with correct namespaces per version
  • 0 runtime dependencies
  • 100% TypeScript
  • MIT licensed

Why

Building a DMN engine, FEEL evaluator, or DMN tooling in JavaScript/TypeScript requires a reliable test corpus. The official OMG TCK targets Java runtimes and focuses on volume over feature completeness. This package takes the opposite approach: every DMN/FEEL spec feature has at least one fixture designed to catch a runner bug, with companion JSON that specifies exact expected outputs.

If you're building a feel-runner or dmn-runner, this library gives you the test harness to verify correctness against the spec.

See COVERAGE.md for detailed coverage percentages by spec section.
See AUDIT.md for the running audit log that tracks how coverage was built up.

Installation

pnpm add -D @veridtools/dmn-fixtures
# or
npm install --save-dev @veridtools/dmn-fixtures

Fixture categories

| Category | DMN files | JSON files | What it covers | |---|---|---|---| | structure | 368 | — | All DMN 1.1–1.5 XML elements: decision tables, boxed expressions, DMNDI, requirements, imports, services | | s-feel | 59 | 59 | S-FEEL unary tests, all 7 hit policies + aggregations, AllowedValues, decision chaining, edge cases (UNIQUE multi-match, dash matches null, empty table) | | feel-types | 155 | 155 | All FEEL data types, operators, for, if, some/every, instance of, path/filter, decimal128, 3-valued null, Unicode | | feel-functions | 144 | 144 | All built-in functions DMN 1.0→1.5 (incl. string join, list replace) with positional and named parameter syntax | | execution | 58 | 58 | Decision table execution, BKMs, boxed conditional/filter/iterator, decision services, multi-model import |

Usage

Load a fixture file

import { loadFixture } from '@veridtools/dmn-fixtures'

const xml = loadFixture('feel/functions/string/fn-substring.dmn')

Run executable fixtures against a FEEL runner

import { CATALOG, loadFixture } from '@veridtools/dmn-fixtures'
import * as fs from 'fs'

// Get all feel-functions fixtures with test cases
const cases = CATALOG
  .filter(f => f.category === 'feel-functions' && f.testCasesPath)
  .map(f => ({
    fixture: f,
    xml: loadFixture(f.path),
    tests: JSON.parse(fs.readFileSync(`./fixtures/${f.testCasesPath}`, 'utf-8')).cases
  }))

for (const { fixture, xml, tests } of cases) {
  for (const { context, expected } of tests) {
    const result = myFeelRunner.evaluate(xml, context)
    assert.deepEqual(result, expected, `${fixture.path} failed`)
  }
}

Filter by category or group

import { CATALOG } from '@veridtools/dmn-fixtures'

// All S-FEEL fixtures
const sfeelFixtures = CATALOG.filter(f => f.category === 's-feel')

// All FEEL type fixtures with companion JSON
const typeFixtures = CATALOG.filter(f => f.category === 'feel-types' && f.testCasesPath)

// Structure fixtures for a specific group
const hitPolicyFixtures = CATALOG.filter(f => f.group === 'hit-policy')

// All executable fixtures across all categories
const executableFixtures = CATALOG.filter(f => f.testCasesPath)

FixtureEntry shape

interface FixtureEntry {
  path: string            // relative path from fixtures/
  category: string        // 'structure' | 's-feel' | 'feel-types' | 'feel-functions' | 'execution'
  group: string           // sub-group within category (e.g. 'hit-policy', 'string', 'bkm')
  format: 'dmn' | 'xml'
  description: string
  testCasesPath?: string  // path to companion JSON (undefined for structure fixtures)
  dmnVersion?: string     // '1.1' | '1.2' | '1.3' | '1.4' | '1.5'
}

Companion JSON format

// fixtures/feel/functions/string/fn-substring.json
{
  "description": "substring(string, startPosition) ...",
  "cases": [
    { "context": { "s": "hello", "start": 2 }, "expected": "ello" },
    { "context": { "s": "hello", "start": -2 }, "expected": "lo" }
  ]
}

For fixtures where the DMN has no input data (self-contained expressions), the context is {} and expected is keyed by decision name:

{
  "cases": [
    {
      "context": {},
      "expected": { "Result": { "substring_named": "world", "contains_named": true } }
    }
  ]
}

Spec coverage highlights

FEEL built-in functions — all 80, with named parameter syntax

Every built-in function is tested positionally and with named parameters:

// Positional
substring("hello world", 7)          // → "world"
floor(-1.567, 1)                      // → -1.6

// Named params
substring(string: "hello world", startPosition: 7)
floor(n: -1.567, scale: 1)
date and time(date: date("2024-06-15"), time: time("09:00:00"))

FEEL expression types — every form

// for with partial (DMN 1.5)
for i in 1..5 return if i = 1 then 1 else partial[-1] + i  // → [1, 3, 6, 10, 15]

// Context with inline function invocation
{ f: function(x) x * 2, result: f(5) }.result  // → 10

// Self-recursive function
{ fact: function(n) if n <= 1 then 1 else n * fact(n - 1), r: fact(5) }.r  // → 120

// instance of with complex types
[1,2,3] instance of list<number>          // → true
(function(x) x+1) instance of function<number>->number  // → true

Temporal arithmetic — all combinations

date("2024-01-31") + duration("P1M")           // → date("2024-02-29")  (end-of-month clamp)
date and time("2024-01-15T09:00:00") + duration("PT2H")  // → "2024-01-15T11:00:00"
duration("PT3H") / duration("PT1H")            // → 3  (duration ÷ duration → number)

DMN execution — all patterns

// Multi-model import
MathLib.Double(Value)       // BKM from imported DMN file
MathLib.Clamp(Value, 0, 100)

// functionDefinition as decision expression (returns callable function)
// Decision "Square Function" returns function(x) x*x
// Decision "Result" invokes Square Function(Input)

// Boxed conditional, filter, iterator (DMN 1.4+)
// All tested with companion JSON

How this compares to the DMN TCK

The DMN Technology Compatibility Kit is the official OMG conformance suite — 3,390 test cases validating FEEL and decision table evaluation.

| Dimension | DMN TCK | This package | |---|---|---| | Primary target | Java runtimes | JavaScript / TypeScript | | FEEL functions | ~2,000 cases, 80 functions | ~450 cases, all 80 spec functions + named params (incl. string join DMN 1.4 and list replace DMN 1.5) | | FEEL types/operators | ~800 cases | ~300 cases, ~100% of spec features | | S-FEEL / Compliance L2 | ~200 cases | ~210 cases, ~100% of features | | DMN execution patterns | ~400 cases | ~160 cases, ~100% of patterns | | DMN structure | 0 (out of scope) | 368 fixtures — unique to this package | | Volume vs TCK | 3,390 cases | ~1,120 executable + 368 structural |

This package prioritizes 100% spec feature coverage over combinatorial volume. If your runner handles each feature correctly, the TCK cases are variations of the same behavior.

Critical runner invariants

If your FEEL runner fails any of these, it is not spec-compliant. All have fixtures in this library:

| Invariant | Expected | |---|---| | 0.1 + 0.2 = 0.3 | true (decimal128, not float) | | 5 / 2 | 2.5 (no integer division) | | 1 / 0 | null (not exception, not infinity) | | null = null | true (not SQL-style null) | | "5" = 5 | false (no implicit coercion) | | count("a") | 1 (singleton coercion) | | [{a:1},{a:2}].a | [1, 2] (path on list) | | all([]) | true (vacuous truth) | | decimal(2.5, 0) | 2 (banker's rounding — half to even) | | modulo(-5, 3) | 1 (sign of divisor, not dividend) | | date("2024-01-31") + duration("P1M") | date("2024-02-29") (end-of-month clamp, leap) | | string length("😀") | 1 (code points, not UTF-16 code units) | | if true then 1 else 1/0 | 1 (dead branch short-circuits) | | -2 ** 2 | 4 (unary minus tighter than exponent) | | {a:1}.b | null (missing key is null, not error) | | {a:1, b:a+1}.b | 2 (sibling references resolve in order) |

See COVERAGE.md for the complete list with fixture mappings.

Documentation

  • COVERAGE.md — Detailed coverage report: spec section by section (FEEL §10.3, S-FEEL §8, decision tables §9, structure §6/§7/§12), complete list of critical invariants, comparison to TCK. Updated after every expansion stage.

  • AUDIT.md — Audit log used to validate changes. Required reading before adding new fixtures.

DMN namespace by version

| Version | Namespace | |---------|-----------| | 1.1 | http://www.omg.org/spec/DMN/20151101/dmn.xsd | | 1.2 | http://www.omg.org/spec/DMN/20180521/MODEL/ | | 1.3 | https://www.omg.org/spec/DMN/20191111/MODEL/ | | 1.4 | https://www.omg.org/spec/DMN/20211108/MODEL/ | | 1.5 | https://www.omg.org/spec/DMN/20230324/MODEL/ |

All fixtures default to DMN 1.5 unless the path or fixture content targets a specific prior version.

Contributing

Before adding fixtures, read AUDIT.md (fixture authoring rules section) and COVERAGE.md (what's already covered). Run pnpm build after any addition — the build must pass before a fixture is considered complete.

See CONTRIBUTING.md for the full workflow.

License

MIT