def printTestResult: . as $result | $result | if .passed then "Test \"\(.name)\" Passed" else (if (.loc != null) then " at \(.loc.file):\(.loc.line)" else "" end) as $fileLocation | "Test \"\(.name)\"\($fileLocation) Failed\nReason: \(.reason)\nOutput: \(.output | tojson)" end; def runTest($loc; $name; testExpr; checkResult; $expectError): try ( (null | testExpr) as $output | if $expectError then { $name, passed: false, reason: "Expected error but no error was raised", $output, $loc } elif ($output | checkResult) then { $name, passed: true, $output, $loc } else { $name, passed: false, reason: "Result was different from expected", $output, $loc } end ) catch ( . as $error | if ($expectError | not) then { $name, passed: false, reason: "Error caught when no error was expected", output: $error, $loc } elif ($expectError and ($error | checkResult)) then { $name, passed: true, output: $error, $loc } elif ($expectError and ($error | checkResult | not)) then { $name, passed: false, reason: "Expected error but received different error", output: $error, $loc } else error("unknown error") end ); def expectPassed: if (.passed | not) then error(. | printTestResult) end; def expectPassed($result): $result | expectPassed; def expectFailed: if (.passed) then error(. | printTestResult) end; def expectFailed($result): $result | expectFailed; def testTests: expectPassed(runTest( $__loc__; "passing test"; true; . == true; false )) | expectPassed(runTest( $__loc__; "error expected and equal"; error("error"); . == "error"; true )) | expectFailed(runTest( $__loc__; "failing test"; true; . == false; false )) | expectFailed(runTest( $__loc__; "error expected but no error"; null; . == null; true )) | expectFailed(runTest( $__loc__; "error not expected"; error("error"); . == null; false )) | expectFailed(runTest( $__loc__; "error different"; error("error"); . == "different error"; true )); def testLibMain: testTests | empty | halt_error(0);