All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.catools.common.extensions.verify.CVerificationInfo Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
package org.catools.common.extensions.verify;

import org.catools.common.collections.CList;
import org.catools.common.concurrent.CSleeper;
import org.catools.common.config.CConfigs;
import org.catools.common.date.CDate;
import org.catools.common.exception.CRuntimeException;
import org.catools.common.logger.CLogger;
import org.catools.common.text.CStringUtil;
import org.catools.common.text.match.CStringDiff;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import static org.catools.common.config.CConfigs.StringDiff.getDiffEditCost;

public class CVerificationInfo {
    private final A actual;
    private final E expected;
    private final String message;
    private final boolean printDiff;
    private final int waitInSeconds;
    private final int intervalInMilliSeconds;
    private final BiFunction verifyMethod;
    private final BiConsumer onFail;

    public CVerificationInfo(A actual, E expected, String message, boolean printDiff, BiFunction verifyMethod) {
        this(actual, expected, message, printDiff, -1, -1, verifyMethod);
    }

    public CVerificationInfo(A actual, E expected, String message, boolean printDiff, BiFunction verifyMethod, BiConsumer onFail) {
        this(actual, expected, message, printDiff, -1, -1, verifyMethod, onFail);
    }

    public CVerificationInfo(A actual, E expected, String message, boolean printDiff, int waitInSeconds, int intervalInMilliSeconds, BiFunction verifyMethod) {
        this(actual, expected, message, printDiff, waitInSeconds, intervalInMilliSeconds, verifyMethod, null);
    }

    public CVerificationInfo(A actual,
                             E expected,
                             String message,
                             boolean printDiff,
                             int waitInSeconds,
                             int intervalInMilliSeconds,
                             BiFunction verifyMethod,
                             BiConsumer onFail) {
        this.actual = actual;
        this.expected = expected;
        this.message = message;
        this.printDiff = printDiff;
        this.verifyMethod = verifyMethod;
        this.waitInSeconds = waitInSeconds;
        this.intervalInMilliSeconds = intervalInMilliSeconds;
        this.onFail = onFail;
    }

    public boolean test(CLogger logger, CList verificationMessages) {
        Boolean result = computerResult(logger);
        if (result.booleanValue()) {
            if (CConfigs.Logger.logPassedVerification()) {
                logger.pass(getMessage(true));
            }
        }
        else {
            String message = getMessage(false);
            logger.fail(message);
            verificationMessages.add(message);
        }
        return result.booleanValue();
    }

    private Boolean computerResult(CLogger logger) {
        // If waitInSeconds is not -1
        // then it means we should retry in case if the verification result is false for defined seconds and interval.
        if (waitInSeconds != -1) {
            return computerResultWithWait(logger);
        }
        Boolean result = false;
        try {
            result = verifyMethod.apply(actual, expected);
        } finally {
            if (!result) {
                applyOnFail(logger);
            }
        }
        return result;
    }

    private Boolean computerResultWithWait(CLogger logger) {
        boolean isTimeOuted = false;
        Throwable lastException = null;
        boolean result;

        CDate deadLine = new CDate().addSeconds(waitInSeconds);
        // A little ugly code for sake of debugging and branch readability
        while (true) {
            try {
                result = verifyMethod.apply(actual, expected);
                if (result) {
                    return true;
                }
                CSleeper.sleepTight(intervalInMilliSeconds);
            } catch (Throwable t) {
                lastException = t;
            }
            if (deadLine.before(CDate.now())) {
                isTimeOuted = true;
                break;
            }
        }

        applyOnFail(logger);

        if (lastException != null) {
            if (lastException instanceof RuntimeException) {
                throw (RuntimeException) lastException;
            }
            throw new CRuntimeException(lastException);
        }

        return !isTimeOuted;
    }

    private void applyOnFail(CLogger logger) {
        if (onFail != null) {
            try {
                onFail.accept(actual, expected);
            } catch (Throwable t) {
                logger.error(t);
            }
        }
    }

    private String getMessage(boolean passed) {
        String text1 = getString(expected);
        String text2 = getString(actual);
        if (!passed && printDiff) {
            String diff = CConfigs.Logger.logColoredOutput() ? CStringDiff.coloredDiff(text1, text2, getDiffEditCost()) : CStringDiff.prettyDiff(text1, text2, getDiffEditCost());
            return CStringUtil.format("%s.\\n" + "Diff: '%s',\\n" + "Exp: '%s',\\n" + "Act: '%s'", message, diff, text1, text2);
        }
        return CStringUtil.format("%s. Exp: '%s', Act: '%s'", message, text1, text2);
    }

    private String getString(Object obj) {
        if (obj == null) {
            return "";
        }
        return obj.getClass().isArray() ? new CList<>((String[]) obj).toString() : (obj + "");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy