Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jvmTest.plot.builder.interact.TestUtil.kt Maven / Gradle / Ivy
/*
* Copyright (c) 2019. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/
package jetbrains.datalore.plot.builder.interact
import jetbrains.datalore.base.function.Functions.identity
import jetbrains.datalore.base.geometry.DoubleRectangle
import jetbrains.datalore.base.geometry.DoubleVector
import jetbrains.datalore.base.values.FontFace
import jetbrains.datalore.base.values.FontFamily
import jetbrains.datalore.plot.base.Aes
import jetbrains.datalore.plot.base.GeomKind
import jetbrains.datalore.plot.base.interact.*
import jetbrains.datalore.plot.base.interact.GeomTargetCollector.TooltipParams
import jetbrains.datalore.plot.base.interact.GeomTargetLocator.*
import jetbrains.datalore.plot.builder.interact.MappedDataAccessMock.Companion.variable
import jetbrains.datalore.plot.builder.interact.MappedDataAccessMock.Mapping
import jetbrains.datalore.plot.builder.interact.loc.TargetPrototype
import jetbrains.datalore.plot.builder.layout.Margins
import jetbrains.datalore.plot.builder.layout.TextJustification
import jetbrains.datalore.plot.builder.presentation.Defaults
import jetbrains.datalore.plot.builder.presentation.Defaults.Common.Tooltip.AXIS_TOOLTIP_COLOR
import jetbrains.datalore.plot.builder.presentation.Defaults.Common.Tooltip.LIGHT_TEXT_COLOR
import jetbrains.datalore.plot.builder.theme.AxisTheme
import jetbrains.datalore.plot.builder.theme.ThemeTextStyle
import org.assertj.core.api.Condition
import org.mockito.Mockito.mock
import kotlin.test.assertEquals
import kotlin.test.assertTrue
object TestUtil {
val axisTheme = object : AxisTheme {
override val axis: String
get() = TODO("Not yet implemented")
override fun showLine() = TODO("Not yet implemented")
override fun showTickMarks() = TODO("Not yet implemented")
override fun showLabels() = TODO("Not yet implemented")
override fun showTitle() = TODO("Not yet implemented")
override fun showTooltip() = TODO("Not yet implemented")
override fun titleStyle(): ThemeTextStyle = TODO("Not yet implemented")
override fun titleJustification() = TextJustification(0.5, 1.0)
override fun titleMargins() = Margins()
override fun lineWidth() = TODO("Not yet implemented")
override fun lineColor() = TODO("Not yet implemented")
override fun tickMarkColor() = TODO("Not yet implemented")
override fun labelStyle(): ThemeTextStyle = TODO("Not yet implemented")
override fun rotateLabels() = TODO("Not yet implemented")
override fun labelAngle(): Double = TODO("Not yet implemented")
override fun tickMarkWidth() = TODO("Not yet implemented")
override fun tickMarkLength() = TODO("Not yet implemented")
override fun tickLabelMargins() = Margins()
override fun tooltipFill() = AXIS_TOOLTIP_COLOR
override fun tooltipColor() = AXIS_TOOLTIP_COLOR
override fun tooltipStrokeWidth() = 1.0
override fun tooltipTextStyle(): ThemeTextStyle = ThemeTextStyle(
// Defaults.FONT_FAMILY_NORMAL,
FontFamily.SERIF,
FontFace.NORMAL,
Defaults.Common.Tooltip.AXIS_TOOLTIP_FONT_SIZE,
LIGHT_TEXT_COLOR
)
}
private const val VARIABLE_NAME = "A"
private const val VARIABLE_VALUE = "value"
internal fun continuous(aes: Aes): Mapping {
return mappedData(aes, true)
}
internal fun discrete(aes: Aes): Mapping {
return mappedData(aes, false)
}
private fun mappedData(aes: Aes, isContinuous: Boolean): Mapping {
return variable().name(VARIABLE_NAME).value(VARIABLE_VALUE).isContinuous(isContinuous).mapping(aes)
}
internal fun assertText(tooltipSpecs: List, vararg expectedTooltipText: String) {
assertText(tooltipSpecs, listOf(*expectedTooltipText))
}
@SafeVarargs
internal fun assertText(tooltipSpecs: List, vararg expectedTooltips: List) {
assertEquals(expectedTooltips.size.toLong(), tooltipSpecs.size.toLong())
var i = 0
val n = tooltipSpecs.size
while (i < n) {
val tooltipText = tooltipSpecs[i].lines.map(TooltipSpec.Line::toString)
assertListsEqual(expectedTooltips[i], tooltipText)
++i
}
}
private fun assertListsEqual(expected: List, actual: List) {
assertEquals(expected.size.toLong(), actual.size.toLong())
var i = 0
val n = expected.size
while (i < n) {
assertEquals(expected[i], actual[i])
++i
}
}
internal fun assertNoTooltips(tooltipSpecs: List) {
assertTrue(tooltipSpecs.isEmpty())
}
private const val OUTSIDE_DELTA = 10.0
private const val PATH_POINTS_COUNT_PER_KEY = 100
internal fun createLocator(
lookupStrategy: LookupStrategy,
lookupSpace: LookupSpace,
vararg list: TargetPrototype
): GeomTargetLocator {
val targetsList = ArrayList()
targetsList.addAll(list)
return createLocator(
lookupSpec = LookupSpec(lookupSpace, lookupStrategy),
contextualMapping = mock(ContextualMapping::class.java),
targetPrototypes = targetsList
)
}
internal fun createLocator(
lookupSpec: LookupSpec,
contextualMapping: ContextualMapping,
targetPrototypes: List,
geomKind: GeomKind = GeomKind.POINT
): GeomTargetLocator {
return jetbrains.datalore.plot.builder.interact.loc.LayerTargetLocator(
geomKind,
lookupSpec,
contextualMapping,
targetPrototypes
)
}
fun coord(x: Double, y: Double): DoubleVector {
return DoubleVector(x, y)
}
fun size(width: Double, height: Double): DoubleVector {
return DoubleVector(width, height)
}
fun rect(pos: DoubleVector, dim: DoubleVector): DoubleRectangle {
return DoubleRectangle(pos, dim)
}
internal fun outsideX(rect: DoubleRectangle): DoubleVector {
return rect.center.add(
point(
rect.width / 2 + OUTSIDE_DELTA,
0.0
)
)
}
internal fun outsideX(rect: DoubleRectangle, delta: Double): DoubleVector {
return rect.origin.add(point(rect.right + delta, 0.0))
}
internal fun outsideY(rect: DoubleRectangle): DoubleVector {
return rect.center.add(
point(
0.0,
rect.height / 2 + OUTSIDE_DELTA
)
)
}
internal fun outsideXY(rect: DoubleRectangle): DoubleVector {
return rect.center.add(
point(
rect.width + OUTSIDE_DELTA,
rect.height / 2 + OUTSIDE_DELTA
)
)
}
private fun betweenX(rect1: DoubleRectangle, rect2: DoubleRectangle): Double {
return between(rect1.left, rect2.left)
}
private fun betweenY(rect1: DoubleRectangle, rect2: DoubleRectangle): Double {
return between(rect1.top, rect2.top)
}
internal fun between(rect1: DoubleRectangle, rect2: DoubleRectangle): DoubleVector {
return DoubleVector(
betweenX(rect1, rect2),
betweenY(rect1, rect2)
)
}
internal fun between(v1: Double, v2: Double): Double {
if (v1 > v2) {
throw IllegalArgumentException()
}
return v1 + (v2 - v1)
}
internal fun middle(v1: Double, v2: Double): Double {
val halfLength = (v2 - v1) / 2
return v1 + halfLength
}
internal fun inside(rect: DoubleRectangle): DoubleVector {
return rect.center
}
internal fun offsetX(p: DoubleVector): DoubleVector {
return p.add(
point(
OUTSIDE_DELTA,
0.0
)
)
}
internal fun offsetX(p: DoubleVector, delta: Double): DoubleVector {
return p.add(point(delta, 0.0))
}
internal fun offsetY(p: DoubleVector): DoubleVector {
return p.add(
point(
0.0,
OUTSIDE_DELTA
)
)
}
internal fun offsetXY(p: DoubleVector): DoubleVector {
return p.add(
point(
OUTSIDE_DELTA,
OUTSIDE_DELTA
)
)
}
internal fun first(collection: List): T {
return collection[0]
}
internal fun last(collection: List): T {
return collection[collection.size - 1]
}
internal fun map(collection: Collection, mapFunction: (T) -> R): List {
val result = ArrayList()
for (item in collection) {
result.add(mapFunction(item))
}
return result
}
internal fun findTargets(locator: GeomTargetLocator, p: DoubleVector): List {
return getGeomTargets(locator.search(p))
}
internal fun assertEncodedObjects(locator: GeomTargetLocator, coord: DoubleVector, vararg key: Any) {
assertObjects(true, locator, coord, *key)
}
internal fun assertObjects(locator: GeomTargetLocator, coord: DoubleVector, vararg key: Any) {
assertObjects(false, locator, coord, *key)
}
private fun assertObjects(encoded: Boolean, locator: GeomTargetLocator, coord: DoubleVector, vararg key: Any) {
val decode = if (encoded) { it -> decodeKey(it) } else identity()
val located = getGeomTargets(locator.search(coord))
assertEquals(key.size, located.size)
var i = 0
val n = key.size
while (i < n) {
val geomTarget = located[i]
assertEquals(key[i], decode(geomTarget.hitIndex), "Hit index: $i")
i++
}
}
private fun getGeomTargets(result: LookupResult?): List {
return result?.targets ?: emptyList()
}
internal fun assertEmpty(locator: GeomTargetLocator, coord: DoubleVector) {
val located = getGeomTargets(locator.search(coord))
assertTrue(located.isEmpty())
}
internal fun rectTarget(key: Any, rect: DoubleRectangle): TargetPrototype {
val rectShape = HitShape.rect(rect)
return TargetPrototype(
rectShape, { key as Int },
TooltipParams(), TipLayoutHint.Kind.HORIZONTAL_TOOLTIP
)
}
internal fun pointTarget(key: Any, p: DoubleVector): TargetPrototype {
val pointShape = HitShape.point(p, 0.0)
return TargetPrototype(
pointShape, { key as Int },
TooltipParams(), TipLayoutHint.Kind.VERTICAL_TOOLTIP
)
}
internal fun pathTarget(key: Int, points: List): TargetPrototype {
val pathShape = HitShape.path(points)
return TargetPrototype(pathShape, { hitIndex ->
encodeIndex(
key,
hitIndex
)
}, TooltipParams(), TipLayoutHint.Kind.HORIZONTAL_TOOLTIP)
}
internal fun pathTarget(points: List): TargetPrototype {
val pathShape = HitShape.path(points)
return TargetPrototype(pathShape, identity(), TooltipParams(), TipLayoutHint.Kind.HORIZONTAL_TOOLTIP)
}
private fun encodeIndex(key: Int, integer: Int?): Int {
return key * PATH_POINTS_COUNT_PER_KEY + integer!!
}
private fun decodeKey(index: Int?): Int {
return index!! / PATH_POINTS_COUNT_PER_KEY
}
private fun decodeIndex(index: Int?): Int {
return index!! % PATH_POINTS_COUNT_PER_KEY
}
internal fun pathTarget(points: List, indexMapper: (Int) -> Int): TargetPrototype {
val pathShape = HitShape.path(points)
return TargetPrototype(pathShape, indexMapper, TooltipParams(), TipLayoutHint.Kind.HORIZONTAL_TOOLTIP)
}
internal fun polygonTarget(key: Int, points: List): TargetPrototype {
val polygonShape = HitShape.polygon(points)
return TargetPrototype(polygonShape, { key }, TooltipParams(), TipLayoutHint.Kind.CURSOR_TOOLTIP)
}
fun point(x: Double, y: Double): DoubleVector {
return DoubleVector(x, y)
}
private fun path(vararg points: DoubleVector): MutableList {
val pointsList = ArrayList()
pointsList.addAll(points)
return pointsList
}
@SafeVarargs
internal fun multipolygon(vararg pointsArray: MutableList): List {
val pointsList = ArrayList()
for (points in pointsArray) {
closePathIfNeeded(points)
pointsList.addAll(points)
}
return pointsList
}
internal fun polygon(vararg points: DoubleVector): MutableList {
val pointsList = path(*points)
closePathIfNeeded(pointsList)
return pointsList
}
private fun closePathIfNeeded(points: MutableList) {
if (points[0] != points[points.size - 1]) {
points.add(points[0])
}
}
internal fun horizontalPath(y: Double, vararg xList: Double): List {
val pathPoints = ArrayList()
for (x in xList) {
pathPoints.add(DoubleVector(x, y))
}
return pathPoints
}
internal fun horizontalPathTarget(key: Int, y: Double, xList: DoubleArray): TargetPrototype {
val pathPoints = horizontalPath(y, *xList)
return pathTarget(key, pathPoints)
}
internal fun pathTarget(key: Int, vararg points: PathPoint): TargetPrototype {
return pathTarget(key, points.map { it.coord })
}
internal class PathPoint(val coord: DoubleVector, val hitIndex: Int) {
val x: Double
get() = coord.x
val y: Double
get() = coord.y
}
internal class PathPointsBuilder {
private var defaultX: Double? = null
private var defaultY: Double? = null
private var counter = 0
fun defaultX(x: Double): PathPointsBuilder {
defaultX = x
return this
}
fun defaultY(y: Double): PathPointsBuilder {
defaultY = y
return this
}
fun x(x: Double): PathPoint {
return PathPoint(DoubleVector(x, defaultY!!), counter++)
}
fun y(y: Double): PathPoint {
return PathPoint(DoubleVector(defaultX!!, y), counter++)
}
fun xy(x: Double, y: Double): PathPoint {
return PathPoint(DoubleVector(x, y), counter++)
}
}
internal class HitIndex(private val myExpected: Int) : Condition() {
override fun matches(geomTarget: GeomTarget): Boolean {
val hitIndex = geomTarget.hitIndex
return myExpected == decodeIndex(hitIndex)
}
companion object {
fun equalTo(expected: Int): HitIndex {
return HitIndex(expected)
}
}
}
}