Vortrag für GIT angefangen.

This commit is contained in:
Tim Schumacher 2012-09-27 22:34:43 +02:00
parent 61165635cd
commit 40e34e4a91
60 changed files with 8603 additions and 0 deletions

24
git/test/fixtures/complex.html vendored Normal file
View file

@ -0,0 +1,24 @@
<div class="deck-container">
<div class="slide1"></div>
<div class="slide2 slide3 slide4">
<div class="slide2 slide10"></div>
<div class="slide3 slide4"></div>
</div>
<div class="slide3 slide5"></div>
<div class="slide6 slide7 slide8 slide9 slide10"></div>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide" value="">
<input type="submit" value="Go">
</form>
</div>

19
git/test/fixtures/empty.html vendored Normal file
View file

@ -0,0 +1,19 @@
<div class="deck-container">
<a href="#" class="deck-prev-link">Previous</a>
<a href="#" class="deck-next-link">Next</a>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide" value="">
<input type="submit" value="Go">
</form>
<a href="#" class="deck-permalink">#</a>
<a href="#custom-id" id="internal-test">Internal Test Link</a>
</div>

10
git/test/fixtures/iframe_simple.html vendored Normal file
View file

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
Simple Iframe
</body>
</html>

32
git/test/fixtures/iframes.html vendored Normal file
View file

@ -0,0 +1,32 @@
<div class="deck-container">
<div class="slide1"></div>
<div class="slide2 slide3 slide4">
</div>
<div class="slide5">
<iframe src='fixtures/iframe_simple.html'></iframe>
</div>
<div class='slide6'>
</div>
<div class="slide7">
<iframe></iframe>
</div>
<div class="slide8 slide9 slide10"></div>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide" value="">
<input type="submit" value="Go">
</form>
</div>

36
git/test/fixtures/nesteds.html vendored Normal file
View file

@ -0,0 +1,36 @@
<div class="deck-container">
<div class="slide">
</div>
<div class="slide">
</div>
<div class="slide root">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
</div>
<div class="slide" id="after">
</div>
<div class="slide">
</div>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide" value="">
<input type="submit" value="Go">
</form>
</div>

42
git/test/fixtures/standard.html vendored Normal file
View file

@ -0,0 +1,42 @@
<div class="deck-container">
<div class="slide slide1"></div>
<div class="slide slide2" id="custom-id"></div>
<div class="slide slide3"></div>
<div class="slide slide4"></div>
<div class="slide slide5"></div>
<a href="#" class="deck-prev-link">Previous</a>
<a href="#" class="deck-next-link">Next</a>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide" value="" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
<a href="#" class="deck-permalink">#</a>
<a href="#custom-id" id="internal-test">Internal Test Link</a>
</div>
<div class="alt-container">
<div class="alt-slide alt-slide1"><input></div>
<div class="alt-slide alt-slide2"></div>
<div class="alt-slide alt-slide3"></div>
<div class="alt-slide alt-slide4"></div>
<div class="alt-slide alt-slide5"></div>
</div>

39
git/test/index.html Normal file
View file

@ -0,0 +1,39 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>deck.js - Jasmine Test Runner</title>
<link rel="stylesheet" type="text/css" href="lib/jasmine.css">
<script type="text/javascript" src="../modernizr.custom.js"></script>
<script type="text/javascript" src="lib/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-html.js"></script>
<script src="../jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="lib/jasmine-jquery.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../core/deck.core.js"></script>
<script type="text/javascript" src="../extensions/hash/deck.hash.js"></script>
<script type="text/javascript" src="../extensions/menu/deck.menu.js"></script>
<script type="text/javascript" src="../extensions/goto/deck.goto.js"></script>
<script type="text/javascript" src="../extensions/status/deck.status.js"></script>
<script type="text/javascript" src="../extensions/navigation/deck.navigation.js"></script>
<script type="text/javascript" src="../extensions/scale/deck.scale.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="settings.js"></script>
<script type="text/javascript" src="spec.core.js"></script>
<script type="text/javascript" src="spec.menu.js"></script>
<script type="text/javascript" src="spec.goto.js"></script>
<script type="text/javascript" src="spec.navigation.js"></script>
<script type="text/javascript" src="spec.hash.js"></script>
<script type="text/javascript" src="spec.status.js"></script>
<script type="text/javascript" src="spec.scale.js"></script>
</head>
<body>
<script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
jasmine.getEnv().execute();
</script>
</body>
</html>

