Procházet zdrojové kódy

refactor: move JSON utility functions to separate package (#3302)

Signed-off-by: sneax <paladesh600@gmail.com>
Co-authored-by: Matt Bolt <mbolt35@gmail.com>
segfault_bits před 8 měsíci
rodič
revize
8b8e905f5b

+ 7 - 21
core/pkg/opencost/json.go

@@ -2,35 +2,21 @@ package opencost
 
 import (
 	"bytes"
-	"fmt"
-	"math"
 
-	"github.com/opencost/opencost/core/pkg/util/json"
+	"github.com/opencost/opencost/core/pkg/util/jsonutil"
 )
 
-// TODO move everything below to a separate package
-
+// jsonEncodeFloat64 encodes a float64 value to JSON, handling NaN and infinity values
 func jsonEncodeFloat64(buffer *bytes.Buffer, name string, val float64, comma string) {
-	var encoding string
-	if math.IsNaN(val) || math.IsInf(val, 0) {
-		encoding = fmt.Sprintf("\"%s\":null%s", name, comma)
-	} else {
-		encoding = fmt.Sprintf("\"%s\":%f%s", name, val, comma)
-	}
-
-	buffer.WriteString(encoding)
+	jsonutil.EncodeFloat64(buffer, name, val, comma)
 }
 
+// jsonEncodeString encodes a string value to JSON
 func jsonEncodeString(buffer *bytes.Buffer, name, val, comma string) {
-	buffer.WriteString(fmt.Sprintf("\"%s\":\"%s\"%s", name, val, comma))
+	jsonutil.EncodeString(buffer, name, val, comma)
 }
 
+// jsonEncode encodes any object to JSON
 func jsonEncode(buffer *bytes.Buffer, name string, obj interface{}, comma string) {
-	buffer.WriteString(fmt.Sprintf("\"%s\":", name))
-	if bytes, err := json.Marshal(obj); err != nil {
-		buffer.WriteString("null")
-	} else {
-		buffer.Write(bytes)
-	}
-	buffer.WriteString(comma)
+	jsonutil.Encode(buffer, name, obj, comma)
 }

+ 37 - 0
core/pkg/util/jsonutil/jsonutil.go

@@ -0,0 +1,37 @@
+package jsonutil
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+
+	"github.com/opencost/opencost/core/pkg/util/json"
+)
+
+// EncodeFloat64 encodes a float64 value to JSON, handling NaN and infinity values
+func EncodeFloat64(buffer *bytes.Buffer, name string, val float64, comma string) {
+	var encoding string
+	if math.IsNaN(val) || math.IsInf(val, 0) {
+		encoding = fmt.Sprintf("\"%s\":null%s", name, comma)
+	} else {
+		encoding = fmt.Sprintf("\"%s\":%f%s", name, val, comma)
+	}
+
+	buffer.WriteString(encoding)
+}
+
+// EncodeString encodes a string value to JSON
+func EncodeString(buffer *bytes.Buffer, name, val, comma string) {
+	buffer.WriteString(fmt.Sprintf("\"%s\":\"%s\"%s", name, val, comma))
+}
+
+// Encode encodes any object to JSON
+func Encode(buffer *bytes.Buffer, name string, obj interface{}, comma string) {
+	buffer.WriteString(fmt.Sprintf("\"%s\":", name))
+	if bytes, err := json.Marshal(obj); err != nil {
+		buffer.WriteString("null")
+	} else {
+		buffer.Write(bytes)
+	}
+	buffer.WriteString(comma)
+}

+ 76 - 0
core/pkg/util/jsonutil/jsonutil_test.go

@@ -0,0 +1,76 @@
+package jsonutil
+
+import (
+	"bytes"
+	"math"
+	"testing"
+)
+
+func TestEncodeFloat64(t *testing.T) {
+	buffer := &bytes.Buffer{}
+	
+	// Test normal float value
+	buffer.Reset()
+	EncodeFloat64(buffer, "test", 3.14, ",")
+	expected := `"test":3.140000,`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+	
+	// Test NaN value
+	buffer.Reset()
+	EncodeFloat64(buffer, "test", math.NaN(), ",")
+	expected = `"test":null,`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+	
+	// Test positive infinity
+	buffer.Reset()
+	EncodeFloat64(buffer, "test", math.Inf(1), ",")
+	expected = `"test":null,`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+	
+	// Test negative infinity
+	buffer.Reset()
+	EncodeFloat64(buffer, "test", math.Inf(-1), ",")
+	expected = `"test":null,`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+}
+
+func TestEncodeString(t *testing.T) {
+	buffer := &bytes.Buffer{}
+	EncodeString(buffer, "key", "value", ",")
+	expected := `"key":"value",`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+}
+
+func TestEncode(t *testing.T) {
+	buffer := &bytes.Buffer{}
+	
+	// Test with a simple struct
+	type testStruct struct {
+		Field string `json:"field"`
+	}
+	
+	testObj := testStruct{Field: "test"}
+	Encode(buffer, "key", testObj, ",")
+	expected := `"key":{"field":"test"},`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+	
+	// Test with nil (should produce null)
+	buffer.Reset()
+	Encode(buffer, "key", nil, ",")
+	expected = `"key":null,`
+	if buffer.String() != expected {
+		t.Errorf("Expected %s, got %s", expected, buffer.String())
+	}
+}