From cdff35c0e21f0bf2189405678b54e37f1d46d43a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Thu, 16 Jun 2011 09:51:49 -0400 Subject: [PATCH] break out running from bin --- bin/jasmine-headless-webkit | 77 +---------------------- lib/jasmine/cli.rb | 54 ---------------- lib/jasmine/headless/cli.rb | 17 +++++ lib/jasmine/headless/errors.rb | 7 +++ lib/jasmine/headless/options.rb | 75 ++++++++++++++++++++++ lib/jasmine/headless/runner.rb | 72 +++++++++++++++++++++ spec/bin/jasmine-headless-webkit_spec.rb | 42 +++---------- spec/lib/jasmine/cli_spec.rb | 61 ------------------ spec/lib/jasmine/headless/cli_spec.rb | 1 + spec/lib/jasmine/headless/options_spec.rb | 59 +++++++++++++++++ spec/lib/jasmine/headless/runner_spec.rb | 63 +++++++++++++++++++ spec/spec_helper.rb | 10 +++ 12 files changed, 313 insertions(+), 225 deletions(-) delete mode 100644 lib/jasmine/cli.rb create mode 100644 lib/jasmine/headless/cli.rb create mode 100644 lib/jasmine/headless/errors.rb create mode 100644 lib/jasmine/headless/options.rb create mode 100644 lib/jasmine/headless/runner.rb delete mode 100644 spec/lib/jasmine/cli_spec.rb create mode 100644 spec/lib/jasmine/headless/cli_spec.rb create mode 100644 spec/lib/jasmine/headless/options_spec.rb create mode 100644 spec/lib/jasmine/headless/runner_spec.rb diff --git a/bin/jasmine-headless-webkit b/bin/jasmine-headless-webkit index 1bb7d69..496a76f 100755 --- a/bin/jasmine-headless-webkit +++ b/bin/jasmine-headless-webkit @@ -8,81 +8,8 @@ end $:.unshift(File.join(gem_dir, 'lib')) -require 'benchmark' -require 'yaml' -require 'fileutils' -require 'getoptlong' - -require 'jasmine/base' -require 'coffee-script' -require 'rainbow' - -require 'jasmine/cli' -require 'jasmine/files_list' -require 'jasmine/template_writer' -include Jasmine::CLI - -if !File.file?(File.join(gem_dir, RUNNER)) - puts "The Qt WebKit widget is not compiled! Try re-installing this gem." - exit 1 -end - -opts = GetoptLong.new( - [ '--colors', '-c', GetoptLong::NO_ARGUMENT ], - [ '--no-colors', GetoptLong::NO_ARGUMENT ], - [ '--keep', GetoptLong::NO_ARGUMENT ], - [ '--report', GetoptLong::REQUIRED_ARGUMENT ], - [ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ], - [ '--no-full-run', GetoptLong::NO_ARGUMENT ] -) - -options = { - :colors => false, - :remove_html_file => true, - :jasmine_config => 'spec/javascripts/support/jasmine.yml', - :report => false, - :full_run => true -} - -@process_options = lambda { |*args| - opt, arg = args.flatten[0..1] - - case opt - when '--colors', '-c' - options[:colors] = true - when '--no-colors', '-nc' - options[:colors] = false - when '--keep' - options[:remove_html_file] = false - when '--report' - options[:report] = arg - when '--jasmine-config', '-j' - options[:jasmine_config] = arg - when '--no-full-run' - options[:full_run] = false - end -} - -read_defaults_files! -opts.each(&@process_options) - puts "Running Jasmine specs..." -files_list = Jasmine::FilesList.new( - :config => load_config(options[:jasmine_config]), - :only => ARGV.dup -) - -targets = Jasmine::TemplateWriter.write!(files_list) -run_targets = targets.dup -run_targets.pop if !options[:full_run] - -system jasmine_command(options, run_targets) -status = $?.exitstatus - -if options[:remove_html_file] || (status == 0) - targets.each { |target| FileUtils.rm_f target } -end - -exit status +require 'jasmine/headless/cli' +exit Jasmine::Headless::CLI.run diff --git a/lib/jasmine/cli.rb b/lib/jasmine/cli.rb deleted file mode 100644 index 4b80429..0000000 --- a/lib/jasmine/cli.rb +++ /dev/null @@ -1,54 +0,0 @@ -module Jasmine - module CLI - DEFAULTS = { - 'spec_files' => [ '**/*[sS]pec.js' ], - 'helpers' => [ 'helpers/**/*.js' ], - 'spec_dir' => 'spec/javascripts', - 'src_dir' => nil, - 'stylesheets' => [], - 'src_files' => [] - } - - RUNNER = 'ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner' - DEFAULTS_FILE = '.jasmine-headless-webkit' - GLOBAL_DEFAULTS_FILE = File.expand_path("~/#{DEFAULTS_FILE}") - - def load_config(file) - process_jasmine_config(YAML.load_file(file)) - end - - def process_jasmine_config(overrides = {}) - DEFAULTS.merge(overrides) - end - - def read_defaults_files! - [ GLOBAL_DEFAULTS_FILE, DEFAULTS_FILE ].each do |file| - if File.file?(file) - File.readlines(file).collect { |line| line.strip.split(' ', 2) }.each(&@process_options) - end - end - end - - def jasmine_html_template(files) - end - - def runner_path - @runner_path ||= File.join(gem_dir, RUNNER) - end - - def jasmine_command(options, targets) - [ - runner_path, - options[:colors] ? '-c' : nil, - options[:report] ? "-r #{options[:report]}" : nil, - *targets - ].join(" ") - end - - private - def read_config_file(file) - - end - end -end - diff --git a/lib/jasmine/headless/cli.rb b/lib/jasmine/headless/cli.rb new file mode 100644 index 0000000..252b323 --- /dev/null +++ b/lib/jasmine/headless/cli.rb @@ -0,0 +1,17 @@ +require 'jasmine/headless/runner' +require 'jasmine/headless/options' +require 'getoptlong' + +module Jasmine + module Headless + class CLI + def self.run + Runner.run(Options.from_command_line) + rescue NoRunnerError + puts "The Qt WebKit widget is not compiled! Try re-installing this gem." + 1 + end + end + end +end + diff --git a/lib/jasmine/headless/errors.rb b/lib/jasmine/headless/errors.rb new file mode 100644 index 0000000..8f6edb7 --- /dev/null +++ b/lib/jasmine/headless/errors.rb @@ -0,0 +1,7 @@ +module Jasmine + module Headless + class NoRunnerError < StandardError + end + end +end + diff --git a/lib/jasmine/headless/options.rb b/lib/jasmine/headless/options.rb new file mode 100644 index 0000000..a6a9f90 --- /dev/null +++ b/lib/jasmine/headless/options.rb @@ -0,0 +1,75 @@ +require 'forwardable' + +module Jasmine + module Headless + class Options + extend Forwardable + + def_delegators :@options, :[], :[]= + + DEFAULT_OPTIONS = { + :colors => false, + :remove_html_file => true, + :jasmine_config => 'spec/javascripts/support/jasmine.yml', + :report => false, + :full_run => true, + :files => [] + } + + DEFAULTS_FILE = '.jasmine-headless-webkit' + GLOBAL_DEFAULTS_FILE = File.expand_path("~/#{DEFAULTS_FILE}") + + def self.from_command_line + options = new + options.process_command_line_args + options[:files] = ARGV + options + end + + def initialize(opts = {}) + @options = DEFAULT_OPTIONS.dup.merge(opts) + end + + def process_option(*args) + opt, arg = args.flatten[0..1] + + case opt + when '--colors', '-c' + @options[:colors] = true + when '--no-colors', '-nc' + @options[:colors] = false + when '--keep' + @options[:remove_html_file] = false + when '--report' + @options[:report] = arg + when '--jasmine-config', '-j' + @options[:jasmine_config] = arg + when '--no-full-run' + @options[:full_run] = false + end + end + + def read_defaults_files + [ GLOBAL_DEFAULTS_FILE, DEFAULTS_FILE ].each do |file| + if File.file?(file) + File.readlines(file).collect { |line| line.strip.split(' ', 2) }.each { |*args| process_option(*args) } + end + end + end + + def process_command_line_args + command_line_args = GetoptLong.new( + [ '--colors', '-c', GetoptLong::NO_ARGUMENT ], + [ '--no-colors', GetoptLong::NO_ARGUMENT ], + [ '--keep', GetoptLong::NO_ARGUMENT ], + [ '--report', GetoptLong::REQUIRED_ARGUMENT ], + [ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ], + [ '--no-full-run', GetoptLong::NO_ARGUMENT ] + ) + + command_line_args.each { |*args| process_option(*args) } + end + end + end +end + diff --git a/lib/jasmine/headless/runner.rb b/lib/jasmine/headless/runner.rb new file mode 100644 index 0000000..a571597 --- /dev/null +++ b/lib/jasmine/headless/runner.rb @@ -0,0 +1,72 @@ +require 'jasmine/headless/errors' +require 'jasmine/headless/options' + +require 'fileutils' + +require 'jasmine/base' +require 'coffee-script' +require 'rainbow' + +require 'jasmine/files_list' +require 'jasmine/template_writer' + +module Jasmine + module Headless + class Runner + JASMINE_DEFAULTS = { + 'spec_files' => [ '**/*[sS]pec.js' ], + 'helpers' => [ 'helpers/**/*.js' ], + 'spec_dir' => 'spec/javascripts', + 'src_dir' => nil, + 'stylesheets' => [], + 'src_files' => [] + } + + RUNNER = File.expand_path('../../../../ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner', __FILE__) + + def self.run(options = DEFAULT_OPTIONS.dup) + new(options).run + end + + def initialize(options) + raise NoRunnerError if !File.file?(RUNNER) + + @options = options + end + + def jasmine_config + @jasmine_config ||= JASMINE_DEFAULTS.dup.merge(YAML.load_file(@options[:jasmine_config])) + end + + def jasmine_command(*targets) + [ + RUNNER, + @options[:colors] ? '-c' : nil, + @options[:report] ? "-r #{@options[:report]}" : nil, + *targets + ].compact.join(" ") + end + + def run + files_list = Jasmine::FilesList.new( + :config => jasmine_config, + :only => @options[:files] + ) + + targets = Jasmine::TemplateWriter.write!(files_list) + run_targets = targets.dup + run_targets.pop if !@options[:full_run] && files_list.filtered? + + system jasmine_command(run_targets) + status = $?.exitstatus + + if @options[:remove_html_file] || (status == 0) + targets.each { |target| FileUtils.rm_f target } + end + + status + end + end + end +end + diff --git a/spec/bin/jasmine-headless-webkit_spec.rb b/spec/bin/jasmine-headless-webkit_spec.rb index b2ff9a5..8d00b77 100644 --- a/spec/bin/jasmine-headless-webkit_spec.rb +++ b/spec/bin/jasmine-headless-webkit_spec.rb @@ -16,11 +16,7 @@ describe "jasmine-headless-webkit" do system %{bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report #{report}} $?.exitstatus.should == 0 - parts = File.read(report).strip.split('/') - parts.length.should == 4 - parts[0].should == "1" - parts[1].should == "0" - parts[2].should == "F" + report.should be_a_report_containing(1, 0, false) end end @@ -30,11 +26,7 @@ describe "jasmine-headless-webkit" do system %{bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml --report #{report}} $?.exitstatus.should == 1 - parts = File.read(report).strip.split('/') - parts.length.should == 4 - parts[0].should == "1" - parts[1].should == "0" - parts[2].should == "F" + report.should be_a_report_containing(1, 0, false) end end @@ -43,11 +35,7 @@ describe "jasmine-headless-webkit" do system %{bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml --report #{report}} $?.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" + report.should be_a_report_containing(1, 1, false) end end @@ -56,11 +44,7 @@ describe "jasmine-headless-webkit" do system %{bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml --report #{report}} $?.exitstatus.should == 2 - parts = File.read(report).strip.split('/') - parts.length.should == 4 - parts[0].should == "1" - parts[1].should == "0" - parts[2].should == "T" + report.should be_a_report_containing(1, 0, true) end end @@ -79,11 +63,7 @@ describe "jasmine-headless-webkit" do system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --no-full-run --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js} $?.exitstatus.should == 0 - parts = File.read(report).strip.split('/') - parts.length.should == 4 - parts[0].should == "1" - parts[1].should == "0" - parts[2].should == "F" + report.should be_a_report_containing(1, 0, false) end end @@ -92,22 +72,14 @@ describe "jasmine-headless-webkit" 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" + report.should be_a_report_containing(1, 1, false) end it "should succeed and run both" do system %{bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml --report #{report} ./spec/jasmine/filtered_success/success_one_spec.js} $?.exitstatus.should == 0 - parts = File.read(report).strip.split('/') - parts.length.should == 4 - parts[0].should == "2" - parts[1].should == "0" - parts[2].should == "F" + report.should be_a_report_containing(2, 0, false) end end end diff --git a/spec/lib/jasmine/cli_spec.rb b/spec/lib/jasmine/cli_spec.rb deleted file mode 100644 index 8759092..0000000 --- a/spec/lib/jasmine/cli_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' -require 'jasmine/cli' -require 'fakefs/spec_helpers' - -describe Jasmine::CLI do - include Jasmine::CLI - include FakeFS::SpecHelpers - - describe '#process_jasmine_config' do - context 'without overrides' do - let(:config) { {} } - - it "should just return the defaults" do - process_jasmine_config(config).should == { - 'src_files' => [], - 'stylesheets' => [], - 'helpers' => [ 'helpers/**/*.js' ], - 'spec_files' => [ '**/*[sS]pec.js' ], - 'src_dir' => nil, - 'spec_dir' => 'spec/javascripts' - } - end - end - - context 'with overrides' do - let(:config) { - { - 'src_files' => [ 'one', 'two' ], - 'src_dir' => 'this-dir', - 'stylesheets' => [ 'three', 'four' ], - 'helpers' => [ 'five', 'six' ], - 'spec_files' => [ 'seven', 'eight' ], - 'spec_dir' => 'that-dir' - } - } - - it "should return the merged data" do - process_jasmine_config(config).should == config - end - end - end - - describe '#read_defaults_file' do - let(:global_test_data) { %w{first second} } - let(:test_data) { %w{third fourth} } - - before do - File.open(Jasmine::CLI::GLOBAL_DEFAULTS_FILE, 'w') { |fh| fh.puts global_test_data.join(' ') } - File.open(Jasmine::CLI::DEFAULTS_FILE, 'w') { |fh| fh.puts test_data.join(' ') } - end - - it "should read the options" do - all_data = [] - @process_options = lambda { |*args| all_data << args.flatten } - - read_defaults_files! - - all_data.should == [ global_test_data, test_data ] - end - end -end diff --git a/spec/lib/jasmine/headless/cli_spec.rb b/spec/lib/jasmine/headless/cli_spec.rb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/spec/lib/jasmine/headless/cli_spec.rb @@ -0,0 +1 @@ + diff --git a/spec/lib/jasmine/headless/options_spec.rb b/spec/lib/jasmine/headless/options_spec.rb new file mode 100644 index 0000000..f85b873 --- /dev/null +++ b/spec/lib/jasmine/headless/options_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' +require 'jasmine/headless/options' +require 'fakefs/spec_helpers' + +describe Jasmine::Headless::Options do + let(:options) { Jasmine::Headless::Options.new(opts) } + let(:opts) { {} } + + describe '#initialize' do + context 'empty' do + it "should have default options" do + options[:jasmine_config].should == 'spec/javascripts/support/jasmine.yml' + end + end + + context 'with provided' do + let(:opts) { { :jasmine_config => 'test' } } + + it 'should override an option' do + options[:jasmine_config].should == 'test' + end + end + end + + describe '#process_option' do + it 'should process the option and update the object in place' do + options[:colors].should be_false + options[:jasmine_config].should == 'spec/javascripts/support/jasmine.yml' + + options.process_option('--colors') + options.process_option('-j', 'test') + + options[:colors].should be_true + options[:jasmine_config].should == 'test' + end + end + + describe '#read_defaults_files' do + include FakeFS::SpecHelpers + + let(:global_test_data) { '--colors' } + let(:test_data) { '-j test' } + + before do + File.open(Jasmine::Headless::Options::GLOBAL_DEFAULTS_FILE, 'w') { |fh| fh.puts global_test_data } + File.open(Jasmine::Headless::Options::DEFAULTS_FILE, 'w') { |fh| fh.puts test_data } + end + + it "should read the options" do + options[:colors].should be_false + options[:jasmine_config].should == 'spec/javascripts/support/jasmine.yml' + + options.read_defaults_files + + options[:colors].should be_true + options[:jasmine_config].should == 'test' + end + end +end diff --git a/spec/lib/jasmine/headless/runner_spec.rb b/spec/lib/jasmine/headless/runner_spec.rb new file mode 100644 index 0000000..1b62747 --- /dev/null +++ b/spec/lib/jasmine/headless/runner_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper' +require 'fakefs/spec_helpers' +require 'jasmine/headless/runner' + +describe Jasmine::Headless::Runner do + let(:runner) { Jasmine::Headless::Runner.new(options) } + let(:options) { Jasmine::Headless::Options.new(opts) } + + describe '#load_config' do + include FakeFS::SpecHelpers + + let(:opts) { { :jasmine_config => 'test.yml' } } + + before do + File.open(Jasmine::Headless::Runner::RUNNER, 'w') + File.open('test.yml', 'w') { |fh| fh.print YAML.dump('test' => 'hello') } + end + + it 'should load the jasmine config' do + runner.jasmine_config['test'].should == 'hello' + runner.jasmine_config['spec_dir'].should == 'spec/javascripts' + end + end + + describe '#jasmine_command' do + let(:opts) { { + :colors => true, + :report => 'test' + } } + + it 'should have the right options' do + runner.jasmine_command.should match(/jasmine-webkit-specrunner/) + runner.jasmine_command.should match(/-c/) + runner.jasmine_command.should match(/-r test/) + runner.jasmine_command('file.js').should match(/file.js/) + end + end + + context 'real tests' do + let(:report) { 'spec/report.txt' } + + before do + FileUtils.rm_f report + end + + after do + FileUtils.rm_f report + end + + it 'should succeed with error code 0' do + Jasmine::Headless::Runner.run( + :jasmine_config => 'spec/jasmine/success/success.yml', + :report => report + ).should == 0 + + report.should be_a_report_containing(1, 0, false) + end + + it 'should succeed but with javascript error' do + Jasmine::Headless::Runner.run(:jasmine_config => 'spec/jasmine/success_with_error/success_with_error.yml').should == 1 + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 61648e4..1a239b3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -10,3 +10,13 @@ if !File.file?(specrunner) end end +RSpec::Matchers.define :be_a_report_containing do |total, fails, used_console| + match do |filename| + parts = File.read(filename).strip.split('/') + parts.length.should == 4 + parts[0].should == total.to_s + parts[1].should == fails.to_s + parts[2].should == (used_console ? "T" : "F") + true + end +end