diff --git a/src/commands/test.cr b/src/commands/test.cr
index d238fa320..08ee705a2 100644
--- a/src/commands/test.cr
+++ b/src/commands/test.cr
@@ -48,14 +48,30 @@ module Mint
description: "Will use supplied runtime path instead of the default distribution",
required: false
- define_argument test : String
+ define_flag watch : Bool,
+ description: "Watch files for changes and rerun tests",
+ required: false
+
+ define_argument test : String,
+ description: "The path to the test file to run"
def run
- succeeded = nil
- execute "Running Tests" do
- succeeded = TestRunner.new(flags, arguments).run
+ MintJson.parse_current.check_dependencies!
+
+ runner =
+ TestRunner.new(flags, arguments)
+
+ if flags.watch
+ runner.watch
+ else
+ succeeded = nil
+
+ execute "Running Tests" do
+ succeeded = runner.run
+ end
+
+ exit(1) unless succeeded
end
- exit(1) unless succeeded
end
end
end
diff --git a/src/render/terminal.cr b/src/render/terminal.cr
index 1dce912a0..769df69c6 100644
--- a/src/render/terminal.cr
+++ b/src/render/terminal.cr
@@ -247,6 +247,10 @@ module Mint
print contents.to_s
end
+ def reset
+ print "\ec"
+ end
+
def puts(contents = nil)
print contents if contents
print "\n"
diff --git a/src/test_runner.cr b/src/test_runner.cr
index d8b377942..f3029e133 100644
--- a/src/test_runner.cr
+++ b/src/test_runner.cr
@@ -5,6 +5,7 @@ module Mint
class Message
include JSON::Serializable
+ property id : String
property type : String
property name : String?
property suite : String?
@@ -30,9 +31,10 @@ module Mint
@artifacts : TypeChecker::Artifacts?
@reporter : Reporter
@browser_path : String?
- @script : String?
+ @browser : {Process, String}?
@failed = [] of Message
+ @test_id = Random::Secure.hex
@succeeded = 0
def initialize(@flags : Cli::Test::Flags, @arguments : Cli::Test::Arguments)
@@ -46,15 +48,38 @@ module Mint
@succeeded = 0
end
- def run : Bool
- MintJson.parse_current.check_dependencies!
+ def watch
+ workspace = Workspace.current
+ workspace.on "change" { run_tests }
+ workspace.watch
- ast = terminal.measure "#{COG} Compiling tests..." do
- compile_ast.tap do |a|
- @script = compile_script(a)
- end
+ setup_kemal
+ run_tests
+
+ Server.run "Test", @flags.host, @flags.port, false
+ end
+
+ def run_tests
+ @test_id = Random::Secure.hex
+ cleanup_browser
+ terminal.reset
+
+ begin
+ type_checker = TypeChecker.new(ast)
+ type_checker.check
+
+ @reporter.reset
+ open_page
+ rescue error : Error
+ terminal.reset
+ terminal.puts error.to_terminal
+ rescue error
+ terminal.reset
+ terminal.puts error.to_s
end
+ end
+ def run : Bool
if ast.try(&.suites.empty?)
terminal.puts
terminal.puts "There are no tests to run!"
@@ -74,7 +99,7 @@ module Mint
@failed.empty?
end
- def compile_ast
+ def ast
file_argument =
@arguments.test
@@ -96,7 +121,7 @@ module Mint
end
end
- def compile_script(ast)
+ def script
type_checker = TypeChecker.new(ast)
type_checker.check
@@ -186,15 +211,21 @@ module Mint
begin
process = open_process(browser_path, profile_directory)
- at_exit do
- process.signal(:kill) rescue nil
- FileUtils.rm_rf(profile_directory)
- end
+ @browser = {process, profile_directory}
+ at_exit { cleanup_browser }
@channel.receive
ensure
- process.try &.signal(:kill) rescue nil
+ cleanup_browser
+ end
+ end
+
+ def cleanup_browser
+ @browser.try do |(process, profile_directory)|
+ process.signal(:kill) rescue nil
FileUtils.rm_rf(profile_directory)
end
+
+ @browser = nil
end
def open_page
@@ -206,9 +237,6 @@ module Mint
ws_url =
"ws://#{@flags.browser_host}:#{@flags.browser_port}/"
- page_source =
- ECR.render("#{__DIR__}/test_runner.ecr")
-
runtime =
if runtime_path = @flags.runtime
Cli.runtime_file_not_found(runtime_path) unless File.exists?(runtime_path)
@@ -219,7 +247,7 @@ module Mint
get "/" do
reset
- page_source
+ ECR.render("#{__DIR__}/test_runner.ecr")
end
get "/external-javascripts.js" do |env|
@@ -258,7 +286,7 @@ module Mint
end
get "/tests" do
- @script
+ script
end
ws "/" do |socket|
@@ -277,6 +305,8 @@ module Mint
end
def handle_message(data : Message) : Nil
+ return unless data.id == @test_id
+
case data.type
when "LOG"
terminal.puts data.result
@@ -296,7 +326,7 @@ module Mint
@failed << data
@reporter.done
- stop_server
+ stop_server unless @flags.watch
end
end
@@ -335,7 +365,7 @@ module Mint
end
end
- stop_server
+ stop_server unless @flags.watch
end
def stop_server
diff --git a/src/test_runner.ecr b/src/test_runner.ecr
index 10f270f95..45f7d4ef7 100644
--- a/src/test_runner.ecr
+++ b/src/test_runner.ecr
@@ -8,6 +8,8 @@