Repository: assertj/assertj

Problem statement:
Trailing space in the modifiers list for ClassModifierShouldBe
#### Summary
When a class is only `package-private` and a `ClassModifierShouldBe` message is created, the list of modifiers in the failure message contains a trailing space right after the `package-private` value.

#### Example

Given:

```java
class PackagePrivate {
}
```

`assertThat(PackagePrivate.class).isPublic()` yields:

```
java.lang.AssertionError: 
Expecting:
  <org.example.PackagePrivate>
to be a "public" class but was "package-private ".
```


Hints:

Patch:
diff --git a/src/main/java/org/assertj/core/error/ClassModifierShouldBe.java b/src/main/java/org/assertj/core/error/ClassModifierShouldBe.java
--- a/src/main/java/org/assertj/core/error/ClassModifierShouldBe.java
+++ b/src/main/java/org/assertj/core/error/ClassModifierShouldBe.java
@@ -12,12 +12,13 @@
  */
 package org.assertj.core.error;
 
-import static java.lang.String.format;
 import static java.lang.reflect.Modifier.isPrivate;
 import static java.lang.reflect.Modifier.isProtected;
 import static java.lang.reflect.Modifier.isPublic;
+import static org.assertj.core.util.Strings.isNullOrEmpty;
 
 import java.lang.reflect.Modifier;
+import java.util.StringJoiner;
 
 /**
  * Error message factory for an assertion which checks that a class has (or has not) a specific modifier.
@@ -87,7 +88,16 @@ private static String modifiers(Class<?> actual) {
     int modifiers = actual.getModifiers();
     boolean isPackagePrivate = !isPublic(modifiers) && !isProtected(modifiers) && !isPrivate(modifiers);
     String modifiersDescription = Modifier.toString(modifiers);
-    return isPackagePrivate ? format("%s %s", PACKAGE_PRIVATE, modifiersDescription) : modifiersDescription;
+    StringJoiner sj = new StringJoiner(" ");
+
+    if (isPackagePrivate) {
+      sj.add(PACKAGE_PRIVATE);
+    }
+    if (!modifiersDescription.isEmpty()) {
+      sj.add(modifiersDescription);
+    }
+
+    return sj.toString();
   }
 
 }


Test patch:
diff --git a/src/test/java/org/assertj/core/error/ClassModifierShouldBe_create_Test.java b/src/test/java/org/assertj/core/error/ClassModifierShouldBe_create_Test.java
--- a/src/test/java/org/assertj/core/error/ClassModifierShouldBe_create_Test.java
+++ b/src/test/java/org/assertj/core/error/ClassModifierShouldBe_create_Test.java
@@ -28,7 +28,7 @@ class ClassModifierShouldBe_create_Test {
   @Test
   void should_create_error_message_for_is_final() {
     // GIVEN
-    Class<Object> nonFinalClass = Object.class;
+    Class<?> nonFinalClass = Object.class;
     // WHEN
     String error = shouldBeFinal(nonFinalClass).create(new TestDescription("TEST"));
     // THEN
@@ -41,7 +41,7 @@ void should_create_error_message_for_is_final() {
   @Test
   void should_create_error_message_for_is_not_final() {
     // GIVEN
-    Class<String> finalClass = String.class;
+    Class<?> finalClass = String.class;
     // WHEN
     String error = shouldNotBeFinal(finalClass).create(new TestDescription("TEST"));
     // THEN
@@ -52,20 +52,35 @@ void should_create_error_message_for_is_not_final() {
   }
 
   @Test
-  void should_create_clear_error_message_when_actual_is_package_private() {
+  void should_create_clear_error_message_when_actual_is_package_private_enum() {
     // GIVEN
-    Class<PackagePrivate> packagePrivateClass = PackagePrivate.class;
+    Class<?> packagePrivateEnum = PackagePrivateEnum.class;
     // WHEN
-    String error = shouldBePublic(packagePrivateClass).create(new TestDescription("TEST"));
+    String error = shouldBePublic(packagePrivateEnum).create(new TestDescription("TEST"));
     // THEN
     then(error).isEqualTo(format("[TEST] %n" +
                                  "Expecting:%n" +
-                                 "  <org.assertj.core.error.ClassModifierShouldBe_create_Test.PackagePrivate>%n" +
+                                 "  <org.assertj.core.error.ClassModifierShouldBe_create_Test.PackagePrivateEnum>%n" +
                                  "to be a \"public\" class but was \"package-private static final\"."));
   }
 
-  enum PackagePrivate {
-    MONITOR
+  @Test
+  void should_create_clear_error_message_when_actual_is_only_package_private() {
+    // GIVEN
+    Class<?> packagePrivateClass = PackagePrivateClass.class;
+    // WHEN
+    String error = shouldBePublic(packagePrivateClass).create(new TestDescription("TEST"));
+    // THEN
+    then(error).isEqualTo(format("[TEST] %n" +
+                                 "Expecting:%n" +
+                                 "  <org.assertj.core.error.ClassModifierShouldBe_create_Test.PackagePrivateClass>%n" +
+                                 "to be a \"public\" class but was \"package-private\"."));
+  }
+
+  enum PackagePrivateEnum {
+  }
+
+  class PackagePrivateClass {
   }
 
 }