55 / 56 lines covered (98.2%)
1unit module BDD::Behave::Watch::Session;23use BDD::Behave::Watch::Watcher;4use BDD::Behave::Watch::SmartSelector;5use BDD::Behave::Watch::UI;67our class RunRequest {8 has IO::Path @.specs;9 has Str $.reason is required;10 has Bool $.only-failures = False;11}1213our class Session {14 has BDD::Behave::Watch::Watcher::Watcher $.watcher is required;15 has BDD::Behave::Watch::SmartSelector::Selector $.selector is required;16 has BDD::Behave::Watch::UI::UI $.ui is required;17 has @.all-specs;18 has &.runner is required;19 has &.sleep-fn = -> $secs { sleep $secs };20 has Real $.poll-interval = 0.25;21 has Bool $.running-test-after-initialize = True;22 has Int $.max-iterations = -1;23 has Bool $!stop = False;24 has @!last-selection;2526 method run() {27 $!stop = False;28 $.watcher.initialize;29 $.ui.start-reader;3031 self!print-startup;3233 if $.running-test-after-initialize {34 self!execute(RunRequest.new(35 :specs($.all-specs.map(*.IO)),36 :reason('initial run'),37 ));38 }3940 my $iter = 0;41 until $!stop {42 last if $.max-iterations >= 0 && $iter >= $.max-iterations;43 $iter++;4445 (&!sleep-fn)($.poll-interval);4647 my $cmd = $.ui.poll-command;48 with $cmd {49 my $req = self!command-to-request($cmd);50 if $req.defined {51 self!execute($req);52 }53 next;54 }5556 my @changes = $.watcher.poll.list;57 next unless @changes.elems;5859 $.ui.change-summary(@changes);60 my @selected = $.selector.select-specs(@changes, $.all-specs).list;6162 if !@selected.elems {63 $.ui.info("no specs mapped to these changes; skipping");64 next;65 }6667 self!execute(RunRequest.new(68 :specs(@selected.map(*.IO)),69 :reason('change detected'),70 ));71 }7273 $.ui.stop;74 }7576 method stopped(--> Bool) { $!stop }7778 method !command-to-request(Str $cmd) {79 given $cmd {80 when 'q' | 'quit' | 'exit' {81 $.ui.info('quitting watch');82 $!stop = True;83 return Nil;84 }85 when 'r' | 'rerun' | '' {86 my @specs = @!last-selection.elems ?? @!last-selection !! $.all-specs.map(*.IO);87 return RunRequest.new(88 :@specs,89 :reason('manual rerun'),90 );91 }92 when 'a' | 'all' {93 return RunRequest.new(94 :specs($.all-specs.map(*.IO)),95 :reason('rerun all'),96 );97 }98 when 'f' | 'failed' {99 return RunRequest.new(100 :specs($.all-specs.map(*.IO)),101 :reason('rerun failed only'),102 :only-failures,103 );104 }105 when 'h' | '?' | 'help' {106 $.ui.prompt;107 return Nil;108 }109 default {110 $.ui.warn("unknown command: '$cmd'");111 $.ui.prompt;112 return Nil;113 }114 }115 }116117 method !execute(RunRequest $req) {118 $.ui.run-banner($req.specs, $req.reason);119 @!last-selection = $req.specs.list;120 my $exit = (&!runner)($req);121 $.ui.run-finished($exit == 0);122 $.ui.prompt;123 }124125 method !print-startup() {126 $.ui.banner('starting watch mode');127 my $tracked = $.watcher.tracked-count;128 $.ui.info("tracking $tracked files");129 }130}