Skip to content

Commit

Permalink
add members().should().{have,notHave}FullName[Not][Matching] syntax
Browse files Browse the repository at this point in the history
Signed-off-by: Manfred Hanke <[email protected]>
  • Loading branch information
hankem authored and codecholeric committed Jul 29, 2019
1 parent 291d1d5 commit 5879c48
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public static DescribedPredicate<HasName.AndFullName> fullName(String fullName)
* Matches full names against a regular expression.
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<HasName.AndFullName> fullNameMatching(String regex) {
return new FullNameMatchingPredicate(regex);
public static <HAS_FULL_NAME extends HasName.AndFullName> DescribedPredicate<HAS_FULL_NAME> fullNameMatching(String regex) {
return new FullNameMatchingPredicate<>(regex);
}

private static class FullNameEqualsPredicate extends DescribedPredicate<HasName.AndFullName> {
Expand All @@ -62,7 +62,7 @@ public boolean apply(HasName.AndFullName input) {
}
}

private static class FullNameMatchingPredicate extends DescribedPredicate<HasName.AndFullName> {
private static class FullNameMatchingPredicate<HAS_FULL_NAME extends HasName.AndFullName> extends DescribedPredicate<HAS_FULL_NAME> {
private final Pattern pattern;

FullNameMatchingPredicate(String regex) {
Expand All @@ -86,16 +86,16 @@ private Predicates() {
* Matches names against a regular expression.
*/
@PublicAPI(usage = ACCESS)
public static DescribedPredicate<HasName> nameMatching(final String regex) {
return new NameMatchingPredicate(regex);
public static <HAS_NAME extends HasName> DescribedPredicate<HAS_NAME> nameMatching(final String regex) {
return new NameMatchingPredicate<>(regex);
}

@PublicAPI(usage = ACCESS)
public static DescribedPredicate<HasName> name(final String name) {
return new NameEqualsPredicate(name);
}

private static class NameMatchingPredicate extends DescribedPredicate<HasName> {
private static class NameMatchingPredicate<HAS_NAME extends HasName> extends DescribedPredicate<HAS_NAME> {
private final Pattern pattern;

NameMatchingPredicate(String regex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.annotatedWith;
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.metaAnnotatedWith;
import static com.tngtech.archunit.core.domain.properties.HasModifiers.Predicates.modifier;
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullName;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameMatching;
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
import static com.tngtech.archunit.core.domain.properties.HasReturnType.Predicates.rawReturnType;
Expand Down Expand Up @@ -451,6 +451,16 @@ public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation
return not(ArchConditions.<HAS_NAME>haveName(name));
}

@PublicAPI(usage = ACCESS)
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> haveFullName(String fullName) {
return new HaveConditionByPredicate<>(fullName(fullName));
}

@PublicAPI(usage = ACCESS)
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> notHaveFullName(String fullName) {
return not(new HaveConditionByPredicate<HAS_FULL_NAME>(fullName(fullName)));
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> haveFullyQualifiedName(final String name) {
return new HaveConditionByPredicate<>(fullyQualifiedName(name));
Expand Down Expand Up @@ -516,15 +526,26 @@ public static ArchCondition<JavaClass> haveSimpleNameNotEndingWith(String suffix

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME> haveNameMatching(final String regex) {
final DescribedPredicate<HasName> haveNameMatching = have(nameMatching(regex));
return new NameMatchingCondition<>(haveNameMatching, regex);
final DescribedPredicate<HAS_NAME> haveNameMatching = have(HasName.Predicates.<HAS_NAME>nameMatching(regex));
return new MatchingCondition<>(haveNameMatching, regex);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME> haveNameNotMatching(String regex) {
return not(ArchConditions.<HAS_NAME>haveNameMatching(regex)).as("have name not matching '%s'", regex);
}

@PublicAPI(usage = ACCESS)
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> haveFullNameMatching(String regex) {
final DescribedPredicate<HAS_FULL_NAME> haveFullNameMatching = have(HasName.AndFullName.Predicates.<HAS_FULL_NAME>fullNameMatching(regex));
return new MatchingCondition<HAS_FULL_NAME>(haveFullNameMatching, regex);
}

@PublicAPI(usage = ACCESS)
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> haveFullNameNotMatching(String regex) {
return not(ArchConditions.<HAS_FULL_NAME>haveFullNameMatching(regex)).as("have full name not matching '%s'", regex);
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideInAPackage(final String packageIdentifier) {
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideInAPackage(packageIdentifier));
Expand Down Expand Up @@ -1095,22 +1116,22 @@ public void check(JavaClass javaClass, ConditionEvents events) {
}
}

private static class NameMatchingCondition<HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> extends ArchCondition<HAS_NAME> {
private final DescribedPredicate<HasName> haveNameMatching;
private static class MatchingCondition<T extends HasDescription & HasSourceCodeLocation> extends ArchCondition<T> {
private final DescribedPredicate<T> matcher;
private final String regex;

NameMatchingCondition(DescribedPredicate<HasName> haveNameMatching, String regex) {
super(haveNameMatching.getDescription());
this.haveNameMatching = haveNameMatching;
MatchingCondition(DescribedPredicate<T> matcher, String regex) {
super(matcher.getDescription());
this.matcher = matcher;
this.regex = regex;
}

@Override
public void check(HAS_NAME hasName, ConditionEvents events) {
boolean satisfied = haveNameMatching.apply(hasName);
String message = createMessage(hasName,
public void check(T item, ConditionEvents events) {
boolean satisfied = matcher.apply(item);
String message = createMessage(item,
String.format("%s '%s'", satisfied ? "matches" : "does not match", regex));
events.add(new SimpleConditionEvent(hasName, satisfied, message));
events.add(new SimpleConditionEvent(item, satisfied, message));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,25 @@ public SELF haveNameNotMatching(String regex) {
return addCondition(ArchConditions.haveNameNotMatching(regex));
}

@Override
public SELF haveFullName(String fullName) {
return addCondition(ArchConditions.haveFullName(fullName));
}

@Override
public SELF notHaveFullName(String fullName) {
return addCondition(ArchConditions.notHaveFullName(fullName));
}

@Override
public SELF haveFullNameMatching(String regex) {
return addCondition(ArchConditions.haveFullNameMatching(regex));
}

@Override
public SELF haveFullNameNotMatching(String regex) {
return addCondition(ArchConditions.haveFullNameNotMatching(regex));
}
@Override
public SELF bePublic() {
return addCondition(ArchConditions.bePublic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,42 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameNotMatching(String regex);

/**
* Asserts that members have a certain full name.
*
* @param fullName The member's full name
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveFullName(String fullName);

/**
* Asserts that members do not have a certain full name.
*
* @param fullName The member's full name
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION notHaveFullName(String fullName);

/**
* Asserts that members have a full name matching a given regular expression.
*
* @param regex A regular expression
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveFullNameMatching(String regex);

/**
* Asserts that members have a full name not matching a given regular expression.
*
* @param regex A regular expression
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveFullNameNotMatching(String regex);

/**
* Asserts that members are public.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public void complex_members_syntax() {

@DataProvider
public static Object[][] restricted_property_rule_ends() {
String classNameDot = ClassWithVariousMembers.class.getName() + ".";
ImmutableList.Builder<Object[]> data = ImmutableList.<Object[]>builder().add(
$(members().should().haveName(FIELD_A), allMembersExcept(FIELD_A)),
$(codeUnits().should().haveName(FIELD_A), ALL_CODE_UNIT_DESCRIPTIONS),
Expand Down Expand Up @@ -131,6 +132,32 @@ public static Object[][] restricted_property_rule_ends() {
$(codeUnits().should().haveNameNotMatching(".*init.*"), ALL_CONSTRUCTOR_DESCRIPTIONS),
$(constructors().should().haveNameNotMatching(".*init.*"), ALL_CONSTRUCTOR_DESCRIPTIONS),

$(members().should().haveFullName(classNameDot + FIELD_A), allMembersExcept(FIELD_A)),
$(fields().should().haveFullName(classNameDot + FIELD_A), allFieldsExcept(FIELD_A)),
$(codeUnits().should().haveFullName(classNameDot + FIELD_A), ALL_CODE_UNIT_DESCRIPTIONS),
$(methods().should().haveFullName(classNameDot + METHOD_A), allMethodsExcept(METHOD_A)),
$(codeUnits().should().haveFullName(classNameDot + METHOD_A), allCodeUnitsExcept(METHOD_A)),
$(members().should().notHaveFullName(classNameDot + FIELD_A), ImmutableSet.of(FIELD_A)),
$(fields().should().notHaveFullName(classNameDot + FIELD_A), ImmutableSet.of(FIELD_A)),
$(codeUnits().should().notHaveFullName(classNameDot + FIELD_A), emptySet()),
$(methods().should().notHaveFullName(classNameDot + METHOD_A), ImmutableSet.of(METHOD_A)),
$(codeUnits().should().notHaveFullName(classNameDot + METHOD_A), ImmutableSet.of(METHOD_A)),

$(members().should().haveFullNameMatching(quote(classNameDot) + ".*A\\(?\\)?"), allMembersExcept(FIELD_A, METHOD_A)),
$(codeUnits().should().haveFullNameMatching(quote(classNameDot) + ".*A"), ALL_CODE_UNIT_DESCRIPTIONS),
$(fields().should().haveFullNameMatching(quote(classNameDot) + ".*A"), allFieldsExcept(FIELD_A)),
$(codeUnits().should().haveFullNameMatching(quote(classNameDot) + ".*A" + quote("()")), allCodeUnitsExcept(METHOD_A)),
$(methods().should().haveFullNameMatching(quote(classNameDot) + ".*A" + quote("()")), allMethodsExcept(METHOD_A)),
$(codeUnits().should().haveFullNameMatching(quote(classNameDot) + "..*init.*"), ALL_METHOD_DESCRIPTIONS),
$(constructors().should().haveFullNameMatching(quote(classNameDot) + ".*init.*"), emptySet()),
$(members().should().haveFullNameNotMatching(quote(classNameDot) + ".*A\\(?\\)?"), ImmutableSet.of(FIELD_A, METHOD_A)),
$(codeUnits().should().haveFullNameNotMatching(quote(classNameDot) + ".*A"), emptySet()),
$(fields().should().haveFullNameNotMatching(quote(classNameDot) + ".*A"), ImmutableSet.of(FIELD_A)),
$(codeUnits().should().haveFullNameNotMatching(quote(classNameDot) + ".*A" + quote("()")), ImmutableSet.of(METHOD_A)),
$(methods().should().haveFullNameNotMatching(quote(classNameDot) + ".*A" + quote("()")), ImmutableSet.of(METHOD_A)),
$(codeUnits().should().haveFullNameNotMatching(quote(classNameDot) + ".*init.*"), ALL_CONSTRUCTOR_DESCRIPTIONS),
$(constructors().should().haveFullNameNotMatching(quote(classNameDot) + ".*init.*"), ALL_CONSTRUCTOR_DESCRIPTIONS),

$(members().should().bePublic(), allMembersExcept(
FIELD_PUBLIC, METHOD_PUBLIC, CONSTRUCTOR_PUBLIC)),
$(fields().should().bePublic(), allFieldsExcept(FIELD_PUBLIC)),
Expand Down

0 comments on commit 5879c48

Please sign in to comment.