Prechádzať zdrojové kódy

Merge branch 'v1-autotest' into v2-autotest

Conflicts:
	bower.json
Adam Shaw 12 rokov pred
rodič
commit
634ec186ee

+ 4 - 1
bower.json

@@ -2,8 +2,11 @@
   "name": "fullcalendar",
   "version": "2.0.0-beta",
   "devDependencies": {
+    "moment": ">=2.5.0",
     "jquery": "~1.10.2",
     "jquery-ui": "~1.10.3",
-    "moment": ">=2.5.0"
+    "jquery-simulate": "*",
+    "jasmine-jquery": "~1.7.0",
+    "jasmine-fixture": "~1.0.8"
   }
 }

+ 61 - 0
karma.conf.js

@@ -0,0 +1,61 @@
+
+module.exports = function(config) {
+	config.set({
+
+		// base path, that will be used to resolve files and exclude
+		basePath: '',
+
+		// frameworks to use
+		frameworks: [ 'jasmine' ],
+
+		// list of files / patterns to load in the browser
+		files: [
+			{ pattern: 'lib/jquery/jquery.js', watched: false },
+			{ pattern: 'lib/jquery-ui/ui/jquery-ui.js', watched: false },
+			{ pattern: 'lib/jquery-simulate/jquery.simulate.js', watched: false },
+			{ pattern: 'lib/jasmine-jquery/lib/jasmine-jquery.js', watched: false },
+			{ pattern: 'lib/jasmine-fixture/dist/jasmine-fixture.js', watched: false },
+			'build/out/fullcalendar.js',
+			'build/out/fullcalendar.css',
+			'tests/base.css',
+			'tests/automated/*.js'
+		],
+
+		// list of files to exclude
+		exclude: [],
+
+		// test results reporter to use
+		// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
+		reporters: [ 'dots' ],
+
+		// web server port
+		port: 9876,
+
+		// enable / disable colors in the output (reporters and logs)
+		colors: true,
+
+		// level of logging
+		// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+		logLevel: config.LOG_INFO,
+
+		// enable / disable watching file and executing tests whenever any file changes
+		autoWatch: true,
+
+		// Start these browsers, currently available:
+		// - Chrome
+		// - ChromeCanary
+		// - Firefox
+		// - Opera
+		// - Safari (only Mac)
+		// - PhantomJS
+		// - IE (only Windows)
+		//browsers: [ 'PhantomJS' ],
+
+		// If browser does not capture in given timeout [ms], kill it
+		captureTimeout: 60000,
+
+		// Continuous Integration mode
+		// if true, it capture browsers, run tests and exit
+		singleRun: false
+	});
+};

+ 15 - 4
readme.md

@@ -45,10 +45,20 @@ If you want to clean up the generated files, run:
 	grunt clean
 
 
-Writing Tests
--------------
+Automated Testing
+-----------------
 
-When fixing a bug or writing a feature, please make a corresponding HTML file in the `./tests/` directory to visually demonstrate your work. If the test requires user intervention to prove its point, please write instructions for the user to follow. Explore the existing tests for more info.
+To run automated tests, you must first install [karma] globally:
+
+	npm install -g karma
+
+Then, assuming all your source files have been built (via `grunt dev` or `watch`), you can run the tests from a browser:
+
+	karma start --single-run
+
+This will output a URL that you can visit in a browser. Alternatively, you can run the tests headlessly:
+
+	karma start --single-run --browsers PhantomJS
 
 
 [fc-homepage]: http://arshaw.com/fullcalendar/
@@ -56,4 +66,5 @@ When fixing a bug or writing a feature, please make a corresponding HTML file in
 [node]: http://nodejs.org/
 [grunt-cli]: http://gruntjs.com/getting-started#installing-the-cli
 [bower]: http://bower.io/
-[jq-readme]: https://github.com/jquery/jquery/blob/master/README.md#what-you-need-to-build-your-own-jquery
+[jq-readme]: https://github.com/jquery/jquery/blob/master/README.md#what-you-need-to-build-your-own-jquery
+[karma]: http://karma-runner.github.io/0.10/index.html

+ 80 - 0
tests/automated/allDaySlot.js

@@ -0,0 +1,80 @@
+
+describe('allDaySlots', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when allDaySlots is not set', function() {
+		describe('in agendaWeek', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(1);
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaDay'
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(1);
+			});
+		});
+	});
+
+	describe('when allDaySlots is set true', function() {
+		describe('in agendaWeek', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaWeek',
+					allDaySlot: true
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(1);
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaDay',
+					allDaySlot: true
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(1);
+			});
+		});
+	});
+
+	describe('when allDaySlots is set false', function() {
+		describe('in agendaWeek', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaWeek',
+					allDaySlot: false
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(0);
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should default to having an allDaySlots table', function() {
+				var options = {
+					defaultView: 'agendaDay',
+					allDaySlot: false
+				};
+				$('#cal').fullCalendar(options);
+				var allDaySlotCount = $('table.fc-agenda-allday').length;
+				expect(allDaySlotCount).toEqual(0);
+			});
+		});
+	});
+});

+ 81 - 0
tests/automated/allDayText.js

