Repository: assertj/assertj (java)

Issue:
`InstanceOfAssertFactories.array` and `InstanceOfAssertFactories.array2D` expect array type parameter instead of the one for their elements
Currently, `InstanceOfAssertFactories.array` and `InstanceOfAssertFactories.array2D` must be used in the following way:

```java
Object array = new Integer[] { 0, 1 };
assertThat(array).asInstanceOf(array(Integer[].class)).containsExactly(0, 1);

Object array2D = new Integer[][] { { 0, 1 }, { 2, 3 } };
assertThat(array2D).asInstanceOf(array2D(Integer[][].class)).hasDimensions(2, 2);
```

where the array type is provided as a parameter.

However, factories like `collection` or `list` expect the element type instead:

```java
Object list = List.of("Homer", "Marge", "Bart", "Lisa", "Maggie");

assertThat(list).asInstanceOf(collection(String.class)).contains("Bart", "Lisa");
assertThat(list).asInstanceOf(list(String.class)).contains("Bart", "Lisa");
```

We should change the type parameter for `array` and `array2d` to be the element type.

Pull request:
Expect component type for `array` and `array2D` factories
Closes #3386.


Patch:
diff --git a/assertj-core/pom.xml b/assertj-core/pom.xml
index 4c2fef452..03839df6e 100644
--- a/assertj-core/pom.xml
+++ b/assertj-core/pom.xml
@@ -153,7 +153,7 @@
     <dependency>
       <groupId>org.hibernate.orm</groupId>
       <artifactId>hibernate-core</artifactId>
-      <version>6.6.10.Final</version>
+      <version>6.6.11.Final</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>
diff --git a/assertj-core/src/main/java/org/assertj/core/api/InstanceOfAssertFactories.java b/assertj-core/src/main/java/org/assertj/core/api/InstanceOfAssertFactories.java
index 648529681..ee11ae5dd 100644
--- a/assertj-core/src/main/java/org/assertj/core/api/InstanceOfAssertFactories.java
+++ b/assertj-core/src/main/java/org/assertj/core/api/InstanceOfAssertFactories.java
@@ -14,6 +14,7 @@ package org.assertj.core.api;
 
 import java.io.File;
 import java.io.InputStream;
