浏览代码

beginnings of an automated testing framework (Karma and Jasmine)

written by Gareth Leachman, squashed and reformatted by Adam Shaw
Gareth Leachman 12 年之前
父节点
当前提交
2bbbbf678e

+ 63 - 0
karma.conf.IntegrationTests.js

@@ -0,0 +1,63 @@
+// Karma configuration
+// Generated on Wed Sep 18 2013 21:29:48 GMT+0100 (GMT Daylight Time)
+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-simulate/*.js', watched: false },
+			{ pattern: './lib/jasmine-jquery/*.js', watched: false },
+			{ pattern: './lib/jquery-ui/ui/jquery-ui.js', watched: false },
+			{ pattern: './lib/jquery-ui/ui/jquery.ui.draggable.js', watched: false },
+			{ pattern: './lib/jasmine-fixture/*.js', watched: false },
+			'./build/out/fullcalendar.js',
+			'./build/out/fullcalendar.css',
+			'./build/out/fullcalendar.print.css',
+			'./specs/fullCalendar*.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
+	});
+};

+ 65 - 0
specs/fullCalendar.js

@@ -0,0 +1,65 @@
+'use strict';
+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());
+			});
+		});
+	});
+});

+ 80 - 0
specs/fullCalendarSpecs-AgendaOptions-allDaySlots.js

@@ -0,0 +1,80 @@
+'use strict';
+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
specs/fullCalendarSpecs-AgendaOptions-allDayText.js

@@ -0,0 +1,81 @@
+'use strict';
+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');
+			});
+		});
+	});
+});

+ 132 - 0
specs/fullCalendarSpecs-AgendaOptions-minTime.js

@@ -0,0 +1,132 @@
+'use strict';
+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
specs/fullCalendarSpecs-AgendaOptions-slotMinutes.js

@@ -0,0 +1,96 @@
+'use strict';
+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);
+				});
+			});
+		});
+	});
+});

+ 140 - 0
specs/fullCalendarSpecs-options-aspectRatio.js

@@ -0,0 +1,140 @@
+'use strict';
+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)
+			});
+		});
+	});
+});

+ 49 - 0
specs/fullCalendarSpecs-options-contentHeight.js

@@ -0,0 +1,49 @@
+'use strict';
+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);
+		});
+	});
+});

+ 166 - 0
specs/fullCalendarSpecs-options-firstDay.js

@@ -0,0 +1,166 @@
+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');
+		});
+	});
+});

+ 19 - 0
specs/fullCalendarSpecs-options-handleWindowResize.js

@@ -0,0 +1,19 @@
+'use strict';
+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
specs/fullCalendarSpecs-options-header.js

@@ -0,0 +1,79 @@
+'use strict';
+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);
+		});
+	});
+});

+ 60 - 0
specs/fullCalendarSpecs-options-headerDateClick.js

@@ -0,0 +1,60 @@
+'use strict';
+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());
+		});
+	});
+});

+ 49 - 0
specs/fullCalendarSpecs-options-height.js

@@ -0,0 +1,49 @@
+'use strict';
+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);
+		});
+	});
+});

+ 87 - 0
specs/fullCalendarSpecs-options-hiddenDays.js

@@ -0,0 +1,87 @@
+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
specs/fullCalendarSpecs-options-isRTL.js

@@ -0,0 +1,231 @@
+'use strict';
+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');
+			});
+		});
+	});
+});

+ 148 - 0
specs/fullCalendarSpecs-options-weekMode.js

@@ -0,0 +1,148 @@
+'use strict';
+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);
+		});
+	});
+});

+ 36 - 0
specs/fullCalendarSpecs-options-weekNumberCalculation.js

@@ -0,0 +1,36 @@
+'use strict';
+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: myWeekNumber
+			});
+			$('#cal').fullCalendar('gotoDate', 2013, 10, 17);
+			var weekNum = parseInt($('.fc-week.fc-first .fc-week-number div').text());
+			expect(weekNum).toEqual(4);
+		});
+	});
+
+	var myWeekNumber = function(someDate) {
+		return 4;
+	};
+});

+ 38 - 0
specs/fullCalendarSpecs-options-weekNumbers.js

@@ -0,0 +1,38 @@
+'use strict';
+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
specs/fullCalendarSpecs-options-weekends.js

@@ -0,0 +1,31 @@
+'use strict';
+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();
+	});
+
+});

+ 26 - 0
specs/fullCalendarSpecs-optionsCombinations-firstDay-isRTL.js

@@ -0,0 +1,26 @@
+describe('First Day : ', 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');
+		});
+	});
+});

+ 141 - 0
specs/fullCalendarSpecs-optionsCombinations-weekNumbers-defaultView.js

@@ -0,0 +1,141 @@
+'use strict';
+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);
+			});
+		});
+	});
+});

+ 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;
+}