All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mvysny.kaributesting.v8.PrettyPrintTree.kt Maven / Gradle / Ivy

package com.github.mvysny.kaributesting.v8

import com.vaadin.data.HasValue
import com.vaadin.server.*
import com.vaadin.ui.*
import java.lang.reflect.Field
import java.lang.reflect.Method

import java.util.ArrayList

/**
 * If true, [PrettyPrintTree] will use `\--` instead of `└──` which tend to render on some terminals as `???`.
 */
public var prettyPrintUseAscii: Boolean = false

public class PrettyPrintTree(public val name: String, public val children: MutableList) {

    private val pipe = if (!prettyPrintUseAscii) '│' else '|'
    private val branchTail = if (!prettyPrintUseAscii) "└── " else "\\-- "
    private val branch = if (!prettyPrintUseAscii) "├── " else "|-- "

    public fun print(): String {
        val sb = StringBuilder()
        print(sb, "", true)
        return sb.toString()
    }

    private fun print(sb: StringBuilder, prefix: String, isTail: Boolean) {
        sb.append(prefix + (if (isTail) branchTail else branch) + name + "\n")
        for (i in 0 until children.size - 1) {
            children[i].print(sb, prefix + if (isTail) "    " else "$pipe   ", false)
        }
        if (children.size > 0) {
            children[children.size - 1]
                    .print(sb, prefix + if (isTail) "    " else "$pipe   ", true)
        }
    }

    public companion object {

        public fun ofVaadin(root: Component): PrettyPrintTree {
            val result = PrettyPrintTree(root.toPrettyString(), mutableListOf())
            if (root is HasComponents) {
                for (child in root) {
                    result.children.add(ofVaadin(child))
                }
            }
            return result
        }
    }
}

public fun Component.toPrettyTree(): String = PrettyPrintTree.ofVaadin(this).print()

public fun Component.toPrettyString(): String {
    val list = ArrayList()
    if (id != null) {
        list.add("#$id")
    }
    if (!isVisible) {
        list.add("INVIS")
    }
    if (this is HasValue<*> && this.isReadOnly) {
        list.add("RO")
    }
    if (!isEnabled) {
        list.add("DISABLED")
    }
    if (!styleName.isNullOrBlank()) {
        list.add(this.styleName.split("\\s+".toRegex())
                .map { it.trim() }
                .filter { it.isNotBlank() }.joinToString(" ") { ".$it" }
        )
    }
    if (caption != null) {
        list.add("caption='$caption'")
    }
    if (this is HasValue<*> || this is Label) {
        list.add("value='$value'")
    }
    if (this is AbstractComponent) {
        if (componentError != null) {
            list.add("componentError='${componentError.message}'")
        }
        if (errorMessage != null && errorMessage != componentError) {
            list.add("errorMessage='${errorMessage.message}'")
        }
    }
    if (this is Grid<*>) {
        list.add("columns=[${this.columns.filter { !it.isHidden }.joinToString { "'${it.caption}'" }}]")
    }
    if (this is Link) {
        list.add("href='${resource?.toPrettyString() ?: ""}'")
    }
    if (this is Image) {
        list.add("src='${source?.toPrettyString() ?: ""}'")
    }
    var name = javaClass.simpleName
    if (name.isEmpty()) {
        // anonymous classes
        name = javaClass.name
    }
    return name + list
}

public fun Resource.toPrettyString(): String = when(this) {
    is ExternalResource -> this.url
    is ClassResource -> this.toPrettyString()
    is GenericFontIcon -> "${javaClass.simpleName}[${this.fontFamily}/0x${this.codepoint.toString(16)}]"
    is StreamResource -> "${javaClass.simpleName}[$filename]"
    is FileResource -> "${javaClass.simpleName}[$sourceFile]"
    else -> "${javaClass.simpleName}[$this]"
}

public fun ClassResource.toPrettyString(): String {
    val getAssociatedClassMethod: Method = ClassResource::class.java.getDeclaredMethod("getAssociatedClass").apply { isAccessible = true }
    val associatedClass: Class<*> = getAssociatedClassMethod.invoke(this) as Class<*>
    val resourceNameField: Field = ClassResource::class.java.getDeclaredField("resourceName").apply { isAccessible = true }
    val resourceName: String = resourceNameField.get(this) as String
    return "ClassResource[${associatedClass.name}/$resourceName]"
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy