diff --git a/contrib/ruby/jasmine_runner.rb b/contrib/ruby/jasmine_runner.rb
new file mode 100644
index 00000000..633c89f6
--- /dev/null
+++ b/contrib/ruby/jasmine_runner.rb
@@ -0,0 +1,188 @@
+require 'socket'
+require 'erb'
+
+module Jasmine
+ # this seemingly-over-complex method is necessary to get an open port on at least some of our Macs
+ def self.open_socket_on_unused_port
+ infos = Socket::getaddrinfo("localhost", nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)
+ families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten]
+
+ return TCPServer.open('0.0.0.0', 0) if families.has_key?('AF_INET')
+ return TCPServer.open('::', 0) if families.has_key?('AF_INET6')
+ return TCPServer.open(0)
+ end
+
+ def self.find_unused_port
+ socket = open_socket_on_unused_port
+ port = socket.addr[1]
+ socket.close
+ port
+ end
+
+ class RunAdapter
+ def initialize(spec_files)
+ p "spec_files: #{spec_files}"
+
+ @spec_files = spec_files
+ end
+
+ def call(env)
+ spec_files = @spec_files
+ body = ERB.new(File.read(File.join(File.dirname(__FILE__), "run.html"))).result(binding)
+ [
+ 200,
+ { 'Content-Type' => 'text/html' },
+ body
+ ]
+ end
+ end
+
+ class SimpleServer
+ def self.start(port, spec_dir, mappings)
+ require 'thin'
+
+ config = {
+ '/run.html' => Jasmine::RunAdapter.new(spec_dir)
+ }
+ mappings.each do |from, to|
+ config[from] = Rack::File.new(to)
+ end
+
+ app = Rack::URLMap.new(config)
+
+ server_port = Jasmine::find_unused_port
+ Thin::Server.start('0.0.0.0', port, app)
+ end
+ end
+
+ class SimpleClient
+ def initialize(selenium_host, selenium_port, selenium_browser_start_command, http_address)
+ require 'selenium'
+ @driver = Selenium::Client::Driver.new(
+ selenium_host,
+ selenium_port,
+ selenium_browser_start_command,
+ http_address
+ )
+ @http_address = http_address
+ end
+
+ def tests_have_finished?
+ @driver.get_eval("window.jasmine.getEnv().currentRunner.finished") == "true"
+ end
+
+ def connect
+ @driver.start
+ @driver.open("/run.html")
+ end
+
+ def disconnect
+ @driver.stop
+ end
+
+ def run
+ until tests_have_finished? do
+ sleep 0.1
+ end
+
+ puts @driver.get_eval("window.getResults()")
+ failed_count = @driver.get_eval("window.jasmine.getEnv().currentRunner.getResults().failedCount").to_i
+ failed_count == 0
+ end
+
+ def eval_js(script)
+ escaped_script = "'" + script.gsub(/(['\\])/) { '\\' + $1 } + "'"
+
+ result = @driver.get_eval("window.eval(#{escaped_script})")
+ JSON.parse("[#{result}]")[0]
+ end
+ end
+
+ class Runner
+ def initialize(selenium_jar_path, spec_files, dir_mappings)
+ @selenium_jar_path = selenium_jar_path
+ @spec_files = spec_files
+ @dir_mappings = dir_mappings
+
+ @selenium_pid = nil
+ @jasmine_server_pid = nil
+ end
+
+ def start
+ start_servers
+ @client = Jasmine::SimpleClient.new("localhost", @selenium_server_port, "*firefox", "http://localhost:#{@jasmine_server_port}/")
+ @client.connect
+ end
+
+ def stop
+ @client.disconnect
+ 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
+
+ @selenium_pid = fork do
+ Process.setpgrp
+ exec "java -jar #{@selenium_jar_path} -port #{@selenium_server_port} > /dev/null 2>&1"
+ end
+ puts "selenium started. pid is #{@selenium_pid}"
+
+ @jasmine_server_pid = fork do
+ Process.setpgrp
+ Jasmine::SimpleServer.start(@jasmine_server_port, @spec_files, @dir_mappings)
+ exit! 0
+ 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)
+ 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
+ end
+
+ def run
+ begin
+ start
+ puts "servers are listening on their ports -- running the test script..."
+ tests_passed = @client.run
+ ensure
+ stop
+ end
+ return tests_passed
+ end
+
+ def eval_js(script)
+ @client.eval_js(script)
+ end
+ end
+end
diff --git a/contrib/ruby/jasmine_spec_builder.rb b/contrib/ruby/jasmine_spec_builder.rb
new file mode 100644
index 00000000..0071a49d
--- /dev/null
+++ b/contrib/ruby/jasmine_spec_builder.rb
@@ -0,0 +1,142 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_runner.rb"))
+
+module Jasmine
+
+ class SpecBuilder
+ attr_accessor :suites
+
+ def initialize(spec_files, runner)
+ @spec_files = spec_files
+ @runner = runner
+ end
+
+ def start
+ guess_example_locations
+
+ @runner.start
+ load_suite_info
+ @spec_results = {}
+ end
+
+ def stop
+ @runner.stop
+ end
+
+ def script_path
+ File.expand_path(__FILE__)
+ end
+
+ def guess_example_locations
+ @example_locations = {}
+
+ example_name_parts = []
+ previous_indent_level = 0
+ @spec_files.each do |filename|
+ line_number = 1
+ File.open(filename, "r") do |file|
+ file.readlines.each do |line|
+ match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
+ if (match)
+ indent_level = match[1].length / 2
+ example_name = match[3]
+ example_name_parts[indent_level] = example_name
+
+ full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
+ @example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
+ end
+ line_number += 1
+ end
+ end
+ end
+ end
+
+ def load_suite_info
+ while !eval_js('jsApiReporter.started') do
+ sleep 0.1
+ end
+
+ @suites = eval_js('JSON.stringify(jsApiReporter.suites)')
+ end
+
+ def results_for(spec_id)
+ spec_id = spec_id.to_s
+ return @spec_results[spec_id] if @spec_results[spec_id]
+
+ @spec_results[spec_id] = eval_js("JSON.stringify(jsApiReporter.results[#{spec_id}])")
+ while @spec_results[spec_id].nil? do
+ sleep 0.1
+ @spec_results[spec_id] = eval_js("JSON.stringify(jsApiReporter.results[#{spec_id}])")
+ end
+
+ @spec_results[spec_id]
+ end
+
+ def declare_suites
+ me = self
+ suites.each do |suite|
+ declare_suite(self, suite)
+ end
+ end
+
+ def declare_suite(parent, suite)
+ me = self
+ parent.describe suite["name"] do
+ suite["children"].each do |suite_or_spec|
+ type = suite_or_spec["type"]
+ if type == "suite"
+ me.declare_suite(self, suite_or_spec)
+ elsif type == "spec"
+ me.declare_spec(self, suite_or_spec)
+ else
+ raise "unknown type #{type} for #{suite_or_spec.inspect}"
+ end
+ end
+ end
+ end
+
+ def declare_spec(parent, spec)
+ me = self
+ example_name = spec["name"]
+
+ backtrace = @example_locations[parent.description + " " + example_name]
+ parent.it example_name, {}, backtrace do
+ me.report_spec(spec["id"])
+ end
+ end
+
+ def report_spec(spec_id)
+ spec_results = results_for(spec_id)
+
+ out = ""
+ messages = spec_results['messages'].each do |message|
+ case
+ when message["type"] == "MessageResult"
+ puts message["text"]
+ puts "\n"
+ else
+ STDERR << message["message"]
+ STDERR << "\n"
+
+ out << message["message"]
+ out << "\n"
+
+ unless message["passed"]
+ stack_trace = message["trace"]["stack"]
+ STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
+ STDERR << "\n"
+ end
+ end
+
+ end
+ fail out unless spec_results['result'] == 'passed'
+ puts out
+ end
+
+ private
+
+ def eval_js(js)
+ @runner.eval_js(js)
+ end
+ end
+end
+
\ No newline at end of file
diff --git a/contrib/ruby/run.html b/contrib/ruby/run.html
new file mode 100644
index 00000000..7ddbe809
--- /dev/null
+++ b/contrib/ruby/run.html
@@ -0,0 +1,29 @@
+
+
+
+
+ Jasmine suite
+
+
+
+
+
+
+
+
+ <% spec_files.each do |spec_file| %>
+
+ <% end %>
+
+
+
+
+
diff --git a/lib/TrivialReporter.js b/lib/TrivialReporter.js
index 5d10f5d0..39b0c5e8 100644
--- a/lib/TrivialReporter.js
+++ b/lib/TrivialReporter.js
@@ -35,7 +35,7 @@ jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var specDiv = this.createDom('div', {
- className: spec.getResults().passed() ? 'spec passed' : 'spec failed'
+ className: spec.getResults().passed ? 'spec passed' : 'spec failed'
}, spec.getFullName());
var resultItems = spec.getResults().getItems();
diff --git a/lib/jasmine.js b/lib/jasmine.js
index 851d6068..63020c29 100644
--- a/lib/jasmine.js
+++ b/lib/jasmine.js
@@ -587,6 +587,7 @@ jasmine.Env = function() {
};
this.nextSpecId_ = 0;
+ this.nextSuiteId_ = 0;
this.equalityTesters_ = [];
};
@@ -869,7 +870,7 @@ jasmine.Reporter.prototype.reportSpecResults = function(spec) {
};
//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.log = function (str) {
+jasmine.Reporter.prototype.log = function(str) {
};
/**
@@ -914,7 +915,8 @@ jasmine.Block.prototype.fail = function(e) {
*/
jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
jasmine.ActionCollection.call(this, env);
-
+
+ this.id = env.nextSuiteId_++;
this.description = description;
this.specs = this.actions;
this.parentSuite = parentSuite;
@@ -948,6 +950,9 @@ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
jasmine.Suite.prototype.getResults = function() {
var results = new jasmine.NestedResults();
+ results.description = this.description;
+ results.id = this.id;
+
for (var i = 0; i < this.specs.length; i++) {
results.rollupCounts(this.specs[i].getResults());
}
@@ -984,7 +989,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
} else if (value instanceof jasmine.Matchers.Any) {
this.emitScalar(value.toString());
} else if (typeof value === 'string') {
- this.emitScalar("'" + value + "'");
+ this.emitString(value);
} else if (typeof value === 'function') {
this.emitScalar('Function');
} else if (typeof value.nodeType === 'number') {
@@ -1019,6 +1024,7 @@ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
jasmine.StringPrettyPrinter = function() {
jasmine.PrettyPrinter.call(this);
@@ -1031,6 +1037,10 @@ jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
this.append(value);
};
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+ this.append("'" + value + "'");
+};
+
jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
this.append('[ ');
for (var i = 0; i < array.length; i++) {
@@ -1097,6 +1107,64 @@ jasmine.MultiReporter.prototype.addReporter = function(reporter) {
})(functionName);
}
})();
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+ this.started = false;
+ this.finished = false;
+ this.suites = [];
+ this.results = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+ this.started = true;
+
+ for (var i = 0; i < runner.suites.length; i++) {
+ var suite = runner.suites[i];
+ this.suites.push(this.summarize_(suite));
+ }
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+ var summary = {
+ id: suiteOrSpec.id,
+ name: suiteOrSpec.description,
+ type: suiteOrSpec instanceof jasmine.Suite ? 'suite' : 'spec',
+ children: []
+ };
+
+ if (suiteOrSpec.specs) {
+ for (var i = 0; i < suiteOrSpec.specs.length; i++) {
+ summary.children.push(this.summarize_(suiteOrSpec.specs[i]));
+ }
+ }
+
+ return summary;
+};
+
+//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
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
/**
* Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
*
@@ -1174,9 +1242,9 @@ jasmine.NestedResults.prototype.addResult = function(result) {
/**
* @returns {Boolean} True if everything below passed
*/
-jasmine.NestedResults.prototype.passed = function() {
+jasmine.NestedResults.prototype.__defineGetter__('passed', function() {
return this.passedCount === this.totalCount;
-};
+});
/**
* Runner
*
diff --git a/spec/bootstrap.html b/spec/bootstrap.html
deleted file mode 100755
index 39fe6514..00000000
--- a/spec/bootstrap.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
- Jasmine Tests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Running all Jasmine Test Suites
-
-
-
-

-
-
-
-
-
-
-
-
diff --git a/spec/bootstrap.js b/spec/bootstrap.js
deleted file mode 100755
index 342b10e5..00000000
--- a/spec/bootstrap.js
+++ /dev/null
@@ -1,146 +0,0 @@
-var createElement = function(tag, attrs) {
- var element = document.createElement(tag);
- for (var attr in attrs) {
- element[attr] = attrs[attr];
- }
- return element;
-};
-
-// Bootstrap Test Reporter function
-var Reporter = function () {
- this.total = 0;
- this.passes = 0;
- this.fails = 0;
- this.start = new Date();
-};
-
-Reporter.prototype.toJSON = function(object) {
- return JSON.stringify(object);
-};
-
-Reporter.prototype.test = function (result, message) {
- this.total++;
-
- if (result) {
- this.passes++;
- iconElement = document.getElementById('icons');
- iconElement.appendChild(createElement('img', {src: '../images/go-16.png'}));
- }
- else {
- this.fails++;
- var fails_report = document.getElementById('fails');
- fails_report.style.display = "";
-
- var iconElement = document.getElementById('icons');
- iconElement.appendChild(createElement('img', {src: '../images/fail-16.png'}));
-
- var failMessages = document.getElementById('fail_messages');
- var newFail = createElement('p', {'class': 'fail'});
- newFail.innerHTML = message;
- failMessages.appendChild(newFail);
- }
-};
-
-Reporter.prototype.summary = function () {
- var el = createElement('p', {'class': ((this.fails > 0) ? 'fail_in_summary' : '') });
- el.innerHTML = this.total + ' expectations, ' + this.passes + ' passing, ' + this.fails + ' failed in ' + (new Date().getTime() - this.start.getTime()) + "ms.";
-
- var summaryElement = document.getElementById('results_summary');
- summaryElement.appendChild(el);
- summaryElement.style.display = "";
-};
-
-
-var reporter = new Reporter();
-
-function runSuite(filename) {
- console.log(filename);
- var suite = jasmine.include(filename);
- suite.execute();
- emitSuiteResults(filename, suite);
-}
-
-function emitSpecResults(testName, spec) {
- var results = spec.results.getItems();
- reporter.test(results.length > 0, testName + ": should have results, got " + results.length);
-
- for (var i = 0; i < results.length; i++) {
- reporter.test(results[i].passed === true, testName + ':' + spec.getFullName() + ": expectation number " + i + " failed: " + results[i].message);
- }
-}
-
-function emitSuiteResults(testName, suite) {
- for (var j = 0; j < suite.specs.length; j++) {
- var specOrSuite = suite.specs[j];
-
- if (specOrSuite instanceof jasmine.Suite) {
- emitSuiteResults(testName, specOrSuite);
- } else {
- emitSpecResults(testName, specOrSuite);
- }
- }
-}
-
-var testExplodes = function () {
- var suite = describe('exploding', function () {
- it('should throw an exception when this.explodes is called inside a spec', function() {
- var exceptionMessage = false;
-
- try {
- this.explodes();
- }
- catch (e) {
- exceptionMessage = e;
- }
- expect(exceptionMessage).toEqual('explodes function should not have been called');
- });
-
- });
- suite.execute();
-
- emitSuiteResults('testExplodes', suite);
-};
-
-function newJasmineEnv() {
- return new jasmine.Env();
-}
-
-var testRunner = function() {
-};
-
-var testRunnerFinishCallback = function () {
- var env = newJasmineEnv();
- var foo = 0;
-
- env.currentRunner.finish();
-
- reporter.test((env.currentRunner.finished === true),
- "Runner finished flag was not set.");
-
- env.currentRunner.finishCallback = function () {
- foo++;
- };
-
- env.currentRunner.finish();
-
- reporter.test((env.currentRunner.finished === true),
- "Runner finished flag was not set.");
- reporter.test((foo === 1),
- "Runner finish callback was not called");
-};
-
-var runTests = function () {
- document.getElementById('spinner').style.display = "";
-
- runSuite('suites/PrettyPrintTest.js');
- runSuite('suites/MatchersTest.js');
- runSuite('suites/SpecRunningTest.js');
- runSuite('suites/NestedResultsTest.js');
- runSuite('suites/ReporterTest.js');
- runSuite('suites/RunnerTest.js');
- runSuite('suites/SpyTest.js');
- runSuite('suites/ExceptionsTest.js');
-
- reporter.summary();
- document.getElementById('spinner').style.display = "none";
-};
\ No newline at end of file
diff --git a/spec/runner.html b/spec/runner.html
index 9f9076e4..0fef41dd 100644
--- a/spec/runner.html
+++ b/spec/runner.html
@@ -3,7 +3,6 @@
Jasmine Test Runner
-
@@ -25,43 +24,43 @@
-
+
-
+ .stackTrace {
+ white-space: pre;
+ font-size: .8em;
+ margin-left: 10px;
+ }
+
+
diff --git a/src/Env.js b/src/Env.js
index fd4dc70d..851adce2 100644
--- a/src/Env.js
+++ b/src/Env.js
@@ -18,6 +18,7 @@ jasmine.Env = function() {
};
this.nextSpecId_ = 0;
+ this.nextSuiteId_ = 0;
this.equalityTesters_ = [];
};
diff --git a/src/JsApiReporter.js b/src/JsApiReporter.js
new file mode 100644
index 00000000..1501123a
--- /dev/null
+++ b/src/JsApiReporter.js
@@ -0,0 +1,58 @@
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+ this.started = false;
+ this.finished = false;
+ this.suites = [];
+ this.results = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+ this.started = true;
+
+ for (var i = 0; i < runner.suites.length; i++) {
+ var suite = runner.suites[i];
+ this.suites.push(this.summarize_(suite));
+ }
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+ var summary = {
+ id: suiteOrSpec.id,
+ name: suiteOrSpec.description,
+ type: suiteOrSpec instanceof jasmine.Suite ? 'suite' : 'spec',
+ children: []
+ };
+
+ if (suiteOrSpec.specs) {
+ for (var i = 0; i < suiteOrSpec.specs.length; i++) {
+ summary.children.push(this.summarize_(suiteOrSpec.specs[i]));
+ }
+ }
+
+ return summary;
+};
+
+//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
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
diff --git a/src/NestedResults.js b/src/NestedResults.js
index c5fabf7f..4e4842fa 100644
--- a/src/NestedResults.js
+++ b/src/NestedResults.js
@@ -75,6 +75,6 @@ jasmine.NestedResults.prototype.addResult = function(result) {
/**
* @returns {Boolean} True if everything below passed
*/
-jasmine.NestedResults.prototype.passed = function() {
+jasmine.NestedResults.prototype.__defineGetter__('passed', function() {
return this.passedCount === this.totalCount;
-};
+});
diff --git a/src/PrettyPrinter.js b/src/PrettyPrinter.js
index 9d8f4f96..ff793a91 100644
--- a/src/PrettyPrinter.js
+++ b/src/PrettyPrinter.js
@@ -28,7 +28,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
} else if (value instanceof jasmine.Matchers.Any) {
this.emitScalar(value.toString());
} else if (typeof value === 'string') {
- this.emitScalar("'" + value + "'");
+ this.emitString(value);
} else if (typeof value === 'function') {
this.emitScalar('Function');
} else if (typeof value.nodeType === 'number') {
@@ -63,6 +63,7 @@ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
jasmine.StringPrettyPrinter = function() {
jasmine.PrettyPrinter.call(this);
@@ -75,6 +76,10 @@ jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
this.append(value);
};
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+ this.append("'" + value + "'");
+};
+
jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
this.append('[ ');
for (var i = 0; i < array.length; i++) {
diff --git a/src/Reporter.js b/src/Reporter.js
index 0e4350ce..06f8c344 100644
--- a/src/Reporter.js
+++ b/src/Reporter.js
@@ -22,6 +22,6 @@ jasmine.Reporter.prototype.reportSpecResults = function(spec) {
};
//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.log = function (str) {
+jasmine.Reporter.prototype.log = function(str) {
};
diff --git a/src/Suite.js b/src/Suite.js
index 60ac46c0..9113ecab 100644
--- a/src/Suite.js
+++ b/src/Suite.js
@@ -9,7 +9,8 @@
*/
jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
jasmine.ActionCollection.call(this, env);
-
+
+ this.id = env.nextSuiteId_++;
this.description = description;
this.specs = this.actions;
this.parentSuite = parentSuite;
@@ -43,6 +44,9 @@ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
jasmine.Suite.prototype.getResults = function() {
var results = new jasmine.NestedResults();
+ results.description = this.description;
+ results.id = this.id;
+
for (var i = 0; i < this.specs.length; i++) {
results.rollupCounts(this.specs[i].getResults());
}