← Back to index

lib/BDD/Behave/Watch/Session.rakumod

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}