rename: rebrand to mire

This commit is contained in:
2026-03-21 12:49:57 +00:00
parent d72f727322
commit 511a4c912c
32 changed files with 209 additions and 209 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
/AGENTS.md /AGENTS.md
/build/ /build/
/e2e/ /e2e/
/miro.toml /mire.toml
+2 -2
View File
@@ -1,10 +1,10 @@
.PHONY: build test .PHONY: build test
BIN := build/miro BIN := build/mire
build: build:
mkdir -p build mkdir -p build
go build -o $(BIN) ./cmd/miro go build -o $(BIN) ./cmd/mire
test: test:
go test ./... go test ./...
+3 -3
View File
@@ -1,8 +1,8 @@
package cmd package cmd
import ( import (
"miro/internal/miro" "mire/internal/mire"
"miro/internal/output" "mire/internal/output"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -12,7 +12,7 @@ func newInitCommand() *cobra.Command {
Use: "init", Use: "init",
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, _ []string) error { RunE: func(_ *cobra.Command, _ []string) error {
if err := miro.Init(); err != nil { if err := mire.Init(); err != nil {
return err return err
} }
+1 -1
View File
@@ -3,7 +3,7 @@ package main
import ( import (
"os" "os"
"miro/cmd" "mire/cmd"
) )
func main() { func main() {
+4 -4
View File
@@ -4,8 +4,8 @@ import (
"errors" "errors"
"path/filepath" "path/filepath"
"miro/internal/miro" "mire/internal/mire"
"miro/internal/output" "mire/internal/output"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -16,9 +16,9 @@ func newRecordCommand() *cobra.Command {
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, args []string) error { RunE: func(_ *cobra.Command, args []string) error {
path := filepath.Clean(args[0]) path := filepath.Clean(args[0])
createdPath, err := miro.Record(path) createdPath, err := mire.Record(path)
if err != nil { if err != nil {
if errors.Is(err, miro.ErrRecordingDiscarded) { if errors.Is(err, mire.ErrRecordingDiscarded) {
return nil return nil
} }
return err return err
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// Run executes the miro CLI and returns a process exit code. // Run executes the mire CLI and returns a process exit code.
func Run(args []string) int { func Run(args []string) int {
if err := ensureDependencies(); err != nil { if err := ensureDependencies(); err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
@@ -27,7 +27,7 @@ func Run(args []string) int {
func newRootCommand() *cobra.Command { func newRootCommand() *cobra.Command {
rootCmd := &cobra.Command{ rootCmd := &cobra.Command{
Use: "miro", Use: "mire",
Short: "A lean CLI E2E testing framework.", Short: "A lean CLI E2E testing framework.",
RunE: func(cmd *cobra.Command, _ []string) error { RunE: func(cmd *cobra.Command, _ []string) error {
return cmd.Help() return cmd.Help()
+10 -10
View File
@@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestRunShowsHelpWhenNoArgs(t *testing.T) { func TestRunShowsHelpWhenNoArgs(t *testing.T) {
@@ -49,7 +49,7 @@ func TestRunInit(t *testing.T) {
return struct{}{} return struct{}{}
}) })
if got := testutil.ReadFile(t, filepath.Join(root, "miro.toml")); got != testutil.DefaultWrittenConfig("e2e") { if got := testutil.ReadFile(t, filepath.Join(root, "mire.toml")); got != testutil.DefaultWrittenConfig("e2e") {
t.Fatalf("config = %q, want %q", got, testutil.DefaultWrittenConfig("e2e")) t.Fatalf("config = %q, want %q", got, testutil.DefaultWrittenConfig("e2e"))
} }
info, err := os.Stat(filepath.Join(root, "e2e", "shell.sh")) info, err := os.Stat(filepath.Join(root, "e2e", "shell.sh"))
@@ -121,8 +121,8 @@ func TestRunInitFailsWhenDependenciesMissing(t *testing.T) {
if !strings.Contains(stderr, `required command "script" not found in PATH`) { if !strings.Contains(stderr, `required command "script" not found in PATH`) {
t.Fatalf("stderr = %q, want missing dependency error", stderr) t.Fatalf("stderr = %q, want missing dependency error", stderr)
} }
if _, err := os.Stat(filepath.Join(root, "miro.toml")); !os.IsNotExist(err) { if _, err := os.Stat(filepath.Join(root, "mire.toml")); !os.IsNotExist(err) {
t.Fatalf("Stat(%q) error = %v, want not exists", filepath.Join(root, "miro.toml"), err) t.Fatalf("Stat(%q) error = %v, want not exists", filepath.Join(root, "mire.toml"), err)
} }
if _, err := os.Stat(filepath.Join(root, "e2e", "shell.sh")); !os.IsNotExist(err) { if _, err := os.Stat(filepath.Join(root, "e2e", "shell.sh")); !os.IsNotExist(err) {
t.Fatalf("Stat(%q) error = %v, want not exists", filepath.Join(root, "e2e", "shell.sh"), err) t.Fatalf("Stat(%q) error = %v, want not exists", filepath.Join(root, "e2e", "shell.sh"), err)
@@ -146,7 +146,7 @@ func TestRunRecordMissingPath(t *testing.T) {
if !strings.Contains(stderr, "accepts 1 arg(s), received 0") { if !strings.Contains(stderr, "accepts 1 arg(s), received 0") {
t.Fatalf("stderr = %q, want argument error", stderr) t.Fatalf("stderr = %q, want argument error", stderr)
} }
if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "miro record <path>") { if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "mire record <path>") {
t.Fatalf("stderr = %q, want record usage", stderr) t.Fatalf("stderr = %q, want record usage", stderr)
} }
} }
@@ -212,7 +212,7 @@ func TestRunTestExtraArgs(t *testing.T) {
if !strings.Contains(stderr, "accepts at most 1 arg(s), received 2") { if !strings.Contains(stderr, "accepts at most 1 arg(s), received 2") {
t.Fatalf("stderr = %q, want extra-arg error", stderr) t.Fatalf("stderr = %q, want extra-arg error", stderr)
} }
if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "miro test [path]") { if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "mire test [path]") {
t.Fatalf("stderr = %q, want test usage", stderr) t.Fatalf("stderr = %q, want test usage", stderr)
} }
} }
@@ -229,10 +229,10 @@ func TestRunInitExtraArgs(t *testing.T) {
if stdout != "" { if stdout != "" {
t.Fatalf("stdout = %q, want empty", stdout) t.Fatalf("stdout = %q, want empty", stdout)
} }
if !strings.Contains(stderr, "unknown command \"extra\" for \"miro init\"") { if !strings.Contains(stderr, "unknown command \"extra\" for \"mire init\"") {
t.Fatalf("stderr = %q, want extra-arg error", stderr) t.Fatalf("stderr = %q, want extra-arg error", stderr)
} }
if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "miro init") { if !strings.Contains(stderr, "Usage:") || !strings.Contains(stderr, "mire init") {
t.Fatalf("stderr = %q, want init usage", stderr) t.Fatalf("stderr = %q, want init usage", stderr)
} }
} }
@@ -249,11 +249,11 @@ func TestRunUnknownCommand(t *testing.T) {
if stdout != "" { if stdout != "" {
t.Fatalf("stdout = %q, want empty", stdout) t.Fatalf("stdout = %q, want empty", stdout)
} }
if !strings.Contains(stderr, "unknown command \"wat\" for \"miro\"") { if !strings.Contains(stderr, "unknown command \"wat\" for \"mire\"") {
t.Fatalf("stderr = %q, want unknown command error", stderr) t.Fatalf("stderr = %q, want unknown command error", stderr)
} }
} }
func prefixed(msg string) string { func prefixed(msg string) string {
return "miro " + msg return "mire " + msg
} }
+2 -2
View File
@@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"miro/internal/miro" "mire/internal/mire"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -16,7 +16,7 @@ func newTestCommand() *cobra.Command {
path = args[0] path = args[0]
} }
return miro.RunTests(path) return mire.RunTests(path)
}, },
} }
} }
+1 -1
View File
@@ -1,4 +1,4 @@
module miro module mire
go 1.25.5 go 1.25.5
+13 -13
View File
@@ -27,11 +27,11 @@ type Config struct {
} }
type tomlConfig struct { type tomlConfig struct {
Miro tomlMiroConfig `toml:"miro"` Mire tomlMireConfig `toml:"mire"`
Sandbox map[string]string `toml:"sandbox"` Sandbox map[string]string `toml:"sandbox"`
} }
type tomlMiroConfig struct { type tomlMireConfig struct {
TestDir string `toml:"test_dir"` TestDir string `toml:"test_dir"`
} }
@@ -39,7 +39,7 @@ func DefaultSandboxConfig() map[string]string {
return cloneSandbox(requiredSandboxDefaults) return cloneSandbox(requiredSandboxDefaults)
} }
// ReadConfig reads miro.toml. // ReadConfig reads mire.toml.
func ReadConfig(path string) (Config, error) { func ReadConfig(path string) (Config, error) {
var raw tomlConfig var raw tomlConfig
@@ -50,14 +50,14 @@ func ReadConfig(path string) (Config, error) {
} }
return Config{}, fmt.Errorf("failed to read %s: %v", path, err) return Config{}, fmt.Errorf("failed to read %s: %v", path, err)
} }
if !meta.IsDefined("miro") { if !meta.IsDefined("mire") {
return Config{}, fmt.Errorf("failed to read %s: missing [miro] config", path) return Config{}, fmt.Errorf("failed to read %s: missing [mire] config", path)
} }
if !meta.IsDefined("miro", "test_dir") { if !meta.IsDefined("mire", "test_dir") {
return Config{}, fmt.Errorf("failed to read %s: missing required miro.test_dir", path) return Config{}, fmt.Errorf("failed to read %s: missing required mire.test_dir", path)
} }
if raw.Miro.TestDir == "" { if raw.Mire.TestDir == "" {
return Config{}, fmt.Errorf("failed to read %s: empty miro.test_dir", path) return Config{}, fmt.Errorf("failed to read %s: empty mire.test_dir", path)
} }
if !meta.IsDefined("sandbox") { if !meta.IsDefined("sandbox") {
return Config{}, fmt.Errorf("failed to read %s: missing [sandbox] config", path) return Config{}, fmt.Errorf("failed to read %s: missing [sandbox] config", path)
@@ -69,15 +69,15 @@ func ReadConfig(path string) (Config, error) {
} }
return Config{ return Config{
TestDir: raw.Miro.TestDir, TestDir: raw.Mire.TestDir,
Sandbox: sandbox, Sandbox: sandbox,
}, nil }, nil
} }
// WriteConfig writes miro.toml. // WriteConfig writes mire.toml.
func WriteConfig(path string, cfg Config) error { func WriteConfig(path string, cfg Config) error {
if cfg.TestDir == "" { if cfg.TestDir == "" {
return errors.New("empty miro.test_dir") return errors.New("empty mire.test_dir")
} }
sandbox, err := validateSandbox(path, cfg.Sandbox) sandbox, err := validateSandbox(path, cfg.Sandbox)
if err != nil { if err != nil {
@@ -85,7 +85,7 @@ func WriteConfig(path string, cfg Config) error {
} }
var buf bytes.Buffer var buf bytes.Buffer
fmt.Fprintf(&buf, "[miro]\n test_dir = %q\n\n[sandbox]\n", cfg.TestDir) fmt.Fprintf(&buf, "[mire]\n test_dir = %q\n\n[sandbox]\n", cfg.TestDir)
keys := make([]string, 0, len(sandbox)) keys := make([]string, 0, len(sandbox))
for key := range sandbox { for key := range sandbox {
+21 -21
View File
@@ -19,7 +19,7 @@ func TestReadConfig(t *testing.T) {
}{ }{
{ {
name: "with test dir and sandbox", name: "with test dir and sandbox",
content: "[miro]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"/home/test\"\nkey_word = \"value\"\n", content: "[mire]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"/home/test\"\nkey_word = \"value\"\n",
wantDir: "custom/suite", wantDir: "custom/suite",
wantSandbox: map[string]string{ wantSandbox: map[string]string{
"visible_home": "/home/test", "visible_home": "/home/test",
@@ -29,51 +29,51 @@ func TestReadConfig(t *testing.T) {
{ {
name: "legacy top level key", name: "legacy top level key",
content: "test_dir = \"custom/suite\"\n", content: "test_dir = \"custom/suite\"\n",
wantErr: "missing [miro] config", wantErr: "missing [mire] config",
}, },
{ {
name: "without miro table", name: "without mire table",
content: "", content: "",
wantErr: "missing [miro] config", wantErr: "missing [mire] config",
}, },
{ {
name: "without test dir", name: "without test dir",
content: "[miro]\n", content: "[mire]\n",
wantErr: "missing required miro.test_dir", wantErr: "missing required mire.test_dir",
}, },
{ {
name: "empty test dir", name: "empty test dir",
content: "[miro]\ntest_dir = \"\"\n", content: "[mire]\ntest_dir = \"\"\n",
wantErr: "empty miro.test_dir", wantErr: "empty mire.test_dir",
}, },
{ {
name: "without sandbox table", name: "without sandbox table",
content: "[miro]\ntest_dir = \"custom/suite\"\n", content: "[mire]\ntest_dir = \"custom/suite\"\n",
wantErr: "missing [sandbox] config", wantErr: "missing [sandbox] config",
}, },
{ {
name: "without required visible home", name: "without required visible home",
content: "[miro]\ntest_dir = \"custom/suite\"\n\n[sandbox]\n", content: "[mire]\ntest_dir = \"custom/suite\"\n\n[sandbox]\n",
wantErr: "missing required sandbox.visible_home", wantErr: "missing required sandbox.visible_home",
}, },
{ {
name: "empty required visible home", name: "empty required visible home",
content: "[miro]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"\"\n", content: "[mire]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"\"\n",
wantErr: "empty sandbox.visible_home", wantErr: "empty sandbox.visible_home",
}, },
{ {
name: "relative visible home", name: "relative visible home",
content: "[miro]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"home/test\"\n", content: "[mire]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"home/test\"\n",
wantErr: "sandbox.visible_home must be an absolute path", wantErr: "sandbox.visible_home must be an absolute path",
}, },
{ {
name: "invalid sandbox key", name: "invalid sandbox key",
content: "[miro]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"/home/test\"\nKeyWord = \"value\"\n", content: "[mire]\ntest_dir = \"custom/suite\"\n\n[sandbox]\nvisible_home = \"/home/test\"\nKeyWord = \"value\"\n",
wantErr: "invalid sandbox key", wantErr: "invalid sandbox key",
}, },
{ {
name: "invalid toml", name: "invalid toml",
content: "[miro]\ntest_dir = [\n", content: "[mire]\ntest_dir = [\n",
wantErr: "failed to read", wantErr: "failed to read",
}, },
{ {
@@ -84,7 +84,7 @@ func TestReadConfig(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
path := filepath.Join(t.TempDir(), "miro.toml") path := filepath.Join(t.TempDir(), "mire.toml")
if !tt.wantMissing { if !tt.wantMissing {
if err := os.WriteFile(path, []byte(tt.content), 0o644); err != nil { if err := os.WriteFile(path, []byte(tt.content), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err) t.Fatalf("WriteFile() error = %v", err)
@@ -126,7 +126,7 @@ func TestReadConfig(t *testing.T) {
} }
func TestWriteConfig(t *testing.T) { func TestWriteConfig(t *testing.T) {
path := filepath.Join(t.TempDir(), "miro.toml") path := filepath.Join(t.TempDir(), "mire.toml")
if err := WriteConfig(path, Config{ if err := WriteConfig(path, Config{
TestDir: "e2e", TestDir: "e2e",
@@ -143,26 +143,26 @@ func TestWriteConfig(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("ReadFile() error = %v", err) t.Fatalf("ReadFile() error = %v", err)
} }
want := "[miro]\n test_dir = \"e2e\"\n\n[sandbox]\n alpha_key = \"a\"\n visible_home = \"/home/test\"\n zulu_key = \"z\"\n" want := "[mire]\n test_dir = \"e2e\"\n\n[sandbox]\n alpha_key = \"a\"\n visible_home = \"/home/test\"\n zulu_key = \"z\"\n"
if string(got) != want { if string(got) != want {
t.Fatalf("config = %q, want %q", string(got), want) t.Fatalf("config = %q, want %q", string(got), want)
} }
} }
func TestWriteConfigEmptyTestDirFails(t *testing.T) { func TestWriteConfigEmptyTestDirFails(t *testing.T) {
path := filepath.Join(t.TempDir(), "miro.toml") path := filepath.Join(t.TempDir(), "mire.toml")
err := WriteConfig(path, Config{}) err := WriteConfig(path, Config{})
if err == nil { if err == nil {
t.Fatal("WriteConfig() error = nil, want error") t.Fatal("WriteConfig() error = nil, want error")
} }
if err.Error() != "empty miro.test_dir" { if err.Error() != "empty mire.test_dir" {
t.Fatalf("WriteConfig() error = %q, want %q", err.Error(), "empty miro.test_dir") t.Fatalf("WriteConfig() error = %q, want %q", err.Error(), "empty mire.test_dir")
} }
} }
func TestWriteConfigMissingRequiredSandboxFails(t *testing.T) { func TestWriteConfigMissingRequiredSandboxFails(t *testing.T) {
path := filepath.Join(t.TempDir(), "miro.toml") path := filepath.Join(t.TempDir(), "mire.toml")
err := WriteConfig(path, Config{ err := WriteConfig(path, Config{
TestDir: "e2e", TestDir: "e2e",
@@ -1,4 +1,4 @@
package miro package mire
var ( var (
ErrRecordingDiscarded = RecordingDiscardedError{} ErrRecordingDiscarded = RecordingDiscardedError{}
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"errors" "errors"
@@ -6,7 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
miroconfig "miro/internal/config" mireconfig "mire/internal/config"
) )
const defaultTestDir = "e2e" const defaultTestDir = "e2e"
@@ -18,17 +18,17 @@ func Init() error {
return err return err
} }
configPath := filepath.Join(root, "miro.toml") configPath := filepath.Join(root, "mire.toml")
if _, err := os.Stat(configPath); err == nil { if _, err := os.Stat(configPath); err == nil {
if _, err := miroconfig.ReadConfig(configPath); err != nil { if _, err := mireconfig.ReadConfig(configPath); err != nil {
return err return err
} }
} else if !errors.Is(err, os.ErrNotExist) { } else if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("failed to check %s: %v", configPath, err) return fmt.Errorf("failed to check %s: %v", configPath, err)
} else { } else {
if err := miroconfig.WriteConfig(configPath, miroconfig.Config{ if err := mireconfig.WriteConfig(configPath, mireconfig.Config{
TestDir: defaultTestDir, TestDir: defaultTestDir,
Sandbox: miroconfig.DefaultSandboxConfig(), Sandbox: mireconfig.DefaultSandboxConfig(),
}); err != nil { }); err != nil {
return fmt.Errorf("failed to write %s: %v", configPath, err) return fmt.Errorf("failed to write %s: %v", configPath, err)
} }
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"fmt" "fmt"
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"os" "os"
@@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestResolvePathWithinTestDirAcceptsRelativePath(t *testing.T) { func TestResolvePathWithinTestDirAcceptsRelativePath(t *testing.T) {
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bytes" "bytes"
@@ -1,10 +1,10 @@
package miro package mire
import ( import (
"path/filepath" "path/filepath"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestLoadRecordedInputTrimsTrailingNewlineAfterEOF(t *testing.T) { func TestLoadRecordedInputTrimsTrailingNewlineAfterEOF(t *testing.T) {
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"fmt" "fmt"
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bufio" "bufio"
@@ -8,7 +8,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"miro/internal/output" "mire/internal/output"
) )
type recordIO struct { type recordIO struct {
@@ -68,7 +68,7 @@ func recordScenario(target, shellPath string, rio recordIO, sandboxConfig map[st
} }
func newRecordFiles() (string, string, func(), error) { func newRecordFiles() (string, string, func(), error) {
dir, err := os.MkdirTemp("", "miro-record-") dir, err := os.MkdirTemp("", "mire-record-")
if err != nil { if err != nil {
return "", "", nil, err return "", "", nil, err
} }
@@ -91,7 +91,7 @@ func newRecordSandbox() (recordSandbox, func(), error) {
} }
func newRecordSandboxForPathEnv(pathEnv string) (recordSandbox, func(), error) { func newRecordSandboxForPathEnv(pathEnv string) (recordSandbox, func(), error) {
dir, err := os.MkdirTemp("", "miro-record-sandbox-") dir, err := os.MkdirTemp("", "mire-record-sandbox-")
if err != nil { if err != nil {
return recordSandbox{}, nil, err return recordSandbox{}, nil, err
} }
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"embed" "embed"
@@ -13,9 +13,9 @@ import (
const recordShellName = "shell.sh" const recordShellName = "shell.sh"
const ( const (
compareMarkerEnvName = "MIRO_COMPARE_MARKER" compareMarkerEnvName = "MIRE_COMPARE_MARKER"
compareMarkerEnabledValue = "1" compareMarkerEnabledValue = "1"
compareOutputMarker = "__MIRO_E2E_BEGIN__" compareOutputMarker = "__MIRE_E2E_BEGIN__"
) )
//go:embed record_shell.sh //go:embed record_shell.sh
@@ -29,7 +29,7 @@ func ensureRecordShell(testDir string) error {
path := recordShellPath(testDir) path := recordShellPath(testDir)
if info, err := os.Stat(path); err == nil { if info, err := os.Stat(path); err == nil {
if info.IsDir() { if info.IsDir() {
return fmt.Errorf("recorder shell %q is a directory; remove it and rerun `miro init`", path) return fmt.Errorf("recorder shell %q is a directory; remove it and rerun `mire init`", path)
} }
} else if !errors.Is(err, os.ErrNotExist) { } else if !errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("failed to check recorder shell %q: %v", path, err) return fmt.Errorf("failed to check recorder shell %q: %v", path, err)
@@ -59,12 +59,12 @@ func resolveRecordShell(testDir string) (string, error) {
info, err := os.Stat(path) info, err := os.Stat(path)
if err != nil { if err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
return "", fmt.Errorf("missing recorder shell %q; rerun `miro init` or restore the file", path) return "", fmt.Errorf("missing recorder shell %q; rerun `mire init` or restore the file", path)
} }
return "", fmt.Errorf("failed to check recorder shell %q: %v", path, err) return "", fmt.Errorf("failed to check recorder shell %q: %v", path, err)
} }
if info.IsDir() { if info.IsDir() {
return "", fmt.Errorf("recorder shell %q is a directory; rerun `miro init` or restore the file", path) return "", fmt.Errorf("recorder shell %q is a directory; rerun `mire init` or restore the file", path)
} }
return path, nil return path, nil
@@ -86,9 +86,9 @@ func recordSessionEnv(sandbox recordSandbox, sandboxConfig map[string]string, se
func recordSessionEnvWithExtra(sandbox recordSandbox, sandboxConfig map[string]string, setupScripts []string, extraEnv map[string]string) []string { func recordSessionEnvWithExtra(sandbox recordSandbox, sandboxConfig map[string]string, setupScripts []string, extraEnv map[string]string) []string {
env := append([]string{}, os.Environ()...) env := append([]string{}, os.Environ()...)
env = append(env, env = append(env,
"MIRO_HOST_HOME="+sandbox.hostHome, "MIRE_HOST_HOME="+sandbox.hostHome,
"MIRO_HOST_TMP="+sandbox.hostTmp, "MIRE_HOST_TMP="+sandbox.hostTmp,
"MIRO_PATH_ENV="+sandbox.pathEnv, "MIRE_PATH_ENV="+sandbox.pathEnv,
setupScriptsEnvName+"="+strings.Join(setupScripts, "\n"), setupScriptsEnvName+"="+strings.Join(setupScripts, "\n"),
) )
for _, key := range sortedKeys(sandboxConfig) { for _, key := range sortedKeys(sandboxConfig) {
@@ -102,7 +102,7 @@ func recordSessionEnvWithExtra(sandbox recordSandbox, sandboxConfig map[string]s
} }
func sandboxEnvName(key string) string { func sandboxEnvName(key string) string {
return "MIRO_" + strings.ToUpper(key) return "MIRE_" + strings.ToUpper(key)
} }
func sortedKeys(values map[string]string) []string { func sortedKeys(values map[string]string) []string {
@@ -2,18 +2,18 @@
set -eu set -eu
# hoisted vars to fail fast if any missing # hoisted vars to fail fast if any missing
host_home=${MIRO_HOST_HOME:?} host_home=${MIRE_HOST_HOME:?}
host_tmp=${MIRO_HOST_TMP:?} host_tmp=${MIRE_HOST_TMP:?}
path_env=${MIRO_PATH_ENV:?} path_env=${MIRE_PATH_ENV:?}
visible_home=${MIRO_VISIBLE_HOME:?} visible_home=${MIRE_VISIBLE_HOME:?}
bootstrap_rc="$host_home/.miro-shell-rc" bootstrap_rc="$host_home/.mire-shell-rc"
visible_bootstrap_rc="$visible_home/.miro-shell-rc" visible_bootstrap_rc="$visible_home/.mire-shell-rc"
setup_scripts_dir='/tmp/miro-setup-scripts' setup_scripts_dir='/tmp/mire-setup-scripts'
cat >"$bootstrap_rc" <<'EOF' cat >"$bootstrap_rc" <<'EOF'
cd "${HOME:?}" cd "${HOME:?}"
for path in /tmp/miro-setup-scripts/*.sh; do for path in /tmp/mire-setup-scripts/*.sh; do
[ -e "$path" ] || continue [ -e "$path" ] || continue
cd "${HOME:?}" cd "${HOME:?}"
source "$path" source "$path"
@@ -21,8 +21,8 @@ for path in /tmp/miro-setup-scripts/*.sh; do
done done
EOF EOF
if [ "${MIRO_COMPARE_MARKER:-0}" = "1" ]; then if [ "${MIRE_COMPARE_MARKER:-0}" = "1" ]; then
printf '__MIRO_E2E_BEGIN__\n' printf '__MIRE_E2E_BEGIN__\n'
fi fi
set -- \ set -- \
@@ -46,7 +46,7 @@ set -- \
--setenv TZ 'UTC' \ --setenv TZ 'UTC' \
--chdir "$visible_home" --chdir "$visible_home"
if [ -n "${MIRO_SETUP_SCRIPTS:-}" ]; then if [ -n "${MIRE_SETUP_SCRIPTS:-}" ]; then
i=1 i=1
while IFS= read -r host_path || [ -n "$host_path" ]; do while IFS= read -r host_path || [ -n "$host_path" ]; do
[ -n "$host_path" ] || continue [ -n "$host_path" ] || continue
@@ -54,7 +54,7 @@ if [ -n "${MIRO_SETUP_SCRIPTS:-}" ]; then
set -- "$@" --ro-bind "$host_path" "$visible_path" set -- "$@" --ro-bind "$host_path" "$visible_path"
i=$((i + 1)) i=$((i + 1))
done <<EOF done <<EOF
${MIRO_SETUP_SCRIPTS-} ${MIRE_SETUP_SCRIPTS-}
EOF EOF
fi fi
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bytes" "bytes"
@@ -9,14 +9,14 @@ import (
"testing" "testing"
"time" "time"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestRecordCreatesRelativePath(t *testing.T) { func TestRecordCreatesRelativePath(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testDir := filepath.Join(root, "e2e") testDir := filepath.Join(root, "e2e")
testutil.MustMkdirAll(t, testDir) testutil.MustMkdirAll(t, testDir)
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("e2e")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("e2e"))
mustWriteRecordShell(t, testDir) mustWriteRecordShell(t, testDir)
testutil.AddFakeRecordDependencies(t, "script") testutil.AddFakeRecordDependencies(t, "script")
@@ -116,23 +116,23 @@ func TestBuildRecordShellScriptUsesExpectedCommands(t *testing.T) {
body := buildRecordShellScript() body := buildRecordShellScript()
for _, want := range []string{ for _, want := range []string{
"host_home=${MIRO_HOST_HOME:?}", "host_home=${MIRE_HOST_HOME:?}",
"host_tmp=${MIRO_HOST_TMP:?}", "host_tmp=${MIRE_HOST_TMP:?}",
"path_env=${MIRO_PATH_ENV:?}", "path_env=${MIRE_PATH_ENV:?}",
"visible_home=${MIRO_VISIBLE_HOME:?}", "visible_home=${MIRE_VISIBLE_HOME:?}",
"bootstrap_rc=\"$host_home/.miro-shell-rc\"", "bootstrap_rc=\"$host_home/.mire-shell-rc\"",
"setup_scripts_dir='/tmp/miro-setup-scripts'", "setup_scripts_dir='/tmp/mire-setup-scripts'",
"visible_bootstrap_rc=\"$visible_home/.miro-shell-rc\"", "visible_bootstrap_rc=\"$visible_home/.mire-shell-rc\"",
"for path in /tmp/miro-setup-scripts/*.sh; do", "for path in /tmp/mire-setup-scripts/*.sh; do",
"source \"$path\"", "source \"$path\"",
`if [ -n "${MIRO_SETUP_SCRIPTS:-}" ]; then`, `if [ -n "${MIRE_SETUP_SCRIPTS:-}" ]; then`,
"i=1", "i=1",
`while IFS= read -r host_path || [ -n "$host_path" ]; do`, `while IFS= read -r host_path || [ -n "$host_path" ]; do`,
`visible_path=$(printf '%s/%03d.sh' "$setup_scripts_dir" "$i")`, `visible_path=$(printf '%s/%03d.sh' "$setup_scripts_dir" "$i")`,
`set -- "$@" --ro-bind "$host_path" "$visible_path"`, `set -- "$@" --ro-bind "$host_path" "$visible_path"`,
"${MIRO_SETUP_SCRIPTS-}", "${MIRE_SETUP_SCRIPTS-}",
`if [ "${MIRO_COMPARE_MARKER:-0}" = "1" ]; then`, `if [ "${MIRE_COMPARE_MARKER:-0}" = "1" ]; then`,
"printf '__MIRO_E2E_BEGIN__\\n'", "printf '__MIRE_E2E_BEGIN__\\n'",
"--bind \"$host_home\" \"$visible_home\"", "--bind \"$host_home\" \"$visible_home\"",
"--bind \"$host_tmp\" '/tmp'", "--bind \"$host_tmp\" '/tmp'",
"--setenv HOME \"$visible_home\"", "--setenv HOME \"$visible_home\"",
@@ -160,19 +160,19 @@ func TestRecordSessionEnvIncludesConfiguredSandboxEnv(t *testing.T) {
}, []string{"/repo/e2e/setup.sh", "/repo/e2e/suite/setup.sh"}) }, []string{"/repo/e2e/setup.sh", "/repo/e2e/suite/setup.sh"})
for _, want := range []string{ for _, want := range []string{
"MIRO_HOST_HOME=/tmp/host-home", "MIRE_HOST_HOME=/tmp/host-home",
"MIRO_HOST_TMP=/tmp/host-tmp", "MIRE_HOST_TMP=/tmp/host-tmp",
"MIRO_PATH_ENV=/tmp/bin", "MIRE_PATH_ENV=/tmp/bin",
"MIRO_KEY_WORD=value", "MIRE_KEY_WORD=value",
"MIRO_VISIBLE_HOME=/sandbox/home", "MIRE_VISIBLE_HOME=/sandbox/home",
"MIRO_SETUP_SCRIPTS=/repo/e2e/setup.sh\n/repo/e2e/suite/setup.sh", "MIRE_SETUP_SCRIPTS=/repo/e2e/setup.sh\n/repo/e2e/suite/setup.sh",
} { } {
if !containsEnvEntry(env, want) { if !containsEnvEntry(env, want) {
t.Fatalf("env = %#v, want entry %q", env, want) t.Fatalf("env = %#v, want entry %q", env, want)
} }
} }
if containsEnvKey(env, "MIRO_SETUP_SCRIPT_BINDS") { if containsEnvKey(env, "MIRE_SETUP_SCRIPT_BINDS") {
t.Fatalf("env = %#v, want MIRO_SETUP_SCRIPT_BINDS omitted", env) t.Fatalf("env = %#v, want MIRE_SETUP_SCRIPT_BINDS omitted", env)
} }
} }
@@ -188,19 +188,19 @@ func TestRecordSessionEnvWithExtraIncludesAdditionalEntries(t *testing.T) {
}) })
for _, want := range []string{ for _, want := range []string{
"MIRO_HOST_HOME=/tmp/host-home", "MIRE_HOST_HOME=/tmp/host-home",
"MIRO_HOST_TMP=/tmp/host-tmp", "MIRE_HOST_TMP=/tmp/host-tmp",
"MIRO_PATH_ENV=/tmp/bin", "MIRE_PATH_ENV=/tmp/bin",
"MIRO_VISIBLE_HOME=/sandbox/home", "MIRE_VISIBLE_HOME=/sandbox/home",
"MIRO_SETUP_SCRIPTS=/repo/e2e/setup.sh", "MIRE_SETUP_SCRIPTS=/repo/e2e/setup.sh",
"MIRO_COMPARE_MARKER=1", "MIRE_COMPARE_MARKER=1",
} { } {
if !containsEnvEntry(env, want) { if !containsEnvEntry(env, want) {
t.Fatalf("env = %#v, want entry %q", env, want) t.Fatalf("env = %#v, want entry %q", env, want)
} }
} }
if containsEnvKey(env, "MIRO_SETUP_SCRIPT_BINDS") { if containsEnvKey(env, "MIRE_SETUP_SCRIPT_BINDS") {
t.Fatalf("env = %#v, want MIRO_SETUP_SCRIPT_BINDS omitted", env) t.Fatalf("env = %#v, want MIRE_SETUP_SCRIPT_BINDS omitted", env)
} }
} }
@@ -229,34 +229,34 @@ func TestRunRecordSessionUsesSandboxedScriptCommand(t *testing.T) {
} }
args := strings.Split(strings.TrimSpace(testutil.ReadFile(t, argsPath)), "\n") args := strings.Split(strings.TrimSpace(testutil.ReadFile(t, argsPath)), "\n")
if len(args) != 10 { if len(args) != 9 {
t.Fatalf("script args = %q, want 10 args", args) t.Fatalf("script args = %q, want 9 args", args)
} }
if got := args[:5]; strings.Join(got, "\n") != strings.Join([]string{"-q", "-e", "-E", "always", "-I"}, "\n") { if got := args[:4]; strings.Join(got, "\n") != strings.Join([]string{"-q", "-E", "always", "-I"}, "\n") {
t.Fatalf("script args prefix = %q, want %q", got, []string{"-q", "-e", "-E", "always", "-I"}) t.Fatalf("script args prefix = %q, want %q", got, []string{"-q", "-E", "always", "-I"})
} }
if args[6] != "-O" { if args[5] != "-O" {
t.Fatalf("script args[6] = %q, want %q", args[6], "-O") t.Fatalf("script args[5] = %q, want %q", args[5], "-O")
} }
if args[8] != "-c" { if args[7] != "-c" {
t.Fatalf("script args[8] = %q, want %q", args[8], "-c") t.Fatalf("script args[7] = %q, want %q", args[7], "-c")
} }
if args[9] != shellPath { if args[8] != shellPath {
t.Fatalf("script args[9] = %q, want %q", args[9], shellPath) t.Fatalf("script args[8] = %q, want %q", args[8], shellPath)
} }
body := testutil.ReadFile(t, commandBodyPath) body := testutil.ReadFile(t, commandBodyPath)
for _, want := range []string{ for _, want := range []string{
"host_home=${MIRO_HOST_HOME:?}", "host_home=${MIRE_HOST_HOME:?}",
"visible_home=${MIRO_VISIBLE_HOME:?}", "visible_home=${MIRE_VISIBLE_HOME:?}",
"bootstrap_rc=\"$host_home/.miro-shell-rc\"", "bootstrap_rc=\"$host_home/.mire-shell-rc\"",
"visible_bootstrap_rc=\"$visible_home/.miro-shell-rc\"", "visible_bootstrap_rc=\"$visible_home/.mire-shell-rc\"",
"for path in /tmp/miro-setup-scripts/*.sh; do", "for path in /tmp/mire-setup-scripts/*.sh; do",
"source \"$path\"", "source \"$path\"",
`if [ -n "${MIRO_SETUP_SCRIPTS:-}" ]; then`, `if [ -n "${MIRE_SETUP_SCRIPTS:-}" ]; then`,
`set -- "$@" --ro-bind "$host_path" "$visible_path"`, `set -- "$@" --ro-bind "$host_path" "$visible_path"`,
`if [ "${MIRO_COMPARE_MARKER:-0}" = "1" ]; then`, `if [ "${MIRE_COMPARE_MARKER:-0}" = "1" ]; then`,
"printf '__MIRO_E2E_BEGIN__\\n'", "printf '__MIRE_E2E_BEGIN__\\n'",
"--ro-bind / /", "--ro-bind / /",
"--tmpfs /home", "--tmpfs /home",
"--setenv HOME \"$visible_home\"", "--setenv HOME \"$visible_home\"",
@@ -298,7 +298,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
defer close(writeDone) defer close(writeDone)
defer writer.Close() defer writer.Close()
if _, err := writer.Write([]byte("pwd\necho \"$HOME\"\necho \"$MIRO_KEY_WORD\"\nif [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\npwd\nexit\n")); err != nil { if _, err := writer.Write([]byte("pwd\necho \"$HOME\"\necho \"$MIRE_KEY_WORD\"\nif [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\npwd\nexit\n")); err != nil {
writeDone <- err writeDone <- err
return return
} }
@@ -331,7 +331,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
if strings.Contains(recordedIn, "Script started on ") { if strings.Contains(recordedIn, "Script started on ") {
t.Fatalf("saved in = %q, want stripped script wrapper", recordedIn) t.Fatalf("saved in = %q, want stripped script wrapper", recordedIn)
} }
for _, want := range []string{"pwd\n", "echo \"$HOME\"\n", "echo \"$MIRO_KEY_WORD\"\n", "if [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\n", "exit\n"} { for _, want := range []string{"pwd\n", "echo \"$HOME\"\n", "echo \"$MIRE_KEY_WORD\"\n", "if [ -e \"$HOME/repo\" ]; then echo FOUND; else echo MISSING; fi\n", "exit\n"} {
if !strings.Contains(recordedIn, want) { if !strings.Contains(recordedIn, want) {
t.Fatalf("saved in = %q, want substring %q", recordedIn, want) t.Fatalf("saved in = %q, want substring %q", recordedIn, want)
} }
@@ -357,7 +357,7 @@ func TestRecordScenarioUsesDeterministicSandbox(t *testing.T) {
func TestRecordFailsWhenRecorderShellMissing(t *testing.T) { func TestRecordFailsWhenRecorderShellMissing(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testDir := filepath.Join(root, "e2e") testDir := filepath.Join(root, "e2e")
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("e2e")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("e2e"))
testutil.MustMkdirAll(t, testDir) testutil.MustMkdirAll(t, testDir)
testutil.AddFakeRecordDependencies(t, "script") testutil.AddFakeRecordDependencies(t, "script")
@@ -369,7 +369,7 @@ func TestRecordFailsWhenRecorderShellMissing(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("Record() error = nil, want error") t.Fatal("Record() error = nil, want error")
} }
if !strings.Contains(err.Error(), "rerun `miro init`") { if !strings.Contains(err.Error(), "rerun `mire init`") {
t.Fatalf("Record() error = %q, want rerun init hint", err.Error()) t.Fatalf("Record() error = %q, want rerun init hint", err.Error())
} }
if _, statErr := os.Stat(target); !os.IsNotExist(statErr) { if _, statErr := os.Stat(target); !os.IsNotExist(statErr) {
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"errors" "errors"
@@ -10,7 +10,7 @@ import (
const ( const (
setupScriptName = "setup.sh" setupScriptName = "setup.sh"
setupScriptsEnvName = "MIRO_SETUP_SCRIPTS" setupScriptsEnvName = "MIRE_SETUP_SCRIPTS"
) )
func discoverSetupScripts(testDir, scenarioDir string) ([]string, error) { func discoverSetupScripts(testDir, scenarioDir string) ([]string, error) {
@@ -1,10 +1,10 @@
package miro package mire
import ( import (
"path/filepath" "path/filepath"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestDiscoverSetupScriptsFindsRootToLeafSetupFiles(t *testing.T) { func TestDiscoverSetupScriptsFindsRootToLeafSetupFiles(t *testing.T) {
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bytes" "bytes"
@@ -11,7 +11,7 @@ import (
"sort" "sort"
"time" "time"
"miro/internal/output" "mire/internal/output"
) )
type testIO struct { type testIO struct {
@@ -266,7 +266,7 @@ func trimReplayOutputToMarker(data []byte, shellPath string) ([]byte, error) {
idx := bytes.Index(data, []byte(compareOutputMarker)) idx := bytes.Index(data, []byte(compareOutputMarker))
if idx == -1 { if idx == -1 {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"missing compare marker %q in replay output; rerun `miro init` or refresh %q", "missing compare marker %q in replay output; rerun `mire init` or refresh %q",
compareOutputMarker, compareOutputMarker,
shellPath, shellPath,
) )
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bytes" "bytes"
@@ -7,7 +7,7 @@ import (
"testing" "testing"
"time" "time"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestFormatElapsed(t *testing.T) { func TestFormatElapsed(t *testing.T) {
@@ -152,7 +152,7 @@ func TestReplayScenarioFailsWhenCompareMarkerMissing(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("replayScenario() error = nil, want error") t.Fatal("replayScenario() error = nil, want error")
} }
if !strings.Contains(err.Error(), "missing compare marker") || !strings.Contains(err.Error(), "rerun `miro init`") { if !strings.Contains(err.Error(), "missing compare marker") || !strings.Contains(err.Error(), "rerun `mire init`") {
t.Fatalf("replayScenario() error = %q, want compare marker refresh hint", err.Error()) t.Fatalf("replayScenario() error = %q, want compare marker refresh hint", err.Error())
} }
} }
@@ -212,7 +212,7 @@ func TestRunTestsScopedRunEmptyDirectoryFails(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testDir := filepath.Join(root, "e2e") testDir := filepath.Join(root, "e2e")
emptyDir := filepath.Join(testDir, "empty") emptyDir := filepath.Join(testDir, "empty")
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("e2e")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("e2e"))
mustWriteRecordShell(t, testDir) mustWriteRecordShell(t, testDir)
testutil.MustMkdirAll(t, emptyDir) testutil.MustMkdirAll(t, emptyDir)
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"errors" "errors"
@@ -8,7 +8,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
miroconfig "miro/internal/config" mireconfig "mire/internal/config"
) )
// ResolveTestDir resolves the project test directory from config. // ResolveTestDir resolves the project test directory from config.
@@ -30,12 +30,12 @@ func resolveTestDirFromRoot(root string) (string, error) {
return resolveTestDirFromConfig(root, cfg) return resolveTestDirFromConfig(root, cfg)
} }
func readConfigFromRoot(root string) (miroconfig.Config, error) { func readConfigFromRoot(root string) (mireconfig.Config, error) {
configPath := filepath.Join(root, "miro.toml") configPath := filepath.Join(root, "mire.toml")
return miroconfig.ReadConfig(configPath) return mireconfig.ReadConfig(configPath)
} }
func resolveTestDirFromConfig(root string, cfg miroconfig.Config) (string, error) { func resolveTestDirFromConfig(root string, cfg mireconfig.Config) (string, error) {
testDir := filepath.Join(root, cfg.TestDir) testDir := filepath.Join(root, cfg.TestDir)
info, err := os.Stat(testDir) info, err := os.Stat(testDir)
if err == nil { if err == nil {
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"os" "os"
@@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func TestInitCreatesConfigAtProjectRoot(t *testing.T) { func TestInitCreatesConfigAtProjectRoot(t *testing.T) {
@@ -19,7 +19,7 @@ func TestInitCreatesConfigAtProjectRoot(t *testing.T) {
return struct{}{} return struct{}{}
}) })
got := testutil.ReadFile(t, filepath.Join(root, "miro.toml")) got := testutil.ReadFile(t, filepath.Join(root, "mire.toml"))
if got != testutil.DefaultWrittenConfig("e2e") { if got != testutil.DefaultWrittenConfig("e2e") {
t.Fatalf("config = %q, want %q", got, testutil.DefaultWrittenConfig("e2e")) t.Fatalf("config = %q, want %q", got, testutil.DefaultWrittenConfig("e2e"))
} }
@@ -39,15 +39,15 @@ func TestInitUsesGitRoot(t *testing.T) {
return struct{}{} return struct{}{}
}) })
if _, err := os.Stat(filepath.Join(root, "miro.toml")); err != nil { if _, err := os.Stat(filepath.Join(root, "mire.toml")); err != nil {
t.Fatalf("Stat(%q) error = %v", filepath.Join(root, "miro.toml"), err) t.Fatalf("Stat(%q) error = %v", filepath.Join(root, "mire.toml"), err)
} }
assertRecordShell(t, filepath.Join(root, "e2e", recordShellName)) assertRecordShell(t, filepath.Join(root, "e2e", recordShellName))
} }
func TestInitLeavesExistingValidConfigUntouchedAndRefreshesShell(t *testing.T) { func TestInitLeavesExistingValidConfigUntouchedAndRefreshesShell(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("custom/suite")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("custom/suite"))
testutil.WriteFile(t, filepath.Join(root, "custom", "suite", recordShellName), "outdated\n") testutil.WriteFile(t, filepath.Join(root, "custom", "suite", recordShellName), "outdated\n")
testutil.WithWorkingDir(t, root, func() struct{} { testutil.WithWorkingDir(t, root, func() struct{} {
@@ -57,7 +57,7 @@ func TestInitLeavesExistingValidConfigUntouchedAndRefreshesShell(t *testing.T) {
return struct{}{} return struct{}{}
}) })
got := testutil.ReadFile(t, filepath.Join(root, "miro.toml")) got := testutil.ReadFile(t, filepath.Join(root, "mire.toml"))
if got != testutil.ValidConfigContent("custom/suite") { if got != testutil.ValidConfigContent("custom/suite") {
t.Fatalf("config = %q, want %q", got, testutil.ValidConfigContent("custom/suite")) t.Fatalf("config = %q, want %q", got, testutil.ValidConfigContent("custom/suite"))
} }
@@ -68,7 +68,7 @@ func TestInitLeavesExistingValidConfigUntouchedAndRefreshesShell(t *testing.T) {
func TestInitCreatesMissingConfiguredTestDir(t *testing.T) { func TestInitCreatesMissingConfiguredTestDir(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("custom/suite")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("custom/suite"))
testutil.WithWorkingDir(t, root, func() struct{} { testutil.WithWorkingDir(t, root, func() struct{} {
if err := Init(); err != nil { if err := Init(); err != nil {
@@ -82,7 +82,7 @@ func TestInitCreatesMissingConfiguredTestDir(t *testing.T) {
func TestInitFailsWhenExistingConfigInvalid(t *testing.T) { func TestInitFailsWhenExistingConfigInvalid(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), "test_dir = \"e2e\"\n") testutil.WriteFile(t, filepath.Join(root, "mire.toml"), "test_dir = \"e2e\"\n")
err := testutil.WithWorkingDir(t, root, func() error { err := testutil.WithWorkingDir(t, root, func() error {
return Init() return Init()
@@ -90,8 +90,8 @@ func TestInitFailsWhenExistingConfigInvalid(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("Init() error = nil, want error") t.Fatal("Init() error = nil, want error")
} }
if !strings.Contains(err.Error(), "missing [miro] config") { if !strings.Contains(err.Error(), "missing [mire] config") {
t.Fatalf("Init() error = %q, want missing [miro] config error", err.Error()) t.Fatalf("Init() error = %q, want missing [mire] config error", err.Error())
} }
} }
@@ -99,7 +99,7 @@ func TestResolveTestDirFromConfig(t *testing.T) {
root := t.TempDir() root := t.TempDir()
configured := filepath.Join(root, "custom", "suite") configured := filepath.Join(root, "custom", "suite")
testutil.MustMkdirAll(t, configured) testutil.MustMkdirAll(t, configured)
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("custom/suite")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("custom/suite"))
got := testutil.WithWorkingDir(t, root, func() string { got := testutil.WithWorkingDir(t, root, func() string {
path, err := ResolveTestDir() path, err := ResolveTestDir()
@@ -132,7 +132,7 @@ func TestResolveTestDirMissingConfigFails(t *testing.T) {
func TestResolveTestDirMissingTestDirFails(t *testing.T) { func TestResolveTestDirMissingTestDirFails(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), "[miro]\n") testutil.WriteFile(t, filepath.Join(root, "mire.toml"), "[mire]\n")
err := testutil.WithWorkingDir(t, root, func() error { err := testutil.WithWorkingDir(t, root, func() error {
_, err := ResolveTestDir() _, err := ResolveTestDir()
@@ -142,14 +142,14 @@ func TestResolveTestDirMissingTestDirFails(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("ResolveTestDir() error = nil, want error") t.Fatal("ResolveTestDir() error = nil, want error")
} }
if !strings.Contains(err.Error(), "missing required miro.test_dir") { if !strings.Contains(err.Error(), "missing required mire.test_dir") {
t.Fatalf("ResolveTestDir() error = %q, want missing required miro.test_dir", err.Error()) t.Fatalf("ResolveTestDir() error = %q, want missing required mire.test_dir", err.Error())
} }
} }
func TestResolveTestDirEmptyTestDirFails(t *testing.T) { func TestResolveTestDirEmptyTestDirFails(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = \"\"\n") testutil.WriteFile(t, filepath.Join(root, "mire.toml"), "[mire]\ntest_dir = \"\"\n")
err := testutil.WithWorkingDir(t, root, func() error { err := testutil.WithWorkingDir(t, root, func() error {
_, err := ResolveTestDir() _, err := ResolveTestDir()
@@ -159,14 +159,14 @@ func TestResolveTestDirEmptyTestDirFails(t *testing.T) {
if err == nil { if err == nil {
t.Fatal("ResolveTestDir() error = nil, want error") t.Fatal("ResolveTestDir() error = nil, want error")
} }
if !strings.Contains(err.Error(), "empty miro.test_dir") { if !strings.Contains(err.Error(), "empty mire.test_dir") {
t.Fatalf("ResolveTestDir() error = %q, want empty miro.test_dir", err.Error()) t.Fatalf("ResolveTestDir() error = %q, want empty mire.test_dir", err.Error())
} }
} }
func TestResolveTestDirMalformedConfigFails(t *testing.T) { func TestResolveTestDirMalformedConfigFails(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), "[miro]\ntest_dir = [\n") testutil.WriteFile(t, filepath.Join(root, "mire.toml"), "[mire]\ntest_dir = [\n")
err := testutil.WithWorkingDir(t, root, func() error { err := testutil.WithWorkingDir(t, root, func() error {
_, err := ResolveTestDir() _, err := ResolveTestDir()
@@ -184,7 +184,7 @@ func TestResolveTestDirMalformedConfigFails(t *testing.T) {
func TestResolveTestDirConfiguredMissingDirectoryReturnsConfiguredPath(t *testing.T) { func TestResolveTestDirConfiguredMissingDirectoryReturnsConfiguredPath(t *testing.T) {
root := t.TempDir() root := t.TempDir()
want := filepath.Join(root, "missing") want := filepath.Join(root, "missing")
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("missing")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("missing"))
got := testutil.WithWorkingDir(t, root, func() string { got := testutil.WithWorkingDir(t, root, func() string {
path, err := ResolveTestDir() path, err := ResolveTestDir()
@@ -202,7 +202,7 @@ func TestResolveTestDirConfiguredMissingDirectoryReturnsConfiguredPath(t *testin
func TestResolveTestDirConfiguredFileFails(t *testing.T) { func TestResolveTestDirConfiguredFileFails(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.WriteFile(t, filepath.Join(root, "case.txt"), "hello\n") testutil.WriteFile(t, filepath.Join(root, "case.txt"), "hello\n")
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("case.txt")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("case.txt"))
err := testutil.WithWorkingDir(t, root, func() error { err := testutil.WithWorkingDir(t, root, func() error {
_, err := ResolveTestDir() _, err := ResolveTestDir()
@@ -221,7 +221,7 @@ func TestResolveTestDirUsesGitRoot(t *testing.T) {
root := t.TempDir() root := t.TempDir()
testutil.MustGitInit(t, root) testutil.MustGitInit(t, root)
want := filepath.Join(root, "e2e") want := filepath.Join(root, "e2e")
testutil.WriteFile(t, filepath.Join(root, "miro.toml"), testutil.ValidConfigContent("e2e")) testutil.WriteFile(t, filepath.Join(root, "mire.toml"), testutil.ValidConfigContent("e2e"))
subdir := filepath.Join(root, "nested", "dir") subdir := filepath.Join(root, "nested", "dir")
testutil.MustMkdirAll(t, subdir) testutil.MustMkdirAll(t, subdir)
@@ -1,4 +1,4 @@
package miro package mire
import ( import (
"bytes" "bytes"
@@ -7,7 +7,7 @@ import (
"strings" "strings"
"testing" "testing"
"miro/internal/testutil" "mire/internal/testutil"
) )
func assertRecordShell(t *testing.T, path string) { func assertRecordShell(t *testing.T, path string) {
+3 -3
View File
@@ -9,13 +9,13 @@ import (
var ( var (
palette = struct { palette = struct {
miroGreen uint32 mireGreen uint32
chevronTeal uint32 chevronTeal uint32
info uint32 info uint32
pass uint32 pass uint32
fail uint32 fail uint32
}{ }{
miroGreen: 0x70E000, mireGreen: 0x70E000,
chevronTeal: 0x1DD3B0, chevronTeal: 0x1DD3B0,
info: 0xD7FFFF, info: 0xD7FFFF,
pass: 0x00d7af, pass: 0x00d7af,
@@ -58,7 +58,7 @@ func noColor() bool {
func prefix() string { func prefix() string {
chevron := NewStyle().FG(palette.chevronTeal).Bold().Italic().Apply("") chevron := NewStyle().FG(palette.chevronTeal).Bold().Italic().Apply("")
return NewStyle().FG(palette.miroGreen).Bold().Italic().Apply("miro") + " " + chevron + " " return NewStyle().FG(palette.mireGreen).Bold().Italic().Apply("mire") + " " + chevron + " "
} }
func Format(msg string) string { func Format(msg string) string {
+4 -4
View File
@@ -21,8 +21,8 @@ func TestFormatIncludesANSIByDefault(t *testing.T) {
func TestFormatPlainWhenNoColorSet(t *testing.T) { func TestFormatPlainWhenNoColorSet(t *testing.T) {
t.Setenv("NO_COLOR", "1") t.Setenv("NO_COLOR", "1")
if got := Format("hello\n"); got != "miro hello\n" { if got := Format("hello\n"); got != "mire hello\n" {
t.Fatalf("Format() = %q, want %q", got, "miro hello\n") t.Fatalf("Format() = %q, want %q", got, "mire hello\n")
} }
} }
@@ -52,7 +52,7 @@ func TestFormatReadsNoColorAtRuntime(t *testing.T) {
if !strings.Contains(styled, "\x1b[") { if !strings.Contains(styled, "\x1b[") {
t.Fatalf("styled Format() = %q, want ANSI styling", styled) t.Fatalf("styled Format() = %q, want ANSI styling", styled)
} }
if plain != "miro hello\n" { if plain != "mire hello\n" {
t.Fatalf("plain Format() = %q, want %q", plain, "miro hello\n") t.Fatalf("plain Format() = %q, want %q", plain, "mire hello\n")
} }
} }
+8 -8
View File
@@ -175,12 +175,12 @@ if [ -n "${FAKE_SCRIPT_COMMAND_BODY_FILE:-}" ] && [ -n "$cmd" ]; then
done < "$cmd" done < "$cmd"
fi fi
command_has_compare_marker=0 command_has_compare_marker=0
if [ -n "$cmd" ] && /bin/grep -q '__MIRO_E2E_BEGIN__' "$cmd" 2>/dev/null; then if [ -n "$cmd" ] && /bin/grep -q '__MIRE_E2E_BEGIN__' "$cmd" 2>/dev/null; then
command_has_compare_marker=1 command_has_compare_marker=1
fi fi
stdin_file='' stdin_file=''
if [ "${FAKE_SCRIPT_ECHO_STDIN:-}" = "1" ] || [ -n "${FAKE_SCRIPT_CAPTURE_STDIN_FILE:-}" ]; then if [ "${FAKE_SCRIPT_ECHO_STDIN:-}" = "1" ] || [ -n "${FAKE_SCRIPT_CAPTURE_STDIN_FILE:-}" ]; then
stdin_file="${TMPDIR:-/tmp}/miro-fake-script-stdin-$$" stdin_file="${TMPDIR:-/tmp}/mire-fake-script-stdin-$$"
/bin/cat > "$stdin_file" /bin/cat > "$stdin_file"
fi fi
if [ -n "${FAKE_SCRIPT_CAPTURE_STDIN_FILE:-}" ] && [ -n "$stdin_file" ]; then if [ -n "${FAKE_SCRIPT_CAPTURE_STDIN_FILE:-}" ] && [ -n "$stdin_file" ]; then
@@ -198,8 +198,8 @@ if [ -n "${FAKE_SCRIPT_STREAM_OUT+x}" ]; then
printf '%s' "$FAKE_SCRIPT_STREAM_OUT" printf '%s' "$FAKE_SCRIPT_STREAM_OUT"
elif [ "${FAKE_SCRIPT_ECHO_STDIN:-}" = "1" ] && [ -n "$stdin_file" ]; then elif [ "${FAKE_SCRIPT_ECHO_STDIN:-}" = "1" ] && [ -n "$stdin_file" ]; then
/bin/cat "$stdin_file" /bin/cat "$stdin_file"
if [ "${MIRO_COMPARE_MARKER:-0}" = "1" ] && [ "$command_has_compare_marker" = "1" ]; then if [ "${MIRE_COMPARE_MARKER:-0}" = "1" ] && [ "$command_has_compare_marker" = "1" ]; then
printf '%s\n' '__MIRO_E2E_BEGIN__' printf '%s\n' '__MIRE_E2E_BEGIN__'
/bin/cat "$stdin_file" /bin/cat "$stdin_file"
fi fi
fi fi
@@ -213,8 +213,8 @@ elif [ -n "$out" ] && [ "${FAKE_SCRIPT_ECHO_STDIN:-}" = "1" ] && [ -n "$stdin_fi
printf '%s' 'Script started on 2026-03-18 11:13:38+00:00 [TERM="xterm-256color"] printf '%s' 'Script started on 2026-03-18 11:13:38+00:00 [TERM="xterm-256color"]
' '
/bin/cat "$stdin_file" /bin/cat "$stdin_file"
if [ "${MIRO_COMPARE_MARKER:-0}" = "1" ] && [ "$command_has_compare_marker" = "1" ]; then if [ "${MIRE_COMPARE_MARKER:-0}" = "1" ] && [ "$command_has_compare_marker" = "1" ]; then
printf '%s\n' '__MIRO_E2E_BEGIN__' printf '%s\n' '__MIRE_E2E_BEGIN__'
/bin/cat "$stdin_file" /bin/cat "$stdin_file"
fi fi
printf '%s' 'Script done on 2026-03-18 11:13:44+00:00 [COMMAND_EXIT_CODE="0"] printf '%s' 'Script done on 2026-03-18 11:13:44+00:00 [COMMAND_EXIT_CODE="0"]
@@ -265,9 +265,9 @@ func MustGitInit(t *testing.T, dir string) {
} }
func DefaultWrittenConfig(testDir string) string { func DefaultWrittenConfig(testDir string) string {
return "[miro]\n test_dir = \"" + testDir + "\"\n\n[sandbox]\n visible_home = \"/home/test\"\n" return "[mire]\n test_dir = \"" + testDir + "\"\n\n[sandbox]\n visible_home = \"/home/test\"\n"
} }
func ValidConfigContent(testDir string) string { func ValidConfigContent(testDir string) string {
return "[miro]\ntest_dir = \"" + testDir + "\"\n\n[sandbox]\nvisible_home = \"/home/test\"\n" return "[mire]\ntest_dir = \"" + testDir + "\"\n\n[sandbox]\nvisible_home = \"/home/test\"\n"
} }