Compare commits
3 Commits
master
...
travis-tes
Author | SHA1 | Date | |
---|---|---|---|
|
f832228325 | ||
|
ade490ba14 | ||
|
64046bc308 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -13,7 +13,3 @@ hydra-runner.log
|
|||||||
jhw-test
|
jhw-test
|
||||||
.jhw-cache/
|
.jhw-cache/
|
||||||
_site/
|
_site/
|
||||||
jhw.*.html
|
|
||||||
coverage/
|
|
||||||
tmp/
|
|
||||||
cache dir/
|
|
||||||
|
27
CHANGELOG.md
27
CHANGELOG.md
@ -1,30 +1,3 @@
|
|||||||
## 0.7.2
|
|
||||||
|
|
||||||
* Improved finding of CoffeeScript spec line locations
|
|
||||||
* Improved Runner reporting of which expectations failed
|
|
||||||
* Initial vendored helper support, paving the way for Sprockets integratioon (maybe!)
|
|
||||||
* Add 1.9.3-rc1 test support and fixes
|
|
||||||
* Add console.peek()
|
|
||||||
|
|
||||||
## 0.7.1
|
|
||||||
|
|
||||||
* Bugfix for missing digest/sha1 import
|
|
||||||
|
|
||||||
## 0.7.0
|
|
||||||
|
|
||||||
* Major C++ cleanup, now much more modular
|
|
||||||
* Greatly improved object inspection and printing provided by jsDump and beautify-js
|
|
||||||
|
|
||||||
## 0.6.3
|
|
||||||
|
|
||||||
* Ensure Rubygems is available before doing version comparison
|
|
||||||
* Fix other build problems
|
|
||||||
* Better output for jQuery nodes
|
|
||||||
|
|
||||||
## 0.6.2
|
|
||||||
|
|
||||||
* Clean up C++ and test running
|
|
||||||
|
|
||||||
## 0.6.1
|
## 0.6.1
|
||||||
|
|
||||||
* Ensure YAML is loaded before use
|
* Ensure YAML is loaded before use
|
||||||
|
21
Gemfile
21
Gemfile
@ -6,25 +6,12 @@ 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 'rake', '0.8.7'
|
||||||
require 'rbconfig'
|
gem 'mocha', '0.9.12'
|
||||||
case RbConfig::CONFIG['host_os']
|
|
||||||
when /darwin/
|
|
||||||
when /linux/
|
|
||||||
gem 'libnotify'
|
|
||||||
end
|
|
||||||
|
|
||||||
gem 'mocha'
|
|
||||||
|
|
||||||
gem 'cucumber'
|
|
||||||
|
|
||||||
gem 'jquery-rails', '~> 1.0.0'
|
|
||||||
gem 'ejs'
|
|
||||||
|
|
||||||
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'
|
||||||
|
|
||||||
|
12
Guardfile
12
Guardfile
@ -3,8 +3,6 @@
|
|||||||
# watch('file/path') { `command(s)` }
|
# watch('file/path') { `command(s)` }
|
||||||
#
|
#
|
||||||
|
|
||||||
guard 'coffeescript', :input => 'vendor/assets/coffeescripts', :output => 'vendor/assets/javascripts'
|
|
||||||
|
|
||||||
guard 'shell' do
|
guard 'shell' do
|
||||||
watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h|pro|pri)}) { |m|
|
watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h|pro|pri)}) { |m|
|
||||||
if !m[0]['moc_']
|
if !m[0]['moc_']
|
||||||
@ -22,20 +20,16 @@ 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 extconf.rb}
|
#system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb}
|
||||||
|
system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb}
|
||||||
end
|
end
|
||||||
|
|
||||||
compile
|
compile
|
||||||
|
|
||||||
|
guard 'coffeescript', :input => 'jasmine'
|
||||||
|
15
README.md
15
README.md
@ -1,5 +1,3 @@
|
|||||||
_This project is dead. You should use [Karma](http://karma-runner.github.io/) instead. I do._
|
|
||||||
|
|
||||||
# Jasmine Headless WebKit runner
|
# Jasmine Headless WebKit runner
|
||||||
|
|
||||||
Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns!
|
Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns!
|
||||||
@ -7,19 +5,6 @@ Run your specs at sonic boom speed! No pesky reload button or page rendering slo
|
|||||||
http://johnbintz.github.com/jasmine-headless-webkit/ has the most up-to-date information on using
|
http://johnbintz.github.com/jasmine-headless-webkit/ has the most up-to-date information on using
|
||||||
this project. You can see the source of that site on the gh-pages branch.
|
this project. You can see the source of that site on the gh-pages branch.
|
||||||
|
|
||||||
## For those who want to hack on the project...
|
|
||||||
|
|
||||||
The best way to get everything running that you need for development and testing is
|
|
||||||
to use Guard:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
bundle install
|
|
||||||
bundle exec guard
|
|
||||||
... build Qt runner ...
|
|
||||||
... compile CoffeeScript to JS ...
|
|
||||||
... run RSpec and JHW ...
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
* Copyright (c) 2011 John Bintz
|
* Copyright (c) 2011 John Bintz
|
||||||
|
38
Rakefile
38
Rakefile
@ -14,24 +14,12 @@ require 'jasmine/headless/task'
|
|||||||
|
|
||||||
Jasmine::Headless::Task.new
|
Jasmine::Headless::Task.new
|
||||||
|
|
||||||
PLATFORMS = %w{1.9.2 1.9.3}
|
|
||||||
|
|
||||||
def rvm_bundle(command = '')
|
|
||||||
Bundler.with_clean_env do
|
|
||||||
system %{bash -c 'unset BUNDLE_BIN_PATH && unset BUNDLE_GEMFILE && rvm #{PLATFORMS.join(',')} do bundle #{command}'}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SpecFailure < StandardError; end
|
|
||||||
class BundleFailure < StandardError; end
|
|
||||||
|
|
||||||
namespace :spec do
|
namespace :spec do
|
||||||
desc "Run on three Rubies"
|
desc "Run on three Rubies"
|
||||||
task :platforms do
|
task :platforms do
|
||||||
rvm_bundle
|
system %{rvm 1.8.7,1.9.2,ree ruby bundle}
|
||||||
rvm_bundle "exec rspec spec"
|
system %{rvm 1.8.7,1.9.2,ree ruby bundle exec rake spec}
|
||||||
rvm_bundle "exec cucumber"
|
raise StandardError.new if $?.exitstatus != 0
|
||||||
raise SpecError.new if $?.exitstatus != 0
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -43,23 +31,3 @@ task :build_runner do
|
|||||||
system %{ruby extconf.rb}
|
system %{ruby extconf.rb}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Generate vendored JS"
|
|
||||||
task :generate_js do
|
|
||||||
require 'sprockets'
|
|
||||||
|
|
||||||
source = 'vendor/assets/coffeescripts'
|
|
||||||
target = 'vendor/assets/javascripts'
|
|
||||||
|
|
||||||
env = Sprockets::Environment.new { |s| s.append_path 'vendor/assets/coffeescripts' }
|
|
||||||
|
|
||||||
Dir[File.join(File.expand_path(source), '*.coffee')].each do |file|
|
|
||||||
file_target = file.gsub(source, target).gsub('.coffee', '.js')
|
|
||||||
puts "#{file} => #{file_target}"
|
|
||||||
|
|
||||||
File.open(file_target, 'wb') do |fh|
|
|
||||||
fh.print env.find_asset(File.expand_path(file)).to_s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
@ -1,11 +1,38 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
|
require 'rainbow'
|
||||||
|
|
||||||
$: << File.expand_path('../../lib', __FILE__)
|
def gem_dir
|
||||||
|
File.expand_path('../..', __FILE__)
|
||||||
|
end
|
||||||
|
|
||||||
|
$:.unshift(File.join(gem_dir, 'lib'))
|
||||||
require 'jasmine-headless-webkit'
|
require 'jasmine-headless-webkit'
|
||||||
require 'coffee-script'
|
|
||||||
|
|
||||||
Jasmine::Headless::CommandLine.run!
|
require 'jasmine/headless/errors'
|
||||||
|
require 'jasmine/headless/runner'
|
||||||
|
require 'jasmine/headless/options'
|
||||||
|
|
||||||
|
begin
|
||||||
|
options = Jasmine::Headless::Options.from_command_line
|
||||||
|
runner = Jasmine::Headless::Runner.new(options)
|
||||||
|
|
||||||
|
if options[:do_list]
|
||||||
|
files_list = Jasmine::FilesList.new(
|
||||||
|
:config => runner.jasmine_config
|
||||||
|
)
|
||||||
|
|
||||||
|
files_list.files.each { |file| puts file }
|
||||||
|
else
|
||||||
|
puts "Running Jasmine specs...".color(:white)
|
||||||
|
exit runner.run
|
||||||
|
end
|
||||||
|
rescue CoffeeScript::CompilationError
|
||||||
|
exit 1
|
||||||
|
rescue StandardError => e
|
||||||
|
$stderr.puts "[%s] %s (%s)" % [ "jasmine-headless-webkit".color(:red), e.message.color(:white), e.class.name.color(:yellow) ]
|
||||||
|
$stderr.puts e.backtrace.collect { |line| " #{line}" }.join("\n")
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
default: -r features
|
|
||||||
|
|
5
dev-bin/hooks/pre-commit
Executable file
5
dev-bin/hooks/pre-commit
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
bundle exec rake
|
||||||
|
if [ $? -ne 0 ]; then exit 1; fi
|
||||||
|
|
6
dev-bin/install-hooks
Executable file
6
dev-bin/install-hooks
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
for i in $PWD/dev-bin/hooks/*; do
|
||||||
|
ln -sf $i .git/hooks/${i##*/}
|
||||||
|
done
|
||||||
|
|
140
ext/jasmine-webkit-specrunner/ConsoleOutput.cpp
Normal file
140
ext/jasmine-webkit-specrunner/ConsoleOutput.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#include "ConsoleOutput.h"
|
||||||
|
|
||||||
|
ConsoleOutput::ConsoleOutput() : QObject(),
|
||||||
|
showColors(false),
|
||||||
|
consoleLogUsed(false) {
|
||||||
|
outputIO = &std::cout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::passed(const QString &specDetail) {
|
||||||
|
green();
|
||||||
|
*outputIO << '.';
|
||||||
|
clear();
|
||||||
|
outputIO->flush();
|
||||||
|
|
||||||
|
consoleLogUsed = false;
|
||||||
|
successes.push(specDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::failed(const QString &specDetail) {
|
||||||
|
red();
|
||||||
|
*outputIO << 'F';
|
||||||
|
clear();
|
||||||
|
outputIO->flush();
|
||||||
|
|
||||||
|
consoleLogUsed = false;
|
||||||
|
failures.push(specDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::green() {
|
||||||
|
if (showColors) std::cout << "\033[0;32m";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::clear() {
|
||||||
|
if (showColors) std::cout << "\033[m";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::red() {
|
||||||
|
if (showColors) std::cout << "\033[0;31m";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::yellow()
|
||||||
|
{
|
||||||
|
if (showColors) std::cout << "\033[0;33m";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) {
|
||||||
|
red();
|
||||||
|
*outputIO << "[error] ";
|
||||||
|
clear();
|
||||||
|
*outputIO << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::internalLog(const QString ¬e, const QString &msg) {
|
||||||
|
red();
|
||||||
|
*outputIO << "[" << qPrintable(note) << "] ";
|
||||||
|
clear();
|
||||||
|
*outputIO << qPrintable(msg);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::consoleLog(const QString &msg) {
|
||||||
|
if (!consoleLogUsed) {
|
||||||
|
*outputIO << std::endl;
|
||||||
|
consoleLogUsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
green();
|
||||||
|
*outputIO << "[console] ";
|
||||||
|
if (msg.contains("\n"))
|
||||||
|
*outputIO << std::endl;
|
||||||
|
clear();
|
||||||
|
*outputIO << qPrintable(msg);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::logSpecFilename(const QString &name) {
|
||||||
|
*outputIO << std::endl << std::endl;
|
||||||
|
red();
|
||||||
|
*outputIO << qPrintable(name) << std::endl;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::logSpecResult(const QString &result) {
|
||||||
|
red();
|
||||||
|
*outputIO << " " << qPrintable(result) << std::endl;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
red();
|
||||||
|
*outputIO << std::endl << "FAIL: ";
|
||||||
|
formatTestResults(totalTests, failedTests, duration);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
green();
|
||||||
|
*outputIO << std::endl << "PASS: ";
|
||||||
|
formatTestResults(totalTests, failedTests, duration);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
yellow();
|
||||||
|
*outputIO << std::endl << "PASS with JS errors: ";
|
||||||
|
formatTestResults(totalTests, failedTests, duration);
|
||||||
|
*outputIO << std::endl;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutput::formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
*outputIO << qPrintable(totalTests) << " ";
|
||||||
|
if (totalTests == "1") {
|
||||||
|
*outputIO << "test";
|
||||||
|
} else {
|
||||||
|
*outputIO << "tests";
|
||||||
|
}
|
||||||
|
|
||||||
|
*outputIO << ", ";
|
||||||
|
|
||||||
|
*outputIO << qPrintable(failedTests) << " ";
|
||||||
|
if (failedTests == "1") {
|
||||||
|
*outputIO << "failure";
|
||||||
|
} else {
|
||||||
|
*outputIO << "failures";
|
||||||
|
}
|
||||||
|
|
||||||
|
*outputIO << ", ";
|
||||||
|
|
||||||
|
*outputIO << qPrintable(duration) << " ";
|
||||||
|
if (duration == "1") {
|
||||||
|
*outputIO << "sec.";
|
||||||
|
} else {
|
||||||
|
*outputIO << "secs.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
ext/jasmine-webkit-specrunner/ConsoleOutput.h
Normal file
38
ext/jasmine-webkit-specrunner/ConsoleOutput.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef JHW_CONSOLE_OUTPUT
|
||||||
|
#define JHW_CONSOLE_OUTPUT
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <iostream>
|
||||||
|
#include <QStack>
|
||||||
|
|
||||||
|
class ConsoleOutput : public QObject {
|
||||||
|
public:
|
||||||
|
ConsoleOutput();
|
||||||
|
|
||||||
|
void passed(const QString &specDetail);
|
||||||
|
void failed(const QString &specDetail);
|
||||||
|
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
|
||||||
|
void internalLog(const QString ¬e, const QString &msg);
|
||||||
|
void consoleLog(const QString &msg);
|
||||||
|
void logSpecFilename(const QString &name);
|
||||||
|
void logSpecResult(const QString &result);
|
||||||
|
|
||||||
|
void reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
void reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
void reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
|
||||||
|
std::ostream *outputIO;
|
||||||
|
QStack<QString> successes;
|
||||||
|
QStack<QString> failures;
|
||||||
|
|
||||||
|
bool showColors;
|
||||||
|
bool consoleLogUsed;
|
||||||
|
private:
|
||||||
|
void green();
|
||||||
|
void clear();
|
||||||
|
void red();
|
||||||
|
void yellow();
|
||||||
|
void formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
129
ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp
Normal file
129
ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "ConsoleOutput.h"
|
||||||
|
#include "ConsoleOutput_test.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
ConsoleOutputTest::ConsoleOutputTest() : QObject() {}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testPassed() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.consoleLogUsed = true;
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.passed("test");
|
||||||
|
QVERIFY(buffer.str() == ".");
|
||||||
|
QVERIFY(output.successes.size() == 1);
|
||||||
|
QVERIFY(output.failures.size() == 0);
|
||||||
|
QVERIFY(output.consoleLogUsed == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testFailed() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.consoleLogUsed = true;
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.failed("test");
|
||||||
|
QVERIFY(buffer.str() == "F");
|
||||||
|
QVERIFY(output.successes.size() == 0);
|
||||||
|
QVERIFY(output.failures.size() == 1);
|
||||||
|
QVERIFY(output.consoleLogUsed == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testErrorLog() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.errorLog("message", 1, "source");
|
||||||
|
QVERIFY(buffer.str() == "[error] source:1 : message\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testInternalLog() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.internalLog("note", "message");
|
||||||
|
QVERIFY(buffer.str() == "[note] message\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testConsoleLog() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.consoleLogUsed = false;
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.consoleLog("log");
|
||||||
|
QVERIFY(buffer.str() == "\n[console] log\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testConsoleLogUsed() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.consoleLogUsed = true;
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.consoleLog("log");
|
||||||
|
QVERIFY(buffer.str() == "[console] log\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testLogSpecFilename() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.logSpecFilename("whatever");
|
||||||
|
QVERIFY(buffer.str() == "\n\nwhatever\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testLogSpecResult() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.logSpecResult("whatever");
|
||||||
|
QVERIFY(buffer.str() == " whatever\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testReportResultsFailedSingular() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportFailure("1", "1", "1");
|
||||||
|
QVERIFY(buffer.str() == "\nFAIL: 1 test, 1 failure, 1 sec.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testReportResultsFailedPlural() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportFailure("2", "2", "2");
|
||||||
|
QVERIFY(buffer.str() == "\nFAIL: 2 tests, 2 failures, 2 secs.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testReportResultsSucceeded() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportSuccess("2", "2", "2");
|
||||||
|
QVERIFY(buffer.str() == "\nPASS: 2 tests, 2 failures, 2 secs.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConsoleOutputTest::testReportResultsSucceededWithJSErrors() {
|
||||||
|
stringstream buffer;
|
||||||
|
ConsoleOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportSuccessWithJSErrors("2", "2", "2");
|
||||||
|
QVERIFY(buffer.str() == "\nPASS with JS errors: 2 tests, 2 failures, 2 secs.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(ConsoleOutputTest);
|
||||||
|
|
32
ext/jasmine-webkit-specrunner/ConsoleOutput_test.h
Normal file
32
ext/jasmine-webkit-specrunner/ConsoleOutput_test.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef JHW_TEST_CONSOLE_OUTPUT
|
||||||
|
#define JHW_TEST_CONSOLE_OUTPUT
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ConsoleOutput.h"
|
||||||
|
|
||||||
|
class ConsoleOutputTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConsoleOutputTest();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void testPassed();
|
||||||
|
void testFailed();
|
||||||
|
void testErrorLog();
|
||||||
|
void testInternalLog();
|
||||||
|
void testConsoleLog();
|
||||||
|
void testConsoleLogUsed();
|
||||||
|
void testLogSpecFilename();
|
||||||
|
void testLogSpecResult();
|
||||||
|
|
||||||
|
void testReportResultsFailedSingular();
|
||||||
|
void testReportResultsFailedPlural();
|
||||||
|
void testReportResultsSucceeded();
|
||||||
|
void testReportResultsSucceededWithJSErrors();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
7
ext/jasmine-webkit-specrunner/ConsoleOutput_test.pro
Normal file
7
ext/jasmine-webkit-specrunner/ConsoleOutput_test.pro
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include(common.pri)
|
||||||
|
include(test.pri)
|
||||||
|
|
||||||
|
SOURCES += ConsoleOutput_test.cpp
|
||||||
|
HEADERS += ConsoleOutput_test.h
|
||||||
|
|
||||||
|
|
@ -4,12 +4,26 @@
|
|||||||
|
|
||||||
#include "Page.h"
|
#include "Page.h"
|
||||||
|
|
||||||
Page::Page() : QWebPage() {}
|
Page::Page() : QWebPage(), confirmResult(true) {}
|
||||||
|
|
||||||
void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID) {
|
void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
|
||||||
emit handleError(message, lineNumber, sourceID);
|
emit consoleLog(message, lineNumber, sourceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Page::javaScriptAlert(QWebFrame *, const QString &) {}
|
bool Page::javaScriptConfirm(QWebFrame*, const QString&) {
|
||||||
bool Page::javaScriptConfirm(QWebFrame *, const QString &) { return false; }
|
if (confirmResult) {
|
||||||
bool Page::javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *) { return false; }
|
emit internalLog("TODO", "jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm for now. Returning true.");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
confirmResult = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::javaScriptAlert(QWebFrame*, const QString &msg) {
|
||||||
|
emit internalLog("alert", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Page::oneFalseConfirm() {
|
||||||
|
confirmResult = false;
|
||||||
|
}
|
||||||
|
@ -4,17 +4,20 @@
|
|||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QtWebKit>
|
#include <QtWebKit>
|
||||||
|
|
||||||
class Page: public QWebPage {
|
class Page: public QWebPage {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Page();
|
Page();
|
||||||
protected:
|
void oneFalseConfirm();
|
||||||
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
signals:
|
||||||
void javaScriptAlert(QWebFrame *, const QString &);
|
void consoleLog(const QString &msg, int lineNumber, const QString &sourceID);
|
||||||
bool javaScriptConfirm(QWebFrame *, const QString &);
|
void internalLog(const QString ¬e, const QString &msg);
|
||||||
bool javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *);
|
protected:
|
||||||
signals:
|
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
||||||
void handleError(const QString & message, int lineNumber, const QString & sourceID);
|
bool javaScriptConfirm(QWebFrame *frame, const QString &msg);
|
||||||
};
|
void javaScriptAlert(QWebFrame *frame, const QString &msg);
|
||||||
|
private:
|
||||||
|
bool confirmResult;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
43
ext/jasmine-webkit-specrunner/Page_test.cpp
Normal file
43
ext/jasmine-webkit-specrunner/Page_test.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "Page.h"
|
||||||
|
#include "Page_test.h"
|
||||||
|
|
||||||
|
PageTest::PageTest() : QObject(), internalLogCalled(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageTest::internalLog(const QString &, const QString &) {
|
||||||
|
internalLogCalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageTest::consoleLog(const QString &, int, const QString &) {
|
||||||
|
consoleLogCalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageTest::testJavaScriptConfirmWithLog() {
|
||||||
|
connect(&page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
||||||
|
internalLogCalled = false;
|
||||||
|
|
||||||
|
page.mainFrame()->setHtml("<script>confirm('test')</script>");
|
||||||
|
QVERIFY(internalLogCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageTest::testJavaScriptConfirmWithoutLog() {
|
||||||
|
connect(&page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
||||||
|
internalLogCalled = false;
|
||||||
|
|
||||||
|
page.oneFalseConfirm();
|
||||||
|
page.mainFrame()->setHtml("<script>confirm('test')</script>");
|
||||||
|
QVERIFY(!internalLogCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PageTest::testJavaScriptConsoleMessage() {
|
||||||
|
connect(&page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(consoleLog(QString, int, QString)));
|
||||||
|
consoleLogCalled = false;
|
||||||
|
|
||||||
|
page.mainFrame()->setHtml("<script>cats();</script>");
|
||||||
|
QVERIFY(consoleLogCalled);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(PageTest);
|
||||||
|
|
27
ext/jasmine-webkit-specrunner/Page_test.h
Normal file
27
ext/jasmine-webkit-specrunner/Page_test.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef JHW_TEST_PAGE
|
||||||
|
#define JHW_TEST_PAGE
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "Page.h"
|
||||||
|
|
||||||
|
class PageTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PageTest();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool internalLogCalled;
|
||||||
|
bool consoleLogCalled;
|
||||||
|
Page page;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void internalLog(const QString ¬e, const QString &msg);
|
||||||
|
void consoleLog(const QString &message, int lineNumber, const QString &source);
|
||||||
|
void testJavaScriptConfirmWithLog();
|
||||||
|
void testJavaScriptConfirmWithoutLog();
|
||||||
|
void testJavaScriptConsoleMessage();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
6
ext/jasmine-webkit-specrunner/Page_test.pro
Normal file
6
ext/jasmine-webkit-specrunner/Page_test.pro
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
include(common.pri)
|
||||||
|
include(test.pri)
|
||||||
|
|
||||||
|
SOURCES += Page_test.cpp
|
||||||
|
HEADERS += Page_test.h
|
||||||
|
|
54
ext/jasmine-webkit-specrunner/ReportFileOutput.cpp
Normal file
54
ext/jasmine-webkit-specrunner/ReportFileOutput.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "ReportFileOutput.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
ReportFileOutput::ReportFileOutput() : QObject() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::reset() {
|
||||||
|
buffer = new stringstream();
|
||||||
|
|
||||||
|
outputIO = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::passed(const QString &specDetail) {
|
||||||
|
*outputIO << "PASS||" << qPrintable(specDetail) << std::endl;
|
||||||
|
successes.push(specDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::failed(const QString &specDetail) {
|
||||||
|
*outputIO << "FAIL||" << qPrintable(specDetail) << std::endl;
|
||||||
|
failures.push(specDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) {
|
||||||
|
*outputIO << "ERROR||" << qPrintable(msg) << "||" << qPrintable(sourceID) << ":" << lineNumber << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::consoleLog(const QString &msg) {
|
||||||
|
*outputIO << "CONSOLE||" << qPrintable(msg) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::internalLog(const QString &, const QString &) {}
|
||||||
|
void ReportFileOutput::logSpecFilename(const QString &) {}
|
||||||
|
void ReportFileOutput::logSpecResult(const QString &) {}
|
||||||
|
|
||||||
|
void ReportFileOutput::reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
reportTotals(totalTests, failedTests, duration, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
reportTotals(totalTests, failedTests, duration, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration) {
|
||||||
|
reportTotals(totalTests, failedTests, duration, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutput::reportTotals(const QString &totalTests, const QString &failedTests, const QString &duration, bool hasJavaScriptError) {
|
||||||
|
*outputIO << "TOTAL||" << qPrintable(totalTests) << "||" << qPrintable(failedTests) << "||" << qPrintable(duration) << "||";
|
||||||
|
*outputIO << (hasJavaScriptError ? "T" : "F");
|
||||||
|
*outputIO << std::endl;
|
||||||
|
}
|
||||||
|
|
37
ext/jasmine-webkit-specrunner/ReportFileOutput.h
Normal file
37
ext/jasmine-webkit-specrunner/ReportFileOutput.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef JHW_REPORT_FILE_OUTPUT
|
||||||
|
#define JHW_REPORT_FILE_OUTPUT
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <iostream>
|
||||||
|
#include <QStack>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class ReportFileOutput : public QObject {
|
||||||
|
public:
|
||||||
|
ReportFileOutput();
|
||||||
|
|
||||||
|
void passed(const QString &specDetail);
|
||||||
|
void failed(const QString &specDetail);
|
||||||
|
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
|
||||||
|
void internalLog(const QString ¬e, const QString &msg);
|
||||||
|
void consoleLog(const QString &msg);
|
||||||
|
void logSpecFilename(const QString &name);
|
||||||
|
void logSpecResult(const QString &result);
|
||||||
|
|
||||||
|
void reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
void reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
void reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
stringstream *buffer;
|
||||||
|
stringstream *outputIO;
|
||||||
|
QStack<QString> successes;
|
||||||
|
QStack<QString> failures;
|
||||||
|
private:
|
||||||
|
void reportTotals(const QString &totalTests, const QString &failedTests, const QString &duration, bool hasJavaScriptError);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
88
ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp
Normal file
88
ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
#include "ReportFileOutput.h"
|
||||||
|
#include "ReportFileOutput_test.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
ReportFileOutputTest::ReportFileOutputTest() : QObject() {}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testPassed() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.passed("test||done||file.js:23");
|
||||||
|
QVERIFY(buffer.str() == "PASS||test||done||file.js:23\n");
|
||||||
|
QVERIFY(output.successes.size() == 1);
|
||||||
|
QVERIFY(output.failures.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testFailed() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.failed("test||done||file.js:23");
|
||||||
|
QVERIFY(buffer.str() == "FAIL||test||done||file.js:23\n");
|
||||||
|
QVERIFY(output.successes.size() == 0);
|
||||||
|
QVERIFY(output.failures.size() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testErrorLog() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.errorLog("JS Error", 23, "file.js");
|
||||||
|
QVERIFY(buffer.str() == "ERROR||JS Error||file.js:23\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testConsoleLog() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.consoleLog("Console");
|
||||||
|
QVERIFY(buffer.str() == "CONSOLE||Console\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testStubMethods() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.internalLog("Internal", "Log");
|
||||||
|
output.logSpecFilename("Filename");
|
||||||
|
output.logSpecResult("REsult");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testReportFailure() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportFailure("5", "2", "1.5");
|
||||||
|
QVERIFY(buffer.str() == "TOTAL||5||2||1.5||F\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testReportSuccess() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportSuccess("5", "0", "1.5");
|
||||||
|
QVERIFY(buffer.str() == "TOTAL||5||0||1.5||F\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReportFileOutputTest::testReportSuccessWithJSErrors() {
|
||||||
|
stringstream buffer;
|
||||||
|
ReportFileOutput output;
|
||||||
|
|
||||||
|
output.outputIO = &buffer;
|
||||||
|
output.reportSuccessWithJSErrors("5", "0", "1.5");
|
||||||
|
QVERIFY(buffer.str() == "TOTAL||5||0||1.5||T\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(ReportFileOutputTest);
|
||||||
|
|
26
ext/jasmine-webkit-specrunner/ReportFileOutput_test.h
Normal file
26
ext/jasmine-webkit-specrunner/ReportFileOutput_test.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef JHW_TEST_REPORT_FILE_OUTPUT
|
||||||
|
#define JHW_TEST_REPORT_FILE_OUTPUT
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ReportFileOutput.h"
|
||||||
|
|
||||||
|
class ReportFileOutputTest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ReportFileOutputTest();
|
||||||
|
private slots:
|
||||||
|
void testPassed();
|
||||||
|
void testFailed();
|
||||||
|
void testErrorLog();
|
||||||
|
void testConsoleLog();
|
||||||
|
void testStubMethods();
|
||||||
|
void testReportFailure();
|
||||||
|
void testReportSuccess();
|
||||||
|
void testReportSuccessWithJSErrors();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
7
ext/jasmine-webkit-specrunner/ReportFileOutput_test.pro
Normal file
7
ext/jasmine-webkit-specrunner/ReportFileOutput_test.pro
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
include(common.pri)
|
||||||
|
include(test.pri)
|
||||||
|
|
||||||
|
SOURCES += ReportFileOutput_test.cpp
|
||||||
|
HEADERS += ReportFileOutput_test.h
|
||||||
|
|
||||||
|
|
@ -3,178 +3,181 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
#include "Runner.h"
|
#include "Runner.h"
|
||||||
#include "Page.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Runner::Runner() : QObject()
|
Runner::Runner() : QObject()
|
||||||
, runs(0)
|
, m_runs(0)
|
||||||
, hasErrors(false)
|
, hasErrors(false)
|
||||||
, _hasSpecFailure(false)
|
|
||||||
, usedConsole(false)
|
, usedConsole(false)
|
||||||
, isFinished(false)
|
, isFinished(false)
|
||||||
, useColors(false)
|
, didFail(false)
|
||||||
, quiet(false)
|
|
||||||
{
|
{
|
||||||
page.settings()->enablePersistentStorage();
|
m_page.settings()->enablePersistentStorage();
|
||||||
ticker.setInterval(TIMER_TICK);
|
m_ticker.setInterval(TIMER_TICK);
|
||||||
|
|
||||||
connect(&ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
|
connect(&m_ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
|
||||||
connect(&page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
||||||
connect(&page, SIGNAL(handleError(const QString &, int, const QString &)), this, SLOT(handleError(const QString &, int, const QString &)));
|
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
|
||||||
connect(page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
||||||
|
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::addFile(const QString &spec) {
|
void Runner::addFile(const QString &spec) {
|
||||||
runnerFiles.enqueue(spec);
|
runnerFiles.enqueue(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::go() {
|
void Runner::go()
|
||||||
ticker.stop();
|
{
|
||||||
page.setPreferredContentsSize(QSize(1024, 600));
|
m_ticker.stop();
|
||||||
|
m_page.setPreferredContentsSize(QSize(1024, 600));
|
||||||
addJHW();
|
addJHW();
|
||||||
|
|
||||||
loadSpec();
|
loadSpec();
|
||||||
|
|
||||||
|
m_ticker.start();
|
||||||
}
|
}
|
||||||
void Runner::addJHW() {
|
void Runner::addJHW()
|
||||||
page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
{
|
||||||
}
|
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
||||||
|
|
||||||
void Runner::handleError(const QString &message, int lineNumber, const QString &sourceID) {
|
|
||||||
QString messageEscaped = QString(message);
|
|
||||||
QString sourceIDEscaped = QString(sourceID);
|
|
||||||
|
|
||||||
messageEscaped.replace(QString("\""), QString("\\\""));
|
|
||||||
sourceIDEscaped.replace(QString("\""), QString("\\\""));
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << lineNumber;
|
|
||||||
|
|
||||||
QString command("JHW._handleError(\"" + messageEscaped + "\", " + QString(ss.str().c_str()) + ", \"" + sourceIDEscaped + "\"); false;");
|
|
||||||
|
|
||||||
page.mainFrame()->evaluateJavaScript(command);
|
|
||||||
|
|
||||||
hasErrors = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::loadSpec()
|
void Runner::loadSpec()
|
||||||
{
|
{
|
||||||
QVectorIterator<QString> iterator(reportFiles);
|
m_page.mainFrame()->load(runnerFiles.dequeue());
|
||||||
|
m_ticker.start();
|
||||||
while (iterator.hasNext()) {
|
|
||||||
QFile *outputFile = new QFile(iterator.next());
|
|
||||||
outputFile->open(QIODevice::WriteOnly);
|
|
||||||
outputFiles.enqueue(outputFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString runnerFile = runnerFiles.dequeue();
|
|
||||||
|
|
||||||
page.mainFrame()->load(runnerFile);
|
|
||||||
ticker.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::watch(bool ok) {
|
void Runner::watch(bool ok)
|
||||||
|
{
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
std::cerr << "Can't load " << qPrintable(page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
|
std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
|
||||||
std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
|
std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
|
||||||
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
|
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
page.mainFrame()->evaluateJavaScript(QString("JHW._setColors(") + (useColors ? QString("true") : QString("false")) + QString("); false;"));
|
}
|
||||||
|
|
||||||
|
bool Runner::hasElement(const char *select)
|
||||||
|
{
|
||||||
|
return !m_page.mainFrame()->findFirstElement(select).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::setColors(bool colors) {
|
void Runner::setColors(bool colors) {
|
||||||
useColors = colors;
|
consoleOutput.showColors = colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::hasUsedConsole() {
|
void Runner::reportFile(const QString &file) {
|
||||||
usedConsole = true;
|
reportFileName = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::hasError() {
|
bool Runner::hasError() {
|
||||||
hasErrors = true;
|
return hasErrors;
|
||||||
}
|
|
||||||
|
|
||||||
void Runner::hasSpecFailure() {
|
|
||||||
_hasSpecFailure = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Runner::setReportFiles(QStack<QString> &files) {
|
|
||||||
reportFiles = files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::timerPause() {
|
void Runner::timerPause() {
|
||||||
ticker.stop();
|
m_ticker.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::timerDone() {
|
void Runner::timerDone() {
|
||||||
ticker.start();
|
m_ticker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::ping() {
|
void Runner::specPassed(const QString &specDetail) {
|
||||||
runs = 0;
|
consoleOutput.passed(specDetail);
|
||||||
|
reportFileOutput.passed(specDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::setSeed(QString s) {
|
void Runner::specFailed(const QString &specDetail) {
|
||||||
seed = s;
|
consoleOutput.failed(specDetail);
|
||||||
|
reportFileOutput.failed(specDetail);
|
||||||
|
|
||||||
|
didFail = true;
|
||||||
|
failedSpecs.push(specDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::setQuiet(bool q) {
|
void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
|
||||||
quiet = q;
|
{
|
||||||
|
consoleOutput.errorLog(msg, lineNumber, sourceID);
|
||||||
|
reportFileOutput.errorLog(msg, lineNumber, sourceID);
|
||||||
|
|
||||||
|
hasErrors = true;
|
||||||
|
m_runs = 0;
|
||||||
|
m_ticker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Runner::getSeed() {
|
void Runner::internalLog(const QString ¬e, const QString &msg) {
|
||||||
return seed;
|
consoleOutput.internalLog(note, msg);
|
||||||
|
reportFileOutput.internalLog(note, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Runner::isQuiet() {
|
void Runner::log(const QString &msg)
|
||||||
return quiet;
|
{
|
||||||
|
usedConsole = true;
|
||||||
|
consoleOutput.consoleLog(msg);
|
||||||
|
reportFileOutput.consoleLog(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::print(const QString &fh, const QString &content) {
|
void Runner::leavePageAttempt(const QString &msg)
|
||||||
if (fh == "stdout") {
|
{
|
||||||
std::cout << qPrintable(content);
|
consoleOutput.internalLog("error", msg);
|
||||||
std::cout.flush();
|
m_page.oneFalseConfirm();
|
||||||
|
hasErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::printName(const QString &name)
|
||||||
|
{
|
||||||
|
consoleOutput.logSpecFilename(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::printResult(const QString &result)
|
||||||
|
{
|
||||||
|
consoleOutput.logSpecResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed)
|
||||||
|
{
|
||||||
|
if (didFail) {
|
||||||
|
consoleOutput.reportFailure(total, failed, duration);
|
||||||
|
reportFileOutput.reportFailure(total, failed, duration);
|
||||||
|
} else {
|
||||||
|
if (hasErrors) {
|
||||||
|
consoleOutput.reportSuccessWithJSErrors(total, failed, duration);
|
||||||
|
reportFileOutput.reportSuccessWithJSErrors(total, failed, duration);
|
||||||
|
} else {
|
||||||
|
consoleOutput.reportSuccess(total, failed, duration);
|
||||||
|
reportFileOutput.reportSuccess(total, failed, duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fh == "stderr") {
|
if (!reportFileName.isEmpty()) {
|
||||||
std::cerr << qPrintable(content);
|
QFile outputFile(reportFileName);
|
||||||
std::cerr.flush();
|
outputFile.open(QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
QTextStream ts(&outputFile);
|
||||||
|
|
||||||
|
ts << reportFileOutput.outputIO->str().c_str();
|
||||||
|
|
||||||
|
outputFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fh.contains("report")) {
|
|
||||||
int index = (int)fh.split(":").last().toUInt();
|
|
||||||
|
|
||||||
QTextStream ts(outputFiles.at(index));
|
|
||||||
ts << qPrintable(content);
|
|
||||||
ts.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Runner::finishSuite() {
|
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
runs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::timerEvent() {
|
void Runner::timerEvent()
|
||||||
++runs;
|
{
|
||||||
|
++m_runs;
|
||||||
|
|
||||||
if (hasErrors && runs > 2)
|
if (hasErrors && m_runs > 2)
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
|
|
||||||
if (isFinished && runs > 2) {
|
if (isFinished) {
|
||||||
while (!outputFiles.isEmpty()) {
|
|
||||||
outputFiles.dequeue()->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
if (_hasSpecFailure || hasErrors) {
|
if (didFail || hasErrors) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
} else {
|
} else {
|
||||||
if (usedConsole) {
|
if (usedConsole) {
|
||||||
@ -200,8 +203,8 @@ void Runner::timerEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runs > MAX_LOOPS) {
|
if (m_runs > MAX_LOOPS) {
|
||||||
std::cerr << "WARNING: too many runs and the test is still not finished!" << std::endl;
|
std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl;
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,67 +7,60 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "Page.h"
|
#include "Page.h"
|
||||||
|
#include "ConsoleOutput.h"
|
||||||
|
#include "ReportFileOutput.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Runner: public QObject {
|
class Runner: public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum { TIMER_TICK = 200, MAX_LOOPS = 50 };
|
enum { TIMER_TICK = 200, MAX_LOOPS = 25 };
|
||||||
|
|
||||||
Runner();
|
Runner();
|
||||||
void setColors(bool colors);
|
void setColors(bool colors);
|
||||||
void setReportFiles(QStack<QString> &files);
|
void reportFile(const QString &file);
|
||||||
void setSeed(QString s);
|
|
||||||
void setQuiet(bool q);
|
|
||||||
|
|
||||||
void addFile(const QString &spec);
|
void addFile(const QString &spec);
|
||||||
void go();
|
void go();
|
||||||
|
public slots:
|
||||||
public slots:
|
void log(const QString &msg);
|
||||||
|
bool hasError();
|
||||||
|
void leavePageAttempt(const QString &msg);
|
||||||
void timerPause();
|
void timerPause();
|
||||||
void timerDone();
|
void timerDone();
|
||||||
void hasUsedConsole();
|
void specPassed(const QString &specDetail);
|
||||||
void hasError();
|
void specFailed(const QString &specDetail);
|
||||||
void hasSpecFailure();
|
void printName(const QString &name);
|
||||||
|
void printResult(const QString &result);
|
||||||
bool isQuiet();
|
void finishSuite(const QString &duration, const QString &total, const QString& failed);
|
||||||
QString getSeed();
|
private slots:
|
||||||
|
void watch(bool ok);
|
||||||
void print(const QString &fh, const QString &content);
|
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
|
||||||
void finishSuite();
|
void internalLog(const QString ¬e, const QString &msg);
|
||||||
void ping();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void watch(bool ok);
|
|
||||||
void addJHW();
|
void addJHW();
|
||||||
void timerEvent();
|
void timerEvent();
|
||||||
void handleError(const QString & message, int lineNumber, const QString & sourceID);
|
protected:
|
||||||
|
bool hasElement(const char *select);
|
||||||
private:
|
private:
|
||||||
Page page;
|
Page m_page;
|
||||||
QTimer ticker;
|
QTimer m_ticker;
|
||||||
int runs;
|
int m_runs;
|
||||||
bool hasErrors;
|
bool hasErrors;
|
||||||
bool _hasSpecFailure;
|
|
||||||
bool usedConsole;
|
bool usedConsole;
|
||||||
bool isFinished;
|
bool isFinished;
|
||||||
bool useColors;
|
bool didFail;
|
||||||
bool quiet;
|
|
||||||
|
|
||||||
QString seed;
|
|
||||||
|
|
||||||
QQueue<QString> runnerFiles;
|
QQueue<QString> runnerFiles;
|
||||||
QStack<QString> reportFiles;
|
QStack<QString> failedSpecs;
|
||||||
|
|
||||||
|
ConsoleOutput consoleOutput;
|
||||||
|
ReportFileOutput reportFileOutput;
|
||||||
|
|
||||||
|
QString reportFileName;
|
||||||
|
|
||||||
void loadSpec();
|
void loadSpec();
|
||||||
|
|
||||||
QQueue<QFile *> outputFiles;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
QMAKE_INFO_PLIST = Info.plist
|
QMAKE_INFO_PLIST = Info.plist
|
||||||
|
QMAKESPEC = macx-g++
|
||||||
QT += network webkit
|
QT += network webkit
|
||||||
|
|
||||||
SOURCES = Page.cpp Runner.cpp
|
SOURCES = Page.cpp Runner.cpp ConsoleOutput.cpp ReportFileOutput.cpp
|
||||||
HEADERS = Page.h Runner.h
|
HEADERS = Page.h Runner.h ConsoleOutput.h ReportFileOutput.h
|
||||||
|
|
||||||
|
19
ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro
Normal file
19
ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
######################################################################
|
||||||
|
# Automatically generated by qmake (2.01a) Tue Aug 2 10:37:48 2011
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
TEMPLATE = app
|
||||||
|
TARGET =
|
||||||
|
DEPENDPATH += . HeadlessSpecRunner Test
|
||||||
|
INCLUDEPATH += . HeadlessSpecRunner Test
|
||||||
|
|
||||||
|
# Input
|
||||||
|
HEADERS += HeadlessSpecRunner/ConsoleOutput.h \
|
||||||
|
HeadlessSpecRunner/Page.h \
|
||||||
|
HeadlessSpecRunner/Runner.h \
|
||||||
|
Test/Page_test.h
|
||||||
|
SOURCES += specrunner.cpp \
|
||||||
|
HeadlessSpecRunner/ConsoleOutput.cpp \
|
||||||
|
HeadlessSpecRunner/Page.cpp \
|
||||||
|
HeadlessSpecRunner/Runner.cpp \
|
||||||
|
Test/Page_test.cpp
|
@ -21,56 +21,43 @@
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Page.h"
|
||||||
#include "Runner.h"
|
#include "Runner.h"
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
|
|
||||||
#include <getopt.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
||||||
#error Use Qt 4.7 or later version
|
#error Use Qt 4.7 or later version
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
bool showColors = false;
|
char *reporter = NULL;
|
||||||
bool isQuiet = false;
|
char showColors = false;
|
||||||
QString seed;
|
|
||||||
QStack<QString> reporterFiles;
|
|
||||||
|
|
||||||
int c, index;
|
int c, index;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "cr:s:q")) != -1) {
|
while ((c = getopt(argc, argv, "cr:")) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
showColors = true;
|
showColors = true;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
|
||||||
isQuiet = true;
|
|
||||||
break;
|
|
||||||
case 'r':
|
case 'r':
|
||||||
reporterFiles.push(QString(optarg));
|
reporter = 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] [-s seed] [-r report file ...] specrunner.html ..." << std::endl;
|
std::cerr << " specrunner [-c] [-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.setColors(showColors);
|
||||||
runner.setQuiet(isQuiet);
|
|
||||||
runner.setReportFiles(reporterFiles);
|
runner.reportFile(reporter);
|
||||||
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]));
|
||||||
|
@ -2,4 +2,3 @@ include(common.pri)
|
|||||||
|
|
||||||
SOURCES += specrunner.cpp
|
SOURCES += specrunner.cpp
|
||||||
TARGET = jasmine-webkit-specrunner
|
TARGET = jasmine-webkit-specrunner
|
||||||
|
|
||||||
|
3
ext/jasmine-webkit-specrunner/test.pri
Normal file
3
ext/jasmine-webkit-specrunner/test.pri
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TARGET = jhw-test
|
||||||
|
QT += testlib
|
||||||
|
|
24
ext/jasmine-webkit-specrunner/test.rb
Normal file
24
ext/jasmine-webkit-specrunner/test.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
system %{make clean}
|
||||||
|
|
||||||
|
$: << File.expand_path("../../../lib", __FILE__)
|
||||||
|
require 'qt/qmake'
|
||||||
|
|
||||||
|
Dir['*_test.pro'].each do |test|
|
||||||
|
FileUtils.rm_f('jhw-test')
|
||||||
|
|
||||||
|
Qt::Qmake.make!('jasmine-headless-webkit', test)
|
||||||
|
|
||||||
|
if File.file?('jhw-test')
|
||||||
|
system %{./jhw-test}
|
||||||
|
if $?.exitstatus != 0
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
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 -f File: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
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Bin - Files
|
|
||||||
Scenario: List the files a test suite will use
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml -l`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the output should include "spec/jasmine/success/success.js"
|
|
||||||
And the output should include "spec/jasmine/success/success_spec.js"
|
|
@ -1,18 +0,0 @@
|
|||||||
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 -f File: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 -f File: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 -f File: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
|
|
@ -1,14 +0,0 @@
|
|||||||
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 -f File: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 -f File: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
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Bin - Help
|
|
||||||
Scenario: Display the Help
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -h`
|
|
||||||
Then I should get help output
|
|
||||||
And the exit status should be 0
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
Feature: Bin - Quiet Messages
|
|
||||||
Scenario: Run a test that would cause a lot of messages to be displayed and silence them all
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -q -j spec/jasmine/noisy/noisy.yml`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the output should not include "[Skipping File]"
|
|
||||||
And the output should not include "You should mock"
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
Feature: Bin - Runner Out
|
|
||||||
Scenario: Write out the runner to a specified file
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --runner-out spec/runner.html`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the file "spec/runner.html" should contain a JHW runner
|
|
||||||
When I delete the file "spec/runner.html"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Bin - Two spec files with same basename
|
|
||||||
Scenario: Run both files
|
|
||||||
Given there is no existing "spec/report.txt" file
|
|
||||||
When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_spec_files_same_basename/jasmine.yml -f File:spec/report.txt`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
Feature: Bin - Success
|
|
||||||
Scenario: Run a successful test with long format definition
|
|
||||||
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 File --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 -f File: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
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
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 -f File:spec/report.txt`
|
|
||||||
Then the exit status should be 1
|
|
@ -1,7 +0,0 @@
|
|||||||
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 -f File:spec/report.txt`
|
|
||||||
Then the exit status should be 1
|
|
||||||
And the report file "spec/report.txt" should exist
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
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 -f File: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
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
Feature: Two files from source files
|
|
||||||
Scenario: Files are ordered directly
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_files_from_src_files/jasmine.yml -l`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the following files should be loaded in order:
|
|
||||||
| vendor/vendor-file.js |
|
|
||||||
| vendor/vendor.js |
|
|
||||||
| app/app-file.js |
|
|
||||||
| app/app.js |
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
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 -f File:spec/report.txt`
|
|
||||||
Then the exit status should be 1
|
|
||||||
And the report file "spec/report.txt" should not exist
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Use 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 -f File: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
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Bin - With Server
|
|
||||||
Scenario: Run using an HTTP server
|
|
||||||
Given there is no existing "spec/report.txt" file
|
|
||||||
When I run `bin/jasmine-headless-webkit --use-server -j spec/jasmine/success/success.yml -f File: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
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
Feature: Bin - With window.prompt()
|
|
||||||
Scenario: Alert the user that window.prompt() needs to be stubbed
|
|
||||||
Given I have a test suite
|
|
||||||
When I run `bin/jasmine-headless-webkit -j spec/jasmine/window_prompt/window_prompt.yml`
|
|
||||||
Then the exit status should be 0
|
|
||||||
And the output should include "You should mock window.prompt"
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
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 "Console" 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 |
|
|
||||||
| Console | |
|
|
||||||
| File | file |
|
|
||||||
When I get a runner
|
|
||||||
And I get a template writer
|
|
||||||
Then the template should use the "Console" reporter to "stdout"
|
|
||||||
And the template should use the "File" reporter to "report:0"
|
|
||||||
And the command to run the runner should include the report file "file"
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
Feature: Using the Runner directly
|
|
||||||
Scenario: Succeed
|
|
||||||
Given I have the following runner options:
|
|
||||||
"""
|
|
||||||
:jasmine_config: spec/jasmine/success/success.yml
|
|
||||||
:reporters:
|
|
||||||
- [ 'File', 'spec/report.txt' ]
|
|
||||||
"""
|
|
||||||
When I get a runner
|
|
||||||
And I run the runner
|
|
||||||
Then the runner should have an exit status of 0
|
|
||||||
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
|
|
||||||
|
|
||||||
Scenario: JavaScript Error
|
|
||||||
Given I have the following runner options:
|
|
||||||
"""
|
|
||||||
:jasmine_config: spec/jasmine/success_with_error/success_with_error.yml
|
|
||||||
"""
|
|
||||||
When I get a runner
|
|
||||||
And I run the runner
|
|
||||||
Then the runner should have an exit status of 1
|
|
||||||
|
|
||||||
Scenario: Failure
|
|
||||||
Given I have the following runner options:
|
|
||||||
"""
|
|
||||||
:jasmine_config: spec/jasmine/failure/failure.yml
|
|
||||||
:reporters:
|
|
||||||
- [ 'File', 'spec/report.txt' ]
|
|
||||||
"""
|
|
||||||
When I get a runner
|
|
||||||
And I run the runner
|
|
||||||
Then the runner should have an exit status of 1
|
|
||||||
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
Given /^I have a test suite$/ do
|
|
||||||
end
|
|
@ -1,4 +0,0 @@
|
|||||||
Given /^there is no existing "([^"]*)" file$/ do |file|
|
|
||||||
FileUtils.rm_rf file
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
Given /^I have the default runner options$/ do
|
|
||||||
@options = Jasmine::Headless::Options.new
|
|
||||||
end
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
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
|
|
@ -1,3 +0,0 @@
|
|||||||
Given /^I have the following runner options:$/ do |string|
|
|
||||||
@options = YAML.load(string)
|
|
||||||
end
|
|
@ -1,3 +0,0 @@
|
|||||||
Then /^the exit status should be (\d+)$/ do |exitstatus|
|
|
||||||
$?.exitstatus.should == exitstatus.to_i
|
|
||||||
end
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^the file "([^"]*)" should contain a JHW runner$/ do |file|
|
|
||||||
File.read(file).should include('jasmine.HeadlessReporter')
|
|
||||||
end
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
Then /^the following files should be loaded in order:$/ do |table|
|
|
||||||
files = table.raw.flatten
|
|
||||||
|
|
||||||
@output.lines.collect(&:strip).each do |line|
|
|
||||||
files.shift if line[files.first]
|
|
||||||
end
|
|
||||||
|
|
||||||
files.should be_empty
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^I should get help output$/ do
|
|
||||||
@output.should include("Usage:")
|
|
||||||
end
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
Then /^the output should include "([^"]*)"$/ do |string|
|
|
||||||
@output.should include(string)
|
|
||||||
end
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^the output should not include "([^"]*)"$/ do |string|
|
|
||||||
@output.should_not include(string)
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^the report file "([^"]*)" should not exist$/ do |file|
|
|
||||||
File.file?(file).should be_false
|
|
||||||
end
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
Then /^the report file "([^"]*)" should exist$/ do |file|
|
|
||||||
File.file?(file).should be_true
|
|
||||||
end
|
|
@ -1,7 +0,0 @@
|
|||||||
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
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^the report file "([^"]*)" should have seed (\d+)$/ do |file, seed|
|
|
||||||
report = Jasmine::Headless::Report.load(file)
|
|
||||||
report.seed.should == seed.to_i
|
|
||||||
end
|
|
@ -1,3 +0,0 @@
|
|||||||
Then /^the runner should have an exit status of (\d+)$/ do |exit_status|
|
|
||||||
@result.should == exit_status.to_i
|
|
||||||
end
|
|
@ -1,4 +0,0 @@
|
|||||||
Then /^the command to run the runner should include the report file "([^"]*)"$/ do |file|
|
|
||||||
@runner.jasmine_command.should include("-r #{file}")
|
|
||||||
end
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
Then /^the command to run the runner should not include a report file$/ do
|
|
||||||
@runner.jasmine_command.should_not include('-r')
|
|
||||||
end
|
|
@ -1,6 +0,0 @@
|
|||||||
Then /^the template should use the "([^"]*)" reporter to "([^"]*)"$/ do |reporter, target|
|
|
||||||
output = @template_writer.render
|
|
||||||
|
|
||||||
output.should include(%{jasmine.HeadlessReporter.#{reporter}("#{target}")})
|
|
||||||
end
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
When /^I delete the file "([^"]*)"$/ do |file|
|
|
||||||
FileUtils.rm_f(file)
|
|
||||||
end
|
|
@ -1,4 +0,0 @@
|
|||||||
When /^I get a runner$/ do
|
|
||||||
@runner = Jasmine::Headless::Runner.new(@options)
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
When /^I get a template writer$/ do
|
|
||||||
@template_writer = Jasmine::Headless::TemplateWriter.new(@runner)
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
When /^I run `(.*)`$/ do |command|
|
|
||||||
@output = `#{command}`
|
|
||||||
end
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
|||||||
When /^I run the runner$/ do
|
|
||||||
@result = @runner.run
|
|
||||||
end
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
require 'jasmine-headless-webkit'
|
|
||||||
|
|
||||||
After do
|
|
||||||
FileUtils.rm_f 'spec/report.txt'
|
|
||||||
FileUtils.rm_f 'spec/runner.html'
|
|
||||||
end
|
|
||||||
|
|
@ -20,11 +20,8 @@ Gem::Specification.new do |s|
|
|||||||
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
|
|
||||||
s.add_runtime_dependency 'jasmine-core'
|
s.add_dependency 'jasmine-core', '~>1.1.beta'
|
||||||
s.add_runtime_dependency 'coffee-script'
|
s.add_dependency 'coffee-script', '>= 2.2'
|
||||||
s.add_runtime_dependency 'rainbow'
|
s.add_dependency 'rainbow'
|
||||||
s.add_runtime_dependency 'multi_json', '>= 1.2.0'
|
s.add_dependency 'multi_json'
|
||||||
s.add_runtime_dependency 'sprockets'
|
|
||||||
s.add_runtime_dependency 'sprockets-vendor_gems'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
120
jasmine/jasmine.headless-reporter.coffee
Normal file
120
jasmine/jasmine.headless-reporter.coffee
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
if !jasmine?
|
||||||
|
throw new Error("jasmine not laoded!")
|
||||||
|
|
||||||
|
# Jasmine extensions
|
||||||
|
getSplitName = (parts) ->
|
||||||
|
parts.push(String(@description).replace(/[\n\r]/g, ' '))
|
||||||
|
parts
|
||||||
|
|
||||||
|
jasmine.Suite.prototype.getSuiteSplitName = ->
|
||||||
|
this.getSplitName(if @parentSuite then @parentSuite.getSuiteSplitName() else [])
|
||||||
|
|
||||||
|
jasmine.Spec.prototype.getSpecSplitName = ->
|
||||||
|
this.getSplitName(@suite.getSuiteSplitName())
|
||||||
|
|
||||||
|
jasmine.Suite.prototype.getSplitName = getSplitName
|
||||||
|
jasmine.Spec.prototype.getSplitName = getSplitName
|
||||||
|
|
||||||
|
jasmine.Spec.prototype.getJHWSpecInformation = ->
|
||||||
|
parts = this.getSpecSplitName()
|
||||||
|
specLineInfo = HeadlessReporterResult.findSpecLine(parts)
|
||||||
|
if specLineInfo.file
|
||||||
|
parts.push("#{specLineInfo.file}:#{specLineInfo.lineNumber}")
|
||||||
|
else
|
||||||
|
parts.push('')
|
||||||
|
parts.join("||")
|
||||||
|
|
||||||
|
if !jasmine.WaitsBlock.prototype._execute
|
||||||
|
jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute
|
||||||
|
jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute
|
||||||
|
|
||||||
|
pauseAndRun = (onComplete) ->
|
||||||
|
JHW.timerPause()
|
||||||
|
this._execute ->
|
||||||
|
JHW.timerDone()
|
||||||
|
onComplete()
|
||||||
|
|
||||||
|
jasmine.WaitsBlock.prototype.execute = pauseAndRun
|
||||||
|
jasmine.WaitsForBlock.prototype.execute = pauseAndRun
|
||||||
|
|
||||||
|
# Try to get the line number of a failed spec
|
||||||
|
class window.HeadlessReporterResult
|
||||||
|
constructor: (@name, @splitName) ->
|
||||||
|
@results = []
|
||||||
|
addResult: (message) ->
|
||||||
|
@results.push(message)
|
||||||
|
print: ->
|
||||||
|
output = @name
|
||||||
|
bestChoice = HeadlessReporterResult.findSpecLine(@splitName)
|
||||||
|
output += " (#{bestChoice.file}:#{bestChoice.lineNumber})" if bestChoice.file
|
||||||
|
|
||||||
|
JHW.printName(output)
|
||||||
|
for result in @results
|
||||||
|
JHW.printResult(result)
|
||||||
|
@findSpecLine: (splitName) ->
|
||||||
|
bestChoice = { accuracy: 0, file: null, lineNumber: null }
|
||||||
|
|
||||||
|
for file, lines of HeadlessReporterResult.specLineNumbers
|
||||||
|
index = 0
|
||||||
|
lineNumber = 0
|
||||||
|
while newLineNumberInfo = lines[splitName[index]]
|
||||||
|
if newLineNumberInfo.length == 0
|
||||||
|
lineNumber = newLineNumberInfo[0]
|
||||||
|
else
|
||||||
|
lastLine = null
|
||||||
|
for line in newLineNumberInfo
|
||||||
|
lastLine = line
|
||||||
|
break if line > lineNumber
|
||||||
|
|
||||||
|
lineNumber = lastLine
|
||||||
|
|
||||||
|
index++
|
||||||
|
|
||||||
|
if index > bestChoice.accuracy
|
||||||
|
bestChoice = { accuracy: index, file: file, lineNumber: lineNumber }
|
||||||
|
|
||||||
|
bestChoice
|
||||||
|
|
||||||
|
# The reporter itself.
|
||||||
|
class jasmine.HeadlessReporter
|
||||||
|
constructor: (@callback = null) ->
|
||||||
|
@results = []
|
||||||
|
@failedCount = 0
|
||||||
|
@length = 0
|
||||||
|
reportRunnerResults: (runner) ->
|
||||||
|
return if this.hasError()
|
||||||
|
|
||||||
|
for result in @results
|
||||||
|
result.print()
|
||||||
|
|
||||||
|
this.callback() if @callback
|
||||||
|
JHW.finishSuite((new Date() - @startTime) / 1000.0, @length, @failedCount)
|
||||||
|
|
||||||
|
reportRunnerStarting: (runner) ->
|
||||||
|
@startTime = new Date()
|
||||||
|
|
||||||
|
reportSpecResults: (spec) ->
|
||||||
|
return if this.hasError()
|
||||||
|
|
||||||
|
results = spec.results()
|
||||||
|
@length++
|
||||||
|
if results.passed()
|
||||||
|
JHW.specPassed(spec.getJHWSpecInformation())
|
||||||
|
else
|
||||||
|
JHW.specFailed(spec.getJHWSpecInformation())
|
||||||
|
@failedCount++
|
||||||
|
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
|
||||||
|
for result in results.getItems()
|
||||||
|
if result.type == 'expect' and !result.passed_
|
||||||
|
failureResult.addResult(result.message)
|
||||||
|
@results.push(failureResult)
|
||||||
|
|
||||||
|
reportSpecStarting: (spec) ->
|
||||||
|
if this.hasError()
|
||||||
|
spec.finish()
|
||||||
|
spec.suite.finish()
|
||||||
|
|
||||||
|
reportSuiteResults: (suite) ->
|
||||||
|
hasError: ->
|
||||||
|
JHW.hasError()
|
||||||
|
|
167
jasmine/jasmine.headless-reporter.js
Normal file
167
jasmine/jasmine.headless-reporter.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
(function() {
|
||||||
|
var getSplitName, pauseAndRun;
|
||||||
|
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
|
||||||
|
throw new Error("jasmine not laoded!");
|
||||||
|
}
|
||||||
|
getSplitName = function(parts) {
|
||||||
|
parts.push(String(this.description).replace(/[\n\r]/g, ' '));
|
||||||
|
return parts;
|
||||||
|
};
|
||||||
|
jasmine.Suite.prototype.getSuiteSplitName = function() {
|
||||||
|
return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
|
||||||
|
};
|
||||||
|
jasmine.Spec.prototype.getSpecSplitName = function() {
|
||||||
|
return this.getSplitName(this.suite.getSuiteSplitName());
|
||||||
|
};
|
||||||
|
jasmine.Suite.prototype.getSplitName = getSplitName;
|
||||||
|
jasmine.Spec.prototype.getSplitName = getSplitName;
|
||||||
|
jasmine.Spec.prototype.getJHWSpecInformation = function() {
|
||||||
|
var parts, specLineInfo;
|
||||||
|
parts = this.getSpecSplitName();
|
||||||
|
specLineInfo = HeadlessReporterResult.findSpecLine(parts);
|
||||||
|
if (specLineInfo.file) {
|
||||||
|
parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
|
||||||
|
} else {
|
||||||
|
parts.push('');
|
||||||
|
}
|
||||||
|
return parts.join("||");
|
||||||
|
};
|
||||||
|
if (!jasmine.WaitsBlock.prototype._execute) {
|
||||||
|
jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
|
||||||
|
jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
|
||||||
|
pauseAndRun = function(onComplete) {
|
||||||
|
JHW.timerPause();
|
||||||
|
return this._execute(function() {
|
||||||
|
JHW.timerDone();
|
||||||
|
return onComplete();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
jasmine.WaitsBlock.prototype.execute = pauseAndRun;
|
||||||
|
jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
|
||||||
|
}
|
||||||
|
window.HeadlessReporterResult = (function() {
|
||||||
|
function HeadlessReporterResult(name, splitName) {
|
||||||
|
this.name = name;
|
||||||
|
this.splitName = splitName;
|
||||||
|
this.results = [];
|
||||||
|
}
|
||||||
|
HeadlessReporterResult.prototype.addResult = function(message) {
|
||||||
|
return this.results.push(message);
|
||||||
|
};
|
||||||
|
HeadlessReporterResult.prototype.print = function() {
|
||||||
|
var bestChoice, output, result, _i, _len, _ref, _results;
|
||||||
|
output = this.name;
|
||||||
|
bestChoice = HeadlessReporterResult.findSpecLine(this.splitName);
|
||||||
|
if (bestChoice.file) {
|
||||||
|
output += " (" + bestChoice.file + ":" + bestChoice.lineNumber + ")";
|
||||||
|
}
|
||||||
|
JHW.printName(output);
|
||||||
|
_ref = this.results;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
_results.push(JHW.printResult(result));
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
};
|
||||||
|
HeadlessReporterResult.findSpecLine = function(splitName) {
|
||||||
|
var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref;
|
||||||
|
bestChoice = {
|
||||||
|
accuracy: 0,
|
||||||
|
file: null,
|
||||||
|
lineNumber: null
|
||||||
|
};
|
||||||
|
_ref = HeadlessReporterResult.specLineNumbers;
|
||||||
|
for (file in _ref) {
|
||||||
|
lines = _ref[file];
|
||||||
|
index = 0;
|
||||||
|
lineNumber = 0;
|
||||||
|
while (newLineNumberInfo = lines[splitName[index]]) {
|
||||||
|
if (newLineNumberInfo.length === 0) {
|
||||||
|
lineNumber = newLineNumberInfo[0];
|
||||||
|
} else {
|
||||||
|
lastLine = null;
|
||||||
|
for (_i = 0, _len = newLineNumberInfo.length; _i < _len; _i++) {
|
||||||
|
line = newLineNumberInfo[_i];
|
||||||
|
lastLine = line;
|
||||||
|
if (line > lineNumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lineNumber = lastLine;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (index > bestChoice.accuracy) {
|
||||||
|
bestChoice = {
|
||||||
|
accuracy: index,
|
||||||
|
file: file,
|
||||||
|
lineNumber: lineNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestChoice;
|
||||||
|
};
|
||||||
|
return HeadlessReporterResult;
|
||||||
|
})();
|
||||||
|
jasmine.HeadlessReporter = (function() {
|
||||||
|
function HeadlessReporter(callback) {
|
||||||
|
this.callback = callback != null ? callback : null;
|
||||||
|
this.results = [];
|
||||||
|
this.failedCount = 0;
|
||||||
|
this.length = 0;
|
||||||
|
}
|
||||||
|
HeadlessReporter.prototype.reportRunnerResults = function(runner) {
|
||||||
|
var result, _i, _len, _ref;
|
||||||
|
if (this.hasError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ref = this.results;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
result.print();
|
||||||
|
}
|
||||||
|
if (this.callback) {
|
||||||
|
this.callback();
|
||||||
|
}
|
||||||
|
return JHW.finishSuite((new Date() - this.startTime) / 1000.0, this.length, this.failedCount);
|
||||||
|
};
|
||||||
|
HeadlessReporter.prototype.reportRunnerStarting = function(runner) {
|
||||||
|
return this.startTime = new Date();
|
||||||
|
};
|
||||||
|
HeadlessReporter.prototype.reportSpecResults = function(spec) {
|
||||||
|
var failureResult, result, results, _i, _len, _ref;
|
||||||
|
if (this.hasError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
results = spec.results();
|
||||||
|
this.length++;
|
||||||
|
if (results.passed()) {
|
||||||
|
return JHW.specPassed(spec.getJHWSpecInformation());
|
||||||
|
} else {
|
||||||
|
JHW.specFailed(spec.getJHWSpecInformation());
|
||||||
|
this.failedCount++;
|
||||||
|
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
|
||||||
|
_ref = results.getItems();
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
if (result.type === 'expect' && !result.passed_) {
|
||||||
|
failureResult.addResult(result.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.results.push(failureResult);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HeadlessReporter.prototype.reportSpecStarting = function(spec) {
|
||||||
|
if (this.hasError()) {
|
||||||
|
spec.finish();
|
||||||
|
return spec.suite.finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HeadlessReporter.prototype.reportSuiteResults = function(suite) {};
|
||||||
|
HeadlessReporter.prototype.hasError = function() {
|
||||||
|
return JHW.hasError();
|
||||||
|
};
|
||||||
|
return HeadlessReporter;
|
||||||
|
})();
|
||||||
|
}).call(this);
|
@ -1,3 +1,22 @@
|
|||||||
require 'jasmine/headless'
|
module Jasmine
|
||||||
|
autoload :FilesList, 'jasmine/files_list'
|
||||||
|
autoload :TemplateWriter, 'jasmine/template_writer'
|
||||||
|
|
||||||
|
module Headless
|
||||||
|
autoload :CoffeeScriptCache, 'jasmine/headless/coffee_script_cache'
|
||||||
|
autoload :SpecFileAnalyzer, 'jasmine/headless/spec_file_analyzer'
|
||||||
|
autoload :CacheableAction, 'jasmine/headless/cacheable_action'
|
||||||
|
autoload :VERSION, 'jasmine/headless/version'
|
||||||
|
autoload :Runner, 'jasmine/headless/runner'
|
||||||
|
autoload :Options, 'jasmine/headless/options'
|
||||||
|
autoload :Task, 'jasmine/headless/task'
|
||||||
|
|
||||||
|
autoload :Report, 'jasmine/headless/report'
|
||||||
|
autoload :ReportMessage, 'jasmine/headless/report_message'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'jasmine/headless/errors'
|
||||||
|
|
||||||
require 'jasmine/headless/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
require 'jasmine/headless/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
||||||
|
|
||||||
|
124
lib/jasmine/files_list.rb
Normal file
124
lib/jasmine/files_list.rb
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
require 'jasmine-core'
|
||||||
|
require 'iconv'
|
||||||
|
require 'time'
|
||||||
|
|
||||||
|
module Jasmine
|
||||||
|
class FilesList
|
||||||
|
attr_reader :files, :spec_files, :filtered_files, :spec_outside_scope
|
||||||
|
|
||||||
|
DEFAULT_FILES = [
|
||||||
|
File.join(Jasmine::Core.path, "jasmine.js"),
|
||||||
|
File.join(Jasmine::Core.path, "jasmine-html.js"),
|
||||||
|
File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__),
|
||||||
|
File.expand_path('../../../js-lib/jsDump.js', __FILE__),
|
||||||
|
File.expand_path('../../../js-lib/beautify-html.js', __FILE__)
|
||||||
|
]
|
||||||
|
|
||||||
|
PLEASE_WAIT_IM_WORKING_TIME = 2
|
||||||
|
|
||||||
|
def initialize(options = {})
|
||||||
|
@options = options
|
||||||
|
@files = DEFAULT_FILES.dup
|
||||||
|
@filtered_files = @files.dup
|
||||||
|
@spec_outside_scope = false
|
||||||
|
@spec_files = []
|
||||||
|
use_config! if config?
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_spec_outside_scope?
|
||||||
|
@spec_outside_scope
|
||||||
|
end
|
||||||
|
|
||||||
|
def filtered?
|
||||||
|
files != filtered_files
|
||||||
|
end
|
||||||
|
|
||||||
|
def files_to_html
|
||||||
|
to_html(files)
|
||||||
|
end
|
||||||
|
|
||||||
|
def filtered_files_to_html
|
||||||
|
to_html(filtered_files)
|
||||||
|
end
|
||||||
|
|
||||||
|
def spec_file_line_numbers
|
||||||
|
@spec_file_line_numbers ||= Hash[@spec_files.collect { |file|
|
||||||
|
if File.exist?(file)
|
||||||
|
if !(lines = Jasmine::Headless::SpecFileAnalyzer.for(file)).empty?
|
||||||
|
[ file, lines ]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
}.compact]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def to_html(files)
|
||||||
|
alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME
|
||||||
|
|
||||||
|
files.collect { |file|
|
||||||
|
if alert_time && alert_time < Time.now
|
||||||
|
puts "Rebuilding cache, please wait..."
|
||||||
|
alert_time = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
case File.extname(file)
|
||||||
|
when '.coffee'
|
||||||
|
begin
|
||||||
|
%{<script type="text/javascript">#{Jasmine::Headless::CoffeeScriptCache.for(file)}</script>}
|
||||||
|
rescue CoffeeScript::CompilationError => ne
|
||||||
|
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), ne.message.to_s.color(:white) ]
|
||||||
|
raise ne
|
||||||
|
rescue StandardError => e
|
||||||
|
puts "[%s] Error in compiling one of the followng: %s" % [ 'coffeescript'.color(:red), files.join(' ').color(:yellow) ]
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
when '.js'
|
||||||
|
%{<script type="text/javascript" src="#{file}"></script>}
|
||||||
|
when '.css'
|
||||||
|
%{<link rel="stylesheet" href="#{file}" type="text/css" />}
|
||||||
|
end
|
||||||
|
}.flatten.compact.reject(&:empty?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def spec_filter
|
||||||
|
@spec_filter ||= (@options[:only] ? @options[:only].collect { |path| Dir[path] }.flatten : [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_config!
|
||||||
|
@filtered_files = @files.dup
|
||||||
|
|
||||||
|
data = @options[:config].dup
|
||||||
|
[ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root|
|
||||||
|
if data[searches]
|
||||||
|
data[searches].flatten.collect do |search|
|
||||||
|
path = search
|
||||||
|
path = File.join(data[root], path) if data[root]
|
||||||
|
found_files = Dir[path] - @files
|
||||||
|
|
||||||
|
@files += found_files
|
||||||
|
|
||||||
|
if searches == 'spec_files'
|
||||||
|
@spec_files += spec_filter.empty? ? found_files : (found_files & spec_filter)
|
||||||
|
end
|
||||||
|
|
||||||
|
@filtered_files += begin
|
||||||
|
if searches == 'spec_files'
|
||||||
|
@spec_outside_scope = ((spec_filter | found_files).sort != found_files.sort)
|
||||||
|
spec_filter.empty? ? found_files : (spec_filter || found_files)
|
||||||
|
else
|
||||||
|
found_files
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def config?
|
||||||
|
@options[:config]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
require 'pathname'
|
|
||||||
|
|
||||||
module Jasmine
|
|
||||||
module Headless
|
|
||||||
|
|
||||||
EXCLUDED_FORMATS = %w{less sass scss erb str}
|
|
||||||
|
|
||||||
autoload :CommandLine, 'jasmine/headless/command_line'
|
|
||||||
|
|
||||||
autoload :CoffeeScriptCache, 'jasmine/headless/coffee_script_cache'
|
|
||||||
autoload :SpecFileAnalyzer, 'jasmine/headless/spec_file_analyzer'
|
|
||||||
autoload :CacheableAction, 'jasmine/headless/cacheable_action'
|
|
||||||
autoload :VERSION, 'jasmine/headless/version'
|
|
||||||
autoload :Runner, 'jasmine/headless/runner'
|
|
||||||
autoload :Options, 'jasmine/headless/options'
|
|
||||||
autoload :Task, 'jasmine/headless/task'
|
|
||||||
|
|
||||||
autoload :FilesList, 'jasmine/headless/files_list'
|
|
||||||
autoload :UniqueAssetList, 'jasmine/headless/unique_asset_list'
|
|
||||||
|
|
||||||
autoload :TemplateWriter, 'jasmine/headless/template_writer'
|
|
||||||
|
|
||||||
autoload :FileChecker, 'jasmine/headless/file_checker'
|
|
||||||
|
|
||||||
autoload :CoffeeTemplate, 'jasmine/headless/coffee_template'
|
|
||||||
autoload :JSTemplate, 'jasmine/headless/js_template'
|
|
||||||
autoload :JSTTemplate, 'jasmine/headless/jst_template'
|
|
||||||
autoload :CSSTemplate, 'jasmine/headless/css_template'
|
|
||||||
autoload :NilTemplate, 'jasmine/headless/nil_template'
|
|
||||||
|
|
||||||
autoload :Report, 'jasmine/headless/report'
|
|
||||||
autoload :ReportMessage, 'jasmine/headless/report_message'
|
|
||||||
|
|
||||||
class << self
|
|
||||||
def root
|
|
||||||
@root ||= Pathname(File.expand_path('../../..', __FILE__))
|
|
||||||
end
|
|
||||||
|
|
||||||
def warn(message)
|
|
||||||
output.puts message if show_warnings?
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_warnings=(show)
|
|
||||||
@show_warnings = show
|
|
||||||
end
|
|
||||||
|
|
||||||
def show_warnings?
|
|
||||||
@show_warnings = true if @show_warnings.nil?
|
|
||||||
|
|
||||||
@show_warnings
|
|
||||||
end
|
|
||||||
|
|
||||||
def output
|
|
||||||
$stdout
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
require 'jasmine/headless/errors'
|
|
||||||
|
|
@ -54,19 +54,11 @@ module Jasmine::Headless
|
|||||||
end
|
end
|
||||||
|
|
||||||
def cache_file
|
def cache_file
|
||||||
@cache_file ||= File.expand_path(relative_cache_file) + '.js'
|
@cache_file ||= File.join(self.class.cache_dir, self.class.cache_type, Digest::SHA1.hexdigest(file))
|
||||||
end
|
|
||||||
|
|
||||||
def relative_cache_file
|
|
||||||
File.join(self.class.cache_dir, self.class.cache_type, file.gsub(Dir.pwd + '/', ''))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fresh?
|
def fresh?
|
||||||
cached? && (File.mtime(file) < File.mtime(cache_file))
|
File.exist?(cache_file) && (File.mtime(file) < File.mtime(cache_file))
|
||||||
end
|
|
||||||
|
|
||||||
def cached?
|
|
||||||
File.exist?(cache_file)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def action
|
def action
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
require 'tilt/template'
|
|
||||||
require 'rainbow'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class CoffeeTemplate < Tilt::Template
|
|
||||||
include Jasmine::Headless::FileChecker
|
|
||||||
|
|
||||||
self.default_mime_type = 'application/javascript'
|
|
||||||
|
|
||||||
def prepare ; end
|
|
||||||
|
|
||||||
def evaluate(scope, locals, &block)
|
|
||||||
if bad_format?(file)
|
|
||||||
alert_bad_format(file)
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
begin
|
|
||||||
cache = Jasmine::Headless::CoffeeScriptCache.new(file)
|
|
||||||
source = cache.handle
|
|
||||||
if cache.cached?
|
|
||||||
%{<script type="text/javascript" src="#{cache.cache_file}"></script>
|
|
||||||
<script type="text/javascript">window.CSTF['#{File.split(cache.cache_file).last}'] = '#{file}';</script>}
|
|
||||||
else
|
|
||||||
%{<script type="text/javascript">#{source}</script>}
|
|
||||||
end
|
|
||||||
rescue CoffeeScript::CompilationError => ne
|
|
||||||
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), "#{ne.message}".color(:white) ]
|
|
||||||
raise ne
|
|
||||||
rescue StandardError => e
|
|
||||||
puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), file.color(:yellow) ]
|
|
||||||
raise e
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
module Jasmine::Headless
|
|
||||||
class CommandLine
|
|
||||||
class << self
|
|
||||||
def run!
|
|
||||||
require 'coffee-script'
|
|
||||||
require 'rainbow'
|
|
||||||
|
|
||||||
begin
|
|
||||||
options = Options.from_command_line
|
|
||||||
runner = Runner.new(options)
|
|
||||||
|
|
||||||
if options[:do_list]
|
|
||||||
FilesList.reset!
|
|
||||||
|
|
||||||
files_list = FilesList.new(:config => runner.jasmine_config)
|
|
||||||
files_list.files.each { |file| puts file }
|
|
||||||
else
|
|
||||||
exit runner.run
|
|
||||||
end
|
|
||||||
rescue CoffeeScript::CompilationError
|
|
||||||
exit 1
|
|
||||||
rescue StandardError => e
|
|
||||||
$stderr.puts "[%s] %s (%s)" % [ "jasmine-headless-webkit".color(:red), e.message.color(:white), e.class.name.color(:yellow) ]
|
|
||||||
$stderr.puts e.backtrace.collect { |line| " #{line}" }.join("\n")
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
require 'tilt/template'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class CSSTemplate < Tilt::Template
|
|
||||||
include Jasmine::Headless::FileChecker
|
|
||||||
self.default_mime_type = 'text/css'
|
|
||||||
|
|
||||||
def prepare ; end
|
|
||||||
|
|
||||||
def evaluate(scope, locals, &block)
|
|
||||||
if bad_format?(file)
|
|
||||||
alert_bad_format(file)
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
file ? %{<link rel="stylesheet" href="#{file}" type="text/css" />} : data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
module Jasmine::Headless::FileChecker
|
|
||||||
def excluded_formats
|
|
||||||
::Jasmine::Headless::EXCLUDED_FORMATS
|
|
||||||
end
|
|
||||||
|
|
||||||
def bad_format?(file)
|
|
||||||
return if file.nil?
|
|
||||||
|
|
||||||
excluded_formats.any? do |format|
|
|
||||||
file[%r{\.#{format}(\.|$)}]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def alert_bad_format(file)
|
|
||||||
Jasmine::Headless.warn("[%s] %s: %s" % [ 'Skipping File'.color(:red), file.color(:yellow), "unsupported format".color(:white) ])
|
|
||||||
end
|
|
||||||
|
|
||||||
def alert_if_bad_format?(file)
|
|
||||||
if result = bad_format?(file)
|
|
||||||
alert_bad_format(file)
|
|
||||||
end
|
|
||||||
|
|
||||||
result
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,332 +0,0 @@
|
|||||||
require 'jasmine-core'
|
|
||||||
require 'time'
|
|
||||||
require 'multi_json'
|
|
||||||
require 'set'
|
|
||||||
require 'sprockets'
|
|
||||||
require 'sprockets/engines'
|
|
||||||
require 'sprockets-vendor_gems'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class FilesList
|
|
||||||
include FileChecker
|
|
||||||
|
|
||||||
class << self
|
|
||||||
def asset_paths
|
|
||||||
@asset_paths ||= Sprockets.find_gem_vendor_paths(:for => 'javascripts')
|
|
||||||
end
|
|
||||||
|
|
||||||
def reset!
|
|
||||||
@asset_paths = nil
|
|
||||||
@registered_engines = {}
|
|
||||||
|
|
||||||
# register haml-sprockets and handlebars_assets if it's available...
|
|
||||||
%w{haml-sprockets handlebars_assets}.each do |library|
|
|
||||||
begin
|
|
||||||
require library
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if ENV['JHW_ENV']
|
|
||||||
begin
|
|
||||||
require 'bundler'
|
|
||||||
|
|
||||||
Bundler.require(ENV['JHW_ENV'].to_sym)
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@sprockets_environment = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def registered_engines
|
|
||||||
@registered_engines ||= {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def register_engine(file_extension, template_class)
|
|
||||||
registered_engines[file_extension] = template_class
|
|
||||||
end
|
|
||||||
|
|
||||||
def register_engines!
|
|
||||||
registered_engines.each do |file_extension, template_class|
|
|
||||||
Sprockets.register_engine file_extension, template_class
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_files
|
|
||||||
%w{jasmine.js jasmine-html jasmine.css jasmine-extensions
|
|
||||||
intense headless_reporter_result jasmine.HeadlessReporter
|
|
||||||
jasmine.HeadlessReporter.ConsoleBase
|
|
||||||
jsDump beautify-html}
|
|
||||||
end
|
|
||||||
|
|
||||||
def extension_filter
|
|
||||||
extensions = (%w{.js .css} + Sprockets.engine_extensions)
|
|
||||||
|
|
||||||
%r{(#{extensions.join('|')})$}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
PLEASE_WAIT_IM_WORKING_TIME = 2
|
|
||||||
|
|
||||||
attr_reader :options, :required_files, :potential_files_to_filter
|
|
||||||
|
|
||||||
def initialize(options = {})
|
|
||||||
@options = options
|
|
||||||
|
|
||||||
Kernel.srand(options[:seed]) if options[:seed]
|
|
||||||
|
|
||||||
@required_files = UniqueAssetList.new
|
|
||||||
@potential_files_to_filter = []
|
|
||||||
|
|
||||||
register_engines!
|
|
||||||
|
|
||||||
load_initial_assets
|
|
||||||
|
|
||||||
use_config if config?
|
|
||||||
end
|
|
||||||
|
|
||||||
def register_engines!
|
|
||||||
begin
|
|
||||||
require spec_helper
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
self.class.register_engines!
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_initial_assets
|
|
||||||
self.class.default_files.each do |file|
|
|
||||||
begin
|
|
||||||
add_path(file)
|
|
||||||
rescue InvalidUniqueAsset => e
|
|
||||||
raise StandardError.new("Not an asset: #{file}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
(options[:reporters] || []).each do |reporter, identifier, file|
|
|
||||||
add_path("jasmine.HeadlessReporter.#{reporter}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def files
|
|
||||||
required_files.flatten.collect { |asset| asset.pathname.to_s }.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_files
|
|
||||||
filter_for_requested_specs(
|
|
||||||
files.find_all { |file| spec_dir.any? { |dir| file[dir] } }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered_files
|
|
||||||
filter_for_requested_specs(files)
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_paths
|
|
||||||
return @search_paths if @search_paths
|
|
||||||
|
|
||||||
@search_paths = [ Jasmine::Core.path, Jasmine::Headless.root.join('vendor/assets/javascripts').to_s ]
|
|
||||||
@search_paths += self.class.asset_paths
|
|
||||||
@search_paths += src_dir.collect { |dir| File.expand_path(dir) }
|
|
||||||
@search_paths += asset_paths.collect { |dir| File.expand_path(dir) }
|
|
||||||
@search_paths += spec_dir.collect { |dir| File.expand_path(dir) }
|
|
||||||
|
|
||||||
@search_paths.uniq!
|
|
||||||
@search_paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def sprockets_environment
|
|
||||||
return @sprockets_environment if @sprockets_environment
|
|
||||||
|
|
||||||
@sprockets_environment = Sprockets::Environment.new
|
|
||||||
search_paths.each { |path| @sprockets_environment.append_path(path) }
|
|
||||||
|
|
||||||
@sprockets_environment.unregister_postprocessor('application/javascript', Sprockets::SafetyColons)
|
|
||||||
|
|
||||||
# ...and unregister ones we don't want/need
|
|
||||||
@sprockets_environment.instance_eval do
|
|
||||||
EXCLUDED_FORMATS.each do |extension|
|
|
||||||
register_engine ".#{extension}", Jasmine::Headless::NilTemplate
|
|
||||||
end
|
|
||||||
|
|
||||||
register_engine '.coffee', Jasmine::Headless::CoffeeTemplate
|
|
||||||
register_engine '.js', Jasmine::Headless::JSTemplate
|
|
||||||
register_engine '.css', Jasmine::Headless::CSSTemplate
|
|
||||||
register_engine '.jst', Jasmine::Headless::JSTTemplate
|
|
||||||
end
|
|
||||||
|
|
||||||
@sprockets_environment
|
|
||||||
end
|
|
||||||
|
|
||||||
def has_spec_outside_scope?
|
|
||||||
if is_outside_scope = !spec_filter.empty?
|
|
||||||
is_outside_scope = spec_dir.any? do |dir|
|
|
||||||
spec_file_searches.any? do |search|
|
|
||||||
!spec_files.any? do |file|
|
|
||||||
target = File.join(dir, search)
|
|
||||||
File.fnmatch?(target, file) || File.fnmatch?(target.gsub(%{^**/}, ''), file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
is_outside_scope
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered?
|
|
||||||
files != filtered_files
|
|
||||||
end
|
|
||||||
|
|
||||||
def files_to_html
|
|
||||||
to_html(files)
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered_files_to_html
|
|
||||||
to_html(filtered_files)
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_file_line_numbers
|
|
||||||
@spec_file_line_numbers ||= Hash[spec_files.collect { |file|
|
|
||||||
if File.exist?(file)
|
|
||||||
if !(lines = Jasmine::Headless::SpecFileAnalyzer.for(file)).empty?
|
|
||||||
[ file, lines ]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
}.compact]
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def to_html(files)
|
|
||||||
alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME
|
|
||||||
|
|
||||||
files.collect do |file|
|
|
||||||
if alert_time && alert_time < Time.now
|
|
||||||
puts "Rebuilding cache, please wait..."
|
|
||||||
alert_time = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
sprockets_environment.find_asset(file, :bundle => false).body
|
|
||||||
end.compact.reject(&:empty?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_filter
|
|
||||||
@spec_filter ||= (@options[:only] && @options[:only].collect { |path| expanded_dir(path) }.flatten) || []
|
|
||||||
end
|
|
||||||
|
|
||||||
SEARCH_ROOTS = {
|
|
||||||
'src_files' => 'src_dir',
|
|
||||||
'stylesheets' => 'src_dir',
|
|
||||||
'helpers' => 'spec_dir',
|
|
||||||
'spec_files' => 'spec_dir'
|
|
||||||
}
|
|
||||||
|
|
||||||
def use_config
|
|
||||||
@config = @options[:config].dup
|
|
||||||
@searches = {}
|
|
||||||
@potential_files_to_filter = []
|
|
||||||
|
|
||||||
%w{src_files stylesheets helpers spec_files}.each do |type|
|
|
||||||
if data = @config[type]
|
|
||||||
add_files(@searches[type] = data.flatten, type, send(SEARCH_ROOTS[type]))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_files(patterns, type, dirs)
|
|
||||||
patterns.each do |pattern|
|
|
||||||
dirs.collect { |dir| expanded_dir(File.join(dir, pattern)) }.each do |files|
|
|
||||||
files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files'
|
|
||||||
|
|
||||||
files.each do |path|
|
|
||||||
add_path(path, type)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if type == 'spec_files'
|
|
||||||
spec_filter.each { |path| add_path(path, type) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def config?
|
|
||||||
@options[:config]
|
|
||||||
end
|
|
||||||
|
|
||||||
def expanded_dir(path)
|
|
||||||
file_list = Dir.glob(path).sort
|
|
||||||
file_list.find_all { |file|
|
|
||||||
file[extension_filter] && !alert_if_bad_format?(file)
|
|
||||||
}.collect {
|
|
||||||
|file| File.expand_path(file)
|
|
||||||
}.find_all {
|
|
||||||
|path| File.file?(path)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def extension_filter
|
|
||||||
self.class.extension_filter
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_path(path, type = nil)
|
|
||||||
asset = sprockets_environment.find_asset(path)
|
|
||||||
|
|
||||||
@required_files << asset
|
|
||||||
|
|
||||||
if type == 'spec_files'
|
|
||||||
@potential_files_to_filter << path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def src_dir
|
|
||||||
@src_dir ||= config_dir_or_pwd('src_dir') + asset_paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_dir
|
|
||||||
@spec_dir ||= config_dir_or_pwd('spec_dir')
|
|
||||||
end
|
|
||||||
|
|
||||||
def asset_paths
|
|
||||||
@asset_paths ||= config_dir('asset_paths')
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_file_searches
|
|
||||||
@searches['spec_files']
|
|
||||||
end
|
|
||||||
|
|
||||||
def config_dir_or_pwd(dir)
|
|
||||||
if (found = config_dir(dir)).empty?
|
|
||||||
found = [ Dir.pwd ]
|
|
||||||
end
|
|
||||||
|
|
||||||
found
|
|
||||||
end
|
|
||||||
|
|
||||||
def config_dir(dir)
|
|
||||||
[ @options[:config] && @options[:config][dir] ].flatten.compact.collect { |dir| File.expand_path(dir) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter_for_requested_specs(files)
|
|
||||||
files.find_all do |file|
|
|
||||||
if potential_files_to_filter.include?(file)
|
|
||||||
spec_filter.empty? || spec_filter.any? { |pattern| File.fnmatch?(pattern, file) }
|
|
||||||
else
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def spec_helper
|
|
||||||
File.join(spec_dir, "helpers", "spec_helper")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
extend self
|
|
||||||
|
|
||||||
def register_engine(file_extension, template_class)
|
|
||||||
Jasmine::Headless::FilesList.register_engine(file_extension, template_class)
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,23 +0,0 @@
|
|||||||
require 'tilt/template'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class JSTemplate < Tilt::Template
|
|
||||||
include Jasmine::Headless::FileChecker
|
|
||||||
self.default_mime_type = 'application/javascript'
|
|
||||||
|
|
||||||
def prepare ; end
|
|
||||||
|
|
||||||
def evaluate(scope, locals, &block)
|
|
||||||
if bad_format?(file)
|
|
||||||
alert_bad_format(file)
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
if data[%r{^<script type="text/javascript"}]
|
|
||||||
data
|
|
||||||
else
|
|
||||||
file ? %{<script type="text/javascript" src="#{file}"></script>} : data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
require 'sprockets/jst_processor'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class JSTTemplate < Sprockets::JstProcessor
|
|
||||||
include Jasmine::Headless::FileChecker
|
|
||||||
def evaluate(*args)
|
|
||||||
if bad_format?(file)
|
|
||||||
alert_bad_format(file)
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
%{<script type="text/javascript">#{super}</script>}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
|||||||
require 'tilt/template'
|
|
||||||
require 'rainbow'
|
|
||||||
|
|
||||||
module Jasmine::Headless
|
|
||||||
class NilTemplate < Tilt::Template
|
|
||||||
|
|
||||||
def prepare ; end
|
|
||||||
|
|
||||||
def evaluate(scope, locals, &block)
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -11,22 +11,16 @@ module Jasmine
|
|||||||
DEFAULT_OPTIONS = {
|
DEFAULT_OPTIONS = {
|
||||||
:colors => false,
|
:colors => false,
|
||||||
:remove_html_file => true,
|
:remove_html_file => true,
|
||||||
: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,
|
||||||
:files => [],
|
:files => []
|
||||||
:reporters => [ [ 'Console' ] ],
|
|
||||||
:quiet => false,
|
|
||||||
:use_server => false,
|
|
||||||
:server_port => nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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("~/#{DEFAULTS_FILE}")
|
||||||
|
|
||||||
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
|
||||||
@ -37,10 +31,7 @@ module Jasmine
|
|||||||
|
|
||||||
def initialize(opts = {})
|
def initialize(opts = {})
|
||||||
@options = DEFAULT_OPTIONS.dup
|
@options = DEFAULT_OPTIONS.dup
|
||||||
srand
|
|
||||||
@options[:seed] = rand(10000)
|
|
||||||
read_defaults_files
|
read_defaults_files
|
||||||
|
|
||||||
opts.each { |k, v| @options[k] = v if v }
|
opts.each { |k, v| @options[k] = v if v }
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -59,34 +50,13 @@ module Jasmine
|
|||||||
when '--keep'
|
when '--keep'
|
||||||
@options[:remove_html_file] = false
|
@options[:remove_html_file] = false
|
||||||
when '--report'
|
when '--report'
|
||||||
warn REPORT_DEPRECATED_MESSAGE
|
@options[:report] = arg
|
||||||
|
|
||||||
add_reporter('File', arg)
|
|
||||||
add_reporter('Console')
|
|
||||||
when '--runner-out'
|
|
||||||
@options[:runner_output_filename] = arg
|
|
||||||
when '--jasmine-config', '-j'
|
when '--jasmine-config', '-j'
|
||||||
@options[:jasmine_config] = arg
|
@options[:jasmine_config] = arg
|
||||||
when '--no-full-run'
|
when '--no-full-run'
|
||||||
@options[:full_run] = false
|
@options[:full_run] = false
|
||||||
when '--list', '-l'
|
when '--list', '-l'
|
||||||
@options[:do_list] = true
|
@options[:do_list] = true
|
||||||
when '--quiet', '-q'
|
|
||||||
@options[:quiet] = true
|
|
||||||
when '--seed'
|
|
||||||
@options[:seed] = arg.to_i
|
|
||||||
when '--format', '-f'
|
|
||||||
add_reporter(arg)
|
|
||||||
when '--use-server'
|
|
||||||
@options[:use_server] = true
|
|
||||||
when '--server-port'
|
|
||||||
@options[:server_port] = arg.to_i
|
|
||||||
when '--out'
|
|
||||||
add_reporter_file(arg)
|
|
||||||
when '-h', '--help'
|
|
||||||
print_help
|
|
||||||
|
|
||||||
exit
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -103,103 +73,16 @@ module Jasmine
|
|||||||
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
|
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
|
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--cache', GetoptLong::NO_ARGUMENT ],
|
[ '--cache', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--no-cache', GetoptLong::NO_ARGUMENT ],
|
[ '--no-t stcache', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--keep', GetoptLong::NO_ARGUMENT ],
|
[ '--keep', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--runner-out', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
|
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
|
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
|
||||||
[ '--no-full-run', GetoptLong::NO_ARGUMENT ],
|
[ '--no-full-run', GetoptLong::NO_ARGUMENT ],
|
||||||
[ '--list', '-l', GetoptLong::NO_ARGUMENT ],
|
[ '--list', '-l', GetoptLong::NO_ARGUMENT ]
|
||||||
[ '--seed', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '--out', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '--use-server', GetoptLong::NO_ARGUMENT ],
|
|
||||||
[ '--server-port', GetoptLong::REQUIRED_ARGUMENT ],
|
|
||||||
[ '-h', '--help', GetoptLong::NO_ARGUMENT ],
|
|
||||||
[ '-q', '--quiet', GetoptLong::NO_ARGUMENT ]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
command_line_args.each { |*args| process_option(*args) }
|
command_line_args.each { |*args| process_option(*args) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def reporters
|
|
||||||
file_index = 0
|
|
||||||
|
|
||||||
@options[:reporters].collect do |reporter, file|
|
|
||||||
output = [ reporter ]
|
|
||||||
if file
|
|
||||||
output << "report:#{file_index}"
|
|
||||||
output << file
|
|
||||||
file_index += 1
|
|
||||||
else
|
|
||||||
output << "stdout"
|
|
||||||
end
|
|
||||||
|
|
||||||
output
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def file_reporters
|
|
||||||
reporters.find_all { |reporter| reporter[1]["report:"] }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def add_reporter(name, file = nil)
|
|
||||||
if !@added_reporter
|
|
||||||
@options[:reporters] = []
|
|
||||||
@added_reporter = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if (parts = name.split(':')).length == 2
|
|
||||||
name, file = parts
|
|
||||||
end
|
|
||||||
|
|
||||||
@options[:reporters] << [ name ]
|
|
||||||
|
|
||||||
add_reporter_file(file) if file
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_reporter_file(file)
|
|
||||||
@options[:reporters].last << file
|
|
||||||
end
|
|
||||||
|
|
||||||
def print_help
|
|
||||||
options = [
|
|
||||||
[ '-c, --colors', 'Enable colors (default: disabled)' ],
|
|
||||||
[ '-nc, --no-colors', 'Disable colors' ],
|
|
||||||
[ '--cache', 'Enable cache (default: enabled)' ],
|
|
||||||
[ '--no-cache', 'Disable cache' ],
|
|
||||||
[ '--keep', 'Keep runner files on failure' ],
|
|
||||||
[ '--runner-out <filename>', 'Write runner to specified filename' ],
|
|
||||||
[ '-j, --jasmine-config <config file>', 'Jasmine Yaml config to use' ],
|
|
||||||
[ '--no-full-run', 'Do not perform a full spec run after a successful targeted spec run' ],
|
|
||||||
[ '--use-server', 'Load tests from an HTTP server instead of from filesystem' ],
|
|
||||||
[ '-l, --list', 'List files in the order they will be required' ],
|
|
||||||
[ '--seed <seed>', 'Random order seed for spec file ordering' ],
|
|
||||||
[ '-f, --format <reporter<:filename>>', 'Specify an output reporter and possibly output filename' ],
|
|
||||||
[ '--out <filename>', 'Specify output filename for last defined reporter' ],
|
|
||||||
[ '-q, --quiet', "Silence most non-test related warnings" ],
|
|
||||||
[ '-h, --help', "You're looking at it" ]
|
|
||||||
]
|
|
||||||
|
|
||||||
longest_length = options.collect(&:first).collect(&:length).max
|
|
||||||
|
|
||||||
puts <<-HELP
|
|
||||||
Usage: #{$0} [ options ] [ spec files ]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
#{options.collect { |option, description| " #{option.ljust(longest_length)} #{description}" }.join("\n")}
|
|
||||||
|
|
||||||
Available reporters:
|
|
||||||
Console Write out spec results to the console in a progress format (default)
|
|
||||||
Verbose Write out spec results to the console in a verbose format
|
|
||||||
File Write spec results in jasmine-headless-webkit ReportFile format
|
|
||||||
Tap Write spec results in TAP format
|
|
||||||
|
|
||||||
Add reporters to the jasmine.HeadlessReporter object to access them
|
|
||||||
(ex: jasmine.HeadlessReporter.Teamcity for the Teamcity reporter)
|
|
||||||
HELP
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -60,13 +60,8 @@ module Jasmine::Headless
|
|||||||
}.collect(&:filename).uniq.compact
|
}.collect(&:filename).uniq.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def seed
|
|
||||||
if seed = report.find { |entry| entry.respond_to?(:seed) }
|
|
||||||
seed.seed
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
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
|
||||||
|
@ -6,7 +6,6 @@ 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
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
module Jasmine::Headless::ReportMessage
|
module Jasmine::Headless::ReportMessage
|
||||||
class Console
|
class Console
|
||||||
def self.new_from_parts(parts)
|
class << self
|
||||||
new(parts.first)
|
def new_from_parts(parts)
|
||||||
|
new(parts.first)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :message
|
attr_reader :message
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
|||||||
module Jasmine::Headless::ReportMessage
|
module Jasmine::Headless::ReportMessage
|
||||||
class Spec
|
class Spec
|
||||||
def self.new_from_parts(parts)
|
class << self
|
||||||
file_info = parts.pop
|
def new_from_parts(parts)
|
||||||
|
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
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user