190
git/test/lib/jasmine-html.js Executable file
View file

@ -0,0 +1,190 @@
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.createTextNode(child));
} else {
if (child) { el.appendChild(child); }
}
}
for (var attr in attrs) {
if (attr == "className") {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var showPassed, showSkipped;
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
this.createDom('div', { className: 'banner' },
this.createDom('div', { className: 'logo' },
this.createDom('span', { className: 'title' }, "Jasmine"),
this.createDom('span', { className: 'version' }, runner.env.versionString())),
this.createDom('div', { className: 'options' },
"Show ",
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
)
),
this.runnerDiv = this.createDom('div', { className: 'runner running' },
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);
this.document.body.appendChild(this.outerDiv);
var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
this.suiteDivs[suite.id] = suiteDiv;
var parentDiv = this.outerDiv;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.id];
}
parentDiv.appendChild(suiteDiv);
}
this.startedAt = new Date();
var self = this;
showPassed.onclick = function(evt) {
if (showPassed.checked) {
self.outerDiv.className += ' show-passed';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
}
};
showSkipped.onclick = function(evt) {
if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
}
};
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
if (this.specFilter(specs[i])) {
specCount++;
}
}
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount === 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.id].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
if (this.logRunningSpecs) {
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var results = spec.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(spec.getFullName()),
title: spec.getFullName()
}, spec.description));
var resultItems = results.getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
specDiv.appendChild(messagesDiv);
}
this.suiteDivs[spec.suite.id].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
if (!paramMap.spec) {
return true;
}
return spec.getFullName().indexOf(paramMap.spec) === 0;
};

288
git/test/lib/jasmine-jquery.js Executable file
View file

@ -0,0 +1,288 @@
var readFixtures = function() {
return jasmine.getFixtures().proxyCallTo_('read', arguments);
};
var preloadFixtures = function() {
jasmine.getFixtures().proxyCallTo_('preload', arguments);
};
var loadFixtures = function() {
jasmine.getFixtures().proxyCallTo_('load', arguments);
};
var setFixtures = function(html) {
jasmine.getFixtures().set(html);
};
var sandbox = function(attributes) {
return jasmine.getFixtures().sandbox(attributes);
};
var spyOnEvent = function(selector, eventName) {
jasmine.JQuery.events.spyOn(selector, eventName);
}
jasmine.getFixtures = function() {
return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
};
jasmine.Fixtures = function() {
this.containerId = 'jasmine-fixtures';
this.fixturesCache_ = {};
this.fixturesPath = 'spec/javascripts/fixtures';
};
jasmine.Fixtures.prototype.set = function(html) {
this.cleanUp();
this.createContainer_(html);
};
jasmine.Fixtures.prototype.preload = function() {
this.read.apply(this, arguments);
};
jasmine.Fixtures.prototype.load = function() {
this.cleanUp();
this.createContainer_(this.read.apply(this, arguments));
};
jasmine.Fixtures.prototype.read = function() {
var htmlChunks = [];
var fixtureUrls = arguments;
for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
}
return htmlChunks.join('');
};
jasmine.Fixtures.prototype.clearCache = function() {
this.fixturesCache_ = {};
};
jasmine.Fixtures.prototype.cleanUp = function() {
jQuery('#' + this.containerId).remove();
};
jasmine.Fixtures.prototype.sandbox = function(attributes) {
var attributesToSet = attributes || {};
return jQuery('<div id="sandbox" />').attr(attributesToSet);
};
jasmine.Fixtures.prototype.createContainer_ = function(html) {
var container;
if(html instanceof jQuery) {
container = jQuery('<div id="' + this.containerId + '" />');
container.html(html);
} else {
container = '<div id="' + this.containerId + '">' + html + '</div>'
}
jQuery('body').append(container);
};
jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
if (typeof this.fixturesCache_[url] == 'undefined') {
this.loadFixtureIntoCache_(url);
}
return this.fixturesCache_[url];
};
jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
var self = this;
var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
jQuery.ajax({
async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded
cache: false,
dataType: 'html',
url: url,
success: function(data) {
self.fixturesCache_[relativeUrl] = data;
},
error: function(jqXHR, status, errorThrown) {
throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')');
}
});
};
jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
return this[methodName].apply(this, passedArguments);
};
jasmine.JQuery = function() {};
jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
return jQuery('<div/>').append(html).html();
};
jasmine.JQuery.elementToString = function(element) {
return jQuery('<div />').append(element.clone()).html();
};
jasmine.JQuery.matchersClass = {};
(function(namespace) {
var data = {
spiedEvents: {},
handlers: []
};
namespace.events = {
spyOn: function(selector, eventName) {
var handler = function(e) {
data.spiedEvents[[selector, eventName]] = e;
};
jQuery(selector).bind(eventName, handler);
data.handlers.push(handler);
},
wasTriggered: function(selector, eventName) {
return !!(data.spiedEvents[[selector, eventName]]);
},
cleanUp: function() {
data.spiedEvents = {};
data.handlers = [];
}
}
})(jasmine.JQuery);
(function(){
var jQueryMatchers = {
toHaveClass: function(className) {
return this.actual.hasClass(className);
},
toBeVisible: function() {
return this.actual.is(':visible');
},
toBeHidden: function() {
return this.actual.is(':hidden');
},
toBeSelected: function() {
return this.actual.is(':selected');
},
toBeChecked: function() {
return this.actual.is(':checked');
},
toBeEmpty: function() {
return this.actual.is(':empty');
},
toExist: function() {
return this.actual.size() > 0;
},
toHaveAttr: function(attributeName, expectedAttributeValue) {
return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
},
toHaveId: function(id) {
return this.actual.attr('id') == id;
},
toHaveHtml: function(html) {
return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
},
toHaveText: function(text) {
if (text && jQuery.isFunction(text.test)) {
return text.test(this.actual.text());
} else {
return this.actual.text() == text;
}
},
toHaveValue: function(value) {
return this.actual.val() == value;
},
toHaveData: function(key, expectedValue) {
return hasProperty(this.actual.data(key), expectedValue);
},
toBe: function(selector) {
return this.actual.is(selector);
},
toContain: function(selector) {
return this.actual.find(selector).size() > 0;
},
toBeDisabled: function(selector){
return this.actual.is(':disabled');
},
// tests the existence of a specific event binding
toHandle: function(eventName) {
var events = this.actual.data("events");
return events && events[eventName].length > 0;
},
// tests the existence of a specific event binding + handler
toHandleWith: function(eventName, eventHandler) {
var stack = this.actual.data("events")[eventName];
var i;
for (i = 0; i < stack.length; i++) {
if (stack[i].handler == eventHandler) {
return true;
}
}
return false;
}
};
var hasProperty = function(actualValue, expectedValue) {
if (expectedValue === undefined) {
return actualValue !== undefined;
}
return actualValue == expectedValue;
};
var bindMatcher = function(methodName) {
var builtInMatcher = jasmine.Matchers.prototype[methodName];
jasmine.JQuery.matchersClass[methodName] = function() {
if (this.actual instanceof jQuery) {
var result = jQueryMatchers[methodName].apply(this, arguments);
this.actual = jasmine.JQuery.elementToString(this.actual);
return result;
}
if (builtInMatcher) {
return builtInMatcher.apply(this, arguments);
}
return false;
};
};
for(var methodName in jQueryMatchers) {
bindMatcher(methodName);
}
})();
beforeEach(function() {
this.addMatchers(jasmine.JQuery.matchersClass);
this.addMatchers({
toHaveBeenTriggeredOn: function(selector) {
this.message = function() {
return [
"Expected event " + this.actual + " to have been triggered on" + selector,
"Expected event " + this.actual + " not to have been triggered on" + selector
];
};
return jasmine.JQuery.events.wasTriggered(selector, this.actual);
}
})
});
afterEach(function() {
jasmine.getFixtures().cleanUp();
jasmine.JQuery.events.cleanUp();
});

