mighty_test 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13aec80fee8a9c48191f615d0f3124046e6143637ef464ca2571fa51742aabe1
4
- data.tar.gz: efd82536b85f8844722b3d085b821c7d330a7b545e8c6d6de26f33178654a33b
3
+ metadata.gz: 5c8ad068e4c978f1a38d6ec2d6fe2cf74c8712ff2b7216ff0d9075dfc8e94959
4
+ data.tar.gz: 685f753bac6c76035572e8d99ae67ec97f10544bfcf34afe3c02c563175e8420
5
5
  SHA512:
6
- metadata.gz: 8bf9883b319e0d53da7660e16dd23fbf447cf205eec617bc840f37357e74347d5c96191af1a0e0a642a5ab3f962fad73bbd09b9cdb05abb4575846bddfed7dbb
7
- data.tar.gz: a7612ddc47104cbcf0efc5b054013be87c94f3367be7fc82fcade4dfa9953950b515be2e0659602f4ed967025457d19f85acb2dd1af8fa3eac9401d947887f8b
6
+ metadata.gz: 94f9ab682bdbc1a61de55ebed5f365615ce8ddf111b4f2689186fb1d8ac763fd6a8cb2075460c88b304a9a9e9db353865c1539d3b62a861f29e3f06f58763891
7
+ data.tar.gz: fb7dfb42e60dc90f35708065e75a3e3bddc01457e5beb81dfd6d6d5c31a6e42ca831af79e92a8d80feb240e5d7d0ae0001226e79689bd1fbcc543cf6e7306910
@@ -1,4 +1,5 @@
1
1
  require "io/console"
2
+ require "io/wait"
2
3
 
3
4
  module MightyTest
4
5
  class Console
@@ -15,11 +16,14 @@ module MightyTest
15
16
  true
16
17
  end
17
18
 
18
- def wait_for_keypress
19
- with_raw_input do
20
- sleep if stdin.eof?
21
- stdin.getc
22
- end
19
+ def with_raw_input(&)
20
+ return yield unless stdin.respond_to?(:raw) && tty?
21
+
22
+ stdin.raw(intr: true, &)
23
+ end
24
+
25
+ def read_keypress_nonblock
26
+ stdin.getc if stdin.wait_readable(0)
23
27
  end
24
28
 
25
29
  def play_sound(name, wait: false)
@@ -55,11 +59,5 @@ module MightyTest
55
59
  def tty?
56
60
  $stdout.respond_to?(:tty?) && $stdout.tty?
57
61
  end
58
-
59
- def with_raw_input(&)
60
- return yield unless stdin.respond_to?(:raw) && tty?
61
-
62
- stdin.raw(intr: true, &)
63
- end
64
62
  end
65
63
  end
@@ -1,3 +1,3 @@
1
1
  module MightyTest
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -0,0 +1,78 @@
1
+ require "io/console"
2
+
3
+ module MightyTest
4
+ class Watcher
5
+ class EventQueue
6
+ def initialize(console: Console.new, file_system: FileSystem.new)
7
+ @console = console
8
+ @file_system = file_system
9
+ @file_system_queue = Thread::Queue.new
10
+ end
11
+
12
+ def pop
13
+ console.with_raw_input do
14
+ until stopped?
15
+ if (key = console.read_keypress_nonblock)
16
+ return [:keypress, key]
17
+ end
18
+ if (paths = pop_files_changed)
19
+ return [:file_system_changed, paths]
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ def start
26
+ raise "Already started" unless stopped?
27
+
28
+ @file_system_listener = file_system.listen do |modified, added, _removed|
29
+ paths = [*modified, *added].uniq
30
+ file_system_queue.push(paths) unless paths.empty?
31
+ end
32
+ true
33
+ end
34
+
35
+ def restart
36
+ stop
37
+ start
38
+ end
39
+
40
+ def stop
41
+ file_system_listener&.stop
42
+ @file_system_listener = nil
43
+ end
44
+
45
+ def stopped?
46
+ !file_system_listener
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :console, :file_system, :file_system_listener, :file_system_queue
52
+
53
+ def pop_files_changed
54
+ paths = try_file_system_pop(timeout: 0.2)
55
+ return if paths.nil?
56
+
57
+ paths += file_system_queue.pop until file_system_queue.empty?
58
+ paths.uniq
59
+ end
60
+
61
+ if RUBY_VERSION.start_with?("3.1.")
62
+ # TODO: Remove once we drop support for Ruby 3.1
63
+ require "timeout"
64
+ def try_file_system_pop(timeout:)
65
+ Timeout.timeout(timeout) do
66
+ file_system_queue.pop
67
+ end
68
+ rescue Timeout::Error
69
+ nil
70
+ end
71
+ else
72
+ def try_file_system_pop(timeout:)
73
+ file_system_queue.pop(timeout:)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,58 +1,41 @@
1
+ require_relative "watcher/event_queue"
2
+
1
3
  module MightyTest
