write out two templates and execute one after the other if everything's cool

This commit is contained in:
John Bintz 2011-06-10 11:02:26 -04:00
parent c32f13fbe1
commit f7d899b0f7
16 changed files with 238 additions and 60 deletions

View File

@ -18,6 +18,7 @@ require 'rainbow'
require 'jasmine/cli' require 'jasmine/cli'
require 'jasmine/files_list' require 'jasmine/files_list'
require 'jasmine/template_writer'
include Jasmine::CLI include Jasmine::CLI
if !File.file?(File.join(gem_dir, RUNNER)) if !File.file?(File.join(gem_dir, RUNNER))
@ -67,12 +68,12 @@ files_list = Jasmine::FilesList.new(
:only => ARGV.dup :only => ARGV.dup
) )
output = jasmine_html_template(files_list.files_to_html) system jasmine_command(options, targets = Jasmine::TemplateWriter.write!(files_list))
File.open(target = "specrunner.#{$$}.html", 'w') { |fh| fh.print output }
system jasmine_command(options, target)
status = $?.exitstatus status = $?.exitstatus
FileUtils.rm_f target if options[:remove_html_file] || (status == 0)
if options[:remove_html_file] || (status == 0)
targets.each { |target| FileUtils.rm_f target }
end
exit status exit status

View File

@ -26,6 +26,7 @@
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
#include <iostream> #include <iostream>
#include <QQueue>
#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
@ -64,9 +65,10 @@ class HeadlessSpecRunner: public QObject
Q_OBJECT Q_OBJECT
public: public:
HeadlessSpecRunner(); HeadlessSpecRunner();
void load(const QString &spec);
void setColors(bool colors); void setColors(bool colors);
void reportFile(const QString &file); void reportFile(const QString &file);
void addFile(const QString &spec);
void go();
public slots: public slots:
void log(const QString &msg); void log(const QString &msg);
void specPassed(); void specPassed();
@ -78,6 +80,7 @@ private slots:
void watch(bool ok); void watch(bool ok);
void errorLog(const QString &msg, int lineNumber, const QString &sourceID); void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg); void internalLog(const QString &note, const QString &msg);
void addJHW();
protected: protected:
bool hasElement(const char *select); bool hasElement(const char *select);
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
@ -91,12 +94,14 @@ private:
bool isFinished; bool isFinished;
bool didFail; bool didFail;
bool consoleNotUsedThisRun; bool consoleNotUsedThisRun;
QQueue<QString> runnerFiles;
QString reportFilename; QString reportFilename;
void red(); void red();
void green(); void green();
void yellow(); void yellow();
void clear(); void clear();
void loadSpec();
}; };
HeadlessSpecRunner::HeadlessSpecRunner() HeadlessSpecRunner::HeadlessSpecRunner()
@ -113,14 +118,30 @@ HeadlessSpecRunner::HeadlessSpecRunner()
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool))); connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString))); connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString))); connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
} }
void HeadlessSpecRunner::load(const QString &spec) void HeadlessSpecRunner::addFile(const QString &spec)
{
runnerFiles.enqueue(spec);
}
void HeadlessSpecRunner::go()
{ {
m_ticker.stop(); m_ticker.stop();
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
m_page.mainFrame()->load(spec);
m_page.setPreferredContentsSize(QSize(1024, 600)); m_page.setPreferredContentsSize(QSize(1024, 600));
addJHW();
loadSpec();
}
void HeadlessSpecRunner::addJHW()
{
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
}
void HeadlessSpecRunner::loadSpec()
{
m_page.mainFrame()->load(runnerFiles.dequeue());
m_ticker.start(200, this);
} }
void HeadlessSpecRunner::watch(bool ok) void HeadlessSpecRunner::watch(bool ok)
@ -298,7 +319,11 @@ void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
} }
} }
QApplication::instance()->exit(exitCode); if ((exitCode == 0 && runnerFiles.count() == 0) || (exitCode != 0)) {
QApplication::instance()->exit(exitCode);
} else {
loadSpec();
}
} }
if (m_runs > 30) { if (m_runs > 30) {
@ -311,7 +336,6 @@ void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
char *filename = NULL;
char *reporter = NULL; char *reporter = NULL;
char showColors = false; char showColors = false;
@ -328,16 +352,9 @@ int main(int argc, char** argv)
} }
} }
bool filenameFound = false; if (optind == argc) {
for (index = optind; index < argc; index++) {
filename = argv[index];
filenameFound = true;
}
if (!filenameFound) {
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] SpecRunner.html" << std::endl; std::cerr << " specrunner [-c] [-r <report file>] specrunner.html ..." << std::endl;
return 1; return 1;
} }
@ -345,7 +362,12 @@ int main(int argc, char** argv)
HeadlessSpecRunner runner; HeadlessSpecRunner runner;
runner.setColors(true); runner.setColors(true);
runner.reportFile(reporter); runner.reportFile(reporter);
runner.load(QString::fromLocal8Bit(filename));
for (index = optind; index < argc; index++) {
runner.addFile(QString::fromLocal8Bit(argv[index]));
}
runner.go();
return app.exec(); return app.exec();
} }

