-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Group chained flows into dynamic containers in junit 5 * Code refactor to maintain existing test execution order * Add junit tests * Group chained flows for junit5 Flocessor based on chainId * Use chain tag for display name of the DynamicContainer --------- Co-authored-by: Chaitanya Srinidhi V <ChaitanyaSrinidhi.V@mastercard.com> Co-authored-by: Ryan McNally <ryan.mcnally@mastercard.com>
- Loading branch information
1 parent
6234c85
commit 02d3cf2
Showing
3 changed files
with
273 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
assert/assert-junit5/src/test/java/com/mastercard/test/flow/assrt/junit5/FlocessorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
package com.mastercard.test.flow.assrt.junit5; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import org.junit.jupiter.api.DynamicContainer; | ||
import org.junit.jupiter.api.DynamicNode; | ||
import org.junit.jupiter.api.DynamicTest; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.mockito.ArgumentMatchers.anySet; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
import com.mastercard.test.flow.Flow; | ||
import com.mastercard.test.flow.Model; | ||
import com.mastercard.test.flow.builder.Chain; | ||
import com.mastercard.test.flow.builder.Creator; | ||
import com.mastercard.test.flow.util.Tags; | ||
|
||
/** | ||
* Validates the {@link Flocessor} class for DynamicContainer creation of | ||
* chained flows | ||
*/ | ||
@SuppressWarnings("static-method") | ||
class FlocessorTest { | ||
|
||
/** | ||
* A simple sequence of flows with no chains | ||
*/ | ||
@Test | ||
void simple() { | ||
expectNodes( model( null, null, null, null, null ), | ||
"test : 0 []", | ||
"test : 1 []", | ||
"test : 2 []", | ||
"test : 3 []", | ||
"test : 4 []" ); | ||
} | ||
|
||
/** | ||
* A single chain of a single flow | ||
*/ | ||
@Test | ||
void link() { | ||
expectNodes( model( null, "a", null ), | ||
"test : 0 []", | ||
"container : chain:a", | ||
" test : 1 [chain:a]", | ||
"test : 2 []" ); | ||
} | ||
|
||
/** | ||
* Consecutive single-flow chains | ||
*/ | ||
@Test | ||
void links() { | ||
expectNodes( model( "a", "b", "c" ), | ||
"container : chain:a", | ||
" test : 0 [chain:a]", | ||
"container : chain:b", | ||
" test : 1 [chain:b]", | ||
"container : chain:c", | ||
" test : 2 [chain:c]" ); | ||
} | ||
|
||
/** | ||
* A single multi-flow chain | ||
*/ | ||
@Test | ||
void chain() { | ||
// in the middle | ||
expectNodes( model( null, "a", "a", "a", null ), | ||
"test : 0 []", | ||
"container : chain:a", | ||
" test : 1 [chain:a]", | ||
" test : 2 [chain:a]", | ||
" test : 3 [chain:a]", | ||
"test : 4 []" ); | ||
|
||
// at the start | ||
expectNodes( model( "a", "a", "a", null ), | ||
"container : chain:a", | ||
" test : 0 [chain:a]", | ||
" test : 1 [chain:a]", | ||
" test : 2 [chain:a]", | ||
"test : 3 []" ); | ||
|
||
// at the end | ||
expectNodes( model( null, "a", "a", "a" ), | ||
"test : 0 []", | ||
"container : chain:a", | ||
" test : 1 [chain:a]", | ||
" test : 2 [chain:a]", | ||
" test : 3 [chain:a]" ); | ||
} | ||
|
||
/** | ||
* Multiple multi-flow chains | ||
*/ | ||
@Test | ||
void chains() { | ||
expectNodes( model( "a", "a", null, "b", "b", "c" ), | ||
"container : chain:a", | ||
" test : 0 [chain:a]", | ||
" test : 1 [chain:a]", | ||
"test : 2 []", | ||
"container : chain:b", | ||
" test : 3 [chain:b]", | ||
" test : 4 [chain:b]", | ||
"container : chain:c", | ||
" test : 5 [chain:c]" ); | ||
} | ||
|
||
private static Model model( String... chains ) { | ||
List<Flow> flows = new ArrayList<>(); | ||
for( int i = 0; i < chains.length; i++ ) { | ||
int idx = i; | ||
Flow flow = Creator | ||
.build( f -> f.meta( data -> data | ||
.description( String.valueOf( idx ) ) | ||
.tags( Tags.add( Optional.ofNullable( chains[idx] ) | ||
.map( v -> Chain.PREFIX + v ) | ||
.orElse( "" ) ) ) ) ); | ||
flows.add( flow ); | ||
} | ||
Model model = mock( Model.class ); | ||
when( model.flows( anySet(), anySet() ) ) | ||
.thenReturn( flows.stream() ); | ||
|
||
return model; | ||
} | ||
|
||
private static void expectNodes( Model model, String... expected ) { | ||
Flocessor flocessor = new Flocessor( "", model ); | ||
List<String> actual = new ArrayList<>(); | ||
flocessor.tests() | ||
.forEach( node -> stringify( node, "", actual ) ); | ||
assertEquals( | ||
copypasta( Stream.of( expected ) ), | ||
copypasta( actual.stream() ) ); | ||
} | ||
|
||
private static void stringify( DynamicNode node, String prefix, List<String> lines ) { | ||
if( node instanceof DynamicTest ) { | ||
DynamicTest test = (DynamicTest) node; | ||
lines.add( prefix + "test : " + test.getDisplayName() ); | ||
} | ||
else if( node instanceof DynamicContainer ) { | ||
DynamicContainer container = (DynamicContainer) node; | ||
lines.add( prefix + "container : " + container.getDisplayName() ); | ||
container.getChildren() | ||
.forEach( child -> stringify( child, prefix + " ", lines ) ); | ||
} | ||
else { | ||
throw new IllegalStateException( "unexpected node " + node.getClass() ); | ||
} | ||
} | ||
|
||
/** | ||
* @param content Some strings | ||
* @return A string that can be trivially copy/pasted into java source | ||
*/ | ||
private static String copypasta( Stream<String> content ) { | ||
return content | ||
.map( s -> s.replaceAll( "\r", "" ) ) | ||
.flatMap( s -> Stream.of( s.split( "\n" ) ) ) | ||
.map( s -> s.replaceAll( "\"", "'" ) ) | ||
.collect( Collectors.joining( "\",\n\"", "\"", "\"" ) ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters