Files
aego/modules/audio/editor/clip_document_test.go
sanspie 5eb1832907
ci-platforms / darwin amd64 smoke (push) Skipped
ci / build (amd64, linux, ubuntu-24.04) (push) Failing after 15m28s
ci / release (push) Skipped
ci-platforms / windows amd64 smoke (push) Skipped
ci-platforms / darwin arm64 smoke (push) Skipped
ci / checks (push) Successful in 7m47s
Complete Stage 12 for v0.12.0
2026-11-05 11:46:53 +03:00

105 lines
3.5 KiB
Go

package editor
import (
"bytes"
"encoding/binary"
"os"
"path/filepath"
"testing"
"aego/asset"
audioimport "aego/asset/importers/audio"
"aego/asset/pipeline"
"aego/core/log"
"aego/editor/core/context"
"aego/editor/core/document"
"aego/format/aetext"
"aego/project"
)
func TestAudioMetadataUsesSharedJournalWithoutEditingBinarySource(t *testing.T) {
pj, err := project.Create(t.TempDir(), "Audio", false)
if err != nil {
t.Fatal(err)
}
// A short PCM fixture exercises the existing importer, no audio device.
wav := make([]byte, 44+32)
copy(wav[0:], "RIFF")
binary.LittleEndian.PutUint32(wav[4:], uint32(len(wav)-8))
copy(wav[8:], "WAVEfmt ")
binary.LittleEndian.PutUint32(wav[16:], 16)
binary.LittleEndian.PutUint16(wav[20:], 1)
binary.LittleEndian.PutUint16(wav[22:], 1)
binary.LittleEndian.PutUint32(wav[24:], 8000)
binary.LittleEndian.PutUint32(wav[28:], 16000)
binary.LittleEndian.PutUint16(wav[32:], 2)
binary.LittleEndian.PutUint16(wav[34:], 16)
copy(wav[36:], "data")
binary.LittleEndian.PutUint32(wav[40:], 32)
const path = "assets/click.wav"
if err := os.WriteFile(filepath.Join(pj.Root, path), wav, 0644); err != nil {
t.Fatal(err)
}
imp := audioimport.New()
meta := asset.NewSourceMeta("audio", imp.Version(), imp.Defaults())
meta.Settings["extension_note"] = aetext.String("keep")
encoded := asset.MarshalSourceMeta(meta)
if err := os.WriteFile(filepath.Join(pj.Root, path+".meta"), encoded, 0644); err != nil {
t.Fatal(err)
}
registry := pipeline.NewImporterRegistry()
if err := registry.Register(imp); err != nil {
t.Fatal(err)
}
pl, err := pipeline.Open(pj, registry, log.Nop())
if err != nil {
t.Fatal(err)
}
defer pl.Close()
if _, _, err := pl.Scan(); err != nil {
t.Fatal(err)
}
batch, err := pl.ImportAll()
if err != nil || len(batch.Failed) != 0 {
t.Fatal("audio fixture import", err, batch.Failed)
}
ed := &context.Editor{Pipeline: pl, Docs: document.NewManager(document.Options{Root: pj.Root})}
if err := ed.Docs.Handlers().Register(document.Handler{ID: "audio.clip", Kinds: []asset.ArtifactKind{asset.ArtAudio}, Capabilities: document.View | document.EditMetadata}); err != nil {
t.Fatal(err)
}
p := &plugin{ed: ed, clip: clipEdit{id: meta.ID}}
after := meta.Settings.Clone()
after["gain"] = aetext.Float32(2)
p.write(ed, meta.Settings, after)
d := ed.Docs.AssetDocument(meta.ID)
if d == nil || d.Metadata == nil || d.Source != nil || !d.Dirty() || !d.Metadata.ExplicitSave {
t.Fatal("audio metadata has a private history or binary text source")
}
if raw, _ := os.ReadFile(ed.Docs.Abs(path + ".meta")); !bytes.Equal(raw, encoded) {
t.Fatal("audio control silently saved metadata")
}
if err := ed.UndoAsset(d); err != nil || d.Dirty() {
t.Fatal("audio edit is not one shared Undo step", err)
}
if err := ed.RedoAsset(d); err != nil {
t.Fatal(err)
}
if err := ed.SaveAsset(d); err != nil {
t.Fatal(err)
}
saved, err := asset.ParseSourceMeta(d.Metadata.Code.Bytes(), d.Metadata.Path)
if err != nil || saved.Settings.Float("gain", 0) != 2 || saved.Settings.String("extension_note", "") != "keep" {
t.Fatal("audio save lost settings or unknown semantic data", err)
}
if raw, _ := os.ReadFile(ed.Docs.Abs(path)); !bytes.Equal(raw, wav) {
t.Fatal("metadata save modified the binary audio source")
}
d.Metadata.Conflict = true
before := bytes.Clone(d.Metadata.Code.Bytes())
after["gain"] = aetext.Float32(3)
p.write(ed, saved.Settings, after)
if !bytes.Equal(before, d.Metadata.Code.Bytes()) {
t.Fatal("audio Inspector ignored an unresolved external conflict")
}
}