Permalink
Browse files

unit tests + bug fixes galore!

  • Loading branch information...
1 parent 6e8d1fd commit 5d5423502ef4a6f62f65d391331ce06b5515dea5 @taijinlee committed May 25, 2012
Showing with 262 additions and 109 deletions.
  1. +3 −0 .gitignore
  2. +39 −21 humanize.js
  3. +33 −0 package.json
  4. +187 −0 specs/humanize.spec.js
  5. +0 −88 tests.html
View
@@ -0,0 +1,3 @@
+*~
+*.swp
+node_modules
View
@@ -11,9 +11,10 @@
var previousHumanize = root.humanize;
var humanize = {};
+ var undefinedString = 'undefined';
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
+ if (typeof exports !== undefinedString) {
+ if (typeof module !== undefinedString && module.exports) {
exports = module.exports = humanize;
}
exports.humanize = humanize;
@@ -45,7 +46,7 @@
* PHP-inspired date
*/
humanize.date = function(format, timestamp) {
- var jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided
+ var jsdate = ((typeof timestamp === undefinedString) ? new Date() : // Not provided
(timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
);
@@ -211,8 +212,8 @@
*/
humanize.numberFormat = function(number, decimals, decPoint, thousandsSep) {
decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
- decPoint = decPoint == undefined ? '.' : decPoint;
- thousandsSep = thousandsSep == undefined ? ',' : thousandsSep;
+ decPoint = (typeof decPoint === undefinedString) ? '.' : decPoint;
+ thousandsSep = (typeof thousandsSep === undefinedString) ? ',' : thousandsSep;
var sign = number < 0 ? '-' : '';
number = Math.abs(+number || 0)
@@ -235,8 +236,8 @@
* Any other day is formatted according to given argument or the DATE_FORMAT setting if no argument is given.
*/
humanize.naturalDay = function(timestamp, format) {
- timestamp = (timestamp === undefined) ? humanize.time() : timestamp;
- format = (format === undefined) ? 'Y-m-d' : format;
+ timestamp = (typeof timestamp === undefinedString) ? humanize.time() : timestamp;
+ format = (typeof format === undefinedString) ? 'Y-m-d' : format;
var oneDay = 86400;
var d = new Date();
@@ -277,8 +278,8 @@
* 18 Feb 2007 16:31:29 becomes 1 day from now.
*/
humanize.naturalTime = function(timestamp, format) {
- timestamp = (timestamp === undefined) ? humanize.time() : timestamp;
- format = (format === undefined) ? 'g:ia' : format;
+ timestamp = (typeof timestamp === undefinedString) ? humanize.time() : timestamp;
+ format = (typeof format === undefinedString) ? 'g:ia' : format;
var d = new Date();
var today = (new Date(d.getFullYear(), d.getMonth(), d.getDate())).getTime() / 1000;
@@ -340,8 +341,12 @@
* 3 becomes 3rd etc
*/
humanize.ordinal = function(number) {
- number = parseInt(number);
- return number > 4 && number < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[number % 10] || 'th';
+ number = parseInt(number, 10);
+ number = isNaN(number) ? 0 : number;
+ var sign = number < 0 ? '-' : '';
+ number = Math.abs(number);
+
+ return sign + number + (number > 4 && number < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[number % 10] || 'th');
};
/**
@@ -351,22 +356,25 @@
* If value is 123456789, the output would be 117.7 MB.
*/
humanize.filesize = function(filesize, kilo, decimals, decPoint, thousandsSep) {
- kilo = kilo == undefined ? 1024 : kilo;
+ kilo = (typeof kilo === undefinedString) ? 1024 : kilo;
decimals = isNaN(decimals) ? 2 : Math.abs(decimals);
- decPoint = decPoint == undefined ? '.' : decPoint;
- thousandsSep = thousandsSep == undefined ? ',' : thousandsSep;
+ decPoint = (typeof decPoint === undefinedString) ? '.' : decPoint;
+ thousandsSep = (typeof thousandsSep === undefinedString) ? ',' : thousandsSep;
if (filesize <= 0) { return '0 bytes'; }
var thresholds = [1];
var units = ['bytes', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'];
- if (filesize < kilo) { return humanize.numberFormat(filesize, 0) + units[0]; }
+ if (filesize < kilo) { return humanize.numberFormat(filesize, 0) + ' ' + units[0]; }
for (var i = 1; i < units.length; i++) {
thresholds[i] = thresholds[i-1] * kilo;
if (filesize < thresholds[i]) {
- return humanize.numberFormat(filesize / thresholds[i-1], decimals, decPoint, thousandsSep) + units[i];
+ return humanize.numberFormat(filesize / thresholds[i-1], decimals, decPoint, thousandsSep) + ' ' + units[i-1];
}
}
+
+ // use the last unit if we drop out to here
+ return humanize.numberFormat(filesize / thresholds[units.length - 1], decimals, decPoint, thousandsSep) + ' ' + units[units.length - 1];
};
/**
@@ -377,16 +385,26 @@
* If value is Joel\nis a\n\nslug, the output will be <p>Joel<br />is a</p><p>slug</p>
*/
humanize.linebreaks = function(str) {
- str = str.replace(/(\r\n|\n|\r){2}/gm, '</p><p>');
- str = str.replace(/(\r\n|\n|\r)/gm, '<br />');
+ // remove beginning and ending newlines
+ str = str.replace(/^([\n|\r]*)/, '');
+ str = str.replace(/([\n|\r]*)$/, '');
+
+ // normalize all to \n
+ str = str.replace(/(\r\n|\n|\r)/g, "\n");
+
+ // any consecutive new lines more than 2 gets turned into p tags
+ str = str.replace(/(\n{2,})/g, '</p><p>');
+
+ // any that are singletons get turned into br
+ str = str.replace(/\n/g, '<br />');
return '<p>' + str + '</p>';
};
/**
* Converts all newlines in a piece of plain text to HTML line breaks (<br />).
*/
humanize.nl2br = function(str) {
- return str.replace(/(\r\n|\n|\r)/gm, '<br />');
+ return str.replace(/(\r\n|\n|\r)/g, '<br />');
};
/**
@@ -395,7 +413,7 @@
*/
humanize.truncatechars = function(string, length) {
if (string.length <= length) { return string; }
- return string.substr(0, length - 1) + '';
+ return string.substr(0, length) + '';
};
/**
@@ -405,7 +423,7 @@
humanize.truncatewords = function(string, numWords) {
var words = string.split(' ');
if (words.length < numWords) { return string; }
- return words.slice(0, numWords) + '';
+ return words.slice(0, numWords).join(' ') + '';
};
}).call(this);
View
@@ -0,0 +1,33 @@
+{
+ "name": "humanize",
+ "description": "Javascript string formatter for human readability",
+ "homepage": "https://github.com/taijinlee/humanize",
+ "keywords": [
+ "util",
+ "client",
+ "browser"
+ ],
+ "author": {
+ "name": "Tai-Jin Lee",
+ "email": "taijin@gmail.com"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/taijinlee/humanize.git"
+ },
+ "main": "humanize.js",
+ "version": "0.0.1",
+ "_id": "humanize@0.0.1",
+ "dependencies": {},
+ "devDependencies": {
+ "mocha": "1.0.3",
+ "should": "0.6.3"
+ },
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "scripts": {
+ "test": "find specs -type f -a -name *.spec.js -exec ./node_modules/mocha/bin/mocha --globals requirejsVars -R list --require should {} \\;"
+ }
+}
View
@@ -0,0 +1,187 @@
+var should = require('should');
+
+var humanize = require('../humanize');
+
+describe('humanize:', function() {
+
+ describe('#time', function() {
+ it('should be able to get the current time', function() {
+ // I'm not sure how to make this better yet ...
+ parseInt(humanize.time()).should.equal(parseInt(new Date().getTime() / 1000, 10));
+ });
+ });
+
+ describe('#date', function() {
+ // this one is big ... fill in later ...
+ });
+
+
+ describe('#numberFormat', function() {
+ var number = 1234567.1234567;
+ var negNumber = -1234567.1234567;
+ it('should default using 2 decimals, "." as decimal point, "," as thousands separator', function() {
+ humanize.numberFormat(number).should.equal('1,234,567.12');
+ });
+
+ it('should be able to deal with different number of decimals properly + rounding', function() {
+ humanize.numberFormat(number, 0).should.equal('1,234,567');
+ humanize.numberFormat(number, 3).should.equal('1,234,567.123');
+ humanize.numberFormat(number, 4).should.equal('1,234,567.1235');
+ humanize.numberFormat(number, 5).should.equal('1,234,567.12346');
+ humanize.numberFormat(number, 6).should.equal('1,234,567.123457');
+ humanize.numberFormat(number, 7).should.equal('1,234,567.1234567');
+ humanize.numberFormat(number, 8).should.equal('1,234,567.12345670');
+ humanize.numberFormat(number, 9).should.equal('1,234,567.123456700');
+
+ humanize.numberFormat(negNumber, 0).should.equal('-1,234,567');
+ humanize.numberFormat(negNumber, 3).should.equal('-1,234,567.123');
+ humanize.numberFormat(negNumber, 4).should.equal('-1,234,567.1235');
+ humanize.numberFormat(negNumber, 5).should.equal('-1,234,567.12346');
+ humanize.numberFormat(negNumber, 6).should.equal('-1,234,567.123457');
+ humanize.numberFormat(negNumber, 7).should.equal('-1,234,567.1234567');
+ humanize.numberFormat(negNumber, 8).should.equal('-1,234,567.12345670');
+ humanize.numberFormat(negNumber, 9).should.equal('-1,234,567.123456700');
+ });
+
+ it('should be able to deal with negative decimals as if they were positive', function() {
+ humanize.numberFormat(number, -3).should.equal(humanize.numberFormat(number, 3));
+ });
+
+ it('should be able to change the decimal point to a different string', function() {
+ humanize.numberFormat(number, 3, 'P').should.equal('1,234,567P123');
+ humanize.numberFormat(number, 3, ',').should.equal('1,234,567,123');
+ humanize.numberFormat(number, 3, 'what?').should.equal('1,234,567what?123');
+ });
+
+ it('should be able to change the thousands separator to a different string', function() {
+ humanize.numberFormat(number, 3, '.', '.').should.equal('1.234.567.123');
+ humanize.numberFormat(number, 3, ',', '.').should.equal('1.234.567,123');
+ humanize.numberFormat(number, 3, '.', 'huh?').should.equal('1huh?234huh?567.123');
+ });
+ });
+
+ describe('#naturalDay', function() {
+ // fill in later...
+ });
+
+ describe('#naturalTime', function() {
+ // fill in later...
+ });
+
+ describe('#ordinal', function() {
+ it('should be able to return the correct ordinal string', function() {
+ var tests = {
+ 0: '0th',
+ 1: '1st',
+ 2: '2nd',
+ 3: '3rd',
+ 4: '4th',
+ 5: '5th',
+ 11: '11th',
+ 12: '12th',
+ 13: '13th',
+ 21: '21st',
+ 31: '31st',
+ 32: '32nd',
+ 43: '43rd',
+ '87 Street': '87th',
+ '223 APT 23': '223rd',
+ 'APT': '0th',
+ '-1': '-1st',
+ '-2': '-2nd',
+ '-3': '-3rd'
+ };
+
+ for (var num in tests) {
+ humanize.ordinal(num).should.equal(tests[num]);
+ }
+ });
+ });
+
+
+ describe('#filesize', function() {
+ it('should be able to use the defaults properly', function() {
+ humanize.filesize(12).should.equal('12 bytes');
+ humanize.filesize(1021).should.equal('1,021 bytes');
+ humanize.filesize(1024).should.equal('1.00 Kb');
+
+ humanize.filesize(Math.pow(1024, 2)).should.equal('1.00 Mb');
+ humanize.filesize(Math.pow(1024, 3)).should.equal('1.00 Gb');
+ humanize.filesize(Math.pow(1024, 4)).should.equal('1.00 Tb');
+ humanize.filesize(Math.pow(1024, 5)).should.equal('1.00 Pb');
+ humanize.filesize(Math.pow(1024, 6)).should.equal('1,024.00 Pb');
+ humanize.filesize(1234567890).should.equal('1.15 Gb');
+ });
+
+ it('should be able to change kilo to a different value', function() {
+ humanize.filesize(12, 1000).should.equal('12 bytes');
+ humanize.filesize(1021, 1000).should.equal('1.02 Kb');
+ humanize.filesize(1024, 1000).should.equal('1.02 Kb');
+ humanize.filesize(Math.pow(1024, 2), 1000).should.equal('1.05 Mb');
+ humanize.filesize(Math.pow(1024, 3), 1000).should.equal('1.07 Gb');
+ humanize.filesize(Math.pow(1024, 4), 1000).should.equal('1.10 Tb');
+ humanize.filesize(Math.pow(1024, 5), 1000).should.equal('1.13 Pb');
+ humanize.filesize(Math.pow(1024, 6), 1000).should.equal('1,152.92 Pb');
+ humanize.filesize(1234567890, 1000).should.equal('1.23 Gb');
+ });
+ });
+
+
+ describe('#linebreaks', function() {
+ it('should wrap the string with <p> tags', function() {
+ humanize.linebreaks('').should.equal('<p></p>');
+ });
+
+ it('should remove new lines at beginning and end', function() {
+ humanize.linebreaks("Foo\n\nBar\n\n\n").should.equal('<p>Foo</p><p>Bar</p>');
+ humanize.linebreaks("\n\r\n\rFoo\n\nBar").should.equal('<p>Foo</p><p>Bar</p>');
+ });
+
+ it('should change all new lines into <br> tags', function() {
+ humanize.linebreaks("Foo\nBar").should.equal('<p>Foo<br />Bar</p>');
+ humanize.linebreaks("Foo\nBar\r\nBlah").should.equal('<p>Foo<br />Bar<br />Blah</p>');
+ });
+
+ it('should change all multi-new lines into <p> tags', function() {
+ humanize.linebreaks("Foo\n\nBar").should.equal('<p>Foo</p><p>Bar</p>');
+ humanize.linebreaks("Foo\n\n\nBar").should.equal('<p>Foo</p><p>Bar</p>');
+ humanize.linebreaks("Foo\n\n\r\nBar").should.equal('<p>Foo</p><p>Bar</p>');
+ humanize.linebreaks("Foo\n\n\r\n\rBar").should.equal('<p>Foo</p><p>Bar</p>');
+ });
+ });
+
+ describe('#nl2br', function() {
+ it('should change any type of new line into a <br />', function() {
+ humanize.nl2br('').should.equal('');
+ humanize.nl2br("\n").should.equal('<br />');
+ humanize.nl2br("\r").should.equal('<br />');
+ humanize.nl2br("\r\n").should.equal('<br />');
+ humanize.nl2br("Foo\nBar").should.equal('Foo<br />Bar');
+ humanize.nl2br("\r\nFoo\nBar\n").should.equal('<br />Foo<br />Bar<br />');
+ humanize.nl2br("\r\r\n\nFoo\nBar\n\n\r\n\r").should.equal('<br /><br /><br />Foo<br />Bar<br /><br /><br /><br />');
+ });
+ });
+
+ describe('#truncatechars', function() {
+ it('should be able to truncate characters properly', function() {
+ humanize.truncatechars('foobar', 0).should.equal('');
+ humanize.truncatechars('foobar', 1).should.equal('f…');
+ humanize.truncatechars('foobar', 2).should.equal('fo…');
+ humanize.truncatechars('foobar', 3).should.equal('foo…');
+ humanize.truncatechars('foobar', 4).should.equal('foob…');
+ });
+ });
+
+ describe('#truncatewords', function() {
+ it('should be able to truncate words properly', function() {
+ humanize.truncatewords('a b c d e', 0).should.equal('');
+ humanize.truncatewords('a b c d e', 1).should.equal('a…');
+ humanize.truncatewords('a b c d e', 2).should.equal('a b…');
+ humanize.truncatewords('a b c d e', 3).should.equal('a b c…');
+ humanize.truncatewords('a b c d e', 4).should.equal('a b c d…');
+ });
+ });
+
+
+
+});
Oops, something went wrong.

0 comments on commit 5d54235

Please sign in to comment.