166
git/test/lib/jasmine.css Executable file
View file

@ -0,0 +1,166 @@
body {
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
}
.jasmine_reporter a:visited, .jasmine_reporter a {
color: #303;
}
.jasmine_reporter a:hover, .jasmine_reporter a:active {
color: blue;
}
.run_spec {
float:right;
padding-right: 5px;
font-size: .8em;
text-decoration: none;
}
.jasmine_reporter {
margin: 0 5px;
}
.banner {
color: #303;
background-color: #fef;
padding: 5px;
}
.logo {
float: left;
font-size: 1.1em;
padding-left: 5px;
}
.logo .version {
font-size: .6em;
padding-left: 1em;
}
.runner.running {
background-color: yellow;
}
.options {
text-align: right;
font-size: .8em;
}
.suite {
border: 1px outset gray;
margin: 5px 0;
padding-left: 1em;
}
.suite .suite {
margin: 5px;
}
.suite.passed {
background-color: #dfd;
}
.suite.failed {
background-color: #fdd;
}
.spec {
margin: 5px;
padding-left: 1em;
clear: both;
}
.spec.failed, .spec.passed, .spec.skipped {
padding-bottom: 5px;
border: 1px solid gray;
}
.spec.failed {
background-color: #fbb;
border-color: red;
}
.spec.passed {
background-color: #bfb;
border-color: green;
}
.spec.skipped {
background-color: #bbb;
}
.messages {
border-left: 1px dashed gray;
padding-left: 1em;
padding-right: 1em;
}
.passed {
background-color: #cfc;
display: none;
}
.failed {
background-color: #fbb;
}
.skipped {
color: #777;
background-color: #eee;
display: none;
}
/*.resultMessage {*/
/*white-space: pre;*/
/*}*/
.resultMessage span.result {
display: block;
line-height: 2em;
color: black;
}
.resultMessage .mismatch {
color: black;
}
.stackTrace {
white-space: pre;
font-size: .8em;
margin-left: 10px;
max-height: 5em;
overflow: auto;
border: 1px inset red;
padding: 1em;
background: #eef;
}
.finished-at {
padding-left: 1em;
font-size: .6em;
}
.show-passed .passed,
.show-skipped .skipped {
display: block;
}
#jasmine_content {
position:fixed;
right: 100%;
}
.runner {
border: 1px solid gray;
display: block;
margin: 5px 0;
padding: 2px 0 2px 10px;
}

2477
git/test/lib/jasmine.js Executable file

File diff suppressed because it is too large Load diff

3
git/test/settings.js Executable file
View file

@ -0,0 +1,3 @@
// SETTINGS, VARS, UTILITY FUNCTIONS
jasmine.getFixtures().fixturesPath = 'fixtures';
var defaults = $.deck.defaults;

436
git/test/spec.core.js Executable file
View file