@@ -0,0 +1,81 @@
+
+describe('allDayText', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when allDaySlots is not set', function() {
+		describe('in agendaWeek', function() {
+			it('should default allDayText to using \'all-day\'', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('all-day');
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should default allDayText to using \'all-day\'', function() {
+				var options = {
+					defaultView: 'agendaDay'
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('all-day');
+			});
+		});
+	});
+
+	describe('when allDaySlots is set true', function() {
+		describe('in agendaWeek', function() {
+			it('should default allDayText to using \'all-day\'', function() {
+				var options = {
+					defaultView: 'agendaWeek',
+					allDaySlot: true
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('all-day');
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should default allDayText to using \'all-day\'', function() {
+				var options = {
+					defaultView: 'agendaDay',
+					allDaySlot: true
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('all-day');
+			});
+		});
+	});
+
+	describe('when allDaySlots is set true and allDayText is specified', function() {
+		describe('in agendaWeek', function() {
+			it('should show specified all day text', function() {
+				var options = {
+					defaultView: 'agendaWeek',
+					allDaySlot: true,
+					allDayText: 'axis-phosy'
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('axis-phosy');
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should show specified all day text', function() {
+				var options = {
+					defaultView: 'agendaDay',
+					allDayText: 'axis-phosy'
+				};
+				$('#cal').fullCalendar(options);
+				var allDayText = $('.fc-agenda-allday .fc-agenda-axis').text();
+				expect(allDayText).toEqual('axis-phosy');
+			});
+		});
+	});
+});

+ 140 - 0
tests/automated/aspectRatio.js

@@ -0,0 +1,140 @@
+
+describe('aspectRatio', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when default settings are used', function() {
+		beforeEach(function() {
+			$('#cal').width(675)
+			$('#cal').fullCalendar();
+		});
+		it('fc-content should use the ratio 1:35 to set height', function() {
+			var height = $('.fc-content').height();
+			expect(height).toEqual(500);
+		});
+		it('fc-content should have width of div', function() {
+			var width = $('.fc-content').width();
+			expect(width).toEqual(675);
+		});
+	});
+
+	describe('when initializing the aspectRatio', function() {
+
+		describe('to 2', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: 2
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width sizes very close to ratio of 2', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var ratio = Math.round(width / height * 100);
+				expect(ratio).toEqual(200);
+			});
+		});
+
+		describe('to 1', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: 1
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width sizes very close to ratio of 2', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var ratio = Math.round(width / height * 100);
+				expect(ratio).toEqual(100)
+			});
+		});
+
+		describe('to less than 0.5', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: 0.4
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width ratio to 0.5', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var ratio = Math.round(width / height * 100);
+				expect(ratio).toEqual(50);
+			});
+		});
+
+		describe('to negative', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: -2
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width ratio to 0.5', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var ratio = Math.round(width / height * 100);
+				expect(ratio).toEqual(50)
+			});
+		});
+
+		describe('to zero', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: 0
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width ratio to 0.5', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var ratio = Math.round(width / height * 100);
+				expect(ratio).toEqual(50);
+			});
+		});
+
+		describe('to very large', function() {
+			beforeEach(function() {
+				$('#cal').width(1000)
+				$('#cal').fullCalendar({
+					aspectRatio: 4000
+				});
+			});
+			it('should not change the width', function() {
+				var width = $('.fc-content').width();
+				expect(width).toEqual(1000);
+			});
+			it('should set the height to width ratio to 0.5', function() {
+				var width = $('.fc-content').width();
+				var height = $('.fc-content').height();
+				var pxHeightPerCharacter = 22;
+				var defaultWeeksInCal = 7;
+				expect(height).toEqual(pxHeightPerCharacter * defaultWeeksInCal)
+			});
+		});
+	});
+});

+ 26 - 0
tests/automated/complex-firstDay-isRTL.js

@@ -0,0 +1,26 @@
+describe('firstDay', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when first day is set to mon and isRTL is true', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 2,
+				isRTL: true
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should put days mon, sun, sat ...', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-mon');
+			expect(daysOfWeek[1]).toHaveClass('fc-sun');
+			expect(daysOfWeek[2]).toHaveClass('fc-sat');
+			expect(daysOfWeek[3]).toHaveClass('fc-fri');
+			expect(daysOfWeek[4]).toHaveClass('fc-thu');
+			expect(daysOfWeek[5]).toHaveClass('fc-wed');
+			expect(daysOfWeek[6]).toHaveClass('fc-tue');
+		});
+	});
+});

+ 60 - 0
tests/automated/complex-headerDateClick.js

@@ -0,0 +1,60 @@
+
+describe('when header options set with next|prev|prevYear|nextYear|today', function() {
+
+	beforeEach(function() {
+		affix('#calendar');
+		var options = {
+			header: {
+				left: 'next,prev,prevYear,nextYear today',
+				center: '',
+				right: 'title'
+			}
+		};
+		$('#calendar').fullCalendar(options);
+	});
+
+	describe('and click next', function() {
+		it('should change view to next month', function() {
+			$('#calendar').fullCalendar('gotoDate', 2010, 1, 1);
+			$('.fc-button-next').simulate('click');
+			var newDate = $('#calendar').fullCalendar('getDate');
+			expect(newDate).toEqual(new Date(2010, 2, 1));
+		});
+	});
+
+	describe('and click prev', function() {
+		it('should change view to prev month', function() {
+			$('#calendar').fullCalendar('gotoDate', 2010, 1, 1);
+			$('.fc-button-prev').simulate('click');
+			var newDate = $('#calendar').fullCalendar('getDate');
+			expect(newDate).toEqual(new Date(2009, 12, 1));
+		});
+	});
+
+	describe('and click prevYear', function() {
+		it('should change view to prev month', function() {
+			$('#calendar').fullCalendar('gotoDate', 2010, 1, 1);
+			$('.fc-button-prevYear').simulate('click');
+			var newDate = $('#calendar').fullCalendar('getDate');
+			expect(newDate).toEqual(new Date(2009, 1, 1));
+		});
+	});
+
+	describe('and click nextYear', function() {
+		it('should change view to prev month', function() {
+			$('#calendar').fullCalendar('gotoDate', 2010, 1, 1);
+			$('.fc-button-nextYear').simulate('click');
+			var newDate = $('#calendar').fullCalendar('getDate');
+			expect(newDate).toEqual(new Date(2011, 1, 1));
+		});
+	});
+
+	describe('and click today', function() {
+		it('should change view to prev month', function() {
+			$('#calendar').fullCalendar('gotoDate', 2010, 1, 1);
+			$('.fc-button-today').simulate('click');
+			var newDate = $('#calendar').fullCalendar('getDate');
+			expect(newDate.toDateString()).toEqual(new Date().toDateString());
+		});
+	});
+});

+ 141 - 0
tests/automated/complex-weekNumbers-defaultView.js

