Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions spec/formatnumber_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
local jsonata = require("jsonata")
local function run(src, input)
return jsonata.compile(src):evaluate(input)
end

describe("M8a: $formatBase rounds (half-even), not floors", function()
it("$formatBase(99.5, 2.5) rounds 99.5->100 and 2.5->2", function()
assert.are.equal("1100100", run("$formatBase(99.5, 2.5)"))
end)
it("existing cases unchanged", function()
assert.are.equal("100", run("$formatBase(100)"))
assert.are.equal("1100100", run("$formatBase(100, 2)"))
assert.are.equal("-1100100", run("$formatBase(-100, 2)"))
assert.are.equal("2s", run("$formatBase(100, 36)"))
assert.are.equal("5890840712243076", run("$formatBase(big_id)", { big_id = 5890840712243076 }))
end)
it("radix out of range -> D3100", function()
local ok, err = pcall(run, "$formatBase(100, 37)")
assert.is_false(ok)
assert.are.equal("D3100", err.code)
end)
end)

describe("M8a: $formatNumber decimal-format picture", function()
it("grouping + mandatory decimals", function()
assert.are.equal("12,345.60", run('$formatNumber(12345.6, "#,###.00")'))
assert.are.equal("12,345,678.90", run('$formatNumber(12345678.9, "9,999.99")'))
end)
it("irregular grouping positions", function()
assert.are.equal("1,234.567,890", run('$formatNumber(1234.56789, "9,999.999,999")'))
end)
it("mandatory-digit padding", function()
assert.are.equal("0124", run('$formatNumber(123.9, "9999")'))
assert.are.equal("-006", run('$formatNumber(-6, "000")'))
end)
it("percent and per-mille (default + custom symbol)", function()
assert.are.equal("14%", run('$formatNumber(0.14, "01%")'))
assert.are.equal("485.7‰", run('$formatNumber(0.4857, "###.###‰")'))
assert.are.equal("140pm", run('$formatNumber(0.14, "###pm", {"per-mille": "pm"})'))
end)
it("exponent notation", function()
assert.are.equal("12.346e2", run('$formatNumber(1234.5678, "00.000e0")'))
assert.are.equal("12.346e002", run('$formatNumber(1234.5678, "00.000e000")'))
assert.are.equal("2.3e-1", run('$formatNumber(0.234, "0.0e0")'))
assert.are.equal("0.23e0", run('$formatNumber(0.234, "#.00e0")'))
end)
it("unicode digit family via zero-digit option", function()
-- oracle (jsonata v2.2.1) emits 23.457e3 in the U+2460 family for this input
assert.are.equal("②③.④⑤⑦e③", run('$formatNumber(1234.5678, "①①.①①①e①", {"zero-digit": "①"})'))
end)
it("undefined input -> undefined", function()
assert.is_nil(run('$formatNumber(blah, "0")', {}))
end)
end)

