a whole ton of reporters work

This commit is contained in:
John Bintz 2011-12-29 18:37:23 -05:00
parent 09f4df94de
commit 0adf3a41b6
61 changed files with 689 additions and 300 deletions

View File

@ -6,15 +6,20 @@ gemspec
gem 'rspec' gem 'rspec'
gem 'fakefs', :require => nil gem 'fakefs', :require => nil
gem 'guard' gem 'guard'
gem 'guard-rspec' gem 'guard-rspec'
gem 'guard-shell' gem 'guard-shell'
gem 'guard-coffeescript' gem 'guard-coffeescript'
gem 'guard-cucumber'
gem 'growl' gem 'growl'
gem 'rake', '0.8.7' gem 'rake', '0.8.7'
gem 'mocha', '0.9.12' gem 'mocha', '0.9.12'
gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git' gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git'
gem 'facter' gem 'facter'
gem 'cucumber'
gem 'jquery-rails' gem 'jquery-rails'
gem 'ejs' gem 'ejs'

View File

@ -22,13 +22,18 @@ guard 'rspec', :version => 2, :all_on_start => false do
watch('spec/spec_helper.rb') { "spec" } watch('spec/spec_helper.rb') { "spec" }
end end
guard 'cucumber', :cli => '-r features --format pretty' do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/steps/(.+)_steps\.rb$}) { 'features' }
end
guard 'jasmine-headless-webkit', :all_on_start => false do guard 'jasmine-headless-webkit', :all_on_start => false do
watch(%r{^spec/javascripts/.+_spec\.coffee}) watch(%r{^spec/javascripts/.+_spec\.coffee})
watch(%r{^jasmine/(.+)\.coffee$}) { |m| "spec/javascripts/#{m[1]}_spec.coffee" } watch(%r{^jasmine/(.+)\.coffee$}) { |m| "spec/javascripts/#{m[1]}_spec.coffee" }
end end
def compile def compile
#system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb}
system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb} system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb}
end end

View File

@ -30,6 +30,7 @@ namespace :spec do
task :platforms do task :platforms do
rvm_bundle rvm_bundle
rvm_bundle "exec rspec spec" rvm_bundle "exec rspec spec"
rvm_bundle "exec cucumber"
raise SpecError.new if $?.exitstatus != 0 raise SpecError.new if $?.exitstatus != 0
end end
end end

View File

