| 1622 | } |
| 1623 | |
| 1624 | void DebuggerTestBase::testCommandHandler() |
| 1625 | { |
| 1626 | QFETCH(const bool, addCommandWithCurrentSessionHandler); |
| 1627 | QFETCH(const bool, destroyHandler); |
| 1628 | QFETCH(const bool, replaceSession); |
| 1629 | |
| 1630 | const QPointer session{createTestDebugSession()}; |
| 1631 | TestLaunchConfiguration cfg; |
| 1632 | |
| 1633 | constexpr auto breakpointLine = 40; // return 0; |
| 1634 | addDebugeeBreakpoint(breakpointLine); |
| 1635 | |
| 1636 | const ActiveStateSessionSpy sessionSpy(session); |
| 1637 | START_DEBUGGING_AND_WAIT_FOR_PAUSED_STATE_E(session, cfg, sessionSpy); |
| 1638 | QCOMPARE(currentMiLine(session), breakpointLine); |
| 1639 | |
| 1640 | auto handler = std::make_unique<MICommandResultSpy>(); |
| 1641 | |
| 1642 | const auto addCommand = [addCommandWithCurrentSessionHandler](MIDebugSession& session, const auto&... args) { |
| 1643 | if (addCommandWithCurrentSessionHandler) { |
| 1644 | session.addCommandWithCurrentSessionHandler(args...); |
| 1645 | } else { |
| 1646 | session.addCommand(args...); |
| 1647 | } |
| 1648 | }; |
| 1649 | addCommand(*session, MI::DataEvaluateExpression, "ts.a", handler.get(), &MICommandResultSpy::handle); |
| 1650 | |
| 1651 | // NOTE: the run() command (continue execution) is removed from the command queue and never sent to the debugger if |
| 1652 | // another session is created below (because starting a new session stops the debugger of the previous one). |
| 1653 | session->run(); |
| 1654 | QCOMPARE(handler->size(), 0); // an MI command is asynchronous |
| 1655 | |
| 1656 | if (destroyHandler) { |
| 1657 | handler.reset(); |
| 1658 | } |
| 1659 | |
| 1660 | if (replaceSession) { |
| 1661 | auto* const session2 = createTestDebugSession(); |
| 1662 | |
| 1663 | const ActiveStateSessionSpy sessionSpy2(session2); |
| 1664 | START_DEBUGGING_AND_WAIT_FOR_PAUSED_STATE_E(session2, cfg, sessionSpy2); |
| 1665 | QCOMPARE(currentMiLine(session2), breakpointLine); |
| 1666 | |
| 1667 | session2->run(); |
| 1668 | WAIT_FOR_STATE(session2, IDebugSession::EndedState); |
| 1669 | } |
| 1670 | |
| 1671 | // Wait for the (first) session to finish and be destroyed (if it is still alive). |
| 1672 | QTRY_COMPARE(session, nullptr); |
| 1673 | |
| 1674 | QCOMPARE(static_cast<bool>(handler), !destroyHandler); |
| 1675 | if (destroyHandler) { |
| 1676 | return; // no crash - good, nothing else to verify |
| 1677 | } |
| 1678 | |
| 1679 | if (addCommandWithCurrentSessionHandler && replaceSession) { |
| 1680 | // The first session stopped being current before the result of the command |
| 1681 | // arrived, therefore the current-session handler must not be invoked. |
nothing calls this directly
no test coverage detected