src/arbitraries
fast-check generators for ASC X12, at @cosyte/x12/arbitraries: delimiter sets, element
values, body segments, transaction set types, whole interchanges, specs for the interchange
builder, messy interchange text and hostile input. We use them to test this library, and you
can use them to test code you build on it.
fast-check is an optional peer dependency: install it to use this entry point. The main
entry point, @cosyte/x12, never loads it.
Every generated value is synthetic and random. Nothing in one looks like a patient's name, date of birth, member id or address, or an amount from a real claim.
Example
import fc from "fast-check";
import { parseX12, serializeX12 } from "@cosyte/x12";
import { interchange } from "@cosyte/x12/arbitraries";
fc.assert(
fc.property(interchange(), (ix) => {
const text = serializeX12(ix);
return serializeX12(parseX12(text)) === text;
}),
);
Interfaces
DelimitersOptions
Options for delimiters.
Properties
delimiters?
readonlyoptionaldelimiters?:"standard"|"any"
"standard" gives only *, ^, : and ~; "any" gives any four distinct characters of
visible ASCII punctuation but ?. Defaults to both, the standard set one time in four.
HostileInputOptions
Options for hostileInput.
Properties
maxLength?
readonlyoptionalmaxLength?:number
The longest random string or byte run. Defaults to 200.
InterchangeOptions
Options for interchange, interchangeText and interchangeSpec.
Properties
delimiters?
readonlyoptionaldelimiters?:Arbitrary<Delimiters>
The delimiters to write with. Defaults to delimiters.
maxElements?
readonlyoptionalmaxElements?:number
The most elements in a body segment. Defaults to 8.
maxGroups?
readonlyoptionalmaxGroups?:number
The most functional groups. Defaults to 2.
maxSegments?
readonlyoptionalmaxSegments?:number
The most body segments in a transaction set. Defaults to 6.
maxTransactions?
readonlyoptionalmaxTransactions?:number
The most transaction sets in a group. Defaults to 2.
SegmentOptions
Options for segment.
Properties
ids?
readonlyoptionalids?: readonlystring[]
The segment ids to draw from. Defaults to common 005010 healthcare segments.
maxElements?
readonlyoptionalmaxElements?:number
The most elements after the id. Defaults to 8.
values?
readonlyoptionalvalues?:Arbitrary<string>
The element values. Defaults to value.
TransactionSetType
A transaction set type: what ST-01, GS-01 and GS-08 (and ST-03) carry for it.
Properties
functionalIdCode
readonlyfunctionalIdCode:string
The functional identifier code, GS-01, such as HP.
id
readonlyid:string
The transaction set identifier, ST-01, such as 835.
version
readonlyversion:string
The implementation guide, GS-08 and ST-03, such as 005010X221A1.
ValueOptions
Options for value.
Properties
maxLength?
readonlyoptionalmaxLength?:number
The most characters. Defaults to 12.
minLength?
readonlyoptionalminLength?:number
The fewest characters. Defaults to 1.
Functions
delimiters()
delimiters(
options?):Arbitrary<Delimiters>
Generate a delimiter set: the standard one, or any four distinct characters of visible ASCII
punctuation but the release character ?. Every set frames an interchange the parser reads.
Parameters
options?
DelimitersOptions = {}
Which sets to draw.
Returns
Arbitrary<Delimiters>
An arbitrary of a Delimiters.
Example
import fc from "fast-check";
import { delimiters } from "@cosyte/x12/arbitraries";
const [d] = fc.sample(delimiters({ delimiters: "any" }), 1);
// d is like { element: "|", repetition: "&", component: "{", segment: "#" }
hostileInput()
hostileInput(
options?):Arbitrary<string|Buffer<ArrayBufferLike>>
Generate hostile input for a lenient parser: random strings, random bytes, text that opens like an ISA and then falls apart, a whole ISA followed by random text, interchanges cut short or with text inserted and deleted anywhere, ISA included, binary segments whose octet count is wrong, negative or huge, and interchanges as bytes in UTF-8 or Latin-1. The parser must turn each into an interchange with warnings, or refuse it with one of its four documented fatal errors, and never throw anything else.
Parameters
options?
HostileInputOptions = {}
The longest random run.
Returns
Arbitrary<string | Buffer<ArrayBufferLike>>
An arbitrary of a string or a Buffer.
Example
import fc from "fast-check";
import { X12ParseError, parseX12 } from "@cosyte/x12";
import { hostileInput } from "@cosyte/x12/arbitraries";
fc.assert(
fc.property(hostileInput(), (raw) => {
try {
parseX12(raw);
} catch (err) {
return err instanceof X12ParseError;
}
return true;
}),
);
interchange()
interchange(
options?):Arbitrary<X12Interchange>
Generate a spec-clean interchange, parsed: an ISA over generated delimiters, sometimes a TA1, then one or more functional groups of one or more transaction sets, each a type the library declares a guide for, with generated body segments whose elements carry repetitions, components and values that need the release character. Every count and control number agrees, so the parser warns about nothing, and the interchange serializes back to the exact text it was parsed from. Every value is random: nothing in one looks like a name, a date of birth, a member id or an amount from a real claim.
Parameters
options?
InterchangeOptions = {}
The delimiters and the size.
Returns
Arbitrary<X12Interchange>
An arbitrary of an X12Interchange.
Example
import fc from "fast-check";
import { parseX12, serializeX12 } from "@cosyte/x12";
import { interchange } from "@cosyte/x12/arbitraries";
fc.assert(
fc.property(interchange(), (ix) => {
const text = serializeX12(ix);
return serializeX12(parseX12(text)) === text;
}),
);
interchangeSpec()
interchangeSpec(
options?):Arbitrary<InterchangeSpec>
Generate a spec for buildInterchange: generated delimiters, sender and receiver ids, a date
and time, control numbers, and one or more functional groups of one or more transaction sets,
each with generated body segments from segment. Values hold characters the builder
must release, so what it writes reads back as the values given.
Parameters
options?
InterchangeOptions = {}
The delimiters and the size.
Returns
Arbitrary<InterchangeSpec>
An arbitrary of an InterchangeSpec.
Example
import fc from "fast-check";
import { buildInterchange } from "@cosyte/x12";
import { interchangeSpec } from "@cosyte/x12/arbitraries";
fc.assert(
fc.property(interchangeSpec(), (spec) => buildInterchange(spec).warnings.length === 0),
);
interchangeText()
interchangeText(
options?):Arbitrary<string>
Generate raw interchange text the parser accepts, messy on purpose: line breaks of any kind between segments, an ISA declaring a version before 005010, counts and control numbers that disagree, a missing SE, GE or IEA, a TA1 inside a group, segments outside any transaction set, a doubled terminator, a segment with no id, bytes after the IEA, no final terminator (and an end on a dangling release character or inside a binary segment's declared span), and body segments with trailing empty elements or components, a lower-case id, padding, a release character before a character that is no delimiter or before the terminator itself, characters outside the X12 character sets, and a binary segment framed by its octet count. The ISA is always whole, so the parser reads every one of these, warning about what it must, and never refuses one.
Parameters
options?
InterchangeOptions = {}
The delimiters and the size.
Returns
Arbitrary<string>
An arbitrary of the interchange text.
Example
import fc from "fast-check";
import { parseX12 } from "@cosyte/x12";
import { interchangeText } from "@cosyte/x12/arbitraries";
fc.assert(
fc.property(interchangeText(), (raw) => {
parseX12(raw); // never throws for this text
}),
);
segment()
segment(
options?):Arbitrary<SegmentSpec>
Generate a body segment as buildInterchange takes one: the segment id, then each element's
value as a reader sees it (the builder releases every delimiter in it). Elements before the
last may be empty; the last never is, as X12 writes no trailing empty element.
Parameters
options?
SegmentOptions = {}
The ids, the most elements, and the values.
Returns
Arbitrary<SegmentSpec>
An arbitrary of a SegmentSpec.
Example
import fc from "fast-check";
import { segment } from "@cosyte/x12/arbitraries";
const [spec] = fc.sample(segment({ ids: ["REF"] }), 1);
// spec is like ["REF", "", "7Q:b"]
transactionSetType()
transactionSetType():
Arbitrary<TransactionSetType>
Generate a transaction set type: an ST-01 such as 835, the GS-01 it travels under and the
implementation guide the library declares for it, one of the 270, 271, 275, 276, 277 (with
the 277CA and the request for additional information), 278, 820, 834, 835, 837 and 999 guides.
Returns
Arbitrary<TransactionSetType>
An arbitrary of a TransactionSetType.
Example
import fc from "fast-check";
import { transactionSetType } from "@cosyte/x12/arbitraries";
const [type] = fc.sample(transactionSetType(), 1);
// type is like { id: "835", functionalIdCode: "HP", version: "005010X221A1" }
value()
value(
options?):Arbitrary<string>
Generate the text of one element or component as a reader sees it, after the release
character is taken out: letters, digits, spaces and the special characters of the X12 basic
and extended character sets, ? and every standard delimiter among them, so a value often
holds a character the writer has to release. Never a line break or a control character.
Parameters
options?
ValueOptions = {}
The length bounds.
Returns
Arbitrary<string>
An arbitrary of the value's text.
Example
import fc from "fast-check";
import { value } from "@cosyte/x12/arbitraries";
const [text] = fc.sample(value(), 1);
// text is like "Q7*b:2"