@ -0,0 +1,436 @@
// 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(selector)', function() {
it('should create slides', function() {
$.deck('.slide');
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('.slide');
});
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('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('.slide');
});
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 = [],
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('container states', function() {
beforeEach(function() {
$.deck('.slide');
});
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 = $('<input type="text" />').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 = $(document);
beforeEach(function() {
spyOnEvent($d, 'deck.init');
spyOnEvent($d, 'deck.beforeInit');
$.deck('.slide');
$.deck('go', 1);
spyOnEvent($d, 'deck.change');
});
describe('deck.change', function() {
it('should fire on go(i)', function() {
$.deck('go', 3);
expect('deck.change').toHaveBeenTriggeredOn($d);
});
it('should fire on next()', function() {
$.deck('next');
expect('deck.change').toHaveBeenTriggeredOn($d);
});
it('should fire on prev()', function() {
$.deck('prev');
expect('deck.change').toHaveBeenTriggeredOn($d);
});
it('should pass parameters with from and to indices', function() {
var f = function(e, from, to) {
expect(from).toEqual(1);
expect(to).toEqual(3);
};
$d.bind('deck.change', f);
$.deck('go', 3);
$d.unbind('deck.change', f);
});
it('should not change slides if default prevented', function() {
$d.bind('deck.change', false);
$.deck('go', 3);
expect($.deck('getSlide')).toEqual($.deck('getSlide', 1));
$d.unbind('deck.change', false);
});
});
describe('deck.init', function() {
it('should fire on deck initialization', function() {
expect('deck.init').toHaveBeenTriggeredOn($d);
});
it('should have already populated the slides array', function() {
var f = function() {
expect($.deck('getSlides').length).toBeGreaterThan(0);
};
$d.bind('deck.init', f);
$.deck('.slide');
$d.unbind('deck.init', f);
});
});
describe('deck.beforeInit', function() {
it('should fire on deck initialization', function() {
expect('deck.beforeInit').toHaveBeenTriggeredOn($d);
});
it('should have not populated the slides array', function() {
var f = function() {
expect($.deck('getSlides').length).toEqual(0);
};
$d.bind('deck.beforeInit', f);
$.deck('.slide');
$d.unbind('deck.beforeInit', f);
});
});
});
});
describe('complex html structure', function() {
beforeEach(function() {
loadFixtures('complex.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
$.deck([
'.slide1',
'.slide2',
'.slide3',
'.slide4',
'.slide5',
'.slide6',
'.slide7',
'.slide8',
'.slide9',
'.slide10',
]);
$.deck('go', 2);
});
describe('compound state classes', function() {
it('should apply current class', function() {
$('.slide3').each(function(i, el) {
expect($(el)).toHaveClass(defaults.classes.current);
});
});
it('should apply previous class', function() {
$('.slide2').each(function(i, el) {
expect($(el)).toHaveClass(defaults.classes.previous);
});
});
it('should apply next class', function() {
$('.slide4').each(function(i, el) {
expect($(el)).toHaveClass(defaults.classes.next);
});
});
it('should apply before class', function() {
$('.slide1').each(function(i, el) {
expect($(el)).toHaveClass(defaults.classes.before);
});
});
it('should apply after class', function() {
$('.slide5, .slide6, .slide7, .slide8, .slide9, .slide10').each(function(i, el) {
expect($(el)).toHaveClass(defaults.classes.after);
});
});
it('should apply child-current class', function() {
expect($('.slide2').not('.slide10')).toHaveClass(defaults.classes.childCurrent);
});
});
it('should remove old state classes', function() {
$.deck('go', 4);
expect($('.slide3').not('.slide5')).not.toHaveClass(defaults.classes.current);
expect($('.slide2').not('.slide4')).not.toHaveClass(defaults.classes.previous);
expect($('.slide4').not('.slide6')).not.toHaveClass(defaults.classes.next);
});
});
describe('iframes', function() {
beforeEach(function() {
loadFixtures('iframes.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
$.deck([
'.slide1',
'.slide2',
'.slide3',
'.slide4',
'.slide5',
'.slide6',
'.slide7',
'.slide8',
'.slide9',
'.slide10',
]);
});
it('should remove/restore iframe sources when leaving/entering a slide', function() {
$.deck('go', 4);
expect($.deck('getSlide').find('iframe').attr('src')).toEqual('fixtures/iframe_simple.html');
$.deck('next');
expect($('.slide5').find('iframe').attr('src')).toEqual('');
$.deck('prev');
expect($('.slide5').find('iframe').attr('src')).toEqual('fixtures/iframe_simple.html');
});
it('should not store blank iframe sources', function() {
$.deck('go', 6);
$.deck('next');
expect($.deck('getSlide').find('iframe').data('src')).toBeUndefined();
});
});
describe('empty deck', function() {
beforeEach(function() {
loadFixtures('empty.html');
$.deck('.slide');
});
describe('getSlide()', function() {
it('should not error on init', $.noop);
});
});
});

