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 @@