Merge in new HTML runner. Tests green, regression on focused running.

This commit is contained in:
ragaskar 2009-08-19 07:42:47 -07:00
commit 0a3358f249
20 changed files with 462 additions and 164 deletions

View File

@ -19,15 +19,39 @@ module Jasmine
port
end
class RunAdapter
def initialize(spec_files)
p "spec_files: #{spec_files}"
def self.server_is_listening_on(hostname, port)
require 'socket'
begin
socket = TCPSocket.open(hostname, port)
rescue Errno::ECONNREFUSED
return false
end
socket.close
true
end
@spec_files = spec_files
def self.wait_for_listener(port, name = "required process", seconds_to_wait = 10)
time_out_at = Time.now + seconds_to_wait
until server_is_listening_on "localhost", port
sleep 0.1
puts "Waiting for #{name} on #{port}..."
raise "#{name} didn't show up on port #{port} after #{seconds_to_wait} seconds." if Time.now > time_out_at
end
end
def self.kill_process_group(process_group_id, signal="TERM")
Process.kill signal, -process_group_id # negative pid means kill process group. (see man 2 kill)
end
class RunAdapter
def initialize(spec_files_or_proc)
@spec_files_or_proc = spec_files_or_proc
end
def call(env)
spec_files = @spec_files
spec_files = @spec_files_or_proc
spec_files = spec_files.call if spec_files.respond_to?(:call)
body = ERB.new(File.read(File.join(File.dirname(__FILE__), "run.html"))).result(binding)
[
200,
@ -38,11 +62,11 @@ module Jasmine
end
class SimpleServer
def self.start(port, spec_dir, mappings)
def self.start(port, spec_files_or_proc, mappings)
require 'thin'
config = {
'/run.html' => Jasmine::RunAdapter.new(spec_dir)
'/run.html' => Jasmine::RunAdapter.new(spec_files_or_proc)
}
mappings.each do |from, to|
config[from] = Rack::File.new(to)
@ -50,7 +74,6 @@ module Jasmine
app = Rack::URLMap.new(config)
server_port = Jasmine::find_unused_port
Thin::Server.start('0.0.0.0', port, app)
end
end
@ -119,26 +142,6 @@ module Jasmine
stop_servers
end
def server_is_listening_on(hostname, port)
require 'socket'
begin
socket = TCPSocket.open(hostname, port)
rescue Errno::ECONNREFUSED
return false
end
socket.close
true
end
def wait_for_listener(port, name = "required process", seconds_to_wait = 10)
seconds_waited = 0
until server_is_listening_on "localhost", port
sleep 1
puts "Waiting for #{name} on #{port}..."
raise "#{name} didn't show up on port #{port} after #{seconds_to_wait} seconds." if (seconds_waited += 1) >= seconds_to_wait
end
end
def start_servers
@jasmine_server_port = Jasmine::find_unused_port
@selenium_server_port = Jasmine::find_unused_port
@ -156,18 +159,14 @@ module Jasmine
end
puts "jasmine server started. pid is #{@jasmine_server_pid}"
wait_for_listener(@selenium_server_port, "selenium server")
wait_for_listener(@jasmine_server_port, "jasmine server")
end
def kill_process_group(process_group_id, signal="TERM")
Process.kill signal, -process_group_id # negative pid means kill process group. (see man 2 kill)
Jasmine::wait_for_listener(@selenium_server_port, "selenium server")
Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
end
def stop_servers
puts "shutting down the servers..."
kill_process_group(@selenium_pid) if @selenium_pid
kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
Jasmine::kill_process_group(@selenium_pid) if @selenium_pid
Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
end
def run

View File

@ -0,0 +1,51 @@
require 'spec'
require 'open-uri'
require File.dirname(__FILE__) + '/jasmine_runner'
describe Jasmine::SimpleServer do
before do
@port = Jasmine::find_unused_port
end
after do
Jasmine::kill_process_group(@jasmine_server_pid) if @jasmine_server_pid
end
it "should start and print script tags" do
@jasmine_server_pid = fork do
Process.setpgrp
Jasmine::SimpleServer.start(@port, ["file1", "file2"], {})
exit! 0
end
Jasmine::wait_for_listener(@port)
run_html = open("http://localhost:#{@port}/run.html").read
run_html.should =~ /<script src="file1"/
run_html.should =~ /<script src="file2"/
end
it "should take a proc that returns a list of spec files" do
spec_fileses = [["file1", "file2"], ["file1", "file2", "file3"]]
spec_files_proc = lambda do
spec_fileses.shift
end
@jasmine_server_pid = fork do
Process.setpgrp
Jasmine::SimpleServer.start(@port, spec_files_proc, {})
exit! 0
end
Jasmine::wait_for_listener(@port)
run_html = open("http://localhost:#{@port}/run.html").read
run_html.should =~ /<script src="file1"/
run_html.should =~ /<script src="file2"/
run_html = open("http://localhost:#{@port}/run.html").read
run_html.should =~ /<script src="file1"/
run_html.should =~ /<script src="file2"/
run_html.should =~ /<script src="file3"/
end
end

View File

@ -121,7 +121,7 @@ module Jasmine
out << "\n"
unless message["passed"]
stack_trace = message["trace"]["stack"]
stack_trace = message["trace"]["stack"].gsub(/<br \/>/, "\n").gsub(/<\/?b>/, " ")
STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
STDERR << "\n"
end

View File

@ -3,20 +3,32 @@
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
<title>Jasmine suite</title>
<script src="/specs/javascripts/jasmine/lib/jasmine.js"></script>
<script src="/specs/javascripts/jasmine/lib/json2.js"></script><!-- todo: don't load JSON in the test runner! [20090710 xw] -->
<script src="/specs/javascripts/jasmine/lib/TrivialReporter.js"></script>
<script src="/jasmine/lib/jasmine.js"></script>
<script src="/jasmine/lib/json2.js"></script><!-- todo: don't load JSON in the test runner! [20090710 xw] -->
<script src="/jasmine/lib/TrivialReporter.js"></script>
<script src="/specs/javascripts/screw-jasmine-compat.js"></script>
<script type="text/javascript"></script>
<link href="/core/jasmine.css" rel="stylesheet"/>
<link href="/jasmine/lib/jasmine.css" rel="stylesheet"/>
<script type="text/javascript">
var jasmineEnv = jasmine.getEnv();
var jsApiReporter = new jasmine.JsApiReporter();
jasmineEnv.addReporter(jsApiReporter);
jasmineEnv.addReporter(new jasmine.TrivialReporter());
window.onload = function() {
jasmineEnv.execute();
};
var jsApiReporter;
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
jsApiReporter = new jasmine.JsApiReporter();
var trivialReporter = new jasmine.TrivialReporter();
jasmineEnv.addReporter(jsApiReporter);
jasmineEnv.addReporter(trivialReporter);
jasmineEnv.specFilter = function(spec) {
return trivialReporter.specFilter(spec);
};
window.onload = function() {
jasmineEnv.execute();
};
})();
</script>
<% spec_files.each do |spec_file| %>

