From 9afec6f4794af897e0fc901eea034cabdf1767ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= Date: Sun, 7 Oct 2018 15:14:30 +0200 Subject: [PATCH] Add NamedParam support for gradle-2.5 with backport to 2.4 (#921) --- internal-backport/internal-backport.gradle | 1 + .../java/groovy/transform/NamedParam.java | 42 +++ .../java/groovy/transform/NamedParams.java | 37 +++ settings.gradle | 4 + spock-core/core.gradle | 3 + .../src/main/java/spock/mock/MockingApi.java | 240 ++++++++++++++++-- 6 files changed, 303 insertions(+), 24 deletions(-) create mode 100644 internal-backport/internal-backport.gradle create mode 100644 internal-backport/src/main/java/groovy/transform/NamedParam.java create mode 100644 internal-backport/src/main/java/groovy/transform/NamedParams.java diff --git a/internal-backport/internal-backport.gradle b/internal-backport/internal-backport.gradle new file mode 100644 index 0000000000..c227310eed --- /dev/null +++ b/internal-backport/internal-backport.gradle @@ -0,0 +1 @@ +// WARNING: This is Module is only present here so that we can build with 2.4 as well, the code will not be shipped. diff --git a/internal-backport/src/main/java/groovy/transform/NamedParam.java b/internal-backport/src/main/java/groovy/transform/NamedParam.java new file mode 100644 index 0000000000..2083e0b634 --- /dev/null +++ b/internal-backport/src/main/java/groovy/transform/NamedParam.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package groovy.transform; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * WARNING: This is only present here so that we can build with 2.4 as well, the code will not be shipped. + * + * Marker interface used to indicate that the name of the annotated parameter + * (or specified optional name) is a valid key name when using named arguments + * and that the parameter type is applicable for type checking purposes. + * + * @since 2.5.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface NamedParam { + String value() default Undefined.STRING; + Class type() default Object.class; + boolean required() default false; +} diff --git a/internal-backport/src/main/java/groovy/transform/NamedParams.java b/internal-backport/src/main/java/groovy/transform/NamedParams.java new file mode 100644 index 0000000000..cd2b0336e8 --- /dev/null +++ b/internal-backport/src/main/java/groovy/transform/NamedParams.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package groovy.transform; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * WARNING: This is only present here so that we can build with 2.4 as well, the code will not be shipped. + * + * Collector annotation for {@link NamedParam}. + * + * @since 2.5.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.PARAMETER) +public @interface NamedParams { + NamedParam[] value(); +} diff --git a/settings.gradle b/settings.gradle index 9f5e588c41..6b19f465ef 100755 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,10 @@ include "spock-spring:spring2-test" include "spock-spring:spring3-test" include "spock-guice" +if ((System.getProperty("variant") as BigDecimal ?: 2.4) == 2.4) { + include "internal-backport" +} + // https://issues.apache.org/jira/projects/TAP5/issues/TAP5-2588 if (JavaVersion.current().isJava7() || JavaVersion.current().isJava8()) { include "spock-tapestry" diff --git a/spock-core/core.gradle b/spock-core/core.gradle index 3034473c10..ac1fe8eba5 100755 --- a/spock-core/core.gradle +++ b/spock-core/core.gradle @@ -20,6 +20,9 @@ dependencies { compile libs.bytebuddy, optional compile libs.cglib, optional compile libs.objenesis, optional + if (variant == 2.4) { + compileOnly project(':internal-backport') + } coreConsoleRuntime groovyConsoleExtraDependency } diff --git a/spock-core/src/main/java/spock/mock/MockingApi.java b/spock-core/src/main/java/spock/mock/MockingApi.java index 8364f2a4a9..b9a36ea3e5 100644 --- a/spock-core/src/main/java/spock/mock/MockingApi.java +++ b/spock-core/src/main/java/spock/mock/MockingApi.java @@ -14,13 +14,15 @@ package spock.mock; -import java.util.Map; +import java.util.*; import groovy.lang.DelegatesTo; +import groovy.transform.*; import groovy.transform.stc.ClosureParams; import groovy.transform.stc.FirstParam; import groovy.transform.stc.SecondParam; import org.spockframework.lang.SpecInternals; +import org.spockframework.mock.*; import org.spockframework.runtime.GroovyRuntimeUtil; import org.spockframework.runtime.InvalidSpecException; import org.spockframework.util.Beta; @@ -163,7 +165,15 @@ public T Mock() { * enclosing variable assignment */ @Beta - public T Mock(Map options) { + public T Mock( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -207,7 +217,15 @@ public T Mock(Class type) { */ @Override @Beta - public T Mock(Map options, Class type) { + public T Mock( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -317,7 +335,14 @@ public T Mock( */ @Beta public T Mock( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0) @@ -360,7 +385,15 @@ public T Stub() { * enclosing variable assignment */ @Beta - public T Stub(Map options) { + public T Stub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -405,7 +438,15 @@ public T Stub(Class type) { */ @Override @Beta - public T Stub(Map options, Class type) { + public T Stub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -456,7 +497,15 @@ public T Stub(Closure interactions) { * from the left-hand side of the enclosing assignment */ @Beta - public T Stub(Map options, Closure interactions) { + public T Stub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, Closure interactions) { invalidMockCreation(); return null; } @@ -515,7 +564,14 @@ public T Stub( */ @Beta public T Stub( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0) @@ -558,7 +614,15 @@ public T Spy() { * enclosing variable assignment */ @Beta - public T Spy(Map options) { + public T Spy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -629,7 +693,15 @@ public T Spy(T obj) { */ @Override @Beta - public T Spy(Map options, Class type) { + public T Spy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -678,7 +750,15 @@ public T Spy(Closure interactions) { * from the left-hand side of the enclosing assignment */ @Beta - public T Spy(Map options, Closure interactions) { + public T Spy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, Closure interactions) { invalidMockCreation(); return null; } @@ -736,7 +816,14 @@ public T Spy( */ @Beta public T Spy( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0) @@ -779,7 +866,16 @@ public T GroovyMock() { * enclosing variable assignment */ @Beta - public T GroovyMock(Map options) { + public T GroovyMock( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -822,7 +918,16 @@ public T GroovyMock(Class type) { * @return a Groovy mock with the specified options and type */ @Beta - public T GroovyMock(Map options, Class type) { + public T GroovyMock( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -873,7 +978,16 @@ public T GroovyMock(Closure interactions) { * from the left-hand side of the enclosing assignment */ @Beta - public T GroovyMock(Map options, Closure interactions) { + public T GroovyMock( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Closure interactions) { invalidMockCreation(); return null; } @@ -932,7 +1046,15 @@ public T GroovyMock( */ @Beta public T GroovyMock( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0) @@ -975,7 +1097,16 @@ public T GroovyStub() { * enclosing variable assignment */ @Beta - public T GroovyStub(Map options) { + public T GroovyStub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -1018,7 +1149,16 @@ public T GroovyStub(Class type) { * @return a Groovy stub with the specified options and type */ @Beta - public T GroovyStub(Map options, Class type) { + public T GroovyStub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -1069,7 +1209,16 @@ public T GroovyStub(Closure interactions) { * from the left-hand side of the enclosing assignment */ @Beta - public T GroovyStub(Map options, Closure interactions) { + public T GroovyStub( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Closure interactions) { invalidMockCreation(); return null; } @@ -1128,7 +1277,15 @@ public T GroovyStub( */ @Beta public T GroovyStub( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0) @@ -1171,7 +1328,16 @@ public T GroovySpy() { * enclosing variable assignment */ @Beta - public T GroovySpy(Map options) { + public T GroovySpy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options) { invalidMockCreation(); return null; } @@ -1214,7 +1380,16 @@ public T GroovySpy(Class type) { * @return a Groovy spy with the specified options and type */ @Beta - public T GroovySpy(Map options, Class type) { + public T GroovySpy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Class type) { invalidMockCreation(); return null; } @@ -1263,7 +1438,16 @@ public T GroovySpy(Closure interactions) { * from the left-hand side of the enclosing assignment */ @Beta - public T GroovySpy(Map options, Closure interactions) { + public T GroovySpy( + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, Closure interactions) { invalidMockCreation(); return null; } @@ -1321,7 +1505,15 @@ public T GroovySpy( */ @Beta public T GroovySpy( - Map options, + @NamedParams({ + @NamedParam(value = "name", type = String.class), + @NamedParam(value = "additionalInterfaces", type = List.class), + @NamedParam(value = "defaultResponse", type = IDefaultResponse.class), + @NamedParam(value = "verified", type = Boolean.class), + @NamedParam(value = "useObjenesis", type = Boolean.class), + @NamedParam(value = "global", type = Boolean.class) + }) + Map options, @DelegatesTo.Target Class type, @DelegatesTo(strategy = Closure.DELEGATE_FIRST, genericTypeIndex = 0)