Implement artifact-level render command with Markdown output and update docs
This commit is contained in:
139
internal/render/normalize_test.go
Normal file
139
internal/render/normalize_test.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/seriatim/internal/artifact"
|
||||
"gitea.maximumdirect.net/eric/seriatim/schema"
|
||||
)
|
||||
|
||||
func TestFromOutputArtifactNormalizesSupportedSchemas(t *testing.T) {
|
||||
t.Run("full", func(t *testing.T) {
|
||||
sourceIndex := 0
|
||||
input := schema.Transcript{
|
||||
Metadata: schema.Metadata{
|
||||
Application: "seriatim",
|
||||
Version: "v-test",
|
||||
InputReader: "json-files",
|
||||
InputFiles: []string{"a.json"},
|
||||
PreprocessingModules: []string{"validate-raw"},
|
||||
PostprocessingModules: []string{"assign-ids", "validate-output"},
|
||||
OutputModules: []string{"json"},
|
||||
},
|
||||
Segments: []schema.Segment{
|
||||
{
|
||||
ID: 1,
|
||||
Source: "a.json",
|
||||
SourceSegmentIndex: &sourceIndex,
|
||||
Speaker: "Alice",
|
||||
Start: 1,
|
||||
End: 2,
|
||||
Text: "hello",
|
||||
Categories: []string{"background"},
|
||||
},
|
||||
},
|
||||
OverlapGroups: []schema.OverlapGroup{},
|
||||
}
|
||||
model := mustNormalizeOutputArtifact(t, input)
|
||||
if model.Schema != artifact.OutputSchemaFull {
|
||||
t.Fatalf("schema = %q, want %q", model.Schema, artifact.OutputSchemaFull)
|
||||
}
|
||||
if len(model.Segments) != 1 {
|
||||
t.Fatalf("segment count = %d, want 1", len(model.Segments))
|
||||
}
|
||||
if model.Segments[0].ID != 1 || model.Segments[0].Speaker != "Alice" || model.Segments[0].Text != "hello" {
|
||||
t.Fatalf("unexpected segment: %#v", model.Segments[0])
|
||||
}
|
||||
if len(model.Segments[0].Categories) != 1 || model.Segments[0].Categories[0] != "background" {
|
||||
t.Fatalf("categories = %#v, want [background]", model.Segments[0].Categories)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("intermediate", func(t *testing.T) {
|
||||
input := schema.IntermediateTranscript{
|
||||
Metadata: schema.IntermediateMetadata{
|
||||
Application: "seriatim",
|
||||
Version: "v-test",
|
||||
OutputSchema: artifact.OutputSchemaIntermediate,
|
||||
},
|
||||
Segments: []schema.IntermediateSegment{
|
||||
{ID: 1, Start: 1, End: 2, Speaker: "Alice", Text: "one", Categories: []string{}},
|
||||
{ID: 2, Start: 2, End: 3, Speaker: "Bob", Text: "two"},
|
||||
},
|
||||
}
|
||||
model := mustNormalizeOutputArtifact(t, input)
|
||||
if model.Schema != artifact.OutputSchemaIntermediate {
|
||||
t.Fatalf("schema = %q, want %q", model.Schema, artifact.OutputSchemaIntermediate)
|
||||
}
|
||||
if len(model.Segments[0].Categories) != 0 {
|
||||
t.Fatalf("segment[0] categories = %#v, want empty slice", model.Segments[0].Categories)
|
||||
}
|
||||
if len(model.Segments[1].Categories) != 0 {
|
||||
t.Fatalf("segment[1] categories = %#v, want empty slice", model.Segments[1].Categories)
|
||||
}
|
||||
if model.Segments[0].Categories == nil || model.Segments[1].Categories == nil {
|
||||
t.Fatal("expected non-nil empty categories slices")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("minimal", func(t *testing.T) {
|
||||
input := schema.MinimalTranscript{
|
||||
Metadata: schema.MinimalMetadata{
|
||||
Application: "seriatim",
|
||||
Version: "v-test",
|
||||
OutputSchema: artifact.OutputSchemaMinimal,
|
||||
},
|
||||
Segments: []schema.MinimalSegment{
|
||||
{ID: 1, Start: 1, End: 2, Speaker: "Alice", Text: "one"},
|
||||
},
|
||||
}
|
||||
model := mustNormalizeOutputArtifact(t, input)
|
||||
if model.Schema != artifact.OutputSchemaMinimal {
|
||||
t.Fatalf("schema = %q, want %q", model.Schema, artifact.OutputSchemaMinimal)
|
||||
}
|
||||
if len(model.Segments[0].Categories) != 0 {
|
||||
t.Fatalf("categories = %#v, want empty slice", model.Segments[0].Categories)
|
||||
}
|
||||
if model.Segments[0].Categories == nil {
|
||||
t.Fatal("expected non-nil empty categories slice")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestFromOutputArtifactRejectsMalformedAndRawInput(t *testing.T) {
|
||||
_, err := artifact.ParseOutputArtifactJSON([]byte(`{"metadata":`))
|
||||
if err == nil {
|
||||
t.Fatal("expected malformed JSON error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "input JSON is malformed") {
|
||||
t.Fatalf("unexpected malformed error: %v", err)
|
||||
}
|
||||
|
||||
rawWhisper := []byte(`{"segments":[{"id":0,"start":0.1,"end":1.2,"text":"hello","words":[{"word":"hello"}]}]}`)
|
||||
_, err = artifact.ParseOutputArtifactJSON(rawWhisper)
|
||||
if err == nil {
|
||||
t.Fatal("expected raw input artifact error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "not a valid seriatim output artifact") {
|
||||
t.Fatalf("unexpected raw input error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func mustNormalizeOutputArtifact(t *testing.T, value any) Transcript {
|
||||
t.Helper()
|
||||
data, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
parsed, err := artifact.ParseOutputArtifactJSON(data)
|
||||
if err != nil {
|
||||
t.Fatalf("parse: %v", err)
|
||||
}
|
||||
model, err := FromOutputArtifact(parsed)
|
||||
if err != nil {
|
||||
t.Fatalf("normalize: %v", err)
|
||||
}
|
||||
return model
|
||||
}
|
||||
Reference in New Issue
Block a user