Skip to content

Commit

Permalink
Better test for receivers.
Browse files Browse the repository at this point in the history
  • Loading branch information
gchallen committed Jun 29, 2021
1 parent 8535dac commit ce2a8f1
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 8 deletions.
17 changes: 15 additions & 2 deletions src/main/kotlin/Annotations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fun Method.isRandomType() = isAnnotationPresent(RandomType::class.java)
annotation class FixedParameters(val methodName: String = "") {
companion object {
val name: String = FixedParameters::class.java.simpleName
fun validate(field: Field): Array<Type> {
fun validate(field: Field, solution: Class<*>): Array<Type> {
check(field.isPrivate()) { "@$name fields must be private" }
check(field.isStatic()) { "@$name fields must be static" }
check(field.genericType is ParameterizedType) {
Expand All @@ -102,6 +102,12 @@ annotation class FixedParameters(val methodName: String = "") {
itemType.actualTypeArguments
} else {
arrayOf(itemType)
}.also { types ->
check(solution !in types) {
"""@$name parameter fields cannot container receiver types.
|Generate receivers by targeting the constructor or factory method with @$name"""
.trimMargin()
}
}
}
}
Expand All @@ -118,7 +124,7 @@ fun Field.fixedParametersMatchAll() = this.getAnnotation(FixedParameters::class.
annotation class RandomParameters(val methodName: String = "") {
companion object {
val name: String = RandomParameters::class.java.simpleName
fun validate(method: Method): Array<Type> {
fun validate(method: Method, solution: Class<*>): Array<Type> {
check(method.isPrivate()) { "@$name methods must be private" }
val message = "@$name methods must either accept parameters (java.util.Random random) " +
"or (int complexity, java.util.Random random)"
Expand All @@ -139,6 +145,13 @@ annotation class RandomParameters(val methodName: String = "") {
(method.genericReturnType as ParameterizedType).actualTypeArguments
} else {
arrayOf(method.genericReturnType)
}.also { types ->
check(solution !in types) {
"""
|@$name return values cannot container receiver types.
|Generate receivers by targeting the constructor or factory method with @$name"""
.trimMargin().trim()
}
}
}
}
Expand Down
16 changes: 11 additions & 5 deletions src/main/kotlin/generators/Parameters.kt
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ class MethodParametersGeneratorGenerator(val target: Executable, val solution: C
fixedParameters = solution.declaredFields
.filter { field -> field.isFixedParameters() }
.filter { field ->
FixedParameters.validate(field).compareBoxed(parameterTypes)
FixedParameters.validate(field, solution).compareBoxed(parameterTypes)
}.filter { field ->
field.getRandomParametersMethodName().let {
if (it.isNotBlank()) {
Expand All @@ -504,9 +504,15 @@ class MethodParametersGeneratorGenerator(val target: Executable, val solution: C
} catch (e: ClassCastException) {
values.map { One(it) }
}
actualValues.forEach {
val solutionParameters = it.deepCopy()
val submissionParameters = it.deepCopy()
actualValues.forEach { group ->
check(group.toList().none { it != null && it::class.java == solution }) {
"""
|@${FixedParameters.name} field should not contain receiver objects, since this will not work as you expect.
|Target the constructor with @${FixedParameters.name} if you need to create receivers."""
.trimMargin().trim()
}
val solutionParameters = group.deepCopy()
val submissionParameters = group.deepCopy()
check(solutionParameters !== submissionParameters) {
"@${FixedParameters.name} field produces referentially equal copies"
}
Expand All @@ -518,7 +524,7 @@ class MethodParametersGeneratorGenerator(val target: Executable, val solution: C
}
randomParameters = solution.declaredMethods
.filter { method -> method.isRandomParameters() }
.filter { method -> RandomParameters.validate(method).compareBoxed(parameterTypes) }
.filter { method -> RandomParameters.validate(method, solution).compareBoxed(parameterTypes) }
.filter { method ->
method.getRandomParametersMethodName().let {
if (it.isNotBlank()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2021.6.4
version=2021.6.5
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ class TestJavaExamples : StringSpec(
examples.java.noreceiver.customtypewithembeddedgenerators.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.noreceiver.kotlinmap.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.noreceiver.kotlinprintmap.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.receiver.timeouttest.Correct::class.java.also {
"${it.testName()}" {
val runnable = object : Runnable {
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/examples/java/noreceiver/kotlinmap/Correct.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examples.java.noreceiver.kotlinmap;

import java.util.Map;

public class Correct {
public static int sumValues(Map<String, Integer> map) {
int sum = 0;
for (int value : map.values()) {
sum += value;
}
return sum;
}
}
9 changes: 9 additions & 0 deletions src/test/java/examples/java/noreceiver/kotlinmap/Correct0.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package examples.java.noreceiver.kotlinmap

fun sumValues(map: Map<String, Int>): Int {
var sum = 0
for (value in map.values) {
sum += value
}
return sum
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package examples.java.noreceiver.kotlinmap;

import java.util.Map;

public class Incorrect0 {
public static int sumValues(Map<String, Integer> map) {
return 0;
}
}
11 changes: 11 additions & 0 deletions src/test/java/examples/java/noreceiver/kotlinprintmap/Correct.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package examples.java.noreceiver.kotlinprintmap;

import java.util.Map;

public class Correct {
public static void printValues(Map<String, Integer> map) {
for (int value : map.values()) {
System.out.println(value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package examples.java.noreceiver.kotlinprintmap

fun printValues(map: Map<String, Int>) {
for (value in map.values) {
println(value)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package examples.java.noreceiver.kotlinprintmap;

import java.util.Map;

public class Incorrect0 {
public static void printValues(Map<String, Integer> map) {
return;
}
}

0 comments on commit ce2a8f1

Please sign in to comment.