Files
2025-08-07 19:23:48 +08:00

233 lines
5.5 KiB
Go

/*
* Copyright 2025 The RuleGo Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package types
import (
"testing"
"time"
)
// TestRow 测试 Row 结构体的基本功能
func TestRow(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
testData := map[string]interface{}{
"user_id": 123,
"amount": 99.99,
"status": "active",
}
testSlot := &TimeSlot{
Start: &testTime,
End: func() *time.Time { t := testTime.Add(time.Hour); return &t }(),
}
row := &Row{
Timestamp: testTime,
Data: testData,
Slot: testSlot,
}
// 测试 GetTimestamp 方法
if !row.GetTimestamp().Equal(testTime) {
t.Errorf("Expected timestamp %v, got %v", testTime, row.GetTimestamp())
}
// 测试 Timestamp 字段
if !row.Timestamp.Equal(testTime) {
t.Errorf("Expected timestamp %v, got %v", testTime, row.Timestamp)
}
// 测试 Data 字段
if row.Data == nil {
t.Error("Expected Data to be non-nil")
}
dataMap, ok := row.Data.(map[string]interface{})
if !ok {
t.Error("Expected Data to be a map[string]interface{}")
}
if dataMap["user_id"] != 123 {
t.Errorf("Expected user_id 123, got %v", dataMap["user_id"])
}
if dataMap["amount"] != 99.99 {
t.Errorf("Expected amount 99.99, got %v", dataMap["amount"])
}
if dataMap["status"] != "active" {
t.Errorf("Expected status 'active', got %v", dataMap["status"])
}
// 测试 Slot 字段
if row.Slot == nil {
t.Error("Expected Slot to be non-nil")
}
if !row.Slot.Start.Equal(testTime) {
t.Errorf("Expected slot start %v, got %v", testTime, row.Slot.Start)
}
if !row.Slot.End.Equal(testTime.Add(time.Hour)) {
t.Errorf("Expected slot end %v, got %v", testTime.Add(time.Hour), row.Slot.End)
}
}
// TestRowWithNilData 测试 Row 结构体处理 nil 数据的情况
func TestRowWithNilData(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
row := &Row{
Timestamp: testTime,
Data: nil,
Slot: nil,
}
// 测试 GetTimestamp 方法仍然正常工作
if !row.GetTimestamp().Equal(testTime) {
t.Errorf("Expected timestamp %v, got %v", testTime, row.GetTimestamp())
}
// 测试 nil 数据
if row.Data != nil {
t.Error("Expected Data to be nil")
}
// 测试 nil slot
if row.Slot != nil {
t.Error("Expected Slot to be nil")
}
}
// TestRowWithDifferentDataTypes 测试 Row 结构体处理不同数据类型的情况
func TestRowWithDifferentDataTypes(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
// 测试字符串数据
rowString := &Row{
Timestamp: testTime,
Data: "test string data",
}
if rowString.Data != "test string data" {
t.Errorf("Expected string data 'test string data', got %v", rowString.Data)
}
// 测试数字数据
rowNumber := &Row{
Timestamp: testTime,
Data: 42,
}
if rowNumber.Data != 42 {
t.Errorf("Expected number data 42, got %v", rowNumber.Data)
}
// 测试布尔数据
rowBool := &Row{
Timestamp: testTime,
Data: true,
}
if rowBool.Data != true {
t.Errorf("Expected boolean data true, got %v", rowBool.Data)
}
// 测试切片数据
sliceData := []string{"item1", "item2", "item3"}
rowSlice := &Row{
Timestamp: testTime,
Data: sliceData,
}
resultSlice, ok := rowSlice.Data.([]string)
if !ok {
t.Error("Expected Data to be a []string")
}
if len(resultSlice) != 3 {
t.Errorf("Expected slice length 3, got %d", len(resultSlice))
}
if resultSlice[0] != "item1" {
t.Errorf("Expected first item 'item1', got %v", resultSlice[0])
}
}
// TestRowEventInterface 测试 Row 实现 RowEvent 接口
func TestRowEventInterface(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
row := &Row{
Timestamp: testTime,
Data: "test data",
}
// 验证 Row 实现了 RowEvent 接口
var rowEvent RowEvent = row
if !rowEvent.GetTimestamp().Equal(testTime) {
t.Errorf("Expected timestamp %v from RowEvent interface, got %v", testTime, rowEvent.GetTimestamp())
}
}
// TestRowZeroTime 测试 Row 结构体处理零时间的情况
func TestRowZeroTime(t *testing.T) {
zeroTime := time.Time{}
row := &Row{
Timestamp: zeroTime,
Data: "test data",
}
if !row.GetTimestamp().Equal(zeroTime) {
t.Errorf("Expected zero timestamp %v, got %v", zeroTime, row.GetTimestamp())
}
if !row.GetTimestamp().IsZero() {
t.Error("Expected timestamp to be zero")
}
}
// TestRowConcurrentAccess 测试 Row 结构体的并发访问
func TestRowConcurrentAccess(t *testing.T) {
testTime := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
row := &Row{
Timestamp: testTime,
Data: "test data",
}
// 启动多个 goroutine 并发访问 GetTimestamp 方法
done := make(chan bool, 10)
for i := 0; i < 10; i++ {
go func() {
for j := 0; j < 100; j++ {
timestamp := row.GetTimestamp()
if !timestamp.Equal(testTime) {
t.Errorf("Concurrent access failed: expected %v, got %v", testTime, timestamp)
}
}
done <- true
}()
}
// 等待所有 goroutine 完成
for i := 0; i < 10; i++ {
<-done
}
}