142
git/test/spec.goto.js Normal file
View file

@ -0,0 +1,142 @@
describe('Deck JS Quick Go-To', function() {
var $d = $(document);
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide');
});
describe('showGoTo()', function() {
it('should show the go-to helper', function() {
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
$.deck('showGoTo');
expect($(defaults.selectors.container)).toHaveClass(defaults.classes.goto);
});
it('should focus the go-to input', function() {
$.deck('showGoTo');
expect($(defaults.selectors.gotoInput)[0]).toEqual(document.activeElement);
});
});
describe('hideGoTo()', function() {
beforeEach(function() {
$.deck('showGoTo');
$.deck('hideGoTo');
});
it('should hide the go-to helper', function() {
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
});
it('should blur the go-to input', function() {
expect($(defaults.selectors.gotoInput)[0]).not.toEqual(document.activeElement);
});
});
describe('toggleGoTo()', function() {
it('should toggle the go-to helper on and off', function() {
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
$.deck('toggleGoTo');
expect($(defaults.selectors.container)).toHaveClass(defaults.classes.goto);
$.deck('toggleGoTo');
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
});
});
describe('Go-To submit', function() {
beforeEach(function() {
$.deck('showGoTo');
});
it('should hide the go-to helper', function() {
$(defaults.selectors.gotoInput).val('3');
$(defaults.selectors.gotoForm).submit();
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
});
it('should go to the slide number entered', function() {
$(defaults.selectors.gotoInput).val('3');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toEqual($.deck('getSlide'), 2);
});
it('should go to the slide id entered', function() {
$(defaults.selectors.gotoInput).val('custom-id');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toEqual($.deck('getSlide'), 1);
});
it('should go nowhere if the number is negative', function() {
$(defaults.selectors.gotoInput).val('-2');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toEqual($.deck('getSlide'), 0);
});
it('should go nowhere if the number is greater than the number of slides', function() {
$(defaults.selectors.gotoInput).val('9');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toEqual($.deck('getSlide'), 0);
});
it('should go nowhere if the id does not exist', function() {
$(defaults.selectors.gotoInput).val('do-not-exist');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toEqual($.deck('getSlide'), 0);
});
});
describe('Datalist population', function() {
it('should fill in options with all the slide ids', function() {
var $dataOptions = $(defaults.selectors.gotoDatalist).find('option');
expect($dataOptions.length).toEqual(5);
expect($dataOptions.eq(0).attr('value')).toEqual('slide-0');
expect($dataOptions.eq(1).attr('value')).toEqual('custom-id');
});
});
describe('key bindings', function() {
var e;
beforeEach(function() {
e = jQuery.Event('keydown.deckgoto');
});
it('should toggle the go-to helper if the specified key is pressed', function() {
e.which = 71; // g
$d.trigger(e);
expect($(defaults.selectors.container)).toHaveClass(defaults.classes.goto);
$d.trigger(e);
expect($(defaults.selectors.container)).not.toHaveClass(defaults.classes.goto);
});
});
describe('countNested false', function() {
beforeEach(function() {
loadFixtures('nesteds.html');
$.deck('.slide', {
countNested: false
});
$.deck('showGoTo');
});
it('should ignore nested slides when given a slide number', function() {
$(defaults.selectors.gotoInput).val('4');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toHaveId('after');
});
it('should respect top side of new slide range', function() {
$.deck('go', 0);
$(defaults.selectors.gotoInput).val('6');
$(defaults.selectors.gotoForm).submit();
expect($.deck('getSlide')).toHaveId('slide-0');
});
});
});

