[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/i18n/RFC.md fully. Find ONE feature... #74

Merged
Virgil merged 1 commit from agent/read---spec-code-core-go-i18n-rfc-md-ful into dev 2026-04-02 01:41:52 +00:00
3 changed files with 42 additions and 5 deletions

View file

@ -1,6 +1,7 @@
package i18n
import (
"fmt"
"strings"
"unicode"
@ -29,7 +30,7 @@ func (h ProgressHandler) Match(key string) bool {
func (h ProgressHandler) Handle(key string, args []any, next func() string) string {
verb := core.TrimPrefix(key, "i18n.progress.")
if len(args) > 0 {
if subj, ok := args[0].(string); ok {
if subj := subjectArgText(args[0]); subj != "" {
return ProgressSubject(verb, subj)
}
}
@ -47,7 +48,7 @@ func (h CountHandler) Handle(key string, args []any, next func() string) string
noun := core.TrimPrefix(key, "i18n.count.")
lang := currentLangForGrammar()
if len(args) > 0 {
count := toInt(args[0])
count := getCount(args[0])
return core.Sprintf("%s %s", FormatNumber(int64(count)), countWordForm(lang, noun, count))
}
return renderWord(lang, noun)
@ -63,7 +64,7 @@ func (h DoneHandler) Match(key string) bool {
func (h DoneHandler) Handle(key string, args []any, next func() string) string {
verb := core.TrimPrefix(key, "i18n.done.")
if len(args) > 0 {
if subj, ok := args[0].(string); ok {
if subj := subjectArgText(args[0]); subj != "" {
return ActionResult(verb, subj)
}
}
@ -80,7 +81,7 @@ func (h FailHandler) Match(key string) bool {
func (h FailHandler) Handle(key string, args []any, next func() string) string {
verb := core.TrimPrefix(key, "i18n.fail.")
if len(args) > 0 {
if subj, ok := args[0].(string); ok {
if subj := subjectArgText(args[0]); subj != "" {
return ActionFailed(verb, subj)
}
}
@ -197,6 +198,22 @@ func isAllUpper(s string) bool {
return hasLetter
}
func subjectArgText(arg any) string {
switch v := arg.(type) {
case string:
return v
case *Subject:
if v == nil {
return ""
}
return v.String()
case fmt.Stringer:
return v.String()
default:
return ""
}
}
// RunHandlerChain executes a chain of handlers for a key.
func RunHandlerChain(handlers []KeyHandler, key string, args []any, fallback func() string) string {
for i, h := range handlers {

View file

@ -48,6 +48,11 @@ func TestProgressHandler(t *testing.T) {
if got != "Building project..." {
t.Errorf("ProgressHandler.Handle(build, project) = %q, want %q", got, "Building project...")
}
got = h.Handle("i18n.progress.build", []any{S("project", "config.yaml")}, nil)
if got != "Building config.yaml..." {
t.Errorf("ProgressHandler.Handle(build, Subject) = %q, want %q", got, "Building config.yaml...")
}
}
func TestCountHandler(t *testing.T) {
@ -87,6 +92,11 @@ func TestCountHandler(t *testing.T) {
}
})
}
got := h.Handle("i18n.count.file", []any{S("file", "config.yaml").Count(3)}, nil)
if got != "3 files" {
t.Errorf("CountHandler.Handle(file, Subject.Count(3)) = %q, want %q", got, "3 files")
}
}
func TestDoneHandler(t *testing.T) {
@ -108,6 +118,11 @@ func TestDoneHandler(t *testing.T) {
t.Errorf("DoneHandler.Handle(delete, config.yaml) = %q, want %q", got, "Config.yaml deleted")
}
got = h.Handle("i18n.done.delete", []any{S("file", "config.yaml")}, nil)
if got != "Config.yaml deleted" {
t.Errorf("DoneHandler.Handle(delete, Subject) = %q, want %q", got, "Config.yaml deleted")
}
// Without subject — just past tense
got = h.Handle("i18n.done.delete", nil, nil)
if got != "Deleted" {
@ -127,6 +142,11 @@ func TestFailHandler(t *testing.T) {
t.Errorf("FailHandler.Handle(push, commits) = %q, want %q", got, "Failed to push commits")
}
got = h.Handle("i18n.fail.push", []any{S("commit", "commits")}, nil)
if got != "Failed to push commits" {
t.Errorf("FailHandler.Handle(push, Subject) = %q, want %q", got, "Failed to push commits")
}
got = h.Handle("i18n.fail.push", nil, nil)
if got != "Failed to push" {
t.Errorf("FailHandler.Handle(push) = %q, want %q", got, "Failed to push")

View file

@ -19,7 +19,7 @@ func getCount(data any) int {
return c
}
}
return 0
return toInt(data)
}
func toInt(v any) int {