1 #### Common functionality for running tests.
3 # Make sure that the lib directory is in $LOAD_PATH
4 $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
9 $errors_mutex = Mutex.new
13 # +reason+ Should be a short message describing the reason for failure.
14 # +stderr+ If not empty, this text is written to standard error.
15 def fail_test reason, stderr = ''
17 puts "FAIL: #{reason}"
26 # Atomically increment $errors
28 $errors_mutex.synchronize { $errors = $errors + 1 }
38 # Runs block and verifies that it returns the given value.
39 # If it doesn't, prints an error message and increments $errors.
40 def expect name, value, &block
47 fail_test "expected #{value.inspect}, but got #{result.inspect}"
50 fail_test "Unexpected #{e.class}\n#{e.message}"
54 # Runs block and verifies that it returns true.
55 # If it doesn't, prints an error message and increments $errors.
56 def expect_true name, &block
57 expect name, true, &block
60 # Runs block and verifies that it throws an exception of type
61 # +exception_type+. If the block doesn't throw such an exception,
62 # prints an error message and increments $errors.
63 def expect_exception name, exception_type, &block
67 fail_test "Expected exception of type #{exception_type}," +
68 " but no exception was raised"
70 if e.kind_of? exception_type
73 fail_test "Expected #{exception_type}, but got #{e.class}"
78 $RUBY = ENV['RUBY'] || 'ruby'
79 $VOODOOC = 'env RUBYLIB=../lib ../bin/voodooc'
81 # Runs a command with exec.
82 # With no block given, returns
83 # [status, stdin, stdout, stderr]
84 # With block given, passes
85 # status, stdin, stdout, stderr to block
87 pw = IO::pipe # pipe[0] for read, pipe[1] for write
112 dummy, status = Process.wait2 pid
113 result = [status, pw[1], pr[0], pe[0]]
117 return yield(*result)
119 [pw[1], pr[0], pe[0]].each { |p| p.close unless p.closed? }
125 def add_test program, command, expected_output = '', params = {}
126 $tests << [program, command, expected_output, params]
129 def run_test program, command, expected_output = '', params = {}
130 input = params.has_key?(:input) ? params[:input] : nil
131 expected_status = params.has_key?(:expected_status) ?
132 params[:expected_status] : 0
133 expected_errors = params.has_key?(:expected_errors) ?
134 params[:expected_errors] : ''
136 message = "#{program}..."
137 status, stdin, stdout, stderr = popen4 command
141 exitstatus = status.exitstatus
143 err_output = stderr.read
144 if exitstatus != expected_status
145 message << "FAIL: exit status is #{exitstatus}, expected #{expected_status}"
147 elsif output != expected_output
148 message << "FAIL: wrong output"
150 elsif err_output != expected_errors
151 message << "FAIL: wrong error output"
152 $stderr.puts "--- ERRORS ---\n#{err_output}\n--- EXPECTED ---\n#{expected_errors}\n--- END ERRORS ---"
160 def add_test2 program, expected_output
161 add_test program, "./#{program}", expected_output
164 def add_test1 program
165 add_test2 program, `cat #{program}.out`
168 # Reports tests results.
169 # Returns 0 if all tests passed, 1 if some failed.
170 def report_test_results
172 puts "All tests passed"
175 puts "#{$errors} tests failed"
180 # Runs all tests in the given queue.
181 # Each test is described by a list
182 # [name, command, expected_output, params].
183 # Those parameters are passed to run_test.
184 def run_tests queue, nthreads = 1
187 threads << Thread.new do
189 name, command, output, params = queue.pop
190 run_test name, command, output, params
194 threads.each { |t| t.join }