來源格式與預期記錄
這是原創假設轉換例子。輸入限下列欄位的普通、無循環 JSON 形記錄,統一記錄格式及拒絕代碼由本例訂明。若換來源,先修改格式約定。
本例最多只可有 ratePercent 或 amountUnits 其中一個自有欄位。兩者同時有便衝突,即使一個是 0。百分比為 0 至 100 整數,定額為來源記賬單位的非負安全整數。兩欄都沒有才是 kind none,已有但 null 不合法。
| 個案 | 輸入記錄(JSON) | 預期輸出(JSON) |
|---|---|---|
| 標示比例折扣資料 | {"ratePercent":10} | {"ok":true,"value":{"kind":"rate","percent":10}} |
| 拒絕同時兩種表示 | {"ratePercent":10,"amountUnits":20} | {"ok":false,"error":"DISCOUNT_CONFLICT"} |
| 保留明確固定零值 | {"amountUnits":0} | {"ok":true,"value":{"kind":"fixed","amountUnits":0}} |
在本機執行轉換
把完整例子以 JavaScript 模組在 Node.js 執行,內含純轉換函數、三個輸入及寫明的預期輸出,對不上便由斷言停止。拒絕個案回傳 ok=false 及代碼,不回傳半份統一記錄。
import assert from 'node:assert/strict';
function discountTag(i){
const fail=error=>({ok:false,error});if(!i||typeof i!=='object'||Array.isArray(i))return fail('DISCOUNT_OBJECT');
const rate=Object.hasOwn(i,'ratePercent'),fixed=Object.hasOwn(i,'amountUnits');
if(rate&&fixed)return fail('DISCOUNT_CONFLICT');
if(rate){if(!Number.isSafeInteger(i.ratePercent)||i.ratePercent<0||i.ratePercent>100)return fail('DISCOUNT_RATE');return {ok:true,value:{kind:'rate',percent:i.ratePercent}};}
if(fixed){if(!Number.isSafeInteger(i.amountUnits)||i.amountUnits<0)return fail('DISCOUNT_AMOUNT');return {ok:true,value:{kind:'fixed',amountUnits:i.amountUnits}};}
return {ok:true,value:{kind:'none'}};
}
// Original synthetic cases; expected outputs are literal records.
const cases = [
{
"label": "Tag a rate representation",
"input": {
"ratePercent": 10
},
"expected": {
"ok": true,
"value": {
"kind": "rate",
"percent": 10
}
}
},
{
"label": "Reject two representations",
"input": {
"ratePercent": 10,
"amountUnits": 20
},
"expected": {
"ok": false,
"error": "DISCOUNT_CONFLICT"
}
},
{
"label": "Preserve explicit fixed zero",
"input": {
"amountUnits": 0
},
"expected": {
"ok": true,
"value": {
"kind": "fixed",
"amountUnits": 0
}
}
}
];
for (const sample of cases) {
const actual = discountTag(sample.input);
assert.deepEqual(actual, sample.expected);
console.log(sample.label, JSON.stringify(actual));
}
判清邊界個案
amountUnits=0 為何不同於沒有折扣欄?
查看參考答案
明確定額 0 產生 {kind:"fixed",amountUnits:0},缺欄才產生 {kind:"none"}。種類保留來源選擇,尚未計最終價格。