aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/event_dispatcher
AgeCommit message (Collapse)Author
2026-08-06feat(plugin): run plugin-provided installers through the RPC workernsfisis
A plugin can now hand an InstallerInterface implementation to InstallationManager::addInstaller across the wire, and a legacy composer-installer package is loaded as one; both are backed by a PhpInstallerProxy forwarding the whole installer contract to the entity in the PHP worker. An installer returning a real promise is an explicit error until promises can cross the boundary. InstallationManager takes installers as shared handles instead of boxes, so the object identity removeInstaller and PluginManager's registeredPlugins compare against survives registration, and holds them in a RefCell: Installer::run keeps a shared borrow of the manager for the whole run, and a plugin activated inside it registers its installer from there. The type cache keys on the installer itself, like upstream, so re-entrant registration cannot leave a stale index behind. InstallerInterface::supports is fallible for the same reason getCapabilities and getCommands are: it answers over RPC. Cloning a proxy stub clones the Rust-side entity and rebinds the copy to the fresh handle. Previously only the classes declaring __clone got a throwing body, and the rest let two stubs share (and twice release) one handle. Package entities answer with AnyPackage::dup, which already carries BasePackage::__clone and the RootAliasPackage override; the others are an explicit error. The package proxy covers the whole PackageInterface surface; only the link maps and the release date still lack a wire image for their value objects. PluginManager gains a test-only seam for the reported Plugin API version, and the three PluginInstallerTest cases that need it are ported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04fix(plugin): resolve review findings in the plugin activation flownsfisis
InstallationManager::execute now takes &self (the mock recorder moved into a RefCell) and its callers hold only shared borrows: plugin registration inside a batch re-enters the same manager handle through Composer::getInstallationManager()->getInstallPath(), which panicked on the RefCell re-borrow under the &mut shape — the same re-entrancy the repository side already fixed, unreachable from the ported tests because they call PluginInstaller::install directly like PHPUnit does. The worker-side InstalledVersions mirror now matches the full tail of FilesystemRepository::write: unconditional reload plus the reflection-based selfDir/installedIsLocalDir restore. The previous class_exists(false) guard rested on a lazy-load assumption that does not hold in the worker (its real ClassLoader only knows the Composer checkout's vendor dir, so a later lazy load would read the checkout's installed.php, not the project's); the mirror is now skipped only when the class is not autoloadable at all, i.e. no plugin runtime and hence no observer code. Boot-time seeding stays TODO(plugin). Also from the review: registered_plugins entries are removed only after the deactivate/uninstall loop (PHP unsets last, and a throw must leave the entry observable); extra.class keeps associative-array values and fails loudly on non-strings instead of silently dropping them; the two discarded write() results now propagate (they carry the reload-push failure); register_package's allow-plugins skip message is DEBUG like the addPlugin side; the loader-eviction divergence of REGISTERED_LOADERS and the lossy UTF-8 spots carry searchable markers; the test-only proxy downcast follows the __ naming rule; the R-table dispatch clones the entity out instead of holding the table borrow across the handler; the IO/PartialComposer stubs turn a plugin-side `new NullIO()` into an explicit error instead of an ArgumentCountError; and the empty() emulation covers float 0.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04feat(plugin): activate plugins through the PHP RPC workernsfisis
Implement the remainder of PluginManager::registerPackage: the plugin autoload map is built by the ported createLoader/parseAutoloads and served to the worker over the existing reverse-RPC autoloader, files entries go through a composerRequire-equivalent glue call, and already-defined classes take the upstream _composer_tmp rename/eval path. Instantiation uses the new NewObject/CallPhpMethod lanes backed by a P table in the worker; PhpPluginProxy adapts the resulting handle to PluginInterface, with $composer/$io exposed to plugin callbacks via an R table (unsupported methods stay explicit errors). Hand-written proxy stubs cover Composer, PartialComposer and the IO hierarchy, and the stub autoloader is re-prepended after loading the Composer PHP runtime so its vendor autoloader cannot shadow proxied FQCNs. FilesystemRepository::write now mirrors InstalledVersions::reload into a running worker (class_exists-guarded, so an unloaded class keeps its upstream lazy-load behavior), removing the previously undefined observation window. The installer pipeline passes the installed repository as a shared handle instead of a long-lived `&mut dyn`: plugin registration runs inside InstallationManager::execute and re-enters the same local repository through the RepositoryManager, which would panic on the RefCell re-borrow under the old shape. PluginInterface lifecycle methods now take an owned ComposerHandle (plugins retain $composer past the call) and return anyhow::Result (PHP plugin code may throw); the plugin list uses shared ownership so the identity comparison of removePlugin survives the dual storage in registeredPlugins, matching PHP reference semantics. Ports the activate/upgrade/uninstall tests of PluginInstallerTest, serialized across the shared worker process whose persistent class table is exactly what exercises the rename path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03feat(event-dispatcher): run composer.json PHP scripts through the RPC workernsfisis
Implement the two script execution paths that previously stopped at todo!(): a Class::method listener is invoked as CallStaticMethod with the event crossing the boundary as a proxy-stub handle, and a Command-class listener runs inside a throwaway bare Symfony Application hosted by the worker via a generated snippet, its BufferedOutput written back through the dispatcher's IO. makeAutoloader is ported for real (canonical-package hash, setDevMode, buildPackageMap/parseAutoloads/createLoader), and the class_exists/is_callable/is_a/defined guards now query the worker, whose script autoloader resolves classes by asking the Rust-side ClassLoader over the reverse channel. EventInterface gains as_any (the IOInterface downcast pattern) so the concrete event type is reachable behind the trait object. Application::do_run now registers ScriptAliasCommand entries as typed commands, unblocking the run-script --list/alias tests; the dev-mode-to-generator test is ported with local mockall mocks. The remaining ignored tests carry re-verified reasons: the listener methods live on the PHPUnit test class itself (unloadable in the worker), or the test needs live import of a user PHP Command class into the Application. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20fix(event-dispatcher): un-ignore test_dispatcher_support_for_additional_argsnsfisis
The only missing seam was the PHP test's ReflectionMethod(getPhpExecCommand) access; add the test-only __get_php_exec_command wrapper and port the test on the existing get_listeners override and process-executor mock infrastructure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20test(event-dispatcher): correct dev-mode test ignore reasonnsfisis
The old reason blamed missing mock infrastructure, but a spy against dyn AutoloadGeneratorInterface is perfectly writable. The actual blocker is that make_autoloader (PHP makeAutoloader, called from doDispatch's script branches, where setDevMode is invoked) is an intentional no-op in the port, so set_dev_mode is never reached and a spy would observe nothing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20fix(event-dispatcher): un-ignore test_dispatcher_outputs_commandnsfisis
The ignore reason went stale: the getListeners override seam and a real ProcessExecutor wired to the IO already cover the PHP setup, and IOStub is the PHPUnit IOInterface-mock equivalent. IOStub now records writeError calls (writeRaw was already recorded) so the expects(once)->with(...) spies on writeError/writeRaw can be reproduced as call-list equality assertions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20fix(process-executor): un-ignore 11 tests by implementing execute_async mock ↵nsfisis
support ProcessExecutor::execute_async's mock branch was an unimplemented todo!(), blocking every test whose code path calls it (feature-branch git diffing, system-unzip/7z fallback extraction). Implement it by: - Adding Process::__mock (mirroring the existing ZipArchive::__mock pattern) so execute_async can resolve with a fabricated, already- terminated Process instead of spawning a real subprocess. - Extracting the sync mock's expectation-matching logic into a shared ProcessExecutor::mock_match, wrapping the mock state in a RefCell so it works from execute_async's &self/&mut self receivers. - Setting error_output/capture_output from the mock branch, matching PHP's ProcessExecutorMock::executeAsync sharing doExecute with the sync path; execute_async now takes &mut self for this (safe, since the borrow only needs to live through the synchronous setup, not across the .await). - Turning a strict-mode expectation mismatch from a panic!() into a shirabe_php_shim::RuntimeException Err, mirroring PHPUnit's AssertionFailedError extending \RuntimeException: PHP call sites that catch (\RuntimeException $e) around a mocked git/hg/svn call (e.g. Git::get_mirror_default_branch, GitDriver::supports) treat a mismatch as an ordinary recoverable failure, and now so does the port. The RefMut is dropped before firing an expectation's optional callback so a re-entrant callback doesn't panic on double-borrow. Also fixes two real bugs found while porting test_private_repository_ no_interaction: GitHub::authorize_oauth and GitLab::authorize_oauth checked their domains config via PhpMixed::as_array(), which only matches the Array (map) variant, but github-domains/gitlab-domains default to PhpMixed::List, so the check always returned false and OAuth token lookup was silently skipped. Use the in_array shim instead, matching PHP's in_array() semantics. Also fix Git::run_command's "capture credentials from git remote -v" call, which used the panic- swallowing execute_args wrapper instead of a fallible execute(), so a mock mismatch there couldn't reach get_mirror_default_branch's catch. Un-ignores: - zip_downloader_test::test_system_unzip_only_{good,failed} - zip_downloader_test::test_non_windows_fallback_{good,failed} - event_dispatcher_test::test_dispatcher_outputs_error_on_failed_command - root_package_loader_test::test_feature_branch_pretty_version - version_guesser_test::test_guess_version_reads_and_respects_non_feature_branches_configuration_for_arbitrary_naming{,_regex} - version_guesser_test::test_remote_branches_are_selected - github_driver_test::test_private_repository_no_interaction (also adds the missing #[serial], since it seeds the shared Git::VERSION static that vcs_repository_test::test_load_versions depends on for real) - init_command_test::test_get_git_config, made deterministic by pointing HOME at a throwaway dir with its own .gitconfig instead of depending on the host's global git config Deduplicates the GitVersionGuard/RestoreEnv test-drop-guard idioms into tests/common/test_case.rs instead of reimplementing them per file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16test: update TODO reason for unported test casesnsfisis
No test logic changes.
2026-07-11chore: use fully-qualified name for Rc/RefCellnsfisis
2026-06-28refactor: add linternsfisis
2026-06-27refactor: fix compiler warnings and clippy warningsnsfisis
2026-06-26test: port 70 perforce/repository/downloader/installer/dispatcher testsnsfisis
Port perforce (36), locker (10), composer_repository (7), installation_manager (6), file_downloader (5), and event_dispatcher (6) tests via the mock infra. Fix production porting bugs surfaced en route: BufferIO::get_output look-behind regex, ComposerRepository list-form package iteration and initialize dispatch, gethostname and spl_autoload_functions shims; add EventDispatcher get_listeners test seam. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22test: port more test casesnsfisis
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21test(tests): expand stub macros into plain test functionsnsfisis
The per-file stub!/encode_stub!/etc. macros generated #[ignore]d test functions but obscured the individual test bodies. Expanding them inline removes the macro indirection so future ports can fill in each function directly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21test(tests): port setUp/tearDown as set_up/tear_down with TearDownnsfisis
Port PHP setUp/tearDown across the ported integration tests using same-named set_up()/tear_down() functions and a TearDown struct whose Drop runs tear_down(). Fixture-init setUp returns its fixtures; tmpdir-style setUp/tearDown carry state in TearDown fields. Parts that depend on unported infrastructure (PHPUnit mocks, Config::merge, the PHP error handler) stay todo!() and are only wired into ignored stubs to avoid breaking live tests. Also fix shirabe-php-shim putenv to handle the no-'=' form (PHP unsets the variable), which Platform::clear_env relies on for the env-clearing tearDowns. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21test: port downloader/installer/io/json/event-dispatcher/functional stubsnsfisis
All ignored: these mock IO/HttpDownloader (curl)/ProcessExecutor/installers, use ZipArchive/JsonManipulator todo!()s, need Symfony console or schema validation, reflect into ClassLoader, or run end-to-end install/functional fixtures. Wires up the event_dispatcher test target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21test: add empty test filesnsfisis