@@ -0,0 +1,141 @@
+
+describe('weekNumbers-defaultView', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using basicWeek', function() {
+		describe('with default weekNumbers ', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicWeek'
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to false', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicWeek',
+					weekNumbers: false
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to true', function() {
+			it('should display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicWeek',
+					weekNumbers: true
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				// 1 row is header
+				// 1 row is actual week number
+				expect(weekNumbersCount).toEqual(2);
+			});
+		});
+	});
+
+	describe('when using basicDay', function() {
+		describe('with default weekNumbers', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicDay'
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to false', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicDay',
+					weekNumbers: false
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to true', function() {
+			it('should display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'basicDay',
+					weekNumbers: true
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				// 1 row is header
+				// 1 row is actual week number
+				expect(weekNumbersCount).toEqual(2);
+			});
+		});
+	});
+
+	describe('when using agendaWeek', function() {
+		describe('with default weekNumbers', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek'
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to false', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek',
+					weekNumbers: false
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to true', function() {
+			it('should display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek',
+					weekNumbers: true
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				// 1 row is axis
+				expect(weekNumbersCount).toEqual(1);
+			});
+		});
+	});
+
+	describe('when using agendaDay', function() {
+		describe('with default weekNumbers', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaDay'
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to false', function() {
+			it('should not display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaDay',
+					weekNumbers: false
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				expect(weekNumbersCount).toEqual(0);
+			});
+		});
+		describe('with weekNumbers to true', function() {
+			it('should display weekNumbers', function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaDay',
+					weekNumbers: true
+				});
+				var weekNumbersCount = $('.fc-week-number').length;
+				// 1 row is axis
+				expect(weekNumbersCount).toEqual(1);
+			});
+		});
+	});
+});

+ 49 - 0
tests/automated/contentHeight.js

@@ -0,0 +1,49 @@
+
+describe('contentHeight', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+		$('#cal').width(900);
+	});
+
+	describe('when the default options are used', function() {
+		it('should set the height', function() {
+			$('#cal').width(1350);
+			$('#cal').fullCalendar();
+			var height = $('.fc-content').height();
+			expect(height).toEqual(1000);
+		});
+	});
+
+	describe('when the content height is set', function() {
+		it('should set the content height', function() {
+			$('#cal').fullCalendar({
+				contentHeight: 1000
+			});
+			var height = $('.fc-content').height();
+			expect(height).toEqual(1000);
+		});
+		it('should not change the container width', function() {
+			$('#cal').fullCalendar({
+				contentHeight: 1000
+			});
+			var width = $('#cal').width();
+			expect(width).toEqual(900);
+		});
+	});
+
+	describe('when the content height setter is used', function() {
+		it('should set the content height', function() {
+			$('#cal').fullCalendar();
+			$('#cal').fullCalendar('option', 'contentHeight', 1137);
+			var height = $('.fc-content').height();
+			expect(height).toEqual(1137);
+		});
+		it('should not change the container width', function() {
+			$('#cal').fullCalendar();
+			$('#cal').fullCalendar('option', 'contentHeight', 1137);
+			var width = $('#cal').width();
+			expect(width).toEqual(900);
+		});
+	});
+});

+ 167 - 0
tests/automated/firstDay.js

@@ -0,0 +1,167 @@
+
+describe('First Day', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using default settings', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar();
+		});
+		it('should make Sunday the first day of the week', function() {
+			var dayFirst = $('.fc-day-header')[0];
+			expect(dayFirst).toHaveClass('fc-sun');
+		});
+	});
+
+	describe('when setting firstDay to 0', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 0
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Sunday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-sun');
+			expect(daysOfWeek[1]).toHaveClass('fc-mon');
+			expect(daysOfWeek[2]).toHaveClass('fc-tue');
+			expect(daysOfWeek[3]).toHaveClass('fc-wed');
+			expect(daysOfWeek[4]).toHaveClass('fc-thu');
+			expect(daysOfWeek[5]).toHaveClass('fc-fri');
+			expect(daysOfWeek[6]).toHaveClass('fc-sat');
+		});
+	});
+
+	describe('when setting firstDay to 1', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 1
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Monday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-mon');
+			expect(daysOfWeek[1]).toHaveClass('fc-tue');
+			expect(daysOfWeek[2]).toHaveClass('fc-wed');
+			expect(daysOfWeek[3]).toHaveClass('fc-thu');
+			expect(daysOfWeek[4]).toHaveClass('fc-fri');
+			expect(daysOfWeek[5]).toHaveClass('fc-sat');
+			expect(daysOfWeek[6]).toHaveClass('fc-sun');
+		});
+	});
+
+	describe('when setting firstDay to 2', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 2
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Tuesday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-tue');
+			expect(daysOfWeek[1]).toHaveClass('fc-wed');
+			expect(daysOfWeek[2]).toHaveClass('fc-thu');
+			expect(daysOfWeek[3]).toHaveClass('fc-fri');
+			expect(daysOfWeek[4]).toHaveClass('fc-sat');
+			expect(daysOfWeek[5]).toHaveClass('fc-sun');
+			expect(daysOfWeek[6]).toHaveClass('fc-mon');
+		});
+	});
+
+	describe('when setting firstDay to 3', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 3
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Wednesday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-wed');
+			expect(daysOfWeek[1]).toHaveClass('fc-thu');
+			expect(daysOfWeek[2]).toHaveClass('fc-fri');
+			expect(daysOfWeek[3]).toHaveClass('fc-sat');
+			expect(daysOfWeek[4]).toHaveClass('fc-sun');
+			expect(daysOfWeek[5]).toHaveClass('fc-mon');
+			expect(daysOfWeek[6]).toHaveClass('fc-tue');
+		});
+	});
+
+	describe('when setting firstDay to 4', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 4
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Thursday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-thu');
+			expect(daysOfWeek[1]).toHaveClass('fc-fri');
+			expect(daysOfWeek[2]).toHaveClass('fc-sat');
+			expect(daysOfWeek[3]).toHaveClass('fc-sun');
+			expect(daysOfWeek[4]).toHaveClass('fc-mon');
+			expect(daysOfWeek[5]).toHaveClass('fc-tue');
+			expect(daysOfWeek[6]).toHaveClass('fc-wed');
+		});
+	});
+
+	describe('when setting firstDay to 5', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 5
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Friday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-fri');
+			expect(daysOfWeek[1]).toHaveClass('fc-sat');
+			expect(daysOfWeek[2]).toHaveClass('fc-sun');
+			expect(daysOfWeek[3]).toHaveClass('fc-mon');
+			expect(daysOfWeek[4]).toHaveClass('fc-tue');
+			expect(daysOfWeek[5]).toHaveClass('fc-wed');
+			expect(daysOfWeek[6]).toHaveClass('fc-thu');
+		});
+	});
+
+	describe('when setting firstDay to 6', function() {
+		beforeEach(function() {
+			var options = {
+				firstDay: 6
+			};
+			$('#cal').fullCalendar(options);
+		});
+		it('should make Saturday the first day of the week', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-sat');
+			expect(daysOfWeek[1]).toHaveClass('fc-sun');
+			expect(daysOfWeek[2]).toHaveClass('fc-mon');
+			expect(daysOfWeek[3]).toHaveClass('fc-tue');
+			expect(daysOfWeek[4]).toHaveClass('fc-wed');
+			expect(daysOfWeek[5]).toHaveClass('fc-thu');
+			expect(daysOfWeek[6]).toHaveClass('fc-fri');
+		});
+	});
+
+	describe('when new firstDay options are set', function() {
+		it('should change the first day of the week', function() {
+			var options = {
+				firstDay: 1
+			};
+			$('#cal').fullCalendar(options);
+			var firstDayBeforeChange = $('.fc-day-header')[0];
+			var newOptions = {
+				firstDay: 4
+			};
+			$('#cal').fullCalendar(newOptions);
+			var firstDayAfterChange = $('.fc-day-header')[0];
+			expect(firstDayBeforeChange).toHaveClass('fc-mon');
+			expect(firstDayAfterChange).toHaveClass('fc-thu');
+		});
+	});
+});