81
git/test/spec.hash.js Normal file
View file

@ -0,0 +1,81 @@
describe('Deck JS Hash Extension', function() {
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.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),
firstID = $firstSlide.attr('id');
$firstSlide.before('<div class="slide"></div>');
$.deck('.slide');
expect($firstSlide).not.toHaveId(firstID);
});
it('should update container with a state class including the slide id', function() {
var $c = $.deck('getContainer'),
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 update the href on slide change', function() {
var $hashLink = $(defaults.selectors.hashLink);
$.deck('go', 3);
expect($hashLink.attr('href')).toMatch('#slide-3');
});
it('should use existing ids if they exist', function() {
var $hashLink = $(defaults.selectors.hashLink);
$.deck('go', 1);
expect($hashLink.attr('href')).toMatch('#custom-id');
});
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');
expect($.deck('getSlide')).toHaveId('slide-3');
});
it('should follow internal hash links using hashchange (if supported)', function() {
if (Modernizr.hashchange) {
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);
}
});
it('should follow internal hash links on click', function() {
/* Triggered clicks dont generate hashchanges, so until I find
a way to do this in an automated fashion, needs to be hand tested. */
});
});

66
git/test/spec.menu.js Normal file
View file

@ -0,0 +1,66 @@
describe('Deck JS Menu', function() {
var $d = $(document),
dsc = defaults.selectors.container;
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide');
});
describe('showMenu()', function() {
it('should show the menu', function() {
expect($(dsc)).not.toHaveClass(defaults.classes.menu);
$.deck('showMenu');
expect($(dsc)).toHaveClass(defaults.classes.menu);
});
it('should do nothing if menu is already showing', function() {
if (Modernizr.csstransforms) {
$.deck('showMenu');
$.deck('showMenu');
$.deck('hideMenu');
expect($('.slide').attr('style')).toBeFalsy();
}
});
});
describe('hideMenu()', function() {
it('should hide the menu', function() {
$.deck('showMenu');
$.deck('hideMenu');
expect($(dsc)).not.toHaveClass(defaults.classes.menu);
});
});
describe('toggleMenu()', function() {
it('should toggle menu on and off', function() {
expect($(dsc)).not.toHaveClass(defaults.classes.menu);
$.deck('toggleMenu');
expect($(dsc)).toHaveClass(defaults.classes.menu);
$.deck('toggleMenu');
expect($(dsc)).not.toHaveClass(defaults.classes.menu);
});
});
describe('key bindings', function() {
var e;
beforeEach(function() {
e = jQuery.Event('keydown.deckmenu');
});
it('should toggle the menu if the specified key is pressed', function() {
e.which = 77; // m
$d.trigger(e);
expect($(dsc)).toHaveClass(defaults.classes.menu);
$d.trigger(e);
expect($(dsc)).not.toHaveClass(defaults.classes.menu);
});
});
});

View file

@ -0,0 +1,51 @@
describe('Deck JS Navigation Buttons', function() {
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide');
});
it('should go to the next slide if next link is clicked', function() {
$(defaults.selectors.nextLink).click();
expect($.deck('getSlide')).toHaveClass('slide2');
});
it('should go to the previous slide if previous link is clicked', function() {
$.deck('go', 2);
$(defaults.selectors.previousLink).click();
expect($.deck('getSlide')).toHaveClass('slide2');
});
it('should add the disabled class to the previous link if on first slide', function() {
expect($(defaults.selectors.previousLink)).toHaveClass(defaults.classes.navDisabled);
$(defaults.selectors.nextLink).click();
expect($(defaults.selectors.previousLink)).not.toHaveClass(defaults.classes.navDisabled);
$(defaults.selectors.previousLink).click();
expect($(defaults.selectors.previousLink)).toHaveClass(defaults.classes.navDisabled);
});
it('should add the disabled class to the next link if on last slide', function() {
expect($(defaults.selectors.nextLink)).not.toHaveClass(defaults.classes.navDisabled);
$.deck('go', $.deck('getSlides').length - 1);
expect($(defaults.selectors.nextLink)).toHaveClass(defaults.classes.navDisabled);
});
it('should not start disabled if deck initialized in the middle', function() {
$.deck('go', 2);
$.deck('.slide');
expect($(defaults.selectors.previousLink)).not.toHaveClass(defaults.classes.navDisabled);
});
it('should update the links hrefs with real fragment ids', function() {
expect($(defaults.selectors.previousLink).attr('href')).toMatch(/#$/);
expect($(defaults.selectors.nextLink).attr('href')).toMatch('#custom-id');
$.deck('go', 2);
expect($(defaults.selectors.previousLink).attr('href')).toMatch('#custom-id');
expect($(defaults.selectors.nextLink).attr('href')).toMatch('#slide-3');
});
});

