package de.uni_hildesheim.sse.trans.convert;

import org.junit.Assert;
import org.junit.Test;

import de.uni_hildesheim.sse.model.cst.CSTSemanticException;
import de.uni_hildesheim.sse.model.cst.OCLFeatureCall;
import de.uni_hildesheim.sse.model.cst.Parenthesis;
import de.uni_hildesheim.sse.model.cst.Variable;
import de.uni_hildesheim.sse.model.varModel.Constraint;
import de.uni_hildesheim.sse.model.varModel.DecisionVariableDeclaration;
import de.uni_hildesheim.sse.model.varModel.datatypes.BooleanType;
import de.uni_hildesheim.sse.model.varModel.datatypes.OclKeyWords;

/**
 * Tests the {@link DisjunctionChecker}.
 * @author El-Sharkawy
 *
 */
public class DisjunctionCheckerTest {

    /**
     * Test whether a disjunction term will be classified correctly.
     * @throws CSTSemanticException Must not occur, otherwise there is an error inside the Model:
     * {@link Constraint#setConsSyntax(de.uni_hildesheim.sse.model.cst.ConstraintSyntaxTree)}
     */
    @Test
    public void testDisjunctionTerm() throws CSTSemanticException {
        DecisionVariableDeclaration declA = new DecisionVariableDeclaration("a", BooleanType.TYPE, null);
        DecisionVariableDeclaration declB = new DecisionVariableDeclaration("b", BooleanType.TYPE, null);
        DecisionVariableDeclaration declC = new DecisionVariableDeclaration("c", BooleanType.TYPE, null);
        
        Variable varB = new Variable(declB);
        OCLFeatureCall notB = new OCLFeatureCall(varB, OclKeyWords.NOT);
        OCLFeatureCall termA = new OCLFeatureCall(new Variable(declA), OclKeyWords.OR, varB);
        OCLFeatureCall termB = new OCLFeatureCall(new Variable(declC), OclKeyWords.OR, notB);
        Parenthesis parenthesis = new Parenthesis(termB);
        OCLFeatureCall completeTerm = new OCLFeatureCall(termA, OclKeyWords.OR, parenthesis);
        
        Constraint constraint = new Constraint(null);
        constraint.setConsSyntax(completeTerm);

        DisjunctionChecker checker = new DisjunctionChecker(constraint);
        Assert.assertTrue(checker.isDisjunctionTerm());
    }
    
    /**
     * Test whether a term, which is not a disjunction term, will be classified correctly.
     * @throws CSTSemanticException Must not occur, otherwise there is an error inside the Model:
     * {@link Constraint#setConsSyntax(de.uni_hildesheim.sse.model.cst.ConstraintSyntaxTree)}
     */
    @Test
    public void testNotDisjunctionTerm() throws CSTSemanticException {
        DecisionVariableDeclaration declA = new DecisionVariableDeclaration("a", BooleanType.TYPE, null);
        DecisionVariableDeclaration declB = new DecisionVariableDeclaration("b", BooleanType.TYPE, null);
        DecisionVariableDeclaration declC = new DecisionVariableDeclaration("c", BooleanType.TYPE, null);
        
        Variable varB = new Variable(declB);
        OCLFeatureCall notB = new OCLFeatureCall(varB, OclKeyWords.NOT);
        OCLFeatureCall termA = new OCLFeatureCall(new Variable(declA), OclKeyWords.OR, varB);
        OCLFeatureCall termB = new OCLFeatureCall(new Variable(declC), OclKeyWords.OR, notB);
        Parenthesis parenthesis = new Parenthesis(termB);
        OCLFeatureCall completeTerm = new OCLFeatureCall(termA, OclKeyWords.AND, parenthesis);
        
        Constraint constraint = new Constraint(null);
        constraint.setConsSyntax(completeTerm);
        
        DisjunctionChecker checker = new DisjunctionChecker(constraint);
        
        Assert.assertFalse(checker.isDisjunctionTerm());
    }

}