View File

@ -1,4 +1,6 @@
jasmine.TrivialReporter = function() {
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
@ -25,37 +27,88 @@ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarA
return el;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var suites = runner.getAllSuites();
this.runnerDiv = this.createDom('div', { className: 'runner running' }, "Running...");
this.document.body.appendChild(this.runnerDiv);
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'runSpec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
suite.description);
this.suiteDivs[suite.getFullName()] = suiteDiv;
var parentDiv = this.document.body;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.getFullName()];
}
parentDiv.appendChild(suiteDiv);
}
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
console.log(runner);
var results = runner.getResults();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
var message = results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
this.runnerDiv.replaceChild(this.document.createTextNode(message), this.runnerDiv.firstChild);
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
console.log(suite);
var results = suite.getResults();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount == 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.getFullName()].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var specDiv = this.createDom('div', {
className: spec.getResults().passed() ? 'spec passed' : 'spec failed'
}, spec.getFullName());
var results = spec.getResults();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'runSpec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
spec.getFullName());
var resultItems = spec.getResults().getItems();
var resultItems = results.getItems();
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (!result.passed) {
var resultMessageDiv = this.createDom('div', {className: 'resultMessage'});
if (!result.passed()) {
var resultMessageDiv = this.createDom('div', {className: 'resultMessage fail'});
resultMessageDiv.innerHTML = result.message; // todo: lame; mend
specDiv.appendChild(resultMessageDiv);
specDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
document.body.appendChild(specDiv);
this.suiteDivs[spec.suite.getFullName()].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
console.log.apply(console, arguments);
};
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;
};
//protect against console.log incidents
if (!("console" in window) || !("firebug" in console)) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

View File

@ -1,6 +1,5 @@
body {
font: 14px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
padding-left: 40px;
}
h1 {
@ -14,11 +13,74 @@ p {
padding-left: 20px;
}
p.fail {
.fail {
background: url( ../images/fail-16.png ) no-repeat;
padding-left: 20px;
color: red;
}
p.fail_in_summary {
.failInSummary {
color: red;
}
.runner {
border: 1px outset gray;
margin: 5px;
padding-left: 1em;
}
.runner.running {
background-color: yellow;
}
.suite {
border: 1px outset gray;
margin: 5px;
padding-left: 1em;
}
.suite.passed {
background-color: #cfc;
}
.suite.failed {
background-color: #fdd;
}
.spec {
margin: 5px;
clear: both;
}
.passed {
background-color: lightgreen;
}
.failed {
background-color: pink;
}
.skipped {
color: #777;
background-color: #eee;
}
.resultMessage {
white-space: pre;
}
.stackTrace {
white-space: pre;
font-size: .8em;
margin-left: 10px;
height: 5em;
overflow: auto;
border: 1px inset red;
padding: 1em;
background: #eef;
}
.runSpec {
margin-left: 5px;
float: right;
}

View File

@ -1084,6 +1084,16 @@ jasmine.Matchers.prototype.toNotContain = function(item) {
'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
};
jasmine.Matchers.prototype.toBeLessThan = function(expected) {
return this.report(this.actual < expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.report(this.actual > expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
/**
* Matcher that checks that the expected exception was thrown by the actual.
*
@ -1366,7 +1376,8 @@ jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
jasmine.StringPrettyPrinter.prototype.append = function(value) {
this.string += value;
};
jasmine.Queue = function() {
jasmine.Queue = function(env) {
this.env = env;
this.blocks = [];
this.running = false;
this.index = 0;
@ -1405,13 +1416,17 @@ jasmine.Queue.prototype.isRunning = function () {
jasmine.Queue.prototype._next = function () {
var self = this;
self.offset = 0;
self.index++;
if (self.index < self.blocks.length) {
self.blocks[self.index].execute(function () {self._next();});
} else {
self.finish();
}
self.env.setTimeout(function () {
self.offset = 0;
self.index++;
if (self.index < self.blocks.length) {
self.blocks[self.index].execute(function () {
self._next();
});
} else {
self.finish();
}
}, 0);
};
jasmine.Queue.prototype.finish = function () {
@ -1472,7 +1487,7 @@ jasmine.Reporters.reporter = function(callbacks) {
jasmine.Runner = function(env) {
var self = this;
self.env = env;
self.queue = new jasmine.Queue();
self.queue = new jasmine.Queue(env);
};
jasmine.Runner.prototype.execute = function() {
@ -1487,10 +1502,34 @@ jasmine.Runner.prototype.finishCallback = function() {
this.env.reporter.reportRunnerResults(this);
};
jasmine.Runner.prototype.add = function(block) {
this.queue.add(block);
};
jasmine.Runner.prototype.getAllSuites = function() {
var suitesToReturn = [];
function addSuite(suite) {
suitesToReturn.push(suite);
for (var j = 0; j < suite.specs.length; j++) {
var spec = suite.specs[j];
if (spec instanceof jasmine.Suite) {
addSuite(spec);
}
}
}
for (var i = 0; i < this.suites.length; i++) {
var suite = this.suites[i];
addSuite(suite);
}
return suitesToReturn;
};
jasmine.Runner.prototype.getResults = function() {
var results = new jasmine.NestedResults();
var runnerResults = this.queue.getResults();
@ -1516,7 +1555,7 @@ jasmine.Spec = function(env, suite, description) {
spec.env = env;
spec.suite = suite;
spec.description = description;
spec.queue = new jasmine.Queue();
spec.queue = new jasmine.Queue(env);
spec.finished = false;
spec.afterCallbacks = [];
@ -1705,7 +1744,7 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
var self = this;
self.id = env.nextSuiteId_++;
self.description = description;
self.queue = new jasmine.Queue();
self.queue = new jasmine.Queue(env);
self.parentSuite = parentSuite;
self.env = env;
self.beforeQueue = [];

View File

@ -3,6 +3,7 @@
<html>
<head>
<title>Jasmine Test Runner</title>
<script type="text/javascript" src="../src/base.js"></script>
<script type="text/javascript" src="../src/util.js"></script>
<script type="text/javascript" src="../src/Env.js"></script>
@ -35,33 +36,12 @@
jasmine.include('suites/RunnerTest.js', true);
jasmine.include('suites/SpecRunningTest.js', true);
jasmine.include('suites/SpyTest.js', true);
jasmine.include('suites/TrivialReporterTest.js', true);
</script>
<style type="text/css">
.spec {
margin: 5px;
}
.passed {
background-color: lightgreen;
}
.failed {
background-color: pink;
}
.resultMessage {
white-space: pre;
}
.stackTrace {
white-space: pre;
font-size: .8em;
margin-left: 10px;
}
</style>
<link href="../lib/jasmine.css" rel="stylesheet"/>
</head>
<body>
<script type="text/javascript">

View File

@ -77,20 +77,29 @@ describe('Exceptions:', function() {
fakeTimer.tick(2500);
var suiteResults = suite.getResults();
expect(suiteResults.length).toEqual(5);
expect(suiteResults[0].passed()).toEqual(false);
expect(suiteResults[0].items_[0].message).toMatch(/fake error 1/);
var specResults = suiteResults.getItems();
expect(suiteResults[1].passed()).toEqual(false),
expect(suiteResults[1].items_[0].message).toMatch(/fake error 2/),
expect(suiteResults[1].items_[1].passed).toEqual(true);
expect(suiteResults.passed()).toEqual(false);
expect(suiteResults[2].passed()).toEqual(true);
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(suiteResults[3].passed()).toEqual(false);
expect(suiteResults[3].items_[0].message).toMatch(/fake error 3/);
expect(specResults[1].passed()).toEqual(false);
var 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(suiteResults[4].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);
});

View File

@ -167,6 +167,18 @@ describe("jasmine.Matchers", function() {
});
});
it("toBeLessThan should pass if actual is less than expected", function() {
expect(match(37).toBeLessThan(42)).toEqual(true);
expect(match(37).toBeLessThan(-42)).toEqual(false);
expect(match(37).toBeLessThan(37)).toEqual(false);
});
it("toBeGreaterThan should pass if actual is greater than expected", function() {
expect(match(37).toBeGreaterThan(42)).toEqual(false);
expect(match(37).toBeGreaterThan(-42)).toEqual(true);
expect(match(37).toBeGreaterThan(37)).toEqual(false);
});
it("toThrow", function() {
var expected = new jasmine.Matchers(env, function() {
throw new Error("Fake Error");
@ -210,7 +222,7 @@ describe("jasmine.Matchers", function() {
expected = match(TestClass.someFunction);
expect(expected.wasCalledWith('c', 'b', 'a')).toEqual(false);
expect(expected.getResults().getItems()[0].passed).toEqual(false);
expect(expected.getResults().getItems()[0].passed()).toEqual(false);
TestClass.someFunction.reset();
TestClass.someFunction('a', 'b', 'c');
@ -233,9 +245,9 @@ describe("jasmine.Matchers", function() {
expect(results.getItems().length).toEqual(2);
expect(results.getItems()[0].passed).toEqual(true);
expect(results.getItems()[0].passed()).toEqual(true);
expect(results.getItems()[1].passed).toEqual(false);
expect(results.getItems()[1].passed()).toEqual(false);
results = new jasmine.NestedResults();
expected = new jasmine.Matchers(env, false, results);
@ -285,17 +297,17 @@ describe("jasmine.Matchers", function() {
expected = new jasmine.Matchers(env, [1, 2, 3], results);
results.getItems().length = 0;
expected.toEqual([1, 2, 3]);
expect(results.getItems()[0].passed).toEqual(true);
expect(results.getItems()[0].passed()).toEqual(true);
expected = new jasmine.Matchers(env, [1, 2, 3], results);
results.getItems().length = 0;
expected.toEqual([{}, {}, {}]);
expect(results.getItems()[0].passed).toEqual(false);
expect(results.getItems()[0].passed()).toEqual(false);
expected = new jasmine.Matchers(env, [{}, {}, {}], results);
results.getItems().length = 0;
expected.toEqual([1, 2, 3]);
expect(results.getItems()[0].passed).toEqual(false);
expect(results.getItems()[0].passed()).toEqual(false);
});
});

View File

@ -3,14 +3,14 @@ describe('jasmine.NestedResults', function() {
// Leaf case
var results = new jasmine.NestedResults();
results.addResult({passed: true, message: 'Passed.'});
results.addResult(new jasmine.ExpectationResult(true,'Passed.'));
expect(results.getItems().length).toEqual(1);
expect(results.totalCount).toEqual(1);
expect(results.passedCount).toEqual(1);
expect(results.failedCount).toEqual(0);
results.addResult({passed: false, message: 'FAIL.'});
results.addResult(new jasmine.ExpectationResult(false, 'FAIL.'));
expect(results.getItems().length).toEqual(2);
expect(results.totalCount).toEqual(2);
@ -21,12 +21,12 @@ describe('jasmine.NestedResults', function() {
it('should roll up counts for nested results', function() {
// Branch case
var leafResultsOne = new jasmine.NestedResults();
leafResultsOne.addResult({passed: true, message: ''});
leafResultsOne.addResult({passed: false, message: ''});
leafResultsOne.addResult(new jasmine.ExpectationResult( true, ''));
leafResultsOne.addResult(new jasmine.ExpectationResult( false, ''));
var leafResultsTwo = new jasmine.NestedResults();
leafResultsTwo.addResult({passed: true, message: ''});
leafResultsTwo.addResult({passed: false, message: ''});
leafResultsTwo.addResult(new jasmine.ExpectationResult( true, ''));
leafResultsTwo.addResult(new jasmine.ExpectationResult( false, ''));
var branchResults = new jasmine.NestedResults();
branchResults.addResult(leafResultsOne);

View File

@ -122,11 +122,32 @@ describe('RunnerTest', function() {
expect(fakeReporter.reportRunnerResults).wasCalledWith(env.currentRunner);
});
it("should report when the tests start running", function() {
expect(fakeReporter.reportRunnerStarting).wasNotCalled();
env.currentRunner.execute();
expect(fakeReporter.reportRunnerStarting).wasCalledWith(env.currentRunner);
});
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);
spyOn(runner.queue, 'start');
runner.execute();
expect(fakeReporter.reportRunnerStarting).wasCalledWith(runner);
expect(runner.queue.start).wasCalled();
});
it("should return a flat array of all suites, including nested suites", function() {
var suite1, suite2;
suite1 = env.describe("spec 1", function() {
suite2 = env.describe("nested spec", function() {});
});
document.runner = env.currentRunner;
var suites = env.currentRunner.getAllSuites();
expect(suites).toEqual([suite1, suite2]);
});
});

View File

@ -69,10 +69,10 @@ describe("jasmine spec running", function () {
expect(specWithNoBody.description).toEqual('new spec');
expect(specWithExpectation.results.getItems().length).toEqual(1); // "Results aren't there after a spec was executed"
expect(specWithExpectation.results.getItems()[0].passed).toEqual(true); // "Results has a result, but it's true"
expect(specWithExpectation.results.getItems()[0].passed()).toEqual(true); // "Results has a result, but it's true"
expect(specWithExpectation.results.description).toEqual('spec with an expectation'); // "Spec's results did not get the spec's description"
expect(specWithFailingExpectations.results.getItems()[0].passed).toEqual(false); // "Expectation that failed, passed"
expect(specWithFailingExpectations.results.getItems()[0].passed()).toEqual(false); // "Expectation that failed, passed"
expect(specWithMultipleExpectations.results.getItems().length).toEqual(2); // "Spec doesn't support multiple expectations"
});
@ -91,8 +91,8 @@ describe("jasmine spec running", function () {
another_spec.done = true;
expect(another_spec.results.getItems().length).toEqual(2);
expect(another_spec.results.getItems()[0].passed).toEqual(true); // "In a spec without a run block, expected first expectation result to be true but was false"
expect(another_spec.results.getItems()[1].passed).toEqual(false); // "In a spec without a run block, expected second expectation result to be false but was true";
expect(another_spec.results.getItems()[0].passed()).toEqual(true); // "In a spec without a run block, expected first expectation result to be true but was false"
expect(another_spec.results.getItems()[1].passed()).toEqual(false); // "In a spec without a run block, expected second expectation result to be false but was true";
expect(another_spec.results.description).toEqual('spec with an expectation'); // "In a spec without a run block, results did not include the spec's description";
});
@ -145,7 +145,7 @@ describe("jasmine spec running", function () {
fakeTimer.tick(0);
expect(a_spec.results.getItems().length).toEqual(1); // 'No call to waits(): Spec queue did not run all functions';
expect(a_spec.results.getItems()[0].passed).toEqual(true); // 'No call to waits(): Queued expectation failed';
expect(a_spec.results.getItems()[0].passed()).toEqual(true); // 'No call to waits(): Queued expectation failed';
foo = 0;
env.describe('test async spec', function() {
@ -173,7 +173,7 @@ describe("jasmine spec running", function () {
fakeTimer.tick(500);
expect(a_spec.results.getItems().length).toEqual(1); // 'Calling waits(): Spec queue did not run all functions';
expect(a_spec.results.getItems()[0].passed).toEqual(true); // 'Calling waits(): Queued expectation failed';
expect(a_spec.results.getItems()[0].passed()).toEqual(true); // 'Calling waits(): Queued expectation failed';
var bar = 0;
var another_spec;
@ -204,7 +204,7 @@ describe("jasmine spec running", function () {
fakeTimer.tick(1000);
expect(another_spec.results.getItems().length).toEqual(1);
expect(another_spec.results.getItems()[0].passed).toEqual(true);
expect(another_spec.results.getItems()[0].passed()).toEqual(true);
var baz = 0;
var yet_another_spec;
@ -230,7 +230,7 @@ describe("jasmine spec running", function () {
expect(yet_another_spec.results.getItems().length).toEqual(1);
expect(yet_another_spec.results.getItems()[0].passed).toEqual(false);
expect(yet_another_spec.results.getItems()[0].passed()).toEqual(false);
});
it("testAsyncSpecsWithMockSuite", function () {
@ -259,7 +259,7 @@ describe("jasmine spec running", function () {
another_spec.execute();
fakeTimer.tick(2000);
expect(another_spec.results.getItems().length).toEqual(1);
expect(another_spec.results.getItems()[0].passed).toEqual(true);
expect(another_spec.results.getItems()[0].passed()).toEqual(true);
});
it("testWaitsFor", function() {
@ -429,11 +429,11 @@ describe("jasmine spec running", function () {
suiteWithBefore.execute();
fakeTimer.tick(0);
var suite = suiteWithBefore;
expect(suite.beforeEachFunction); // "testBeforeAndAfterCallbacks: Suite's beforeEach was not defined");
expect(suite.getResults()[0].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the first spec's foo should have been 2");
expect(suite.getResults()[1].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the second spec's this.foo should have been 2");
expect(suite.getResults().getItems()[0].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the first spec's foo should have been 2");
expect(suite.getResults().getItems()[1].passed()).toEqual(true); // "testBeforeAndAfterCallbacks: the second spec's this.foo should have been 2");
var foo = 1;
@ -461,8 +461,8 @@ describe("jasmine spec running", function () {
suite = suiteWithAfter;
expect(suite.afterEach.length).toEqual(1);
expect(suite.getResults()[0].passed()).toEqual(true);
expect(suite.getResults()[1].passed()).toEqual(true);
expect(suite.getResults().getItems()[0].passed()).toEqual(true);
expect(suite.getResults().getItems()[1].passed()).toEqual(true);
expect(foo).toEqual(0);
});
@ -822,8 +822,8 @@ describe("jasmine spec running", function () {
expect(report).toEqual("firstsecond");
var suiteResults = suite.getResults();
expect(suiteResults[0].getItems()[0].passed).toEqual(false);
expect(suiteResults[1].getItems()[0].passed).toEqual(true);
expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(false);
expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true);
});
it("testAfterExecutesSafely", function() {
@ -862,16 +862,16 @@ describe("jasmine spec running", function () {
expect(report).toEqual("firstsecondthird"); // "all tests should run");
//After each errors should not go in spec results because it confuses the count.
var suiteResults = suite.getResults();
expect(suiteResults.length).toEqual(3, 'testAfterExecutesSafely should have results for three specs');
expect(suiteResults.getItems().length).toEqual(3, 'testAfterExecutesSafely should have results for three specs');
expect(suiteResults[0].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 1st spec should pass");
expect(suiteResults[1].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 2nd spec should pass");
expect(suiteResults[2].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 3rd spec should pass");
expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 1st spec should pass");
expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 2nd spec should pass");
expect(suiteResults.getItems()[2].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 3rd spec should pass");
expect(suiteResults[0].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 1st result for 1st suite spec should pass");
expect(suiteResults[0].getItems()[1].passed).toEqual(false, "testAfterExecutesSafely 2nd result for 1st suite spec should fail because afterEach failed");
expect(suiteResults[1].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 2nd suite spec should pass");
expect(suiteResults[2].getItems()[0].passed).toEqual(true, "testAfterExecutesSafely 3rd suite spec should pass");
expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 1st result for 1st suite spec should pass");
expect(suiteResults.getItems()[0].getItems()[1].passed()).toEqual(false, "testAfterExecutesSafely 2nd result for 1st suite spec should fail because afterEach failed");
expect(suiteResults.getItems()[1].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 2nd suite spec should pass");
expect(suiteResults.getItems()[2].getItems()[0].passed()).toEqual(true, "testAfterExecutesSafely 3rd suite spec should pass");
});
it("testNestedDescribes", function() {
@ -998,9 +998,9 @@ describe("jasmine spec running", function () {
fakeTimer.tick(600);
expect(spec.foo).toEqual(2);
var suiteResults = suite.getResults();
expect(suiteResults[0].getItems().length).toEqual(2);
expect(suiteResults[0].getItems()[0].passed).toEqual(false);
expect(suiteResults[0].getItems()[1].passed).toEqual(true);
expect(suiteResults.getItems()[0].getItems().length).toEqual(2);
expect(suiteResults.getItems()[0].getItems()[0].passed()).toEqual(false);
expect(suiteResults.getItems()[0].getItems()[1].passed()).toEqual(true);
});
it("shouldn't run disabled tests", function() {

View File

@ -0,0 +1,34 @@
describe("TrivialReporter", function() {
var trivialReporter;
var body;
beforeEach(function() {
body = document.createElement("body");
});
function fakeSpec(name) {
return {
getFullName: function() { return name; }
};
}
it("should run only specs beginning with spec parameter", function() {
trivialReporter = new jasmine.TrivialReporter({ 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 = new jasmine.TrivialReporter({ body: body });
trivialReporter.reportRunnerStarting({
getAllSuites: function() {
return [ new jasmine.Suite({}, "suite 1", null, null) ];
}
});
var divs = body.getElementsByTagName("div");
expect(divs.length).toEqual(2);
expect(divs[1].innerHTML).toContain("suite 1");
});
});

View File

@ -216,6 +216,16 @@ jasmine.Matchers.prototype.toNotContain = function(item) {
'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
};
jasmine.Matchers.prototype.toBeLessThan = function(expected) {
return this.report(this.actual < expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.report(this.actual > expected,
'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
};
/**
* Matcher that checks that the expected exception was thrown by the actual.
*

View File

@ -62,7 +62,7 @@ jasmine.NestedResults.prototype.addResult = function(result) {
this.rollupCounts(result);
} else {
this.totalCount++;
if (result.passed) {
if (result.passed()) {
this.passedCount++;
} else {
this.failedCount++;

View File

@ -59,9 +59,11 @@ jasmine.Queue.prototype.finish = function () {
};
jasmine.Queue.prototype.getResults = function () {
var results = [];
var results = new jasmine.NestedResults();
for (var i = 0; i < this.blocks.length; i++) {
results.push(this.blocks[i].getResults());
if (this.blocks[i].getResults) {
results.addResult(this.blocks[i].getResults());
}
}
return results;
};

View File

@ -8,6 +8,7 @@ jasmine.Runner = function(env) {
var self = this;
self.env = env;
self.queue = new jasmine.Queue(env);
self.suites = [];
};
jasmine.Runner.prototype.execute = function() {
@ -15,25 +16,31 @@ jasmine.Runner.prototype.execute = function() {
if (self.env.reporter.reportRunnerStarting) {
self.env.reporter.reportRunnerStarting(this);
}
self.queue.start(function () { self.finishCallback(); });
self.queue.start(function () {
self.finishCallback();
});
};
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.getAllSuites = function() {
return this.suites;
};
jasmine.Runner.prototype.getResults = function() {
var results = new jasmine.NestedResults();
var runnerResults = this.queue.getResults();
for (var i=0; i < runnerResults.length; i++) {
var suiteResults = runnerResults[i];
for (var j=0; j < suiteResults.length; j++) {
results.rollupCounts(suiteResults[j]);
}
}
return results;
return this.queue.getResults();
};

View File

@ -50,6 +50,9 @@ jasmine.Suite.prototype.getResults = function() {
};
jasmine.Suite.prototype.add = function(block) {
if (block instanceof jasmine.Suite) {
this.env.currentRunner.addSuite(block);
}
this.queue.add(block);
};

View File

@ -40,12 +40,16 @@ jasmine.MessageResult = function(text) {
jasmine.ExpectationResult = function(passed, message, details) {
this.type = 'ExpectationResult';
this.passed = passed;
this.passed_ = passed;
this.message = message;
this.details = details;
this.trace = new Error(message); // todo: test better
};
jasmine.ExpectationResult.prototype.passed = function () {
return this.passed_;
};
/**
* Getter for the Jasmine environment. Ensures one gets created
*/