2
4
  class Watcher
3
- class ListenerTriggered < StandardError
4
- attr_reader :paths
5
-
6
- def initialize(paths)
7
- @paths = paths
8
- super()
9
- end
10
- end
11
-
12
5
  WATCHING_FOR_CHANGES = 'Watching for changes to source and test files. Press "h" for help or "q" to quit.'.freeze
13
6
 
14
- def initialize(console: Console.new, extra_args: [], file_system: FileSystem.new, system_proc: method(:system))
7
+ def initialize(console: Console.new, extra_args: [], event_queue: nil, file_system: nil, system_proc: nil)
15
8
  @console = console
16
9
  @extra_args = extra_args
17
- @file_system = file_system
18
- @system_proc = system_proc
10
+ @file_system = file_system || FileSystem.new
11
+ @system_proc = system_proc || method(:system)
12
+ @event_queue = event_queue || EventQueue.new(console: @console, file_system: @file_system)
19
13
  end
20
14
 
21
- def run(iterations: :indefinitely) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
22
- started = false
23
- @foreground_thread = Thread.current
24
-
25
- loop_for(iterations) do
26
- start_file_system_listener && puts(WATCHING_FOR_CHANGES) unless started
27
- started = true
28
-
29
- case console.wait_for_keypress
30
- when "\r", "\n"
31
- run_all_tests
32
- when "a"
33
- run_all_tests(flags: ["--all"])
34
- when "d"
35
- run_matching_test_files_from_git_diff
36
- when "h"
37
- show_help
38
- when "q"
39
- file_system_listener.stop
40
- break
15
+ def run
16
+ event_queue.start
17
+ puts WATCHING_FOR_CHANGES
18
+
19
+ loop do
20
+ case event_queue.pop
21
+ in [:file_system_changed, [_, *] => paths] then run_matching_test_files(paths)
22
+ in [:keypress, "\r" | "\n"] then run_all_tests
23
+ in [:keypress, "a"] then run_all_tests(flags: ["--all"])
24
+ in [:keypress, "d"] then run_matching_test_files_from_git_diff
25
+ in [:keypress, "h"] then show_help
26
+ in [:keypress, "q"] then break
27
+ else
28
+ nil
41
29
  end
42
- rescue ListenerTriggered => e
43
- run_matching_test_files(e.paths)
44
- file_system_listener.start if file_system_listener.paused?
45
- rescue Interrupt
46
- file_system_listener&.stop
47
- raise
48
30
  end
49
31
  ensure
32
+ event_queue.stop
50
33
  puts "\nExiting."
51
34
  end
52
35
 
53
36
  private
54
37
 
55
- attr_reader :console, :extra_args, :file_system, :file_system_listener, :system_proc, :foreground_thread
38
+ attr_reader :console, :extra_args, :file_system, :event_queue, :system_proc
56
39
 
57
40
  def show_help
58
41
  console.clear
@@ -109,25 +92,7 @@ module MightyTest
109
92
  $stdout.flush
110
93
  rescue Interrupt
111
94
  # Pressing ctrl-c kills the fs_event background process, so we have to manually restart it.
112
- restart_file_system_listener
113
- end
114
-
115
- def start_file_system_listener
116
- file_system_listener.stop if file_system_listener && !file_system_listener.stopped?
117
-
118
- @file_system_listener = file_system.listen do |modified, added, _removed|
119
- paths = [*modified, *added].uniq
120
- next if paths.empty?
121
-
122
- # Pause listener so that subsequent changes are queued up while we are running the tests
123
- file_system_listener.pause unless file_system_listener.stopped?
124
- foreground_thread.raise ListenerTriggered.new(paths)
125
- end
126
- end
127
- alias restart_file_system_listener start_file_system_listener
128
-
129
- def loop_for(iterations, &)
130
- iterations == :indefinitely ? loop(&) : iterations.times(&)
95
+ event_queue.restart
131
96
  end
132
97
  end
133
98
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mighty_test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brictson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-04 00:00:00.000000000 Z
11
+ date: 2024-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: listen
@@ -101,6 +101,7 @@ files:
101
101
  - lib/mighty_test/test_parser.rb
102
102
  - lib/mighty_test/version.rb
103
103
  - lib/mighty_test/watcher.rb
104
+ - lib/mighty_test/watcher/event_queue.rb
104
105
  homepage: https://github.com/mattbrictson/mighty_test
105
106
  licenses:
106
107
  - MIT
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
126
  - !ruby/object:Gem::Version
126
127
  version: '0'
127
128
  requirements: []
128
- rubygems_version: 3.5.9
129
+ rubygems_version: 3.5.11
129
130
  signing_key:
130
131
  specification_version: 4
131
132
  summary: A modern Minitest runner for TDD, with watch mode and more