From 8dd3d67884a204ca40e3364206868fea77a312be Mon Sep 17 00:00:00 2001 From: nsfisis Date: Thu, 25 Jun 2026 14:57:23 +0900 Subject: feat(test): add HttpDownloaderMock, IOStub, and Config stub helpers IOStub and ConfigStubBuilder provide getMockBuilder-style configurable stubs. Wired into util/repository/downloader/command test targets. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/shirabe/tests/common/config_stub.rs | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 crates/shirabe/tests/common/config_stub.rs (limited to 'crates/shirabe/tests/common/config_stub.rs') diff --git a/crates/shirabe/tests/common/config_stub.rs b/crates/shirabe/tests/common/config_stub.rs new file mode 100644 index 0000000..7566b89 --- /dev/null +++ b/crates/shirabe/tests/common/config_stub.rs @@ -0,0 +1,77 @@ +//! Configurable Config stub, equivalent to PHPUnit's +//! `getMockBuilder(Config::class)` where `get('x')` is stubbed via +//! `->method('get')->willReturn(y)`. +//! +//! `Config` is a concrete (non-trait) struct, so rather than mocking it we build a +//! real `Config` and seed the requested keys through `Config::merge`, which is how +//! `get('key')` actually resolves its value. This keeps the stub faithful to the +//! real resolution logic instead of intercepting `get`. +#![allow(dead_code)] + +use std::cell::RefCell; +use std::rc::Rc; + +use indexmap::IndexMap; +use shirabe::config::Config; +use shirabe_php_shim::PhpMixed; + +pub struct ConfigStubBuilder { + use_environment: bool, + base_dir: Option, + // Config values to seed, applied via Config::merge under the `config` section. + values: IndexMap, + source: String, +} + +impl Default for ConfigStubBuilder { + fn default() -> Self { + Self { + use_environment: false, + base_dir: None, + values: IndexMap::new(), + source: Config::SOURCE_UNKNOWN.to_string(), + } + } +} + +impl ConfigStubBuilder { + pub fn new() -> Self { + Self::default() + } + + pub fn use_environment(mut self, value: bool) -> Self { + self.use_environment = value; + self + } + + pub fn base_dir(mut self, base_dir: impl Into) -> Self { + self.base_dir = Some(base_dir.into()); + self + } + + /// Sets the value `Config::get(key)` will return. Equivalent to PHPUnit's + /// `->method('get')->with(key)->willReturn(value)`. + pub fn with(mut self, key: impl Into, value: PhpMixed) -> Self { + self.values.insert(key.into(), value); + self + } + + pub fn build(self) -> Config { + let mut config = Config::new(self.use_environment, self.base_dir); + if !self.values.is_empty() { + let mut merge: IndexMap = IndexMap::new(); + merge.insert("config".to_string(), PhpMixed::Array(self.values)); + config.merge(&merge, &self.source); + } + config + } + + pub fn build_shared(self) -> Rc> { + Rc::new(RefCell::new(self.build())) + } +} + +// For testing only. Convenience for the common case of a default `Config(false)`. +pub fn get_config_stub() -> Config { + ConfigStubBuilder::new().build() +} -- cgit v1.3.1