Skip to content

Commit

Permalink
Split out utility functions, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Hughes committed Aug 2, 2018
1 parent 88924ae commit 0630e55
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 44 deletions.
45 changes: 1 addition & 44 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const axios = require('axios');
const moment = require('moment');
const stringifyDates = require('./stringifyDates');

class Forecast {
constructor({ accountId, token }) {
Expand Down Expand Up @@ -45,47 +45,4 @@ class Forecast {
}
}

function stringifyDates(options) {
const qs = {};

if (options.startDate) {
qs.start_date = toDateString(options.startDate);
}

if (options.endDate) {
qs.end_date = toDateString(options.endDate);
}

return qs;
}

function toDateString(obj) {
let date;

if (typeof obj === 'string') {
date = moment(obj);
if (!date.isValid()) {
throw new Error(
'Invalid date string; expecting ISO-8601 compatible format.'
);
}
} else if (obj instanceof Date) {
// Check for bad date objects like: new Date('LOL');
if (isNaN(+obj)) {
throw new Error('Invalid date object; expecting non NaN date value.');
}
date = moment(obj);
} else if (obj._isAMomentObject) {
date = obj;
}

if (!date) {
throw new Error(
'Invalid date; expecting a valid: ISO-8601 compatible date string, a Date object or a moment date object.'
);
}

return date.format('YYYY-MM-DD');
}

module.exports = Forecast;
13 changes: 13 additions & 0 deletions src/stringifyDates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const toDateString = require('./toDateString');

module.exports = options => {
const qs = {};

if (options.startDate) qs.start_date = toDateString(options.startDate);

if (options.endDate) {
qs.end_date = toDateString(options.endDate);
}

return qs;
};
28 changes: 28 additions & 0 deletions src/stringifyDates.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const stringifyDates = require('./stringifyDates');

// Mocks the toDateString function to always return
// the input. It isn't the system under test in this
// file.
jest.mock('./toDateString', () => args => args);

describe('stringifyDates', () => {
it('returns input as-is', () => {
expect(stringifyDates({})).toEqual({});
});

it('converts the start date', () => {
expect(stringifyDates({ startDate: 'someValue' })).toMatchObject({
start_date: 'someValue',
});
});

it('converts the end date', () => {
const output = stringifyDates({ endDate: 'someValue' });

expect(output).toMatchObject({
end_date: 'someValue',
});

expect(Object.keys(output).length).toBe(1);
});
});
30 changes: 30 additions & 0 deletions src/toDateString.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const moment = require('moment');

module.exports = obj => {
let date;

if (typeof obj === 'string') {
date = moment(obj);
if (!date.isValid()) {
throw new Error(
'Invalid date string; expecting ISO-8601 compatible format.'
);
}
} else if (obj instanceof Date) {
// Check for bad date objects like: new Date('LOL');
if (isNaN(+obj)) {
throw new Error('Invalid date object; expecting non NaN date value.');
}
date = moment(obj);
} else if (obj && obj._isAMomentObject) {
date = obj;
}

if (!date) {
throw new Error(
'Invalid date; expecting a valid: ISO-8601 compatible date string, a Date object or a moment date object.'
);
}

return date.format('YYYY-MM-DD');
};
47 changes: 47 additions & 0 deletions src/toDateString.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const toDateString = require('./toDateString');

describe('toDateString', () => {
it('throws without input', () => {
expect(() => toDateString()).toThrow(
'Invalid date; expecting a valid: ISO-8601 compatible date string, a Date object or a moment date object.'
);
});

it('throws on invalid string input', () => {
const warn = jest
.spyOn(global.console, 'warn')
.mockImplementation(() => {});

expect(() => toDateString('Invalid')).toThrow(
'Invalid date string; expecting ISO-8601 compatible format.'
);

// Moment deprecation warning
expect(warn).toHaveBeenCalled();
});

it('works on valid string input', () => {
expect(toDateString('01-31-2000')).toBe('2000-01-31');
});

it('throws on invalid Date input', () => {
expect(() => toDateString(new Date('Invalid'))).toThrow(
'Invalid date object; expecting non NaN date value.'
);
});

it('works on valid Date input', () => {
expect(toDateString(new Date('01-31-2000'))).toBe('2000-01-31');
});

it('accepts any moment-ish object', () => {
const input = {
_isAMomentObject: true,
format: jest.fn().mockReturnValue('mocked value'),
};

expect(toDateString(input)).toBe('mocked value');

expect(input.format).toHaveBeenCalledWith('YYYY-MM-DD');
});
});

0 comments on commit 0630e55

Please sign in to comment.