mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2025-12-20 08:10:26 -06:00
207 lines
5.1 KiB
Go
207 lines
5.1 KiB
Go
package hatchet
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Mock Task implementation for testing
|
|
type mockTask struct {
|
|
name string
|
|
}
|
|
|
|
func (m *mockTask) GetName() string {
|
|
return m.name
|
|
}
|
|
|
|
type TestOutputStruct struct {
|
|
Value string `json:"value"`
|
|
Number int `json:"number"`
|
|
}
|
|
|
|
func TestTaskOutput_WithMapResult(t *testing.T) {
|
|
// Test the core functionality with a map result (most common case)
|
|
expectedOutput := TestOutputStruct{
|
|
Value: "test-value",
|
|
Number: 42,
|
|
}
|
|
|
|
// Create a workflow result with task-specific outputs
|
|
taskResults := map[string]any{
|
|
"task1": expectedOutput,
|
|
"task2": map[string]any{"other": "data"},
|
|
}
|
|
|
|
workflowResult := &WorkflowResult{
|
|
result: taskResults,
|
|
}
|
|
|
|
// Create mock task
|
|
task1 := &mockTask{name: "task1"}
|
|
|
|
// Test TaskOutput method
|
|
taskResult := workflowResult.TaskOutput(task1.GetName())
|
|
if taskResult == nil {
|
|
t.Fatal("TaskOutput returned nil")
|
|
}
|
|
|
|
// Test Into method
|
|
var actualOutput TestOutputStruct
|
|
err := taskResult.Into(&actualOutput)
|
|
if err != nil {
|
|
t.Fatalf("TaskResult.Into() failed: %v", err)
|
|
}
|
|
|
|
// Verify the output
|
|
if actualOutput.Value != expectedOutput.Value {
|
|
t.Errorf("Expected Value %s, got %s", expectedOutput.Value, actualOutput.Value)
|
|
}
|
|
if actualOutput.Number != expectedOutput.Number {
|
|
t.Errorf("Expected Number %d, got %d", expectedOutput.Number, actualOutput.Number)
|
|
}
|
|
}
|
|
|
|
func TestTaskOutput_WithJSONStringResult(t *testing.T) {
|
|
// Test with JSON string result (pointer to string)
|
|
expectedOutput := TestOutputStruct{
|
|
Value: "json-test",
|
|
Number: 456,
|
|
}
|
|
|
|
jsonBytes, err := json.Marshal(expectedOutput)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal test data: %v", err)
|
|
}
|
|
jsonString := string(jsonBytes)
|
|
|
|
taskResults := map[string]any{
|
|
"json-task": &jsonString,
|
|
}
|
|
|
|
workflowResult := &WorkflowResult{
|
|
result: taskResults,
|
|
}
|
|
|
|
task := &mockTask{name: "json-task"}
|
|
|
|
// Test TaskOutput and Into
|
|
taskResult := workflowResult.TaskOutput(task.GetName())
|
|
var actualOutput TestOutputStruct
|
|
err = taskResult.Into(&actualOutput)
|
|
if err != nil {
|
|
t.Fatalf("TaskResult.Into() failed: %v", err)
|
|
}
|
|
|
|
if actualOutput.Value != expectedOutput.Value {
|
|
t.Errorf("Expected Value %s, got %s", expectedOutput.Value, actualOutput.Value)
|
|
}
|
|
if actualOutput.Number != expectedOutput.Number {
|
|
t.Errorf("Expected Number %d, got %d", expectedOutput.Number, actualOutput.Number)
|
|
}
|
|
}
|
|
|
|
func TestTaskOutput_TaskNotFound(t *testing.T) {
|
|
// Test behavior when task is not found in results
|
|
taskResults := map[string]any{
|
|
"existing-task": TestOutputStruct{Value: "exists", Number: 1},
|
|
}
|
|
|
|
workflowResult := &WorkflowResult{
|
|
result: taskResults,
|
|
}
|
|
|
|
// Request a task that doesn't exist
|
|
nonExistentTask := &mockTask{name: "non-existent-task"}
|
|
taskResult := workflowResult.TaskOutput(nonExistentTask.GetName())
|
|
|
|
// Should return the entire result when task not found
|
|
var actualOutput map[string]any
|
|
err := taskResult.Into(&actualOutput)
|
|
if err != nil {
|
|
t.Fatalf("TaskResult.Into() failed: %v", err)
|
|
}
|
|
|
|
// Should contain all task results
|
|
if len(actualOutput) != 1 {
|
|
t.Errorf("Expected 1 result, got %d", len(actualOutput))
|
|
}
|
|
}
|
|
|
|
func TestTaskOutput_SingleTaskWorkflow(t *testing.T) {
|
|
// Test behavior with single task (common case)
|
|
expectedOutput := TestOutputStruct{
|
|
Value: "single-task",
|
|
Number: 789,
|
|
}
|
|
|
|
// Single task result map
|
|
taskResults := map[string]any{
|
|
"only-task": expectedOutput,
|
|
}
|
|
|
|
workflowResult := &WorkflowResult{
|
|
result: taskResults,
|
|
}
|
|
|
|
task := &mockTask{name: "only-task"}
|
|
|
|
// Test TaskOutput and Into
|
|
taskResult := workflowResult.TaskOutput(task.GetName())
|
|
var actualOutput TestOutputStruct
|
|
err := taskResult.Into(&actualOutput)
|
|
if err != nil {
|
|
t.Fatalf("TaskResult.Into() failed: %v", err)
|
|
}
|
|
|
|
if actualOutput.Value != expectedOutput.Value {
|
|
t.Errorf("Expected Value %s, got %s", expectedOutput.Value, actualOutput.Value)
|
|
}
|
|
if actualOutput.Number != expectedOutput.Number {
|
|
t.Errorf("Expected Number %d, got %d", expectedOutput.Number, actualOutput.Number)
|
|
}
|
|
}
|
|
|
|
func TestTaskResult_Into_InvalidJSON(t *testing.T) {
|
|
// Test error handling with invalid data
|
|
taskResult := &TaskResult{
|
|
result: make(chan int), // Cannot be marshaled to JSON
|
|
}
|
|
|
|
var output TestOutputStruct
|
|
err := taskResult.Into(&output)
|
|
if err == nil {
|
|
t.Fatal("Expected error when marshaling invalid data, got nil")
|
|
}
|
|
|
|
if !strings.Contains(err.Error(), "marshal") {
|
|
t.Errorf("Expected marshal error, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestTaskResult_Into_WithPointerToInterface(t *testing.T) {
|
|
// Test with pointer to interface{} (common internal representation)
|
|
expectedOutput := TestOutputStruct{
|
|
Value: "pointer-test",
|
|
Number: 999,
|
|
}
|
|
|
|
var data any = expectedOutput
|
|
taskResult := &TaskResult{
|
|
result: &data,
|
|
}
|
|
|
|
var actualOutput TestOutputStruct
|
|
err := taskResult.Into(&actualOutput)
|
|
if err != nil {
|
|
t.Fatalf("TaskResult.Into() failed: %v", err)
|
|
}
|
|
|
|
if actualOutput.Value != expectedOutput.Value {
|
|
t.Errorf("Expected Value %s, got %s", expectedOutput.Value, actualOutput.Value)
|
|
}
|
|
if actualOutput.Number != expectedOutput.Number {
|
|
t.Errorf("Expected Number %d, got %d", expectedOutput.Number, actualOutput.Number)
|
|
}
|
|
}
|