From 791bf255f53b6e21bf1faa27f0856e2e493cfc39 Mon Sep 17 00:00:00 2001 From: tryan Date: Sat, 9 May 2020 17:31:46 +1100 Subject: [PATCH] handle negative numbers in parens --- bits/82_eval.js | 12 +++++----- test/negative.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 test/negative.js diff --git a/bits/82_eval.js b/bits/82_eval.js index cf750c9..f6aa85d 100644 --- a/bits/82_eval.js +++ b/bits/82_eval.js @@ -60,7 +60,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { } /* falls through */ case '0': case '#': - o = c; while((++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) || (c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1)) o += c; + o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c; out[out.length] = {t:'n', v:o}; break; case '?': o = c; while(fmt.charAt(++i) === c) o+=c; @@ -119,7 +119,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { /*::if(!dt) throw "unreachable"; */ out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); out[i].t = 't'; break; - case 'n': case '(': case '?': + case 'n': case '?': jj = i+1; while(out[jj] != null && ( (c=out[jj].t) === "?" || c === "D" || @@ -139,7 +139,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { if(nstr.length > 0) { if(nstr.charCodeAt(0) == 40) /* '(' */ { myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); - ostr = write_num('(', nstr, myv); + ostr = write_num('n', nstr, myv); } else { myv = (v<0 && flen > 1 ? -v : v); ostr = write_num('n', nstr, myv); @@ -154,7 +154,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { var lasti=out.length; if(decpt === out.length && ostr.indexOf("E") === -1) { for(i=out.length-1; i>= 0;--i) { - if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; + if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } else if(jj < 0) out[i].v = ""; else { out[i].v = ostr.substr(0, jj+1); jj = -1; } @@ -166,7 +166,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { else if(decpt !== out.length && ostr.indexOf("E") === -1) { jj = ostr.indexOf(".")-1; for(i=decpt; i>= 0; --i) { - if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; + if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue; j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; vv = out[i].v.substr(j+1); for(; j>=0; --j) { @@ -191,7 +191,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { } } } - for(i=0; i-1) { + for(i=0; i-1) { myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); out[i].v = write_num(out[i].t, out[i].v, myv); out[i].t = 't'; diff --git a/test/negative.js b/test/negative.js new file mode 100644 index 0000000..c2c95c5 --- /dev/null +++ b/test/negative.js @@ -0,0 +1,57 @@ +/* vim: set ts=2: */ +/*jshint loopfunc:true, mocha:true, node:true */ +/*eslint-env mocha */ +var SSF = require('../'); +var assert = require('assert'); + +/* {format, data:[[value, result]]} */ +var data = [ + { + format: '"$"#,##0_);\\("$"#,##0\\);"-"', + data: [ + [10000, "$10,000 "], + [9000.98, "$9,001 "], + [100, "$100 "], + [50.02, "$50 "], + [1, "$1 "], + [0.1, "$0 "], + [0.01, "$0 "], + [0, "-"], + [-10000, "($10,000)"], + [-9000.98, "($9,001)"], + [-100, "($100)"], + [-50.02, "($50)"], + [-1, "($1)"], + [-0.1, "($0)"], + [-0.01, "($0)"] + ] + }, + { + format: '(#,##0.00)', + data: [ + [-12345.6789, "-(12,345.68)"] + ] + }, + { + format: '#,##0.00;\\(#,##0.00\\)', + data: [ + [-12345.6789, "(12,345.68)"] + ] + }, + { + format: '[<=9999999]###\\-####;(###) ###\\-####', + data: [ + [2813308004, '(281) 330-8004'] + ] + } +]; + +describe("negatives", function() { + data.forEach(function(row) { + it(row.format, function() { + row.data.forEach(function(r) { + assert.equal(SSF.format(row.format, r[0]), r[1]); + }); + }); + }); +});