[K/N][cinterop] Indexer unit-tests of objcClassesIncludingCategories
This commit is contained in:
committed by
Space Team
parent
eded880225
commit
898dd02d29
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.native.interop.gen
|
||||
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.native.interop.indexer.IndexerResult
|
||||
import org.junit.Assume
|
||||
import kotlin.test.*
|
||||
|
||||
// Note: A better place for these tests would be Indexer module.
|
||||
// But infrastructure that is required for these tests belongs to StubGenerator.
|
||||
class IncludeCategoriesTests : InteropTestsBase() {
|
||||
|
||||
private fun IndexerResult.getObjCClass(name: String) =
|
||||
index.objCClasses.first { it.name == name }
|
||||
|
||||
private fun IndexerResult.getObjCCategory(name: String) =
|
||||
index.objCCategories.first { it.name == name }
|
||||
|
||||
@BeforeTest
|
||||
fun checkPlatform() {
|
||||
Assume.assumeTrue(HostManager.hostIsMac)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `smoke 0`() {
|
||||
val index = buildNativeIndex("IncludeCategories", "includeCategory0.def")
|
||||
val myClass = index.getObjCClass("MyClass")
|
||||
val myClassCategories = myClass.includedCategories.map { it.name }
|
||||
assertContains(myClassCategories, "IncludeCategory")
|
||||
assertContains(myClassCategories, "IncludeCategory2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `only specific classes include categories`() {
|
||||
val index = buildNativeIndex("IncludeCategories", "includeCategory0.def")
|
||||
val skipClass = index.getObjCClass("SkipClass")
|
||||
assertTrue(skipClass.includedCategories.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `category from another header is not included`() {
|
||||
val index = buildNativeIndex("IncludeCategories", "includeCategory0.def")
|
||||
val myClass = index.getObjCClass("MyClass")
|
||||
val myClassCategories = myClass.includedCategories.map { it.name }
|
||||
assertContains(myClassCategories, "IncludeCategory")
|
||||
assertFalse("SkipCategory" in myClassCategories)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `external category is not included into index`() {
|
||||
val dependencyIndex = buildNativeIndex("IncludeCategories", "includeCategory0.def")
|
||||
val index = buildNativeIndex("IncludeCategories", "includeCategory1.def", mockImports(dependencyIndex))
|
||||
|
||||
val derivedClass = index.getObjCClass("Derived")
|
||||
val myClass = derivedClass.baseClass!!
|
||||
assertEquals("MyClass", myClass.name)
|
||||
assertFalse(myClass in index.index.objCClasses)
|
||||
val myClassCategories = myClass.includedCategories
|
||||
assertTrue(myClassCategories.isNotEmpty())
|
||||
assertTrue(myClassCategories.all { it !in index.index.objCCategories })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `category is not included into dependency class`() {
|
||||
val dependencyIndex = buildNativeIndex("IncludeCategories", "includeCategory0.def")
|
||||
val index = buildNativeIndex("IncludeCategories", "includeCategory2.def", mockImports(dependencyIndex))
|
||||
val category = index.getObjCCategory("ChildCategory")
|
||||
assertFalse(category in category.clazz.includedCategories)
|
||||
}
|
||||
}
|
||||
+39
-2
@@ -12,10 +12,14 @@ import org.jetbrains.kotlin.konan.util.NativeMemoryAllocator
|
||||
import org.jetbrains.kotlin.native.interop.gen.jvm.KotlinPlatform
|
||||
import org.jetbrains.kotlin.native.interop.gen.jvm.buildNativeLibrary
|
||||
import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool
|
||||
import org.jetbrains.kotlin.native.interop.indexer.HeaderId
|
||||
import org.jetbrains.kotlin.native.interop.indexer.IndexerResult
|
||||
import org.jetbrains.kotlin.native.interop.indexer.Location
|
||||
import org.jetbrains.kotlin.native.interop.indexer.NativeLibrary
|
||||
import org.jetbrains.kotlin.native.interop.tool.CInteropArguments
|
||||
import kotlin.test.*
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
abstract class InteropTestsBase {
|
||||
init {
|
||||
@@ -47,7 +51,7 @@ abstract class InteropTestsBase {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun buildNativeLibraryFrom(defFile: File, headersDirectory: File): NativeLibrary {
|
||||
protected fun buildNativeLibraryFrom(defFile: File, headersDirectory: File, imports: Imports = ImportsMock()): NativeLibrary {
|
||||
val tool = prepareTool(HostManager.hostName, KotlinPlatform.NATIVE, runFromDaemon = true)
|
||||
val cinteropArguments = CInteropArguments()
|
||||
cinteropArguments.argParser.parse(arrayOf(
|
||||
@@ -57,7 +61,40 @@ abstract class InteropTestsBase {
|
||||
tool,
|
||||
DefFile(defFile, tool.substitutions),
|
||||
cinteropArguments,
|
||||
ImportsImpl(emptyMap())
|
||||
imports
|
||||
)
|
||||
}
|
||||
|
||||
protected fun getTestResources(directoryName: String): File {
|
||||
val resource = this::class.java.getResource("/$directoryName")
|
||||
return Paths.get(resource.toURI()).toFile()
|
||||
}
|
||||
|
||||
protected fun buildNativeLibraryFrom(directoryName: String, defFileName: String, imports: Imports = ImportsMock()): NativeLibrary {
|
||||
val directory = getTestResources(directoryName)
|
||||
val defFile = File(directory, defFileName)
|
||||
return buildNativeLibraryFrom(defFile, directory, imports)
|
||||
}
|
||||
|
||||
protected fun buildNativeIndex(directoryName: String, defFileName: String, imports: Imports = ImportsMock()): IndexerResult {
|
||||
val library = buildNativeLibraryFrom(directoryName, defFileName, imports)
|
||||
return org.jetbrains.kotlin.native.interop.indexer.buildNativeIndex(library, verbose = false)
|
||||
}
|
||||
|
||||
protected fun mockImports(dependencyIndex: IndexerResult, packageName: String = "dependencyLibrary"): Imports {
|
||||
return ImportsMock(dependencyIndex.index.includedHeaders.associateWith { packageName })
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivial implementation of [Imports] interface, untied from KonanLibrary.
|
||||
*/
|
||||
protected class ImportsMock(private val headerToPackage: Map<HeaderId, String> = emptyMap()) : Imports {
|
||||
override fun getPackage(location: Location): String? {
|
||||
return headerToPackage[location.headerId]
|
||||
}
|
||||
|
||||
override fun isImported(headerId: HeaderId): Boolean {
|
||||
return headerId in headerToPackage
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef _HEADER1_
|
||||
#define _HEADER1_
|
||||
|
||||
@interface MyClass
|
||||
@end
|
||||
|
||||
@interface MyClass(IncludeCategory)
|
||||
@end
|
||||
|
||||
@interface MyClass(IncludeCategory2)
|
||||
@end
|
||||
|
||||
@interface SkipClass
|
||||
@end
|
||||
|
||||
@interface SkipClass(IncludeCategory)
|
||||
@end
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef _HEADER2_
|
||||
#define _HEADER2_
|
||||
|
||||
#include "header1.h"
|
||||
|
||||
@interface MyClass(SkipCategory)
|
||||
- (void)skipMethod;
|
||||
@end
|
||||
|
||||
#endif
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
language = Objective-C
|
||||
headers = header1.h header2.h
|
||||
|
||||
objcClassesIncludingCategories = MyClass
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
language = Objective-C
|
||||
objcClassesIncludingCategories = MyClass
|
||||
---
|
||||
#include <header1.h>
|
||||
|
||||
@interface Derived : MyClass
|
||||
@end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
language = Objective-C
|
||||
objcClassesIncludingCategories = MyClass
|
||||
---
|
||||
#include <header1.h>
|
||||
|
||||
@interface MyClass(ChildCategory)
|
||||
@end
|
||||
Reference in New Issue
Block a user