/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package abs.frontend.delta;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import abs.ABSTest.Config;
import abs.common.WrongProgramArgumentException;
import abs.frontend.analyser.ErrorMessage;
import abs.frontend.analyser.SemanticConditionList;
import abs.frontend.ast.*;
import abs.frontend.typechecker.TypeCheckerHelper;
public class ProductDeclarationTest extends DeltaTest {
@Test
public void oldProductSyntax() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1(F1, F2, F3);"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(3, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F2", "F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void productFeatureSet() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(3, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F2", "F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void productIntersect() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3} && {F2, F3};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(2, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F2", "F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void productUnion() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3} || {F4};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(4, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F2", "F3", "F4"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void productDifference() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3, F4} - {F2, F3};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(2, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F4"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void productName() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3};"
+ "product P2 = P1;"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P2");
Product impl = p.getProduct();
assertEquals(3, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F2", "F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test(expected=DeltaModellingException.class)
public void cylicProduct() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P4 = P5;"
+ "product P5 = P4;"
);
model.evaluateAllProductDeclarations();
}
@Test
public void undeclaredProduct() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = P2 && P3 || P4 || {F1, F2};"
);
ProductDecl p = model.findProduct("P1");
SemanticConditionList e = new SemanticConditionList();
typeCheck(model, p, e);
assertEquals(3, e.getErrorCount());
assertEquals(ErrorMessage.UNDECLARED_PRODUCT, e.getFirstError().msg);
}
@Test
public void validProduct() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3};"
+ "root FM {"
+ "group allof { F1, F2, F3 }"
+ "}"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
SemanticConditionList e = new SemanticConditionList();
typeCheck(model, p, e);
assertEquals(0, e.getErrorCount());
}
@Test
public void invalidProduct() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2};"
+ "root FM {"
+ "group allof { F1, F2, F3 }"
+ "}"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
SemanticConditionList e = new SemanticConditionList();
typeCheck(model, p, e);
assertEquals(1, e.getErrorCount());
assertEquals(ErrorMessage.INVALID_PRODUCT, e.getFirstError().msg);
}
@Test
public void complexExpression() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3} && {F3, F4} || {F5, F6} - {F6};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(2, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F3", "F5"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void complexExpressionWithParenthesis() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P1 = {F1, F2, F3} && ({F3, F4} || {F5}) || {F6} - {F6};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P1");
Product impl = p.getProduct();
assertEquals(1, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
@Test
public void rightSideProductName() throws WrongProgramArgumentException {
Model model = assertParseOk("product P1 = P2 && P3 || P4 || {F1, F2};");
ProductDecl p = model.findProduct("P1");
Set<String> actual = new HashSet<String>();
p.getProductExpr().setRightSideProductNames(actual);
assertEquals(3, actual.size());
Set<String> expected = new HashSet<String>(Arrays.asList("P2", "P3", "P4"));
assertEquals(expected, actual);
}
@Test
public void unorderedProduct() throws WrongProgramArgumentException {
Model model = assertParseOk(
"product P2 = P1;"
+ "product P3 = P2;"
+ "product P1 = {F1, F2, F3};"
);
model.evaluateAllProductDeclarations();
ProductDecl p = model.findProduct("P3");
Product impl = p.getProduct();
assertEquals(3, impl.getNumFeature());
Set<String> expected = new HashSet<String>(Arrays.asList("F1", "F2", "F3"));
Set<String> actual = new HashSet<String>();
for (Feature f : impl.getFeatures())
actual.add(f.getName());
assertEquals(expected, actual);
}
}