Skip to content

Commit

Permalink
Merge pull request #12 from antkorwin/feature/expected-regexp
Browse files Browse the repository at this point in the history
Using regular expressions in expected datasets
  • Loading branch information
antkorwin authored Dec 16, 2018
2 parents e9a0577 + b4c97bd commit cc6b675
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

/**
* Created on 09.12.2018.
*
* <p>
* Match two data sets, evaluate a combination of full matching.
*
* <p>
* Each data record match at least to one pattern
* and each pattern applies at least to one data record.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.antkorwin.springtestmongo.internal.expect;

import com.antkorwin.springtestmongo.internal.expect.matcher.MatcherFactory;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Created on 08.12.2018.
Expand Down Expand Up @@ -36,6 +39,8 @@ public boolean match(Object comparable) {

Map<String, Object> comparableMap = convertToMap(comparable);

MatcherFactory matcherFactory = new MatcherFactory();

for (Map.Entry<String, Object> comparableEntry : comparableMap.entrySet()) {

String cmpKey = comparableEntry.getKey();
Expand All @@ -59,10 +64,14 @@ public boolean match(Object comparable) {
}
}

// Check equals of values
if (!originValue.equals(cmpValue)) {
if (!originValue.getClass().equals(cmpValue.getClass())) {
return false;
}

boolean match = matcherFactory.getMatcher(cmpValue)
.match(originValue, cmpValue);

if(!match) return false;
}

return true;
Expand All @@ -71,4 +80,5 @@ public boolean match(Object comparable) {
private Map<String, Object> convertToMap(Object object) {
return objectMapper.convertValue(object, Map.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.antkorwin.springtestmongo.internal.expect.matcher;


/**
* Factory for obtaining a {@link ValueMatcher} to match the given value
*
* @author Korovin Anatoliy
*/
public class MatcherFactory {

private final RegexMatcher regexMatcher;
private final SimpleMatcher simpleMatcher;

public MatcherFactory() {
regexMatcher = new RegexMatcher();
simpleMatcher = new SimpleMatcher();
}

/**
* get matcher by the value of expected object
*
* @param value the value of expected object
*
* @return matcher for this value
*/
public ValueMatcher getMatcher(Object value) {
if (regexMatcher.isNecessary(value)) {
return regexMatcher;
} else {
return simpleMatcher;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.antkorwin.springtestmongo.internal.expect.matcher;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
* Match two objects with using a regular expression in the expected value.
*
* @author Korovin Anatoliy
*/
public class RegexMatcher implements ValueMatcher {

@Override
public boolean match(Object originValue, Object comparableValue) {
String cmpValue = (String) comparableValue;
cmpValue = cmpValue.replaceFirst("regex:", "").trim();
Pattern pattern = Pattern.compile(cmpValue);
Matcher matcher = pattern.matcher((String) originValue);
return matcher.matches();
}

@Override
public boolean isNecessary(Object value) {
if (!(value instanceof String)) {
return false;
}
String strValue = (String) value;
return (strValue.startsWith("regex:"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.antkorwin.springtestmongo.internal.expect.matcher;


/**
* Match two objects of simple types.
*
* @author Korovin Anatoliy
*/
class SimpleMatcher implements ValueMatcher {

@Override
public boolean match(Object originValue, Object comparableValue) {
return originValue.equals(comparableValue);
}

@Override
public boolean isNecessary(Object value) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.antkorwin.springtestmongo.internal.expect.matcher;


/**
* Algorithm to match two objects and check equals.
*
* @author Korovin Anatoliy
*/
public interface ValueMatcher {

/**
* Match two objects
*
* @param originValue value of original object
* @param comparableValue value of comparable(expected) object
*
* @return tru is this objects are same and false if not.
*/
boolean match(Object originValue, Object comparableValue);

/**
* Check necessary of applied this matcher to current value of expected object.
*/
boolean isNecessary(Object value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.antkorwin.springtestmongo.junit5.EnableMongoDbTestContainers;
import com.antkorwin.springtestmongo.junit5.MongoDbExtension;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -14,6 +15,7 @@
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Date;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -176,4 +178,62 @@ void testExpectNotExistsCollection() {
.contains("actual: \n[com.antkorwin.springtestmongo.Bar," +
" com.antkorwin.springtestmongo.Foo]");
}


@Nested
@SpringBootTest
@ExtendWith(SpringExtension.class)
@ExtendWith(MongoDbExtension.class)
@EnableMongoDbTestContainers
class RegexTests {

@Autowired
private MongoTemplate mongoTemplate;

@Test
@MongoDataSet(cleanBefore = true, cleanAfter = true)
void foundMatch() {
// Arrange
Bar bar1 = new Bar(UUID.randomUUID().toString(), "data-1");
mongoTemplate.save(bar1);
// Act
Assertions.assertDoesNotThrow(() -> {
new MongoDbTest(mongoTemplate).expect("/dataset/internal/expect/regex_test.json");
});
}

@Test
@MongoDataSet(cleanBefore = true, cleanAfter = true)
void notFoundMatch() {
// Arrange
Bar bar1 = new Bar("12345", "data-1");
mongoTemplate.save(bar1);
// Act
Error error = Assertions.assertThrows(Error.class, () -> {
new MongoDbTest(mongoTemplate).expect("/dataset/internal/expect/regex_test.json");
});

assertThat(error.getMessage()).contains("ExpectedDataSet of com.antkorwin.springtestmongo.Bar")
.contains("Not expected: \n" +
"{\"id\":\"12345\",\"data\":\"data-1\"}")
.contains("Expected but not found: \n" +
"{\"id\":\"regex: [a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}\",\"data\":\"data-1\"}");
}

@Test
@MongoDataSet(cleanBefore = true, cleanAfter = true)
void multipleRegexp() {
// Arrange
Bar bar1 = new Bar("1", "data-1");
Bar bar2 = new Bar("2", "data-2");
Bar bar3 = new Bar("3", "data-3");
Bar bar4 = new Bar("4", "data-4");
mongoTemplate.save(bar1);
mongoTemplate.save(bar2);
mongoTemplate.save(bar3);
mongoTemplate.save(bar4);
// Act
new MongoDbTest(mongoTemplate).expect("/dataset/internal/expect/multiple_regex.json");
}
}
}
Loading

0 comments on commit cc6b675

Please sign in to comment.