+ 65 - 0
tests/automated/fullCalendar.js

@@ -0,0 +1,65 @@
+
+describe('fullCalendar(Integration)', function() {
+
+	beforeEach(function() {
+		affix('#calendar');
+	});
+
+	describe('When fullCalendar() is called on a div', function() {
+
+		beforeEach(function() {
+			$('#calendar').fullCalendar();
+		});
+
+		it('should contain a table fc-header', function() {
+			var header = $('#calendar > table.fc-header');
+			expect(header[0]).not.toBeUndefined();
+		});
+
+		it('should contain a div fc-content', function() {
+			var content = ($('#calendar > div.fc-content'));
+			expect(content[0]).not.toBeUndefined();
+		});
+
+		it('should only contain 2 elements', function() {
+			var calenderNodeCount = $('#calendar >').length;
+			expect(calenderNodeCount).toEqual(2);
+		});
+
+		describe('and then called again', function() {
+			it('should still only have a single set of calendar [header,content]', function() {
+				$('#calendar').fullCalendar();
+				var count = $('#calendar >').length;
+				expect(count).toEqual(2);
+			});
+		});
+
+		// can't do event dragging yet.
+		// need to work out how fullCalendar is intercepting events.
+		xdescribe('when event is dragged from one cell to another', function() {
+			it('should move to the new cell', function() {
+				var eventName = 'xyzAllDayEvent';
+				$('#calendar').fullCalendar({
+					editable: true
+				});
+				$('#calendar').fullCalendar('addEventSource', {
+					events: [{
+						title: eventName,
+						start: new Date()
+					}]
+				});
+				var el = $('div .fc-event');
+				var offsetBefore = el.offset();
+				dump(offsetBefore);
+				var options = {
+					dx: 200,
+					dy: 0,
+					moves: 10,
+					handle: 'corner'
+				};
+				el.simulate('drag', options);
+				dump(el.offset());
+			});
+		});
+	});
+});

+ 19 - 0
tests/automated/handleWindowResize.js

@@ -0,0 +1,19 @@
+
+describe('handleWindowResize', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('When default is used, should fire resize event', function() {
+		it('should fire resize', function() {
+			var resized = 0;
+			$('#cal').fullCalendar({
+				windowResize: function(view) {
+					resized++;
+				}
+			});
+			expect(resized).toEqual(1);
+		});
+	});
+});

+ 79 - 0
tests/automated/header.js

@@ -0,0 +1,79 @@
+
+describe('header testing', function() {
+
+	beforeEach(function() {
+		affix('#calendar');
+	});
+
+	describe('when using default header options', function() {
+		it('should have title as default on left', function() {
+			$('#calendar').fullCalendar();
+			var headr = $('#calendar > table.fc-header .fc-header-left > span')[0];
+			expect(headr).toHaveClass('fc-header-title');
+		});
+		it('should have empty center', function() {
+			$('#calendar').fullCalendar();
+			var cntr = $('#calendar > table.fc-header .fc-header-center')[0];
+			expect(cntr).toBeEmpty();
+		});
+		it('should have right with today|space|left|right', function() {
+			$('#calendar').fullCalendar();
+			var td = $('#calendar > table.fc-header .fc-header-right > span')[0];
+			var sp = $('#calendar > table.fc-header .fc-header-right > span')[1];
+			var lft = $('#calendar > table.fc-header .fc-header-right > span')[2];
+			var rt = $('#calendar > table.fc-header .fc-header-right > span')[3];
+			expect(td).toHaveClass('fc-button-today');
+			expect(sp).toHaveClass('fc-header-space');
+			expect(lft).toHaveClass('fc-button-prev');
+			expect(rt).toHaveClass('fc-button-next');
+		});
+	});
+
+	describe('when supplying header options', function() {
+		beforeEach(function() {
+			var options = {
+				header: {
+					left: 'next,prev',
+					center: 'prevYear today nextYear agendaView,dayView',
+					right: 'title'
+				}
+			};
+			$('#calendar').fullCalendar(options);
+		});
+		it('should have title on the right', function() {
+			var item = $('#calendar > table.fc-header .fc-header-right > span')[0];
+			expect(item).toHaveClass('fc-header-title');
+		});
+		it('should have next|prev on left', function() {
+			var nxt = $('#calendar > table.fc-header .fc-header-left > span')[0];
+			var prv = $('#calendar > table.fc-header .fc-header-left > span')[1];
+			expect(nxt).toHaveClass('fc-button-next');
+			expect(prv).toHaveClass('fc-button-prev');
+		});
+		it('should have prevYear|space|today|space|nextYear in center', function() {
+			var py = $('#calendar > table.fc-header .fc-header-center > span')[0];
+			var sp1 = $('#calendar > table.fc-header .fc-header-center > span')[1];
+			var td = $('#calendar > table.fc-header .fc-header-center > span')[2];
+			var sp2 = $('#calendar > table.fc-header .fc-header-center > span')[3];
+			var ny = $('#calendar > table.fc-header .fc-header-center > span')[4];
+			expect(py).toHaveClass('fc-button-prevYear');
+			expect(sp1).toHaveClass('fc-header-space');
+			expect(td).toHaveClass('fc-button-today');
+			expect(sp2).toHaveClass('fc-header-space');
+			expect(ny).toHaveClass('fc-button-nextYear');
+		});
+	});
+
+	describe('when setting header to false', function() {
+		beforeEach(function() {
+			var options = {
+				header: false
+			};
+			$('#calendar').fullCalendar(options);
+		})
+		it('should not have header table', function() {
+			var headerTableCount = $('table.fc-header').length;
+			expect(headerTableCount).toEqual(0);
+		});
+	});
+});