57
git/test/spec.scale.js Normal file
View file

@ -0,0 +1,57 @@
describe('Deck JS Status Indicator', function() {
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide');
});
it('should start with scaling enabled', function() {
expect($.deck('getContainer')).toHaveClass(defaults.classes.scale);
});
describe('disableScale()', function() {
it('should remove the scale class from the container', function() {
$.deck('disableScale');
expect($.deck('getContainer')).not.toHaveClass(defaults.classes.scale);
});
});
describe('enableScale()', function() {
it('should add the scale class to the container', function() {
$.deck('disableScale');
$.deck('enableScale');
expect($.deck('getContainer')).toHaveClass(defaults.classes.scale);
});
});
describe('toggleScale()', function() {
it('should toggle between adding and removing the scale class', function() {
$.deck('toggleScale');
expect($.deck('getContainer')).not.toHaveClass(defaults.classes.scale);
$.deck('toggleScale');
expect($.deck('getContainer')).toHaveClass(defaults.classes.scale);
});
});
describe('key bindings', function() {
var e,
$d = $(document);
beforeEach(function() {
e = jQuery.Event('keydown.deckscale');
});
it('should toggle scaling if the specified key is pressed', function() {
e.which = 83; // s
$d.trigger(e);
expect($.deck('getContainer')).not.toHaveClass(defaults.classes.scale);
$d.trigger(e);
expect($.deck('getContainer')).toHaveClass(defaults.classes.scale);
});
});
});

58
git/test/spec.status.js Normal file
View file

@ -0,0 +1,58 @@
describe('Deck JS Status Indicator', function() {
beforeEach(function() {
loadFixtures('standard.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide');
});
it('should show the correct total number of slides', function() {
expect($(defaults.selectors.statusTotal)).toHaveText($.deck('getSlides').length);
});
it('should start at the right current slide', function() {
expect($(defaults.selectors.statusCurrent)).toHaveText(1);
$.deck('go', 2);
$.deck('.slide');
expect($(defaults.selectors.statusCurrent)).toHaveText(3);
});
it('should update to the correct number on slide change', function() {
$.deck('go', 2);
expect($(defaults.selectors.statusCurrent)).toHaveText('3');
});
});
describe('countNested false indicator', function() {
beforeEach(function() {
loadFixtures('nesteds.html');
if (Modernizr.history) {
history.replaceState({}, "", "#")
}
else {
window.location.hash = '#';
}
$.deck('.slide', {
countNested: false
});
});
it('should ignore nested slides in the total', function() {
expect($(defaults.selectors.statusTotal)).toHaveText('5');
});
it('should update to the root slide number when nested becomes active', function() {
$.deck('go', 10);
expect($(defaults.selectors.statusCurrent)).toHaveText('4');
$.deck('prev');
expect($(defaults.selectors.statusCurrent)).toHaveText('3');
$.deck('go', 3);
expect($(defaults.selectors.statusCurrent)).toHaveText('3');
$.deck('go', 1);
expect($(defaults.selectors.statusCurrent)).toHaveText('2');
});
});