package model import ( "database/sql" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestBuildParameterDataObjectHashesCreatesCanonicalHashAndLocalAliases(t *testing.T) { records := []ParameterInitializationRecord{ { GridTag: "grid000", ZoneTag: "zone000", StationTag: "station000", StationIsLocal: true, ComponentUUID: "component-uuid", ComponentNSPath: "220kV_xuefulu1", ComponentTag: "cable_22", AttributeGroup: "base_extend", AttributeName: "vnom_kv", AttributeValue: "7800.00", AttributeType: "DOUBLE PRECISION", Description: sql.NullString{String: "额定电压", Valid: true}, DescriptionCount: 1, DynamicRecordCount: 1, }, } hashes, err := buildParameterDataObjectHashes(records) require.NoError(t, err) require.Len(t, hashes, 1) fullToken := "grid000.zone000.station000.220kV_xuefulu1.cable_22.base_extend.vnom_kv" shortToken := "220kV_xuefulu1.cable_22.base_extend.vnom_kv" assert.Equal(t, fullToken, hashes[0].Key) assert.Equal(t, []string{fullToken, shortToken}, hashes[0].Aliases) assert.Equal(t, "7800.00", hashes[0].Fields["value"]) assert.Equal(t, "PARAM", hashes[0].Fields["meta"]) assert.Equal(t, "DOUBLE PRECISION", hashes[0].Fields["type"]) assert.Equal(t, shortToken, hashes[0].Fields["name"]) assert.Equal(t, "额定电压", hashes[0].Fields["description"]) assert.Equal(t, fullToken, hashes[0].Fields["id"]) } func TestBuildParameterDataObjectHashesSkipsShortKeyForNonLocalStation(t *testing.T) { records := []ParameterInitializationRecord{ { GridTag: "grid", ZoneTag: "zone", StationTag: "station", StationIsLocal: false, ComponentUUID: "component-uuid", ComponentNSPath: "nspath", ComponentTag: "component", AttributeGroup: "stable", AttributeName: "attribute", AttributeValue: "true", AttributeType: "BOOLEAN", Description: sql.NullString{String: "属性", Valid: true}, DescriptionCount: 1, DynamicRecordCount: 1, }, } hashes, err := buildParameterDataObjectHashes(records) require.NoError(t, err) require.Len(t, hashes, 1) assert.Equal(t, "grid.zone.station.nspath.component.stable.attribute", hashes[0].Key) assert.Equal(t, []string{"grid.zone.station.nspath.component.stable.attribute"}, hashes[0].Aliases) assert.Equal(t, true, hashes[0].Fields["value"]) } func TestBuildParameterDataObjectHashesRejectsAmbiguousShortToken(t *testing.T) { baseRecord := ParameterInitializationRecord{ GridTag: "grid1", ZoneTag: "zone1", StationTag: "station1", StationIsLocal: true, ComponentUUID: "component-uuid-1", ComponentNSPath: "nspath", ComponentTag: "component", AttributeGroup: "stable", AttributeName: "attribute", AttributeValue: "1", AttributeType: "INTEGER", Description: sql.NullString{String: "属性", Valid: true}, DescriptionCount: 1, DynamicRecordCount: 1, } otherRecord := baseRecord otherRecord.GridTag = "grid2" otherRecord.ZoneTag = "zone2" otherRecord.StationTag = "station2" otherRecord.ComponentUUID = "component-uuid-2" _, err := buildParameterDataObjectHashes([]ParameterInitializationRecord{baseRecord, otherRecord}) require.Error(t, err) assert.Contains(t, err.Error(), "ambiguous parameter token") assert.Contains(t, err.Error(), "nspath.component.stable.attribute") } func TestParameterRedisValuePreservesHashRepresentations(t *testing.T) { tests := []struct { name string rawValue string expected any }{ {name: "null", rawValue: "null", expected: "null"}, {name: "string", rawValue: `"text"`, expected: "text"}, {name: "number precision", rawValue: "1234567890.123456789", expected: "1234567890.123456789"}, {name: "boolean", rawValue: "true", expected: true}, {name: "object", rawValue: `{"key":"value"}`, expected: `{"key":"value"}`}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { actual, err := parameterRedisValue(test.rawValue) require.NoError(t, err) assert.Equal(t, test.expected, actual) }) } }