aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-external-packages/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-23 03:49:00 +0900
committernsfisis <nsfisis@gmail.com>2026-06-23 03:49:29 +0900
commit8fe3390d064303b86133a1d2983144a4818a7121 (patch)
tree3d7979e8fcce3db28ec9edc9b1ce16a593026454 /crates/shirabe-external-packages/src
parentc644aa4df0dfcd58e3f0a1372611921678ed6c6d (diff)
downloadphp-shirabe-8fe3390d064303b86133a1d2983144a4818a7121.tar.gz
php-shirabe-8fe3390d064303b86133a1d2983144a4818a7121.tar.zst
php-shirabe-8fe3390d064303b86133a1d2983144a4818a7121.zip
test(command): port InitCommandTest
Port the pure-method cases (parse/namespace/formatAuthors/git/vendor-ignore) and build the ApplicationTester / initTempComposer harness the run cases need. Supporting production changes: - carry the streamable input stream as PhpResource (not PhpMixed) and add InputInterface::as_streamable so QuestionHelper reads the injected stream - add StreamOutput/ConsoleOutput __set_stream test helpers and ApplicationHandle::set_catch_exceptions for the tester - implement the interact() author validator via parse_author_string Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-external-packages/src')
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs16
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/argv_input.rs8
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/array_input.rs15
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/input.rs17
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs7
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/input/streamable_input_interface.rs6
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/output/console_output.rs7
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs7
8 files changed, 58 insertions, 25 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs
index f2c2a00..9eb8fff 100644
--- a/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/helper/question_helper.rs
@@ -66,12 +66,11 @@ impl QuestionHelper {
return Ok(Ok(self.get_default_answer(question)));
}
- // TODO(phase-b): `$input instanceof StreamableInputInterface` cannot be
- // expressed as a trait-object-to-trait-object downcast, and no concrete
- // streamable input type is wired up yet. The stream is left unset so the
- // helper falls back to STDIN. Revisit once StreamableInputInterface has a
- // concrete implementor and the PhpResource/PhpMixed split is resolved.
- let _ = &mut self.input_stream;
+ if let Some(streamable) = input.as_streamable()
+ && let Some(stream) = streamable.get_stream()
+ {
+ self.input_stream = Some(stream);
+ }
let result: anyhow::Result<Result<PhpMixed, MissingInputException>> = (|| {
if question.get_validator().is_none() {
@@ -344,10 +343,7 @@ impl QuestionHelper {
input_stream: &shirabe_php_shim::PhpResource,
autocomplete: &dyn Fn(&str) -> Vec<PhpMixed>,
) -> String {
- // TODO(phase-b): Cursor takes Option<PhpMixed>, but the input stream is a
- // PhpResource and PhpMixed has no resource variant. Defaulting to STDIN
- // until the PhpResource/PhpMixed stream representation is unified.
- let cursor = Cursor::new(Rc::clone(&output), None);
+ let cursor = Cursor::new(Rc::clone(&output), Some(input_stream.clone()));
let mut full_choice = String::new();
let mut ret = String::new();
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/argv_input.rs b/crates/shirabe-external-packages/src/symfony/console/input/argv_input.rs
index d7ddafc..0784c7b 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/argv_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/argv_input.rs
@@ -619,14 +619,18 @@ impl InputInterface for ArgvInput {
fn set_interactive(&mut self, interactive: bool) {
self.inner.set_interactive(interactive)
}
+
+ fn as_streamable(&self) -> Option<&dyn StreamableInputInterface> {
+ Some(self)
+ }
}
impl StreamableInputInterface for ArgvInput {
- fn set_stream(&mut self, stream: PhpMixed) {
+ fn set_stream(&mut self, stream: shirabe_php_shim::PhpResource) {
self.inner.set_stream(stream)
}
- fn get_stream(&self) -> Option<PhpMixed> {
+ fn get_stream(&self) -> Option<shirabe_php_shim::PhpResource> {
self.inner.get_stream()
}
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs b/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
index 3fc9abb..327650b 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/array_input.rs
@@ -5,6 +5,7 @@ use crate::symfony::console::exception::invalid_option_exception::InvalidOptionE
use crate::symfony::console::input::input::Input;
use crate::symfony::console::input::input_definition::InputDefinition;
use crate::symfony::console::input::input_interface::InputInterface;
+use crate::symfony::console::input::streamable_input_interface::StreamableInputInterface;
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
@@ -373,6 +374,20 @@ impl InputInterface for ArrayInput {
fn set_interactive(&mut self, interactive: bool) {
self.inner.set_interactive(interactive)
}
+
+ fn as_streamable(&self) -> Option<&dyn StreamableInputInterface> {
+ Some(self)
+ }
+}
+
+impl StreamableInputInterface for ArrayInput {
+ fn set_stream(&mut self, stream: shirabe_php_shim::PhpResource) {
+ self.inner.set_stream(stream)
+ }
+
+ fn get_stream(&self) -> Option<shirabe_php_shim::PhpResource> {
+ self.inner.get_stream()
+ }
}
/// PHP `(array) $values` cast: a string becomes a single-element array.
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/input.rs b/crates/shirabe-external-packages/src/symfony/console/input/input.rs
index d13ab6c..d365f8d 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/input.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/input.rs
@@ -4,7 +4,7 @@ use crate::symfony::console::exception::invalid_argument_exception::InvalidArgum
use crate::symfony::console::exception::runtime_exception::RuntimeException;
use crate::symfony::console::input::input_definition::InputDefinition;
use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
+use shirabe_php_shim::{PhpMixed, PhpResource};
/// Input is the base class for all concrete Input classes.
///
@@ -16,7 +16,7 @@ use shirabe_php_shim::PhpMixed;
#[derive(Debug, Clone)]
pub struct Input {
pub(crate) definition: InputDefinition,
- pub(crate) stream: PhpMixed,
+ pub(crate) stream: Option<PhpResource>,
pub(crate) options: IndexMap<String, PhpMixed>,
pub(crate) arguments: IndexMap<String, PhpMixed>,
pub(crate) interactive: bool,
@@ -26,7 +26,7 @@ impl Input {
pub fn new(definition: Option<InputDefinition>) -> anyhow::Result<Self> {
let mut input = Input {
definition: InputDefinition::new(vec![])?,
- stream: PhpMixed::Null,
+ stream: None,
options: IndexMap::new(),
arguments: IndexMap::new(),
interactive: true,
@@ -238,14 +238,11 @@ impl Input {
}
}
- pub fn set_stream(&mut self, stream: PhpMixed) {
- self.stream = stream;
+ pub fn set_stream(&mut self, stream: PhpResource) {
+ self.stream = Some(stream);
}
- pub fn get_stream(&self) -> Option<PhpMixed> {
- match &self.stream {
- PhpMixed::Null => None,
- other => Some(other.clone()),
- }
+ pub fn get_stream(&self) -> Option<PhpResource> {
+ self.stream.clone()
}
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs b/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
index c115df0..ccb5a98 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/input_interface.rs
@@ -1,6 +1,7 @@
//! ref: composer/vendor/symfony/console/Input/InputInterface.php
use crate::symfony::console::input::input_definition::InputDefinition;
+use crate::symfony::console::input::streamable_input_interface::StreamableInputInterface;
use shirabe_php_shim::PhpMixed;
pub trait InputInterface: std::fmt::Debug + shirabe_php_shim::AsAny {
@@ -41,4 +42,10 @@ pub trait InputInterface: std::fmt::Debug + shirabe_php_shim::AsAny {
fn is_interactive(&self) -> bool;
fn set_interactive(&mut self, interactive: bool);
+
+ /// Models PHP's `$input instanceof StreamableInputInterface` check. Streamable inputs override
+ /// this to return `Some(self)`; everything else falls back to `None`.
+ fn as_streamable(&self) -> Option<&dyn StreamableInputInterface> {
+ None
+ }
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/input/streamable_input_interface.rs b/crates/shirabe-external-packages/src/symfony/console/input/streamable_input_interface.rs
index f687e0e..d4bdbfd 100644
--- a/crates/shirabe-external-packages/src/symfony/console/input/streamable_input_interface.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/input/streamable_input_interface.rs
@@ -1,10 +1,10 @@
//! ref: composer/vendor/symfony/console/Input/StreamableInputInterface.php
use crate::symfony::console::input::input_interface::InputInterface;
-use shirabe_php_shim::PhpMixed;
+use shirabe_php_shim::PhpResource;
pub trait StreamableInputInterface: InputInterface {
- fn set_stream(&mut self, stream: PhpMixed);
+ fn set_stream(&mut self, stream: PhpResource);
- fn get_stream(&self) -> Option<PhpMixed>;
+ fn get_stream(&self) -> Option<PhpResource>;
}
diff --git a/crates/shirabe-external-packages/src/symfony/console/output/console_output.rs b/crates/shirabe-external-packages/src/symfony/console/output/console_output.rs
index 0808fef..dd6840d 100644
--- a/crates/shirabe-external-packages/src/symfony/console/output/console_output.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/output/console_output.rs
@@ -110,6 +110,13 @@ impl ConsoleOutput {
shirabe_php_shim::stripos(&shirabe_php_shim::implode(";", &checks), "OS400").is_some()
}
+ /// For testing only. Overwrites the inner `StreamOutput`'s private `stream` field, mirroring
+ /// what `Symfony\Component\Console\Tester\TesterTrait::initOutput` does via reflection on the
+ /// parent `StreamOutput::$stream` property of a `ConsoleOutput`.
+ pub fn __set_stream(&mut self, stream: shirabe_php_shim::PhpResource) {
+ self.inner.__set_stream(stream);
+ }
+
fn open_output_stream() -> shirabe_php_shim::PhpResource {
if !Self::has_stdout_support() {
return shirabe_php_shim::php_fopen_resource("php://output", "w");
diff --git a/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs b/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
index 569b348..fa63557 100644
--- a/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
+++ b/crates/shirabe-external-packages/src/symfony/console/output/stream_output.rs
@@ -66,6 +66,13 @@ impl StreamOutput {
&self.stream
}
+ /// For testing only. Overwrites the private `stream` field, mirroring what
+ /// `Symfony\Component\Console\Tester\TesterTrait::initOutput` does via reflection on the
+ /// `StreamOutput::$stream` property.
+ pub fn __set_stream(&mut self, stream: shirabe_php_shim::PhpResource) {
+ self.stream = stream;
+ }
+
/// Returns true if the stream supports colorization.
///
/// Colorization is disabled if not supported by the stream: