picoclaw/pkg/tools/time_test.go
dtapps 0705b38b60 feat: add get_current_time tool
Add a new utility tool to get current time/date with the following features:
- Multiple output formats: iso, time, date, datetime, unix
- Timezone support (e.g., UTC, America/New_York, Asia/Shanghai)
- Configurable via PICOCLAW_TOOLS_GET_CURRENT_TIME_ENABLED env var
- Web UI support with utility category and i18n translations

The tool is registered in the agent tool registry and can be enabled/disabled
via configuration or web interface.
2026-04-27 21:21:16 +08:00

196 lines
4.9 KiB
Go

package tools
import (
"context"
"strings"
"testing"
"time"
)
func TestGetCurrentTimeTool_Name(t *testing.T) {
tool := NewGetCurrentTimeTool("")
if tool.Name() != "get_current_time" {
t.Errorf("expected name 'get_current_time', got %s", tool.Name())
}
}
func TestGetCurrentTimeTool_Description(t *testing.T) {
tool := NewGetCurrentTimeTool("")
if tool.Description() == "" {
t.Error("description should not be empty")
}
}
func TestGetCurrentTimeTool_Parameters(t *testing.T) {
tool := NewGetCurrentTimeTool("")
params := tool.Parameters()
if params == nil {
t.Fatal("parameters should not be nil")
}
// Check type
if params["type"] != "object" {
t.Errorf("expected type 'object', got %v", params["type"])
}
// Check properties exist
properties, ok := params["properties"].(map[string]any)
if !ok {
t.Fatal("properties should be a map")
}
if _, ok := properties["format"]; !ok {
t.Error("format property should exist")
}
if _, ok := properties["timezone"]; !ok {
t.Error("timezone property should exist")
}
}
func TestGetCurrentTimeTool_Execute_DefaultFormat(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Check that result contains time information
if result.ForLLM == "" {
t.Error("ForLLM should not be empty")
}
// Default format is ISO, should contain current year
currentYear := time.Now().Format("2006")
if !strings.Contains(result.ForLLM, currentYear) {
t.Errorf("result should contain current year %s, got: %s", currentYear, result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_TimeFormat(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"format": "time",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Time format should be HH:MM:SS
if !strings.Contains(result.ForLLM, ":") {
t.Errorf("time format should contain colon, got: %s", result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_DateFormat(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"format": "date",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Date format should be YYYY-MM-DD
currentYear := time.Now().Format("2006")
if !strings.Contains(result.ForLLM, currentYear) {
t.Errorf("date format should contain current year %s, got: %s", currentYear, result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_DateTimeFormat(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"format": "datetime",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Datetime format should contain both date and time
if !strings.Contains(result.ForLLM, "-") || !strings.Contains(result.ForLLM, ":") {
t.Errorf("datetime format should contain both date and time, got: %s", result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_UnixFormat(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"format": "unix",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Unix timestamp should be a number (just check it doesn't contain date separators)
// The response format is "Current time (Local): 1777295143" which contains a colon after "Local"
// So we just check the actual timestamp part is numeric
if !strings.Contains(result.ForLLM, "Current time") {
t.Errorf("result should contain 'Current time', got: %s", result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_WithTimezone(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"timezone": "UTC",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Errorf("should not return error: %s", result.ForLLM)
}
// Should mention UTC
if !strings.Contains(result.ForLLM, "UTC") {
t.Errorf("result should mention UTC timezone, got: %s", result.ForLLM)
}
}
func TestGetCurrentTimeTool_Execute_InvalidTimezone(t *testing.T) {
tool := NewGetCurrentTimeTool("")
result := tool.Execute(context.Background(), map[string]any{
"timezone": "Invalid/Timezone",
})
if result == nil {
t.Fatal("result should not be nil")
}
if result.IsError {
t.Error("should handle invalid timezone gracefully without error")
}
// Should fallback to Local
if !strings.Contains(result.ForLLM, "Local") {
t.Errorf("should fallback to Local timezone, got: %s", result.ForLLM)
}
}