+ 49 - 0
tests/automated/height.js

@@ -0,0 +1,49 @@
+
+describe('height', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using default height', function() {
+		it('should use default height based on default aspect ratio of 1:35', function() {
+			$('#cal').width(1350);
+			$('#cal').fullCalendar();
+			var height = $('.fc-content').height();
+			expect(height).toEqual(1000);
+		});
+	});
+
+	describe('when setting height with the setter', function() {
+		beforeEach(function() {
+			$('#cal').width(673);
+			$('#cal').fullCalendar();
+			$('#cal').fullCalendar('option', 'height', 751);
+		});
+		it('should not change the width of the block level container', function() {
+			var width = $('#cal').width();
+			expect(width).toEqual(673);
+		});
+		it('should set the size of the block level container to the height', function() {
+			var height = $('#cal').height();
+			expect(height).toEqual(751);
+		});
+	});
+
+	describe('when setting height at instantiation', function() {
+		beforeEach(function() {
+			$('#cal').width(673);
+			$('#cal').fullCalendar({
+				height: 751
+			});
+		});
+		it('should not change the width of the block level container', function() {
+			var width = $('#cal').width();
+			expect(width).toEqual(673);
+		});
+		it('should set the size of the block level container to the height', function() {
+			var height = $('#cal').height();
+			expect(height).toEqual(751);
+		});
+	});
+});

+ 88 - 0
tests/automated/hiddenDays.js

@@ -0,0 +1,88 @@
+
+describe('hiddenDays', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using default', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar();
+		});
+		it('should show 7 days of the week', function() {
+			var daysCount = $('.fc-day-header').length;
+			expect(daysCount).toEqual(7);
+		});
+	});
+
+	describe('when setting an empty hiddenDays', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				hiddenDays: []
+			});
+		});
+		it('should return 7 days of the week', function() {
+			var daysCount = $('.fc-day-header').length;
+			expect(daysCount).toEqual(7);
+		});
+	});
+
+	describe('when setting hiddenDays with 1', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				hiddenDays: [1]
+			});
+		});
+		it('should return 6 days', function() {
+			var daysCount = $('.fc-day-header').length;
+			expect(daysCount).toEqual(6);
+		});
+		it('should return sun,tue,wed..sat days', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-sun');
+			expect(daysOfWeek[1]).toHaveClass('fc-tue');
+			expect(daysOfWeek[5]).toHaveClass('fc-sat');
+		});
+		it('should expect 7th day to be undefined', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[6]).toBeUndefined();
+		});
+	});
+
+	describe('when setting hiddenDays with 3,5', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				hiddenDays: [3, 5]
+			});
+		});
+		it('should return 6 days', function() {
+			var daysCount = $('.fc-day-header').length;
+			expect(daysCount).toEqual(5);
+		});
+		it('should return s,m,t,t,s ', function() {
+			var daysOfWeek = $('.fc-day-header');
+			expect(daysOfWeek[0]).toHaveClass('fc-sun');
+			expect(daysOfWeek[1]).toHaveClass('fc-mon');
+			expect(daysOfWeek[2]).toHaveClass('fc-tue');
+			expect(daysOfWeek[3]).toHaveClass('fc-thu');
+			expect(daysOfWeek[4]).toHaveClass('fc-sat');
+		});
+		it('should expect wed and fri be undefined', function() {
+			var fri = $('.fc-day-header.fc-fri')[0];
+			var wed = $('.fc-day-header.fc-wed')[0];
+			expect(fri).toBeUndefined();
+			expect(wed).toBeUndefined();
+		});
+	});
+
+	describe('when setting all hiddenDays', function() {
+		it('should expect to throw an exception', function() {
+			var options = {
+				hiddenDays: [0, 1, 2, 3, 4, 5, 6]
+			};
+			expect(function() {
+				$('#cal').fullCalendar(options);
+			}).toThrow('invalid hiddenDays');
+		});
+	});
+});

+ 231 - 0
tests/automated/isRTL.js

