package model import ( "testing" "time" ) func TestDataPointID(t *testing.T) { tests := []struct { name string id DataPointID wantEqual DataPointID wantHash string }{ { name: "basic data point id", id: DataPointID{ DeviceID: "device1", MetricCode: "temperature", Labels: map[string]string{ "location": "room1", "floor": "1st", }, }, wantEqual: DataPointID{ DeviceID: "device1", MetricCode: "temperature", Labels: map[string]string{ "location": "room1", "floor": "1st", }, }, wantHash: "device1:temperature:floor=1st:location=room1", }, { name: "empty labels", id: DataPointID{ DeviceID: "device2", MetricCode: "humidity", Labels: map[string]string{}, }, wantEqual: DataPointID{ DeviceID: "device2", MetricCode: "humidity", Labels: map[string]string{}, }, wantHash: "device2:humidity:", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Test equality if !tt.id.Equal(tt.wantEqual) { t.Errorf("DataPointID.Equal() = false, want true") } // Test hash generation if hash := tt.id.Hash(); hash != tt.wantHash { t.Errorf("DataPointID.Hash() = %v, want %v", hash, tt.wantHash) } }) } } func TestDataValue(t *testing.T) { now := time.Now() tests := []struct { name string value DataValue want interface{} }{ { name: "float value", value: DataValue{ Timestamp: now, Value: 25.5, }, want: 25.5, }, { name: "integer value", value: DataValue{ Timestamp: now, Value: 100, }, want: 100, }, { name: "string value", value: DataValue{ Timestamp: now, Value: "test", }, want: "test", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.value.Value != tt.want { t.Errorf("DataValue.Value = %v, want %v", tt.value.Value, tt.want) } if !tt.value.Timestamp.Equal(now) { t.Errorf("DataValue.Timestamp = %v, want %v", tt.value.Timestamp, now) } }) } } func TestQuery(t *testing.T) { tests := []struct { name string queryType QueryType params map[string]interface{} wantType QueryType wantParams map[string]interface{} }{ { name: "latest query", queryType: QueryTypeLatest, params: nil, wantType: QueryTypeLatest, wantParams: map[string]interface{}{}, }, { name: "all query", queryType: QueryTypeAll, params: map[string]interface{}{ "limit": 100, }, wantType: QueryTypeAll, wantParams: map[string]interface{}{ "limit": 100, }, }, { name: "duration query", queryType: QueryTypeDuration, params: map[string]interface{}{ "from": "2023-01-01T00:00:00Z", "to": "2023-01-02T00:00:00Z", }, wantType: QueryTypeDuration, wantParams: map[string]interface{}{ "from": "2023-01-01T00:00:00Z", "to": "2023-01-02T00:00:00Z", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { query := NewQuery(tt.queryType, tt.params) if query.Type() != tt.wantType { t.Errorf("Query.Type() = %v, want %v", query.Type(), tt.wantType) } params := query.Params() if len(params) != len(tt.wantParams) { t.Errorf("Query.Params() length = %v, want %v", len(params), len(tt.wantParams)) } for k, v := range tt.wantParams { if params[k] != v { t.Errorf("Query.Params()[%v] = %v, want %v", k, params[k], v) } } }) } } func TestQueryResult(t *testing.T) { now := time.Now() tests := []struct { name string result Result wantLatest DataValue wantAll []DataValue wantDuration time.Duration }{ { name: "latest result", result: NewLatestResult(DataValue{ Timestamp: now, Value: 25.5, }), wantLatest: DataValue{ Timestamp: now, Value: 25.5, }, }, { name: "all result", result: NewAllResult([]DataValue{ { Timestamp: now, Value: 25.5, }, { Timestamp: now.Add(time.Second), Value: 26.0, }, }), wantAll: []DataValue{ { Timestamp: now, Value: 25.5, }, { Timestamp: now.Add(time.Second), Value: 26.0, }, }, }, { name: "duration result", result: NewDurationResult(time.Hour), wantDuration: time.Hour, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if latest, ok := tt.result.AsLatest(); ok { if !latest.Timestamp.Equal(tt.wantLatest.Timestamp) || latest.Value != tt.wantLatest.Value { t.Errorf("Result.AsLatest() = %v, want %v", latest, tt.wantLatest) } } if all, ok := tt.result.AsAll(); ok { if len(all) != len(tt.wantAll) { t.Errorf("Result.AsAll() length = %v, want %v", len(all), len(tt.wantAll)) } for i, v := range tt.wantAll { if !all[i].Timestamp.Equal(v.Timestamp) || all[i].Value != v.Value { t.Errorf("Result.AsAll()[%v] = %v, want %v", i, all[i], v) } } } if duration, ok := tt.result.AsDuration(); ok { if duration != tt.wantDuration { t.Errorf("Result.AsDuration() = %v, want %v", duration, tt.wantDuration) } } }) } }