Skip to content

Commit 1873ff0

Browse files
authored
Add hasPackage Class assertion (#2019)
1 parent 9774849 commit 1873ff0

9 files changed

+485
-4
lines changed

src/main/java/org/assertj/core/api/AbstractClassAssert.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,64 @@ public SELF hasPublicMethods(String... methodNames) {
647647
classes.assertHasPublicMethods(info, actual, methodNames);
648648
return myself;
649649
}
650+
651+
/**
652+
* Verifies that the actual {@code Class} has the given package name (as in {@link Class#getPackage()}).
653+
*
654+
* <p>
655+
* Example:
656+
* <pre><code class='java'> package one.two;
657+
*
658+
* class MyClass {}
659+
*
660+
* // this assertions succeeds:
661+
* assertThat(MyClass.class).hasPackage("one.two");
662+
*
663+
* // these assertions fail:
664+
* assertThat(MyClass.class).hasPackage("one");
665+
* assertThat(MyClass.class).hasPackage("");
666+
* assertThat(MyClass.class).hasPackage("java.lang");</code></pre>
667+
*
668+
* @param packageName the package name the class should have
669+
* @return {@code this} assertions object
670+
* @throws AssertionError if {@code actual} is {@code null}.
671+
* @throws AssertionError if the actual {@code Class} does not have the given package.
672+
*
673+
* @since 3.18.0
674+
*/
675+
public SELF hasPackage(String packageName) {
676+
classes.assertHasPackage(info, actual, packageName);
677+
return myself;
678+
}
679+
680+
/**
681+
* Verifies that the actual {@code Class} has the given package (as in {@link Class#getPackage()}).
682+
*
683+
* <p>
684+
* Example:
685+
* <pre><code class='java'> package one.two;
686+
*
687+
* class MyClass {}
688+
**
689+
* // these assertions succeed:
690+
* assertThat(MyClass.class).hasPackage(Package.getPackage("one.two"));
691+
* assertThat(MyClass.class).hasPackage(MyClass.class.getPackage());
692+
*
693+
* // these assertions fail:
694+
* assertThat(MyClass.class).hasPackage(Package.getPackage("one"));
695+
* assertThat(MyClass.class).hasPackage(Package.getPackage(""));
696+
* assertThat(MyClass.class).hasPackage(Object.class.getPackage());</code></pre>
697+
*
698+
* @param aPackage the package the class should have
699+
* @return {@code this} assertions object
700+
* @throws AssertionError if {@code actual} is {@code null}.
701+
* @throws AssertionError if the actual {@code Class} does not have the given package.
702+
*
703+
* @since 3.18.0
704+
*/
705+
public SELF hasPackage(Package aPackage) {
706+
classes.assertHasPackage(info, actual, aPackage);
707+
return myself;
708+
}
709+
650710
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
package org.assertj.core.error;
14+
15+
import java.util.StringJoiner;
16+
17+
/**
18+
* Creates an error message indicating that a {@link Class} should have a given package.
19+
*
20+
* @author Matteo Mirk
21+
*/
22+
public class ShouldHavePackage extends BasicErrorMessageFactory {
23+
private static final String SHOULD_HAVE_PACKAGE = new StringJoiner("%n", "%n", "").add("Expecting")
24+
.add(" <%s>")
25+
.add("to have package:")
26+
.add(" <%s>")
27+
.toString();
28+
private static final String BUT_HAD_NONE = new StringJoiner("%n", "%n", "").add("but had none.")
29+
.toString();
30+
private static final String BUT_HAD = new StringJoiner("%n", "%n", "").add("but had:")
31+
.add(" <%s>")
32+
.toString();
33+
34+
/**
35+
* Creates a new <code>ShouldHavePackage</code> with a {@link Package} instance.
36+
*
37+
* @param actual the actual value in the failed assertion.
38+
* @param aPackage the expected package
39+
* @return the created {@code ErrorMessageFactory}.
40+
*/
41+
public static ErrorMessageFactory shouldHavePackage(Class<?> actual, Package aPackage) {
42+
return shouldHavePackage(actual, aPackage.getName());
43+
}
44+
45+
/**
46+
* Creates a new <code>ShouldHavePackage</code> with a package name.
47+
*
48+
* @param actual the actual value in the failed assertion.
49+
* @param packageName the expected package name
50+
* @return the created {@code ErrorMessageFactory}.
51+
*/
52+
public static ErrorMessageFactory shouldHavePackage(Class<?> actual, String packageName) {
53+
final Package actualPackage = actual.getPackage();
54+
return (actualPackage == null)
55+
? new ShouldHavePackage(actual, packageName)
56+
: new ShouldHavePackage(actual, packageName, actualPackage.getName());
57+
}
58+
59+
private ShouldHavePackage(Class<?> actual, String expectedPackage) {
60+
super(SHOULD_HAVE_PACKAGE + BUT_HAD_NONE, actual, expectedPackage);
61+
}
62+
63+
private ShouldHavePackage(Class<?> actual, String expectedPackage, String actualPackage) {
64+
super(SHOULD_HAVE_PACKAGE + BUT_HAD, actual, expectedPackage, actualPackage);
65+
}
66+
67+
}

src/main/java/org/assertj/core/error/ShouldHaveSuperclass.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,9 @@ public class ShouldHaveSuperclass extends BasicErrorMessageFactory {
4343
*/
4444
public static ErrorMessageFactory shouldHaveSuperclass(Class<?> actual, Class<?> superclass) {
4545
Class<?> actualSuperclass = actual.getSuperclass();
46-
if (actualSuperclass == null) {
47-
return new ShouldHaveSuperclass(actual, superclass);
48-
}
49-
return new ShouldHaveSuperclass(actual, superclass, actualSuperclass);
46+
return (actualSuperclass == null)
47+
? new ShouldHaveSuperclass(actual, superclass)
48+
: new ShouldHaveSuperclass(actual, superclass, actualSuperclass);
5049
}
5150

5251
private ShouldHaveSuperclass(Class<?> actual, Class<?> expectedSuperclass) {

src/main/java/org/assertj/core/internal/Classes.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import static org.assertj.core.error.ShouldHaveNoFields.shouldHaveNoDeclaredFields;
3434
import static org.assertj.core.error.ShouldHaveNoFields.shouldHaveNoPublicFields;
3535
import static org.assertj.core.error.ShouldHaveNoSuperclass.shouldHaveNoSuperclass;
36+
import static org.assertj.core.error.ShouldHavePackage.shouldHavePackage;
3637
import static org.assertj.core.error.ShouldHaveSuperclass.shouldHaveSuperclass;
3738
import static org.assertj.core.error.ShouldNotBeNull.shouldNotBeNull;
3839
import static org.assertj.core.error.ShouldOnlyHaveFields.shouldOnlyHaveDeclaredFields;
@@ -581,4 +582,45 @@ private static void assertNotNull(AssertionInfo info, Class<?> actual) {
581582
private static void classParameterIsNotNull(Class<?> clazz) {
582583
requireNonNull(clazz, "The class to compare actual with should not be null");
583584
}
585+
586+
/**
587+
* Verifies that the actual {@code Class} has the given {@code packageName}.
588+
*
589+
* @param info contains information about the assertion.
590+
* @param actual the "actual" {@code Class}.
591+
* @param packageName the package that must be declared in the class.
592+
* @throws NullPointerException if {@code packageName} is {@code null}.
593+
* @throws AssertionError if {@code actual} is {@code null}.
594+
* @throws AssertionError if {@code actual} does not have the given package name.
595+
*/
596+
public void assertHasPackage(AssertionInfo info, Class<?> actual, String packageName) {
597+
assertNotNull(info, actual);
598+
requireNonNull(packageName, shouldNotBeNull("packageName").create());
599+
Package actualPackage = actual.getPackage();
600+
601+
if (actualPackage == null || !actualPackage.getName().equals(packageName)) {
602+
throw failures.failure(info, shouldHavePackage(actual, packageName));
603+
}
604+
}
605+
606+
/**
607+
* Verifies that the actual {@code Class} has the given {@code Package}.
608+
*
609+
* @param info contains information about the assertion.
610+
* @param actual the "actual" {@code Class}.
611+
* @param aPackage the package that must be declared in the class.
612+
* @throws NullPointerException if {@code aPackage} is {@code null}.
613+
* @throws AssertionError if {@code actual} is {@code null}.
614+
* @throws AssertionError if {@code actual} does not have the given package.
615+
*/
616+
public void assertHasPackage(AssertionInfo info, Class<?> actual, Package aPackage) {
617+
assertNotNull(info, actual);
618+
requireNonNull(aPackage, shouldNotBeNull("aPackage").create());
619+
Package actualPackage = actual.getPackage();
620+
621+
if (!aPackage.equals(actualPackage)) {
622+
throw failures.failure(info, shouldHavePackage(actual, aPackage));
623+
}
624+
}
625+
584626
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
package org.assertj.core.api.classes;
14+
15+
import static org.mockito.Mockito.mock;
16+
import static org.mockito.Mockito.verify;
17+
18+
import org.assertj.core.api.ClassAssert;
19+
import org.assertj.core.api.ClassAssertBaseTest;
20+
import org.junit.jupiter.api.DisplayName;
21+
22+
/**
23+
* Tests for <code>{@link ClassAssert#hasPackage(Package)}</code>.
24+
*
25+
* @author Matteo Mirk
26+
*/
27+
@DisplayName("ClassAssert hasPackage(Package)")
28+
class ClassAssert_hasPackage_with_Package_Test extends ClassAssertBaseTest {
29+
30+
private static final Package PACKAGE = mock(Package.class);
31+
32+
@Override
33+
protected ClassAssert invoke_api_method() {
34+
return assertions.hasPackage(PACKAGE);
35+
}
36+
37+
@Override
38+
protected void verify_internal_effects() {
39+
verify(classes).assertHasPackage(getInfo(assertions), getActual(assertions), PACKAGE);
40+
}
41+
42+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
package org.assertj.core.api.classes;
14+
15+
import static org.mockito.Mockito.verify;
16+
17+
import org.assertj.core.api.ClassAssert;
18+
import org.assertj.core.api.ClassAssertBaseTest;
19+
import org.junit.jupiter.api.DisplayName;
20+
21+
/**
22+
* Tests for <code>{@link ClassAssert#hasPackage(String)}</code>.
23+
*
24+
* @author Matteo Mirk
25+
*/
26+
@DisplayName("ClassAssert hasPackage(String)")
27+
class ClassAssert_hasPackage_with_String_Test extends ClassAssertBaseTest {
28+
29+
private static final String PACKAGE = "org.assertj.core.api";
30+
31+
@Override
32+
protected ClassAssert invoke_api_method() {
33+
return assertions.hasPackage(PACKAGE);
34+
}
35+
36+
@Override
37+
protected void verify_internal_effects() {
38+
verify(classes).assertHasPackage(getInfo(assertions), getActual(assertions), PACKAGE);
39+
}
40+
41+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
3+
* the License. You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9+
* specific language governing permissions and limitations under the License.
10+
*
11+
* Copyright 2012-2020 the original author or authors.
12+
*/
13+
package org.assertj.core.error;
14+
15+
import static java.lang.String.format;
16+
import static org.assertj.core.api.BDDAssertions.then;
17+
import static org.assertj.core.error.ShouldHavePackage.shouldHavePackage;
18+
import static org.assertj.core.presentation.StandardRepresentation.STANDARD_REPRESENTATION;
19+
20+
import java.util.Collection;
21+
22+
import org.assertj.core.description.Description;
23+
import org.assertj.core.internal.TestDescription;
24+
import org.assertj.core.presentation.Representation;
25+
import org.junit.jupiter.api.DisplayName;
26+
import org.junit.jupiter.api.Test;
27+
28+
/**
29+
* Tests for <code>{@link ShouldHavePackage#create(Description, Representation)}</code>.
30+
*
31+
* @author Stefano Cordio
32+
*/
33+
@DisplayName("ShouldHavePackage create")
34+
class ShouldHavePackage_create_Test {
35+
36+
@Test
37+
void should_create_error_message_with_String_if_actual_has_package() {
38+
// WHEN
39+
String message = shouldHavePackage(Object.class, "java.util").create(new TestDescription("TEST"),
40+
STANDARD_REPRESENTATION);
41+
// THEN
42+
then(message).isEqualTo(format("[TEST] %n" +
43+
"Expecting%n" +
44+
" <java.lang.Object>%n" +
45+
"to have package:%n" +
46+
" <\"java.util\">%n" +
47+
"but had:%n" +
48+
" <\"java.lang\">"));
49+
}
50+
51+
@Test
52+
void should_create_error_message_with_String_if_actual_has_no_package() {
53+
// WHEN
54+
String message = shouldHavePackage(Object[].class, "java.util").create(new TestDescription("TEST"),
55+
STANDARD_REPRESENTATION);
56+
// THEN
57+
then(message).isEqualTo(format("[TEST] %n" +
58+
"Expecting%n" +
59+
" <java.lang.Object[]>%n" +
60+
"to have package:%n" +
61+
" <\"java.util\">%n" +
62+
"but had none."));
63+
}
64+
65+
@Test
66+
void should_create_error_message_with_Package_if_actual_has_package() {
67+
// WHEN
68+
String message = shouldHavePackage(Object.class, Collection.class.getPackage()).create(new TestDescription("TEST"),
69+
STANDARD_REPRESENTATION);
70+
// THEN
71+
then(message).isEqualTo(format("[TEST] %n" +
72+
"Expecting%n" +
73+
" <java.lang.Object>%n" +
74+
"to have package:%n" +
75+
" <\"java.util\">%n" +
76+
"but had:%n" +
77+
" <\"java.lang\">"));
78+
}
79+
80+
@Test
81+
void should_create_error_message_with_Package_if_actual_has_no_package() {
82+
// WHEN
83+
String message = shouldHavePackage(Object[].class, Collection.class.getPackage()).create(new TestDescription("TEST"),
84+
STANDARD_REPRESENTATION);
85+
// THEN
86+
then(message).isEqualTo(format("[TEST] %n" +
87+
"Expecting%n" +
88+
" <java.lang.Object[]>%n" +
89+
"to have package:%n" +
90+
" <\"java.util\">%n" +
91+
"but had none."));
92+
}
93+
94+
}

0 commit comments

Comments
 (0)