1+ import org .junit .jupiter .params .ParameterizedTest ;
2+ import org .junit .jupiter .params .provider .MethodSource ;
3+ import org .prop4j .And ;
4+ import org .prop4j .Literal ;
5+ import org .prop4j .Node ;
6+ import org .prop4j .Or ;
7+ import org .variantsync .diffdetective .feature .PropositionalFormulaParser ;
8+
9+ import java .util .List ;
10+
11+ import static org .variantsync .diffdetective .util .Assert .assertEquals ;
12+
13+ public class PropositionalFormulaParserTest {
14+ private record TestCase (String formula , Node expected ) {
15+ }
16+
17+ /*
18+ * These testCases are based on a subset of the CPPParserTest testCases.
19+ * It is not necessary to keep all testCases from CPPParserTest as most of them result in a single but long Literal anyway.
20+ * The idea is to ensure that the PropositionalFormulaParser is not confused by any symbols in the output of CPPDiffLineFormulaExtractor.
21+ * It is not designed to extensively test the functionality of the PropositionalFormulaParser itself as this is expected to be tested by FeatureIDE already.
22+ */
23+ private static List <TestCase > testCases () {
24+ return List .of (
25+ new TestCase ("A" , new Literal ("A" )),
26+ new TestCase ("!(A)" , new Literal ("A" , false )),
27+ new TestCase ("!A" , new Literal ("A" , false )),
28+
29+ new TestCase ("A&&B" , new And (new Literal ("A" ), new Literal ("B" ))),
30+ new TestCase ("A||B" , new Or (new Literal ("A" ), new Literal ("B" ))),
31+ new TestCase ("A&&(B||C)" , new And (new Literal ("A" ), new Or (new Literal ("B" ), new Literal ("C" )))),
32+ new TestCase ("A&&B||C" , new Or (new And (new Literal ("A" ), new Literal ("B" )), new Literal ("C" ))),
33+
34+ new TestCase ("A__GEQ__B&&C__GT__D" , new And (new Literal ("A__GEQ__B" ), new Literal ("C__GT__D" ))),
35+ new TestCase ("DEFINED___LB__A__RB__&&__LB__B__MUL__2__RB____GT__C" , new And (new Literal ("DEFINED___LB__A__RB__" ), new Literal ("__LB__B__MUL__2__RB____GT__C" ))),
36+ new TestCase ("(STDC__EQ__1)&&(DEFINED___LB__LARGE__RB__||DEFINED___LB__COMPACT__RB__)" , new And (new Literal ("STDC__EQ__1" ), new Or (new Literal ("DEFINED___LB__LARGE__RB__" ), new Literal ("DEFINED___LB__COMPACT__RB__" )))),
37+ new TestCase ("APR_CHARSET_EBCDIC&&!(__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25)" , new And (new Literal ("APR_CHARSET_EBCDIC" ), new Literal ("__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25" , false ))),
38+ new TestCase ("A&&(B__GT__C)" , new And (new Literal ("A" ), new Literal ("B__GT__C" ))),
39+ new TestCase ("A&&(__LB__B__ADD__1__RB____GT____LB__C__L_OR__D__RB__)" , new And (new Literal ("A" ), new Literal ("__LB__B__ADD__1__RB____GT____LB__C__L_OR__D__RB__" ))),
40+ new TestCase ("DEFINED_HAS_ATTRIBUTE_&&HAS_ATTRIBUTE___LB__nonnull__RB__" , new And (new Literal ("DEFINED_HAS_ATTRIBUTE_" ), new Literal ("HAS_ATTRIBUTE___LB__nonnull__RB__" ))),
41+ new TestCase ("HAS_BUILTIN___LB__nonnull__RB__&&A" , new And (new Literal ("HAS_BUILTIN___LB__nonnull__RB__" ), new Literal ("A" ))),
42+ new TestCase ("A||(DEFINED___LB__NAME__RB__&&(NAME__GEQ__199630))" , new Or (new Literal ("A" ), new And (new Literal ("DEFINED___LB__NAME__RB__" ), new Literal ("NAME__GEQ__199630" )))),
43+ new TestCase ("(DEFINED___LB__NAME__RB__&&(NAME__GEQ__199905)&&(NAME__LT__1991011))||(NAME__GEQ__300000)||DEFINED___LB__NAME__RB__" , new Or (new And (new Literal ("DEFINED___LB__NAME__RB__" ), new And (new Literal ("NAME__GEQ__199905" ), new Literal ("NAME__LT__1991011" ))), new Or (new Literal ("NAME__GEQ__300000" ), new Literal ("DEFINED___LB__NAME__RB__" )))),
44+ new TestCase ("1__GT____U_MINUS__42" , new Literal ("1__GT____U_MINUS__42" )),
45+ new TestCase ("1__GT____U_PLUS__42" , new Literal ("1__GT____U_PLUS__42" )),
46+ new TestCase ("42__GT____U_TILDE__A" , new Literal ("42__GT____U_TILDE__A" )),
47+ new TestCase ("A__ADD__B__GT__42" , new Literal ("A__ADD__B__GT__42" )),
48+ new TestCase ("A__LSHIFT__B" , new Literal ("A__LSHIFT__B" )),
49+ new TestCase ("A__THEN__B__COLON__C" , new Literal ("A__THEN__B__COLON__C" )),
50+ new TestCase ("A__MUL____LB__B__ADD__C__RB__" , new Literal ("A__MUL____LB__B__ADD__C__RB__" )),
51+ new TestCase ("(__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25)" , new Literal ("__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25" )),
52+ new TestCase ("(__LB__GNUTLS_VERSION_MAJOR__ADD____LB__GNUTLS_VERSION_MINOR__GT__0__L_OR__GNUTLS_VERSION_PATCH__GEQ__20__RB____RB____GT__3)" , new Literal ("__LB__GNUTLS_VERSION_MAJOR__ADD____LB__GNUTLS_VERSION_MINOR__GT__0__L_OR__GNUTLS_VERSION_PATCH__GEQ__20__RB____RB____GT__3" )),
53+ new TestCase ("(__LB__A__L_AND__B__RB____GT__C)" , new Literal ("__LB__A__L_AND__B__RB____GT__C" )),
54+ new TestCase ("A__EQ__B" , new Literal ("A__EQ__B" )),
55+ new TestCase ("(DEFINED_A)" , new Literal ("DEFINED_A" )),
56+ new TestCase ("MACRO___LB__A__B__RB____EQ__1" , new Literal ("MACRO___LB__A__B__RB____EQ__1" )),
57+ new TestCase ("ifndef" , new Literal ("ifndef" )),
58+ new TestCase ("__HAS_WARNING___LB____QUOTE____SUB__Wa__SUB__warning__QUOTE_____foo__RB__" , new Literal ("__HAS_WARNING___LB____QUOTE____SUB__Wa__SUB__warning__QUOTE_____foo__RB__" ))
59+ );
60+ }
61+
62+ /*
63+ * A testCase is evaluated using syntactic equivalence between expectation and result because deterministic results are expected.
64+ * Therefore, modifications in FeatureIDE might break these tests although the result remains semantically equivalent.
65+ */
66+ @ ParameterizedTest
67+ @ MethodSource ("testCases" )
68+ public void testCase (TestCase testCase ) {
69+ assertEquals (
70+ testCase .expected ,
71+ PropositionalFormulaParser .Default .parse (testCase .formula )
72+ );
73+ }
74+ }
0 commit comments