/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.compiler.integrationtests;
import org.drools.compiler.Cheese;
import org.drools.compiler.CommonTestMethodBase;
import org.drools.compiler.Person;
import org.drools.compiler.StockTick;
import org.junit.Test;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.builder.conf.PropertySpecificOption;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.kie.internal.utils.KieHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.Arrays.asList;
public class NamedConsequencesTest extends CommonTestMethodBase {
@Test
public void testNamedConsequences() {
List<String> results = executeTestWithCondition("do[t1]");
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "stilton" ) );
}
private List<String> executeTestWithCondition(String conditionElement) {
String drl = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" " + conditionElement + "\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
return executeTestWithDRL(drl);
}
private List<String> executeTestWithDRL(String drl) {
KnowledgeBase kbase = loadKnowledgeBaseFromString(drl);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List<String> results = new ArrayList<String>();
ksession.setGlobal( "results", results );
Cheese stilton = new Cheese( "stilton", 5 );
Cheese cheddar = new Cheese( "cheddar", 7 );
Cheese brie = new Cheese( "brie", 5 );
ksession.insert( stilton );
ksession.insert( cheddar );
ksession.insert( brie );
ksession.fireAllRules();
return results;
}
@Test
public void testNonCompilingBreakingConsequences() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" break[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testNonCompilingDuplicatedNamedConsequence() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testOutOfScopeNamedConsequences() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $b.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testAllowedIfDo() {
List<String> results = executeTestWithCondition("if ( price < 10 ) do[t1]");
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testNotAllowedIfDo() {
List<String> results = executeTestWithCondition("if ( price > 10 ) do[t1]");
assertEquals( 1, results.size() );
assertTrue( results.contains( "cheddar" ) );
}
@Test
public void testAllowedIfBreak() {
List<String> results = executeTestWithCondition("if ( price < 10 ) break[t1]");
assertEquals( 1, results.size() );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testNotAllowedIfBreak() {
List<String> results = executeTestWithCondition("if ( price > 10 ) break[t1]");
assertEquals( 1, results.size() );
assertTrue( results.contains( "cheddar" ) );
}
@Test
public void testNamedConsequencesOutsideOR() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" )\n" +
" or\n" +
" $a: Cheese ( type == \"gorgonzola\" ) )\n" +
" do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testNamedConsequencesInsideOR1() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" ) do[t1]\n" +
" or\n" +
" $b: Cheese ( type == \"gorgonzola\" ) )\n" +
" $c: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $c.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testNamedConsequencesInsideOR2() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" )\n" +
" or\n" +
" $b: Cheese ( type == \"gorgonzola\" ) do[t1] )\n" +
" $c: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $c.getType() );\n" +
"then[t1]\n" +
" results.add( $b.getType() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "cheddar" ) );
}
@Test
public void testOutOfScopeNamedConsequencesWithOr1() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" )\n" +
" or\n" +
" $b: Cheese ( type == \"gorgonzola\" ) do[t1] )\n" +
" $c: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $c.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testOutOfScopeNamedConsequencesWithOr2() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" )\n" +
" or\n" +
" $b: Cheese ( type == \"gorgonzola\" ) do[t1] )\n" +
" $c: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $c.getType() );\n" +
"then[t1]\n" +
" results.add( $c.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testNonCompilingIFAfterOR() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" ( $a: Cheese ( type == \"stilton\" )\n" +
" or\n" +
" $a: Cheese ( type == \"gorgonzola\" ) )\n" +
" if ( price > 10 ) do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL );
assertTrue(kbuilder.hasErrors());
}
@Test
public void testIfElse1() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > 10 ) do[t1] else do[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testIfElseWithConstant() {
// DROOLS-325
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > Cheese.BASE_PRICE ) do[t1] else do[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testIfElseWithMvelAccessor() {
// DROOLS-324
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 dialect \"mvel\" when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( $a.price > Cheese.BASE_PRICE ) do[t1] else do[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testIfElse2() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price < 10 ) do[t1] else do[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "cheddar" ) );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testIfElseBreak() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > 10 ) do[t1] else break[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testNestedIfElseBreak() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( type.startsWith(\"a\") ) do[t0] else if ( price > 10 ) do[t1] else break[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t0]\n" +
" results.add( \"WRONG!\" );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "STILTON" ) );
}
@Test
public void testIfWithModify() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > 10 ) break[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" modify( $a ) { setPrice(15) };\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "stilton" ) );
}
@Test(expected=RuntimeException.class)
public void testEndlessIfWithModify() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > 10 ) do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" modify( $a ) { setPrice(15) };\n" +
" results.add( \"modify\" );\n" +
" if (results.size() > 10) throw new RuntimeException();\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
" if (results.size() > 10) throw new RuntimeException();\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
}
@Test
public void testIfWithModify2() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price < 10 ) break[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $a.getType() );\n" +
"then[t1]\n" +
" modify( $a ) { setPrice(15) };\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testIfWithModify3() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\", price < 10 )\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" modify( $a ) { setPrice(15) };\n" +
"end\n" +
"rule R2 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price > 10 ) break[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
assertEquals( 1, results.size() );
assertTrue( results.contains( "stilton" ) );
}
@Test
public void testIfElseWithModify() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price < 10 ) do[t1] else break[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" modify( $a ) { setPrice(15) };\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
"end\n";
// Cheese stilton = new Cheese( "stilton", 5 );
// Cheese cheddar = new Cheese( "cheddar", 7 );
// Cheese brie = new Cheese( "brie", 5 );
List<String> results = executeTestWithDRL(str);
assertEquals( 2, results.size() );
assertTrue( results.contains( "STILTON" ) );
}
@Test(expected=RuntimeException.class)
public void testEndlessIfElseWithModify() {
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" if ( price < 10 ) do[t1] else do[t2]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" modify( $a ) { setPrice(15) };\n" +
" results.add( \"modify\" );\n" +
" if (results.size() > 10) throw new RuntimeException();\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"then[t2]\n" +
" results.add( $a.getType().toUpperCase() );\n" +
" if (results.size() > 10) throw new RuntimeException();\n" +
"end\n";
List<String> results = executeTestWithDRL(str);
}
@Test
public void testNamedConsequenceAfterNotPattern() {
// DROOLS-5
String str = "import org.drools.compiler.Cheese;\n " +
"global java.util.List results;\n" +
"\n" +
"rule R1 when\n" +
" $a: Cheese ( type == \"stilton\" )\n" +
" not Cheese ( type == \"brie\" )\n" +
" do[t1]\n" +
" $b: Cheese ( type == \"cheddar\" )\n" +
"then\n" +
" results.add( $b.getType() );\n" +
"then[t1]\n" +
" results.add( $a.getType() );\n" +
"end\n";
KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List<String> results = new ArrayList<String>();
ksession.setGlobal( "results", results );
ksession.insert( new Cheese( "stilton", 5 ) );
ksession.insert( new Cheese("cheddar", 7 ) );
ksession.fireAllRules();
assertTrue(results.contains("stilton"));
assertTrue(results.contains("cheddar"));
}
@Test
public void testMultipleIfElseInARow() {
// DROOLS-26
String str =
"global java.util.List results;" +
"declare UnBlocker end \n" +
"\n" +
"declare Car\n" +
" colour\t: String \n" +
" price \t: int\n" +
" horsepower \t: int\n" +
" abs \t\t: boolean\n" +
"end\n" +
"\n" +
"rule \"Init\" \n" +
"when \n" +
"then \n" +
" insert( \n" +
"\tnew Car( \"red\", 1200, 170, true ) \n" +
" ); \n" +
"end\n" +
"\n" +
"rule \"Car\" \n" +
"when \n" +
" $car: Car( abs == true ) \n" +
" if ( colour == \"red\" ) do[red] " +
" else if ( colour != \"red\" ) do[notRed]\n" +
" if ( price < 1000 ) do[cheap] " +
" else do[notCheap]\n" +
" UnBlocker() \n" +
"then\n" +
" results.add( \"Found a Car\" ); \n" +
"then[red]\n" +
" results.add( \"Car is red\" ); " +
" insert( new UnBlocker() ); \n" +
"then[notRed]\n" +
" results.add( \"Car is NOT red\" ); \n" +
"then[cheap]\n" +
" results.add( \"Car is cheap\" ); \n" +
"then[notCheap]\n" +
" results.add( \"Car is NOT cheap\" ); \n" +
"end";
KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List<String> results = new ArrayList<String>();
ksession.setGlobal("results", results);
ksession.fireAllRules();
assertEquals(3, results.size());
assertTrue(results.contains("Found a Car"));
assertTrue(results.contains("Car is red"));
assertTrue(results.contains("Car is NOT cheap"));
}
@Test
public void testDynamicSalience() {
// DROOLS-335
String str =
"import " + Fact.class.getCanonicalName() + ";\n" +
"global java.util.List results;\n" +
"rule R1 salience( -$id ) when\n" +
" fact : Fact( status == Fact.Status.UNKNOWN, $id : id)\n" +
" count : Long() from accumulate ( $s:Fact(this != fact, status==Fact.Status.NO, id < fact.id), count( $s ) )" +
" if (count.intValue() > 1) break[yes]\n" +
"then\n" +
" results.add(\"n\" + $id);" +
" fact.setStatus(Fact.Status.NO);\n" +
" update(fact);\n" +
"then[yes]\n" +
" results.add(\"y\" + $id);" +
" fact.setStatus(Fact.Status.YES);\n" +
" update(fact);\n" +
"end\n" +
" \n" +
"rule R2 salience 1 when\n" +
" fact : Fact( status == Fact.Status.NO, $id : id )\n" +
" Fact( status == Fact.Status.YES, id > $id )\n" +
"then\n" +
" delete(fact);\n" +
"end";
KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List<String> results = new ArrayList<String>();
ksession.setGlobal("results", results);
for (int i = 1; i < 7; i++) {
ksession.insert(new Fact(i));
}
ksession.fireAllRules();
assertEquals(asList("n1", "n2", "y3", "n4", "n5", "y6"), results);
}
public static class Fact {
public enum Status { UNKNOWN, NO, YES };
private final int id;
private Status status = Status.UNKNOWN;
public Fact(int id) {
this.id = id;
}
public int getId() {
return id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
@Test
public void testNamedConsequenceOnEvents() {
// DROOLS-641
String drl =
"import " + StockTick.class.getCanonicalName() + ";\n" +
"global java.util.List list;\n" +
"declare StockTick \n" +
" @role( event )" +
" @timestamp( time )\n" +
"end\n" +
"rule R when\n" +
" $s1 : StockTick( company == \"XXX\" )\n" +
" $s2 : StockTick( price > $s1.price ) do[t1]\n" +
" $s3 : StockTick( price < $s1.price )\n" +
"then\n" +
" list.add( \"t0:\" + $s3.getCompany() );\n" +
"then[t1]\n" +
" list.add( \"t1:\" + $s2.getCompany() );\n" +
"end\n";
KieSession ksession = new KieHelper().addContent(drl, ResourceType.DRL)
//.build(EventProcessingOption.STREAM)
.build()
.newKieSession();
List<String> list = new ArrayList<String>();
ksession.setGlobal("list", list);
ksession.insert(new StockTick(1L, "XXX", 10, 0L));
ksession.insert(new StockTick(2L, "YYY", 15, 1L));
ksession.insert(new StockTick(3L, "ZZZ", 5, 2L));
ksession.fireAllRules();
assertEquals(2, list.size());
assertTrue(list.containsAll(asList("t1:YYY", "t0:ZZZ")));
}
@Test(timeout = 10000L)
public void testNoLoop() {
// DROOLS-644
String drl =
"import " + Person.class.getCanonicalName() + ";\n" +
"global java.util.List list;\n" +
"rule R no-loop when\n" +
" $p1 : Person( name == \"Mario\" ) do[t1]\n" +
" $p2 : Person( age > $p1.age )\n" +
"then\n" +
" list.add(\"t0\");\n" +
" modify($p2) { setAge(30); }\n" +
"then[t1]\n" +
" list.add(\"t1\");\n" +
" modify($p1) { setAge(35); }\n" +
"end\n";
// This test has uncovered a BLOCKER which is reported in the PropertyReactiveBlockersTest
KieSession ksession = new KieHelper(PropertySpecificOption.ALLOWED).addContent(drl, ResourceType.DRL)
.build()
.newKieSession();
List<String> list = new ArrayList<String>();
ksession.setGlobal("list", list);
Person mario = new Person("Mario", 40);
Person mark = new Person("Mark", 37);
ksession.insert(mario);
ksession.insert(mark);
ksession.fireAllRules();
assertEquals(35, mario.getAge());
assertEquals(30, mark.getAge());
assertEquals(2, list.size());
assertEquals("t1", list.get(0));
assertEquals("t0", list.get(1));
}
@Test
public void testMvelInsertWithNamedConsequence() {
// DROOLS-726
String drl2 =
"package org.drools.compiler\n" +
"global java.util.concurrent.atomic.AtomicInteger counter\n" +
"declare Output\n" +
" feedback: String\n" +
"end\n" +
"rule \"Move to next\" dialect \"mvel\"\n" +
" when\n" +
" $i: Integer()\n" +
" if ($i == 1) break[nextStep1]\n" +
" then\n" +
" insert(new Output(\"defualt\"));\n" +
" then[nextStep1]\n" +
" insert(new Output(\"step 1\"));\n" +
"end\n" +
"\n" +
"rule \"Produce output\"\n" +
" when\n" +
" $output: Output()\n" +
" then\n" +
" System.out.println($output);\n" +
" retract($output);" +
" counter.incrementAndGet();\n" +
"end\n";
KieSession kSession = new KieHelper().addContent(drl2, ResourceType.DRL)
.build()
.newKieSession();
AtomicInteger counter = new AtomicInteger(0);
kSession.setGlobal("counter", counter);
FactHandle messageHandle = kSession.insert(1);
kSession.fireAllRules();
kSession.delete(messageHandle);
kSession.insert(2);
kSession.fireAllRules();
assertEquals(2, counter.get());
}
@Test
public void testDeleteWithBreakingBranch() throws Exception {
// DROOLS-1068
String drl =
"global java.util.List list;\n" +
"rule R when\n" +
" Integer()\n" +
" if (true) break[branch]\n" +
" not Integer()\n" +
"then\n" +
" list.add(\"main\");\n" +
"then[branch]\n" +
" list.add(\"branch\");\n" +
"end\n";
KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
List<String> list = new ArrayList<String>();
ksession.setGlobal( "list", list );
FactHandle fh = ksession.insert(1);
ksession.fireAllRules();
ksession.delete(fh);
ksession.fireAllRules();
assertEquals( 1, list.size() );
assertEquals( "branch", list.get( 0 ) );
}
@Test
public void testQueryWithBreakingBranch() throws Exception {
// DROOLS-1115
String drl =
"import " + ListHolder.class.getCanonicalName() + ";\n" +
"query q(ListHolder $listHolder)\n" +
" $listHolder := ListHolder()\n" +
" $i : Integer()\n" +
"end\n" +
"\n" +
"rule R when\n" +
" q($listHolder;)\n" +
" $s : String() from $listHolder.list\n" +
" if (1==2) break[branch]\n" +
"then\n" +
" $listHolder.getList().add(\"ok\");\n" +
"then[branch]\n" +
" $listHolder.getList().add(\"ko\");\n" +
"end\n" +
"\n" +
"rule Init when then insert(1); end\n";
KieSession ksession = new KieHelper().addContent( drl, ResourceType.DRL )
.build()
.newKieSession();
List<String> list = new ArrayList<String>();
list.add("test");
ksession.insert( new ListHolder(list) );
ksession.fireAllRules();
assertEquals( "ok", list.get(1) );
}
public static class ListHolder {
private final List<String> list;
public ListHolder( List<String> list ) {
this.list = list;
}
public List<String> getList() {
return list;
}
}
}