Skip to content

4. Inspect Override Expectations

After finish running the overrided functions, you can inspect what functions did not meet the expectations you set during the instruct phase.


Check Failed Expectations

Use CO_GET_FAILED_EXPECTS to get a list of functions that failed to meet their expectations:

std::vector<std::string> failedFunctions = CO_GET_FAILED_EXPECTS(overrideInstance);

This returns a vector of function names (as strings) that - Failed the .Expected() checks - Failed the .ExpectedNotSatisfy() checks

In addition to that, if passthrough doesn't meet the expectation but cannot contribute to any specific function (Say must passthrough 5 times, but only passthrough 3 times), then the string "Passthrough" will be added to the vector. Otherwise, the string "(Passthrough)" will be appended to the functions that contributes to the failure of the expectation.

Example
CO_DECLARE_INSTANCE(MyOverrideInstance);

//Set up expectations
CO_INSTRUCT_REF(MyOverrideInstance, CO_GLOBAL, MyFunction)
               .WhenCalledWith(42)
               .Returns<int>(100)
               .Times(2)
               .Expected();

CO_INSTRUCT_REF(MyOverrideInstance, CO_GLOBAL, AnotherFunction)
               .Returns<void>()
               .ExpectedNotSatisfy();

//Run your code
MyFunction(42);        //Called once, but expected twice
AnotherFunction();     //Called, but expected not to be called

//Check for failed expectations
std::vector<std::string> failed = CO_GET_FAILED_EXPECTS(MyOverrideInstance);

if(!failed.empty())
{
    std::cout << "Failed expectations:" << std::endl;
    for(const std::string& funcName : failed)
    {
        std::cout << "- " << funcName << std::endl;
    }
}


Debug Override Logs

If for any reason, it is unclear why the override did not get triggered and the override result did not give any useful information. You can force CppOverride to output verbose logs by defining CO_SHOW_OVERRIDE_LOG 1 before #include "CppOverride.hpp".

This will show all the debug logs on each stage of selecting override data and what conditions are not met.


Override Result

CppOverride::ResultPtr is just a shared_ptr defined as this

using ResultPtr = std::shared_ptr<OverrideResult>;

Each time when there's an override attempt (whether successful or not), it will add to the list of override status.

To get the list of status:

std::vector<OverrideStatus> statuses = result.GetAllStatuses();

List of possible status
enum class OverrideStatus
{
    //Default status.
    // Any matching override will modify the status to not be this value.
    // If the status is not modified (i.e. staying in this value), 
    // Could be one of these reasons:
    // - Function name not matching
    // - Argument types not matching
    // - Return type not matching
    NO_OVERRIDE,

    //The last override was successful. 
    // Please reset the status to NO_OVERRIDE before every expected override. 
    // If the status is not reset, it will not be modified if no matching override is found.
    OVERRIDE_SUCCESS,

    MATCHING_CONDITION_VALUE_FAILED,
    MATCHING_CONDITION_ACTION_FAILED,
    MATCHING_OVERRIDE_TIMES_FAILED,

    //------------------------------------------
    //Internal error
    //------------------------------------------
    INTERNAL_MISSING_CHECK_ERROR,

    //------------------------------------------
    //Unsupported operation errors
    //------------------------------------------
    MODIFY_NON_ASSIGNABLE_ARG_ERROR,
    MODIFY_CONST_ARG_ERROR,
    CHECK_ARG_MISSING_INEQUAL_OPERATOR_ERROR,
};

Here are a list of helper functions to perform the most common actions:

class OverrideResult
{
    //Returns true if status list is not empty and last one is OVERRIDE_SUCCESS
    bool LastStatusSucceed();

    //Returns true if status list is not empty and last one is **NOT** OVERRIDE_SUCCESS
    bool LastStatusFailed();

    //Returns the last status if the status list is not empty, otherwise NO_OVERRIDE
    OverrideStatus GetLastStatus();

    //Returns true if the status list contains said status
    bool HasStatus(OverrideStatus status);

    //Returns the number of status in the status list
    int GetStatusCount();

    //Returns the number of statuses that are OVERRIDE_SUCCESS
    int GetSucceedCount();

    //Returns the number of statuses that are **NOT** OVERRIDE_SUCCESS
    int GetFailedCount();

    //Removes all the status from the status list
    void ClearStatuses()

    //Get a copy of the status list
    std::vector<OverrideStatus> GetAllStatuses()
};


Get Override Results For A Specific Function

Use CO_GET_OVERRIDE_RESULTS to get detailed result information for a specific function:

std::vector<CppOverride::ResultPtr> results = CO_GET_OVERRIDE_RESULTS(overrideInstance, functionName);

This returns a vector of ResultPtr objects (one for each override instruction for that function) containing detailed status information.

Note

If you have multiple overrides for the same function, the results will be returned in the order you set up the instructs for the overrides.

Example
CO_DECLARE_INSTANCE(MyOverrideInstance);

//Set up multiple overrides for the same function
CO_INSTRUCT_REF(MyOverrideInstance, CO_GLOBAL, MyFunction)
               .WhenCalledWith(1)
               .Returns<int>(100)
               .Expected();

CO_INSTRUCT_REF(MyOverrideInstance, CO_GLOBAL, MyFunction)
               .WhenCalledWith(2)
               .Returns<int>(200)
               .Expected();

//Run your code
MyFunction(1);
MyFunction(3);  //This won't match any override

//Get detailed results
std::vector<CppOverride::ResultPtr> results = 
    CO_GET_OVERRIDE_RESULTS(MyOverrideInstance, "MyFunction");

for(size_t i = 0; i < results.size(); ++i)
{
    if(results[i])
    {
        std::cout << "Override " << i << ":" << std::endl;
        std::cout << "  Success count: " << results[i]->GetSucceedCount() << std::endl;
        std::cout << "  Failed count: " << results[i]->GetFailedCount() << std::endl;
        std::cout << "  Last status: " << 
            CppOverride::OverrideStatusToString(results[i]->GetLastStatus()) << std::endl;
    }
}