Appends `result` as the expected test output to `statement.newOutput` based on the given output type. Used in `EndToEndTest::rewriteTests` to rewrite outputs in test files.
| 280 | // Appends `result` as the expected test output to `statement.newOutput` based on the given output |
| 281 | // type. Used in `EndToEndTest::rewriteTests` to rewrite outputs in test files. |
| 282 | void TestRunner::generateOutput(QueryResult* result, TestStatement& statement, size_t resultIdx) { |
| 283 | TestQueryResult& testAnswer = statement.result[resultIdx]; |
| 284 | statement.testResultType = testAnswer.type; |
| 285 | switch (testAnswer.type) { |
| 286 | case ResultType::OK: { |
| 287 | statement.newOutput += |
| 288 | "---- " + (result->isSuccess() ? std::string("ok") : std::string("error")) + '\n'; |
| 289 | if (!result->isSuccess()) { |
| 290 | statement.newOutput += result->getErrorMessage() + '\n'; |
| 291 | } |
| 292 | } break; |
| 293 | case ResultType::HASH: { |
| 294 | std::string resultHash = |
| 295 | convertResultToMD5Hash(*result, statement.checkOutputOrder, statement.checkColumnNames); |
| 296 | statement.newOutput += "---- hash\n" + std::to_string(result->getNumTuples()) + |
| 297 | " tuples hashed to " + resultHash + '\n'; |
| 298 | } break; |
| 299 | case ResultType::TUPLES: { |
| 300 | statement.newOutput += |
| 301 | "---- " + std::to_string(result->getNumTuples() + statement.checkColumnNames) + '\n'; |
| 302 | std::vector<std::string> resultTuples = |
| 303 | convertResultToString(*result, statement.checkOutputOrder, statement.checkColumnNames); |
| 304 | |
| 305 | // Use the test file output if it otherwise matches the actual output. This allows |
| 306 | // preserving the existing user-written order and avoids producing unnecessary diffs. |
| 307 | auto orderedResults = testAnswer.expectedResult; |
| 308 | if (!statement.checkOutputOrder) { |
| 309 | std::ranges::sort(orderedResults); |
| 310 | } |
| 311 | auto& output = resultTuples == orderedResults ? testAnswer.expectedResult : resultTuples; |
| 312 | |
| 313 | for (auto& res : output) { |
| 314 | statement.newOutput += res + '\n'; |
| 315 | } |
| 316 | } break; |
| 317 | case ResultType::CSV_FILE: |
| 318 | // Not supported yet. |
| 319 | return; |
| 320 | case ResultType::ERROR_MSG: { |
| 321 | statement.newOutput += |
| 322 | "---- " + (result->isSuccess() ? std::string("ok") : std::string("error")) + '\n'; |
| 323 | statement.newOutput += StringUtils::rtrim(result->getErrorMessage()) + '\n'; |
| 324 | } break; |
| 325 | case ResultType::ERROR_REGEX: { |
| 326 | statement.newOutput += |
| 327 | "---- " + (result->isSuccess() ? std::string("ok") : std::string("error(regex)")) + |
| 328 | '\n'; |
| 329 | } break; |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | void TestRunner::outputFailedPlan(Connection& conn, const TestStatement& statement) { |
| 334 | spdlog::error("QUERY FAILED."); |
nothing calls this directly
no test coverage detected