@@ -112,7 +112,15 @@ func (tr *TestRunner) RunTestSuite(suite TestSuite) TestResult {
112112 }
113113
114114 for _ , test := range suite .Tests {
115- testResult := tr .runTest (test )
115+ err := tr .runTest (test )
116+ testResult := SingleTestResult {
117+ TestID : test .ID ,
118+ Passed : err == nil ,
119+ }
120+ if err != nil {
121+ testResult .Message = err .Error ()
122+ }
123+
116124 result .TestResults = append (result .TestResults , testResult )
117125 if testResult .Passed {
118126 result .PassedTests ++
@@ -124,8 +132,9 @@ func (tr *TestRunner) RunTestSuite(suite TestSuite) TestResult {
124132 return result
125133}
126134
127- // runTest executes a single test case
128- func (tr * TestRunner ) runTest (test TestCase ) SingleTestResult {
135+ // runTest executes a single test case and validates the response.
136+ // Returns an error if communication with the handler fails or validation fails.
137+ func (tr * TestRunner ) runTest (test TestCase ) error {
129138 req := Request {
130139 ID : test .ID ,
131140 Method : test .Method ,
@@ -134,118 +143,102 @@ func (tr *TestRunner) runTest(test TestCase) SingleTestResult {
134143
135144 resp , err := tr .SendRequest (req )
136145 if err != nil {
137- return SingleTestResult {
138- TestID : test .ID ,
139- Passed : false ,
140- Message : fmt .Sprintf ("Failed to send request: %v" , err ),
141- }
142- }
143- if resp .ID != test .ID {
144- return SingleTestResult {
145- TestID : test .ID ,
146- Passed : false ,
147- Message : fmt .Sprintf ("Response ID mismatch: expected %s, got %s" , test .ID , resp .ID ),
148- }
146+ return err
149147 }
148+
150149 return validateResponse (test , resp )
151150}
152151
153- // validateResponse checks if response matches expected result
154- func validateResponse (test TestCase , resp * Response ) SingleTestResult {
155- // Check if we expected an error
152+ // validateResponse validates that a response matches the expected test outcome.
153+ // Returns an error if:
154+ //
155+ // Response ID does not match the request ID
156+ // Response does not match the expected outcome (error or success)
157+ func validateResponse (test TestCase , resp * Response ) error {
158+ if resp .ID != test .ID {
159+ return fmt .Errorf ("response ID mismatch: expected %s, got %s" , test .ID , resp .ID )
160+ }
161+
156162 if test .Expected .Error != nil {
157- if resp .Error == nil {
158- return SingleTestResult {
159- TestID : test .ID ,
160- Passed : false ,
161- Message : fmt .Sprintf ("Expected error type %s, but got no error" , test .Expected .Error .Type ),
162- }
163- }
163+ return validateResponseForError (test , resp )
164+ }
164165
165- // Check error type
166- if resp .Error .Type != test .Expected .Error .Type {
167- return SingleTestResult {
168- TestID : test .ID ,
169- Passed : false ,
170- Message : fmt .Sprintf ("Expected error type %s, got %s" , test .Expected .Error .Type , resp .Error .Type ),
171- }
172- }
166+ return validateResponseForSuccess (test , resp )
167+ }
173168
174- // Check error variant if specified
175- if test .Expected .Error .Variant != "" && resp .Error .Variant != test .Expected .Error .Variant {
176- return SingleTestResult {
177- TestID : test .ID ,
178- Passed : false ,
179- Message : fmt .Sprintf ("Expected error variant %s, got %s" , test .Expected .Error .Variant , resp .Error .Variant ),
180- }
181- }
169+ // validateResponseForError validates that a response correctly represents an error case.
170+ // It ensures the response contains an error, the result is null or omitted, and if an
171+ // error code is expected, it matches the expected type and member.
172+ func validateResponseForError (test TestCase , resp * Response ) error {
173+ if test .Expected .Error == nil {
174+ panic ("validateResponseForError expects non-nil error" )
175+ }
182176
183- return SingleTestResult {
184- TestID : test .ID ,
185- Passed : true ,
186- Message : "Test passed (expected error matched)" ,
177+ if resp . Error == nil {
178+ if test .Expected . Error . Code != nil {
179+ return fmt . Errorf ( "expected error %s.%s, but got no error" ,
180+ test . Expected . Error . Code . Type , test . Expected . Error . Code . Member )
187181 }
182+ return fmt .Errorf ("expected error, but got no error" )
188183 }
189184
190- // Check if we expected success
191- if test .Expected .Success != nil {
192- if resp .Error != nil {
193- errMsg := fmt .Sprintf ("Expected success, but got error: %s" , resp .Error .Type )
194- if resp .Error .Variant != "" {
195- errMsg += fmt .Sprintf (" (variant: %s)" , resp .Error .Variant )
196- }
197- return SingleTestResult {
198- TestID : test .ID ,
199- Passed : false ,
200- Message : errMsg ,
201- }
202- }
185+ if ! resp .Result .IsNullOrOmitted () {
186+ return fmt .Errorf ("expected result to be null or omitted when error is present, got: %s" , string (resp .Result ))
187+ }
203188
204- if resp .Success == nil {
205- return SingleTestResult {
206- TestID : test .ID ,
207- Passed : false ,
208- Message : "Expected success, but response contained no success field" ,
209- }
189+ if test .Expected .Error .Code != nil {
190+ if resp .Error .Code == nil {
191+ return fmt .Errorf ("expected error code %s.%s, but got error with no code" ,
192+ test .Expected .Error .Code .Type , test .Expected .Error .Code .Member )
210193 }
211194
212- // Normalize JSON for comparison
213- var expectedData , actualData interface {}
214- if err := json .Unmarshal (bytes .TrimSpace (* test .Expected .Success ), & expectedData ); err != nil {
215- return SingleTestResult {
216- TestID : test .ID ,
217- Passed : false ,
218- Message : fmt .Sprintf ("Invalid expected JSON: %v" , err ),
219- }
195+ if resp .Error .Code .Type != test .Expected .Error .Code .Type {
196+ return fmt .Errorf ("expected error type %s, got %s" , test .Expected .Error .Code .Type , resp .Error .Code .Type )
220197 }
221- if err := json .Unmarshal (bytes .TrimSpace (* resp .Success ), & actualData ); err != nil {
222- return SingleTestResult {
223- TestID : test .ID ,
224- Passed : false ,
225- Message : fmt .Sprintf ("Invalid response JSON: %v" , err ),
226- }
198+
199+ if resp .Error .Code .Member != test .Expected .Error .Code .Member {
200+ return fmt .Errorf ("expected error member %s, got %s" , test .Expected .Error .Code .Member , resp .Error .Code .Member )
227201 }
228- expectedNormalized , _ := json .Marshal (expectedData )
229- actualNormalized , _ := json .Marshal (actualData )
230-
231- if ! bytes .Equal (expectedNormalized , actualNormalized ) {
232- return SingleTestResult {
233- TestID : test .ID ,
234- Passed : false ,
235- Message : fmt .Sprintf ("Success mismatch:\n Expected: %s\n Actual: %s" , string (expectedNormalized ), string (actualNormalized )),
236- }
202+ }
203+ return nil
204+ }
205+
206+ // validateResponseForSuccess validates that a response correctly represents a success case.
207+ // It ensures the response contains no error, and if a result is expected, it matches the
208+ // expected value.
209+ func validateResponseForSuccess (test TestCase , resp * Response ) error {
210+ if test .Expected .Error != nil {
211+ panic ("validateResponseForSuccess expects nil error" )
212+ }
213+
214+ if resp .Error != nil {
215+ if resp .Error .Code != nil {
216+ return fmt .Errorf ("expected success with no error, but got error: %s.%s" , resp .Error .Code .Type , resp .Error .Code .Member )
237217 }
238- return SingleTestResult {
239- TestID : test .ID ,
240- Passed : true ,
241- Message : "Test passed" ,
218+ return fmt .Errorf ("expected success with no error, but got error" )
219+ }
220+
221+ if test .Expected .Result .IsNullOrOmitted () {
222+ if ! resp .Result .IsNullOrOmitted () {
223+ return fmt .Errorf ("expected null or omitted result, got: %s" , string (resp .Result ))
242224 }
225+ return nil
243226 }
244- return SingleTestResult {
245- TestID : test .ID ,
246- Passed : false ,
247- Message : "Test has no expected result defined" ,
227+
228+ expectedNorm , err := test .Expected . Result . Normalize ()
229+ if err != nil {
230+ return fmt . Errorf ( "failed to normalize expected result: %w" , err )
248231 }
232+
233+ actualNorm , err := resp .Result .Normalize ()
234+ if err != nil {
235+ return fmt .Errorf ("failed to normalize actual result: %w" , err )
236+ }
237+
238+ if expectedNorm != actualNorm {
239+ return fmt .Errorf ("result mismatch: expected %s, got %s" , expectedNorm , actualNorm )
240+ }
241+ return nil
249242}
250243
251244// TestResult contains results from running a test suite
0 commit comments