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
GOALS_2.0.md Normal file
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?

View File

@@ -1,11 +1,11 @@
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
gem 'debugger' gem 'debugger'
end end
end end
gemspec gemspec

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:"

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

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;
}
}());

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>

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;
}; };

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; }

File diff suppressed because it is too large Load Diff

1
pages

Submodule pages deleted from dae7b20e1c

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");
}); });
}); });
}); });

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
spec/core/ClockSpec.js Normal file
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();
});
});

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']]); // });
}); //});
});

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();
});
});

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.");
});
});

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)');
});
});

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/);
}); });
}); });
}); });

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');
});
});

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'}});
});
});

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 () {

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();
});
});

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');
});
});

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);
});
});

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);
});
});

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);
});
});

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();
});
});

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);
});
});

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

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);
spec.runs(function () {
this.expect(true).toEqual(true);
this.expect(true).toEqual(true);
});
});
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]);
});
}); });
});
it("#status returns passed if all expectations in the spec have passed", function() {
var spec = new jasmine.Spec({});
spec.addExpectationResult(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');
});
});

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,65 +131,78 @@ 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;
} }
expect(exception).toBeDefined(); expect(exception).toBeDefined();
}); });
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');
}); });

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,
fakeTimer = new jasmine.FakeTimer(); id: 456,
env.setTimeout = fakeTimer.setTimeout; description: "I am a suite"
env.clearTimeout = fakeTimer.clearTimeout;
env.setInterval = fakeTimer.setInterval;
env.clearInterval = fakeTimer.clearInterval;
});
describe('Specs', function () {
var suite;
beforeEach(function() {
suite = env.describe('Suite 1', function () {
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 () {
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('should keep a count of the number of specs that are run', function() {
var suite = env.describe('one suite description', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.it('should be another test', function() {
this.runs(function () {
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.id).toEqual(456);
}); });
it('specCount should be correct even with runs/waits blocks', function() { it("returns its full name", 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"
});
});
env.it('should be another test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
this.waits(10);
this.runs(function () {
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 suite");
});
it("returns its full name when it has parent suites", function() {
var env = new jasmine.Env(),
parentSuite = new jasmine.Suite({
env: env,
description: "I am a parent suite",
parentSuite: jasmine.createSpy('pretend top level suite')
}),
suite = new jasmine.Suite({
env: env,
description: "I am a suite",
parentSuite: parentSuite
});
expect(suite.getFullName()).toEqual("I am a parent suite I am a suite");
});
it("adds before functions in order of needed execution", function() {
var env = new jasmine.Env(),
suite = new jasmine.Suite({
env: env,
description: "I am a suite"
}),
outerBefore = jasmine.createSpy('outerBeforeEach'),
innerBefore = jasmine.createSpy('insideBeforeEach');
suite.beforeEach(outerBefore);
suite.beforeEach(innerBefore);
expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
});
it("adds after functions in order of needed execution", function() {
var env = new jasmine.Env(),
suite = new jasmine.Suite({
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.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"
}); });
}); });
}); });

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);

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();
});
});
});

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...');
});
});
});

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);
}
});

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() {
@@ -35,4 +35,4 @@ describe("MatchersSpec - HTML Dependent", function () {
expect((match(nodeA).toEqual(nodeA))).toPass(); expect((match(nodeA).toEqual(nodeA))).toPass();
expect((match(nodeA).toEqual(nodeB))).toFail(); expect((match(nodeA).toEqual(nodeB))).toFail();
}); });
}); });

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();
});
});
});

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]);
});
});

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...');
});
});
});

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'

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'

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);

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);

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>

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
spec/support/boot.js Symbolic link
View File

@@ -0,0 +1 @@
../../lib/jasmine-core/boot/boot.js

2
spec/support/dev_boot.js Normal file
View File

@@ -0,0 +1,2 @@
var originalJasmine = jasmine;
jasmine = null;

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;

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);
};
}; };

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
src/core/Clock.js Normal file
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);
}
};

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);
}
}
};

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);
};
}());

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;
};

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
};
};

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) {
var children = suiteOrSpec.children();
for (var i = 0; i < children.length; i++) {
summary.children.push(this.summarize_(children[i]));
}
}
return summary;
};
jasmine.JsApiReporter.prototype.results = function() { this.jasmineDone = function() {
return this.results_; this.finished = true;
}; status = 'done';
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;
};
};

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;
}; };
}; };

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);
}
})();

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;
};

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
src/core/QueueRunner.js Normal file
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;
}
}
}
};

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);
}
}
}
};

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) {
};

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();
};

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_ = [];
};

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();
}
}
}; };

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);
};

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);
}
};

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;

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);
}
};

View File

@@ -58,10 +58,4 @@ jasmine.util.argsToArray = function(args) {
var arrayOfArgs = []; var arrayOfArgs = [];
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;
};

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);
}; };
}
};
jasmine.HtmlReporter.parameters = function(doc) {
var paramStr = doc.location.search.substring(1);
var params = [];
if (paramStr.length > 0) { if (specsExecuted < totalSpecsDefined) {
params = paramStr.split('&'); var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
} alert.appendChild(
return params; createDom("span", {className: "bar skipped"},
} createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
jasmine.HtmlReporter.sectionLink = function(sectionName) { )
var link = '?'; );
var params = []; }
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount),
statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
if (sectionName) { var results = find(".results")[0];
params.push('spec=' + encodeURIComponent(sectionName)); results.appendChild(summary);
}
if (!jasmine.CATCH_EXCEPTIONS) { summaryList(topResults, summary);
params.push("catch=false");
} function summaryList(resultsTree, domParent) {
if (params.length > 0) { var specListNode;
link += params.join("&"); 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);
}
} }
return link; function createDom(type, attrs, childrenVarArgs) {
}; var el = createElement(type);
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
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);
}
};

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
src/html/QueryString.js Normal file
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;
}
};

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
src/html/ResultsNode.js Normal file
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];
}
};

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) {
@@ -76,4 +79,4 @@ jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
} }
}; };
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView); jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);

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);

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;
};

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;
@@ -36,101 +36,104 @@ body {
a { a {
text-decoration: none; text-decoration: none;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
p, h1, h2, h3, h4, h5, h6 { p, h1, h2, h3, h4, h5, h6 {
margin: 0; margin: 0;
line-height: $line-height; line-height: $line-height;
} }
.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 {
position: fixed; position: fixed;
right: 100%; right: 100%;
} }
.version { .version {
color: $feint-text-color; color: $faint-text-color;
} }
//--- Banner ---// //--- Banner ---//
.banner { .banner {
margin-top: $line-height; margin-top: $line-height;
} }
.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;
li { li {
display: block; display: block;
float: left; float: left;
height: $line-height / 2; height: $line-height / 2;
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";
} }
} }
&.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;
margin-left: -1px; margin-left: -1px;
} }
} }
&.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;

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;
}
}

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; }

View File

@@ -1,2 +1 @@
@import "HTMLReporter"; @import "HTMLReporter";
@import "TrivialReporter";

View File

@@ -21,9 +21,9 @@ 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
end end
end end

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