Skip to content

Commit

Permalink
Extract Matcher classname to plugable strategy
Browse files Browse the repository at this point in the history
Or, well, a function, if you want.
Default implementation with support for nested records, fixes #3
  • Loading branch information
runeflobakk committed Mar 11, 2024
1 parent 0540fce commit 35c1403
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package no.rune.record;

final class DefaultRecordMatcherClassNameResolver implements RecordMatcherClassNameResolver {

@Override
public String resolve(Class<? extends Record> record) {
var className = new StringBuilder(record.getSimpleName() + "Matcher");

for (var enclosing = record.getEnclosingClass(); enclosing != null; enclosing = enclosing.getEnclosingClass()) {
className.insert(0, enclosing.getSimpleName());
}
return className.toString();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package no.rune.record;

@FunctionalInterface
public interface RecordMatcherClassNameResolver {

String resolve(Class<? extends Record> record);

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@

public class RecordMatcherGenerator {

public static final RecordMatcherClassNameResolver DEFAULT_MATCHER_NAME_RESOLVER = new DefaultRecordMatcherClassNameResolver();

public String generateFromRecord(Class<? extends Record> record) {
return generateFromRecord(record, record.getPackage(), record.getSimpleName() + "Matcher");
return generateFromRecord(record, record.getPackage(), DEFAULT_MATCHER_NAME_RESOLVER.resolve(record));
}

public String generateFromRecord(Class<? extends Record> record, Package target, String matcherSimpleClassName) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package no.rune.record;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static uk.co.probablyfine.matchers.Java8Matchers.where;

class DefaultRecordMatcherClassNameResolverTest {

DefaultRecordMatcherClassNameResolver nameResolver = new DefaultRecordMatcherClassNameResolver();

@Test
void topLevelRecordResolvesMatcherClassName() {
assertThat(Foo.class, where(nameResolver::resolve, is("FooMatcher")));
}

@Test
void firstLevelNestedMatcherClassName() {
assertThat(Foo.Bar.class, where(nameResolver::resolve, is("FooBarMatcher")));
}

@Test
void secondLevelNestedMatcherClassName() {
assertThat(Foo.Bar.Baz.class, where(nameResolver::resolve, is("FooBarBazMatcher")));
}
}


record Foo() {
record Bar() {
record Baz() {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
public record ExpectedMatcher(String fullyQualifiedClassName, String sourceCode, Class<? extends Record> record) {

public static ExpectedMatcher expectedMatcherFor(Class<? extends Record> record) {
String fullyQualifiedMatcherClassName = record.getName() + "Matcher";
String fullyQualifiedMatcherClassName = record.getPackageName() + "." + RecordMatcherGenerator.DEFAULT_MATCHER_NAME_RESOLVER.resolve(record);
Path expectedMatcherSourceFile = javaTestSourceFiles.resolve(fullyQualifiedMatcherClassName.replaceAll("\\.", "/") + ".java");
try {
return new ExpectedMatcher(fullyQualifiedMatcherClassName, readString(expectedMatcherSourceFile), record);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package no.rune.record.matcher.example.nested;

import org.junit.jupiter.api.Test;

import static no.rune.record.matcher.ExpectedMatcher.expectedMatcherFor;

class NestedRecordsMatcherTest {

@Test
void generatesExpectedMatcherForOneLevelNestedRecord() {
expectedMatcherFor(TopLevel.Nested.class).assertEqualToGeneratedMatcherSourceCode();
}

@Test
void generatesExpectedMatcherForTwoLevelsNestedRecord() {
expectedMatcherFor(TopLevel.Nested.EvenMore.class).assertEqualToGeneratedMatcherSourceCode();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package no.rune.record.matcher.example.nested;

public record TopLevel() {

public record Nested(int value) {
public record EvenMore() {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package no.rune.record.matcher.example.nested;

import org.hamcrest.Description;
import org.hamcrest.TypeSafeDiagnosingMatcher;

public final class TopLevelNestedEvenMoreMatcher extends TypeSafeDiagnosingMatcher<TopLevel.Nested.EvenMore> {
private TopLevelNestedEvenMoreMatcher() {
}

public static TopLevelNestedEvenMoreMatcher anEvenMore() {
return new TopLevelNestedEvenMoreMatcher();
}

@Override
public void describeTo(Description description) {
description.appendText("any ").appendText(TopLevel.Nested.EvenMore.class.getSimpleName()).appendText(" record");
}

@Override
protected boolean matchesSafely(TopLevel.Nested.EvenMore element,
Description mismatchDescription) {
boolean matches = true;
return matches;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package no.rune.record.matcher.example.nested;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.hamcrest.core.IsAnything;

public final class TopLevelNestedMatcher extends TypeSafeDiagnosingMatcher<TopLevel.Nested> {
private final Matcher<? super Integer> valueMatcher;

private TopLevelNestedMatcher(Matcher<? super Integer> valueMatcher) {
this.valueMatcher = valueMatcher;
}

public static TopLevelNestedMatcher aNested() {
return new TopLevelNestedMatcher(new IsAnything<>("any value"));
}

public TopLevelNestedMatcher withValue(int value) {
return withValue(Matchers.is(value));
}

public TopLevelNestedMatcher withValue(Matcher<? super Integer> valueMatcher) {
return new TopLevelNestedMatcher(valueMatcher);
}

@Override
public void describeTo(Description description) {
if (valueMatcher instanceof IsAnything) {
description.appendText("any ").appendText(TopLevel.Nested.class.getSimpleName()).appendText(" record");
}
else {
description
.appendText(TopLevel.Nested.class.getSimpleName()).appendText(" record where");
if (!(valueMatcher instanceof IsAnything))
description.appendText(" value ").appendDescriptionOf(valueMatcher);
}
}

@Override
protected boolean matchesSafely(TopLevel.Nested element, Description mismatchDescription) {
boolean matches = true;
if (!valueMatcher.matches(element.value())) {
mismatchDescription.appendText(" value ");
valueMatcher.describeMismatch(element.value(), mismatchDescription);
matches = false;
}
return matches;
}
}

0 comments on commit 35c1403

Please sign in to comment.