@@ -0,0 +1,231 @@
+
+describe('isRTL tests', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when setting l:prev c:today r:next settings with isRTL default', function() {
+		beforeEach(function() {
+			var options = {
+				header: {
+					left: 'prev',
+					center: 'today',
+					right: 'next'
+				}
+			};
+			$('#cal').fullCalendar(options);
+			var cal = $('#cal');
+		});
+		it('should have prev in left', function() {
+			var fcHeaderLeft = $(cal).find('.fc-header-left')[0];
+			expect(fcHeaderLeft).toContain('.fc-button-prev');
+		});
+		it('should have today in center', function() {
+			var fcHeaderCenter = $(cal).find('.fc-header-center')[0];
+			expect(fcHeaderCenter).toContain('.fc-button-today');
+		});
+		it('should have next in right', function() {
+			var fcHeaderRight = $(cal).find('.fc-header-right')[0];
+			expect(fcHeaderRight).toContain('.fc-button-next');
+		});
+	});
+
+	describe('when setting l:prev c:today r:next settings with isRTL false', function() {
+		beforeEach(function() {
+			var options = {};
+			$('#cal').fullCalendar({
+				header: {
+					left: 'prev',
+					center: 'today',
+					right: 'next'
+				},
+				isRTL: false
+			});
+			var cal = $('#cal');
+		});
+		it('should have prev in left', function() {
+			var fcHeaderLeft = $(cal).find('.fc-header-left')[0];
+			expect(fcHeaderLeft).toContain('.fc-button-prev');
+		});
+		it('should have today in center', function() {
+			var fcHeaderCenter = $(cal).find('.fc-header-center')[0];
+			expect(fcHeaderCenter).toContain('.fc-button-today');
+		});
+		it('should have next in right', function() {
+			var fcHeaderRight = $(cal).find('.fc-header-right')[0];
+			expect(fcHeaderRight).toContain('.fc-button-next');
+		});
+	});
+
+	describe('when setting l:prev c:today r:next settings with isRTL true', function() {
+		beforeEach(function() {
+			var options = {};
+			$('#cal').fullCalendar({
+				header: {
+					left: 'prev',
+					center: 'today',
+					right: 'next'
+				},
+				isRTL: true
+			});
+			var cal = $('#cal');
+		});
+		it('should have prev in left', function() {
+			var fcHeaderLeft = $(cal).find('.fc-header-left')[0];
+			expect(fcHeaderLeft).toContain('.fc-button-prev');
+		});
+		it('should have today in center', function() {
+			var fcHeaderCenter = $(cal).find('.fc-header-center')[0];
+			expect(fcHeaderCenter).toContain('.fc-button-today');
+		});
+		it('should have next in right', function() {
+			var fcHeaderRight = $(cal).find('.fc-header-right')[0];
+			expect(fcHeaderRight).toContain('.fc-button-next');
+		});
+	});
+
+	describe('when using default view (month)', function() {
+
+		describe('using default isRTL', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar();
+				var cal = $('#cal');
+			});
+			it('should have have days ordered sun to sat', function() {
+				var fc = $(cal).find('.fc-day-header');
+				expect(fc[0]).toHaveClass('fc-sun');
+				expect(fc[1]).toHaveClass('fc-mon');
+				expect(fc[2]).toHaveClass('fc-tue');
+				expect(fc[3]).toHaveClass('fc-wed');
+				expect(fc[4]).toHaveClass('fc-thu');
+				expect(fc[5]).toHaveClass('fc-fri');
+				expect(fc[6]).toHaveClass('fc-sat');
+			});
+		});
+
+		describe('using default isRTL is set to false', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar({
+					isRTL: false
+				});
+				var cal = $('#cal');
+			});
+			it('should have have days ordered sun to sat', function() {
+				var fc = $(cal).find('.fc-day-header');
+				expect(fc[0]).toHaveClass('fc-sun');
+				expect(fc[1]).toHaveClass('fc-mon');
+				expect(fc[2]).toHaveClass('fc-tue');
+				expect(fc[3]).toHaveClass('fc-wed');
+				expect(fc[4]).toHaveClass('fc-thu');
+				expect(fc[5]).toHaveClass('fc-fri');
+				expect(fc[6]).toHaveClass('fc-sat');
+			});
+		});
+
+		describe('using default isRTL is set to false', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar({
+					isRTL: true
+				});
+				var cal = $('#cal');
+			});
+			it('should have have days ordered back sat to sun', function() {
+				var fc = $(cal).find('.fc-day-header');
+				expect(fc[6]).toHaveClass('fc-sun');
+				expect(fc[5]).toHaveClass('fc-mon');
+				expect(fc[4]).toHaveClass('fc-tue');
+				expect(fc[3]).toHaveClass('fc-wed');
+				expect(fc[2]).toHaveClass('fc-thu');
+				expect(fc[1]).toHaveClass('fc-fri');
+				expect(fc[0]).toHaveClass('fc-sat');
+			});
+		});
+	});
+
+	describe('when using agendaWeek view', function() {
+
+		describe('when using default isRTL', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek'
+				});
+			});
+			it('should have have days ordered sun to sat', function() {
+				var fc = $(cal).find('.fc-agenda-days th');
+				expect(fc[0]).toHaveClass('fc-agenda-axis');
+				expect(fc[1]).toHaveClass('fc-sun');
+				expect(fc[2]).toHaveClass('fc-mon');
+				expect(fc[3]).toHaveClass('fc-tue');
+				expect(fc[4]).toHaveClass('fc-wed');
+				expect(fc[5]).toHaveClass('fc-thu');
+				expect(fc[6]).toHaveClass('fc-fri');
+				expect(fc[7]).toHaveClass('fc-sat');
+			});
+		});
+
+		describe('when using isRTL false', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek',
+					isRTL: false
+				});
+			});
+			it('should have have days ordered sun to sat', function() {
+				var fc = $(cal).find('.fc-agenda-days th');
+				expect(fc[0]).toHaveClass('fc-agenda-axis');
+				expect(fc[1]).toHaveClass('fc-sun');
+				expect(fc[2]).toHaveClass('fc-mon');
+				expect(fc[3]).toHaveClass('fc-tue');
+				expect(fc[4]).toHaveClass('fc-wed');
+				expect(fc[5]).toHaveClass('fc-thu');
+				expect(fc[6]).toHaveClass('fc-fri');
+				expect(fc[7]).toHaveClass('fc-sat');
+			});
+		});
+
+		describe('when using isRTL true', function() {
+			beforeEach(function() {
+				var options = {};
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek',
+					isRTL: true
+				});
+			});
+			it('should have have days ordered sun to sat', function() {
+				var fc = $(cal).find('.fc-agenda-days th');
+				expect(fc[0]).toHaveClass('fc-agenda-axis');
+				expect(fc[1]).toHaveClass('fc-sat');
+				expect(fc[2]).toHaveClass('fc-fri');
+				expect(fc[3]).toHaveClass('fc-thu');
+				expect(fc[4]).toHaveClass('fc-wed');
+				expect(fc[5]).toHaveClass('fc-tue');
+				expect(fc[6]).toHaveClass('fc-mon');
+				expect(fc[7]).toHaveClass('fc-sun');
+			});
+		});
+	});
+
+	xdescribe('when using agendaWeek view', function() {
+		describe('and switching from isRTL false to true', function() {
+			beforeEach(function() {
+				$('#cal').fullCalendar({
+					defaultView: 'agendaWeek',
+					isRTL: false
+				});
+			});
+			it('should result in sunday moving from first to last day', function() {
+				var fcDaysBefore = $(cal).find('.fc-agenda-days th');
+				$('#cal').fullCalendar('isRTL', 'true');
+				var fcDaysAfter = $(cal).find('.fc-agenda-days th');
+				expect(fcDaysBefore[1]).toHaveClass('fc-sun');
+				expect(fcDaysAfter[7]).toHaveCalss('fc-sun');
+			});
+		});
+	});
+});