describe("M8a fixes: large-integer rounding fidelity", function()
it("$formatNumber preserves 13+ significant digits", function()
assert.are.equal("1234567890123", run('$formatNumber(1234567890123, "0")'))
assert.are.equal("9999999999999", run('$formatNumber(9999999999999, "0")'))
assert.are.equal("12345678901.23", run('$formatNumber(12345678901.23, "0.00")'))
end)
it("$round preserves 13-digit integers", function()
assert.are.equal(1234567890123, run("$round(1234567890123)"))
assert.are.equal(4.52, run("$round(4.525, 2)"))
assert.are.equal(2, run("$round(2.5)"))
assert.are.equal(4, run("$round(3.5)"))
end)
it("$formatBase preserves large integers", function()
assert.are.equal("5890840712243076", run("$formatBase(big_id)", { big_id = 5890840712243076 }))
assert.are.equal("1234567890123", run("$formatBase(1234567890123)"))
end)
end)
describe("M8a fixes: error messages match oracle", function()
it("D3080 message is the sub-picture-count message", function()
local ok, err = pcall(run, '$formatNumber(20, "#;#;#")')
assert.is_false(ok)
assert.are.equal("D3080", err.code)
assert.is_truthy(err.message and err.message:find("two sub%-pictures"))
end)
end)
28 changes: 28 additions & 0 deletions spec/jsonata-suite/baseline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,31 @@ return {
["function-formatBase/case002"] = true,
["function-formatBase/case003"] = true,
["function-formatBase/case004"] = true,
["function-formatBase/case005"] = true,
["function-formatBase/case006"] = true,
["function-formatBase/case007"] = true,
["function-formatBase/case008"] = true,
["function-formatInteger/formatInteger/15"] = true,
["function-formatInteger/formatInteger/64"] = true,
["function-formatNumber/case000"] = true,
["function-formatNumber/case001"] = true,
["function-formatNumber/case002"] = true,
["function-formatNumber/case003"] = true,
["function-formatNumber/case004"] = true,
["function-formatNumber/case005"] = true,
["function-formatNumber/case006"] = true,
["function-formatNumber/case007"] = true,
["function-formatNumber/case008"] = true,
["function-formatNumber/case009"] = true,
["function-formatNumber/case010"] = true,
["function-formatNumber/case011"] = true,
["function-formatNumber/case012"] = true,
["function-formatNumber/case013"] = true,
["function-formatNumber/case014"] = true,
["function-formatNumber/case015"] = true,
["function-formatNumber/case016"] = true,
["function-formatNumber/case017"] = true,
["function-formatNumber/case018"] = true,
["function-formatNumber/case019"] = true,
["function-formatNumber/case020"] = true,
["function-formatNumber/case021"] = true,
Expand All @@ -440,6 +460,14 @@ return {
["function-formatNumber/case030"] = true,
["function-formatNumber/case031"] = true,
["function-formatNumber/case032"] = true,
["function-formatNumber/case033"] = true,
["function-formatNumber/case034"] = true,
["function-formatNumber/case035"] = true,
["function-formatNumber/case036"] = true,
["function-formatNumber/issue785/0"] = true,
["function-formatNumber/issue785/1"] = true,
["function-formatNumber/issue785/2"] = true,
["function-formatNumber/issue785/3"] = true,
["function-formatNumber/issue786/0"] = true,
["function-formatNumber/issue786/1"] = true,
["function-formatNumber/issue786/2"] = true,
Expand Down
14 changes: 14 additions & 0 deletions src/jsonata/errors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ local MESSAGES = {
D3060 = "$sqrt of a number that is less than zero",
D3070 = "The single argument of the $sort function must be an array of strings or numbers. Use a comparator function to sort other types.",
D3100 = "The radix of $formatBase must be between 2 and 36",
D3080 = "The picture string must only contain a maximum of two sub-pictures",
D3081 = "The sub-picture must not contain more than one instance of the 'decimal-separator' character",
D3082 = "The sub-picture must not contain more than one instance of the 'percent' character",
D3083 = "The sub-picture must not contain more than one instance of the 'per-mille' character",
D3084 = "The sub-picture must not contain both a 'percent' and a 'per-mille' character",
D3085 = "The mantissa part of a sub-picture must contain at least one character that is either an 'optional digit character' or a member of the 'decimal digit family'",
D3086 = "The sub-picture must not contain a passive character that is preceded by an active character and that is followed by another active character",
D3087 = "The sub-picture must not contain a 'grouping-separator' character that appears adjacent to a 'decimal-separator' character",
D3088 = "The sub-picture must not contain a 'grouping-separator' at the end of the integer part",
D3089 = "The sub-picture must not contain two adjacent instances of the 'grouping-separator' character",
D3090 = "The integer part of the sub-picture must not contain a member of the 'decimal digit family' that is followed by an instance of the 'optional digit character'",
D3091 = "The fractional part of the sub-picture must not contain an instance of the 'optional digit character' that is followed by a member of the 'decimal digit family'",
D3092 = "A sub-picture that contains a 'percent' or 'per-mille' character must not contain a character treated as an 'exponent-separator'",
D3093 = "The exponent part of the sub-picture must comprise only of one or more characters that are members of the 'decimal digit family'",
D3137 = "$error() function evaluated",
D3138 = "The single() function expected exactly 1 matching result. Instead it matched more.",
D3139 = "The single() function expected exactly 1 matching result. Instead it matched 0.",
Expand Down
Loading
Loading