+import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.URI;
@@ -434,18 +435,20 @@ public interface InstanceOfAssertFactories {
    *
    * @see #array(Class)
    */
-  InstanceOfAssertFactory<Object[], ObjectArrayAssert<Object>> ARRAY = array(Object[].class);
+  InstanceOfAssertFactory<Object[], ObjectArrayAssert<Object>> ARRAY = array(Object.class);
 
   /**
    * {@link InstanceOfAssertFactory} for an array of elements.
    *
-   * @param <ELEMENT> the element type.
-   * @param arrayType the element type instance.
+   * @param <COMPONENT> the component type.
+   * @param componentType the component type instance.
    * @return the factory instance.
    *
    * @see #ARRAY
    */
-  static <ELEMENT> InstanceOfAssertFactory<ELEMENT[], ObjectArrayAssert<ELEMENT>> array(Class<ELEMENT[]> arrayType) {
+  static <COMPONENT> InstanceOfAssertFactory<COMPONENT[], ObjectArrayAssert<COMPONENT>> array(Class<COMPONENT> componentType) {
+    @SuppressWarnings("unchecked")
+    Class<COMPONENT[]> arrayType = (Class<COMPONENT[]>) Array.newInstance(componentType, 0).getClass();
     return new InstanceOfAssertFactory<>(arrayType, Assertions::assertThat);
   }
 
@@ -454,18 +457,20 @@ public interface InstanceOfAssertFactories {
    *
    * @see #array(Class)
    */
-  InstanceOfAssertFactory<Object[][], Object2DArrayAssert<Object>> ARRAY_2D = array2D(Object[][].class);
+  InstanceOfAssertFactory<Object[][], Object2DArrayAssert<Object>> ARRAY_2D = array2D(Object.class);
 
   /**
    * {@link InstanceOfAssertFactory} for a two-dimensional array of elements.
    *
-   * @param <ELEMENT> the element type.
-   * @param arrayType the element type instance.
+   * @param <COMPONENT> the component type.
+   * @param componentType the component type instance.
    * @return the factory instance.
    *
    * @see #ARRAY
    */
-  static <ELEMENT> InstanceOfAssertFactory<ELEMENT[][], Object2DArrayAssert<ELEMENT>> array2D(Class<ELEMENT[][]> arrayType) {
+  static <COMPONENT> InstanceOfAssertFactory<COMPONENT[][], Object2DArrayAssert<COMPONENT>> array2D(Class<COMPONENT> componentType) {
+    @SuppressWarnings("unchecked")
+    Class<COMPONENT[][]> arrayType = (Class<COMPONENT[][]>) Array.newInstance(componentType, 0, 0).getClass();
     return new InstanceOfAssertFactory<>(arrayType, Assertions::assertThat);
   }
 
diff --git a/assertj-parent/pom.xml b/assertj-parent/pom.xml
index 9f5343aca..bb15d0bc1 100644
--- a/assertj-parent/pom.xml
+++ b/assertj-parent/pom.xml
@@ -36,7 +36,7 @@
     <maven-clean-plugin.version>3.3.2</maven-clean-plugin.version>
     <maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
     <maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
-    <maven-deploy-plugin.version>3.1.3</maven-deploy-plugin.version>
+    <maven-deploy-plugin.version>3.1.4</maven-deploy-plugin.version>
     <maven-install-plugin.version>3.1.4</maven-install-plugin.version>
     <maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
     <maven-javadoc-plugin.version>3.7.0</maven-javadoc-plugin.version>


Test patch:
diff --git a/assertj-core/src/test/java/org/assertj/core/api/InstanceOfAssertFactoriesTest.java b/assertj-core/src/test/java/org/assertj/core/api/InstanceOfAssertFactoriesTest.java
index 2b95889ae..95bb57e15 100644
--- a/assertj-core/src/test/java/org/assertj/core/api/InstanceOfAssertFactoriesTest.java
+++ b/assertj-core/src/test/java/org/assertj/core/api/InstanceOfAssertFactoriesTest.java
@@ -1849,7 +1849,7 @@ class InstanceOfAssertFactoriesTest {
     @Test
     void getRawClass() {
       // WHEN
-      Class<?> result = array(Integer[].class).getRawClass();
+      Class<?> result = array(Integer.class).getRawClass();
       // THEN
       then(result).isEqualTo(Integer[].class);
     }
@@ -1857,7 +1857,7 @@ class InstanceOfAssertFactoriesTest {
     @Test
     void createAssert() {
       // WHEN
-      ObjectArrayAssert<Integer> result = array(Integer[].class).createAssert(actual);
+      ObjectArrayAssert<Integer> result = array(Integer.class).createAssert(actual);
       // THEN
       result.containsExactly(0, 1);
     }
@@ -1868,7 +1868,7 @@ class InstanceOfAssertFactoriesTest {
       // GIVEN
       ValueProvider<?> valueProvider = mockThatDelegatesTo(delegate);
       // WHEN
-      ObjectArrayAssert<Integer> result = array(Integer[].class).createAssert(valueProvider);
+      ObjectArrayAssert<Integer> result = array(Integer.class).createAssert(valueProvider);
       // THEN
       result.containsExactly(0, 1);
       verify(valueProvider).apply(Integer[].class);
@@ -1923,7 +1923,7 @@ class InstanceOfAssertFactoriesTest {
     @Test
     void getRawClass() {
       // WHEN
-      Class<?> result = array2D(Integer[][].class).getRawClass();
+      Class<?> result = array2D(Integer.class).getRawClass();
       // THEN
       then(result).isEqualTo(Integer[][].class);
     }
@@ -1931,7 +1931,7 @@ class InstanceOfAssertFactoriesTest {
     @Test
     void createAssert() {
       // WHEN
-      Object2DArrayAssert<Integer> result = array2D(Integer[][].class).createAssert(actual);
+      Object2DArrayAssert<Integer> result = array2D(Integer.class).createAssert(actual);
       // THEN
       result.hasDimensions(2, 2);
     }
@@ -1941,12 +1941,11 @@ class InstanceOfAssertFactoriesTest {
       // GIVEN
       ValueProvider<?> valueProvider = mockThatDelegatesTo(type -> actual);
       // WHEN
-      Object2DArrayAssert<Integer> result = array2D(Integer[][].class).createAssert(valueProvider);
+      Object2DArrayAssert<Integer> result = array2D(Integer.class).createAssert(valueProvider);
       // THEN
       result.hasDimensions(2, 2);
       verify(valueProvider).apply(Integer[][].class);
     }
-
   }
 
   @Nested