mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 19:37:55 +08:00
7b31d8a11b
We had checks for the chrome binary in 3 different places for tests and only one of them checked for google-chrome-stable, which is problematic for Arch linux users (there are dozens of us!) This PR moves all the code to one place and references it instead of copying and pasting.
180 lines
4.1 KiB
Ruby
180 lines
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "demon/rails_autospec"
|
|
require "chrome_installed_checker"
|
|
|
|
module Autospec
|
|
|
|
class QunitRunner < BaseRunner
|
|
|
|
WATCHERS = {}
|
|
def self.watch(pattern, &blk)
|
|
WATCHERS[pattern] = blk
|
|
end
|
|
def watchers
|
|
WATCHERS
|
|
end
|
|
|
|
# Discourse specific
|
|
watch(%r{^app/assets/javascripts/discourse/(.+)\.js$}) { |m| "test/javascripts/#{m[1]}-test.js" }
|
|
watch(%r{^app/assets/javascripts/admin/(.+)\.js$}) { |m| "test/javascripts/admin/#{m[1]}-test.js" }
|
|
watch(%r{^test/javascripts/.+\.js$})
|
|
watch(%r{^app/assets/javascripts/discourse/tests/.+\.js$})
|
|
|
|
RELOADERS = Set.new
|
|
def self.reload(pattern)
|
|
RELOADERS << pattern
|
|
end
|
|
def reloaders
|
|
RELOADERS
|
|
end
|
|
|
|
# Discourse specific
|
|
reload(%r{^discourse/tests/javascripts/fixtures/.+_fixtures\.js(\.es6)?$})
|
|
reload(%r{^discourse/tests/javascripts/(helpers|mixins)/.+\.js(\.es6)?$})
|
|
reload("app/assets/javascripts/discoruse/tests/javascripts/test_helper.js")
|
|
|
|
watch(%r{^plugins/.*/test/.+\.js(\.es6)?$})
|
|
|
|
require "socket"
|
|
|
|
def initialize
|
|
ChromeInstalledChecker.run
|
|
end
|
|
|
|
def start
|
|
# ensure we can launch the rails server
|
|
unless port_available?(port)
|
|
puts "Port #{port} is not available"
|
|
puts "Either kill the process using that port or use the `TEST_SERVER_PORT` environment variable"
|
|
return
|
|
end
|
|
|
|
# start rails
|
|
start_rails_server
|
|
@running = true
|
|
end
|
|
|
|
def running?
|
|
@running
|
|
end
|
|
|
|
def run(specs)
|
|
puts "Running Qunit: #{specs}"
|
|
Demon::RailsAutospec.ensure_running
|
|
|
|
abort
|
|
|
|
qunit_url = +"http://localhost:#{port}/qunit"
|
|
|
|
if specs != "spec"
|
|
module_or_filename, test_id, _name = specs.strip.split(":::")
|
|
module_name = module_or_filename
|
|
if !test_id
|
|
module_name = try_to_find_module_name(module_or_filename)
|
|
qunit_url << "?module=#{module_name}" if module_name
|
|
else
|
|
qunit_url << "?testId=#{test_id}"
|
|
end
|
|
end
|
|
|
|
cmd = "node #{Rails.root}/test/run-qunit.js \"#{qunit_url}\" 3000000 ./tmp/qunit_result"
|
|
|
|
@pid = Process.spawn(cmd)
|
|
_, status = Process.wait2(@pid)
|
|
|
|
status.exitstatus
|
|
end
|
|
|
|
def reload
|
|
stop_rails_server
|
|
sleep 1
|
|
start_rails_server
|
|
end
|
|
|
|
def abort
|
|
if @pid
|
|
children_processes(@pid).each { |pid| kill_process(pid) }
|
|
kill_process(@pid)
|
|
@pid = nil
|
|
end
|
|
end
|
|
|
|
def failed_specs
|
|
specs = []
|
|
path = './tmp/qunit_result'
|
|
specs = File.readlines(path) if File.exist?(path)
|
|
specs
|
|
end
|
|
|
|
def stop
|
|
abort
|
|
stop_rails_server
|
|
@running = false
|
|
end
|
|
|
|
private
|
|
|
|
def port_available?(port)
|
|
TCPServer.open(port).close
|
|
true
|
|
rescue Errno::EADDRINUSE
|
|
false
|
|
end
|
|
|
|
def port
|
|
@port ||= ENV["TEST_SERVER_PORT"] || 60099
|
|
end
|
|
|
|
def start_rails_server
|
|
Demon::RailsAutospec.start(1)
|
|
end
|
|
|
|
def stop_rails_server
|
|
Demon::RailsAutospec.stop
|
|
end
|
|
|
|
def children_processes(base = Process.pid)
|
|
process_tree = Hash.new { |hash, key| hash[key] = [key] }
|
|
Hash[*`ps -eo pid,ppid`.scan(/\d+/).map(&:to_i)].each do |pid, ppid|
|
|
process_tree[ppid] << process_tree[pid]
|
|
end
|
|
process_tree[base].flatten - [base]
|
|
end
|
|
|
|
def kill_process(pid)
|
|
return unless pid
|
|
Process.kill("INT", pid) rescue nil
|
|
while (Process.getpgid(pid) rescue nil)
|
|
sleep 0.001
|
|
end
|
|
end
|
|
|
|
def try_to_find_module_name(file)
|
|
file, _ = file.split(/:\d+$/)
|
|
return unless File.exists?(file)
|
|
File.open(file, "r").each_line do |line|
|
|
if m = /module\(['"]([^'"]+)/i.match(line)
|
|
return m[1]
|
|
end
|
|
if m = /moduleForWidget\(['"]([^"']+)/i.match(line)
|
|
return "widget:#{m[1]}"
|
|
end
|
|
if m = /acceptance\(['"]([^"']+)/i.match(line)
|
|
return "Acceptance: #{m[1]}"
|
|
end
|
|
if m = /moduleFor\(['"]([^'"]+)/i.match(line)
|
|
return m[1]
|
|
end
|
|
if m = /moduleForComponent\(['"]([^"']+)/i.match(line)
|
|
return m[1]
|
|
end
|
|
end
|
|
|
|
nil
|
|
end
|
|
|
|
end
|
|
|
|
end
|