Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
test(calendar): Add tests for calendar construction
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Chen authored and jelbourn committed Aug 13, 2015
1 parent e6b1d23 commit 15c7362
Showing 1 changed file with 134 additions and 10 deletions.
144 changes: 134 additions & 10 deletions src/components/calendar/calendar.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@

describe('md-checkbox', function() {
var ngElement, element, scope, pageScope, controller, $animate;
describe('md-calendar', function() {
// When constructing a Date, the month is zero-based. This can be confusing, since people are
// used to seeing them one-based. So we create these aliases to make reading the tests easier.
var JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9,
NOV = 10, DEC = 11;

var ngElement, element, scope, pageScope, controller, $animate, $compile;
var $rootScope, dateLocale;

/**
* To apply a change in the date, a scope $apply() AND a manual triggering of animation
Expand All @@ -11,40 +17,158 @@ describe('md-checkbox', function() {
$animate.triggerCallbacks();
}

beforeEach(module('material.components.calendar', 'ngAnimateMock'));
/**
* Extracts text as an array (one element per cell) from a tr element.
*/
function extractRowText(tr) {
var cellContents = [];
angular.forEach(tr.children, function(tableElement) {
cellContents.push(tableElement.textContent);
});

return cellContents;
}

/**
* Finds a date td given a day of the month from an .md-calendar-month element.
*/
function findDateElement(monthElement, day) {
var tds = monthElement.querySelectorAll('td');
var td;

for (var i = 0; i < tds.length; i++) {
td = tds[i];
if (td.textContent === day.toString()) {
return td;
}
}
}

beforeEach(inject(function($compile, $rootScope, _$animate_) {
$animate = _$animate_;

/**
* Creates and compiles an md-calendar element.
*/
function createElement(parentScope) {
var directiveScope = parentScope || $rootScope.$new();
var template = '<md-calendar ng-model="myDate"></md-calendar>';
var newElement = $compile(template)(directiveScope);
directiveScope.$apply();
return newElement;
}

beforeEach(module('material.components.calendar', 'ngAnimateMock'));

beforeEach(inject(function($injector) {
$animate = $injector.get('$animate');
$compile = $injector.get('$compile');
$rootScope = $injector.get('$rootScope');
dateLocale = $injector.get('$$mdDateLocale');

pageScope = $rootScope.$new();
pageScope.myDate = null;

ngElement = $compile(template)(pageScope);
ngElement = createElement(pageScope);
element = ngElement[0];
scope = ngElement.scope();
controller = ngElement.controller('mdCalendar');

pageScope.$apply();
}));

describe('ngModel binding', function() {

it('should update the calendar based on ngModel change', function() {
pageScope.myDate = new Date(2014, 4, 30);
pageScope.myDate = new Date(2014, MAY, 30);
applyDateChange();

var displayedMonth = element.querySelector('.md-calendar-month-label');
var selectedDate = element.querySelector('.md-calendar-selected-date');

expect(displayedMonth.textContent).toBe('May');
expect(selectedDate.textContent).toBe('30')
expect(selectedDate.textContent).toBe('30');
});

});

describe('calendar construction', function() {
describe('weeks header', function() {
it('should display the weeks header in the first row', function() {
var header = element.querySelector('.md-calendar-day-header tr');

expect(extractRowText(header)).toEqual(['S', 'M', 'T', 'W', 'T', 'F' ,'S']);
});

it('should use $$mdDateLocale.shortDays as weeks header values', function() {
var oldShortDays = dateLocale.shortDays;
dateLocale.shortDays = ['SZ', 'MZ', 'TZ', 'WZ', 'TZ', 'FZ', 'SZ'];

var newElement = createElement()[0];
var header = newElement.querySelector('.md-calendar-day-header tr');

expect(extractRowText(header)).toEqual(['SZ', 'MZ', 'TZ', 'WZ', 'TZ', 'FZ','SZ']);
dateLocale.shortDays = oldShortDays;
});
});

describe('#buildCalendarForMonth', function() {
it('should render a month correctly as a table', function() {
var date = new Date(2014, MAY, 30);
var monthElement = controller.buildCalendarForMonth(date);

var calendarRows = monthElement.querySelectorAll('tr');
var calendarDates = [];

angular.forEach(calendarRows, function(tr) {
calendarDates.push(extractRowText(tr));
});

var expectedDates = [
['May', '', '', '1', '2', '3'],
['4', '5', '6', '7', '8', '9', '10'],
['11', '12', '13', '14', '15', '16', '17'],
['18', '19', '20', '21', '22', '23', '24'],
['25', '26', '27', '28', '29', '30', '31'],
];
expect(calendarDates).toEqual(expectedDates);
});

it('should show the month on its own row if the first day is before Tuesday', function() {
var date = new Date(2014, JUN, 30); // 1st on Sunday
var monthElement = controller.buildCalendarForMonth(date);

var firstRow = monthElement.querySelector('tr');
expect(extractRowText(firstRow)).toEqual(['Jun']);
});
});


it('should highlight today', function() {
pageScope.myDate = controller.today;
applyDateChange();

var monthElement = element.querySelector('.md-calendar-month');
var day = controller.today.getDate();

var dateElement = findDateElement(monthElement, day);
expect(dateElement.classList.contains('md-calendar-date-today')).toBe(true);
});

it('should have ids for date elements unique to the directive instance', function() {
pageScope.myDate = controller.today;
applyDateChange();

var otherScope = $rootScope.$new();

otherScope.myDate = controller.today;
var otherNgElement = createElement(otherScope);

var monthElement = element.querySelector('.md-calendar-month');
var day = controller.today.getDate();
var dateElement = findDateElement(monthElement, day);

var otherMonthElement = otherNgElement[0].querySelector('.md-calendar-month');
var otherDateElement = findDateElement(otherMonthElement, day);

expect(dateElement.id).not.toEqual(otherDateElement.id);
});
});

describe('keyboard events', function() {
Expand Down

0 comments on commit 15c7362

Please sign in to comment.