Skip to content

Commit

Permalink
refactor: removes ability to specify time as strings
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Removes ability to pass `start`, `end`, or
`recurrence.end` as strings. They must now be passed as Date objects.
  • Loading branch information
jshor committed Sep 28, 2020
1 parent de5b0a8 commit af23513
Show file tree
Hide file tree
Showing 17 changed files with 96 additions and 132 deletions.
8 changes: 4 additions & 4 deletions src/CalendarBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ class CalendarBase implements ICalendarBase {
*/
setTimestamps (options: IOptions): void {
this.allday = !options.end
this.start = time.parseDate(options.start)
this.start = options.start

if (this.end) {
this.end = time.parseDate(options.end)
if (options.end) {
this.end = options.end
} else {
// if allday is specified, make the end date exactly 1 day from the start date
this.end = time.incrementDate(this.start, 1)
Expand All @@ -96,7 +96,7 @@ class CalendarBase implements ICalendarBase {
this.recurrence = options.recurrence

if (this.recurrence && this.recurrence.end) {
this.recurrence.end = time.parseDate(this.recurrence.end)
this.recurrence.end = this.recurrence.end
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/GoogleCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export default class GoogleCalendar extends CalendarBase {
details: this.description,
location: this.location,
dates: [
time.formatTimestampDate(this.start, timestampFormat),
time.formatTimestampDate(this.end, timestampFormat)
time.formatDate(this.start, timestampFormat),
time.formatDate(this.end, timestampFormat)
].join('/')
}

Expand Down
4 changes: 2 additions & 2 deletions src/ICalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export default class ICalendar extends CalendarBase {
const event = [
'CLASS:PUBLIC',
`DESCRIPTION:${description}`,
`DTSTART:${time.formatTimestampDate(this.start, FORMAT.FULL)}`,
`DTEND:${time.formatTimestampDate(this.end, FORMAT.FULL)}`,
`DTSTART:${time.formatDate(this.start, FORMAT.FULL)}`,
`DTEND:${time.formatDate(this.end, FORMAT.FULL)}`,
`LOCATION:${location}`,
`SUMMARY:${summary}`,
'TRANSP:TRANSPARENT'
Expand Down
4 changes: 2 additions & 2 deletions src/OutlookCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export default class OutlookCalendar extends CalendarBase {

const params: Record<string, string | number | boolean> = {
rru: 'addevent',
startdt: time.formatTimestampDate(this.start, timestampFormat),
enddt: time.formatTimestampDate(this.end, timestampFormat),
startdt: time.formatDate(this.start, timestampFormat),
enddt: time.formatDate(this.end, timestampFormat),
subject: this.title,
body: this.description,
location: this.location,
Expand Down
8 changes: 4 additions & 4 deletions src/YahooCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ export default class YahooCalendar extends CalendarBase {

if (this.allday) {
params.dur = 'allday'
params.st = time.formatTimestampDate(this.start, FORMAT.DATE)
params.st = time.formatDate(this.start, FORMAT.DATE)
} else {
params.st = time.formatTimestampDate(this.start, FORMAT.FULL)
params.st = time.formatDate(this.start, FORMAT.FULL)

if (this.getHoursDuration(this.start.getTime(), this.end.getTime()) > 99) {
// Yahoo only supports up to 99 hours, so we are forced to specify the end time instead of the duration
params.et = time.formatTimestampDate(this.end, FORMAT.FULL)
params.et = time.formatDate(this.end, FORMAT.FULL)
} else {
// we prefer specifying duration in lieu of end time, because apparently Yahoo's end time is buggy w.r.t. timezones
params.dur = this.getDuration(this.start.getTime(), this.end.getTime())
Expand All @@ -181,7 +181,7 @@ export default class YahooCalendar extends CalendarBase {
const days = this.getRecurrenceLengthDays(this.recurrence)
const rend = time.incrementDate(this.end, Math.ceil(days))

params.REND = time.formatTimestampDate(rend, FORMAT.DATE)
params.REND = time.formatDate(rend, FORMAT.DATE)
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/__tests__/CalendarBase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ describe('Calendar Base', () => {

it('should set allday to true', () => {
calendarObj.setTimestamps({
start: new Date('2019-03-23T17:00:00.000'),
end: ''
start: new Date('2019-03-23T17:00:00.000')
})

expect(calendarObj.allday).toBe(true)
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/GoogleCalendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ describe('GoogleCalendar', () => {

const paramsObj = queryString.parse(result.split('?')[1])
const expectedDates = `${
time.formatTimestampDate(testObj.start, FORMAT.DATE)
time.formatDate(testObj.start, FORMAT.DATE)
}/${
time.formatTimestampDate(testObj.end, FORMAT.DATE)
time.formatDate(testObj.end, FORMAT.DATE)
}`

expect(paramsObj.dates).toBe(expectedDates)
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/ICalendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ describe('ICalendar', () => {
'BEGIN:VEVENT',
'CLASS:PUBLIC',
`DESCRIPTION:${baseOpts.description}`,
`DTSTART:${time.formatTimestampString(new Date(baseOpts.start), FORMAT.FULL)}`,
`DTEND:${time.formatTimestampString(new Date(baseOpts.end), FORMAT.FULL)}`,
`DTSTART:${time.formatDate(new Date(baseOpts.start), FORMAT.FULL)}`,
`DTEND:${time.formatDate(new Date(baseOpts.end), FORMAT.FULL)}`,
`LOCATION:${baseOpts.location}`,
`SUMMARY:${baseOpts.title}`,
'TRANSP:TRANSPARENT',
Expand Down
12 changes: 6 additions & 6 deletions src/__tests__/OutlookCalendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ describe('Outlook Calendar', () => {
title: 'Fun Party',
description: 'BYOB',
location: 'New York',
start: '2019-07-04T19:00:00.000'
start: new Date('2019-07-04T19:00:00.000')
})).toBeInstanceOf(CalendarBase)
})

describe('render()', () => {
const testOpts: IOptions = {
start: '2019-03-23T17:00:00.000'
start: new Date('2019-03-23T17:00:00.000')
}

beforeEach(() => {
Expand Down Expand Up @@ -45,8 +45,8 @@ describe('Outlook Calendar', () => {
expect(paramsObj).toMatchObject({
path: '/calendar/action/compose',
rru: 'addevent',
startdt: time.formatTimestampDate(obj.start, FORMAT.OUTLOOK_FULL),
enddt: time.formatTimestampDate(obj.end, FORMAT.OUTLOOK_FULL),
startdt: time.formatDate(obj.start, FORMAT.OUTLOOK_FULL),
enddt: time.formatDate(obj.end, FORMAT.OUTLOOK_FULL),
subject: testOpts.title,
body: testOpts.description,
location: testOpts.location,
Expand All @@ -67,8 +67,8 @@ describe('Outlook Calendar', () => {
expect(paramsObj).toMatchObject({
path: '/calendar/action/compose',
rru: 'addevent',
startdt: time.formatTimestampDate(obj.start, FORMAT.OUTLOOK_FULL),
enddt: time.formatTimestampDate(obj.end, FORMAT.OUTLOOK_FULL),
startdt: time.formatDate(obj.start, FORMAT.OUTLOOK_FULL),
enddt: time.formatDate(obj.end, FORMAT.OUTLOOK_FULL),
subject: testOpts.title,
body: testOpts.description,
location: testOpts.location,
Expand Down
69 changes: 15 additions & 54 deletions src/__tests__/YahooCalendar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@ import IOptions from '../interfaces/IOptions'
const {
FREQUENCY: { DAILY, WEEKLY, MONTHLY }
} = RECURRENCE
<<<<<<< HEAD
=======
const yahooFreqMap = {
[DAILY]: 'Dy',
[WEEKLY]: 'Wk',
[MONTHLY]: 'Mh',
[YEARLY]: 'Yr'
}
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc

describe('YahooCalendar', () => {
let testOpts: IOptions
Expand Down Expand Up @@ -74,17 +65,8 @@ describe('YahooCalendar', () => {
expect(obj.getFrequency(FREQUENCY.WEEKLY)).toEqual('Wk')
})

<<<<<<< HEAD
it('should default to daily recurrences', () => {
expect(obj.getFrequency(FREQUENCY.DAILY)).toEqual('Dy')
=======
for (const frequency of [ DAILY, WEEKLY, MONTHLY, YEARLY, 'foobar' ]) {
const result = obj.getFrequency({ frequency })
const expected = yahooFreqMap[frequency] || yahooFreqMap[WEEKLY]
expect(result).toBe(expected)
}
})
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc
})
})

Expand Down Expand Up @@ -239,7 +221,7 @@ describe('YahooCalendar', () => {
title: 'Fun Party',
description: 'BYOB',
location: 'New York',
start: '2019-07-04T19:00:00.000'
start: new Date('2019-07-04T19:00:00.000')
}

describe('no recurrence', () => {
Expand All @@ -255,7 +237,7 @@ describe('YahooCalendar', () => {
desc: 'BYOB',
in_loc: 'New York',
dur: 'allday',
st: time.formatTimestampString(testOpts.start, FORMAT.DATE)
st: time.formatDate(obj.start, FORMAT.DATE)
}
expect(params).toMatchObject(expectedObj)
expect(expectedObj).toMatchObject(params)
Expand All @@ -264,7 +246,7 @@ describe('YahooCalendar', () => {

describe('recurrence', () => {
it('should format the query string with start and end times containing only their dates', () => {
const recurrenceEnd = '2019-07-10T19:00:00.000'
const recurrenceEnd = new Date('2019-07-10T19:00:00.000')
const obj = new YahooCalendar({
...testOpts,
recurrence: {
Expand All @@ -283,15 +265,9 @@ describe('YahooCalendar', () => {
desc: 'BYOB',
in_loc: 'New York',
dur: 'allday',
<<<<<<< HEAD
st: time.formatTimestampString(testOpts.start, FORMAT.FULL),
RPAT: '01Dy',
REND: time.formatTimestampString(recurrenceEnd, FORMAT.FULL),
=======
st: time.formatTimestampString(testOpts.start, 'YYYYMMDD'),
st: time.formatDate(testOpts.start, FORMAT.DATE),
RPAT: '01Dy',
REND: time.formatTimestampString(recurrenceEnd, 'YYYYMMDD')
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc
REND: time.formatDate(recurrenceEnd, FORMAT.DATE)
}
expect(params).toMatchObject(expectedObj)
})
Expand All @@ -303,8 +279,8 @@ describe('YahooCalendar', () => {
title: 'Fun Party',
description: 'BYOB',
location: 'New York',
start: '2019-07-04T19:00:00.000',
end: '2019-07-04T21:00:00.000' // two-hour long event (19h to 21h)
start: new Date('2019-07-04T19:00:00.000'),
end: new Date('2019-07-04T21:00:00.000') // two-hour long event (19h to 21h)
}

describe('no recurrence', () => {
Expand All @@ -320,11 +296,7 @@ describe('YahooCalendar', () => {
title: 'Fun Party',
desc: 'BYOB',
in_loc: 'New York',
<<<<<<< HEAD
st: time.formatTimestampString(testOpts.start, FORMAT.FULL),
=======
st: time.formatTimestampString(testOpts.start, 'YYYYMMDDThhmmss'),
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc
st: time.formatDate(testOpts.start, FORMAT.FULL),
dur: '0200'
}
expect(params).toMatchObject(expectedObj)
Expand All @@ -334,8 +306,8 @@ describe('YahooCalendar', () => {

describe('when the duration of the event spans longer than 99 hours', () => {
it('should format the query string with the time parameters in start/end timestamps', () => {
const start = '2019-07-04T19:00:00.000'
const end = '2019-07-08T23:00:00.000' // one-hundred-hour long event, (four days, three hours)
const start = new Date('2019-07-04T19:00:00.000')
const end = new Date('2019-07-08T23:00:00.000') // one-hundred-hour long event, (four days, three hours)

const obj = new YahooCalendar({ ...testOpts, start, end })
const result = obj.render()
Expand All @@ -347,13 +319,8 @@ describe('YahooCalendar', () => {
title: 'Fun Party',
desc: 'BYOB',
in_loc: 'New York',
<<<<<<< HEAD
st: time.formatTimestampString(start, FORMAT.FULL),
et: time.formatTimestampString(end, FORMAT.FULL)
=======
st: time.formatTimestampString(start, 'YYYYMMDDThhmmss'),
et: time.formatTimestampString(end, 'YYYYMMDDThhmmss')
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc
st: time.formatDate(start, FORMAT.FULL),
et: time.formatDate(end, FORMAT.FULL)
}
expect(params).toMatchObject(expectedObj)
expect(expectedObj).toMatchObject(params)
Expand All @@ -363,7 +330,7 @@ describe('YahooCalendar', () => {

describe('recurrence', () => {
it('should format the query string with RPAT and REND params', () => {
const recurrenceEnd = '2019-07-10T19:00:00.000'
const recurrenceEnd = new Date('2019-07-10T19:00:00.000')
const obj = new YahooCalendar({
...testOpts,
recurrence: {
Expand All @@ -382,15 +349,9 @@ describe('YahooCalendar', () => {
desc: 'BYOB',
in_loc: 'New York',
dur: '0200',
<<<<<<< HEAD
st: time.formatTimestampString(testOpts.start, FORMAT.FULL),
RPAT: '01Dy',
REND: time.formatTimestampString(recurrenceEnd, FORMAT.DATE)
=======
st: time.formatTimestampString(testOpts.start, 'YYYYMMDDThhmmss'),
st: time.formatDate(testOpts.start, FORMAT.FULL),
RPAT: '01Dy',
REND: time.formatTimestampString(recurrenceEnd, 'YYYYMMDD')
>>>>>>> 878ccf7... refactor(ts): adds ESLint, TypeDoc
REND: time.formatDate(recurrenceEnd, FORMAT.DATE)
}
expect(params).toMatchObject(expectedObj)
})
Expand Down
13 changes: 9 additions & 4 deletions src/interfaces/ICalendarBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import IRecurrence from './IRecurrence'
* CalendarBase properties
*/
export default interface ICalendarBase {
allday: boolean
/** The event description. */
description: string
/** The event title (i.e., summary). */
title: string
/** A summary description of the event location. */
location: string
start: Date | string
end?: Date | string
/** The event start timestamp. */
start: Date
/** The event end timestamp. For all-day events, this field should be omitted. */
end: Date
/** The recurrence of an event is how often the event is supposed to occur. See {@link IRecurrence}. */
recurrence?: IRecurrence
title: string
}
5 changes: 2 additions & 3 deletions src/interfaces/IOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ export default interface IOptions {
/** A summary description of the event location. */
location?: string
/** The event start timestamp. */
start: string | Date
/** The event end timestamp. For all-day events, this field should be omitted. */
end?: string | Date
start: Date
/** The event end timestamp. For all-day events, this field should be omitted. */
end?: Date
/** The recurrence of an event is how often the event is supposed to occur. See {@link IRecurrence}. */
recurrence?: IRecurrence
}
2 changes: 1 addition & 1 deletion src/interfaces/IRecurrence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default interface IRecurrence {
/** The maximum number of times the event should repeat. */
count?: number
/** The latest date that this event may occur on. */
end?: Date | string
end?: Date
/** The day of the week to denote when the the week starts on. */
weekstart?: string
/** The days of the week that the event should occur on. */
Expand Down
4 changes: 2 additions & 2 deletions src/utils/__tests__/ics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe('IcsUtil', () => {
interval: 1,
count: 5,
weekstart: 'MO',
end: '2019-05-02',
end: new Date('2019-05-02'),
weekdays: 'MO',
monthdays: '5'
}
Expand All @@ -104,7 +104,7 @@ describe('IcsUtil', () => {
'WKST=MO',
'BYDAY=MO',
'BYMONTHDAY=5',
`UNTIL=${time.formatTimestampString(recurrence.end, 'YYYYMMDDThhmmss')}`
`UNTIL=${time.formatDate(recurrence.end, 'YYYYMMDDThhmmss')}`
].join(';')

const actualRrule = ics.getRrule(recurrence)
Expand Down
Loading

0 comments on commit af23513

Please sign in to comment.