Skip to content
Snippets Groups Projects
Commit d525231a authored by René Schöne's avatar René Schöne
Browse files

WIP: add support for receiving single elements of lists

- resolved weird bug, that causes errors when nonterminal A (in the singleList-test) has no children.
- add new testcase for different structure/variants of some node to be sent/received
parent bce7c5c6
No related branches found
No related tags found
1 merge request!10Allow connection endpoints for list nonterminals
Pipeline #10598 passed
Showing
with 826 additions and 4 deletions
......@@ -102,8 +102,8 @@ aspect AttributesForMustache {
return preemptiveExpectedValue() + " == " + lastResult();
}
if (endpointDef().isReceiveTypeEndpointDefinition() && endpointDef().asReceiveTypeEndpointDefinition().getWithAdd()) {
// only check if received list is empty (may also be skipped, since addAll would not do anything anyways)
return lastResult() + " == null || " + lastResult() + ".numChildren() == 0";
// only check if received list is not null
return lastResult() + " == null";
}
if (endpointDef().isTypeEndpointDefinition() && type().isOptComponent()) {
// use "hasX()" instead of "getX() != null" for optionals
......
......@@ -503,3 +503,62 @@ task compileSingleListIncremental(type: RagConnectTest, dependsOn: ':ragconnect.
'--flush=full']
}
}
// --- Test: singleListVariant-manual ---
task compileSingleListVariantManual(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
ragconnect {
outputDir = file('src/test/02-after-ragconnect/singleListVariant')
inputFiles = [file('src/test/01-input/singleListVariant/Test.relast'),
file('src/test/01-input/singleListVariant/Test.connect'),
file('src/test/01-input/singleListVariant/TestDependencies.connect')]
rootNode = 'Root'
}
relast {
useJastAddNames = true
grammarName = 'src/test/03-after-relast/singleListVariant/singleListVariant'
serializer = 'jackson'
}
jastadd {
jastAddList = 'JastAddList'
packageName = 'singleListVariant.ast'
inputFiles = [file('src/test/01-input/singleListVariant/Test.jadd')]
}
}
// --- Test: singleListVariant-incremental ---
task compileSingleListVariantIncremental(type: RagConnectTest, dependsOn: ':ragconnect.base:jar') {
ragconnect {
outputDir = file('src/test/02-after-ragconnect/singleListVariantInc')
inputFiles = [file('src/test/01-input/singleListVariant/Test.relast'),
file('src/test/01-input/singleListVariant/Test.connect')]
rootNode = 'Root'
}
relast {
useJastAddNames = true
grammarName = 'src/test/03-after-relast/singleListVariantInc/singleListVariantInc'
serializer = 'jackson'
}
jastadd {
jastAddList = 'JastAddList'
packageName = 'singleListVariantInc.ast'
inputFiles = [file('src/test/01-input/singleListVariant/Test.jadd')]
extraOptions = ['--tracing=cache,flush',
'--incremental=param',
'--cache=all',
'--rewrite=cnta',
'--flush=full']
}
}
//task cleanCurrentManualTest(type: Delete) {
// delete "src/test/02-after-ragconnect/singleListVariant"
// delete "src/test/03-after-relast/singleListVariant"
// delete "src/test/java-gen/singleListVariant/ast"
//}
//task cleanCurrentIncrementalTest(type: Delete) {
// delete "src/test/02-after-ragconnect/singleListVariantInc"
// delete "src/test/03-after-relast/singleListVariantInc"
// delete "src/test/java-gen/singleListVariantInc/ast"
//}
//compileSingleListVariantManual.dependsOn cleanCurrentManualTest
//compileSingleListVariantIncremental.dependsOn cleanCurrentIncrementalTest
......@@ -8,5 +8,4 @@ SenderRoot : Nameable ::= <Input1:int> /A1:A/
<InOutput:int> ;
ReceiverRoot : Nameable ::= A* UsingWildcardA:A* WithAddA:A* UsingWildcardWithAddA:A* ;
A : Nameable ::= ;
B : Nameable ;
A : Nameable ;
# Single List
Idea: send and receive single values for lists of subtrees.
Test different variants of the structure/shape of the send/received value.
## Execution-Model
TODO: check again (old model copied from `singleList`)
```
SenderRoot/ReceiverRoot
|- T_Empty ::= /* empty */ ;
|- T_Token ::= <Value:String> ;
|- T_OneChild ::= Other ;
|- T_OneOpt ::= [Other] ;
|- T_OneList ::= Other* ;
|- T_TwoChildren ::= Left:Other Right:Other ;
|- T_OneOfEach ::= First:Other [Second:Other] Third:Other* <Fourth:String> ;
|- abstract T_Abstract ::= <ValueAbstract> ;
```
## Computation
```
T.ID = Input
T.token = Input
T.Other.ID = Input + 1
```
## Execution-Trace (SendInitialValue)
Inputs:
- 1
- 1
- 2
- 3
| Input | [A1,A2,A3,A4,IO] | # | A* | UsingWcA | WithAddA | UsingWcWithAddA:A |
|---|---|---|---|---|---|---|
| * | [1,2,3,4,0] | 5 | [1,2,3,4,0] | [1,2,3,4,0] | [1,2,3,4,0] | [1,2,3,4,0] |
| I1:1 | [2,2,3,4,0] | 6 | [2,2,3,4,0] | [2,2,3,4,0] | [1,2,3,4,0,2] | [1,2,3,4,0,2] |
| I1:1 | [2,2,3,4,0] | 6 | [2,2,3,4,0] | [2,2,3,4,0] | [1,2,3,4,0,2] | [1,2,3,4,0,2] |
| I1:2 | [3,2,3,4,0] | 7 | [3,2,3,4,0] | [3,2,3,4,0] | [1,2,3,4,0,2,3] | [1,2,3,4,0,2,3] |
| IO:5 | [3,2,3,4,5] | 8 | [3,2,3,4,5] | [3,2,3,4,5] | [1,2,3,4,0,2,3,5] | [1,2,3,4,0,2,3,5]
| I3:4 | [3,2,7,4,5] | 9 | [3,2,7,4,5] | [3,2,7,4,5] | [1,2,3,4,0,2,3,5,7] | [1,2,3,4,0,2,3,5,7] |
*: (1:0, 2:0, 3:0, 4:0, 5:0)
## Execution-Trace (OnlyUpdate)
| Input | [A1,A2,A3,A4,IO] | # | A* | UsingWcA | WithAddA | UsingWcWithAddA:A |
|---|---|---|---|---|---|---|
| * | [-,-,-,-,-] | 0 | [0,0,0,0,0] | [] | [] | [] |
| I1:1 | [2,-,-,-,-] | 1 | [2,0,0,0,0] | [2] | [2] | [2] |
| I1:1 | [2,-,-,-,-] | 1 | [2,0,0,0,0] | [2] | [2] | [2] |
| I1:2 | [3,-,-,-,-] | 2 | [3,0,0,0,0] | [3] | [2,3] | [2,3] |
| IO:5 | [2,-,-,-,5] | 3 | [3,0,0,0,5] | [3,5] | [2,3,5] | [2,3,5]
| I3:4 | [2,-,7,-,5] | 4 | [3,0,7,0,5] | [3,5,7] | [2,3,5,7] | [2,3,5,7] |
*: (1:0, 2:0, 3:0, 4:0, 5:0)
send tree SenderRoot.T_Empty ;
send tree SenderRoot.T_Token ;
send tree SenderRoot.T_OneChild ;
send tree SenderRoot.T_OneOpt ;
send tree SenderRoot.T_OneList ;
send tree SenderRoot.T_TwoChildren ;
send tree SenderRoot.T_OneOfEach ;
send tree SenderRoot.T_Abstract ;
receive tree ReceiverRoot.T_Empty ;
receive tree ReceiverRoot.T_Token ;
receive tree ReceiverRoot.T_OneChild ;
receive tree ReceiverRoot.T_OneOpt ;
receive tree ReceiverRoot.T_OneList ;
receive tree ReceiverRoot.T_TwoChildren ;
receive tree ReceiverRoot.T_OneOfEach ;
receive tree ReceiverRoot.T_Abstract ;
receive tree ReceiverRoot.MyEmpty ;
receive tree with add ReceiverRoot.EmptyWithAdd ;
receive tree with add ReceiverRoot.TokenWithAdd ;
receive tree with add ReceiverRoot.OneChildWithAdd ;
receive tree with add ReceiverRoot.OneOptWithAdd ;
receive tree with add ReceiverRoot.OneListWithAdd ;
receive tree with add ReceiverRoot.TwoChildrenWithAdd ;
receive tree with add ReceiverRoot.OneOfEachWithAdd ;
receive tree with add ReceiverRoot.AbstractWithAdd ;
aspect Computation {
syn T_Empty SenderRoot.getT_Empty() = new T_Empty().setID(getInput());
syn T_Token SenderRoot.getT_Token() = new T_Token().setID(getInput())
.setValue(Integer.toString(getInput()));
syn T_OneChild SenderRoot.getT_OneChild() {
T_OneChild result = new T_OneChild().setID(getInput());
result.setOther(createOther());
return result;
}
syn T_OneOpt SenderRoot.getT_OneOpt() {
T_OneOpt result = new T_OneOpt().setID(getInput());
if (getShouldSetOptAndList()) {
result.setOther(createOther());
}
return result;
}
syn T_OneList SenderRoot.getT_OneList() {
T_OneList result = new T_OneList().setID(getInput());
if (getShouldSetOptAndList()) {
result.addOther(createOther());
}
return result;
}
syn T_TwoChildren SenderRoot.getT_TwoChildren() {
T_TwoChildren result = new T_TwoChildren().setID(getInput());
result.setLeft(createOther());
result.setRight(createOther());
return result;
}
syn T_OneOfEach SenderRoot.getT_OneOfEach() {
T_OneOfEach result = new T_OneOfEach().setID(getInput());
result.setFirst(createOther());
if (getShouldSetOptAndList()) {
result.setSecond(createOther());
result.addThird(createOther());
}
result.setFourth(Integer.toString(getInput()));
return result;
}
syn T_Abstract SenderRoot.getT_Abstract() = new T_SubClass()
.setValueSub(Integer.toString(getInput()))
.setID(getInput())
.setValueAbstract(Integer.toString(getInput()));
private Other SenderRoot.createOther() {
return new Other().setID(getInput() + 1);
}
syn boolean ASTNode.isNameable() = false;
eq Nameable.isNameable() = true;
}
aspect Testing {
class SenderRoot implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperSenderRoot {}
class ReceiverRoot implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperReceiverRoot {}
class Other implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperOther {}
class T_Empty implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_Empty {}
class T_Token implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_Token {}
class T_OneChild implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_OneChild {}
class T_OneOpt implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_OneOpt {}
class T_OneList implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_OneList {}
class T_TwoChildren implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_TwoChildren {}
class T_OneOfEach implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_OneOfEach {}
class T_Abstract implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperT_Abstract {}
class JastAddList<T> implements org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.TestWrapperJastAddList<T> {}
}
aspect NameResolution {
// overriding customID guarantees to produce the same JSON representation for equal lists
// otherwise, the value for id is different each time
@Override
protected String Nameable.customID() {
return getClass().getSimpleName() + getID();
}
}
Root ::= SenderRoot* ReceiverRoot* ;
Nameable ::= <ID:int> ;
SenderRoot : Nameable ::= <Input:int> <ShouldSetOptAndList:boolean>
/T_Empty/
/T_Token/
/T_OneChild/
/T_OneOpt/
/T_OneList/
/T_TwoChildren/
/T_OneOfEach/
/T_Abstract/
;
ReceiverRoot : Nameable ::=
T_Empty*
T_Token*
T_OneChild*
T_OneOpt*
T_OneList*
T_TwoChildren*
T_OneOfEach*
T_Abstract*
MyEmpty:T_Empty*
EmptyWithAdd:T_Empty*
TokenWithAdd:T_Token*
OneChildWithAdd:T_OneChild*
OneOptWithAdd:T_OneOpt*
OneListWithAdd:T_OneList*
TwoChildrenWithAdd:T_TwoChildren*
OneOfEachWithAdd:T_OneOfEach*
AbstractWithAdd:T_Abstract*
;
T_Empty : Nameable ::= /* empty */ ;
T_Token : Nameable ::= <Value:String> ;
T_OneChild : Nameable ::= Other ;
T_OneOpt : Nameable ::= [Other] ;
T_OneList : Nameable ::= Other* ;
T_TwoChildren : Nameable ::= Left:Other Right:Other ;
T_OneOfEach : Nameable ::= First:Other [Second:Other] Third:Other* <Fourth:String> ;
abstract T_Abstract : Nameable ::= <ValueAbstract>;
T_SubClass : T_Abstract ::= <ValueSub> ;
Other : Nameable ;
SenderRoot.T_Empty canDependOn SenderRoot.Input as InputDependencyToT_Empty ;
SenderRoot.T_Token canDependOn SenderRoot.Input as InputDependencyToT_Token ;
SenderRoot.T_OneChild canDependOn SenderRoot.Input as InputDependencyToT_OneChild ;
SenderRoot.T_OneOpt canDependOn SenderRoot.ShouldSetOptAndList as ShouldSetOptAndListDependencyToT_OneOpt ;
SenderRoot.T_OneOpt canDependOn SenderRoot.Input as InputDependencyToT_OneOpt ;
SenderRoot.T_OneList canDependOn SenderRoot.ShouldSetOptAndList as ShouldSetOptAndListDependencyToT_OneList ;
SenderRoot.T_OneList canDependOn SenderRoot.Input as InputDependencyToT_OneList ;
SenderRoot.T_TwoChildren canDependOn SenderRoot.Input as InputDependencyToT_TwoChildren ;
SenderRoot.T_OneOfEach canDependOn SenderRoot.ShouldSetOptAndList as ShouldSetOptAndListDependencyToT_OneOfEach ;
SenderRoot.T_OneOfEach canDependOn SenderRoot.Input as InputDependencyToT_OneOfEach ;
SenderRoot.T_Abstract canDependOn SenderRoot.Input as InputDependencyToT_Abstract ;
package org.jastadd.ragconnect.tests.singleListVariant;
import org.jastadd.ragconnect.tests.AbstractMqttTest;
import org.jastadd.ragconnect.tests.TestUtils;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;
import java.util.function.BiConsumer;
import static java.lang.Math.abs;
import static java.util.Collections.addAll;
import static org.assertj.core.util.Lists.newArrayList;
import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
import static org.jastadd.ragconnect.tests.singleListVariant.AbstractSingleListVariantTest.IntList.list;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Base class for test cases "singleList manual" and "singleList incremental".
*
* @author rschoene - Initial contribution
*/
@Tag("List")
@Tag("SingleList")
public abstract class AbstractSingleListVariantTest extends AbstractMqttTest {
public interface TestWrapperJastAddList<T> extends Iterable<T> {
int getNumChild();
}
public interface TestWrapperReceiverRoot {
TestWrapperJastAddList<? extends TestWrapperT_Empty> getT_EmptyList();
TestWrapperJastAddList<? extends TestWrapperT_Token> getT_TokenList();
TestWrapperJastAddList<? extends TestWrapperT_OneChild> getT_OneChildList();
TestWrapperJastAddList<? extends TestWrapperT_OneOpt> getT_OneOptList();
TestWrapperJastAddList<? extends TestWrapperT_OneList> getT_OneListList();
TestWrapperJastAddList<? extends TestWrapperT_TwoChildren> getT_TwoChildrenList();
TestWrapperJastAddList<? extends TestWrapperT_OneOfEach> getT_OneOfEachList();
TestWrapperJastAddList<? extends TestWrapperT_Abstract> getT_AbstractList();
TestWrapperJastAddList<? extends TestWrapperT_Empty> getMyEmptyList();
TestWrapperJastAddList<? extends TestWrapperT_Empty> getEmptyWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_Token> getTokenWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_OneChild> getOneChildWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_OneOpt> getOneOptWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_OneList> getOneListWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_TwoChildren> getTwoChildrenWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_OneOfEach> getOneOfEachWithAddList();
TestWrapperJastAddList<? extends TestWrapperT_Abstract> getAbstractWithAddList();
boolean connectT_Empty(String mqttUri) throws IOException;
boolean connectT_Token(String mqttUri) throws IOException;
boolean connectT_OneChild(String mqttUri) throws IOException;
boolean connectT_OneOpt(String mqttUri) throws IOException;
boolean connectT_OneList(String mqttUri) throws IOException;
boolean connectT_TwoChildren(String mqttUri) throws IOException;
boolean connectT_OneOfEach(String mqttUri) throws IOException;
boolean connectT_Abstract(String mqttUri) throws IOException;
boolean connectMyEmpty(String mqttUri) throws IOException;
boolean connectEmptyWithAdd(String mqttUri) throws IOException;
boolean connectTokenWithAdd(String mqttUri) throws IOException;
boolean connectOneChildWithAdd(String mqttUri) throws IOException;
boolean connectOneOptWithAdd(String mqttUri) throws IOException;
boolean connectOneListWithAdd(String mqttUri) throws IOException;
boolean connectTwoChildrenWithAdd(String mqttUri) throws IOException;
boolean connectOneOfEachWithAdd(String mqttUri) throws IOException;
boolean connectAbstractWithAdd(String mqttUri) throws IOException;
}
@SuppressWarnings("UnusedReturnValue")
public interface TestWrapperSenderRoot {
boolean connectT_Empty(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_Token(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_OneChild(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_OneOpt(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_OneList(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_TwoChildren(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_OneOfEach(String mqttUri, boolean writeCurrentValue) throws IOException;
boolean connectT_Abstract(String mqttUri, boolean writeCurrentValue) throws IOException;
TestWrapperSenderRoot setInput(int input);
TestWrapperSenderRoot setShouldSetOptAndList(boolean shouldSetOptAndList);
TestWrapperT_Empty getT_Empty();
TestWrapperT_OneOpt getT_OneOpt();
}
public interface TestWrapperNameable {
int getID();
}
public interface TestWrapperOther extends TestWrapperNameable {}
public interface TestWrapperT_Empty extends TestWrapperNameable {}
public interface TestWrapperT_Token extends TestWrapperNameable {
String getValue();
}
public interface TestWrapperT_OneChild extends TestWrapperNameable {
TestWrapperNameable getOther();
}
public interface TestWrapperT_OneOpt extends TestWrapperNameable {
boolean hasOther();
TestWrapperNameable getOther();
}
public interface TestWrapperT_OneList extends TestWrapperNameable {
int getNumOther();
TestWrapperNameable getOther(int index);
}
public interface TestWrapperT_TwoChildren extends TestWrapperNameable {
TestWrapperNameable getLeft();
TestWrapperNameable getRight();
}
public interface TestWrapperT_OneOfEach extends TestWrapperNameable {
TestWrapperNameable getFirst();
boolean hasSecond();
TestWrapperNameable getSecond();
int getNumThird();
TestWrapperNameable getThird(int index);
String getFourth();
}
public interface TestWrapperT_Abstract extends TestWrapperNameable {
String getValueAbstract();
String getValueSub();
}
AbstractSingleListVariantTest(String shortName) {
this.shortName = shortName;
}
protected static final String TOPIC_T_Empty = "t/Empty";
protected static final String TOPIC_T_Token = "t/Token";
protected static final String TOPIC_T_OneChild = "t/OneChild";
protected static final String TOPIC_T_OneOpt = "t/OneOpt";
protected static final String TOPIC_T_OneList = "t/OneList";
protected static final String TOPIC_T_TwoChildren = "t/TwoChildren";
protected static final String TOPIC_T_OneOfEach = "t/OneOfEach";
protected static final String TOPIC_T_Abstract = "t/Abstract";
protected static final String TOPIC_T_all = "t/#";
protected TestWrapperSenderRoot senderRoot;
protected TestWrapperReceiverRoot receiverRoot;
protected ReceiverData data;
private final String shortName;
@Test
public void checkJacksonReference() {
testJaddContainReferenceToJackson(
Paths.get("src", "test",
"02-after-ragconnect", shortName, "RagConnect.jadd"), true);
}
@Override
protected void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException, InterruptedException {
// late model initialization
setInput(0);
setShouldSetOptAndList(false);
setupReceiverAndConnectPart();
// connect. important: first receivers, then senders. to not miss initial value.
// receive: unnamed
assertTrue(receiverRoot.connectT_Empty(mqttUri(TOPIC_T_Empty)));
assertTrue(receiverRoot.connectT_Token(mqttUri(TOPIC_T_Token)));
assertTrue(receiverRoot.connectT_OneChild(mqttUri(TOPIC_T_OneChild)));
assertTrue(receiverRoot.connectT_OneOpt(mqttUri(TOPIC_T_OneOpt)));
assertTrue(receiverRoot.connectT_OneList(mqttUri(TOPIC_T_OneList)));
assertTrue(receiverRoot.connectT_TwoChildren(mqttUri(TOPIC_T_TwoChildren)));
assertTrue(receiverRoot.connectT_OneOfEach(mqttUri(TOPIC_T_OneOfEach)));
assertTrue(receiverRoot.connectT_Abstract(mqttUri(TOPIC_T_Abstract)));
// receive: named
assertTrue(receiverRoot.connectMyEmpty(mqttUri(TOPIC_T_Empty)));
// receive: with add
assertTrue(receiverRoot.connectEmptyWithAdd(mqttUri(TOPIC_T_Empty)));
assertTrue(receiverRoot.connectTokenWithAdd(mqttUri(TOPIC_T_Token)));
assertTrue(receiverRoot.connectOneChildWithAdd(mqttUri(TOPIC_T_OneChild)));
assertTrue(receiverRoot.connectOneOptWithAdd(mqttUri(TOPIC_T_OneOpt)));
assertTrue(receiverRoot.connectOneListWithAdd(mqttUri(TOPIC_T_OneList)));
assertTrue(receiverRoot.connectTwoChildrenWithAdd(mqttUri(TOPIC_T_TwoChildren)));
assertTrue(receiverRoot.connectOneOfEachWithAdd(mqttUri(TOPIC_T_OneOfEach)));
assertTrue(receiverRoot.connectAbstractWithAdd(mqttUri(TOPIC_T_Abstract)));
// send
assertTrue(senderRoot.connectT_Empty(mqttUri(TOPIC_T_Empty), writeCurrentValue));
assertTrue(senderRoot.connectT_Token(mqttUri(TOPIC_T_Token), writeCurrentValue));
assertTrue(senderRoot.connectT_OneChild(mqttUri(TOPIC_T_OneChild), writeCurrentValue));
assertTrue(senderRoot.connectT_OneOpt(mqttUri(TOPIC_T_OneOpt), writeCurrentValue));
assertTrue(senderRoot.connectT_OneList(mqttUri(TOPIC_T_OneList), writeCurrentValue));
assertTrue(senderRoot.connectT_TwoChildren(mqttUri(TOPIC_T_TwoChildren), writeCurrentValue));
assertTrue(senderRoot.connectT_OneOfEach(mqttUri(TOPIC_T_OneOfEach), writeCurrentValue));
assertTrue(senderRoot.connectT_Abstract(mqttUri(TOPIC_T_Abstract), writeCurrentValue));
}
abstract protected void setupReceiverAndConnectPart() throws IOException;
@Override
protected void communicateSendInitialValue() throws InterruptedException {
// transmissions: 8 * 1 = 8
checkTree(8, list(-0), list(0), list(-0));
setInput(1);
// transmissions: 8 + 8 = 16
checkTree(16, list(-1), list(0, 1), list(-0, -1));
setInput(1);
// transmissions: 16
checkTree(16, list(-1), list(0, 1), list(-0, -1));
setShouldSetOptAndList(true);
// transmissions: 16 + 3 = 19
checkTree(19, list(1), list(0, 1), list(-0, -1, 1));
setShouldSetOptAndList(true);
// transmissions: 19
checkTree(19, list(1), list(0, 1), list(-0, -1, 1));
setInput(2);
// transmissions: 19 + 8 = 27
checkTree(27, list(2), list(0, 1, 2), list(-0, -1, 1, 2));
setInput(5);
// transmissions: 27 + 8 = 35
checkTree(35, list(5), list(0, 1, 2, 5), list(-0, -1, 1, 2, 5));
}
@Override
protected void communicateOnlyUpdatedValue() throws InterruptedException {
// transmissions: 0
checkTree(0, list(), list(), list());
setInput(1);
// transmissions: 8 * 1 = 0
checkTree(8, list(-1), list(1), list(-1));
setInput(1);
// transmissions: 8
checkTree(8, list(-1), list(1), list(-1));
setShouldSetOptAndList(true);
// transmissions: 8 + 3 = 11
checkTree(11, list(1), list(1), list(-1, 1));
setShouldSetOptAndList(true);
// transmissions: 11
checkTree(11, list(1), list(1), list(-1, 1));
setInput(2);
// transmissions: 11 + 8 = 19
checkTree(19, list(2), list(1, 2), list(-1, 1, 2));
setInput(5);
// transmissions: 19 + 8 = 27
checkTree(27, list(5), list(1, 2, 5), list(-1, 1, 2, 5));
}
protected void setInput(int input) {
senderRoot.setInput(input);
assertEquals(input, senderRoot.getT_Empty().getID(), "ID value of empty");
}
protected void setShouldSetOptAndList(boolean shouldSetOptAndList) {
senderRoot.setShouldSetOptAndList(shouldSetOptAndList);
assertEquals(shouldSetOptAndList, senderRoot.getT_OneOpt().hasOther(), "opt is filled or not");
}
/**
* Check against expected lists of IDs.
* If an ID is negative, do not check Opts and Lists, but use absolute value for comparison.
* The tests starts with ID 0 and does not use opts and lists at this point, so checking with > 0 is used.
* @param expectedTransmissions expected number of total transmissions
* @param expectedList ids for unnamed and named endpoints without add
* @param expectedWithAddList ids for endpoints with add, but not those with opts and lists
* (only positive numbers can/need to be passed)
* @param expectedWithAddListForOptAndList ids for endpoints with add and with opts and lists
* @throws InterruptedException if interrupted in TestUtils.waitForMqtt
*/
private void checkTree(int expectedTransmissions,
IntList expectedList,
IntList expectedWithAddList,
IntList expectedWithAddListForOptAndList)
throws InterruptedException {
TestUtils.waitForMqtt();
assertEquals(expectedTransmissions, data.numberOfElements, "transmissions for any element");
// check unnamed
checkList(expectedList.toList(), receiverRoot.getT_EmptyList(), (e, n) -> {});
checkList(expectedList.toList(), receiverRoot.getT_TokenList(),
(e, n) -> assertEquals(Integer.toString(abs(e)), n.getValue()));
checkList(expectedList.toList(), receiverRoot.getT_OneChildList(),
(e, n) -> assertEquals(abs(e) + 1, n.getOther().getID()));
checkList(expectedList.toList(), receiverRoot.getT_OneOptList(),
(e, n) -> {
assertEquals(e > 0, n.hasOther());
if (n.hasOther()) {
assertEquals(abs(e) + 1, n.getOther().getID());
}
});
checkList(expectedList.toList(), receiverRoot.getT_OneListList(),
(e, n) -> {
assertEquals(e > 0 ? 1 : 0, n.getNumOther());
if (n.getNumOther() > 0) {
assertEquals(abs(e) + 1, n.getOther(0).getID());
}
});
checkList(expectedList.toList(), receiverRoot.getT_TwoChildrenList(),
(e, n) -> {
assertEquals(abs(e) + 1, n.getLeft().getID());
assertEquals(abs(e) + 1, n.getRight().getID());
});
checkList(expectedList.toList(), receiverRoot.getT_OneOfEachList(),
(e, n) -> {
assertEquals(abs(e) + 1, n.getFirst().getID());
assertEquals(e > 0, n.hasSecond());
if (n.hasSecond()) {
assertEquals(abs(e) + 1, n.getSecond().getID());
}
assertEquals(e > 0 ? 1 : 0, n.getNumThird());
if (n.getNumThird() > 0) {
assertEquals(abs(e) + 1, n.getThird(0).getID());
}
assertEquals(Integer.toString(abs(e)), n.getFourth());
});
checkList(expectedList.toList(), receiverRoot.getT_AbstractList(),
(e, n) -> {
assertEquals(Integer.toString(abs(e)), n.getValueAbstract());
assertEquals(Integer.toString(abs(e)), n.getValueSub());
});
// check named
checkList(expectedList.toList(), receiverRoot.getMyEmptyList(), (e, n) -> {});
// check with add
checkList(expectedWithAddList.toList(), receiverRoot.getEmptyWithAddList(), (e, n) -> {});
checkList(expectedWithAddList.toList(), receiverRoot.getTokenWithAddList(),
(e, n) -> assertEquals(Integer.toString(abs(e)), n.getValue()));
checkList(expectedWithAddList.toList(), receiverRoot.getOneChildWithAddList(),
(e, n) -> assertEquals(abs(e) + 1, n.getOther().getID()));
checkList(expectedWithAddListForOptAndList.toList(), receiverRoot.getOneOptWithAddList(),
(e, n) -> {
if (n.hasOther()) {
assertEquals(abs(e) + 1, n.getOther().getID());
}
});
checkList(expectedWithAddListForOptAndList.toList(), receiverRoot.getOneListWithAddList(),
(e, n) -> {
if (n.getNumOther() > 0) {
assertEquals(abs(e) + 1, n.getOther(0).getID());
}
});
checkList(expectedWithAddList.toList(), receiverRoot.getTwoChildrenWithAddList(),
(e, n) -> {
assertEquals(abs(e) + 1, n.getLeft().getID());
assertEquals(abs(e) + 1, n.getRight().getID());
});
checkList(expectedWithAddListForOptAndList.toList(), receiverRoot.getOneOfEachWithAddList(),
(e, n) -> {
assertEquals(abs(e) + 1, n.getFirst().getID());
if (n.hasSecond()) {
assertEquals(abs(e) + 1, n.getSecond().getID());
}
if (n.getNumThird() > 0) {
assertEquals(abs(e) + 1, n.getThird(0).getID());
}
assertEquals(Integer.toString(abs(e)), n.getFourth());
});
checkList(expectedWithAddList.toList(), receiverRoot.getAbstractWithAddList(),
(e, n) -> {
assertEquals(Integer.toString(abs(e)), n.getValueAbstract());
assertEquals(Integer.toString(abs(e)), n.getValueSub());
});
}
private <T extends TestWrapperNameable> void checkList(List<Integer> expectedList, TestWrapperJastAddList<T> actualList, BiConsumer<Integer, T> additionalTest) {
assertEquals(expectedList.size(), actualList.getNumChild(), "same list size");
int index = 0;
for (T element : actualList) {
assertEquals(abs(expectedList.get(index)), element.getID(), "correct ID for A");
additionalTest.accept(expectedList.get(index), element);
index++;
}
}
protected static class ReceiverData {
int numberOfElements = 0;
}
protected static class IntList {
private final List<Integer> integers = newArrayList();
public IntList(Integer... values) {
addAll(integers, values);
}
public List<Integer> toList() {
return integers;
}
public static IntList list(Integer... values) {
return new IntList(values);
}
}
}
package org.jastadd.ragconnect.tests.singleListVariant;
import org.jastadd.ragconnect.tests.TestUtils;
import org.junit.jupiter.api.Tag;
import singleListVariantInc.ast.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "list incremental".
*
* @author rschoene - Initial contribution
*/
@Tag("Incremental")
public class SingleListVariantIncrementalVariantTest extends AbstractSingleListVariantTest {
private Root model;
private MqttHandler handler;
SingleListVariantIncrementalVariantTest() {
super("singleListVariantInc");
}
@Override
protected void createModel() {
model = new Root();
senderRoot = new SenderRoot();
model.addSenderRoot((SenderRoot) senderRoot);
ReceiverRoot localReceiverRoot = new ReceiverRoot();
model.addReceiverRoot(localReceiverRoot);
receiverRoot = localReceiverRoot;
assertEquals(0, receiverRoot.getT_EmptyList().getNumChild());
}
@Override
protected void setupReceiverAndConnectPart() throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
// no dependencies
data = new ReceiverData();
handler.newConnection(TOPIC_T_all, bytes -> data.numberOfElements += 1);
}
@Override
protected void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
}
package org.jastadd.ragconnect.tests.singleListVariant;
import org.jastadd.ragconnect.tests.TestUtils;
import singleListVariant.ast.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test case "list manual".
*
* @author rschoene - Initial contribution
*/
public class SingleListVariantManualVariantTest extends AbstractSingleListVariantTest {
private Root model;
private MqttHandler handler;
SingleListVariantManualVariantTest() {
super("singleListVariant");
}
@Override
protected void createModel() {
model = new Root();
senderRoot = new SenderRoot();
model.addSenderRoot((SenderRoot) senderRoot);
ReceiverRoot localReceiverRoot = new ReceiverRoot();
model.addReceiverRoot(localReceiverRoot);
receiverRoot = localReceiverRoot;
assertEquals(0, receiverRoot.getT_EmptyList().getNumChild());
}
@Override
protected void setupReceiverAndConnectPart() throws IOException {
model.ragconnectSetupMqttWaitUntilReady(2, TimeUnit.SECONDS);
handler = new MqttHandler().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
// add dependencies: input
((SenderRoot) senderRoot).addInputDependencyToT_Empty((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_Token((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_OneChild((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_OneOpt((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_OneList((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_TwoChildren((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_OneOfEach((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addInputDependencyToT_Abstract((SenderRoot) senderRoot);
// add dependencies: shouldSetOptAndList
((SenderRoot) senderRoot).addShouldSetOptAndListDependencyToT_OneOpt((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addShouldSetOptAndListDependencyToT_OneList((SenderRoot) senderRoot);
((SenderRoot) senderRoot).addShouldSetOptAndListDependencyToT_OneOfEach((SenderRoot) senderRoot);
data = new ReceiverData();
handler.newConnection(TOPIC_T_all, bytes -> data.numberOfElements += 1);
}
@Override
protected void closeConnections() {
if (handler != null) {
handler.close();
}
if (model != null) {
model.ragconnectCloseConnections();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment