2026-03-24 23:30:38 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
|
|
|
|
|
|
package agentic
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-26 06:38:02 +00:00
|
|
|
"context"
|
2026-03-24 23:30:38 +00:00
|
|
|
"testing"
|
|
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
core "dappco.re/go/core"
|
2026-03-24 23:30:38 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// initBareRepo creates a minimal git repo with one commit and returns its path.
|
|
|
|
|
func initBareRepo(t *testing.T) string {
|
|
|
|
|
t.Helper()
|
|
|
|
|
dir := t.TempDir()
|
2026-03-26 06:38:02 +00:00
|
|
|
gitEnv := []string{
|
|
|
|
|
"GIT_AUTHOR_NAME=Test",
|
|
|
|
|
"GIT_AUTHOR_EMAIL=test@test.com",
|
|
|
|
|
"GIT_COMMITTER_NAME=Test",
|
|
|
|
|
"GIT_COMMITTER_EMAIL=test@test.com",
|
|
|
|
|
}
|
2026-03-24 23:30:38 +00:00
|
|
|
run := func(args ...string) {
|
|
|
|
|
t.Helper()
|
2026-03-26 06:38:02 +00:00
|
|
|
r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...)
|
|
|
|
|
require.True(t, r.OK, "cmd %v failed: %s", args, r.Value)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
run("git", "init", "-b", "main")
|
|
|
|
|
run("git", "config", "user.name", "Test")
|
|
|
|
|
run("git", "config", "user.email", "test@test.com")
|
|
|
|
|
|
|
|
|
|
// Create a file and commit
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.Write(core.JoinPath(dir, "README.md"), "# Test").OK)
|
2026-03-24 23:30:38 +00:00
|
|
|
run("git", "add", "README.md")
|
|
|
|
|
run("git", "commit", "-m", "initial commit")
|
|
|
|
|
return dir
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- hasRemote ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_HasRemote_Good_OriginExists(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
|
|
|
|
// origin won't exist for a fresh repo, so add it
|
2026-03-26 06:38:02 +00:00
|
|
|
testCore.Process().RunIn(context.Background(), dir, "git", "remote", "add", "origin", "https://example.com/repo.git")
|
2026-03-24 23:30:38 +00:00
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
assert.True(t, testPrep.hasRemote(dir, "origin"))
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_HasRemote_Good_CustomRemote(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
2026-03-26 06:38:02 +00:00
|
|
|
testCore.Process().RunIn(context.Background(), dir, "git", "remote", "add", "github", "https://github.com/test/repo.git")
|
2026-03-24 23:30:38 +00:00
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
assert.True(t, testPrep.hasRemote(dir, "github"))
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_HasRemote_Bad_NoSuchRemote(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
assert.False(t, testPrep.hasRemote(dir, "nonexistent"))
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_HasRemote_Bad_NotAGitRepo(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := t.TempDir() // plain directory, no .git
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
assert.False(t, testPrep.hasRemote(dir, "origin"))
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_HasRemote_Ugly_EmptyDir(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
// Empty dir defaults to cwd which may or may not be a repo.
|
|
|
|
|
// Just ensure no panic.
|
|
|
|
|
assert.NotPanics(t, func() {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
testPrep.hasRemote("", "origin")
|
2026-03-24 23:30:38 +00:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- commitsAhead ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Good_OneAhead(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
|
|
|
|
|
|
|
|
|
// Create a branch at the current commit to act as "base"
|
2026-03-26 06:38:02 +00:00
|
|
|
gitEnv := []string{"GIT_AUTHOR_NAME=Test", "GIT_AUTHOR_EMAIL=test@test.com", "GIT_COMMITTER_NAME=Test", "GIT_COMMITTER_EMAIL=test@test.com"}
|
2026-03-24 23:30:38 +00:00
|
|
|
run := func(args ...string) {
|
|
|
|
|
t.Helper()
|
2026-03-26 06:38:02 +00:00
|
|
|
r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...)
|
|
|
|
|
require.True(t, r.OK, "cmd %v failed: %s", args, r.Value)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run("git", "branch", "base")
|
|
|
|
|
|
|
|
|
|
// Add a commit on main
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.Write(core.JoinPath(dir, "new.txt"), "data").OK)
|
2026-03-24 23:30:38 +00:00
|
|
|
run("git", "add", "new.txt")
|
|
|
|
|
run("git", "commit", "-m", "second commit")
|
|
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead(dir, "base", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 1, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Good_ThreeAhead(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
2026-03-26 06:38:02 +00:00
|
|
|
gitEnv := []string{"GIT_AUTHOR_NAME=Test", "GIT_AUTHOR_EMAIL=test@test.com", "GIT_COMMITTER_NAME=Test", "GIT_COMMITTER_EMAIL=test@test.com"}
|
2026-03-24 23:30:38 +00:00
|
|
|
run := func(args ...string) {
|
|
|
|
|
t.Helper()
|
2026-03-26 06:38:02 +00:00
|
|
|
r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...)
|
|
|
|
|
require.True(t, r.OK, "cmd %v failed: %s", args, r.Value)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run("git", "branch", "base")
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 3; i++ {
|
2026-03-26 01:39:41 +00:00
|
|
|
name := core.JoinPath(dir, "file"+string(rune('a'+i))+".txt")
|
2026-03-24 23:30:38 +00:00
|
|
|
require.True(t, fs.Write(name, "content").OK)
|
|
|
|
|
run("git", "add", ".")
|
|
|
|
|
run("git", "commit", "-m", "commit "+string(rune('0'+i)))
|
|
|
|
|
}
|
|
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead(dir, "base", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 3, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Good_ZeroAhead(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
|
|
|
|
// Same ref on both sides
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead(dir, "main", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Bad_InvalidRef(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead(dir, "nonexistent-ref", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Bad_NotARepo(t *testing.T) {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead(t.TempDir(), "main", "dev")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_CommitsAhead_Ugly_EmptyDir(t *testing.T) {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
ahead := testPrep.commitsAhead("", "a", "b")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, ahead)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- filesChanged ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Good_OneFile(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
2026-03-26 06:38:02 +00:00
|
|
|
gitEnv := []string{"GIT_AUTHOR_NAME=Test", "GIT_AUTHOR_EMAIL=test@test.com", "GIT_COMMITTER_NAME=Test", "GIT_COMMITTER_EMAIL=test@test.com"}
|
2026-03-24 23:30:38 +00:00
|
|
|
run := func(args ...string) {
|
|
|
|
|
t.Helper()
|
2026-03-26 06:38:02 +00:00
|
|
|
r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...)
|
|
|
|
|
require.True(t, r.OK, "cmd %v failed: %s", args, r.Value)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run("git", "branch", "base")
|
|
|
|
|
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.Write(core.JoinPath(dir, "changed.txt"), "new").OK)
|
2026-03-24 23:30:38 +00:00
|
|
|
run("git", "add", "changed.txt")
|
|
|
|
|
run("git", "commit", "-m", "add file")
|
|
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged(dir, "base", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 1, files)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Good_MultipleFiles(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
2026-03-26 06:38:02 +00:00
|
|
|
gitEnv := []string{"GIT_AUTHOR_NAME=Test", "GIT_AUTHOR_EMAIL=test@test.com", "GIT_COMMITTER_NAME=Test", "GIT_COMMITTER_EMAIL=test@test.com"}
|
2026-03-24 23:30:38 +00:00
|
|
|
run := func(args ...string) {
|
|
|
|
|
t.Helper()
|
2026-03-26 06:38:02 +00:00
|
|
|
r := testCore.Process().RunWithEnv(context.Background(), dir, gitEnv, args[0], args[1:]...)
|
|
|
|
|
require.True(t, r.OK, "cmd %v failed: %s", args, r.Value)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
run("git", "branch", "base")
|
|
|
|
|
|
|
|
|
|
for _, name := range []string{"a.go", "b.go", "c.go"} {
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.Write(core.JoinPath(dir, name), "package main").OK)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
run("git", "add", ".")
|
|
|
|
|
run("git", "commit", "-m", "add three files")
|
|
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged(dir, "base", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 3, files)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Good_NoChanges(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged(dir, "main", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, files)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Bad_InvalidRef(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged(dir, "nonexistent", "main")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, files)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Bad_NotARepo(t *testing.T) {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged(t.TempDir(), "main", "dev")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, files)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_FilesChanged_Ugly_EmptyDir(t *testing.T) {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
files := testPrep.filesChanged("", "a", "b")
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, 0, files)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- extractJSONField (extending existing 91% coverage) ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Good_ArrayFirstItem(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
json := `[{"url":"https://github.com/test/pr/1","title":"Fix bug"}]`
|
|
|
|
|
assert.Equal(t, "https://github.com/test/pr/1", extractJSONField(json, "url"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Good_ObjectField(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
json := `{"name":"test-repo","status":"active"}`
|
|
|
|
|
assert.Equal(t, "test-repo", extractJSONField(json, "name"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Good_ArrayMultipleItems(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
json := `[{"id":"first"},{"id":"second"}]`
|
|
|
|
|
// Should return the first match
|
|
|
|
|
assert.Equal(t, "first", extractJSONField(json, "id"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Bad_EmptyJSON(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "", extractJSONField("", "url"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Bad_EmptyField(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "", extractJSONField(`{"url":"test"}`, ""))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Bad_FieldNotFound(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
json := `{"name":"test"}`
|
|
|
|
|
assert.Equal(t, "", extractJSONField(json, "missing"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Bad_InvalidJSON(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "", extractJSONField("not json at all", "url"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Ugly_EmptyArray(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "", extractJSONField("[]", "url"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Ugly_EmptyObject(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "", extractJSONField("{}", "url"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Ugly_NumericValue(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
// Field exists but is not a string — should return ""
|
|
|
|
|
json := `{"count":42}`
|
|
|
|
|
assert.Equal(t, "", extractJSONField(json, "count"))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ExtractJSONField_Ugly_NullValue(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
json := `{"url":null}`
|
|
|
|
|
assert.Equal(t, "", extractJSONField(json, "url"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- DefaultBranch ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestPaths_DefaultBranch_Good_MainBranch(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := initBareRepo(t)
|
|
|
|
|
// initBareRepo creates with -b main
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
branch := testPrep.DefaultBranch(dir)
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "main", branch)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestPaths_DefaultBranch_Bad_NotARepo(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
dir := t.TempDir()
|
|
|
|
|
// Falls back to "main" when detection fails
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
branch := testPrep.DefaultBranch(dir)
|
2026-03-24 23:30:38 +00:00
|
|
|
assert.Equal(t, "main", branch)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- listLocalRepos ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ListLocalRepos_Good_FindsRepos(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
base := t.TempDir()
|
|
|
|
|
|
|
|
|
|
// Create two git repos under base
|
|
|
|
|
for _, name := range []string{"repo-a", "repo-b"} {
|
2026-03-26 01:39:41 +00:00
|
|
|
repoDir := core.JoinPath(base, name)
|
2026-03-26 06:38:02 +00:00
|
|
|
testCore.Process().Run(context.Background(), "git", "init", repoDir)
|
2026-03-24 23:30:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a non-repo directory
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.EnsureDir(core.JoinPath(base, "not-a-repo")).OK)
|
2026-03-24 23:30:38 +00:00
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
s := &PrepSubsystem{ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{})}
|
2026-03-24 23:30:38 +00:00
|
|
|
repos := s.listLocalRepos(base)
|
|
|
|
|
assert.Contains(t, repos, "repo-a")
|
|
|
|
|
assert.Contains(t, repos, "repo-b")
|
|
|
|
|
assert.NotContains(t, repos, "not-a-repo")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ListLocalRepos_Bad_EmptyDir(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
base := t.TempDir()
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
s := &PrepSubsystem{ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{})}
|
2026-03-24 23:30:38 +00:00
|
|
|
repos := s.listLocalRepos(base)
|
|
|
|
|
assert.Empty(t, repos)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestMirror_ListLocalRepos_Bad_NonExistentDir(t *testing.T) {
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
s := &PrepSubsystem{ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{})}
|
2026-03-24 23:30:38 +00:00
|
|
|
repos := s.listLocalRepos("/nonexistent/path/that/doesnt/exist")
|
|
|
|
|
assert.Nil(t, repos)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- GitHubOrg ---
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestPaths_GitHubOrg_Good_Default(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
t.Setenv("GITHUB_ORG", "")
|
|
|
|
|
assert.Equal(t, "dAppCore", GitHubOrg())
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 08:32:08 +00:00
|
|
|
func TestPaths_GitHubOrg_Good_Custom(t *testing.T) {
|
2026-03-24 23:30:38 +00:00
|
|
|
t.Setenv("GITHUB_ORG", "my-org")
|
|
|
|
|
assert.Equal(t, "my-org", GitHubOrg())
|
|
|
|
|
}
|
test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).
Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.
AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
|
|
|
|
|
|
|
|
// --- listLocalRepos Ugly ---
|
|
|
|
|
|
|
|
|
|
func TestMirror_ListLocalRepos_Ugly(t *testing.T) {
|
|
|
|
|
base := t.TempDir()
|
|
|
|
|
|
|
|
|
|
// Create two git repos
|
|
|
|
|
for _, name := range []string{"real-repo-a", "real-repo-b"} {
|
2026-03-26 01:39:41 +00:00
|
|
|
repoDir := core.JoinPath(base, name)
|
2026-03-26 06:38:02 +00:00
|
|
|
testCore.Process().Run(context.Background(), "git", "init", repoDir)
|
test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).
Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.
AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create non-git directories (no .git inside)
|
|
|
|
|
for _, name := range []string{"plain-dir", "another-dir"} {
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.EnsureDir(core.JoinPath(base, name)).OK)
|
test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).
Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.
AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a regular file (not a directory)
|
2026-03-26 01:39:41 +00:00
|
|
|
require.True(t, fs.Write(core.JoinPath(base, "some-file.txt"), "hello").OK)
|
test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).
Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.
AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
|
|
|
|
feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As
core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
|
|
|
s := &PrepSubsystem{ServiceRuntime: core.NewServiceRuntime(testCore, AgentOptions{})}
|
test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).
Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.
AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
|
|
|
repos := s.listLocalRepos(base)
|
|
|
|
|
assert.Contains(t, repos, "real-repo-a")
|
|
|
|
|
assert.Contains(t, repos, "real-repo-b")
|
|
|
|
|
assert.NotContains(t, repos, "plain-dir")
|
|
|
|
|
assert.NotContains(t, repos, "another-dir")
|
|
|
|
|
assert.NotContains(t, repos, "some-file.txt")
|
|
|
|
|
assert.Len(t, repos, 2)
|
|
|
|
|
}
|