diff options
Diffstat (limited to 'plugins/base/src/test/kotlin/model')
-rw-r--r-- | plugins/base/src/test/kotlin/model/ClassesTest.kt | 533 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/CommentTest.kt | 332 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/FunctionsTest.kt | 396 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/InheritorsTest.kt | 95 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/JavaTest.kt | 346 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/PackagesTest.kt | 134 | ||||
-rw-r--r-- | plugins/base/src/test/kotlin/model/PropertyTest.kt | 265 |
7 files changed, 2101 insertions, 0 deletions
diff --git a/plugins/base/src/test/kotlin/model/ClassesTest.kt b/plugins/base/src/test/kotlin/model/ClassesTest.kt new file mode 100644 index 00000000..5dc8812e --- /dev/null +++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt @@ -0,0 +1,533 @@ +package model + +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.sureClassNames +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.KotlinModifier.* +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test +import utils.AbstractModelTest +import utils.assertNotNull +import utils.name +import utils.supers + + +class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "classes") { + + @Test + fun emptyClass() { + inlineModelTest( + """ + |class Klass {}""" + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + children counts 4 + } + } + } + + @Test + fun emptyObject() { + inlineModelTest( + """ + |object Obj {} + """ + ) { + with((this / "classes" / "Obj").cast<DObject>()) { + name equals "Obj" + children counts 3 + } + } + } + + @Test + fun classWithConstructor() { + inlineModelTest( + """ + |class Klass(name: String) + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + children counts 4 + + with(constructors.firstOrNull().assertNotNull("Constructor")) { + visibility.values allEquals KotlinVisibility.Public + parameters counts 1 + with(parameters.firstOrNull().assertNotNull("Constructor parameter")) { + name equals "name" + type.name equals "String" + } + } + + } + } + } + + @Test + fun classWithFunction() { + inlineModelTest( + """ + |class Klass { + | fun fn() {} + |} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + children counts 5 + + with((this / "fn").cast<DFunction>()) { + type.name equals "Unit" + parameters counts 0 + visibility.values allEquals KotlinVisibility.Public + } + } + } + } + + @Test + fun classWithProperty() { + inlineModelTest( + """ + |class Klass { + | val name: String = "" + |} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + children counts 5 + + with((this / "name").cast<DProperty>()) { + name equals "name" + // TODO property name + } + } + } + } + + @Test + fun classWithCompanionObject() { + inlineModelTest( + """ + |class Klass() { + | companion object { + | val x = 1 + | fun foo() {} + | } + |} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + children counts 5 + + with((this / "Companion").cast<DObject>()) { + name equals "Companion" + children counts 5 + + with((this / "x").cast<DProperty>()) { + name equals "x" + } + + with((this / "foo").cast<DFunction>()) { + name equals "foo" + parameters counts 0 + type.name equals "Unit" + } + } + } + } + } + + @Test + fun dataClass() { + inlineModelTest( + """ + |data class Klass() {} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + visibility.values allEquals KotlinVisibility.Public + with(extra[AdditionalModifiers]!!.content.entries.single().value.assertNotNull("Extras")) { + this counts 1 + first() equals ExtraModifiers.KotlinOnlyModifiers.Data + } + } + } + } + + @Test + fun sealedClass() { + inlineModelTest( + """ + |sealed class Klass() {} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + modifier.values.forEach { it equals Sealed } + } + } + } + + @Test + fun annotatedClassWithAnnotationParameters() { + inlineModelTest( + """ + |@Deprecated("should no longer be used") class Foo() {} + """ + ) { + with((this / "classes" / "Foo").cast<DClass>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "Deprecated" + params.entries counts 1 + (params["message"].assertNotNull("message") as StringValue).value equals "\"should no longer be used\"" + } + } + } + } + } + + @Test + fun notOpenClass() { + inlineModelTest( + """ + |open class C() { + | open fun f() {} + |} + | + |class D() : C() { + | override fun f() {} + |} + """ + ) { + val C = (this / "classes" / "C").cast<DClass>() + val D = (this / "classes" / "D").cast<DClass>() + + with(C) { + modifier.values.forEach { it equals Open } + with((this / "f").cast<DFunction>()) { + modifier.values.forEach { it equals Open } + } + } + with(D) { + modifier.values.forEach { it equals Final } + with((this / "f").cast<DFunction>()) { + modifier.values.forEach { it equals Open } + } + D.supertypes.flatMap { it.component2() }.firstOrNull()?.dri equals C.dri + } + } + } + + @Test + fun indirectOverride() { + inlineModelTest( + """ + |abstract class C() { + | abstract fun foo() + |} + | + |abstract class D(): C() + | + |class E(): D() { + | override fun foo() {} + |} + """ + ) { + val C = (this / "classes" / "C").cast<DClass>() + val D = (this / "classes" / "D").cast<DClass>() + val E = (this / "classes" / "E").cast<DClass>() + + with(C) { + modifier.values.forEach { it equals Abstract } + ((this / "foo").cast<DFunction>()).modifier.values.forEach { it equals Abstract } + } + + with(D) { + modifier.values.forEach { it equals Abstract } + } + + with(E) { + modifier.values.forEach { it equals Final } + + } + D.supers.single().dri equals C.dri + E.supers.single().dri equals D.dri + } + } + + @Test + fun innerClass() { + inlineModelTest( + """ + |class C { + | inner class D {} + |} + """ + ) { + with((this / "classes" / "C").cast<DClass>()) { + + with((this / "D").cast<DClass>()) { + with(extra[AdditionalModifiers]!!.content.entries.single().value.assertNotNull("AdditionalModifiers")) { + this counts 1 + first() equals ExtraModifiers.KotlinOnlyModifiers.Inner + } + } + } + } + } + + @Test + fun companionObjectExtension() { + inlineModelTest( + """ + |class Klass { + | companion object Default {} + |} + | + |/** + | * The def + | */ + |val Klass.Default.x: Int get() = 1 + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + + with((this / "Default").cast<DObject>()) { + name equals "Default" + // TODO extensions + } + } + } + } + +// @Test fun companionObjectExtension() { +// checkSourceExistsAndVerifyModel("testdata/classes/companionObjectExtension.kt", defaultModelConfig) { model -> +// val pkg = model.members.single() +// val cls = pkg.members.single { it.name == "Foo" } +// val extensions = cls.extensions.filter { it.kind == NodeKind.CompanionObjectProperty } +// assertEquals(1, extensions.size) +// } +// } + + @Test + fun secondaryConstructor() { + inlineModelTest( + """ + |class C() { + | /** This is a secondary constructor. */ + | constructor(s: String): this() {} + |} + """ + ) { + with((this / "classes" / "C").cast<DClass>()) { + name equals "C" + constructors counts 2 + + constructors.map { it.name } allEquals "<init>" + + with(constructors.find { it.parameters.isNullOrEmpty() } notNull "C()") { + parameters counts 0 + } + + with(constructors.find { it.parameters.isNotEmpty() } notNull "C(String)") { + parameters counts 1 + with(parameters.firstOrNull() notNull "Constructor parameter") { + name equals "s" + type.name equals "String" + } + } + } + } + } + + @Test + fun sinceKotlin() { + inlineModelTest( + """ + |/** + | * Useful + | */ + |@SinceKotlin("1.1") + |class C + """ + ) { + with((this / "classes" / "C").cast<DClass>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "SinceKotlin" + params.entries counts 1 + (params["version"].assertNotNull("version") as StringValue).value equals "\"1.1\"" + } + } + } + } + } + + @Test + fun privateCompanionObject() { + inlineModelTest( + """ + |class Klass { + | private companion object { + | fun fn() {} + | val a = 0 + | } + |} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + assertNull(companion, "Companion should not be visible by default") + } + } + } + + @Test + fun companionObject() { + inlineModelTest( + """ + |class Klass { + | companion object { + | fun fn() {} + | val a = 0 + | } + |} + """ + ) { + with((this / "classes" / "Klass").cast<DClass>()) { + name equals "Klass" + with((this / "Companion").cast<DObject>()) { + name equals "Companion" + visibility.values allEquals KotlinVisibility.Public + + with((this / "fn").cast<DFunction>()) { + name equals "fn" + parameters counts 0 + receiver equals null + } + } + } + } + } + + @Test + fun annotatedClass() { + inlineModelTest( + """@Suppress("abc") class Foo() {}""" + ) { + with((this / "classes" / "Foo").cast<DClass>()) { + with(extra[Annotations]?.content?.values?.firstOrNull()?.firstOrNull().assertNotNull("annotations")) { + dri.toString() equals "kotlin/Suppress///PointingToDeclaration/" + (params["names"].assertNotNull("param") as ArrayValue).value equals listOf(StringValue("\"abc\"")) + } + } + } + } + + @Test + fun javaAnnotationClass() { + inlineModelTest( + """ + |import java.lang.annotation.Retention + |import java.lang.annotation.RetentionPolicy + | + |@Retention(RetentionPolicy.SOURCE) + |public annotation class throws() + """ + ) { + with((this / "classes" / "throws").cast<DAnnotation>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "Retention" + params["value"].assertNotNull("value") equals EnumValue( + "RetentionPolicy.SOURCE", + DRI("java.lang.annotation", "RetentionPolicy.SOURCE") + ) + } + } + } + } + } + + @Test fun genericAnnotationClass() { + inlineModelTest( + """annotation class Foo<A,B,C,D:Number>() {}""" + ) { + with((this / "classes" / "Foo").cast<DAnnotation>()){ + generics.map { it.name to it.bounds.first().name } equals listOf("A" to "Any", "B" to "Any", "C" to "Any", "D" to "Number") + } + } + } + + @Test fun nestedGenericClasses(){ + inlineModelTest( + """ + |class Outer<OUTER> { + | inner class Inner<INNER, T : OUTER> { } + |} + """.trimMargin() + ){ + with((this / "classes" / "Outer").cast<DClass>()){ + val inner = classlikes.single().cast<DClass>() + inner.generics.map { it.name to it.bounds.first().name } equals listOf("INNER" to "Any", "T" to "OUTER") + } + } + } + + @Test fun allImplementedInterfaces() { + inlineModelTest( + """ + | interface Highest { } + | open class HighestImpl: Highest { } + | interface Lower { } + | interface LowerImplInterface: Lower { } + | class Tested : HighestImpl(), LowerImplInterface { } + """.trimIndent() + ){ + with((this / "classes" / "Tested").cast<DClass>()){ + extra[ImplementedInterfaces]?.interfaces?.entries?.single()?.value?.map { it.sureClassNames }?.sorted() equals listOf("Highest", "Lower", "LowerImplInterface").sorted() + } + } + } + + @Test fun multipleClassInheritance() { + inlineModelTest( + """ + | open class A { } + | open class B: A() { } + | class Tested : B() { } + """.trimIndent() + ) { + with((this / "classes" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames }.single() equals "B" + } + } + } + + @Test fun multipleClassInheritanceWithInterface(){ + inlineModelTest( + """ + | open class A { } + | open class B: A() { } + | interface X { } + | interface Y : X { } + | class Tested : B(), Y { } + """.trimIndent() + ){ + with((this / "classes" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames to it.kind }.sortedBy { it.first } equals listOf("B" to KotlinClassKindTypes.CLASS, "Y" to KotlinClassKindTypes.INTERFACE) + } + } + } +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/model/CommentTest.kt b/plugins/base/src/test/kotlin/model/CommentTest.kt new file mode 100644 index 00000000..c1da8ee0 --- /dev/null +++ b/plugins/base/src/test/kotlin/model/CommentTest.kt @@ -0,0 +1,332 @@ +package model + +import org.jetbrains.dokka.model.DProperty +import org.jetbrains.dokka.model.doc.CustomTagWrapper +import org.jetbrains.dokka.model.doc.Text +import org.junit.jupiter.api.Test +import utils.* + +class CommentTest : AbstractModelTest("/src/main/kotlin/comment/Test.kt", "comment") { + + @Test + fun codeBlockComment() { + inlineModelTest( + """ + |/** + | * ```brainfuck + | * ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. + | * ``` + | */ + |val prop1 = "" + | + | + |/** + | * ``` + | * a + b - c + | * ``` + | */ + |val prop2 = "" + """ + ) { + with((this / "comment" / "prop1").cast<DProperty>()) { + name equals "prop1" + with(this.docs().firstOrNull()?.root.assertNotNull("Code")) { + (children.firstOrNull() as? Text) + ?.body equals "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." + + params["lang"] equals "brainfuck" + } + } + with((this / "comment" / "prop2").cast<DProperty>()) { + name equals "prop2" + comments() equals "a + b - c" + } + } + } + + @Test + fun emptyDoc() { + inlineModelTest( + """ + val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + name equals "property" + comments() equals "" + } + } + } + + @Test + fun emptyDocButComment() { + inlineModelTest( + """ + |/* comment */ + |val property = "test" + |fun tst() = property + """ + ) { + val p = this + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "" + } + } + } + + @Test + fun multilineDoc() { + inlineModelTest( + """ + |/** + | * doc1 + | * + | * doc2 + | * doc3 + | */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "doc1\ndoc2 doc3" + } + } + } + + @Test + fun multilineDocWithComment() { + inlineModelTest( + """ + |/** + | * doc1 + | * + | * doc2 + | * doc3 + | */ + |// comment + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "doc1\ndoc2 doc3" + } + } + } + + @Test + fun oneLineDoc() { + inlineModelTest( + """ + |/** doc */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "doc" + } + } + } + + @Test + fun oneLineDocWithComment() { + inlineModelTest( + """ + |/** doc */ + |// comment + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "doc" + } + } + } + + @Test + fun oneLineDocWithEmptyLine() { + inlineModelTest( + """ + |/** doc */ + | + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "doc" + } + } + } + + @Test + fun emptySection() { + inlineModelTest( + """ + |/** + | * Summary + | * @one + | */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "Summary\none: []" + docs().find { it is CustomTagWrapper && it.name == "one" }.let { + with(it.assertNotNull("'one' entry")) { + root.children counts 0 + root.params.keys counts 0 + } + } + } + } + } + + @Test + fun quotes() { + inlineModelTest( + """ + |/** it's "useful" */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals """it's "useful"""" + } + } + } + + @Test + fun section1() { + inlineModelTest( + """ + |/** + | * Summary + | * @one section one + | */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "Summary\none: [section one]" + } + } + } + + + @Test + fun section2() { + inlineModelTest( + """ + |/** + | * Summary + | * @one section one + | * @two section two + | */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "Summary\none: [section one]\ntwo: [section two]" + } + } + } + + @Test + fun multilineSection() { + inlineModelTest( + """ + |/** + | * Summary + | * @one + | * line one + | * line two + | */ + |val property = "test" + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + comments() equals "Summary\none: [line one line two]" + } + } + } + +// @Test todo + fun directive() { + inlineModelTest( + """ + |/** + | * Summary + | * + | * @sample example1 + | * @sample example2 + | * @sample X.example3 + | * @sample X.Y.example4 + | */ + |val property = "test" + | + |fun example1(node: String) = if (true) { + | println(property) + |} + | + |fun example2(node: String) { + | if (true) { + | println(property) + | } + |} + | + |class X { + | fun example3(node: String) { + | if (true) { + | println(property) + | } + | } + | + | class Y { + | fun example4(node: String) { + | if (true) { + | println(property) + | } + | } + | } + |} + """ + ) { + with((this / "comment" / "property").cast<DProperty>()) { + this + } + } + } + + +// @Test fun directive() { +// checkSourceExistsAndVerifyModel("testdata/comments/directive.kt", defaultModelConfig) { model -> +// with(model.members.single().members.first()) { +// assertEquals("Summary", content.summary.toTestString()) +// with (content.description) { +// assertEqualsIgnoringSeparators(""" +// |[code lang=kotlin] +// |if (true) { +// | println(property) +// |} +// |[/code] +// |[code lang=kotlin] +// |if (true) { +// | println(property) +// |} +// |[/code] +// |[code lang=kotlin] +// |if (true) { +// | println(property) +// |} +// |[/code] +// |[code lang=kotlin] +// |if (true) { +// | println(property) +// |} +// |[/code] +// |""".trimMargin(), toTestString()) +// } +// } +// } +// } + +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/model/FunctionsTest.kt b/plugins/base/src/test/kotlin/model/FunctionsTest.kt new file mode 100644 index 00000000..c96e7df6 --- /dev/null +++ b/plugins/base/src/test/kotlin/model/FunctionsTest.kt @@ -0,0 +1,396 @@ +package model + +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.model.* +import org.junit.jupiter.api.Test +import utils.AbstractModelTest +import utils.assertNotNull +import utils.comments +import utils.name + +class FunctionTest : AbstractModelTest("/src/main/kotlin/function/Test.kt", "function") { + + @Test + fun function() { + inlineModelTest( + """ + |/** + | * Function fn + | */ + |fun fn() {} + """ + ) { + with((this / "function" / "fn").cast<DFunction>()) { + name equals "fn" + type.name equals "Unit" + this.children.assertCount(0, "Function children: ") + } + } + } + + @Test + fun overloads() { + inlineModelTest( + """ + |/** + | * Function fn + | */ + |fun fn() {} + | /** + | * Function fn(Int) + | */ + |fun fn(i: Int) {} + """ + ) { + with((this / "function").cast<DPackage>()) { + val fn1 = functions.find { + it.name == "fn" && it.parameters.isNullOrEmpty() + }.assertNotNull("fn()") + val fn2 = functions.find { + it.name == "fn" && it.parameters.isNotEmpty() + }.assertNotNull("fn(Int)") + + with(fn1) { + name equals "fn" + parameters.assertCount(0) + } + + with(fn2) { + name equals "fn" + parameters.assertCount(1) + parameters.first().type.name equals "Int" + } + } + } + } + + @Test + fun functionWithReceiver() { + inlineModelTest( + """ + |/** + | * Function with receiver + | */ + |fun String.fn() {} + | + |/** + | * Function with receiver + | */ + |fun String.fn(x: Int) {} + """ + ) { + with((this / "function").cast<DPackage>()) { + val fn1 = functions.find { + it.name == "fn" && it.parameters.isNullOrEmpty() + }.assertNotNull("fn()") + val fn2 = functions.find { + it.name == "fn" && it.parameters.count() == 1 + }.assertNotNull("fn(Int)") + + with(fn1) { + name equals "fn" + parameters counts 0 + receiver.assertNotNull("fn() receiver") + } + + with(fn2) { + name equals "fn" + parameters counts 1 + receiver.assertNotNull("fn(Int) receiver") + parameters.first().type.name equals "Int" + } + } + } + } + + @Test + fun functionWithParams() { + inlineModelTest( + """ + |/** + | * Multiline + | * + | * Function + | * Documentation + | */ + |fun function(/** parameter */ x: Int) { + |} + """ + ) { + with((this / "function" / "function").cast<DFunction>()) { + comments() equals "Multiline\nFunction Documentation" + + name equals "function" + parameters counts 1 + parameters.firstOrNull().assertNotNull("Parameter: ").also { + it.name equals "x" + it.type.name equals "Int" + it.comments() equals "parameter" + } + + type.assertNotNull("Return type: ").name equals "Unit" + } + } + } + + @Test + fun functionWithNotDocumentedAnnotation() { + inlineModelTest( + """ + |@Suppress("FOO") fun f() {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "Suppress" + params.entries counts 1 + (params["names"].assertNotNull("param") as ArrayValue).value equals listOf(StringValue("\"FOO\"")) + } + } + } + } + } + + @Test + fun inlineFunction() { + inlineModelTest( + """ + |inline fun f(a: () -> String) {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + extra[AdditionalModifiers]!!.content.entries.single().value counts 1 + extra[AdditionalModifiers]!!.content.entries.single().value exists ExtraModifiers.KotlinOnlyModifiers.Inline + } + } + } + + @Test + fun suspendFunction() { + inlineModelTest( + """ + |suspend fun f() {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + extra[AdditionalModifiers]!!.content.entries.single().value counts 1 + extra[AdditionalModifiers]!!.content.entries.single().value exists ExtraModifiers.KotlinOnlyModifiers.Suspend + } + } + } + + @Test + fun suspendInlineFunctionOrder() { + inlineModelTest( + """ + |suspend inline fun f(a: () -> String) {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + extra[AdditionalModifiers]!!.content.entries.single().value counts 2 + extra[AdditionalModifiers]!!.content.entries.single().value exists ExtraModifiers.KotlinOnlyModifiers.Suspend + extra[AdditionalModifiers]!!.content.entries.single().value exists ExtraModifiers.KotlinOnlyModifiers.Inline + } + } + } + + @Test + fun inlineSuspendFunctionOrderChanged() { + inlineModelTest( + """ + |inline suspend fun f(a: () -> String) {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + with(extra[AdditionalModifiers]!!.content.entries.single().value.assertNotNull("AdditionalModifiers")) { + this counts 2 + this exists ExtraModifiers.KotlinOnlyModifiers.Suspend + this exists ExtraModifiers.KotlinOnlyModifiers.Inline + } + } + } + } + + @Test + fun functionWithAnnotatedParam() { + inlineModelTest( + """ + |@Target(AnnotationTarget.VALUE_PARAMETER) + |@Retention(AnnotationRetention.SOURCE) + |@MustBeDocumented + |public annotation class Fancy + | + |fun function(@Fancy notInlined: () -> Unit) {} + """ + ) { + with((this / "function" / "Fancy").cast<DAnnotation>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 3 + with(map { it.dri.classNames to it }.toMap()) { + with(this["Target"].assertNotNull("Target")) { + (params["allowedTargets"].assertNotNull("allowedTargets") as ArrayValue).value equals listOf( + EnumValue( + "AnnotationTarget.VALUE_PARAMETER", + DRI("kotlin.annotation", "AnnotationTarget.VALUE_PARAMETER") + ) + ) + } + with(this["Retention"].assertNotNull("Retention")) { + (params["value"].assertNotNull("value") as EnumValue) equals EnumValue( + "AnnotationRetention.SOURCE", + DRI("kotlin.annotation", "AnnotationRetention.SOURCE") + ) + } + this["MustBeDocumented"].assertNotNull("MustBeDocumented").params.entries counts 0 + } + } + + } + with((this / "function" / "function" / "notInlined").cast<DParameter>()) { + with(this.extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "Fancy" + params.entries counts 0 + } + } + } + } + } + + @Test + fun functionWithNoinlineParam() { + inlineModelTest( + """ + |fun f(noinline notInlined: () -> Unit) {} + """ + ) { + with((this / "function" / "f" / "notInlined").cast<DParameter>()) { + extra[AdditionalModifiers]!!.content.entries.single().value counts 1 + extra[AdditionalModifiers]!!.content.entries.single().value exists ExtraModifiers.KotlinOnlyModifiers.NoInline + } + } + } + + @Test + fun annotatedFunctionWithAnnotationParameters() { + inlineModelTest( + """ + |@Target(AnnotationTarget.VALUE_PARAMETER) + |@Retention(AnnotationRetention.SOURCE) + |@MustBeDocumented + |public annotation class Fancy(val size: Int) + | + |@Fancy(1) fun f() {} + """ + ) { + with((this / "function" / "Fancy").cast<DAnnotation>()) { + constructors counts 1 + with(constructors.first()) { + parameters counts 1 + with(parameters.first()) { + type.name equals "Int" + name equals "size" + } + } + + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 3 + with(map { it.dri.classNames to it }.toMap()) { + with(this["Target"].assertNotNull("Target")) { + (params["allowedTargets"].assertNotNull("allowedTargets") as ArrayValue).value equals listOf( + EnumValue( + "AnnotationTarget.VALUE_PARAMETER", + DRI("kotlin.annotation", "AnnotationTarget.VALUE_PARAMETER") + ) + ) + } + with(this["Retention"].assertNotNull("Retention")) { + (params["value"].assertNotNull("value") as EnumValue) equals EnumValue( + "AnnotationRetention.SOURCE", + DRI("kotlin.annotation", "AnnotationRetention.SOURCE") + ) + } + this["MustBeDocumented"].assertNotNull("MustBeDocumented").params.entries counts 0 + } + } + + } + with((this / "function" / "f").cast<DFunction>()) { + with(this.extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(this.first()) { + dri.classNames equals "Fancy" + params.entries counts 1 + (params["size"] as StringValue).value equals "1" + } + } + } + } + } + + @Test + fun functionWithDefaultStringParameter() { + inlineModelTest( + """ + |/src/main/kotlin/function/Test.kt + |package function + |fun f(x: String = "") {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + parameters.forEach { p -> + p.name equals "x" + p.type.name.assertNotNull("Parameter type: ") equals "String" + p.extra[DefaultValue]?.value equals "\"\"" + } + } + } + } + + @Test + fun functionWithDefaultFloatParameter() { + inlineModelTest( + """ + |/src/main/kotlin/function/Test.kt + |package function + |fun f(x: Float = 3.14f) {} + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + parameters.forEach { p -> + p.name equals "x" + p.type.name.assertNotNull("Parameter type: ") equals "Float" + p.extra[DefaultValue]?.value equals "3.14f" + } + } + } + } + + @Test + fun sinceKotlin() { + inlineModelTest( + """ + |/** + | * Quite useful [String] + | */ + |@SinceKotlin("1.1") + |fun f(): String = "1.1 rulezz" + """ + ) { + with((this / "function" / "f").cast<DFunction>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "SinceKotlin" + params.entries counts 1 + (params["version"].assertNotNull("version") as StringValue).value equals "\"1.1\"" + } + } + } + } + } + +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/model/InheritorsTest.kt b/plugins/base/src/test/kotlin/model/InheritorsTest.kt new file mode 100644 index 00000000..503cf50c --- /dev/null +++ b/plugins/base/src/test/kotlin/model/InheritorsTest.kt @@ -0,0 +1,95 @@ +package model + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.base.transformers.documentables.InheritorsExtractorTransformer +import org.jetbrains.dokka.base.transformers.documentables.InheritorsInfo +import org.jetbrains.dokka.model.DInterface +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import utils.AbstractModelTest +import utils.assertNotNull + +class InheritorsTest : AbstractModelTest("/src/main/kotlin/inheritors/Test.kt", "inheritors") { + + object InheritorsPlugin : DokkaPlugin() { + val inheritors by extending { + CoreExtensions.documentableTransformer with InheritorsExtractorTransformer() + } + } + + @Disabled("reenable after fixing subtypes") + @Test + fun simple() { + inlineModelTest( + """|interface A{} + |class B() : A {} + """.trimMargin(), + pluginsOverrides = listOf(InheritorsPlugin) + ) { + with((this / "inheritors" / "A").cast<DInterface>()) { + val map = extra[InheritorsInfo].assertNotNull("InheritorsInfo").value + with(map.keys.also { it counts 1 }.find { it.analysisPlatform == Platform.jvm }.assertNotNull("jvm key").let { map[it]!! } + ) { + this counts 1 + first().classNames equals "B" + } + } + } + } + + @Disabled("reenable after fixing subtypes") + @Test + fun multiplatform() { + val configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("common/src/", "jvm/src/") + analysisPlatform = "jvm" + } + sourceSet { + sourceRoots = listOf("common/src/", "js/src/") + analysisPlatform = "js" + } + } + } + + testInline( + """ + |/common/src/main/kotlin/inheritors/Test.kt + |package inheritors + |interface A{} + |/jvm/src/main/kotlin/inheritors/Test.kt + |package inheritors + |class B() : A {} + |/js/src/main/kotlin/inheritors/Test.kt + |package inheritors + |class B() : A {} + |class C() : A {} + """.trimMargin(), + configuration, + cleanupOutput = false, + pluginOverrides = listOf(InheritorsPlugin) + ) { + documentablesTransformationStage = { m -> + with((m / "inheritors" / "A").cast<DInterface>()) { + val map = extra[InheritorsInfo].assertNotNull("InheritorsInfo").value + with(map.keys.also { it counts 2 }) { + with(find { it.analysisPlatform == Platform.jvm }.assertNotNull("jvm key").let { map[it]!! }) { + this counts 1 + first().classNames equals "B" + } + with(find { it.analysisPlatform == Platform.js }.assertNotNull("js key").let { map[it]!! }) { + this counts 2 + val classes = listOf("B", "C") + assertTrue(all { classes.contains(it.classNames) }, "One of subclasses missing in js" ) + } + } + + } + } + } + } +} diff --git a/plugins/base/src/test/kotlin/model/JavaTest.kt b/plugins/base/src/test/kotlin/model/JavaTest.kt new file mode 100644 index 00000000..1f042304 --- /dev/null +++ b/plugins/base/src/test/kotlin/model/JavaTest.kt @@ -0,0 +1,346 @@ +package model + +import org.jetbrains.dokka.base.transformers.documentables.InheritorsInfo +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.links.sureClassNames +import org.jetbrains.dokka.model.* +import org.jetbrains.dokka.model.doc.Param +import org.jetbrains.dokka.model.doc.Text +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import utils.AbstractModelTest +import utils.assertNotNull +import utils.name + +class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") { + + @Test + fun function() { + inlineModelTest( + """ + |class Test { + | /** + | * Summary for Function + | * @param name is String parameter + | * @param value is int parameter + | */ + | public void fn(String name, int value) {} + |} + """ + ) { + with((this / "java" / "Test").cast<DClass>()) { + name equals "Test" + children counts 1 + with((this / "fn").cast<DFunction>()) { + name equals "fn" + val params = parameters.map { it.documentation.values.first().children.first() as Param } + params.mapNotNull { it.firstChildOfTypeOrNull<Text>()?.body } equals listOf("is String parameter", "is int parameter") + } + } + } + } + + @Test fun allImplementedInterfacesInJava() { + inlineModelTest( + """ + |interface Highest { } + |interface Lower extends Highest { } + |class Extendable { } + |class Tested extends Extendable implements Lower { } + """){ + with((this / "java" / "Tested").cast<DClass>()){ + extra[ImplementedInterfaces]?.interfaces?.entries?.single()?.value?.map { it.sureClassNames }?.sorted() equals listOf("Highest", "Lower").sorted() + } + } + } + + @Test fun multipleClassInheritanceWithInterface() { + inlineModelTest( + """ + |interface Highest { } + |interface Lower extends Highest { } + |class Extendable { } + |class Tested extends Extendable implements Lower { } + """){ + with((this / "java" / "Tested").cast<DClass>()) { + supertypes.entries.single().value.map { it.dri.sureClassNames to it.kind }.sortedBy { it.first } equals listOf("Extendable" to JavaClassKindTypes.CLASS, "Lower" to JavaClassKindTypes.INTERFACE) + } + } + } + + @Test // todo + fun memberWithModifiers() { + inlineModelTest( + """ + |class Test { + | /** + | * Summary for Function + | * @param name is String parameter + | * @param value is int parameter + | */ + | public void fn(String name, int value) {} + |} + """ + ) { + with((this / "java" / "Test" / "fn").cast<DFunction>()) { + this + } + } + } + + @Test + fun superClass() { + inlineModelTest( + """ + |public class Foo extends Exception implements Cloneable {} + """ + ) { + with((this / "java" / "Foo").cast<DClass>()) { + val sups = listOf("Exception", "Cloneable") + assertTrue( + sups.all { s -> supertypes.values.flatten().any { it.dri.classNames == s } }) + "Foo must extend ${sups.joinToString(", ")}" + } + } + } + + @Test + fun arrayType() { + inlineModelTest( + """ + |class Test { + | public String[] arrayToString(int[] data) { + | return null; + | } + |} + """ + ) { + with((this / "java" / "Test").cast<DClass>()) { + name equals "Test" + children counts 1 + + with((this / "arrayToString").cast<DFunction>()) { + name equals "arrayToString" + type.name equals "Array" + with(parameters.firstOrNull().assertNotNull("parameters")) { + name equals "data" + type.name equals "Array" + } + } + } + } + } + + @Test + fun typeParameter() { + inlineModelTest( + """ + |class Foo<T extends Comparable<T>> { + | public <E> E foo(); + |} + """ + ) { + with((this / "java" / "Foo").cast<DClass>()) { + generics counts 1 + } + } + } + + @Test + fun constructors() { + inlineModelTest( + """ + |class Test { + | public Test() {} + | + | public Test(String s) {} + |} + """ + ) { + with((this / "java" / "Test").cast<DClass>()) { + name equals "Test" + + constructors counts 2 + constructors.find { it.parameters.isNullOrEmpty() }.assertNotNull("Test()") + + with(constructors.find { it.parameters.isNotEmpty() }.assertNotNull("Test(String)")) { + parameters.firstOrNull()?.type?.name equals "String" + } + } + } + } + + @Test + fun innerClass() { + inlineModelTest( + """ + |class InnerClass { + | public class D {} + |} + """ + ) { + with((this / "java" / "InnerClass").cast<DClass>()) { + children counts 1 + with((this / "D").cast<DClass>()) { + name equals "D" + children counts 0 + } + } + } + } + + @Test + fun varargs() { + inlineModelTest( + """ + |class Foo { + | public void bar(String... x); + |} + """ + ) { + with((this / "java" / "Foo").cast<DClass>()) { + name equals "Foo" + children counts 1 + + with((this / "bar").cast<DFunction>()) { + name equals "bar" + with(parameters.firstOrNull().assertNotNull("parameter")) { + name equals "x" + type.name equals "Array" + } + } + } + } + } + + @Test // todo + fun fields() { + inlineModelTest( + """ + |class Test { + | public int i; + | public static final String s; + |} + """ + ) { + with((this / "java" / "Test").cast<DClass>()) { + children counts 2 + + with((this / "i").cast<DProperty>()) { + getter equals null + setter equals null + } + + with((this / "s").cast<DProperty>()) { + getter equals null + setter equals null + } + } + } + } + + @Test + fun staticMethod() { + inlineModelTest( + """ + |class C { + | public static void foo() {} + |} + """ + ) { + with((this / "java" / "C" / "foo").cast<DFunction>()) { + with(extra[AdditionalModifiers]!!.content.entries.single().value.assertNotNull("AdditionalModifiers")) { + this counts 1 + first() equals ExtraModifiers.JavaOnlyModifiers.Static + } + } + } + } + + @Test + fun annotatedAnnotation() { + inlineModelTest( + """ + |import java.lang.annotation.*; + | + |@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) + |public @interface Attribute { + | String value() default ""; + |} + """ + ) { + with((this / "java" / "Attribute").cast<DAnnotation>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + with(single()) { + dri.classNames equals "Target" + (params["value"].assertNotNull("value") as ArrayValue).value equals listOf( + EnumValue("ElementType.FIELD", DRI("java.lang.annotation", "ElementType")), + EnumValue("ElementType.TYPE", DRI("java.lang.annotation", "ElementType")), + EnumValue("ElementType.METHOD", DRI("java.lang.annotation", "ElementType")) + ) + } + } + } + } + } + + @Test + fun javaLangObject() { + inlineModelTest( + """ + |class Test { + | public Object fn() { return null; } + |} + """ + ) { + with((this / "java" / "Test" / "fn").cast<DFunction>()) { + assertTrue(type is JavaObject) + } + } + } + + @Test + fun enumValues() { + inlineModelTest( + """ + |enum E { + | Foo + |} + """ + ) { + with((this / "java" / "E").cast<DEnum>()) { + name equals "E" + entries counts 1 + + with((this / "Foo").cast<DEnumEntry>()) { + name equals "Foo" + } + } + } + } + + @Test + fun inheritorLinks() { + inlineModelTest( + """ + |public class InheritorLinks { + | public static class Foo {} + | + | public static class Bar extends Foo {} + |} + """ + ) { + with((this / "java" / "InheritorLinks").cast<DClass>()) { + val dri = (this / "Bar").assertNotNull("Foo dri").dri + with((this / "Foo").cast<DClass>()) { + with(extra[InheritorsInfo].assertNotNull("InheritorsInfo")) { + with(value.values.flatten().distinct()) { + this counts 1 + first() equals dri + } + } + } + } + } + } +} diff --git a/plugins/base/src/test/kotlin/model/PackagesTest.kt b/plugins/base/src/test/kotlin/model/PackagesTest.kt new file mode 100644 index 00000000..86222d95 --- /dev/null +++ b/plugins/base/src/test/kotlin/model/PackagesTest.kt @@ -0,0 +1,134 @@ +package model + +import org.jetbrains.dokka.model.DPackage +import org.junit.jupiter.api.Test +import utils.AbstractModelTest + +class PackagesTest : AbstractModelTest("/src/main/kotlin/packages/Test.kt", "packages") { + + @Test + fun rootPackage() { + inlineModelTest( + """ + | + """.trimIndent(), + prependPackage = false, + configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("src/main/kotlin") + displayName = "JVM" + } + } + } + ) { + with((this / "[JVM root]").cast<DPackage>()) { + name equals "[JVM root]" + children counts 0 + } + } + } + + @Test + fun simpleNamePackage() { + inlineModelTest( + """ + |package simple + """.trimIndent(), + prependPackage = false + ) { + with((this / "simple").cast<DPackage>()) { + name equals "simple" + children counts 0 + } + } + } + + @Test + fun dottedNamePackage() { + inlineModelTest( + """ + |package dot.name + """.trimIndent(), + prependPackage = false + ) { + with((this / "dot.name").cast<DPackage>()) { + name equals "dot.name" + children counts 0 + } + } + + } + + @Test + fun multipleFiles() { + inlineModelTest( + """ + |package dot.name + |/src/main/kotlin/packages/Test2.kt + |package simple + """.trimIndent(), + prependPackage = false + ) { + children counts 2 + with((this / "dot.name").cast<DPackage>()) { + name equals "dot.name" + children counts 0 + } + with((this / "simple").cast<DPackage>()) { + name equals "simple" + children counts 0 + } + } + } + + @Test + fun multipleFilesSamePackage() { + inlineModelTest( + """ + |package simple + |/src/main/kotlin/packages/Test2.kt + |package simple + """.trimIndent(), + prependPackage = false + ) { + children counts 1 + with((this / "simple").cast<DPackage>()) { + name equals "simple" + children counts 0 + } + } + } + + @Test + fun classAtPackageLevel() { + inlineModelTest( + """ + |package simple.name + | + |class Foo {} + """.trimIndent(), + prependPackage = false + ) { + with((this / "simple.name").cast<DPackage>()) { + name equals "simple.name" + children counts 1 + } + } + } + + // todo +// @Test fun suppressAtPackageLevel() { +// verifyModel( +// ModelConfig( +// roots = arrayOf(KotlinSourceRoot("testdata/packages/classInPackage.kt", false)), +// perPackageOptions = listOf( +// PackageOptionsImpl(prefix = "simple.name", suppress = true) +// ), +// analysisPlatform = analysisPlatform +// ) +// ) { model -> +// assertEquals(0, model.members.count()) +// } +// } +}
\ No newline at end of file diff --git a/plugins/base/src/test/kotlin/model/PropertyTest.kt b/plugins/base/src/test/kotlin/model/PropertyTest.kt new file mode 100644 index 00000000..af952b43 --- /dev/null +++ b/plugins/base/src/test/kotlin/model/PropertyTest.kt @@ -0,0 +1,265 @@ +package model + +import org.jetbrains.dokka.model.* +import org.junit.jupiter.api.Test +import utils.AbstractModelTest +import utils.assertNotNull +import utils.name + +class PropertyTest : AbstractModelTest("/src/main/kotlin/property/Test.kt", "property") { + + @Test + fun valueProperty() { + inlineModelTest( + """ + |val property = "test"""" + ) { + with((this / "property" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + with(getter.assertNotNull("Getter")) { + type.name equals "String" + } + type.name equals "String" + } + } + } + + @Test + fun variableProperty() { + inlineModelTest( + """ + |var property = "test" + """ + ) { + with((this / "property" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + setter.assertNotNull("Setter") + with(getter.assertNotNull("Getter")) { + type.name equals "String" + } + type.name equals "String" + } + } + } + + @Test + fun valuePropertyWithGetter() { + inlineModelTest( + """ + |val property: String + | get() = "test" + """ + ) { + with((this / "property" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + with(getter.assertNotNull("Getter")) { + type.name equals "String" + } + type.name equals "String" + } + } + } + + @Test + fun variablePropertyWithAccessors() { + inlineModelTest( + """ + |var property: String + | get() = "test" + | set(value) {} + """ + ) { + with((this / "property" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + setter.assertNotNull("Setter") + with(getter.assertNotNull("Getter")) { + type.name equals "String" + } + visibility.values allEquals KotlinVisibility.Public + } + } + } + + @Test + fun propertyWithReceiver() { + inlineModelTest( + """ + |val String.property: Int + | get() = size() * 2 + """ + ) { + with((this / "property" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + with(receiver.assertNotNull("property receiver")) { + name equals null + type.name equals "String" + } + with(getter.assertNotNull("Getter")) { + type.name equals "Int" + } + visibility.values allEquals KotlinVisibility.Public + } + } + } + + @Test + fun propertyOverride() { + inlineModelTest( + """ + |open class Foo() { + | open val property: Int get() = 0 + |} + |class Bar(): Foo() { + | override val property: Int get() = 1 + |} + """ + ) { + with((this / "property").cast<DPackage>()) { + with((this / "Foo" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + with(getter.assertNotNull("Getter")) { + type.name equals "Int" + } + } + with((this / "Bar" / "property").cast<DProperty>()) { + name equals "property" + children counts 0 + with(getter.assertNotNull("Getter")) { + type.name equals "Int" + } + } + } + } + } + + @Test + fun sinceKotlin() { + inlineModelTest( + """ + |/** + | * Quite useful [String] + | */ + |@SinceKotlin("1.1") + |val prop: String = "1.1 rulezz" + """ + ) { + with((this / "property" / "prop").cast<DProperty>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "SinceKotlin" + params.entries counts 1 + (params["version"].assertNotNull("version") as StringValue).value equals "\"1.1\"" + } + } + } + } + } + + @Test + fun annotatedProperty() { + inlineModelTest( + """ + |@Strictfp var property = "test" + """, + configuration = dokkaConfiguration { + sourceSets { + sourceSet { + sourceRoots = listOf("src/") + classpath = listOfNotNull(jvmStdlibPath) + } + } + } + ) { + with((this / "property" / "property").cast<DProperty>()) { + with(extra[Annotations]!!.content.entries.single().value.assertNotNull("Annotations")) { + this counts 1 + with(first()) { + dri.classNames equals "Strictfp" + params.entries counts 0 + } + } + } + } + } + + @Test fun genericTopLevelExtensionProperty(){ + inlineModelTest( + """ | val <T : Number> List<T>.sampleProperty: T + | get() { TODO() } + """.trimIndent() + ){ + with((this / "property" / "sampleProperty").cast<DProperty>()) { + name equals "sampleProperty" + with(receiver.assertNotNull("Property receiver")) { + type.name equals "List" + } + with(getter.assertNotNull("Getter")) { + type.name equals "T" + } + setter equals null + generics counts 1 + generics.forEach { + it.name equals "T" + it.bounds.first().name equals "Number" + } + visibility.values allEquals KotlinVisibility.Public + } + } + } + + @Test fun genericExtensionPropertyInClass(){ + inlineModelTest( + """ | package test + | class XD<T> { + | var List<T>.sampleProperty: T + | get() { TODO() } + | set(value) { TODO() } + | } + """.trimIndent() + ){ + with((this / "property" / "XD" / "sampleProperty").cast<DProperty>()) { + name equals "sampleProperty" + children counts 0 + with(receiver.assertNotNull("Property receiver")) { + type.name equals "List" + } + with(getter.assertNotNull("Getter")) { + type.name equals "T" + } + with(setter.assertNotNull("Setter")){ + type.name equals "Unit" + } + generics counts 0 + visibility.values allEquals KotlinVisibility.Public + } + } + } +// @Test +// fun annotatedProperty() { +// checkSourceExistsAndVerifyModel( +// "testdata/properties/annotatedProperty.kt", +// modelConfig = ModelConfig( +// analysisPlatform = analysisPlatform, +// withKotlinRuntime = true +// ) +// ) { model -> +// with(model.members.single().members.single()) { +// Assert.assertEquals(1, annotations.count()) +// with(annotations[0]) { +// Assert.assertEquals("Strictfp", name) +// Assert.assertEquals(Content.Empty, content) +// Assert.assertEquals(NodeKind.Annotation, kind) +// } +// } +// } +// } +// +//} +} |