Skip to content

Commit 95765bc

Browse files
authored
TypeArgumentConstraint handles primitive types constraints (#1975)
Now the TypeArgumentConstraint also is satisfied when a type is a primitive type and the passed arg is a wrapper instance of that primitive type. Fixes #1974
1 parent 25498ef commit 95765bc

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

docs/release_notes.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ include::include.adoc[]
1010
* Add support for combining two or more data providers using cartesian product spockIssue:1062[]
1111
* Add support for a `filter` block after a `where` block to filter out unwanted iterations
1212

13+
=== Misc
14+
15+
* Types constraints or arguments in interactions can now handle primitive types like `_ as int` spockIssue:1974[]
16+
1317
== 2.4-M4 (2024-03-21)
1418

1519
* Fix nested regex finding in conditions spockPull:1931[]

spock-core/src/main/java/org/spockframework/mock/constraint/TypeArgumentConstraint.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.spockframework.mock.IArgumentConstraint;
2020
import org.spockframework.runtime.Condition;
2121
import org.spockframework.util.CollectionUtil;
22+
import org.spockframework.util.ReflectionUtil;
2223

2324
/**
2425
*
@@ -35,15 +36,23 @@ public TypeArgumentConstraint(Class<?> type, IArgumentConstraint constraint) {
3536

3637
@Override
3738
public boolean isSatisfiedBy(Object argument) {
38-
return type.isInstance(argument) && constraint.isSatisfiedBy(argument);
39+
return isInstance(argument) && constraint.isSatisfiedBy(argument);
40+
}
41+
42+
private boolean isInstance(Object argument) {
43+
if (type.isInstance(argument))
44+
return true;
45+
if (type.isPrimitive())
46+
return ReflectionUtil.getWrapperType(type).isInstance(argument);
47+
return false;
3948
}
4049

4150
@Override
4251
public String describeMismatch(Object argument) {
43-
if (type.isInstance(argument)) {
52+
if (isInstance(argument)) {
4453
return constraint.describeMismatch(argument);
4554
}
46-
Condition condition = new Condition(CollectionUtil.listOf( argument, type, false),
55+
Condition condition = new Condition(CollectionUtil.listOf(argument, type, false),
4756
String.format("argument instanceof %s", type.getName()), null, null,
4857
null, null);
4958
return condition.getRendering();

spock-core/src/main/java/org/spockframework/util/ReflectionUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public static boolean isAssignable(Class<?> type, @Nullable Object arg) {
256256
}
257257

258258
@SuppressWarnings("ConstantConditions")
259-
private static Class<?> getWrapperType(Class<?> type) {
259+
public static Class<?> getWrapperType(Class<?> type) {
260260
return type.isPrimitive() ? getDefaultValue(type).getClass()
261261
: type;
262262
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.spockframework.mock.response
17+
18+
import spock.lang.Issue
19+
import spock.lang.Specification
20+
21+
class MockPrimitiveTypeResponsesSpec extends Specification {
22+
private static final String SUCCESS = "success"
23+
24+
@Issue("https://github.com/spockframework/spock/issues/1974")
25+
def "Mock Response TypeArgumentConstraint with primitive type Issue #1974"() {
26+
given:
27+
ObjClass client = Mock()
28+
29+
when: "invoke with int"
30+
def response = client.test(123, 456)
31+
then: "validate with int TypeArgumentConstraint (as int)"
32+
1 * client.test(_ as int, _ as int) >> SUCCESS
33+
response == SUCCESS
34+
}
35+
36+
@Issue("https://github.com/spockframework/spock/issues/1974")
37+
def "Mock Response TypeArgumentConstraint with different primitive types Issue #1974"() {
38+
given:
39+
ObjClass client = Mock()
40+
41+
when: "invoke with other instance"
42+
def response = client.test(123d, false)
43+
then: "validate with int TypeArgumentConstraint (as int)"
44+
0 * client.test(_ as int, _ as int)
45+
response == null
46+
}
47+
48+
static class ObjClass {
49+
@SuppressWarnings('GrMethodMayBeStatic')
50+
String test(int a, int b) {
51+
return a + b
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)