Module: Tapioca::Helpers::Test::Isolation::Subprocess

Extended by:
T::Sig
Included in:
Tapioca::Helpers::Test::Isolation
Defined in:
lib/tapioca/helpers/test/isolation.rb

Overview

@requires_ancestor: Kernel

Constant Summary collapse

ORIG_ARGV =

: Array

ARGV.dup

Instance Method Summary collapse

Instance Method Details

#run_in_isolation(&_blk) ⇒ Object

Crazy H4X to get this working in windows / jruby with no forking. : ?{ (?) -> untyped } -> String



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
# File 'lib/tapioca/helpers/test/isolation.rb', line 82

def run_in_isolation(&_blk)
  this = T.cast(self, Minitest::Test)
  require "tempfile"

  if ENV["ISOLATION_TEST"]
    yield
    test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : this.dup
    File.open(T.must(ENV["ISOLATION_OUTPUT"]), "w") do |file|
      file.puts [Marshal.dump(test_result)].pack("m")
    end
    exit!(false)
  else
    Tempfile.open("isolation") do |tmpfile|
      env = {
        "ISOLATION_TEST" => this.class.name,
        "ISOLATION_OUTPUT" => tmpfile.path,
      }

      test_opts = "-n#{this.class.name}##{this.name}"

      load_path_args = []
      $-I.each do |p|
        load_path_args << "-I"
        load_path_args << File.expand_path(p)
      end

      child = IO.popen([env, ::Gem.ruby, *load_path_args, $PROGRAM_NAME, *ORIG_ARGV, test_opts])

      begin
        Process.wait(child.pid)
      rescue Errno::ECHILD # The child process may exit before we wait
        nil
      end

      return T.must(tmpfile.read).unpack1("m")
    end
  end
end