Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend MembersThat and MembersShould to have starting,… (Resolves #239) #314

Merged
merged 2 commits into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@ public static DescribedPredicate<HasName> nameMatching(final String regex) {
return new NameMatchingPredicate(regex);
}

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

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

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

private static class NameEqualsPredicate extends DescribedPredicate<HasName> {
private final String name;

Expand Down Expand Up @@ -138,6 +153,49 @@ public boolean apply(HasName input) {
return pattern.matcher(input.getName()).matches();
}
}

private static class NameStartingWithPredicate extends DescribedPredicate<HasName> {
private final String prefix;

NameStartingWithPredicate(String prefix) {
super(String.format("name starting with '%s'", prefix));
this.prefix = prefix;
}

@Override
public boolean apply(HasName input) {
return input.getName().startsWith(prefix);
}

}

private static class NameContainingPredicate extends DescribedPredicate<HasName> {
private final String infix;

NameContainingPredicate(String infix) {
super(String.format("name containing '%s'", infix));
this.infix = infix;
}

@Override
public boolean apply(HasName input) {
return input.getName().contains(infix);
}
}

private static class NameEndingWithPredicate extends DescribedPredicate<HasName> {
private final String suffix;

NameEndingWithPredicate(String suffix) {
super(String.format("name ending with '%s'", suffix));
this.suffix = suffix;
}

@Override
public boolean apply(HasName input) {
return input.getName().endsWith(suffix);
}
}
}

