[Runtime testing] Add basic runtime tests infrastructure
This commit is contained in:
committed by
Ilya Matveev
parent
378dc1954b
commit
f606c59d5b
@@ -103,6 +103,7 @@ val compileGroovy: GroovyCompile by tasks
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-37435
|
||||
compileKotlin.apply {
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.freeCompilerArgs += listOf("-Xno-optimized-callable-references", "-Xskip-prerelease-check")
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.testing.native
|
||||
|
||||
import groovy.lang.Closure
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import org.gradle.api.*
|
||||
import org.gradle.api.tasks.*
|
||||
import org.jetbrains.kotlin.ExecClang
|
||||
import org.jetbrains.kotlin.bitcode.CompileToBitcode
|
||||
import org.jetbrains.kotlin.konan.target.*
|
||||
|
||||
open class CompileNativeTest @Inject constructor(
|
||||
@InputFile val inputFile: File,
|
||||
@Input val target: String
|
||||
) : DefaultTask () {
|
||||
@OutputFile
|
||||
var outputFile = project.buildDir.resolve("bin/test/$target/${inputFile.nameWithoutExtension}.o")
|
||||
|
||||
@Input
|
||||
val clangArgs = mutableListOf<String>()
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
val plugin = project.convention.getPlugin(ExecClang::class.java)
|
||||
plugin.execBareClang(Action {
|
||||
it.executable = "clang++"
|
||||
it.args = clangArgs + listOf(inputFile.absolutePath, "-o", outputFile.absolutePath)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
open class LinkNativeTest @Inject constructor(
|
||||
@InputFiles val inputFiles: List<File>,
|
||||
@OutputFile val outputFile: File,
|
||||
@Internal val target: String,
|
||||
@Internal val linkerArgs: List<String>,
|
||||
private val platformManager: PlatformManager
|
||||
) : DefaultTask () {
|
||||
companion object {
|
||||
fun create(
|
||||
project: Project,
|
||||
platformManager: PlatformManager,
|
||||
taskName: String,
|
||||
inputFiles: List<File>,
|
||||
target: String,
|
||||
outputFile: File,
|
||||
linkerArgs: List<String>
|
||||
): LinkNativeTest = project.tasks.create(
|
||||
taskName,
|
||||
LinkNativeTest::class.java,
|
||||
inputFiles,
|
||||
outputFile,
|
||||
target,
|
||||
linkerArgs,
|
||||
platformManager)
|
||||
|
||||
fun create(
|
||||
project: Project,
|
||||
platformManager: PlatformManager,
|
||||
taskName: String,
|
||||
inputFiles: List<File>,
|
||||
target: String,
|
||||
executableName: String,
|
||||
linkerArgs: List<String> = listOf()
|
||||
): LinkNativeTest = create(
|
||||
project,
|
||||
platformManager,
|
||||
taskName,
|
||||
inputFiles,
|
||||
target,
|
||||
project.buildDir.resolve("bin/test/$target/$executableName"),
|
||||
linkerArgs)
|
||||
}
|
||||
|
||||
@get:Input
|
||||
val commands: List<List<String>>
|
||||
get() {
|
||||
// Getting link commands requires presence of a target toolchain.
|
||||
// Thus we cannot get them at the configuration stage because the toolchain may be not downloaded yet.
|
||||
val linker = platformManager.platform(platformManager.targetByName(target)).linker
|
||||
return linker.finalLinkCommands(
|
||||
inputFiles.map { it.absolutePath },
|
||||
outputFile.absolutePath,
|
||||
listOf(),
|
||||
linkerArgs,
|
||||
optimize = false,
|
||||
debug = false,
|
||||
kind = LinkerOutputKind.EXECUTABLE,
|
||||
outputDsymBundle = "",
|
||||
needsProfileLibrary = false
|
||||
).map { it.argsWithExecutable }
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun link() {
|
||||
for (command in commands) {
|
||||
project.exec {
|
||||
it.commandLine(command)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T: Task> T.configure(f: T.() -> Unit): T =
|
||||
this.configure(object: Closure<Unit>(this) {
|
||||
// Dynamically invoked by Groovy
|
||||
fun doCall() {
|
||||
f()
|
||||
}
|
||||
}) as T
|
||||
|
||||
fun createTestTask(
|
||||
project: Project,
|
||||
testTaskName: String,
|
||||
testedTaskNames: List<String>
|
||||
): Task {
|
||||
val platformManager = project.rootProject.findProperty("platformManager") as PlatformManager
|
||||
val googleTestExtension = project.extensions.getByName(RuntimeTestingPlugin.GOOGLE_TEST_EXTENSION_NAME) as GoogleTestExtension
|
||||
val testedTasks = testedTaskNames.map {
|
||||
project.tasks.getByName(it) as CompileToBitcode
|
||||
}
|
||||
val target = testedTasks.map {
|
||||
it.target
|
||||
}.distinct().single()
|
||||
val konanTarget = platformManager.targetByName(target)
|
||||
val compileToBitcodeTasks = testedTasks.mapNotNull {
|
||||
val name = "${it.name}TestBitcode"
|
||||
val task = project.tasks.findByName(name) as? CompileToBitcode ?:
|
||||
project.tasks.create(name,
|
||||
CompileToBitcode::class.java,
|
||||
it.srcRoot,
|
||||
"${it.folderName}Tests",
|
||||
target, "test"
|
||||
).configure {
|
||||
excludeFiles = emptyList()
|
||||
includeFiles = listOf("**/*Test.cpp", "**/*Test.mm")
|
||||
dependsOn(it)
|
||||
compilerArgs.addAll(it.compilerArgs)
|
||||
headersDirs += googleTestExtension.headersDirs
|
||||
}
|
||||
if (task.inputFiles.count() == 0)
|
||||
null
|
||||
else
|
||||
task
|
||||
}
|
||||
val testFrameworkTasks = listOf(
|
||||
project.tasks.getByName("${target}Googletest") as CompileToBitcode,
|
||||
project.tasks.getByName("${target}Googlemock") as CompileToBitcode
|
||||
)
|
||||
val compileToObjectFileTasks = (compileToBitcodeTasks + testedTasks + testFrameworkTasks).map {
|
||||
val name = "${it.name}Object"
|
||||
val clangFlags = platformManager.platform(konanTarget).configurables as ClangFlags
|
||||
project.tasks.findByName(name) as? CompileNativeTest ?:
|
||||
project.tasks.create(name,
|
||||
CompileNativeTest::class.java,
|
||||
it.outFile,
|
||||
target
|
||||
).configure {
|
||||
dependsOn(it)
|
||||
clangArgs.addAll(clangFlags.clangFlags)
|
||||
clangArgs.addAll(clangFlags.clangNooptFlags)
|
||||
}
|
||||
}
|
||||
val linkTask = LinkNativeTest.create(
|
||||
project,
|
||||
platformManager,
|
||||
"${testTaskName}Link",
|
||||
compileToObjectFileTasks.map { it.outputFile },
|
||||
target,
|
||||
testTaskName
|
||||
).configure {
|
||||
dependsOn(compileToObjectFileTasks)
|
||||
}
|
||||
|
||||
return project.tasks.create(testTaskName, Exec::class.java).apply {
|
||||
dependsOn(linkTask)
|
||||
|
||||
workingDir = project.buildDir.resolve("testReports/$testTaskName")
|
||||
val xmlReport = workingDir.resolve("report.xml")
|
||||
executable(linkTask.outputFile)
|
||||
args("--gtest_output=xml:${xmlReport.absoluteFile}")
|
||||
|
||||
doFirst {
|
||||
workingDir.mkdirs()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,14 @@ set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
set(SRC_DIR ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
set(GOOGLETEST_DIR ${CMAKE_SOURCE_DIR}/googletest)
|
||||
|
||||
include_directories(${SRC_DIR}/main/cpp)
|
||||
include_directories(${SRC_DIR}/debug/headers)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/../common/src/hash/headers)
|
||||
|
||||
include_directories(${GOOGLETEST_DIR}/googletest/include)
|
||||
include_directories(${GOOGLETEST_DIR}/googlemock/include)
|
||||
|
||||
add_executable(runtime
|
||||
src/main/cpp/Arrays.cpp
|
||||
@@ -76,6 +80,12 @@ add_executable(runtime
|
||||
src/objc/cpp/ObjCExportCollections.mm
|
||||
src/objc/cpp/ObjCInteropUtilsClasses.mm
|
||||
|
||||
# Tests
|
||||
src/test_support/cpp/CompilerGenerated.cpp
|
||||
src/test_support/cpp/CompilerGeneratedObjC.mm
|
||||
src/test_support/cpp/TestLauncher.cpp
|
||||
|
||||
src/main/cpp/ArraysTest.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(runtime PUBLIC "-DKONAN_OSX=1")
|
||||
|
||||
@@ -86,12 +86,54 @@ bitcode {
|
||||
create("objc") {
|
||||
includeRuntime()
|
||||
}
|
||||
|
||||
create("test_support", outputGroup = "test") {
|
||||
includeRuntime()
|
||||
dependsOn("downloadGoogleTest")
|
||||
headersDirs += googletest.headersDirs
|
||||
}
|
||||
}
|
||||
|
||||
targetList.forEach { targetName ->
|
||||
createTestTask(
|
||||
project,
|
||||
"${targetName}StdAllocRuntimeTests",
|
||||
listOf(
|
||||
"${targetName}Runtime",
|
||||
"${targetName}TestSupport",
|
||||
"${targetName}Strict",
|
||||
"${targetName}Release",
|
||||
"${targetName}StdAlloc"
|
||||
)
|
||||
)
|
||||
|
||||
createTestTask(
|
||||
project,
|
||||
"${targetName}MimallocRuntimeTests",
|
||||
listOf(
|
||||
"${targetName}Runtime",
|
||||
"${targetName}TestSupport",
|
||||
"${targetName}Strict",
|
||||
"${targetName}Release",
|
||||
"${targetName}Mimalloc",
|
||||
"${targetName}OptAlloc"
|
||||
)
|
||||
)
|
||||
|
||||
tasks.register("${targetName}RuntimeTests") {
|
||||
dependsOn("${targetName}StdAllocRuntimeTests")
|
||||
dependsOn("${targetName}MimallocRuntimeTests")
|
||||
}
|
||||
}
|
||||
|
||||
val hostRuntime by tasks.registering {
|
||||
dependsOn("${hostName}Runtime")
|
||||
}
|
||||
|
||||
val hostRuntimeTests by tasks.registering {
|
||||
dependsOn("${hostName}RuntimeTests")
|
||||
}
|
||||
|
||||
val assemble by tasks.registering {
|
||||
dependsOn(tasks.withType(CompileToBitcode::class).matching {
|
||||
it.outputGroup == "main"
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "CompilerGenerated.h"
|
||||
#include "Types.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TypeInfo theAnyTypeInfoImpl = {};
|
||||
TypeInfo theArrayTypeInfoImpl = {};
|
||||
TypeInfo theBooleanArrayTypeInfoImpl = {};
|
||||
TypeInfo theByteArrayTypeInfoImpl = {};
|
||||
TypeInfo theCharArrayTypeInfoImpl = {};
|
||||
TypeInfo theDoubleArrayTypeInfoImpl = {};
|
||||
TypeInfo theFloatArrayTypeInfoImpl = {};
|
||||
TypeInfo theForeignObjCObjectTypeInfoImpl = {};
|
||||
TypeInfo theFreezableAtomicReferenceTypeInfoImpl = {};
|
||||
TypeInfo theIntArrayTypeInfoImpl = {};
|
||||
TypeInfo theLongArrayTypeInfoImpl = {};
|
||||
TypeInfo theNativePtrArrayTypeInfoImpl = {};
|
||||
TypeInfo theObjCObjectWrapperTypeInfoImpl = {};
|
||||
TypeInfo theOpaqueFunctionTypeInfoImpl = {};
|
||||
TypeInfo theShortArrayTypeInfoImpl = {};
|
||||
TypeInfo theStringTypeInfoImpl = {};
|
||||
TypeInfo theThrowableTypeInfoImpl = {};
|
||||
TypeInfo theUnitTypeInfoImpl = {};
|
||||
TypeInfo theWorkerBoundReferenceTypeInfoImpl = {};
|
||||
|
||||
ArrayHeader theEmptyStringImpl = { &theStringTypeInfoImpl, /* element count */ 0 };
|
||||
|
||||
template <class T>
|
||||
struct KBox {
|
||||
ObjHeader header;
|
||||
const T value;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern const int KonanNeedDebugInfo = 0;
|
||||
|
||||
extern const TypeInfo* theAnyTypeInfo = &theAnyTypeInfoImpl;
|
||||
extern const TypeInfo* theArrayTypeInfo = &theArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theBooleanArrayTypeInfo = &theBooleanArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theByteArrayTypeInfo = &theByteArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theCharArrayTypeInfo = &theCharArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theDoubleArrayTypeInfo = &theDoubleArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theFloatArrayTypeInfo = &theFloatArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theForeignObjCObjectTypeInfo = &theForeignObjCObjectTypeInfoImpl;
|
||||
extern const TypeInfo* theFreezableAtomicReferenceTypeInfo = &theFreezableAtomicReferenceTypeInfoImpl;
|
||||
extern const TypeInfo* theIntArrayTypeInfo = &theIntArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theLongArrayTypeInfo = &theLongArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theNativePtrArrayTypeInfo = &theNativePtrArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theObjCObjectWrapperTypeInfo = &theObjCObjectWrapperTypeInfoImpl;
|
||||
extern const TypeInfo* theOpaqueFunctionTypeInfo = &theOpaqueFunctionTypeInfoImpl;
|
||||
extern const TypeInfo* theShortArrayTypeInfo = &theShortArrayTypeInfoImpl;
|
||||
extern const TypeInfo* theStringTypeInfo = &theStringTypeInfoImpl;
|
||||
extern const TypeInfo* theThrowableTypeInfo = &theThrowableTypeInfoImpl;
|
||||
extern const TypeInfo* theUnitTypeInfo = &theUnitTypeInfoImpl;
|
||||
extern const TypeInfo* theWorkerBoundReferenceTypeInfo = &theWorkerBoundReferenceTypeInfoImpl;
|
||||
|
||||
extern const ArrayHeader theEmptyArray = { &theArrayTypeInfoImpl, /* element count */0 };
|
||||
|
||||
OBJ_GETTER0(TheEmptyString) {
|
||||
RETURN_OBJ(theEmptyStringImpl.obj());
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(makeWeakReferenceCounter, void*) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(makePermanentWeakReferenceImpl, void*) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(makeObjCWeakReferenceImpl, void*) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void checkRangeIndexes(KInt from, KInt to, KInt size) {
|
||||
if (from < 0 || to > size) {
|
||||
throw std::out_of_range("Index out of bounds: from=" + std::to_string(from)
|
||||
+ ", to=" + std::to_string(to)
|
||||
+ ", size=" + std::to_string(size));
|
||||
}
|
||||
if (from > to) {
|
||||
throw std::invalid_argument("Illegal argument: from > to, from=" + std::to_string(from) + ", to=" + std::to_string(to));
|
||||
}
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(WorkerLaunchpad, KRef) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowWorkerInvalidState() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowNullPointerException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowArrayIndexOutOfBoundsException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowClassCastException(const ObjHeader* instance, const TypeInfo* type_info) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowArithmeticException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowNumberFormatException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowOutOfMemoryError() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowNotImplementedError() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowCharacterCodingException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowIllegalArgumentException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowIllegalStateException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowInvalidMutabilityException(KConstRef where) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowIncorrectDereferenceException() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowIllegalObjectSharingException(KConstNativePtr typeInfo, KConstNativePtr address) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void RUNTIME_NORETURN ThrowFreezingException(KRef toFreeze, KRef blocker) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void ReportUnhandledException(KRef throwable) {
|
||||
konan::consolePrintf("Uncaught Kotlin exception.");
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(DescribeObjectForDebugging, KConstNativePtr typeInfo, KConstNativePtr address) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void ExceptionReporterLaunchpad(KRef reporter, KRef throwable) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_WorkerBoundReference_freezeHook(KRef thiz) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
extern const KBoolean BOOLEAN_RANGE_FROM = false;
|
||||
extern const KBoolean BOOLEAN_RANGE_TO = true;
|
||||
extern KBox<KBoolean> BOOLEAN_CACHE[] = {
|
||||
{{}, false},
|
||||
{{}, true},
|
||||
};
|
||||
|
||||
OBJ_GETTER(Kotlin_boxBoolean, KBoolean value) {
|
||||
if (value) {
|
||||
RETURN_OBJ(&BOOLEAN_CACHE[1].header);
|
||||
} else {
|
||||
RETURN_OBJ(&BOOLEAN_CACHE[0].header);
|
||||
}
|
||||
}
|
||||
|
||||
extern const KByte BYTE_RANGE_FROM = -1;
|
||||
extern const KByte BYTE_RANGE_TO = 1;
|
||||
extern KBox<KByte> BYTE_CACHE[] = {
|
||||
{{}, -1},
|
||||
{{}, 0},
|
||||
{{}, 1},
|
||||
};
|
||||
|
||||
extern const KChar CHAR_RANGE_FROM = 0;
|
||||
extern const KChar CHAR_RANGE_TO = 2;
|
||||
extern KBox<KChar> CHAR_CACHE[] = {
|
||||
{{}, 0},
|
||||
{{}, 1},
|
||||
{{}, 2},
|
||||
};
|
||||
|
||||
extern const KShort SHORT_RANGE_FROM = -1;
|
||||
extern const KShort SHORT_RANGE_TO = 1;
|
||||
extern KBox<KShort> SHORT_CACHE[] = {
|
||||
{{}, -1},
|
||||
{{}, 0},
|
||||
{{}, 1},
|
||||
};
|
||||
|
||||
extern const KInt INT_RANGE_FROM = -1;
|
||||
extern const KInt INT_RANGE_TO = 1;
|
||||
extern KBox<KInt> INT_CACHE[] = {
|
||||
{{}, -1},
|
||||
{{}, 0},
|
||||
{{}, 1},
|
||||
};
|
||||
|
||||
extern const KLong LONG_RANGE_FROM = -1;
|
||||
extern const KLong LONG_RANGE_TO = 1;
|
||||
extern KBox<KLong> LONG_CACHE[] = {
|
||||
{{}, -1},
|
||||
{{}, 0},
|
||||
{{}, 1},
|
||||
};
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(Kotlin_Throwable_getMessage, KRef throwable) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef RUNTIME_COMPILER_GENERATED_H
|
||||
#define RUNTIME_COMPILER_GENERATED_H
|
||||
|
||||
#define THROW_NOT_IMPLEMENTED throw std::runtime_error("Not implemented for tests");
|
||||
|
||||
#endif //RUNTIME_COMPILER_GENERATED_H
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#if KONAN_OBJC_INTEROP
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
#include "CompilerGenerated.h"
|
||||
#include "Types.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Class Kotlin_Interop_getObjCClass(const char* name) {
|
||||
Class result = objc_lookUpClass(name);
|
||||
if (result == nil) {
|
||||
// GTest can display error messages of C++ exceptions so we use them instead of ObjC ones.
|
||||
throw std::invalid_argument("Incorrect class name");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER0(Kotlin_NSEnumeratorAsKIterator_create) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_NSEnumeratorAsKIterator_done(KRef thiz) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_NSEnumeratorAsKIterator_setNext(KRef thiz, KRef value) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_NSErrorAsExceptionImpl, KRef message, KRef error) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_ObjCExport_ThrowCollectionConcurrentModification() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_ObjCExport_ThrowCollectionTooLarge() {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
typedef OBJ_GETTER((*convertReferenceFromObjC), id obj);
|
||||
extern convertReferenceFromObjC Kotlin_ObjCExport_blockToFunctionConverters[] = {};
|
||||
extern int Kotlin_ObjCExport_blockToFunctionConverters_size = 0;
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_createContinuationArgumentImpl, KRef completionHolder, const TypeInfo** exceptionTypes) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
RUNTIME_NORETURN OBJ_GETTER(Kotlin_ObjCExport_getWrappedError, KRef throwable) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_ObjCExport_resumeContinuationFailure(KRef continuation, KRef exception) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void Kotlin_ObjCExport_resumeContinuationSuccess(KRef continuation, KRef result) {
|
||||
THROW_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // KONAN_OBJC_INTEROP
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -28,6 +28,8 @@ open class Command(initialCommand: List<String>) {
|
||||
constructor(vararg command: String) : this(command.toList<String>())
|
||||
protected val command = initialCommand.toMutableList()
|
||||
|
||||
val argsWithExecutable: List<String> = command
|
||||
|
||||
val args: List<String>
|
||||
get() = command.drop(1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user