+ 132 - 0
tests/automated/minTime.js

@@ -0,0 +1,132 @@
+
+describe('minTime', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	var numToStringConverter = function(timeIn) {
+		var time = (timeIn % 12);
+		if ($.inArray(timeIn, [0, 12]) != -1) {
+			time = 12;
+		}
+		var amPm = 'am';
+		if (timeIn > 11) {
+			amPm = 'pm';
+		}
+		return time + amPm;
+	};
+
+	describe('when using the default settings', function() {
+
+		describe('in agendaWeek', function() {
+			it('should start at 12am', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var firstSlotText = $('.fc-slot0 th').text();
+				expect(firstSlotText).toEqual('12am');
+			});
+		});
+
+		describe('in agendaDay', function() {
+			it('should start at 12am', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var firstSlotText = $('.fc-slot0 th').text();
+				expect(firstSlotText).toEqual('12am');
+			});
+		});
+	});
+
+	describe('when using a whole number', function() {
+
+		var hourNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
+
+		describe('in agendaWeek', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			hourNumbers.forEach(function(minTimeIn) {
+				it('should start at ' + minTimeIn, function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						minTime: minTimeIn
+					};
+					$('#cal2').fullCalendar(options);
+					var firstSlotText = $('.fc-slot0 th').text();
+					var expected = numToStringConverter(minTimeIn);
+					expect(firstSlotText).toEqual(expected);
+				});
+			});
+		});
+
+		describe('in agendaDay', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			hourNumbers.forEach(function(minTimeIn) {
+				it('should start at ' + minTimeIn, function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						minTime: minTimeIn
+					};
+					$('#cal2').fullCalendar(options);
+					var firstSlotText = $('.fc-slot0 th').text();
+					var expected = numToStringConverter(minTimeIn);
+					expect(firstSlotText).toEqual(expected);
+				});
+			});
+		});
+	});
+
+	describe('when using default slotInterval and \'uneven\' minTime', function() {
+
+		var hourNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
+
+		describe('in agendaWeek', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			hourNumbers.forEach(function(minTimeIn) {
+				it('should start at ' + minTimeIn + 0.12, function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						minTime: minTimeIn + 0.12
+					};
+					$('#cal2').fullCalendar(options);
+					var firstSlotElement = $('.fc-slot0')[0];
+					var secondSlotElement = $('.fc-slot1')[0];
+					var thirdSlotElement = $('.fc-slot2')[0];
+					expect(firstSlotElement).toHaveClass('fc-minor');
+					expect(secondSlotElement).toHaveClass('fc-minor');
+					expect(thirdSlotElement).toHaveClass('fc-minor');
+				});
+			});
+		});
+
+		describe('in agendaDay', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			hourNumbers.forEach(function(minTimeIn) {
+				it('should start at ' + minTimeIn + 0.12, function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						minTime: minTimeIn + 0.12
+					};
+					$('#cal2').fullCalendar(options);
+					var firstSlotElement = $('.fc-slot0')[0];
+					var secondSlotElement = $('.fc-slot1')[0];
+					var thirdSlotElement = $('.fc-slot2')[0];
+					expect(firstSlotElement).toHaveClass('fc-minor');
+					expect(secondSlotElement).toHaveClass('fc-minor');
+					expect(thirdSlotElement).toHaveClass('fc-minor');
+				});
+			});
+		});
+	});
+});

+ 96 - 0
tests/automated/slotMinutes.js

@@ -0,0 +1,96 @@
+
+describe('slotMinutes', function() {
+
+	var minutesInADay = 1440;
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using the default settings', function() {
+		describe('in agendaWeek', function() {
+			it('should have slots 1440/30 slots', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var slotCount = $('.fc-agenda-slots tr').length;
+				expect(slotCount).toEqual(Math.ceil(minutesInADay / 30));
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should have slots 1440/30 slots', function() {
+				var options = {
+					defaultView: 'agendaDay'
+				};
+				$('#cal').fullCalendar(options);
+				var slotCount = $('.fc-agenda-slots tr').length;
+				expect(slotCount).toEqual(Math.ceil(minutesInADay / 30));
+			});
+		});
+	});
+
+	describe('when slotMinutes is set to 30', function() {
+		describe('in agendaWeek', function() {
+			it('should have slots 1440/30 slots', function() {
+				var options = {
+					defaultView: 'agendaWeek'
+				};
+				$('#cal').fullCalendar(options);
+				var slotCount = $('.fc-agenda-slots tr').length;
+				expect(slotCount).toEqual(Math.ceil(minutesInADay / 30));
+			});
+		});
+		describe('in agendaDay', function() {
+			it('should have slots 1440/30 slots', function() {
+				var options = {
+					defaultView: 'agendaDay'
+				};
+				$('#cal').fullCalendar(options);
+				var slotCount = $('.fc-agenda-slots tr').length;
+				expect(slotCount).toEqual(Math.ceil(minutesInADay / 30));
+			});
+		});
+	});
+
+	describe('when slotMinutes is set to a series of times', function() {
+
+		var slotMinutesList = [10, 12, 15, 17, 20, 30, 35, 45, 60, 62, 120, 300];
+
+		describe('in agendaWeek', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			slotMinutesList.forEach(function(slotMinutesIn) {
+				it('should have slots 1440/x slots', function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						slotMinutes: slotMinutesIn
+					};
+					$('#cal2').fullCalendar(options);
+					var slotCount = $('.fc-agenda-slots tr').length;
+					var expected = Math.ceil(minutesInADay / slotMinutesIn);
+					expect(slotCount).toEqual(expected);
+				});
+			});
+		});
+
+		describe('in agendaDay', function() {
+			beforeEach(function() {
+				affix('#cal2');
+			});
+			slotMinutesList.forEach(function(slotMinutesIn) {
+				it('should have slots 1440/x slots', function() {
+					var options = {
+						defaultView: 'agendaWeek',
+						slotMinutes: slotMinutesIn
+					};
+					$('#cal2').fullCalendar(options);
+					var slotCount = $('.fc-agenda-slots tr').length;
+					var expected = Math.ceil(minutesInADay / slotMinutesIn);
+					expect(slotCount).toEqual(expected);
+				});
+			});
+		});
+	});
+});

+ 148 - 0
tests/automated/weekMode.js

