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 source accepts g or kg and nonnegative decimal text with at most three fractional digits, no grouping or exponent and no leading zero except zero itself. Parse thousandths from digits, then express the result as safe whole milligrams. Preserve the original value and unit. Four fractional digits are rejected even if a finer calculation could be possible.
| Case | Input record (JSON) | Expected output (JSON) |
|---|---|---|
| Scale decimal exactly | {"value":"1.250","unit":"kg"} | {"ok":true,"value":{"milligrams":1250000,"source":{"value":"1.250","unit":"kg"}}} |
| Reject excess precision | {"value":"1.0001","unit":"g"} | {"ok":false,"error":"MASS_DECIMAL"} |
| Preserve zero mass | {"value":"0","unit":"g"} | {"ok":true,"value":{"milligrams":0,"source":{"value":"0","unit":"g"}}} |
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 massToMilligrams(i){
const fail=error=>({ok:false,error});if(!i||typeof i.value!=='string'||!['g','kg'].includes(i.unit))return fail('MASS_UNIT');
const m=/^(0|[1-9]\d*)(?:\.(\d{1,3}))?$/.exec(i.value);if(!m)return fail('MASS_DECIMAL');
const thousandths=Number(m[1])*1000+Number((m[2]||'').padEnd(3,'0'));
const milligrams=thousandths*(i.unit==='kg'?1000:1);
if(!Number.isSafeInteger(thousandths)||!Number.isSafeInteger(milligrams))return fail('MASS_RANGE');
return {ok:true,value:{milligrams,source:{value:i.value,unit:i.unit}}};
}
// Original synthetic cases; expected outputs are literal records.
const cases = [
{
"label": "Scale decimal exactly",
"input": {
"value": "1.250",
"unit": "kg"
},
"expected": {
"ok": true,
"value": {
"milligrams": 1250000,
"source": {
"value": "1.250",
"unit": "kg"
}
}
}
},
{
"label": "Reject excess precision",
"input": {
"value": "1.0001",
"unit": "g"
},
"expected": {
"ok": false,
"error": "MASS_DECIMAL"
}
},
{
"label": "Preserve zero mass",
"input": {
"value": "0",
"unit": "g"
},
"expected": {
"ok": true,
"value": {
"milligrams": 0,
"source": {
"value": "0",
"unit": "g"
}
}
}
}
];
for (const sample of cases) {
const actual = massToMilligrams(sample.input);
assert.deepEqual(actual, sample.expected);
console.log(sample.label, JSON.stringify(actual));
}
Work through the boundary
What does 1.250 kg become, and why is 1.0001 g rejected?
Show the worked answer
1.250 kg is 1,250,000 mg: 1.250 × 1,000,000. The second value exceeds the original three-digit fraction limit and returns MASS_DECIMAL. It is not rounded.