pimbay / sequence-formatter-spec
Language-agnostic JSON test vectors and schemas for the PimBay Sequence Stack
Package info
codeberg.org/pimbay/sequence-formatter-spec
pkg:composer/pimbay/sequence-formatter-spec
README
Language-agnostic JSON test vectors and schemas for the PimBay Sequence Stack. Used to verify ports of the sequence formatter to other languages and runtimes.
What is this
The sequence formatter formats integer sequence values into business identifiers, generates initial values for sequence groups, and produces random codes — all driven by a pattern string. This repository contains the canonical test vectors that any port must pass to be considered correct.
Pattern syntax
Patterns are strings with {token} placeholders. Literals outside tokens pass through unchanged.
Sequence tokens — PatternFormatter / InitialValueGenerator
| Token | Description |
|---|---|
{N} | Single digit, right-to-left indexed |
{N4} / {NNNN} | Fixed padding — 4 digits |
{N3..5} | Dynamic range — min 3, max 5 digits |
{N+} | Unlimited — full number, no padding |
Random tokens — CodeGenerator
| Token | Description |
|---|---|
{R} | One random character |
{R4} | Exactly 4 random characters |
{R3..5} | Random length between 3 and 5 |
Shared tokens
| Token | Output (2026-04-16) |
|---|---|
{YYYY} | 2026 |
{YY} | 26 |
{MM} | 04 |
{DD} | 16 |
{key} | runtime context value |
Examples:
| Pattern | Input | Output |
|---|---|---|
INV/{N4} | 1 | INV/0001 |
INV/{YYYY}/{N4} | 125 | INV/2026/0125 |
{branch}/{YY}/{N4} | 1, branch=SK | SK/26/0001 |
{YY}{MM}{N4} | 1 | 26040001 |
{R4}-{R4} | — | A3KM-7PXT |
{YY}{MM}-{R4} | — | 2604-A3KM |
Structure
schema/ — JSON Schema 2020-12 definitions
vectors/ — test vector files, one per component
scripts/ — validation tooling (Node.js)
Vectors
| File | Component | Positive | Negative |
|---|---|---|---|
alphabet.json | Alphabet | 2 | 2 |
pattern-formatter.json | PatternFormatter | 20 | 13 |
initial-value-generator.json | InitialValueGenerator | 12 | 13 |
code-generator.json | CodeGenerator | 11 | 13 |
transformer-base-n.json | Transformer.Number.BaseNTransformer | 8 | 2 |
transformer-luhn.json | Transformer.Number.LuhnChecksumTransformer | 3 | 2 |
transformer-modulo.json | Transformer.Number.ModuloChecksumTransformer | 4 | 1 |
transformer-obfuscator32.json | Transformer.Number.Obfuscator32Transformer | 5 | 3 |
transformer-obfuscator64.json | Transformer.Number.Obfuscator64Transformer | 6 | 2 |
transformer-mask.json | Transformer.Code.MaskTransformer | 6 | 8 |
Vector conventions
config.reference_date — ISO 8601 datetime used as the clock value. null means no clock is needed. Cases tagged clocked require a non-null value; ports must inject it into whatever clock mechanism they use.
config.alphabet — named constant (e.g. "UNAMBIGUOUS_UPPER") or inline string (e.g. "ABC"). Named constants are defined in vectors/alphabet.json under constants.
expected.matches_regex — PCRE regex the generated output must match. Present on all CodeGenerator positive cases because output is random. For clocked cases the date prefix is hardcoded in the regex (e.g. ^2604-).
expected.unique_chars — when true, all characters in the output must be distinct. Used for repeatable: false cases.
expected.max_length — present in all PatternFormatter and CodeGenerator positive cases. null for patterns containing {N+} or a context token.
expected_error.reason — snake_case identifier a port must map to its own error type. The type field uses class name conventions as reference only. All reason values used across vectors:
| Reason | Used by |
|---|---|
missing_clock | PatternFormatter, InitialValueGenerator, CodeGenerator |
missing_key | PatternFormatter, InitialValueGenerator, CodeGenerator |
non_numeric_value | InitialValueGenerator |
max_value_exceeded | PatternFormatter |
max_length_exceeded | PatternFormatter, CodeGenerator |
initial_value_exceeds_capacity | InitialValueGenerator |
unsupported_token_type | PatternFormatter, InitialValueGenerator, CodeGenerator |
empty_pattern | PatternFormatter, InitialValueGenerator, CodeGenerator |
mixed_digit_tokens | PatternFormatter, InitialValueGenerator, CodeGenerator |
multiple_unlimited | PatternFormatter, InitialValueGenerator, CodeGenerator |
invalid_range | PatternFormatter, InitialValueGenerator, CodeGenerator |
zero_count | PatternFormatter, InitialValueGenerator, CodeGenerator |
unknown_token | PatternFormatter, InitialValueGenerator, CodeGenerator |
no_sequence_token | PatternFormatter, InitialValueGenerator, CodeGenerator |
non_numeric_result | InitialValueGenerator |
invalid_alphabet | Alphabet, CodeGenerator, BaseNTransformer |
invalid_configuration | CodeGenerator, MaskTransformer, ModuloChecksumTransformer, Obfuscator32Transformer, Obfuscator64Transformer |
invalid_key | Obfuscator32Transformer, Obfuscator64Transformer |
invalid_modulus | ModuloChecksumTransformer |
invalid_value | MaskTransformer |
value_out_of_range | Obfuscator32Transformer, Obfuscator64Transformer |
insufficient_alphabet_for_non_repeatable | CodeGenerator |
char_not_in_alphabet | BaseNTransformer |
luhn_check_failed | LuhnChecksumTransformer |
value_too_short | LuhnChecksumTransformer |
tags — informational, not enforced by schema:
| Tag | Meaning |
|---|---|
clocked | requires reference_date to be set |
random | output is non-deterministic; verify with matches_regex |
context | requires input.context key(s) |
overflow | tests overflow: silent or overflow throw behaviour |
round_trip | obfuscator: inverse(transform(n)) === n; encoded value is fixed |
Porting checklist
- Load the vector file for the component you are implementing.
- Positive case — instantiate with
pattern+config, call the method withinput, assert result matchesexpected. - Negative case — assert the correct error type and reason is raised.
randomtag — assertexpected.matches_regexinstead of equality. Ifunique_chars: true, assert all characters are distinct.clockedtag — injectconfig.reference_dateas the clock value before calling.round_triptag — assertinverse(transform(input)) === input. Encoded string must matchexpected.transformexactly.
Validation
Requires Node.js 18+.
npm install
npm test
Packages in the stack
| Package | Description |
|---|---|
pimbay/sequence-formatter-spec | This package |
pimbay/sequence-number-sql | SQL snippets for number sequence adapters |
pimbay/sequence-random-sql | SQL snippets for random sequence adapters |
License
Public domain — Unlicense
Created by Jan Sarmir · No conditions · No copyright