mighty_test 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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