From d0a3d15c81d59b6da4b53911b2e88aaf58543b4f Mon Sep 17 00:00:00 2001 From: taylorhakes Date: Sat, 13 Feb 2016 10:50:07 -0500 Subject: [PATCH] 100% test coverage. Throw error on invalid date. Updated to 2.0.0 --- .gitignore | 3 ++- CHANGELOG.md | 2 ++ Gulpfile.js | 12 ----------- bower.json | 2 +- fecha.js | 3 ++- fecha.min.js | 2 +- karma.conf.js | 56 --------------------------------------------------- package.json | 12 +++++------ test.js | 7 +++++++ 9 files changed, 21 insertions(+), 78 deletions(-) create mode 100644 CHANGELOG.md delete mode 100644 Gulpfile.js delete mode 100644 karma.conf.js diff --git a/.gitignore b/.gitignore index 3091757..1f5514c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -coverage \ No newline at end of file +coverage +.nyc_output \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..52e1e15 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2 @@ +## 2.0.0 +Fecha now throws errors on invalid dates in `fecha.format` and is stricter about what dates it accepts. Dates must pass `Object.prototype.toString.call(dateObj) !== '[object Date]'`. diff --git a/Gulpfile.js b/Gulpfile.js deleted file mode 100644 index 8215cd8..0000000 --- a/Gulpfile.js +++ /dev/null @@ -1,12 +0,0 @@ -var uglify = require('gulp-uglify'), - gulp = require('gulp'), - rename = require('gulp-rename'); - -gulp.task('build', function () { - gulp.src('fecha.js') - .pipe(uglify()) - .pipe(rename(function (path) { - path.extname = ".min.js" - })) - .pipe(gulp.dest('./')) -}); diff --git a/bower.json b/bower.json index 091a1bb..2244366 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "fecha", "main": "fecha.js", - "version": "1.2.0", + "version": "2.0.0", "homepage": "https://github.com/taylorhakes/fecha", "authors": [ "Taylor Hakes" diff --git a/fecha.js b/fecha.js index 3919ae5..bb53729 100644 --- a/fecha.js +++ b/fecha.js @@ -142,7 +142,7 @@ dateObj = new Date(dateObj); } - if (!dateObj || typeof dateObj !== 'object' && typeof dateObj.getDate !== 'function') { + if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) { throw new Error('Invalid Date in fecha.format'); } @@ -256,6 +256,7 @@ return date; }; + /* istanbul ignore next */ if (typeof module !== 'undefined' && module.exports) { module.exports = fecha; } else if (typeof define === 'function' && define.amd) { diff --git a/fecha.min.js b/fecha.min.js index 741fe62..1b81832 100644 --- a/fecha.min.js +++ b/fecha.min.js @@ -1 +1 @@ -!function(e){"use strict";function n(e){return function(n,t){var o=i.i18n[e].indexOf(t.charAt(0).toUpperCase()+t.substr(1).toLowerCase());~o&&(n.month=o)}}function t(e,n){for(e=String(e),n=n||2;e.lengtho;o++)t.push(e[o].substr(0,n));return t}function a(e){return e+["th","st","nd","rd"][e%10>3?0:(e-e%10!==10)*e%10]}var r,u,i={},s=/d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,d=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],m=["January","February","March","April","May","June","July","August","September","October","November","December"],f=["am","pm"],h=/\d\d?/,c=/\d{3}/,l=/\d{4}/,M=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Y=function(){},D={D:[h,function(e,n){e.day=n}],M:[h,function(e,n){e.month=n-1}],YY:[h,function(e,n){var t=new Date,o=+(""+t.getFullYear()).substr(0,2);e.year=""+(n>68?o-1:o)+n}],h:[h,function(e,n){e.hour=n}],m:[h,function(e,n){e.minute=n}],s:[h,function(e,n){e.second=n}],YYYY:[l,function(e,n){e.year=n}],S:[/\d/,function(e,n){e.millisecond=100*n}],SS:[/\d{2}/,function(e,n){e.millisecond=10*n}],SSS:[c,function(e,n){e.millisecond=n}],d:[h,Y],ddd:[M,Y],MMM:[M,n("monthNamesShort")],MMMM:[M,n("monthNames")],a:[M,function(e,n){var t=n.toLowerCase();t===f[0]?e.isPm=!1:t===f[1]&&(e.isPm=!0)}],ZZ:[/[\+\-]\d\d:?\d\d/,function(e,n){var t,o=(n+"").match(/([\+\-]|\d\d)/gi);o&&(t=+(60*o[1])+parseInt(o[2],10),e.timezoneOffset="+"===o[0]?t:-t)}]};D.dd=D.d,D.dddd=D.ddd,D.Do=D.DD=D.D,D.mm=D.m,D.hh=D.H=D.HH=D.h,D.MM=D.M,D.ss=D.s,D.A=D.a,u=o(m,3),r=o(d,3),i.i18n={dayNamesShort:r,dayNames:d,monthNamesShort:u,monthNames:m,amPm:f,DoFn:a},i.masks={"default":"ddd MMM DD YYYY HH:mm:ss",shortDate:"M/D/YY",mediumDate:"MMM D, YYYY",longDate:"MMMM D, YYYY",fullDate:"dddd, MMMM D, YYYY",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},i.format=function(e,n){if("number"==typeof e&&(e=new Date(e)),!e||"object"!=typeof e&&"function"!=typeof e.getDate)throw new Error("Invalid Date in fecha.format");n=i.masks[n]||n||i.masks["default"];var o=e.getDate(),a=e.getDay(),r=e.getMonth(),u=e.getFullYear(),d=e.getHours(),m=e.getMinutes(),f=e.getSeconds(),h=e.getMilliseconds(),c=e.getTimezoneOffset(),l={D:o,DD:t(o),Do:i.i18n.DoFn(o),d:a,dd:t(a),ddd:i.i18n.dayNamesShort[a],dddd:i.i18n.dayNames[a],M:r+1,MM:t(r+1),MMM:i.i18n.monthNamesShort[r],MMMM:i.i18n.monthNames[r],YY:String(u).slice(2),YYYY:u,h:d%12||12,hh:t(d%12||12),H:d,HH:t(d),m:m,mm:t(m),s:f,ss:t(f),S:Math.round(h/100),SS:t(Math.round(h/10),2),SSS:t(h,3),a:12>d?i.i18n.amPm[0]:i.i18n.amPm[1],A:12>d?i.i18n.amPm[0].toUpperCase():i.i18n.amPm[1].toUpperCase(),ZZ:(c>0?"-":"+")+t(100*Math.floor(Math.abs(c)/60)+Math.abs(c)%60,4)};return n.replace(s,function(e){return e in l?l[e]:e.slice(1,e.length-1)})},i.parse=function(e,n){var t,o,a,r,u,d;if("string"!=typeof n)throw new Error("Invalid format in fecha.parse");return n=i.masks[n]||n,e.length>1e3?!1:(t=!0,o={},n.replace(s,function(n){return D[n]&&(u=D[n],d=e.search(u[0]),~d?e.replace(u[0],function(n){return u[1](o,n),e=e.substr(d+n.length),n}):t=!1),D[n]?"":n.slice(1,n.length-1)}),t?(a=new Date,o.isPm===!0&&null!=o.hour&&12!==+o.hour?o.hour=+o.hour+12:o.isPm===!1&&12===+o.hour&&(o.hour=0),null!=o.timezoneOffset?(o.minute=+(o.minute||0)-+o.timezoneOffset,r=new Date(Date.UTC(o.year||a.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0))):r=new Date(o.year||a.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0),r):!1)},"undefined"!=typeof module&&module.exports?module.exports=i:"function"==typeof define&&define.amd?define(function(){return i}):e.fecha=i}(this); \ No newline at end of file +(function(e){"use strict";var t={},n=/d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,a=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],r=["January","February","March","April","May","June","July","August","September","October","November","December"],i=["am","pm"],o=/\d\d?/,u=/\d{3}/,s=/\d{4}/,m=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,d=function(){},f,l,h={D:[o,function(e,t){e.day=t}],M:[o,function(e,t){e.month=t-1}],YY:[o,function(e,t){var n=new Date,a=+(""+n.getFullYear()).substr(0,2);e.year=""+(t>68?a-1:a)+t}],h:[o,function(e,t){e.hour=t}],m:[o,function(e,t){e.minute=t}],s:[o,function(e,t){e.second=t}],YYYY:[s,function(e,t){e.year=t}],S:[/\d/,function(e,t){e.millisecond=t*100}],SS:[/\d{2}/,function(e,t){e.millisecond=t*10}],SSS:[u,function(e,t){e.millisecond=t}],d:[o,d],ddd:[m,d],MMM:[m,c("monthNamesShort")],MMMM:[m,c("monthNames")],a:[m,function(e,t){var n=t.toLowerCase();if(n===i[0]){e.isPm=false}else if(n===i[1]){e.isPm=true}}],ZZ:[/[\+\-]\d\d:?\d\d/,function(e,t){var n=(t+"").match(/([\+\-]|\d\d)/gi),a;if(n){a=+(n[1]*60)+parseInt(n[2],10);e.timezoneOffset=n[0]==="+"?a:-a}}]};h.dd=h.d;h.dddd=h.ddd;h.Do=h.DD=h.D;h.mm=h.m;h.hh=h.H=h.HH=h.h;h.MM=h.M;h.ss=h.s;h.A=h.a;l=Y(r,3);f=Y(a,3);function c(e){return function(n,a){var r=t.i18n[e].indexOf(a.charAt(0).toUpperCase()+a.substr(1).toLowerCase());if(~r){n.month=r}}}function M(e,t){e=String(e);t=t||2;while(e.length3?0:(e-e%10!==10)*e%10]}t.i18n={dayNamesShort:f,dayNames:a,monthNamesShort:l,monthNames:r,amPm:i,DoFn:D};t.masks={"default":"ddd MMM DD YYYY HH:mm:ss",shortDate:"M/D/YY",mediumDate:"MMM D, YYYY",longDate:"MMMM D, YYYY",fullDate:"dddd, MMMM D, YYYY",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"};t.format=function(e,a){if(typeof e==="number"){e=new Date(e)}if(Object.prototype.toString.call(e)!=="[object Date]"||isNaN(e.getTime())){throw new Error("Invalid Date in fecha.format")}a=t.masks[a]||a||t.masks["default"];var r=e.getDate(),i=e.getDay(),o=e.getMonth(),u=e.getFullYear(),s=e.getHours(),m=e.getMinutes(),d=e.getSeconds(),f=e.getMilliseconds(),l=e.getTimezoneOffset(),h={D:r,DD:M(r),Do:t.i18n.DoFn(r),d:i,dd:M(i),ddd:t.i18n.dayNamesShort[i],dddd:t.i18n.dayNames[i],M:o+1,MM:M(o+1),MMM:t.i18n.monthNamesShort[o],MMMM:t.i18n.monthNames[o],YY:String(u).slice(2),YYYY:u,h:s%12||12,hh:M(s%12||12),H:s,HH:M(s),m:m,mm:M(m),s:d,ss:M(d),S:Math.round(f/100),SS:M(Math.round(f/10),2),SSS:M(f,3),a:s<12?t.i18n.amPm[0]:t.i18n.amPm[1],A:s<12?t.i18n.amPm[0].toUpperCase():t.i18n.amPm[1].toUpperCase(),ZZ:(l>0?"-":"+")+M(Math.floor(Math.abs(l)/60)*100+Math.abs(l)%60,4)};return a.replace(n,function(e){return e in h?h[e]:e.slice(1,e.length-1)})};t.parse=function(e,a){var r,i,o,u,s,m;if(typeof a!=="string"){throw new Error("Invalid format in fecha.parse")}a=t.masks[a]||a;if(e.length>1e3){return false}r=true;i={};a.replace(n,function(t){if(h[t]){s=h[t];m=e.search(s[0]);if(!~m){r=false}else{e.replace(s[0],function(t){s[1](i,t);e=e.substr(m+t.length);return t})}}return h[t]?"":t.slice(1,t.length-1)});if(!r){return false}o=new Date;if(i.isPm===true&&i.hour!=null&&+i.hour!==12){i.hour=+i.hour+12}else if(i.isPm===false&&+i.hour===12){i.hour=0}if(i.timezoneOffset!=null){i.minute=+(i.minute||0)-+i.timezoneOffset;u=new Date(Date.UTC(i.year||o.getFullYear(),i.month||0,i.day||1,i.hour||0,i.minute||0,i.second||0,i.millisecond||0))}else{u=new Date(i.year||o.getFullYear(),i.month||0,i.day||1,i.hour||0,i.minute||0,i.second||0,i.millisecond||0)}return u};if(typeof module!=="undefined"&&module.exports){module.exports=t}else if(typeof define==="function"&&define.amd){define(function(){return t})}else{e.fecha=t}})(this); \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 523398d..0000000 --- a/karma.conf.js +++ /dev/null @@ -1,56 +0,0 @@ -// Karma configuration -// Generated on Fri Jan 09 2015 19:02:50 GMT-0500 (EST) - -module.exports = function (config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['jasmine'], - - // list of files / patterns to load in the browser - files: [ - 'fecha.js', - 'fecha.spec.js' - ], - - // list of files to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - /* preprocessors: { - 'fecha.js': ['coverage'] - },*/ - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress', /*'coverage'*/], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['PhantomJS'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true - }); -}; diff --git a/package.json b/package.json index ab19ce0..1335082 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "fecha", - "version": "1.2.2", + "version": "2.0.0", "description": "Date formatting and parsing", "main": "fecha.js", "scripts": { - "test": "node test.js" + "test": "nyc --cache --reporter=text node test.js", + "build": "uglifyjs fecha.js -m -o fecha.min.js" }, "repository": { "type": "git", @@ -25,9 +26,8 @@ }, "homepage": "https://github.com/taylorhakes/fecha", "devDependencies": { - "gulp": "^3.8.10", - "gulp-rename": "^1.2.0", - "gulp-uglify": "^1.0.2", - "painless": "^0.6.1" + "nyc": "^5.6.0", + "painless": "^0.6.1", + "uglify-js": "^2.6.1" } } diff --git a/test.js b/test.js index e14b61e..3022cb7 100644 --- a/test.js +++ b/test.js @@ -40,6 +40,7 @@ testParse('milliseconds medium', '10:20:30.12', 'HH:mm:ss.SS', new Date(year, 0, testParse('milliseconds short', '10:20:30.1', 'HH:mm:ss.S', new Date(year, 0, 1, 10, 20, 30, 100)); testParse('timezone offset', '09:20:31 GMT-0500 (EST)', 'HH:mm:ss ZZ', new Date(Date.UTC(year, 0, 1, 14, 20, 31))); testParse('UTC timezone offset', '09:20:31 GMT-0000 (UTC)', 'HH:mm:ss ZZ', new Date(Date.UTC(year, 0, 1, 9,20, 31))); +testParse('UTC timezone offset without GMT', '09:20:31 -0000 (UTC)', 'HH:mm:ss ZZ', new Date(Date.UTC(year, 0, 1, 9,20, 31))); testParse('invalid date', 'hello', 'HH:mm:ss ZZ', false); test('invalid date no format', function () { assert.throws(function () { @@ -132,12 +133,18 @@ testFormat('YYYY/MM/DD HH:mm:ss', new Date(2031, 10, 29, 2, 1, 9, 5), 'YYYY/MM/D testFormat('D-M-YYYY', new Date(2043, 8, 18, 2, 1, 9, 5), 'D-M-YYYY', '18-9-2043'); testFormat('current date', new Date(), 'YYYY', '' + (new Date()).getFullYear()); testFormat('mask', new Date(1999, 0, 2), 'mediumDate', 'Jan 2, 1999'); +testFormat('number date', 1325376000000, 'YYY-MM-DD HH:mm:ss', fecha.format(new Date(Date.UTC(2012,0,1)), 'YYY-MM-DD HH:mm:ss')); test('Invalid date', function () { assert.throws(function () { fecha.format('hello', 'YYYY'); }); }); +test('Invalid date number', function () { + assert.throws(function () { + fecha.format(89237983724982374, 'YYYY'); + }); +}); test('string date', function () { assert.throws(function () { fecha.format('2011-10-01', 'MM-DD-YYYY')