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.
Surface width/height and rectangle width/height are positive safe integers; x/y are nonnegative safe integers. The rectangle must fit completely within the surface, touching edges permitted. Divide x and width by surface width, and y and height by surface height. Retain sourceSize and tag unit fraction.
| Case | Input record (JSON) | Expected output (JSON) |
|---|---|---|
| Scale a supplied rectangle | {"surface":{"width":200,"height":100},"rect":{"x":20,"y":10,"width":100,"height":40}} | {"ok":true,"value":{"left":0.1,"top":0.1,"width":0.5,"height":0.4,"unit":"fraction","sourceSize":{"width":200,"height":100}}} |
| Reject outside edge | {"surface":{"width":200,"height":100},"rect":{"x":190,"y":0,"width":20,"height":10}} | {"ok":false,"error":"RECTANGLE_BOUNDS"} |
| Preserve touching edges | {"surface":{"width":200,"height":100},"rect":{"x":100,"y":0,"width":100,"height":100}} | {"ok":true,"value":{"left":0.5,"top":0,"width":0.5,"height":1,"unit":"fraction","sourceSize":{"width":200,"height":100}}} |
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 rectangleFractions(i){
const fail=error=>({ok:false,error});if(!i||!i.surface||!i.rect)return fail('RECTANGLE_SHAPE');
const s=i.surface,r=i.rect;
if(![s.width,s.height].every(n=>Number.isSafeInteger(n)&&n>0))return fail('SURFACE_SIZE');
if(![r.x,r.y,r.width,r.height].every(Number.isSafeInteger)||r.x<0||r.y<0||r.width<=0||r.height<=0||r.x+r.width>s.width||r.y+r.height>s.height)return fail('RECTANGLE_BOUNDS');
return {ok:true,value:{left:r.x/s.width,top:r.y/s.height,width:r.width/s.width,height:r.height/s.height,unit:'fraction',sourceSize:{width:s.width,height:s.height}}};
}
// Original synthetic cases; expected outputs are literal records.
const cases = [
{
"label": "Scale a supplied rectangle",
"input": {
"surface": {
"width": 200,
"height": 100
},
"rect": {
"x": 20,
"y": 10,
"width": 100,
"height": 40
}
},
"expected": {
"ok": true,
"value": {
"left": 0.1,
"top": 0.1,
"width": 0.5,
"height": 0.4,
"unit": "fraction",
"sourceSize": {
"width": 200,
"height": 100
}
}
}
},
{
"label": "Reject outside edge",
"input": {
"surface": {
"width": 200,
"height": 100
},
"rect": {
"x": 190,
"y": 0,
"width": 20,
"height": 10
}
},
"expected": {
"ok": false,
"error": "RECTANGLE_BOUNDS"
}
},
{
"label": "Preserve touching edges",
"input": {
"surface": {
"width": 200,
"height": 100
},
"rect": {
"x": 100,
"y": 0,
"width": 100,
"height": 100
}
},
"expected": {
"ok": true,
"value": {
"left": 0.5,
"top": 0,
"width": 0.5,
"height": 1,
"unit": "fraction",
"sourceSize": {
"width": 200,
"height": 100
}
}
}
}
];
for (const sample of cases) {
const actual = rectangleFractions(sample.input);
assert.deepEqual(actual, sample.expected);
console.log(sample.label, JSON.stringify(actual));
}
Work through the boundary
On a 200×100 surface, what does x20/y10/w100/h40 become?
Show the worked answer
left=20/200=0.1, top=10/100=0.1, width=100/200=0.5, height=40/100=0.4. The rectangle ends at x120/y50, within the source bounds.