Skip to content

[draft] Implement overrides for toArray(IntFunction[]) #912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-and-run-tests-from-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
# The option forces to execute all jobs even though some of them have failed.
fail-fast: false
matrix:
project: [utbot-api, utbot-cli, utbot-core, utbot-framework, utbot-framework-api, utbot-fuzzers, utbot-gradle, utbot-instrumentation, utbot-instrumentation-tests, utbot-intellij, utbot-junit-contest, utbot-rd, utbot-sample, utbot-summary, utbot-summary-tests]
project: [utbot-api, utbot-cli, utbot-core, utbot-framework, utbot-framework-test-java11, utbot-framework-api, utbot-fuzzers, utbot-gradle, utbot-instrumentation, utbot-instrumentation-tests, utbot-intellij, utbot-junit-contest, utbot-rd, utbot-sample, utbot-summary, utbot-summary-tests]
runs-on: ubuntu-20.04
container: unittestbot/java-env:java11-zulu-jdk-gradle7.4.2-kotlinc1.7.0
steps:
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ include 'utbot-gradle'
include 'utbot-maven'
include 'utbot-summary-tests'
include 'utbot-framework-test'
include 'utbot-framework-test-java11'
include 'utbot-rd'

1 change: 1 addition & 0 deletions utbot-framework-test-java11/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Engine/codegen unit tests that require Java 11 features
89 changes: 89 additions & 0 deletions utbot-framework-test-java11/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
apply from: "${parent.projectDir}/gradle/include/jvm-project.gradle"

compileKotlin {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
freeCompilerArgs += ["-Xallow-result-return-type", "-Xsam-conversions=class"]
}
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

//noinspection GroovyAssignabilityCheck
repositories {
flatDir {
dirs 'dist'
}
}

//noinspection GroovyAssignabilityCheck
configurations {
z3native
}

dependencies {
api project(':utbot-api')
api project(':utbot-fuzzers')
api project(':utbot-core')
api project(':utbot-instrumentation')
api project(':utbot-summary')
api project(':utbot-framework-api')

implementation project(':utbot-framework')
testImplementation project(":utbot-framework").sourceSets.test.output
testImplementation project(":utbot-core").sourceSets.test.output

implementation "com.github.UnitTestBot:soot:${soot_commit_hash}"

implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: jackson_version
implementation group: 'org.sosy-lab', name: 'javasmt-solver-z3', version: javasmt_solver_z3_version
implementation group: 'com.github.curious-odd-man', name: 'rgxgen', version: rgxgen_version
implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: log4j2_version
implementation group: 'io.github.microutils', name: 'kotlin-logging', version: kotlin_logging_version
implementation group: 'org.jacoco', name: 'org.jacoco.report', version: jacoco_version
implementation group: 'org.apache.commons', name: 'commons-text', version: apache_commons_text_version
// we need this for construction mocks from composite models
implementation group: 'org.mockito', name: 'mockito-core', version: '4.2.0'

// To use JUnit4, comment out JUnit5 and uncomment JUnit4 dependencies here. Please also check "test" section
// testImplementation group: 'junit', name: 'junit', version: '4.13.1'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.8.1'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.1'

// used for testing code generation
testImplementation group: 'commons-io', name: 'commons-io', version: commons_io_version
testImplementation group: 'junit', name: 'junit', version: junit4_version
testImplementation group: 'org.junit.platform', name: 'junit-platform-console-standalone', version: junit4_platform_version
testImplementation group: 'org.antlr', name: 'antlr4', version: antlr_version
testImplementation group: 'org.mockito', name: 'mockito-core', version: mockito_version
testImplementation group: 'org.testng', name: 'testng', version: testng_version
testImplementation group: 'org.mockito', name: 'mockito-inline', version: mockito_inline_version
testImplementation group: 'com.google.guava', name: 'guava', version: guava_version

testImplementation group: 'org.mockito', name: 'mockito-inline', version: mockito_inline_version
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4j2_version

z3native group: 'com.microsoft.z3', name: 'z3-native-win64', version: z3_version, ext: 'zip'
z3native group: 'com.microsoft.z3', name: 'z3-native-linux64', version: z3_version, ext: 'zip'
z3native group: 'com.microsoft.z3', name: 'z3-native-osx', version: z3_version, ext: 'zip'
}

