summaryrefslogtreecommitdiff
path: root/bootstraptest/runner.rb
blob: f47ecd9e6ec6acb96e83aa4d6f246f444264b21f (plain)
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
# $Id: $

# NOTE:
# Never use optparse in this file.
# Never use test/unit in this file.
# Never use Ruby extensions in this file.

require 'fileutils'

def main
  @ruby = nil
  dir = 'bootstraptest.tmpwd'
  tests = nil
  ARGV.delete_if {|arg|
    case arg
    when /\A--ruby=(.*)/
      @ruby = File.expand_path($1)
      true
    when /\A--sets=(.*)/
      tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb")
      puts tests.map {|path| File.basename(path) }.inspect
      true
    when /\A(-h|--h(elp)?)\z/
      puts(<<-End)
Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...]
    --sets=NAME,NAME,...        Name of test sets.
    --help                      Print this message and quit.
End
      exit 0
    else
      false
    end
  }
  if tests and not ARGV.empty?
    $stderr.puts "--tests and arguments are exclusive"
    exit 1
  end
  tests ||= ARGV
  tests = Dir.glob("#{File.dirname($0)}/test_*.rb") if tests.empty?
  pathes = tests.map {|path| File.expand_path(path) }
  in_temporary_working_directory(dir) {
    exec_test pathes
  }
end

def exec_test(pathes)
  @count = 0
  @error = 0
  @errbuf = []
  @location = nil
  pathes.each do |path|
    load File.expand_path(path)
  end
  $stderr.puts
  if @error == 0
    $stderr.puts "PASS #{@count} tests"
    exit 0
  else
    @errbuf.each do |msg|
      $stderr.puts msg
    end
    $stderr.puts "FAIL #{@error}/#{@count} tests failed"
    exit 1
  end
end

def assert_equal(expected, really)
  newtest
  restr = get_result_string(really)
  check_coredump
  if expected == restr
    $stderr.print '.'
  else
    $stderr.print 'F'
    error "expected #{expected.inspect} but is: #{restr.inspect}"
  end
rescue Exception => err
  $stderr.print 'E'
  error err.message
end

def get_result_string(src)
  if @ruby
    File.open('bootstraptest.tmp.rb', 'w') {|f|
      f.puts "print(begin; #{src}; end)"
    }
    `#{@ruby} bootstraptest.tmp.rb`
  else
    eval(src).to_s
  end
end

def newtest
  @location = File.basename(caller(2).first)
  @count += 1
  cleanup_coredump
end

def error(msg)
  @errbuf.push "\##{@count} #{@location}: #{msg}"
  @error += 1
end

def in_temporary_working_directory(dir)
  FileUtils.rm_rf dir
  Dir.mkdir dir
  Dir.chdir(dir) {
    yield
  }
end

def cleanup_coredump
  FileUtils.rm_f 'core'
  Dir.glob('core.*').each do |ent|
    FileUtils.rm_f ent
  end
end

class CoreDumpError < StandardError; end

def check_coredump
  if File.file?('core') or not Dir.glob('core.*').empty?
    raise CoreDumpError, "core dumped"
  end
end

main