diff --git a/OpenGraph.go b/OpenGraph.go index f53071c..dfaba65 100644 --- a/OpenGraph.go +++ b/OpenGraph.go @@ -260,14 +260,21 @@ func (g *OpenGraph) ExportJSON(includeMetadata bool) (string, error) { graphContent := make(map[string]interface{}) // Convert nodes to dict format - var nodesData []map[string]interface{} + // Initialize nodesData as an empty slice (not nil) so it marshals to [] instead of null if no nodes exist. + nodesData := make([]map[string]interface{}, 0, len(g.nodes)) for _, n := range g.nodes { nodesData = append(nodesData, n.ToDict()) } graphContent["nodes"] = nodesData // Convert edges to dict format - var edgesData []map[string]interface{} + // Initialize edgesData as an empty slice (not nil) so it marshals to [] instead of null if no edges exist. + // The original `var edgesData []map[string]interface{}` declares a nil slice. + // If `g.edges` is empty, the loop is skipped, and `edgesData` remains nil, + // which `json.Marshal` converts to `null`. + // By using `make([]map[string]interface{}, 0)`, it's explicitly an empty slice, + // which `json.Marshal` converts to `[]`. + edgesData := make([]map[string]interface{}, 0, len(g.edges)) for _, e := range g.edges { edgesData = append(edgesData, e.ToDict()) } diff --git a/OpenGraph_test.go b/OpenGraph_test.go index 325bc0f..30f89de 100644 --- a/OpenGraph_test.go +++ b/OpenGraph_test.go @@ -3,12 +3,92 @@ package gopengraph_test import ( "testing" + "encoding/json" + "github.com/TheManticoreProject/gopengraph" "github.com/TheManticoreProject/gopengraph/edge" "github.com/TheManticoreProject/gopengraph/node" "github.com/TheManticoreProject/gopengraph/properties" ) +func TestExportJSON(t *testing.T) { + t.Run("empty graph exports empty nodes and edges arrays", func(t *testing.T) { + g := gopengraph.NewOpenGraph("test-source") + jsonData, err := g.ExportJSON(true) + if err != nil { + t.Fatalf("ExportJSON failed: %v", err) + } + + var result map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &result); err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + + graphContent, ok := result["graph"].(map[string]interface{}) + if !ok { + t.Fatalf("Expected 'graph' key in JSON output") + } + + // Check for empty nodes array + nodes, ok := graphContent["nodes"].([]interface{}) + if !ok { + t.Fatalf("Expected 'nodes' key to be an array") + } + if len(nodes) != 0 { + t.Errorf("Expected 'nodes' array to be empty, got %d elements", len(nodes)) + } + + // Check for empty edges array + edges, ok := graphContent["edges"].([]interface{}) + if !ok { + t.Fatalf("Expected 'edges' key to be an array") + } + if len(edges) != 0 { + t.Errorf("Expected 'edges' array to be empty, got %d elements", len(edges)) + } + }) + + t.Run("metadata not present when includeMetadata is false", func(t *testing.T) { + g := gopengraph.NewOpenGraph("test-source") // Ensure sourceKind is set for potential metadata + jsonData, err := g.ExportJSON(false) + if err != nil { + t.Fatalf("ExportJSON failed: %v", err) + } + + var result map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &result); err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + + if _, exists := result["metadata"]; exists { + t.Error("Expected 'metadata' key not to be present when includeMetadata is false") + } + }) + + t.Run("metadata present when includeMetadata is true and sourceKind is set", func(t *testing.T) { + g := gopengraph.NewOpenGraph("test-source") + jsonData, err := g.ExportJSON(true) + if err != nil { + t.Fatalf("ExportJSON failed: %v", err) + } + + var result map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &result); err != nil { + t.Fatalf("Failed to unmarshal JSON: %v", err) + } + + metadata, ok := result["metadata"].(map[string]interface{}) + if !ok { + t.Fatalf("Expected 'metadata' key to be present and a map when includeMetadata is true") + } + + sourceKind, ok := metadata["source_kind"].(string) + if !ok || sourceKind != "test-source" { + t.Errorf("Expected 'source_kind' in metadata to be 'test-source', got %v", metadata["source_kind"]) + } + }) +} + func TestNewOpenGraph(t *testing.T) { g := gopengraph.NewOpenGraph("test") if g == nil {