test {
minHeapSize = "128m"
maxHeapSize = "2048m"

jvmArgs '-XX:MaxHeapSize=2048m'

// To use JUnit4, comment out useJUnitPlatform and uncomment useJUnit. Please also check "dependencies" section
//useJUnit()
useJUnitPlatform() {
excludeTags 'slow', 'IntegrationTest'
}

if (System.getProperty('DEBUG', 'false') == 'true') {
jvmArgs '-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9009'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package org.utbot.examples.java11.collections;

import org.jetbrains.annotations.NotNull;

import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

public class ToArrayWithGenerator<T> {
@SuppressWarnings("MismatchedReadAndWriteOfArray")
public boolean checkSetSize(int size) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i < size; i++) {
set.add(i);
}

Integer[] array = set.toArray(Integer[]::new);
return array.length == size;
}

@SuppressWarnings({"SuspiciousToArrayCall", "MismatchedReadAndWriteOfArray"})
public boolean checkSetSizeArrayStoreException(int size) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i < size; i++) {
set.add(i);
}

String[] array = set.toArray(String[]::new);
return array.length == size;
}

public boolean checkListSize(int size) {
List<Integer> integers = new LinkedList<>();
for (int i = 0; i < size; i++) {
integers.add(i);
}

return integers.toArray(Integer[]::new).length == size;
}

@SuppressWarnings("MismatchedReadAndWriteOfArray")
public boolean checkMapKeysSize(int size) {
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < size; i++) {
map.put(i, "hello");
}

Integer[] keyArray = map.keySet().toArray(Integer[]::new);
return keyArray.length == size;
}

@SuppressWarnings("MismatchedReadAndWriteOfArray")
public boolean checkMapValuesSize(int size) {
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < size; i++) {
map.put(i, "hello");
}

String[] valuesArray = map.values().toArray(String[]::new);
return valuesArray.length == size;
}

@SuppressWarnings({"SuspiciousToArrayCall", "UnnecessaryLocalVariable"})
public String[] getMapEntrySetArrayStoreException() {
Map<String, String> namesMap = new HashMap<>();
namesMap.put("Joe", "Jane");
namesMap.put("Bill", "Anna");
String[] names = namesMap.entrySet().toArray(String[]::new);
return names;
}

public int getMapEntrySetSize() {
Map<String, String> namesMap = new HashMap<>();
namesMap.put("Joe", "Jane");
namesMap.put("Bill", "Anna");
Set<Map.Entry<String, String>> entries = namesMap.entrySet();
return entries.toArray(Map.Entry[]::new).length;
}

public int getCollectionArgumentSize(@NotNull Collection<Integer> arg) {
return arg.toArray(Integer[]::new).length;
}

public int getSetArgumentSize(@NotNull Set<Integer> arg) {
return arg.toArray(Integer[]::new).length;
}

public int getListArgumentSize(@NotNull List<Integer> arg) {
return arg.toArray(Integer[]::new).length;
}

public int getAbstractCollectionArgumentSize(@NotNull AbstractCollection<Integer> arg) {
return arg.toArray(Integer[]::new).length;
}

public int getGenericCollectionArgumentSize(@NotNull Collection<T> arg) {
return arg.toArray(Object[]::new).length;
}

