Files
kotlin-fork/libraries/stdlib/test/properties/delegation/PropertyReferenceTest.kt
T
2020-04-15 18:37:33 +03:00

192 lines
5.8 KiB
Kotlin

/*
* Copyright 2010-2020 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 test.properties.delegation.references
import kotlin.reflect.*
import kotlin.test.*
import kotlin.internal.*
import kotlin.random.*
open class Data(val stringVal: String, var intVar: Int, var builderVar: StringBuilder = StringBuilder("default"))
val Data.formattedVal: String get() = "Hello $stringVal"
var Data.displacedVar: Int
get() = intVar + 2
set(value) { intVar = value - 2 }
val data = Data("bound string", 42)
val topVal: Double get() = 3.14
var topVar: ULong = 0xFFFFUL
// top-level properties
// val to bound val
val tlValBoundVal by data::stringVal
// val to bound var
val tlValBoundVar by data::intVar
// var to bound var
var tlVarBoundVar by data::intVar
// val to top-level val
val tlValTopLevelVal by ::topVal
// val to top-level var
val tlValTopLevelVar by ::topVar
// var to top-level var
var tlVarTopLevelVar by ::topVar
// member properties
class DataExt : Data("member string", -1) {
// val to top-level val
val valTopLevelVal by ::topVal
// val to top-level var
val valTopLevelVar by ::topVar
// var to top-level var
var varTopLevelVar by ::topVar
// val to bound val
val valBoundVal by this::stringVal
// val to bound var
val valBoundVar by data::intVar
// var to bound var
var varBoundVar by ::intVar
// val to extension val
val valExtVal by Data::formattedVal
// val to extension var
val valExtVar by Data::displacedVar
// var to extension var
var varExtVar by Data::displacedVar
}
// extension properties
// val to bound val
val Data.extValBoundVal by data::stringVal
// val to bound var
val Data.extValBoundVar by data::intVar
// var to bound var
var Data.extVarBoundVar by data::intVar
// val to top-level val
val Data.extValTopLevelVal by ::topVal
// val to top-level var
val Data.extValTopLevelVar by ::topVar
// var to top-level var
var Data.extVarTopLevelVar by ::topVar
// val to member val
val Data.extValMemberVal by Data::stringVal
// val to member var
val Data.extValMemberVar by Data::intVar
// var to member var
var Data.extVarMemberVar by Data::intVar
// val to extension val
val Data.extValExtVal by Data::formattedVal
// val to extension var
val Data.extValExtVar by Data::displacedVar
// var to extension var
var Data.extVarExtVar by Data::displacedVar
// covariance
val covariantVal: Number by ::topVal
val Data.extCovariantVal: CharSequence by Data::builderVar
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
class PropertyReferenceTest {
private fun <V> checkDelegate0(delegated: KProperty0<@NoInfer V>, source: KProperty0<V>) {
assertEquals(delegated.get(), source.get())
}
private fun <V> checkDelegate1(delegated: KProperty0<@NoInfer V>, source: KMutableProperty0<V>, newValue: @NoInfer V) {
assertEquals(delegated.get(), source.get())
source.set(newValue)
assertEquals(newValue, source.get())
assertEquals(newValue, delegated.get())
}
private fun <V> checkDelegate2(delegated: KMutableProperty0<@NoInfer V>, source: KMutableProperty0<V>, newValue1: @NoInfer V, newValue2: @NoInfer V) {
assertEquals(delegated.get(), source.get())
source.set(newValue1)
assertEquals(newValue1, source.get())
assertEquals(newValue1, delegated.get())
delegated.set(newValue2)
assertEquals(newValue2, source.get())
assertEquals(newValue2, delegated.get())
}
private fun int(): Int = Random.nextInt()
private fun ulong(): ULong = Random.nextULong()
@Test
fun topLevelProperties() {
checkDelegate0(::tlValBoundVal, data::stringVal)
checkDelegate1(::tlValBoundVar, data::intVar, int())
checkDelegate2(::tlVarBoundVar, data::intVar, int(), int())
checkDelegate0(::tlValTopLevelVal, ::topVal)
checkDelegate1(::tlValTopLevelVar, ::topVar, ulong())
checkDelegate2(::tlVarTopLevelVar, ::topVar, ulong(), ulong())
}
@Test
fun memberProperties() {
val local = DataExt()
checkDelegate0(local::valBoundVal, local::stringVal)
checkDelegate1(local::valBoundVar, data::intVar, int())
checkDelegate2(local::varBoundVar, local::intVar, int(), int())
checkDelegate0(local::valTopLevelVal, ::topVal)
checkDelegate1(local::valTopLevelVar, ::topVar, ulong())
checkDelegate2(local::varTopLevelVar, ::topVar, ulong(), ulong())
checkDelegate0(local::valExtVal, local::formattedVal)
checkDelegate1(local::valExtVar, local::displacedVar, int())
checkDelegate2(local::varExtVar, local::displacedVar, int(), int())
}
@Test
fun extensionProperties() {
val local = Data("ext", Int.MAX_VALUE)
checkDelegate0(local::extValBoundVal, data::stringVal)
checkDelegate1(local::extValBoundVar, data::intVar, int())
checkDelegate2(local::extVarBoundVar, data::intVar, int(), int())
checkDelegate0(local::extValMemberVal, local::stringVal)
checkDelegate1(local::extValMemberVar, local::intVar, int())
checkDelegate2(local::extVarMemberVar, local::intVar, int(), int())
checkDelegate0(local::extValTopLevelVal, ::topVal)
checkDelegate1(local::extValTopLevelVar, ::topVar, ulong())
checkDelegate2(local::extVarTopLevelVar, ::topVar, ulong(), ulong())
checkDelegate0(local::extValExtVal, local::formattedVal)
checkDelegate1(local::extValExtVar, local::displacedVar, int())
checkDelegate2(local::extVarExtVar, local::displacedVar, int(), int())
}
@Test
fun covariantProperties() {
checkDelegate0<Number>(::covariantVal, ::topVal)
checkDelegate0<CharSequence>(data::extCovariantVal, data::builderVar)
}
}