[ 
https://issues.apache.org/jira/browse/GROOVY-11258?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17801208#comment-17801208
 ] 

Eric Milles commented on GROOVY-11258:
--------------------------------------

There are two other workarounds available besides cast/coerce:
 # ...
 # You can use a type-checking extension to resolve which method to use for 
{{{}map{}}}. This can be applied at the call site or more widely using some 
ideas below.
{code:groovy}
@Grab('org.assertj:assertj-core:3.24.2')
import static org.assertj.core.api.Assertions.assertThat

class Pojo { String x }
Collection<Pojo> getPojos() {
  [new Pojo(x: 'a'), new Pojo(x: 'b')]
}
@groovy.transform.CompileStatic(extensions='Groovy11258.groovy')
void test() {
  assertThat(pojos).map { it.x }
    .containsExactlyInAnyOrderElementsOf(['a', 'b'])
}

test()
{code}
{code:groovy}
// Groovy11258.groovy
ambiguousMethods { methods, call ->
  if (call instanceof MethodCallExpression
      && call.methodAsString == 'map') {
    return methods.find { method ->
      def firstParam = method.parameters[0]
      firstParam.type.nameWithoutPackage == 'ThrowingExtractor'
    }
  }
}
{code}
And you could make it easy to apply using {{{}AnnotationCollector{}}}.
{code:groovy}
@org.junit.jupiter.api.Test
@groovy.transform.CompileStatic(extensions='Groovy11258.groovy')
@groovy.transform.AnnotationCollector(mode=groovy.transform.AnnotationCollectorMode.PREFER_COLLECTOR_MERGED)
@interface MyTest {
}
{code}
Then you could designate a test method like:
{code:groovy}
class AssertJCollectionMappingTest {
  @MyTest // JUnit 5 test and CompileStatic w/ extension
  void mapping() {
    //...
  }
}
{code}
Including the {{@Test}} annotation is just an idea to demonstrate the concept. 
You could do this at the test class level or by AST transform or by compiler 
configuration.

> AssertJ collection mapping is badly supported
> ---------------------------------------------
>
>                 Key: GROOVY-11258
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11258
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static Type Checker
>    Affects Versions: 4.0.17
>            Reporter: Jan Hackel
>            Assignee: Eric Milles
>            Priority: Major
>
> The following code will fail with the message 
> {noformat}
> [Static type checking] - No such property: x for class: java.lang.Object
>  @ line 8, column 13.
>          .map{ it.x }
>                ^
> {noformat}
> {code:groovy}
> @groovy.transform.CompileStatic
> class AssertJCollectionMappingTest {
>   @org.junit.jupiter.api.Test
>   void mapping() {
>     def texts = somePojos()
>     org.assertj.core.api.Assertions.assertThat(texts)
>       .map{ it.x }
>       .containsExactlyInAnyOrderElementsOf(['a', 'b'])
>   }
>   private static Collection<Pojo> somePojos() {
>     return [new Pojo(x: 'a'), new Pojo(x: 'b')]
>   }
>   static class Pojo {
>     String x
>   }
> }
> {code}
> Changing the line  to  
> {noformat}
> .map({ it.x } as Function<Pojo, String>) 
> {noformat}
> makes it compile but it is clumsy for more complicated types.
> It would be nice if Groovy was able to resolve the types without hints.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to