@ -62,8 +62,10 @@ void Runner::handleError(const QString &message, int lineNumber, const QString &
void Runner::loadSpec() void Runner::loadSpec()
{ {
if (!reportFileName.isEmpty()) { QVectorIterator<QString> iterator(reportFiles);
QFile *outputFile = new QFile(reportFileName);
while (iterator.hasNext()) {
QFile *outputFile = new QFile(iterator.next());
outputFile->open(QIODevice::WriteOnly); outputFile->open(QIODevice::WriteOnly);
outputFiles.enqueue(outputFile); outputFiles.enqueue(outputFile);
} }
@ -100,8 +102,8 @@ void Runner::hasSpecFailure() {
_hasSpecFailure = true; _hasSpecFailure = true;
} }
void Runner::reportFile(const QString &file) { void Runner::setReportFiles(QStack<QString> &files) {
reportFileName = file; reportFiles = files;
} }
void Runner::timerPause() { void Runner::timerPause() {
@ -116,6 +118,14 @@ void Runner::ping() {
runs = 0; runs = 0;
} }
void Runner::setSeed(QString s) {
seed = s;
}
QString Runner::getSeed() {
return seed;
}
void Runner::print(const QString &fh, const QString &content) { void Runner::print(const QString &fh, const QString &content) {
if (fh == "stdout") { if (fh == "stdout") {
std::cout << qPrintable(content); std::cout << qPrintable(content);
@ -127,14 +137,12 @@ void Runner::print(const QString &fh, const QString &content) {
std::cerr.flush(); std::cerr.flush();
} }
if (fh == "report") { if (fh.contains("report")) {
QListIterator<QFile *> iterator(outputFiles); int index = (int)fh.split(":").last().toUInt();
while (iterator.hasNext()) { QTextStream ts(outputFiles.at(index));
QTextStream ts(iterator.next()); ts << qPrintable(content);
ts << qPrintable(content); ts.flush();
ts.flush();
}
} }
} }
@ -150,10 +158,8 @@ void Runner::timerEvent() {
QApplication::instance()->exit(1); QApplication::instance()->exit(1);
if (isFinished && runs > 2) { if (isFinished && runs > 2) {
QListIterator<QFile *> iterator(outputFiles); while (!outputFiles.isEmpty()) {
outputFiles.dequeue()->close();
while (iterator.hasNext()) {
iterator.next()->close();
} }
int exitCode = 0; int exitCode = 0;

View File

@ -20,7 +20,9 @@ class Runner: public QObject {
Runner(); Runner();
void setColors(bool colors); void setColors(bool colors);
void reportFile(const QString &file); void setReportFiles(QStack<QString> &files);
void setSeed(QString s);
void addFile(const QString &spec); void addFile(const QString &spec);
void go(); void go();
@ -30,6 +32,9 @@ class Runner: public QObject {
void hasUsedConsole(); void hasUsedConsole();
void hasError(); void hasError();
void hasSpecFailure(); void hasSpecFailure();
QString getSeed();
void print(const QString &fh, const QString &content); void print(const QString &fh, const QString &content);
void finishSuite(); void finishSuite();
void ping(); void ping();
@ -50,15 +55,14 @@ class Runner: public QObject {
bool isFinished; bool isFinished;
bool useColors; bool useColors;
QQueue<QString> runnerFiles; QString seed;
QString reportFileName; QQueue<QString> runnerFiles;
QStack<QString> reportFiles;
void loadSpec(); void loadSpec();
QQueue<QFile *> outputFiles; QQueue<QFile *> outputFiles;
QFile *outputFile;
}; };
#endif #endif

View File

@ -29,34 +29,40 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
char *reporter = NULL; bool showColors = false;
char showColors = false; QString seed;
QStack<QString> reporterFiles;
int c, index; int c, index;
while ((c = getopt(argc, argv, "cr:")) != -1) { while ((c = getopt(argc, argv, "cr:s:")) != -1) {
switch(c) { switch(c) {
case 'c': case 'c':
showColors = true; showColors = true;
break; break;
case 'r': case 'r':
reporter = optarg; reporterFiles.push(QString(optarg));
break;
case 's':
seed = QString(optarg);
break; break;
} }
} }
if (optind == argc) { if (optind == argc) {
std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl; std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl;
std::cerr << " specrunner [-c] [-r <report file>] specrunner.html ..." << std::endl; std::cerr << " specrunner [-c] [-s seed] [-r report file ...] specrunner.html ..." << std::endl;
return 1; return 1;
} }
QApplication app(argc, argv); QApplication app(argc, argv);
app.setApplicationName("jasmine-headless-webkit"); app.setApplicationName("jasmine-headless-webkit");
Runner runner; Runner runner;
runner.setColors(showColors);
runner.reportFile(reporter); runner.setColors(showColors);
runner.setReportFiles(reporterFiles);
runner.setSeed(seed);
for (index = optind; index < argc; index++) { for (index = optind; index < argc; index++) {
runner.addFile(QString::fromLocal8Bit(argv[index])); runner.addFile(QString::fromLocal8Bit(argv[index]));

View File

@ -0,0 +1,7 @@
Feature: Bin - Failure
Scenario: Run a failing test
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage

View File

@ -0,0 +1,18 @@
Feature: Bin - Filtered Run - Both Runs
Background:
Given there is no existing "spec/report.txt" file
Scenario: Run one and fail
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml --format HeadlessFileReporter --out spec/report.txt ./spec/jasmine/filtered_failure/failure_spec.js`
Then the exit status should be 1
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
Scenario: Run both and succeed
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --format HeadlessFileReporter --out spec/report.txt ./spec/jasmine/filtered_success/success_one_spec.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage
Scenario: Run both with console.log
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success_with_console/filtered_success.yml --format HeadlessFileReporter --out spec/report.txt ./spec/jasmine/filtered_success_with_console/success_one_spec.js`
Then the exit status should be 2
And the report file "spec/report.txt" should have 2 total, 0 failures, yes console usage

View File

@ -0,0 +1,14 @@
Feature: Bin - No Full Run
Background:
Given there is no existing "spec/report.txt" file
Scenario: Only run the filtered run
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --format HeadlessFileReporter --out spec/report.txt --no-full-run ./spec/jasmine/filtered_success/success_one_spec.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage
Scenario: Use a file outside of the normal test run
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --format HeadlessFileReporter --out spec/report.txt ./spec/jasmine/filtered_success/success_other_file.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage

View File

View File

@ -0,0 +1,20 @@
Feature: Bin - Success
Scenario: Run a successful test
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit --seed 1234 -j spec/jasmine/success/success.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
And the report file "spec/report.txt" should have seed 1234
Scenario: Run a successful test with legacy file reporting
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
Scenario: Run a successful test with shortened format definition
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --format HeadlessFileReporter:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage

View File

@ -0,0 +1,5 @@
Feature: Bin - Success with JS Error
Scenario: Succeed
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 1

View File

@ -0,0 +1,7 @@
Feature: Bin - Try to Leave Page
Scenario: Fail on trying to leave the page
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/leave_page/leave_page.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should exist

View File

@ -0,0 +1,7 @@
Feature: Bin - Try to Click A Button
Scenario: Don't leave page when clicking a button
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/click_button/click_button.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 0 total, 0 failures, no console usage

View File

@ -0,0 +1,7 @@
Feature: Bin - With CoffeeScript error
Scenario: Fail on CoffeeScript error
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/coffeescript_error/coffeescript_error.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should not exist

View File

@ -0,0 +1,7 @@
Feature: Bin - With console.log
Scenario: Run a successful test that uses console.log
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml --format HeadlessFileReporter --out spec/report.txt`
Then the exit status should be 2
And the report file "spec/report.txt" should have 1 total, 0 failures, yes console usage

View File

@ -0,0 +1,24 @@
Feature: Reporters
In order to allow for multiple types of output
I should be able to
Manage reporters and decide which ones to use
Scenario: Use default reporters
Given I have the default runner options
When I get a runner
And I get a template writer
Then the template should use the "HeadlessConsoleReporter" reporter to "stdout"
And the command to run the runner should not include a report file
Scenario: Use a file reporter
Given I have the default runner options
And I have the following reporters:
| Name | File |
| ConsoleReporter | |
| FileReporter | file |
When I get a runner
And I get a template writer
Then the template should use the "ConsoleReporter" reporter to "stdout"
And the template should use the "FileReporter" reporter to "report:0"
And the command to run the runner should include the report file "file"

View File

@ -0,0 +1,4 @@
Given /^there is no existing "([^"]*)" file$/ do |file|
FileUtils.rm_rf file
end

View File

@ -0,0 +1,4 @@
Given /^I have the default runner options$/ do
@options = Jasmine::Headless::Options.new
end

View File

@ -0,0 +1,10 @@
Given /^I have the following reporters:$/ do |table|
@options[:reporters] = []
table.hashes.each do |hash|
reporter = [ hash['Name'] ]
reporter << hash['File'] if !hash['File'].empty?
@options[:reporters] << reporter
end
end

View File

@ -0,0 +1,3 @@
Then /^the exit status should be (\d+)$/ do |exitstatus|
$?.exitstatus.should == exitstatus.to_i
end

View File

@ -0,0 +1,4 @@
Then /^the report file "([^"]*)" should not exist$/ do |file|
File.file?(file).should be_false
end

View File

@ -0,0 +1,3 @@
Then /^the report file "([^"]*)" should exist$/ do |file|
File.file?(file).should be_true
end

View File

@ -0,0 +1,7 @@
Then /^the report file "(.*)" should have (\d+) total, (\d+) failures?, (no|yes) console usage$/ do |file, total, failures, console_usage|
report = Jasmine::Headless::Report.load(file)
report.total.should == total.to_i
report.failed.should == failures.to_i
report.has_used_console?.should == (console_usage == 'yes')
end

View File

@ -0,0 +1,4 @@
Then /^the report file "([^"]*)" should have seed (\d+)$/ do |file, seed|
report = Jasmine::Headless::Report.load(file)
report.seed.should == seed.to_i
end

View File

@ -0,0 +1,4 @@
Then /^the command to run the runner should include the report file "([^"]*)"$/ do |file|
@runner.jasmine_command.should include("-r #{file}")
end

View File

@ -0,0 +1,3 @@
Then /^the command to run the runner should not include a report file$/ do
@runner.jasmine_command.should_not include('-r')
end

View File

@ -0,0 +1,6 @@
Then /^the template should use the "([^"]*)" reporter to "([^"]*)"$/ do |reporter, target|
output = @template_writer.render
output.should include(%{jasmine.#{reporter}("#{target}")})
end

View File

@ -0,0 +1,4 @@
When /^I get a runner$/ do
@runner = Jasmine::Headless::Runner.new(@options)
end

View File

@ -0,0 +1,4 @@
When /^I get a template writer$/ do
@template_writer = Jasmine::Headless::TemplateWriter.new(@runner)
end

View File

@ -0,0 +1,4 @@
When /^I run `(.*)`$/ do |command|
system command
end

2
features/support/env.rb Normal file
View File

@ -0,0 +1,2 @@
require 'jasmine-headless-webkit'

View File

@ -72,7 +72,9 @@ module Jasmine::Headless
def default_files def default_files
%w{jasmine.js jasmine-html jasmine.css jasmine-extensions %w{jasmine.js jasmine-html jasmine.css jasmine-extensions
intense headless_reporter_result jasmine.HeadlessReporter intense headless_reporter_result jasmine.HeadlessReporter
jasmine.HeadlessFileReporter jasmine.HeadlessConsoleReporter jsDump beautify-html} jasmine.HeadlessFileReporter jasmine.HeadlessConsoleReporter
jasmine.HeadlessTAPReporter
jsDump beautify-html}
end end
def extension_filter def extension_filter
@ -84,7 +86,7 @@ module Jasmine::Headless
PLEASE_WAIT_IM_WORKING_TIME = 2 PLEASE_WAIT_IM_WORKING_TIME = 2
attr_reader :required_files, :potential_files_to_filter attr_reader :options, :required_files, :potential_files_to_filter
def initialize(options = {}) def initialize(options = {})
@options = options @options = options
@ -184,16 +186,12 @@ module Jasmine::Headless
def to_html(files) def to_html(files)
alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME
p self.class.extension_filter
files.collect do |file| files.collect do |file|
if alert_time && alert_time < Time.now if alert_time && alert_time < Time.now
puts "Rebuilding cache, please wait..." puts "Rebuilding cache, please wait..."
alert_time = nil alert_time = nil
end end
p file
sprockets_environment.find_asset(file, :bundle => false).body sprockets_environment.find_asset(file, :bundle => false).body
end.compact.reject(&:empty?) end.compact.reject(&:empty?)
end end

View File

@ -13,7 +13,6 @@ module Jasmine
:remove_html_file => true, :remove_html_file => true,
:runner_output_filename => false, :runner_output_filename => false,
:jasmine_config => 'spec/javascripts/support/jasmine.yml', :jasmine_config => 'spec/javascripts/support/jasmine.yml',
:report => false,
:do_list => false, :do_list => false,
:full_run => true, :full_run => true,
:enable_cache => true, :enable_cache => true,
@ -26,6 +25,8 @@ module Jasmine
DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit') DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit')
GLOBAL_DEFAULTS_FILE = File.expand_path('~/.jasmine-headless-webkit') GLOBAL_DEFAULTS_FILE = File.expand_path('~/.jasmine-headless-webkit')
REPORT_DEPRECATED_MESSAGE = "--report is deprecated. Use --format HeadlessFileReporter --out <filename>"
def self.from_command_line def self.from_command_line
options = new options = new
options.process_command_line_args options.process_command_line_args
@ -56,7 +57,10 @@ module Jasmine
when '--keep' when '--keep'
@options[:remove_html_file] = false @options[:remove_html_file] = false
when '--report' when '--report'
@options[:report] = arg warn REPORT_DEPRECATED_MESSAGE
add_reporter('HeadlessFileReporter', arg)
add_reporter('HeadlessConsoleReporter')
when '--runner-out' when '--runner-out'
@options[:runner_output_filename] = arg @options[:runner_output_filename] = arg
when '--jasmine-config', '-j' when '--jasmine-config', '-j'
@ -70,7 +74,7 @@ module Jasmine
when '--format', '-f' when '--format', '-f'
add_reporter(arg) add_reporter(arg)
when '--out' when '--out'
@options[:reporters].last << arg add_reporter_file(arg)
end end
end end
@ -119,14 +123,28 @@ module Jasmine
end end
end end
def file_reporters
reporters.find_all { |reporter| reporter[1]["report:"] }
end
private private
def add_reporter(name) def add_reporter(name, file = nil)
if !@added_reporter if !@added_reporter
@options[:reporters] = [] @options[:reporters] = []
@added_reporter = true @added_reporter = true
end end
if (parts = name.split(':')).length == 2
name, file = parts
end
@options[:reporters] << [ name ] @options[:reporters] << [ name ]
add_reporter_file(file) if file
end
def add_reporter_file(file)
@options[:reporters].last << file
end end
end end
end end

View File

@ -60,8 +60,13 @@ module Jasmine::Headless
}.collect(&:filename).uniq.compact }.collect(&:filename).uniq.compact
end end
private def seed
if seed = report.find { |entry| entry.respond_to?(:seed) }
seed.seed
end
end
private
def last_total def last_total
@report.reverse.find { |entry| entry.respond_to?(:total) } @report.reverse.find { |entry| entry.respond_to?(:total) }
end end

View File

@ -6,6 +6,7 @@ module Jasmine::Headless
autoload :Console, 'jasmine/headless/report_message/console' autoload :Console, 'jasmine/headless/report_message/console'
autoload :Error, 'jasmine/headless/report_message/error' autoload :Error, 'jasmine/headless/report_message/error'
autoload :Total, 'jasmine/headless/report_message/total' autoload :Total, 'jasmine/headless/report_message/total'
autoload :Seed, 'jasmine/headless/report_message/seed'
end end
end end

View File

@ -1,9 +1,7 @@
module Jasmine::Headless::ReportMessage module Jasmine::Headless::ReportMessage
class Console class Console
class << self def self.new_from_parts(parts)
def new_from_parts(parts) new(parts.first)
new(parts.first)
end
end end
attr_reader :message attr_reader :message

View File

@ -0,0 +1,14 @@
module Jasmine::Headless::ReportMessage
class Seed
def self.new_from_parts(parts)
new(parts.first)
end
attr_reader :seed
def initialize(seed)
@seed = seed.to_i
end
end
end

View File

@ -1,11 +1,9 @@
module Jasmine::Headless::ReportMessage module Jasmine::Headless::ReportMessage
class Spec class Spec
class << self def self.new_from_parts(parts)
def new_from_parts(parts) file_info = parts.pop
file_info = parts.pop
new(parts.join(' '), file_info) new(parts.join(' '), file_info)
end
end end
attr_reader :statement, :file_info attr_reader :statement, :file_info

View File

@ -34,14 +34,6 @@ module Jasmine
end end
def initialize(options) def initialize(options)
if !File.file?(RUNNER)
$stderr.puts "No runner found, attempting to compile..."
Dir.chdir RUNNER_DIR do
system %{ruby extconf.rb}
end
raise NoRunnerError if !File.file?(RUNNER)
end
@options = options @options = options
end end
@ -60,25 +52,25 @@ module Jasmine
end end
def jasmine_command(*targets) def jasmine_command(*targets)
[ command = [ RUNNER ]
RUNNER,
@options[:colors] ? '-c' : nil, command << "-s #{options[:seed]}"
@options[:report] ? "-r #{@options[:report]}" : nil, command << '-c' if options[:colors]
*targets
].compact.join(" ") options.file_reporters.each do |reporter, identifier, file|
command << "-r #{file}"
end
command += targets
command.compact.join(' ')
end end
def run def run
Jasmine::Headless::CacheableAction.enabled = @options[:enable_cache] Jasmine::Headless::CacheableAction.enabled = @options[:enable_cache]
FilesList.reset! FilesList.reset!
files_list = Jasmine::Headless::FilesList.new( @_targets = template_writer.write
:config => jasmine_config,
:only => @options[:files],
:seed => @options[:seed]
)
@_targets = template_writer.write!(files_list)
run_targets = @_targets.dup run_targets = @_targets.dup
@ -90,8 +82,6 @@ module Jasmine
system jasmine_command(run_targets) system jasmine_command(run_targets)
puts "\nTest ordering seed: --seed #{@options[:seed]}"
@_status = $?.exitstatus @_status = $?.exitstatus
ensure ensure
if @_targets && !runner_filename && (@options[:remove_html_file] || (@_status == 0)) if @_targets && !runner_filename && (@options[:remove_html_file] || (@_status == 0))
@ -109,6 +99,14 @@ module Jasmine
end end
end end
def files_list
@files_list ||= Jasmine::Headless::FilesList.new(
:config => jasmine_config,
:only => @options[:files],
:seed => @options[:seed]
)
end
private private
def jasmine_config_data def jasmine_config_data
raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config]) raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config])

View File

@ -1,24 +1,30 @@
require 'multi_json' require 'multi_json'
require 'erb' require 'erb'
require 'tempfile' require 'tempfile'
require 'forwardable'
module Jasmine::Headless module Jasmine::Headless
class TemplateWriter class TemplateWriter
attr_reader :runner attr_reader :runner
extend Forwardable
def_delegators :runner, :files_list, :options
def_delegators :options, :reporters
def initialize(runner) def initialize(runner)
@runner = runner @runner = runner
end end
def write!(files_list) def write
output = [ output = [
[ all_tests_filename, files_list.files_to_html ] [ all_tests_filename, files_list.files_to_html ]
] ]
output.unshift([filtered_tests_filename , files_list.filtered_files_to_html ]) if files_list.filtered? output.unshift([filtered_tests_filename, files_list.filtered_files_to_html ]) if files_list.filtered?
output.each do |name, files| output.each do |name, files|
File.open(name, 'w') { |fh| fh.print template_for(files, files_list.spec_file_line_numbers) } File.open(name, 'w') { |fh| fh.print template_for(files) }
end end
output.collect(&:first) output.collect(&:first)
@ -32,8 +38,24 @@ module Jasmine::Headless
all_tests_filename.gsub(%r{\.html$}, '.filter.html') all_tests_filename.gsub(%r{\.html$}, '.filter.html')
end end
def render
template_for(all_files)
end
def all_files
files_list.files_to_html
end
def jhw_reporters
reporters.collect do |reporter, output|
%{jasmine.getEnv().addReporter(new jasmine.#{reporter}("#{output}"));}
end.join("\n")
end
private private
def template_for(files, spec_lines) def template_for(files)
spec_lines = files_list.spec_file_line_numbers
ERB.new(Jasmine::Headless.root.join('skel/template.html.erb').read).result(binding) ERB.new(Jasmine::Headless.root.join('skel/template.html.erb').read).result(binding)
end end
end end

View File

@ -12,7 +12,7 @@
<body> <body>
<script type="text/javascript"> <script type="text/javascript">
jasmine.getEnv().console = { jasmine.getEnv().console = {
log: function(msg) { JHW.stdout.puts(msg) } log: function(msg) { JHW.print('stdout', msg + "\n"); }
} }
window._onload = window.onload; window._onload = window.onload;
@ -23,8 +23,7 @@
} }
if (window.JHW) { if (window.JHW) {
jasmine.getEnv().addReporter(new jasmine.HeadlessConsoleReporter()); <%= jhw_reporters %>
jasmine.getEnv().addReporter(new jasmine.HeadlessFileReporter());
} else { } else {
types = [ 'HtmlReporter', 'TrivialReporter' ]; types = [ 'HtmlReporter', 'TrivialReporter' ];

View File

@ -12,112 +12,6 @@ describe "jasmine-headless-webkit" do
FileUtils.rm_f report FileUtils.rm_f report
end end
describe 'success' do
it "should succeed with error code 0" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report #{report}}
$?.exitstatus.should == 0
report.should be_a_report_containing(1, 0, false)
end
end
describe 'success but with js error' do
it "should succeed with error code 0" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml --report #{report}}
$?.exitstatus.should == 1
# returns are unpredictable due to changes in jasmine! >.<
# all we can do is ensure that we've actually failed
#
# report.should be_a_report_containing(0, 0, false)
end
end
describe 'failure' do
it "should fail with an error code of 1" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml --report #{report}}
$?.exitstatus.should == 1
report.should be_a_report_containing(1, 1, false)
end
end
describe 'with console.log' do
it "should succeed, but has a console.log so an error code of 2" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml --report #{report}}
$?.exitstatus.should == 2
report.should be_a_report_containing(1, 0, true)
end
end
describe 'with coffeescript error' do
it "should fail" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/coffeescript_error/coffeescript_error.yml --report #{report}}
$?.exitstatus.should == 1
File.exist?(report).should be_false
end
end
describe 'tries to leave page' do
it "should not leave the page nor loop" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/leave_page/leave_page.yml --report #{report}}
$?.exitstatus.should == 1
end
end
describe 'tries to click a button' do
it "should not leave the page nor loop" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/click_button/click_button.yml --report #{report}}
$?.exitstatus.should == 0
report.should be_a_report_containing(0, 0, false)
end
end
describe 'with filtered run' do
context "don't run a full run, just the filtered run" do
it "should succeed and run both" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --no-full-run --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js}
$?.exitstatus.should == 0
report.should be_a_report_containing(1, 0, false)
end
it "should use a file outside the normal test run and only run one" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_other_file.js}
$?.exitstatus.should == 0
report.should be_a_report_containing(1, 0, false)
end
end
context "do both runs" do
it "should fail and not run the second" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml --report #{report} ./spec/jasmine/filtered_failure/failure_spec.js}
$?.exitstatus.should == 1
report.should be_a_report_containing(1, 1, false)
end
it "should succeed and run both" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js}
$?.exitstatus.should == 0
report.should be_a_report_containing(2, 0, false)
end
it "should succeed and run both, with the first having a console.log call" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success_with_console/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success_with_console/success_one_spec.js}
$?.exitstatus.should == 2
report.should be_a_report_containing(2, 0, true)
end
end
end
describe 'files' do describe 'files' do
it 'should list all the files that will be found' do it 'should list all the files that will be found' do
files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/success/success.yml} files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/success/success.yml}

View File

@ -0,0 +1,19 @@
describe 'jasmine.HeadlessTAPReporter', ->
beforeEach ->
@reporter = new jasmine.HeadlessTAPReporter()
describe '#reportRunnerResults', ->
it 'should write nothing for nothing', ->
@reporter.output = []
@reporter.reportRunnerResults(null)
expect(@reporter.output[0]).not.toBeDefined()
it 'should report the length right', ->
@reporter.output = [ 'test' ]
@reporter.reportRunnerResults(null)
expect(@reporter.output[0]).toEqual('1..1')

View File

@ -17,6 +17,7 @@ describe Jasmine::Headless::FilesList do
File.expand_path('vendor/assets/javascripts/jasmine.HeadlessReporter.js'), File.expand_path('vendor/assets/javascripts/jasmine.HeadlessReporter.js'),
File.expand_path('vendor/assets/javascripts/jasmine.HeadlessFileReporter.js'), File.expand_path('vendor/assets/javascripts/jasmine.HeadlessFileReporter.js'),
File.expand_path('vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js'), File.expand_path('vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js'),
File.expand_path('vendor/assets/javascripts/jasmine.HeadlessTAPReporter.js'),
File.expand_path('vendor/assets/javascripts/jsDump.js'), File.expand_path('vendor/assets/javascripts/jsDump.js'),
File.expand_path('vendor/assets/javascripts/beautify-html.js'), File.expand_path('vendor/assets/javascripts/beautify-html.js'),
] ]

View File

@ -43,6 +43,35 @@ describe Jasmine::Headless::Options do
options[:colors].should be_true options[:colors].should be_true
options[:jasmine_config].should == 'test' options[:jasmine_config].should == 'test'
end end
context 'legacy reporter' do
let(:file) { 'file' }
before do
options.expects(:warn)
end
it 'should add a legacy reporter' do
options[:reporters] = []
options.process_option("--report", file)
options[:reporters].should == [ [ 'HeadlessFileReporter', file ], [ 'HeadlessConsoleReporter' ] ]
end
end
context 'short reporter' do
let(:reporter) { 'reporter' }
let(:file) { 'file' }
it 'should add a reporter' do
options[:reporters] = []
options.process_option("--format", "#{reporter}:#{file}")
options[:reporters].should == [ [ reporter, file ] ]
end
end
end end
describe '#read_defaults_files' do describe '#read_defaults_files' do
@ -145,12 +174,21 @@ describe Jasmine::Headless::Options do
end end
end end
context 'two reporters' do
end
after do after do
ARGV.replace(@argv) ARGV.replace(@argv)
end end
end end
describe '#file_reporters' do
subject { options.file_reporters }
let(:stdout_reporter) { [ 'Console', 'stdout' ] }
let(:file_reporter) { [ 'File', 'report:0', 'file' ] }
before do
options.stubs(:reporters).returns([ stdout_reporter, file_reporter ])
end
it { should == [ file_reporter ] }
end
end end

View File

@ -0,0 +1,18 @@
require 'spec_helper'
describe Jasmine::Headless::ReportMessage::Seed do
let(:seed) { described_class.new(seed_value) }
let(:seed_value) { '1' }
subject { seed }
its(:seed) { should == seed_value.to_i }
describe '.new_from_parts' do
subject { described_class.new_from_parts(parts) }
let(:parts) { [ seed_value ] }
its(:seed) { should == seed_value.to_i }
end
end

View File

@ -3,6 +3,9 @@ require 'spec_helper'
describe Jasmine::Headless::Report do describe Jasmine::Headless::Report do
include FakeFS::SpecHelpers include FakeFS::SpecHelpers
let(:report) { described_class.new(file) }
let(:file) { 'file' }
let(:file) { 'report.txt' } let(:file) { 'report.txt' }
describe '.load' do describe '.load' do
@ -75,5 +78,18 @@ REPORT
end end
end end
end end
describe '#seed' do
subject { report.seed }
let(:seed) { stub(:seed => seed_number) }
let(:seed_number) { 1 }
before do
report.stubs(:report).returns([ seed ])
end
it { should == seed_number }
end
end end

View File

@ -36,7 +36,6 @@ describe Jasmine::Headless::Runner do
context 'file exists' do context 'file exists' do
before do before do
File.open(Jasmine::Headless::Runner::RUNNER, 'w')
File.open(config_filename, 'w') { |fh| fh.print YAML.dump('test' => 'hello', 'erb' => '<%= "erb" %>') } File.open(config_filename, 'w') { |fh| fh.print YAML.dump('test' => 'hello', 'erb' => '<%= "erb" %>') }
end end
@ -58,16 +57,39 @@ describe Jasmine::Headless::Runner do
end end
describe '#jasmine_command' do describe '#jasmine_command' do
let(:opts) { { subject { runner.jasmine_command(target) }
:colors => true,
:report => 'test'
} }
it 'should have the right options' do let(:target) { 'target' }
runner.jasmine_command.should match(/jasmine-webkit-specrunner/)
runner.jasmine_command.should match(/-c/) let(:options) { {} }
runner.jasmine_command.should match(/-r test/) let(:reporters) { [] }
runner.jasmine_command('file.js').should match(/file.js/)
before do
runner.stubs(:options).returns(options)
options.stubs(:file_reporters).returns(reporters)
end
def self.it_should_have_basics
it { should include(target) }
end
context 'colors' do
before do
options[:colors] = true
end
it_should_have_basics
it { should include('-c') }
end
context 'reporters' do
let(:reporter) { [ 'Reporter', 'identifier', file ] }
let(:reporters) { [ reporter ] }
let(:file) { 'file' }
it_should_have_basics
it { should include("-r #{file}") }
end end
end end
@ -85,7 +107,9 @@ describe Jasmine::Headless::Runner do
it 'should succeed with error code 0' do it 'should succeed with error code 0' do
Jasmine::Headless::Runner.run( Jasmine::Headless::Runner.run(
:jasmine_config => 'spec/jasmine/success/success.yml', :jasmine_config => 'spec/jasmine/success/success.yml',
:report => report :reporters => [
[ 'HeadlessFileReporter', report ]
]
).should == 0 ).should == 0
report.should be_a_report_containing(1, 0, false) report.should be_a_report_containing(1, 0, false)
@ -98,7 +122,9 @@ describe Jasmine::Headless::Runner do
it 'should fail on one test' do it 'should fail on one test' do
Jasmine::Headless::Runner.run( Jasmine::Headless::Runner.run(
:jasmine_config => 'spec/jasmine/failure/failure.yml', :jasmine_config => 'spec/jasmine/failure/failure.yml',
:report => report :reporters => [
[ 'HeadlessFileReporter', report ]
]
).should == 1 ).should == 1
report.should be_a_report_containing(1, 1, false) report.should be_a_report_containing(1, 1, false)
@ -171,4 +197,27 @@ describe Jasmine::Headless::Runner do
runner.jasmine_config['spec_files'].should == described_class::JASMINE_DEFAULTS['spec_files'] runner.jasmine_config['spec_files'].should == described_class::JASMINE_DEFAULTS['spec_files']
end end
end end
describe '#files_list' do
subject { runner.files_list }
let(:options) { { :files => only, :seed => seed } }
let(:only) { 'only' }
let(:seed) { 12345 }
let(:jasmine_config) { 'jasmine config' }
before do
runner.stubs(:options).returns(options)
runner.stubs(:jasmine_config).returns(jasmine_config)
end
it { should be_a_kind_of(Jasmine::Headless::FilesList) }
it 'should have settings' do
subject.options[:config].should == jasmine_config
subject.options[:only].should == only
subject.options[:seed].should == seed
end
end
end end

View File

@ -43,46 +43,50 @@ describe Jasmine::Headless::TemplateWriter do
end end
end end
describe '#write!' do describe '#render' do
include FakeFS::SpecHelpers subject { template_writer.render }
let(:all_files) { 'all files' }
let(:template) { 'template' }
before do before do
Jasmine::Headless::FilesList.stubs(:default_files).returns([]) template_writer.stubs(:all_files).returns(all_files)
File.stubs(:read).returns(nil) template_writer.expects(:template_for).with(all_files).returns(template)
runner.stubs(:keep_runner).returns(true)
runner.stubs(:runner_filename).returns(false)
Sprockets::Environment.any_instance.stubs(:find_asset).returns(stub(:body => ''))
end end
let(:files_list) { Jasmine::Headless::FilesList.new } it { should == template }
end
describe '#all_files' do
subject { template_writer.all_files }
let(:files_list) { stub }
let(:files) { 'files' }
before do before do
files_list.stubs(:files).returns([ 'file.js' ]) template_writer.stubs(:files_list).returns(files_list)
files_list.stubs(:filtered_files).returns([ 'file.js' ])
files_list.stubs(:files_to_html).returns(files)
end end
context 'no filter' do it { should == files }
it 'should write one file' do end
template_writer.write!(files_list).should == [
"jhw.#{$$}.html" describe '#jhw_reporters' do
] subject { template_writer.jhw_reporters }
end
let(:reporter) { 'reporter' }
let(:output) { 'output' }
before do
template_writer.stubs(:reporters).returns([
[ reporter, output ]
])
end end
context 'filtered files' do it { should include(reporter) }
before do it { should include(output) }
files_list.stubs(:files).returns([ 'file.js', 'file2.js' ])
end
it 'should write two files' do
template_writer.write!(files_list).should == [
"jhw.#{$$}.filter.html", "jhw.#{$$}.html"
]
end
end
end end
end end

View File

@ -0,0 +1,8 @@
require 'spec_helper'
describe 'skel/template.html.erb' do
describe 'reporters' do
end
end

View File

@ -10,33 +10,32 @@ class jasmine.HeadlessConsoleReporter extends jasmine.HeadlessReporter
reportRunnerResults: (runner) -> reportRunnerResults: (runner) ->
super() super()
JHW.stdout.print("\n") this.print("\n")
resultLine = this.formatResultLine(this._runtime()) resultLine = this.formatResultLine(this._runtime())
if @failedCount == 0 if @failedCount == 0
JHW.stdout.puts("PASS: #{resultLine}".foreground('green')) this.puts("PASS: #{resultLine}".foreground('green'))
else else
JHW.stdout.puts("FAIL: #{resultLine}".foreground('red')) this.puts("FAIL: #{resultLine}".foreground('red'))
for result in @results for result in @results
JHW.stdout.puts(result.toString()) this.puts(result.toString())
if window.JHW this.puts("\nTest ordering seed: --seed #{JHW.getSeed()}")
window.onbeforeunload = null
reportRunnerStarting: (runner) -> reportRunnerStarting: (runner) ->
super(runner) super(runner)
JHW.stdout.puts("\nRunning Jasmine specs...".bright()) if !this.hasError() this.puts("\nRunning Jasmine specs...".bright()) if !this.hasError()
reportSpecResults: (spec) -> reportSpecResults: (spec) ->
super(spec) super(spec)
this._reportSpecResult(spec, { this._reportSpecResult(spec, {
success: (results) => success: (results) =>
JHW.stdout.print('.'.foreground('green')) this.print('.'.foreground('green'))
failure: (results) => failure: (results) =>
JHW.stdout.print('F'.foreground('red')) this.print('F'.foreground('red'))
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName()) failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
testCount = 1 testCount = 1
@ -61,7 +60,7 @@ class jasmine.HeadlessConsoleReporter extends jasmine.HeadlessReporter
if @timer if @timer
clearTimeout(@timer) clearTimeout(@timer)
@timer = null @timer = null
JHW.stdout.print(Intense.moveBack()) this.print(Intense.moveBack())
formatResultLine: (runtime) -> formatResultLine: (runtime) ->
line = [] line = []
@ -80,8 +79,8 @@ class jasmine.HeadlessConsoleReporter extends jasmine.HeadlessReporter
@timer = setTimeout( @timer = setTimeout(
=> =>
if @timer if @timer
JHW.stdout.print(Intense.moveBack()) if !@first this.print(Intense.moveBack()) if !@first
JHW.stdout.print(@positions.substr(@position, 1).foreground('yellow')) this.print(@positions.substr(@position, 1).foreground('yellow'))
@position += 1 @position += 1
@position %= @positions.length @position %= @positions.length
@first = false @first = false

View File

@ -4,14 +4,19 @@ class jasmine.HeadlessFileReporter extends jasmine.HeadlessReporter
output = "TOTAL||#{@length}||#{@failedCount}||#{this._runtime()}||#{if JHW._hasErrors then "T" else "F"}" output = "TOTAL||#{@length}||#{@failedCount}||#{this._runtime()}||#{if JHW._hasErrors then "T" else "F"}"
JHW.report.puts(output) this.puts(output)
this.puts("SEED||#{JHW.getSeed()}")
consoleLogUsed: (msg) ->
this.puts("CONSOLE||#{msg}")
reportSpecResults: (spec) -> reportSpecResults: (spec) ->
super(spec) super(spec)
this._reportSpecResult(spec, { this._reportSpecResult(spec, {
success: (results) => success: (results) =>
JHW.report.puts("PASS||" + spec.getJHWSpecInformation()) this.puts("PASS||" + spec.getJHWSpecInformation())
failure: (results) => failure: (results) =>
JHW.report.puts("FAIL||" + spec.getJHWSpecInformation()) this.puts("FAIL||" + spec.getJHWSpecInformation())
}) })

View File

@ -2,7 +2,7 @@ if !jasmine?
throw new Error("jasmine not loaded!") throw new Error("jasmine not loaded!")
class jasmine.HeadlessReporter class jasmine.HeadlessReporter
constructor: (@callback = null) -> constructor: (@outputTarget = null) ->
@results = [] @results = []
@failedCount = 0 @failedCount = 0
@length = 0 @length = 0
@ -29,6 +29,9 @@ class jasmine.HeadlessReporter
JHW.finishSuite() JHW.finishSuite()
if window.JHW
window.onbeforeunload = null
reportSpecResults: (spec) -> reportSpecResults: (spec) ->
return if this.hasError() return if this.hasError()
JHW.ping() JHW.ping()
@ -46,3 +49,10 @@ class jasmine.HeadlessReporter
_runtime: -> _runtime: ->
(new Date() - @startTime) / 1000.0 (new Date() - @startTime) / 1000.0
print: (output) =>
JHW.print(@outputTarget, output)
puts: (output) =>
JHW.print(@outputTarget, output + "\n")

View File

@ -0,0 +1,26 @@
class jasmine.HeadlessTAPReporter extends jasmine.HeadlessReporter
constructor: (@outputTarget = null) ->
super(@outputTarget)
@output = []
reportRunnerResults: (runner) ->
super(runner)
@output.unshift("1..#{@output.length}") if @output.length > 0
this.puts(@output.join("\n"))
reportSpecResults: (spec) ->
super(spec)
index = @output.length + 1
description = spec.getSpecSplitName().join(' ')
this._reportSpecResult(spec, {
success: (results) =>
@output.push("ok #{index} #{description}")
failure: (results) =>
@output.push("not ok #{index} #{description}")
})

View File

@ -30,7 +30,7 @@ if window.JHW
e = e || window.event e = e || window.event
JHW.hasError() JHW.hasError()
JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.') JHW.print('stdout', "The code tried to leave the test page. Check for unhandled form submits and link clicks.\n")
if e if e
e.returnValue = 'string' e.returnValue = 'string'
@ -38,35 +38,31 @@ if window.JHW
return 'string' return 'string'
window.confirm = (message) -> window.confirm = (message) ->
JHW.stderr.puts("#{"[confirm]".foreground('red')} jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.") JHW.print('stdout', "#{"[confirm]".foreground('red')} jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.\n")
true true
window.alert = (message) -> window.alert = (message) ->
JHW.stderr.puts("[alert] ".foreground('red') + message) JHW.print('stdout', "[alert] ".foreground('red') + message + "\n")
JHW._hasErrors = false JHW._hasErrors = false
JHW._handleError = (message, lineNumber, sourceURL) -> JHW._handleError = (message, lineNumber, sourceURL) ->
JHW.stderr.puts(message) JHW.print('stderr', message + "\n")
JHW._hasErrors = true JHW._hasErrors = true
false false
JHW._setColors = (useColors) -> JHW._setColors = (useColors) ->
Intense.useColors = useColors Intense.useColors = useColors
createHandle = (handle) ->
JHW[handle] =
print: (content) -> JHW.print(handle, content)
puts: (content) -> JHW.print(handle, content + "\n")
createHandle(handle) for handle in [ 'stdout', 'stderr', 'report' ]
JHW._usedConsole = false JHW._usedConsole = false
JHW.log = (msg) -> JHW.log = (msg) ->
JHW.hasUsedConsole() JHW.hasUsedConsole()
JHW.report.puts("CONSOLE||#{msg}")
for reporter in jasmine.getEnv().reporter.subReporters_
reporter.consoleLogUsed(msg) if reporter.consoleLogUsed?
JHW._usedConsole = true JHW._usedConsole = true
JHW.stdout.puts(msg) JHW.print('stdout', msg + "\n")
window.CoffeeScriptToFilename = {} window.CoffeeScriptToFilename = {}
window.CSTF = window.CoffeeScriptToFilename window.CSTF = window.CoffeeScriptToFilename

View File

@ -16,25 +16,25 @@
HeadlessConsoleReporter.prototype.reportRunnerResults = function(runner) { HeadlessConsoleReporter.prototype.reportRunnerResults = function(runner) {
var result, resultLine, _i, _len, _ref; var result, resultLine, _i, _len, _ref;
HeadlessConsoleReporter.__super__.reportRunnerResults.call(this); HeadlessConsoleReporter.__super__.reportRunnerResults.call(this);
JHW.stdout.print("\n"); this.print("\n");
resultLine = this.formatResultLine(this._runtime()); resultLine = this.formatResultLine(this._runtime());
if (this.failedCount === 0) { if (this.failedCount === 0) {
JHW.stdout.puts(("PASS: " + resultLine).foreground('green')); this.puts(("PASS: " + resultLine).foreground('green'));
} else { } else {
JHW.stdout.puts(("FAIL: " + resultLine).foreground('red')); this.puts(("FAIL: " + resultLine).foreground('red'));
} }
_ref = this.results; _ref = this.results;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i]; result = _ref[_i];
JHW.stdout.puts(result.toString()); this.puts(result.toString());
} }
if (window.JHW) return window.onbeforeunload = null; return this.puts("\nTest ordering seed: --seed " + (JHW.getSeed()));
}; };
HeadlessConsoleReporter.prototype.reportRunnerStarting = function(runner) { HeadlessConsoleReporter.prototype.reportRunnerStarting = function(runner) {
HeadlessConsoleReporter.__super__.reportRunnerStarting.call(this, runner); HeadlessConsoleReporter.__super__.reportRunnerStarting.call(this, runner);
if (!this.hasError()) { if (!this.hasError()) {
return JHW.stdout.puts("\nRunning Jasmine specs...".bright()); return this.puts("\nRunning Jasmine specs...".bright());
} }
}; };
@ -43,11 +43,11 @@
HeadlessConsoleReporter.__super__.reportSpecResults.call(this, spec); HeadlessConsoleReporter.__super__.reportSpecResults.call(this, spec);
return this._reportSpecResult(spec, { return this._reportSpecResult(spec, {
success: function(results) { success: function(results) {
return JHW.stdout.print('.'.foreground('green')); return _this.print('.'.foreground('green'));
}, },
failure: function(results) { failure: function(results) {
var failureResult, foundLine, result, testCount, _i, _len, _ref; var failureResult, foundLine, result, testCount, _i, _len, _ref;
JHW.stdout.print('F'.foreground('red')); _this.print('F'.foreground('red'));
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName()); failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
testCount = 1; testCount = 1;
_ref = results.getItems(); _ref = results.getItems();
@ -78,7 +78,7 @@
if (this.timer) { if (this.timer) {
clearTimeout(this.timer); clearTimeout(this.timer);
this.timer = null; this.timer = null;
return JHW.stdout.print(Intense.moveBack()); return this.print(Intense.moveBack());
} }
}; };
@ -98,8 +98,8 @@
var _this = this; var _this = this;
return this.timer = setTimeout(function() { return this.timer = setTimeout(function() {
if (_this.timer) { if (_this.timer) {
if (!_this.first) JHW.stdout.print(Intense.moveBack()); if (!_this.first) _this.print(Intense.moveBack());
JHW.stdout.print(_this.positions.substr(_this.position, 1).foreground('yellow')); _this.print(_this.positions.substr(_this.position, 1).foreground('yellow'));
_this.position += 1; _this.position += 1;
_this.position %= _this.positions.length; _this.position %= _this.positions.length;
_this.first = false; _this.first = false;

View File

@ -13,7 +13,12 @@
var output; var output;
HeadlessFileReporter.__super__.reportRunnerResults.call(this, runner); HeadlessFileReporter.__super__.reportRunnerResults.call(this, runner);
output = "TOTAL||" + this.length + "||" + this.failedCount + "||" + (this._runtime()) + "||" + (JHW._hasErrors ? "T" : "F"); output = "TOTAL||" + this.length + "||" + this.failedCount + "||" + (this._runtime()) + "||" + (JHW._hasErrors ? "T" : "F");
return JHW.report.puts(output); this.puts(output);
return this.puts("SEED||" + (JHW.getSeed()));
};
HeadlessFileReporter.prototype.consoleLogUsed = function(msg) {
return this.puts("CONSOLE||" + msg);
}; };
HeadlessFileReporter.prototype.reportSpecResults = function(spec) { HeadlessFileReporter.prototype.reportSpecResults = function(spec) {
@ -21,10 +26,10 @@
HeadlessFileReporter.__super__.reportSpecResults.call(this, spec); HeadlessFileReporter.__super__.reportSpecResults.call(this, spec);
return this._reportSpecResult(spec, { return this._reportSpecResult(spec, {
success: function(results) { success: function(results) {
return JHW.report.puts("PASS||" + spec.getJHWSpecInformation()); return _this.puts("PASS||" + spec.getJHWSpecInformation());
}, },
failure: function(results) { failure: function(results) {
return JHW.report.puts("FAIL||" + spec.getJHWSpecInformation()); return _this.puts("FAIL||" + spec.getJHWSpecInformation());
} }
}); });
}; };

View File

@ -1,3 +1,5 @@
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (!(typeof jasmine !== "undefined" && jasmine !== null)) { if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
throw new Error("jasmine not loaded!"); throw new Error("jasmine not loaded!");
@ -5,8 +7,10 @@
jasmine.HeadlessReporter = (function() { jasmine.HeadlessReporter = (function() {
function HeadlessReporter(callback) { function HeadlessReporter(outputTarget) {
this.callback = callback != null ? callback : null; this.outputTarget = outputTarget != null ? outputTarget : null;
this.puts = __bind(this.puts, this);
this.print = __bind(this.print, this);
this.results = []; this.results = [];
this.failedCount = 0; this.failedCount = 0;
this.length = 0; this.length = 0;
@ -33,7 +37,8 @@
HeadlessReporter.prototype.reportRunnerResults = function(runner) { HeadlessReporter.prototype.reportRunnerResults = function(runner) {
if (this.hasError()) return; if (this.hasError()) return;
if (this.failedCount !== 0) JHW.hasSpecFailure(); if (this.failedCount !== 0) JHW.hasSpecFailure();
return JHW.finishSuite(); JHW.finishSuite();
if (window.JHW) return window.onbeforeunload = null;
}; };
HeadlessReporter.prototype.reportSpecResults = function(spec) { HeadlessReporter.prototype.reportSpecResults = function(spec) {
@ -57,6 +62,16 @@
return (new Date() - this.startTime) / 1000.0; return (new Date() - this.startTime) / 1000.0;
}; };
HeadlessReporter.prototype.print = function(output) {
return JHW.print(this.outputTarget, output);
};
HeadlessReporter.prototype.puts = function(output) {
return JHW.print(this.outputTarget, output + "\n");
};
return HeadlessReporter; return HeadlessReporter;
})(); })();
}).call(this);

View File

@ -0,0 +1,40 @@
(function() {
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
jasmine.HeadlessTAPReporter = (function() {
__extends(HeadlessTAPReporter, jasmine.HeadlessReporter);
function HeadlessTAPReporter(outputTarget) {
this.outputTarget = outputTarget != null ? outputTarget : null;
HeadlessTAPReporter.__super__.constructor.call(this, this.outputTarget);
this.output = [];
}
HeadlessTAPReporter.prototype.reportRunnerResults = function(runner) {
HeadlessTAPReporter.__super__.reportRunnerResults.call(this, runner);
if (this.output.length > 0) this.output.unshift("1.." + this.output.length);
return this.puts(this.output.join("\n"));
};
HeadlessTAPReporter.prototype.reportSpecResults = function(spec) {
var description, index;
var _this = this;
HeadlessTAPReporter.__super__.reportSpecResults.call(this, spec);
index = this.output.length + 1;
description = spec.getSpecSplitName().join(' ');
return this._reportSpecResult(spec, {
success: function(results) {
return _this.output.push("ok " + index + " " + description);
},
failure: function(results) {
return _this.output.push("not ok " + index + " " + description);
}
});
};
return HeadlessTAPReporter;
})();
}).call(this);

View File

@ -1,5 +1,3 @@
(function() {
var createHandle, handle, _i, _len, _ref;
if (window.JHW) { if (window.JHW) {
window.console = { window.console = {
@ -40,52 +38,40 @@
window.onbeforeunload = function(e) { window.onbeforeunload = function(e) {
e = e || window.event; e = e || window.event;
JHW.hasError(); JHW.hasError();
JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.'); JHW.print('stdout', "The code tried to leave the test page. Check for unhandled form submits and link clicks.\n");
if (e) e.returnValue = 'string'; if (e) e.returnValue = 'string';
return 'string'; return 'string';
}; };
window.confirm = function(message) { window.confirm = function(message) {
JHW.stderr.puts("" + ("[confirm]".foreground('red')) + " jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true."); JHW.print('stdout', "" + ("[confirm]".foreground('red')) + " jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.\n");
return true; return true;
}; };
window.alert = function(message) { window.alert = function(message) {
return JHW.stderr.puts("[alert] ".foreground('red') + message); return JHW.print('stdout', "[alert] ".foreground('red') + message + "\n");
}; };
JHW._hasErrors = false; JHW._hasErrors = false;
JHW._handleError = function(message, lineNumber, sourceURL) { JHW._handleError = function(message, lineNumber, sourceURL) {
JHW.stderr.puts(message); JHW.print('stderr', message + "\n");
JHW._hasErrors = true; JHW._hasErrors = true;
return false; return false;
}; };
JHW._setColors = function(useColors) { JHW._setColors = function(useColors) {
return Intense.useColors = useColors; return Intense.useColors = useColors;
}; };
createHandle = function(handle) {
return JHW[handle] = {
print: function(content) {
return JHW.print(handle, content);
},
puts: function(content) {
return JHW.print(handle, content + "\n");
}
};
};
_ref = ['stdout', 'stderr', 'report'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
handle = _ref[_i];
createHandle(handle);
}
JHW._usedConsole = false; JHW._usedConsole = false;
JHW.log = function(msg) { JHW.log = function(msg) {
var reporter, _i, _len, _ref;
JHW.hasUsedConsole(); JHW.hasUsedConsole();
JHW.report.puts("CONSOLE||" + msg); _ref = jasmine.getEnv().reporter.subReporters_;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
reporter = _ref[_i];
if (reporter.consoleLogUsed != null) reporter.consoleLogUsed(msg);
}
JHW._usedConsole = true; JHW._usedConsole = true;
return JHW.stdout.puts(msg); return JHW.print('stdout', msg + "\n");
}; };
} }
window.CoffeeScriptToFilename = {}; window.CoffeeScriptToFilename = {};
window.CSTF = window.CoffeeScriptToFilename; window.CSTF = window.CoffeeScriptToFilename;
}).call(this);