From dbc5336c15fc22a6ea364c549b224e1e2844ba51 Mon Sep 17 00:00:00 2001 From: Stephen Edwards Date: Thu, 14 Nov 2024 14:25:11 -0500 Subject: [PATCH 1/3] Add public debuggingName to WorkflowAction, use it in default toString() --- .../kotlin/com/squareup/workflow1/Sink.kt | 4 +-- .../squareup/workflow1/StatefulWorkflow.kt | 9 +++-- .../squareup/workflow1/StatelessWorkflow.kt | 9 +++-- .../com/squareup/workflow1/WorkerWorkflow.kt | 4 +-- .../com/squareup/workflow1/WorkflowAction.kt | 15 +++++++-- .../workflow1/WorkflowIdentifierType.kt | 4 +-- .../workflow1/WorkflowIdentifierTest.kt | 2 +- ...rTypeNamer.kt => CommonKClassTypeNamer.kt} | 2 +- ...rTypeNamer.kt => CommonKClassTypeNamer.kt} | 2 +- ...rTypeNamer.kt => CommonKClassTypeNamer.kt} | 2 +- .../workflow1/internal/RealRenderContext.kt | 3 +- .../internal/RealRenderContextTest.kt | 6 ++-- .../workflow1/internal/WorkflowNodeTest.kt | 4 +-- .../workflow1/testing/RealRenderTester.kt | 6 ++-- .../workflow1/testing/RealRenderTesterTest.kt | 33 +++++++++++-------- .../tracing/TracingWorkflowInterceptorTest.kt | 8 +++-- .../tracing/expected_trace_file.txt | 4 +-- 17 files changed, 71 insertions(+), 46 deletions(-) rename workflow-core/src/iosMain/kotlin/com.squareup.workflow1/{WorkflowIdentifierTypeNamer.kt => CommonKClassTypeNamer.kt} (77%) rename workflow-core/src/jsMain/kotlin/com.squareup.workflow1/{WorkflowIdentifierTypeNamer.kt => CommonKClassTypeNamer.kt} (95%) rename workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/{WorkflowIdentifierTypeNamer.kt => CommonKClassTypeNamer.kt} (77%) diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt index eadd491bb..5afd3983f 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt @@ -4,7 +4,6 @@ package com.squareup.workflow1 import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.suspendCancellableCoroutine import kotlin.coroutines.resume import kotlin.jvm.JvmMultifileClass @@ -86,7 +85,8 @@ internal suspend fun < ) { suspendCancellableCoroutine { continuation -> val resumingAction = object : WorkflowAction() { - override fun toString(): String = "sendAndAwaitApplication($action)" + override fun toString(): String = "sendAndAwaitApplication(${action})" + override fun Updater.apply() { // Don't execute anything if the caller was cancelled while we were in the queue. if (!continuation.isActive) return diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatefulWorkflow.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatefulWorkflow.kt index a6586d5d3..4631c9117 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatefulWorkflow.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatefulWorkflow.kt @@ -998,8 +998,9 @@ public fun * of the receiving [StatefulWorkflow]. The action will invoke the given [lambda][update] * when it is [applied][WorkflowAction.apply]. * - * @param name Function that returns a string describing the update for debugging, included - * in [toString]. + * @param name Function that returns a string describing the update for debugging, this will + * be returned by [WorkflowAction.debuggingName], which is in turn included in the default + * [WorkflowAction.toString]. * @param update Function that defines the workflow update. */ public fun @@ -1007,6 +1008,8 @@ public fun name: () -> String, update: WorkflowAction.Updater.() -> Unit ): WorkflowAction = object : WorkflowAction() { + override val debuggingName: String + get() = name() + override fun Updater.apply() = update.invoke(this) - override fun toString(): String = "action(${name()})-${this@action}" } diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt index cb3d7ca34..97fc1cc75 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/StatelessWorkflow.kt @@ -141,8 +141,9 @@ public fun * of the receiving [StatefulWorkflow]. The action will invoke the given [lambda][update] * when it is [applied][WorkflowAction.apply]. * - * @param name Function that returns a string describing the update for debugging, included in - * [toString]. + * @param name Function that returns a string describing the update for debugging, this will + * be returned by [WorkflowAction.debuggingName], which is in turn included in the default + * [WorkflowAction.toString]. * @param update Function that defines the workflow update. */ public fun @@ -150,6 +151,8 @@ public fun name: () -> String, update: WorkflowAction.Updater.() -> Unit ): WorkflowAction = object : WorkflowAction() { + override val debuggingName: String + get() = name() + override fun Updater.apply() = update.invoke(this) - override fun toString(): String = "action(${name()})-${this@action}" } diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkerWorkflow.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkerWorkflow.kt index 983f7ac5d..5219b5c86 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkerWorkflow.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkerWorkflow.kt @@ -88,8 +88,8 @@ private class EmitWorkerOutputAction( private val renderKey: String, private val output: O, ) : WorkflowAction() { - override fun toString(): String = - WorkflowIdentifierTypeNamer.uniqueName(EmitWorkerOutputAction::class) + + override val debuggingName: String + get() = CommonKClassTypeNamer.uniqueName(EmitWorkerOutputAction::class) + "(worker=$worker, key=$renderKey)" override fun Updater.apply() { diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt index 3b5688a53..1af9b6384 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt @@ -31,6 +31,12 @@ import kotlin.jvm.JvmOverloads */ public abstract class WorkflowAction { + /** + * The name to use for debugging. This is handy for logging and is used by the default + * [toString] implementation provided here. + */ + public open val debuggingName: String = CommonKClassTypeNamer.uniqueName(this::class) + /** * The context for calls to [WorkflowAction.apply]. Allows the action to read and change the * [state], and to emit an [output][setOutput] value. @@ -60,6 +66,8 @@ public abstract class WorkflowAction { */ public abstract fun Updater.apply() + public override fun toString(): String = "action(${debuggingName})-@${hashCode()}" + public companion object { /** * Returns a [WorkflowAction] that does nothing: no output will be emitted, and @@ -72,7 +80,7 @@ public abstract class WorkflowAction { NO_ACTION as WorkflowAction private val NO_ACTION = object : WorkflowAction() { - override fun toString(): String = "WorkflowAction.noAction()" + override val debuggingName: String = "noAction()" override fun Updater.apply() { // Noop @@ -124,9 +132,10 @@ public fun action( name: () -> String, apply: WorkflowAction.Updater.() -> Unit ): WorkflowAction = object : WorkflowAction() { - override fun Updater.apply() = apply.invoke(this) + override val debuggingName: String + get() = name() - override fun toString(): String = "WorkflowAction(${name()})@${hashCode()}" + override fun Updater.apply() = apply.invoke(this) } /** Applies this [WorkflowAction] to [state]. */ diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowIdentifierType.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowIdentifierType.kt index 6adafb727..e99c8c591 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowIdentifierType.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowIdentifierType.kt @@ -24,7 +24,7 @@ public sealed class WorkflowIdentifierType { val kClass: KClass<*>? = null, ) : WorkflowIdentifierType() { public constructor(kClass: KClass<*>) : this( - WorkflowIdentifierTypeNamer.uniqueName(kClass), + CommonKClassTypeNamer.uniqueName(kClass), kClass ) } @@ -46,6 +46,6 @@ public sealed class WorkflowIdentifierType { } } -internal expect object WorkflowIdentifierTypeNamer { +internal expect object CommonKClassTypeNamer { public fun uniqueName(kClass: KClass<*>): String } diff --git a/workflow-core/src/commonTest/kotlin/com/squareup/workflow1/WorkflowIdentifierTest.kt b/workflow-core/src/commonTest/kotlin/com/squareup/workflow1/WorkflowIdentifierTest.kt index 669d4834a..e83db8820 100644 --- a/workflow-core/src/commonTest/kotlin/com/squareup/workflow1/WorkflowIdentifierTest.kt +++ b/workflow-core/src/commonTest/kotlin/com/squareup/workflow1/WorkflowIdentifierTest.kt @@ -186,7 +186,7 @@ internal class WorkflowIdentifierTest { ) : Workflow, ImpostorWorkflow { override val realIdentifier: WorkflowIdentifier = proxied.identifier override fun describeRealIdentifier(): String = - "TestImpostor1(${WorkflowIdentifierTypeNamer.uniqueName(proxied::class)})" + "TestImpostor1(${CommonKClassTypeNamer.uniqueName(proxied::class)})" override fun asStatefulWorkflow(): StatefulWorkflow = throw NotImplementedError() } diff --git a/workflow-core/src/iosMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt b/workflow-core/src/iosMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt similarity index 77% rename from workflow-core/src/iosMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt rename to workflow-core/src/iosMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt index 6f7b00f55..7327e59f5 100644 --- a/workflow-core/src/iosMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt +++ b/workflow-core/src/iosMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt @@ -2,7 +2,7 @@ package com.squareup.workflow1 import kotlin.reflect.KClass -internal actual object WorkflowIdentifierTypeNamer { +internal actual object CommonKClassTypeNamer { public actual fun uniqueName(kClass: KClass<*>): String { return kClass.qualifiedName ?: kClass.toString() } diff --git a/workflow-core/src/jsMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt b/workflow-core/src/jsMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt similarity index 95% rename from workflow-core/src/jsMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt rename to workflow-core/src/jsMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt index a74052e8b..91e226194 100644 --- a/workflow-core/src/jsMain/kotlin/com.squareup.workflow1/WorkflowIdentifierTypeNamer.kt +++ b/workflow-core/src/jsMain/kotlin/com.squareup.workflow1/CommonKClassTypeNamer.kt @@ -2,7 +2,7 @@ package com.squareup.workflow1 import kotlin.reflect.KClass -internal actual object WorkflowIdentifierTypeNamer { +internal actual object CommonKClassTypeNamer { // Stores mappings between KClass instances and their assigned names. val mappings = mutableMapOf, String>() diff --git a/workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/WorkflowIdentifierTypeNamer.kt b/workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/CommonKClassTypeNamer.kt similarity index 77% rename from workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/WorkflowIdentifierTypeNamer.kt rename to workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/CommonKClassTypeNamer.kt index 6f7b00f55..7327e59f5 100644 --- a/workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/WorkflowIdentifierTypeNamer.kt +++ b/workflow-core/src/jvmMain/kotlin/com/squareup/workflow1/CommonKClassTypeNamer.kt @@ -2,7 +2,7 @@ package com.squareup.workflow1 import kotlin.reflect.KClass -internal actual object WorkflowIdentifierTypeNamer { +internal actual object CommonKClassTypeNamer { public actual fun uniqueName(kClass: KClass<*>): String { return kClass.qualifiedName ?: kClass.toString() } diff --git a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/RealRenderContext.kt b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/RealRenderContext.kt index f4572f7ef..1e4d60128 100644 --- a/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/RealRenderContext.kt +++ b/workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/RealRenderContext.kt @@ -43,7 +43,8 @@ internal class RealRenderContext( override fun send(value: WorkflowAction) { if (!frozen) { throw UnsupportedOperationException( - "Expected sink to not be sent to until after the render pass. Received action: $value" + "Expected sink to not be sent to until after the render pass. " + + "Received action: ${value.debuggingName}" ) } eventActionsChannel.trySend(value) diff --git a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/RealRenderContextTest.kt b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/RealRenderContextTest.kt index 6bf8503ab..4c58b9be2 100644 --- a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/RealRenderContextTest.kt +++ b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/RealRenderContextTest.kt @@ -124,12 +124,12 @@ internal class RealRenderContextTest { @Test fun send_allows_multiple_sends() { val context = createdPoisonedContext() val firstAction = object : WorkflowAction() { + override val debuggingName: String = "firstAction" override fun Updater.apply() = Unit - override fun toString(): String = "firstAction" } val secondAction = object : WorkflowAction() { + override val debuggingName: String = "secondAction" override fun Updater.apply() = Unit - override fun toString(): String = "secondAction" } // Enable sink sends. context.freeze() @@ -143,8 +143,8 @@ internal class RealRenderContextTest { @Test fun send_throws_before_render_returns() { val context = createdPoisonedContext() val action = object : WorkflowAction() { + override val debuggingName: String = "action" override fun Updater.apply() = Unit - override fun toString(): String = "action" } val error = assertFailsWith { diff --git a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt index 69a3023cc..25849fa17 100644 --- a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt +++ b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt @@ -1143,7 +1143,7 @@ internal class WorkflowNodeTest { assertTrue( error.message!!.startsWith( "Expected sink to not be sent to until after the render pass. " + - "Received action: WorkflowAction(eventHandler)@" + "Received action: eventHandler" ) ) } @@ -1151,7 +1151,7 @@ internal class WorkflowNodeTest { @Test fun send_fails_before_render_pass_completed() { class TestAction : WorkflowAction() { override fun Updater.apply() = fail("Expected sink send to fail.") - override fun toString(): String = "TestAction()" + override val debuggingName: String = "TestAction()" } val workflow = Workflow.stateless { diff --git a/workflow-testing/src/main/java/com/squareup/workflow1/testing/RealRenderTester.kt b/workflow-testing/src/main/java/com/squareup/workflow1/testing/RealRenderTester.kt index 1c0afb5fd..efe4b1233 100644 --- a/workflow-testing/src/main/java/com/squareup/workflow1/testing/RealRenderTester.kt +++ b/workflow-testing/src/main/java/com/squareup/workflow1/testing/RealRenderTester.kt @@ -216,7 +216,7 @@ internal class RealRenderTester( if (match.output != null) { check(processedAction == null) { "Expected only one output to be expected: $description expected to emit " + - "${match.output.value} but $processedAction was already processed." + "${match.output.value} but ${processedAction?.debuggingName} was already processed." } @Suppress("UNCHECKED_CAST") processedAction = handler(match.output.value as ChildOutputT) @@ -273,8 +273,8 @@ internal class RealRenderTester( checkNoOutputs() check(processedAction == null) { "Tried to send action to sink after another action was already processed:\n" + - " processed action=$processedAction\n" + - " attempted action=$value" + " processed action=${processedAction?.debuggingName}\n" + + " attempted action=${value.debuggingName}" } processedAction = value } diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt index d4d700ae0..77171759a 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt @@ -64,7 +64,7 @@ internal class RealRenderTesterTest { } assertEquals( "Expected only one output to be expected: child ${child2.identifier} " + - "expected to emit kotlin.Unit but WorkflowAction.noAction() was already processed.", + "expected to emit kotlin.Unit but noAction() was already processed.", failure.message ) } @@ -87,7 +87,7 @@ internal class RealRenderTesterTest { assertEquals( "Expected only one output to be expected: " + "child ${typeOf>()} expected to emit " + - "kotlin.Unit but WorkflowAction.noAction() was already processed.", + "kotlin.Unit but noAction() was already processed.", failure.message ) } @@ -154,9 +154,9 @@ internal class RealRenderTesterTest { } @Test fun `sending to sink throws when called multiple times`() { - class TestAction(private val name: String) : WorkflowAction() { + class TestAction(name: String) : WorkflowAction() { override fun Updater.apply() {} - override fun toString(): String = "TestAction($name)" + override val debuggingName: String = "TestAction($name)" } val workflow = Workflow.stateful>( @@ -175,8 +175,8 @@ internal class RealRenderTesterTest { } assertEquals( "Tried to send action to sink after another action was already processed:\n" + - " processed action=$action1\n" + - " attempted action=$action2", + " processed action=${action1.debuggingName}\n" + + " attempted action=${action2.debuggingName}", error.message ) } @@ -185,7 +185,7 @@ internal class RealRenderTesterTest { @Test fun `sending to sink throws when child output expected`() { class TestAction : WorkflowAction() { override fun Updater.apply() {} - override fun toString(): String = "TestAction" + override val debuggingName: String = "TestAction" } val workflow = Workflow.stateful>( @@ -205,7 +205,7 @@ internal class RealRenderTesterTest { } assertEquals( "Tried to send action to sink after another action was already processed:\n" + - " processed action=WorkflowAction.noAction()\n" + + " processed action=noAction()\n" + " attempted action=TestAction", error.message ) @@ -964,9 +964,9 @@ internal class RealRenderTesterTest { assertEquals("bad props: wrong props", error.message) } - private class TestAction(val name: String) : WorkflowAction() { + private class TestAction(name: String) : WorkflowAction() { override fun Updater.apply() {} - override fun toString(): String = "TestAction($name)" + override val debuggingName: String = name } @Test fun `verifyAction failure fails test`() { @@ -997,7 +997,7 @@ internal class RealRenderTesterTest { testResult.verifyAction { assertTrue(it is TestAction) - assertEquals("output", it.name) + assertEquals("output", it.debuggingName) } } @@ -1012,7 +1012,7 @@ internal class RealRenderTesterTest { testResult.verifyAction { assertTrue(it is TestAction) - assertEquals("output", it.name) + assertEquals("output", it.debuggingName) } } @@ -1027,7 +1027,7 @@ internal class RealRenderTesterTest { testResult.verifyAction { assertTrue(it is TestAction) - assertEquals("event", it.name) + assertEquals("event", it.debuggingName) } } @@ -1087,6 +1087,7 @@ internal class RealRenderTesterTest { @Test fun `testNextRender could daisy-chain consecutive renderings with verifyAction`() { data class TestAction(val add: Int) : WorkflowAction() { + override val debuggingName: String get() = "add:$add" override fun Updater.apply() { setOutput(state) state += add @@ -1123,6 +1124,8 @@ internal class RealRenderTesterTest { @Test fun `testNextRender could daisy-chain consecutive renderings with verifyActionResult`() { data class TestAction(val add: Int) : WorkflowAction() { + override val debuggingName: String get() = "add:$add" + override fun Updater.apply() { setOutput(state) state += add @@ -1162,6 +1165,8 @@ internal class RealRenderTesterTest { @Test fun `testNextRenderWithProps respects new props`() { data class TestAction(val add: Int) : WorkflowAction() { + override val debuggingName: String get() = "add:$add" + override fun Updater.apply() { setOutput(state) state += props * add @@ -1201,6 +1206,8 @@ internal class RealRenderTesterTest { @Test fun `testNextRenderWithProps uses onPropsChanged`() { data class TestAction(val add: Int) : WorkflowAction() { + override val debuggingName: String get() = "add:$add" + override fun Updater.apply() { setOutput(state) state += props * add diff --git a/workflow-tracing/src/test/java/com/squareup/workflow1/diagnostic/tracing/TracingWorkflowInterceptorTest.kt b/workflow-tracing/src/test/java/com/squareup/workflow1/diagnostic/tracing/TracingWorkflowInterceptorTest.kt index baf901aec..ecac0fc2a 100644 --- a/workflow-tracing/src/test/java/com/squareup/workflow1/diagnostic/tracing/TracingWorkflowInterceptorTest.kt +++ b/workflow-tracing/src/test/java/com/squareup/workflow1/diagnostic/tracing/TracingWorkflowInterceptorTest.kt @@ -10,7 +10,6 @@ import com.squareup.workflow1.renderWorkflowIn import com.squareup.workflow1.runningWorker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.Unconfined -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED @@ -30,7 +29,6 @@ import org.mockito.kotlin.mock import kotlin.test.Test import kotlin.test.assertEquals -@OptIn(ExperimentalCoroutinesApi::class) internal class TracingWorkflowInterceptorTest { private lateinit var onGcDetected: () -> Unit @@ -85,7 +83,8 @@ internal class TracingWorkflowInterceptorTest { .getResourceAsStream("expected_trace_file.txt") .source() .buffer() - assertEquals(expected.readUtf8(), buffer.readUtf8()) + .readUtf8() + assertEquals(expected, buffer.readUtf8().removeActionHashCodes()) } private inner class TestWorkflow : StatefulWorkflow() { @@ -141,6 +140,9 @@ internal class TracingWorkflowInterceptorTest { } } +// [WorkflowAction::toString] includes "@-${hashCode()}", so strip it. +private fun String.removeActionHashCodes(): String = replace(Regex("-@([0-9]*)"), "") + private object ZeroTimeMark : TimeMark { override val elapsedNow: Long = 0L } diff --git a/workflow-tracing/src/test/resources/com/squareup/workflow1/diagnostic/tracing/expected_trace_file.txt b/workflow-tracing/src/test/resources/com/squareup/workflow1/diagnostic/tracing/expected_trace_file.txt index 837a53df3..bb72869fa 100644 --- a/workflow-tracing/src/test/resources/com/squareup/workflow1/diagnostic/tracing/expected_trace_file.txt +++ b/workflow-tracing/src/test/resources/com/squareup/workflow1/diagnostic/tracing/expected_trace_file.txt @@ -60,8 +60,8 @@ {"name":"used/free memory","ph":"C","ts":0,"pid":0,"tid":0,"args":{"usedMemory":1,"freeMemory":42}}, {"name":"Snapshot","ph":"B","ts":0,"pid":0,"tid":0,"args":{}}, {"name":"Snapshot","ph":"E","ts":0,"pid":0,"tid":0,"args":{}}, -{"name":"Sink received: Worker (2)","cat":"update","ph":"i","ts":0,"pid":0,"tid":0,"s":"t","args":{"action":"sendAndAwaitApplication(com.squareup.workflow1.EmitWorkerOutputAction(worker=TypedWorker(java.lang.String (Kotlin reflection is not available)), key=))"}}, -{"name":"WorkflowAction: Worker (2)","cat":"update","ph":"i","ts":0,"pid":0,"tid":0,"s":"p","args":{"action":"sendAndAwaitApplication(com.squareup.workflow1.EmitWorkerOutputAction(worker=TypedWorker(java.lang.String (Kotlin reflection is not available)), key=))","oldState":"0","newState":"{no change}","output":"fired!"}}, +{"name":"Sink received: Worker (2)","cat":"update","ph":"i","ts":0,"pid":0,"tid":0,"s":"t","args":{"action":"sendAndAwaitApplication(action(com.squareup.workflow1.EmitWorkerOutputAction(worker=TypedWorker(java.lang.String (Kotlin reflection is not available)), key=)))"}}, +{"name":"WorkflowAction: Worker (2)","cat":"update","ph":"i","ts":0,"pid":0,"tid":0,"s":"p","args":{"action":"sendAndAwaitApplication(action(com.squareup.workflow1.EmitWorkerOutputAction(worker=TypedWorker(java.lang.String (Kotlin reflection is not available)), key=)))","oldState":"0","newState":"{no change}","output":"fired!"}}, {"name":"Worker (2)","ph":"O","ts":0,"pid":0,"tid":0,"id":"2","args":{"snapshot":"0"}}, {"name":"Render Pass","cat":"rendering","ph":"B","ts":0,"pid":0,"tid":0,"args":{"props":"3"}}, {"name":"used/free memory","ph":"C","ts":0,"pid":0,"tid":0,"args":{"usedMemory":1,"freeMemory":42}}, From 2663c1244462c93c7b8c54b1b79cbe7614210e04 Mon Sep 17 00:00:00 2001 From: steve-the-edwards Date: Thu, 14 Nov 2024 21:25:52 +0000 Subject: [PATCH 2/3] Apply changes from apiDump Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- workflow-core/api/workflow-core.api | 2 ++ 1 file changed, 2 insertions(+) diff --git a/workflow-core/api/workflow-core.api b/workflow-core/api/workflow-core.api index 475fa33f8..8a9739add 100644 --- a/workflow-core/api/workflow-core.api +++ b/workflow-core/api/workflow-core.api @@ -330,6 +330,8 @@ public abstract class com/squareup/workflow1/WorkflowAction { public static final field Companion Lcom/squareup/workflow1/WorkflowAction$Companion; public fun ()V public abstract fun apply (Lcom/squareup/workflow1/WorkflowAction$Updater;)V + public fun getDebuggingName ()Ljava/lang/String; + public fun toString ()Ljava/lang/String; } public final class com/squareup/workflow1/WorkflowAction$Companion { From be89c024919a855d30e724e7d967b85c0271a760 Mon Sep 17 00:00:00 2001 From: RBusarow Date: Thu, 14 Nov 2024 21:33:44 +0000 Subject: [PATCH 3/3] Apply changes from ktLintFormat Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../src/commonMain/kotlin/com/squareup/workflow1/Sink.kt | 2 +- .../commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt | 2 +- .../kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt | 2 +- .../java/com/squareup/workflow1/testing/RealRenderTesterTest.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt index 5afd3983f..b24294964 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/Sink.kt @@ -85,7 +85,7 @@ internal suspend fun < ) { suspendCancellableCoroutine { continuation -> val resumingAction = object : WorkflowAction() { - override fun toString(): String = "sendAndAwaitApplication(${action})" + override fun toString(): String = "sendAndAwaitApplication($action)" override fun Updater.apply() { // Don't execute anything if the caller was cancelled while we were in the queue. diff --git a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt index 1af9b6384..da41e153a 100644 --- a/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt +++ b/workflow-core/src/commonMain/kotlin/com/squareup/workflow1/WorkflowAction.kt @@ -66,7 +66,7 @@ public abstract class WorkflowAction { */ public abstract fun Updater.apply() - public override fun toString(): String = "action(${debuggingName})-@${hashCode()}" + public override fun toString(): String = "action($debuggingName)-@${hashCode()}" public companion object { /** diff --git a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt index 25849fa17..129b5de01 100644 --- a/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt +++ b/workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/internal/WorkflowNodeTest.kt @@ -1151,7 +1151,7 @@ internal class WorkflowNodeTest { @Test fun send_fails_before_render_pass_completed() { class TestAction : WorkflowAction() { override fun Updater.apply() = fail("Expected sink send to fail.") - override val debuggingName: String = "TestAction()" + override val debuggingName: String = "TestAction()" } val workflow = Workflow.stateless { diff --git a/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt b/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt index 77171759a..b575003a3 100644 --- a/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt +++ b/workflow-testing/src/test/java/com/squareup/workflow1/testing/RealRenderTesterTest.kt @@ -185,7 +185,7 @@ internal class RealRenderTesterTest { @Test fun `sending to sink throws when child output expected`() { class TestAction : WorkflowAction() { override fun Updater.apply() {} - override val debuggingName: String = "TestAction" + override val debuggingName: String = "TestAction" } val workflow = Workflow.stateful>(