@@ -51,3 +51,102 @@ func TestPredictionOutputSucceeded(t *testing.T) {
5151 }
5252 assert .Equal (t , expectedOutput , predictionResponse .Output )
5353}
54+
55+ func TestComplexOutputTypes (t * testing.T ) {
56+ t .Parallel ()
57+ if * legacyCog {
58+ t .Skip ("legacy Cog does not support complex output types" )
59+ }
60+ runtimeServer := setupCogRuntime (t , cogRuntimeServerConfig {
61+ procedureMode : false ,
62+ explicitShutdown : true ,
63+ uploadURL : "" ,
64+ module : "output_complex_types" ,
65+ predictorClass : "Predictor" ,
66+ })
67+ waitForSetupComplete (t , runtimeServer , runner .StatusReady , runner .SetupSucceeded )
68+
69+ input := map [string ]any {"s" : "test" }
70+ req := httpPredictionRequest (t , runtimeServer , runner.PredictionRequest {Input : input })
71+ resp , err := http .DefaultClient .Do (req )
72+ require .NoError (t , err )
73+ defer resp .Body .Close ()
74+ assert .Equal (t , http .StatusOK , resp .StatusCode )
75+ body , err := io .ReadAll (resp .Body )
76+ require .NoError (t , err )
77+ var predictionResponse server.PredictionResponse
78+ err = json .Unmarshal (body , & predictionResponse )
79+ require .NoError (t , err )
80+
81+ // Create expected output using JSON round-trip to match server serialization
82+ expectedOutputs := []map [string ]any {
83+ {
84+ "strings" : []string {"hello" , "world" },
85+ "numbers" : []int {1 , 2 , 3 },
86+ "single_item" : map [string ]any {
87+ "name" : "item1" ,
88+ "value" : 42 ,
89+ },
90+ "items" : []map [string ]any {
91+ {"name" : "item1" , "value" : 42 },
92+ {"name" : "item2" , "value" : 84 },
93+ },
94+ "container" : map [string ]any {
95+ "items" : []map [string ]any {
96+ {"name" : "item1" , "value" : 42 },
97+ {"name" : "item2" , "value" : 84 },
98+ },
99+ "tags" : []string {"tag1" , "tag2" },
100+ "nested" : map [string ]any {
101+ "item" : map [string ]any {"name" : "item1" , "value" : 42 },
102+ "description" : "nested description" ,
103+ },
104+ "optional_list" : []string {"opt1" , "opt2" },
105+ "count" : 2 ,
106+ },
107+ "nested_items" : []map [string ]any {
108+ {
109+ "item" : map [string ]any {"name" : "item1" , "value" : 42 },
110+ "description" : "nested description" ,
111+ },
112+ },
113+ },
114+ {
115+ "strings" : []string {"foo" , "bar" },
116+ "numbers" : []int {4 , 5 , 6 },
117+ "single_item" : map [string ]any {
118+ "name" : "item2" ,
119+ "value" : 84 ,
120+ },
121+ "items" : []map [string ]any {
122+ {"name" : "item2" , "value" : 84 },
123+ },
124+ "container" : map [string ]any {
125+ "items" : []map [string ]any {
126+ {"name" : "item1" , "value" : 42 },
127+ {"name" : "item2" , "value" : 84 },
128+ },
129+ "tags" : []string {"tag1" , "tag2" },
130+ "nested" : map [string ]any {
131+ "item" : map [string ]any {"name" : "item1" , "value" : 42 },
132+ "description" : "nested description" ,
133+ },
134+ "optional_list" : []string {"opt1" , "opt2" },
135+ "count" : 2 ,
136+ },
137+ "nested_items" : []map [string ]any {
138+ {
139+ "item" : map [string ]any {"name" : "item1" , "value" : 42 },
140+ "description" : "nested description" ,
141+ },
142+ },
143+ },
144+ }
145+ expectedJSON , err := json .Marshal (expectedOutputs )
146+ require .NoError (t , err )
147+ var expectedOutput []any
148+ err = json .Unmarshal (expectedJSON , & expectedOutput )
149+ require .NoError (t , err )
150+ assert .Equal (t , expectedOutput , predictionResponse .Output )
151+ assert .Equal (t , runner .PredictionSucceeded , predictionResponse .Status )
152+ }
0 commit comments