summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrent Richardson <trentdrichardson@gmail.com>2013-07-15 05:04:36 -0700
committerTrent Richardson <trentdrichardson@gmail.com>2013-07-15 05:04:36 -0700
commita1e67c52f3689a0618285048befaacdd6c776c4a (patch)
tree8f94c93c9f52fdc0bd9ee7b1642ee58859f730a2
parentaf2f050bf8c983003a6812fb45b73cf8182e4547 (diff)
parent032adf1ed6eff592955cfd56981bc14c776d2ae7 (diff)
downloadjQuery-Timepicker-Addon-a1e67c52f3689a0618285048befaacdd6c776c4a.zip
jQuery-Timepicker-Addon-a1e67c52f3689a0618285048befaacdd6c776c4a.tar.gz
jQuery-Timepicker-Addon-a1e67c52f3689a0618285048befaacdd6c776c4a.tar.bz2
Merge pull request #606 from srvance/dev
More tests added, cleanup
-rw-r--r--jquery-ui-timepicker-addon.js134
-rw-r--r--test/jquery-ui-timepicker-addon_spec.js265
2 files changed, 328 insertions, 71 deletions
diff --git a/jquery-ui-timepicker-addon.js b/jquery-ui-timepicker-addon.js
index 8dbf0d2..50d6da3 100644
--- a/jquery-ui-timepicker-addon.js
+++ b/jquery-ui-timepicker-addon.js
@@ -152,8 +152,8 @@
/*
* Override the default settings for all instances of the time picker.
- * @param settings object - the new settings to use as defaults (anonymous object)
- * @return the manager object
+ * @param {Object} settings object - the new settings to use as defaults (anonymous object)
+ * @return {Object} the manager object
*/
setDefaults: function(settings) {
extendRemove(this._defaults, settings || {});
@@ -1823,51 +1823,36 @@
return String(hour);
};
+ var computeEffectiveSetting = function (settings, property) {
+ return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];
+ };
+
/*
* Splits datetime string into date and time substrings.
* Throws exception when date can't be parsed
- * Returns [dateString, timeString]
+ * Returns {dateString: dateString, timeString: timeString}
*/
- var splitDateTime = function(dateFormat, dateTimeString, dateSettings, timeSettings) {
- try {
- // The idea is to get the number separator occurrences in datetime and the time format requested (since time has
- // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.
- var separator = timeSettings && timeSettings.separator ? timeSettings.separator : $.timepicker._defaults.separator,
- format = timeSettings && timeSettings.timeFormat ? timeSettings.timeFormat : $.timepicker._defaults.timeFormat,
- timeParts = format.split(separator), // how many occurrences of separator may be in our format?
- timePartsLen = timeParts.length,
- allParts = dateTimeString.split(separator),
- allPartsLen = allParts.length;
-
- if (allPartsLen > 1) {
- return [
- allParts.splice(0,allPartsLen-timePartsLen).join(separator),
- allParts.splice(0,timePartsLen).join(separator)
- ];
- }
-
- } catch (err) {
- $.timepicker.log('Could not split the date from the time. Please check the following datetimepicker options' +
- "\nthrown error: " + err +
- "\ndateTimeString" + dateTimeString +
- "\ndateFormat = " + dateFormat +
- "\nseparator = " + timeSettings.separator +
- "\ntimeFormat = " + timeSettings.timeFormat);
-
- if (err.indexOf(":") >= 0) {
- // Hack! The error message ends with a colon, a space, and
- // the "extra" characters. We rely on that instead of
- // attempting to perfectly reproduce the parsing algorithm.
- var dateStringLength = dateTimeString.length - (err.length - err.indexOf(':') - 2),
- timeString = dateTimeString.substring(dateStringLength);
-
- return [$.trim(dateTimeString.substring(0, dateStringLength)), $.trim(dateTimeString.substring(dateStringLength))];
-
- } else {
- throw err;
- }
+ var splitDateTime = function(dateTimeString, timeSettings) {
+ // The idea is to get the number separator occurrences in datetime and the time format requested (since time has
+ // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.
+ var separator = computeEffectiveSetting(timeSettings, 'separator'),
+ format = computeEffectiveSetting(timeSettings, 'timeFormat'),
+ timeParts = format.split(separator), // how many occurrences of separator may be in our format?
+ timePartsLen = timeParts.length,
+ allParts = dateTimeString.split(separator),
+ allPartsLen = allParts.length;
+
+ if (allPartsLen > 1) {
+ return {
+ dateString: allParts.splice(0,allPartsLen-timePartsLen).join(separator),
+ timeString: allParts.splice(0,timePartsLen).join(separator)
+ };
}
- return [dateTimeString, ''];
+
+ return {
+ dateString: dateTimeString,
+ timeString: ''
+ };
};
/*
@@ -1877,25 +1862,29 @@
* timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional
*/
var parseDateTimeInternal = function(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {
- var date;
- var splitRes = splitDateTime(dateFormat, dateTimeString, dateSettings, timeSettings);
- date = $.datepicker._base_parseDate(dateFormat, splitRes[0], dateSettings);
- if (splitRes[1] !== '') {
- var timeString = splitRes[1],
- parsedTime = $.datepicker.parseTime(timeFormat, timeString, timeSettings);
-
- if (parsedTime === null) {
- throw 'Wrong time format';
- }
- return {
- date: date,
- timeObj: parsedTime
- };
- } else {
+ var date,
+ parts,
+ parsedTime;
+
+ parts = splitDateTime(dateTimeString, timeSettings);
+ date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);
+
+ if (parts.timeString === '') {
return {
date: date
};
}
+
+ parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);
+
+ if (!parsedTime) {
+ throw 'Wrong time format';
+ }
+
+ return {
+ date: date,
+ timeObj: parsedTime
+ };
};
/*
@@ -1915,12 +1904,12 @@
/**
* Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)
- * @param {number} tzMinutes if not a number this value is returned
+ * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned
* @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45"
* @return {string}
*/
$.timepicker.timezoneOffsetString = function(tzMinutes, iso8601) {
- if(isNaN(tzMinutes) || tzMinutes > 840){
+ if(isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720){
return tzMinutes;
}
@@ -1928,7 +1917,7 @@
minutes = off % 60,
hours = (off - minutes) / 60,
iso = iso8601? ':':'',
- tz = (off >= 0 ? '+' : '-') + ('0' + (hours * 101).toString()).slice(-2) + iso + ('0' + (minutes * 101).toString()).slice(-2);
+ tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);
if(tz == '+00:00'){
return 'Z';
@@ -1938,23 +1927,23 @@
/**
* Get the number in minutes that represents a timezone string
- * @param {string} tzString formatted like "+0500", "-1245"
- * @return {number}
+ * @param {string} tzString formatted like "+0500", "-1245", "Z"
+ * @return {number} the offset minutes or the original string if it doesn't match expectations
*/
$.timepicker.timezoneOffsetNumber = function(tzString) {
- tzString = tzString.toString().replace(':',''); // excuse any iso8601, end up with "+1245"
+ var normalized = tzString.toString().replace(':',''); // excuse any iso8601, end up with "+1245"
- if(tzString.toUpperCase() === 'Z'){ // if iso8601 with Z, its 0 minute offset
+ if(normalized.toUpperCase() === 'Z'){ // if iso8601 with Z, its 0 minute offset
return 0;
}
- if(!/^(\-|\+)\d{4}$/.test(tzString)){ // possibly a user defined tz, so just give it back
+ if(!/^(\-|\+)\d{4}$/.test(normalized)){ // possibly a user defined tz, so just give it back
return tzString;
}
- return ((tzString.substr(0,1) =='-'? -1 : 1) * // plus or minus
- ((parseInt(tzString.substr(1,2),10)*60) + // hours (converted to minutes)
- parseInt(tzString.substr(3,2),10))); // minutes
+ return ((normalized.substr(0,1) =='-'? -1 : 1) * // plus or minus
+ ((parseInt(normalized.substr(1,2),10)*60) + // hours (converted to minutes)
+ parseInt(normalized.substr(3,2),10))); // minutes
};
/**
@@ -1966,7 +1955,7 @@
$.timepicker.timezoneAdjust = function(date, toTimezone) {
var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);
if(!isNaN(toTz)){
- date.setMinutes(date.getMinutes()*1 + (date.getTimezoneOffset()*-1 - toTz*1) );
+ date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz);
}
return date;
};
@@ -1999,7 +1988,7 @@
};
/**
- * Calls `method` on the `startTime` and `endTime` elements, and configures them to
+ * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to
* enforce date range limits.
* @param {Element} startTime
* @param {Element} endTime
@@ -2113,7 +2102,10 @@
_isEmptyObject: isEmptyObject,
_convert24to12: convert24to12,
_detectSupport: detectSupport,
- _selectLocalTimezone: selectLocalTimezone
+ _selectLocalTimezone: selectLocalTimezone,
+ _computeEffectiveSetting: computeEffectiveSetting,
+ _splitDateTime: splitDateTime,
+ _parseDateTimeInternal: parseDateTimeInternal
};
/*
diff --git a/test/jquery-ui-timepicker-addon_spec.js b/test/jquery-ui-timepicker-addon_spec.js
index 70f44b2..4676c25 100644
--- a/test/jquery-ui-timepicker-addon_spec.js
+++ b/test/jquery-ui-timepicker-addon_spec.js
@@ -195,5 +195,270 @@ describe('datetimepicker', function() {
expect(timepicker.timezone_select.val()).toBe(timezoneOffset);
});
});
+
+ describe('computeEffectiveSetting', function() {
+ it('pulls the setting from the passed settings object if it is there', function() {
+ var expectedUniqueValue = 'This is very unique',
+ settings = {
+ property: expectedUniqueValue
+ };
+
+ expect(util._computeEffectiveSetting(settings, 'property')).toBe(expectedUniqueValue);
+ });
+
+ it('pulls the setting from the timepicker defaults if there are no passed settings', function() {
+ var expectedValue = $.timepicker._defaults.separator;
+ expect(expectedValue).toBeDefined();
+
+ expect(util._computeEffectiveSetting(undefined, 'separator')).toBe(expectedValue);
+ });
+
+ it('pulls the setting from the timepicker defaults if not present in the passed settings', function() {
+ var expectedValue = $.timepicker._defaults.separator,
+ settings = {};
+ expect(expectedValue).toBeDefined();
+
+ expect(util._computeEffectiveSetting(settings, 'separator')).toBe(expectedValue);
+ });
+ });
+
+ describe('splitDateTime', function() {
+ var expectedDateString = '3/6/1967',
+ expectedTimeString = '07:32';
+
+ it('splits a date and time into its parts using the default separator', function() {
+ var inputDateTimeString = expectedDateString + $.timepicker._defaults.separator + expectedTimeString,
+ result;
+
+ result = $.timepicker._util._splitDateTime(inputDateTimeString, {});
+
+ expect(result).toEqual({dateString: expectedDateString, timeString: expectedTimeString});
+ });
+
+ it('splits a date and time into its parts using a supplied separator', function() {
+ var separator = '-',
+ inputDateTimeString = expectedDateString + separator + expectedTimeString,
+ result;
+
+ result = $.timepicker._util._splitDateTime(inputDateTimeString, {separator: separator});
+
+ expect(result).toEqual({dateString: expectedDateString, timeString: expectedTimeString});
+ });
+
+ it('splits a date and time into its parts when there are multiple separators in the time format', function() {
+ var timeFormat = 'hh mm tt',
+ separator = ' ',
+ alternateTimeString = '07 32 am',
+ inputDateTimeString = expectedDateString + separator + alternateTimeString,
+ timeSettings = {separator: separator, timeFormat: timeFormat},
+ result;
+
+ result = $.timepicker._util._splitDateTime(inputDateTimeString, timeSettings);
+
+ expect(result).toEqual({dateString: expectedDateString, timeString: alternateTimeString});
+ });
+
+ it('splits only a date into itself', function() {
+ var result = $.timepicker._util._splitDateTime(expectedDateString, {});
+
+ expect(result).toEqual({dateString: expectedDateString, timeString: ''});
+ });
+ });
+
+ describe('parseDateTimeInternal', function() {
+ var dateFormat = 'mm/dd/yy';
+
+ it('should return only a date if there is no time component', function() {
+ var inputDateString = '9/11/2001',
+ expectedDate = new Date(inputDateString),
+ result;
+
+ result = util._parseDateTimeInternal(dateFormat, undefined, inputDateString, undefined, undefined);
+
+ expect(result.date).toEqual(expectedDate);
+ expect(result.timeObj).toBeUndefined();
+ });
+
+ it('should return a date and a parsed time if a time is included', function() {
+ var expectedDateString = '7/4/1976',
+ expectedParsedTime = {
+ hour: 1,
+ minute: 23,
+ second: 45,
+ millisec: 678,
+ microsec: 0
+ },
+ inputDateTimeString = expectedDateString + ' '
+ + expectedParsedTime.hour + ':'
+ + expectedParsedTime.minute + ':'
+ + expectedParsedTime.second + '.'
+ + expectedParsedTime.millisec,
+ expectedDate = new Date(expectedDateString),
+ result;
+
+ result = util._parseDateTimeInternal(dateFormat, 'H:m:s.l', inputDateTimeString, undefined, undefined);
+
+ expect(result.date).toEqual(expectedDate);
+ expect(result.timeObj).toEqual(expectedParsedTime);
+ });
+
+ it('should throw an exception if it cannot parse the time', function() {
+ var inputDateString = '4/17/2008 11:22:33';
+
+ expect(function() {
+ util._parseDateTimeInternal(dateFormat, 'q', inputDateString, undefined, undefined);
+ }).toThrow('Wrong time format');
+ });
+ });
+ });
+
+ describe('timepicker functions', function() {
+ describe('timezoneOffsetNumber', function() {
+ it('returns 0 if the time zone string is iso8601 Zulu', function() {
+ expect($.timepicker.timezoneOffsetNumber('Z')).toBe(0);
+ expect($.timepicker.timezoneOffsetNumber('z')).toBe(0);
+ expect($.timepicker.timezoneOffsetNumber(':Z')).toBe(0);
+ });
+
+ it('returns a string that does not match the expected representations', function() {
+ expect($.timepicker.timezoneOffsetNumber('EDT')).toBe('EDT');
+ expect($.timepicker.timezoneOffsetNumber('1234')).toBe('1234');
+ expect($.timepicker.timezoneOffsetNumber('+123')).toBe('+123');
+ expect($.timepicker.timezoneOffsetNumber('-123')).toBe('-123');
+ expect($.timepicker.timezoneOffsetNumber('abc:def')).toBe('abc:def');
+ });
+
+ it('returns the minute offset from a time zone offset string', function() {
+ expect($.timepicker.timezoneOffsetNumber('-0000')).toBe(0);
+ expect($.timepicker.timezoneOffsetNumber('+0000')).toBe(0);
+ expect($.timepicker.timezoneOffsetNumber('-0400')).toBe(-240);
+ expect($.timepicker.timezoneOffsetNumber('+0400')).toBe(240);
+ });
+ });
+
+ describe('timezoneOffsetString', function() {
+ it('returns NaN if the input is NaN', function() {
+ expect($.timepicker.timezoneOffsetString(NaN)).toBeNaN();
+ });
+
+ it('returns the input if the input is greater than 840 (+14:00)', function() {
+ var expectedMinutes = 850;
+
+ var actualMinutes = $.timepicker.timezoneOffsetString(expectedMinutes);
+
+ expect(actualMinutes).toBe(expectedMinutes);
+ });
+
+ it('returns the input if the input is less than -720 (-12:00)', function() {
+ var expectedMinutes = -730;
+
+ var actualMinutes = $.timepicker.timezoneOffsetString(expectedMinutes);
+
+ expect(actualMinutes).toBe(expectedMinutes);
+ });
+
+ it('returns "Z" if the offset is 0 and iso8601 is true', function() {
+ expect($.timepicker.timezoneOffsetString(0, true)).toBe('Z');
+ });
+
+ it('returns the expected offset string for non-iso8601 values', function() {
+ expect($.timepicker.timezoneOffsetString(0, false)).toBe('+0000');
+ expect($.timepicker.timezoneOffsetString(60, false)).toBe('+0100');
+ expect($.timepicker.timezoneOffsetString(480, false)).toBe('+0800');
+ expect($.timepicker.timezoneOffsetString(-60, false)).toBe('-0100');
+ expect($.timepicker.timezoneOffsetString(-480, false)).toBe('-0800');
+ expect($.timepicker.timezoneOffsetString(-720, false)).toBe('-1200');
+ expect($.timepicker.timezoneOffsetString(840, false)).toBe('+1400');
+ });
+
+ it('returns the expected offset string for iso8601 values', function() {
+ expect($.timepicker.timezoneOffsetString(60, true)).toBe('+01:00');
+ expect($.timepicker.timezoneOffsetString(480, true)).toBe('+08:00');
+ expect($.timepicker.timezoneOffsetString(-60, true)).toBe('-01:00');
+ expect($.timepicker.timezoneOffsetString(-480, true)).toBe('-08:00');
+ expect($.timepicker.timezoneOffsetString(-720, true)).toBe('-12:00');
+ expect($.timepicker.timezoneOffsetString(840, true)).toBe('+14:00');
+ });
+ });
+
+ describe('timezoneAdjust', function() {
+ it('does not change the date if the timezone yields NaN for an offset', function() {
+ var expectedDate = new Date();
+
+ expect($.timepicker.timezoneAdjust(expectedDate, NaN)).toEqual(expectedDate);
+ });
+
+ it('changes the minutes by the time zone offset minutes', function() {
+ var inputDate,
+ originalMillis,
+ expectedDifference,
+ adjustedDate;
+
+ inputDate = new Date();
+ originalMillis = inputDate.getTime();
+ expectedDifference = -(inputDate.getTimezoneOffset() + 60) * 60 * 1000;
+
+ adjustedDate = $.timepicker.timezoneAdjust(inputDate, '+0100');
+
+ expect(adjustedDate.getTime() - originalMillis).toBe(expectedDifference);
+ });
+ });
+
+ describe('log', function() {
+ it('calls console.log with the message if the console exists', function() {
+ var expectedMessage = "Just what I expected!";
+ spyOn(window.console, "log");
+
+ $.timepicker.log(expectedMessage);
+
+ expect(window.console.log).toHaveBeenCalledWith(expectedMessage);
+ });
+
+ it('does not call console.log if there is no console', function() {
+ var originalConsole = window.console,
+ consoleLogSpy = spyOn(window.console, "log");
+ window.console = undefined;
+
+ $.timepicker.log("Don't care");
+
+ expect(consoleLogSpy).not.toHaveBeenCalled();
+
+ window.console = originalConsole;
+ });
+ });
+
+ describe('range functions', function() {
+ var startTime = $('<p>start</p>'),
+ endTime = $('<p>end</p>'),
+ options = {};
+
+ describe('convenience functions', function() {
+ beforeEach(function() {
+ spyOn($.timepicker, 'handleRange');
+ });
+
+ it('timeRange calls handleRange the right way', function() {
+ $.timepicker.timeRange(startTime, endTime, options);
+
+ expect($.timepicker.handleRange).toHaveBeenCalledWith('timepicker', startTime, endTime, options);
+ });
+
+ it('datetimeRange calls handleRange the right way', function() {
+ $.timepicker.datetimeRange(startTime, endTime, options);
+
+ expect($.timepicker.handleRange).toHaveBeenCalledWith('datetimepicker', startTime, endTime, options);
+ });
+
+ it('dateRange calls handleRange the right way', function() {
+ $.timepicker.dateRange(startTime, endTime, options);
+
+ expect($.timepicker.handleRange).toHaveBeenCalledWith('datepicker', startTime, endTime, options);
+ });
+ });
+
+ xdescribe('handleRange', function() {
+ // TODO: Difficult to test. Needs attention.
+ });
+ });
});
}); \ No newline at end of file