aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/isolation_test.rb
blob: 20e11df1dde4ceaacb5d59a5bc792641082b2c14 (plain) (blame)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
require 'abstract_unit'
require 'rbconfig'

if defined?(MiniTest) || defined?(Test::Unit::TestResultFailureSupport)
  $stderr.puts "Isolation tests can test test-unit 1 only"

else
  # Does awesome
  if ENV['CHILD']
    class ChildIsolationTest < ActiveSupport::TestCase
      include ActiveSupport::Testing::Isolation

      def self.setup
        File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f|
          f.puts "hello"
        end
      end

      def setup
        @instance = "HELLO"
      end

      def teardown
        raise if @boom
      end

      test "runs the test" do
        assert true
      end

      test "captures errors" do
        raise
      end

      test "captures failures" do
        assert false
      end

      test "first runs in isolation" do
        assert_nil $x
        $x = 1
      end

      test "second runs in isolation" do
        assert_nil $x
        $x = 2
      end

      test "runs with slow tests" do
        sleep 0.3
        assert true
        sleep 0.2
      end

      test "runs setup" do
        assert "HELLO", @instance
      end

      test "runs teardown" do
        @boom = true
      end

      test "resets requires one" do
        assert !defined?(OmgOmg)
        assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size
        require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg"))
      end

      test "resets requires two" do
        assert !defined?(OmgOmg)
        assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size
        require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg"))
      end
    end
  else
    class ParentIsolationTest < ActiveSupport::TestCase

      File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {}

      ENV["CHILD"] = "1"
      OUTPUT = `#{RbConfig::CONFIG["bindir"]}/#{RbConfig::CONFIG["ruby_install_name"]} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v`
      ENV.delete("CHILD")

      def setup
        # Extract the results
        @results = {}
        OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result|
          result =~ %r'^(\w+)\(\w+\):\s*(\.|E|F)$'
          @results[$1] = { 'E' => :error, '.' => :success, 'F' => :failure }[$2]
        end

        # Extract the backtraces
        @backtraces = {}
        OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace|
          # \n  1) Error:\ntest_captures_errors(ChildIsolationTest):
          backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i
          @backtraces[$2] = { :type => $1, :output => backtrace }
        end
      end

      def assert_failing(name)
        assert_equal :failure, @results[name.to_s], "Test #{name} did not fail"
      end

      def assert_passing(name)
        assert_equal :success, @results[name.to_s], "Test #{name} did not pass"
      end

      def assert_erroring(name)
        assert_equal :error, @results[name.to_s], "Test #{name} did not error"
      end

      test "has all tests" do
        assert_equal 10, @results.length
      end

      test "passing tests are still reported" do
        assert_passing :test_runs_the_test
        assert_passing :test_runs_with_slow_tests
      end

      test "resets global variables" do
        assert_passing :test_first_runs_in_isolation
        assert_passing :test_second_runs_in_isolation
      end

      test "resets requires" do
        assert_passing :test_resets_requires_one
        assert_passing :test_resets_requires_two
      end

      test "erroring tests are still reported" do
        assert_erroring :test_captures_errors
      end

      test "runs setup and teardown methods" do
        assert_passing :test_runs_setup
        assert_erroring :test_runs_teardown
      end

      test "correct tests fail" do
        assert_failing :test_captures_failures
      end

      test "backtrace is printed for errors" do
        assert_equal 'Error', @backtraces["test_captures_errors"][:type]
        assert_match %r{isolation_test.rb:\d+:in `test_captures_errors'}, @backtraces["test_captures_errors"][:output]
      end

      test "backtrace is printed for failures" do
        assert_equal 'Failure', @backtraces["test_captures_failures"][:type]
        assert_match %r{isolation_test.rb:\d+:in `test_captures_failures'}, @backtraces["test_captures_failures"][:output]
      end

      test "self.setup is run only once" do
        text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"))
        assert_equal "hello\n", text
      end

    end
  end
end