Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

tests passing after internal rewrite

  • Loading branch information...
commit 817b54bc86325da06f136fa4a873c44756e1b4a8 1 parent 55cca69
@stuarthalloway authored
View
246 public/javascripts/jquery.numberformatter-1.1.2.js
@@ -122,10 +122,26 @@
str = str + padding;
}
return str;
- };
+ };
+ nf.times100 = function(str) {
+ var result = str + "00";
+ var dotIndex = result.indexOf('.');
+ if (dotIndex != -1) {
+ result = result.substring(0,dotIndex) + result.substring(dotIndex+1, dotIndex+3) + "." + result.substring(dotIndex+3);
+ }
+ return result;
+ }
nf.countDecimalDigits = function(format) {
- var match = format.match(/\.[#0]+/)
+ var match = format.match(/\.[#0]+0/)
+ if (match) {
+ return match[0].length - 1;
+ }
+ return 0;
+ };
+
+ nf.countOptionalDecimalDigits = function(format) {
+ var match = format.match(/\.[#0]/)
if (match) {
return match[0].length - 1;
}
@@ -145,6 +161,7 @@
// make a special case for the negative sign "-" though, so
// we can have formats like -$23.32
nf.normalizeOptions = function(options) {
+ var options = jQuery.extend({},jQuery.fn.format.defaults, options);
var match = /^(-?)([^-0#,.]*)([-0#,.]*)([^-0#,.]*)$/.exec(options.format)
if (!match) throw "invalid number format " + options.format;
options.negativeInFront = (match[1] == "-");
@@ -152,20 +169,42 @@
options.format = match[3];
options.suffix = match[4];
options.decimalDigits = nf.countDecimalDigits(options.format);
- options.digitsPerGroup = nf.countDigitsPerGroup(options.format);
+ options.optionalDecimalDigits = nf.countOptionalDecimalDigits(options.format);
+ options.digitsPerGroup = nf.countDigitsPerGroup(options.format);
+
+ var formatData = formatCodes(options.locale.toLowerCase());
+ options.dec = formatData.dec;
+ options.group = formatData.group;
+ options.neg = formatData.neg;
+ return options;
};
- nf.formatNumber = function(str, options) {
- var left_right = str.split(".");
- var left = left_right[0];
- var right = left_right[1];
- options.decimalDigits = options.decimalDigits || 0;
+ // called only by formatNumber
+ // inserts grouping punctuation, e.g. 12345 => 12,345
+ nf.formatLeft = function(left, options) {
if (options.digitsPerGroup) {
- left = s.reverse(s.join(s.partition(s.reverse(left), options.digitsPerGroup, options.digitsPerGroup), options.group));
- }
- var result = (left +
- "." +
- nf.pad(right.substring(0, options.decimalDigits), options.decimalDigits, "0")
+ return s.reverse(s.join(s.partition(s.reverse(left), options.digitsPerGroup, options.digitsPerGroup), options.group));
+ }
+ return left;
+ }
+
+ // called only by formatNumber, which finishes the job by rounding if necessary
+ // truncates to the correct amount of digits, possibly padding with 0 on the right
+ nf.formatRight = function(right, options) {
+ var digits = Math.max(options.decimalDigits,
+ Math.min(options.optionalDecimalDigits || 0, right.length));
+ console.log("" + right + " " + options.decimalDigits + " " + options.optionalDecimalDigits + " " + right.length);
+ return nf.pad(right.substring(0, digits), digits, "0");
+ }
+
+ nf.formatNumber = function(str, options) {
+ var match = str.split(/^(-?)(\d*)\.?(\d*?)0*$/);
+ var sign = match[1];
+ var left = match[2];
+ var right = match[3];
+ var result = (nf.formatLeft(left, options) +
+ options.dec +
+ nf.formatRight(right, options)
).replace(/\.$/, "");
if (right.charAt(options.decimalDigits).match(/[5-9]/)) {
//need to round up
@@ -274,144 +313,59 @@
return array;
};
- jQuery.fn.valOrText = function() {
- return (jQuery(this).is(":input") ? jQuery.fn.val : jQuery.fn.text).apply(this,arguments);
- };
+ jQuery.fn.valOrText = function() {
+ return (jQuery(this).is(":input") ? jQuery.fn.val : jQuery.fn.text).apply(this,arguments);
+ };
- jQuery.fn.format = function(options) {
-
- var options = jQuery.extend({},jQuery.fn.format.defaults, options);
- nf.normalizeOptions(options);
-
- var formatData = formatCodes(options.locale.toLowerCase());
-
- var dec = formatData.dec;
- var group = formatData.group;
- var neg = formatData.neg;
+ jQuery.fn.format = function(options) {
- return this.each(function(){
+ options = nf.normalizeOptions(options);
- var text = new String(jQuery(this).valOrText());
-
- // now we need to convert it into a number
- // technical debt: what happens to numbers with more than one decimal or negative sign?
- var number = parseFloat(text.replace(new RegExp('[' + group + ']', "g"), "")
- .replace(dec,".")
- .replace(neg,"-"), 10);
+ return this.each(function(){
- // special case for percentages
- if (options.suffix == "%")
- number = number * 100;
+ var text = new String(jQuery(this).valOrText());
- var returnString = "";
+ text = text.replace(new RegExp('[' + options.group + ']', "g"), "")
+ .replace(options.dec,".")
+ .replace(options.neg,"-");
- var decimalValue = number % 1;
- if (options.format.indexOf(".") > -1)
- {
- var decimalPortion = dec;
- var decimalFormat = options.format.substring(options.format.lastIndexOf(".")+1);
- var decimalString = new String(decimalValue.toFixed(decimalFormat.length));
- decimalString = decimalString.substring(decimalString.lastIndexOf(".")+1);
- for (var i=0; i<decimalFormat.length; i++)
- {
- if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) != '0')
- {
- decimalPortion += decimalString.charAt(i);
- continue;
- }
- else if (decimalFormat.charAt(i) == '#' && decimalString.charAt(i) == '0')
- {
- var notParsed = decimalString.substring(i);
- if (notParsed.match('[1-9]'))
- {
- decimalPortion += decimalString.charAt(i);
- continue;
- }
- else
- {
- break;
- }
- }
- else if (decimalFormat.charAt(i) == "0")
- {
- decimalPortion += decimalString.charAt(i);
- }
- }
- returnString += decimalPortion
- }
- else
- number = Math.round(number);
-
- var ones = Math.floor(number);
- if (number < 0)
- ones = Math.ceil(number);
-
- var onePortion = "";
- if (ones == 0)
- {
- onePortion = "0";
- }
- else
- {
- // find how many digits are in the group
- var onesFormat = "";
- if (options.format.indexOf(".") == -1)
- onesFormat = options.format;
- else
- onesFormat = options.format.substring(0, options.format.indexOf("."));
- var oneText = new String(Math.abs(ones));
- var groupLength = 9999;
- if (onesFormat.lastIndexOf(",") != -1)
- groupLength = onesFormat.length - onesFormat.lastIndexOf(",")-1;
- var groupCount = 0;
- for (var i=oneText.length-1; i>-1; i--)
- {
- onePortion = oneText.charAt(i) + onePortion;
-
- groupCount++;
-
- if (groupCount == groupLength && i!=0)
- {
- onePortion = group + onePortion;
- groupCount = 0;
- }
-
- }
- }
- returnString = onePortion + returnString;
-
- // handle special case where negative is in front of the invalid
- // characters
- if (number < 0 && options.negativeInFront && options.prefix.length > 0)
- {
- options.prefix = neg + options.prefix;
+ // special case for percentages
+ if (options.suffix == "%") {
+ text = nf.times100(text);
+ }
+
+ var negative = parseFloat(text, 10) < 0;
+ var returnString = nf.formatNumber(text, options).replace(/^-/,"");
+
+ // handle special case where negative is in front of the invalid characters
+ if (negative) {
+ if (options.negativeInFront && options.prefix.length > 0) {
+ options.prefix = options.neg + options.prefix;
+ } else {
+ returnString = options.neg + returnString;
}
- else if (number < 0)
- {
- returnString = neg + returnString;
+ }
+
+ if (options.decimalSeparatorAlwaysShown) {
+ if (returnString.indexOf(options.dec) == -1) {
+ returnString = returnString + options.dec;
}
-
- if (! options.decimalSeparatorAlwaysShown) {
- if (returnString.lastIndexOf(dec) == returnString.length - 1) {
- returnString = returnString.substring(0, returnString.length - 1);
- }
- }
- returnString = options.prefix + returnString + options.suffix;
-
- jQuery(this).valOrText(returnString);
- });
- };
-
- jQuery.fn.parse.defaults = {
- locale: "us",
- decimalSeparatorAlwaysShown: false
- };
-
- jQuery.fn.format.defaults = {
- format: "#,###.00",
- locale: "us",
- decimalSeparatorAlwaysShown: false
- };
-
-
- })(jQuery);
+ }
+
+ returnString = options.prefix + returnString + options.suffix;
+
+ jQuery(this).valOrText(returnString);
+ });
+ };
+
+ jQuery.fn.parse.defaults = {
+ locale: "us",
+ decimalSeparatorAlwaysShown: false
+ };
+
+ jQuery.fn.format.defaults = {
+ format: "#,###.00",
+ locale: "us",
+ decimalSeparatorAlwaysShown: false
+ };
+})(jQuery);
View
42 test/javascript/numberformatter_spec.js
@@ -6,20 +6,34 @@ Screw.Unit(function(){
it("detects required decimal zeros", function() {
var options = {format: "##.###0CRAP"}
- $.numberFormatter.normalizeOptions(options);
- expect(options.decimalDigits).to(equal, 4);
+ expect($.numberFormatter.normalizeOptions(options).decimalDigits).to(equal, 4);
+ });
+
+ it("ignores pure optional zeros", function() {
+ var options = {format: "##.###"}
+ expect($.numberFormatter.normalizeOptions(options).decimalDigits).to(equal, 0);
});
it("detects absence digit groups", function() {
var options = {format: "##"}
- $.numberFormatter.normalizeOptions(options);
- expect(options.digitsPerGroup).to(equal, null);
+ expect($.numberFormatter.normalizeOptions(options).digitsPerGroup).to(equal, null);
});
it("detects presence of digit groups", function() {
var options = {format: "#,#####"}
- $.numberFormatter.normalizeOptions(options);
- expect(options.digitsPerGroup).to(equal, 5);
+ expect($.numberFormatter.normalizeOptions(options).digitsPerGroup).to(equal, 5);
+ });
+
+ });
+
+ describe("times100",function() {
+
+ it ("works without decimal point", function() {
+ expect($.numberFormatter.times100("10")).to(equal, "1000");
+ });
+
+ it ("works with decimal point", function() {
+ expect($.numberFormatter.times100("3.14159")).to(equal, "314.15900");
});
});
@@ -39,23 +53,23 @@ Screw.Unit(function(){
describe("numberFormatter.formatNumber", function() {
it("handles zero format digits", function() {
- expect($.numberFormatter.formatNumber("123.45", {decimalDigits: 0})).to(equal, "123");
+ expect($.numberFormatter.formatNumber("123.45", {decimalDigits: 0, dec: "."})).to(equal, "123");
});
it("handles a few format digits", function() {
- expect($.numberFormatter.formatNumber("0.0136", {decimalDigits: 2})).to(equal, "0.01");
+ expect($.numberFormatter.formatNumber("0.0136", {decimalDigits: 2, dec: "."})).to(equal, "0.01");
});
it("handles a lot of format digits", function() {
- expect($.numberFormatter.formatNumber("1.01234567890001", {decimalDigits: 14})).to(equal, "1.01234567890001");
+ expect($.numberFormatter.formatNumber("1.01234567890001", {decimalDigits: 14, dec: "."})).to(equal, "1.01234567890001");
});
it("handles more format digits than actual digits", function() {
- expect($.numberFormatter.formatNumber("1.5", {decimalDigits: 8})).to(equal, "1.50000000");
+ expect($.numberFormatter.formatNumber("1.5", {decimalDigits: 8, dec: "."})).to(equal, "1.50000000");
});
it("rounds correctly", function() {
- expect($.numberFormatter.formatNumber("1.875", {decimalDigits: 2})).to(equal, "1.88");
+ expect($.numberFormatter.formatNumber("1.875", {decimalDigits: 2, dec: "."})).to(equal, "1.88");
});
});
@@ -98,10 +112,10 @@ Screw.Unit(function(){
});
describe("format", function(){
- it("does not work with numbers with higher precision than floats", function(){
+ it("works with numbers with higher precision than floats", function(){
$("#value").text("123456789.9876543210123456789");
$("#value").format({format: "##.0000000000000000000"});
- expect($("#value").text()).to_not(equal, "123456789.9876543210123456789");
+ expect($("#value").text()).to(equal, "123456789.9876543210123456789");
});
it("defaults to us #,###.00", function(){
@@ -139,7 +153,7 @@ Screw.Unit(function(){
expect(function () {$("#value").format({format: "## AND ##"})}).to(throw_object, "invalid number format ## AND ##");
});
- it("default to not show decimal for whole numbers", function(){
+ it("defaults to not show decimal for whole numbers", function(){
$("#value").text("15");
$("#value").format({format: "#.##"});
expect($("#value").text()).to(equal, "15");
Please sign in to comment.
Something went wrong with that request. Please try again.