diff --git a/Steepfile b/Steepfile index bc0d583f43..0689f7f82d 100644 --- a/Steepfile +++ b/Steepfile @@ -28,6 +28,10 @@ target :lib do check "lib/react_on_rails.rb" check "lib/react_on_rails/configuration.rb" check "lib/react_on_rails/controller.rb" + check "lib/react_on_rails/dev/file_manager.rb" + check "lib/react_on_rails/dev/pack_generator.rb" + check "lib/react_on_rails/dev/process_manager.rb" + check "lib/react_on_rails/dev/server_manager.rb" check "lib/react_on_rails/git_utils.rb" check "lib/react_on_rails/helper.rb" check "lib/react_on_rails/packer_utils.rb" diff --git a/lib/react_on_rails/dev/pack_generator.rb b/lib/react_on_rails/dev/pack_generator.rb index a339d5860f..48e1f4eb4a 100644 --- a/lib/react_on_rails/dev/pack_generator.rb +++ b/lib/react_on_rails/dev/pack_generator.rb @@ -2,6 +2,7 @@ require "English" require "stringio" +require_relative "../packer_utils" module ReactOnRails module Dev diff --git a/lib/react_on_rails/dev/server_manager.rb b/lib/react_on_rails/dev/server_manager.rb index e1ff3e0825..63e8962634 100644 --- a/lib/react_on_rails/dev/server_manager.rb +++ b/lib/react_on_rails/dev/server_manager.rb @@ -3,6 +3,7 @@ require "English" require "open3" require "rainbow" +require_relative "../packer_utils" module ReactOnRails module Dev diff --git a/sig/react_on_rails/dev/file_manager.rbs b/sig/react_on_rails/dev/file_manager.rbs new file mode 100644 index 0000000000..88d3b4f93f --- /dev/null +++ b/sig/react_on_rails/dev/file_manager.rbs @@ -0,0 +1,15 @@ +module ReactOnRails + module Dev + class FileManager + def self.cleanup_stale_files: () -> bool + + private + + def self.cleanup_overmind_sockets: () -> bool + def self.cleanup_rails_pid_file: () -> bool + def self.overmind_running?: () -> bool + def self.process_running?: (Integer) -> bool + def self.remove_file_if_exists: (String, String) -> bool + end + end +end diff --git a/sig/react_on_rails/dev/pack_generator.rbs b/sig/react_on_rails/dev/pack_generator.rbs new file mode 100644 index 0000000000..76669b35e2 --- /dev/null +++ b/sig/react_on_rails/dev/pack_generator.rbs @@ -0,0 +1,19 @@ +module ReactOnRails + module Dev + class PackGenerator + def self.generate: (?verbose: bool) -> void + + private + + def self.run_pack_generation: (?silent: bool) -> bool + def self.should_run_directly?: () -> bool + def self.rails_available?: () -> bool + def self.run_rake_task_directly: (?silent: bool) -> bool + def self.load_rake_tasks: () -> void + def self.prepare_rake_task: () -> untyped + def self.capture_output: (bool) { () -> bool } -> bool + def self.handle_rake_error: (Exception, bool) -> void + def self.run_via_bundle_exec: (?silent: bool) -> (bool | nil) + end + end +end diff --git a/sig/react_on_rails/dev/process_manager.rbs b/sig/react_on_rails/dev/process_manager.rbs new file mode 100644 index 0000000000..bdcd6dc464 --- /dev/null +++ b/sig/react_on_rails/dev/process_manager.rbs @@ -0,0 +1,22 @@ +module ReactOnRails + module Dev + class ProcessManager + VERSION_CHECK_TIMEOUT: Integer + + def self.installed?: (String) -> bool + def self.ensure_procfile: (String) -> void + def self.run_with_process_manager: (String) -> void + + private + + def self.installed_in_current_context?: (String) -> bool + def self.version_flags_for: (String) -> Array[String] + def self.run_process_if_available: (String, Array[String]) -> bool + def self.run_process_outside_bundle: (String, Array[String]) -> bool + def self.process_available_in_system?: (String) -> bool + def self.with_unbundled_context: () { () -> untyped } -> untyped + def self.show_process_manager_installation_help: () -> void + def self.valid_procfile_path?: (String) -> bool + end + end +end diff --git a/sig/react_on_rails/dev/server_manager.rbs b/sig/react_on_rails/dev/server_manager.rbs new file mode 100644 index 0000000000..a890627deb --- /dev/null +++ b/sig/react_on_rails/dev/server_manager.rbs @@ -0,0 +1,39 @@ +module ReactOnRails + module Dev + class ServerManager + type mode = :development | :production_like | :static | :hmr + + def self.start: (mode, String?, ?verbose: bool, ?route: String?, ?rails_env: String?) -> void + def self.kill_processes: () -> void + def self.development_processes: () -> Hash[String, String] + def self.kill_running_processes: () -> bool + def self.find_process_pids: (String) -> Array[Integer] + def self.terminate_processes: (Array[Integer]) -> void + def self.kill_port_processes: (Array[Integer]) -> bool + def self.find_port_pids: (Integer) -> Array[Integer] + def self.cleanup_socket_files: () -> bool + def self.print_kill_summary: (bool) -> void + def self.show_help: () -> void + def self.run_from_command_line: (?Array[String]) -> void + + private + + def self.help_usage: () -> String + def self.help_commands: () -> String + def self.help_options: () -> String + def self.help_customization: () -> String + def self.help_mode_details: () -> String + def self.help_troubleshooting: () -> String + def self.run_production_like: (?_verbose: bool, ?route: String?, ?rails_env: String?) -> void + def self.run_static_development: (String, ?verbose: bool, ?route: String?) -> void + def self.run_development: (String, ?verbose: bool, ?route: String?) -> void + def self.print_server_info: (String, Array[String], ?Integer, ?route: String?) -> void + def self.print_procfile_info: (String, ?route: String?) -> void + def self.procfile_port: (String) -> Integer + def self.box_border: (Integer) -> String + def self.box_bottom: (Integer) -> String + def self.box_empty_line: (Integer) -> String + def self.format_box_line: (String, Integer) -> String + end + end +end diff --git a/spec/react_on_rails/binstubs/dev_spec.rb b/spec/react_on_rails/binstubs/dev_spec.rb index 0f699af27d..c2ff504a2e 100644 --- a/spec/react_on_rails/binstubs/dev_spec.rb +++ b/spec/react_on_rails/binstubs/dev_spec.rb @@ -4,6 +4,7 @@ RSpec.describe "bin/dev script" do let(:script_path) { "lib/generators/react_on_rails/templates/base/base/bin/dev" } + let(:dummy_dev_path) { "spec/dummy/bin/dev" } # To suppress stdout during tests original_stderr = $stderr @@ -58,4 +59,28 @@ def setup_script_execution_for_tool_tests load script_path end + + # Integration test: verify bin/dev can load without NameError + describe "integration test" do + it "spec/dummy/bin/dev can load the template script without errors" do + # This test verifies that all required dependencies are properly loaded + # when bin/dev is executed, catching issues like missing require statements + expect(File.exist?(dummy_dev_path)).to be true + expect(File.exist?(script_path)).to be true + + # Verify the dummy script references the template + dummy_content = File.read(dummy_dev_path) + expect(dummy_content).to include(script_path) + end + + it "can require react_on_rails/dev and access all necessary modules" do + # This catches missing require statements in pack_generator.rb and other files + # If PackerUtils isn't required, this would fail with NameError + require "react_on_rails/dev" + + expect { ReactOnRails::Dev::ServerManager }.not_to raise_error + expect { ReactOnRails::Dev::PackGenerator }.not_to raise_error + expect { ReactOnRails::PackerUtils }.not_to raise_error + end + end end diff --git a/spec/react_on_rails/dev/pack_generator_spec.rb b/spec/react_on_rails/dev/pack_generator_spec.rb index 19afb35df7..751725eccb 100644 --- a/spec/react_on_rails/dev/pack_generator_spec.rb +++ b/spec/react_on_rails/dev/pack_generator_spec.rb @@ -4,6 +4,15 @@ require "react_on_rails/dev/pack_generator" RSpec.describe ReactOnRails::Dev::PackGenerator do + # Integration test: verify PackerUtils is properly required + describe "module dependencies" do + it "can access ReactOnRails::PackerUtils without errors" do + # This test ensures the require statement is present in pack_generator.rb + # If the require is missing, this will raise NameError: uninitialized constant + expect { ReactOnRails::PackerUtils }.not_to raise_error + end + end + describe ".generate" do context "when shakapacker precompile hook is configured" do before do diff --git a/spec/react_on_rails/generators/generator_helper_spec.rb b/spec/react_on_rails/generators/generator_helper_spec.rb index f00c9e4a24..eb8b447549 100644 --- a/spec/react_on_rails/generators/generator_helper_spec.rb +++ b/spec/react_on_rails/generators/generator_helper_spec.rb @@ -13,6 +13,9 @@ let(:mock_manager) { instance_double("PackageJson::Manager") } # rubocop:disable RSpec/VerifiedDoubleReference before do + # Stub PackageJson constant so instance_double can reference it + stub_const("PackageJson", Class.new) unless defined?(PackageJson) + allow(self).to receive(:package_json).and_return(mock_package_json) allow(mock_package_json).to receive(:manager).and_return(mock_manager) end