Merge branch '2_0'

src/html/HtmlReporter.js
This commit is contained in:
Dan Hansen and Davis W. Frank
2013-02-19 12:07:47 -08:00
87 changed files with 5701 additions and 8007 deletions
+46
View File
@@ -0,0 +1,46 @@
# (Vague) Jasmine 2.0 Goals/(Guidelines)
1. No globals!
* jasmine library is entirely inside `jasmine` namespace
* globals required for backwards compatibility should be added in `boot.js` (EG, var describe = jasmine.getCurrentEnv().describe lives in boot.js)
1. Don't use properties as getters. Use methods.
* Properties aren't encapsulated -- can be mutated, unsafe.
1. Reporters get data objects (no methods).
* easier to refactor as needed
1. More unit tests - fewer nasty integration tests
## Remaining non-story-able work:
* Make a `TODO` list
### Hard
* Finish killing Globals
* Guidelines:
* New objects can have constructors on `jasmine`
* Top level functions can live on `jasmine`
* Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor
* Spies
* isA functions:
* isArray_ - used in matchers and spies
* isString_
* isDOMNode_
* isA_
* unimplementedMethod_, used by PrettyPrinter
* jasmine.util should be util closure inside of env or something
* argsToArray is used for Spies and matching
* inherit is for how matchers are added/mixed in, reporters, and pretty printers
* formatException is used only inside Env/spec
* htmlEscape is for messages in matchers - should this be HTML at all? Is that * Matchers improvements
* move AddMatchers to Env & global (away from spec)
* make matchers unit-testable
* write doc on how to make a matcher
### Easy
## Other Topics
* Build - can we, should we redo the build and release process AGAIN in order to make it less arcane
* Want to add JSHint to build
* Use a standard JS/Node based concat system instead of custom Ruby?
* Docs
* JsDoc is a pain to host and RubyMine is pretty good at navigating. I say we kill it officially
* Docco has gone over well. Should we annotate all the sources and then have Pages be more complex, having tutorials and annotated source like Backbone? Are we small enough?
+1 -1
View File
@@ -1,6 +1,6 @@
source :rubygems source :rubygems
gem "rake" gem "rake"
gem "jasmine", git: 'https://github.com/pivotal/jasmine-gem.git' gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git', :branch => '2_0'
unless ENV["TRAVIS"] unless ENV["TRAVIS"]
group :debug do group :debug do
+3 -2
View File
@@ -55,9 +55,10 @@ end
namespace :jasmine do namespace :jasmine do
task :server do task :server do
port = ENV['JASMINE_PORT'] || 8888 port = ENV['JASMINE_PORT'] || 8888
Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', 'jasmine.yml')) jasmine_yml = ENV['JASMINE_YML'] || 'jasmine.yml'
Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', jasmine_yml))
config = Jasmine.config config = Jasmine.config
server = Jasmine::Server.new(8888, Jasmine::Application.app(config)) server = Jasmine::Server.new(port, Jasmine::Application.app(config))
server.start server.start
puts "your tests are here:" puts "your tests are here:"
+8
View File
@@ -23,6 +23,14 @@ module Jasmine
spec_files("node") spec_files("node")
end end
def boot_files
["boot.js"]
end
def boot_dir
File.join(path, 'boot')
end
def spec_files(type) def spec_files(type)
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type) raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq (Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
+92
View File
@@ -0,0 +1,92 @@
(function() {
var env = jasmine.getEnv();
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
addMatchers: function(matchers) {
return env.addMatchers(matchers);
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
clock: env.clock,
setTimeout: env.clock.setTimeout,
clearTimeout: env.clock.clearTimeout,
setInterval: env.clock.setInterval,
clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter(jasmine)
};
if (typeof window == "undefined" && typeof exports == "object") {
extend(exports, jasmineInterface);
} else {
extend(window, jasmineInterface);
}
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
});
env.catchExceptions(queryString.getParam("catch"));
var htmlReporter = new jasmine.HtmlReporter({
env: env,
queryString: queryString,
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
env.addReporter(jasmineInterface.jsApiReporter);
env.addReporter(htmlReporter);
env.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
htmlReporter.initialize();
env.execute();
};
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());
-54
View File
@@ -1,54 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0.rc1/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0.rc1/jasmine.css">
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine-html.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="spec/SpecHelper.js"></script>
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="src/Player.js"></script>
<script type="text/javascript" src="src/Song.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var trivialReporter = new jasmine.TrivialReporter();
jasmineEnv.addReporter(trivialReporter);
jasmineEnv.specFilter = function(spec) {
return trivialReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body>
</body>
</html>
+271 -633
View File
@@ -1,681 +1,319 @@
jasmine.HtmlReporterHelpers = {}; jasmine.HtmlReporter = function(options) {
var env = options.env || {},
getContainer = options.getContainer,
now = options.now || function() { return new Date().getTime();},
createElement = options.createElement,
createTextNode = options.createTextNode,
results = [],
queryString = options.queryString,
startTime,
specsExecuted = 0,
failureCount = 0,
htmlReporterMain,
symbols;
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { this.initialize = function() {
var el = document.createElement(type); htmlReporterMain = createDom("div", {className: "html-reporter"},
createDom("div", {className: "banner"},
createDom("span", {className: "title"}, "Jasmine"),
createDom("span", {className: "version"}, env.versionString())
),
createDom("ul", {className: "symbol-summary"}),
createDom("div", {className: "alert"}),
createDom("div", {className: "results"},
createDom("div", {className: "failures"})
)
);
getContainer().appendChild(htmlReporterMain);
for (var i = 2; i < arguments.length; i++) { symbols = find(".symbol-summary")[0];
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.HtmlReporterHelpers.getSpecStatus = function(child) {
var results = child.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
return status;
};
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
var parentDiv = this.dom.summary;
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
var parent = child[parentSuite];
if (parent) {
if (typeof this.views.suites[parent.id] == 'undefined') {
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
}
parentDiv = this.views.suites[parent.id].element;
}
parentDiv.appendChild(childElement);
};
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
for(var fn in jasmine.HtmlReporterHelpers) {
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
}
};
jasmine.HtmlReporter = function(_doc) {
var self = this;
var doc = _doc || window.document;
var reporterView;
var dom = {};
// Jasmine Reporter Public Interface
self.logRunningSpecs = false;
self.reportRunnerStarting = function(runner) {
var specs = runner.specs() || [];
if (specs.length == 0) {
return;
}
createReporterDom(runner.env.versionString());
doc.body.appendChild(dom.reporter);
setExceptionHandling();
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
reporterView.addSpecs(specs, self.specFilter);
}; };
self.reportRunnerResults = function(runner) { var specFilterPattern;
reporterView && reporterView.complete();
};
self.reportSuiteResults = function(suite) { this.specFilter = function(spec) {
reporterView.suiteComplete(suite); if (!isFiltered()) {
};
self.reportSpecStarting = function(spec) {
if (self.logRunningSpecs) {
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
self.reportSpecResults = function(spec) {
reporterView.specComplete(spec);
};
self.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
}
}
};
self.specFilter = function(spec) {
if (!focusedSpecName()) {
return true; return true;
} }
return spec.getFullName().indexOf(focusedSpecName()) === 0; var specName = spec.getFullName();
return !!(specName.match(specFilterPattern));
}; };
return self; var totalSpecsDefined;
this.jasmineStarted = function(options) {
function focusedSpecName() { totalSpecsDefined = options.totalSpecsDefined || 0;
var specName; startTime = now();
(function memoizeFocusedSpec() {
if (specName) {
return;
}
var paramMap = [];
var params = jasmine.HtmlReporter.parameters(doc);
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
specName = paramMap.spec;
})();
return specName;
}
function createReporterDom(version) {
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
dom.banner = self.createDom('div', { className: 'banner' },
self.createDom('span', { className: 'title' }, "Jasmine "),
self.createDom('span', { className: 'version' }, version)),
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'},
self.createDom('span', { className: 'exceptions' },
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),
dom.details = self.createDom('div', { id: 'details' }))
);
}
function noTryCatch() {
return window.location.search.match(/catch=false/);
}
function searchWithCatch() {
var params = jasmine.HtmlReporter.parameters(window.document);
var removed = false;
var i = 0;
while (!removed && i < params.length) {
if (params[i].match(/catch=/)) {
params.splice(i, 1);
removed = true;
}
i++;
}
if (jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
return params.join("&");
}
function setExceptionHandling() {
var chxCatch = document.getElementById('no_try_catch');
if (noTryCatch()) {
chxCatch.setAttribute('checked', true);
jasmine.CATCH_EXCEPTIONS = false;
}
chxCatch.onclick = function() {
window.location.search = searchWithCatch();
};
}
};
jasmine.HtmlReporter.parameters = function(doc) {
var paramStr = doc.location.search.substring(1);
var params = [];
if (paramStr.length > 0) {
params = paramStr.split('&');
}
return params;
}
jasmine.HtmlReporter.sectionLink = function(sectionName) {
var link = '?';
var params = [];
if (sectionName) {
params.push('spec=' + encodeURIComponent(sectionName));
}
if (!jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
if (params.length > 0) {
link += params.join("&");
}
return link;
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
jasmine.HtmlReporter.ReporterView = function(dom) {
this.startedAt = new Date();
this.runningSpecCount = 0;
this.completeSpecCount = 0;
this.passedCount = 0;
this.failedCount = 0;
this.skippedCount = 0;
this.createResultsMenu = function() {
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
' | ',
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
this.summaryMenuItem.onclick = function() {
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
};
this.detailsMenuItem.onclick = function() {
showDetails();
};
}; };
this.addSpecs = function(specs, specFilter) { var summary = createDom("div", {className: "summary"});
this.totalSpecCount = specs.length;
this.views = { var topResults = new jasmine.ResultsNode({}, "", null),
specs: {}, currentParent = topResults;
suites: {}
};
for (var i = 0; i < specs.length; i++) { this.suiteStarted = function(result) {
var spec = specs[i]; currentParent.addChild(result, "suite");
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); currentParent = currentParent.last();
if (specFilter(spec)) {
this.runningSpecCount++;
}
}
}; };
this.specComplete = function(spec) { this.suiteDone = function(result) {
this.completeSpecCount++; if (currentParent == topResults) {
if (isUndefined(this.views.specs[spec.id])) {
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
}
var specView = this.views.specs[spec.id];
switch (specView.status()) {
case 'passed':
this.passedCount++;
break;
case 'failed':
this.failedCount++;
break;
case 'skipped':
this.skippedCount++;
break;
}
specView.refresh();
this.refresh();
};
this.suiteComplete = function(suite) {
var suiteView = this.views.suites[suite.id];
if (isUndefined(suiteView)) {
return; return;
} }
suiteView.refresh();
currentParent = currentParent.parent;
}; };
this.refresh = function() { this.specStarted = function(result) {
currentParent.addChild(result, "spec");
if (isUndefined(this.resultsMenu)) {
this.createResultsMenu();
}
// currently running UI
if (isUndefined(this.runningAlert)) {
this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
dom.alert.appendChild(this.runningAlert);
}
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
// skipped specs UI
if (isUndefined(this.skippedAlert)) {
this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
}
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.skippedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.skippedAlert);
}
// passing specs UI
if (isUndefined(this.passedAlert)) {
this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
}
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
// failing specs UI
if (isUndefined(this.failedAlert)) {
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
}
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
if (this.failedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.failedAlert);
dom.alert.appendChild(this.resultsMenu);
}
// summary info
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
}; };
this.complete = function() { var failures = [];
dom.alert.removeChild(this.runningAlert); this.specDone = function(result) {
if (result.status != "disabled") {
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; specsExecuted++;
if (this.failedCount === 0) {
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
} else {
showDetails();
} }
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s")); symbols.appendChild(createDom("li", {
className: result.status,
id: "spec_" + result.id}
));
if (result.status == "failed") {
failureCount++;
var failure =
createDom("div", {className: "spec-detail failed"},
createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
createDom("div", {className: "messages"})
);
var messages = failure.childNodes[1];
for (var i = 0; i < result.failedExpectations.length; i++) {
var expectation = result.failedExpectations[i];
var stack = (expectation.trace && expectation.trace.stack) || "";
messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
messages.appendChild(createDom("div", {className: "stack-trace"}, stack));
}
failures.push(failure);
}
};
this.jasmineDone = function() {
var elapsed = now() - startTime;
var banner = find(".banner")[0];
banner.appendChild(createDom("span", {className: "duration"}, "finished in " + elapsed / 1000 + "s"));
var alert = find(".alert")[0];
alert.appendChild(createDom("span", { className: "exceptions" },
createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
createDom("input", {
className: "raise",
id: "raise-exceptions",
type: "checkbox"
})
));
var checkbox = find("input")[0];
checkbox.checked = !env.catchingExceptions();
checkbox.onclick = function() {
queryString.setParam("catch", !checkbox.checked);
};
if (specsExecuted < totalSpecsDefined) {
var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
alert.appendChild(
createDom("span", {className: "bar skipped"},
createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
)
);
}
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount),
statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
var results = find(".results")[0];
results.appendChild(summary);
summaryList(topResults, summary);
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
if (resultNode.type == "suite") {
var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
createDom("li", {className: "suite-detail"},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
summaryList(resultNode, suiteListNode);
domParent.appendChild(suiteListNode);
}
if (resultNode.type == "spec") {
if (domParent.getAttribute("class") != "specs") {
specListNode = createDom("ul", {className: "specs"});
domParent.appendChild(specListNode);
}
specListNode.appendChild(
createDom("li", {
className: resultNode.result.status,
id: "spec-" + resultNode.result.id
},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
}
}
}
if (failures.length) {
alert.appendChild(
createDom('span', {className: "menu bar spec-list"},
createDom("span", {}, "Spec List | "),
createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
alert.appendChild(
createDom('span', {className: "menu bar failure-list"},
createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
createDom("span", {}, " | Failures ")));
find(".failures-menu")[0].onclick = function() {
setMenuModeTo('failure-list');
};
find(".spec-list-menu")[0].onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
var failureNode = find(".failures")[0];
for (var i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
}
}; };
return this; return this;
function showDetails() { function find(selector) {
if (dom.reporter.className.search(/showDetails/) === -1) { if (selector.match(/^\./)) {
dom.reporter.className += " showDetails"; var className = selector.substring(1);
return getContainer().getElementsByClassName(className);
} else {
return getContainer().getElementsByTagName(selector);
} }
} }
function isUndefined(obj) { function createDom(type, attrs, childrenVarArgs) {
return typeof obj === 'undefined'; var el = createElement(type);
}
function isDefined(obj) { for (var i = 2; i < arguments.length; i++) {
return !isUndefined(obj); var child = arguments[i];
}
function specPluralizedFor(count) { if (typeof child === 'string') {
var str = count + " spec"; el.appendChild(createTextNode(child));
if (count > 1) { } else {
str += "s" if (child) {
} el.appendChild(child);
return str; }
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
this.spec = spec;
this.dom = dom;
this.views = views;
this.symbol = this.createDom('li', { className: 'pending' });
this.dom.symbolSummary.appendChild(this.symbol);
this.summary = this.createDom('div', { className: 'specSummary' },
this.createDom('a', {
className: 'description',
href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.description)
);
this.detail = this.createDom('div', { className: 'specDetail' },
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.getFullName())
);
};
jasmine.HtmlReporter.SpecView.prototype.status = function() {
return this.getSpecStatus(this.spec);
};
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
this.symbol.className = this.status();
switch (this.status()) {
case 'skipped':
break;
case 'passed':
this.appendSummaryToSuiteDiv();
break;
case 'failed':
this.appendSummaryToSuiteDiv();
this.appendFailureDetail();
break;
}
};
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
this.summary.className += ' ' + this.status();
this.appendToSummary(this.spec, this.summary);
};
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
this.detail.className += ' ' + this.status();
var resultItems = this.spec.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) { for (var attr in attrs) {
this.detail.appendChild(messagesDiv); if (attr == "className") {
this.dom.details.appendChild(this.detail); el[attr] = attrs[attr];
} } else {
}; el.setAttribute(attr, attrs[attr]);
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
this.suite = suite;
this.dom = dom;
this.views = views;
this.element = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
);
this.appendToSummary(this.suite, this.element);
};
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
return this.getSpecStatus(this.suite);
};
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
this.element.className += " " + this.status();
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
/* @deprecated Use jasmine.HtmlReporter instead
*/
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', { id: 'TrivialReporter', 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));
} }
} }
return el;
} }
if (messagesDiv.childNodes.length > 0) { function pluralize(singular, count) {
specDiv.appendChild(messagesDiv); var word = (count == 1 ? singular : singular + "s");
return "" + count + " " + word;
} }
this.suiteDivs[spec.suite.id].appendChild(specDiv); function specHref(result) {
}; return "?spec=" + encodeURIComponent(result.fullName);
}
jasmine.TrivialReporter.prototype.log = function() { function isFiltered() {
var console = jasmine.getGlobal().console; buildSpecFilter();
if (console && console.log) {
if (console.log.apply) { return !!specFilterPattern;
console.log.apply(console, arguments); }
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie function buildSpecFilter() {
var specFilterParam = queryString.getParam("spec") || "";
specFilterPattern = new RegExp(specFilterParam);
}
function setMenuModeTo(mode) {
htmlReporterMain.setAttribute("class", "html-reporter " + mode);
}
};jasmine.ResultsNode = function(result, type, parent) {
this.result = result;
this.type = type;
this.parent = parent;
this.children = [];
this.addChild = function(result, type) {
this.children.push(new jasmine.ResultsNode(result, type, this));
};
this.last = function() {
return this.children[this.children.length-1];
}
};jasmine.QueryString = function(options) {
this.setParam = function(key, value) {
var paramMap = queryStringToParamMap();
paramMap[key] = value;
options.getWindowLocation().search = toQueryString(paramMap);
};
this.getParam = function(key) {
return queryStringToParamMap()[key];
};
return this;
function toQueryString(paramMap) {
var qStrPairs = [];
for (var prop in paramMap) {
qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
} }
} return "?" + qStrPairs.join('&');
};
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) { function queryStringToParamMap() {
return true; var paramStr = options.getWindowLocation().search.substring(1),
params = [],
paramMap = {};
if (paramStr.length > 0) {
params = paramStr.split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
var value = decodeURIComponent(p[1]);
if (value === "true" || value === "false") {
value = JSON.parse(value);
}
paramMap[decodeURIComponent(p[0])] = value;
}
}
return paramMap;
} }
return spec.getFullName().indexOf(paramMap.spec) === 0;
}; };
+51 -80
View File
@@ -1,82 +1,53 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; } .html-reporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; } .html-reporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; } .html-reporter .banner .version { margin-left: 14px; }
#HTMLReporter .version { color: #aaaaaa; } .html-reporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .banner { margin-top: 14px; } .html-reporter .version { color: #aaaaaa; }
#HTMLReporter .duration { color: #aaaaaa; float: right; } .html-reporter .banner { margin-top: 14px; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } .html-reporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; } .html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } .html-reporter .symbol-summary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; } .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } .html-reporter .symbol-summary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } .html-reporter .symbol-summary li.disabled { font-size: 14px; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; } .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } .html-reporter .symbol-summary li.pending { line-height: 11px; }
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } .html-reporter .symbol-summary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
#HTMLReporter .runningAlert { background-color: #666666; } .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; } .html-reporter .bar.failed { background-color: #b03911; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; } .html-reporter .bar.passed { background-color: #a6b779; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } .html-reporter .bar.skipped { background-color: #bababa; }
#HTMLReporter .passingAlert { background-color: #a6b779; } .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } .html-reporter .bar.menu a { color: #333333; }
#HTMLReporter .failingAlert { background-color: #cf867e; } .html-reporter .bar a { color: white; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; } .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
#HTMLReporter .results { margin-top: 14px; } .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
#HTMLReporter #details { display: none; } .html-reporter .running-alert { background-color: #666666; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } .html-reporter .results { margin-top: 14px; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; } .html-reporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; } .html-reporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; } .html-reporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; } .html-reporter .summary li.passed a { color: #5e7d00; }
#HTMLReporter .description + .suite { margin-top: 0; } .html-reporter .summary li.failed a { color: #b03911; }
#HTMLReporter .suite { margin-top: 14px; } .html-reporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite a { color: #333333; } .html-reporter .suite { margin-top: 14px; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; } .html-reporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } .html-reporter .failures .spec-detail { margin-bottom: 28px; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } .html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage span.result { display: block; } .html-reporter .result-message { padding-top: 14px; color: #333333; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } .html-reporter .result-message span.result { display: block; }
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
+943 -1553
View File
File diff suppressed because it is too large Load Diff
Submodule pages deleted from dae7b20e1c
+157 -401
View File
@@ -1,451 +1,207 @@
describe("ConsoleReporter", function() { describe("ConsoleReporter", function() {
//keep these literal. otherwise the test loses value as a test. var out;
function green(str) {
return '\033[32m' + str + '\033[0m';
}
function red(str) {
return '\033[31m' + str + '\033[0m';
}
function yellow(str) {
return '\033[33m' + str + '\033[0m';
}
function prefixGreen(str) {
return '\033[32m' + str;
}
function prefixRed(str) {
return '\033[31m' + str;
}
var newline = "\n";
var passingSpec = {
results: function() {
return {
passed: function() {
return true;
}
};
}
},
failingSpec = {
results: function() {
return {
passed: function() {
return false;
}
};
}
},
skippedSpec = {
results: function() {
return {skipped: true};
}
},
passingRun = {
specs: function() {
return [null, null, null];
},
results: function() {
return {failedCount: 0, items_: [null, null, null]};
}
},
failingRun = {
specs: function() {
return [null, null, null];
},
results: function() {
return {
failedCount: 7, items_: [null, null, null]};
}
};
function repeatedlyInvoke(f, times) {
for (var i = 0; i < times; i++) f(times + 1);
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) arr.push(thing);
return arr;
}
function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
reporter.reportRunnerStarting();
for (var i = 0; i < specResults.length; i++) {
reporter.reportSpecResults(specResults[i]);
}
for (i = 0; i < suiteResults.length; i++) {
reporter.reportSuiteResults(suiteResults[i]);
}
reporter.runnerStartTime = startTime;
reporter.now = function() {
return endTime;
};
reporter.reportRunnerResults(finalRunner);
}
var reporter, out, done;
beforeEach(function() { beforeEach(function() {
out = (function() { out = (function() {
var output = ""; var output = "";
return { return {
print:function(str) { print: function(str) {
output += str; output += str;
}, },
getOutput:function() { getOutput: function() {
return output; return output;
}, },
clear: function() { clear: function() {
output = ""; output = "";
} }
}; };
})(); }());
done = false;
reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
done = true
});
}); });
it("reports that the suite has started to the console", function() {
describe('Integration', function() { var reporter = new jasmine.ConsoleReporter({
it("prints the proper output under a pass scenario - small numbers.", function() { print: out.print
simulateRun(reporter,
repeat(passingSpec, 3),
[],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 0
};
}
},
1000,
1777
);
var output = out.getOutput();
expect(output).toMatch(/^Started/);
expect(output).toMatch(/\.\.\./);
expect(output).toMatch(/3 specs, 0 failures/);
}); });
it("prints the proper output under a pass scenario. large numbers.", function() { reporter.jasmineStarted();
simulateRun(reporter,
repeat(passingSpec, 57),
[],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 0
};
}
},
1000,
1777);
var output = out.getOutput(); expect(out.getOutput()).toEqual("Started\n");
expect(output).toMatch(/^Started/);
expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
expect(output).toMatch(/3 specs, 0 failures/);
});
it("prints the proper output under a failure scenario.", function() {
simulateRun(reporter,
[failingSpec, passingSpec, failingSpec],
[
{description:"The oven",
results:function() {
return {
items_:[
{failedCount:2,
description:"heats up",
items_:[
{trace:{stack:"stack trace one\n second line"}},
{trace:{stack:"stack trace two"}}
]}
]
};
}},
{description:"The washing machine",
results:function() {
return {
items_:[
{failedCount:2,
description:"washes clothes",
items_:[
{trace:{stack:"stack trace one"}}
]}
]
};
}}
],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 2
};
}
},
1000,
1777);
var output = out.getOutput();
expect(output).toMatch(/^Started/);
expect(output).toMatch(/F\.F/);
expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
expect(output).toMatch(/3 specs, 2 failures/);
});
}); });
describe('When a Jasmine environment executes', function() { it("reports a passing spec as a dot", function() {
beforeEach(function() { var reporter = new jasmine.ConsoleReporter({
reporter.reportRunnerStarting(); print: out.print
}); });
it("should print 'Started' to the console", function() { reporter.specDone({status: "passed"});
expect(out.getOutput()).toEqual("Started" + newline);
expect(out.getOutput()).toEqual(".");
});
it("does not report a disabled spec", function() {
var reporter = new jasmine.ConsoleReporter({
print: out.print
}); });
describe('when a spec reports', function() { reporter.specDone({status: "disabled"});
beforeEach(function() {
out.clear();
});
it("prints a green dot if the spec passes", function() { expect(out.getOutput()).toEqual("");
reporter.reportSpecResults(passingSpec); });
expect(out.getOutput()).toMatch(/\./); it("reports a failing spec as an 'F'", function() {
}); var reporter = new jasmine.ConsoleReporter({
print: out.print
it("prints a red dot if the spec fails", function() {
reporter.reportSpecResults(failingSpec);
expect(out.getOutput()).toMatch(/F/);
});
it("prints a yellow star if the spec was skipped", function() {
reporter.reportSpecResults(skippedSpec);
expect(out.getOutput()).toMatch(/\*/);
});
}); });
describe('when a suite reports', function() { reporter.specDone({status: "failed"});
var emptyResults;
beforeEach(function() { expect(out.getOutput()).toEqual("F");
emptyResults = function() { });
return {
items_:[] it("reports a summary when done (singluar spec and time)", function() {
}; var fakeNow = jasmine.createSpy('fake Date.now'),
}; reporter = new jasmine.ConsoleReporter({
print: out.print,
now: fakeNow
}); });
it("remembers suite results", function() { fakeNow.andReturn(500);
reporter.reportSuiteResults({description: "Oven", results: emptyResults});
reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
expect(reporter.suiteResults[0].description).toEqual('Oven'); reporter.jasmineStarted();
expect(reporter.suiteResults[1].description).toEqual('Mixer'); reporter.specDone({status: "passed"});
fakeNow.andReturn(1500);
out.clear();
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/1 spec, 0 failures/);
expect(out.getOutput()).toMatch("Finished in 1 second\n");
});
it("reports a summary when done (pluralized specs and seconds)", function() {
var fakeNow = jasmine.createSpy('fake Date.now'),
reporter = new jasmine.ConsoleReporter({
print: out.print,
now: fakeNow
}); });
it("creates a description out of the current suite and any parent suites", function() { fakeNow.andReturn(500);
var grandparentSuite = { reporter.jasmineStarted();
description: "My house", reporter.specDone({status: "passed"});
results: emptyResults reporter.specDone({
}; status: "failed",
var parentSuite = { description: "with a failing spec",
description: "kitchen", fullName: "A suite with a failing spec",
parentSuite: grandparentSuite, failedExpectations: [
results: emptyResults {
}; passed: false,
reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults }); message: "Expected true to be false.",
expected: false,
expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven"); actual: true,
}); trace: {
stack: "foo\nbar\nbaz"
it("gathers failing spec results from the suite - the spec must have a description.", function() {
reporter.reportSuiteResults({description:"Oven",
results: function() {
return {
items_:[
{ failedCount: 0, description: "specOne" },
{ failedCount: 99, description: "specTwo" },
{ failedCount: 0, description: "specThree" },
{ failedCount: 88, description: "specFour" },
{ failedCount: 3 }
]
};
}});
expect(reporter.suiteResults[0].failedSpecResults).
toEqual([
{ failedCount: 99, description: "specTwo" },
{ failedCount: 88, description: "specFour" }
]);
});
});
describe('and finishes', function() {
describe('when reporting spec failure information', function() {
it("prints suite and spec descriptions together as a sentence", function() {
reporter.suiteResults = [
{description:"The oven", failedSpecResults:[
{description:"heats up", items_:[]},
{description:"cleans itself", items_:[]}
]},
{description:"The mixer", failedSpecResults:[
{description:"blends things together", items_:[]}
]}
];
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("The oven heats up");
expect(out.getOutput()).toContain("The oven cleans itself");
expect(out.getOutput()).toContain("The mixer blends things together");
});
it("prints stack trace of spec failure", function() {
reporter.suiteResults = [
{description:"The oven", failedSpecResults:[
{description:"heats up",
items_:[
{trace:{stack:"stack trace one"}},
{trace:{stack:"stack trace two"}}
]}
]}
];
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("The oven heats up");
expect(out.getOutput()).toContain("stack trace one");
expect(out.getOutput()).toContain("stack trace two");
});
});
describe('when reporting the execution time', function() {
it("prints the full finished message", function() {
reporter.now = function() {
return 1000;
};
reporter.reportRunnerStarting();
reporter.now = function() {
return 1777;
};
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("Finished in 0.777 seconds");
});
it("prints round time numbers correctly", function() {
function run(startTime, endTime) {
out.clear();
reporter.runnerStartTime = startTime;
reporter.now = function() {
return endTime;
};
reporter.reportRunnerResults(passingRun);
} }
}
]
});
run(1000, 11000); out.clear();
expect(out.getOutput()).toContain("10 seconds");
run(1000, 2000); fakeNow.andReturn(600);
expect(out.getOutput()).toContain("1 seconds"); reporter.jasmineDone();
run(1000, 1100); expect(out.getOutput()).toMatch(/2 specs, 1 failure/);
expect(out.getOutput()).toContain("0.1 seconds"); expect(out.getOutput()).toMatch("Finished in 0.1 seconds\n");
});
run(1000, 1010); it("reports a summary when done that includes stack traces for a failing suite", function() {
expect(out.getOutput()).toContain("0.01 seconds"); var reporter = new jasmine.ConsoleReporter({
print: out.print
});
run(1000, 1001); reporter.jasmineStarted();
expect(out.getOutput()).toContain("0.001 seconds"); reporter.specDone({status: "passed"});
}); reporter.specDone({
status: "failed",
description: "with a failing spec",
fullName: "A suite with a failing spec",
failedExpectations: [
{
passed: false,
message: "Expected true to be false.",
expected: false,
actual: true,
trace: {
stack: "foo bar baz"
}
}
]
});
out.clear();
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/foo bar baz/);
});
it("calls the onComplete callback when the suite is done", function() {
var onComplete = jasmine.createSpy('onComplete'),
reporter = new jasmine.ConsoleReporter({
print: out.print,
onComplete: onComplete
}); });
describe("when reporting the results summary", function() { reporter.jasmineDone();
it("prints statistics in green if there were no failures", function() {
reporter.reportRunnerResults({
specs: function() {
return [null, null, null];
},
results:function() {
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
}
});
expect(out.getOutput()).
toContain("3 specs, 0 failures");
});
it("prints statistics in red if there was a failure", function() { expect(onComplete).toHaveBeenCalled();
reporter.reportRunnerResults({ });
specs: function() {
return [null, null, null];
},
results:function() {
return {items_: [null, null, null], totalCount: 7, failedCount: 3};
}
});
expect(out.getOutput()).
toContain("3 specs, 3 failures");
});
it("handles pluralization with 1's ones appropriately", function() {
reporter.reportRunnerResults({ describe("with color", function() {
specs: function() {
return [null]; it("reports that the suite has started to the console", function() {
}, var reporter = new jasmine.ConsoleReporter({
results:function() { print: out.print,
return {items_: [null], totalCount: 1, failedCount: 1}; showColors: true
}
});
expect(out.getOutput()).
toContain("1 spec, 1 failure");
});
}); });
describe("done callback", function() { reporter.jasmineStarted();
it("calls back when done", function() {
expect(done).toBeFalsy(); expect(out.getOutput()).toEqual("Started\n");
reporter.reportRunnerResults({ });
specs: function() {
return [null, null, null]; it("reports a passing spec as a dot", function() {
}, var reporter = new jasmine.ConsoleReporter({
results:function() { print: out.print,
return {items_: [null, null, null], totalCount: 7, failedCount: 0}; showColors: true
}
});
expect(done).toBeTruthy();
});
}); });
reporter.specDone({status: "passed"});
expect(out.getOutput()).toEqual("\033[32m.\033[0m");
});
it("does not report a disabled spec", function() {
var reporter = new jasmine.ConsoleReporter({
print: out.print,
showColors: true
});
reporter.specDone({status: 'disabled'});
expect(out.getOutput()).toEqual("");
});
it("reports a failing spec as an 'F'", function() {
var reporter = new jasmine.ConsoleReporter({
print: out.print,
showColors: true
});
reporter.specDone({status: 'failed'});
expect(out.getOutput()).toEqual("\033[31mF\033[0m");
}); });
}); });
}); });
-27
View File
@@ -1,27 +0,0 @@
describe("base.js", function() {
describe("jasmine.MessageResult", function() {
it("#toString should pretty-print and concatenate each part of the message", function() {
var values = ["log", "message", 123, {key: "value"}, "FTW!"];
var messageResult = new jasmine.MessageResult(values);
expect(messageResult.toString()).toEqual("log message 123 { key : 'value' } FTW!");
});
});
describe("jasmine.log", function() {
it("should accept n arguments", function() {
spyOn(jasmine.getEnv().currentSpec, 'log');
jasmine.log(1, 2, 3);
expect(jasmine.getEnv().currentSpec.log).toHaveBeenCalledWith(1, 2, 3);
});
});
describe("jasmine.getGlobal", function() {
it("should return the global object", function() {
var globalObject = (function() {
return this;
})();
expect(jasmine.getGlobal()).toBe(globalObject);
});
});
});
+294
View File
@@ -0,0 +1,294 @@
describe("Clock", function() {
it("calls the global setTimeout directly if Clock is not installed", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
global = { setTimeout: setTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.setTimeout(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
expect(setTimeout).toHaveBeenCalledWith(delayedFn, 0);
});
it("schedules the delayed function with the fake timer", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
scheduleFunction = jasmine.createSpy('scheduleFunction'),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setTimeout: setTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.install();
clock.setTimeout(delayedFn, 0, 'a', 'b');
expect(setTimeout).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
});
it("returns an id for the delayed function", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
scheduleId = 123,
scheduleFunction = jasmine.createSpy('scheduleFunction').andReturn(scheduleId),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setTimeout: setTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler),
timeoutId;
clock.install();
timeoutId = clock.setTimeout(delayedFn, 0);
expect(timeoutId).toEqual(123);
});
it("calls the global clearTimeout directly if Clock is not installed", function() {
var clearTimeout = jasmine.createSpy('clearTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
global = { clearTimeout: clearTimeout },
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.clearTimeout(123);
expect(clearTimeout).toHaveBeenCalledWith(123);
});
it("clears the scheduled function with the scheduler", function() {
var clearTimeout = jasmine.createSpy('clearTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
global = { setTimeout: clearTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.install();
clock.clearTimeout(123);
expect(clearTimeout).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
});
it("calls the global setInterval directly if Clock is not installed", function() {
var setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
global = { setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.setInterval(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
expect(setInterval).toHaveBeenCalledWith(delayedFn, 0);
});
it("schedules the delayed function with the fake timer", function() {
var setInterval = jasmine.createSpy('setInterval'),
scheduleFunction = jasmine.createSpy('scheduleFunction'),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.install();
clock.setInterval(delayedFn, 0, 'a', 'b');
expect(setInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
});
it("returns an id for the delayed function", function() {
var setInterval = jasmine.createSpy('setInterval'),
scheduleId = 123,
scheduleFunction = jasmine.createSpy('scheduleFunction').andReturn(scheduleId),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler),
intervalId;
clock.install();
intervalId = clock.setInterval(delayedFn, 0);
expect(intervalId).toEqual(123);
});
it("calls the global clearInterval directly if Clock is not installed", function() {
var clearInterval = jasmine.createSpy('clearInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearInterval']),
global = { clearInterval: clearInterval },
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.clearInterval(123);
expect(clearInterval).toHaveBeenCalledWith(123);
});
it("clears the scheduled function with the scheduler", function() {
var clearInterval = jasmine.createSpy('clearInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
global = { setInterval: clearInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.install();
clock.clearInterval(123);
expect(clearInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
});
it("gives you a friendly reminder if the Clock is not installed and you tick", function() {
var clock = new jasmine.Clock({}, jasmine.createSpyObj('delayedFunctionScheduler', ['tick']));
expect(function() {
clock.tick(50);
}).toThrow();
});
it("can be uninstalled", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction', 'tick', 'reset']),
global = { setTimeout: setTimeout, setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new jasmine.Clock(global, delayedFunctionScheduler);
clock.install();
clock.setTimeout(delayedFn, 0);
expect(setTimeout).not.toHaveBeenCalled();
clock.setInterval(delayedFn, 0);
expect(setInterval).not.toHaveBeenCalled();
expect(function() {
clock.tick(0);
}).not.toThrow();
clock.uninstall();
expect(delayedFunctionScheduler.reset).toHaveBeenCalled();
clock.setTimeout(delayedFn, 0);
expect(setTimeout).toHaveBeenCalled();
clock.setInterval(delayedFn, 0);
expect(setInterval).toHaveBeenCalled();
expect(function() {
clock.tick(0);
}).toThrow();
});
it("on IE < 9, fails if extra args are passed to fake clock", function() {
//fail, because this would break in IE9.
var setTimeout = jasmine.createSpy('setTimeout'),
setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
fn = jasmine.createSpy('fn'),
global = { setTimeout: setTimeout, setInterval: setInterval },
clock = new jasmine.Clock(global, delayedFunctionScheduler);
setTimeout.apply = null;
setInterval.apply = null;
clock.install();
clock.setTimeout(fn, 0);
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, []);
expect(function() {
clock.setTimeout(fn, 0, 'extra');
}).toThrow();
clock.setInterval(fn, 0);
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(fn, 0, [], true);
expect(function() {
clock.setInterval(fn, 0, 'extra');
}).toThrow();
});
});
describe("Clock (acceptance)", function() {
it("can run setTimeouts/setIntervals synchronously", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFn3 = jasmine.createSpy('delayedFn3'),
recurring1 = jasmine.createSpy('recurring1'),
delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
clock = new jasmine.Clock({setTimeout: setTimeout}, delayedFunctionScheduler);
clock.install();
clock.setTimeout(delayedFn1, 0, 'some', 'arg');
var intervalId = clock.setInterval(recurring1, 50, 'some', 'other', 'args');
clock.setTimeout(delayedFn2, 100);
clock.setTimeout(delayedFn3, 200);
expect(delayedFn1).not.toHaveBeenCalled();
expect(delayedFn2).not.toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
clock.tick(0);
expect(delayedFn1).toHaveBeenCalledWith('some', 'arg');
expect(delayedFn2).not.toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
clock.tick(50);
expect(recurring1).toHaveBeenCalledWith('some', 'other', 'args');
expect(recurring1.callCount).toBe(1);
expect(delayedFn2).not.toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
clock.tick(50);
expect(recurring1.callCount).toBe(2);
expect(delayedFn2).toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
clock.tick(100);
expect(recurring1.callCount).toBe(4);
expect(delayedFn3).toHaveBeenCalled();
clock.clearInterval(intervalId);
clock.tick(50);
expect(recurring1.callCount).toBe(4);
});
it("can clear a previously set timeout", function() {
var clearedFn = jasmine.createSpy('clearedFn'),
delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
clock = new jasmine.Clock({setTimeout: function() {}}, delayedFunctionScheduler),
timeoutId;
clock.install();
timeoutId = clock.setTimeout(clearedFn, 100);
expect(clearedFn).not.toHaveBeenCalled();
clock.clearTimeout(timeoutId);
clock.tick(100);
expect(clearedFn).not.toHaveBeenCalled();
});
it("correctly schedules functions after the Clock has advanced", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFunctionScheduler = new jasmine.DelayedFunctionScheduler(),
clock = new jasmine.Clock({setTimeout: function(){}}, delayedFunctionScheduler);
clock.install();
clock.tick(100);
clock.setTimeout(delayedFn1, 10, ['some', 'arg']);
clock.tick(5);
expect(delayedFn1).not.toHaveBeenCalled();
clock.tick(5);
expect(delayedFn1).toHaveBeenCalled();
});
});
+96 -97
View File
@@ -1,97 +1,96 @@
describe("Custom Matchers", function() { ////TODO: matchers should be add-able to the env, not to the spec.
var env; //describe("Custom Matchers", function() {
var fakeTimer; // var env;
// var fakeTimer;
beforeEach(function() { //
env = new jasmine.Env(); // beforeEach(function() {
env.updateInterval = 0; // env = new jasmine.Env();
}); // env.updateInterval = 0;
// });
it("should be easy to add more matchers local to a spec, suite, etc.", function() { //
var spec1, spec2, spec1Matcher, spec2Matcher; // it("should be easy to add more matchers local to a spec, suite, etc.", function() {
var suite = env.describe('some suite', function() { // var spec1, spec2, spec1Matcher, spec2Matcher;
env.beforeEach(function() { // var suite = env.describe('some suite', function() {
this.addMatchers({ // env.beforeEach(function() {
matcherForSuite: function(expected) { // this.addMatchers({
this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected; // matcherForSuite: function(expected) {
return true; // this.message = "matcherForSuite: actual: " + this.actual + "; expected: " + expected;
} // return true;
}); // }
}); // });
// });
spec1 = env.it('spec with an expectation').runs(function () { //
this.addMatchers({ // spec1 = env.it('spec with an expectation').runs(function () {
matcherForSpec: function(expected) { // this.addMatchers({
this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected; // matcherForSpec: function(expected) {
return true; // this.message = "matcherForSpec: actual: " + this.actual + "; expected: " + expected;
} // return true;
}); // }
spec1Matcher = this.expect("xxx"); // });
}); // spec1Matcher = this.expect("xxx");
// });
spec2 = env.it('spec with failing expectation').runs(function () { //
spec2Matcher = this.expect("yyy"); // spec2 = env.it('spec with failing expectation').runs(function () {
}); // spec2Matcher = this.expect("yyy");
}); // });
// });
suite.execute(); //
// suite.execute();
spec1Matcher.matcherForSuite("expected"); //
expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected"); // spec1Matcher.matcherForSuite("expected");
spec1Matcher.matcherForSpec("expected"); // expect(spec1Matcher.message).toEqual("matcherForSuite: actual: xxx; expected: expected");
expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected"); // spec1Matcher.matcherForSpec("expected");
// expect(spec1Matcher.message).toEqual("matcherForSpec: actual: xxx; expected: expected");
spec2Matcher.matcherForSuite("expected"); //
expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected"); // spec2Matcher.matcherForSuite("expected");
expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined); // expect(spec2Matcher.message).toEqual("matcherForSuite: actual: yyy; expected: expected");
}); // expect(spec2Matcher.matcherForSpec).toBe(jasmine.undefined);
// });
it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() { //
var spec; // it("should generate messages with the same rules as for regular matchers when this.report() is not called", function() {
var suite = env.describe('some suite', function() { // var spec;
spec = env.it('spec with an expectation').runs(function () { // var suite = env.describe('some suite', function() {
this.addMatchers({ // spec = env.it('spec with an expectation').runs(function () {
toBeTrue: function() { // this.addMatchers({
return this.actual === true; // toBeTrue: function() {
} // return this.actual === true;
}); // }
this.expect(true).toBeTrue(); // });
this.expect(false).toBeTrue(); // this.expect(true).toBeTrue();
}); // this.expect(false).toBeTrue();
}); // });
// });
suite.execute(); //
var passResult = new jasmine.ExpectationResult({passed: true, matcherName: 'toBeTrue', // suite.execute();
actual: true, expected: jasmine.undefined, message: "Passed." }); //
var failResult = new jasmine.ExpectationResult({passed: false, matcherName: 'toBeTrue', // var results = spec.results().getItems();
actual: false, expected: jasmine.undefined, message: "Expected false to be true." }); // expect(results[0].message).toEqual("Passed.");
failResult.trace = jasmine.any(Object); // expect(results[1].message).toEqual("Expected false to be true.");
expect(spec.results().getItems()).toEqual([passResult, failResult]); // });
}); //
// it("should pass args", function() {
it("should pass args", function() { // var matcherCallArgs = [];
var matcherCallArgs = []; // var spec;
var spec; // var suite = env.describe('some suite', function() {
var suite = env.describe('some suite', function() { // spec = env.it('spec with an expectation').runs(function () {
spec = env.it('spec with an expectation').runs(function () { // this.addMatchers({
this.addMatchers({ // toBeTrue: function() {
toBeTrue: function() { // matcherCallArgs.push(jasmine.util.argsToArray(arguments));
matcherCallArgs.push(jasmine.util.argsToArray(arguments)); // return this.actual === true;
return this.actual === true; // }
} // });
}); // this.expect(true).toBeTrue();
this.expect(true).toBeTrue(); // this.expect(false).toBeTrue('arg');
this.expect(false).toBeTrue('arg'); // this.expect(true).toBeTrue('arg1', 'arg2');
this.expect(true).toBeTrue('arg1', 'arg2'); // });
}); // });
}); //
// suite.execute();
suite.execute(); // var results = spec.results().getItems();
var results = spec.results().getItems(); // expect(results[0].expected).toEqual(jasmine.undefined);
expect(results[0].expected).toEqual(jasmine.undefined); // expect(results[1].expected).toEqual('arg');
expect(results[1].expected).toEqual('arg'); // expect(results[2].expected).toEqual(['arg1', 'arg2']);
expect(results[2].expected).toEqual(['arg1', 'arg2']); //
// expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]);
expect(matcherCallArgs).toEqual([[], ['arg'], ['arg1', 'arg2']]); // });
}); //});
});
+142
View File
@@ -0,0 +1,142 @@
describe("DelayedFunctionScheduler", function() {
it("schedules a function for later execution", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(0);
expect(fn).toHaveBeenCalled();
});
it("optionally passes params to scheduled functions", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0, ['foo', 'bar']);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(0);
expect(fn).toHaveBeenCalledWith('foo', 'bar');
});
it("scheduled fns can optionally reoccur", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 20, [], true);
expect(fn).not.toHaveBeenCalled();
scheduler.tick(20);
expect(fn.callCount).toBe(1);
scheduler.tick(40);
expect(fn.callCount).toBe(3);
scheduler.tick(21);
expect(fn.callCount).toBe(4);
});
it("increments scheduled fns ids unless one is passed", function() {
var scheduler = new jasmine.DelayedFunctionScheduler();
expect(scheduler.scheduleFunction(function() {
}, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() {
}, 0)).toBe(2);
expect(scheduler.scheduleFunction(function() {
}, 0, [], false, 123)).toBe(123);
expect(scheduler.scheduleFunction(function() {
}, 0)).toBe(3);
});
it("#removeFunctionWithId removes a previously scheduled function with a given id", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, 0);
expect(fn).not.toHaveBeenCalled();
scheduler.removeFunctionWithId(timeoutKey);
scheduler.tick(0);
expect(fn).not.toHaveBeenCalled();
});
it("reset removes scheduled functions", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
scheduler.scheduleFunction(fn, 0);
expect(fn).not.toHaveBeenCalled();
scheduler.reset();
scheduler.tick(0);
expect(fn).not.toHaveBeenCalled();
});
it("reset resets the returned ids", function() {
var scheduler = new jasmine.DelayedFunctionScheduler();
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
scheduler.reset();
expect(scheduler.scheduleFunction(function() { }, 0)).toBe(1);
expect(scheduler.scheduleFunction(function() { }, 0, [], false, 123)).toBe(123);
});
it("reset resets the current tick time", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn');
expect(fn).not.toHaveBeenCalled();
scheduler.tick(15);
scheduler.reset();
scheduler.scheduleFunction(fn, 20, [], false, 1, 20);
scheduler.tick(5);
expect(fn).not.toHaveBeenCalled();
});
it("executes recurring functions interleaved with regular functions in the correct order", function() {
var scheduler = new jasmine.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
recurringCallCount = 0,
recurring = jasmine.createSpy('recurring').andCallFake(function() {
recurringCallCount++;
if (recurringCallCount < 5) {
expect(fn).not.toHaveBeenCalled();
}
});
scheduler.scheduleFunction(recurring, 10, [], true);
scheduler.scheduleFunction(fn, 50);
scheduler.tick(60);
expect(recurring).toHaveBeenCalled();
expect(recurring.callCount).toBe(6);
expect(fn).toHaveBeenCalled();
});
});
+191 -13
View File
@@ -1,12 +1,13 @@
describe("jasmine.Env", function() { // TODO: Fix these unit tests!
describe("Env", function() {
var env; var env;
beforeEach(function() { beforeEach(function() {
env = new jasmine.Env(); env = new jasmine.Env();
env.updateInterval = 0; env.updateInterval = 0;
}); });
describe('ids', function () { describe('ids', function() {
it('nextSpecId should return consecutive integers, starting at 0', function () { it('nextSpecId should return consecutive integers, starting at 0', function() {
expect(env.nextSpecId()).toEqual(0); expect(env.nextSpecId()).toEqual(0);
expect(env.nextSpecId()).toEqual(1); expect(env.nextSpecId()).toEqual(1);
expect(env.nextSpecId()).toEqual(2); expect(env.nextSpecId()).toEqual(2);
@@ -17,21 +18,21 @@ describe("jasmine.Env", function() {
var fakeReporter; var fakeReporter;
beforeEach(function() { beforeEach(function() {
fakeReporter = jasmine.createSpyObj("fakeReporter", ["log"]); fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["jasmineStarted"]);
}); });
describe('version', function () { describe('version', function() {
var oldVersion; var oldVersion;
beforeEach(function () { beforeEach(function() {
oldVersion = jasmine.version_; oldVersion = jasmine.version_;
}); });
afterEach(function () { afterEach(function() {
jasmine.version_ = oldVersion; jasmine.version_ = oldVersion;
}); });
it('should raise an error if version is not set', function () { it('should raise an error if version is not set', function() {
jasmine.version_ = null; jasmine.version_ = null;
var exception; var exception;
try { try {
@@ -79,8 +80,8 @@ describe("jasmine.Env", function() {
it("should allow reporters to be registered", function() { it("should allow reporters to be registered", function() {
env.addReporter(fakeReporter); env.addReporter(fakeReporter);
env.reporter.log("message"); env.reporter.jasmineStarted();
expect(fakeReporter.log).toHaveBeenCalledWith("message"); expect(fakeReporter.jasmineStarted).toHaveBeenCalled();
}); });
}); });
@@ -138,8 +139,12 @@ describe("jasmine.Env", function() {
describe("even if there are several", function() { describe("even if there are several", function() {
beforeEach(function() { beforeEach(function() {
env.addEqualityTester(function(a, b) { return jasmine.undefined; }); env.addEqualityTester(function(a, b) {
env.addEqualityTester(function(a, b) { return jasmine.undefined; }); return jasmine.undefined;
});
env.addEqualityTester(function(a, b) {
return jasmine.undefined;
});
}); });
it("should use normal equality rules", function() { it("should use normal equality rules", function() {
@@ -151,9 +156,182 @@ describe("jasmine.Env", function() {
it("should evaluate custom equality testers in the order they are declared", function() { it("should evaluate custom equality testers in the order they are declared", function() {
isEqual = false; isEqual = false;
env.addEqualityTester(function(a, b) { return true; }); env.addEqualityTester(function(a, b) {
return true;
});
expect(env.equals_('abc', 'abc')).toBeFalsy(); expect(env.equals_('abc', 'abc')).toBeFalsy();
}); });
}); });
}); });
}); });
describe("Env (integration)", function() {
it("Suites execute as expected (no nesting)", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("A Suite", function() {
env.it("with a spec", function() {
calls.push("with a spec");
});
env.it("and another spec", function() {
calls.push("and another spec");
});
});
env.execute();
expect(calls).toEqual([
"with a spec",
"and another spec"
]);
});
it("Nested Suites execute as expected", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.execute();
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec'
]);
});
it("Multiple top-level Suites execute as expected", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.describe("Another outer suite", function() {
env.it("a 2nd outer spec", function() {
calls.push('a 2nd outer spec')
});
});
env.execute();
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec',
'a 2nd outer spec'
]);
});
it("Mock clock can be installed and used in tests", function() {
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
delayedFunctionForMockClock = jasmine.createSpy('delayedFunctionForMockClock'),
env = new jasmine.Env({global: { setTimeout: globalSetTimeout }});
env.describe("tests", function() {
env.it("test with mock clock", function() {
env.clock.install();
env.clock.setTimeout(delayedFunctionForMockClock, 100);
env.clock.tick(100);
});
env.it("test without mock clock", function() {
env.clock.setTimeout(delayedFunctionForGlobalClock, 100);
});
});
expect(globalSetTimeout).not.toHaveBeenCalled();
expect(delayedFunctionForMockClock).not.toHaveBeenCalled();
env.execute();
expect(delayedFunctionForMockClock).toHaveBeenCalled();
expect(globalSetTimeout).toHaveBeenCalledWith(delayedFunctionForGlobalClock, 100);
});
it("should report as expected", function() {
var env = new jasmine.Env(),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("A Suite", function() {
env.it("with a top level spec", function() {
env.expect(true).toBe(true);
});
env.describe("with a nested suite", function() {
env.xit("with a disabled spec", function() {
env.expect(true).toBe(true);
});
env.it("with a spec", function() {
env.expect(true).toBe(false);
});
});
});
env.execute();
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
totalSpecsDefined: 3
});
var suiteResult = reporter.suiteStarted.calls[0].args[0];
expect(suiteResult.description).toEqual("A Suite");
expect(reporter.jasmineDone).toHaveBeenCalled();
});
it("should be possible to get full name from a spec", function() {
var env = new jasmine.Env({global: { setTimeout: setTimeout }}),
topLevelSpec, nestedSpec, doublyNestedSpec;
env.describe("my tests", function() {
topLevelSpec = env.it("are sometimes top level", function() {
});
env.describe("are sometimes", function() {
nestedSpec = env.it("singly nested", function() {
});
env.describe("even", function() {
doublyNestedSpec = env.it("doubly nested", function() {
});
});
});
});
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level.");
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");
});
});
+26
View File
@@ -0,0 +1,26 @@
describe("ExceptionFormatter", function() {
it('formats Firefox exception messages', function() {
var sampleFirefoxException = {
fileName: 'foo.js',
line: '1978',
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
},
message = jasmine.exceptionMessageFor(sampleFirefoxException);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
});
it('formats Webkit exception messages', function() {
var sampleWebkitException = {
sourceURL: 'foo.js',
lineNumber: '1978',
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
},
message = jasmine.exceptionMessageFor(sampleWebkitException);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar in foo.js (line 1978)');
});
});
+13 -124
View File
@@ -6,34 +6,9 @@ describe('Exceptions:', function() {
env.updateInterval = 0; env.updateInterval = 0;
}); });
it('jasmine.formatException formats Firefox exception messages as expected', function() {
var sampleFirefoxException = {
fileName: 'foo.js',
line: '1978',
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
};
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
expect(jasmine.util.formatException(sampleFirefoxException)).toEqual(expected);
});
it('jasmine.formatException formats Webkit exception messages as expected', function() {
var sampleWebkitException = {
sourceURL: 'foo.js',
lineNumber: '1978',
message: 'you got your foo in my bar',
name: 'A Classic Mistake'
};
var expected = 'A Classic Mistake: you got your foo in my bar in foo.js (line 1978)';
expect(jasmine.util.formatException(sampleWebkitException)).toEqual(expected);
});
describe('with break on exception', function() { describe('with break on exception', function() {
it('should not catch the exception', function() { it('should not catch the exception', function() {
env.catchExceptions(false);
var suite = env.describe('suite for break on exceptions', function() { var suite = env.describe('suite for break on exceptions', function() {
env.it('should break when an exception is thrown', function() { env.it('should break when an exception is thrown', function() {
throw new Error('I should hit a breakpoint!'); throw new Error('I should hit a breakpoint!');
@@ -42,16 +17,11 @@ describe('Exceptions:', function() {
var runner = env.currentRunner(); var runner = env.currentRunner();
var dont_change = 'I will never change!'; var dont_change = 'I will never change!';
var oldCatch = jasmine.CATCH_EXCEPTIONS;
jasmine.CATCH_EXCEPTIONS = false;
try { try {
suite.execute(); suite.execute();
dont_change = 'oops I changed'; dont_change = 'oops I changed';
} }
catch (e) {} catch (e) {}
finally {
jasmine.CATCH_EXCEPTIONS = oldCatch;
}
expect(dont_change).toEqual('I will never change!'); expect(dont_change).toEqual('I will never change!');
}); });
@@ -59,117 +29,36 @@ describe('Exceptions:', function() {
describe("with catch on exception", function() { describe("with catch on exception", function() {
it('should handle exceptions thrown, but continue', function() { it('should handle exceptions thrown, but continue', function() {
var fakeTimer = new jasmine.FakeTimer(); var ranSecondTest = false,
env.setTimeout = fakeTimer.setTimeout; suite = env.describe('Suite for handles exceptions', function () {
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
//we run two exception tests to make sure we continue after throwing an exception
var suite = env.describe('Suite for handles exceptions', function () {
env.it('should be a test that fails because it throws an exception', function() { env.it('should be a test that fails because it throws an exception', function() {
throw new Error('fake error 1'); throw new Error();
}); });
env.it('should be another test that fails because it throws an exception', function() {
this.runs(function () {
throw new Error('fake error 2');
});
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.it('should be a passing test that runs after exceptions are thrown', function() {
this.expect(true).toEqual(true);
});
env.it('should be another test that fails because it throws an exception after a wait', function() {
this.runs(function () {
var foo = 'foo';
});
this.waits(250);
this.runs(function () {
throw new Error('fake error 3');
});
});
env.it('should be a passing test that runs after exceptions are thrown from a async test', function() { env.it('should be a passing test that runs after exceptions are thrown from a async test', function() {
this.expect(true).toEqual(true); ranSecondTest = true;
}); });
}); });
var runner = env.currentRunner();
suite.execute(); suite.execute();
fakeTimer.tick(2500); expect(ranSecondTest).toBe(true);
var suiteResults = suite.results();
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
//
expect(specResults.length).toEqual(5);
expect(specResults[0].passed()).toMatch(false);
var blockResults = specResults[0].getItems();
expect(blockResults[0].passed()).toEqual(false);
expect(blockResults[0].message).toMatch(/fake error 1/);
expect(specResults[1].passed()).toEqual(false);
blockResults = specResults[1].getItems();
expect(blockResults[0].passed()).toEqual(false);
expect(blockResults[0].message).toMatch(/fake error 2/);
expect(blockResults[1].passed()).toEqual(true);
expect(specResults[2].passed()).toEqual(true);
expect(specResults[3].passed()).toEqual(false);
blockResults = specResults[3].getItems();
expect(blockResults[0].message).toMatch(/fake error 3/);
expect(specResults[4].passed()).toEqual(true);
}); });
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () { it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
var suite = env.describe("a top level describe block that throws an exception", function () { var ranSecondDescribe = false, suite, suite2, runner = env.currentRunner();
suite = env.describe("a suite that throws an exception", function () {
env.it("is a test that should pass", function () { env.it("is a test that should pass", function () {
this.expect(true).toEqual(true); this.expect(true).toEqual(true);
}); });
throw new Error("top level error"); throw new Error("top level error");
}); });
suite2 = env.describe("a suite that doesn't throw an exception", function () {
suite.execute(); ranSecondDescribe = true;
var suiteResults = suite.results();
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
expect(specResults.length).toEqual(2);
expect(specResults[1].description).toMatch(/encountered a declaration exception/);
});
it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
var suite = env.describe("a top level describe", function () {
env.describe("a mid-level describe that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
throw new Error("a mid-level error");
});
}); });
suite.execute(); runner.execute();
var suiteResults = suite.results(); expect(ranSecondDescribe).toBe(true);
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
expect(specResults.length).toEqual(1);
var nestedSpecResults = specResults[0].getItems();
expect(nestedSpecResults.length).toEqual(2);
expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
}); });
}); });
}); });
+48
View File
@@ -0,0 +1,48 @@
describe("buildExpectationResult", function() {
it("defaults to passed", function() {
var result = jasmine.buildExpectationResult({passed: 'some-value'});
expect(result.passed).toBe('some-value');
});
it("has a type of expect", function() {
var result = jasmine.buildExpectationResult({});
expect(result.type).toBe('expect');
});
it("message defaults to Passed for passing specs", function() {
var result = jasmine.buildExpectationResult({passed: true, message: 'some-value'});
expect(result.message).toBe('Passed.');
});
it("message returns the message for failing specs", function() {
var result = jasmine.buildExpectationResult({passed: false, message: 'some-value'});
expect(result.message).toBe('some-value');
});
it("trace passes trace if exists", function() {
var result = jasmine.buildExpectationResult({trace: 'some-value'});
expect(result.trace).toBe('some-value');
});
it("trace returns a new error if trace is falsy", function() {
var result = jasmine.buildExpectationResult({trace: false});
expect(result.trace).toEqual(jasmine.any(Error));
});
it("matcherName returns passed matcherName", function() {
var result = jasmine.buildExpectationResult({matcherName: 'some-value'});
expect(result.matcherName).toBe('some-value');
});
it("expected returns passed expected", function() {
var result = jasmine.buildExpectationResult({expected: 'some-value'});
expect(result.expected).toBe('some-value');
});
it("actual returns passed actual", function() {
var result = jasmine.buildExpectationResult({actual: 'some-value'});
expect(result.actual).toBe('some-value');
});
});
+106 -37
View File
@@ -1,6 +1,6 @@
describe('jasmine.jsApiReporter', function() { xdescribe('JsApiReporter (integration specs)', function() {
describe('results', function () { describe('results', function() {
var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results; var reporter, spec1, spec2;
var env; var env;
var suite, nestedSuite, nestedSpec; var suite, nestedSuite, nestedSpec;
@@ -24,34 +24,24 @@ describe('jasmine.jsApiReporter', function() {
}); });
}); });
spec3 = env.it("spec 3", function() {
this.log('some debug message');
});
}); });
reporter = new jasmine.JsApiReporter(); reporter = new jasmine.JsApiReporter(jasmine);
env.addReporter(reporter); env.addReporter(reporter);
env.execute(); env.execute();
expectedSpec1Results = {
messages: spec1.results().getItems(),
result: "passed"
};
expectedSpec2Results = {
messages: spec2.results().getItems(),
result: "failed"
};
}); });
it('resultForSpec() should return the result for the given spec', function () { it('results() should return a hash of all results, indexed by spec id', function() {
expect(reporter.resultsForSpec(spec1.id)).toEqual(expectedSpec1Results); var expectedSpec1Results = {
expect(reporter.resultsForSpec(spec2.id)).toEqual(expectedSpec2Results); result: "passed"
}); },
expectedSpec2Results = {
it('results() should return a hash of all results, indexed by spec id', function () { result: "failed"
expect(reporter.results()[spec1.id]).toEqual(expectedSpec1Results); };
expect(reporter.results()[spec2.id]).toEqual(expectedSpec2Results); expect(reporter.results()[spec1.id].result).toEqual('passed');
expect(reporter.results()[spec2.id].result).toEqual('failed');
}); });
it("should return nested suites as children of their parents", function() { it("should return nested suites as children of their parents", function() {
@@ -65,7 +55,6 @@ describe('jasmine.jsApiReporter', function() {
{ id: 2, name: 'nested spec', type: 'spec', children: [ ] } { id: 2, name: 'nested spec', type: 'spec', children: [ ] }
] ]
}, },
{ id: 3, name: 'spec 3', type: 'spec', children: [ ] }
] ]
} }
]); ]);
@@ -76,12 +65,7 @@ describe('jasmine.jsApiReporter', function() {
var result = reporter.results()[spec1.id]; var result = reporter.results()[spec1.id];
var summarizedResult = reporter.summarizeResult_(result); var summarizedResult = reporter.summarizeResult_(result);
expect(summarizedResult.result).toEqual('passed'); expect(summarizedResult.result).toEqual('passed');
expect(summarizedResult.messages.length).toEqual(1); expect(summarizedResult.messages.length).toEqual(0);
expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message);
expect(summarizedResult.messages[0].passed).toBeTruthy();
expect(summarizedResult.messages[0].type).toEqual('expect');
expect(summarizedResult.messages[0].text).toBeUndefined();
expect(summarizedResult.messages[0].trace.stack).toBeUndefined();
}); });
it("should have a stack trace for failing specs", function() { it("should have a stack trace for failing specs", function() {
@@ -91,13 +75,98 @@ describe('jasmine.jsApiReporter', function() {
expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack); expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack);
}); });
it("should have messages for specs with messages", function() {
var result = reporter.results()[spec3.id];
var summarizedResult = reporter.summarizeResult_(result);
expect(summarizedResult.result).toEqual('passed');
expect(summarizedResult.messages[0].type).toEqual('log');
expect(summarizedResult.messages[0].text).toEqual('some debug message');
});
}); });
}); });
}); });
describe("JsApiReporter", function() {
it("knows when a full environment is started", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
reporter.jasmineStarted();
expect(reporter.started).toBe(true);
expect(reporter.finished).toBe(false);
});
it("knows when a full environment is done", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
reporter.jasmineStarted();
reporter.jasmineDone();
expect(reporter.finished).toBe(true);
});
it("defaults to 'loaded' status", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.status()).toEqual('loaded');
});
it("reports 'started' when Jasmine has started", function() {
var reporter = new jasmine.JsApiReporter();
reporter.jasmineStarted();
expect(reporter.status()).toEqual('started');
});
it("reports 'done' when Jasmine is done", function() {
var reporter = new jasmine.JsApiReporter();
reporter.jasmineDone();
expect(reporter.status()).toEqual('done');
});
it("tracks a suite", function() {
var reporter = new jasmine.JsApiReporter();
reporter.suiteStarted({
id: 123,
description: "A suite"
});
var suites = reporter.suites();
expect(suites).toEqual({123: {id: 123, description: "A suite"}});
reporter.suiteDone({
id: 123,
description: "A suite",
status: 'passed'
});
expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
});
it("tracks a spec", function() {
var reporter = new jasmine.JsApiReporter();
reporter.specStarted({
id: 123,
description: "A spec"
});
var specs = reporter.specs();
expect(specs).toEqual({123: {id: 123, description: "A spec"}});
reporter.specDone({
id: 123,
description: "A spec",
status: 'passed'
});
expect(specs).toEqual({123: {id: 123, description: "A spec", status: 'passed'}});
});
});
+69 -69
View File
@@ -9,14 +9,14 @@ describe("jasmine.Matchers", function() {
spec = env.it("spec", function() { spec = env.it("spec", function() {
}); });
}); });
spyOn(spec, 'addMatcherResult'); spyOn(spec, 'addExpectationResult');
this.addMatchers({ addMatchers({
toPass: function() { toPass: function() {
return lastResult().passed(); return lastResult().passed;
}, },
toFail: function() { toFail: function() {
return !lastResult().passed(); return !lastResult().passed;
} }
}); });
}); });
@@ -26,7 +26,7 @@ describe("jasmine.Matchers", function() {
} }
function lastResult() { function lastResult() {
return spec.addMatcherResult.mostRecentCall.args[0]; return spec.addExpectationResult.mostRecentCall.args[1];
} }
function catchException(fn) { function catchException(fn) {
@@ -82,7 +82,7 @@ describe("jasmine.Matchers", function() {
expect((match(/[abc]/gm).toNotEqual(/1/i))).toPass(); expect((match(/[abc]/gm).toNotEqual(/1/i))).toPass();
// only test if the browser supports the sticky option on a regExp see pull #234 // only test if the browser supports the sticky option on a regExp see pull #234
if (typeof RegExp.prototype.sticky !== 'undefined') { if (RegExp.prototype.sticky !== undefined) {
var sticky_regexp = new RegExp("[abc]", "y"); var sticky_regexp = new RegExp("[abc]", "y");
expect((match(sticky_regexp).toEqual(/1/i))).toFail(); expect((match(sticky_regexp).toEqual(/1/i))).toFail();
expect((match(sticky_regexp).toNotEqual(/1/i))).toPass(); expect((match(sticky_regexp).toNotEqual(/1/i))).toPass();
@@ -98,7 +98,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toEqual"); expect(result.matcherName).toEqual("toEqual");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
@@ -113,7 +113,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toNotEqual"); expect(result.matcherName).toEqual("toNotEqual");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(str)); expect(result.message).toMatch(jasmine.pp(str));
expect(result.message).toMatch('not'); expect(result.message).toMatch('not');
expect(result.expected).toEqual(str); expect(result.expected).toEqual(str);
@@ -142,7 +142,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBe"); expect(result.matcherName).toEqual("toBe");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
@@ -157,7 +157,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toNotBe"); expect(result.matcherName).toEqual("toNotBe");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(str); expect(result.message).toMatch(str);
expect(result.expected).toEqual(str); expect(result.expected).toEqual(str);
expect(result.actual).toEqual(str); expect(result.actual).toEqual(str);
@@ -186,7 +186,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toMatch"); expect(result.matcherName).toEqual("toMatch");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch(expected.toString()); expect(result.message).toMatch(expected.toString());
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
@@ -202,7 +202,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toMatch"); expect(result.matcherName).toEqual("toMatch");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to match 'b'."); expect(result.message).toEqual("Expected 'a' to match 'b'.");
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -217,7 +217,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toNotMatch"); expect(result.matcherName).toEqual("toNotMatch");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to not match /a/."); expect(result.message).toEqual("Expected 'a' to not match /a/.");
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -231,7 +231,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toNotMatch"); expect(result.matcherName).toEqual("toNotMatch");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected 'a' to not match 'a'."); expect(result.message).toEqual("Expected 'a' to not match 'a'.");
expect(result.expected).toEqual(str); expect(result.expected).toEqual(str);
expect(result.actual).toEqual(str); expect(result.actual).toEqual(str);
@@ -249,7 +249,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeDefined"); expect(result.matcherName).toEqual("toBeDefined");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toEqual('Expected undefined to be defined.'); expect(result.message).toEqual('Expected undefined to be defined.');
expect(result.actual).toEqual(jasmine.undefined); expect(result.actual).toEqual(jasmine.undefined);
}); });
@@ -273,7 +273,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeNull"); expect(result.matcherName).toEqual("toBeNull");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null'); expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -287,34 +287,34 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeNull"); expect(result.matcherName).toEqual("toBeNull");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('null'); expect(result.message).toMatch('null');
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
}); });
it("toBeNaN", function() { it("toBeNaN", function() {
expect(match(Number.NaN).toBeNaN()).toPass(); expect(match(Number.NaN).toBeNaN()).toPass();
expect(match(0).toBeNaN()).toFail(); expect(match(0).toBeNaN()).toFail();
expect(match(1).toBeNaN()).toFail(); expect(match(1).toBeNaN()).toFail();
expect(match(null).toBeNaN()).toFail(); expect(match(null).toBeNaN()).toFail();
expect(match(Number.POSITIVE_INFINITY).toBeNaN()).toFail(); expect(match(Number.POSITIVE_INFINITY).toBeNaN()).toFail();
expect(match(Number.NEGATIVE_INFINITY).toBeNaN()).toFail(); expect(match(Number.NEGATIVE_INFINITY).toBeNaN()).toFail();
expect(match('NaN').toBeNaN()).toFail(); expect(match('NaN').toBeNaN()).toFail();
}); });
it("toBeNaN to build an ExpectationResult", function() { it("toBeNaN to build an ExpectationResult", function() {
var actual = 'a'; var actual = 'a';
var matcher = match(actual); var matcher = match(actual);
matcher.toBeNaN(); matcher.toBeNaN();
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeNaN"); expect(result.matcherName).toEqual("toBeNaN");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch("Expected 'a' to be NaN."); expect(result.message).toMatch("Expected 'a' to be NaN.");
expect(result.actual).toMatch(actual); expect(result.actual).toMatch(actual);
}); });
it("toBeFalsy", function() { it("toBeFalsy", function() {
expect(match(false).toBeFalsy()).toPass(); expect(match(false).toBeFalsy()).toPass();
@@ -332,7 +332,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeFalsy"); expect(result.matcherName).toEqual("toBeFalsy");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('falsy'); expect(result.message).toMatch('falsy');
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -356,7 +356,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeTruthy"); expect(result.matcherName).toEqual("toBeTruthy");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toEqual("Expected false to be truthy."); expect(result.message).toEqual("Expected false to be truthy.");
expect(result.actual).toFail(); expect(result.actual).toFail();
}); });
@@ -378,11 +378,11 @@ describe("jasmine.Matchers", function() {
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail(); expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
expect(match( expect(match(
function() { function() {
}).toEqual(jasmine.any(Object))).toFail(); }).toEqual(jasmine.any(Object))).toFail();
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass(); expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
expect(match( expect(match(
function() { function() {
}).toEqual(jasmine.any(Function))).toPass(); }).toEqual(jasmine.any(Function))).toPass();
expect(match(["a", function() { expect(match(["a", function() {
}]).toEqual(["a", jasmine.any(Function)])).toPass(); }]).toEqual(["a", jasmine.any(Function)])).toPass();
}); });
@@ -391,7 +391,7 @@ describe("jasmine.Matchers", function() {
var matcher; var matcher;
beforeEach(function () { beforeEach(function () {
matcher = { matcher = {
jasmineMatches: jasmine.createSpy("jasmineMatches") jasmineMatches: originalJasmine.createSpy("jasmineMatches")
}; };
}); });
@@ -459,7 +459,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toContain"); expect(result.matcherName).toEqual("toContain");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('contain'); expect(result.message).toMatch('contain');
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
@@ -476,7 +476,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toNotContain"); expect(result.matcherName).toEqual("toNotContain");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual)); expect(result.message).toMatch(jasmine.pp(actual));
expect(result.message).toMatch('not contain'); expect(result.message).toMatch('not contain');
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
@@ -499,7 +499,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeLessThan"); expect(result.matcherName).toEqual("toBeLessThan");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than'); expect(result.message).toMatch(jasmine.pp(actual) + ' to be less than');
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -521,7 +521,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toBeGreaterThan"); expect(result.matcherName).toEqual("toBeGreaterThan");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than'); expect(result.message).toMatch(jasmine.pp(actual) + ' to be greater than');
expect(result.message).toMatch(jasmine.pp(expected)); expect(result.message).toMatch(jasmine.pp(expected));
expect(result.actual).toEqual(actual); expect(result.actual).toEqual(actual);
@@ -608,13 +608,13 @@ describe("jasmine.Matchers", function() {
it("should match exceptions specified by message", function() { it("should match exceptions specified by message", function() {
expect(match(throwingFn).not.toThrow("Fake Error")).toFail(); expect(match(throwingFn).not.toThrow("Fake Error")).toFail();
// expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./); // expect(lastResult().message).toMatch(/Expected function not to throw Fake Error./);
expect(match(throwingFn).not.toThrow("Other Error")).toPass(); expect(match(throwingFn).not.toThrow("Other Error")).toPass();
}); });
it("should match exceptions specified by Error", function() { it("should match exceptions specified by Error", function() {
expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail(); expect(match(throwingFn).not.toThrow(new Error("Fake Error"))).toFail();
// expect(lastResult().message).toMatch("Other Error"); // expect(lastResult().message).toMatch("Other Error");
expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass(); expect(match(throwingFn).not.toThrow(new Error("Other Error"))).toPass();
}); });
}); });
@@ -645,7 +645,7 @@ describe("jasmine.Matchers", function() {
it("should fail (or pass when inverted with .not)", function() { it("should fail (or pass when inverted with .not)", function() {
expect(match( expect(match(
function() { function() {
}).toThrow()).toFail(); }).toThrow()).toFail();
expect(lastResult().message).toEqual('Expected function to throw an exception.'); expect(lastResult().message).toEqual('Expected function to throw an exception.');
}); });
}); });
@@ -668,7 +668,7 @@ describe("jasmine.Matchers", function() {
}); });
it("should use the second message when the matcher sets an array of custom messages", function() { it("should use the second message when the matcher sets an array of custom messages", function() {
spec.addMatchers({ env.addMatchers({
custom: function() { custom: function() {
this.message = function() { this.message = function() {
return ['Expected it was called.', 'Expected it wasn\'t called.']; return ['Expected it was called.', 'Expected it wasn\'t called.'];
@@ -694,7 +694,7 @@ describe("jasmine.Matchers", function() {
TestClass = { TestClass = {
normalFunction: function() { normalFunction: function() {
}, },
spyFunction: jasmine.createSpy("My spy") spyFunction: originalJasmine.createSpy("My spy")
}; };
}); });
@@ -702,23 +702,23 @@ describe("jasmine.Matchers", function() {
return function() { return function() {
expect( expect(
function() { function() {
match(TestClass.normalFunction)[methodName](); match(TestClass.normalFunction)[methodName]();
}).toThrow('Expected a spy, but got Function.'); }).toThrow('Expected a spy, but got Function.');
expect( expect(
function() { function() {
match(jasmine.undefined)[methodName](); match(jasmine.undefined)[methodName]();
}).toThrow('Expected a spy, but got undefined.'); }).toThrow('Expected a spy, but got undefined.');
expect( expect(
function() { function() {
match({some:'object'})[methodName](); match({some:'object'})[methodName]();
}).toThrow('Expected a spy, but got { some : \'object\' }.'); }).toThrow('Expected a spy, but got { some : \'object\' }.');
expect( expect(
function() { function() {
match("<b>")[methodName](); match("<b>")[methodName]();
}).toThrow('Expected a spy, but got \'<b>\'.'); }).toThrow('Expected a spy, but got \'<b>\'.');
}; };
} }
@@ -733,8 +733,8 @@ describe("jasmine.Matchers", function() {
it("should throw an exception when invoked with any arguments", function() { it("should throw an exception when invoked with any arguments", function() {
expect( expect(
function() { function() {
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument"); match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); }).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
}); });
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled')); it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalled'));
@@ -762,8 +762,8 @@ describe("jasmine.Matchers", function() {
it("should throw an exception when invoked with any arguments", function() { it("should throw an exception when invoked with any arguments", function() {
expect( expect(
function() { function() {
match(TestClass.normalFunction).wasNotCalled("unwanted argument"); match(TestClass.normalFunction).wasNotCalled("unwanted argument");
}).toThrow('wasNotCalled does not take arguments'); }).toThrow('wasNotCalled does not take arguments');
}); });
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled')); it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('wasNotCalled'));
@@ -780,7 +780,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction); var expected = match(TestClass.spyFunction);
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail(); expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
var result = lastResult(); var result = lastResult();
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.expected).toEqual(['c', 'b', 'a']); expect(result.expected).toEqual(['c', 'b', 'a']);
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']); expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
expect(result.message).toContain(jasmine.pp(result.expected)); expect(result.message).toContain(jasmine.pp(result.expected));
@@ -791,7 +791,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction); var expected = match(TestClass.spyFunction);
expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail(); expect(expected.toHaveBeenCalledWith('c', 'b', 'a')).toFail();
var result = lastResult(); var result = lastResult();
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.expected).toEqual(['c', 'b', 'a']); expect(result.expected).toEqual(['c', 'b', 'a']);
expect(result.actual.argsForCall).toEqual([]); expect(result.actual.argsForCall).toEqual([]);
expect(result.message).toContain(jasmine.pp(result.expected)); expect(result.message).toContain(jasmine.pp(result.expected));
@@ -839,7 +839,7 @@ describe("jasmine.Matchers", function() {
}, spec); }, spec);
TestClass = { someFunction: function(a, b) { TestClass = { someFunction: function(a, b) {
} }; } };
spec.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
}); });
it("should should handle the case of a spy", function() { it("should should handle the case of a spy", function() {
@@ -849,7 +849,7 @@ describe("jasmine.Matchers", function() {
var result = lastResult(); var result = lastResult();
expect(result.matcherName).toEqual("toHaveBeenCalledWith"); expect(result.matcherName).toEqual("toHaveBeenCalledWith");
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.message).toContain(jasmine.pp(['a', 'b'])); expect(result.message).toContain(jasmine.pp(['a', 'b']));
expect(result.message).toContain(jasmine.pp(['a', 'c'])); expect(result.message).toContain(jasmine.pp(['a', 'c']));
expect(result.actual).toEqual(TestClass.someFunction); expect(result.actual).toEqual(TestClass.someFunction);
@@ -879,7 +879,7 @@ describe("jasmine.Matchers", function() {
var expected = match(TestClass.spyFunction); var expected = match(TestClass.spyFunction);
expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail(); expect(expected.wasNotCalledWith('a', 'b', 'c')).toFail();
var result = lastResult(); var result = lastResult();
expect(result.passed()).toFail(); expect(result.passed).toBe(false);
expect(result.expected).toEqual(['a', 'b', 'c']); expect(result.expected).toEqual(['a', 'b', 'c']);
expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']); expect(result.actual.mostRecentCall.args).toEqual(['a', 'b', 'c']);
expect(result.message).toContain(jasmine.pp(result.expected)); expect(result.message).toContain(jasmine.pp(result.expected));
@@ -910,7 +910,7 @@ describe("jasmine.Matchers", function() {
containing = new jasmine.Matchers.ObjectContaining({}); containing = new jasmine.Matchers.ObjectContaining({});
}); });
it("matches everything", function () { it("matches everything", function () {
expect(containing.jasmineMatches("foo", [], [])).toBe(true); expect(containing.jasmineMatches("foo", [], [])).toBe(true);
}); });
it("says it didn't expect to contain anything", function () { it("says it didn't expect to contain anything", function () {
@@ -974,7 +974,7 @@ describe("jasmine.Matchers", function() {
describe("in real life", function () { describe("in real life", function () {
var method; var method;
beforeEach(function () { beforeEach(function () {
method = jasmine.createSpy("method"); method = originalJasmine.createSpy("method");
method({a:"b", c:"d"}); method({a:"b", c:"d"});
}); });
it("works correctly for positive matches", function () { it("works correctly for positive matches", function () {
-38
View File
@@ -1,38 +0,0 @@
describe("MockClock", function () {
beforeEach(function() {
jasmine.Clock.useMock();
});
describe("setTimeout", function () {
it("should mock the clock when useMock is in a beforeEach", function() {
var expected = false;
setTimeout(function() {
expected = true;
}, 30000);
expect(expected).toBe(false);
jasmine.Clock.tick(30001);
expect(expected).toBe(true);
});
});
describe("setInterval", function () {
it("should mock the clock when useMock is in a beforeEach", function() {
var interval = 0;
setInterval(function() {
interval++;
}, 30000);
expect(interval).toEqual(0);
jasmine.Clock.tick(30001);
expect(interval).toEqual(1);
jasmine.Clock.tick(30001);
expect(interval).toEqual(2);
jasmine.Clock.tick(1);
expect(interval).toEqual(2);
});
});
it("shouldn't complain if you call jasmine.Clock.useMock() more than once", function() {
jasmine.Clock.useMock();
});
});
-45
View File
@@ -1,45 +0,0 @@
describe("jasmine.MultiReporter", function() {
var multiReporter, fakeReporter1, fakeReporter2;
beforeEach(function() {
multiReporter = new jasmine.MultiReporter();
fakeReporter1 = jasmine.createSpyObj("fakeReporter1", ["reportSpecResults"]);
fakeReporter2 = jasmine.createSpyObj("fakeReporter2", ["reportSpecResults", "reportRunnerStarting"]);
multiReporter.addReporter(fakeReporter1);
multiReporter.addReporter(fakeReporter2);
});
it("should support all the method calls that jasmine.Reporter supports", function() {
var delegate = {};
multiReporter.addReporter(delegate);
this.addMatchers({
toDelegateMethod: function(methodName) {
delegate[methodName] = jasmine.createSpy(methodName);
this.actual[methodName]("whatever argument");
return delegate[methodName].wasCalled &&
delegate[methodName].mostRecentCall.args.length == 1 &&
delegate[methodName].mostRecentCall.args[0] == "whatever argument";
}
});
expect(multiReporter).toDelegateMethod('reportRunnerStarting');
expect(multiReporter).toDelegateMethod('reportRunnerResults');
expect(multiReporter).toDelegateMethod('reportSuiteResults');
expect(multiReporter).toDelegateMethod('reportSpecStarting');
expect(multiReporter).toDelegateMethod('reportSpecResults');
expect(multiReporter).toDelegateMethod('log');
});
it("should delegate to any and all subreporters", function() {
multiReporter.reportSpecResults('blah', 'foo');
expect(fakeReporter1.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
expect(fakeReporter2.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
});
it("should quietly skip delegating to any subreporters which lack the given method", function() {
multiReporter.reportRunnerStarting('blah', 'foo');
expect(fakeReporter2.reportRunnerStarting).toHaveBeenCalledWith('blah', 'foo');
});
});
-54
View File
@@ -1,54 +0,0 @@
describe('jasmine.NestedResults', function() {
it('#addResult increments counters', function() {
// Leaf case
var results = new jasmine.NestedResults();
results.addResult(new jasmine.ExpectationResult({
matcherName: "foo", passed: true, message: 'Passed.', actual: 'bar', expected: 'bar'}
));
expect(results.getItems().length).toEqual(1);
expect(results.totalCount).toEqual(1);
expect(results.passedCount).toEqual(1);
expect(results.failedCount).toEqual(0);
results.addResult(new jasmine.ExpectationResult({
matcherName: "baz", passed: false, message: 'FAIL.', actual: "corge", expected: "quux"
}));
expect(results.getItems().length).toEqual(2);
expect(results.totalCount).toEqual(2);
expect(results.passedCount).toEqual(1);
expect(results.failedCount).toEqual(1);
});
it('should roll up counts for nested results', function() {
// Branch case
var leafResultsOne = new jasmine.NestedResults();
leafResultsOne.addResult(new jasmine.ExpectationResult({
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected:''
}));
leafResultsOne.addResult(new jasmine.ExpectationResult({
matcherName: "toSomethingElse", passed: false, message: 'message', actual: 'a', expected: 'b'
}));
var leafResultsTwo = new jasmine.NestedResults();
leafResultsTwo.addResult(new jasmine.ExpectationResult({
matcherName: "toSomething", passed: true, message: 'message', actual: '', expected: ''
}));
leafResultsTwo.addResult(new jasmine.ExpectationResult({
matcherName: "toSomethineElse", passed: false, message: 'message', actual: 'c', expected: 'd'
}));
var branchResults = new jasmine.NestedResults();
branchResults.addResult(leafResultsOne);
branchResults.addResult(leafResultsTwo);
expect(branchResults.getItems().length).toEqual(2);
expect(branchResults.totalCount).toEqual(4);
expect(branchResults.passedCount).toEqual(2);
expect(branchResults.failedCount).toEqual(2);
});
});
+132
View File
@@ -0,0 +1,132 @@
describe("QueueRunner", function() {
it("runs all the functions it's passed", function() {
var calls = [],
fn1 = jasmine.createSpy('fn1'),
fn2 = jasmine.createSpy('fn2'),
queueRunner = new jasmine.QueueRunner({
fns: [fn1, fn2]
});
fn1.andCallFake(function() {
calls.push('fn1');
});
fn2.andCallFake(function() {
calls.push('fn2');
});
queueRunner.execute();
expect(calls).toEqual(['fn1', 'fn2']);
});
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
//createSpy('asyncfn').andCallFake(function(done) {});
var onComplete = originalJasmine.createSpy('onComplete'),
beforeCallback = originalJasmine.createSpy('beforeCallback'),
fnCallback = originalJasmine.createSpy('fnCallback'),
afterCallback = originalJasmine.createSpy('afterCallback'),
fn1 = function(done) {
beforeCallback();
setTimeout(function() {
done()
}, 100);
},
fn2 = function(done) {
fnCallback();
setTimeout(function() {
done()
}, 100);
},
fn3 = function(done) {
afterCallback();
setTimeout(function() {
done()
}, 100);
},
queueRunner = new jasmine.QueueRunner({
fns: [fn1, fn2, fn3],
onComplete: onComplete
});
clock.install();
queueRunner.execute();
expect(beforeCallback).toHaveBeenCalled();
expect(fnCallback).not.toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(fnCallback).toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(afterCallback).toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(onComplete).toHaveBeenCalled();
});
it("calls an exception handler when an exception is thrown in a fn", function() {
var fn = function() {
throw new Error('fake error');
},
exceptionCallback = jasmine.createSpy('exception callback'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
onException: exceptionCallback
});
queueRunner.execute();
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
});
it("rethrows an exception if told to", function() {
var fn = function() {
throw new Error('fake error');
},
queueRunner = new jasmine.QueueRunner({
fns: [fn],
catchingExceptions: function() { return false; }
});
expect(function() { queueRunner.execute(); }).toThrow();
});
it("calls a provided complete callback when done", function() {
var fn = jasmine.createSpy('fn'),
completeCallback = jasmine.createSpy('completeCallback'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
onComplete: completeCallback
});
queueRunner.execute();
expect(completeCallback).toHaveBeenCalled();
});
it("calls a provided garbage collection function with the complete callback when done", function() {
var fn = jasmine.createSpy('fn'),
completeCallback = jasmine.createSpy('completeCallback'),
encourageGC = jasmine.createSpy('encourageGC'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
encourageGC: encourageGC,
onComplete: completeCallback
});
queueRunner.execute();
expect(encourageGC).toHaveBeenCalledWith(completeCallback);
});
});
-23
View File
@@ -1,23 +0,0 @@
describe("jasmine.Queue", function() {
it("should not call itself recursively, so we don't get stack overflow errors", function() {
var queue = new jasmine.Queue(new jasmine.Env());
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
queue.add(new jasmine.Block(null, function() {}));
var nestCount = 0;
var maxNestCount = 0;
var nextCallCount = 0;
queue.next_ = function() {
nestCount++;
if (nestCount > maxNestCount) maxNestCount = nestCount;
jasmine.Queue.prototype.next_.apply(queue, arguments);
nestCount--;
};
queue.start();
expect(maxNestCount).toEqual(1);
});
});
+40
View File
@@ -0,0 +1,40 @@
describe("ReportDispatcher", function() {
it("builds an interface of requested methods", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar', 'baz']);
expect(dispatcher.foo).toBeDefined();
expect(dispatcher.bar).toBeDefined();
expect(dispatcher.baz).toBeDefined();
});
it("dispatches requested methods to added reporters", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar']),
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
dispatcher.addReporter(reporter);
dispatcher.addReporter(anotherReporter);
dispatcher.foo(123, 456);
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
dispatcher.bar('a', 'b');
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
});
it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo']),
reporter = jasmine.createSpyObj('reporter', ['baz']);
dispatcher.addReporter(reporter);
expect(function() {
dispatcher.foo(123, 456);
}).not.toThrow();
});
});
-56
View File
@@ -1,56 +0,0 @@
describe('jasmine.Reporter', function() {
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
});
it('should get called from the test runner', function() {
env.describe('Suite for JSON Reporter with Callbacks', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.it('should be a failing test', function() {
this.runs(function () {
this.expect(false).toEqual(true);
});
});
});
env.describe('Suite for JSON Reporter with Callbacks 2', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
var foo = 0;
var bar = 0;
var baz = 0;
env.addReporter({
reportSpecResults: function() {
foo++;
},
reportSuiteResults: function() {
bar++;
},
reportRunnerResults: function() {
baz++;
}
});
var runner = env.currentRunner();
runner.execute();
expect(foo).toEqual(3); // 'foo was expected to be 3, was ' + foo);
expect(bar).toEqual(2); // 'bar was expected to be 2, was ' + bar);
expect(baz).toEqual(1); // 'baz was expected to be 1, was ' + baz);
});
});
-280
View File
@@ -1,280 +0,0 @@
describe('RunnerTest', function() {
var fakeTimer;
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
fakeTimer = new jasmine.FakeTimer();
env.setTimeout = fakeTimer.setTimeout;
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
});
describe('beforeEach', function() {
it('should run before each spec for all suites', function () {
var foo;
env.beforeEach(function () {
foo = 0;
});
env.describe('suite 1', function () {
env.it('test 1-1', function() {
foo++;
this.expect(foo).toEqual(1);
});
env.it('test 1-2', function() {
foo++;
this.expect(foo).toEqual(1);
});
});
env.describe('suite 2', function () {
env.it('test 2-1', function() {
foo++;
this.expect(foo).toEqual(1);
});
});
env.currentRunner().execute();
var runnerResults = env.currentRunner().results();
expect(runnerResults.totalCount).toEqual(3);
expect(runnerResults.passedCount).toEqual(3);
});
it('should provide all specs', function () {
var foo;
env.beforeEach(function () {
foo = 0;
});
env.describe('suite 1', function () {
env.it('test 1-1', function() {
foo++;
this.expect(foo).toEqual(1);
});
env.it('test 1-2', function() {
foo++;
this.expect(foo).toEqual(1);
});
});
env.describe('suite 2', function () {
env.it('test 2-1', function() {
foo++;
this.expect(foo).toEqual(1);
});
});
env.currentRunner().execute();
expect(env.currentRunner().specs().length).toEqual(3);
});
});
describe('afterEach', function() {
it('should run after each spec for all suites', function () {
var foo = 3;
env.afterEach(function () {
foo = foo - 1;
});
env.describe('suite 1', function () {
env.it('test 1-1', function() {
this.expect(foo).toEqual(3);
});
env.it('test 1-2', function() {
this.expect(foo).toEqual(2);
});
});
env.describe('suite 2', function () {
env.it('test 2-1', function() {
this.expect(foo).toEqual(1);
});
});
env.currentRunner().execute();
var runnerResults = env.currentRunner().results();
expect(runnerResults.totalCount).toEqual(3);
expect(runnerResults.passedCount).toEqual(3);
});
it('should run after a failing spec', function () {
var afterEach = jasmine.createSpy();
env.afterEach(afterEach);
env.describe('suite', function () {
env.it('fails', function () {
this.explodes();
});
}).execute();
expect(afterEach).toHaveBeenCalled();
});
});
it('should run child suites and specs and generate results when execute is called', function() {
env.describe('one suite description', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
env.describe('another suite description', function () {
env.it('should be another test', function() {
this.runs(function () {
this.expect(true).toEqual(false);
});
});
});
env.currentRunner().execute();
var runnerResults = env.currentRunner().results();
expect(runnerResults.totalCount).toEqual(2);
expect(runnerResults.passedCount).toEqual(1);
expect(runnerResults.failedCount).toEqual(1);
});
it('should ignore suites that have been x\'d', function() {
env.xdescribe('one suite description', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
env.describe('another suite description', function () {
env.it('should be another test', function() {
this.runs(function () {
this.expect(true).toEqual(false);
});
});
});
env.currentRunner().execute();
var runnerResults = env.currentRunner().results();
expect(runnerResults.totalCount).toEqual(1);
expect(runnerResults.passedCount).toEqual(0);
expect(runnerResults.failedCount).toEqual(1);
});
it('should roll up results from all specs', function() {
env.describe('one suite description', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
env.describe('another suite description', function () {
env.it('should be another test', function() {
this.runs(function () {
this.expect(true).toEqual(false);
});
});
});
env.currentRunner().execute();
var results = env.currentRunner().results();
expect(results.totalCount).toEqual(2);
expect(results.passedCount).toEqual(1);
expect(results.failedCount).toEqual(1);
});
describe('reporting', function () {
var fakeReporter;
beforeEach(function () {
fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting", "reportRunnerResults"]);
env.addReporter(fakeReporter);
});
it('should report runner results when the runner has completed running', function() {
env.describe('one suite description', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
env.describe('another suite description', function () {
env.it('should be another test', function() {
this.waits(200);
this.runs(function () {
this.expect(true).toEqual(false);
});
});
});
env.currentRunner().execute();
expect(fakeReporter.reportRunnerResults).not.toHaveBeenCalled();
fakeTimer.tick(200);
//This blows up the JSApiReporter.
//expect(fakeReporter.reportRunnerResults).toHaveBeenCalledWith(env.currentRunner);
expect(fakeReporter.reportRunnerResults).toHaveBeenCalled();
expect(fakeReporter.reportRunnerResults.mostRecentCall.args[0].results()).toEqual(env.currentRunner().results());
});
});
it("should report when the tests start running", function() {
var fakeReporter = jasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting"]);
env.addReporter(fakeReporter);
var runner = new jasmine.Runner(env);
runner.arbitraryVariable = 'foo';
spyOn(runner.queue, 'start');
expect(fakeReporter.reportRunnerStarting).not.toHaveBeenCalled();
runner.execute();
expect(fakeReporter.reportRunnerStarting).toHaveBeenCalled();
var reportedRunner = fakeReporter.reportRunnerStarting.mostRecentCall.args[0];
expect(reportedRunner.arbitraryVariable).toEqual('foo');
expect(runner.queue.start).toHaveBeenCalled();
});
describe("when suites are nested", function() {
var suite1, suite2, suite3;
function suiteNames(suites) {
var suiteDescriptions = [];
for (var i = 0; i < suites.length; i++) {
suiteDescriptions.push(suites[i].getFullName());
}
return suiteDescriptions;
}
beforeEach(function() {
suite1 = env.describe("suite 1", function() {
suite2 = env.describe("suite 2", function() {
});
});
suite3 = env.describe("suite 3", function() {});
});
it("#suites should return a flat array of all suites, including nested suites", function() {
var suites = env.currentRunner().suites();
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite2.getFullName(), suite3.getFullName()]);
});
it("#topLevelSuites should return a flat array of all top-level suites only", function() {
var suites = env.currentRunner().topLevelSuites();
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite3.getFullName()]);
});
});
});
File diff suppressed because it is too large Load Diff
+170 -110
View File
@@ -1,124 +1,184 @@
describe('Spec', function () { describe("Spec", function() {
var env, suite;
beforeEach(function() { it("delegates execution to a QueueRunner", function() {
env = new jasmine.Env(); var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
env.updateInterval = 0; spec = new jasmine.Spec({
suite = new jasmine.Suite(env, 'suite 1'); description: 'my test',
id: 'some-id',
fn: function() {},
queueRunner: fakeQueueRunner
});
spec.execute();
expect(fakeQueueRunner).toHaveBeenCalled();
}); });
describe('initialization', function () { it("should call the start callback on execution", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
beforesWereCalled = false,
startCallback = originalJasmine.createSpy('startCallback'),
spec = new jasmine.Spec({
id: 123,
description: 'foo bar',
fn: function() {},
onStart: startCallback,
queueRunner: fakeQueueRunner
});
it('should raise an error if an env is not passed', function () { spec.execute();
try {
new jasmine.Spec();
}
catch (e) {
expect(e.message).toEqual('jasmine.Env() required');
}
});
it('should raise an error if a suite is not passed', function () { expect(startCallback).toHaveBeenCalledWith(spec);
try { });
new jasmine.Spec(env);
}
catch (e) {
expect(e.message).toEqual('jasmine.Suite() required');
}
});
it('should assign sequential ids for specs belonging to the same env', function () { it("should call the start callback on execution but before any befores are called", function() {
var spec1 = new jasmine.Spec(env, suite); var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
var spec2 = new jasmine.Spec(env, suite); beforesWereCalled = false,
var spec3 = new jasmine.Spec(env, suite); startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
expect(spec1.id).toEqual(0); expect(beforesWereCalled).toBe(false);
expect(spec2.id).toEqual(1); }),
expect(spec3.id).toEqual(2); spec = new jasmine.Spec({
fn: function() {},
beforeFns: function() {
return [function() {
beforesWereCalled = true
}]
},
onStart: startCallback,
queueRunner: fakeQueueRunner
});
spec.execute();
expect(startCallback).toHaveBeenCalled();
});
it("provides all before fns and after fns to be run", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
before = originalJasmine.createSpy('before'),
after = originalJasmine.createSpy('after'),
fn = originalJasmine.createSpy('test body').andCallFake(function() {
expect(before).toHaveBeenCalled();
expect(after).not.toHaveBeenCalled();
}),
spec = new jasmine.Spec({
fn: fn,
beforeFns: function() {
return [before]
},
afterFns: function() {
return [after]
},
queueRunner: fakeQueueRunner
});
spec.execute();
var allSpecFns = fakeQueueRunner.mostRecentCall.args[0].fns;
expect(allSpecFns).toEqual([before, fn, after]);
});
it("can be disabled, but still calls callbacks", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = originalJasmine.createSpy('startCallback'),
specBody = originalJasmine.createSpy('specBody'),
resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
onStart:startCallback,
fn: specBody,
resultCallback: resultCallback,
queueRunner: fakeQueueRunner
});
spec.disable();
expect(spec.status()).toBe('disabled');
spec.execute();
expect(startCallback).not.toHaveBeenCalled();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
});
it("should call the results callback on execution complete", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = originalJasmine.createSpy('startCallback'),
specBody = originalJasmine.createSpy('specBody'),
resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
onStart:startCallback,
fn: specBody,
resultCallback: resultCallback,
description: "with a spec",
getSpecName: function() { return "a suite with a spec"},
queueRunner: fakeQueueRunner
});
spec.disable();
expect(spec.status()).toBe('disabled');
spec.execute();
expect(startCallback).not.toHaveBeenCalled();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalledWith({
id: spec.id,
status: 'disabled',
description: 'with a spec',
fullName: 'a suite with a spec',
failedExpectations: []
}); });
}); });
it('getFullName returns suite & spec description', function () { it("should call the done callback on execution complete", function() {
var spec = new jasmine.Spec(env, suite, 'spec 1'); var done = originalJasmine.createSpy('done callback'),
expect(spec.getFullName()).toEqual('suite 1 spec 1.'); spec = new jasmine.Spec({
fn: function() {},
catchExceptions: function() { return false; },
resultCallback: function() {},
queueRunner: function(attrs) { attrs.onComplete(); }
});
spec.execute(done);
expect(done).toHaveBeenCalled();
}); });
describe('results', function () { it("#status returns null by default", function() {
var spec, results; var spec = new jasmine.Spec({});
beforeEach(function () { expect(spec.status()).toBeNull();
spec = new jasmine.Spec(env, suite); });
results = spec.results();
expect(results.totalCount).toEqual(0); it("#status returns passed if all expectations in the spec have passed", function() {
spec.runs(function () { var spec = new jasmine.Spec({});
this.expect(true).toEqual(true); spec.addExpectationResult(true);
this.expect(true).toEqual(true); expect(spec.status()).toBe('passed');
}); });
it("#status returns failed if any expectations in the spec have failed", function() {
var spec = new jasmine.Spec({});
spec.addExpectationResult(true);
spec.addExpectationResult(false);
expect(spec.status()).toBe('failed');
});
it("can return its full name", function() {
var spec;
spec = new jasmine.Spec({
getSpecName: function(passedVal) {
// expect(passedVal).toBe(spec); TODO: a exec time, spec is undefined WTF?
return 'expected val';
}
}); });
expect(spec.getFullName()).toBe('expected val');
it('results shows the total number of expectations for each spec after execution', function () {
expect(results.totalCount).toEqual(0);
spec.execute();
expect(results.totalCount).toEqual(2);
});
it('results shows the number of passed expectations for each spec after execution', function () {
expect(results.passedCount).toEqual(0);
spec.execute();
expect(results.passedCount).toEqual(2);
});
it('results shows the number of failed expectations for each spec after execution', function () {
spec.runs(function () {
this.expect(true).toEqual(false);
});
expect(results.failedCount).toEqual(0);
spec.execute();
expect(results.failedCount).toEqual(1);
});
describe('results.passed', function () {
it('is true if all spec expectations pass', function () {
spec.runs(function () {
this.expect(true).toEqual(true);
});
spec.execute();
expect(results.passed()).toEqual(true);
});
it('is false if one spec expectation fails', function () {
spec.runs(function () {
this.expect(true).toEqual(false);
});
spec.execute();
expect(results.passed()).toEqual(false);
});
it('a spec with no expectations will return true', function () {
var specWithoutExpectations = new jasmine.Spec(env, suite);
specWithoutExpectations.runs(function() {
});
specWithoutExpectations.execute();
expect(results.passed()).toEqual(true);
});
it('an unexecuted spec will return true', function () {
expect(results.passed()).toEqual(true);
});
});
it("includes log messages, which may contain arbitary objects", function() {
spec.runs(function() {
this.log("here's some log message", {key: 'value'}, 123);
});
spec.execute();
var items = results.getItems();
expect(items).toEqual([
jasmine.any(jasmine.ExpectationResult),
jasmine.any(jasmine.ExpectationResult),
jasmine.any(jasmine.MessageResult)
]);
var logResult = items[2];
expect(logResult.values).toEqual(["here's some log message", {key: 'value'}, 123]);
});
}); });
}); });
+53 -33
View File
@@ -1,4 +1,9 @@
describe('Spies', function () { describe('Spies', function () {
var env;
beforeEach(function() {
env = new jasmine.Env();
});
it('should replace the specified function with a spy object', function() { it('should replace the specified function with a spy object', function() {
var originalFunctionWasCalled = false; var originalFunctionWasCalled = false;
var TestClass = { var TestClass = {
@@ -6,11 +11,13 @@ describe('Spies', function () {
originalFunctionWasCalled = true; originalFunctionWasCalled = true;
} }
}; };
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
expect(TestClass.someFunction.wasCalled).toEqual(false); expect(TestClass.someFunction.wasCalled).toEqual(false);
expect(TestClass.someFunction.callCount).toEqual(0); expect(TestClass.someFunction.callCount).toEqual(0);
TestClass.someFunction('foo'); TestClass.someFunction('foo');
expect(TestClass.someFunction.wasCalled).toEqual(true); expect(TestClass.someFunction.wasCalled).toEqual(true);
expect(TestClass.someFunction.callCount).toEqual(1); expect(TestClass.someFunction.callCount).toEqual(1);
expect(TestClass.someFunction.mostRecentCall.args).toEqual(['foo']); expect(TestClass.someFunction.mostRecentCall.args).toEqual(['foo']);
@@ -29,7 +36,7 @@ describe('Spies', function () {
originalFunctionWasCalled = true; originalFunctionWasCalled = true;
} }
}; };
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
TestClass.someFunction('foo'); TestClass.someFunction('foo');
TestClass.someFunction('bar'); TestClass.someFunction('bar');
@@ -51,7 +58,7 @@ describe('Spies', function () {
} }
}; };
this.spyOn(TestClass, 'someFunction').andCallThrough(); env.spyOn(TestClass, 'someFunction').andCallThrough();
var result = TestClass.someFunction('arg1', 'arg2'); var result = TestClass.someFunction('arg1', 'arg2');
expect(result).toEqual("return value from original function"); expect(result).toEqual("return value from original function");
expect(originalFunctionWasCalled).toEqual(true); expect(originalFunctionWasCalled).toEqual(true);
@@ -69,7 +76,7 @@ describe('Spies', function () {
} }
}; };
this.spyOn(TestClass, 'someFunction').andReturn("some value"); env.spyOn(TestClass, 'someFunction').andReturn("some value");
originalFunctionWasCalled = false; originalFunctionWasCalled = false;
var result = TestClass.someFunction('arg1', 'arg2'); var result = TestClass.someFunction('arg1', 'arg2');
expect(result).toEqual("some value"); expect(result).toEqual("some value");
@@ -85,7 +92,7 @@ describe('Spies', function () {
} }
}; };
this.spyOn(TestClass, 'someFunction').andThrow(new Error('fake error')); env.spyOn(TestClass, 'someFunction').andThrow(new Error('fake error'));
var exception; var exception;
try { try {
TestClass.someFunction('arg1', 'arg2'); TestClass.someFunction('arg1', 'arg2');
@@ -108,7 +115,7 @@ describe('Spies', function () {
} }
}; };
this.spyOn(TestClass, 'someFunction').andCallFake(function() { env.spyOn(TestClass, 'someFunction').andCallFake(function() {
fakeFunctionWasCalled = true; fakeFunctionWasCalled = true;
passedArgs = arguments; passedArgs = arguments;
passedObj = this; passedObj = this;
@@ -124,41 +131,54 @@ describe('Spies', function () {
expect(TestClass.someFunction.wasCalled).toEqual(true); expect(TestClass.someFunction.wasCalled).toEqual(true);
}); });
it('is torn down when this.removeAllSpies is called', function() { it('is torn down when env.removeAllSpies is called', function() {
var originalFunctionWasCalled = false; var originalFunctionWasCalled = false,
var TestClass = { env = new jasmine.Env(),
TestClass = {
someFunction: function() { someFunction: function() {
originalFunctionWasCalled = true; originalFunctionWasCalled = true;
} }
}; };
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
TestClass.someFunction('foo'); TestClass.someFunction('foo');
expect(originalFunctionWasCalled).toEqual(false); expect(originalFunctionWasCalled).toEqual(false);
this.removeAllSpies(); env.removeAllSpies();
TestClass.someFunction('foo'); TestClass.someFunction('foo');
expect(originalFunctionWasCalled).toEqual(true); expect(originalFunctionWasCalled).toEqual(true);
}); });
it('calls removeAllSpies during spec finish', function() { it('calls removeAllSpies during spec finish', function() {
var test = new jasmine.Spec(new jasmine.Env(), {}, 'sample test'); var env = new jasmine.Env(),
originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = originalJasmine.createSpy('firstSpec').andCallFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = originalJasmine.createSpy('secondSpec').andCallFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
this.spyOn(test, 'removeAllSpies'); env.execute();
expect(firstSpec).toHaveBeenCalled();
test.finish(); expect(secondSpec).toHaveBeenCalled();
expect(test.removeAllSpies).wasCalled();
}); });
it('throws an exception when some method is spied on twice', function() { it('throws an exception when some method is spied on twice', function() {
var TestClass = { someFunction: function() { var TestClass = { someFunction: function() {
} }; } };
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
var exception; var exception;
try { try {
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
@@ -166,23 +186,23 @@ describe('Spies', function () {
}); });
it('to spy on an undefined method throws exception', function() { it('to spy on an undefined method throws exception', function() {
var TestClass = { var TestClass = {
someFunction : function() { someFunction : function() {
} }
}; };
function efunc() { function efunc() {
this.spyOn(TestClass, 'someOtherFunction'); env.spyOn(TestClass, 'someOtherFunction');
}; };
expect(function() { expect(function() {
efunc(); efunc();
}).toThrow('someOtherFunction() method does not exist'); }).toThrow('someOtherFunction() method does not exist');
}); });
it('should be able to reset a spy', function() { it('should be able to reset a spy', function() {
var TestClass = { someFunction: function() {} }; var TestClass = { someFunction: function() {} };
this.spyOn(TestClass, 'someFunction'); env.spyOn(TestClass, 'someFunction');
expect(TestClass.someFunction).not.toHaveBeenCalled(); expect(TestClass.someFunction).not.toHaveBeenCalled();
TestClass.someFunction(); TestClass.someFunction();
@@ -195,7 +215,7 @@ describe('Spies', function () {
describe("createSpyObj", function() { describe("createSpyObj", function() {
it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() { it("should create an object with a bunch of spy methods when you call jasmine.createSpyObj()", function() {
var spyObj = jasmine.createSpyObj('BaseName', ['method1', 'method2']); var spyObj = jasmine.createSpyObj('BaseName', ['method1', 'method2']);
expect(spyObj).toEqual({ method1: jasmine.any(Function), method2: jasmine.any(Function)}); expect(spyObj).toEqual({ method1: originalJasmine.any(Function), method2: originalJasmine.any(Function)});
expect(spyObj.method1.identity).toEqual('BaseName.method1'); expect(spyObj.method1.identity).toEqual('BaseName.method1');
expect(spyObj.method2.identity).toEqual('BaseName.method2'); expect(spyObj.method2.identity).toEqual('BaseName.method2');
}); });
+214 -104
View File
@@ -1,120 +1,230 @@
describe('Suite', function() { describe("Suite", function() {
var fakeTimer;
var env;
beforeEach(function() { it("keeps its id", function() {
env = new jasmine.Env(); var env = new jasmine.Env(),
env.updateInterval = 0; suite = new jasmine.Suite({
env: env,
id: 456,
description: "I am a suite"
});
fakeTimer = new jasmine.FakeTimer(); expect(suite.id).toEqual(456);
env.setTimeout = fakeTimer.setTimeout;
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
}); });
describe('Specs', function () { it("returns its full name", function() {
var suite; var env = new jasmine.Env(),
suite = new jasmine.Suite({
beforeEach(function() { env: env,
suite = env.describe('Suite 1', function () { description: "I am a suite"
env.it('Spec 1', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.it('Spec 2', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.describe('Suite 2', function () {
env.it('Spec 3', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
env.it('Spec 4', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
}); });
});
it('#specs should return all immediate children that are specs.', function () { expect(suite.getFullName()).toEqual("I am a suite");
var suiteSpecs = suite.specs();
expect(suiteSpecs.length).toEqual(3);
expect(suiteSpecs[0].description).toEqual('Spec 1');
expect(suiteSpecs[1].description).toEqual('Spec 2');
expect(suiteSpecs[2].description).toEqual('Spec 4');
});
it("#suites should return all immediate children that are suites.", function() {
var nestedSuites = suite.suites();
expect(nestedSuites.length).toEqual(1);
expect(nestedSuites[0].description).toEqual('Suite 2');
});
it("#children should return all immediate children including suites and specs.", function() {
var children = suite.children();
expect(children.length).toEqual(4);
expect(children[0].description).toEqual('Spec 1');
expect(children[1].description).toEqual('Spec 2');
expect(children[2].description).toEqual('Suite 2');
expect(children[3].description).toEqual('Spec 4');
});
}); });
describe('SpecCount', function () { it("returns its full name when it has parent suites", function() {
var env = new jasmine.Env(),
it('should keep a count of the number of specs that are run', function() { parentSuite = new jasmine.Suite({
var suite = env.describe('one suite description', function () { env: env,
env.it('should be a test', function() { description: "I am a parent suite",
this.runs(function () { parentSuite: jasmine.createSpy('pretend top level suite')
this.expect(true).toEqual(true); }),
}); suite = new jasmine.Suite({
}); env: env,
env.it('should be another test', function() { description: "I am a suite",
this.runs(function () { parentSuite: parentSuite
this.expect(true).toEqual(true);
});
});
env.it('should be a third test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
}); });
expect(suite.specs().length).toEqual(3); expect(suite.getFullName()).toEqual("I am a parent suite I am a suite");
}); });
it('specCount should be correct even with runs/waits blocks', function() { it("adds before functions in order of needed execution", function() {
var suite = env.describe('one suite description', function () { var env = new jasmine.Env(),
env.it('should be a test', function() { suite = new jasmine.Suite({
this.runs(function () { env: env,
this.expect(true).toEqual(true); description: "I am a suite"
}); }),
}); outerBefore = jasmine.createSpy('outerBeforeEach'),
env.it('should be another test', function() { innerBefore = jasmine.createSpy('insideBeforeEach');
this.runs(function () {
this.expect(true).toEqual(true); suite.beforeEach(outerBefore);
}); suite.beforeEach(innerBefore);
this.waits(10);
this.runs(function () { expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
this.expect(true).toEqual(true); });
});
}); it("adds after functions in order of needed execution", function() {
env.it('should be a third test', function() { var env = new jasmine.Env(),
this.runs(function () { suite = new jasmine.Suite({
this.expect(true).toEqual(true); env: env,
}); description: "I am a suite"
}); }),
outerAfter = jasmine.createSpy('outerAfterEach'),
innerAfter = jasmine.createSpy('insideAfterEach');
suite.afterEach(outerAfter);
suite.afterEach(innerAfter);
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
});
it("adds specs", function() {
var env = new jasmine.Env(),
fakeQueue = {
add: jasmine.createSpy()
},
suite = new jasmine.Suite({
env: env,
description: "I am a suite",
queueFactory: function() {
return fakeQueue
}
}),
fakeSpec = {};
expect(suite.specs.length).toEqual(0);
suite.addSpec(fakeSpec);
expect(suite.specs.length).toEqual(1);
});
it("adds suites", function() {
var env = new jasmine.Env(),
fakeQueue = {
add: jasmine.createSpy()
},
suite = new jasmine.Suite({
env: env,
description: "I am a suite",
queueFactory: function() {
return fakeQueue
}
}),
anotherSuite = new jasmine.Suite({
env: env,
description: "I am another suite",
queueFactory: function() {
return fakeQueue
}
}); });
expect(suite.specs().length).toEqual(3); expect(suite.suites.length).toEqual(0);
suite.addSuite(anotherSuite);
expect(suite.suites.length).toEqual(1);
});
it("can be disabled", function() {
var env = new jasmine.Env(),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
});
suite.disable();
expect(suite.disabled).toBe(true);
suite.execute();
expect(fakeQueueRunner).not.toHaveBeenCalled();
});
it("delegates execution of its specs and suites", function() {
var env = new jasmine.Env(),
parentSuiteDone = jasmine.createSpy('parent suite done'),
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
parentSuite = new jasmine.Suite({
env: env,
description: "I am a parent suite",
queueRunner: fakeQueueRunnerForParent
}),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
spyOn(suite, "execute");
parentSuite.addSpec(fakeSpec1);
parentSuite.addSuite(suite);
parentSuite.execute(parentSuiteDone);
var parentSuiteFns = fakeQueueRunnerForParent.mostRecentCall.args[0].fns;
parentSuiteFns[0]();
expect(fakeSpec1.execute).toHaveBeenCalled();
parentSuiteFns[1]();
expect(suite.execute).toHaveBeenCalled();
});
it("calls a provided onStart callback when starting", function() {
var env = new jasmine.Env(),
suiteStarted = jasmine.createSpy('suiteStarted'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
onStart: suiteStarted,
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute();
expect(suiteStarted).toHaveBeenCalledWith(suite);
});
it("calls a provided onComplete callback when done", function() {
var env = new jasmine.Env(),
suiteCompleted = jasmine.createSpy('parent suite done'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute(suiteCompleted);
expect(suiteCompleted).toHaveBeenCalled();
});
it("calls a provided result callback when done", function() {
var env = new jasmine.Env(),
suiteResultsCallback = jasmine.createSpy('suite result callback'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner,
resultCallback: suiteResultsCallback
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute();
expect(suiteResultsCallback).toHaveBeenCalledWith({
id: suite.id,
status: '',
description: "with a child suite",
fullName: "with a child suite"
}); });
}); });
}); });
-22
View File
@@ -1,26 +1,4 @@
describe("jasmine.util", function() { describe("jasmine.util", function() {
describe("extend", function () {
it("should add properies to a destination object ", function() {
var destination = {baz: 'baz'};
jasmine.util.extend(destination, {
foo: 'foo', bar: 'bar'
});
expect(destination).toEqual({foo: 'foo', bar: 'bar', baz: 'baz'});
});
it("should replace properies that already exist on a destination object", function() {
var destination = {foo: 'foo'};
jasmine.util.extend(destination, {
foo: 'bar'
});
expect(destination).toEqual({foo: 'bar'});
jasmine.util.extend(destination, {
foo: null
});
expect(destination).toEqual({foo: null});
});
});
describe("isArray_", function() { describe("isArray_", function() {
it("should return true if the argument is an array", function() { it("should return true if the argument is an array", function() {
expect(jasmine.isArray_([])).toBe(true); expect(jasmine.isArray_([])).toBe(true);
-118
View File
@@ -1,118 +0,0 @@
describe('WaitsForBlock', function () {
var env, suite, timeout, spec, message, onComplete, fakeTimer;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
suite = new jasmine.Suite(env, 'suite 1');
timeout = 1000;
spec = new jasmine.Spec(env, suite);
message = "some error message";
onComplete = jasmine.createSpy("onComplete");
});
describe("jasmine.VERBOSE", function() {
var jasmineVerboseOriginal;
beforeEach(function() {
jasmineVerboseOriginal = jasmine.VERBOSE;
spyOn(env.reporter, 'log');
});
it('do not show information if jasmine.VERBOSE is set to false', function () {
jasmine.VERBOSE = false;
var latchFunction = function() {
return true;
};
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(env.reporter.log).not.toHaveBeenCalled();
block.execute(onComplete);
expect(env.reporter.log).not.toHaveBeenCalled();
jasmine.VERBOSE = jasmineVerboseOriginal;
});
it('show information if jasmine.VERBOSE is set to true', function () {
jasmine.VERBOSE = true;
var latchFunction = function() {
return true;
};
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(env.reporter.log).not.toHaveBeenCalled();
block.execute(onComplete);
expect(env.reporter.log).toHaveBeenCalled();
jasmine.VERBOSE = jasmineVerboseOriginal;
});
});
it('onComplete should be called if the latchFunction returns true', function () {
var latchFunction = function() {
return true;
};
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(onComplete).not.toHaveBeenCalled();
block.execute(onComplete);
expect(onComplete).toHaveBeenCalled();
});
it('latchFunction should run in same scope as spec', function () {
var result;
var latchFunction = function() {
result = this.scopedValue;
};
spec.scopedValue = 'foo';
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
block.execute(onComplete);
expect(result).toEqual('foo');
});
it('should fail spec and call onComplete if there is an error in the latchFunction', function() {
var latchFunction = jasmine.createSpy('latchFunction').andThrow('some error');
spyOn(spec, 'fail');
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
block.execute(onComplete);
expect(spec.fail).toHaveBeenCalledWith('some error');
expect(onComplete).toHaveBeenCalled();
});
describe("if latchFunction returns false", function() {
var latchFunction, fakeTimer;
beforeEach(function() {
latchFunction = jasmine.createSpy('latchFunction').andReturn(false);
fakeTimer = new jasmine.FakeTimer();
env.setTimeout = fakeTimer.setTimeout;
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
});
it('latchFunction should be retried after 10 ms', function () {
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(latchFunction).not.toHaveBeenCalled();
block.execute(onComplete);
expect(latchFunction.callCount).toEqual(1);
fakeTimer.tick(5);
expect(latchFunction.callCount).toEqual(1);
fakeTimer.tick(5);
expect(latchFunction.callCount).toEqual(2);
});
it('onComplete should be called if latchFunction returns true before timeout', function () {
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(onComplete).not.toHaveBeenCalled();
block.execute(onComplete);
expect(onComplete).not.toHaveBeenCalled();
latchFunction.andReturn(true);
fakeTimer.tick(100);
expect(onComplete).toHaveBeenCalled();
});
it('spec should fail with the passed message if the timeout is reached (and not call onComplete)', function () {
spyOn(spec, 'fail');
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
block.execute(onComplete);
expect(spec.fail).not.toHaveBeenCalled();
fakeTimer.tick(timeout);
expect(spec.fail).toHaveBeenCalled();
var failMessage = spec.fail.mostRecentCall.args[0].message;
expect(failMessage).toMatch(message);
expect(onComplete).toHaveBeenCalled();
});
});
});
-209
View File
@@ -1,209 +0,0 @@
describe("HtmlReporter", function() {
var env;
var htmlReporter;
var body;
var fakeDocument;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
body = document.createElement("body");
fakeDocument = { body: body, location: { search: "" } };
htmlReporter = new jasmine.HtmlReporter(fakeDocument);
});
function fakeSpec(name) {
return {
getFullName: function() {
return name;
}
};
}
function findElements(divs, withClass) {
var els = [];
for (var i = 0; i < divs.length; i++) {
if (divs[i].className == withClass) els.push(divs[i]);
}
return els;
}
function findElement(divs, withClass) {
var els = findElements(divs, withClass);
if (els.length > 0) {
return els[0];
}
throw new Error("couldn't find div with class " + withClass);
}
it("should run only specs beginning with spec parameter", function() {
fakeDocument.location.search = "?spec=run%20this";
expect(htmlReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
expect(htmlReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
expect(htmlReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
});
describe("running without any specs", function() {
var runner;
beforeEach(function() {
runner = env.currentRunner();
env.addReporter(htmlReporter);
});
it("should not error", function() {
var exec = function() {
runner.execute();
};
expect(exec).not.toThrow();
});
});
describe('Matcher reporting', function() {
var getResultMessageDiv = function(body) {
var divs = body.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
if (divs[i].className.match(/resultMessage/)) {
return divs[i];
}
}
};
var runner, spec, fakeTimer;
beforeEach(function() {
fakeTimer = new jasmine.FakeTimer();
env.setTimeout = fakeTimer.setTimeout;
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
runner = env.currentRunner();
var suite = new jasmine.Suite(env, 'some suite');
runner.add(suite);
spec = new jasmine.Spec(env, suite, 'some spec');
suite.add(spec);
fakeDocument.location.search = "?";
env.addReporter(htmlReporter);
});
describe('toContain', function() {
it('should show actual and expected', function() {
spec.runs(function() {
this.expect('foo').toContain('bar');
});
runner.execute();
fakeTimer.tick(0);
var resultEl = getResultMessageDiv(body);
expect(resultEl.innerHTML).toMatch(/foo/);
expect(resultEl.innerHTML).toMatch(/bar/);
});
});
});
describe("failure messages (integration)", function() {
var spec, results, expectationResult;
it("should add the failure message to the DOM (non-toEquals matchers)", function() {
env.describe("suite", function() {
env.it("will have log messages", function() {
this.expect('a').toBeNull();
});
});
env.addReporter(htmlReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'resultMessage fail');
expect(errorDiv.innerHTML).toMatch(/Expected 'a' to be null/);
});
it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
env.describe("suite", function() {
env.it("will have log messages", function() {
this.expect('1 < 2').toBeNull();
});
});
env.addReporter(htmlReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'resultMessage fail');
expect(errorDiv.innerHTML).toMatch(/Expected '1 &lt; 2' to be null/);
});
});
describe("log messages", function() {
it("should appear in the report of a failed spec", function() {
env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this is a", "multipart log message");
this.expect(true).toBeFalsy();
});
});
env.addReporter(htmlReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'specDetail failed');
expect(errorDiv.innerHTML).toMatch("this is a multipart log message");
});
xit("should work on IE without console.log.apply", function() {
});
});
describe("duplicate example names", function() {
it("should report failures correctly", function() {
var suite1 = env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this one fails!");
this.expect(true).toBeFalsy();
});
});
var suite2 = env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this one passes!");
this.expect(true).toBeTruthy();
});
});
env.addReporter(htmlReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var failedSpecDiv = findElement(divs, 'specDetail failed');
expect(failedSpecDiv.className).toEqual('specDetail failed');
expect(failedSpecDiv.innerHTML).toContain("this one fails!");
expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
});
});
describe('#reportSpecStarting', function() {
beforeEach(function() {
env.describe("suite 1", function() {
env.it("spec 1", function() {
});
});
spyOn(htmlReporter, 'log').andCallThrough();
});
it('DOES NOT log running specs by default', function() {
env.addReporter(htmlReporter);
env.execute();
expect(htmlReporter.log).not.toHaveBeenCalled();
});
it('logs running specs when log_running_specs is true', function() {
htmlReporter.logRunningSpecs = true;
env.addReporter(htmlReporter);
env.execute();
expect(htmlReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
});
});
});
+571
View File
@@ -0,0 +1,571 @@
describe("New HtmlReporter", function() {
it("builds the initial DOM elements, including the title banner", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
// Main top-level elements
var divs = container.getElementsByTagName("div");
expect(findElement(divs, "html-reporter")).toBeTruthy();
expect(findElement(divs, "banner")).toBeTruthy();
expect(findElement(divs, "alert")).toBeTruthy();
expect(findElement(divs, "results")).toBeTruthy();
var uls = container.getElementsByTagName("ul");
expect(findElement(uls, "symbol-summary")).toBeTruthy();
// title banner
var banner = container.getElementsByClassName("banner")[0];
var title = banner.getElementsByClassName("title")[0];
expect(title.innerHTML).toMatch(/Jasmine/);
var version = banner.getElementsByClassName("version")[0];
expect(version.innerHTML).toMatch(/\d+\.\d+\.\d+\srevision\s+\d+/);
});
describe("when a spec is done", function() {
it("reports the status symbol of a disabled spec", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.specDone({id: 789, status: "disabled"});
var statuses = container.getElementsByClassName('symbol-summary')[0];
var specEl = statuses.getElementsByTagName('li')[0];
expect(specEl.getAttribute("class")).toEqual("disabled");
expect(specEl.getAttribute("id")).toEqual("spec_789");
});
it("reports the status symbol of a passing spec", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.specDone({id: 123, status: "passed"});
var statuses = container.getElementsByClassName("symbol-summary")[0];
var specEl = statuses.getElementsByTagName("li")[0];
expect(specEl.getAttribute("class")).toEqual("passed");
expect(specEl.getAttribute("id")).toEqual("spec_123");
});
it("reports the status symbol of a failing spec", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.specDone({
id: 345,
status: "failed",
failedExpectations: []
});
var statuses = container.getElementsByClassName('symbol-summary')[0];
var specEl = statuses.getElementsByTagName('li')[0];
expect(specEl.getAttribute("class")).toEqual("failed");
expect(specEl.getAttribute("id")).toEqual("spec_345");
});
});
describe("when Jasmine is done", function() {
it("reports the run time", function() {
var env = new jasmine.Env(),
fakeNow = jasmine.createSpy('fake Date.now'),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
now: fakeNow,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
fakeNow.andReturn(500);
reporter.jasmineStarted({});
fakeNow.andReturn(600);
reporter.jasmineDone();
var banner = container.getElementsByClassName("banner")[0];
var duration = banner.getElementsByClassName("duration")[0];
expect(duration.innerHTML).toMatch(/finished in 0.1s/);
});
it("reports the suite and spec names with status", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.suiteStarted({
id: 1,
description: "A Suite",
fullName: "A Suite"
});
var specResult = {
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "passed"
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
reporter.suiteStarted({
id: 2,
description: "inner suite",
fullName: "A Suite inner suite"
});
var specResult = {
id: 124,
description: "with another spec",
fullName: "A Suite inner suite with another spec",
status: "passed"
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
reporter.suiteDone({id: 2});
specResult = {
id: 209,
description: "with a failing spec",
fullName: "A Suite inner with a failing spec",
status: "failed",
failedExpectations: []
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
reporter.suiteDone({id: 1});
reporter.jasmineDone();
var summary = container.getElementsByClassName("summary")[0];
console.error("=============>", summary);
expect(summary.childNodes.length).toEqual(1);
var outerSuite = summary.childNodes[0];
expect(outerSuite.childNodes.length).toEqual(4);
var classes = [];
for (var i = 0; i < outerSuite.childNodes.length; i++) {
var node = outerSuite.childNodes[i];
classes.push(node.getAttribute("class"));
}
expect(classes).toEqual(["suite-detail", "specs", "suite", "specs"]);
var suiteDetail = outerSuite.childNodes[0];
var suiteLink = suiteDetail.childNodes[0];
expect(suiteLink.text).toEqual("A Suite");
expect(suiteLink.getAttribute('href')).toEqual("?spec=A%20Suite");
var specs = outerSuite.childNodes[1];
var spec = specs.childNodes[0];
expect(spec.getAttribute("class")).toEqual("passed");
expect(spec.getAttribute("id")).toEqual("spec-123");
var specLink = spec.childNodes[0];
expect(specLink.text).toEqual("with a spec");
expect(specLink.getAttribute("href")).toEqual("?spec=A%20Suite%20with%20a%20spec");
// expect(specLink.getAttribute("title")).toEqual("A Suite with a spec");
});
describe("UI for raising/catching exceptions", function() {
it("should be unchecked if the env is catching", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineDone();
var raisingExceptionsUI = container.getElementsByClassName("raise")[0];
expect(raisingExceptionsUI.checked).toBe(false);
});
it("should be checked if the env is not catching", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
fakeQueryString = "",
fakeWindowLocation = {
search: fakeQueryString
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return fakeWindowLocation; }
}),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
queryString: queryString,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
env.catchExceptions(false);
reporter.jasmineDone();
var raisingExceptionsUI = container.getElementsByClassName("raise")[0];
expect(raisingExceptionsUI.checked).toBe(true);
});
it("should affect the query param for catching exceptions", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
fakeQueryString = "",
fakeWindowLocation = {
search: fakeQueryString
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return fakeWindowLocation; }
}),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
queryString: queryString,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineDone();
var input = container.getElementsByClassName("raise")[0];
input.click();
expect(queryString.getParam("catch")).toEqual(false);
input.click();
expect(queryString.getParam("catch")).toEqual(true);
});
});
describe("and all specs pass", function() {
var env, container, reporter;
beforeEach(function() {
env = new jasmine.Env();
container = document.createElement("div");
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.specDone({
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "passed"
});
reporter.specDone({
id: 124,
description: "with another spec",
fullName: "A Suite inner suite with another spec",
status: "passed"
});
reporter.jasmineDone();
});
it("reports the specs counts", function() {
var alert = container.getElementsByClassName("alert")[0];
var alertBars = alert.getElementsByClassName("bar");
expect(alertBars.length).toEqual(1);
expect(alertBars[0].getAttribute('class')).toMatch(/passed/);
expect(alertBars[0].innerHTML).toMatch(/2 specs, 0 failures/);
});
it("reports no failure details", function() {
var specFailure = container.getElementsByClassName("failures")[0];
expect(specFailure.childNodes.length).toEqual(0);
});
});
describe("and some tests fail", function() {
var env, container, reporter;
beforeEach(function() {
env = new jasmine.Env();
container = document.createElement("div");
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
var passingResult = {id: 123, status: "passed"};
reporter.specStarted(passingResult);
reporter.specDone(passingResult);
var failingResult = {
id: 124,
status: "failed",
description: "a failing spec",
fullName: "a suite with a failing spec",
failedExpectations: [
{
message: "a failure message",
trace: {
stack: "a stack trace"
}
}
]
};
reporter.specStarted(failingResult);
reporter.specDone(failingResult);
reporter.jasmineDone();
});
it("reports the specs counts", function() {
var alert = container.getElementsByClassName("alert")[0];
var alertBars = alert.getElementsByClassName("bar");
expect(alertBars[0].getAttribute('class')).toMatch(/failed/);
expect(alertBars[0].innerHTML).toMatch(/2 specs, 1 failure/);
});
it("reports failure messages and stack traces", function() {
var specFailures = container.getElementsByClassName("failures")[0];
var failure = specFailures.childNodes[0];
expect(failure.getAttribute("class")).toMatch(/failed/);
expect(failure.getAttribute("class")).toMatch(/spec-detail/);
var specLink = failure.childNodes[0];
expect(specLink.getAttribute("class")).toEqual("description");
expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
expect(specLink.getAttribute("href")).toEqual("?spec=a%20suite%20with%20a%20failing%20spec");
var message = failure.childNodes[1].childNodes[0];
expect(message.getAttribute("class")).toEqual("result-message");
expect(message.innerHTML).toEqual("a failure message");
var stackTrace = failure.childNodes[1].childNodes[1];
expect(stackTrace.getAttribute("class")).toEqual("stack-trace");
expect(stackTrace.innerHTML).toEqual("a stack trace");
});
it("allows switching between failure details and the spec summary", function() {
var menuBar = container.getElementsByClassName("bar")[1];
expect(menuBar.getAttribute("class")).not.toMatch(/hidden/);
var link = menuBar.getElementsByTagName('a')[0];
expect(link.text).toEqual("Failures");
expect(link.getAttribute("href")).toEqual("#");
});
it("sets the reporter to 'Failures List' mode", function() {
var reporterNode = container.getElementsByClassName("html-reporter")[0];
expect(reporterNode.getAttribute("class")).toMatch("failure-list");
});
});
});
describe("specFilter", function() {
it("always returns true if there is no filter", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
fakeQueryString = "",
fakeWindowLocation = {
search: fakeQueryString
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return fakeWindowLocation; }
}),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
queryString: queryString,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
}),
fakeSpec = {
getFullName: function() { return "A suite with a spec"}
};
expect(reporter.specFilter(fakeSpec)).toBe(true);
});
it("matches a focused spec name", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
fakeWindowLocation = {
search: "?spec=A%20suite%20with%20a%20spec"
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return fakeWindowLocation; }
}),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
queryString: queryString,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
}),
fakeMatchingSpec = {
getFullName: function() { return "A suite with a spec"}
},
fakeNonMatchingSpec = {
getFullName: function() { return "sasquatch"}
};
expect(reporter.specFilter(fakeMatchingSpec)).toBe(true);
expect(reporter.specFilter(fakeNonMatchingSpec)).toBe(false);
});
it("matches a substring of a spec name", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
fakeWindowLocation = {
search: "?spec=with"
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return fakeWindowLocation; }
}),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
queryString: queryString,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
}),
fakeMatchingSpec = {
getFullName: function() { return "A suite with a spec" }
},
fakeNonMatchingSpec = {
getFullName: function() { return "sasquatch"}
};
expect(reporter.specFilter(fakeMatchingSpec)).toBe(true);
expect(reporter.specFilter(fakeNonMatchingSpec)).toBe(false);
});
});
describe("when specs are filtered", function() {
it("shows the count of run specs and defined specs", function() {
var env = new jasmine.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new jasmine.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({
totalSpecsDefined: 2
});
reporter.specDone({
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "passed"
});
reporter.specDone({
id: 124,
description: "with another spec",
fullName: "A Suite inner suite with another spec",
status: "disabled"
});
reporter.jasmineDone();
var skippedBar = container.getElementsByClassName("bar")[0];
expect(skippedBar.getAttribute("class")).toMatch(/skipped/);
var runAllLink = skippedBar.childNodes[0];
expect(runAllLink.getAttribute("href")).toEqual("?");
expect(runAllLink.text).toMatch(/Ran \d+ of \d+ specs - run all/);
});
});
// try/catch
// utility functions
function findElements(divs, withClass) {
var els = [];
for (var i = 0; i < divs.length; i++) {
if (divs[i].className == withClass) els.push(divs[i]);
}
return els;
}
function findElement(divs, withClass) {
var els = findElements(divs, withClass);
if (els.length > 0) {
return els[0];
}
throw new Error("couldn't find div with class " + withClass);
}
});
+5 -5
View File
@@ -9,14 +9,14 @@ describe("MatchersSpec - HTML Dependent", function () {
spec = env.it("spec", function() { spec = env.it("spec", function() {
}); });
}); });
spyOn(spec, 'addMatcherResult'); spyOn(spec, 'addExpectationResult');
this.addMatchers({ addMatchers({
toPass: function() { toPass: function() {
return lastResult().passed(); return lastResult().passed;
}, },
toFail: function() { toFail: function() {
return !lastResult().passed(); return !lastResult().passed;
} }
}); });
}); });
@@ -26,7 +26,7 @@ describe("MatchersSpec - HTML Dependent", function () {
} }
function lastResult() { function lastResult() {
return spec.addMatcherResult.mostRecentCall.args[0]; return spec.addExpectationResult.mostRecentCall.args[1];
} }
it("toEqual with DOM nodes", function() { it("toEqual with DOM nodes", function() {
+43
View File
@@ -0,0 +1,43 @@
describe("QueryString", function() {
describe("#setParam", function() {
it("sets the query string to include the given key/value pair", function() {
var windowLocation = {
search: ""
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return windowLocation }
});
queryString.setParam("foo", "bar baz");
expect(windowLocation.search).toMatch(/foo=bar%20baz/);
});
});
describe("#getParam", function() {
it("returns the value of the requested key", function() {
var windowLocation = {
search: "?baz=quux%20corge"
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return windowLocation }
});
expect(queryString.getParam("baz")).toEqual("quux corge");
});
it("returns null if the key is not present", function() {
var windowLocation = {
search: ""
},
queryString = new jasmine.QueryString({
getWindowLocation: function() { return windowLocation }
});
expect(queryString.getParam("baz")).toBeFalsy();
});
});
});
+62
View File
@@ -0,0 +1,62 @@
describe("ResultsNode", function() {
it("wraps a result", function() {
var fakeResult = {
id: 123,
message: "foo"
},
node = new jasmine.ResultsNode(fakeResult, "suite", null);
expect(node.result).toBe(fakeResult);
expect(node.type).toEqual("suite");
});
it("can add children with a type", function() {
var fakeResult = {
id: 123,
message: "foo"
},
fakeChildResult = {
id: 456,
message: "bar"
},
node = new jasmine.ResultsNode(fakeResult, "suite", null);
node.addChild(fakeChildResult, "spec");
expect(node.children.length).toEqual(1);
expect(node.children[0].result).toEqual(fakeChildResult);
expect(node.children[0].type).toEqual("spec");
});
it("has a pointer back to its parent ResultNode", function() {
var fakeResult = {
id: 123,
message: "foo"
},
fakeChildResult = {
id: 456,
message: "bar"
},
node = new jasmine.ResultsNode(fakeResult, "suite", null);
node.addChild(fakeChildResult, "spec");
expect(node.children[0].parent).toBe(node);
});
it("can provide the most recent child", function() {
var fakeResult = {
id: 123,
message: "foo"
},
fakeChildResult = {
id: 456,
message: "bar"
},
node = new jasmine.ResultsNode(fakeResult, "suite", null);
node.addChild(fakeChildResult, "spec");
expect(node.last()).toBe(node.children[node.children.length - 1]);
});
});
-239
View File
@@ -1,239 +0,0 @@
describe("TrivialReporter", function() {
var env;
var trivialReporter;
var body;
var fakeDocument;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
body = document.createElement("body");
fakeDocument = { body: body, location: { search: "" } };
trivialReporter = new jasmine.TrivialReporter(fakeDocument);
});
function fakeSpec(name) {
return {
getFullName: function() {
return name;
}
};
}
function findElements(divs, withClass) {
var els = [];
for (var i = 0; i < divs.length; i++) {
if (divs[i].className == withClass) els.push(divs[i]);
}
return els;
}
function findElement(divs, withClass) {
var els = findElements(divs, withClass);
if (els.length > 0) {
return els[0];
}
throw new Error("couldn't find div with class " + withClass);
}
it("should run only specs beginning with spec parameter", function() {
fakeDocument.location.search = "?spec=run%20this";
expect(trivialReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
expect(trivialReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
expect(trivialReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
});
it("should display empty divs for every suite when the runner is starting", function() {
trivialReporter.reportRunnerStarting({
env: env,
suites: function() {
return [ new jasmine.Suite({}, "suite 1", null, null) ];
}
});
var divs = findElements(body.getElementsByTagName("div"), "suite");
expect(divs.length).toEqual(1);
expect(divs[0].innerHTML).toContain("suite 1");
});
describe('Matcher reporting', function () {
var getResultMessageDiv = function (body) {
var divs = body.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
if (divs[i].className.match(/resultMessage/)) {
return divs[i];
}
}
};
var runner, spec, fakeTimer;
beforeEach(function () {
fakeTimer = new jasmine.FakeTimer();
env.setTimeout = fakeTimer.setTimeout;
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
runner = env.currentRunner();
var suite = new jasmine.Suite(env, 'some suite');
runner.add(suite);
spec = new jasmine.Spec(env, suite, 'some spec');
suite.add(spec);
fakeDocument.location.search = "?";
env.addReporter(trivialReporter);
});
describe('toContain', function () {
it('should show actual and expected', function () {
spec.runs(function () {
this.expect('foo').toContain('bar');
});
runner.execute();
fakeTimer.tick(0);
var resultEl = getResultMessageDiv(body);
expect(resultEl.innerHTML).toMatch(/foo/);
expect(resultEl.innerHTML).toMatch(/bar/);
});
});
});
describe("failure messages (integration)", function () {
var spec, results, expectationResult;
beforeEach(function() {
results = {
passed: function() {
return false;
},
getItems: function() {
}};
var suite1 = new jasmine.Suite(env, "suite 1", null, null);
spec = {
suite: suite1,
getFullName: function() {
return "foo";
},
results: function() {
return results;
}
};
trivialReporter.reportRunnerStarting({
env: env,
suites: function() {
return [ suite1 ];
}
});
});
it("should add the failure message to the DOM (non-toEquals matchers)", function() {
expectationResult = new jasmine.ExpectationResult({
matcherName: "toBeNull", passed: false, message: "Expected 'a' to be null, but it was not"
});
spyOn(results, 'getItems').andReturn([expectationResult]);
trivialReporter.reportSpecResults(spec);
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'resultMessage fail');
expect(errorDiv.innerHTML).toEqual("Expected 'a' to be null, but it was not");
});
it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
expectationResult = new jasmine.ExpectationResult({
matcherName: "toBeNull", passed: false, message: "Expected '1 < 2' to <b>e null, & it was not"
});
spyOn(results, 'getItems').andReturn([expectationResult]);
trivialReporter.reportSpecResults(spec);
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'resultMessage fail');
expect(errorDiv.innerHTML).toEqual("Expected '1 &lt; 2' to &lt;b&gt;e null, &amp; it was not");
});
});
describe("log messages", function() {
it("should appear in the report", function() {
env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this is a", "multipart log message");
});
});
env.addReporter(trivialReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var errorDiv = findElement(divs, 'resultMessage log');
expect(errorDiv.innerHTML).toEqual("this is a multipart log message");
});
xit("should work on IE without console.log.apply", function() {
});
});
describe("duplicate example names", function() {
it("should report failures correctly", function() {
var suite1 = env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this one fails!");
this.expect(true).toBeFalsy();
});
});
var suite2 = env.describe("suite", function() {
env.it("will have log messages", function() {
this.log("this one passes!");
this.expect(true).toBeTruthy();
});
});
env.addReporter(trivialReporter);
env.execute();
var divs = body.getElementsByTagName("div");
var passedSpecDiv = findElement(divs, 'suite passed');
expect(passedSpecDiv.className).toEqual('suite passed');
expect(passedSpecDiv.innerHTML).toContain("this one passes!");
expect(passedSpecDiv.innerHTML).not.toContain("this one fails!");
var failedSpecDiv = findElement(divs, 'suite failed');
expect(failedSpecDiv.className).toEqual('suite failed');
expect(failedSpecDiv.innerHTML).toContain("this one fails!");
expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
});
});
describe('#reportSpecStarting', function() {
var spec1;
beforeEach(function () {
env.describe("suite 1", function() {
spec1 = env.it("spec 1", function() {
});
});
});
it('DOES NOT log running specs by default', function() {
spyOn(trivialReporter, 'log');
trivialReporter.reportSpecStarting(spec1);
expect(trivialReporter.log).not.toHaveBeenCalled();
});
it('logs running specs when log_running_specs is true', function() {
trivialReporter.logRunningSpecs = true;
spyOn(trivialReporter, 'log');
trivialReporter.reportSpecStarting(spec1);
expect(trivialReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
});
});
});
+21
View File
@@ -0,0 +1,21 @@
jasmine_dir:
- 'src'
jasmine_files:
- 'core/base.js'
- 'core/util.js'
- 'core/Reporter.js'
- 'html/HtmlReporterHelpers.js'
- 'core/ExpectationResult.js'
- '**/*.js'
jasmine_css_files:
- 'html/jasmine.css'
src_files:
stylesheets:
helpers:
spec_files:
- 'smoke/performance_test.js'
src_dir:
spec_dir:
- 'spec'
+9 -19
View File
@@ -1,38 +1,28 @@
jasmine_dir:
- 'src'
#This 'magic' inclusion order allows the travis build to pass. #This 'magic' inclusion order allows the travis build to pass.
#TODO: search for the correct files to include to prevent #TODO: search for the correct files to include to prevent
jasmine_files: src_dir:
- 'src'
src_files:
- 'core/base.js' - 'core/base.js'
- 'core/util.js' - 'core/util.js'
- 'core/Reporter.js'
#end of known dependencies #end of known dependencies
- 'core/Spec.js'
- 'core/Env.js' - 'core/Env.js'
- 'core/Block.js'
- 'core/JsApiReporter.js' - 'core/JsApiReporter.js'
- 'core/Matchers.js' - 'core/Matchers.js'
- 'core/mock-timeout.js'
- 'core/MultiReporter.js'
- 'core/NestedResults.js'
- 'core/PrettyPrinter.js' - 'core/PrettyPrinter.js'
- 'core/Queue.js'
- 'core/Runner.js'
- 'core/Spec.js'
- 'core/Suite.js' - 'core/Suite.js'
- 'core/WaitsBlock.js' - 'html/**.js'
- 'core/WaitsForBlock.js'
- 'html/HtmlReporterHelpers.js'
- 'html/HtmlReporter.js'
- '**/*.js' - '**/*.js'
jasmine_css_files:
- 'html/jasmine.css'
src_files:
stylesheets: stylesheets:
boot_dir: 'spec/support'
boot_files:
- 'boot.js'
- 'dev_boot.js'
helpers: helpers:
- 'helpers/**/*.js' - 'helpers/**/*.js'
spec_files: spec_files:
- '**/*[Ss]pec.js' - '**/*[Ss]pec.js'
src_dir:
spec_dir: spec_dir:
- 'spec' - 'spec'
+180
View File
@@ -0,0 +1,180 @@
var fs = require('fs');
var util = require('util');
var path = require('path');
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
// undefined = "diz be undefined yo";
var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k];
}
var env = jasmine.getEnv();
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
addMatchers: function(matchers) {
return env.addMatchers(matchers);
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter(jasmine)
};
for (var k in jasmineInterface) {
global[k] = jasmineInterface[k];
}
require('../src/console/ConsoleReporter.js');
/*
Pulling in code from jasmine-node.
We can't just depend on jasmine-node because it has its own jasmine that it uses.
*/
global.window = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval
};
delete global.window;
function noop() {
}
jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
global.originalJasmine = jasmine;
for (var i = 0, len = specs.length; i < len; ++i) {
var filename = specs[i];
require(filename.replace(/\.\w+$/, ""));
}
var jasmineEnv = jasmine.getEnv();
var consoleReporter = new jasmine.ConsoleReporter({
print: util.print,
onComplete: done,
showColors: showColors
});
jasmineEnv.addReporter(consoleReporter);
jasmineEnv.execute();
};
jasmine.getAllSpecFiles = function(dir, matcher) {
var specs = [];
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
specs.push(dir);
} else {
var files = fs.readdirSync(dir);
for (var i = 0, len = files.length; i < len; ++i) {
var filename = dir + '/' + files[i];
if (fs.statSync(filename).isFile() && filename.match(matcher)) {
specs.push(filename);
} else if (fs.statSync(filename).isDirectory()) {
var subfiles = this.getAllSpecFiles(filename, matcher);
subfiles.forEach(function(result) {
specs.push(result);
});
}
}
}
return specs;
};
function now() {
return new Date().getTime();
}
jasmine.asyncSpecWait = function() {
var wait = jasmine.asyncSpecWait;
wait.start = now();
wait.done = false;
(function innerWait() {
waits(10);
runs(function() {
if (wait.start + wait.timeout < now()) {
expect('timeout waiting for spec').toBeNull();
} else if (wait.done) {
wait.done = false;
} else {
innerWait();
}
});
})();
};
jasmine.asyncSpecWait.timeout = 4 * 1000;
jasmine.asyncSpecDone = function() {
jasmine.asyncSpecWait.done = true;
};
for (var key in jasmine) {
exports[key] = jasmine[key];
}
/*
End jasmine-node runner
*/
var isVerbose = false;
var showColors = true;
process.argv.forEach(function(arg) {
switch (arg) {
case '--color': showColors = true; break;
case '--noColor': showColors = false; break;
case '--verbose': isVerbose = true; break;
}
});
var specs = jasmine.getAllSpecFiles(__dirname + '/smoke/', new RegExp("test.js$"));
var domIndependentSpecs = [];
for (var i = 0; i < specs.length; i++) {
if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) {
domIndependentSpecs.push(specs[i]);
}
}
jasmine.executeSpecs(domIndependentSpecs, function(passed) {
if (passed) {
process.exit(0);
} else {
process.exit(1);
}
}, isVerbose, showColors);
+64 -5
View File
@@ -10,6 +10,58 @@ var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
for (var k in jasmineGlobals) { for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k]; global[k] = jasmineGlobals[k];
} }
var env = jasmine.getEnv();
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
addMatchers: function(matchers) {
return env.addMatchers(matchers);
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
clock: env.clock,
setTimeout: env.clock.setTimeout,
clearTimeout: env.clock.clearTimeout,
setInterval: env.clock.setInterval,
clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter(jasmine)
};
for (var k in jasmineInterface) {
global[k] = jasmineInterface[k];
}
require('../src/console/ConsoleReporter.js'); require('../src/console/ConsoleReporter.js');
/* /*
@@ -31,13 +83,19 @@ function noop() {
} }
jasmine.executeSpecs = function(specs, done, isVerbose, showColors) { jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
global.originalJasmine = jasmine;
for (var i = 0, len = specs.length; i < len; ++i) { for (var i = 0, len = specs.length; i < len; ++i) {
var filename = specs[i]; var filename = specs[i];
require(filename.replace(/\.\w+$/, "")); require(filename.replace(/\.\w+$/, ""));
} }
var jasmineEnv = jasmine.getEnv(); var jasmineEnv = jasmine.getEnv();
var consoleReporter = new jasmine.ConsoleReporter(util.print, done, showColors); var consoleReporter = new jasmine.ConsoleReporter({
print: util.print,
onComplete: done,
showColors: showColors
});
jasmineEnv.addReporter(consoleReporter); jasmineEnv.addReporter(consoleReporter);
jasmineEnv.execute(); jasmineEnv.execute();
@@ -110,16 +168,17 @@ process.argv.forEach(function(arg) {
} }
}); });
var specs = jasmine.getAllSpecFiles(__dirname, new RegExp(".js$")); // var specs = jasmine.getAllSpecFiles(__dirname + '/smoke', new RegExp("test.js$"));
var specs = jasmine.getAllSpecFiles(__dirname, new RegExp("Spec.js$"));
var domIndependentSpecs = []; var domIndependentSpecs = [];
for (var i = 0; i < specs.length; i++) { for (var i = 0; i < specs.length; i++) {
if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) { if (!specs[i].match('html')) {
domIndependentSpecs.push(specs[i]); domIndependentSpecs.push(specs[i]);
} }
} }
jasmine.executeSpecs(domIndependentSpecs, function(runner, log) { jasmine.executeSpecs(domIndependentSpecs, function(passed) {
if (runner.results().failedCount === 0) { if (passed) {
process.exit(0); process.exit(0);
} else { } else {
process.exit(1); process.exit(1);
+23 -52
View File
@@ -1,5 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
<head> <head>
<title>Jasmine Spec Runner: Jasmine Core</title> <title>Jasmine Spec Runner: Jasmine Core</title>
@@ -8,77 +8,48 @@
<link href="../lib/jasmine-core/jasmine.css" rel="stylesheet"/> <link href="../lib/jasmine-core/jasmine.css" rel="stylesheet"/>
<script type="text/javascript" src="../lib/jasmine-core/jasmine.js"></script> <script type="text/javascript" src="../lib/jasmine-core/jasmine.js"></script>
<script type="text/javascript" src="../lib/jasmine-core/jasmine-html.js"></script>
<script type="text/javascript" src="../lib/jasmine-core/boot/boot.js"></script>
<!--This file is not included in jasmine.js - but let's put it here for now -->
<script type="text/javascript" src="../src/console/ConsoleReporter.js"></script>
<script type="text/javascript">
//shim for our tests using originalJasmine.createSpy and the like that should really be using globals defined in boot.
var originalJasmine = jasmine;
</script>
<script type="text/javascript"> <script type="text/javascript">
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw] // yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
undefined = "diz be undefined yo"; undefined = "diz be undefined yo";
</script> </script>
<!-- include source files here... -->
<script type="text/javascript" src=".././src/html/HtmlReporterHelpers.js"></script>
<script type="text/javascript" src=".././src/html/HtmlReporter.js"></script>
<script type="text/javascript" src=".././src/html/HtmlReporterHelpers.js"></script>
<script type="text/javascript" src=".././src/html/ReporterView.js"></script>
<script type="text/javascript" src=".././src/html/SpecView.js"></script>
<script type="text/javascript" src=".././src/html/SuiteView.js"></script>
<script type="text/javascript" src=".././src/html/TrivialReporter.js"></script>
<script type="text/javascript" src=".././src/console/ConsoleReporter.js"></script>
<!-- include spec files here... --> <!-- include spec files here... -->
<script type="text/javascript" src=".././spec/core/BaseSpec.js"></script> <script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ClockSpec.js"></script>
<script type="text/javascript" src=".././spec/core/CustomMatchersSpec.js"></script> <script type="text/javascript" src=".././spec/core/CustomMatchersSpec.js"></script>
<script type="text/javascript" src=".././spec/core/DelayedFunctionSchedulerSpec.js"></script>
<script type="text/javascript" src=".././spec/core/EnvSpec.js"></script> <script type="text/javascript" src=".././spec/core/EnvSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ExceptionFormatterSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ExceptionsSpec.js"></script> <script type="text/javascript" src=".././spec/core/ExceptionsSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ExpectationResultSpec.js"></script>
<script type="text/javascript" src=".././spec/core/JsApiReporterSpec.js"></script> <script type="text/javascript" src=".././spec/core/JsApiReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/core/MatchersSpec.js"></script> <script type="text/javascript" src=".././spec/core/MatchersSpec.js"></script>
<script type="text/javascript" src=".././spec/core/MockClockSpec.js"></script>
<script type="text/javascript" src=".././spec/core/MultiReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/core/NestedResultsSpec.js"></script>
<script type="text/javascript" src=".././spec/core/PrettyPrintSpec.js"></script> <script type="text/javascript" src=".././spec/core/PrettyPrintSpec.js"></script>
<script type="text/javascript" src=".././spec/core/QueueSpec.js"></script> <script type="text/javascript" src=".././spec/core/QueueRunnerSpec.js"></script>
<script type="text/javascript" src=".././spec/core/ReporterSpec.js"></script> <script type="text/javascript" src=".././spec/core/ReportDispatcherSpec.js"></script>
<script type="text/javascript" src=".././spec/core/RunnerSpec.js"></script>
<script type="text/javascript" src=".././spec/core/SpecRunningSpec.js"></script> <script type="text/javascript" src=".././spec/core/SpecRunningSpec.js"></script>
<script type="text/javascript" src=".././spec/core/SpecSpec.js"></script> <script type="text/javascript" src=".././spec/core/SpecSpec.js"></script>
<script type="text/javascript" src=".././spec/core/SpySpec.js"></script> <script type="text/javascript" src=".././spec/core/SpySpec.js"></script>
<script type="text/javascript" src=".././spec/core/SuiteSpec.js"></script> <script type="text/javascript" src=".././spec/core/SuiteSpec.js"></script>
<script type="text/javascript" src=".././spec/core/UtilSpec.js"></script> <script type="text/javascript" src=".././spec/core/UtilSpec.js"></script>
<script type="text/javascript" src=".././spec/core/WaitsForBlockSpec.js"></script>
<script type="text/javascript" src=".././spec/html/HTMLReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/html/MatchersHtmlSpec.js"></script> <script type="text/javascript" src=".././spec/html/MatchersHtmlSpec.js"></script>
<script type="text/javascript" src="html/HtmlReporterSpec.js"></script>
<script type="text/javascript" src=".././spec/html/PrettyPrintHtmlSpec.js"></script> <script type="text/javascript" src=".././spec/html/PrettyPrintHtmlSpec.js"></script>
<script type="text/javascript" src=".././spec/html/TrivialReporterSpec.js"></script> <script type="text/javascript" src=".././spec/html/QueryStringSpec.js"></script>
<script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script> <script type="text/javascript" src=".././spec/html/ResultsNodeSpec.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head> </head>
<body> <body>
+10
View File
@@ -0,0 +1,10 @@
describe("performance", function() {
for (var i = 0; i < 10000; i++) {
it("should pass", function() {
expect(true).toBe(true);
});
it("should fail", function() {
expect(true).toBe(false);
});
}
});
+1
View File
@@ -0,0 +1 @@
../../lib/jasmine-core/boot/boot.js
+2
View File
@@ -0,0 +1,2 @@
var originalJasmine = jasmine;
jasmine = null;
+1
View File
@@ -14,6 +14,7 @@
<%= spec_file_tags %> <%= spec_file_tags %>
<script type="text/javascript"> <script type="text/javascript">
//hello
(function() { (function() {
var jasmineEnv = jasmine.getEnv(); var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000; jasmineEnv.updateInterval = 1000;
+64 -137
View File
@@ -1,55 +1,72 @@
jasmine.ConsoleReporter = function(print, doneCallback, showColors) { jasmine.ConsoleReporter = function(options) {
//inspired by mhevery's jasmine-node reporter var print = options.print,
//https://github.com/mhevery/jasmine-node showColors = options.showColors || false,
onComplete = options.onComplete || function() {},
doneCallback = doneCallback || function() {}; now = options.now || function() { return new Date().getTime();},
startTime = 0,
var ansi = { specCount,
failureCount,
failedSpecs = [],
ansi = {
green: '\033[32m', green: '\033[32m',
red: '\033[31m', red: '\033[31m',
yellow: '\033[33m', yellow: '\033[33m',
none: '\033[0m' none: '\033[0m'
},
language = {
spec: "spec",
failure: "failure"
}; };
function coloredStr(color, str) { this.jasmineStarted = function() {
return showColors ? (ansi[color] + str + ansi.none) : str; startTime = now();
} specCount = 0;
failureCount = 0;
print("Started");
printNewline();
};
function greenStr(str) { this.jasmineDone = function() {
return coloredStr("green", str); var elapsed = now() - startTime;
}
function redStr(str) { printNewline();
return coloredStr("red", str); for (var i = 0; i < failedSpecs.length; i++) {
} specFailureDetails(failedSpecs[i]);
}
function yellowStr(str) { printNewline();
return coloredStr("yellow", str); var specCounts = specCount + " " + plural("spec", specCount) + ", " +
} failureCount + " " + plural("failure", failureCount);
print(specCounts);
function newline() { printNewline();
var seconds = elapsed / 1000;
print("Finished in " + seconds + " " + plural("second", seconds));
printNewline();
onComplete();
};
this.specDone = function(result) {
specCount++;
if (result.status == "passed") {
print(colored("green", '.'));
return;
}
if (result.status == "failed") {
failureCount++;
failedSpecs.push(result);
print(colored("red", 'F'));
}
};
return this;
function printNewline() {
print("\n"); print("\n");
} }
function started() { function colored(color, str) {
print("Started"); return showColors ? (ansi[color] + str + ansi.none) : str;
newline();
}
function greenDot() {
print(greenStr("."));
}
function redF() {
print(redStr("F"));
}
function yellowStar() {
print(yellowStr("*"));
} }
function plural(str, count) { function plural(str, count) {
@@ -73,106 +90,16 @@ jasmine.ConsoleReporter = function(print, doneCallback, showColors) {
return newArr.join("\n"); return newArr.join("\n");
} }
function specFailureDetails(suiteDescription, specDescription, stackTraces) { function specFailureDetails(result) {
newline(); printNewline();
print(suiteDescription + " " + specDescription); print(result.fullName);
newline();
for (var i = 0; i < stackTraces.length; i++) {
print(indent(stackTraces[i], 2));
newline();
}
}
function finished(elapsed) { for (var i = 0; i < result.failedExpectations.length; i++) {
newline(); var failedExpectation = result.failedExpectations[i];
print("Finished in " + elapsed / 1000 + " seconds"); printNewline();
} print(indent(failedExpectation.trace.stack, 2));
function summary(colorF, specs, failed) {
newline();
print(colorF(specs + " " + plural(language.spec, specs) + ", " +
failed + " " + plural(language.failure, failed)));
newline();
newline();
}
function greenSummary(specs, failed) {
summary(greenStr, specs, failed);
}
function redSummary(specs, failed) {
summary(redStr, specs, failed);
}
function fullSuiteDescription(suite) {
var fullDescription = suite.description;
if (suite.parentSuite) fullDescription = fullSuiteDescription(suite.parentSuite) + " " + fullDescription;
return fullDescription;
}
this.now = function() {
return new Date().getTime();
};
this.reportRunnerStarting = function() {
this.runnerStartTime = this.now();
started();
};
this.reportSpecStarting = function() { /* do nothing */
};
this.reportSpecResults = function(spec) {
var results = spec.results();
if (results.skipped) {
yellowStar();
} else if (results.passed()) {
greenDot();
} else {
redF();
}
};
this.suiteResults = [];
this.reportSuiteResults = function(suite) {
var suiteResult = {
description: fullSuiteDescription(suite),
failedSpecResults: []
};
for(var i = 0; i < suite.results().items_.length; i++) {
var spec = suite.results().items_[i];
if (spec.failedCount > 0 && spec.description) suiteResult.failedSpecResults.push(spec);
} }
this.suiteResults.push(suiteResult); printNewline();
};
function eachSpecFailure(suiteResults, callback) {
for (var i = 0; i < suiteResults.length; i++) {
var suiteResult = suiteResults[i];
for (var j = 0; j < suiteResult.failedSpecResults.length; j++) {
var failedSpecResult = suiteResult.failedSpecResults[j];
var stackTraces = [];
for (var k = 0; k < failedSpecResult.items_.length; k++) stackTraces.push(failedSpecResult.items_[k].trace.stack);
callback(suiteResult.description, failedSpecResult.description, stackTraces);
}
}
} }
this.reportRunnerResults = function(runner) {
newline();
eachSpecFailure(this.suiteResults, function(suiteDescription, specDescription, stackTraces) {
specFailureDetails(suiteDescription, specDescription, stackTraces);
});
finished(this.now() - this.runnerStartTime);
var results = runner.results();
var summaryFunction = results.failedCount === 0 ? greenSummary : redSummary;
summaryFunction(runner.specs().length, results.failedCount);
doneCallback(runner);
};
}; };
-27
View File
@@ -1,27 +0,0 @@
/**
* Blocks are functions with executable code that make up a spec.
*
* @constructor
* @param {jasmine.Env} env
* @param {Function} func
* @param {jasmine.Spec} spec
*/
jasmine.Block = function(env, func, spec) {
this.env = env;
this.func = func;
this.spec = spec;
};
jasmine.Block.prototype.execute = function(onComplete) {
if (!jasmine.CATCH_EXCEPTIONS) {
this.func.apply(this.spec);
}
else {
try {
this.func.apply(this.spec);
} catch (e) {
this.spec.fail(e);
}
}
onComplete();
};
+93
View File
@@ -0,0 +1,93 @@
jasmine.Clock = function(global, delayedFunctionScheduler) {
var self = this,
realTimingFunctions = {
setTimeout: global.setTimeout,
clearTimeout: global.clearTimeout,
setInterval: global.setInterval,
clearInterval: global.clearInterval
},
fakeTimingFunctions = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval
},
timer = realTimingFunctions,
installed = false;
self.install = function() {
installed = true;
timer = fakeTimingFunctions;
};
self.uninstall = function() {
delayedFunctionScheduler.reset();
installed = false;
timer = realTimingFunctions;
};
self.setTimeout = function(fn, delay, params) {
if (legacyIE()) {
if (arguments.length > 2) {
throw new Error("IE < 9 cannot support extra params to setTimeout without a polyfill");
}
return timer.setTimeout(fn, delay);
}
return timer.setTimeout.apply(null, arguments);
};
self.setInterval = function(fn, delay, params) {
if (legacyIE()) {
if (arguments.length > 2) {
throw new Error("IE < 9 cannot support extra params to setInterval without a polyfill");
}
return timer.setInterval(fn, delay);
}
return timer.setInterval.apply(null, arguments);
};
self.clearTimeout = function(id) {
return timer.clearTimeout(id);
};
self.clearInterval = function(id) {
return timer.clearInterval(id);
};
self.tick = function(millis) {
if (installed) {
delayedFunctionScheduler.tick(millis)
} else {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
}
};
return self;
function legacyIE() {
//if these methods are polyfilled, apply will be present
//TODO: it may be difficult to load the polyfill before jasmine loads
//(env should be new-ed inside of onload)
return !(global.setTimeout || global.setInterval).apply;
}
function setTimeout(fn, delay) {
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
}
function clearTimeout(id) {
return delayedFunctionScheduler.removeFunctionWithId(id);
}
function setInterval(fn, interval) {
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
}
function clearInterval(id) {
return delayedFunctionScheduler.removeFunctionWithId(id);
}
function argSlice(argsObj, n) {
return Array.prototype.slice.call(argsObj, 2);
}
};
+102
View File
@@ -0,0 +1,102 @@
jasmine.DelayedFunctionScheduler = function() {
var self = this;
var scheduledFunctions = {};
var currentTime = 0;
var delayedFnCount = 0;
self.tick = function(millis) {
runFunctionsWithinRange(currentTime, currentTime + millis);
currentTime = currentTime + millis;
};
self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
timeoutKey = timeoutKey || ++delayedFnCount;
runAtMillis = runAtMillis || (currentTime + millis);
scheduledFunctions[timeoutKey] = {
runAtMillis: runAtMillis,
funcToCall: funcToCall,
recurring: recurring,
params: params,
timeoutKey: timeoutKey,
millis: millis
};
return timeoutKey;
};
self.removeFunctionWithId = function(timeoutKey) {
delete scheduledFunctions[timeoutKey];
};
self.reset = function() {
currentTime = 0;
scheduledFunctions = {};
delayedFnCount = 0;
};
return self;
//finds/dupes functions within range and removes them.
function functionsWithinRange(startMillis, endMillis) {
var fnsToRun = [];
for (var timeoutKey in scheduledFunctions) {
var scheduledFunc = scheduledFunctions[timeoutKey];
if (scheduledFunc &&
scheduledFunc.runAtMillis >= startMillis &&
scheduledFunc.runAtMillis <= endMillis) {
//remove fn -- we'll reschedule later if it is recurring.
self.removeFunctionWithId(timeoutKey);
if (!scheduledFunc.recurring) {
fnsToRun.push(scheduledFunc); // schedules each function only once
} else {
fnsToRun.push(buildNthInstanceOf(scheduledFunc, 0));
var additionalTimesFnRunsInRange =
Math.floor((endMillis - scheduledFunc.runAtMillis) / scheduledFunc.millis);
for (var i = 0; i < additionalTimesFnRunsInRange; i++) {
fnsToRun.push(buildNthInstanceOf(scheduledFunc, i + 1));
}
reschedule(buildNthInstanceOf(scheduledFunc, additionalTimesFnRunsInRange));
}
}
}
return fnsToRun;
}
function buildNthInstanceOf(scheduledFunc, n) {
return {
runAtMillis: scheduledFunc.runAtMillis + (scheduledFunc.millis * n),
funcToCall: scheduledFunc.funcToCall,
params: scheduledFunc.params,
millis: scheduledFunc.millis,
recurring: scheduledFunc.recurring,
timeoutKey: scheduledFunc.timeoutKey
};
}
function reschedule(scheduledFn) {
self.scheduleFunction(scheduledFn.funcToCall,
scheduledFn.millis,
scheduledFn.params,
true,
scheduledFn.timeoutKey,
scheduledFn.runAtMillis + scheduledFn.millis);
}
function runFunctionsWithinRange(startMillis, endMillis) {
var funcsToRun = functionsWithinRange(startMillis, endMillis);
if (funcsToRun.length === 0) {
return;
}
funcsToRun.sort(function(a, b) {
return a.runAtMillis - b.runAtMillis;
});
for (var i = 0; i < funcsToRun.length; ++i) {
var funcToRun = funcsToRun[i];
funcToRun.funcToCall.apply(null, funcToRun.params);
}
}
};
+443 -272
View File
@@ -1,300 +1,471 @@
/** (function() {
* Environment for Jasmine jasmine.Env = function(options) {
* options = options || {};
* @constructor var self = this;
*/ var global = options.global || jasmine.getGlobal();
jasmine.Env = function() {
this.currentSpec = null;
this.currentSuite = null;
this.currentRunner_ = new jasmine.Runner(this);
this.reporter = new jasmine.MultiReporter(); var catchExceptions = true;
this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; this.clock = new jasmine.Clock(global, new jasmine.DelayedFunctionScheduler());
this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
this.lastUpdate = 0;
this.specFilter = function() {
return true;
};
this.nextSpecId_ = 0; this.jasmine = jasmine;
this.nextSuiteId_ = 0; this.spies_ = [];
this.equalityTesters_ = []; this.currentSpec = null;
// wrap matchers this.undefined = jasmine.undefined;
this.matchersClass = function() {
jasmine.Matchers.apply(this, arguments);
};
jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); this.reporter = new jasmine.ReportDispatcher([
}; "jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
this.lastUpdate = 0;
this.specFilter = function() {
return true;
};
this.nextSpecId_ = 0;
this.nextSuiteId_ = 0;
this.equalityTesters_ = [];
// wrap matchers
this.matchersClass = function() {
jasmine.Matchers.apply(this, arguments);
};
jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
var expectationFactory = function(actual, spec) {
var expect = new (self.matchersClass)(self, actual, spec);
expect.not = new (self.matchersClass)(self, actual, spec, true);
return expect;
};
var specStarted = function(spec) {
self.currentSpec = spec;
self.reporter.specStarted(spec.result);
};
var beforeFns = function(currentSuite) {
return function() {
var befores = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) {
befores = befores.concat(suite.beforeFns)
}
return befores.reverse();
}
};
var afterFns = function(currentSuite) {
return function() {
var afters = [];
for (var suite = currentSuite; suite; suite = suite.parentSuite) {
afters = afters.concat(suite.afterFns)
}
return afters;
}
};
var exceptionFormatter = jasmine.exceptionFormatter;
var specConstructor = jasmine.Spec;
var getSpecName = function(spec, currentSuite) {
return currentSuite.getFullName() + ' ' + spec.description + '.';
};
var buildExpectationResult = jasmine.buildExpectationResult;
var expectationResultFactory = function(attrs) {
return buildExpectationResult(attrs);
};
// TODO: fix this naming, and here's where the value comes in
this.catchExceptions = function(value) {
catchExceptions = !!value;
return catchExceptions;
};
this.catchingExceptions = function() {
return catchExceptions;
};
var maximumSpecCallbackDepth = 100;
var currentSpecCallbackDepth = 0;
function encourageGarbageCollection(fn) {
currentSpecCallbackDepth++;
if (currentSpecCallbackDepth > maximumSpecCallbackDepth) {
currentSpecCallbackDepth = 0;
global.setTimeout(fn, 0);
} else {
fn();
}
}
var queueRunnerFactory = function(options) {
options.catchingExceptions = self.catchingExceptions;
options.encourageGC = options.encourageGarbageCollection || encourageGarbageCollection;
new jasmine.QueueRunner(options).run(options.fns, 0);
};
jasmine.Env.prototype.setTimeout = jasmine.setTimeout; var totalSpecsDefined = 0;
jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; this.specFactory = function(description, fn, suite) {
jasmine.Env.prototype.setInterval = jasmine.setInterval; totalSpecsDefined++;
jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
/** var spec = new specConstructor({
* @returns an object containing jasmine version build info, if set. id: self.nextSpecId(),
*/ beforeFns: beforeFns(suite),
jasmine.Env.prototype.version = function () { afterFns: afterFns(suite),
if (jasmine.version_) { expectationFactory: expectationFactory,
return jasmine.version_; exceptionFormatter: exceptionFormatter,
} else { resultCallback: specResultCallback,
throw new Error('Version not set'); getSpecName: function(spec) {
} return getSpecName(spec, suite)
}; },
onStart: specStarted,
description: description,
expectationResultFactory: expectationResultFactory,
queueRunner: queueRunnerFactory,
fn: fn
});
/** if (!self.specFilter(spec)) {
* @returns string containing jasmine version build info, if set. spec.disable();
*/ }
jasmine.Env.prototype.versionString = function() {
if (!jasmine.version_) {
return "version unknown";
}
var version = this.version(); return spec;
var versionString = version.major + "." + version.minor + "." + version.build;
if (version.release_candidate) {
versionString += ".rc" + version.release_candidate;
}
versionString += " revision " + version.revision;
return versionString;
};
/** function specResultCallback(result) {
* @returns a sequential integer starting at 0 self.removeAllSpies();
*/ self.clock.uninstall();
jasmine.Env.prototype.nextSpecId = function () { self.currentSpec = null;
return this.nextSpecId_++; self.reporter.specDone(result);
}; }
};
/** var suiteStarted = function(suite) {
* @returns a sequential integer starting at 0 self.reporter.suiteStarted(suite.result);
*/ };
jasmine.Env.prototype.nextSuiteId = function () {
return this.nextSuiteId_++;
};
/** var suiteConstructor = jasmine.Suite;
* Register a reporter to receive status updates from Jasmine.
* @param {jasmine.Reporter} reporter An object which will receive status updates.
*/
jasmine.Env.prototype.addReporter = function(reporter) {
this.reporter.addReporter(reporter);
};
jasmine.Env.prototype.execute = function() { this.topSuite = new jasmine.Suite({
this.currentRunner_.execute(); env: this,
}; id: this.nextSuiteId(),
description: 'Jasmine__TopLevel__Suite',
jasmine.Env.prototype.describe = function(description, specDefinitions) { queueRunner: queueRunnerFactory,
var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); completeCallback: function() {}, // TODO - hook this up
resultCallback: function() {} // TODO - hook this up
var parentSuite = this.currentSuite;
if (parentSuite) {
parentSuite.add(suite);
} else {
this.currentRunner_.add(suite);
}
this.currentSuite = suite;
var declarationError = null;
try {
specDefinitions.call(suite);
} catch(e) {
declarationError = e;
}
if (declarationError) {
this.it("encountered a declaration exception", function() {
throw declarationError;
}); });
} this.currentSuite = this.topSuite;
this.currentSuite = parentSuite; this.suiteFactory = function(description) {
return new suiteConstructor({
env: self,
id: self.nextSuiteId(),
description: description,
parentSuite: self.currentSuite,
queueRunner: queueRunnerFactory,
onStart: suiteStarted,
resultCallback: function(attrs) {
self.reporter.suiteDone(attrs);
}
});
};
return suite; this.execute = function() {
}; this.reporter.jasmineStarted({
totalSpecsDefined: totalSpecsDefined
});
this.topSuite.execute(this.reporter.jasmineDone);
};
};
jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { //TODO: shim Spec addMatchers behavior into Env. Should be rewritten to remove globals, etc.
if (this.currentSuite) { jasmine.Env.prototype.addMatchers = function(matchersPrototype) {
var parent = this.matchersClass;
var newMatchersClass = function() {
parent.apply(this, arguments);
};
jasmine.util.inherit(newMatchersClass, parent);
jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
this.matchersClass = newMatchersClass;
};
jasmine.Env.prototype.version = function() {
if (this.jasmine.version_) {
return this.jasmine.version_;
} else {
throw new Error('Version not set');
}
};
jasmine.Env.prototype.expect = function(actual) {
return this.currentSpec.expect(actual);
};
jasmine.Env.prototype.spyOn = function(obj, methodName) {
if (obj == this.undefined) {
throw "spyOn could not find an object to spy upon for " + methodName + "()";
}
if (obj[methodName] === this.undefined) {
throw methodName + '() method does not exist';
}
if (obj[methodName] && obj[methodName].isSpy) {
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
throw new Error(methodName + ' has already been spied upon');
}
var spyObj = jasmine.createSpy(methodName);
this.spies_.push(spyObj);
spyObj.baseObj = obj;
spyObj.methodName = methodName;
spyObj.originalValue = obj[methodName];
obj[methodName] = spyObj;
return spyObj;
};
// TODO: move this to closure
jasmine.Env.prototype.removeAllSpies = function() {
for (var i = 0; i < this.spies_.length; i++) {
var spy = this.spies_[i];
spy.baseObj[spy.methodName] = spy.originalValue;
}
this.spies_ = [];
};
// TODO: move this to closure
jasmine.Env.prototype.versionString = function() {
if (!this.jasmine.version_) {
return "version unknown";
}
var version = this.version();
var versionString = version.major + "." + version.minor + "." + version.build;
if (version.release_candidate) {
versionString += ".rc" + version.release_candidate;
}
versionString += " revision " + version.revision;
return versionString;
};
// TODO: move this to closure
jasmine.Env.prototype.nextSpecId = function() {
return this.nextSpecId_++;
};
// TODO: move this to closure
jasmine.Env.prototype.nextSuiteId = function() {
return this.nextSuiteId_++;
};
// TODO: move this to closure
jasmine.Env.prototype.addReporter = function(reporter) {
this.reporter.addReporter(reporter);
};
// TODO: move this to closure
jasmine.Env.prototype.describe = function(description, specDefinitions) {
var suite = this.suiteFactory(description, specDefinitions);
var parentSuite = this.currentSuite;
parentSuite.addSuite(suite);
this.currentSuite = suite;
var declarationError = null;
try {
specDefinitions.call(suite);
} catch (e) {
declarationError = e;
}
if (declarationError) {
this.it("encountered a declaration exception", function() {
throw declarationError;
});
}
this.currentSuite = parentSuite;
return suite;
};
// TODO: move this to closure
jasmine.Env.prototype.xdescribe = function(description, specDefinitions) {
var suite = this.describe(description, specDefinitions);
suite.disable();
return suite;
};
// TODO: move this to closure
jasmine.Env.prototype.it = function(description, fn) {
var spec = this.specFactory(description, fn, this.currentSuite);
this.currentSuite.addSpec(spec);
return spec;
};
// TODO: move this to closure
jasmine.Env.prototype.xit = function(description, fn) {
var spec = this.it(description, fn);
spec.disable();
return spec;
};
// TODO: move this to closure
jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
this.currentSuite.beforeEach(beforeEachFunction); this.currentSuite.beforeEach(beforeEachFunction);
} else { };
this.currentRunner_.beforeEach(beforeEachFunction);
}
};
jasmine.Env.prototype.currentRunner = function () { // TODO: move this to closure
return this.currentRunner_; jasmine.Env.prototype.afterEach = function(afterEachFunction) {
};
jasmine.Env.prototype.afterEach = function(afterEachFunction) {
if (this.currentSuite) {
this.currentSuite.afterEach(afterEachFunction); this.currentSuite.afterEach(afterEachFunction);
} else {
this.currentRunner_.afterEach(afterEachFunction);
}
};
jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
return {
execute: function() {
}
};
};
jasmine.Env.prototype.it = function(description, func) {
var spec = new jasmine.Spec(this, this.currentSuite, description);
this.currentSuite.add(spec);
this.currentSpec = spec;
if (func) {
spec.runs(func);
}
return spec;
};
jasmine.Env.prototype.xit = function(desc, func) {
return {
id: this.nextSpecId(),
runs: function() {
}
};
};
jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
if (a.source != b.source)
mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
if (a.ignoreCase != b.ignoreCase)
mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
if (a.global != b.global)
mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
if (a.multiline != b.multiline)
mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
if (a.sticky != b.sticky)
mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
return (mismatchValues.length === 0);
};
jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
return true;
}
a.__Jasmine_been_here_before__ = b;
b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) {
return obj !== null && obj[keyName] !== jasmine.undefined;
}; };
for (var property in b) { // TODO: Still needed?
if (!hasKey(a, property) && hasKey(b, property)) { jasmine.Env.prototype.currentRunner = function() {
mismatchKeys.push("expected has key '" + property + "', but missing from actual."); return this.topSuite;
};
jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
if (a.source != b.source)
mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
if (a.ignoreCase != b.ignoreCase)
mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
if (a.global != b.global)
mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
if (a.multiline != b.multiline)
mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
if (a.sticky != b.sticky)
mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
return (mismatchValues.length === 0);
};
jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
return true;
} }
}
for (property in a) { a.__Jasmine_been_here_before__ = b;
if (!hasKey(b, property) && hasKey(a, property)) { b.__Jasmine_been_here_before__ = a;
mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
var hasKey = function(obj, keyName) {
return obj !== null && obj[keyName] !== this.undefined;
};
for (var property in b) {
if (!hasKey(a, property) && hasKey(b, property)) {
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
}
} }
} for (property in a) {
for (property in b) { if (!hasKey(b, property) && hasKey(a, property)) {
if (property == '__Jasmine_been_here_before__') continue; mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { }
mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
} }
} for (property in b) {
if (property == '__Jasmine_been_here_before__') continue;
if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
mismatchValues.push("arrays were not the same length"); mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
} }
delete a.__Jasmine_been_here_before__;
delete b.__Jasmine_been_here_before__;
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
};
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
mismatchKeys = mismatchKeys || [];
mismatchValues = mismatchValues || [];
for (var i = 0; i < this.equalityTesters_.length; i++) {
var equalityTester = this.equalityTesters_[i];
var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
if (result !== jasmine.undefined) return result;
}
if (a === b) return true;
if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
return (a == jasmine.undefined && b == jasmine.undefined);
}
if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
return a === b;
}
if (a instanceof Date && b instanceof Date) {
return a.getTime() == b.getTime();
}
if (a.jasmineMatches) {
return a.jasmineMatches(b);
}
if (b.jasmineMatches) {
return b.jasmineMatches(a);
}
if (a instanceof jasmine.Matchers.ObjectContaining) {
return a.matches(b);
}
if (b instanceof jasmine.Matchers.ObjectContaining) {
return b.matches(a);
}
if (jasmine.isString_(a) && jasmine.isString_(b)) {
return (a == b);
}
if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
return (a == b);
}
if (a instanceof RegExp && b instanceof RegExp) {
return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
}
if (typeof a === "object" && typeof b === "object") {
return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
}
//Straight check
return (a === b);
};
jasmine.Env.prototype.contains_ = function(haystack, needle) {
if (jasmine.isArray_(haystack)) {
for (var i = 0; i < haystack.length; i++) {
if (this.equals_(haystack[i], needle)) return true;
} }
return false;
}
return haystack.indexOf(needle) >= 0;
};
jasmine.Env.prototype.addEqualityTester = function(equalityTester) { if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
this.equalityTesters_.push(equalityTester); mismatchValues.push("arrays were not the same length");
}; }
delete a.__Jasmine_been_here_before__;
delete b.__Jasmine_been_here_before__;
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
};
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
mismatchKeys = mismatchKeys || [];
mismatchValues = mismatchValues || [];
for (var i = 0; i < this.equalityTesters_.length; i++) {
var equalityTester = this.equalityTesters_[i];
var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
if (result !== this.undefined) return result;
}
if (a === b) return true;
if (a === this.undefined || a === null || b === this.undefined || b === null) {
return (a == this.undefined && b == this.undefined);
}
if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
return a === b;
}
if (a instanceof Date && b instanceof Date) {
return a.getTime() == b.getTime();
}
if (a.jasmineMatches) {
return a.jasmineMatches(b);
}
if (b.jasmineMatches) {
return b.jasmineMatches(a);
}
if (a instanceof jasmine.Matchers.ObjectContaining) {
return a.matches(b);
}
if (b instanceof jasmine.Matchers.ObjectContaining) {
return b.matches(a);
}
if (jasmine.isString_(a) && jasmine.isString_(b)) {
return (a == b);
}
if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
return (a == b);
}
if (a instanceof RegExp && b instanceof RegExp) {
return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
}
if (typeof a === "object" && typeof b === "object") {
return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
}
//Straight check
return (a === b);
};
jasmine.Env.prototype.contains_ = function(haystack, needle) {
if (jasmine.isArray_(haystack)) {
for (var i = 0; i < haystack.length; i++) {
if (this.equals_(haystack[i], needle)) return true;
}
return false;
}
return haystack.indexOf(needle) >= 0;
};
jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
this.equalityTesters_.push(equalityTester);
};
}());
+12
View File
@@ -0,0 +1,12 @@
jasmine.exceptionMessageFor = function(e) {
var message = e.name
+ ': '
+ e.message
+ ' in '
+ (e.fileName || e.sourceURL || '')
+ ' (line '
+ (e.line || e.lineNumber || '')
+ ')';
return message;
};
+12
View File
@@ -0,0 +1,12 @@
//TODO: expectation result may make more sense as a presentation of an expectation.
jasmine.buildExpectationResult = function(params) {
return {
type: 'expect',
matcherName: params.matcherName,
expected: params.expected,
actual: params.actual,
message: params.passed ? 'Passed.' : params.message,
trace: params.passed ? '' : (params.trace || new Error(this.message)),
passed: params.passed
};
};
+48 -90
View File
@@ -1,102 +1,60 @@
/** JavaScript API reporter. jasmine.JsApiReporter = function(jasmine) {
* this.jasmine = jasmine || {};
* @constructor
*/
jasmine.JsApiReporter = function() {
this.started = false; this.started = false;
this.finished = false; this.finished = false;
this.suites_ = []; this.suites_ = [];
this.results_ = {}; this.results_ = {};
};
jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { var status = 'loaded';
this.started = true;
var suites = runner.topLevelSuites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
this.suites_.push(this.summarize_(suite));
}
};
jasmine.JsApiReporter.prototype.suites = function() { this.jasmineStarted = function() {
return this.suites_; this.started = true;
}; status = 'started';
jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
var isSuite = suiteOrSpec instanceof jasmine.Suite;
var summary = {
id: suiteOrSpec.id,
name: suiteOrSpec.description,
type: isSuite ? 'suite' : 'spec',
children: []
}; };
if (isSuite) { this.jasmineDone = function() {
var children = suiteOrSpec.children(); this.finished = true;
for (var i = 0; i < children.length; i++) { status = 'done';
summary.children.push(this.summarize_(children[i]));
}
}
return summary;
};
jasmine.JsApiReporter.prototype.results = function() {
return this.results_;
};
jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
return this.results_[specId];
};
//noinspection JSUnusedLocalSymbols
jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
this.finished = true;
};
//noinspection JSUnusedLocalSymbols
jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
};
//noinspection JSUnusedLocalSymbols
jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
this.results_[spec.id] = {
messages: spec.results().getItems(),
result: spec.results().failedCount > 0 ? "failed" : "passed"
}; };
};
//noinspection JSUnusedLocalSymbols this.status = function() {
jasmine.JsApiReporter.prototype.log = function(str) { return status;
};
jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
var results = {};
for (var i = 0; i < specIds.length; i++) {
var specId = specIds[i];
results[specId] = this.summarizeResult_(this.results_[specId]);
}
return results;
};
jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
var summaryMessages = [];
var messagesLength = result.messages.length;
for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
var resultMessage = result.messages[messageIndex];
summaryMessages.push({
text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
passed: resultMessage.passed ? resultMessage.passed() : true,
type: resultMessage.type,
message: resultMessage.message,
trace: {
stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
}
});
}
return {
result : result.result,
messages : summaryMessages
}; };
};
var suites = {};
this.suiteStarted = function(result) {
storeSuite(result);
};
this.suiteDone = function(result) {
storeSuite(result);
};
function storeSuite(result) {
suites[result.id] = result;
}
this.suites = function() {
return suites;
};
var specs = {};
this.specStarted = function(result) {
storeSpec(result);
};
this.specDone = function(result) {
storeSpec(result);
};
function storeSpec(result) {
specs[result.id] = result;
}
this.specs = function() {
return specs;
};
};
+3 -10
View File
@@ -5,11 +5,11 @@
* @param {jasmine.Spec} spec * @param {jasmine.Spec} spec
*/ */
jasmine.Matchers = function(env, actual, spec, opt_isNot) { jasmine.Matchers = function(env, actual, spec, opt_isNot) {
//TODO: true dependency: equals, contains
this.env = env; this.env = env;
this.actual = actual; this.actual = actual;
this.spec = spec; this.spec = spec;
this.isNot = opt_isNot || false; this.isNot = opt_isNot || false;
this.reportWasCalled_ = false;
}; };
// todo: @deprecated as of Jasmine 0.11, remove soon [xw] // todo: @deprecated as of Jasmine 0.11, remove soon [xw]
@@ -17,14 +17,9 @@ jasmine.Matchers.pp = function(str) {
throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
}; };
// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
jasmine.Matchers.prototype.report = function(result, failing_message, details) {
throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
};
jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
for (var methodName in prototype) { for (var methodName in prototype) {
if (methodName == 'report') continue;
var orig = prototype[methodName]; var orig = prototype[methodName];
matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
} }
@@ -39,8 +34,6 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
result = !result; result = !result;
} }
if (this.reportWasCalled_) return result;
var message; var message;
if (!result) { if (!result) {
if (this.message) { if (this.message) {
@@ -60,14 +53,14 @@ jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
message += "."; message += ".";
} }
} }
var expectationResult = new jasmine.ExpectationResult({ var expectationResult = jasmine.buildExpectationResult({
matcherName: matcherName, matcherName: matcherName,
passed: result, passed: result,
expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
actual: this.actual, actual: this.actual,
message: message message: message
}); });
this.spec.addMatcherResult(expectationResult); this.spec.addExpectationResult(result, expectationResult);
return jasmine.undefined; return jasmine.undefined;
}; };
}; };
-35
View File
@@ -1,35 +0,0 @@
/**
* @constructor
*/
jasmine.MultiReporter = function() {
this.subReporters_ = [];
};
jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
jasmine.MultiReporter.prototype.addReporter = function(reporter) {
this.subReporters_.push(reporter);
};
(function() {
var functionNames = [
"reportRunnerStarting",
"reportRunnerResults",
"reportSuiteResults",
"reportSpecStarting",
"reportSpecResults",
"log"
];
for (var i = 0; i < functionNames.length; i++) {
var functionName = functionNames[i];
jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
return function() {
for (var j = 0; j < this.subReporters_.length; j++) {
var subReporter = this.subReporters_[j];
if (subReporter[functionName]) {
subReporter[functionName].apply(subReporter, arguments);
}
}
};
})(functionName);
}
})();
-80
View File
@@ -1,80 +0,0 @@
/**
* Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
*
* @constructor
*/
jasmine.NestedResults = function() {
/**
* The total count of results
*/
this.totalCount = 0;
/**
* Number of passed results
*/
this.passedCount = 0;
/**
* Number of failed results
*/
this.failedCount = 0;
/**
* Was this suite/spec skipped?
*/
this.skipped = false;
/**
* @ignore
*/
this.items_ = [];
};
/**
* Roll up the result counts.
*
* @param result
*/
jasmine.NestedResults.prototype.rollupCounts = function(result) {
this.totalCount += result.totalCount;
this.passedCount += result.passedCount;
this.failedCount += result.failedCount;
};
/**
* Adds a log message.
* @param values Array of message parts which will be concatenated later.
*/
jasmine.NestedResults.prototype.log = function(values) {
this.items_.push(new jasmine.MessageResult(values));
};
/**
* Getter for the results: message & results.
*/
jasmine.NestedResults.prototype.getItems = function() {
return this.items_;
};
/**
* Adds a result, tracking counts (total, passed, & failed)
* @param {jasmine.ExpectationResult|jasmine.NestedResults} result
*/
jasmine.NestedResults.prototype.addResult = function(result) {
if (result.type != 'log') {
if (result.items_) {
this.rollupCounts(result);
} else {
this.totalCount++;
if (result.passed()) {
this.passedCount++;
} else {
this.failedCount++;
}
}
}
this.items_.push(result);
};
/**
* @returns {Boolean} True if <b>everything</b> below passed
*/
jasmine.NestedResults.prototype.passed = function() {
return this.passedCount === this.totalCount;
};
-118
View File
@@ -1,118 +0,0 @@
jasmine.Queue = function(env) {
this.env = env;
// parallel to blocks. each true value in this array means the block will
// get executed even if we abort
this.ensured = [];
this.blocks = [];
this.running = false;
this.index = 0;
this.offset = 0;
this.abort = false;
};
jasmine.Queue.prototype.addBefore = function(block, ensure) {
if (ensure === jasmine.undefined) {
ensure = false;
}
this.blocks.unshift(block);
this.ensured.unshift(ensure);
};
jasmine.Queue.prototype.add = function(block, ensure) {
if (ensure === jasmine.undefined) {
ensure = false;
}
this.blocks.push(block);
this.ensured.push(ensure);
};
jasmine.Queue.prototype.insertNext = function(block, ensure) {
if (ensure === jasmine.undefined) {
ensure = false;
}
this.ensured.splice((this.index + this.offset + 1), 0, ensure);
this.blocks.splice((this.index + this.offset + 1), 0, block);
this.offset++;
};
jasmine.Queue.prototype.start = function(onComplete) {
this.running = true;
this.onComplete = onComplete;
this.next_();
};
jasmine.Queue.prototype.isRunning = function() {
return this.running;
};
jasmine.Queue.LOOP_DONT_RECURSE = true;
jasmine.Queue.prototype.next_ = function() {
var self = this;
var goAgain = true;
while (goAgain) {
goAgain = false;
if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
var calledSynchronously = true;
var completedSynchronously = false;
var onComplete = function () {
if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
completedSynchronously = true;
return;
}
if (self.blocks[self.index].abort) {
self.abort = true;
}
self.offset = 0;
self.index++;
var now = new Date().getTime();
if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
self.env.lastUpdate = now;
self.env.setTimeout(function() {
self.next_();
}, 0);
} else {
if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
goAgain = true;
} else {
self.next_();
}
}
};
self.blocks[self.index].execute(onComplete);
calledSynchronously = false;
if (completedSynchronously) {
onComplete();
}
} else {
self.running = false;
if (self.onComplete) {
self.onComplete();
}
}
}
};
jasmine.Queue.prototype.results = function() {
var results = new jasmine.NestedResults();
for (var i = 0; i < this.blocks.length; i++) {
if (this.blocks[i].results) {
results.addResult(this.blocks[i].results());
}
}
return results;
};
+40
View File
@@ -0,0 +1,40 @@
jasmine.QueueRunner = function(attrs) {
this.fns = attrs.fns || [];
this.onComplete = attrs.onComplete || function() {};
this.encourageGC = attrs.encourageGC || function(fn) {fn()};
this.onException = attrs.onException || function() {};
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
};
jasmine.QueueRunner.prototype.execute = function() {
this.run(this.fns, 0)
};
jasmine.QueueRunner.prototype.run = function(fns, index) {
if (index >= fns.length) {
this.encourageGC(this.onComplete);
return;
}
var fn = fns[index];
var self = this;
if (fn.length > 0) {
attempt(function() { fn.call(self, function() { self.run(fns, index + 1) }) });
} else {
attempt(function() { fn.call(self); });
self.run(fns, index + 1);
}
function attempt(fn) {
try {
fn();
} catch (e) {
self.onException(e);
if (!self.catchingExceptions()) {
//TODO: set a var when we catch an exception and
//use a finally block to close the loop in a nice way..
throw e;
}
}
}
};
+30
View File
@@ -0,0 +1,30 @@
jasmine.ReportDispatcher = function(methods) {
var dispatchedMethods = methods || [];
for (var i = 0; i < dispatchedMethods.length; i++) {
var method = dispatchedMethods[i];
this[method] = function(m) {
return function() {
dispatch(m, arguments);
};
}(method);
}
var reporters = [];
this.addReporter = function(reporter) {
reporters.push(reporter);
};
return this;
function dispatch(method, args) {
for (var i = 0; i < reporters.length; i++) {
var reporter = reporters[i];
if (reporter[method]) {
reporter[method].apply(reporter, args);
}
}
}
};
-31
View File
@@ -1,31 +0,0 @@
/** No-op base class for Jasmine reporters.
*
* @constructor
*/
jasmine.Reporter = function() {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.reportSpecResults = function(spec) {
};
//noinspection JSUnusedLocalSymbols
jasmine.Reporter.prototype.log = function(str) {
};
-77
View File
@@ -1,77 +0,0 @@
/**
* Runner
*
* @constructor
* @param {jasmine.Env} env
*/
jasmine.Runner = function(env) {
var self = this;
self.env = env;
self.queue = new jasmine.Queue(env);
self.before_ = [];
self.after_ = [];
self.suites_ = [];
};
jasmine.Runner.prototype.execute = function() {
var self = this;
if (self.env.reporter.reportRunnerStarting) {
self.env.reporter.reportRunnerStarting(this);
}
self.queue.start(function () {
self.finishCallback();
});
};
jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
beforeEachFunction.typeName = 'beforeEach';
this.before_.splice(0,0,beforeEachFunction);
};
jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
afterEachFunction.typeName = 'afterEach';
this.after_.splice(0,0,afterEachFunction);
};
jasmine.Runner.prototype.finishCallback = function() {
this.env.reporter.reportRunnerResults(this);
};
jasmine.Runner.prototype.addSuite = function(suite) {
this.suites_.push(suite);
};
jasmine.Runner.prototype.add = function(block) {
if (block instanceof jasmine.Suite) {
this.addSuite(block);
}
this.queue.add(block);
};
jasmine.Runner.prototype.specs = function () {
var suites = this.suites();
var specs = [];
for (var i = 0; i < suites.length; i++) {
specs = specs.concat(suites[i].specs());
}
return specs;
};
jasmine.Runner.prototype.suites = function() {
return this.suites_;
};
jasmine.Runner.prototype.topLevelSuites = function() {
var topLevelSuites = [];
for (var i = 0; i < this.suites_.length; i++) {
if (!this.suites_[i].parentSuite) {
topLevelSuites.push(this.suites_[i]);
}
}
return topLevelSuites;
};
jasmine.Runner.prototype.results = function() {
return this.queue.results();
};
+77 -222
View File
@@ -1,243 +1,98 @@
/** jasmine.Spec = function(attrs) {
* Internal representation of a Jasmine specification, or test. this.encounteredExpectations = false;
* this.expectationFactory = attrs.expectationFactory;
* @constructor this.resultCallback = attrs.resultCallback || function() {};
* @param {jasmine.Env} env this.id = attrs.id;
* @param {jasmine.Suite} suite this.description = attrs.description || '';
* @param {String} description this.fn = attrs.fn;
*/ this.beforeFns = attrs.beforeFns || function() {};
jasmine.Spec = function(env, suite, description) { this.afterFns = attrs.afterFns || function() {};
if (!env) { this.catchingExceptions = attrs.catchingExceptions;
throw new Error('jasmine.Env() required'); this.onStart = attrs.onStart || function() {};
this.exceptionFormatter = attrs.exceptionFormatter || function() {};
this.getSpecName = attrs.getSpecName || function() { return ''; };
this.expectationResultFactory = attrs.expectationResultFactory || function() {};
this.queueRunner = attrs.queueRunner || { execute: function() {}};
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
this.result = {
id: this.id,
description: this.description,
fullName: this.getFullName(),
status: this.status(),
failedExpectations: []
};
};
jasmine.Spec.prototype.addExpectationResult = function(passed, data) {
this.encounteredExpectations = true;
if (!passed) {
this.result.failedExpectations.push(data);
} }
if (!suite) {
throw new Error('jasmine.Suite() required');
}
var spec = this;
spec.id = env.nextSpecId ? env.nextSpecId() : null;
spec.env = env;
spec.suite = suite;
spec.description = description;
spec.queue = new jasmine.Queue(env);
spec.afterCallbacks = [];
spec.spies_ = [];
spec.results_ = new jasmine.NestedResults();
spec.results_.description = description;
spec.matchersClass = null;
};
jasmine.Spec.prototype.getFullName = function() {
return this.suite.getFullName() + ' ' + this.description + '.';
};
jasmine.Spec.prototype.results = function() {
return this.results_;
};
/**
* All parameters are pretty-printed and concatenated together, then written to the spec's output.
*
* Be careful not to leave calls to <code>jasmine.log</code> in production code.
*/
jasmine.Spec.prototype.log = function() {
return this.results_.log(arguments);
};
jasmine.Spec.prototype.runs = function (func) {
var block = new jasmine.Block(this.env, func, this);
this.addToQueue(block);
return this;
};
jasmine.Spec.prototype.addToQueue = function (block) {
if (this.queue.isRunning()) {
this.queue.insertNext(block);
} else {
this.queue.add(block);
}
};
/**
* @param {jasmine.ExpectationResult} result
*/
jasmine.Spec.prototype.addMatcherResult = function(result) {
this.results_.addResult(result);
}; };
jasmine.Spec.prototype.expect = function(actual) { jasmine.Spec.prototype.expect = function(actual) {
var positive = new (this.getMatchersClass_())(this.env, actual, this); return this.expectationFactory(actual, this);
positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
return positive;
};
/**
* Waits a fixed time period before moving to the next block.
*
* @deprecated Use waitsFor() instead
* @param {Number} timeout milliseconds to wait
*/
jasmine.Spec.prototype.waits = function(timeout) {
var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
this.addToQueue(waitsFunc);
return this;
};
/**
* Waits for the latchFunction to return true before proceeding to the next block.
*
* @param {Function} latchFunction
* @param {String} optional_timeoutMessage
* @param {Number} optional_timeout
*/
jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
var latchFunction_ = null;
var optional_timeoutMessage_ = null;
var optional_timeout_ = null;
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i];
switch (typeof arg) {
case 'function':
latchFunction_ = arg;
break;
case 'string':
optional_timeoutMessage_ = arg;
break;
case 'number':
optional_timeout_ = arg;
break;
}
}
var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
this.addToQueue(waitsForFunc);
return this;
};
jasmine.Spec.prototype.fail = function (e) {
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message: e ? jasmine.util.formatException(e) : 'Exception',
trace: { stack: e.stack }
});
this.results_.addResult(expectationResult);
};
jasmine.Spec.prototype.getMatchersClass_ = function() {
return this.matchersClass || this.env.matchersClass;
};
jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
var parent = this.getMatchersClass_();
var newMatchersClass = function() {
parent.apply(this, arguments);
};
jasmine.util.inherit(newMatchersClass, parent);
jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
this.matchersClass = newMatchersClass;
};
jasmine.Spec.prototype.finishCallback = function() {
this.env.reporter.reportSpecResults(this);
};
jasmine.Spec.prototype.finish = function(onComplete) {
this.removeAllSpies();
this.finishCallback();
if (onComplete) {
onComplete();
}
};
jasmine.Spec.prototype.after = function(doAfter) {
if (this.queue.isRunning()) {
this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
} else {
this.afterCallbacks.unshift(doAfter);
}
}; };
jasmine.Spec.prototype.execute = function(onComplete) { jasmine.Spec.prototype.execute = function(onComplete) {
var spec = this; var self = this;
if (!spec.env.specFilter(spec)) {
spec.results_.skipped = true; if (this.disabled) {
spec.finish(onComplete); complete();
return; return;
} }
this.env.reporter.reportSpecStarting(this); var befores = this.beforeFns() || [],
afters = this.afterFns() || [];
var allFns = befores.concat(this.fn).concat(afters);
spec.env.currentSpec = spec; this.onStart(this);
this.queueRunner({
spec.addBeforesAndAftersToQueue(); fns: allFns,
onException: function(e) {
spec.queue.start(function () { self.addExpectationResult(false, self.expectationResultFactory({
spec.finish(onComplete); matcherName: "",
passed: false,
expected: "",
actual: "",
message: self.exceptionFormatter(e),
trace: e
}));
},
onComplete: complete
}); });
};
jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { function complete() {
var runner = this.env.currentRunner(); self.result.status = self.status();
var i; self.resultCallback(self.result);
for (var suite = this.suite; suite; suite = suite.parentSuite) { if (onComplete) {
for (i = 0; i < suite.before_.length; i++) { onComplete();
this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
} }
} }
for (i = 0; i < runner.before_.length; i++) { };
this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
jasmine.Spec.prototype.disable = function() {
this.disabled = true;
};
jasmine.Spec.prototype.status = function() {
if (this.disabled) {
return 'disabled';
} }
for (i = 0; i < this.afterCallbacks.length; i++) {
this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); if (!this.encounteredExpectations) {
return null;
} }
for (suite = this.suite; suite; suite = suite.parentSuite) {
for (i = 0; i < suite.after_.length; i++) { if (this.result.failedExpectations.length > 0) {
this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); return 'failed';
} } else {
} return 'passed';
for (i = 0; i < runner.after_.length; i++) {
this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
} }
}; };
jasmine.Spec.prototype.explodes = function() { jasmine.Spec.prototype.getFullName = function() {
throw 'explodes function should not have been called'; return this.getSpecName(this);
}; }
jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
if (obj == jasmine.undefined) {
throw "spyOn could not find an object to spy upon for " + methodName + "()";
}
if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
throw methodName + '() method does not exist';
}
if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
throw new Error(methodName + ' has already been spied upon');
}
var spyObj = jasmine.createSpy(methodName);
this.spies_.push(spyObj);
spyObj.baseObj = obj;
spyObj.methodName = methodName;
spyObj.originalValue = obj[methodName];
obj[methodName] = spyObj;
return spyObj;
};
jasmine.Spec.prototype.removeAllSpies = function() {
for (var i = 0; i < this.spies_.length; i++) {
var spy = this.spies_[i];
spy.baseObj[spy.methodName] = spy.originalValue;
}
this.spies_ = [];
};
+72 -55
View File
@@ -1,73 +1,61 @@
/** jasmine.Suite = function(attrs) {
* Internal representation of a Jasmine suite. this.env = attrs.env;
* this.id = attrs.id;
* @constructor this.parentSuite = attrs.parentSuite;
* @param {jasmine.Env} env this.description = attrs.description;
* @param {String} description this.onStart = attrs.onStart || function() {};
* @param {Function} specDefinitions this.completeCallback = attrs.completeCallback || function() {};
* @param {jasmine.Suite} parentSuite this.resultCallback = attrs.resultCallback || function() {};
*/ this.encourageGC = attrs.encourageGC || function(fn) {fn();};
jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
var self = this; this.beforeFns = [];
self.id = env.nextSuiteId ? env.nextSuiteId() : null; this.afterFns = [];
self.description = description; this.queueRunner = attrs.queueRunner || function() {};
self.queue = new jasmine.Queue(env); this.disabled = false;
self.parentSuite = parentSuite;
self.env = env; this.children_ = []; // TODO: rename
self.before_ = []; this.suites = []; // TODO: needed?
self.after_ = []; this.specs = []; // TODO: needed?
self.children_ = [];
self.suites_ = []; this.result = {
self.specs_ = []; id: this.id,
status: this.disabled ? 'disabled' : '',
description: this.description,
fullName: this.getFullName()
};
}; };
jasmine.Suite.prototype.getFullName = function() { jasmine.Suite.prototype.getFullName = function() {
var fullName = this.description; var fullName = this.description;
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
fullName = parentSuite.description + ' ' + fullName; if (parentSuite.parentSuite) {
fullName = parentSuite.description + ' ' + fullName;
}
} }
return fullName; return fullName;
}; };
jasmine.Suite.prototype.finish = function(onComplete) { jasmine.Suite.prototype.disable = function() {
this.env.reporter.reportSuiteResults(this); this.disabled = true;
this.finished = true;
if (typeof(onComplete) == 'function') {
onComplete();
}
}; };
jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { jasmine.Suite.prototype.beforeEach = function(fn) {
beforeEachFunction.typeName = 'beforeEach'; this.beforeFns.unshift(fn);
this.before_.unshift(beforeEachFunction);
}; };
jasmine.Suite.prototype.afterEach = function(afterEachFunction) { jasmine.Suite.prototype.afterEach = function(fn) {
afterEachFunction.typeName = 'afterEach'; this.afterFns.unshift(fn);
this.after_.unshift(afterEachFunction);
}; };
jasmine.Suite.prototype.results = function() { jasmine.Suite.prototype.addSpec = function(spec) {
return this.queue.results(); this.children_.push(spec);
this.specs.push(spec); // TODO: needed?
}; };
jasmine.Suite.prototype.add = function(suiteOrSpec) { jasmine.Suite.prototype.addSuite = function(suite) {
this.children_.push(suiteOrSpec); suite.parentSuite = this;
if (suiteOrSpec instanceof jasmine.Suite) { this.children_.push(suite);
this.suites_.push(suiteOrSpec); this.suites.push(suite); // TODO: needed?
this.env.currentRunner().addSuite(suiteOrSpec);
} else {
this.specs_.push(suiteOrSpec);
}
this.queue.add(suiteOrSpec);
};
jasmine.Suite.prototype.specs = function() {
return this.specs_;
};
jasmine.Suite.prototype.suites = function() {
return this.suites_;
}; };
jasmine.Suite.prototype.children = function() { jasmine.Suite.prototype.children = function() {
@@ -76,7 +64,36 @@ jasmine.Suite.prototype.children = function() {
jasmine.Suite.prototype.execute = function(onComplete) { jasmine.Suite.prototype.execute = function(onComplete) {
var self = this; var self = this;
this.queue.start(function () { if (this.disabled) {
self.finish(onComplete); complete();
return;
}
var allFns = [],
children = this.children_;
for (var i = 0; i < children.length; i++) {
allFns.push(wrapChild(children[i]));
function wrapChild(child) {
return function(done) {
child.execute(done);
}
}
}
this.onStart(this);
this.queueRunner({
fns: allFns,
onComplete: complete
}); });
function complete() {
self.resultCallback(self.result);
if (onComplete) {
onComplete();
}
}
}; };
-15
View File
@@ -1,15 +0,0 @@
jasmine.WaitsBlock = function(env, timeout, spec) {
this.timeout = timeout;
jasmine.Block.call(this, env, null, spec);
};
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
jasmine.WaitsBlock.prototype.execute = function (onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
}
this.env.setTimeout(function () {
onComplete();
}, this.timeout);
};
-54
View File
@@ -1,54 +0,0 @@
/**
* A block which waits for some condition to become true, with timeout.
*
* @constructor
* @extends jasmine.Block
* @param {jasmine.Env} env The Jasmine environment.
* @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
* @param {Function} latchFunction A function which returns true when the desired condition has been met.
* @param {String} message The message to display if the desired condition hasn't been met within the given time period.
* @param {jasmine.Spec} spec The Jasmine spec.
*/
jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
this.timeout = timeout || env.defaultTimeoutInterval;
this.latchFunction = latchFunction;
this.message = message;
this.totalTimeSpentWaitingForLatch = 0;
jasmine.Block.call(this, env, null, spec);
};
jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
}
var latchFunctionResult;
try {
latchFunctionResult = this.latchFunction.apply(this.spec);
} catch (e) {
this.spec.fail(e);
onComplete();
return;
}
if (latchFunctionResult) {
onComplete();
} else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
this.spec.fail({
name: 'timeout',
message: message
});
this.abort = true;
onComplete();
} else {
this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
var self = this;
this.env.setTimeout(function() {
self.execute(onComplete);
}, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
}
};
+9 -273
View File
@@ -1,4 +1,3 @@
var isCommonJS = typeof window == "undefined" && typeof exports == "object";
/** /**
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
@@ -6,7 +5,12 @@ var isCommonJS = typeof window == "undefined" && typeof exports == "object";
* @namespace * @namespace
*/ */
var jasmine = {}; var jasmine = {};
if (isCommonJS) exports.jasmine = jasmine;
// TODO: do we need this now that we have boot.js?
if (typeof window == "undefined" && typeof exports == "object") {
exports.jasmine = jasmine
}
/** /**
* @private * @private
*/ */
@@ -22,12 +26,6 @@ jasmine.unimplementedMethod_ = function() {
*/ */
jasmine.undefined = jasmine.___undefined___; jasmine.undefined = jasmine.___undefined___;
/**
* Show diagnostic messages in the console if set to true
*
*/
jasmine.VERBOSE = false;
/** /**
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
* *
@@ -44,13 +42,6 @@ jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
*/ */
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
/**
* By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
* Set to false to let the exception bubble up in the browser.
*
*/
jasmine.CATCH_EXCEPTIONS = true;
jasmine.getGlobal = function() { jasmine.getGlobal = function() {
function getGlobal() { function getGlobal() {
return this; return this;
@@ -59,75 +50,12 @@ jasmine.getGlobal = function() {
return getGlobal(); return getGlobal();
}; };
/**
* Allows for bound functions to be compared. Internal use only.
*
* @ignore
* @private
* @param base {Object} bound 'this' for the function
* @param name {Function} function to find
*/
jasmine.bindOriginal_ = function(base, name) {
var original = base[name];
if (original.apply) {
return function() {
return original.apply(base, arguments);
};
} else {
// IE support
return jasmine.getGlobal()[name];
}
};
jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
jasmine.MessageResult = function(values) {
this.type = 'log';
this.values = values;
this.trace = new Error(); // todo: test better
};
jasmine.MessageResult.prototype.toString = function() {
var text = "";
for (var i = 0; i < this.values.length; i++) {
if (i > 0) text += " ";
if (jasmine.isString_(this.values[i])) {
text += this.values[i];
} else {
text += jasmine.pp(this.values[i]);
}
}
return text;
};
jasmine.ExpectationResult = function(params) {
this.type = 'expect';
this.matcherName = params.matcherName;
this.passed_ = params.passed;
this.expected = params.expected;
this.actual = params.actual;
this.message = this.passed_ ? 'Passed.' : params.message;
var trace = (params.trace || new Error(this.message));
this.trace = this.passed_ ? '' : trace;
};
jasmine.ExpectationResult.prototype.toString = function () {
return this.message;
};
jasmine.ExpectationResult.prototype.passed = function () {
return this.passed_;
};
/** /**
* Getter for the Jasmine environment. Ensures one gets created * Getter for the Jasmine environment. Ensures one gets created
*/ */
jasmine.getEnv = function() { jasmine.getEnv = function(options) {
var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(options);
//jasmine. singletons in here (setTimeout blah blah).
return env; return env;
}; };
@@ -451,195 +379,3 @@ jasmine.createSpyObj = function(baseName, methodNames) {
} }
return obj; return obj;
}; };
/**
* All parameters are pretty-printed and concatenated together, then written to the current spec's output.
*
* Be careful not to leave calls to <code>jasmine.log</code> in production code.
*/
jasmine.log = function() {
var spec = jasmine.getEnv().currentSpec;
spec.log.apply(spec, arguments);
};
/**
* Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
*
* @example
* // spy example
* var foo = {
* not: function(bool) { return !bool; }
* }
* spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
*
* @see jasmine.createSpy
* @param obj
* @param methodName
* @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
*/
var spyOn = function(obj, methodName) {
return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
};
if (isCommonJS) exports.spyOn = spyOn;
/**
* Creates a Jasmine spec that will be added to the current suite.
*
* // TODO: pending tests
*
* @example
* it('should be true', function() {
* expect(true).toEqual(true);
* });
*
* @param {String} desc description of this specification
* @param {Function} func defines the preconditions and expectations of the spec
*/
var it = function(desc, func) {
return jasmine.getEnv().it(desc, func);
};
if (isCommonJS) exports.it = it;
/**
* Creates a <em>disabled</em> Jasmine spec.
*
* A convenience method that allows existing specs to be disabled temporarily during development.
*
* @param {String} desc description of this specification
* @param {Function} func defines the preconditions and expectations of the spec
*/
var xit = function(desc, func) {
return jasmine.getEnv().xit(desc, func);
};
if (isCommonJS) exports.xit = xit;
/**
* Starts a chain for a Jasmine expectation.
*
* It is passed an Object that is the actual value and should chain to one of the many
* jasmine.Matchers functions.
*
* @param {Object} actual Actual value to test against and expected value
* @return {jasmine.Matchers}
*/
var expect = function(actual) {
return jasmine.getEnv().currentSpec.expect(actual);
};
if (isCommonJS) exports.expect = expect;
/**
* Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
*
* @param {Function} func Function that defines part of a jasmine spec.
*/
var runs = function(func) {
jasmine.getEnv().currentSpec.runs(func);
};
if (isCommonJS) exports.runs = runs;
/**
* Waits a fixed time period before moving to the next block.
*
* @deprecated Use waitsFor() instead
* @param {Number} timeout milliseconds to wait
*/
var waits = function(timeout) {
jasmine.getEnv().currentSpec.waits(timeout);
};
if (isCommonJS) exports.waits = waits;
/**
* Waits for the latchFunction to return true before proceeding to the next block.
*
* @param {Function} latchFunction
* @param {String} optional_timeoutMessage
* @param {Number} optional_timeout
*/
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
};
if (isCommonJS) exports.waitsFor = waitsFor;
/**
* A function that is called before each spec in a suite.
*
* Used for spec setup, including validating assumptions.
*
* @param {Function} beforeEachFunction
*/
var beforeEach = function(beforeEachFunction) {
jasmine.getEnv().beforeEach(beforeEachFunction);
};
if (isCommonJS) exports.beforeEach = beforeEach;
/**
* A function that is called after each spec in a suite.
*
* Used for restoring any state that is hijacked during spec execution.
*
* @param {Function} afterEachFunction
*/
var afterEach = function(afterEachFunction) {
jasmine.getEnv().afterEach(afterEachFunction);
};
if (isCommonJS) exports.afterEach = afterEach;
/**
* Defines a suite of specifications.
*
* Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
* are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
* of setup in some tests.
*
* @example
* // TODO: a simple suite
*
* // TODO: a simple suite with a nested describe block
*
* @param {String} description A string, usually the class under test.
* @param {Function} specDefinitions function that defines several specs.
*/
var describe = function(description, specDefinitions) {
return jasmine.getEnv().describe(description, specDefinitions);
};
if (isCommonJS) exports.describe = describe;
/**
* Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
*
* @param {String} description A string, usually the class under test.
* @param {Function} specDefinitions function that defines several specs.
*/
var xdescribe = function(description, specDefinitions) {
return jasmine.getEnv().xdescribe(description, specDefinitions);
};
if (isCommonJS) exports.xdescribe = xdescribe;
// Provide the XMLHttpRequest class for IE 5.x-6.x:
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
function tryIt(f) {
try {
return f();
} catch(e) {
}
return null;
}
var xhr = tryIt(function() {
return new ActiveXObject("Msxml2.XMLHTTP.6.0");
}) ||
tryIt(function() {
return new ActiveXObject("Msxml2.XMLHTTP.3.0");
}) ||
tryIt(function() {
return new ActiveXObject("Msxml2.XMLHTTP");
}) ||
tryIt(function() {
return new ActiveXObject("Microsoft.XMLHTTP");
});
if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
return xhr;
} : XMLHttpRequest;
-183
View File
@@ -1,183 +0,0 @@
// Mock setTimeout, clearTimeout
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
jasmine.FakeTimer = function() {
this.reset();
var self = this;
self.setTimeout = function(funcToCall, millis) {
self.timeoutsMade++;
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
return self.timeoutsMade;
};
self.setInterval = function(funcToCall, millis) {
self.timeoutsMade++;
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
return self.timeoutsMade;
};
self.clearTimeout = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
self.clearInterval = function(timeoutKey) {
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
};
};
jasmine.FakeTimer.prototype.reset = function() {
this.timeoutsMade = 0;
this.scheduledFunctions = {};
this.nowMillis = 0;
};
jasmine.FakeTimer.prototype.tick = function(millis) {
var oldMillis = this.nowMillis;
var newMillis = oldMillis + millis;
this.runFunctionsWithinRange(oldMillis, newMillis);
this.nowMillis = newMillis;
};
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
var scheduledFunc;
var funcsToRun = [];
for (var timeoutKey in this.scheduledFunctions) {
scheduledFunc = this.scheduledFunctions[timeoutKey];
if (scheduledFunc != jasmine.undefined &&
scheduledFunc.runAtMillis >= oldMillis &&
scheduledFunc.runAtMillis <= nowMillis) {
funcsToRun.push(scheduledFunc);
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
}
}
if (funcsToRun.length > 0) {
funcsToRun.sort(function(a, b) {
return a.runAtMillis - b.runAtMillis;
});
for (var i = 0; i < funcsToRun.length; ++i) {
try {
var funcToRun = funcsToRun[i];
this.nowMillis = funcToRun.runAtMillis;
funcToRun.funcToCall();
if (funcToRun.recurring) {
this.scheduleFunction(funcToRun.timeoutKey,
funcToRun.funcToCall,
funcToRun.millis,
true);
}
} catch(e) {
}
}
this.runFunctionsWithinRange(oldMillis, nowMillis);
}
};
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
this.scheduledFunctions[timeoutKey] = {
runAtMillis: this.nowMillis + millis,
funcToCall: funcToCall,
recurring: recurring,
timeoutKey: timeoutKey,
millis: millis
};
};
/**
* @namespace
*/
jasmine.Clock = {
defaultFakeTimer: new jasmine.FakeTimer(),
reset: function() {
jasmine.Clock.assertInstalled();
jasmine.Clock.defaultFakeTimer.reset();
},
tick: function(millis) {
jasmine.Clock.assertInstalled();
jasmine.Clock.defaultFakeTimer.tick(millis);
},
runFunctionsWithinRange: function(oldMillis, nowMillis) {
jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
},
scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
},
useMock: function() {
if (!jasmine.Clock.isInstalled()) {
var spec = jasmine.getEnv().currentSpec;
spec.after(jasmine.Clock.uninstallMock);
jasmine.Clock.installMock();
}
},
installMock: function() {
jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
},
uninstallMock: function() {
jasmine.Clock.assertInstalled();
jasmine.Clock.installed = jasmine.Clock.real;
},
real: {
setTimeout: jasmine.getGlobal().setTimeout,
clearTimeout: jasmine.getGlobal().clearTimeout,
setInterval: jasmine.getGlobal().setInterval,
clearInterval: jasmine.getGlobal().clearInterval
},
assertInstalled: function() {
if (!jasmine.Clock.isInstalled()) {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
}
},
isInstalled: function() {
return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
},
installed: null
};
jasmine.Clock.installed = jasmine.Clock.real;
//else for IE support
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
if (jasmine.Clock.installed.setTimeout.apply) {
return jasmine.Clock.installed.setTimeout.apply(this, arguments);
} else {
return jasmine.Clock.installed.setTimeout(funcToCall, millis);
}
};
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
if (jasmine.Clock.installed.setInterval.apply) {
return jasmine.Clock.installed.setInterval.apply(this, arguments);
} else {
return jasmine.Clock.installed.setInterval(funcToCall, millis);
}
};
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
if (jasmine.Clock.installed.clearTimeout.apply) {
return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
} else {
return jasmine.Clock.installed.clearTimeout(timeoutKey);
}
};
jasmine.getGlobal().clearInterval = function(timeoutKey) {
if (jasmine.Clock.installed.clearTimeout.apply) {
return jasmine.Clock.installed.clearInterval.apply(this, arguments);
} else {
return jasmine.Clock.installed.clearInterval(timeoutKey);
}
};
-6
View File
@@ -59,9 +59,3 @@ jasmine.util.argsToArray = function(args) {
for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
return arrayOfArgs; return arrayOfArgs;
}; };
jasmine.util.extend = function(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
};
+241 -143
View File
@@ -1,165 +1,263 @@
jasmine.HtmlReporter = function(_doc) { jasmine.HtmlReporter = function(options) {
var self = this; var env = options.env || {},
var doc = _doc || window.document; getContainer = options.getContainer,
now = options.now || function() { return new Date().getTime();},
createElement = options.createElement,
createTextNode = options.createTextNode,
results = [],
queryString = options.queryString,
startTime,
specsExecuted = 0,
failureCount = 0,
htmlReporterMain,
symbols;
var reporterView; this.initialize = function() {
htmlReporterMain = createDom("div", {className: "html-reporter"},
createDom("div", {className: "banner"},
createDom("span", {className: "title"}, "Jasmine"),
createDom("span", {className: "version"}, env.versionString())
),
createDom("ul", {className: "symbol-summary"}),
createDom("div", {className: "alert"}),
createDom("div", {className: "results"},
createDom("div", {className: "failures"})
)
);
getContainer().appendChild(htmlReporterMain);
var dom = {}; symbols = find(".symbol-summary")[0];
// Jasmine Reporter Public Interface
self.logRunningSpecs = false;
self.reportRunnerStarting = function(runner) {
var specs = runner.specs() || [];
if (specs.length == 0) {
return;
}
createReporterDom(runner.env.versionString());
doc.body.appendChild(dom.reporter);
setExceptionHandling();
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
reporterView.addSpecs(specs, self.specFilter);
}; };
self.reportRunnerResults = function(runner) { var specFilterPattern;
reporterView && reporterView.complete();
};
self.reportSuiteResults = function(suite) { this.specFilter = function(spec) {
reporterView.suiteComplete(suite); if (!isFiltered()) {
};
self.reportSpecStarting = function(spec) {
if (self.logRunningSpecs) {
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
self.reportSpecResults = function(spec) {
reporterView.specComplete(spec);
};
self.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
}
}
};
self.specFilter = function(spec) {
if (!focusedSpecName()) {
return true; return true;
} }
return spec.getFullName().indexOf(focusedSpecName()) === 0; var specName = spec.getFullName();
return !!(specName.match(specFilterPattern));
}; };
return self; var totalSpecsDefined;
this.jasmineStarted = function(options) {
totalSpecsDefined = options.totalSpecsDefined || 0;
startTime = now();
};
function focusedSpecName() { var summary = createDom("div", {className: "summary"});
var specName;
(function memoizeFocusedSpec() { var topResults = new jasmine.ResultsNode({}, "", null),
if (specName) { currentParent = topResults;
return;
}
var paramMap = []; this.suiteStarted = function(result) {
var params = jasmine.HtmlReporter.parameters(doc); currentParent.addChild(result, "suite");
currentParent = currentParent.last();
};
for (var i = 0; i < params.length; i++) { this.suiteDone = function(result) {
var p = params[i].split('='); if (currentParent == topResults) {
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); return;
}
specName = paramMap.spec;
})();
return specName;
}
function createReporterDom(version) {
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
dom.banner = self.createDom('div', { className: 'banner' },
self.createDom('span', { className: 'title' }, "Jasmine "),
self.createDom('span', { className: 'version' }, version)),
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'},
self.createDom('span', { className: 'exceptions' },
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),
dom.details = self.createDom('div', { id: 'details' }))
);
}
function noTryCatch() {
return window.location.search.match(/catch=false/);
}
function searchWithCatch() {
var params = jasmine.HtmlReporter.parameters(window.document);
var removed = false;
var i = 0;
while (!removed && i < params.length) {
if (params[i].match(/catch=/)) {
params.splice(i, 1);
removed = true;
}
i++;
}
if (jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
} }
return params.join("&"); currentParent = currentParent.parent;
} };
function setExceptionHandling() { this.specStarted = function(result) {
var chxCatch = document.getElementById('no_try_catch'); currentParent.addChild(result, "spec");
};
if (noTryCatch()) { var failures = [];
chxCatch.setAttribute('checked', true); this.specDone = function(result) {
jasmine.CATCH_EXCEPTIONS = false; if (result.status != "disabled") {
specsExecuted++;
} }
chxCatch.onclick = function() {
window.location.search = searchWithCatch(); symbols.appendChild(createDom("li", {
className: result.status,
id: "spec_" + result.id}
));
if (result.status == "failed") {
failureCount++;
var failure =
createDom("div", {className: "spec-detail failed"},
createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
createDom("div", {className: "messages"})
);
var messages = failure.childNodes[1];
for (var i = 0; i < result.failedExpectations.length; i++) {
var expectation = result.failedExpectations[i];
var stack = (expectation.trace && expectation.trace.stack) || "";
messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
messages.appendChild(createDom("div", {className: "stack-trace"}, stack));
}
failures.push(failure);
}
};
this.jasmineDone = function() {
var elapsed = now() - startTime;
var banner = find(".banner")[0];
banner.appendChild(createDom("span", {className: "duration"}, "finished in " + elapsed / 1000 + "s"));
var alert = find(".alert")[0];
alert.appendChild(createDom("span", { className: "exceptions" },
createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
createDom("input", {
className: "raise",
id: "raise-exceptions",
type: "checkbox"
})
));
var checkbox = find("input")[0];
checkbox.checked = !env.catchingExceptions();
checkbox.onclick = function() {
queryString.setParam("catch", !checkbox.checked);
}; };
if (specsExecuted < totalSpecsDefined) {
var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
alert.appendChild(
createDom("span", {className: "bar skipped"},
createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
)
);
}
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount),
statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
var results = find(".results")[0];
results.appendChild(summary);
summaryList(topResults, summary);
function summaryList(resultsTree, domParent) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
if (resultNode.type == "suite") {
var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
createDom("li", {className: "suite-detail"},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
summaryList(resultNode, suiteListNode);
domParent.appendChild(suiteListNode);
}
if (resultNode.type == "spec") {
if (domParent.getAttribute("class") != "specs") {
specListNode = createDom("ul", {className: "specs"});
domParent.appendChild(specListNode);
}
specListNode.appendChild(
createDom("li", {
className: resultNode.result.status,
id: "spec-" + resultNode.result.id
},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
}
}
}
if (failures.length) {
alert.appendChild(
createDom('span', {className: "menu bar spec-list"},
createDom("span", {}, "Spec List | "),
createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
alert.appendChild(
createDom('span', {className: "menu bar failure-list"},
createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
createDom("span", {}, " | Failures ")));
find(".failures-menu")[0].onclick = function() {
setMenuModeTo('failure-list');
};
find(".spec-list-menu")[0].onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
var failureNode = find(".failures")[0];
for (var i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
}
};
return this;
function find(selector) {
if (selector.match(/^\./)) {
var className = selector.substring(1);
return getContainer().getElementsByClassName(className);
} else {
return getContainer().getElementsByTagName(selector);
}
}
function createDom(type, attrs, childrenVarArgs) {
var el = createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(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;
}
function pluralize(singular, count) {
var word = (count == 1 ? singular : singular + "s");
return "" + count + " " + word;
}
function specHref(result) {
return "?spec=" + encodeURIComponent(result.fullName);
}
function isFiltered() {
buildSpecFilter();
return !!specFilterPattern;
}
function buildSpecFilter() {
var specFilterParam = queryString.getParam("spec") || "";
specFilterPattern = new RegExp(specFilterParam);
}
function setMenuModeTo(mode) {
htmlReporterMain.setAttribute("class", "html-reporter " + mode);
} }
}; };
jasmine.HtmlReporter.parameters = function(doc) {
var paramStr = doc.location.search.substring(1);
var params = [];
if (paramStr.length > 0) {
params = paramStr.split('&');
}
return params;
}
jasmine.HtmlReporter.sectionLink = function(sectionName) {
var link = '?';
var params = [];
if (sectionName) {
params.push('spec=' + encodeURIComponent(sectionName));
}
if (!jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
if (params.length > 0) {
link += params.join("&");
}
return link;
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
-60
View File
@@ -1,60 +0,0 @@
jasmine.HtmlReporterHelpers = {};
jasmine.HtmlReporterHelpers.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.HtmlReporterHelpers.getSpecStatus = function(child) {
var results = child.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
return status;
};
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
var parentDiv = this.dom.summary;
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
var parent = child[parentSuite];
if (parent) {
if (typeof this.views.suites[parent.id] == 'undefined') {
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
}
parentDiv = this.views.suites[parent.id].element;
}
parentDiv.appendChild(childElement);
};
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
for(var fn in jasmine.HtmlReporterHelpers) {
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
}
};
+43
View File
@@ -0,0 +1,43 @@
jasmine.QueryString = function(options) {
this.setParam = function(key, value) {
var paramMap = queryStringToParamMap();
paramMap[key] = value;
options.getWindowLocation().search = toQueryString(paramMap);
};
this.getParam = function(key) {
return queryStringToParamMap()[key];
};
return this;
function toQueryString(paramMap) {
var qStrPairs = [];
for (var prop in paramMap) {
qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
}
return "?" + qStrPairs.join('&');
}
function queryStringToParamMap() {
var paramStr = options.getWindowLocation().search.substring(1),
params = [],
paramMap = {};
if (paramStr.length > 0) {
params = paramStr.split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
var value = decodeURIComponent(p[1]);
if (value === "true" || value === "false") {
value = JSON.parse(value);
}
paramMap[decodeURIComponent(p[0])] = value;
}
}
return paramMap;
}
};
+13 -11
View File
@@ -1,10 +1,11 @@
jasmine.HtmlReporter.ReporterView = function(dom) { jasmine.HtmlReporter.ReporterView = function(dom, jasmine, catchExceptions) {
this.startedAt = new Date(); this.startedAt = new Date();
this.runningSpecCount = 0; this.runningSpecCount = 0;
this.completeSpecCount = 0; this.completeSpecCount = 0;
this.passedCount = 0; this.passedCount = 0;
this.failedCount = 0; this.failedCount = 0;
this.skippedCount = 0; this.skippedCount = 0;
this.jasmine = jasmine || {};
this.createResultsMenu = function() { this.createResultsMenu = function() {
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'}, this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
@@ -31,21 +32,22 @@ jasmine.HtmlReporter.ReporterView = function(dom) {
for (var i = 0; i < specs.length; i++) { for (var i = 0; i < specs.length; i++) {
var spec = specs[i]; var spec = specs[i];
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views); this.views.specs[spec.id] = new this.jasmine.HtmlReporter.SpecView(spec, dom, this.views, this.jasmine, catchExceptions);
if (specFilter(spec)) { if (specFilter(spec)) {
this.runningSpecCount++; this.runningSpecCount++;
} }
} }
}; };
this.specComplete = function(spec) { this.specComplete = function(result) {
this.completeSpecCount++; this.completeSpecCount++;
if (isUndefined(this.views.specs[spec.id])) { //TODO: this needs to work in order to get blanks for skipped specs.
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom); // if (isUndefined(this.views.specs[result.id])) {
} // this.views.specs[result.id] = new this.jasmine.HtmlReporter.SpecView(result, dom);
// }
var specView = this.views.specs[spec.id]; var specView = this.views.specs[result.id];
switch (specView.status()) { switch (specView.status()) {
case 'passed': case 'passed':
@@ -56,7 +58,7 @@ jasmine.HtmlReporter.ReporterView = function(dom) {
this.failedCount++; this.failedCount++;
break; break;
case 'skipped': case 'disabled':
this.skippedCount++; this.skippedCount++;
break; break;
} }
@@ -81,14 +83,14 @@ jasmine.HtmlReporter.ReporterView = function(dom) {
// currently running UI // currently running UI
if (isUndefined(this.runningAlert)) { if (isUndefined(this.runningAlert)) {
this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" }); this.runningAlert = this.createDom('a', { href: this.jasmine.HtmlReporter.sectionLink(null, catchExceptions), className: "runningAlert bar" });
dom.alert.appendChild(this.runningAlert); dom.alert.appendChild(this.runningAlert);
} }
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount); this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
// skipped specs UI // skipped specs UI
if (isUndefined(this.skippedAlert)) { if (isUndefined(this.skippedAlert)) {
this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" }); this.skippedAlert = this.createDom('a', { href: this.jasmine.HtmlReporter.sectionLink(null, catchExceptions), className: "skippedAlert bar" });
} }
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all"; this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
@@ -99,7 +101,7 @@ jasmine.HtmlReporter.ReporterView = function(dom) {
// passing specs UI // passing specs UI
if (isUndefined(this.passedAlert)) { if (isUndefined(this.passedAlert)) {
this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" }); this.passedAlert = this.createDom('span', { href: this.jasmine.HtmlReporter.sectionLink(null, catchExceptions), className: "passingAlert bar" });
} }
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount); this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
+15
View File
@@ -0,0 +1,15 @@
jasmine.ResultsNode = function(result, type, parent) {
this.result = result;
this.type = type;
this.parent = parent;
this.children = [];
this.addChild = function(result, type) {
this.children.push(new jasmine.ResultsNode(result, type, this));
};
this.last = function() {
return this.children[this.children.length-1];
}
};
+10 -7
View File
@@ -1,7 +1,9 @@
jasmine.HtmlReporter.SpecView = function(spec, dom, views) { jasmine.HtmlReporter.SpecView = function(spec, dom, views, jasmine, catchExceptions) {
this.spec = spec; this.spec = spec;
this.dom = dom; this.dom = dom;
this.views = views; this.views = views;
this.jasmine = jasmine || {};
this.catchExceptions = catchExceptions;
this.symbol = this.createDom('li', { className: 'pending' }); this.symbol = this.createDom('li', { className: 'pending' });
this.dom.symbolSummary.appendChild(this.symbol); this.dom.symbolSummary.appendChild(this.symbol);
@@ -9,7 +11,9 @@ jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
this.summary = this.createDom('div', { className: 'specSummary' }, this.summary = this.createDom('div', { className: 'specSummary' },
this.createDom('a', { this.createDom('a', {
className: 'description', className: 'description',
href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()), //TODO: sectionLink is a dependency passed in that knows about catchingExceptions
//so we don't pass catchExceptions everywhere.
href: this.jasmine.HtmlReporter.sectionLink(this.spec.getFullName(), catchExceptions),
title: this.spec.getFullName() title: this.spec.getFullName()
}, this.spec.description) }, this.spec.description)
); );
@@ -24,16 +28,15 @@ jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
}; };
jasmine.HtmlReporter.SpecView.prototype.status = function() { jasmine.HtmlReporter.SpecView.prototype.status = function() {
return this.getSpecStatus(this.spec); return this.spec.status();
}; };
jasmine.HtmlReporter.SpecView.prototype.refresh = function() { jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
this.symbol.className = this.status(); this.symbol.className = this.status();
switch (this.status()) { switch (this.status()) {
case 'skipped': case 'disabled':
break; break;
case 'passed': case 'passed':
this.appendSummaryToSuiteDiv(); this.appendSummaryToSuiteDiv();
break; break;
@@ -53,7 +56,7 @@ jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() { jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
this.detail.className += ' ' + this.status(); this.detail.className += ' ' + this.status();
var resultItems = this.spec.results().getItems(); var resultItems = this.spec.failedExpectations;
var messagesDiv = this.createDom('div', { className: 'messages' }); var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) { for (var i = 0; i < resultItems.length; i++) {
@@ -61,7 +64,7 @@ jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
if (result.type == 'log') { if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) { } else if (result.type == 'expect' && !result.passed) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) { if (result.trace.stack) {
+4 -2
View File
@@ -1,10 +1,12 @@
jasmine.HtmlReporter.SuiteView = function(suite, dom, views) { jasmine.HtmlReporter.SuiteView = function(suite, dom, views, jasmine, catchExceptions) {
this.suite = suite; this.suite = suite;
this.dom = dom; this.dom = dom;
this.views = views; this.views = views;
this.jasmine = jasmine || {};
this.catchExceptions = catchExceptions;
this.element = this.createDom('div', { className: 'suite' }, this.element = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description) this.createDom('a', { className: 'description', href: this.jasmine.HtmlReporter.sectionLink(this.suite.getFullName(), catchExceptions) }, this.suite.description)
); );
this.appendToSummary(this.suite, this.element); this.appendToSummary(this.suite, this.element);
-192
View File
@@ -1,192 +0,0 @@
/* @deprecated Use jasmine.HtmlReporter instead
*/
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', { id: 'TrivialReporter', 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;
};
+80 -68
View File
@@ -3,7 +3,7 @@
$line-height: 14px; $line-height: 14px;
$margin-unit: 14px; $margin-unit: 14px;
$feint-text-color: #aaa; $faint-text-color: #aaa;
$light-text-color: #666; $light-text-color: #666;
$text-color: #333; $text-color: #333;
@@ -27,7 +27,7 @@ body {
overflow-y: scroll; overflow-y: scroll;
} }
#HTMLReporter { .html-reporter {
font-size: $font-size; font-size: $font-size;
font-family: Monaco, "Lucida Console", monospace; font-family: Monaco, "Lucida Console", monospace;
@@ -48,16 +48,21 @@ body {
} }
.banner, .banner,
.symbolSummary, .symbol-summary,
.summary, .summary,
.resultMessage, .result-message,
.specDetail .description, .spec .description,
.spec-detail .description,
.alert .bar, .alert .bar,
.stackTrace { .stack-trace {
padding-left: $margin-unit - 5px; padding-left: $margin-unit - 5px;
padding-right: $margin-unit - 5px; padding-right: $margin-unit - 5px;
} }
.banner .version {
margin-left: $margin-unit;
};
// This div is available for testing elements that must be added to the DOM. // This div is available for testing elements that must be added to the DOM.
// We position it out of view, so it doesn't obstruct the runner. // We position it out of view, so it doesn't obstruct the runner.
#jasmine_content { #jasmine_content {
@@ -66,7 +71,7 @@ body {
} }
.version { .version {
color: $feint-text-color; color: $faint-text-color;
} }
//--- Banner ---// //--- Banner ---//
@@ -76,13 +81,13 @@ body {
} }
.duration { .duration {
color: $feint-text-color; color: $faint-text-color;
float: right; float: right;
} }
//--- Symbol summary ---// //--- Symbol summary ---//
.symbolSummary { .symbol-summary {
@include clearfix; @include clearfix;
margin: $line-height 0; margin: $line-height 0;
@@ -93,14 +98,12 @@ body {
width: $line-height; width: $line-height;
margin-bottom: $line-height / 2; margin-bottom: $line-height / 2;
//opacity: .9;
font-size: 16px; font-size: 16px;
&.passed { &.passed {
font-size: 14px; font-size: 14px;
&:before{ &:before {
color: $passing-color; color: $passing-color;
content: "\02022"; content: "\02022";
} }
@@ -109,7 +112,7 @@ body {
&.failed { &.failed {
line-height: ($line-height / 2) + 2; line-height: ($line-height / 2) + 2;
&:before{ &:before {
color: $failing-color; color: $failing-color;
content: "x"; content: "x";
font-weight: bold; font-weight: bold;
@@ -117,20 +120,20 @@ body {
} }
} }
&.skipped { &.disabled {
font-size: 14px; font-size: 14px;
&:before{ &:before {
color: $neutral-color; color: $neutral-color;
content: "\02022"; content: "\02022";
} }
} }
&.pending{ &.pending {
line-height: ($line-height / 2) + 4; line-height: ($line-height / 2) + 4;
&:before { &:before {
color: $feint-text-color; color: $faint-text-color;
content: "-"; content: "-";
} }
} }
@@ -144,7 +147,7 @@ body {
margin-right: 5px; margin-right: 5px;
} }
//--- Alert ---// //--- Alerts: status bars ---//
.bar { .bar {
line-height: $line-height * 2; line-height: $line-height * 2;
@@ -152,40 +155,50 @@ body {
display: block; display: block;
color: #eee; color: #eee;
}
.runningAlert { &.failed {
background-color: $light-text-color;
}
.skippedAlert {
background-color: $feint-text-color;
&:first-child {
background-color: $text-color;
}
&:hover {
text-decoration: none;
color: white;
text-decoration: underline;
}
}
.passingAlert {
background-color: $light-passing-color;
&:first-child {
background-color: $passing-color;
}
}
.failingAlert {
background-color: $light-failing-color;
&:first-child {
background-color: $failing-color background-color: $failing-color
} }
&.passed {
background-color: $light-passing-color;
}
&.skipped {
background-color: $neutral-color;
}
&.menu {
background-color: #fff;
color: $faint-text-color;
a {
color: $text-color;
}
}
a {
color: white;
}
}
// simplify toggle control between the two menu bars
&.spec-list {
.bar.menu.failure-list,
.results .failures {
display: none;
}
}
&.failure-list {
.bar.menu.spec-list,
.summary {
display: none;
}
}
.running-alert {
background-color: $light-text-color;
} }
//--- Results ---// //--- Results ---//
@@ -196,16 +209,6 @@ body {
//--- Results menu ---// //--- Results menu ---//
#details {
display: none;
}
.resultsMenu,
.resultsMenu a {
background-color: #fff;
color: $text-color;
}
&.showDetails { &.showDetails {
.summaryMenuItem { .summaryMenuItem {
@@ -236,19 +239,28 @@ body {
text-decoration: underline; text-decoration: underline;
} }
//--- Results summary ---// //--- Results summary: Suites and Specs names/links ---//
.summary { .summary {
margin-top: $margin-unit; margin-top: $margin-unit;
.suite .suite, .specSummary { ul {
list-style-type: none;
margin-left: $margin-unit; margin-left: $margin-unit;
padding-top: 0;
padding-left: 0;
&.suite {
margin-top: $margin-unit/2;
margin-bottom: $margin-unit/2
}
} }
.specSummary { li {
&.passed a { &.passed a {
color: $passing-color; color: $passing-color;
} }
&.failed a { &.failed a {
color: $failing-color; color: $failing-color;
} }
@@ -267,10 +279,10 @@ body {
} }
} }
//--- Results details ---// //--- Failure details ---//
#details { .failures {
.specDetail { .spec-detail {
margin-bottom: $line-height * 2; margin-bottom: $line-height * 2;
.description { .description {
@@ -285,17 +297,17 @@ body {
} }
} }
.resultMessage { .result-message {
padding-top: $line-height; padding-top: $line-height;
color: $text-color; color: $text-color;
} }
.resultMessage span.result { .result-message span.result {
display: block; display: block;
} }
.stackTrace { .stack-trace {
margin: 5px 0 0 0; margin: 5px 0 0 0;
max-height: $line-height * 16; max-height: $line-height * 16;
overflow: auto; overflow: auto;
-169
View File
@@ -1,169 +0,0 @@
#TrivialReporter {
padding: 8px 13px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: scroll;
background-color: white;
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
a:visited, a {
color: #303;
}
a:hover, a:active {
color: blue;
}
.run_spec {
float:right;
padding-right: 5px;
font-size: .8em;
text-decoration: none;
}
.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;
}
}
+51 -80
View File
@@ -1,82 +1,53 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; } body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; } .html-reporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; } .html-reporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; } .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; } .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; } .html-reporter .banner .version { margin-left: 14px; }
#HTMLReporter .version { color: #aaaaaa; } .html-reporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .banner { margin-top: 14px; } .html-reporter .version { color: #aaaaaa; }
#HTMLReporter .duration { color: #aaaaaa; float: right; } .html-reporter .banner { margin-top: 14px; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; } .html-reporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; } .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; } .html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; } .html-reporter .symbol-summary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; } .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; } .html-reporter .symbol-summary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; } .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; } .html-reporter .symbol-summary li.disabled { font-size: 14px; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; } .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; } .html-reporter .symbol-summary li.pending { line-height: 11px; }
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } .html-reporter .symbol-summary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
#HTMLReporter .runningAlert { background-color: #666666; } .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; } .html-reporter .bar.failed { background-color: #b03911; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; } .html-reporter .bar.passed { background-color: #a6b779; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; } .html-reporter .bar.skipped { background-color: #bababa; }
#HTMLReporter .passingAlert { background-color: #a6b779; } .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; } .html-reporter .bar.menu a { color: #333333; }
#HTMLReporter .failingAlert { background-color: #cf867e; } .html-reporter .bar a { color: white; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; } .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
#HTMLReporter .results { margin-top: 14px; } .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
#HTMLReporter #details { display: none; } .html-reporter .running-alert { background-color: #666666; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; } .html-reporter .results { margin-top: 14px; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; } .html-reporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; } .html-reporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; } .html-reporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; } .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; } .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; } .html-reporter .summary li.passed a { color: #5e7d00; }
#HTMLReporter .description + .suite { margin-top: 0; } .html-reporter .summary li.failed a { color: #b03911; }
#HTMLReporter .suite { margin-top: 14px; } .html-reporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite a { color: #333333; } .html-reporter .suite { margin-top: 14px; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; } .html-reporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; } .html-reporter .failures .spec-detail { margin-bottom: 28px; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; } .html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage span.result { display: block; } .html-reporter .result-message { padding-top: 14px; color: #333333; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } .html-reporter .result-message span.result { display: block; }
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
-1
View File
@@ -1,2 +1 @@
@import "HTMLReporter"; @import "HTMLReporter";
@import "TrivialReporter";
+1 -1
View File
@@ -21,7 +21,7 @@ class JasmineDev < Thor
def count_specs_in(relative_path) def count_specs_in(relative_path)
files = Dir.glob(File.join(JasmineDev.project_root, relative_path, '*.js')) files = Dir.glob(File.join(JasmineDev.project_root, relative_path, '*.js'))
files.inject(0) do |count, file| files.inject(0) do |count, file|
File.read(file).scan(/\sit\s*\(/) { |s| count += 1 } File.read(file).scan(/^\s*it\(.*/) { |s| count += 1 }
count count
end end
end end
+8 -14
View File
@@ -3,30 +3,24 @@ class JasmineDev < Thor
:core => [ :core => [
"base.js", "base.js",
"util.js", "util.js",
"ExceptionFormatter.js",
"ExpectationResult.js",
"Env.js", "Env.js",
"Reporter.js",
"Block.js",
"JsApiReporter.js", "JsApiReporter.js",
"Matchers.js", "Matchers.js",
"mock-timeout.js",
"MultiReporter.js",
"NestedResults.js",
"PrettyPrinter.js", "PrettyPrinter.js",
"Queue.js", "QueueRunner.js",
"Runner.js",
"Spec.js", "Spec.js",
"Suite.js", "Suite.js",
"WaitsBlock.js", "Clock.js",
"WaitsForBlock.js" "DelayedFunctionScheduler.js",
"ReportDispatcher.js"
], ],
:html => [ :html => [
"HtmlReporterHelpers.js",
"HtmlReporter.js", "HtmlReporter.js",
"ReporterView.js", "ResultsNode.js",
"SpecView.js", "QueryString.js"
"SuiteView.js",
"TrivialReporter.js"
] ]
} }
end end