Skip to content

Commit 71a524e

Browse files
committed
Review:
- Added some Javadoc (since I'm not sure if 'full name' can be immediately understood by every user) - Removed the generic return type from the predicates in HasName and HasName.AndFullName since the caller should be responsible to map to the subtype (or it would have to be consistently changed in many other places) - Tried to make some tests more decisive by matching at least some element of the passed collection - Unrelated: Added HasName.AndFullName.Functions.GET_FULL_NAME to be consistent with HasName Signed-off-by: Peter Gafert <[email protected]>
1 parent 5879c48 commit 71a524e

File tree

11 files changed

+99
-39
lines changed

11 files changed

+99
-39
lines changed

archunit/src/main/java/com/tngtech/archunit/core/domain/AccessTarget.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ public JavaClass getOwner() {
9191
return owner;
9292
}
9393

94+
/**
95+
* @return The full name of this {@link AccessTarget}, i.e. a string containing {@code ${declaringClass}.${name}} for a field and
96+
* {@code ${declaringClass}.${name}(${parameterTypes})} for a code unit
97+
*/
9498
@Override
9599
@PublicAPI(usage = ACCESS)
96100
public String getFullName() {

archunit/src/main/java/com/tngtech/archunit/core/domain/JavaClass.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ public Set<JavaMember> get() {
109109
javaPackage = JavaPackage.simple(this);
110110
}
111111

112+
/**
113+
* @return The {@link Source} of this {@link JavaClass}, i.e. where this class has been imported from
114+
*/
112115
@PublicAPI(usage = ACCESS)
113116
public Optional<Source> getSource() {
114117
return source;
@@ -126,12 +129,18 @@ public String getDescription() {
126129
return "Class <" + getName() + ">";
127130
}
128131

132+
/**
133+
* @return The fully qualified name of this {@link JavaClass}, compare {@link Class#getName()} of the Reflection API
134+
*/
129135
@Override
130136
@PublicAPI(usage = ACCESS)
131137
public String getName() {
132138
return javaType.getName();
133139
}
134140

141+
/**
142+
* @return The fully qualified name of this {@link JavaClass}, i.e. the result is the same as invoking {@link #getName()}
143+
*/
135144
@Override
136145
@PublicAPI(usage = ACCESS)
137146
public String getFullName() {

archunit/src/main/java/com/tngtech/archunit/core/domain/JavaCodeUnit.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public abstract class JavaCodeUnit extends JavaMember implements HasParameterTyp
6262
fullName = formatMethod(getOwner().getName(), getName(), getRawParameterTypes());
6363
}
6464

65+
/**
66+
* @return The full name of this {@link JavaCodeUnit}, i.e. a string containing {@code ${declaringClass}.${name}(${parameterTypes})}
67+
*/
6568
@Override
6669
@PublicAPI(usage = ACCESS)
6770
public String getFullName() {

archunit/src/main/java/com/tngtech/archunit/core/domain/JavaField.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class JavaField extends JavaMember implements HasType {
4242
fieldSupplier = Suppliers.memoize(new ReflectFieldSupplier());
4343
}
4444

45+
/**
46+
* @return The full name of this {@link JavaField}, i.e. a string containing {@code ${declaringClass}.${name}}
47+
*/
4548
@Override
4649
@PublicAPI(usage = ACCESS)
4750
public String getFullName() {

archunit/src/main/java/com/tngtech/archunit/core/domain/properties/HasName.java

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public interface HasName {
2828
String getName();
2929

3030
interface AndFullName extends HasName {
31+
/**
32+
* @return The full name of the given object. Varies by context, for details consult Javadoc of the concrete subclass.
33+
*/
3134
@PublicAPI(usage = ACCESS)
3235
String getFullName();
3336

@@ -44,8 +47,8 @@ public static DescribedPredicate<HasName.AndFullName> fullName(String fullName)
4447
* Matches full names against a regular expression.
4548
*/
4649
@PublicAPI(usage = ACCESS)
47-
public static <HAS_FULL_NAME extends HasName.AndFullName> DescribedPredicate<HAS_FULL_NAME> fullNameMatching(String regex) {
48-
return new FullNameMatchingPredicate<>(regex);
50+
public static DescribedPredicate<HasName.AndFullName> fullNameMatching(String regex) {
51+
return new FullNameMatchingPredicate(regex);
4952
}
5053

5154
private static class FullNameEqualsPredicate extends DescribedPredicate<HasName.AndFullName> {
@@ -62,7 +65,7 @@ public boolean apply(HasName.AndFullName input) {
6265
}
6366
}
6467

65-
private static class FullNameMatchingPredicate<HAS_FULL_NAME extends HasName.AndFullName> extends DescribedPredicate<HAS_FULL_NAME> {
68+
private static class FullNameMatchingPredicate extends DescribedPredicate<HasName.AndFullName> {
6669
private final Pattern pattern;
6770

6871
FullNameMatchingPredicate(String regex) {
@@ -76,50 +79,63 @@ public boolean apply(HasName.AndFullName input) {
7679
}
7780
}
7881
}
82+
83+
final class Functions {
84+
private Functions() {
85+
}
86+
87+
@PublicAPI(usage = ACCESS)
88+
public static final ChainableFunction<HasName.AndFullName, String> GET_FULL_NAME = new ChainableFunction<HasName.AndFullName, String>() {
89+
@Override
90+
public String apply(HasName.AndFullName input) {
91+
return input.getFullName();
92+
}
93+
};
94+
}
7995
}
8096

8197
final class Predicates {
8298
private Predicates() {
8399
}
84100

85-
/**
86-
* Matches names against a regular expression.
87-
*/
88101
@PublicAPI(usage = ACCESS)
89-
public static <HAS_NAME extends HasName> DescribedPredicate<HAS_NAME> nameMatching(final String regex) {
90-
return new NameMatchingPredicate<>(regex);
102+
public static DescribedPredicate<HasName> name(final String name) {
103+
return new NameEqualsPredicate(name);
91104
}
92105

106+
/**
107+
* Matches names against a regular expression.
108+
*/
93109
@PublicAPI(usage = ACCESS)
94-
public static DescribedPredicate<HasName> name(final String name) {
95-
return new NameEqualsPredicate(name);
110+
public static DescribedPredicate<HasName> nameMatching(final String regex) {
111+
return new NameMatchingPredicate(regex);
96112
}
97113

98-
private static class NameMatchingPredicate<HAS_NAME extends HasName> extends DescribedPredicate<HAS_NAME> {
99-
private final Pattern pattern;
114+
private static class NameEqualsPredicate extends DescribedPredicate<HasName> {
115+
private final String name;
100116

101-
NameMatchingPredicate(String regex) {
102-
super(String.format("name matching '%s'", regex));
103-
this.pattern = Pattern.compile(regex);
117+
NameEqualsPredicate(String name) {
118+
super(String.format("name '%s'", name));
119+
this.name = name;
104120
}
105121

106122
@Override
107123
public boolean apply(HasName input) {
108-
return pattern.matcher(input.getName()).matches();
124+
return input.getName().equals(name);
109125
}
110126
}
111127

112-
private static class NameEqualsPredicate extends DescribedPredicate<HasName> {
113-
private final String name;
128+
private static class NameMatchingPredicate extends DescribedPredicate<HasName> {
129+
private final Pattern pattern;
114130

115-
NameEqualsPredicate(String name) {
116-
super(String.format("name '%s'", name));
117-
this.name = name;
131+
NameMatchingPredicate(String regex) {
132+
super(String.format("name matching '%s'", regex));
133+
this.pattern = Pattern.compile(regex);
118134
}
119135

120136
@Override
121137
public boolean apply(HasName input) {
122-
return input.getName().equals(name);
138+
return pattern.matcher(input.getName()).matches();
123139
}
124140
}
125141
}

archunit/src/main/java/com/tngtech/archunit/core/domain/properties/HasSourceCodeLocation.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
2222

2323
public interface HasSourceCodeLocation {
24+
/**
25+
* @return The {@link SourceCodeLocation} of this object, i.e. how to locate the respective object within the set of source files.
26+
*/
2427
@PublicAPI(usage = ACCESS)
2528
SourceCodeLocation getSourceCodeLocation();
2629
}

archunit/src/main/java/com/tngtech/archunit/lang/conditions/ArchConditions.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@
9999
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.metaAnnotatedWith;
100100
import static com.tngtech.archunit.core.domain.properties.HasModifiers.Predicates.modifier;
101101
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullName;
102+
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullNameMatching;
102103
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
104+
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameMatching;
103105
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
104106
import static com.tngtech.archunit.core.domain.properties.HasParameterTypes.Predicates.rawParameterTypes;
105107
import static com.tngtech.archunit.core.domain.properties.HasReturnType.Predicates.rawReturnType;
@@ -452,12 +454,14 @@ public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation
452454
}
453455

454456
@PublicAPI(usage = ACCESS)
455-
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> haveFullName(String fullName) {
457+
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation>
458+
ArchCondition<HAS_FULL_NAME> haveFullName(String fullName) {
456459
return new HaveConditionByPredicate<>(fullName(fullName));
457460
}
458461

459462
@PublicAPI(usage = ACCESS)
460-
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> notHaveFullName(String fullName) {
463+
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation>
464+
ArchCondition<HAS_FULL_NAME> notHaveFullName(String fullName) {
461465
return not(new HaveConditionByPredicate<HAS_FULL_NAME>(fullName(fullName)));
462466
}
463467

@@ -526,7 +530,7 @@ public static ArchCondition<JavaClass> haveSimpleNameNotEndingWith(String suffix
526530

527531
@PublicAPI(usage = ACCESS)
528532
public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_NAME> haveNameMatching(final String regex) {
529-
final DescribedPredicate<HAS_NAME> haveNameMatching = have(HasName.Predicates.<HAS_NAME>nameMatching(regex));
533+
final DescribedPredicate<HAS_NAME> haveNameMatching = have(nameMatching(regex)).forSubType();
530534
return new MatchingCondition<>(haveNameMatching, regex);
531535
}
532536

@@ -536,13 +540,15 @@ public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation
536540
}
537541

538542
@PublicAPI(usage = ACCESS)
539-
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_FULL_NAME> haveFullNameMatching(String regex) {
540-
final DescribedPredicate<HAS_FULL_NAME> haveFullNameMatching = have(HasName.AndFullName.Predicates.<HAS_FULL_NAME>fullNameMatching(regex));
541-
return new MatchingCondition<HAS_FULL_NAME>(haveFullNameMatching, regex);
543+
public static <HAS_FULL_NAME extends HasName.AndFullName & HasDescription & HasSourceCodeLocation>
544+
ArchCondition<HAS_FULL_NAME> haveFullNameMatching(String regex) {
545+
final DescribedPredicate<HAS_FULL_NAME> haveFullNameMatching = have(fullNameMatching(regex)).forSubType();
546+
return new MatchingCondition<>(haveFullNameMatching, regex);
542547
}
543548

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

archunit/src/main/java/com/tngtech/archunit/lang/syntax/elements/MembersShould.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import com.tngtech.archunit.base.DescribedPredicate;
2222
import com.tngtech.archunit.core.domain.JavaAnnotation;
2323
import com.tngtech.archunit.core.domain.JavaClass;
24+
import com.tngtech.archunit.core.domain.JavaCodeUnit;
2425
import com.tngtech.archunit.core.domain.JavaConstructor;
26+
import com.tngtech.archunit.core.domain.JavaField;
2527
import com.tngtech.archunit.core.domain.JavaModifier;
2628
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
2729

@@ -68,7 +70,7 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
6870
CONJUNCTION haveNameNotMatching(String regex);
6971

7072
/**
71-
* Asserts that members have a certain full name.
73+
* Asserts that members have a certain full name (compare {@link JavaField#getFullName()} and {@link JavaCodeUnit#getFullName()}).
7274
*
7375
* @param fullName The member's full name
7476
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
@@ -77,7 +79,7 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
7779
CONJUNCTION haveFullName(String fullName);
7880

7981
/**
80-
* Asserts that members do not have a certain full name.
82+
* Asserts that members do not have a certain full name (compare {@link JavaField#getFullName()} and {@link JavaCodeUnit#getFullName()}).
8183
*
8284
* @param fullName The member's full name
8385
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
@@ -86,7 +88,8 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
8688
CONJUNCTION notHaveFullName(String fullName);
8789

8890
/**
89-
* Asserts that members have a full name matching a given regular expression.
91+
* Asserts that members have a full name matching a given regular expression (compare {@link JavaField#getFullName()}
92+
* and {@link JavaCodeUnit#getFullName()}).
9093
*
9194
* @param regex A regular expression
9295
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule
@@ -95,7 +98,8 @@ public interface MembersShould<CONJUNCTION extends MembersShouldConjunction<?>>
9598
CONJUNCTION haveFullNameMatching(String regex);
9699

97100
/**
98-
* Asserts that members have a full name not matching a given regular expression.
101+
* Asserts that members have a full name not matching a given regular expression (compare {@link JavaField#getFullName()}
102+
* and {@link JavaCodeUnit#getFullName()}).
99103
*
100104
* @param regex A regular expression
101105
* @return A syntax element that can either be used as working rule, or to continue specifying a more complex rule

archunit/src/test/java/com/tngtech/archunit/core/domain/properties/HasNameTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import org.assertj.core.api.AbstractBooleanAssert;
44
import org.junit.Test;
55

6+
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Functions.GET_FULL_NAME;
67
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullName;
78
import static com.tngtech.archunit.core.domain.properties.HasName.AndFullName.Predicates.fullNameMatching;
9+
import static com.tngtech.archunit.core.domain.properties.HasName.Functions.GET_NAME;
810
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.name;
911
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.nameMatching;
1012
import static com.tngtech.archunit.testutil.Assertions.assertThat;
@@ -53,6 +55,13 @@ public void fullNameMatching_predicate() {
5355
.hasDescription("full name matching '.*method\\(.*\\)'");
5456
}
5557

58+
@Test
59+
public void functions() {
60+
HasName.AndFullName test = newHasNameAndFullName("simple", "full");
61+
assertThat(GET_NAME.apply(test)).isEqualTo("simple");
62+
assertThat(GET_FULL_NAME.apply(test)).isEqualTo("full");
63+
}
64+
5665
private AbstractBooleanAssert assertNameMatches(String input, String regex) {
5766
return assertThat(nameMatching(regex).apply(newHasName(input)))
5867
.as(input + " =~ " + regex);

archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMembersTest.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.List;
66
import java.util.Map;
77
import java.util.Set;
8-
import java.util.regex.Pattern;
98

109
import com.google.common.collect.FluentIterable;
1110
import com.google.common.collect.ImmutableList;
@@ -195,22 +194,24 @@ public static Object[][] restricted_property_rule_starts() {
195194
$(described(constructors().that().haveFullName(classNameDot + CONSTRUCTOR_ONE_ARG)), ImmutableSet.of(CONSTRUCTOR_ONE_ARG)),
196195
$(described(fields().that().haveFullName(classNameDot + FIELD_A)), ImmutableSet.of(FIELD_A)),
197196
$(described(members().that().doNotHaveFullName(classNameDot + FIELD_A)), union(allFieldsExcept(FIELD_A), ALL_CODE_UNIT_DESCRIPTIONS)),
198-
$(described(codeUnits().that().doNotHaveFullName(classNameDot + FIELD_A)), ALL_CODE_UNIT_DESCRIPTIONS),
197+
$(described(codeUnits().that().doNotHaveFullName(classNameDot + METHOD_A)), allCodeUnitsExcept(METHOD_A)),
199198
$(described(methods().that().doNotHaveFullName(classNameDot + METHOD_A)), allMethodsExcept(METHOD_A)),
200199
$(described(constructors().that().doNotHaveFullName(classNameDot + CONSTRUCTOR_ONE_ARG)), allConstructorsExcept(CONSTRUCTOR_ONE_ARG)),
201200
$(described(fields().that().doNotHaveFullName(classNameDot + FIELD_A)), allFieldsExcept(FIELD_A)),
202201

203202
$(described(members().that().haveFullNameMatching(quote(classNameDot) + ".*A.*")), ImmutableSet.of(FIELD_A, METHOD_A)),
204203
$(described(codeUnits().that().haveFullNameMatching(quote(classNameDot) + ".*A.*")), ImmutableSet.of(METHOD_A)),
205204
$(described(methods().that().haveFullNameMatching(quote(classNameDot) + ".*A.*")), ImmutableSet.of(METHOD_A)),
206-
$(described(constructors().that().haveFullNameMatching(".*init.*")), ALL_CONSTRUCTOR_DESCRIPTIONS),
205+
$(described(constructors().that().haveFullNameMatching(quote(classNameDot) + ".*init.*String\\)")),
206+
ImmutableSet.of(CONSTRUCTOR_ONE_ARG)),
207207
$(described(fields().that().haveFullNameMatching(quote(classNameDot) + ".*A.*")), ImmutableSet.of(FIELD_A)),
208208
$(described(members().that().haveFullNameNotMatching(quote(classNameDot) + "f.*A.*")), union(
209209
allFieldsExcept(FIELD_A),
210210
ALL_CODE_UNIT_DESCRIPTIONS)),
211211
$(described(codeUnits().that().haveFullNameNotMatching(quote(classNameDot) + "f.*A.*")), ALL_CODE_UNIT_DESCRIPTIONS),
212212
$(described(methods().that().haveFullNameNotMatching(quote(classNameDot) + ".*A.*")), allMethodsExcept(METHOD_A)),
213-
$(described(constructors().that().haveFullNameNotMatching(".*init.*")), emptySet()),
213+
$(described(constructors().that().haveFullNameNotMatching(quote(classNameDot) + ".*init.*String\\)")),
214+
allConstructorsExcept(CONSTRUCTOR_ONE_ARG)),
214215
$(described(fields().that().haveFullNameNotMatching(quote(classNameDot) + ".*A.*")), allFieldsExcept(FIELD_A)),
215216

216217
$(described(members().that().arePublic()), ImmutableSet.of(

0 commit comments

Comments
 (0)