Skip to content

Commit 156b638

Browse files
author
Kevin Delisle
authored
Merge pull request #1356 from strongloop/datetype-allow-strings
Add DateString type
2 parents 5d10c72 + 5e80837 commit 156b638

File tree

3 files changed

+182
-0
lines changed

3 files changed

+182
-0
lines changed

lib/date-string.js

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright IBM Corp. 2013,2016. All Rights Reserved.
2+
// Node module: loopback-datasource-juggler
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
'use strict';
7+
8+
var inspect = require('util').inspect;
9+
10+
module.exports = DateString;
11+
12+
/**
13+
* A String whose value is a valid representation of a Date.
14+
* Use this type if you need to preserve the format of the value and still
15+
* check if it's valid.
16+
* Example:
17+
* ```js
18+
* var loopback = require('loopback');
19+
* var dt = new loopback.DateString('2001-01-01');
20+
*
21+
* dt.toString();
22+
* // '2001-01-01'
23+
* dt._date.toISOString();
24+
* // '2001-01-01T00:00:00.000Z'
25+
* ```
26+
*
27+
* You can use this definition on your models as well:
28+
* ```json
29+
* {
30+
* "name": "Person",
31+
* "base": "PersistedModel",
32+
* "properties": {
33+
* "name": {
34+
* "type": "string"
35+
* },
36+
* "dob": {
37+
* "type": "DateString",
38+
* "required": true
39+
* },
40+
* },
41+
* "validations": [],
42+
* "relations": {},
43+
* "acls": [],
44+
* "methods": {}
45+
* }
46+
* ```
47+
* @class DateString
48+
* @param {String} value
49+
* @constructor
50+
*/
51+
function DateString(value) {
52+
if (!(this instanceof DateString)) {
53+
return new DateString(value);
54+
}
55+
56+
if (typeof(value) !== 'string') {
57+
throw new Error('Input must be a string');
58+
}
59+
60+
Object.defineProperty(this, 'when', {
61+
get: () => { return this._when; },
62+
set: (val) => {
63+
var d = new Date(val);
64+
if (isNaN(d.getTime())) {
65+
throw new Error('Invalid date');
66+
} else {
67+
this._when = val;
68+
this._date = d;
69+
}
70+
},
71+
});
72+
73+
this.when = value;
74+
};
75+
76+
/**
77+
* Returns the value of DateString in its original form.
78+
* @returns {String} The Date as a String.
79+
*/
80+
DateString.prototype.toString = function() {
81+
return this.when;
82+
};
83+
84+
/**
85+
* Returns the JSON representation of the DateString object.
86+
* @returns {String} A JSON string.
87+
*/
88+
DateString.prototype.toJSON = function() {
89+
return JSON.stringify({
90+
when: this.when,
91+
});
92+
};
93+
94+
DateString.prototype.inspect = function(depth, options) {
95+
return 'DateString ' + inspect({
96+
when: this.when,
97+
_date: this._date,
98+
});
99+
};

lib/types.js

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Types.Any.prototype.toObject = Types.Any.prototype.toJSON = function() {
4040
};
4141

4242
module.exports = function(modelTypes) {
43+
var DateString = require('./date-string');
4344
var GeoPoint = require('./geo').GeoPoint;
4445

4546
for (var t in Types) {
@@ -63,6 +64,7 @@ module.exports = function(modelTypes) {
6364
modelTypes.registerType(Number);
6465
modelTypes.registerType(Boolean);
6566
modelTypes.registerType(Date);
67+
modelTypes.registerType(DateString);
6668
modelTypes.registerType(Buffer, ['Binary']);
6769
modelTypes.registerType(Array);
6870
modelTypes.registerType(GeoPoint);

test/date-string.test.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
2+
// Node module: loopback-datasource-juggler
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
/* global describe,it */
7+
/* jshint expr:true */
8+
9+
'use strict';
10+
11+
require('should');
12+
13+
var DateString = require('../lib/date-string');
14+
var fmt = require('util').format;
15+
var inspect = require('util').inspect;
16+
var os = require('os');
17+
18+
describe('DateString', function() {
19+
describe('constructor', function() {
20+
it('should support a valid date string', function() {
21+
var theDate = '2015-01-01';
22+
var date = new DateString(theDate);
23+
date.should.not.eql(null);
24+
date.when.should.eql(theDate);
25+
date.toString().should.eql(theDate);
26+
});
27+
28+
testValidInput('should allow date with time', '2015-01-01 02:00:00');
29+
testValidInput('should allow full UTC datetime', '2015-06-30T20:00:00.000Z');
30+
testValidInput('should allow date with UTC offset', '2015-01-01 20:00:00 GMT-5');
31+
32+
testInvalidInput('should throw on non-date string', 'notadate', 'Invalid date');
33+
testInvalidInput('should throw on incorrect date-like value',
34+
'2015-01-01 25:00:00', 'Invalid date');
35+
testInvalidInput('should throw on non-string input', 20150101,
36+
'Input must be a string');
37+
testInvalidInput('should throw on null input', null, 'Input must be a string');
38+
39+
it('should update internal date on set', function() {
40+
var date = new DateString('2015-01-01');
41+
date.when = '2016-01-01';
42+
date.when.should.eql('2016-01-01');
43+
var d = new Date('2016-01-01');
44+
// The internal date representation should also be updated!
45+
date._date.toString().should.eql(d.toString());
46+
});
47+
it('should return custom inspect output', function() {
48+
var date = new DateString('2015-01-01');
49+
var result = inspect(date);
50+
result.should.not.eql(null);
51+
result.should.eql(fmt('DateString ' + inspect({
52+
when: date.when,
53+
_date: date._date,
54+
})));
55+
});
56+
57+
it('should return JSON output', function() {
58+
var date = new DateString('2015-01-01');
59+
var result = date.toJSON();
60+
result.should.eql(JSON.stringify({when: date.when}));
61+
});
62+
63+
function testValidInput(msg, val) {
64+
it(msg, function() {
65+
var theDate = new DateString(val);
66+
theDate.when.should.eql(val);
67+
var d = new Date(val);
68+
theDate._date.toString().should.eql(d.toString());
69+
});
70+
}
71+
72+
function testInvalidInput(msg, val, err) {
73+
it(msg, () => {
74+
var fn = () => {
75+
var theDate = new DateString(val);
76+
};
77+
fn.should.throw(err);
78+
});
79+
}
80+
});
81+
});

0 commit comments

Comments
 (0)