feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
package sdk
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
"dappco.re/go/core/build/internal/ax"
|
|
|
|
|
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-31 16:45:45 +00:00
|
|
|
func writeFakePHP(t *testing.T, dir string) string {
|
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
|
|
phpPath := ax.Join(dir, "php")
|
|
|
|
|
script := `#!/bin/sh
|
|
|
|
|
set -eu
|
|
|
|
|
if [ "$1" != "artisan" ] || [ "$2" != "scramble:export" ]; then
|
|
|
|
|
exit 64
|
|
|
|
|
fi
|
|
|
|
|
output_path="api.json"
|
|
|
|
|
shift 2
|
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
|
|
|
case "$1" in
|
|
|
|
|
--path=*)
|
|
|
|
|
output_path="${1#--path=}"
|
|
|
|
|
;;
|
|
|
|
|
--path)
|
|
|
|
|
shift
|
|
|
|
|
output_path="$1"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
shift
|
|
|
|
|
done
|
|
|
|
|
printf '{"openapi":"3.1.0"}\n' > "$output_path"
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
require.NoError(t, ax.WriteFile(phpPath, []byte(script), 0o755))
|
|
|
|
|
return phpPath
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_DetectSpecConfigPath_Good(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
tmpDir := t.TempDir()
|
2026-03-26 17:41:53 +00:00
|
|
|
specPath := ax.Join(tmpDir, "api", "spec.yaml")
|
|
|
|
|
err := ax.MkdirAll(ax.Dir(specPath), 0755)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
require.NoError(t, err)
|
2026-03-26 17:41:53 +00:00
|
|
|
err = ax.WriteFile(specPath, []byte("openapi: 3.0.0"), 0644)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, &Config{Spec: "api/spec.yaml"})
|
|
|
|
|
got, err := sdk.DetectSpec()
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, specPath, got)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_DetectSpecCommonPath_Good(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
tmpDir := t.TempDir()
|
2026-03-26 17:41:53 +00:00
|
|
|
specPath := ax.Join(tmpDir, "openapi.yaml")
|
|
|
|
|
err := ax.WriteFile(specPath, []byte("openapi: 3.0.0"), 0644)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, nil)
|
2026-04-01 20:45:45 +00:00
|
|
|
got, err := sdk.DetectSpec()
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, specPath, got)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestDetect_DetectSpecCommonYAMLPath_Good(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
specPath := ax.Join(tmpDir, "openapi.yml")
|
|
|
|
|
err := ax.WriteFile(specPath, []byte("openapi: 3.0.0"), 0644)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, nil)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
got, err := sdk.DetectSpec()
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, specPath, got)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_DetectSpecNotFound_Bad(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
sdk := New(tmpDir, nil)
|
|
|
|
|
_, err := sdk.DetectSpec()
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no OpenAPI spec found")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_DetectSpecConfigNotFound_Bad(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
sdk := New(tmpDir, &Config{Spec: "non-existent.yaml"})
|
|
|
|
|
_, err := sdk.DetectSpec()
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "configured spec not found")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_ContainsScramble_Good(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
tests := []struct {
|
|
|
|
|
data string
|
|
|
|
|
expected bool
|
|
|
|
|
}{
|
|
|
|
|
{`{"require": {"dedoc/scramble": "^0.1"}}`, true},
|
|
|
|
|
{`{"require": {"scramble": "^0.1"}}`, true},
|
|
|
|
|
{`{"require": {"laravel/framework": "^11.0"}}`, false},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
assert.Equal(t, tt.expected, containsScramble(tt.data))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 17:41:53 +00:00
|
|
|
func TestDetect_DetectScramble_Bad(t *testing.T) {
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
t.Run("no composer.json", func(t *testing.T) {
|
|
|
|
|
sdk := New(t.TempDir(), nil)
|
|
|
|
|
_, err := sdk.detectScramble()
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no composer.json")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("no scramble in composer.json", func(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
2026-03-26 17:41:53 +00:00
|
|
|
err := ax.WriteFile(ax.Join(tmpDir, "composer.json"), []byte(`{}`), 0644)
|
feat: extract build/, release/, sdk/ from go-devops
Build system (8 builders, signing, archiving), release pipeline
(7 publishers, versioning, changelog), and SDK generation
(OpenAPI diff, code gen). 18K LOC, all tests pass except Go
builder workspace isolation (pre-existing).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-09 12:37:36 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, nil)
|
|
|
|
|
_, err = sdk.detectScramble()
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "scramble not found")
|
|
|
|
|
})
|
|
|
|
|
}
|
2026-03-31 16:45:45 +00:00
|
|
|
|
|
|
|
|
func TestDetect_DetectSpecScramble_Good(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
err := ax.WriteFile(ax.Join(tmpDir, "composer.json"), []byte(`{"require":{"dedoc/scramble":"^0.1"}}`), 0o644)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
phpDir := t.TempDir()
|
|
|
|
|
writeFakePHP(t, phpDir)
|
|
|
|
|
t.Setenv("PATH", phpDir)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, nil)
|
|
|
|
|
got, err := sdk.DetectSpec()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, ax.Join(tmpDir, "api.json"), got)
|
|
|
|
|
|
|
|
|
|
data, err := ax.ReadFile(got)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Contains(t, string(data), `"openapi":"3.1.0"`)
|
|
|
|
|
}
|
2026-04-01 21:55:31 +00:00
|
|
|
|
|
|
|
|
func TestDetect_DetectSpecScrambleOverwritesExistingSpec_Good(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
require.NoError(t, ax.WriteFile(ax.Join(tmpDir, "composer.json"), []byte(`{"require":{"dedoc/scramble":"^0.1"}}`), 0o644))
|
|
|
|
|
require.NoError(t, ax.WriteFile(ax.Join(tmpDir, "api.json"), []byte(`{"openapi":"3.0.0","info":{"title":"stale"}}`), 0o644))
|
|
|
|
|
|
|
|
|
|
phpDir := t.TempDir()
|
|
|
|
|
writeFakePHP(t, phpDir)
|
|
|
|
|
t.Setenv("PATH", phpDir)
|
|
|
|
|
|
|
|
|
|
sdk := New(tmpDir, nil)
|
|
|
|
|
got, err := sdk.DetectSpec()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.Equal(t, ax.Join(tmpDir, "api.json"), got)
|
|
|
|
|
|
|
|
|
|
data, err := ax.ReadFile(got)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
assert.NotContains(t, string(data), "stale")
|
|
|
|
|
assert.Contains(t, string(data), `"openapi":"3.1.0"`)
|
|
|
|
|
}
|