mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
[CORDA-1676] Adjust progress tracking rendering for skipped elements (#4372)
* Adjust styling for flow steps that are skipped
This commit is contained in:
parent
bad7b9b187
commit
f58757bda9
@ -52,8 +52,6 @@ object Emoji {
|
||||
val CODE_DEVELOPER: String = codePointsString(0x1F469, 0x200D, 0x1F4BB)
|
||||
@JvmStatic
|
||||
val CODE_WARNING_SIGN: String = codePointsString(0x26A0, 0xFE0F)
|
||||
@JvmStatic
|
||||
val CROSS_MARK_BUTTON: String = codePointsString(0x274E)
|
||||
|
||||
/**
|
||||
* When non-null, toString() methods are allowed to use emoji in the output as we're going to render them to a
|
||||
@ -81,7 +79,6 @@ object Emoji {
|
||||
val rightArrow: String get() = if (emojiMode.get() != null) "$CODE_RIGHT_ARROW " else "▶︎"
|
||||
val skullAndCrossbones: String get() = if (emojiMode.get() != null) "$CODE_SKULL_AND_CROSSBONES " else "☂"
|
||||
val noEntry: String get() = if (emojiMode.get() != null) "$CODE_NO_ENTRY " else "✘"
|
||||
val notRun: String get() = if (emojiMode.get() != null) "$CROSS_MARK_BUTTON " else "-"
|
||||
|
||||
inline fun <T> renderIfSupported(body: () -> T): T {
|
||||
if (hasEmojiTerminal)
|
||||
|
@ -10,6 +10,7 @@ import org.apache.logging.log4j.core.appender.ConsoleAppender
|
||||
import org.apache.logging.log4j.core.appender.OutputStreamManager
|
||||
import org.crsh.text.RenderPrintWriter
|
||||
import org.fusesource.jansi.Ansi
|
||||
import org.fusesource.jansi.Ansi.Attribute
|
||||
import org.fusesource.jansi.AnsiConsole
|
||||
import org.fusesource.jansi.AnsiOutputStream
|
||||
import rx.Subscription
|
||||
@ -146,22 +147,25 @@ abstract class ANSIProgressRenderer {
|
||||
with(ansi) {
|
||||
var lines = 0
|
||||
for ((index, step) in tree.withIndex()) {
|
||||
val processedStep = treeIndexProcessed.contains(index)
|
||||
val skippedStep = index < treeIndex && !processedStep
|
||||
val activeStep = index == treeIndex
|
||||
|
||||
val marker = when {
|
||||
treeIndexProcessed.contains(index) -> " ${Emoji.greenTick} "
|
||||
index < treeIndex -> " ${Emoji.notRun} "
|
||||
treeIndex == tree.lastIndex -> "${Emoji.greenTick} "
|
||||
index == treeIndex -> "${Emoji.rightArrow} "
|
||||
processedStep -> " ${Emoji.greenTick} "
|
||||
skippedStep -> " "
|
||||
activeStep -> "${Emoji.rightArrow} "
|
||||
error -> "${Emoji.noEntry} "
|
||||
else -> " " // Not reached yet.
|
||||
}
|
||||
a(" ".repeat(step.first))
|
||||
a(marker)
|
||||
|
||||
val active = index == treeIndex
|
||||
if (active) bold()
|
||||
a(step.second)
|
||||
if (active) boldOff()
|
||||
when {
|
||||
activeStep -> renderInBold(step.second, ansi)
|
||||
skippedStep -> renderInFaint(step.second, ansi)
|
||||
else -> a(step.second)
|
||||
}
|
||||
|
||||
eraseLine(Ansi.Erase.FORWARD)
|
||||
newline()
|
||||
@ -171,6 +175,21 @@ abstract class ANSIProgressRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderInBold(payload: String, ansi: Ansi): Unit {
|
||||
with(ansi) {
|
||||
a(Attribute.INTENSITY_BOLD)
|
||||
a(payload)
|
||||
a(Attribute.INTENSITY_BOLD_OFF)
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderInFaint(payload: String, ansi: Ansi): Unit {
|
||||
with(ansi) {
|
||||
a(Attribute.INTENSITY_FAINT)
|
||||
a(payload)
|
||||
a(Attribute.INTENSITY_BOLD_OFF)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,64 @@
|
||||
package net.corda.tools.shell.utilities
|
||||
|
||||
import com.nhaarman.mockito_kotlin.argumentCaptor
|
||||
import com.nhaarman.mockito_kotlin.mock
|
||||
import com.nhaarman.mockito_kotlin.verify
|
||||
import net.corda.core.flows.StateMachineRunId
|
||||
import net.corda.core.internal.concurrent.openFuture
|
||||
import net.corda.core.messaging.DataFeed
|
||||
import net.corda.core.messaging.FlowProgressHandleImpl
|
||||
import net.corda.tools.shell.utlities.ANSIProgressRenderer
|
||||
import net.corda.tools.shell.utlities.CRaSHANSIProgressRenderer
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.crsh.text.RenderPrintWriter
|
||||
import org.junit.Test
|
||||
import rx.Observable
|
||||
import org.fusesource.jansi.Ansi
|
||||
import org.junit.Before
|
||||
import rx.subjects.PublishSubject
|
||||
|
||||
class ANSIProgressRendererTest {
|
||||
|
||||
companion object {
|
||||
private const val INTENSITY_BOLD_ON_ASCII = "[1m"
|
||||
private const val INTENSITY_OFF_ASCII = "[22m"
|
||||
private const val INTENSITY_FAINT_ON_ASCII = "[2m"
|
||||
|
||||
private const val STEP_1_LABEL = "Running step 1"
|
||||
private const val STEP_2_LABEL = "Running step 2"
|
||||
private const val STEP_3_LABEL = "Running step 3"
|
||||
|
||||
private const val STEP_1_SUCCESS_OUTPUT = """✓ $STEP_1_LABEL"""
|
||||
private const val STEP_2_SKIPPED_OUTPUT = """ $INTENSITY_FAINT_ON_ASCII$STEP_2_LABEL$INTENSITY_OFF_ASCII"""
|
||||
private const val STEP_3_ACTIVE_OUTPUT = """✓ $INTENSITY_BOLD_ON_ASCII$STEP_3_LABEL$INTENSITY_OFF_ASCII"""
|
||||
}
|
||||
|
||||
lateinit var printWriter: RenderPrintWriter
|
||||
lateinit var progressRenderer: ANSIProgressRenderer
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
printWriter = mock()
|
||||
progressRenderer = CRaSHANSIProgressRenderer(printWriter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test that steps are rendered appropriately depending on their status`() {
|
||||
val indexSubject = PublishSubject.create<Int>()
|
||||
val feedSubject = PublishSubject.create<List<Pair<Int, String>>>()
|
||||
val stepsTreeIndexFeed = DataFeed<Int, Int>(0, indexSubject)
|
||||
val stepsTreeFeed = DataFeed<List<Pair<Int, String>>, List<Pair<Int, String>>>(listOf(), feedSubject)
|
||||
val flowProgressHandle = FlowProgressHandleImpl(StateMachineRunId.createRandom(), openFuture<String>(), Observable.empty(), stepsTreeIndexFeed, stepsTreeFeed)
|
||||
|
||||
progressRenderer.render(flowProgressHandle)
|
||||
// The flow is currently at step 3, while step 1 has been completed and step 2 has been skipped.
|
||||
indexSubject.onNext(2)
|
||||
feedSubject.onNext(listOf(Pair(0, STEP_1_LABEL), Pair(0, STEP_2_LABEL), Pair(0, STEP_3_LABEL)))
|
||||
|
||||
val captor = argumentCaptor<Ansi>()
|
||||
verify(printWriter).print(captor.capture())
|
||||
assertThat(captor.firstValue.toString()).containsSequence(STEP_1_SUCCESS_OUTPUT, STEP_2_SKIPPED_OUTPUT, STEP_3_ACTIVE_OUTPUT)
|
||||
verify(printWriter).flush()
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user