Source contract and expected records
This is an original, fully synthetic mapping example. Inputs are plain, acyclic JSON-shaped records with the fields shown; the canonical shape and rejection codes belong to this example. Adapt the contract before using a different source.
The original input supplies exactly one L, W and H observation, each with positive safe integer millimetres. Reject missing axes, duplicates and unknown axes. The canonical object names lengthMm, widthMm and heightMm, regardless of source order.
| Case | Input record (JSON) | Expected output (JSON) |
|---|---|---|
| Map axes by label | {"axes":[{"axis":"W","mm":20},{"axis":"H","mm":10},{"axis":"L","mm":30}]} | {"ok":true,"value":{"lengthMm":30,"widthMm":20,"heightMm":10}} |
| Reject repeated axis | {"axes":[{"axis":"L","mm":30},{"axis":"L","mm":20}]} | {"ok":false,"error":"AXIS_VALUE"} |
| Reject missing height | {"axes":[{"axis":"L","mm":30},{"axis":"W","mm":20}]} | {"ok":false,"error":"AXIS_MISSING"} |
Run the local transformation
Run the complete example as a JavaScript module in Node.js. It contains the pure mapping function, all three inputs and literal expected outputs; assertions stop on a mismatch. A rejected case returns ok=false with an error code, rather than a partial canonical record.
import assert from 'node:assert/strict';
function axisDimensions(i){
const fail=error=>({ok:false,error});if(!i||!Array.isArray(i.axes))return fail('AXIS_LIST');
const values={};
for(const a of i.axes){if(!a||!['L','W','H'].includes(a.axis)||Object.hasOwn(values,a.axis)||!Number.isSafeInteger(a.mm)||a.mm<=0)return fail('AXIS_VALUE');values[a.axis]=a.mm;}
if(!['L','W','H'].every(x=>Object.hasOwn(values,x)))return fail('AXIS_MISSING');
return {ok:true,value:{lengthMm:values.L,widthMm:values.W,heightMm:values.H}};
}
// Original synthetic cases; expected outputs are literal records.
const cases = [
{
"label": "Map axes by label",
"input": {
"axes": [
{
"axis": "W",
"mm": 20
},
{
"axis": "H",
"mm": 10
},
{
"axis": "L",
"mm": 30
}
]
},
"expected": {
"ok": true,
"value": {
"lengthMm": 30,
"widthMm": 20,
"heightMm": 10
}
}
},
{
"label": "Reject repeated axis",
"input": {
"axes": [
{
"axis": "L",
"mm": 30
},
{
"axis": "L",
"mm": 20
}
]
},
"expected": {
"ok": false,
"error": "AXIS_VALUE"
}
},
{
"label": "Reject missing height",
"input": {
"axes": [
{
"axis": "L",
"mm": 30
},
{
"axis": "W",
"mm": 20
}
]
},
"expected": {
"ok": false,
"error": "AXIS_MISSING"
}
}
];
for (const sample of cases) {
const actual = axisDimensions(sample.input);
assert.deepEqual(actual, sample.expected);
console.log(sample.label, JSON.stringify(actual));
}
Work through the boundary
The array begins W=20, H=10, then L=30. Which value becomes length?
Show the worked answer
Length is 30 mm, width 20 mm and height 10 mm. The L label supplies length. Repeating L cannot stand in for a missing H.