Skip to content

Commit

Permalink
Model tagging check assertion inversion (#951)
Browse files Browse the repository at this point in the history
Model tagging check assertion inversion; Add model title uniqueness test

Co-authored-by: Chaitanya Srinidhi V <[email protected]>
  • Loading branch information
vchaitanya and Chaitanya Srinidhi V authored Oct 1, 2024
1 parent 02d3cf2 commit 6af510d
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.mastercard.test.flow.validation.check.InteractionIdentityCheck;
import com.mastercard.test.flow.validation.check.MessageSharingCheck;
import com.mastercard.test.flow.validation.check.ModelTaggingCheck;
import com.mastercard.test.flow.validation.check.ModelUniquenessCheck;
import com.mastercard.test.flow.validation.check.ReflectiveModelTaggingCheck;
import com.mastercard.test.flow.validation.check.ResultTagCheck;
import com.mastercard.test.flow.validation.check.TraceUniquenessCheck;
Expand Down Expand Up @@ -49,6 +50,7 @@ public static final Validation[] defaultChecks() {
new InteractionIdentityCheck(),
new MessageSharingCheck(),
new ModelTaggingCheck(),
new ModelUniquenessCheck(),
new ReflectiveModelTaggingCheck(),
new ResultTagCheck(),
new TraceUniquenessCheck(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ private List<Check> buildChecks( Model model, List<Check> checks ) {
} );
flowUnionTags.removeAll( flowIntersectionTags );

String expected = flowsFound.get()
String actual = flowsFound.get()
? formatCopypasta( flowUnionTags, flowIntersectionTags )
: "null;";
String actual = Optional.ofNullable( model.tags() )
String expected = Optional.ofNullable( model.tags() )
.map( mt -> {
Set<String> modelUnionTags = mt.union()
.collect( Collectors.toCollection( TreeSet::new ) );
Expand All @@ -83,8 +83,9 @@ private List<Check> buildChecks( Model model, List<Check> checks ) {
} )
.orElse( "null;" );

if( !expected.equals( actual ) ) {
return new Violation( this, "Inaccurate tagging", expected, actual );
if( !actual.equals( expected ) ) {
return new Violation( this, "Inaccurate tagging in model: " + model.title(), expected,
actual );
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2024 Mastercard. All rights reserved.
*/

package com.mastercard.test.flow.validation.check;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;

import com.mastercard.test.flow.Model;
import com.mastercard.test.flow.validation.Check;
import com.mastercard.test.flow.validation.Validation;
import com.mastercard.test.flow.validation.Violation;

/**
* Checks that all {@link Model} have a unique title
*/
public final class ModelUniquenessCheck implements Validation {
@Override
public String name() {
return "Model uniqueness";
}

@Override
public String explanation() {
return "Models should be uniquely identified by its title";
}

@Override
public Stream<Check> checks( Model model ) {
Set<String> modelTitles = new HashSet<>();
return checkModelTitles( model, modelTitles ).stream();
}

private Set<Check> checkModelTitles( Model model, Set<String> modelTitles ) {
Set<Check> checks = new HashSet<>();
if( !modelTitles.add( model.title() ) ) {
checks.add( new Check( this, model.title(),
() -> new Violation( this, "Duplicate model title found: " + model.title() ) ) );
}
model.subModels()
.forEach( subModel -> checks.addAll( checkModelTitles( subModel, modelTitles ) ) );
return checks;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void with() {
+ "Interaction Identity\n"
+ "Message sharing\n"
+ "Model tagging\n"
+ "Model uniqueness\n"
+ "Reflective model tagging\n"
+ "Result tag misuse\n"
+ "Trace uniqueness",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,27 @@ void violation() {
test( leaf( "empty model tags",
null,
"a,b,c" ),
" details: Inaccurate tagging\n"
+ " expected: new TaggedGroup(\"a\", \"b\", \"c\");\n"
+ " actual: null;\n"
" details: Inaccurate tagging in model: empty model tags\n"
+ " expected: null;\n"
+ " actual: new TaggedGroup(\"a\", \"b\", \"c\");\n"
+ "offenders: " );

test( leaf( "empty flow tags",
new TaggedGroup( "a", "b", "c" ).union( "d" ) ),
" details: Inaccurate tagging\n"
+ " expected: null;\n"
+ " actual: new TaggedGroup(\"a\", \"b\", \"c\")\n"
" details: Inaccurate tagging in model: empty flow tags\n"
+ " expected: new TaggedGroup(\"a\", \"b\", \"c\")\n"
+ " .union(\"d\");\n"
+ " actual: null;\n"
+ "offenders: " );

test( leaf( "mismatch",
new TaggedGroup( "a", "b", "c" ).union( "d" ),
"a,b,c", "b,c,d" ),
" details: Inaccurate tagging\n"
+ " expected: new TaggedGroup(\"b\", \"c\")\n"
+ " .union(\"a\", \"d\");\n"
+ " actual: new TaggedGroup(\"a\", \"b\", \"c\")\n"
" details: Inaccurate tagging in model: mismatch\n"
+ " expected: new TaggedGroup(\"a\", \"b\", \"c\")\n"
+ " .union(\"d\");\n"
+ " actual: new TaggedGroup(\"b\", \"c\")\n"
+ " .union(\"a\", \"d\");\n"
+ "offenders: " );
}

Expand All @@ -99,15 +99,15 @@ void recursiveViolation() {
leaf( "left", new TaggedGroup( "a", "b" ), "a,b" ),
leaf( "right", new TaggedGroup( "b", "c" ), "b,c,d" ) ),
"left : pass",
" details: Inaccurate tagging\n"
+ " expected: new TaggedGroup(\"b\", \"c\", \"d\");\n"
+ " actual: new TaggedGroup(\"b\", \"c\");\n"
" details: Inaccurate tagging in model: right\n"
+ " expected: new TaggedGroup(\"b\", \"c\");\n"
+ " actual: new TaggedGroup(\"b\", \"c\", \"d\");\n"
+ "offenders: ",
" details: Inaccurate tagging\n"
" details: Inaccurate tagging in model: branch\n"
+ " expected: new TaggedGroup(\"b\")\n"
+ " .union(\"a\", \"c\", \"d\");\n"
+ " actual: new TaggedGroup(\"b\")\n"
+ " .union(\"a\", \"c\", \"x\");\n"
+ " actual: new TaggedGroup(\"b\")\n"
+ " .union(\"a\", \"c\", \"d\");\n"
+ "offenders: " );
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2024 Mastercard. All rights reserved.
*/

package com.mastercard.test.flow.validation.check;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.mastercard.test.flow.Model;

/**
* Exercises {@link ModelUniquenessCheck}
*/
class ModelUniquenessCheckTest extends AbstractValidationTest {

ModelUniquenessCheckTest() {
super( new ModelUniquenessCheck(), "Model uniqueness",
"Models should be uniquely identified by its title" );
}

private List<Model> createMockModels( List<String> titles ) {
return titles.stream().map( title -> {
Model model = mock( Model.class );
when( model.title() ).thenReturn( title );
when( model.subModels() ).thenReturn( Stream.empty() );
return model;
} ).collect( Collectors.toList() );
}

@Test
void testModelUniquenessFailureAssertion() {
// Create a list of model titles
List<String> titles = Arrays.asList( "Model1", "Model2", "Model1" );

// Create mock models
List<Model> models = createMockModels( titles );

// Create a parent model and set its subModels
Model parentModel = mock( Model.class );
when( parentModel.title() ).thenReturn( "ParentModel" );
when( parentModel.subModels() ).thenReturn( models.stream() );

test( parentModel, " details: Duplicate model title found: Model1\n"
+ " expected: null\n"
+ " actual: null\n"
+ "offenders: " );

}

@Test
void testModelUniquenessSuccessAssertion() {
// Create a list of model titles
List<String> titles = Arrays.asList( "Model1", "Model2", "Model3" );

// Create mock models
List<Model> models = createMockModels( titles );

// Create a parent model and set its subModels
Model parentModel = mock( Model.class );
when( parentModel.title() ).thenReturn( "ParentModel" );
when( parentModel.subModels() ).thenReturn( models.stream() );

test( parentModel );

}

}

0 comments on commit 6af510d

Please sign in to comment.