@@ -0,0 +1,148 @@
+
+describe('weekMode', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	//
+	// Remember gotoDate uses month base 0
+	//
+	describe('when weekMode is default', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar();
+		});
+		it('should show 6 weeks for a 5 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should show 6 weeks for a 4 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 2);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should show 6 weeks for a 6 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should not change height whether 4,5 or weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var fourWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var sixWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fourWeekHeight).toEqual(fiveWeekHeight);
+			expect(fiveWeekHeight).toEqual(sixWeekHeight);
+		});
+	});
+
+	describe('when weekMode is set to fixed', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				weekMode: 'fixed'
+			});
+		});
+		it('should show 6 weeks for a 5 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should show 6 weeks for a 4 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 2);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should show 6 weeks for a 6 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+	});
+
+	describe('when weekMode is set to liquid', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				weekMode: 'liquid'
+			});
+		});
+		it('should show 5 weeks for a 5 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(5);
+		});
+		it('should show 4 weeks for a 4 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(4);
+		});
+		it('should show 6 weeks for a 6 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should increase height when moving from 6 week to 5 weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var sixWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fiveWeekHeight).toBeGreaterThan(sixWeekHeight);
+		});
+		it('should reduce height when moving from 5 weeks to 6 weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var sixWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fiveWeekHeight).toBeGreaterThan(sixWeekHeight);
+		});
+		it('should increase height when moving from 5 weeks to 4 weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 4);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var fourWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fourWeekHeight).toBeGreaterThan(fiveWeekHeight);
+		});
+		it('should reduce height when moving from 4 weeks to 5 weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var fourWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 4);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fourWeekHeight).toBeGreaterThan(fiveWeekHeight);
+		});
+	});
+
+	describe('when weekMode is set to variable', function() {
+		beforeEach(function() {
+			$('#cal').fullCalendar({
+				weekMode: 'variable'
+			});
+		});
+		it('should show 5 weeks for a 5 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(5);
+		});
+		it('should show 4 weeks for a 4 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(4);
+		});
+		it('should show 6 weeks for a 6 week month', function() {
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var weekCount = $('.fc-week').length;
+			expect(weekCount).toEqual(6);
+		});
+		it('should not change height whether 4,5 or weeks', function() {
+			$('#cal').fullCalendar('gotoDate', 2009, 1);
+			var fourWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 9);
+			var fiveWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			$('#cal').fullCalendar('gotoDate', 2013, 5);
+			var sixWeekHeight = parseInt($('.fc-week.fc-first .fc-first.fc-day div').css('min-height'));
+			expect(fourWeekHeight).toEqual(fiveWeekHeight);
+			expect(fiveWeekHeight).toEqual(sixWeekHeight);
+		});
+	});
+});

+ 34 - 0
tests/automated/weekNumberCalculation.js

@@ -0,0 +1,34 @@
+
+describe('weekNumberCalculation', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using the default', function() {
+		it('should return iso standard', function() {
+			$('#cal').fullCalendar({
+				editable: true,
+				weekNumbers: true
+			});
+			$('#cal').fullCalendar('gotoDate', 2013, 10, 17);
+			var weekNum = parseInt($('.fc-week.fc-first .fc-week-number div').text());
+			expect(weekNum).toEqual(43);
+		});
+	});
+
+	describe('when using a defined weekNumber calculation', function() {
+		it('should return the calculated number', function() {
+			$('#cal').fullCalendar({
+				editable: true,
+				weekNumbers: true,
+				weekNumberCalculation: function() {
+					return 4;
+				}
+			});
+			$('#cal').fullCalendar('gotoDate', 2013, 10, 17);
+			var weekNum = parseInt($('.fc-week.fc-first .fc-week-number div').text());
+			expect(weekNum).toEqual(4);
+		});
+	});
+});

+ 38 - 0
tests/automated/weekNumbers.js

@@ -0,0 +1,38 @@
+
+describe('weekNumbers', function() {
+
+	beforeEach(function() {
+		affix('#cal');
+	});
+
+	describe('when using default weekNumbers in default view', function() {
+		it('should not display weekNumbers', function() {
+			$('#cal').fullCalendar();
+			var weekNumbersCount = $('.fc-week-number').length;
+			expect(weekNumbersCount).toEqual(0);
+		});
+	});
+
+	describe('when setting weekNumbers to false in default view', function() {
+		it('should not display weekNumbers', function() {
+			$('#cal').fullCalendar({
+				weekNumbers: false
+			});
+			var weekNumbersCount = $('.fc-week-number').length;
+			expect(weekNumbersCount).toEqual(0);
+		});
+	});
+
+	describe('when setting weekNumbers to true in default view', function() {
+		it('should not display weekNumbers', function() {
+			$('#cal').fullCalendar({
+				weekNumbers: true
+			});
+			$('#cal').fullCalendar('gotoDate', 2013, 10);
+			var weekNumbersCount = $('.fc-week-number').length;
+			// 1 row is header
+			// 6 rows are week numbers
+			expect(weekNumbersCount).toEqual(7);
+		});
+	});
+});

+ 31 - 0
tests/automated/weekends.js

@@ -0,0 +1,31 @@
+
+describe('when weekends option is set', function() {
+
+	beforeEach(function() {
+		affix('#calendar');
+		var cal = $('#calendar');
+	})
+
+	it('should show sat and sun if true', function() {
+		var options = {
+			weekends: true
+		};
+		$('#calendar').fullCalendar(options);
+		var sun = $('.fc-day-header.fc-sun')[0];
+		var sat = $('.fc-day-header.fc-sun')[0];
+		expect(sun).toBeDefined();
+		expect(sat).toBeDefined();
+	});
+
+	it('should not show sat and sun if false', function() {
+		var options = {
+			weekends: false
+		};
+		$('#calendar').fullCalendar(options);
+		var sun = $('.fc-day-header.fc-sun')[0];
+		var sat = $('.fc-day-header.fc-sun')[0];
+		expect(sun).not.toBeDefined();
+		expect(sat).not.toBeDefined();
+	});
+
+});

+ 12 - 0
tests/base.css

@@ -0,0 +1,12 @@
+
+body {
+	margin-top: 40px;
+	text-align: center;
+	font-size: 13px;
+	font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
+}
+
+#calendar {
+	width: 900px;
+	margin: 0 auto;
+}