# These tests start a real server and talk to it over TCP so we can # isolate the effects of require "angelo/main" in a separate process # but still test them. # # See test/main/app.rb for the code of the app we test against. require_relative '../spec_helper' class MainSpec < Minitest::Spec # Info for starting the server. app_file = File.expand_path("../app.rb", __FILE__) address = "127.0.0.1" port = 14410 server_command = "#{RbConfig.ruby} #{app_file} -o #{address} -p #{port}" # Start the server. pid = spawn server_command, out: "/dev/null", err: "/dev/null" # Prepare to shut it down. MiniTest.after_run do begin Process.kill("KILL", pid) rescue Errno::ESRCH end end # Client for talking to the server. client = HTTPClient.new client.connect_timeout = 1 client.send_timeout = 1 client.receive_timeout = 1 # Use define method so client_get's body is a closure that captures # the lovely variables we just set up. Nevermind all the hoops we # have to jump through to do that. Define this on the class because # we're going to need it in a bit to check that the server is alive. self.singleton_class.class_eval do define_method :client_get do |url| client.get("http://#{address}:#{port}#{url}").body end end def client_get(url) self.class.client_get(url) end # Wait for the server to start up. If it doesn't start, the # cleanest thing to do seems ot be to let the tests run anyway and # fail to connect. def self.wait_for_server(timeout) started = Time.now while !(alive = alive?) && Time.now - started < timeout sleep 0.1 end alive end def self.alive? # This will 404 but that's good enough. 3.times { client_get("/ping") } true rescue Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError, SystemCallError # No doubt that's not an exhaustive list of exceptions we should # rescue. false end if !self.wait_for_server(2) # Write this out after the tests finish, where it's likely to be seen. MiniTest.after_run do STDERR.puts STDERR.puts "The server for main_spec.rb failed to start." STDERR.puts "Try running it manually for debugging like this:" STDERR.puts " #{server_command}" STDERR.puts end end describe 'require "angelo/main"' do it "sets app_file to the file being run" do client_get("/app_file").must_equal app_file end it "only extends main" do client_get("/mainonly").must_equal "true" end it "makes helpers accessible" do client_get("/help").must_equal "help me!" end end end