package eu.dnetlib.validator2.engine

import eu.dnetlib.validator2.engine.builtins.AlwaysErrRule
import eu.dnetlib.validator2.engine.builtins.AlwaysFailRule
import eu.dnetlib.validator2.engine.builtins.AlwaysSucceedRule
import eu.dnetlib.validator2.engine.builtins.StandardRuleDiagnostics
import spock.lang.Shared
import spock.lang.Specification

class RuleEngineSpecification extends Specification {

    @Shared StandardRuleDiagnostics diagnostics = new StandardRuleDiagnostics()
    @Shared Reporter<String, Rule<String>> reporter = new Reporter<>(diagnostics)

    def "Engine reports the success of a rule evaluation correctly"() {
        given:
        AlwaysSucceedRule<String> rule = new AlwaysSucceedRule<>()

        when:
        RuleEngine.applyAndReport(rule, "whatever", reporter)

        then:
        diagnostics.getLastReportedError() == null &&
        diagnostics.getLastReportedStatus() == Status.SUCCESS &&
        diagnostics.getLastReportedRule() == rule &&
        "whatever" == diagnostics.getLastReportedValue()
    }

    def "Engine reports the failure of a rule evaluation correctly"() {
        given:
        AlwaysFailRule<String> rule = new AlwaysFailRule<>()

        when:
        RuleEngine.applyAndReport(rule, "whatever", reporter)

        then:
        diagnostics.getLastReportedError() == null &&
        diagnostics.getLastReportedStatus() == Status.FAILURE &&
        diagnostics.getLastReportedRule() == rule &&
        "whatever" == diagnostics.getLastReportedValue()
    }

    def "Engine reports the error of a rule evaluation correctly"() {
        given:
        AlwaysErrRule<String> rule = new AlwaysErrRule<>()

        when:
        RuleEngine.applyAndReport(rule, "whatever", reporter)

        then:
        diagnostics.getLastReportedError() != null &&
        diagnostics.getLastReportedError() instanceof RuleEvaluationException &&
        diagnostics.getLastReportedStatus() == Status.ERROR &&
        diagnostics.getLastReportedRule() == rule &&
        "whatever" == diagnostics.getLastReportedValue()
    }
}
