Path: blob/main/pkg/river/internal/value/value_object_test.go
4096 views
package value_test12import (3"testing"45"github.com/grafana/agent/pkg/river/internal/value"6"github.com/stretchr/testify/require"7)89// TestBlockRepresentation ensures that the struct tags for blocks are10// represented correctly.11func TestBlockRepresentation(t *testing.T) {12type UnlabledBlock struct {13Value int `river:"value,attr"`14}15type LabeledBlock struct {16Value int `river:"value,attr"`17Label string `river:",label"`18}19type OuterBlock struct {20Attr1 string `river:"attr_1,attr"`21Attr2 string `river:"attr_2,attr"`2223UnlabledBlock1 UnlabledBlock `river:"unlabeled.a,block"`24UnlabledBlock2 UnlabledBlock `river:"unlabeled.b,block"`25UnlabledBlock3 UnlabledBlock `river:"other_unlabeled,block"`2627LabeledBlock1 LabeledBlock `river:"labeled.a,block"`28LabeledBlock2 LabeledBlock `river:"labeled.b,block"`29LabeledBlock3 LabeledBlock `river:"other_labeled,block"`30}3132val := OuterBlock{33Attr1: "value_1",34Attr2: "value_2",35UnlabledBlock1: UnlabledBlock{36Value: 1,37},38UnlabledBlock2: UnlabledBlock{39Value: 2,40},41UnlabledBlock3: UnlabledBlock{42Value: 3,43},44LabeledBlock1: LabeledBlock{45Value: 4,46Label: "label_a",47},48LabeledBlock2: LabeledBlock{49Value: 5,50Label: "label_b",51},52LabeledBlock3: LabeledBlock{53Value: 6,54Label: "label_c",55},56}5758t.Run("Map decode", func(t *testing.T) {59var m map[string]interface{}60require.NoError(t, value.Decode(value.Encode(val), &m))6162type object = map[string]interface{}6364expect := object{65"attr_1": "value_1",66"attr_2": "value_2",67"unlabeled": object{68"a": object{"value": float64(1)},69"b": object{"value": float64(2)},70},71"other_unlabeled": object{"value": float64(3)},72"labeled": object{73"a": object{74"label_a": object{"value": float64(4)},75},76"b": object{77"label_b": object{"value": float64(5)},78},79},80"other_labeled": object{81"label_c": object{"value": float64(6)},82},83}8485require.Equal(t, m, expect)86})8788t.Run("Object decode from other object", func(t *testing.T) {89// Decode into a separate type which is structurally identical but not90// literally the same.91type OuterBlock2 OuterBlock9293var actualVal OuterBlock294require.NoError(t, value.Decode(value.Encode(val), &actualVal))95require.Equal(t, val, OuterBlock(actualVal))96})97}9899// TestSquashedBlockRepresentation ensures that the struct tags for squashed100// blocks are represented correctly.101func TestSquashedBlockRepresentation(t *testing.T) {102type InnerStruct struct {103InnerField1 string `river:"inner_field_1,attr,optional"`104InnerField2 string `river:"inner_field_2,attr,optional"`105}106107type OuterStruct struct {108OuterField1 string `river:"outer_field_1,attr,optional"`109Inner InnerStruct `river:",squash"`110OuterField2 string `river:"outer_field_2,attr,optional"`111}112113val := OuterStruct{114OuterField1: "value1",115Inner: InnerStruct{116InnerField1: "value3",117InnerField2: "value4",118},119OuterField2: "value2",120}121122t.Run("Map decode", func(t *testing.T) {123var m map[string]interface{}124require.NoError(t, value.Decode(value.Encode(val), &m))125126type object = map[string]interface{}127128expect := object{129"outer_field_1": "value1",130"inner_field_1": "value3",131"inner_field_2": "value4",132"outer_field_2": "value2",133}134135require.Equal(t, m, expect)136})137}138139func TestSliceOfBlocks(t *testing.T) {140type UnlabledBlock struct {141Value int `river:"value,attr"`142}143type LabeledBlock struct {144Value int `river:"value,attr"`145Label string `river:",label"`146}147type OuterBlock struct {148Attr1 string `river:"attr_1,attr"`149Attr2 string `river:"attr_2,attr"`150151Unlabeled []UnlabledBlock `river:"unlabeled,block"`152Labeled []LabeledBlock `river:"labeled,block"`153}154155val := OuterBlock{156Attr1: "value_1",157Attr2: "value_2",158Unlabeled: []UnlabledBlock{159{Value: 1},160{Value: 2},161{Value: 3},162},163Labeled: []LabeledBlock{164{Label: "label_a", Value: 4},165{Label: "label_b", Value: 5},166{Label: "label_c", Value: 6},167},168}169170t.Run("Map decode", func(t *testing.T) {171var m map[string]interface{}172require.NoError(t, value.Decode(value.Encode(val), &m))173174type object = map[string]interface{}175type list = []interface{}176177expect := object{178"attr_1": "value_1",179"attr_2": "value_2",180"unlabeled": list{181object{"value": float64(1)},182object{"value": float64(2)},183object{"value": float64(3)},184},185"labeled": object{186"label_a": object{"value": float64(4)},187"label_b": object{"value": float64(5)},188"label_c": object{"value": float64(6)},189},190}191192require.Equal(t, m, expect)193})194195t.Run("Object decode from other object", func(t *testing.T) {196// Decode into a separate type which is structurally identical but not197// literally the same.198type OuterBlock2 OuterBlock199200var actualVal OuterBlock2201require.NoError(t, value.Decode(value.Encode(val), &actualVal))202require.Equal(t, val, OuterBlock(actualVal))203})204}205206207