From 9782981fb258811bba8d08e9264150d37091609a Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sun, 31 May 2026 03:39:34 +0000 Subject: [PATCH] Migrate duplicated test fixtures --- internal/app/run_test.go | 110 ++++---------------------------- internal/cli/root_test.go | 71 ++------------------- internal/publish/output_test.go | 71 ++++++--------------- 3 files changed, 39 insertions(+), 213 deletions(-) diff --git a/internal/app/run_test.go b/internal/app/run_test.go index cb03db8..7db596f 100644 --- a/internal/app/run_test.go +++ b/internal/app/run_test.go @@ -3,7 +3,6 @@ package app import ( "bytes" "context" - "encoding/json" "fmt" "os" "path/filepath" @@ -15,6 +14,7 @@ import ( "gitea.maximumdirect.net/eric/distributor/internal/notify" "gitea.maximumdirect.net/eric/distributor/internal/state" "gitea.maximumdirect.net/eric/distributor/internal/storage" + "gitea.maximumdirect.net/eric/distributor/internal/testutil" ) func TestRunDryRunPrintsConfigSummary(t *testing.T) { @@ -436,61 +436,20 @@ type testFile struct { func writeSourceBundle(t *testing.T, root, relative string, opts testBundleOptions) bundle.Manifest { t.Helper() - if opts.ID == "" { - opts.ID = "weather.daily.brentwood.2026-05-30" + extraFiles := make([]testutil.SourceFile, 0, len(opts.ExtraFiles)) + for _, file := range opts.ExtraFiles { + extraFiles = append(extraFiles, testutil.SourceFile{Path: file.Path, Data: file.Data}) } - if opts.Created.IsZero() { - opts.Created = time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC) - } - bundleRoot := filepath.Join(root, filepath.FromSlash(relative)) - if err := os.MkdirAll(bundleRoot, 0o755); err != nil { - t.Fatalf("mkdir bundle: %v", err) - } - files := []struct { - path string - data string - }{ - {path: "report.md", data: "# Report\nSunny.\n"}, - {path: "summary.txt", data: "Summary\n"}, - } - for _, extra := range opts.ExtraFiles { - files = append(files, struct { - path string - data string - }{path: extra.Path, data: extra.Data}) - } - manifestFiles := make([]bundle.ManifestFile, 0, len(files)) - for _, file := range files { - if err := os.WriteFile(filepath.Join(bundleRoot, filepath.FromSlash(file.path)), []byte(file.data), 0o600); err != nil { - t.Fatalf("write source file: %v", err) - } - manifestFiles = append(manifestFiles, bundle.ManifestFile{ - Path: file.path, - SHA256: bundle.FileDigest([]byte(file.data)), - Size: int64(len(file.data)), - }) - } - manifest := bundle.Manifest{ - SchemaVersion: 1, - ID: opts.ID, - Created: opts.Created, - Files: manifestFiles, - } - manifest.Digest = bundle.BundleDigest(manifest.Files) - data, err := json.MarshalIndent(manifest, "", " ") - if err != nil { - t.Fatalf("marshal manifest: %v", err) - } - data = append(data, '\n') - if err := os.WriteFile(filepath.Join(bundleRoot, "manifest.json"), data, 0o600); err != nil { - t.Fatalf("write manifest: %v", err) - } - return manifest + return testutil.WriteSourceBundle(t, root, relative, testutil.BundleOptions{ + ID: opts.ID, + Created: opts.Created, + ExtraFiles: extraFiles, + }) } func writeLocalConfig(t *testing.T, sourceRoot, destinationRoot string) string { t.Helper() - return writeLocalConfigWithPolicy(t, sourceRoot, destinationRoot, true, false) + return testutil.WriteMinimalLocalConfig(t, sourceRoot, destinationRoot) } func writeLocalConfigWithPolicy(t *testing.T, sourceRoot, destinationRoot string, publishSource, publishHTML bool) string { @@ -521,20 +480,7 @@ pipelines: func writeFanoutConfig(t *testing.T, sourceRoot, firstDestination, secondDestination string) string { t.Helper() - return writeConfigFile(t, ` -pipelines: - - id: reports - source: - backend: local - path: `+sourceRoot+` - destinations: - - id: archive-one - backend: local - path: `+firstDestination+` - - id: archive-two - backend: local - path: `+secondDestination+` -`) + return testutil.WriteFanoutLocalConfig(t, sourceRoot, firstDestination, secondDestination) } func writeConfigFile(t *testing.T, body string) string { @@ -548,42 +494,12 @@ func writeConfigFile(t *testing.T, body string) string { func writeDestinationState(t *testing.T, root, relative string, manifest bundle.Manifest) { t.Helper() - bundleRoot := filepath.Join(root, filepath.FromSlash(relative)) - if err := os.MkdirAll(bundleRoot, 0o755); err != nil { - t.Fatalf("mkdir destination: %v", err) - } - destinationState := state.DistributorState{ - SchemaVersion: state.SchemaVersion, - PipelineID: "reports", - DestinationID: "archive", - PublishedAt: time.Date(2026, 5, 30, 11, 12, 0, 0, time.UTC), - Source: state.SourceState{Manifest: manifest}, - Outputs: []state.OutputFile{ - {Path: "report.md", Kind: state.OutputKindSource, SourcePath: "report.md", SHA256: manifest.Files[0].SHA256, Size: manifest.Files[0].Size}, - {Path: "summary.txt", Kind: state.OutputKindSource, SourcePath: "summary.txt", SHA256: manifest.Files[1].SHA256, Size: manifest.Files[1].Size}, - }, - } - data, err := json.MarshalIndent(destinationState, "", " ") - if err != nil { - t.Fatalf("marshal state: %v", err) - } - data = append(data, '\n') - if err := os.WriteFile(filepath.Join(bundleRoot, storage.StateFileName), data, 0o600); err != nil { - t.Fatalf("write state: %v", err) - } + testutil.WriteDestinationState(t, root, relative, manifest, testutil.DestinationStateOptions{}) } func readStateFile(t *testing.T, path string) state.DistributorState { t.Helper() - data, err := os.ReadFile(path) - if err != nil { - t.Fatalf("read state: %v", err) - } - destinationState, err := state.Parse(data) - if err != nil { - t.Fatalf("parse state: %v", err) - } - return destinationState + return testutil.ReadDestinationState(t, path) } func assertFile(t *testing.T, path, want string) { diff --git a/internal/cli/root_test.go b/internal/cli/root_test.go index d51b8e3..49958ee 100644 --- a/internal/cli/root_test.go +++ b/internal/cli/root_test.go @@ -9,6 +9,7 @@ import ( "testing" "gitea.maximumdirect.net/eric/distributor/internal/storage" + "gitea.maximumdirect.net/eric/distributor/internal/testutil" ) func TestExecuteRootHelp(t *testing.T) { @@ -161,22 +162,8 @@ func TestExecuteInspectArgs(t *testing.T) { func TestExecuteRunDryRun(t *testing.T) { sourceRoot := t.TempDir() - writeCLIBundle(t, sourceRoot) - configPath := filepath.Join(t.TempDir(), "config.yml") - err := os.WriteFile(configPath, []byte(` -pipelines: - - id: reports - source: - backend: local - path: `+sourceRoot+` - destinations: - - id: archive - backend: local - path: `+t.TempDir()+` -`), 0o600) - if err != nil { - t.Fatalf("write config: %v", err) - } + testutil.WriteSourceBundle(t, sourceRoot, "", testutil.BundleOptions{}) + configPath := testutil.WriteMinimalLocalConfig(t, sourceRoot, t.TempDir()) var stdout, stderr bytes.Buffer @@ -209,22 +196,8 @@ func TestExecuteRunRejectsExtraPositionalArgs(t *testing.T) { func TestExecuteRunPublishes(t *testing.T) { sourceRoot := t.TempDir() destinationRoot := t.TempDir() - writeCLIBundle(t, sourceRoot) - configPath := filepath.Join(t.TempDir(), "config.yml") - err := os.WriteFile(configPath, []byte(` -pipelines: - - id: reports - source: - backend: local - path: `+sourceRoot+` - destinations: - - id: archive - backend: local - path: `+destinationRoot+` -`), 0o600) - if err != nil { - t.Fatalf("write config: %v", err) - } + testutil.WriteSourceBundle(t, sourceRoot, "", testutil.BundleOptions{}) + configPath := testutil.WriteMinimalLocalConfig(t, sourceRoot, destinationRoot) var stdout, stderr bytes.Buffer @@ -250,37 +223,3 @@ func TestUnknownCommandIsUsageError(t *testing.T) { t.Fatalf("stderr = %q, want unknown command error", stderr.String()) } } - -func writeCLIBundle(t *testing.T, root string) { - t.Helper() - for _, file := range []struct { - path string - data string - }{ - {"manifest.json", `{ - "schema_version": 1, - "id": "weather.daily.brentwood.2026-05-30", - "digest": "sha256:099b205780d2b050024868399961b05731729a548d5d6329c7b06a6740dd75fe", - "created": "2026-05-30T11:10:00Z", - "files": [ - { - "path": "report.md", - "sha256": "sha256:3640fd37140ee4d2e0e93e78834f232ea67a50e7bc6279203690cc7de1975fa6", - "size": 16 - }, - { - "path": "summary.txt", - "sha256": "sha256:3cbb36aca330b3bd113955dfbada0adb7a5f95ad9f678bd61f175406c6a37e95", - "size": 8 - } - ] -} -`}, - {"report.md", "# Report\nSunny.\n"}, - {"summary.txt", "Summary\n"}, - } { - if err := os.WriteFile(filepath.Join(root, file.path), []byte(file.data), 0o600); err != nil { - t.Fatalf("write bundle file: %v", err) - } - } -} diff --git a/internal/publish/output_test.go b/internal/publish/output_test.go index 3b69604..6075906 100644 --- a/internal/publish/output_test.go +++ b/internal/publish/output_test.go @@ -3,42 +3,27 @@ package publish import ( "context" "testing" - "time" "gitea.maximumdirect.net/eric/distributor/internal/bundle" "gitea.maximumdirect.net/eric/distributor/internal/config" - "gitea.maximumdirect.net/eric/distributor/internal/storage" "gitea.maximumdirect.net/eric/distributor/internal/storage/fake" + "gitea.maximumdirect.net/eric/distributor/internal/testutil" "gitea.maximumdirect.net/eric/distributor/internal/transform" ) func TestPlanOutputsRejectsCollision(t *testing.T) { sourceBackend := fake.New() - if _, err := sourceBackend.WriteFile(context.Background(), "report.md", []byte("# Report\n"), storage.WriteOptions{}); err != nil { - t.Fatalf("WriteFile report.md error = %v", err) - } - if _, err := sourceBackend.WriteFile(context.Background(), "report.html", []byte("

source html

\n"), storage.WriteOptions{}); err != nil { - t.Fatalf("WriteFile report.html error = %v", err) - } - reportDigest := bundle.FileDigest([]byte("# Report\n")) - htmlDigest := bundle.FileDigest([]byte("

source html

\n")) - files := []bundle.ManifestFile{ - {Path: "report.md", SHA256: reportDigest, Size: 9}, - {Path: "report.html", SHA256: htmlDigest, Size: 19}, - } + sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{ + Files: []testutil.SourceFile{ + {Path: "report.md", Data: "# Report\n"}, + {Path: "report.html", Data: "

source html

\n"}, + }, + }) _, err := PlanOutputs(context.Background(), Request{ SourceBackend: sourceBackend, - SourceBundle: bundle.Bundle{ - Manifest: bundle.Manifest{ - SchemaVersion: 1, - ID: "bundle", - Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC), - Digest: bundle.BundleDigest(files), - Files: files, - }, - }, - Publish: config.PublishPolicy{Source: true, HTML: true}, - Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}}, + SourceBundle: sourceBundle, + Publish: config.PublishPolicy{Source: true, HTML: true}, + Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}}, Transformers: testResolver{transform.MarkdownToHTML: testTransformer{outputs: []transform.Output{{ Path: "report.html", SourcePath: "report.md", @@ -55,21 +40,14 @@ func TestPlanOutputsRejectsCollision(t *testing.T) { func TestPlanOutputsRejectsHTMLWithoutMarkdown(t *testing.T) { sourceBackend := fake.New() - if _, err := sourceBackend.WriteFile(context.Background(), "summary.txt", []byte("Summary\n"), storage.WriteOptions{}); err != nil { - t.Fatalf("WriteFile summary.txt error = %v", err) - } - files := []bundle.ManifestFile{{Path: "summary.txt", SHA256: bundle.FileDigest([]byte("Summary\n")), Size: 8}} + sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{ + Files: []testutil.SourceFile{{Path: "summary.txt", Data: "Summary\n"}}, + }) _, err := PlanOutputs(context.Background(), Request{ SourceBackend: sourceBackend, - SourceBundle: bundle.Bundle{Manifest: bundle.Manifest{ - SchemaVersion: 1, - ID: "bundle", - Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC), - Digest: bundle.BundleDigest(files), - Files: files, - }}, - Publish: config.PublishPolicy{HTML: true}, - Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}}, + SourceBundle: sourceBundle, + Publish: config.PublishPolicy{HTML: true}, + Transform: config.Transform{MarkdownToHTML: &config.MarkdownToHTML{Enabled: true, Mode: config.TransformModeSidecar}}, Transformers: testResolver{ transform.MarkdownToHTML: testTransformer{}, }, @@ -128,24 +106,17 @@ func TestPlanOutputsUsesRegisteredTransformer(t *testing.T) { func TestBuildRejectsHTMLWithoutTransform(t *testing.T) { sourceBackend := fake.New() destinationBackend := fake.New() - if _, err := sourceBackend.WriteFile(context.Background(), "report.md", []byte("# Report\n"), storage.WriteOptions{}); err != nil { - t.Fatalf("WriteFile report.md error = %v", err) - } - files := []bundle.ManifestFile{{Path: "report.md", SHA256: bundle.FileDigest([]byte("# Report\n")), Size: 9}} + sourceBundle := testutil.WriteFakeSourceBundle(t, sourceBackend, "", testutil.BundleOptions{ + Files: []testutil.SourceFile{{Path: "report.md", Data: "# Report\n"}}, + }) _, err := Build(context.Background(), Request{ PipelineID: "reports", DestinationID: "archive", SourceBackend: sourceBackend, DestinationBackend: destinationBackend, DestinationBundlePath: "", - SourceBundle: bundle.Bundle{Manifest: bundle.Manifest{ - SchemaVersion: 1, - ID: "bundle", - Created: time.Date(2026, 5, 30, 11, 10, 0, 0, time.UTC), - Digest: bundle.BundleDigest(files), - Files: files, - }}, - Publish: config.PublishPolicy{HTML: true}, + SourceBundle: sourceBundle, + Publish: config.PublishPolicy{HTML: true}, Transfer: config.TransferPolicy{ OnDestinationSame: config.TransferActionSkip, OnDestinationOlder: config.TransferActionReplace,