package net.ssehub.kernel_haven.feature_effects;

import java.util.List;

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

import net.ssehub.kernel_haven.SetUpException;
import net.ssehub.kernel_haven.analysis.AnalysisComponent;
import net.ssehub.kernel_haven.code_model.CodeBlock;
import net.ssehub.kernel_haven.code_model.CodeElement;
import net.ssehub.kernel_haven.code_model.SourceFile;
import net.ssehub.kernel_haven.feature_effects.FeatureEffectFinder.VariableWithFeatureEffect;
import net.ssehub.kernel_haven.feature_effects.PresenceConditionAnalysisHelper.SimplificationType;
import net.ssehub.kernel_haven.test_utils.TestConfiguration;
import net.ssehub.kernel_haven.util.Logger;
import net.ssehub.kernel_haven.util.logic.True;
import net.ssehub.kernel_haven.util.logic.Variable;

/**
 * Tests the {@link FeatureEffectFinder} without any simplification.
 * @author El-Sharkawy
 *
 */
public class FeatureEffectFinderTests extends AbstractFinderTests<VariableWithFeatureEffect> {
    
    /**
     * Initializes the logger.
     */
    @BeforeClass
    public static void setUpBeforeClass() {
        Logger.init();
    }
    
    /**
     * Checks if a variable, which is used at toplevel, has no feature effect condition.
     */
    @Test
    public void testAlwaysOnFeature() {
        Variable varA = new Variable("A");
        CodeElement element = new CodeBlock(varA);
        List<VariableWithFeatureEffect> results = detectFEs(element);
        
        // Test the expected outcome
        Assert.assertEquals(1,  results.size());
        VariableWithFeatureEffect result1 = results.get(0);
        Assert.assertEquals(varA.getName(), result1.getVariable());
        Assert.assertSame(True.INSTANCE, result1.getFeatureEffect());
    }

    /**
     * Runs the {@link FeatureEffectFinder} on the passed element and returns the result for testing.
     * @param element A mocked element, which should be analyzed by the {@link FeatureEffectFinder}. 
     * @return The detected feature effects.
     */
    private List<VariableWithFeatureEffect> detectFEs(CodeElement element) {
        return super.runAnalysis(element, SimplificationType.NO_SIMPLIFICATION);
    }
    
    @Override
    protected AnalysisComponent<VariableWithFeatureEffect> callAnalysor(TestConfiguration tConfig,
        AnalysisComponent<SourceFile> cmComponent) throws SetUpException {

        PcFinder pcFinder = new PcFinder(tConfig, cmComponent);
        FeatureEffectFinder feFinder = new FeatureEffectFinder(tConfig, pcFinder);
        feFinder.execute();
        return feFinder;
    }

}

@@ -712,16 +712,71 @@
 Logger;%0A
+import net.ssehub.kernel_haven.util.logic.Conjunction;%0A
 import n
@@ -815,16 +815,16 @@
 c.True;%0A
-
 import n
@@ -1708,22 +1708,870 @@
 t.assert
-Equals
+Same(varA.getName(), result1.getVariable());%0A        Assert.assertSame(True.INSTANCE, result1.getFeatureEffect());%0A    %7D%0A    %0A    /**%0A     * Checks if a variable, which is (always) nested below the same feature is handled correctly.%0A     */%0A    @Test%0A    public void testSimpleNestedFeature() %7B%0A        Variable varA = new Variable(%22A%22);%0A        Variable varB = new Variable(%22B%22);%0A        CodeElement element = new CodeBlock(varA);%0A        CodeElement nestedElement = new CodeBlock(new Conjunction(varB, varA));%0A        element.addNestedElement(nestedElement);%0A        List%3CVariableWithFeatureEffect%3E results = detectFEs(element);%0A        %0A        // Test the expected outcome (results should be ordered alphabetically)%0A        Assert.assertEquals(2,  results.size());%0A        VariableWithFeatureEffect resultA = results.get(0);%0A        Assert.assertSame
 (varA.ge
@@ -2577,33 +2577,33 @@
 etName(), result
-1
+A
 .getVariable());
@@ -2642,33 +2642,220 @@
 INSTANCE, result
-1
+A.getFeatureEffect());%0A        VariableWithFeatureEffect resultB = results.get(1);%0A        Assert.assertSame(varB.getName(), resultB.getVariable());%0A        Assert.assertSame(varA, resultB
 .getFeatureEffec

Test case for the detection of a real feature effect.