aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/command/init_command.rs
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/src/command/init_command.rs
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/src/command/init_command.rs')
-rw-r--r--crates/shirabe/src/command/init_command.rs33
1 files changed, 15 insertions, 18 deletions
diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs
index a04836d..68b4b69 100644
--- a/crates/shirabe/src/command/init_command.rs
+++ b/crates/shirabe/src/command/init_command.rs
@@ -623,28 +623,25 @@ impl Command for InitCommand {
}
),
// PHP: function ($value) use ($self, $author) { ... $author = $self->parseAuthorString($value); ... }
- // TODO(phase-c): IOInterface::ask_and_validate takes a `Box<dyn Fn> + 'static`
- // validator, so it cannot borrow &self to call self.parse_author_string; and
- // ask_and_validate itself is a deferred QuestionHelper todo!() (see console_io). The
- // validator body below therefore stays a placeholder. (parse_author_string and
- // is_valid_email are stateless, so a future fix can make them associated functions and
- // call them from the closure once the helper interaction is modelled.)
+ // The validator is a `'static` closure and cannot borrow `&self`, but
+ // parse_author_string is stateless (it only delegates to the stateless
+ // is_valid_email), so a fresh InitCommand stands in for `$self` here.
Box::new(move |value: PhpMixed| -> anyhow::Result<PhpMixed> {
- let value_str = value.as_string().unwrap_or("").to_string();
- if value_str == "n" || value_str == "no" {
+ let value_str = value.as_string().map(|s| s.to_string());
+ if value_str.as_deref() == Some("n") || value_str.as_deref() == Some("no") {
return Ok(PhpMixed::Null);
}
- let value_or_default = if value_str.is_empty() {
- author_for_validate.clone()
- } else {
- value_str
+ // PHP: $value = $value ?: $author
+ let value = match &value_str {
+ Some(s) if !s.is_empty() => s.clone(),
+ _ => author_for_validate.clone(),
};
- // PHP: $author = $self->parseAuthorString($value); return $author['email'] === null
- // ? $author['name'] : sprintf('%s <%s>', $author['name'], $author['email']);
- // TODO(phase-c): see the closure note above — cannot reach parse_author_string from
- // this 'static validator yet.
- let _ = value_or_default;
- Ok(PhpMixed::Null)
+ let parsed = InitCommand::new().parse_author_string(&value)?;
+ let name = parsed.get("name").cloned().flatten().unwrap_or_default();
+ match parsed.get("email").cloned().flatten() {
+ None => Ok(PhpMixed::String(name)),
+ Some(email) => Ok(PhpMixed::String(format!("{} <{}>", name, email))),
+ }
}),
None,
PhpMixed::String(author_default),