spec-smoothScroll.js 4.06 KB
describe('Smooth Scroll', function () {

	//
	// Helper Methods
	//
	var removeElements = function() {
		var p = document.querySelector('p');
		if (p && p.remove) {
			p.remove();
		}
		var a = document.querySelector('a');
		if (a && a.remove) {
			a.remove();
		}
		var target = document.querySelector('div');
		if (target && target.remove) {
			target.remove();
		}
	};
	/**
	 * Create a link element, add it to the body.
	 * @public
	 * @param {String} the href attribute of the new link
	 * @param {Boolean} whether to add data-scroll to the link or not
	 * @returns {Element}
	 */
	var injectElem = function (href, smooth) {
		removeElements();

		var elt = document.createElement('a');
		elt.href = href;
		elt.style.background = '#f0f';
		elt.textContent="newtext";
		if (smooth) {
			elt.setAttribute('data-scroll', true);
		}
		document.body.appendChild(elt);

		var p = document.createElement('p');
		p.style.height = '20000px';
		p.style.background = '#f00';
		document.body.appendChild(p);

		var target = document.createElement('div');
		target.id = 'target';
		target.style.height = '200px';
		target.style.background = '#0ff';
		document.body.appendChild(target);
		window.top.callPhantom({type: 'render', fname: './myscreen.png'});
		return elt;
	};

	/**
	 * Simulate a click event.
	 * @public
	 * @param {Element} the element to simulate a click on
	 */
	var simulateClick = function (elt) {
		var click = document.createEvent('MouseEvents');
		click.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
		elt.dispatchEvent(click);
	};

	// A pattern for settings to validate their format.
	var settingsStub = {
		speed: jasmine.any(Number),
		easing: jasmine.any(String),
		offset: jasmine.any(Number),
		updateURL: jasmine.any(Boolean),
		callback: jasmine.any(Function)
	};


	//
	// Init
	//

	describe('Should initialize plugin', function () {
		it('Should export the smoothScroll module', function () {
			expect(smoothScroll).toBeDefined();
		});

		it('Should expose public functions', function () {
			expect(smoothScroll.init).toEqual(jasmine.any(Function));
			expect(smoothScroll.destroy).toEqual(jasmine.any(Function));
			expect(smoothScroll.animateScroll).toEqual(jasmine.any(Function));
		});

		it('Should add event listeners', function () {
			spyOn(document, 'addEventListener');
			smoothScroll.init();
			expect(document.addEventListener).toHaveBeenCalledWith('click', jasmine.any(Function), false);

			spyOn(document, 'removeEventListener');
			smoothScroll.destroy();
			expect(document.removeEventListener).toHaveBeenCalledWith('click', jasmine.any(Function), false);
		});
	});

	describe('Should merge user options into defaults', function () {

		var elt = injectElem('#target', true);

		beforeEach(function () {
			smoothScroll.init({
				callback: function () { document.documentElement.classList.add('callback'); }
			});
		});

		it('User options should be merged into defaults', function (done) {
			simulateClick(elt);
			setTimeout(function() {
				expect(document.documentElement.classList.contains('callback')).toBe(true);
				done();
			}, 200);
		});

	});


	//
	// Events
	//

	describe('Should animate scroll when anchor clicked', function () {
		var elt = injectElem('#target', true);
		// document.body.id = 'anchor';

		beforeEach(function() {
			spyOn(smoothScroll, 'animateScroll');
		});

		afterEach(function () {
			smoothScroll.destroy();
		});


		it('Should trigger smooth scrolling on click', function (done) {
			smoothScroll.init();
			simulateClick(elt);
			setTimeout(function() {
				expect(smoothScroll.animateScroll).toHaveBeenCalledWith('#target', elt, jasmine.objectContaining(settingsStub));
				done();
			}, 200);
		});

		it('Should do nothing if not initialized', function () {
			simulateClick(elt);
			expect(smoothScroll.animateScroll).not.toHaveBeenCalled();
		});

		it('Should do nothing if destroyed', function (done) {
			smoothScroll.init();
			smoothScroll.destroy();
			simulateClick(elt);
			setTimeout(function() {
				expect(smoothScroll.animateScroll).not.toHaveBeenCalled();
				done();
			}, 200);
		});
	});
});