// Copyright 2024 Matthew Rich . All rights reserved. package folio import ( "fmt" "github.com/stretchr/testify/assert" "path/filepath" "strings" "testing" "decl/internal/data" "decl/internal/codec" "decl/internal/types" "io" "log/slog" ) var ( TestResourceTypes *types.Types[data.Resource] = types.New[data.Resource]() ) func TestNewDocument(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes d := NewDocument(nil) assert.NotNil(t, d) } func TestDocumentInterface(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes var doc data.Document = NewDocument(nil) assert.NotNil(t, doc) } func TestDocumentLoader(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes slog.Info("TestDocumentLoader", "rt", TestResourceTypes) file, _ := filepath.Abs(filepath.Join(TempDir, "foo.txt")) document := fmt.Sprintf(` --- resources: - type: foo attributes: name: "%s" size: %d - type: bar attributes: name: "testbar" size: %d `, file, 55, 11) d := NewDocument(nil) assert.NotNil(t, d) assert.Equal(t, TestResourceTypes, d.Types()) docReader := io.NopCloser(strings.NewReader(document)) e := d.LoadReader(docReader, codec.FormatYaml) assert.Nil(t, e) resources := d.Resources() assert.Equal(t, 2, len(resources)) } func TestDocumentGenerator(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes f := NewFooResource() assert.NotNil(t, f) expected := fmt.Sprintf(` format: yaml resources: - type: foo attributes: name: %s size: %d `, "mytestresource", 3) var documentYaml strings.Builder d := NewDocument(nil) assert.NotNil(t, d) f.Name = "mytestresource" f.Size = 3 d.AddResourceDeclaration("foo", f) ey := d.Generate(&documentYaml) assert.Nil(t, ey) assert.Greater(t, documentYaml.Len(), 0) assert.YAMLEq(t, expected, documentYaml.String()) } func TestDocumentAddResource(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes d := NewDocument(nil) assert.NotNil(t, d) e := d.AddResource("foo://bar") assert.Nil(t, e) } func TestDocumentJSON(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes document := ` --- resources: - type: foo attributes: name: "testfoo" size: 10022 ` d := NewDocument(nil) assert.NotNil(t, d) docReader := io.NopCloser(strings.NewReader(document)) e := d.LoadReader(docReader, codec.FormatYaml) assert.Nil(t, e) marshalledJSON, jsonErr := d.JSON() assert.Nil(t, jsonErr) assert.Greater(t, len(marshalledJSON), 0) } func TestDocumentJSONSchema(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes document := NewDocument(nil) document.ResourceDeclarations = []*Declaration{} e := document.Validate() assert.Nil(t, e) f := NewFooResource() assert.NotNil(t, f) f.Name = "mytestresource" f.Size = 3 document.AddResourceDeclaration("foo", f) resourceErr := document.Validate() assert.ErrorContains(t, resourceErr, "Must be greater than or equal to 5") f.Size = 7 b := NewBarResource() assert.NotNil(t, b) b.Name = "testbarresource" b.Size = 3 b.Owner = "a" document.AddResourceDeclaration("bar", b) assert.ErrorContains(t, document.Validate(), "String length must be greater than or equal to 3") } func TestDocumentYAML(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes document := ` --- format: yaml resources: - type: testuser attributes: name: "foo" uid: "10022" group: "10022" home: "/home/foo" ` d := NewDocument(nil) assert.NotNil(t, d) docReader := io.NopCloser(strings.NewReader(document)) e := d.LoadReader(docReader, codec.FormatYaml) assert.Nil(t, e) marshalledYAML, yamlErr := d.YAML() assert.Nil(t, yamlErr) assert.YAMLEq(t, string(document), string(marshalledYAML)) } func TestDocumentResourceFilter(t *testing.T) { DocumentRegistry.ResourceTypes = TestResourceTypes document := ` --- resources: - type: testuser attributes: name: "testuser" uid: "10022" home: "/home/testuser" - type: foo attributes: name: "foo.txt" - type: bar attributes: name: "bar.txt" ` d := NewDocument(nil) assert.NotNil(t, d) docReader := io.NopCloser(strings.NewReader(document)) e := d.LoadReader(docReader, codec.FormatYaml) assert.Nil(t, e) resources := d.Filter(func(d data.Declaration) bool { return d.ResourceType() == "foo" }) assert.Equal(t, 1, len(resources)) }