X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=Tom-Marble%2Fdeck.js%2Ftest%2Fspec.core.js;fp=Tom-Marble%2Fdeck.js%2Ftest%2Fspec.core.js;h=cec71413b3d40d14bcf9ae1abcfe187af425d1b9;hb=d0f6c3cd6fa0c1b7dc83f3ae3d548209e4f1c6fd;hp=0000000000000000000000000000000000000000;hpb=8048db2de1e49dc68c0c2f8b2e133fe4a43dbd70;p=lp17-speaker-slides.git diff --git a/Tom-Marble/deck.js/test/spec.core.js b/Tom-Marble/deck.js/test/spec.core.js new file mode 100755 index 0000000..cec7141 --- /dev/null +++ b/Tom-Marble/deck.js/test/spec.core.js @@ -0,0 +1,527 @@ +// Go tests, go +describe('Deck JS', function() { + describe('standard html structure', function() { + beforeEach(function() { + loadFixtures('standard.html'); + if (Modernizr.history) { + history.replaceState({}, "", "#") + } + else { + window.location.hash = '#'; + } + }); + + describe('init(options.selectors.slides)', function() { + it('should create slides', function() { + $.deck({ + selectors: { + slides: '.slide3' + } + }); + expect($.deck('getSlides').length).toEqual($('.slide3').length); + }); + }); + + describe('init(selector)', function() { + it('should create slides', function() { + $.deck(); + expect($.deck('getSlides').length).toEqual($('.slide').length); + }); + }); + + describe('init([selectors])', function() { + it('should create slides', function() { + $.deck([ + '.slide1', + '.slide2', + '.slide3', + '.slide4', + '.slide5' + ]); + expect($.deck('getSlides').length).toEqual($('.slide').length); + }); + }); + + describe('navigation functions', function() { + beforeEach(function() { + $.deck(); + }); + + describe('go(i)', function() { + it('should go to the i slide (0 based index)', function() { + $.deck('go', 3); + expect($.deck('getSlide')).toHaveClass('slide4'); + }); + + it('should go to the slide with specified id', function() { + $.deck('go', 'custom-id'); + expect($.deck('getSlide')).toHaveId('custom-id'); + }); + + it('should go nowhere if i is out of bounds', function() { + $.deck('go', 5); + expect($.deck('getSlide')).toHaveClass('slide1'); + }); + + it('should go nowhere if id does not exist', function() { + $.deck('go', 'i-dont-exist'); + expect($.deck('getSlide')).toHaveClass('slide1'); + }); + + describe('aria attribute updates', function() { + beforeEach(function() { + loadFixtures('nesteds.html'); + $.deck(); + $.deck('go', 5); + }); + + it('should set offscreen slides to hidden true', function() { + $([ + '.toplevel.deck-before:not(.deck-child-current)', + '.toplevel.deck-previous:not(.deck-child-current)', + '.deck-next', + '.deck-after' + ].join(', ')).each(function() { + expect($(this)).toHaveAttr('aria-hidden', 'true'); + }); + }); + + it('should set onscreen slides to hidden false', function() { + $([ + '.deck-child-current.slide', + '.deck-child-current .deck-before', + '.deck-child-current .deck-previous', + '.deck-current' + ].join(', ')).each(function() { + expect($(this)).toHaveAttr('aria-hidden', 'false'); + }); + }); + }); + }); + + describe('next()', function() { + it('should go to the next slide', function() { + $.deck('next'); + expect($.deck('getSlide')).toHaveClass('slide2'); + }); + + it('should go nowhere if on the last slide', function() { + $.deck('go', 4); + $.deck('next'); + expect($.deck('getSlide')).toHaveClass('slide5'); + }); + }); + + describe('prev()', function() { + it('should go to the previous slide', function() { + $.deck('go', 2); + $.deck('prev'); + expect($.deck('getSlide')).toHaveClass('slide2'); + }); + + it('should go nowhere if on the first slide', function() { + $.deck('prev'); + expect($.deck('getSlide')).toHaveClass('slide1'); + }); + }); + }); + + describe('getters', function() { + beforeEach(function() { + $.deck(); + }); + + describe('getSlide()', function() { + it('should get the current slide', function() { + expect($.deck('getSlide')).toHaveClass('slide1'); + $.deck('go', 2); + expect($.deck('getSlide')).toHaveClass('slide3'); + }); + }); + + describe('getSlide(i)', function() { + it('should get slide number i (0 based index)', function() { + expect($.deck('getSlide', 1)).toHaveClass('slide2'); + expect($.deck('getSlide', 3)).toHaveClass('slide4'); + }); + + it('should return null if i is NaN', function() { + expect($.deck('getSlide', 'barfoo')).toBeNull(); + }); + + it('should return null if i is out of bounds', function() { + expect($.deck('getSlide', 6)).toBeNull(); + }); + }); + + describe('getSlides()', function() { + it('should return an array of jQuery objects for each slide', function() { + var expectation = []; + var slides = $.deck('getSlides'); + $('.slide').each(function() { + expectation.push($(this)); + }); + expect(slides).toEqual(expectation); + }); + }); + + describe('getContainer()', function() { + it('should return a jQuery object with the container element(s)', function() { + expect($.deck('getContainer')).toBe(defaults.selectors.container); + }); + }); + + describe('getOptions()', function() { + it('should return the current options object', function() { + expect($.deck('getOptions')).toEqual(defaults); + }); + }); + + describe('getTopLevelSlides()', function() { + it('should return only root slides', function() { + loadFixtures('nesteds.html'); + $.deck(); + var expectation = []; + var topLevelSlides = $.deck('getTopLevelSlides'); + $('.toplevel').each(function() { + expectation.push($(this)); + }); + expect(topLevelSlides).toEqual(expectation); + }); + }); + + describe('getNestedSlides()', function() { + it('should return nested slides for current slide', function() { + loadFixtures('nesteds.html'); + $.deck(); + $.deck('go', 2); + var expectation = []; + var nestedSlides = $.deck('getNestedSlides'); + $.deck('getSlide').find('.slide').each(function() { + expectation.push($(this)); + }); + expect(nestedSlides).toEqual(expectation); + }); + }); + }); + + describe('container states', function() { + beforeEach(function() { + $.deck(); + }); + + it('should start at state 0', function() { + expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '0'); + }); + + it('should change states with the slide number', function() { + $.deck('next'); + expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '1'); + $.deck('go', 3); + expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '3'); + $.deck('prev'); + expect($(defaults.selectors.container)).toHaveClass(defaults.classes.onPrefix + '2'); + }); + }); + + describe('options object', function() { + var $d = $(document); + + beforeEach(function() { + $.deck('.alt-slide', { + classes: { + after: 'alt-after', + before: 'alt-before', + current: 'alt-current', + onPrefix: 'alt-on-', + next: 'alt-next', + previous: 'alt-prev' + }, + + selectors: { + container: '.alt-container' + }, + + keys: { + next: 87, + previous: 69 + } + }); + }); + + describe('classes', function() { + it('should use the specified after class', function() { + expect($('.alt-slide3, .alt-slide4, .alt-slide5')).toHaveClass('alt-after'); + }); + + it('should use the specified before class', function() { + $.deck('go', 4); + expect($('.alt-slide1, .alt-slide2, .alt-slide3')).toHaveClass('alt-before'); + }); + + it('should use the specified container class', function() { + $.deck('go', 2); + expect($('.alt-container')).toHaveClass('alt-on-2'); + }); + + it('should use the specified current class', function() { + expect($.deck('getSlide')).toHaveClass('alt-current'); + }); + + it('should use the specified next class', function() { + expect($('.alt-slide2')).toHaveClass('alt-next'); + }); + + it('should use the specified previous class', function() { + $.deck('next'); + expect($('.alt-slide1')).toHaveClass('alt-prev'); + }); + }); + + describe('key bindings', function() { + var e; + + beforeEach(function() { + e = jQuery.Event('keydown.deck'); + }); + + it('should go to the next slide using the specified key', function() { + e.which = 87; // 'w' + $d.trigger(e); + expect($.deck('getSlide')).toHaveClass('alt-slide2'); + }); + + it('should go to the previous slide using the specified key', function() { + $.deck('next'); + e.which = 69; // 'e' + $d.trigger(e); + expect($.deck('getSlide')).toHaveClass('alt-slide1'); + }); + + it('should not trigger events that originate within editable elements', function() { + var $outside = $('').appendTo('body'); + e = jQuery.Event('keydown'); + e.which = 87; + $outside.trigger(e); + expect($.deck('getSlide')).toHaveClass('alt-slide1'); + $outside.remove(); + }); + }); + }); + + describe('events', function() { + var $d; + + beforeEach(function() { + $d = $(document); + }); + + describe('deck.change', function() { + var index, oldIndex; + + beforeEach(function() { + $.deck(); + $.deck('go', 1); + $d.one('deck.change', function(event, from, to) { + index = to; + oldIndex = from; + }); + }); + + it('should fire on go(i)', function() { + $.deck('go', 3); + expect(index).toEqual(3); + }); + + it('should fire on next()', function() { + $.deck('next'); + expect(index).toEqual(2); + }); + + it('should fire on prev()', function() { + $.deck('prev'); + expect(index).toEqual(0); + }); + + it('should pass parameters with from and to indices', function() { + $.deck('go', 3); + expect(index).toEqual(3); + expect(oldIndex).toEqual(1); + }); + + it('should not fire if default prevented in beforeChange', function() { + $d.bind('deck.beforeChange', false); + $.deck('go', 3); + expect($.deck('getSlide')).toEqual($.deck('getSlide', 1)); + $d.unbind('deck.beforeChange', false); + }); + }); + + describe('deck.init', function() { + it('should fire on deck initialization', function() { + $.deck(); + expect($.deck('getSlides').length).toBeGreaterThan(0); + }); + }); + + describe('deck.beforeInit', function() { + var beforeHit; + + beforeEach(function() { + beforeHit = false; + $d.on('deck.beforeInit', function() { + beforeHit = true; + }); + }); + + it('should fire on deck initialization', function() { + $.deck(); + expect(beforeHit).toBeTruthy(); + }); + + it('should have populated the slides array', function() { + var f = function() { + expect($.deck('getSlides').length).toEqual($('.slide').length); + }; + + $d.bind('deck.beforeInit', f); + $.deck(); + $d.unbind('deck.beforeInit', f); + }); + + it('should prevent the init event if lockInit is called', function() { + var initHit = false; + var f = function(event) { + event.lockInit(); + }; + var g = function() { + initHit = true; + }; + + $d.bind('deck.beforeInit', f); + $d.bind('deck.init', g); + $.deck(); + $d.unbind('deck.beforeInit', f); + $d.unbind('deck.init', g); + expect(initHit).toBeFalsy(); + }); + + it('should warn if locked without release', function() { + var warned = false; + var f = function(event) { + event.lockInit(); + }; + var warn = console.warn; + window.console.warn = function() { + warned = true; + }; + + $d.bind('deck.beforeInit', f); + $.deck('.slide', { + initLockTimeout: 20 + }); + $d.unbind('deck.beforeInit', f); + + waitsFor(function() { + return warned; + }, 'warning', 2000); + + runs(function() { + window.console.warn = warn; + }); + }); + + it('should fire init event once releaseInit is called', function() { + var f = function(event) { + event.lockInit(); + window.setTimeout(function() { + event.releaseInit(); + }, 20); + }; + + runs(function() { + $d.bind('deck.beforeInit', f); + $.deck(); + $d.unbind('deck.beforeInit', f); + }); + + waitsFor(function() { + return $.deck('getSlides').length > 0; + }, 'lock to release', 2000); + }); + }); + }); + + describe('hash/id assignments', function() { + beforeEach(function() { + $.deck('.slide'); + }); + + it('should assign ids to slides that do not have them', function() { + var slides = $.deck('getSlides'); + $.each(slides, function(i, $e) { + expect($e.attr('id')).toBeTruthy(); + }); + }); + + it('should reassign ids on reinitialization', function() { + var $firstSlide = $.deck('getSlide', 0); + var firstID = $firstSlide.attr('id'); + + $firstSlide.before('
'); + $.deck('.slide'); + expect($firstSlide).not.toHaveId(firstID); + }); + + it('should update container with a state class including the slide id', function() { + var $c = $.deck('getContainer'); + var osp = defaults.classes.onPrefix; + + expect($c).toHaveClass(osp + $.deck('getSlide', 0).attr('id')); + $.deck('next'); + expect($c).toHaveClass(osp + $.deck('getSlide', 1).attr('id')); + $.deck('next'); + expect($c).not.toHaveClass(osp + $.deck('getSlide', 1).attr('id')); + expect($c).toHaveClass(osp + $.deck('getSlide', 2).attr('id')); + }); + + it('should use existing ids if they exist', function() { + expect($('#custom-id')).toExist(); + }); + + it('should update the URL on slide change (if supported)', function() { + if (Modernizr.history) { + $.deck('go', 3); + expect(window.location.hash).toEqual('#slide-3'); + } + }); + + it('should deep link to slide on deck init', function() { + window.location.hash = "#slide-3"; + $.deck('.slide'); + waitsFor(function() { + return $.deck('getSlide').attr('id') === 'slide-3'; + }); + }); + + it('should follow internal hash links using hashchange (if supported)', function() { + window.location.hash = "#slide-3"; + // Hashchange event doesn't fire right when the hash changes? + waitsFor(function() { + return $.deck('getSlide').attr('id') === 'slide-3'; + }, 'hash to change to slide-3', 2000); + }); + }); + }); + + describe('empty deck', function() { + beforeEach(function() { + loadFixtures('empty.html'); + $.deck(); + }); + + describe('getSlide()', function() { + it('should not error on init', $.noop); + }); + }); +});