Skip to content

Commit

Permalink
Merge pull request #230 from AlexB52/v2.0
Browse files Browse the repository at this point in the history
* listen to user inputs in executable (#213)

* Listen to user inputs in executable

      * 'h' or 'help'    -> Prints help
      * 'p' or 'pause'   -> Pauses Retest. Tests aren't run until unpaused.
      * 'u' or 'unpause' -> Unpauses Retest
      * <Enter>          -> Runs last changed triggered command
      * 'ra', 'run all'  -> Runs all tests
      * 'e' or 'exit'    -> Exits Retest

* Create version 2.0.0.pre

* Fix gets chomp no method error (#217)

* Convert nil to string
* Update version to v2 in tests

* Update the help prompt

* Refactor Runner#run_all_tests to raise unless for TestRunner (#219)

* Manage stdin based on the process running (#220)

* Create Program#run_synchronously (#221)

* Create pre release 3 (#223)

* Multiplex stdin between user input and listen input (#224)

* Reverse Listen communication and restrict its usage as an automatic input
* Delete Program#run_synchronously
* Clear input dependencies on runner and prompt & refactor program

* Create version v2.0.0.pre3

* v2 - Refactor runners (#226)

* Update file selection logs
* Create Command::Hardcoded
* Use the Command::Hardcoded command
* Update Runner#run arguments
* Delete all runners except Runner

* Switch to bundler  2.3.27

* Standardize ruby version in ci definition

* Remove clear terminal call

* Ask user which tests to run

We add TTY::Prompt dependency for ease of user experience

* Refactoring

  * Cleanup runner and commands
  * Remove all_test_runner
  * Refactor format batch of Ruby and Rake

* V2 - Force selection of test files to run (#228)

* Remove command dependency from program objects
* Force selection of tests and run them on file changes
* Small fixes:
  * Clear terminal window from the executable instead
  * Add a hint to reset when on forced selection
  * Update interactive help
* Run last command on Enter

* Create version 2.0.0.pre4

* Add Watchexec watcher as default when installed on machine

  * Revert to Bundler 2.3.27
  * Create --exts and Delete --ext option
    We allow to pass a list of extensions instead of a regex and build the regex
    from the options instead of the user. This is simpler and easier for the user.
  * Display watcher used
  * Switch Listen to Wrapper Watcher::Default
  * Override watchexec with default watcher on CI
  * Allow VersionControl.files to take file extensions
  * Default to watchexec when installed
  * Remove .puts (for now)

* Remove watchexec feature specs (for now)

* Fix order of file change events in watchexec watcher (#231)

* V2/watchexec feature test (#232)

* Create Watchexec feature specs
* Build watchexec in separate image
* Add command to build watchexec image

* Merge ruby-app to use both watchexec and listen watchers (#233)

* Create version 2.0.0.pre5

* Add Interactive Feature tests (#234)

* Fix Runner#last_command when running all tests
* Refactor bundler-app helpers and test command
* Add interactive feature tests
  * Pause/Unpause
  * Run all
  * Force selection
  * Start / Help
  * Run last command

* V2/refactor test helper (#235)

* Enable new test helper for all feature specs
* Refactor all feature specs

* Fix rails-app feature spec
  • Loading branch information
AlexB52 authored Dec 11, 2024
2 parents e2b8912 + a304aac commit 9ebece2
Show file tree
Hide file tree
Showing 107 changed files with 2,299 additions and 1,493 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ jobs:
matrix:
os: [ubuntu-latest]
ruby:
- 2.5
- 2.6
- 2.7
- '2.5'
- '2.6'
- '2.7'
- '3.0'
- 3.1
- 3.2
- 3.3
- '3.1'
- '3.2'
- '3.3'
include:
- os: macos-13
ruby: 2.5
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ gemspec

gem "rake", "~> 13.0"
gem "minitest", "~> 5.0"
gem "byebug"
gem "byebug", require: false
22 changes: 18 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
PATH
remote: .
specs:
retest (1.13.2)
retest (2.0.0.pre5)
listen (~> 3.9)
observer (~> 0.1)
string-similarity (~> 2.1)
tty-option (~> 0.1)
tty-prompt (~> 0.1)

GEM
remote: https://rubygems.org/
specs:
byebug (11.1.3)
ffi (1.16.3)
ffi (1.17.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
minitest (5.15.0)
observer (0.1.2)
pastel (0.8.0)
tty-color (~> 0.5)
rake (13.0.6)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
rb-inotify (0.11.1)
ffi (~> 1.0)
string-similarity (2.1.0)
tty-color (0.6.0)
tty-cursor (0.7.1)
tty-option (0.3.0)
tty-prompt (0.23.1)
pastel (~> 0.8)
tty-reader (~> 0.8)
tty-reader (0.9.0)
tty-cursor (~> 0.7)
tty-screen (~> 0.8)
wisper (~> 2.0)
tty-screen (0.8.2)
wisper (2.0.1)

PLATFORMS
ruby
Expand All @@ -34,4 +48,4 @@ DEPENDENCIES
retest!

BUNDLED WITH
2.3.22
2.3.27
7 changes: 7 additions & 0 deletions bin/build/watchexec
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

docker buildx build \
--platform linux/amd64,linux/arm64 \
-t ghcr.io/alexb52/slim-bullseye-watchexec:latest \
-f builds/dockerfiles/WatchexecSlimBullseye \
--push .
11 changes: 9 additions & 2 deletions bin/test/bundler-app
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#!/usr/bin/env bash

FOLDER="features/bundler-app"

bundle install
bundle exec rake build
cp -R features/support features/bundler-app/retest
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/bundler-app/retest.gem
docker compose -f features/bundler-app/docker-compose.yml up --build --exit-code-from retest
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} "$FOLDER/retest.gem"

if [[ "$1" == "--no-build" ]]; then
docker compose -f "$FOLDER/docker-compose.yml" up --exit-code-from retest
else
docker compose -f "$FOLDER/docker-compose.yml" up --build --exit-code-from retest
fi
2 changes: 1 addition & 1 deletion bin/test/ruby-app
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ bundle install
bundle exec rake build
cp -R features/support features/ruby-app/retest
ls -t pkg | head -n1 | xargs -I {} mv pkg/{} features/ruby-app/retest.gem
docker compose -f features/ruby-app/docker-compose.yml up --build --exit-code-from retest
docker compose -f features/ruby-app/docker-compose.yml up --build --exit-code-from retest
12 changes: 12 additions & 0 deletions builds/dockerfiles/WatchexecSlimBullseye
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Stage 1: Build watchexec with Rust
FROM rust:1.83.0-slim-bullseye AS rust-builder

# Install necessary dependencies for Rust
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git

# Install watchexec
RUN cargo install watchexec-cli

# Verify installation
RUN watchexec --version
103 changes: 90 additions & 13 deletions exe/retest
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,39 @@
require 'retest'

$stdout.sync = true

Signal.trap(:INT) { $stdout.puts "Goodbye"; exit }
listen_rd, listen_wr = IO.pipe
Signal.trap(:INT) do
puts "Goodbye"
listen_rd.close
listen_wr.close
exit
end

options = Retest::Options.new(ARGV)

if options.help?
$stdout.puts options.help
puts options.help
return
end

if options.version?
$stdout.puts Retest::VERSION
puts Retest::VERSION
return
end

prompt = Retest::Prompt.new
repository = Retest::Repository.new(files: Retest::VersionControl.files, prompt: prompt)
command = Retest::Command.for_options(options)
runner = Retest::Runners.runner_for(command.to_s)
runner = Retest::Runner.new(command)
sounds = Retest::Sounds.for(options)
watcher = Retest::Watcher.for(options.watcher)

sounds.play(:start)
runner.add_observer(sounds)
prompt.add_observer(sounds)

program = Retest::Program.new(
repository: repository,
command: command,
runner: runner
)

Expand All @@ -39,23 +44,95 @@ if options.params[:diff]
return
end

if watcher == Retest::Watcher::Watchexec
puts "Watcher: [WATCHEXEC]"
else
puts "Watcher: [LISTEN]"
end

launching_message = "Launching Retest..."
if options.force_polling?
launching_message = "Launching Retest with polling method..."
end

# Main action

$stdout.puts launching_message
Retest.listen(options) do |modified, added, removed|
puts launching_message
Retest.listen(options, listener: watcher) do |modified, added, removed|
begin
program.run(modified, added, removed)
repository.sync(added: added, removed: removed)
runner.sync(added: added, removed: removed)

listen_wr.puts "file changed: #{(modified + added).first}"
rescue => e
$stdout.puts "Something went wrong: #{e.message}"
puts "Something went wrong: #{e.message}"
end
end
$stdout.puts "Ready to refactor! You can make file changes now"
puts "Ready to refactor! You can make file changes now"

# not blocking
def run_command(input:, program:)
case input.strip
when /^file changed:\s(.*)$/
puts "File changed: #{$1}"
program.run($1)
when 'p', 'pause'
program.pause
puts "Program is paused\n"
when 'u', 'unpause'
program.resume
puts "Program has been resumed\n"
when 'e', 'exit'
Process.kill("INT", 0)
when 'r', 'reset'
program.reset_selection
puts "command reset to '#{program.runner.command.to_s}'"
when 'f', 'force'
require 'tty-prompt'
prompt = TTY::Prompt.new
program.force_selection prompt.multi_select(
"What test files do you want to run when saving a file?",
program.repository.test_files,
filter: true, min: 1
)
program.run(nil, force_run: true)
when ''
puts "Running last command: '#{program.last_command}'\n"
program.run_last_command
when 'ra', 'run all'
puts "Running all tests\n"
program.run_all
when /^di?f?f?\s(.*)$/
program.diff($1)
when 'c'
program.clear_terminal
when 'h', 'help'
puts <<~HELP
sleep
* 'h', 'help' # Prints help.
* 'p', 'pause' # Pauses Retest. Tests aren't run on file change events until unpaused.
* 'u', 'unpause' # Unpauses Retest.
* <ENTER> # Runs last changed triggered command.
* 'ra, 'run all' # Runs all tests.
* 'f', 'force' # Forces a selection of test to run on every file change.
* 'r', 'reset' # Disables forced selection.
* 'd', 'diff' [GIT BRANCH] # Runs matching specs that changed from a target branch.
* 'c' # Clears window.
* 'e', 'exit' # Exits Retest.
HELP
else
puts "Unknown interactive command #{input}\n"
end
end

connections = [$stdin, listen_rd]
loop do
puts "\nType interactive command and press enter. Enter 'h' for help."
print(">\s")

ready = IO.select(connections)
readable_connections = ready[0]
readable_connections.each do |conn|
data = conn.readpartial(4096)
run_command(input: data.to_s.chomp, program: program)
end
end
1 change: 1 addition & 0 deletions features/bundler-app/lib/bundler_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative "bundler_app/version"
require_relative "bundler_app/bottles"
require_relative "bundler_app/fibonacci"

module BundlerApp
class Error < StandardError; end
Expand Down
11 changes: 11 additions & 0 deletions features/bundler-app/lib/bundler_app/fibonacci.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# fibonacci.rb
class Fibonacci
def self.calculate(n)
raise ArgumentError, "Input must be a non-negative integer." unless n.is_a?(Integer) && n >= 0
return n if n <= 1

a, b = 0, 1
(n - 1).times { a, b = b, a + b }
b
end
end
4 changes: 1 addition & 3 deletions features/bundler-app/retest/retest_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
require_relative 'support/test_helper'
require 'minitest/autorun'
require_relative 'retest_test/file_changes_test'
require_relative 'retest_test/interactive_commands_test'

$stdout.sync = true

include FileHelper

33 changes: 17 additions & 16 deletions features/bundler-app/retest/retest_test/file_changes_test.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class FileChangesTest < Minitest::Test
include RetestHelper

def setup
@command = 'retest'
end
Expand All @@ -10,7 +12,7 @@ def teardown
def test_start_retest
launch_retest @command

assert_match <<~EXPECTED, @output.read
assert_output_matches <<~EXPECTED
Launching Retest...
Ready to refactor! You can make file changes now
EXPECTED
Expand All @@ -21,25 +23,27 @@ def test_modifying_existing_file

modify_file('lib/bundler_app/bottles.rb')

assert_match "Test File Selected: test/bundler_app/test_bottles.rb", @output.read
assert_match "12 runs, 12 assertions, 0 failures, 0 errors, 0 skips", @output.read
assert_output_matches(
'Test file: test/bundler_app/test_bottles.rb',
'12 runs, 12 assertions, 0 failures, 0 errors, 0 skips')
end

def test_modifying_existing_test_file
launch_retest @command

modify_file('test/bundler_app/test_bottles.rb')

assert_match "Test File Selected: test/bundler_app/test_bottles.rb", @output.read
assert_match "12 runs, 12 assertions, 0 failures, 0 errors, 0 skips", @output.read
assert_output_matches(
'Test file: test/bundler_app/test_bottles.rb',
'12 runs, 12 assertions, 0 failures, 0 errors, 0 skips')
end

def test_creating_a_new_test_file
launch_retest @command

create_file 'test/bundler_app/test_foo.rb'

assert_match "Test File Selected: test/bundler_app/test_foo.rb", @output.read
assert_output_matches 'Test file: test/bundler_app/test_foo.rb'

ensure
delete_file 'test/bundler_app/test_foo.rb'
Expand All @@ -49,33 +53,30 @@ def test_creating_a_new_file
launch_retest @command

create_file 'lib/bundler_app/foo.rb'
assert_match <<~EXPECTED, @output.read
404 - Test File Not Found
Retest could not find a matching test file to run.
EXPECTED
assert_output_matches 'FileNotFound - Retest could not find a matching test file to run.'

create_file 'test/bundler_app/test_foo.rb'
assert_match "Test File Selected: test/bundler_app/test_foo.rb", @output.read
assert_output_matches 'Test file: test/bundler_app/test_foo.rb'

modify_file('lib/bundler_app/bottles.rb')
assert_match "Test File Selected: test/bundler_app/test_bottles.rb", @output.read
assert_output_matches 'Test file: test/bundler_app/test_bottles.rb'

modify_file('lib/bundler_app/foo.rb')
assert_match "Test File Selected: test/bundler_app/test_foo.rb", @output.read
assert_output_matches 'Test file: test/bundler_app/test_foo.rb'

ensure
delete_file 'lib/bundler_app/foo.rb'
delete_file 'test/bundler_app/test_foo.rb'
end

def test_untracked_file
create_file 'lib/bundler_app/foo.rb', should_sleep: false
create_file 'test/bundler_app/test_foo.rb', should_sleep: false
create_file 'lib/bundler_app/foo.rb', sleep_for: 0
create_file 'test/bundler_app/test_foo.rb', sleep_for: 0

launch_retest @command

modify_file 'lib/bundler_app/foo.rb'
assert_match "Test File Selected: test/bundler_app/test_foo.rb", @output.read
assert_output_matches 'Test file: test/bundler_app/test_foo.rb'

ensure
delete_file 'lib/bundler_app/foo.rb'
Expand Down
Loading

0 comments on commit 9ebece2

Please sign in to comment.