File: tests/spec/moHoverGallerySpec.js

Recommend this page to a friend!
  Classes of Michael Milev   JavaScript Hover Image Gallery   tests/spec/moHoverGallerySpec.js   Download  
File: tests/spec/moHoverGallerySpec.js
Role: Unit test script
Content type: text/plain
Description: Jasmine tests specification
Class: JavaScript Hover Image Gallery
Switch images in a gallery when user hovers them
Author: By
Last change: Fixed positioning embedded for position in screen center and position relative to thumb.
Date: 2 years ago
Size: 19,348 bytes
 

Contents

Class file image Download
$(document).ready(function() { // initialize test html and styles $(document.body).append('<div class="mo-hover-gallery"></div>'); readFile('fixtures/html/moHoverGallery.html', function(data) { $('div.mo-hover-gallery').html(data); }); readFile('fixtures/css/moHoverGallery.css', function(data) { $('head').append('<style>' + data + '</style>'); }); // write spec describe('moHoverGallery', function() { var thumbs = $('.hover-thumb'), gallery = new moHoverGallery({thumbs: thumbs, popupClass: 'mo-hover-gallery-popup'}); beforeEach(function() { jQuery.fx.off = true; }); afterEach(function() { jQuery.fx.off = false; }); describe('when created', function() { it('contains a set of thumbs', function() { expect(gallery.thumbs).toBe(thumbs); }); it('the thumbs are empty by default', function() { var emptyGallery = new moHoverGallery({popupId: 'empty-mo-hover-gallery-popup'}); expect(emptyGallery.thumbs).toEqual({}); emptyGallery.destroy(); }); it('contains a current open thumb (null by default)', function() { expect(gallery.current).toBeNull(); }); it('contains a popup class (null by default)', function() { var noClassGallery = new moHoverGallery({popupId: 'no-class-mo-hover-gallery-popup'}); expect(noClassGallery.popupClass).toBeNull(); noClassGallery.destroy(); }); it('contains a popup id (\'mo-hover-gallery-popup\' by default)', function() { expect(gallery.popupId).toBe('mo-hover-gallery-popup'); }); it('contains an image wildcard (\'%IMAGEPATH%\' by default)', function() { expect(gallery.imageWildcard).toBe('%IMAGEPATH%'); }); it('contains a popup html template reloaded on each opening', function() { expect(gallery.popupTemplate).toBeDefined(); }); it('the popup template contains an img tag with the image wildcard by default', function() { expect(gallery.popupTemplate).toBe('<img src="' + gallery.imageWildcard + '" alt="mo-hover-gallery-image">'); }); it('contains a position popup method name that is called before popup opening', function() { expect(gallery.positionPopup).toBe('positionPopupInScreenCenter'); }); it('contains an image cache object', function() { expect(gallery.imageCache).toBeDefined(); }); it('contains a thumb\'s index to start the gallery with (null by default)', function() { expect(gallery.startIndex).toBeNull(); }); it('contains a skip create popup flag (false by default)', function() { expect(gallery.skipCreatePopup).toBeDefined(); expect(gallery.skipCreatePopup).toBeFalsy(); }); it('contains a skip close popup flag (false by default)', function() { expect(gallery.skipClosePopup).toBeDefined(); expect(gallery.skipClosePopup).toBeFalsy(); }); it('creates a popup div appended to the body', function() { expect(gallery.selectPopup().length).not.toBe(0); }); it('loads the image cache', function() { expect(gallery.imageCache.length).toBe(3); }); it('binds the on mouse move event with the corresponding method', function() { spyOn(gallery, 'onMouseMove'); $(document).mousemove(); expect(gallery.onMouseMove.calls.count()).toBe(1); }); it('initializes the gallery if the start index is valid', function() { jasmine.clock().install(); var startGallery = new moHoverGallery({thumbs: thumbs, popupId: 'init-mo-hover-gallery-popup', startIndex: 0}); jasmine.clock().tick(150); expect(startGallery.current).toBe(startGallery.thumbs[0]); startGallery.destroy(); jasmine.clock().uninstall(); }); it('does not initialize the gallery if the start index is invalid', function() { var startGallery = new moHoverGallery({thumbs: thumbs, popupId: 'init-mo-hover-gallery-popup', startIndex: 4}); expect(startGallery.current).toBeNull(); startGallery.destroy(); }); }); describe('can create a popup for hovered images', function() { it('appended to the body', function() { gallery.selectPopup().remove(); gallery.createPopup(); expect(gallery.selectPopup().length).toBe(1); }); it('that has a certain class', function() { expect(gallery.selectPopup().hasClass('mo-hover-gallery-popup')).toBeTruthy(); }); it('that is invisible at first', function() { expect(gallery.selectPopup().css('visibility')).toBe('hidden'); }); it('but throws an exception if such popup already exists', function() { var secondGallery = new moHoverGallery({popupId: 'second-mo-hover-gallery-popup'}); expect(function() { secondGallery.createPopup(); }).toThrow(); secondGallery.destroy(); }); it('that is actually not created if the skip create popup flag is true', function() { var noPopupGallery = new moHoverGallery({popupId: 'no-popup-mo-hover-gallery-popup', skipCreatePopup: true}); expect(noPopupGallery.selectPopup().length).toBe(0); noPopupGallery.destroy(); }); }); describe('can open the popup', function() { afterEach(function() { gallery.closePopup(); }); it('by extracting the image path from the passed thumb', function() { spyOn(gallery, 'getImageFromThumb'); gallery.openPopup(gallery.thumbs[0]); gallery.closePopup(); gallery.openPopup({}); expect(gallery.getImageFromThumb.calls.count()).toBe(2); }); describe('when an image path has been found', function() { beforeEach(function() { gallery.openPopup(gallery.thumbs[0]); }); it('by setting the current thumb to the passed thumb', function() { expect(gallery.current).toBe(gallery.thumbs[0]); }); it('by replacing the popup html with the combined popup template and target image', function() { var popupImg = $(gallery.selectPopup().html()), generatedImg = $(gallery.popupTemplate.replace(gallery.imageWildcard, 'images/barbarian.jpg')); expect(popupImg.attr('src')).toEqual(generatedImg.attr('src')); }); it('by calling the configured position popup method', function() { spyOn(gallery, 'positionPopupInScreenCenter'); gallery.closePopup(); gallery.openPopup(gallery.thumbs[0]); expect(gallery.positionPopupInScreenCenter.calls.count()).toBe(1); }); it('by making it visible', function() { expect(gallery.selectPopup().css('visibility')).toBe('visible'); }); }); describe('or... not really open it when an image path is not found', function() { beforeEach(function() { gallery.openPopup({}); }); it('by not setting the current thumb', function() { expect(gallery.current).not.toBe({}); }); it('by not replacing the popup html', function() { expect(gallery.selectPopup().html()).toBe(''); }); it('by not calling the configured position popup method', function() { spyOn(gallery, 'positionPopupInScreenCenter'); gallery.closePopup(); gallery.openPopup({}); expect(gallery.positionPopupInScreenCenter.calls.count()).toBe(0); }); it('by not making it visible', function() { expect(gallery.selectPopup().css('visibility')).toBe('hidden'); }); }); }); describe('can close the popup', function() { beforeEach(function() { gallery.openPopup(gallery.thumbs[0]); gallery.closePopup(); }); it('only if the skip close popup flag is false', function() { gallery.skipClosePopup = true; gallery.openPopup(gallery.thumbs[0]); gallery.closePopup(); expect(gallery.current).not.toBeNull(); expect(gallery.selectPopup().html()).not.toEqual(''); expect(gallery.selectPopup().css('visibility')).toBe('visible'); gallery.skipClosePopup = false; gallery.closePopup(); }); it('by setting the current thumb to null', function() { expect(gallery.current).toBeNull(); }); it('by removing it\'s content', function() { expect(gallery.selectPopup().html()).toBe(''); }); it('by making it invisible', function() { expect(gallery.selectPopup().css('visibility')).toBe('hidden'); }); }); describe('can position the popup', function() { afterEach(function() { gallery.closePopup(); gallery.positionPopup = 'positionPopupInScreenCenter'; }); it('in the center of the screen', function() { var winHeight = $(window).height(), winWidth = $(window).width(), popup = gallery.selectPopup(), expectedTop = 0, expectedLeft = 0, realTop = 0, realLeft = 0; popup.css('position', 'static'); gallery.openPopup(gallery.thumbs[0]); expectedTop = (winHeight - popup.height()) / 2; expectedLeft = (winWidth - popup.width()) / 2; realTop = popup.css('top').replace('px', '') * 1; realLeft = popup.css('left').replace('px', '') * 1; expect(popup.css('position')).toBe('fixed'); expect(Math.floor(realTop)).toBe(Math.floor(expectedTop)); expect(Math.floor(realLeft)).toBe(Math.floor(expectedLeft)); }); it('next to a gallery thumb', function() { var popup = gallery.selectPopup(), position = null; popup.css('position', 'static'); gallery.positionPopup = 'positionPopupRelativeToThumb'; gallery.openPopup(gallery.thumbs[0]); position = $(gallery.thumbs[0]).position(); expect(popup.css('position')).toBe('fixed'); expect(popup.css('top')).toBe((position.top + 30) + 'px'); expect(popup.css('left')).toBe((position.left + 40) + 'px'); }); it('right where it is', function() { var popup = gallery.selectPopup(); popup.css('top', '10px'); popup.css('right', '10px'); gallery.positionPopup = 'positionPopupStatically'; gallery.openPopup(gallery.thumbs[0]); expect(popup.css('top')).toBe('10px'); expect(popup.css('right')).toBe('10px'); }); }); describe('can select the popup', function() { it('based on it\'s id', function() { expect(gallery.selectPopup()).toEqual($('div#' + gallery.popupId)); }); }); describe('can get the coordinates of an element', function() { it('based on it\'s properties', function() { var offset = $('body').offset(); expect(gallery.getElementCoords(thumbs[0])).toEqual({ top: offset.top, left: offset.left, bottom: offset.top + 60, right: offset.left + 80 }); }); }); describe('can check if a certain position (X, Y) is in an element', function() { it('and returns true if so', function() { expect(gallery.isPositionInElement(25, 30, thumbs[0])).toBeTruthy(); }); it('and returns false if not', function() { expect(gallery.isPositionInElement(25, 230, thumbs[0])).toBeFalsy(); }); it('by using the get element coordinates method', function() { spyOn(gallery, 'getElementCoords').and.callThrough();; gallery.isPositionInElement(25, 30, thumbs[0]); expect(gallery.getElementCoords.calls.count()).toBe(1); }); }); describe('can identify a certain thumb in the set', function() { it('based on a pair of coordinates', function() { expect(gallery.getThumbByCoords(25, 30)).toEqual(thumbs[0]); }); it('and returns null if no match is found', function() { expect(gallery.getThumbByCoords(200, 200)).toBeNull(); }); it('by using the is position in element method', function() { spyOn(gallery, 'isPositionInElement').and.callThrough();; gallery.getThumbByCoords(25, 30); expect(gallery.isPositionInElement.calls.count()).toBe(thumbs.length); }); }); describe('can get an image path from a certain thumb in the set', function() { it('based on the href of it\'s child anchor by default', function() { expect(gallery.getImageFromThumb(thumbs[0])).toBe('images/barbarian.jpg'); }); it('and returns null if nothing could be found', function() { expect(gallery.getImageFromThumb('sgogurmos')).toBeNull(); }); }); describe('can check a custom is over thumb rule', function() { it('that returns true by default', function() { expect(gallery.isOverThumb()).toBeTruthy(); }); }); describe('can handle mouse moves', function() { afterEach(function() { gallery.closePopup(); }); it('by checking if the mouse is over a thumb', function() { spyOn(gallery, 'getThumbByCoords'); gallery.onMouseMove({pageX: 200, pageY: 200}); gallery.onMouseMove({pageX: 20, pageY: 20}); expect(gallery.getThumbByCoords.calls.count()).toBe(2); }); it('by checking if the custom is over thumb rule is ok with the current mouse coordinates', function() { spyOn(gallery, 'isOverThumb'); gallery.onMouseMove({pageX: 20, pageY: 20}); expect(gallery.isOverThumb.calls.count()).toBe(1); }); it('by opening the popup if the mouse is over a thumb', function() { spyOn(gallery, 'openPopup'); gallery.onMouseMove({pageX: 200, pageY: 200}); gallery.onMouseMove({pageX: 20, pageY: 20}); expect(gallery.openPopup.calls.count()).toBe(1); }); it('by not opening the popup if the mouse is over an already open thumb', function() { spyOn(gallery, 'openPopup').and.callThrough(); gallery.onMouseMove({pageX: 20, pageY: 20}); gallery.onMouseMove({pageX: 20, pageY: 20}); expect(gallery.openPopup.calls.count()).toBe(1); }); it('by closing the popup if the mouse is not over a thumb', function() { spyOn(gallery, 'closePopup'); gallery.onMouseMove({pageX: 20, pageY: 20}); gallery.onMouseMove({pageX: 20, pageY: 20}); gallery.onMouseMove({pageX: 200, pageY: 200}); expect(gallery.closePopup.calls.count()).toBe(1); }); it('always being sure to not switch the places of X and Y', function() { spyOn(gallery, 'getThumbByCoords'); gallery.onMouseMove({pageX: 25, pageY: 20}); expect(gallery.getThumbByCoords).toHaveBeenCalledWith(25, 20); }); }); describe('can load images into cache', function() { it('by creating an image object for each thumb', function() { var expectedImg = new Image(); expectedImg.src = 'images/barbarian.jpg'; gallery.loadImageCache(); expect(gallery.imageCache[0].src).toEqual(expectedImg.src); expect(gallery.imageCache.length).toBe(3); }); }); describe('can be destroyed when not needed', function() { it('by removing all related properties', function() { var popupId = gallery.popupId, docEvents = null, eventExists = false, counter = 0; gallery.destroy(); docEvents = $._data($(document)[0], 'events'); expect(gallery.thumbs).toEqual({}); expect(gallery.selectPopup().length).toBe(0); if (typeof docEvents !== 'undefined') { for (counter; counter < docEvents['mousemove'].length; counter++) { if (docEvents['mousemove'][counter]['namespace'] === popupId) { eventExists = true; } } } expect(eventExists).toBeFalsy(); }); }); }); // instantiate a human testable gallery new moHoverGallery({ thumbs: $('.hover-thumb'), popupId: 'test-mo-hover-gallery', popupClass: 'static-mo-hover-gallery-popup', positionPopup: 'positionPopupStatically', skipClosePopup: true, startIndex: 0 }); }); function readFile(url, callback) { // must be synchronous to guarantee that no tests are run before fixture is loaded $.ajax({ async: false, cache: false, url: url, success: function(data) { callback(data); } }); }