View File

@ -30,42 +30,18 @@ module Jasmine
end end
def jasmine_html_template(files) def jasmine_html_template(files)
<<-HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<script type="text/javascript">
window.console = { log: function(data) {
JHW.log(JSON.stringify(data));
}, pp: function(data) {
JHW.log(jasmine ? jasmine.pp(data) : JSON.stringify(data));
} };
</script>
#{files.join("\n")}
</head>
<body>
<script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.HeadlessReporter());
jasmine.getEnv().execute();
</script>
</body>
</html>
HTML
end end
def runner_path def runner_path
@runner_path ||= File.join(gem_dir, RUNNER) @runner_path ||= File.join(gem_dir, RUNNER)
end end
def jasmine_command(options, target) def jasmine_command(options, targets)
[ [
runner_path, runner_path,
options[:colors] ? '-c' : nil, options[:colors] ? '-c' : nil,
options[:report] ? "-r #{options[:report]}" : nil, options[:report] ? "-r #{options[:report]}" : nil,
target *targets
].join(" ") ].join(" ")
end end

View File

@ -12,7 +12,8 @@ module Jasmine
def initialize(options = {}) def initialize(options = {})
@options = options @options = options
@files = DEFAULT_FILES @files = DEFAULT_FILES.dup
@filtered_files = @files.dup
use_config! if config? use_config! if config?
end end
@ -20,7 +21,20 @@ module Jasmine
spec_filter.empty? || spec_filter.include?(file) spec_filter.empty? || spec_filter.include?(file)
end end
def filtered?
files != filtered_files
end
def files_to_html def files_to_html
to_html(files)
end
def filtered_files_to_html
to_html(filtered_files)
end
private
def to_html(files)
files.collect { |file| files.collect { |file|
case File.extname(file) case File.extname(file)
when '.js' when '.js'
@ -40,7 +54,6 @@ module Jasmine
} }
end end
private
def spec_filter def spec_filter
@options[:only] || [] @options[:only] || []
end end

View File

@ -0,0 +1,50 @@
require 'jasmine/files_list'
module Jasmine
class TemplateWriter
class << self
def write!(files_list)
output = [
[ "specrunner.#{$$}.html", files_list.files_to_html ]
]
output.unshift([ "specrunner.#{$$}.filter.html", files_list.filtered_files_to_html ]) if files_list.filtered?
output.each do |name, files|
File.open(name, 'w') { |fh| fh.print template_for(files) }
end
output.collect(&:first)
end
private
def template_for(files)
<<-HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<script type="text/javascript">
window.console = { log: function(data) {
JHW.log(JSON.stringify(data));
}, pp: function(data) {
JHW.log(jasmine ? jasmine.pp(data) : JSON.stringify(data));
} };
</script>
#{files.join("\n")}
</head>
<body>
<script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.HeadlessReporter());
jasmine.getEnv().execute();
</script>
</body>
</html>
HTML
end
end
end
end

View File

@ -63,5 +63,29 @@ describe "jasmine-headless-webkit" do
parts[2].should == "T" parts[2].should == "T"
end end
end end
describe 'with filtered run' do
it "should fail and not run the second" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml --report #{report} ./spec/jasmine/filtered_failure/failure_spec.js}
$?.exitstatus.should == 1
parts = File.read(report).strip.split('/')
parts.length.should == 4
parts[0].should == "1"
parts[1].should == "1"
parts[2].should == "F"
end
it "should succeed and run both" do
system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js}
$?.exitstatus.should == 0
parts = File.read(report).strip.split('/')
parts.length.should == 4
parts[0].should == "2"
parts[1].should == "0"
parts[2].should == "F"
end
end
end end

