lib/testrbl.rb in testrbl-0.5.2 vs lib/testrbl.rb in testrbl-0.6.0

- old
+ new

@@ -8,169 +8,171 @@ ] OPTION_WITH_ARGUMENT = ["-I", "-r", "-n", "-e", "--seed"] INTERPOLATION = /\\\#\\\{.*?\\\}/ - def self.run_from_cli(argv) - files, options = partition_argv(argv) - files.concat(changed_files) if options.delete("--changed") - files = files.map { |f| localize(f) } - load_options, options = partition_options(options) + class << self + def run_from_cli(argv) + files, options = partition_argv(argv) + files.concat(changed_files) if options.delete("--changed") + files = files.map { |f| localize(f) } + load_options, options = partition_options(options) - if files.size == 1 and files.first =~ /^(\S+):(\d+)$/ - file = $1 - line = $2 - run(ruby + load_options + line_pattern_option(file, line) + options) - else - if files.size == 1 and File.file?(files.first) - run(ruby + load_options + files + options) - elsif options.none? { |arg| arg =~ /^-n/ } - seed = if seed = options.index("--seed") - ["--"] + options.slice!(seed, 2) - else - [] + if files.size == 1 and files.first =~ /^(\S+):(\d+)$/ + file = $1 + line = $2 + run(ruby + load_options + line_pattern_option(file, line) + options) + else + if files.size == 1 and File.file?(files.first) + run(ruby + load_options + files + options) + elsif options.none? { |arg| arg =~ /^-n/ } + seed = if seed = options.index("--seed") + ["--"] + options.slice!(seed, 2) + else + [] + end + files = files.map { |f| File.directory?(f) ? all_test_files_in(f) : f }.flatten + run(ruby + load_options + files.map { |f| "-r#{f}" } + options + ["-e", ""] + seed) + else # pass though + # no bundle exec: projects with mini and unit-test do not run well via bundle exec testrb + run ["testrb"] + argv end - files = files.map { |f| File.directory?(f) ? all_test_files_in(f) : f }.flatten - run(ruby + load_options + files.map { |f| "-r#{f}" } + options + ["-e", ""] + seed) - else # pass though - # no bundle exec: projects with mini and unit-test do not run well via bundle exec testrb - run ["testrb"] + argv end end - end - # overwritten by maxitest to just return line - def self.line_pattern_option(file, line) - [file, "-n", "/#{pattern_from_file(File.readlines(file), line)}/"] - end + # overwritten by maxitest to just return line + def line_pattern_option(file, line) + [file, "-n", "/#{pattern_from_file(File.readlines(file), line)}/"] + end - # usable via external tools like zeus - def self.pattern_from_file(lines, line) - possible_lines = lines[0..(line.to_i-1)].reverse + # usable via external tools like zeus + def pattern_from_file(lines, line) + possible_lines = lines[0..(line.to_i-1)].reverse - found = possible_lines.map { |line| test_pattern_from_line(line) || block_start_from_line(line) }.compact + found = possible_lines.map { |line| test_pattern_from_line(line) || block_start_from_line(line) }.compact - # pattern and the groups it is nested under (like describe - describe - it) - last_spaces = " " * 100 - patterns = found.select do |spaces, name| - last_spaces = spaces if spaces.size < last_spaces.size - end.map(&:last).compact + # pattern and the groups it is nested under (like describe - describe - it) + last_spaces = " " * 100 + patterns = found.select do |spaces, name| + last_spaces = spaces if spaces.size < last_spaces.size + end.map(&:last).compact - return filter_duplicate_final(patterns).reverse.join(".*") if found.size > 0 + return filter_duplicate_final(patterns).reverse.join(".*") if found.size > 0 - raise "no test found before line #{line}" - end + raise "no test found before line #{line}" + end - # only keep 1 pattern that stops matching via $ - def self.filter_duplicate_final(patterns) - found_final = 0 - patterns.reject { |p| p.end_with?("$") and (found_final += 1) > 1 } - end + # only keep 1 pattern that stops matching via $ + def filter_duplicate_final(patterns) + found_final = 0 + patterns.reject { |p| p.end_with?("$") and (found_final += 1) > 1 } + end - private + private - def self.all_test_files_in(folder) - Dir[File.join(folder, "{**/,}*_{test,spec}.rb")].uniq - end + def all_test_files_in(folder) + Dir[File.join(folder, "{**/,}*_{test,spec}.rb")].uniq + end - def self.partition_options(options) - next_is_before = false - options.partition do |option| - if next_is_before - next_is_before = false - true - else - if option =~ /^-(r|I)/ - next_is_before = (option.size == 2) + def partition_options(options) + next_is_before = false + options.partition do |option| + if next_is_before + next_is_before = false true else - false + if option =~ /^-(r|I)/ + next_is_before = (option.size == 2) + true + else + false + end end end end - end - # fix 1.9 not being able to load local files - def self.localize(file) - file =~ /^[-a-z\d_]/ ? "./#{file}" : file - end + # fix 1.9 not being able to load local files + def localize(file) + file =~ /^[-a-z\d_]/ ? "./#{file}" : file + end - def self.partition_argv(argv) - next_is_option = false - argv.partition do |arg| - if next_is_option - next_is_option = false - else - if arg =~ /^-.$/ or arg =~ /^--/ # single letter option followed by argument like -I test or long options like --verbose - next_is_option = true if OPTION_WITH_ARGUMENT.include?(arg) - false - elsif arg =~ /^-/ # multi letter option like -Itest - false + def partition_argv(argv) + next_is_option = false + argv.partition do |arg| + if next_is_option + next_is_option = false else - true + if arg =~ /^-.$/ or arg =~ /^--/ # single letter option followed by argument like -I test or long options like --verbose + next_is_option = true if OPTION_WITH_ARGUMENT.include?(arg) + false + elsif arg =~ /^-/ # multi letter option like -Itest + false + else + true + end end end end - end - def self.changed_files - changed_files = `git status -s`.split("\n").map { |l| l.strip.split(/\s+/, 2)[1] } - raise "Failed: #{changed_files}" unless $?.success? - changed_files.select { |f| f =~ /_(test|spec)\.rb$/ && File.exist?(f) } - end + def changed_files + changed_files = `git status -s`.split("\n").map { |l| l.strip.split(/\s+/, 2)[1] } + raise "Failed: #{changed_files}" unless $?.success? + changed_files.select { |f| f =~ /_(test|spec)\.rb$/ && File.exist?(f) } + end - def self.ruby - if File.file?("Gemfile") - ["ruby", "-rbundler/setup"] # faster then bundle exec ruby - else - ["ruby"] + def ruby + if File.file?("Gemfile") + ["ruby", "-rbundler/setup"] # faster then bundle exec ruby + else + ["ruby"] + end end - end - def self.run(command) - puts command.join(" ") - STDOUT.flush # if exec fails horribly we at least see some output - Kernel.exec *command - end + def run(command) + puts command.join(" ") + STDOUT.flush # if exec fails horribly we at least see some output + Kernel.exec *command + end - def self.block_start_from_line(line) - if line =~ /^(\s*).* do( \|.*\|)?$/ - [$1, nil] + def block_start_from_line(line) + if line =~ /^(\s*).* do( \|.*\|)?$/ + [$1, nil] + end end - end - def self.test_pattern_from_line(line) - PATTERNS.each do |r| - next unless line =~ r - whitespace, method, test_name = $1, $2, $3 - return [whitespace, test_pattern_from_match(method, test_name)] + def test_pattern_from_line(line) + PATTERNS.each do |r| + next unless line =~ r + whitespace, method, test_name = $1, $2, $3 + return [whitespace, test_pattern_from_match(method, test_name)] + end + nil end - nil - end - def self.test_pattern_from_match(method, test_name) - regex = Regexp.escape(test_name).gsub("\\ "," ").gsub(INTERPOLATION, ".*") + def test_pattern_from_match(method, test_name) + regex = Regexp.escape(test_name).gsub("\\ "," ").gsub(INTERPOLATION, ".*") - regex = if method == "test" - # test "xxx -_ yyy" - # test-unit: "test: xxx -_ yyy" - # activesupport: "test_xxx_-__yyy" - "^test(: |_)#{regex.gsub(" ", ".")}$" - elsif method == "describe" || (method == "context" && !via_shoulda?) - "#{test_name}(::)?" - elsif method == "should" && via_shoulda? - optional_test_name = "(?:\(.*\))?" - "#{method} #{regex}\. #{optional_test_name}$" - elsif ["it", "should"].include?(method) # minitest aliases for shoulda - "#test_\\d+_#{test_name}$" - else - regex + regex = if method == "test" + # test "xxx -_ yyy" + # test-unit: "test: xxx -_ yyy" + # activesupport: "test_xxx_-__yyy" + "^test(: |_)#{regex.gsub(" ", ".")}$" + elsif method == "describe" || (method == "context" && !via_shoulda?) + "#{regex}(::)?" + elsif method == "should" && via_shoulda? + optional_test_name = "(?:\(.*\))?" + "#{method} #{regex}\. #{optional_test_name}$" + elsif ["it", "should"].include?(method) # minitest aliases for shoulda + "#test_\\d+_#{regex}$" + else + regex + end + + regex.gsub("'", ".") end - regex.gsub("'", ".") - end - - def self.via_shoulda? - return @via_shoulda if defined?(@via_shoulda) - @via_shoulda = !File.exist?("Gemfile.lock") || File.read("Gemfile.lock").include?(" shoulda-context ") + def via_shoulda? + return @via_shoulda if defined?(@via_shoulda) + @via_shoulda = !File.exist?("Gemfile.lock") || File.read("Gemfile.lock").include?(" shoulda-context ") + end end end