public int countMatchingElements(@NotNull ArrayList<Integer> arrayList) {
int size = arrayList.size();
Integer[] array = arrayList.toArray(Integer[]::new);
if (array.length != size) {
return -1;
}

int count = 0;
for (int i = 0; i < size; i++) {
Integer arrayElement = array[i];
Integer listElement = arrayList.get(i);
if (arrayElement == null) {
if (listElement == null) {
count++;
} else {
return -2;
}
} else {
if (arrayElement.equals(listElement)) {
count++;
}
}
}

return count;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package org.utbot.examples.java11.collections

import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import org.utbot.framework.plugin.api.CodegenLanguage
import org.utbot.testcheckers.between
import org.utbot.testcheckers.eq
import org.utbot.tests.infrastructure.CodeGeneration
import org.utbot.tests.infrastructure.DoNotCalculate
import org.utbot.tests.infrastructure.UtValueTestCaseChecker
import org.utbot.tests.infrastructure.ignoreExecutionsNumber
import org.utbot.tests.infrastructure.isException

class ToArrayWithGeneratorTest : UtValueTestCaseChecker(
testClass = ToArrayWithGenerator::class,
testCodeGeneration = true,
languagePipelines = listOf(
CodeGenerationLanguageLastStage(CodegenLanguage.JAVA),
// TODO: We are generating Kotlin code for generic collections that will not compile
CodeGenerationLanguageLastStage(CodegenLanguage.KOTLIN, lastStage = CodeGeneration)
)
) {
@Test
fun testCheckSetSize() {
check(
ToArrayWithGenerator<Int>::checkSetSize,
ignoreExecutionsNumber,
{ size, result -> size < 0 && result == false },
{ size, result -> size >= 0 && result == true }
)
}

@Test
@Disabled("TODO: we can't yet model throwing ArrayStoreException")
fun testCheckSetSizeArrayStoreException() {
checkWithException(
ToArrayWithGenerator<Int>::checkSetSizeArrayStoreException,
eq(3),
{ size, result -> size < 0 && result.isSuccess && result.getOrNull() == false },
{ size, result -> size == 0 && result.isSuccess && result.getOrNull() == true },
{ size, result -> size > 0 && result.isException<ArrayStoreException>() }
)
}

@Test
fun testCheckListSize() {
check(
ToArrayWithGenerator<Int>::checkListSize,
ignoreExecutionsNumber,
{ size, result -> size < 0 && result == false },
{ size, result -> size >= 0 && result == true }
)
}

@Test
fun testCheckMapKeysSize() {
check(
ToArrayWithGenerator<Int>::checkMapKeysSize,
ignoreExecutionsNumber,
{ size, result -> size < 0 && result == false },
{ size, result -> size >= 0 && result == true }
)
}

@Test
fun testCheckMapValuesSize() {
check(
ToArrayWithGenerator<Int>::checkMapValuesSize,
ignoreExecutionsNumber,
{ size, result -> size < 0 && result == false },
{ size, result -> size >= 0 && result == true }
)
}

@Test
@Disabled("TODO: we can't yet model throwing ArrayStoreException")
fun testGetMapEntrySetArrayStoreException() {
checkWithException(
ToArrayWithGenerator<Int>::getMapEntrySetArrayStoreException,
eq(1),
{ result -> result.isFailure && result.isException<ArrayStoreException>() },
coverage = DoNotCalculate
)
}

@Test
fun testGetMapEntrySetSize() {
check(
ToArrayWithGenerator<Int>::getMapEntrySetSize,
eq(1),
{ result -> result == 2 }
)
}

@Test
fun testGetCollectionArgumentSize() {
check(
ToArrayWithGenerator<Int>::getCollectionArgumentSize,
ignoreExecutionsNumber,
{ arg, result -> result == arg.size }
)
}

@Test
fun testSetCollectionArgumentSize() {
check(
ToArrayWithGenerator<Int>::getSetArgumentSize,
ignoreExecutionsNumber,
{ arg, result -> result == arg.size }
)
}

@Test
fun testListCollectionArgumentSize() {
check(
ToArrayWithGenerator<Int>::getListArgumentSize,
ignoreExecutionsNumber,
{ arg, result -> result == arg.size }
)
}

@Test
@Disabled("TODO: this test takes too long and results in non-instantiable concrete type substitutions")
fun testGetAbstractCollectionArgumentSize() {
check(
ToArrayWithGenerator<Int>::getAbstractCollectionArgumentSize,
ignoreExecutionsNumber,
{ arg, result -> result == arg.size }
)
}

@Test
@Disabled("TODO: translate of UtArrayApplyForAll expression (#630)")
fun testGetGenericCollectionArgumentSize() {
check(
ToArrayWithGenerator<Int>::getGenericCollectionArgumentSize,
ignoreExecutionsNumber,
{ arg, result -> result == arg.size },
coverage = DoNotCalculate
)
}

@Test
fun testCountMatchingElements() {
check(
ToArrayWithGenerator<Int>::countMatchingElements,
between(3..4),
{ arg, result -> arg.isEmpty() && result == 0 },
{ arg, result -> arg.contains(null) && result == arg.size },
{ arg, result -> arg.isNotEmpty() && !arg.contains(null) && result == arg.size },
coverage = DoNotCalculate // TODO: investigate the incomplete coverage
)
}
}
Loading