148 lines
4.1 KiB
Go
148 lines
4.1 KiB
Go
package appendorder
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/core/artifacts"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
|
)
|
|
|
|
func TestModuleSpecAndRegister(t *testing.T) {
|
|
want := pipeline.ModuleSpec{
|
|
Key: Key,
|
|
Stage: pipeline.StageMerge,
|
|
Provides: []string{"merged"},
|
|
}
|
|
if got := ModuleSpec(); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("ModuleSpec() = %#v, want %#v", got, want)
|
|
}
|
|
|
|
registry := pipeline.NewMergerRegistry()
|
|
if err := Register(registry); err != nil {
|
|
t.Fatalf("Register() error = %v, want nil", err)
|
|
}
|
|
spec, ok := registry.Spec(Key)
|
|
if !ok {
|
|
t.Fatalf("Spec(%q) ok = false, want true", Key)
|
|
}
|
|
if !reflect.DeepEqual(spec, want) {
|
|
t.Fatalf("registered spec = %#v, want %#v", spec, want)
|
|
}
|
|
}
|
|
|
|
func TestMergePreservesChunkAndCandidateOrder(t *testing.T) {
|
|
result, err := New().Merge(context.Background(), contracts.MergeRequest{
|
|
ChunkArtifacts: []contracts.ChunkArtifacts{
|
|
{
|
|
Chunk: sourceChunk(0),
|
|
Candidates: []artifacts.ArtifactCandidate{candidate(2, "first-b"), candidate(1, "first-a")},
|
|
},
|
|
{
|
|
Chunk: sourceChunk(1),
|
|
Candidates: []artifacts.ArtifactCandidate{candidate(4, "second-b"), candidate(3, "second-a")},
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Merge() error = %v, want nil", err)
|
|
}
|
|
|
|
got := candidateNames(result.Candidates)
|
|
want := []string{"first-b", "first-a", "second-b", "second-a"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("candidate order = %#v, want %#v", got, want)
|
|
}
|
|
if len(result.Warnings) != 0 {
|
|
t.Fatalf("Warnings = %#v, want none", result.Warnings)
|
|
}
|
|
}
|
|
|
|
func TestMergeDefensivelyCopiesCandidates(t *testing.T) {
|
|
input := []contracts.ChunkArtifacts{
|
|
{
|
|
Chunk: sourceChunk(0),
|
|
Candidates: []artifacts.ArtifactCandidate{candidate(1, "original")},
|
|
},
|
|
}
|
|
|
|
result, err := New().Merge(context.Background(), contracts.MergeRequest{ChunkArtifacts: input})
|
|
if err != nil {
|
|
t.Fatalf("Merge() error = %v, want nil", err)
|
|
}
|
|
if len(result.Candidates) != 1 {
|
|
t.Fatalf("len(Candidates) = %d, want 1", len(result.Candidates))
|
|
}
|
|
|
|
input[0].Candidates[0].Index = 99
|
|
input[0].Candidates[0].Payload[0] = '['
|
|
input[0].Candidates[0].SourceRefs[0].StartUnitID = "changed"
|
|
input[0].Candidates[0].Metadata["name"] = "changed"
|
|
|
|
got := result.Candidates[0]
|
|
if got.Index != 1 {
|
|
t.Fatalf("Index = %d, want 1", got.Index)
|
|
}
|
|
if string(got.Payload) != `{"name":"original"}` {
|
|
t.Fatalf("Payload = %s, want original payload", got.Payload)
|
|
}
|
|
if got.SourceRefs[0].StartUnitID != "u1" {
|
|
t.Fatalf("SourceRefs = %#v, want original source ref", got.SourceRefs)
|
|
}
|
|
if got.Metadata["name"] != "original" {
|
|
t.Fatalf("Metadata = %#v, want original metadata", got.Metadata)
|
|
}
|
|
}
|
|
|
|
func TestMergeHandlesEmptyInput(t *testing.T) {
|
|
result, err := New().Merge(context.Background(), contracts.MergeRequest{})
|
|
if err != nil {
|
|
t.Fatalf("Merge() error = %v, want nil", err)
|
|
}
|
|
if len(result.Candidates) != 0 {
|
|
t.Fatalf("len(Candidates) = %d, want 0", len(result.Candidates))
|
|
}
|
|
if len(result.Warnings) != 0 {
|
|
t.Fatalf("Warnings = %#v, want none", result.Warnings)
|
|
}
|
|
}
|
|
|
|
func candidate(index int, name string) artifacts.ArtifactCandidate {
|
|
return artifacts.ArtifactCandidate{
|
|
Index: index,
|
|
ExtractorKey: "generic-extractor",
|
|
ArtifactType: "generic-artifact",
|
|
SchemaVersion: "v1",
|
|
Payload: json.RawMessage(`{"name":"` + name + `"}`),
|
|
SourceRefs: []source.SourceRef{
|
|
{SourceID: "source-1", StartUnitID: "u1", EndUnitID: "u1"},
|
|
},
|
|
Metadata: map[string]any{
|
|
"name": name,
|
|
},
|
|
}
|
|
}
|
|
|
|
func candidateNames(candidates []artifacts.ArtifactCandidate) []string {
|
|
names := make([]string, 0, len(candidates))
|
|
for _, candidate := range candidates {
|
|
names = append(names, candidate.Metadata["name"].(string))
|
|
}
|
|
return names
|
|
}
|
|
|
|
func sourceChunk(index int) contracts.SourceChunk {
|
|
return contracts.SourceChunk{
|
|
ID: "chunk",
|
|
SourceID: "source-1",
|
|
Index: index,
|
|
Units: []source.SourceUnit{
|
|
{ID: "u1", Kind: "unit", Text: "Source unit."},
|
|
},
|
|
}
|
|
}
|