View File

@ -0,0 +1,6 @@
describe('fail', function() {
it('should fail', function() {
expect(false).toEqual(true);
});
});

View File

@ -0,0 +1,10 @@
src_files:
- spec/jasmine/filtered_failure/src.js
spec_files:
- spec/jasmine/filtered_failure/*_spec.js
src_dir: .
spec_dir: .

View File

View File

@ -0,0 +1,6 @@
describe('success', function() {
it('should succeed', function() {
expect(true).toEqual(true);
});
});

View File

@ -0,0 +1,10 @@
src_files:
- spec/jasmine/filtered_success/src.js
spec_files:
- spec/jasmine/filtered_success/*_spec.js
src_dir: .
spec_dir: .

View File

View File

@ -0,0 +1,6 @@
describe('success', function() {
it('should succeed', function() {
expect(true).toEqual(true);
});
});

View File

@ -0,0 +1,6 @@
describe('also success', function() {
it('should succeed', function() {
expect(true).toEqual(true);
});
});

View File

@ -90,7 +90,7 @@ describe Jasmine::FilesList do
'spec_files' => [ '*_spec.js' ], 'spec_files' => [ '*_spec.js' ],
'spec_dir' => spec_dir 'spec_dir' => spec_dir
} } } }
before do before do
%w{one_spec.js two_spec.js}.each do |file| %w{one_spec.js two_spec.js}.each do |file|
File.open(File.join(spec_dir, file), 'w') File.open(File.join(spec_dir, file), 'w')
@ -101,6 +101,7 @@ describe Jasmine::FilesList do
it 'should return all files for files' do it 'should return all files for files' do
files_list.files.any? { |file| file['two_spec.js'] }.should be_true files_list.files.any? { |file| file['two_spec.js'] }.should be_true
files_list.filtered?.should be_true
end end
it 'should return only filtered files for filtered_files' do it 'should return only filtered files for filtered_files' do
@ -113,9 +114,14 @@ describe Jasmine::FilesList do
before do before do
files_list.instance_variable_set(:@files, [ files_list.instance_variable_set(:@files, [
'test.js', 'test.js',
'test.coffee', 'test.coffee',
'test.css' 'test.css'
])
files_list.instance_variable_set(:@filtered_files, [
'test.js',
'test.coffee'
]) ])
File.open('test.coffee', 'w') File.open('test.coffee', 'w')
@ -126,16 +132,21 @@ describe Jasmine::FilesList do
describe '#files_to_html' do describe '#files_to_html' do
it "should create the right HTML" do it "should create the right HTML" do
files_list.files_to_html.should == [ files_list.files_to_html.should == [
%{<script type="text/javascript" src="test.js"></script>}, %{<script type="text/javascript" src="test.js"></script>},
%{<script type="text/javascript">i compiled</script>}, %{<script type="text/javascript">i compiled</script>},
%{<link rel="stylesheet" href="test.css" type="text/css" />} %{<link rel="stylesheet" href="test.css" type="text/css" />}
]
end
end
describe '#filtered_files_to_html' do
it "should create the right HTML" do
files_list.filtered_files_to_html.should == [
%{<script type="text/javascript" src="test.js"></script>},
%{<script type="text/javascript">i compiled</script>}
] ]
end end
end end
end end
describe '#filtered_files_to_html' do
end
end end

View File

@ -0,0 +1,37 @@
require 'spec_helper'
require 'jasmine/template_writer'
require 'fakefs/spec_helpers'
describe Jasmine::TemplateWriter do
describe '.write!' do
include FakeFS::SpecHelpers
let(:files_list) { Jasmine::FilesList.new }
before do
files_list.files << 'file.js'
files_list.filtered_files << 'file.js'
end
context 'no filter' do
it 'should write one file' do
Jasmine::TemplateWriter.write!(files_list).should == [
"specrunner.#{$$}.html"
]
end
end
context 'filtered files' do
before do
files_list.files << 'file2.js'
end
it 'should write two files' do
Jasmine::TemplateWriter.write!(files_list).should == [
"specrunner.#{$$}.filter.html", "specrunner.#{$$}.html"
]
end
end
end
end