1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
require 'autotest'
require 'tempfile'
require 'cucumber'
require 'cucumber/cli/profile_loader'
module Autotest::CucumberMixin
def self.included(receiver)
receiver::ALL_HOOKS << [:run_features, :ran_features]
end
attr_accessor :features_to_run
def initialize
super
reset_features
end
def run
hook :initialize
reset
reset_features
add_sigint_handler
self.last_mtime = Time.now if $f
loop do # ^c handler
begin
get_to_green
if self.tainted then
rerun_all_tests
rerun_all_features if all_good
else
hook :all_good
end
wait_for_changes
# Once tests and features are green, reset features every
# time a file is changed to see if anything breaks.
reset_features
rescue Interrupt
break if self.wants_to_quit
reset
reset_features
end
end
hook :quit
end
def all_features_good
features_to_run == ""
end
def get_to_green
begin
super
run_features
wait_for_changes unless all_features_good
end until all_features_good
end
def rerun_all_features
reset_features
run_features
end
def reset_features
self.features_to_run = :all
end
def run_features
hook :run_features
Tempfile.open('autotest-cucumber') do |dirty_features_file|
cmd = self.make_cucumber_cmd(self.features_to_run, dirty_features_file.path)
return if cmd.empty?
puts cmd unless $q
old_sync = $stdout.sync
$stdout.sync = true
self.results = []
line = []
begin
open("| #{cmd}", "r") do |f|
until f.eof? do
c = f.getc or break
if RUBY_VERSION >= "1.9" then
print c
else
putc c
end
line << c
if c == ?\n then
self.results << if RUBY_VERSION >= "1.9" then
line.join
else
line.pack "c*"
end
line.clear
end
end
end
ensure
$stdout.sync = old_sync
end
self.features_to_run = dirty_features_file.read.strip
self.tainted = true unless self.features_to_run == ''
end
hook :ran_features
end
def make_cucumber_cmd(features_to_run, dirty_features_filename)
return '' if features_to_run == ''
profile_loader = Cucumber::Cli::ProfileLoader.new
profile ||= "autotest-all" if profile_loader.has_profile?("autotest-all") && features_to_run == :all
profile ||= "autotest" if profile_loader.has_profile?("autotest")
profile ||= nil
if profile
args = ["--profile", profile]
else
args = %w{--format} << (features_to_run == :all ? "progress" : "pretty")
end
# No --color option as some IDEs (Netbeans) don't output them very well ([31m1 failed step[0m)
args += %w{--format rerun --out} << dirty_features_filename
args << (features_to_run == :all ? "" : features_to_run)
# Unless I do this, all the steps turn up undefined during the rerun...
unless features_to_run == :all
args << 'features/step_definitions' << 'features/support'
end
args = args.join(' ')
return "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} #{args}"
end
end
|