Class: Nestor::Mappers::Rails::Test::Unit

Inherits:
Object
  • Object
show all
Defined in:
lib/nestor/mappers/rails/test/unit.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_script_pathObject

Returns the path to the script this Mapper uses.



17
18
19
# File 'lib/nestor/mappers/rails/test/unit.rb', line 17

def self.default_script_path
  Pathname.new(File.dirname(__FILE__) + "/rails_test_unit.rb")
end

.parse_failure(failure, test_files) ⇒ String

Utility method to extract data from a Test::Unit failure.

Parameters:

  • failure (Test::Unit::Failure, Test::Unit::Error)

    The Test::Unit failure or error from which to extract information.

  • test_files (Array<String>)

    The list of files that might have generated this failure. This is used to detect the file that caused the failure.

Returns:

  • (String, String)

    Returns the filename and test name as a 2 element Array.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/nestor/mappers/rails/test/unit.rb', line 27

def self.parse_failure(failure, test_files)
  filename = if failure.respond_to?(:location) then
               failure.location.map do |loc|
                 filename = loc.split(":", 2).first
                 test_files.detect {|tf| filename.include?(tf)}
               end.compact.first
             elsif failure.respond_to?(:exception) then
               failure.exception.backtrace.map do |loc|
                 filename = loc.split(":", 2).first
                 loc = loc[1..-1] if loc[0,1] == "/"
                 test_files.detect {|tf| filename.include?(tf)}
               end.compact.first
             else
               raise "Unknown object type received as failure: #{failure.inspect} doesn't have #exception or #location methods."
             end

  test_name = failure.test_name.split("(", 2).first.strip.sub(/\.$/, "")

  [filename, test_name]
end

Instance Method Details

#log(message) ⇒ Object

Logs a message to STDOUT. This implementation forks, so the #log method also provides the PID of the logger.



50
51
52
53
# File 'lib/nestor/mappers/rails/test/unit.rb', line 50

def log(message)
  STDOUT.printf "[%d] %s - %s\n", Process.pid, Time.now.strftime("%H:%M:%S"), message
  STDOUT.flush
end

#map(path) ⇒ Array<String>?

Given a path, returns an Array of strings for the tests that should be run.

This implementation maps app/models to test/unit, app/controllers and app/views to test/functional. It is not the responsibility of #map to determine if the files actually exist on disk. The Nestor::Machine will verify the files exist before attempting to run them.

Examples:


mapper = Nestor::Mappers::Rails::Test::Unit.new
mapper.map("app/models/user.rb")
#=> ["test/unit/user_test.rb"]
mapper.map("app/helpers/users_helper.rb")
#=> ["test/unit/helpers/users_helper.rb", "test/functional/users_controller_test.rb"]

# Mapper is saying to re-run all functional tests
mapper.map("app/controller/application_controller.rb")
#=> ["test/functional/"]

# Mapper is saying to run all tests
mapper.map("config/environment.rb")
#=> []

Parameters:

  • path (String)

    A relative path to a file in the project.

Returns:

  • (Array<String>, nil)

    One or more paths the Nestor::Machine should run in response to the change. It is entirely possible and appropriate that this method return an empty array, which implies to run all tests. If a path points to a directory, this implies running all tests under that directory. Returning nil implies no tests need to run (such as when editing a README).



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/nestor/mappers/rails/test/unit.rb', line 119

def map(path)
  case path
  when %r{^app/.+/(.+_observer)\.rb$}              # Has to be first, or app/models might kick in first
    orig, plain  = $1, $1.sub("_observer", "")
    ["test/unit/#{orig}_test.rb", "test/unit/#{plain}_test.rb"]

  when "app/controllers/application_controller.rb" # Again, special cases first
    ["test/functional/"]

  when "app/helpers/application_helper.rb"         # Again, special cases first
    ["test/unit/helpers/", "test/functional/"]

  when %r{^app/models/(.+)\.rb$}, %r{^lib/(.+)\.rb$}
    ["test/unit/#{$1}_test.rb"]

  when %r{^app/controllers/(.+)\.rb$}
    ["test/functional/#{$1}_test.rb"]

  when %r{^app/views/(.+)/(.+)\.\w+$}
    ["test/functional/#{$1}_controller_test.rb"]

  when %r{^app/helpers/(.+)_helper\.rb$}
    ["test/unit/helpers/#{$1}_helper_test.rb", "test/functional/#{$1}_controller_test.rb"]

  when %r{^(?:test/test_helper.rb|config/.+\.(?:rb|ya?ml|xml)|db/schema\.rb)$}
    # Rerun all tests because something fundamental changed
    []

  when %r{^test/.+_test.rb}
    # Rerun the sole test when it's a test
    Array(path)

  else
    # I don't know how to map this, so it's probably a README or something
    nil
  end
end

#run(test_files, focuses = []) ⇒ Object

Runs only the named files, and optionally focuses on only a couple of tests within the loaded test cases.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/nestor/mappers/rails/test/unit.rb', line 74

def run(test_files, focuses=[])
  receive_results do
    log "Running #{focuses.length} focused tests"
    load_test_files(test_files)

    reset_db_connection_post_fork
    test_runner = ::Nestor::Mappers::Rails::Test::TestRunner.new(nil)
    result = ::Test::Unit::AutoRunner.run(false, nil, []) do |autorunner|
      autorunner.runner = lambda { test_runner }
      autorunner.filters << proc{|t| focuses.include?(t.method_name)} unless focuses.empty?
    end

    # Returns a Hash the parent process will retrieve
    report(test_runner, test_files)
  end
end

#run_allObject

Runs absolutely all tests as found by walking test/.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/nestor/mappers/rails/test/unit.rb', line 56

def run_all
  receive_results do
    log "Run all tests"
    test_files = load_test_files(["test"])

    reset_db_connection_post_fork
    test_runner = ::Nestor::Mappers::Rails::Test::TestRunner.new(nil)
    result = ::Test::Unit::AutoRunner.run(false, nil, []) do |autorunner|
      autorunner.runner = lambda { test_runner }
    end

    # Returns a Hash which the parent process will retrieve
    report(test_runner, test_files)
  end
end