Skip to content

Commit 43487e6

Browse files
WojciechZankowskijoel-costigliola
authored andcommitted
Add Static class assertions
Fix assertj#2455
1 parent 0700850 commit 43487e6

File tree

7 files changed

+295
-0
lines changed

7 files changed

+295
-0
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,54 @@ public SELF isPackagePrivate() {
289289
return myself;
290290
}
291291

292+
/**
293+
* Verifies that the actual {@code Class} is static (has {@code static} modifier).
294+
* <p>
295+
* Example:
296+
* <pre><code class='java'> class OuterClass {
297+
* static class StaticNestedClass { }
298+
* }
299+
* // this assertion succeeds:
300+
* assertThat(OuterClass.StaticNestedClass.class).isStatic();
301+
*
302+
* // these assertions fail:
303+
* assertThat(Object.class).isStatic();
304+
* assertThat(Throwable.class).isStatic();</code></pre>
305+
*
306+
* @return {@code this} assertions object
307+
* @throws AssertionError if {@code actual} is {@code null}.
308+
* @throws AssertionError if the actual {@code Class} is not static.
309+
* @since 3.23.0
310+
*/
311+
public SELF isStatic() {
312+
classes.assertIsStatic(info, actual);
313+
return myself;
314+
}
315+
316+
/**
317+
* Verifies that the actual {@code Class} is not static (does not have {@code static} modifier).
318+
* <p>
319+
* Example:
320+
* <pre><code class='java'> // these assertions succeed:
321+
* assertThat(Object.class).isNotStatic();
322+
* assertThat(Throwable.class).isNotStatic();
323+
*
324+
* class OuterClass {
325+
* static class StaticNestedClass { }
326+
* }
327+
* // this assertion fails:
328+
* assertThat(OuterClass.StaticNestedClass.class).isNotStatic();</code></pre>
329+
*
330+
* @return {@code this} assertions object
331+
* @throws AssertionError if {@code actual} is {@code null}.
332+
* @throws AssertionError if the actual {@code Class} is static.
333+
* @since 3.23.0
334+
*/
335+
public SELF isNotStatic() {
336+
classes.assertIsNotStatic(info, actual);
337+
return myself;
338+
}
339+
292340
/**
293341
* Verifies that the actual {@code Class} has the given {@code Annotation}s.
294342
* <p>

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,26 @@ public static ErrorMessageFactory shouldBePackagePrivate(Class<?> actual) {
8383
return new ClassModifierShouldBe(actual, true, PACKAGE_PRIVATE);
8484
}
8585

86+
/**
87+
* Creates a new instance for a positive check of the {@code static} modifier.
88+
*
89+
* @param actual the actual value in the failed assertion.
90+
* @return the created {@code ErrorMessageFactory}.
91+
*/
92+
public static ErrorMessageFactory shouldBeStatic(Class<?> actual) {
93+
return new ClassModifierShouldBe(actual, true, Modifier.toString(Modifier.STATIC));
94+
}
95+
96+
/**
97+
* Creates a new instance for a negative check of the {@code static} modifier.
98+
*
99+
* @param actual the actual value in the failed assertion.
100+
* @return the created {@code ErrorMessageFactory}.
101+
*/
102+
public static ErrorMessageFactory shouldNotBeStatic(Class<?> actual) {
103+
return new ClassModifierShouldBe(actual, false, Modifier.toString(Modifier.STATIC));
104+
}
105+
86106
private static String modifiers(Class<?> actual) {
87107
int modifiers = actual.getModifiers();
88108
boolean isPackagePrivate = !isPublic(modifiers) && !isProtected(modifiers) && !isPrivate(modifiers);

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
import static org.assertj.core.error.ClassModifierShouldBe.shouldBePackagePrivate;
1919
import static org.assertj.core.error.ClassModifierShouldBe.shouldBeProtected;
2020
import static org.assertj.core.error.ClassModifierShouldBe.shouldBePublic;
21+
import static org.assertj.core.error.ClassModifierShouldBe.shouldBeStatic;
2122
import static org.assertj.core.error.ClassModifierShouldBe.shouldNotBeFinal;
23+
import static org.assertj.core.error.ClassModifierShouldBe.shouldNotBeStatic;
2224
import static org.assertj.core.error.ShouldBeAbstract.shouldBeAbstract;
2325
import static org.assertj.core.error.ShouldBeAnnotation.shouldBeAnnotation;
2426
import static org.assertj.core.error.ShouldBeAnnotation.shouldNotBeAnnotation;
@@ -240,6 +242,36 @@ public void assertIsNotFinal(AssertionInfo info, Class<?> actual) {
240242
if (Modifier.isFinal(actual.getModifiers())) throw failures.failure(info, shouldNotBeFinal(actual));
241243
}
242244

245+
/**
246+
* Verifies that the actual {@code Class} is static.
247+
*
248+
* @param info contains information about the assertion.
249+
* @param actual the "actual" {@code Class}.
250+
* @throws AssertionError if {@code actual} is {@code null}.
251+
* @throws AssertionError if the actual {@code Class} is not static.
252+
*/
253+
public void assertIsStatic(AssertionInfo info, Class<?> actual) {
254+
assertNotNull(info, actual);
255+
if (!Modifier.isStatic(actual.getModifiers())) {
256+
throw failures.failure(info, shouldBeStatic(actual));
257+
}
258+
}
259+
260+
/**
261+
* Verifies that the actual {@code Class} is not static.
262+
*
263+
* @param info contains information about the assertion.
264+
* @param actual the "actual" {@code Class}.
265+
* @throws AssertionError if {@code actual} is {@code null}.
266+
* @throws AssertionError if the actual {@code Class} is static.
267+
*/
268+
public void assertIsNotStatic(AssertionInfo info, Class<?> actual) {
269+
assertNotNull(info, actual);
270+
if (Modifier.isStatic(actual.getModifiers())) {
271+
throw failures.failure(info, shouldNotBeStatic(actual));
272+
}
273+
}
274+
243275
/**
244276
* Verifies that the actual {@code Class} contains the given {@code Annotation}s.
245277
*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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-2022 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+
20+
class ClassAssert_isNotStatic_Test extends ClassAssertBaseTest {
21+
22+
@Override
23+
protected ClassAssert invoke_api_method() {
24+
return assertions.isNotStatic();
25+
}
26+
27+
@Override
28+
protected void verify_internal_effects() {
29+
verify(classes).assertIsNotStatic(getInfo(assertions), getActual(assertions));
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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-2022 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+
20+
class ClassAssert_isStatic_Test extends ClassAssertBaseTest {
21+
22+
@Override
23+
protected ClassAssert invoke_api_method() {
24+
return assertions.isStatic();
25+
}
26+
27+
@Override
28+
protected void verify_internal_effects() {
29+
verify(classes).assertIsStatic(getInfo(assertions), getActual(assertions));
30+
}
31+
32+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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-2022 the original author or authors.
12+
*/
13+
package org.assertj.core.internal.classes;
14+
15+
import static org.assertj.core.api.BDDAssertions.then;
16+
import static org.assertj.core.error.ClassModifierShouldBe.shouldNotBeStatic;
17+
import static org.assertj.core.test.TestData.someInfo;
18+
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
19+
import static org.assertj.core.util.FailureMessages.actualIsNull;
20+
21+
import org.assertj.core.internal.ClassesBaseTest;
22+
import org.junit.jupiter.api.Test;
23+
24+
class Classes_assertIsNotStatic_Test extends ClassesBaseTest {
25+
26+
@Test
27+
void should_fail_if_actual_is_null() {
28+
// GIVEN
29+
Class<?> actual = null;
30+
// WHEN
31+
AssertionError assertionError = expectAssertionError(() -> classes.assertIsNotStatic(someInfo(), actual));
32+
// THEN
33+
then(assertionError).hasMessage(actualIsNull());
34+
}
35+
36+
@Test
37+
void should_pass_if_actual_is_not_a_static_class() {
38+
// GIVEN
39+
Class<?> actual = Math.class;
40+
// WHEN/THEN
41+
classes.assertIsNotStatic(someInfo(), actual);
42+
}
43+
44+
@Test
45+
void should_fail_if_actual_is_an_interface() {
46+
// GIVEN
47+
Class<?> actual = Classes_assertIsStatic_Test.NestedInterface.class;
48+
// WHEN
49+
AssertionError assertionError = expectAssertionError(() -> classes.assertIsNotStatic(someInfo(), actual));
50+
// THEN
51+
then(assertionError).hasMessage(shouldNotBeStatic(actual).create());
52+
}
53+
54+
@Test
55+
void should_fail_if_actual_is_not_a_static_class() {
56+
// GIVEN
57+
Class<?> actual = Classes_assertIsStatic_Test.StaticNestedClass.class;
58+
// WHEN
59+
AssertionError assertionError = expectAssertionError(() -> classes.assertIsNotStatic(someInfo(), actual));
60+
// THEN
61+
then(assertionError).hasMessage(shouldNotBeStatic(actual).create());
62+
}
63+
64+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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-2022 the original author or authors.
12+
*/
13+
package org.assertj.core.internal.classes;
14+
15+
import static org.assertj.core.api.BDDAssertions.then;
16+
import static org.assertj.core.error.ClassModifierShouldBe.shouldBeStatic;
17+
import static org.assertj.core.test.TestData.someInfo;
18+
import static org.assertj.core.util.AssertionsUtil.expectAssertionError;
19+
import static org.assertj.core.util.FailureMessages.actualIsNull;
20+
21+
import org.assertj.core.internal.ClassesBaseTest;
22+
import org.junit.jupiter.api.Test;
23+
24+
class Classes_assertIsStatic_Test extends ClassesBaseTest {
25+
26+
@Test
27+
void should_fail_if_actual_is_null() {
28+
// GIVEN
29+
Class<?> actual = null;
30+
// WHEN
31+
AssertionError assertionError = expectAssertionError(() -> classes.assertIsStatic(someInfo(), actual));
32+
// THEN
33+
then(assertionError).hasMessage(actualIsNull());
34+
}
35+
36+
@Test
37+
void should_pass_if_actual_is_a_static_class() {
38+
// GIVEN
39+
Class<?> actual = StaticNestedClass.class;
40+
// WHEN/THEN
41+
classes.assertIsStatic(someInfo(), actual);
42+
}
43+
44+
@Test
45+
void should_pass_if_actual_is_an_interface() {
46+
// GIVEN
47+
Class<?> actual = NestedInterface.class;
48+
// WHEN/THEN
49+
classes.assertIsStatic(someInfo(), actual);
50+
}
51+
52+
@Test
53+
void should_fail_if_actual_is_not_a_static_class() {
54+
// GIVEN
55+
Class<?> actual = Math.class;
56+
// WHEN
57+
AssertionError assertionError = expectAssertionError(() -> classes.assertIsStatic(someInfo(), actual));
58+
// THEN
59+
then(assertionError).hasMessage(shouldBeStatic(actual).create());
60+
}
61+
62+
static class StaticNestedClass {
63+
}
64+
65+
interface NestedInterface {
66+
}
67+
68+
}

0 commit comments

Comments
 (0)