final class Functions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullName;
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullNameMatching;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameContaining;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameEndingWith;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameMatching;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameStartingWith;
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 @@ -553,6 +556,48 @@ ArchCondition<HAS_FULL_NAME> haveFullNameMatching(String regex) {
return not(ArchConditions.<HAS_FULL_NAME>haveFullNameMatching(regex)).as("have full name not matching '%s'", regex);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameStartingWith(String prefix) {
final DescribedPredicate<HAS_NAME> haveNameStartingWith = have(nameStartingWith(prefix)).forSubType();
return new StartingCondition<>(haveNameStartingWith, prefix);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameNotStartingWith(String prefix) {
final DescribedPredicate<HAS_NAME> haveNameStartingWith = have(nameStartingWith(prefix)).forSubType();
return not(new StartingCondition<>(haveNameStartingWith, prefix)).as("have name not starting with '%s'", prefix);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameContaining(String infix) {
final DescribedPredicate<HAS_NAME> haveNameContaining = have(nameContaining(infix)).forSubType();
return new ContainingCondition<>(haveNameContaining, infix);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameNotContaining(String infix) {
final DescribedPredicate<HAS_NAME> haveNameContaining = have(nameContaining(infix)).forSubType();
return not(new ContainingCondition<>(haveNameContaining, infix)).as("have name not containing '%s'", infix);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameEndingWith(String suffix) {
final DescribedPredicate<HAS_NAME> haveNameEndingWith = have(nameEndingWith(suffix)).forSubType();
return new EndingCondition<>(haveNameEndingWith, suffix);
}

@PublicAPI(usage = ACCESS)
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME>
haveNameNotEndingWith(String suffix) {
final DescribedPredicate<HAS_NAME> haveNameEndingWith = have(nameEndingWith(suffix)).forSubType();
return not(new EndingCondition<>(haveNameEndingWith, suffix)).as("have name not ending with '%s'", suffix);
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideInAPackage(final String packageIdentifier) {
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideInAPackage(packageIdentifier));
Expand Down Expand Up @@ -1243,6 +1288,63 @@ public void check(T item, ConditionEvents events) {
}
}

private static class StartingCondition<T extends HasDescription & HasSourceCodeLocation> extends ArchCondition<T> {
private final DescribedPredicate<T> startingWith;
private final String prefix;

StartingCondition(DescribedPredicate<T> startingWith, String prefix) {
super(startingWith.getDescription());
this.startingWith = startingWith;
this.prefix = prefix;
}

@Override
public void check(T item, ConditionEvents events) {
boolean satisfied = startingWith.apply(item);
String message = createMessage(item,
String.format("name %s '%s'", satisfied ? "starts with" : "does not start with", prefix));
events.add(new SimpleConditionEvent(item, satisfied, message));
}
}

private static class ContainingCondition<T extends HasDescription & HasSourceCodeLocation> extends ArchCondition<T> {
private final DescribedPredicate<T> containing;
private final String infix;

ContainingCondition(DescribedPredicate<T> containing, String infix) {
super(containing.getDescription());
this.containing = containing;
this.infix = infix;
}

@Override
public void check(T item, ConditionEvents events) {
boolean satisfied = containing.apply(item);
String message = createMessage(item,
String.format("name %s '%s'", satisfied ? "contains" : "does not contain", infix));
events.add(new SimpleConditionEvent(item, satisfied, message));
}
}

private static class EndingCondition<T extends HasDescription & HasSourceCodeLocation> extends ArchCondition<T> {
private final DescribedPredicate<T> endingWith;
private final String suffix;

EndingCondition(DescribedPredicate<T> endingWith, String suffix) {
super(endingWith.getDescription());
this.endingWith = endingWith;
this.suffix = suffix;
}

@Override
public void check(T item, ConditionEvents events) {
boolean satisfied = endingWith.apply(item);
String message = createMessage(item,
String.format("name %s '%s'", satisfied ? "ends with" : "does not end with", suffix));
events.add(new SimpleConditionEvent(item, satisfied, message));
}
}

private static class DoesConditionByPredicate<T extends HasDescription & HasSourceCodeLocation>
extends ArchCondition<T> {
private final DescribedPredicate<? super T> predicate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,37 @@ public SELF haveFullNameMatching(String regex) {
public SELF haveFullNameNotMatching(String regex) {
return addCondition(ArchConditions.haveFullNameNotMatching(regex));
}

@Override
public SELF haveNameStartingWith(String prefix) {
return addCondition(ArchConditions.haveNameStartingWith(prefix));
}

@Override
public SELF haveNameNotStartingWith(String prefix) {
return addCondition(ArchConditions.haveNameNotStartingWith(prefix));
}

@Override
public SELF haveNameContaining(String infix) {
return addCondition(ArchConditions.haveNameContaining(infix));
}

@Override
public SELF haveNameNotContaining(String infix) {
return addCondition(ArchConditions.haveNameNotContaining(infix));
}

@Override
public SELF haveNameEndingWith(String suffix) {
return addCondition(ArchConditions.haveNameEndingWith(suffix));
}

@Override
public SELF haveNameNotEndingWith(String suffix) {
return addCondition(ArchConditions.haveNameNotEndingWith(suffix));
}

@Override
public SELF bePublic() {
return addCondition(ArchConditions.bePublic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullName;
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullNameMatching;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameContaining;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameEndingWith;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameMatching;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameStartingWith;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.have;

Expand Down Expand Up @@ -93,6 +96,36 @@ public CONJUNCTION haveFullNameNotMatching(String regex) {
return givenWith(have(not(fullNameMatching(regex)).as("full name not matching '%s'", regex)));
}

@Override
public CONJUNCTION haveNameStartingWith(String prefix) {
return givenWith(have(nameStartingWith(prefix)));
}

@Override
public CONJUNCTION haveNameNotStartingWith(String prefix) {
return givenWith(have(not(nameStartingWith(prefix)).as("name not starting with '%s'", prefix)));
}

@Override
public CONJUNCTION haveNameContaining(String infix) {
return givenWith(have(nameContaining(infix)));
}

@Override
public CONJUNCTION haveNameNotContaining(String infix) {
return givenWith(have(not(nameContaining(infix)).as("name not containing '%s'", infix)));
}

@Override
public CONJUNCTION haveNameEndingWith(String suffix) {
return givenWith(have(nameEndingWith(suffix)));
}

@Override
public CONJUNCTION haveNameNotEndingWith(String suffix) {
return givenWith(have(not(nameEndingWith(suffix)).as("name not ending with '%s'", suffix)));
}

@Override
public CONJUNCTION arePublic() {
return givenWith(SyntaxPredicates.arePublic());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,60 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
@PublicAPI(usage = ACCESS)
CONJUNCTION haveFullNameNotMatching(String regex);

/**
* Asserts that members have a name starting with the specified prefix.
*
* @param prefix A prefix the member name should start with
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameStartingWith(String prefix);

/**
* Asserts that members have a name not starting with the specified prefix.
*
* @param prefix A prefix the member name should not start with
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameNotStartingWith(String prefix);

/**
* Asserts that members have a name containing the specified infix.
*
* @param infix An infix the member name should contain
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameContaining(String infix);

/**
* Asserts that members have a name not containing the specified infix.
*
* @param infix An infix the member name should not contain
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameNotContaining(String infix);

/**
* Asserts that members have a name ending with the specified suffix.
*
* @param suffix A suffix the member name should end with
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameEndingWith(String suffix);

/**
* Asserts that members have a name not ending with the specified suffix.
*
* @param suffix A suffix the member name should not end with
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
*/
@PublicAPI(usage = ACCESS)
CONJUNCTION haveNameNotEndingWith(String suffix);

/**
* Asserts that members are public.
*
Expand Down
Loading