summaryrefslogtreecommitdiff
path: root/test/inlinetest.rb
blob: 6b9fdd1dda1bed2833afcdebf2b373a9c80f4a2f (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
module InlineTest
  def eval_part(libname, sep, part)
    path = libpath(libname)
    program = File.open(path) { |f| f.read }
    mainpart, endpart = program.split(sep)
    if endpart.nil?
      raise RuntimeError.new("No #{part} part in the library '#{filename}'")
    end
    eval(endpart, TOPLEVEL_BINDING, path, mainpart.count("\n")+1)
  end
  module_function :eval_part

  def loadtest(libname)
    require(libname)
    in_critical do
      in_progname(libpath(libname)) do
        eval_part(libname, /^(?=if\s+(?:\$0\s*==\s*__FILE__|__FILE__\s*==\s*\$0)(?:[\#\s]|$))/, '$0 == __FILE__')
      end
    end
  end
  module_function :loadtest

  def loadtest__END__part(libname)
    require(libname)
    eval_part(libname, /^__END__$/, '__END__')
  end
  module_function :loadtest__END__part

  def self.in_critical
    th_criticality = Thread.critical
    Thread.critical = true
    begin
      yield
    ensure
      Thread.critical = th_criticality
    end
  end

  def self.in_progname(progname)
    progname_backup = $0.dup
    $0.replace(progname)
    begin
      yield
    ensure
      $0.replace(progname_backup)
    end
  end

  def self.libpath(libname)
    libpath = nil
    $:.find do |path|
      File.file?(testname = File.join(path, libname)) && libpath = testname
    end
    if libpath.nil?
      raise RuntimeError.new("'#{libname}' not found")
    end
    libpath
  end
end