lib/tasks/tests.rake in newrelic_rpm-9.5.0 vs lib/tasks/tests.rake in newrelic_rpm-9.6.0

- old
+ new

@@ -9,18 +9,89 @@ require 'rake/testtask' rescue LoadError end if defined? Rake::TestTask + def name_for_number(content, number) + (number - 1).downto(0).each do |i| + return Regexp.last_match(1) if content[i] =~ /^\s*def (test_.+)\s*$/ + end + end + + def info_from_test_var + return {} unless ENV['TEST'].to_s =~ /^(.+)((?::\d+)+)/ + + file = Regexp.last_match(1) + numbers = Regexp.last_match(2).split(':').reject(&:empty?).uniq.map(&:to_i) + abs = File.expand_path(File.join('../../..', file), __FILE__) + raise "File >>#{abs}<< does not exist!" unless File.exist?(abs) + + content = File.read(abs).split("\n") + {file: file, numbers: numbers, content: content} + end + + def test_names_from_test_file(info) + info[:numbers].each_with_object([]) do |number, names| + name = name_for_number(info[:content], number) + unless name + warn "Unable to determine a test name given line >>#{number}<< for file >>#{info[:file]}<<" + next + end + names << name + end + end + + # Allow ENV['TEST'] to be set to a test file path with one or more + # `:<line number>` patterns on the end of it. + # + # For example: + # TEST=test/new_relic/agent/autostart_test.rb:57 bundle exec rake test + # + # The `autostart_test.rb` file will be read, and starting from line 57 and + # working upwards in the file (downwards by line number), a test definition + # will be searched for that matches `def test_<rest of the test name>`. + # + # Multiple line numbers can be specified like so: + # TEST=test/new_relic/agent/autostart_test.rb:57:26 bundle exec rake test + # + # For this multiple line number based example, both lines 57 and 26 will + # serve as separate starting points for the search for a test name. + # + # All test names that are discovered will be "ORed" into a regex pattern with + # pipes ('|') that is passed to Minitest via + # `TESTOPTS="--name='test_name1|test_name2'"` + # + # Once a line with one or more `:<line number>` values on the end of it has + # been found, replace the value of ENV['TEST'] with the path leading up to + # the first colon before invoking Minitest. + # + # Why refer to a test by line number instead of just supplying the name + # directly? The primary use case is text editor integration. A text editor + # can be taught to "run the single unit test containing the line the cursor is + # on" by building a string containing the path to the file, a colon, (':'), + # and the line number. + def process_line_numbers + info = info_from_test_var + return unless info.key?(:file) + + test_names = test_names_from_test_file(info) + raise "Could not determine any test names for file >>#{abs}<< given numbers >>#{numbers}" if test_names.empty? + + ENV['TESTOPTS'] = "#{ENV['TESTOPTS']} --name='#{test_names.map { |n| Regexp.escape(n) }.join('|')}'" + ENV['TEST'] = info[:file] + end + namespace :test do tasks = Rake.application.top_level_tasks ENV['TESTOPTS'] ||= '' if tasks.any? { |t| t.include?('verbose') } ENV['TESTOPTS'] += ' -v' end if seed = look_for_seed(tasks) ENV['TESTOPTS'] += ' --' + seed end + + process_line_numbers agent_home = File.expand_path(File.join(File.dirname(__FILE__), '..', '..')) Rake::TestTask.new(:newrelic) do |t| file_pattern = ENV['file']