]> git.ipfire.org Git - thirdparty/moment.git/commitdiff
Add validity check for decimal values on non-smallest duration unit
authorKunal Marwaha <marwahaha@berkeley.edu>
Sat, 21 Jan 2017 02:23:29 +0000 (21:23 -0500)
committerIskren Chernev <iskren.chernev@gmail.com>
Thu, 2 Mar 2017 08:45:50 +0000 (10:45 +0200)
src/lib/duration/valid.js
src/test/moment/duration.js
src/test/moment/duration_invalid.js

index 799100c867585d261336d6488380e2df32a1faa1..ebb8fcaf62c2f82abe024b498c7f7322c1fd611e 100644 (file)
@@ -1,9 +1,24 @@
+var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
+
 export default function isDurationValid(m) {
     for (var key in m) {
-        if (['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'].indexOf(key) === -1 ||
+        if (ordering.indexOf(key) === -1 ||
         m[key] !== undefined && isNaN(parseInt(m[key]))) {
             return false;
         }
     }
+
+    var unitHasDecimal = false;
+    for (var i = 0; i < ordering.length; ++i) {
+        if (m[ordering[i]]) {
+            if (unitHasDecimal) {
+                return false; // only allow non-integers for smallest unit
+            }
+            if (parseFloat(m[ordering[i]]) !== parseInt(m[ordering[i]])) {
+                unitHasDecimal = true;
+            }
+        }
+    }
+
     return true;
 }
index dc57f21caaf82a83200abb8ede1d70cbfd6c58d8..c7e0ea377bf5b36353808305bb524e039a04df2e 100644 (file)
@@ -305,7 +305,7 @@ test('serialization to ISO 8601 duration strings', function (assert) {
     assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');
     assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');
     assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');
-    assert.equal(moment.duration({y: -0.5, M: 1}).toISOString(), '-P5M', 'a month after half a year ago');
+    assert.equal(moment.duration({y: -1, M: 1}).toISOString(), '-P11M', 'a month after a year ago');
     assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');
     assert.equal(moment.duration({M: 16, d:40, s: 86465}).toISOString(), 'P1Y4M40DT24H1M5S', 'all fields');
 });
@@ -315,7 +315,7 @@ test('toString acts as toISOString', function (assert) {
     assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');
     assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');
     assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');
-    assert.equal(moment.duration({y: -0.5, M: 1}).toString(), '-P5M', 'a month after half a year ago');
+    assert.equal(moment.duration({y: -1, M: 1}).toString(), '-P11M', 'a month after a year ago');
     assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');
     assert.equal(moment.duration({M: 16, d:40, s: 86465}).toString(), 'P1Y4M40DT24H1M5S', 'all fields');
 });
index c56662191c6bda35238484af65e95fe51dc4fcf9..e888310a598fc4c1e770f535e6e983b7e534b565 100644 (file)
@@ -9,6 +9,18 @@ test('invalid duration', function (assert) {
     assert.ok(isNaN(m.valueOf()));
 });
 
+test('invalid duration - only smallest unit can have decimal', function (assert) {
+    var m = moment.duration({'days': 3.5, 'hours': 1.1}); // should be invalid
+    assert.equal(m.isValid(), false);
+    assert.ok(isNaN(m.valueOf())); // .valueOf() returns NaN for invalid durations
+});
+
+test('valid duration - smallest unit can have decimal', function (assert) {
+    var m = moment.duration({'days': 3, 'hours': 1.1}); // should be valid
+    assert.equal(m.isValid(), true);
+    assert.equal(m.asHours(), 73.1);
+});
+
 test('invalid duration with two arguments', function (assert) {
     var m = moment.duration(NaN, 'days');
     assert.equal(m.isValid(), false);