[{"data":1,"prerenderedAt":6775},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fbuilding\u002Ftesting":314,"\u002Fdocs\u002Fbuilding\u002Ftesting-surround":6770},[4,38,86,149,176,219,257,273],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started\u002F1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"Getting started","i-lucide-flag",{"title":13,"path":14,"stem":15,"icon":16},"Modules overview","\u002Fdocs\u002Fgetting-started\u002Fmodules-overview","1.docs\u002F1.getting-started\u002F2.modules-overview","i-lucide-boxes",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","1.docs\u002F1.getting-started\u002F3.installation","i-lucide-download",{"title":23,"path":24,"stem":25,"icon":26},"License configuration","\u002Fdocs\u002Fgetting-started\u002Flicense-configuration","1.docs\u002F1.getting-started\u002F4.license-configuration","i-lucide-key-round",{"title":28,"path":29,"stem":30,"icon":31},"Your first app","\u002Fdocs\u002Fgetting-started\u002Ffirst-app","1.docs\u002F1.getting-started\u002F5.first-app","i-lucide-square-play",{"title":33,"path":34,"stem":35,"icon":36},"Project setup","\u002Fdocs\u002Fgetting-started\u002Fproject-setup","1.docs\u002F1.getting-started\u002F6.project-setup","i-lucide-package",false,{"title":39,"path":40,"stem":41,"children":42,"icon":45},"Core Concepts","\u002Fdocs\u002Fconcepts","1.docs\u002F2.concepts\u002F1.index",[43,46,51,56,61,66,71,76,81],{"title":44,"path":40,"stem":41,"icon":45},"Core concepts","i-lucide-book-open",{"title":47,"path":48,"stem":49,"icon":50},"Architecture","\u002Fdocs\u002Fconcepts\u002Farchitecture","1.docs\u002F2.concepts\u002F2.architecture","i-lucide-layers",{"title":52,"path":53,"stem":54,"icon":55},"Exactly-once semantics","\u002Fdocs\u002Fconcepts\u002Fexactly-once","1.docs\u002F2.concepts\u002F3.exactly-once","i-lucide-shield-check",{"title":57,"path":58,"stem":59,"icon":60},"Lanes and parallelism","\u002Fdocs\u002Fconcepts\u002Flanes-and-parallelism","1.docs\u002F2.concepts\u002F4.lanes-and-parallelism","i-lucide-split",{"title":62,"path":63,"stem":64,"icon":65},"State and thread-safety","\u002Fdocs\u002Fconcepts\u002Fstate-and-thread-safety","1.docs\u002F2.concepts\u002F5.state-and-thread-safety","i-lucide-lock",{"title":67,"path":68,"stem":69,"icon":70},"Event time and watermarks","\u002Fdocs\u002Fconcepts\u002Fevent-time-and-watermarks","1.docs\u002F2.concepts\u002F6.event-time-and-watermarks","i-lucide-clock",{"title":72,"path":73,"stem":74,"icon":75},"The configuration model","\u002Fdocs\u002Fconcepts\u002Fconfiguration-model","1.docs\u002F2.concepts\u002F7.configuration-model","i-lucide-sliders-horizontal",{"title":77,"path":78,"stem":79,"icon":80},"The error-handling model","\u002Fdocs\u002Fconcepts\u002Ferror-handling-model","1.docs\u002F2.concepts\u002F8.error-handling-model","i-lucide-triangle-alert",{"title":82,"path":83,"stem":84,"icon":85},"How StoatFlow differs from Kafka Streams","\u002Fdocs\u002Fconcepts\u002Fhow-stoatflow-differs-from-ks","1.docs\u002F2.concepts\u002F9.how-stoatflow-differs-from-ks","i-lucide-arrow-left-right",{"title":87,"path":88,"stem":89,"children":90,"icon":93},"Building Topologies","\u002Fdocs\u002Fbuilding","1.docs\u002F3.building\u002F1.index",[91,94,99,104,109,114,119,124,129,134,139,144],{"title":92,"path":88,"stem":89,"icon":93},"Building topologies","i-lucide-blocks",{"title":95,"path":96,"stem":97,"icon":98},"Error handling and DLQ","\u002Fdocs\u002Fbuilding\u002Ferror-handling-dlq","1.docs\u002F3.building\u002F10.error-handling-dlq","i-lucide-circle-x",{"title":100,"path":101,"stem":102,"icon":103},"State stores","\u002Fdocs\u002Fbuilding\u002Fstate-stores","1.docs\u002F3.building\u002F11.state-stores","i-lucide-database",{"title":105,"path":106,"stem":107,"icon":108},"Testing topologies","\u002Fdocs\u002Fbuilding\u002Ftesting","1.docs\u002F3.building\u002F12.testing","i-lucide-flask-conical",{"title":110,"path":111,"stem":112,"icon":113},"Sources and sinks","\u002Fdocs\u002Fbuilding\u002Fstreams-builder","1.docs\u002F3.building\u002F2.streams-builder","i-lucide-import",{"title":115,"path":116,"stem":117,"icon":118},"KStream and KTable operations","\u002Fdocs\u002Fbuilding\u002Fkstream-ktable","1.docs\u002F3.building\u002F3.kstream-ktable","i-lucide-waypoints",{"title":120,"path":121,"stem":122,"icon":123},"Aggregations","\u002Fdocs\u002Fbuilding\u002Faggregations","1.docs\u002F3.building\u002F4.aggregations","i-lucide-sigma",{"title":125,"path":126,"stem":127,"icon":128},"Windowing","\u002Fdocs\u002Fbuilding\u002Fwindowing","1.docs\u002F3.building\u002F5.windowing","i-lucide-calendar-clock",{"title":130,"path":131,"stem":132,"icon":133},"Joins","\u002Fdocs\u002Fbuilding\u002Fjoins","1.docs\u002F3.building\u002F6.joins","i-lucide-git-merge",{"title":135,"path":136,"stem":137,"icon":138},"The Processor API","\u002Fdocs\u002Fbuilding\u002Fprocessor-api","1.docs\u002F3.building\u002F7.processor-api","i-lucide-cpu",{"title":140,"path":141,"stem":142,"icon":143},"Scheduled sources","\u002Fdocs\u002Fbuilding\u002Fscheduled-sources","1.docs\u002F3.building\u002F8.scheduled-sources","i-lucide-timer",{"title":145,"path":146,"stem":147,"icon":148},"Serdes and Avro","\u002Fdocs\u002Fbuilding\u002Fserdes","1.docs\u002F3.building\u002F9.serdes","i-lucide-binary",{"title":150,"path":151,"stem":152,"children":153,"icon":75},"Configuration","\u002Fdocs\u002Fconfiguration","1.docs\u002F4.configuration\u002F1.index",[154,156,161,166,171],{"title":155,"path":151,"stem":152,"icon":75},"How configuration works",{"title":157,"path":158,"stem":159,"icon":160},"Engine configuration (:core)","\u002Fdocs\u002Fconfiguration\u002Fcore-config","1.docs\u002F4.configuration\u002F2.core-config","i-lucide-settings-2",{"title":162,"path":163,"stem":164,"icon":165},"Runtime configuration (:runtime)","\u002Fdocs\u002Fconfiguration\u002Fruntime-config","1.docs\u002F4.configuration\u002F3.runtime-config","i-lucide-server-cog",{"title":167,"path":168,"stem":169,"icon":170},"Defaults, adaptivity, and presets","\u002Fdocs\u002Fconfiguration\u002Fdefaults-and-presets","1.docs\u002F4.configuration\u002F4.defaults-and-presets","i-lucide-gauge",{"title":172,"path":173,"stem":174,"icon":175},"Kafka client configuration","\u002Fdocs\u002Fconfiguration\u002Fkafka-client-config","1.docs\u002F4.configuration\u002F5.kafka-client-config","i-lucide-plug",{"title":177,"path":178,"stem":179,"children":180,"icon":183},"Running in Production","\u002Fdocs\u002Fruntime","1.docs\u002F5.runtime\u002F1.index",[181,184,189,194,199,204,209,214],{"title":182,"path":178,"stem":179,"icon":183},"The runtime","i-lucide-server",{"title":185,"path":186,"stem":187,"icon":188},"The REST API","\u002Fdocs\u002Fruntime\u002Frest-api","1.docs\u002F5.runtime\u002F2.rest-api","i-lucide-globe",{"title":190,"path":191,"stem":192,"icon":193},"Health checks","\u002Fdocs\u002Fruntime\u002Fhealth-checks","1.docs\u002F5.runtime\u002F3.health-checks","i-lucide-heart-pulse",{"title":195,"path":196,"stem":197,"icon":198},"Metrics","\u002Fdocs\u002Fruntime\u002Fmetrics","1.docs\u002F5.runtime\u002F4.metrics","i-lucide-activity",{"title":200,"path":201,"stem":202,"icon":203},"Pause and resume","\u002Fdocs\u002Fruntime\u002Fpause-unpause","1.docs\u002F5.runtime\u002F5.pause-unpause","i-lucide-pause",{"title":205,"path":206,"stem":207,"icon":208},"Plugins and lifecycle hooks","\u002Fdocs\u002Fruntime\u002Fplugins","1.docs\u002F5.runtime\u002F6.plugins","i-lucide-puzzle",{"title":210,"path":211,"stem":212,"icon":213},"Docker images","\u002Fdocs\u002Fruntime\u002Fdocker","1.docs\u002F5.runtime\u002F7.docker","i-lucide-container",{"title":215,"path":216,"stem":217,"icon":218},"GraalVM native image","\u002Fdocs\u002Fruntime\u002Fnative-image","1.docs\u002F5.runtime\u002F8.native-image","i-lucide-zap",{"title":220,"path":221,"stem":222,"children":223,"icon":226},"Deploying & Operating","\u002Fdocs\u002Foperating","1.docs\u002F6.operating\u002F1.index",[224,227,232,237,242,247,252],{"title":225,"path":221,"stem":222,"icon":226},"Deploying and operating","i-lucide-life-buoy",{"title":228,"path":229,"stem":230,"icon":231},"Running on Kubernetes","\u002Fdocs\u002Foperating\u002Fkubernetes","1.docs\u002F6.operating\u002F2.kubernetes","i-lucide-ship",{"title":233,"path":234,"stem":235,"icon":236},"High availability","\u002Fdocs\u002Foperating\u002Fhigh-availability","1.docs\u002F6.operating\u002F3.high-availability","i-lucide-copy",{"title":238,"path":239,"stem":240,"icon":241},"Liveness and readiness probes","\u002Fdocs\u002Foperating\u002Fprobes","1.docs\u002F6.operating\u002F4.probes","i-lucide-stethoscope",{"title":243,"path":244,"stem":245,"icon":246},"Observability","\u002Fdocs\u002Foperating\u002Fobservability","1.docs\u002F6.operating\u002F5.observability","i-lucide-telescope",{"title":248,"path":249,"stem":250,"icon":251},"Tuning under load","\u002Fdocs\u002Foperating\u002Ftuning","1.docs\u002F6.operating\u002F6.tuning","i-lucide-sliders",{"title":253,"path":254,"stem":255,"icon":256},"Production checklist","\u002Fdocs\u002Foperating\u002Fproduction-checklist","1.docs\u002F6.operating\u002F7.production-checklist","i-lucide-clipboard-check",{"title":258,"path":259,"stem":260,"children":261,"icon":85},"Migrating from Kafka Streams","\u002Fdocs\u002Fmigration","1.docs\u002F7.migration\u002F1.index",[262,263,268],{"title":258,"path":259,"stem":260,"icon":85},{"title":264,"path":265,"stem":266,"icon":267},"Migration without carrying state","\u002Fdocs\u002Fmigration\u002Fwithout-data-migration","1.docs\u002F7.migration\u002F2.without-data-migration","i-lucide-sparkles",{"title":269,"path":270,"stem":271,"icon":272},"Migration carrying state","\u002Fdocs\u002Fmigration\u002Fwith-data-migration","1.docs\u002F7.migration\u002F3.with-data-migration","i-lucide-database-backup",{"title":274,"path":275,"stem":276,"children":277,"icon":279},"Reference","\u002Fdocs\u002Freference","1.docs\u002F8.reference\u002F1.index",[278,280,285,290,295,300,305,309],{"title":274,"path":275,"stem":276,"icon":279},"i-lucide-list",{"title":281,"path":282,"stem":283,"icon":284},"Configuration reference","\u002Fdocs\u002Freference\u002Fconfiguration-reference","1.docs\u002F8.reference\u002F2.configuration-reference","i-lucide-table",{"title":286,"path":287,"stem":288,"icon":289},"REST API reference","\u002Fdocs\u002Freference\u002Frest-api-reference","1.docs\u002F8.reference\u002F3.rest-api-reference","i-lucide-network",{"title":291,"path":292,"stem":293,"icon":294},"Gradle plugin reference","\u002Fdocs\u002Freference\u002Fgradle-plugin-reference","1.docs\u002F8.reference\u002F4.gradle-plugin-reference","i-lucide-box",{"title":296,"path":297,"stem":298,"icon":299},"Maven reference","\u002Fdocs\u002Freference\u002Fmaven-reference","1.docs\u002F8.reference\u002F5.maven-reference","i-simple-icons-apachemaven",{"title":301,"path":302,"stem":303,"icon":304},"Kafka Streams compatibility matrix","\u002Fdocs\u002Freference\u002Fks-compatibility-matrix","1.docs\u002F8.reference\u002F6.ks-compatibility-matrix","i-lucide-table-2",{"title":306,"path":307,"stem":308,"icon":170},"Metrics reference","\u002Fdocs\u002Freference\u002Fmetrics-reference","1.docs\u002F8.reference\u002F7.metrics-reference",{"title":310,"path":311,"stem":312,"icon":313},"Glossary","\u002Fdocs\u002Freference\u002Fglossary","1.docs\u002F8.reference\u002F8.glossary","i-lucide-book-a",{"id":315,"title":105,"body":316,"description":6763,"extension":6764,"meta":6765,"navigation":6766,"pageType":6767,"path":106,"seo":6768,"stem":107,"__hash__":6769},"docs\u002F1.docs\u002F3.building\u002F12.testing.md",{"type":317,"value":318,"toc":6748},"minimark",[319,327,402,407,428,583,593,597,613,643,1921,1946,1951,1981,1994,1998,2007,2672,2690,2706,2710,2725,3141,3161,3179,3183,3202,3249,3268,3275,4109,4119,4123,4126,4263,4276,4991,5007,5011,5031,5272,5276,5283,5311,5329,5963,5967,5987,6002,6015,6223,6249,6253,6259,6332,6685,6703,6707,6744],[320,321,322,326],"p",{},[323,324,325],"code",{},"stoatflow-test-utils"," runs your topology synchronously, in-process, with no Kafka broker. You pipe records in, read records out, advance time and watermarks by hand, and read state stores directly for assertions. Because processing is synchronous and single-threaded, tests are deterministic and easy to debug.",[328,329,330],"tldr-panel",{},[331,332,333,345,358,370,386],"ul",{},[334,335,336,340,341,344],"li",{},[337,338,339],"strong",{},"Driver:"," ",[323,342,343],{},"TopologyTestDriver.fromBuilder(builder)"," — captures your topology, processors, and state stores.",[334,346,347,340,350,353,354,357],{},[337,348,349],{},"In \u002F out:",[323,351,352],{},"createInputTopic(...).pipeInput(...)"," and ",[323,355,356],{},"createOutputTopic(...).readRecord()",".",[334,359,360,340,363,353,366,369],{},[337,361,362],{},"Time:",[323,364,365],{},"advanceWallClockTime(Duration)",[323,367,368],{},"advanceWatermark(timestampMs)"," drive punctuators, timers, window closes, and scheduled sources.",[334,371,372,340,375,378,379,378,382,385],{},[337,373,374],{},"State:",[323,376,377],{},"getKeyValueStore(name)"," \u002F ",[323,380,381],{},"getWindowStore",[323,383,384],{},"getSessionStore"," for direct assertions.",[334,387,388,340,391,394,395,398,399,357],{},[337,389,390],{},"Config-driven:",[323,392,393],{},"StoatFlowTestDriver.fromConfig(...)"," builds a driver from ",[323,396,397],{},"application.yaml"," on the test classpath — the test-time mirror of ",[323,400,401],{},"StoatFlowRuntime.fromConfig(...)",[403,404,406],"h2",{"id":405},"add-the-dependency","Add the dependency",[320,408,409,411,412,415,416,418,419,424,425,357],{},[323,410,325],{}," is a ",[323,413,414],{},"testImplementation"," dependency. If you load configuration from ",[323,417,397],{}," in tests (see ",[420,421,423],"a",{"href":422},"#config-driven-tests-stoatflowtestdriver","Config-driven tests","), also add ",[323,426,427],{},"stoatflow-test-runtime",[429,430,432,502],"code-tabs",{"group":431},"build",[433,434,440],"pre",{"className":435,"code":436,"filename":437,"language":438,"meta":439,"style":439},"language-kotlin shiki shiki-themes vitesse-light","\u002F\u002F build.gradle.kts\ndependencies {\n    testImplementation(\"io.stoatflow:stoatflow-test-utils:\u003Cstoatflow-version>\")\n    \u002F\u002F Config-driven tests (loads application.yaml):\n    testImplementation(\"io.stoatflow:stoatflow-test-runtime:\u003Cstoatflow-version>\")\n}\n","Gradle","kotlin","",[323,441,442,451,462,478,484,496],{"__ignoreMap":439},[443,444,447],"span",{"class":445,"line":446},"line",1,[443,448,450],{"class":449},"s8zF2","\u002F\u002F build.gradle.kts\n",[443,452,454,458],{"class":445,"line":453},2,[443,455,457],{"class":456},"sySUi","dependencies",[443,459,461],{"class":460},"suHK_"," {\n",[443,463,465,468,471,475],{"class":445,"line":464},3,[443,466,467],{"class":456},"    testImplementation",[443,469,470],{"class":460},"(",[443,472,474],{"class":473},"spphp","\"io.stoatflow:stoatflow-test-utils:\u003Cstoatflow-version>\"",[443,476,477],{"class":460},")\n",[443,479,481],{"class":445,"line":480},4,[443,482,483],{"class":449},"    \u002F\u002F Config-driven tests (loads application.yaml):\n",[443,485,487,489,491,494],{"class":445,"line":486},5,[443,488,467],{"class":456},[443,490,470],{"class":460},[443,492,493],{"class":473},"\"io.stoatflow:stoatflow-test-runtime:\u003Cstoatflow-version>\"",[443,495,477],{"class":460},[443,497,499],{"class":445,"line":498},6,[443,500,501],{"class":460},"}\n",[433,503,508],{"className":504,"code":505,"filename":506,"language":507,"meta":439,"style":439},"language-xml shiki shiki-themes vitesse-light","\u003C!-- pom.xml -->\n\u003Cdependency>\n  \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n  \u003CartifactId>stoatflow-test-utils\u003C\u002FartifactId>\n  \u003Cversion>${stoatflow.version}\u003C\u002Fversion>\n  \u003Cscope>test\u003C\u002Fscope>\n\u003C\u002Fdependency>\n\u003C!-- Config-driven tests (loads application.yaml): -->\n\u003Cdependency>\n  \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n  \u003CartifactId>stoatflow-test-runtime\u003C\u002FartifactId>\n  \u003Cversion>${stoatflow.version}\u003C\u002Fversion>\n  \u003Cscope>test\u003C\u002Fscope>\n\u003C\u002Fdependency>\n","Maven","xml",[323,509,510,515,520,525,530,535,540,546,552,557,562,568,573,578],{"__ignoreMap":439},[443,511,512],{"class":445,"line":446},[443,513,514],{},"\u003C!-- pom.xml -->\n",[443,516,517],{"class":445,"line":453},[443,518,519],{},"\u003Cdependency>\n",[443,521,522],{"class":445,"line":464},[443,523,524],{},"  \u003CgroupId>io.stoatflow\u003C\u002FgroupId>\n",[443,526,527],{"class":445,"line":480},[443,528,529],{},"  \u003CartifactId>stoatflow-test-utils\u003C\u002FartifactId>\n",[443,531,532],{"class":445,"line":486},[443,533,534],{},"  \u003Cversion>${stoatflow.version}\u003C\u002Fversion>\n",[443,536,537],{"class":445,"line":498},[443,538,539],{},"  \u003Cscope>test\u003C\u002Fscope>\n",[443,541,543],{"class":445,"line":542},7,[443,544,545],{},"\u003C\u002Fdependency>\n",[443,547,549],{"class":445,"line":548},8,[443,550,551],{},"\u003C!-- Config-driven tests (loads application.yaml): -->\n",[443,553,555],{"class":445,"line":554},9,[443,556,519],{},[443,558,560],{"class":445,"line":559},10,[443,561,524],{},[443,563,565],{"class":445,"line":564},11,[443,566,567],{},"  \u003CartifactId>stoatflow-test-runtime\u003C\u002FartifactId>\n",[443,569,571],{"class":445,"line":570},12,[443,572,534],{},[443,574,576],{"class":445,"line":575},13,[443,577,539],{},[443,579,581],{"class":445,"line":580},14,[443,582,545],{},[320,584,585,586,589,590,592],{},"The current version is ",[587,588],"stoatflow-version",{},". See ",[420,591,18],{"href":19}," for the repository and version setup.",[403,594,596],{"id":595},"a-first-test","A first test",[320,598,599,601,602,605,606,378,609,612],{},[323,600,343],{}," compiles the topology from a ",[323,603,604],{},"StreamsBuilder"," and wires up the processor and state-store registries automatically — it's the recommended entry point. Then ",[323,607,608],{},"createInputTopic",[323,610,611],{},"createOutputTopic"," give you typed handles for piping records and reading results.",[320,614,615,616,378,618,620,621,624,625,378,628,631,632,635,636,639,640,642],{},"The serdes you pass to ",[323,617,608],{},[323,619,611],{}," are ",[337,622,623],{},"applied",", exactly as the engine would: piped keys and values are serialized to wire bytes and re-deserialized through the source-node serde before the first processor sees them, and sink output is deserialized through the serdes you pass at read time. (KS-shaped ",[323,626,627],{},"createInputTopic(topic, Serializer, Serializer)",[323,629,630],{},"createOutputTopic(topic, Deserializer, Deserializer)"," overloads exist too.) Records flow through the topology ",[337,633,634],{},"synchronously"," on ",[323,637,638],{},"pipeInput"," — by the time ",[323,641,638],{}," returns, the output is already on the sink queue.",[429,644,646,1142],{"group":645},"lang",[433,647,650],{"className":435,"code":648,"filename":649,"language":438,"meta":439,"style":439},"import io.stoatflow.core.topology.StreamsBuilder\nimport io.stoatflow.testutils.TopologyTestDriver\nimport org.apache.kafka.common.serialization.Serdes\nimport org.assertj.core.api.Assertions.assertThat\nimport org.junit.jupiter.api.AfterEach\nimport org.junit.jupiter.api.BeforeEach\nimport org.junit.jupiter.api.Test\n\nclass UppercaseTopologyTest {\n    private lateinit var driver: TopologyTestDriver\n\n    @BeforeEach\n    fun setup() {\n        val builder = StreamsBuilder()\n        builder\n            .stream\u003CString, String>(\"input-topic\")\n            .mapValues { value -> value.uppercase() }\n            .filter { _, value -> value.length > 3 }\n            .to(\"output-topic\")\n\n        driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG)\n    }\n\n    @AfterEach\n    fun teardown() = driver.close()\n\n    @Test\n    fun `maps and filters values`() {\n        val input = driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String())\n        val output = driver.createOutputTopic\u003CString, String>(\"output-topic\", Serdes.String(), Serdes.String())\n\n        input.pipeInput(\"k1\", \"hello\")\n        input.pipeInput(\"k2\", \"no\")   \u002F\u002F filtered out (length \u003C= 3 after uppercasing)\n\n        assertThat(output.readRecord()?.value).isEqualTo(\"HELLO\")\n        assertThat(output.isEmpty()).isTrue()\n    }\n}\n","Kotlin",[323,651,652,661,668,675,682,689,696,703,709,720,738,742,747,758,776,782,810,838,868,883,888,905,911,916,922,943,948,954,964,995,1031,1036,1056,1079,1084,1114,1132,1137],{"__ignoreMap":439},[443,653,654,658],{"class":445,"line":446},[443,655,657],{"class":656},"sbBg2","import",[443,659,660],{"class":456}," io.stoatflow.core.topology.StreamsBuilder\n",[443,662,663,665],{"class":445,"line":453},[443,664,657],{"class":656},[443,666,667],{"class":456}," io.stoatflow.testutils.TopologyTestDriver\n",[443,669,670,672],{"class":445,"line":464},[443,671,657],{"class":656},[443,673,674],{"class":456}," org.apache.kafka.common.serialization.Serdes\n",[443,676,677,679],{"class":445,"line":480},[443,678,657],{"class":656},[443,680,681],{"class":456}," org.assertj.core.api.Assertions.assertThat\n",[443,683,684,686],{"class":445,"line":486},[443,685,657],{"class":656},[443,687,688],{"class":456}," org.junit.jupiter.api.AfterEach\n",[443,690,691,693],{"class":445,"line":498},[443,692,657],{"class":656},[443,694,695],{"class":456}," org.junit.jupiter.api.BeforeEach\n",[443,697,698,700],{"class":445,"line":542},[443,699,657],{"class":656},[443,701,702],{"class":456}," org.junit.jupiter.api.Test\n",[443,704,705],{"class":445,"line":548},[443,706,708],{"emptyLinePlaceholder":707},true,"\n",[443,710,711,714,718],{"class":445,"line":554},[443,712,713],{"class":656},"class",[443,715,717],{"class":716},"sUxyF"," UppercaseTopologyTest",[443,719,461],{"class":460},[443,721,722,726,729,732,735],{"class":445,"line":559},[443,723,725],{"class":724},"si04Y","    private",[443,727,728],{"class":724}," lateinit",[443,730,731],{"class":656}," var",[443,733,734],{"class":460}," driver: ",[443,736,737],{"class":716},"TopologyTestDriver\n",[443,739,740],{"class":445,"line":564},[443,741,708],{"emptyLinePlaceholder":707},[443,743,744],{"class":445,"line":570},[443,745,746],{"class":716},"    @BeforeEach\n",[443,748,749,752,755],{"class":445,"line":575},[443,750,751],{"class":656},"    fun",[443,753,754],{"class":456}," setup",[443,756,757],{"class":460},"() {\n",[443,759,760,763,766,770,773],{"class":445,"line":580},[443,761,762],{"class":656},"        val",[443,764,765],{"class":460}," builder ",[443,767,769],{"class":768},"sYZai","=",[443,771,772],{"class":456}," StreamsBuilder",[443,774,775],{"class":460},"()\n",[443,777,779],{"class":445,"line":778},15,[443,780,781],{"class":460},"        builder\n",[443,783,785,788,791,794,797,800,802,805,808],{"class":445,"line":784},16,[443,786,787],{"class":460},"            .",[443,789,790],{"class":456},"stream",[443,792,793],{"class":460},"\u003C",[443,795,796],{"class":716},"String",[443,798,799],{"class":460},", ",[443,801,796],{"class":716},[443,803,804],{"class":460},">(",[443,806,807],{"class":473},"\"input-topic\"",[443,809,477],{"class":460},[443,811,813,815,818,821,824,827,830,832,835],{"class":445,"line":812},17,[443,814,787],{"class":460},[443,816,817],{"class":456},"mapValues",[443,819,820],{"class":460}," { ",[443,822,823],{"class":724},"value",[443,825,826],{"class":768}," ->",[443,828,829],{"class":724}," value",[443,831,357],{"class":460},[443,833,834],{"class":456},"uppercase",[443,836,837],{"class":460},"() }\n",[443,839,841,843,846,849,851,853,855,858,861,865],{"class":445,"line":840},18,[443,842,787],{"class":460},[443,844,845],{"class":456},"filter",[443,847,848],{"class":460}," { _, ",[443,850,823],{"class":724},[443,852,826],{"class":768},[443,854,829],{"class":724},[443,856,857],{"class":460},".length ",[443,859,860],{"class":724},">",[443,862,864],{"class":863},"s-TwI"," 3",[443,866,867],{"class":460}," }\n",[443,869,871,873,876,878,881],{"class":445,"line":870},19,[443,872,787],{"class":460},[443,874,875],{"class":456},"to",[443,877,470],{"class":460},[443,879,880],{"class":473},"\"output-topic\"",[443,882,477],{"class":460},[443,884,886],{"class":445,"line":885},20,[443,887,708],{"emptyLinePlaceholder":707},[443,889,891,894,896,899,902],{"class":445,"line":890},21,[443,892,893],{"class":460},"        driver ",[443,895,769],{"class":768},[443,897,898],{"class":460}," TopologyTestDriver.",[443,900,901],{"class":456},"fromBuilder",[443,903,904],{"class":460},"(builder, TopologyTestDriver.STRING_CONFIG)\n",[443,906,908],{"class":445,"line":907},22,[443,909,910],{"class":460},"    }\n",[443,912,914],{"class":445,"line":913},23,[443,915,708],{"emptyLinePlaceholder":707},[443,917,919],{"class":445,"line":918},24,[443,920,921],{"class":716},"    @AfterEach\n",[443,923,925,927,930,933,935,938,941],{"class":445,"line":924},25,[443,926,751],{"class":656},[443,928,929],{"class":456}," teardown",[443,931,932],{"class":460},"() ",[443,934,769],{"class":768},[443,936,937],{"class":460}," driver.",[443,939,940],{"class":456},"close",[443,942,775],{"class":460},[443,944,946],{"class":445,"line":945},26,[443,947,708],{"emptyLinePlaceholder":707},[443,949,951],{"class":445,"line":950},27,[443,952,953],{"class":716},"    @Test\n",[443,955,957,959,962],{"class":445,"line":956},28,[443,958,751],{"class":656},[443,960,961],{"class":456}," `maps and filters values`",[443,963,757],{"class":460},[443,965,967,969,972,974,976,978,980,982,985,987,990,992],{"class":445,"line":966},29,[443,968,762],{"class":656},[443,970,971],{"class":460}," input ",[443,973,769],{"class":768},[443,975,937],{"class":460},[443,977,608],{"class":456},[443,979,470],{"class":460},[443,981,807],{"class":473},[443,983,984],{"class":460},", Serdes.",[443,986,796],{"class":456},[443,988,989],{"class":460},"(), Serdes.",[443,991,796],{"class":456},[443,993,994],{"class":460},"())\n",[443,996,998,1000,1003,1005,1007,1009,1011,1013,1015,1017,1019,1021,1023,1025,1027,1029],{"class":445,"line":997},30,[443,999,762],{"class":656},[443,1001,1002],{"class":460}," output ",[443,1004,769],{"class":768},[443,1006,937],{"class":460},[443,1008,611],{"class":456},[443,1010,793],{"class":460},[443,1012,796],{"class":716},[443,1014,799],{"class":460},[443,1016,796],{"class":716},[443,1018,804],{"class":460},[443,1020,880],{"class":473},[443,1022,984],{"class":460},[443,1024,796],{"class":456},[443,1026,989],{"class":460},[443,1028,796],{"class":456},[443,1030,994],{"class":460},[443,1032,1034],{"class":445,"line":1033},31,[443,1035,708],{"emptyLinePlaceholder":707},[443,1037,1039,1042,1044,1046,1049,1051,1054],{"class":445,"line":1038},32,[443,1040,1041],{"class":460},"        input.",[443,1043,638],{"class":456},[443,1045,470],{"class":460},[443,1047,1048],{"class":473},"\"k1\"",[443,1050,799],{"class":460},[443,1052,1053],{"class":473},"\"hello\"",[443,1055,477],{"class":460},[443,1057,1059,1061,1063,1065,1068,1070,1073,1076],{"class":445,"line":1058},33,[443,1060,1041],{"class":460},[443,1062,638],{"class":456},[443,1064,470],{"class":460},[443,1066,1067],{"class":473},"\"k2\"",[443,1069,799],{"class":460},[443,1071,1072],{"class":473},"\"no\"",[443,1074,1075],{"class":460},")   ",[443,1077,1078],{"class":449},"\u002F\u002F filtered out (length \u003C= 3 after uppercasing)\n",[443,1080,1082],{"class":445,"line":1081},34,[443,1083,708],{"emptyLinePlaceholder":707},[443,1085,1087,1090,1093,1096,1099,1101,1104,1107,1109,1112],{"class":445,"line":1086},35,[443,1088,1089],{"class":456},"        assertThat",[443,1091,1092],{"class":460},"(output.",[443,1094,1095],{"class":456},"readRecord",[443,1097,1098],{"class":460},"()?.",[443,1100,823],{"class":724},[443,1102,1103],{"class":460},").",[443,1105,1106],{"class":456},"isEqualTo",[443,1108,470],{"class":460},[443,1110,1111],{"class":473},"\"HELLO\"",[443,1113,477],{"class":460},[443,1115,1117,1119,1121,1124,1127,1130],{"class":445,"line":1116},36,[443,1118,1089],{"class":456},[443,1120,1092],{"class":460},[443,1122,1123],{"class":456},"isEmpty",[443,1125,1126],{"class":460},"()).",[443,1128,1129],{"class":456},"isTrue",[443,1131,775],{"class":460},[443,1133,1135],{"class":445,"line":1134},37,[443,1136,910],{"class":460},[443,1138,1140],{"class":445,"line":1139},38,[443,1141,501],{"class":460},[433,1143,1148],{"className":1144,"code":1145,"filename":1146,"language":1147,"meta":439,"style":439},"language-java shiki shiki-themes vitesse-light","import io.stoatflow.core.topology.StreamsBuilder;\nimport io.stoatflow.testutils.TestInputTopic;\nimport io.stoatflow.testutils.TestOutputTopic;\nimport io.stoatflow.testutils.TopologyTestDriver;\nimport org.apache.kafka.common.serialization.Serdes;\nimport org.junit.jupiter.api.AfterEach;\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\n\nimport static org.assertj.core.api.Assertions.assertThat;\n\nclass UppercaseTopologyTest {\n\n    private TopologyTestDriver driver;\n\n    @BeforeEach\n    void setup() {\n        StreamsBuilder builder = new StreamsBuilder();\n        builder.\u003CString, String>stream(\"input-topic\")\n            .mapValues(value -> value.toUpperCase())\n            .filter((key, value) -> value.length() > 3)\n            .to(\"output-topic\");\n\n        driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG);\n    }\n\n    @AfterEach\n    void teardown() {\n        driver.close();\n    }\n\n    @Test\n    void mapsAndFiltersValues() {\n        TestInputTopic\u003CString, String> input =\n            driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String());\n        TestOutputTopic\u003CString, String> output =\n            driver.createOutputTopic(\"output-topic\", Serdes.String(), Serdes.String());\n\n        input.pipeInput(\"k1\", \"hello\");\n        input.pipeInput(\"k2\", \"no\");   \u002F\u002F filtered out\n\n        assertThat(output.readRecord().getValue()).isEqualTo(\"HELLO\");\n        assertThat(output.isEmpty()).isTrue();\n    }\n}\n","Java","java",[323,1149,1150,1179,1201,1222,1243,1277,1305,1330,1355,1359,1393,1397,1405,1409,1422,1426,1434,1446,1465,1499,1522,1559,1577,1581,1609,1613,1617,1624,1634,1645,1649,1653,1660,1671,1692,1730,1750,1784,1788,1819,1852,1857,1892,1911,1916],{"__ignoreMap":439},[443,1151,1152,1154,1157,1159,1162,1164,1167,1169,1172,1174,1176],{"class":445,"line":446},[443,1153,657],{"class":656},[443,1155,1156],{"class":460}," io",[443,1158,357],{"class":768},[443,1160,1161],{"class":460},"stoatflow",[443,1163,357],{"class":768},[443,1165,1166],{"class":460},"core",[443,1168,357],{"class":768},[443,1170,1171],{"class":460},"topology",[443,1173,357],{"class":768},[443,1175,604],{"class":460},[443,1177,1178],{"class":768},";\n",[443,1180,1181,1183,1185,1187,1189,1191,1194,1196,1199],{"class":445,"line":453},[443,1182,657],{"class":656},[443,1184,1156],{"class":460},[443,1186,357],{"class":768},[443,1188,1161],{"class":460},[443,1190,357],{"class":768},[443,1192,1193],{"class":460},"testutils",[443,1195,357],{"class":768},[443,1197,1198],{"class":460},"TestInputTopic",[443,1200,1178],{"class":768},[443,1202,1203,1205,1207,1209,1211,1213,1215,1217,1220],{"class":445,"line":464},[443,1204,657],{"class":656},[443,1206,1156],{"class":460},[443,1208,357],{"class":768},[443,1210,1161],{"class":460},[443,1212,357],{"class":768},[443,1214,1193],{"class":460},[443,1216,357],{"class":768},[443,1218,1219],{"class":460},"TestOutputTopic",[443,1221,1178],{"class":768},[443,1223,1224,1226,1228,1230,1232,1234,1236,1238,1241],{"class":445,"line":480},[443,1225,657],{"class":656},[443,1227,1156],{"class":460},[443,1229,357],{"class":768},[443,1231,1161],{"class":460},[443,1233,357],{"class":768},[443,1235,1193],{"class":460},[443,1237,357],{"class":768},[443,1239,1240],{"class":460},"TopologyTestDriver",[443,1242,1178],{"class":768},[443,1244,1245,1247,1250,1252,1255,1257,1260,1262,1265,1267,1270,1272,1275],{"class":445,"line":486},[443,1246,657],{"class":656},[443,1248,1249],{"class":460}," org",[443,1251,357],{"class":768},[443,1253,1254],{"class":460},"apache",[443,1256,357],{"class":768},[443,1258,1259],{"class":460},"kafka",[443,1261,357],{"class":768},[443,1263,1264],{"class":460},"common",[443,1266,357],{"class":768},[443,1268,1269],{"class":460},"serialization",[443,1271,357],{"class":768},[443,1273,1274],{"class":460},"Serdes",[443,1276,1178],{"class":768},[443,1278,1279,1281,1283,1285,1288,1290,1293,1295,1298,1300,1303],{"class":445,"line":498},[443,1280,657],{"class":656},[443,1282,1249],{"class":460},[443,1284,357],{"class":768},[443,1286,1287],{"class":460},"junit",[443,1289,357],{"class":768},[443,1291,1292],{"class":460},"jupiter",[443,1294,357],{"class":768},[443,1296,1297],{"class":460},"api",[443,1299,357],{"class":768},[443,1301,1302],{"class":460},"AfterEach",[443,1304,1178],{"class":768},[443,1306,1307,1309,1311,1313,1315,1317,1319,1321,1323,1325,1328],{"class":445,"line":542},[443,1308,657],{"class":656},[443,1310,1249],{"class":460},[443,1312,357],{"class":768},[443,1314,1287],{"class":460},[443,1316,357],{"class":768},[443,1318,1292],{"class":460},[443,1320,357],{"class":768},[443,1322,1297],{"class":460},[443,1324,357],{"class":768},[443,1326,1327],{"class":460},"BeforeEach",[443,1329,1178],{"class":768},[443,1331,1332,1334,1336,1338,1340,1342,1344,1346,1348,1350,1353],{"class":445,"line":548},[443,1333,657],{"class":656},[443,1335,1249],{"class":460},[443,1337,357],{"class":768},[443,1339,1287],{"class":460},[443,1341,357],{"class":768},[443,1343,1292],{"class":460},[443,1345,357],{"class":768},[443,1347,1297],{"class":460},[443,1349,357],{"class":768},[443,1351,1352],{"class":460},"Test",[443,1354,1178],{"class":768},[443,1356,1357],{"class":445,"line":554},[443,1358,708],{"emptyLinePlaceholder":707},[443,1360,1361,1363,1366,1368,1370,1373,1375,1377,1379,1381,1383,1386,1388,1391],{"class":445,"line":559},[443,1362,657],{"class":656},[443,1364,1365],{"class":724}," static",[443,1367,1249],{"class":460},[443,1369,357],{"class":768},[443,1371,1372],{"class":460},"assertj",[443,1374,357],{"class":768},[443,1376,1166],{"class":460},[443,1378,357],{"class":768},[443,1380,1297],{"class":460},[443,1382,357],{"class":768},[443,1384,1385],{"class":460},"Assertions",[443,1387,357],{"class":768},[443,1389,1390],{"class":460},"assertThat",[443,1392,1178],{"class":768},[443,1394,1395],{"class":445,"line":564},[443,1396,708],{"emptyLinePlaceholder":707},[443,1398,1399,1401,1403],{"class":445,"line":570},[443,1400,713],{"class":724},[443,1402,717],{"class":716},[443,1404,461],{"class":768},[443,1406,1407],{"class":445,"line":575},[443,1408,708],{"emptyLinePlaceholder":707},[443,1410,1411,1413,1416,1420],{"class":445,"line":580},[443,1412,725],{"class":724},[443,1414,1415],{"class":460}," TopologyTestDriver",[443,1417,1419],{"class":1418},"svycV"," driver",[443,1421,1178],{"class":768},[443,1423,1424],{"class":445,"line":778},[443,1425,708],{"emptyLinePlaceholder":707},[443,1427,1428,1431],{"class":445,"line":784},[443,1429,1430],{"class":768},"    @",[443,1432,1433],{"class":724},"BeforeEach\n",[443,1435,1436,1439,1441,1444],{"class":445,"line":812},[443,1437,1438],{"class":724},"    void",[443,1440,754],{"class":456},[443,1442,1443],{"class":768},"()",[443,1445,461],{"class":768},[443,1447,1448,1451,1454,1457,1460,1462],{"class":445,"line":840},[443,1449,1450],{"class":460},"        StreamsBuilder",[443,1452,1453],{"class":1418}," builder",[443,1455,1456],{"class":768}," =",[443,1458,1459],{"class":656}," new",[443,1461,772],{"class":456},[443,1463,1464],{"class":768},"();\n",[443,1466,1467,1470,1472,1474,1476,1479,1482,1484,1486,1488,1492,1495,1497],{"class":445,"line":870},[443,1468,1469],{"class":460},"        builder",[443,1471,357],{"class":768},[443,1473,793],{"class":724},[443,1475,796],{"class":460},[443,1477,1478],{"class":768},",",[443,1480,1481],{"class":460}," String",[443,1483,860],{"class":724},[443,1485,790],{"class":456},[443,1487,470],{"class":768},[443,1489,1491],{"class":1490},"sSP4y","\"",[443,1493,1494],{"class":473},"input-topic",[443,1496,1491],{"class":1490},[443,1498,477],{"class":768},[443,1500,1501,1503,1505,1507,1510,1513,1515,1517,1520],{"class":445,"line":885},[443,1502,787],{"class":768},[443,1504,817],{"class":456},[443,1506,470],{"class":768},[443,1508,1509],{"class":460},"value ",[443,1511,1512],{"class":768},"->",[443,1514,829],{"class":1418},[443,1516,357],{"class":768},[443,1518,1519],{"class":456},"toUpperCase",[443,1521,994],{"class":768},[443,1523,1524,1526,1528,1531,1534,1536,1538,1541,1543,1545,1547,1550,1552,1555,1557],{"class":445,"line":890},[443,1525,787],{"class":768},[443,1527,845],{"class":456},[443,1529,1530],{"class":768},"((",[443,1532,1533],{"class":460},"key",[443,1535,1478],{"class":768},[443,1537,829],{"class":460},[443,1539,1540],{"class":768},")",[443,1542,826],{"class":768},[443,1544,829],{"class":1418},[443,1546,357],{"class":768},[443,1548,1549],{"class":456},"length",[443,1551,1443],{"class":768},[443,1553,1554],{"class":724}," >",[443,1556,864],{"class":863},[443,1558,477],{"class":768},[443,1560,1561,1563,1565,1567,1569,1572,1574],{"class":445,"line":907},[443,1562,787],{"class":768},[443,1564,875],{"class":456},[443,1566,470],{"class":768},[443,1568,1491],{"class":1490},[443,1570,1571],{"class":473},"output-topic",[443,1573,1491],{"class":1490},[443,1575,1576],{"class":768},");\n",[443,1578,1579],{"class":445,"line":913},[443,1580,708],{"emptyLinePlaceholder":707},[443,1582,1583,1585,1587,1589,1591,1593,1595,1598,1600,1602,1604,1607],{"class":445,"line":918},[443,1584,893],{"class":460},[443,1586,769],{"class":768},[443,1588,1415],{"class":1418},[443,1590,357],{"class":768},[443,1592,901],{"class":456},[443,1594,470],{"class":768},[443,1596,1597],{"class":460},"builder",[443,1599,1478],{"class":768},[443,1601,1415],{"class":1418},[443,1603,357],{"class":768},[443,1605,1606],{"class":1418},"STRING_CONFIG",[443,1608,1576],{"class":768},[443,1610,1611],{"class":445,"line":924},[443,1612,910],{"class":768},[443,1614,1615],{"class":445,"line":945},[443,1616,708],{"emptyLinePlaceholder":707},[443,1618,1619,1621],{"class":445,"line":950},[443,1620,1430],{"class":768},[443,1622,1623],{"class":724},"AfterEach\n",[443,1625,1626,1628,1630,1632],{"class":445,"line":956},[443,1627,1438],{"class":724},[443,1629,929],{"class":456},[443,1631,1443],{"class":768},[443,1633,461],{"class":768},[443,1635,1636,1639,1641,1643],{"class":445,"line":966},[443,1637,1638],{"class":1418},"        driver",[443,1640,357],{"class":768},[443,1642,940],{"class":456},[443,1644,1464],{"class":768},[443,1646,1647],{"class":445,"line":997},[443,1648,910],{"class":768},[443,1650,1651],{"class":445,"line":1033},[443,1652,708],{"emptyLinePlaceholder":707},[443,1654,1655,1657],{"class":445,"line":1038},[443,1656,1430],{"class":768},[443,1658,1659],{"class":724},"Test\n",[443,1661,1662,1664,1667,1669],{"class":445,"line":1058},[443,1663,1438],{"class":724},[443,1665,1666],{"class":456}," mapsAndFiltersValues",[443,1668,1443],{"class":768},[443,1670,461],{"class":768},[443,1672,1673,1676,1678,1680,1682,1684,1686,1689],{"class":445,"line":1081},[443,1674,1675],{"class":460},"        TestInputTopic",[443,1677,793],{"class":768},[443,1679,796],{"class":724},[443,1681,1478],{"class":768},[443,1683,1481],{"class":724},[443,1685,860],{"class":768},[443,1687,1688],{"class":1418}," input",[443,1690,1691],{"class":768}," =\n",[443,1693,1694,1697,1699,1701,1703,1705,1707,1709,1711,1714,1716,1718,1721,1723,1725,1727],{"class":445,"line":1086},[443,1695,1696],{"class":1418},"            driver",[443,1698,357],{"class":768},[443,1700,608],{"class":456},[443,1702,470],{"class":768},[443,1704,1491],{"class":1490},[443,1706,1494],{"class":473},[443,1708,1491],{"class":1490},[443,1710,1478],{"class":768},[443,1712,1713],{"class":1418}," Serdes",[443,1715,357],{"class":768},[443,1717,796],{"class":456},[443,1719,1720],{"class":768},"(),",[443,1722,1713],{"class":1418},[443,1724,357],{"class":768},[443,1726,796],{"class":456},[443,1728,1729],{"class":768},"());\n",[443,1731,1732,1735,1737,1739,1741,1743,1745,1748],{"class":445,"line":1116},[443,1733,1734],{"class":460},"        TestOutputTopic",[443,1736,793],{"class":768},[443,1738,796],{"class":724},[443,1740,1478],{"class":768},[443,1742,1481],{"class":724},[443,1744,860],{"class":768},[443,1746,1747],{"class":1418}," output",[443,1749,1691],{"class":768},[443,1751,1752,1754,1756,1758,1760,1762,1764,1766,1768,1770,1772,1774,1776,1778,1780,1782],{"class":445,"line":1134},[443,1753,1696],{"class":1418},[443,1755,357],{"class":768},[443,1757,611],{"class":456},[443,1759,470],{"class":768},[443,1761,1491],{"class":1490},[443,1763,1571],{"class":473},[443,1765,1491],{"class":1490},[443,1767,1478],{"class":768},[443,1769,1713],{"class":1418},[443,1771,357],{"class":768},[443,1773,796],{"class":456},[443,1775,1720],{"class":768},[443,1777,1713],{"class":1418},[443,1779,357],{"class":768},[443,1781,796],{"class":456},[443,1783,1729],{"class":768},[443,1785,1786],{"class":445,"line":1139},[443,1787,708],{"emptyLinePlaceholder":707},[443,1789,1791,1794,1796,1798,1800,1802,1805,1807,1809,1812,1815,1817],{"class":445,"line":1790},39,[443,1792,1793],{"class":1418},"        input",[443,1795,357],{"class":768},[443,1797,638],{"class":456},[443,1799,470],{"class":768},[443,1801,1491],{"class":1490},[443,1803,1804],{"class":473},"k1",[443,1806,1491],{"class":1490},[443,1808,1478],{"class":768},[443,1810,1811],{"class":1490}," \"",[443,1813,1814],{"class":473},"hello",[443,1816,1491],{"class":1490},[443,1818,1576],{"class":768},[443,1820,1822,1824,1826,1828,1830,1832,1835,1837,1839,1841,1844,1846,1849],{"class":445,"line":1821},40,[443,1823,1793],{"class":1418},[443,1825,357],{"class":768},[443,1827,638],{"class":456},[443,1829,470],{"class":768},[443,1831,1491],{"class":1490},[443,1833,1834],{"class":473},"k2",[443,1836,1491],{"class":1490},[443,1838,1478],{"class":768},[443,1840,1811],{"class":1490},[443,1842,1843],{"class":473},"no",[443,1845,1491],{"class":1490},[443,1847,1848],{"class":768},");",[443,1850,1851],{"class":449},"   \u002F\u002F filtered out\n",[443,1853,1855],{"class":445,"line":1854},41,[443,1856,708],{"emptyLinePlaceholder":707},[443,1858,1860,1862,1864,1867,1869,1871,1874,1877,1879,1881,1883,1885,1888,1890],{"class":445,"line":1859},42,[443,1861,1089],{"class":456},[443,1863,470],{"class":768},[443,1865,1866],{"class":1418},"output",[443,1868,357],{"class":768},[443,1870,1095],{"class":456},[443,1872,1873],{"class":768},"().",[443,1875,1876],{"class":456},"getValue",[443,1878,1126],{"class":768},[443,1880,1106],{"class":456},[443,1882,470],{"class":768},[443,1884,1491],{"class":1490},[443,1886,1887],{"class":473},"HELLO",[443,1889,1491],{"class":1490},[443,1891,1576],{"class":768},[443,1893,1895,1897,1899,1901,1903,1905,1907,1909],{"class":445,"line":1894},43,[443,1896,1089],{"class":456},[443,1898,470],{"class":768},[443,1900,1866],{"class":1418},[443,1902,357],{"class":768},[443,1904,1123],{"class":456},[443,1906,1126],{"class":768},[443,1908,1129],{"class":456},[443,1910,1464],{"class":768},[443,1912,1914],{"class":445,"line":1913},44,[443,1915,910],{"class":768},[443,1917,1919],{"class":445,"line":1918},45,[443,1920,501],{"class":768},[1922,1923,1925],"callout",{"icon":80,"color":1924},"warning",[320,1926,1927,1929,1930,1933,1934,1937,1938,1941,1942,1945],{},[323,1928,1240],{}," is ",[337,1931,1932],{},"not thread-safe"," — it is designed for single-threaded test execution. Create a fresh instance per test case (",[323,1935,1936],{},"@BeforeEach",") and ",[323,1939,1940],{},"close()"," it in ",[323,1943,1944],{},"@AfterEach"," when running parallel test runners.",[1947,1948,1950],"h3",{"id":1949},"picking-a-config","Picking a config",[320,1952,1953,1956,1957,1960,1961,1964,1965,1968,1969,1971,1972,1974,1975,1977,1978,1980],{},[323,1954,1955],{},"fromBuilder(builder)"," defaults to ",[323,1958,1959],{},"ByteArray"," key\u002Fvalue serdes (matching the production ",[323,1962,1963],{},"StreamsConfig"," defaults). For String-keyed topologies, pass the bundled ",[323,1966,1967],{},"TopologyTestDriver.STRING_CONFIG",", which sets ",[323,1970,796],{}," default serdes. For anything else, build a ",[323,1973,1963],{}," explicitly, or use ",[323,1976,393],{}," to load your real ",[323,1979,397],{}," (see below).",[320,1982,1983,1985,1986,1989,1990,1993],{},[323,1984,901],{}," is overloaded with an optional ",[323,1987,1988],{},"initialWallClockTime"," (an ",[323,1991,1992],{},"Instant",") — useful when a test asserts on absolute wall-clock-based fire times of scheduled sources or processing-time timers.",[403,1995,1997],{"id":1996},"piping-input","Piping input",[320,1999,2000,2002,2003,2006],{},[323,2001,1198],{}," pipes records into a source topic. The simplest form takes a key and value; overloads add an explicit timestamp and headers, and a ",[323,2004,2005],{},"TestRecord"," form.",[429,2008,2009,2279],{"group":645},[433,2010,2012],{"className":435,"code":2011,"filename":649,"language":438,"meta":439,"style":439},"import io.stoatflow.core.state.KeyValue\n\nval input = driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String())\n\ninput.pipeInput(\"k1\", \"v1\")                       \u002F\u002F uses the topic's current timestamp\ninput.pipeInput(\"k1\", \"v2\", timestamp = 1_000L)   \u002F\u002F explicit event time (ms)\ninput.pipeInput(\"k1\", null)                        \u002F\u002F tombstone (null value)\n\n\u002F\u002F Bulk helpers (KeyValue, matching Kafka Streams)\ninput.pipeKeyValueList(listOf(KeyValue(\"k1\", \"a\"), KeyValue(\"k2\", \"b\")))\ninput.pipeValueList(listOf(\"x\", \"y\"))              \u002F\u002F null keys\n\n\u002F\u002F Auto-advancing timestamps: each record steps 1s forward\ninput.withTimestamp(0L).withAutoAdvance(1_000L)\ninput.pipeInput(\"k1\", \"t0\")   \u002F\u002F ts = 0\ninput.pipeInput(\"k1\", \"t1\")   \u002F\u002F ts = 1000\n",[323,2013,2014,2021,2025,2052,2056,2078,2106,2127,2131,2136,2179,2206,2210,2215,2239,2259],{"__ignoreMap":439},[443,2015,2016,2018],{"class":445,"line":446},[443,2017,657],{"class":656},[443,2019,2020],{"class":456}," io.stoatflow.core.state.KeyValue\n",[443,2022,2023],{"class":445,"line":453},[443,2024,708],{"emptyLinePlaceholder":707},[443,2026,2027,2030,2032,2034,2036,2038,2040,2042,2044,2046,2048,2050],{"class":445,"line":464},[443,2028,2029],{"class":656},"val",[443,2031,971],{"class":460},[443,2033,769],{"class":768},[443,2035,937],{"class":460},[443,2037,608],{"class":456},[443,2039,470],{"class":460},[443,2041,807],{"class":473},[443,2043,984],{"class":460},[443,2045,796],{"class":456},[443,2047,989],{"class":460},[443,2049,796],{"class":456},[443,2051,994],{"class":460},[443,2053,2054],{"class":445,"line":480},[443,2055,708],{"emptyLinePlaceholder":707},[443,2057,2058,2061,2063,2065,2067,2069,2072,2075],{"class":445,"line":486},[443,2059,2060],{"class":460},"input.",[443,2062,638],{"class":456},[443,2064,470],{"class":460},[443,2066,1048],{"class":473},[443,2068,799],{"class":460},[443,2070,2071],{"class":473},"\"v1\"",[443,2073,2074],{"class":460},")                       ",[443,2076,2077],{"class":449},"\u002F\u002F uses the topic's current timestamp\n",[443,2079,2080,2082,2084,2086,2088,2090,2093,2096,2098,2101,2103],{"class":445,"line":498},[443,2081,2060],{"class":460},[443,2083,638],{"class":456},[443,2085,470],{"class":460},[443,2087,1048],{"class":473},[443,2089,799],{"class":460},[443,2091,2092],{"class":473},"\"v2\"",[443,2094,2095],{"class":460},", timestamp ",[443,2097,769],{"class":768},[443,2099,2100],{"class":863}," 1_000L",[443,2102,1075],{"class":460},[443,2104,2105],{"class":449},"\u002F\u002F explicit event time (ms)\n",[443,2107,2108,2110,2112,2114,2116,2118,2121,2124],{"class":445,"line":542},[443,2109,2060],{"class":460},[443,2111,638],{"class":456},[443,2113,470],{"class":460},[443,2115,1048],{"class":473},[443,2117,799],{"class":460},[443,2119,2120],{"class":724},"null",[443,2122,2123],{"class":460},")                        ",[443,2125,2126],{"class":449},"\u002F\u002F tombstone (null value)\n",[443,2128,2129],{"class":445,"line":548},[443,2130,708],{"emptyLinePlaceholder":707},[443,2132,2133],{"class":445,"line":554},[443,2134,2135],{"class":449},"\u002F\u002F Bulk helpers (KeyValue, matching Kafka Streams)\n",[443,2137,2138,2140,2143,2145,2148,2150,2153,2155,2157,2159,2162,2165,2167,2169,2171,2173,2176],{"class":445,"line":559},[443,2139,2060],{"class":460},[443,2141,2142],{"class":456},"pipeKeyValueList",[443,2144,470],{"class":460},[443,2146,2147],{"class":456},"listOf",[443,2149,470],{"class":460},[443,2151,2152],{"class":456},"KeyValue",[443,2154,470],{"class":460},[443,2156,1048],{"class":473},[443,2158,799],{"class":460},[443,2160,2161],{"class":473},"\"a\"",[443,2163,2164],{"class":460},"), ",[443,2166,2152],{"class":456},[443,2168,470],{"class":460},[443,2170,1067],{"class":473},[443,2172,799],{"class":460},[443,2174,2175],{"class":473},"\"b\"",[443,2177,2178],{"class":460},")))\n",[443,2180,2181,2183,2186,2188,2190,2192,2195,2197,2200,2203],{"class":445,"line":564},[443,2182,2060],{"class":460},[443,2184,2185],{"class":456},"pipeValueList",[443,2187,470],{"class":460},[443,2189,2147],{"class":456},[443,2191,470],{"class":460},[443,2193,2194],{"class":473},"\"x\"",[443,2196,799],{"class":460},[443,2198,2199],{"class":473},"\"y\"",[443,2201,2202],{"class":460},"))              ",[443,2204,2205],{"class":449},"\u002F\u002F null keys\n",[443,2207,2208],{"class":445,"line":570},[443,2209,708],{"emptyLinePlaceholder":707},[443,2211,2212],{"class":445,"line":575},[443,2213,2214],{"class":449},"\u002F\u002F Auto-advancing timestamps: each record steps 1s forward\n",[443,2216,2217,2219,2222,2224,2227,2229,2232,2234,2237],{"class":445,"line":580},[443,2218,2060],{"class":460},[443,2220,2221],{"class":456},"withTimestamp",[443,2223,470],{"class":460},[443,2225,2226],{"class":863},"0L",[443,2228,1103],{"class":460},[443,2230,2231],{"class":456},"withAutoAdvance",[443,2233,470],{"class":460},[443,2235,2236],{"class":863},"1_000L",[443,2238,477],{"class":460},[443,2240,2241,2243,2245,2247,2249,2251,2254,2256],{"class":445,"line":778},[443,2242,2060],{"class":460},[443,2244,638],{"class":456},[443,2246,470],{"class":460},[443,2248,1048],{"class":473},[443,2250,799],{"class":460},[443,2252,2253],{"class":473},"\"t0\"",[443,2255,1075],{"class":460},[443,2257,2258],{"class":449},"\u002F\u002F ts = 0\n",[443,2260,2261,2263,2265,2267,2269,2271,2274,2276],{"class":445,"line":784},[443,2262,2060],{"class":460},[443,2264,638],{"class":456},[443,2266,470],{"class":460},[443,2268,1048],{"class":473},[443,2270,799],{"class":460},[443,2272,2273],{"class":473},"\"t1\"",[443,2275,1075],{"class":460},[443,2277,2278],{"class":449},"\u002F\u002F ts = 1000\n",[433,2280,2282],{"className":1144,"code":2281,"filename":1146,"language":1147,"meta":439,"style":439},"import io.stoatflow.core.state.KeyValue;\n\nTestInputTopic\u003CString, String> input =\n    driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String());\n\ninput.pipeInput(\"k1\", \"v1\");                  \u002F\u002F uses the topic's current timestamp\ninput.pipeInput(\"k1\", \"v2\", 1_000L);          \u002F\u002F explicit event time (ms)\ninput.pipeInput(\"k1\", null);                  \u002F\u002F tombstone (null value)\n\n\u002F\u002F Bulk helpers (KeyValue, matching Kafka Streams)\ninput.pipeKeyValueList(List.of(KeyValue.pair(\"k1\", \"a\"), KeyValue.pair(\"k2\", \"b\")));\ninput.pipeValueList(List.of(\"x\", \"y\"));       \u002F\u002F null keys\n\n\u002F\u002F Auto-advancing timestamps: each record steps 1s forward\ninput.withTimestamp(0L).withAutoAdvance(1_000L);\ninput.pipeInput(\"k1\", \"t0\");   \u002F\u002F ts = 0\ninput.pipeInput(\"k1\", \"t1\");   \u002F\u002F ts = 1000\n",[323,2283,2284,2309,2313,2331,2366,2370,2401,2435,2461,2465,2469,2542,2582,2586,2590,2612,2642],{"__ignoreMap":439},[443,2285,2286,2288,2290,2292,2294,2296,2298,2300,2303,2305,2307],{"class":445,"line":446},[443,2287,657],{"class":656},[443,2289,1156],{"class":460},[443,2291,357],{"class":768},[443,2293,1161],{"class":460},[443,2295,357],{"class":768},[443,2297,1166],{"class":460},[443,2299,357],{"class":768},[443,2301,2302],{"class":460},"state",[443,2304,357],{"class":768},[443,2306,2152],{"class":460},[443,2308,1178],{"class":768},[443,2310,2311],{"class":445,"line":453},[443,2312,708],{"emptyLinePlaceholder":707},[443,2314,2315,2317,2319,2321,2323,2325,2327,2329],{"class":445,"line":464},[443,2316,1198],{"class":460},[443,2318,793],{"class":768},[443,2320,796],{"class":724},[443,2322,1478],{"class":768},[443,2324,1481],{"class":724},[443,2326,860],{"class":768},[443,2328,1688],{"class":1418},[443,2330,1691],{"class":768},[443,2332,2333,2336,2338,2340,2342,2344,2346,2348,2350,2352,2354,2356,2358,2360,2362,2364],{"class":445,"line":480},[443,2334,2335],{"class":1418},"    driver",[443,2337,357],{"class":768},[443,2339,608],{"class":456},[443,2341,470],{"class":768},[443,2343,1491],{"class":1490},[443,2345,1494],{"class":473},[443,2347,1491],{"class":1490},[443,2349,1478],{"class":768},[443,2351,1713],{"class":1418},[443,2353,357],{"class":768},[443,2355,796],{"class":456},[443,2357,1720],{"class":768},[443,2359,1713],{"class":1418},[443,2361,357],{"class":768},[443,2363,796],{"class":456},[443,2365,1729],{"class":768},[443,2367,2368],{"class":445,"line":486},[443,2369,708],{"emptyLinePlaceholder":707},[443,2371,2372,2375,2377,2379,2381,2383,2385,2387,2389,2391,2394,2396,2398],{"class":445,"line":498},[443,2373,2374],{"class":1418},"input",[443,2376,357],{"class":768},[443,2378,638],{"class":456},[443,2380,470],{"class":768},[443,2382,1491],{"class":1490},[443,2384,1804],{"class":473},[443,2386,1491],{"class":1490},[443,2388,1478],{"class":768},[443,2390,1811],{"class":1490},[443,2392,2393],{"class":473},"v1",[443,2395,1491],{"class":1490},[443,2397,1848],{"class":768},[443,2399,2400],{"class":449},"                  \u002F\u002F uses the topic's current timestamp\n",[443,2402,2403,2405,2407,2409,2411,2413,2415,2417,2419,2421,2424,2426,2428,2430,2432],{"class":445,"line":542},[443,2404,2374],{"class":1418},[443,2406,357],{"class":768},[443,2408,638],{"class":456},[443,2410,470],{"class":768},[443,2412,1491],{"class":1490},[443,2414,1804],{"class":473},[443,2416,1491],{"class":1490},[443,2418,1478],{"class":768},[443,2420,1811],{"class":1490},[443,2422,2423],{"class":473},"v2",[443,2425,1491],{"class":1490},[443,2427,1478],{"class":768},[443,2429,2100],{"class":863},[443,2431,1848],{"class":768},[443,2433,2434],{"class":449},"          \u002F\u002F explicit event time (ms)\n",[443,2436,2437,2439,2441,2443,2445,2447,2449,2451,2453,2456,2458],{"class":445,"line":548},[443,2438,2374],{"class":1418},[443,2440,357],{"class":768},[443,2442,638],{"class":456},[443,2444,470],{"class":768},[443,2446,1491],{"class":1490},[443,2448,1804],{"class":473},[443,2450,1491],{"class":1490},[443,2452,1478],{"class":768},[443,2454,2455],{"class":656}," null",[443,2457,1848],{"class":768},[443,2459,2460],{"class":449},"                  \u002F\u002F tombstone (null value)\n",[443,2462,2463],{"class":445,"line":554},[443,2464,708],{"emptyLinePlaceholder":707},[443,2466,2467],{"class":445,"line":559},[443,2468,2135],{"class":449},[443,2470,2471,2473,2475,2477,2479,2482,2484,2487,2489,2491,2493,2496,2498,2500,2502,2504,2506,2508,2510,2512,2515,2518,2520,2522,2524,2526,2528,2530,2532,2534,2537,2539],{"class":445,"line":564},[443,2472,2374],{"class":1418},[443,2474,357],{"class":768},[443,2476,2142],{"class":456},[443,2478,470],{"class":768},[443,2480,2481],{"class":1418},"List",[443,2483,357],{"class":768},[443,2485,2486],{"class":456},"of",[443,2488,470],{"class":768},[443,2490,2152],{"class":1418},[443,2492,357],{"class":768},[443,2494,2495],{"class":456},"pair",[443,2497,470],{"class":768},[443,2499,1491],{"class":1490},[443,2501,1804],{"class":473},[443,2503,1491],{"class":1490},[443,2505,1478],{"class":768},[443,2507,1811],{"class":1490},[443,2509,420],{"class":473},[443,2511,1491],{"class":1490},[443,2513,2514],{"class":768},"),",[443,2516,2517],{"class":1418}," KeyValue",[443,2519,357],{"class":768},[443,2521,2495],{"class":456},[443,2523,470],{"class":768},[443,2525,1491],{"class":1490},[443,2527,1834],{"class":473},[443,2529,1491],{"class":1490},[443,2531,1478],{"class":768},[443,2533,1811],{"class":1490},[443,2535,2536],{"class":473},"b",[443,2538,1491],{"class":1490},[443,2540,2541],{"class":768},")));\n",[443,2543,2544,2546,2548,2550,2552,2554,2556,2558,2560,2562,2565,2567,2569,2571,2574,2576,2579],{"class":445,"line":570},[443,2545,2374],{"class":1418},[443,2547,357],{"class":768},[443,2549,2185],{"class":456},[443,2551,470],{"class":768},[443,2553,2481],{"class":1418},[443,2555,357],{"class":768},[443,2557,2486],{"class":456},[443,2559,470],{"class":768},[443,2561,1491],{"class":1490},[443,2563,2564],{"class":473},"x",[443,2566,1491],{"class":1490},[443,2568,1478],{"class":768},[443,2570,1811],{"class":1490},[443,2572,2573],{"class":473},"y",[443,2575,1491],{"class":1490},[443,2577,2578],{"class":768},"));",[443,2580,2581],{"class":449},"       \u002F\u002F null keys\n",[443,2583,2584],{"class":445,"line":575},[443,2585,708],{"emptyLinePlaceholder":707},[443,2587,2588],{"class":445,"line":580},[443,2589,2214],{"class":449},[443,2591,2592,2594,2596,2598,2600,2602,2604,2606,2608,2610],{"class":445,"line":778},[443,2593,2374],{"class":1418},[443,2595,357],{"class":768},[443,2597,2221],{"class":456},[443,2599,470],{"class":768},[443,2601,2226],{"class":863},[443,2603,1103],{"class":768},[443,2605,2231],{"class":456},[443,2607,470],{"class":768},[443,2609,2236],{"class":863},[443,2611,1576],{"class":768},[443,2613,2614,2616,2618,2620,2622,2624,2626,2628,2630,2632,2635,2637,2639],{"class":445,"line":784},[443,2615,2374],{"class":1418},[443,2617,357],{"class":768},[443,2619,638],{"class":456},[443,2621,470],{"class":768},[443,2623,1491],{"class":1490},[443,2625,1804],{"class":473},[443,2627,1491],{"class":1490},[443,2629,1478],{"class":768},[443,2631,1811],{"class":1490},[443,2633,2634],{"class":473},"t0",[443,2636,1491],{"class":1490},[443,2638,1848],{"class":768},[443,2640,2641],{"class":449},"   \u002F\u002F ts = 0\n",[443,2643,2644,2646,2648,2650,2652,2654,2656,2658,2660,2662,2665,2667,2669],{"class":445,"line":812},[443,2645,2374],{"class":1418},[443,2647,357],{"class":768},[443,2649,638],{"class":456},[443,2651,470],{"class":768},[443,2653,1491],{"class":1490},[443,2655,1804],{"class":473},[443,2657,1491],{"class":1490},[443,2659,1478],{"class":768},[443,2661,1811],{"class":1490},[443,2663,2664],{"class":473},"t1",[443,2666,1491],{"class":1490},[443,2668,1848],{"class":768},[443,2670,2671],{"class":449},"   \u002F\u002F ts = 1000\n",[1922,2673,2676],{"icon":2674,"color":2675},"i-lucide-info","info",[320,2677,2678,353,2680,2682,2683,2685,2686,2689],{},[323,2679,2221],{},[323,2681,2231],{}," mutate state on the ",[323,2684,1198],{}," instance that persists across calls. Call ",[323,2687,2688],{},"reset()"," to restore defaults (auto-advance disabled, timestamp back to the driver's current wall-clock time) if you reuse one input topic across test cases.",[320,2691,2692,2693,2695,2696,2699,2700,2703,2704,357],{},"The event timestamp you pass to ",[323,2694,638],{}," is the record's ",[337,2697,2698],{},"event time"," — it drives windowing, joins, and watermark-based logic. If the source was configured with a ",[323,2701,2702],{},"WatermarkStrategy"," that carries a timestamp assigner, the driver applies it the same way the runtime does, overriding the passed timestamp. See ",[420,2705,67],{"href":68},[403,2707,2709],{"id":2708},"reading-output","Reading output",[320,2711,2712,2714,2715,2718,2719,2721,2722,2724],{},[323,2713,1219],{}," drains records the topology produced to a sink topic. ",[323,2716,2717],{},"readRecord()"," returns a ",[323,2720,2005],{}," (or ",[323,2723,2120],{}," when empty); there are convenience readers for keys, values, and bulk drains.",[429,2726,2727,2911],{"group":645},[433,2728,2730],{"className":435,"code":2729,"filename":649,"language":438,"meta":439,"style":439},"val output = driver.createOutputTopic\u003CString, Long>(\"output-topic\", Serdes.String(), Serdes.Long())\n\nval record = output.readRecord()        \u002F\u002F TestRecord\u003CString, Long>? — null if empty\nrecord?.key                              \u002F\u002F \"k1\"\nrecord?.value                            \u002F\u002F 3L\nrecord?.timestamp                        \u002F\u002F event time of the emission\n\noutput.readValue()                       \u002F\u002F next value only\noutput.readKeyValue()                    \u002F\u002F next KeyValue (or null if empty)\noutput.readRecordsToList()               \u002F\u002F drain all remaining as a list of TestRecord\noutput.readKeyValuesToList()             \u002F\u002F drain all remaining as a list of KeyValues\noutput.readKeyValuesToMap()              \u002F\u002F drain all; last value per key wins\noutput.getQueueSize()                    \u002F\u002F records currently waiting\noutput.isEmpty()                         \u002F\u002F true when drained\n",[323,2731,2732,2767,2771,2791,2799,2809,2817,2821,2835,2848,2861,2874,2887,2899],{"__ignoreMap":439},[443,2733,2734,2736,2738,2740,2742,2744,2746,2748,2750,2753,2755,2757,2759,2761,2763,2765],{"class":445,"line":446},[443,2735,2029],{"class":656},[443,2737,1002],{"class":460},[443,2739,769],{"class":768},[443,2741,937],{"class":460},[443,2743,611],{"class":456},[443,2745,793],{"class":460},[443,2747,796],{"class":716},[443,2749,799],{"class":460},[443,2751,2752],{"class":716},"Long",[443,2754,804],{"class":460},[443,2756,880],{"class":473},[443,2758,984],{"class":460},[443,2760,796],{"class":456},[443,2762,989],{"class":460},[443,2764,2752],{"class":456},[443,2766,994],{"class":460},[443,2768,2769],{"class":445,"line":453},[443,2770,708],{"emptyLinePlaceholder":707},[443,2772,2773,2775,2778,2780,2783,2785,2788],{"class":445,"line":464},[443,2774,2029],{"class":656},[443,2776,2777],{"class":460}," record ",[443,2779,769],{"class":768},[443,2781,2782],{"class":460}," output.",[443,2784,1095],{"class":456},[443,2786,2787],{"class":460},"()        ",[443,2789,2790],{"class":449},"\u002F\u002F TestRecord\u003CString, Long>? — null if empty\n",[443,2792,2793,2796],{"class":445,"line":480},[443,2794,2795],{"class":460},"record?.key                              ",[443,2797,2798],{"class":449},"\u002F\u002F \"k1\"\n",[443,2800,2801,2804,2806],{"class":445,"line":486},[443,2802,2803],{"class":460},"record?.",[443,2805,823],{"class":724},[443,2807,2808],{"class":449},"                            \u002F\u002F 3L\n",[443,2810,2811,2814],{"class":445,"line":498},[443,2812,2813],{"class":460},"record?.timestamp                        ",[443,2815,2816],{"class":449},"\u002F\u002F event time of the emission\n",[443,2818,2819],{"class":445,"line":542},[443,2820,708],{"emptyLinePlaceholder":707},[443,2822,2823,2826,2829,2832],{"class":445,"line":548},[443,2824,2825],{"class":460},"output.",[443,2827,2828],{"class":456},"readValue",[443,2830,2831],{"class":460},"()                       ",[443,2833,2834],{"class":449},"\u002F\u002F next value only\n",[443,2836,2837,2839,2842,2845],{"class":445,"line":554},[443,2838,2825],{"class":460},[443,2840,2841],{"class":456},"readKeyValue",[443,2843,2844],{"class":460},"()                    ",[443,2846,2847],{"class":449},"\u002F\u002F next KeyValue (or null if empty)\n",[443,2849,2850,2852,2855,2858],{"class":445,"line":559},[443,2851,2825],{"class":460},[443,2853,2854],{"class":456},"readRecordsToList",[443,2856,2857],{"class":460},"()               ",[443,2859,2860],{"class":449},"\u002F\u002F drain all remaining as a list of TestRecord\n",[443,2862,2863,2865,2868,2871],{"class":445,"line":564},[443,2864,2825],{"class":460},[443,2866,2867],{"class":456},"readKeyValuesToList",[443,2869,2870],{"class":460},"()             ",[443,2872,2873],{"class":449},"\u002F\u002F drain all remaining as a list of KeyValues\n",[443,2875,2876,2878,2881,2884],{"class":445,"line":570},[443,2877,2825],{"class":460},[443,2879,2880],{"class":456},"readKeyValuesToMap",[443,2882,2883],{"class":460},"()              ",[443,2885,2886],{"class":449},"\u002F\u002F drain all; last value per key wins\n",[443,2888,2889,2891,2894,2896],{"class":445,"line":575},[443,2890,2825],{"class":460},[443,2892,2893],{"class":456},"getQueueSize",[443,2895,2844],{"class":460},[443,2897,2898],{"class":449},"\u002F\u002F records currently waiting\n",[443,2900,2901,2903,2905,2908],{"class":445,"line":580},[443,2902,2825],{"class":460},[443,2904,1123],{"class":456},[443,2906,2907],{"class":460},"()                         ",[443,2909,2910],{"class":449},"\u002F\u002F true when drained\n",[433,2912,2914],{"className":1144,"code":2913,"filename":1146,"language":1147,"meta":439,"style":439},"TestOutputTopic\u003CString, Long> output =\n    driver.createOutputTopic(\"output-topic\", Serdes.String(), Serdes.Long());\n\nTestRecord\u003CString, Long> record = output.readRecord();   \u002F\u002F null if empty\nrecord.getKey();        \u002F\u002F \"k1\"\nrecord.getValue();      \u002F\u002F 3L\nrecord.getTimestamp();  \u002F\u002F event time of the emission\n\noutput.readValue();              \u002F\u002F next value only\noutput.readKeyValue();           \u002F\u002F next KeyValue (or null if empty)\noutput.readRecordsToList();      \u002F\u002F drain all remaining as a list of TestRecord\noutput.readKeyValuesToList();    \u002F\u002F drain all remaining as a list of KeyValues\noutput.readKeyValuesToMap();     \u002F\u002F drain all; last value per key wins\noutput.getQueueSize();           \u002F\u002F records currently waiting\noutput.isEmpty();                \u002F\u002F true when drained\n",[323,2915,2916,2935,2969,2973,3004,3019,3032,3046,3050,3063,3076,3089,3102,3115,3128],{"__ignoreMap":439},[443,2917,2918,2920,2922,2924,2926,2929,2931,2933],{"class":445,"line":446},[443,2919,1219],{"class":460},[443,2921,793],{"class":768},[443,2923,796],{"class":724},[443,2925,1478],{"class":768},[443,2927,2928],{"class":724}," Long",[443,2930,860],{"class":768},[443,2932,1747],{"class":1418},[443,2934,1691],{"class":768},[443,2936,2937,2939,2941,2943,2945,2947,2949,2951,2953,2955,2957,2959,2961,2963,2965,2967],{"class":445,"line":453},[443,2938,2335],{"class":1418},[443,2940,357],{"class":768},[443,2942,611],{"class":456},[443,2944,470],{"class":768},[443,2946,1491],{"class":1490},[443,2948,1571],{"class":473},[443,2950,1491],{"class":1490},[443,2952,1478],{"class":768},[443,2954,1713],{"class":1418},[443,2956,357],{"class":768},[443,2958,796],{"class":456},[443,2960,1720],{"class":768},[443,2962,1713],{"class":1418},[443,2964,357],{"class":768},[443,2966,2752],{"class":456},[443,2968,1729],{"class":768},[443,2970,2971],{"class":445,"line":464},[443,2972,708],{"emptyLinePlaceholder":707},[443,2974,2975,2977,2979,2981,2983,2985,2987,2990,2992,2994,2996,2998,3001],{"class":445,"line":480},[443,2976,2005],{"class":460},[443,2978,793],{"class":768},[443,2980,796],{"class":724},[443,2982,1478],{"class":768},[443,2984,2928],{"class":724},[443,2986,860],{"class":768},[443,2988,2989],{"class":1418}," record",[443,2991,1456],{"class":768},[443,2993,1747],{"class":1418},[443,2995,357],{"class":768},[443,2997,1095],{"class":456},[443,2999,3000],{"class":768},"();",[443,3002,3003],{"class":449},"   \u002F\u002F null if empty\n",[443,3005,3006,3009,3011,3014,3016],{"class":445,"line":486},[443,3007,3008],{"class":1418},"record",[443,3010,357],{"class":768},[443,3012,3013],{"class":456},"getKey",[443,3015,3000],{"class":768},[443,3017,3018],{"class":449},"        \u002F\u002F \"k1\"\n",[443,3020,3021,3023,3025,3027,3029],{"class":445,"line":498},[443,3022,3008],{"class":1418},[443,3024,357],{"class":768},[443,3026,1876],{"class":456},[443,3028,3000],{"class":768},[443,3030,3031],{"class":449},"      \u002F\u002F 3L\n",[443,3033,3034,3036,3038,3041,3043],{"class":445,"line":542},[443,3035,3008],{"class":1418},[443,3037,357],{"class":768},[443,3039,3040],{"class":456},"getTimestamp",[443,3042,3000],{"class":768},[443,3044,3045],{"class":449},"  \u002F\u002F event time of the emission\n",[443,3047,3048],{"class":445,"line":548},[443,3049,708],{"emptyLinePlaceholder":707},[443,3051,3052,3054,3056,3058,3060],{"class":445,"line":554},[443,3053,1866],{"class":1418},[443,3055,357],{"class":768},[443,3057,2828],{"class":456},[443,3059,3000],{"class":768},[443,3061,3062],{"class":449},"              \u002F\u002F next value only\n",[443,3064,3065,3067,3069,3071,3073],{"class":445,"line":559},[443,3066,1866],{"class":1418},[443,3068,357],{"class":768},[443,3070,2841],{"class":456},[443,3072,3000],{"class":768},[443,3074,3075],{"class":449},"           \u002F\u002F next KeyValue (or null if empty)\n",[443,3077,3078,3080,3082,3084,3086],{"class":445,"line":564},[443,3079,1866],{"class":1418},[443,3081,357],{"class":768},[443,3083,2854],{"class":456},[443,3085,3000],{"class":768},[443,3087,3088],{"class":449},"      \u002F\u002F drain all remaining as a list of TestRecord\n",[443,3090,3091,3093,3095,3097,3099],{"class":445,"line":570},[443,3092,1866],{"class":1418},[443,3094,357],{"class":768},[443,3096,2867],{"class":456},[443,3098,3000],{"class":768},[443,3100,3101],{"class":449},"    \u002F\u002F drain all remaining as a list of KeyValues\n",[443,3103,3104,3106,3108,3110,3112],{"class":445,"line":575},[443,3105,1866],{"class":1418},[443,3107,357],{"class":768},[443,3109,2880],{"class":456},[443,3111,3000],{"class":768},[443,3113,3114],{"class":449},"     \u002F\u002F drain all; last value per key wins\n",[443,3116,3117,3119,3121,3123,3125],{"class":445,"line":580},[443,3118,1866],{"class":1418},[443,3120,357],{"class":768},[443,3122,2893],{"class":456},[443,3124,3000],{"class":768},[443,3126,3127],{"class":449},"           \u002F\u002F records currently waiting\n",[443,3129,3130,3132,3134,3136,3138],{"class":445,"line":778},[443,3131,1866],{"class":1418},[443,3133,357],{"class":768},[443,3135,1123],{"class":456},[443,3137,3000],{"class":768},[443,3139,3140],{"class":449},"                \u002F\u002F true when drained\n",[1922,3142,3143],{"icon":2674,"color":2675},[320,3144,3145,3146,3148,3149,3152,3153,3156,3157,3160],{},"Type parameters on ",[323,3147,1219],{}," are erased at runtime — they are not validated. If the topology emits a different type than declared, you get a ",[323,3150,3151],{},"ClassCastException"," only when you read a property. Match the declared ",[323,3154,3155],{},"K","\u002F",[323,3158,3159],{},"V"," to the actual sink output types.",[320,3162,3163,3164,3167,3168,378,3171,3174,3175,3178],{},"A common assertion for a ",[323,3165,3166],{},"KTable","-backed aggregation is the changelog stream: ",[323,3169,3170],{},"count()",[323,3172,3173],{},"aggregate()"," emit the running result per key, so ",[323,3176,3177],{},"readKeyValuesToMap()"," (last-value-per-key) is the idiomatic way to assert the final state.",[403,3180,3182],{"id":3181},"advancing-time","Advancing time",[320,3184,3185,3186,3189,3190,3193,3194,3196,3197,3201],{},"Stateful time-based logic — windowed aggregations with ",[323,3187,3188],{},"OnWindowClose",", suppress, punctuators, timers, scheduled sources — fires when the relevant clock advances. By default the ",[337,3191,3192],{},"event-time"," clock advances automatically to each piped record's timestamp (matching Kafka Streams' ",[323,3195,1240],{},"), so piping a record ",[3198,3199,3200],"em",{},"past"," a window's close already flushes it. You can also drive either clock manually:",[331,3203,3204,3228],{},[334,3205,3206,3210,3211,3213,3214,3217,3218,3220,3221,3223,3224,3227],{},[337,3207,3208],{},[323,3209,368],{}," advances ",[337,3212,2698],{},". This fires event-time timers and ",[323,3215,3216],{},"STREAM_TIME"," punctuators, closes windows past their end + grace, flushes suppressed results, and fires ",[323,3219,3216],{}," scheduled sources. The watermark is monotonic — by default a backward request is ignored (a silent no-op), since each ",[323,3222,638],{}," already drives event time forward; an explicit call is only needed to push event time ",[3198,3225,3226],{},"beyond"," the last piped record.",[334,3229,3230,3210,3234,3237,3238,3241,3242,3244,3245,1103],{},[337,3231,3232],{},[323,3233,365],{},[337,3235,3236],{},"processing time",". This fires processing-time timers and ",[323,3239,3240],{},"WALL_CLOCK_TIME"," punctuators, fires ",[323,3243,3240],{}," (and cron) scheduled sources, and triggers a barrier commit (which flushes any caching-store emissions — see ",[420,3246,3248],{"href":3247},"#flushing-caches-with-commitbarrier","commitBarrier()",[1922,3250,3251],{"icon":2674},[320,3252,3253,3254,3257,3258,3261,3262,378,3264,3267],{},"Set ",[323,3255,3256],{},"test.driver.commit-per-pipe=false"," in your config ",[323,3259,3260],{},"Properties"," to opt out of the per-pipe parity: pipes then neither commit the cache nor advance event time, and you control both explicitly via ",[323,3263,3248],{},[323,3265,3266],{},"advanceWatermark()"," (where a backward request throws, the legacy manual-control mode).",[320,3269,3270,3271,3274],{},"A windowed aggregation that only emits on window close needs event time pushed past the window's end plus its grace period — either by piping a later-timestamped record, or with an explicit ",[323,3272,3273],{},"advanceWatermark",":",[429,3276,3277,3642],{"group":645},[433,3278,3280],{"className":435,"code":3279,"filename":649,"language":438,"meta":439,"style":439},"\u002F\u002F Window [0, 5min), grace 30s — emits only on close\nval builder = StreamsBuilder()\nbuilder\n    .stream\u003CString, Int>(\"input\")\n    .groupByKey()\n    .windowedBy(TimeWindows.ofSizeAndGrace(Duration.ofMinutes(5), Duration.ofSeconds(30)))\n    .emitStrategy(EmitStrategy.onWindowClose())\n    .count()\n    .toStream()\n    .map { windowedKey, count -> KeyValue(windowedKey.key, count) }\n    .to(\"output\")\n\nval driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG)\nval input = driver.createInputTopic(\"input\", Serdes.String(), Serdes.Integer())\nval output = driver.createOutputTopic\u003CString, Long>(\"output\", Serdes.String(), Serdes.Long())\n\ninput.pipeInput(\"k1\", 1, timestamp = 1_000L)\ninput.pipeInput(\"k1\", 2, timestamp = 2_000L)\n\nassertThat(output.isEmpty()).isTrue()           \u002F\u002F window not closed yet\n\n\u002F\u002F Advance past window end (5min) + grace (30s) = 330s\ndriver.advanceWatermark(330_001L)\n\nassertThat(output.readRecord()?.value).isEqualTo(2L)   \u002F\u002F two records counted\n",[323,3281,3282,3287,3299,3304,3327,3336,3373,3388,3397,3406,3423,3436,3440,3455,3482,3516,3520,3543,3567,3571,3589,3593,3598,3612,3616],{"__ignoreMap":439},[443,3283,3284],{"class":445,"line":446},[443,3285,3286],{"class":449},"\u002F\u002F Window [0, 5min), grace 30s — emits only on close\n",[443,3288,3289,3291,3293,3295,3297],{"class":445,"line":453},[443,3290,2029],{"class":656},[443,3292,765],{"class":460},[443,3294,769],{"class":768},[443,3296,772],{"class":456},[443,3298,775],{"class":460},[443,3300,3301],{"class":445,"line":464},[443,3302,3303],{"class":460},"builder\n",[443,3305,3306,3309,3311,3313,3315,3317,3320,3322,3325],{"class":445,"line":480},[443,3307,3308],{"class":460},"    .",[443,3310,790],{"class":456},[443,3312,793],{"class":460},[443,3314,796],{"class":716},[443,3316,799],{"class":460},[443,3318,3319],{"class":716},"Int",[443,3321,804],{"class":460},[443,3323,3324],{"class":473},"\"input\"",[443,3326,477],{"class":460},[443,3328,3329,3331,3334],{"class":445,"line":486},[443,3330,3308],{"class":460},[443,3332,3333],{"class":456},"groupByKey",[443,3335,775],{"class":460},[443,3337,3338,3340,3343,3346,3349,3352,3355,3357,3360,3363,3366,3368,3371],{"class":445,"line":498},[443,3339,3308],{"class":460},[443,3341,3342],{"class":456},"windowedBy",[443,3344,3345],{"class":460},"(TimeWindows.",[443,3347,3348],{"class":456},"ofSizeAndGrace",[443,3350,3351],{"class":460},"(Duration.",[443,3353,3354],{"class":456},"ofMinutes",[443,3356,470],{"class":460},[443,3358,3359],{"class":863},"5",[443,3361,3362],{"class":460},"), Duration.",[443,3364,3365],{"class":456},"ofSeconds",[443,3367,470],{"class":460},[443,3369,3370],{"class":863},"30",[443,3372,2178],{"class":460},[443,3374,3375,3377,3380,3383,3386],{"class":445,"line":542},[443,3376,3308],{"class":460},[443,3378,3379],{"class":456},"emitStrategy",[443,3381,3382],{"class":460},"(EmitStrategy.",[443,3384,3385],{"class":456},"onWindowClose",[443,3387,994],{"class":460},[443,3389,3390,3392,3395],{"class":445,"line":548},[443,3391,3308],{"class":460},[443,3393,3394],{"class":456},"count",[443,3396,775],{"class":460},[443,3398,3399,3401,3404],{"class":445,"line":554},[443,3400,3308],{"class":460},[443,3402,3403],{"class":456},"toStream",[443,3405,775],{"class":460},[443,3407,3408,3410,3413,3416,3418,3420],{"class":445,"line":559},[443,3409,3308],{"class":460},[443,3411,3412],{"class":456},"map",[443,3414,3415],{"class":460}," { windowedKey, count ",[443,3417,1512],{"class":768},[443,3419,2517],{"class":456},[443,3421,3422],{"class":460},"(windowedKey.key, count) }\n",[443,3424,3425,3427,3429,3431,3434],{"class":445,"line":564},[443,3426,3308],{"class":460},[443,3428,875],{"class":456},[443,3430,470],{"class":460},[443,3432,3433],{"class":473},"\"output\"",[443,3435,477],{"class":460},[443,3437,3438],{"class":445,"line":570},[443,3439,708],{"emptyLinePlaceholder":707},[443,3441,3442,3444,3447,3449,3451,3453],{"class":445,"line":575},[443,3443,2029],{"class":656},[443,3445,3446],{"class":460}," driver ",[443,3448,769],{"class":768},[443,3450,898],{"class":460},[443,3452,901],{"class":456},[443,3454,904],{"class":460},[443,3456,3457,3459,3461,3463,3465,3467,3469,3471,3473,3475,3477,3480],{"class":445,"line":580},[443,3458,2029],{"class":656},[443,3460,971],{"class":460},[443,3462,769],{"class":768},[443,3464,937],{"class":460},[443,3466,608],{"class":456},[443,3468,470],{"class":460},[443,3470,3324],{"class":473},[443,3472,984],{"class":460},[443,3474,796],{"class":456},[443,3476,989],{"class":460},[443,3478,3479],{"class":456},"Integer",[443,3481,994],{"class":460},[443,3483,3484,3486,3488,3490,3492,3494,3496,3498,3500,3502,3504,3506,3508,3510,3512,3514],{"class":445,"line":778},[443,3485,2029],{"class":656},[443,3487,1002],{"class":460},[443,3489,769],{"class":768},[443,3491,937],{"class":460},[443,3493,611],{"class":456},[443,3495,793],{"class":460},[443,3497,796],{"class":716},[443,3499,799],{"class":460},[443,3501,2752],{"class":716},[443,3503,804],{"class":460},[443,3505,3433],{"class":473},[443,3507,984],{"class":460},[443,3509,796],{"class":456},[443,3511,989],{"class":460},[443,3513,2752],{"class":456},[443,3515,994],{"class":460},[443,3517,3518],{"class":445,"line":784},[443,3519,708],{"emptyLinePlaceholder":707},[443,3521,3522,3524,3526,3528,3530,3532,3535,3537,3539,3541],{"class":445,"line":812},[443,3523,2060],{"class":460},[443,3525,638],{"class":456},[443,3527,470],{"class":460},[443,3529,1048],{"class":473},[443,3531,799],{"class":460},[443,3533,3534],{"class":863},"1",[443,3536,2095],{"class":460},[443,3538,769],{"class":768},[443,3540,2100],{"class":863},[443,3542,477],{"class":460},[443,3544,3545,3547,3549,3551,3553,3555,3558,3560,3562,3565],{"class":445,"line":840},[443,3546,2060],{"class":460},[443,3548,638],{"class":456},[443,3550,470],{"class":460},[443,3552,1048],{"class":473},[443,3554,799],{"class":460},[443,3556,3557],{"class":863},"2",[443,3559,2095],{"class":460},[443,3561,769],{"class":768},[443,3563,3564],{"class":863}," 2_000L",[443,3566,477],{"class":460},[443,3568,3569],{"class":445,"line":870},[443,3570,708],{"emptyLinePlaceholder":707},[443,3572,3573,3575,3577,3579,3581,3583,3586],{"class":445,"line":885},[443,3574,1390],{"class":456},[443,3576,1092],{"class":460},[443,3578,1123],{"class":456},[443,3580,1126],{"class":460},[443,3582,1129],{"class":456},[443,3584,3585],{"class":460},"()           ",[443,3587,3588],{"class":449},"\u002F\u002F window not closed yet\n",[443,3590,3591],{"class":445,"line":890},[443,3592,708],{"emptyLinePlaceholder":707},[443,3594,3595],{"class":445,"line":907},[443,3596,3597],{"class":449},"\u002F\u002F Advance past window end (5min) + grace (30s) = 330s\n",[443,3599,3600,3603,3605,3607,3610],{"class":445,"line":913},[443,3601,3602],{"class":460},"driver.",[443,3604,3273],{"class":456},[443,3606,470],{"class":460},[443,3608,3609],{"class":863},"330_001L",[443,3611,477],{"class":460},[443,3613,3614],{"class":445,"line":918},[443,3615,708],{"emptyLinePlaceholder":707},[443,3617,3618,3620,3622,3624,3626,3628,3630,3632,3634,3637,3639],{"class":445,"line":924},[443,3619,1390],{"class":456},[443,3621,1092],{"class":460},[443,3623,1095],{"class":456},[443,3625,1098],{"class":460},[443,3627,823],{"class":724},[443,3629,1103],{"class":460},[443,3631,1106],{"class":456},[443,3633,470],{"class":460},[443,3635,3636],{"class":863},"2L",[443,3638,1075],{"class":460},[443,3640,3641],{"class":449},"\u002F\u002F two records counted\n",[433,3643,3645],{"className":1144,"code":3644,"filename":1146,"language":1147,"meta":439,"style":439},"\u002F\u002F Window [0, 5min), grace 30s — emits only on close\nStreamsBuilder builder = new StreamsBuilder();\nbuilder.\u003CString, Integer>stream(\"input\")\n    .groupByKey()\n    .windowedBy(TimeWindows.ofSizeAndGrace(Duration.ofMinutes(5), Duration.ofSeconds(30)))\n    .emitStrategy(EmitStrategy.onWindowClose())\n    .count()\n    .toStream()\n    .map((windowedKey, count) -> new KeyValue\u003C>(windowedKey.getKey(), count))\n    .to(\"output\");\n\nTopologyTestDriver driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG);\nTestInputTopic\u003CString, Integer> input =\n    driver.createInputTopic(\"input\", Serdes.String(), Serdes.Integer());\nTestOutputTopic\u003CString, Long> output =\n    driver.createOutputTopic(\"output\", Serdes.String(), Serdes.Long());\n\ninput.pipeInput(\"k1\", 1, 1_000L);\ninput.pipeInput(\"k1\", 2, 2_000L);\n\nassertThat(output.isEmpty()).isTrue();           \u002F\u002F window not closed yet\n\n\u002F\u002F Advance past window end (5min) + grace (30s) = 330s\ndriver.advanceWatermark(330_001L);\n\nassertThat(output.readRecord().getValue()).isEqualTo(2L);   \u002F\u002F two records counted\n",[323,3646,3647,3651,3665,3694,3702,3745,3762,3770,3778,3818,3834,3838,3866,3884,3918,3936,3970,3974,4001,4028,4032,4053,4057,4061,4076,4080],{"__ignoreMap":439},[443,3648,3649],{"class":445,"line":446},[443,3650,3286],{"class":449},[443,3652,3653,3655,3657,3659,3661,3663],{"class":445,"line":453},[443,3654,604],{"class":460},[443,3656,1453],{"class":1418},[443,3658,1456],{"class":768},[443,3660,1459],{"class":656},[443,3662,772],{"class":456},[443,3664,1464],{"class":768},[443,3666,3667,3669,3671,3673,3675,3677,3680,3682,3684,3686,3688,3690,3692],{"class":445,"line":464},[443,3668,1597],{"class":460},[443,3670,357],{"class":768},[443,3672,793],{"class":724},[443,3674,796],{"class":460},[443,3676,1478],{"class":768},[443,3678,3679],{"class":460}," Integer",[443,3681,860],{"class":724},[443,3683,790],{"class":456},[443,3685,470],{"class":768},[443,3687,1491],{"class":1490},[443,3689,2374],{"class":473},[443,3691,1491],{"class":1490},[443,3693,477],{"class":768},[443,3695,3696,3698,3700],{"class":445,"line":480},[443,3697,3308],{"class":768},[443,3699,3333],{"class":456},[443,3701,775],{"class":768},[443,3703,3704,3706,3708,3710,3713,3715,3717,3719,3722,3724,3726,3728,3730,3732,3735,3737,3739,3741,3743],{"class":445,"line":486},[443,3705,3308],{"class":768},[443,3707,3342],{"class":456},[443,3709,470],{"class":768},[443,3711,3712],{"class":1418},"TimeWindows",[443,3714,357],{"class":768},[443,3716,3348],{"class":456},[443,3718,470],{"class":768},[443,3720,3721],{"class":1418},"Duration",[443,3723,357],{"class":768},[443,3725,3354],{"class":456},[443,3727,470],{"class":768},[443,3729,3359],{"class":863},[443,3731,2514],{"class":768},[443,3733,3734],{"class":1418}," Duration",[443,3736,357],{"class":768},[443,3738,3365],{"class":456},[443,3740,470],{"class":768},[443,3742,3370],{"class":863},[443,3744,2178],{"class":768},[443,3746,3747,3749,3751,3753,3756,3758,3760],{"class":445,"line":498},[443,3748,3308],{"class":768},[443,3750,3379],{"class":456},[443,3752,470],{"class":768},[443,3754,3755],{"class":1418},"EmitStrategy",[443,3757,357],{"class":768},[443,3759,3385],{"class":456},[443,3761,994],{"class":768},[443,3763,3764,3766,3768],{"class":445,"line":542},[443,3765,3308],{"class":768},[443,3767,3394],{"class":456},[443,3769,775],{"class":768},[443,3771,3772,3774,3776],{"class":445,"line":548},[443,3773,3308],{"class":768},[443,3775,3403],{"class":456},[443,3777,775],{"class":768},[443,3779,3780,3782,3784,3786,3789,3791,3794,3796,3798,3800,3802,3805,3807,3809,3811,3813,3815],{"class":445,"line":554},[443,3781,3308],{"class":768},[443,3783,3412],{"class":456},[443,3785,1530],{"class":768},[443,3787,3788],{"class":460},"windowedKey",[443,3790,1478],{"class":768},[443,3792,3793],{"class":460}," count",[443,3795,1540],{"class":768},[443,3797,826],{"class":768},[443,3799,1459],{"class":656},[443,3801,2517],{"class":460},[443,3803,3804],{"class":768},"\u003C>(",[443,3806,3788],{"class":1418},[443,3808,357],{"class":768},[443,3810,3013],{"class":456},[443,3812,1720],{"class":768},[443,3814,3793],{"class":460},[443,3816,3817],{"class":768},"))\n",[443,3819,3820,3822,3824,3826,3828,3830,3832],{"class":445,"line":559},[443,3821,3308],{"class":768},[443,3823,875],{"class":456},[443,3825,470],{"class":768},[443,3827,1491],{"class":1490},[443,3829,1866],{"class":473},[443,3831,1491],{"class":1490},[443,3833,1576],{"class":768},[443,3835,3836],{"class":445,"line":564},[443,3837,708],{"emptyLinePlaceholder":707},[443,3839,3840,3842,3844,3846,3848,3850,3852,3854,3856,3858,3860,3862,3864],{"class":445,"line":570},[443,3841,1240],{"class":460},[443,3843,1419],{"class":1418},[443,3845,1456],{"class":768},[443,3847,1415],{"class":1418},[443,3849,357],{"class":768},[443,3851,901],{"class":456},[443,3853,470],{"class":768},[443,3855,1597],{"class":460},[443,3857,1478],{"class":768},[443,3859,1415],{"class":1418},[443,3861,357],{"class":768},[443,3863,1606],{"class":1418},[443,3865,1576],{"class":768},[443,3867,3868,3870,3872,3874,3876,3878,3880,3882],{"class":445,"line":575},[443,3869,1198],{"class":460},[443,3871,793],{"class":768},[443,3873,796],{"class":724},[443,3875,1478],{"class":768},[443,3877,3679],{"class":724},[443,3879,860],{"class":768},[443,3881,1688],{"class":1418},[443,3883,1691],{"class":768},[443,3885,3886,3888,3890,3892,3894,3896,3898,3900,3902,3904,3906,3908,3910,3912,3914,3916],{"class":445,"line":580},[443,3887,2335],{"class":1418},[443,3889,357],{"class":768},[443,3891,608],{"class":456},[443,3893,470],{"class":768},[443,3895,1491],{"class":1490},[443,3897,2374],{"class":473},[443,3899,1491],{"class":1490},[443,3901,1478],{"class":768},[443,3903,1713],{"class":1418},[443,3905,357],{"class":768},[443,3907,796],{"class":456},[443,3909,1720],{"class":768},[443,3911,1713],{"class":1418},[443,3913,357],{"class":768},[443,3915,3479],{"class":456},[443,3917,1729],{"class":768},[443,3919,3920,3922,3924,3926,3928,3930,3932,3934],{"class":445,"line":778},[443,3921,1219],{"class":460},[443,3923,793],{"class":768},[443,3925,796],{"class":724},[443,3927,1478],{"class":768},[443,3929,2928],{"class":724},[443,3931,860],{"class":768},[443,3933,1747],{"class":1418},[443,3935,1691],{"class":768},[443,3937,3938,3940,3942,3944,3946,3948,3950,3952,3954,3956,3958,3960,3962,3964,3966,3968],{"class":445,"line":784},[443,3939,2335],{"class":1418},[443,3941,357],{"class":768},[443,3943,611],{"class":456},[443,3945,470],{"class":768},[443,3947,1491],{"class":1490},[443,3949,1866],{"class":473},[443,3951,1491],{"class":1490},[443,3953,1478],{"class":768},[443,3955,1713],{"class":1418},[443,3957,357],{"class":768},[443,3959,796],{"class":456},[443,3961,1720],{"class":768},[443,3963,1713],{"class":1418},[443,3965,357],{"class":768},[443,3967,2752],{"class":456},[443,3969,1729],{"class":768},[443,3971,3972],{"class":445,"line":812},[443,3973,708],{"emptyLinePlaceholder":707},[443,3975,3976,3978,3980,3982,3984,3986,3988,3990,3992,3995,3997,3999],{"class":445,"line":840},[443,3977,2374],{"class":1418},[443,3979,357],{"class":768},[443,3981,638],{"class":456},[443,3983,470],{"class":768},[443,3985,1491],{"class":1490},[443,3987,1804],{"class":473},[443,3989,1491],{"class":1490},[443,3991,1478],{"class":768},[443,3993,3994],{"class":863}," 1",[443,3996,1478],{"class":768},[443,3998,2100],{"class":863},[443,4000,1576],{"class":768},[443,4002,4003,4005,4007,4009,4011,4013,4015,4017,4019,4022,4024,4026],{"class":445,"line":870},[443,4004,2374],{"class":1418},[443,4006,357],{"class":768},[443,4008,638],{"class":456},[443,4010,470],{"class":768},[443,4012,1491],{"class":1490},[443,4014,1804],{"class":473},[443,4016,1491],{"class":1490},[443,4018,1478],{"class":768},[443,4020,4021],{"class":863}," 2",[443,4023,1478],{"class":768},[443,4025,3564],{"class":863},[443,4027,1576],{"class":768},[443,4029,4030],{"class":445,"line":885},[443,4031,708],{"emptyLinePlaceholder":707},[443,4033,4034,4036,4038,4040,4042,4044,4046,4048,4050],{"class":445,"line":890},[443,4035,1390],{"class":456},[443,4037,470],{"class":768},[443,4039,1866],{"class":1418},[443,4041,357],{"class":768},[443,4043,1123],{"class":456},[443,4045,1126],{"class":768},[443,4047,1129],{"class":456},[443,4049,3000],{"class":768},[443,4051,4052],{"class":449},"           \u002F\u002F window not closed yet\n",[443,4054,4055],{"class":445,"line":907},[443,4056,708],{"emptyLinePlaceholder":707},[443,4058,4059],{"class":445,"line":913},[443,4060,3597],{"class":449},[443,4062,4063,4066,4068,4070,4072,4074],{"class":445,"line":918},[443,4064,4065],{"class":1418},"driver",[443,4067,357],{"class":768},[443,4069,3273],{"class":456},[443,4071,470],{"class":768},[443,4073,3609],{"class":863},[443,4075,1576],{"class":768},[443,4077,4078],{"class":445,"line":924},[443,4079,708],{"emptyLinePlaceholder":707},[443,4081,4082,4084,4086,4088,4090,4092,4094,4096,4098,4100,4102,4104,4106],{"class":445,"line":945},[443,4083,1390],{"class":456},[443,4085,470],{"class":768},[443,4087,1866],{"class":1418},[443,4089,357],{"class":768},[443,4091,1095],{"class":456},[443,4093,1873],{"class":768},[443,4095,1876],{"class":456},[443,4097,1126],{"class":768},[443,4099,1106],{"class":456},[443,4101,470],{"class":768},[443,4103,3636],{"class":863},[443,4105,1848],{"class":768},[443,4107,4108],{"class":449},"   \u002F\u002F two records counted\n",[320,4110,4111,4112,353,4115,4118],{},"For session windows and suppress, the runtime pattern is the same one the example apps use: push the watermark past the inactivity gap (plus grace) to close the session and let suppress emit its final result. ",[323,4113,4114],{},"getCurrentWatermark()",[323,4116,4117],{},"getWallClockTime()"," return the current clocks for assertions.",[403,4120,4122],{"id":4121},"reading-state-stores","Reading state stores",[320,4124,4125],{},"For stateful topologies you can read the state store directly instead of (or in addition to) asserting on output records. The accessor matches the store type the DSL operator created.",[4127,4128,4129,4145],"table",{},[4130,4131,4132],"thead",{},[4133,4134,4135,4139,4142],"tr",{},[4136,4137,4138],"th",{},"Accessor",[4136,4140,4141],{},"Returns",[4136,4143,4144],{},"For",[4146,4147,4148,4173,4188,4203,4218,4233,4248],"tbody",{},[4133,4149,4150,4155,4160],{},[4151,4152,4153],"td",{},[323,4154,377],{},[4151,4156,4157],{},[323,4158,4159],{},"KeyValueStore\u003CK, V>",[4151,4161,4162,799,4164,799,4167,4170,4171],{},[323,4163,3394],{},[323,4165,4166],{},"reduce",[323,4168,4169],{},"aggregate",", materialized ",[323,4172,3166],{},[4133,4174,4175,4180,4185],{},[4151,4176,4177],{},[323,4178,4179],{},"getWindowStore(name)",[4151,4181,4182],{},[323,4183,4184],{},"WindowStore\u003CK, V>",[4151,4186,4187],{},"time \u002F sliding windowed aggregations",[4133,4189,4190,4195,4200],{},[4151,4191,4192],{},[323,4193,4194],{},"getSessionStore(name)",[4151,4196,4197],{},[323,4198,4199],{},"SessionStore\u003CK, V>",[4151,4201,4202],{},"session windowed aggregations",[4133,4204,4205,4210,4215],{},[4151,4206,4207],{},[323,4208,4209],{},"getTimestampedKeyValueStore(name)",[4151,4211,4212],{},[323,4213,4214],{},"TimestampedKeyValueStore\u003CK, V>",[4151,4216,4217],{},"when you also want the value's event timestamp",[4133,4219,4220,4225,4230],{},[4151,4221,4222],{},[323,4223,4224],{},"getTimestampedWindowStore(name)",[4151,4226,4227],{},[323,4228,4229],{},"TimestampedWindowStore\u003CK, V>",[4151,4231,4232],{},"windowed, with value timestamps",[4133,4234,4235,4240,4245],{},[4151,4236,4237],{},[323,4238,4239],{},"getVersionedKeyValueStore(name)",[4151,4241,4242],{},[323,4243,4244],{},"VersionedKeyValueStore\u003CK, V>",[4151,4246,4247],{},"versioned (point-in-time) stores",[4133,4249,4250,4255,4260],{},[4151,4251,4252],{},[323,4253,4254],{},"getStateStore(name)",[4151,4256,4257],{},[323,4258,4259],{},"S : StateStore",[4151,4261,4262],{},"custom Processor stores",[320,4264,4265,4268,4269,4271,4272,4275],{},[323,4266,4267],{},"getKeyValueStore"," transparently unwraps DSL-created timestamped stores, so it returns the raw value ",[323,4270,3159],{}," (matching Kafka Streams behaviour). The state-store name is the one you set via ",[323,4273,4274],{},"Materialized.as(\"...\")"," or the store supplier.",[429,4277,4278,4575],{"group":645},[433,4279,4281],{"className":435,"code":4280,"filename":649,"language":438,"meta":439,"style":439},"val builder = StreamsBuilder()\nbuilder\n    .stream\u003CString, String>(\"input-topic\")\n    .groupByKey()\n    .count(Materialized.`as`\u003CString, Long, StateStore>(\"count-store\"))\n    .toStream()\n    .to(\"output-topic\")\n\nval driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG)\nval input = driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String())\n\ninput.pipeInput(\"a\", \"x\")\ninput.pipeInput(\"a\", \"y\")\ninput.pipeInput(\"b\", \"z\")\n\nval store = driver.getKeyValueStore\u003CString, Long>(\"count-store\")\nassertThat(store.get(\"a\")).isEqualTo(2L)\nassertThat(store.get(\"b\")).isEqualTo(1L)\nassertThat(store.get(\"missing\")).isNull()\n",[323,4282,4283,4295,4299,4319,4327,4359,4367,4379,4383,4397,4423,4427,4443,4459,4476,4480,4507,4532,4555],{"__ignoreMap":439},[443,4284,4285,4287,4289,4291,4293],{"class":445,"line":446},[443,4286,2029],{"class":656},[443,4288,765],{"class":460},[443,4290,769],{"class":768},[443,4292,772],{"class":456},[443,4294,775],{"class":460},[443,4296,4297],{"class":445,"line":453},[443,4298,3303],{"class":460},[443,4300,4301,4303,4305,4307,4309,4311,4313,4315,4317],{"class":445,"line":464},[443,4302,3308],{"class":460},[443,4304,790],{"class":456},[443,4306,793],{"class":460},[443,4308,796],{"class":716},[443,4310,799],{"class":460},[443,4312,796],{"class":716},[443,4314,804],{"class":460},[443,4316,807],{"class":473},[443,4318,477],{"class":460},[443,4320,4321,4323,4325],{"class":445,"line":480},[443,4322,3308],{"class":460},[443,4324,3333],{"class":456},[443,4326,775],{"class":460},[443,4328,4329,4331,4333,4336,4339,4341,4343,4345,4347,4349,4352,4354,4357],{"class":445,"line":486},[443,4330,3308],{"class":460},[443,4332,3394],{"class":456},[443,4334,4335],{"class":460},"(Materialized.",[443,4337,4338],{"class":456},"`as`",[443,4340,793],{"class":460},[443,4342,796],{"class":716},[443,4344,799],{"class":460},[443,4346,2752],{"class":716},[443,4348,799],{"class":460},[443,4350,4351],{"class":716},"StateStore",[443,4353,804],{"class":460},[443,4355,4356],{"class":473},"\"count-store\"",[443,4358,3817],{"class":460},[443,4360,4361,4363,4365],{"class":445,"line":498},[443,4362,3308],{"class":460},[443,4364,3403],{"class":456},[443,4366,775],{"class":460},[443,4368,4369,4371,4373,4375,4377],{"class":445,"line":542},[443,4370,3308],{"class":460},[443,4372,875],{"class":456},[443,4374,470],{"class":460},[443,4376,880],{"class":473},[443,4378,477],{"class":460},[443,4380,4381],{"class":445,"line":548},[443,4382,708],{"emptyLinePlaceholder":707},[443,4384,4385,4387,4389,4391,4393,4395],{"class":445,"line":554},[443,4386,2029],{"class":656},[443,4388,3446],{"class":460},[443,4390,769],{"class":768},[443,4392,898],{"class":460},[443,4394,901],{"class":456},[443,4396,904],{"class":460},[443,4398,4399,4401,4403,4405,4407,4409,4411,4413,4415,4417,4419,4421],{"class":445,"line":559},[443,4400,2029],{"class":656},[443,4402,971],{"class":460},[443,4404,769],{"class":768},[443,4406,937],{"class":460},[443,4408,608],{"class":456},[443,4410,470],{"class":460},[443,4412,807],{"class":473},[443,4414,984],{"class":460},[443,4416,796],{"class":456},[443,4418,989],{"class":460},[443,4420,796],{"class":456},[443,4422,994],{"class":460},[443,4424,4425],{"class":445,"line":564},[443,4426,708],{"emptyLinePlaceholder":707},[443,4428,4429,4431,4433,4435,4437,4439,4441],{"class":445,"line":570},[443,4430,2060],{"class":460},[443,4432,638],{"class":456},[443,4434,470],{"class":460},[443,4436,2161],{"class":473},[443,4438,799],{"class":460},[443,4440,2194],{"class":473},[443,4442,477],{"class":460},[443,4444,4445,4447,4449,4451,4453,4455,4457],{"class":445,"line":575},[443,4446,2060],{"class":460},[443,4448,638],{"class":456},[443,4450,470],{"class":460},[443,4452,2161],{"class":473},[443,4454,799],{"class":460},[443,4456,2199],{"class":473},[443,4458,477],{"class":460},[443,4460,4461,4463,4465,4467,4469,4471,4474],{"class":445,"line":580},[443,4462,2060],{"class":460},[443,4464,638],{"class":456},[443,4466,470],{"class":460},[443,4468,2175],{"class":473},[443,4470,799],{"class":460},[443,4472,4473],{"class":473},"\"z\"",[443,4475,477],{"class":460},[443,4477,4478],{"class":445,"line":778},[443,4479,708],{"emptyLinePlaceholder":707},[443,4481,4482,4484,4487,4489,4491,4493,4495,4497,4499,4501,4503,4505],{"class":445,"line":784},[443,4483,2029],{"class":656},[443,4485,4486],{"class":460}," store ",[443,4488,769],{"class":768},[443,4490,937],{"class":460},[443,4492,4267],{"class":456},[443,4494,793],{"class":460},[443,4496,796],{"class":716},[443,4498,799],{"class":460},[443,4500,2752],{"class":716},[443,4502,804],{"class":460},[443,4504,4356],{"class":473},[443,4506,477],{"class":460},[443,4508,4509,4511,4514,4517,4519,4521,4524,4526,4528,4530],{"class":445,"line":812},[443,4510,1390],{"class":456},[443,4512,4513],{"class":460},"(store.",[443,4515,4516],{"class":456},"get",[443,4518,470],{"class":460},[443,4520,2161],{"class":473},[443,4522,4523],{"class":460},")).",[443,4525,1106],{"class":456},[443,4527,470],{"class":460},[443,4529,3636],{"class":863},[443,4531,477],{"class":460},[443,4533,4534,4536,4538,4540,4542,4544,4546,4548,4550,4553],{"class":445,"line":840},[443,4535,1390],{"class":456},[443,4537,4513],{"class":460},[443,4539,4516],{"class":456},[443,4541,470],{"class":460},[443,4543,2175],{"class":473},[443,4545,4523],{"class":460},[443,4547,1106],{"class":456},[443,4549,470],{"class":460},[443,4551,4552],{"class":863},"1L",[443,4554,477],{"class":460},[443,4556,4557,4559,4561,4563,4565,4568,4570,4573],{"class":445,"line":870},[443,4558,1390],{"class":456},[443,4560,4513],{"class":460},[443,4562,4516],{"class":456},[443,4564,470],{"class":460},[443,4566,4567],{"class":473},"\"missing\"",[443,4569,4523],{"class":460},[443,4571,4572],{"class":456},"isNull",[443,4574,775],{"class":460},[433,4576,4578],{"className":1144,"code":4577,"filename":1146,"language":1147,"meta":439,"style":439},"StreamsBuilder builder = new StreamsBuilder();\nbuilder.\u003CString, String>stream(\"input-topic\")\n    .groupByKey()\n    .count(Materialized.\u003CString, Long, StateStore>as(\"count-store\"))\n    .toStream()\n    .to(\"output-topic\");\n\nTopologyTestDriver driver = TopologyTestDriver.fromBuilder(builder, TopologyTestDriver.STRING_CONFIG);\nTestInputTopic\u003CString, String> input =\n    driver.createInputTopic(\"input-topic\", Serdes.String(), Serdes.String());\n\ninput.pipeInput(\"a\", \"x\");\ninput.pipeInput(\"a\", \"y\");\ninput.pipeInput(\"b\", \"z\");\n\nKeyValueStore\u003CString, Long> store = driver.getKeyValueStore(\"count-store\");\nassertThat(store.get(\"a\")).isEqualTo(2L);\nassertThat(store.get(\"b\")).isEqualTo(1L);\nassertThat(store.get(\"missing\")).isNull();\n",[323,4579,4580,4594,4622,4630,4672,4680,4696,4700,4728,4746,4780,4784,4810,4836,4863,4867,4903,4934,4964],{"__ignoreMap":439},[443,4581,4582,4584,4586,4588,4590,4592],{"class":445,"line":446},[443,4583,604],{"class":460},[443,4585,1453],{"class":1418},[443,4587,1456],{"class":768},[443,4589,1459],{"class":656},[443,4591,772],{"class":456},[443,4593,1464],{"class":768},[443,4595,4596,4598,4600,4602,4604,4606,4608,4610,4612,4614,4616,4618,4620],{"class":445,"line":453},[443,4597,1597],{"class":460},[443,4599,357],{"class":768},[443,4601,793],{"class":724},[443,4603,796],{"class":460},[443,4605,1478],{"class":768},[443,4607,1481],{"class":460},[443,4609,860],{"class":724},[443,4611,790],{"class":456},[443,4613,470],{"class":768},[443,4615,1491],{"class":1490},[443,4617,1494],{"class":473},[443,4619,1491],{"class":1490},[443,4621,477],{"class":768},[443,4623,4624,4626,4628],{"class":445,"line":464},[443,4625,3308],{"class":768},[443,4627,3333],{"class":456},[443,4629,775],{"class":768},[443,4631,4632,4634,4636,4638,4641,4643,4645,4647,4649,4651,4653,4656,4658,4661,4663,4665,4668,4670],{"class":445,"line":480},[443,4633,3308],{"class":768},[443,4635,3394],{"class":456},[443,4637,470],{"class":768},[443,4639,4640],{"class":460},"Materialized",[443,4642,357],{"class":768},[443,4644,793],{"class":724},[443,4646,796],{"class":460},[443,4648,1478],{"class":768},[443,4650,2928],{"class":460},[443,4652,1478],{"class":768},[443,4654,4655],{"class":460}," StateStore",[443,4657,860],{"class":724},[443,4659,4660],{"class":456},"as",[443,4662,470],{"class":768},[443,4664,1491],{"class":1490},[443,4666,4667],{"class":473},"count-store",[443,4669,1491],{"class":1490},[443,4671,3817],{"class":768},[443,4673,4674,4676,4678],{"class":445,"line":486},[443,4675,3308],{"class":768},[443,4677,3403],{"class":456},[443,4679,775],{"class":768},[443,4681,4682,4684,4686,4688,4690,4692,4694],{"class":445,"line":498},[443,4683,3308],{"class":768},[443,4685,875],{"class":456},[443,4687,470],{"class":768},[443,4689,1491],{"class":1490},[443,4691,1571],{"class":473},[443,4693,1491],{"class":1490},[443,4695,1576],{"class":768},[443,4697,4698],{"class":445,"line":542},[443,4699,708],{"emptyLinePlaceholder":707},[443,4701,4702,4704,4706,4708,4710,4712,4714,4716,4718,4720,4722,4724,4726],{"class":445,"line":548},[443,4703,1240],{"class":460},[443,4705,1419],{"class":1418},[443,4707,1456],{"class":768},[443,4709,1415],{"class":1418},[443,4711,357],{"class":768},[443,4713,901],{"class":456},[443,4715,470],{"class":768},[443,4717,1597],{"class":460},[443,4719,1478],{"class":768},[443,4721,1415],{"class":1418},[443,4723,357],{"class":768},[443,4725,1606],{"class":1418},[443,4727,1576],{"class":768},[443,4729,4730,4732,4734,4736,4738,4740,4742,4744],{"class":445,"line":554},[443,4731,1198],{"class":460},[443,4733,793],{"class":768},[443,4735,796],{"class":724},[443,4737,1478],{"class":768},[443,4739,1481],{"class":724},[443,4741,860],{"class":768},[443,4743,1688],{"class":1418},[443,4745,1691],{"class":768},[443,4747,4748,4750,4752,4754,4756,4758,4760,4762,4764,4766,4768,4770,4772,4774,4776,4778],{"class":445,"line":559},[443,4749,2335],{"class":1418},[443,4751,357],{"class":768},[443,4753,608],{"class":456},[443,4755,470],{"class":768},[443,4757,1491],{"class":1490},[443,4759,1494],{"class":473},[443,4761,1491],{"class":1490},[443,4763,1478],{"class":768},[443,4765,1713],{"class":1418},[443,4767,357],{"class":768},[443,4769,796],{"class":456},[443,4771,1720],{"class":768},[443,4773,1713],{"class":1418},[443,4775,357],{"class":768},[443,4777,796],{"class":456},[443,4779,1729],{"class":768},[443,4781,4782],{"class":445,"line":564},[443,4783,708],{"emptyLinePlaceholder":707},[443,4785,4786,4788,4790,4792,4794,4796,4798,4800,4802,4804,4806,4808],{"class":445,"line":570},[443,4787,2374],{"class":1418},[443,4789,357],{"class":768},[443,4791,638],{"class":456},[443,4793,470],{"class":768},[443,4795,1491],{"class":1490},[443,4797,420],{"class":473},[443,4799,1491],{"class":1490},[443,4801,1478],{"class":768},[443,4803,1811],{"class":1490},[443,4805,2564],{"class":473},[443,4807,1491],{"class":1490},[443,4809,1576],{"class":768},[443,4811,4812,4814,4816,4818,4820,4822,4824,4826,4828,4830,4832,4834],{"class":445,"line":575},[443,4813,2374],{"class":1418},[443,4815,357],{"class":768},[443,4817,638],{"class":456},[443,4819,470],{"class":768},[443,4821,1491],{"class":1490},[443,4823,420],{"class":473},[443,4825,1491],{"class":1490},[443,4827,1478],{"class":768},[443,4829,1811],{"class":1490},[443,4831,2573],{"class":473},[443,4833,1491],{"class":1490},[443,4835,1576],{"class":768},[443,4837,4838,4840,4842,4844,4846,4848,4850,4852,4854,4856,4859,4861],{"class":445,"line":580},[443,4839,2374],{"class":1418},[443,4841,357],{"class":768},[443,4843,638],{"class":456},[443,4845,470],{"class":768},[443,4847,1491],{"class":1490},[443,4849,2536],{"class":473},[443,4851,1491],{"class":1490},[443,4853,1478],{"class":768},[443,4855,1811],{"class":1490},[443,4857,4858],{"class":473},"z",[443,4860,1491],{"class":1490},[443,4862,1576],{"class":768},[443,4864,4865],{"class":445,"line":778},[443,4866,708],{"emptyLinePlaceholder":707},[443,4868,4869,4872,4874,4876,4878,4880,4882,4885,4887,4889,4891,4893,4895,4897,4899,4901],{"class":445,"line":784},[443,4870,4871],{"class":460},"KeyValueStore",[443,4873,793],{"class":768},[443,4875,796],{"class":724},[443,4877,1478],{"class":768},[443,4879,2928],{"class":724},[443,4881,860],{"class":768},[443,4883,4884],{"class":1418}," store",[443,4886,1456],{"class":768},[443,4888,1419],{"class":1418},[443,4890,357],{"class":768},[443,4892,4267],{"class":456},[443,4894,470],{"class":768},[443,4896,1491],{"class":1490},[443,4898,4667],{"class":473},[443,4900,1491],{"class":1490},[443,4902,1576],{"class":768},[443,4904,4905,4907,4909,4912,4914,4916,4918,4920,4922,4924,4926,4928,4930,4932],{"class":445,"line":812},[443,4906,1390],{"class":456},[443,4908,470],{"class":768},[443,4910,4911],{"class":1418},"store",[443,4913,357],{"class":768},[443,4915,4516],{"class":456},[443,4917,470],{"class":768},[443,4919,1491],{"class":1490},[443,4921,420],{"class":473},[443,4923,1491],{"class":1490},[443,4925,4523],{"class":768},[443,4927,1106],{"class":456},[443,4929,470],{"class":768},[443,4931,3636],{"class":863},[443,4933,1576],{"class":768},[443,4935,4936,4938,4940,4942,4944,4946,4948,4950,4952,4954,4956,4958,4960,4962],{"class":445,"line":840},[443,4937,1390],{"class":456},[443,4939,470],{"class":768},[443,4941,4911],{"class":1418},[443,4943,357],{"class":768},[443,4945,4516],{"class":456},[443,4947,470],{"class":768},[443,4949,1491],{"class":1490},[443,4951,2536],{"class":473},[443,4953,1491],{"class":1490},[443,4955,4523],{"class":768},[443,4957,1106],{"class":456},[443,4959,470],{"class":768},[443,4961,4552],{"class":863},[443,4963,1576],{"class":768},[443,4965,4966,4968,4970,4972,4974,4976,4978,4980,4983,4985,4987,4989],{"class":445,"line":870},[443,4967,1390],{"class":456},[443,4969,470],{"class":768},[443,4971,4911],{"class":1418},[443,4973,357],{"class":768},[443,4975,4516],{"class":456},[443,4977,470],{"class":768},[443,4979,1491],{"class":1490},[443,4981,4982],{"class":473},"missing",[443,4984,1491],{"class":1490},[443,4986,4523],{"class":768},[443,4988,4572],{"class":456},[443,4990,1464],{"class":768},[1922,4992,4993],{"icon":2674,"color":2675},[320,4994,4995,4996,4999,5000,5003,5004,1103],{},"The test driver does ",[337,4997,4998],{},"not"," write changelog topics — it runs without a broker, so state writes use a no-op changelog. Tests cover processing and state logic, not state backup \u002F restore. To exercise changelog and recovery behaviour, use a broker-backed integration test (the example apps pair each ",[323,5001,5002],{},"...AppTest"," with a ",[323,5005,5006],{},"...IntegrationTest",[403,5008,5010],{"id":5009},"flushing-caches-with-commitbarrier","Flushing caches with commitBarrier()",[320,5012,5013,5014,5017,5018,5020,5021,5024,5025,5027,5028,5030],{},"State stores with caching enabled (via ",[323,5015,5016],{},"Materialized.withCachingEnabled()",") suppress intermediate updates and emit only the final value per key on commit. In the runtime that happens on a commit barrier; in the test driver you trigger it explicitly with ",[323,5019,3248],{},". ",[323,5022,5023],{},"advanceWallClockTime(...)"," also triggers one. If a caching-enabled topology emits nothing after ",[323,5026,638],{},", call ",[323,5029,3248],{}," (or advance wall-clock time) to flush.",[429,5032,5033,5137],{"group":645},[433,5034,5036],{"className":435,"code":5035,"filename":649,"language":438,"meta":439,"style":439},"input.pipeInput(\"a\", \"x\")\ninput.pipeInput(\"a\", \"y\")\n\n\u002F\u002F Nothing emitted yet — caching holds intermediate updates\nassertThat(output.isEmpty()).isTrue()\n\ndriver.commitBarrier()                 \u002F\u002F flush cached emissions\n\nassertThat(output.readKeyValuesToMap()).containsEntry(\"a\", 2L)\n",[323,5037,5038,5054,5070,5074,5079,5093,5097,5110,5114],{"__ignoreMap":439},[443,5039,5040,5042,5044,5046,5048,5050,5052],{"class":445,"line":446},[443,5041,2060],{"class":460},[443,5043,638],{"class":456},[443,5045,470],{"class":460},[443,5047,2161],{"class":473},[443,5049,799],{"class":460},[443,5051,2194],{"class":473},[443,5053,477],{"class":460},[443,5055,5056,5058,5060,5062,5064,5066,5068],{"class":445,"line":453},[443,5057,2060],{"class":460},[443,5059,638],{"class":456},[443,5061,470],{"class":460},[443,5063,2161],{"class":473},[443,5065,799],{"class":460},[443,5067,2199],{"class":473},[443,5069,477],{"class":460},[443,5071,5072],{"class":445,"line":464},[443,5073,708],{"emptyLinePlaceholder":707},[443,5075,5076],{"class":445,"line":480},[443,5077,5078],{"class":449},"\u002F\u002F Nothing emitted yet — caching holds intermediate updates\n",[443,5080,5081,5083,5085,5087,5089,5091],{"class":445,"line":486},[443,5082,1390],{"class":456},[443,5084,1092],{"class":460},[443,5086,1123],{"class":456},[443,5088,1126],{"class":460},[443,5090,1129],{"class":456},[443,5092,775],{"class":460},[443,5094,5095],{"class":445,"line":498},[443,5096,708],{"emptyLinePlaceholder":707},[443,5098,5099,5101,5104,5107],{"class":445,"line":542},[443,5100,3602],{"class":460},[443,5102,5103],{"class":456},"commitBarrier",[443,5105,5106],{"class":460},"()                 ",[443,5108,5109],{"class":449},"\u002F\u002F flush cached emissions\n",[443,5111,5112],{"class":445,"line":548},[443,5113,708],{"emptyLinePlaceholder":707},[443,5115,5116,5118,5120,5122,5124,5127,5129,5131,5133,5135],{"class":445,"line":554},[443,5117,1390],{"class":456},[443,5119,1092],{"class":460},[443,5121,2880],{"class":456},[443,5123,1126],{"class":460},[443,5125,5126],{"class":456},"containsEntry",[443,5128,470],{"class":460},[443,5130,2161],{"class":473},[443,5132,799],{"class":460},[443,5134,3636],{"class":863},[443,5136,477],{"class":460},[433,5138,5140],{"className":1144,"code":5139,"filename":1146,"language":1147,"meta":439,"style":439},"input.pipeInput(\"a\", \"x\");\ninput.pipeInput(\"a\", \"y\");\n\n\u002F\u002F Nothing emitted yet — caching holds intermediate updates\nassertThat(output.isEmpty()).isTrue();\n\ndriver.commitBarrier();                \u002F\u002F flush cached emissions\n\nassertThat(output.readKeyValuesToMap()).containsEntry(\"a\", 2L);\n",[323,5141,5142,5168,5194,5198,5202,5220,5224,5237,5241],{"__ignoreMap":439},[443,5143,5144,5146,5148,5150,5152,5154,5156,5158,5160,5162,5164,5166],{"class":445,"line":446},[443,5145,2374],{"class":1418},[443,5147,357],{"class":768},[443,5149,638],{"class":456},[443,5151,470],{"class":768},[443,5153,1491],{"class":1490},[443,5155,420],{"class":473},[443,5157,1491],{"class":1490},[443,5159,1478],{"class":768},[443,5161,1811],{"class":1490},[443,5163,2564],{"class":473},[443,5165,1491],{"class":1490},[443,5167,1576],{"class":768},[443,5169,5170,5172,5174,5176,5178,5180,5182,5184,5186,5188,5190,5192],{"class":445,"line":453},[443,5171,2374],{"class":1418},[443,5173,357],{"class":768},[443,5175,638],{"class":456},[443,5177,470],{"class":768},[443,5179,1491],{"class":1490},[443,5181,420],{"class":473},[443,5183,1491],{"class":1490},[443,5185,1478],{"class":768},[443,5187,1811],{"class":1490},[443,5189,2573],{"class":473},[443,5191,1491],{"class":1490},[443,5193,1576],{"class":768},[443,5195,5196],{"class":445,"line":464},[443,5197,708],{"emptyLinePlaceholder":707},[443,5199,5200],{"class":445,"line":480},[443,5201,5078],{"class":449},[443,5203,5204,5206,5208,5210,5212,5214,5216,5218],{"class":445,"line":486},[443,5205,1390],{"class":456},[443,5207,470],{"class":768},[443,5209,1866],{"class":1418},[443,5211,357],{"class":768},[443,5213,1123],{"class":456},[443,5215,1126],{"class":768},[443,5217,1129],{"class":456},[443,5219,1464],{"class":768},[443,5221,5222],{"class":445,"line":498},[443,5223,708],{"emptyLinePlaceholder":707},[443,5225,5226,5228,5230,5232,5234],{"class":445,"line":542},[443,5227,4065],{"class":1418},[443,5229,357],{"class":768},[443,5231,5103],{"class":456},[443,5233,3000],{"class":768},[443,5235,5236],{"class":449},"                \u002F\u002F flush cached emissions\n",[443,5238,5239],{"class":445,"line":548},[443,5240,708],{"emptyLinePlaceholder":707},[443,5242,5243,5245,5247,5249,5251,5253,5255,5257,5259,5261,5263,5265,5267,5270],{"class":445,"line":554},[443,5244,1390],{"class":456},[443,5246,470],{"class":768},[443,5248,1866],{"class":1418},[443,5250,357],{"class":768},[443,5252,2880],{"class":456},[443,5254,1126],{"class":768},[443,5256,5126],{"class":456},[443,5258,470],{"class":768},[443,5260,1491],{"class":1490},[443,5262,420],{"class":473},[443,5264,1491],{"class":1490},[443,5266,1478],{"class":768},[443,5268,5269],{"class":863}," 2L",[443,5271,1576],{"class":768},[403,5273,5275],{"id":5274},"triggering-scheduled-sources","Triggering scheduled sources",[320,5277,5278,5279,5282],{},"A ",[420,5280,5281],{"href":141},"scheduled source"," generates records on a clock rather than from Kafka. You drive it two ways:",[331,5284,5285,5293],{},[334,5286,5287,5292],{},[337,5288,5289],{},[323,5290,5291],{},"triggerScheduledSource(name)"," fires the emitter once, immediately, without advancing time — handy for asserting the emitter logic in isolation.",[334,5294,5295,5299,5300,5302,5303,5299,5308,5310],{},[337,5296,5297],{},[323,5298,5023],{}," (for ",[323,5301,3240],{}," \u002F cron sources) or ",[337,5304,5305],{},[323,5306,5307],{},"advanceWatermark(...)",[323,5309,3216],{}," sources) fires every scheduled execution due up to the new time.",[320,5312,5313,5314,5317,5318,5321,5322,5325,5326,5328],{},"The default name of the first ",[323,5315,5316],{},"builder.scheduled(...)"," source is ",[323,5319,5320],{},"scheduled-source-0","; pass a ",[323,5323,5324],{},"Named"," to the operator to set your own. In Kotlin the key serde is optional (defaults to ",[323,5327,2120],{},"); in Java, pass it explicitly since Java has no default arguments.",[429,5330,5331,5616],{"group":645},[433,5332,5334],{"className":435,"code":5333,"filename":649,"language":438,"meta":439,"style":439},"val builder = StreamsBuilder()\nbuilder\n    .scheduled\u003CString, String>(\n        interval = Duration.ofSeconds(10),\n        type = PunctuationType.WALL_CLOCK_TIME,\n        emitter = { ctx -> ctx.forward(\"hb\", \"heartbeat-${ctx.currentWallClockTime()}\") },\n    )\n    .to(\"output\", Produced.with(Serdes.String(), Serdes.String()))\n\nval driver = TopologyTestDriver.fromBuilder(builder)\nval output = driver.createOutputTopic\u003CString, String>(\"output\", Serdes.String(), Serdes.String())\n\n\u002F\u002F Fire once, no time advance\ndriver.triggerScheduledSource(\"scheduled-source-0\")\nassertThat(output.readRecord()?.key).isEqualTo(\"hb\")\n\n\u002F\u002F Or fire by advancing the wall clock past the interval\ndriver.advanceWallClockTime(Duration.ofSeconds(10))\nassertThat(output.isEmpty()).isFalse()\n",[323,5335,5336,5348,5352,5370,5390,5400,5447,5452,5480,5484,5499,5533,5537,5542,5556,5575,5579,5584,5601],{"__ignoreMap":439},[443,5337,5338,5340,5342,5344,5346],{"class":445,"line":446},[443,5339,2029],{"class":656},[443,5341,765],{"class":460},[443,5343,769],{"class":768},[443,5345,772],{"class":456},[443,5347,775],{"class":460},[443,5349,5350],{"class":445,"line":453},[443,5351,3303],{"class":460},[443,5353,5354,5356,5359,5361,5363,5365,5367],{"class":445,"line":464},[443,5355,3308],{"class":460},[443,5357,5358],{"class":456},"scheduled",[443,5360,793],{"class":460},[443,5362,796],{"class":716},[443,5364,799],{"class":460},[443,5366,796],{"class":716},[443,5368,5369],{"class":460},">(\n",[443,5371,5372,5375,5377,5380,5382,5384,5387],{"class":445,"line":480},[443,5373,5374],{"class":460},"        interval ",[443,5376,769],{"class":768},[443,5378,5379],{"class":460}," Duration.",[443,5381,3365],{"class":456},[443,5383,470],{"class":460},[443,5385,5386],{"class":863},"10",[443,5388,5389],{"class":460},"),\n",[443,5391,5392,5395,5397],{"class":445,"line":486},[443,5393,5394],{"class":460},"        type ",[443,5396,769],{"class":768},[443,5398,5399],{"class":460}," PunctuationType.WALL_CLOCK_TIME,\n",[443,5401,5402,5405,5407,5410,5412,5415,5418,5420,5423,5425,5428,5431,5434,5437,5439,5442,5444],{"class":445,"line":498},[443,5403,5404],{"class":460},"        emitter ",[443,5406,769],{"class":768},[443,5408,5409],{"class":460}," { ctx ",[443,5411,1512],{"class":768},[443,5413,5414],{"class":460}," ctx.",[443,5416,5417],{"class":456},"forward",[443,5419,470],{"class":460},[443,5421,5422],{"class":473},"\"hb\"",[443,5424,799],{"class":460},[443,5426,5427],{"class":473},"\"heartbeat-",[443,5429,5430],{"class":656},"${",[443,5432,5433],{"class":473},"ctx.",[443,5435,5436],{"class":456},"currentWallClockTime",[443,5438,1443],{"class":473},[443,5440,5441],{"class":656},"}",[443,5443,1491],{"class":473},[443,5445,5446],{"class":460},") },\n",[443,5448,5449],{"class":445,"line":542},[443,5450,5451],{"class":460},"    )\n",[443,5453,5454,5456,5458,5460,5462,5465,5468,5471,5473,5475,5477],{"class":445,"line":548},[443,5455,3308],{"class":460},[443,5457,875],{"class":456},[443,5459,470],{"class":460},[443,5461,3433],{"class":473},[443,5463,5464],{"class":460},", Produced.",[443,5466,5467],{"class":456},"with",[443,5469,5470],{"class":460},"(Serdes.",[443,5472,796],{"class":456},[443,5474,989],{"class":460},[443,5476,796],{"class":456},[443,5478,5479],{"class":460},"()))\n",[443,5481,5482],{"class":445,"line":554},[443,5483,708],{"emptyLinePlaceholder":707},[443,5485,5486,5488,5490,5492,5494,5496],{"class":445,"line":559},[443,5487,2029],{"class":656},[443,5489,3446],{"class":460},[443,5491,769],{"class":768},[443,5493,898],{"class":460},[443,5495,901],{"class":456},[443,5497,5498],{"class":460},"(builder)\n",[443,5500,5501,5503,5505,5507,5509,5511,5513,5515,5517,5519,5521,5523,5525,5527,5529,5531],{"class":445,"line":564},[443,5502,2029],{"class":656},[443,5504,1002],{"class":460},[443,5506,769],{"class":768},[443,5508,937],{"class":460},[443,5510,611],{"class":456},[443,5512,793],{"class":460},[443,5514,796],{"class":716},[443,5516,799],{"class":460},[443,5518,796],{"class":716},[443,5520,804],{"class":460},[443,5522,3433],{"class":473},[443,5524,984],{"class":460},[443,5526,796],{"class":456},[443,5528,989],{"class":460},[443,5530,796],{"class":456},[443,5532,994],{"class":460},[443,5534,5535],{"class":445,"line":570},[443,5536,708],{"emptyLinePlaceholder":707},[443,5538,5539],{"class":445,"line":575},[443,5540,5541],{"class":449},"\u002F\u002F Fire once, no time advance\n",[443,5543,5544,5546,5549,5551,5554],{"class":445,"line":580},[443,5545,3602],{"class":460},[443,5547,5548],{"class":456},"triggerScheduledSource",[443,5550,470],{"class":460},[443,5552,5553],{"class":473},"\"scheduled-source-0\"",[443,5555,477],{"class":460},[443,5557,5558,5560,5562,5564,5567,5569,5571,5573],{"class":445,"line":778},[443,5559,1390],{"class":456},[443,5561,1092],{"class":460},[443,5563,1095],{"class":456},[443,5565,5566],{"class":460},"()?.key).",[443,5568,1106],{"class":456},[443,5570,470],{"class":460},[443,5572,5422],{"class":473},[443,5574,477],{"class":460},[443,5576,5577],{"class":445,"line":784},[443,5578,708],{"emptyLinePlaceholder":707},[443,5580,5581],{"class":445,"line":812},[443,5582,5583],{"class":449},"\u002F\u002F Or fire by advancing the wall clock past the interval\n",[443,5585,5586,5588,5591,5593,5595,5597,5599],{"class":445,"line":840},[443,5587,3602],{"class":460},[443,5589,5590],{"class":456},"advanceWallClockTime",[443,5592,3351],{"class":460},[443,5594,3365],{"class":456},[443,5596,470],{"class":460},[443,5598,5386],{"class":863},[443,5600,3817],{"class":460},[443,5602,5603,5605,5607,5609,5611,5614],{"class":445,"line":870},[443,5604,1390],{"class":456},[443,5606,1092],{"class":460},[443,5608,1123],{"class":456},[443,5610,1126],{"class":460},[443,5612,5613],{"class":456},"isFalse",[443,5615,775],{"class":460},[433,5617,5619],{"className":1144,"code":5618,"filename":1146,"language":1147,"meta":439,"style":439},"StreamsBuilder builder = new StreamsBuilder();\nbuilder.\u003CString, String>scheduled(\n        Duration.ofSeconds(10),\n        PunctuationType.WALL_CLOCK_TIME,\n        Serdes.String(),   \u002F\u002F key serde (Java has no default args)\n        ctx -> ctx.forward(\"hb\", \"heartbeat-\" + ctx.currentWallClockTime()))\n    .to(\"output\", Produced.with(Serdes.String(), Serdes.String()));\n\nTopologyTestDriver driver = TopologyTestDriver.fromBuilder(builder);\nTestOutputTopic\u003CString, String> output =\n    driver.createOutputTopic(\"output\", Serdes.String(), Serdes.String());\n\n\u002F\u002F Fire once, no time advance\ndriver.triggerScheduledSource(\"scheduled-source-0\");\nassertThat(output.readRecord().getKey()).isEqualTo(\"hb\");\n\n\u002F\u002F Or fire by advancing the wall clock past the interval\ndriver.advanceWallClockTime(Duration.ofSeconds(10));\nassertThat(output.isEmpty()).isFalse();\n",[323,5620,5621,5635,5656,5671,5683,5697,5740,5782,5786,5806,5824,5858,5862,5866,5884,5914,5918,5922,5945],{"__ignoreMap":439},[443,5622,5623,5625,5627,5629,5631,5633],{"class":445,"line":446},[443,5624,604],{"class":460},[443,5626,1453],{"class":1418},[443,5628,1456],{"class":768},[443,5630,1459],{"class":656},[443,5632,772],{"class":456},[443,5634,1464],{"class":768},[443,5636,5637,5639,5641,5643,5645,5647,5649,5651,5653],{"class":445,"line":453},[443,5638,1597],{"class":460},[443,5640,357],{"class":768},[443,5642,793],{"class":724},[443,5644,796],{"class":460},[443,5646,1478],{"class":768},[443,5648,1481],{"class":460},[443,5650,860],{"class":724},[443,5652,5358],{"class":456},[443,5654,5655],{"class":768},"(\n",[443,5657,5658,5661,5663,5665,5667,5669],{"class":445,"line":464},[443,5659,5660],{"class":1418},"        Duration",[443,5662,357],{"class":768},[443,5664,3365],{"class":456},[443,5666,470],{"class":768},[443,5668,5386],{"class":863},[443,5670,5389],{"class":768},[443,5672,5673,5676,5678,5680],{"class":445,"line":480},[443,5674,5675],{"class":1418},"        PunctuationType",[443,5677,357],{"class":768},[443,5679,3240],{"class":1418},[443,5681,5682],{"class":768},",\n",[443,5684,5685,5688,5690,5692,5694],{"class":445,"line":486},[443,5686,5687],{"class":1418},"        Serdes",[443,5689,357],{"class":768},[443,5691,796],{"class":456},[443,5693,1720],{"class":768},[443,5695,5696],{"class":449},"   \u002F\u002F key serde (Java has no default args)\n",[443,5698,5699,5702,5704,5707,5709,5711,5713,5715,5718,5720,5722,5724,5727,5729,5732,5734,5736,5738],{"class":445,"line":498},[443,5700,5701],{"class":460},"        ctx ",[443,5703,1512],{"class":768},[443,5705,5706],{"class":1418}," ctx",[443,5708,357],{"class":768},[443,5710,5417],{"class":456},[443,5712,470],{"class":768},[443,5714,1491],{"class":1490},[443,5716,5717],{"class":473},"hb",[443,5719,1491],{"class":1490},[443,5721,1478],{"class":768},[443,5723,1811],{"class":1490},[443,5725,5726],{"class":473},"heartbeat-",[443,5728,1491],{"class":1490},[443,5730,5731],{"class":724}," +",[443,5733,5706],{"class":1418},[443,5735,357],{"class":768},[443,5737,5436],{"class":456},[443,5739,5479],{"class":768},[443,5741,5742,5744,5746,5748,5750,5752,5754,5756,5759,5761,5763,5765,5767,5769,5771,5773,5775,5777,5779],{"class":445,"line":542},[443,5743,3308],{"class":768},[443,5745,875],{"class":456},[443,5747,470],{"class":768},[443,5749,1491],{"class":1490},[443,5751,1866],{"class":473},[443,5753,1491],{"class":1490},[443,5755,1478],{"class":768},[443,5757,5758],{"class":1418}," Produced",[443,5760,357],{"class":768},[443,5762,5467],{"class":456},[443,5764,470],{"class":768},[443,5766,1274],{"class":1418},[443,5768,357],{"class":768},[443,5770,796],{"class":456},[443,5772,1720],{"class":768},[443,5774,1713],{"class":1418},[443,5776,357],{"class":768},[443,5778,796],{"class":456},[443,5780,5781],{"class":768},"()));\n",[443,5783,5784],{"class":445,"line":548},[443,5785,708],{"emptyLinePlaceholder":707},[443,5787,5788,5790,5792,5794,5796,5798,5800,5802,5804],{"class":445,"line":554},[443,5789,1240],{"class":460},[443,5791,1419],{"class":1418},[443,5793,1456],{"class":768},[443,5795,1415],{"class":1418},[443,5797,357],{"class":768},[443,5799,901],{"class":456},[443,5801,470],{"class":768},[443,5803,1597],{"class":460},[443,5805,1576],{"class":768},[443,5807,5808,5810,5812,5814,5816,5818,5820,5822],{"class":445,"line":559},[443,5809,1219],{"class":460},[443,5811,793],{"class":768},[443,5813,796],{"class":724},[443,5815,1478],{"class":768},[443,5817,1481],{"class":724},[443,5819,860],{"class":768},[443,5821,1747],{"class":1418},[443,5823,1691],{"class":768},[443,5825,5826,5828,5830,5832,5834,5836,5838,5840,5842,5844,5846,5848,5850,5852,5854,5856],{"class":445,"line":564},[443,5827,2335],{"class":1418},[443,5829,357],{"class":768},[443,5831,611],{"class":456},[443,5833,470],{"class":768},[443,5835,1491],{"class":1490},[443,5837,1866],{"class":473},[443,5839,1491],{"class":1490},[443,5841,1478],{"class":768},[443,5843,1713],{"class":1418},[443,5845,357],{"class":768},[443,5847,796],{"class":456},[443,5849,1720],{"class":768},[443,5851,1713],{"class":1418},[443,5853,357],{"class":768},[443,5855,796],{"class":456},[443,5857,1729],{"class":768},[443,5859,5860],{"class":445,"line":570},[443,5861,708],{"emptyLinePlaceholder":707},[443,5863,5864],{"class":445,"line":575},[443,5865,5541],{"class":449},[443,5867,5868,5870,5872,5874,5876,5878,5880,5882],{"class":445,"line":580},[443,5869,4065],{"class":1418},[443,5871,357],{"class":768},[443,5873,5548],{"class":456},[443,5875,470],{"class":768},[443,5877,1491],{"class":1490},[443,5879,5320],{"class":473},[443,5881,1491],{"class":1490},[443,5883,1576],{"class":768},[443,5885,5886,5888,5890,5892,5894,5896,5898,5900,5902,5904,5906,5908,5910,5912],{"class":445,"line":778},[443,5887,1390],{"class":456},[443,5889,470],{"class":768},[443,5891,1866],{"class":1418},[443,5893,357],{"class":768},[443,5895,1095],{"class":456},[443,5897,1873],{"class":768},[443,5899,3013],{"class":456},[443,5901,1126],{"class":768},[443,5903,1106],{"class":456},[443,5905,470],{"class":768},[443,5907,1491],{"class":1490},[443,5909,5717],{"class":473},[443,5911,1491],{"class":1490},[443,5913,1576],{"class":768},[443,5915,5916],{"class":445,"line":784},[443,5917,708],{"emptyLinePlaceholder":707},[443,5919,5920],{"class":445,"line":812},[443,5921,5583],{"class":449},[443,5923,5924,5926,5928,5930,5932,5934,5936,5938,5940,5942],{"class":445,"line":840},[443,5925,4065],{"class":1418},[443,5927,357],{"class":768},[443,5929,5590],{"class":456},[443,5931,470],{"class":768},[443,5933,3721],{"class":1418},[443,5935,357],{"class":768},[443,5937,3365],{"class":456},[443,5939,470],{"class":768},[443,5941,5386],{"class":863},[443,5943,5944],{"class":768},"));\n",[443,5946,5947,5949,5951,5953,5955,5957,5959,5961],{"class":445,"line":870},[443,5948,1390],{"class":456},[443,5950,470],{"class":768},[443,5952,1866],{"class":1418},[443,5954,357],{"class":768},[443,5956,1123],{"class":456},[443,5958,1126],{"class":768},[443,5960,5613],{"class":456},[443,5962,1464],{"class":768},[403,5964,5966],{"id":5965},"config-driven-tests-stoatflowtestdriver","Config-driven tests (StoatFlowTestDriver)",[320,5968,5969,5971,5972,5974,5975,5977,5978,5980,5981,5983,5984,5986],{},[323,5970,393],{}," is the test-time mirror of the production ",[323,5973,401],{}," (see ",[420,5976,28],{"href":29},"). It loads ",[323,5979,397],{}," from the classpath, maps it into a ",[323,5982,1963],{},", builds your topology with the configured default serdes, and returns a ready ",[323,5985,1240],{},". No broker, no HTTP server — just the topology under the same configuration your app runs with.",[320,5988,5989,5990,5993,5994,5997,5998,6001],{},"Configuration is resolved from the classpath, so a ",[323,5991,5992],{},"src\u002Ftest\u002Fresources\u002Fapplication.yaml"," shadows the main one — letting tests pin a deterministic config. Environment variables with the ",[323,5995,5996],{},"STOATFLOW_"," prefix take highest priority; the optional ",[323,5999,6000],{},"configOverrides"," lambda overrides programmatically above everything else.",[320,6003,6004,6005,6007,6008,6010,6011,6014],{},"The topology-builder callback receives both the ",[323,6006,604],{}," and the loaded ",[323,6009,1963],{},", so a topology that needs config values (e.g. ",[323,6012,6013],{},"config.schemaRegistryUrl",") can read them.",[429,6016,6017,6097],{"group":645},[433,6018,6020],{"className":435,"code":6019,"filename":649,"language":438,"meta":439,"style":439},"import io.stoatflow.testruntime.StoatFlowTestDriver\nimport io.stoatflow.testutils.TopologyTestDriver\n\nprivate fun buildDriver(): TopologyTestDriver =\n    StoatFlowTestDriver.fromConfig(\n        topologyBuilder = { builder, config -> MyApp.buildTopology(builder, config) },\n        \u002F\u002F optional: configOverrides = { \u002F* StreamsConfig.Builder receiver *\u002F },\n    )\n",[323,6021,6022,6029,6035,6039,6057,6067,6088,6093],{"__ignoreMap":439},[443,6023,6024,6026],{"class":445,"line":446},[443,6025,657],{"class":656},[443,6027,6028],{"class":456}," io.stoatflow.testruntime.StoatFlowTestDriver\n",[443,6030,6031,6033],{"class":445,"line":453},[443,6032,657],{"class":656},[443,6034,667],{"class":456},[443,6036,6037],{"class":445,"line":464},[443,6038,708],{"emptyLinePlaceholder":707},[443,6040,6041,6044,6047,6050,6053,6055],{"class":445,"line":480},[443,6042,6043],{"class":724},"private",[443,6045,6046],{"class":656}," fun",[443,6048,6049],{"class":456}," buildDriver",[443,6051,6052],{"class":460},"(): ",[443,6054,1240],{"class":716},[443,6056,1691],{"class":768},[443,6058,6059,6062,6065],{"class":445,"line":486},[443,6060,6061],{"class":460},"    StoatFlowTestDriver.",[443,6063,6064],{"class":456},"fromConfig",[443,6066,5655],{"class":460},[443,6068,6069,6072,6074,6077,6079,6082,6085],{"class":445,"line":498},[443,6070,6071],{"class":460},"        topologyBuilder ",[443,6073,769],{"class":768},[443,6075,6076],{"class":460}," { builder, config ",[443,6078,1512],{"class":768},[443,6080,6081],{"class":460}," MyApp.",[443,6083,6084],{"class":456},"buildTopology",[443,6086,6087],{"class":460},"(builder, config) },\n",[443,6089,6090],{"class":445,"line":542},[443,6091,6092],{"class":449},"        \u002F\u002F optional: configOverrides = { \u002F* StreamsConfig.Builder receiver *\u002F },\n",[443,6094,6095],{"class":445,"line":548},[443,6096,5451],{"class":460},[433,6098,6100],{"className":1144,"code":6099,"filename":1146,"language":1147,"meta":439,"style":439},"import io.stoatflow.testruntime.StoatFlowTestDriver;\nimport io.stoatflow.testutils.TopologyTestDriver;\n\nstatic TopologyTestDriver buildDriver() {\n    return StoatFlowTestDriver.fromConfig(\n        (builder, config) -> MyApp.buildTopology(builder),\n        null   \u002F\u002F optional Consumer\u003CStreamsConfig.Builder> for overrides\n    );\n}\n",[323,6101,6102,6124,6144,6148,6163,6177,6206,6214,6219],{"__ignoreMap":439},[443,6103,6104,6106,6108,6110,6112,6114,6117,6119,6122],{"class":445,"line":446},[443,6105,657],{"class":656},[443,6107,1156],{"class":460},[443,6109,357],{"class":768},[443,6111,1161],{"class":460},[443,6113,357],{"class":768},[443,6115,6116],{"class":460},"testruntime",[443,6118,357],{"class":768},[443,6120,6121],{"class":460},"StoatFlowTestDriver",[443,6123,1178],{"class":768},[443,6125,6126,6128,6130,6132,6134,6136,6138,6140,6142],{"class":445,"line":453},[443,6127,657],{"class":656},[443,6129,1156],{"class":460},[443,6131,357],{"class":768},[443,6133,1161],{"class":460},[443,6135,357],{"class":768},[443,6137,1193],{"class":460},[443,6139,357],{"class":768},[443,6141,1240],{"class":460},[443,6143,1178],{"class":768},[443,6145,6146],{"class":445,"line":464},[443,6147,708],{"emptyLinePlaceholder":707},[443,6149,6150,6153,6156,6159,6161],{"class":445,"line":480},[443,6151,6152],{"class":724},"static",[443,6154,6155],{"class":460}," TopologyTestDriver ",[443,6157,6158],{"class":456},"buildDriver",[443,6160,1443],{"class":768},[443,6162,461],{"class":768},[443,6164,6165,6168,6171,6173,6175],{"class":445,"line":486},[443,6166,6167],{"class":656},"    return",[443,6169,6170],{"class":1418}," StoatFlowTestDriver",[443,6172,357],{"class":768},[443,6174,6064],{"class":456},[443,6176,5655],{"class":768},[443,6178,6179,6182,6184,6186,6189,6191,6193,6196,6198,6200,6202,6204],{"class":445,"line":498},[443,6180,6181],{"class":768},"        (",[443,6183,1597],{"class":460},[443,6185,1478],{"class":768},[443,6187,6188],{"class":460}," config",[443,6190,1540],{"class":768},[443,6192,826],{"class":768},[443,6194,6195],{"class":1418}," MyApp",[443,6197,357],{"class":768},[443,6199,6084],{"class":456},[443,6201,470],{"class":768},[443,6203,1597],{"class":460},[443,6205,5389],{"class":768},[443,6207,6208,6211],{"class":445,"line":542},[443,6209,6210],{"class":656},"        null",[443,6212,6213],{"class":449},"   \u002F\u002F optional Consumer\u003CStreamsConfig.Builder> for overrides\n",[443,6215,6216],{"class":445,"line":548},[443,6217,6218],{"class":768},"    );\n",[443,6220,6221],{"class":445,"line":554},[443,6222,501],{"class":768},[320,6224,6225,6226,6228,6229,799,6231,799,6233,799,6235,6237,6238,6241,6242,378,6245,6248],{},"From there it is the same ",[323,6227,1240],{}," API — ",[323,6230,608],{},[323,6232,611],{},[323,6234,3273],{},[323,6236,4267],{},", and so on. This is the pattern the example apps use; see ",[323,6239,6240],{},"examples\u002Fstock-tick-filter"," (Kotlin) and ",[323,6243,6244],{},"examples\u002Fecommerce-daily-customer-behaviour",[323,6246,6247],{},"examples\u002Fnews-feed-subscription-processor"," (Java) for full end-to-end topology tests, each paired with a broker-backed integration test.",[403,6250,6252],{"id":6251},"porting-kafka-streams-tests","Porting Kafka Streams tests",[320,6254,6255,6256,6258],{},"If you're migrating a Kafka Streams test suite, you don't have to rewrite it around ",[323,6257,901],{},". The driver also carries the KS-shaped surface, so an existing KS test ports with the same import swap as the topology it exercises:",[331,6260,6261,6292,6316,6324],{},[334,6262,6263,6266,6267,799,6270,799,6273,6276,6277,6280,6281,6283,6284,6287,6288,6291],{},[337,6264,6265],{},"KS constructors"," — ",[323,6268,6269],{},"TopologyTestDriver(topology)",[323,6271,6272],{},"(topology, Properties)",[323,6274,6275],{},"(topology, Instant)",", and ",[323,6278,6279],{},"(topology, Properties, Instant)",". The ",[323,6282,3260],{}," overloads accept KS-keyed config (",[323,6285,6286],{},"application.id",", default serde class names, …) through the same adapter the engine uses. Typed ",[323,6289,6290],{},"(topology, StreamsConfig[, Instant])"," forms exist too.",[334,6293,6294,6299,6300,6303,6304,378,6307,378,6310,6313,6314,357],{},[337,6295,6296],{},[323,6297,6298],{},"fromTopology(topology[, config][, initialWallClockTime])"," — for a ",[323,6301,6302],{},"Topology"," assembled with the Processor API (",[323,6305,6306],{},"addSource",[323,6308,6309],{},"addProcessor",[323,6311,6312],{},"addSink",") rather than a ",[323,6315,604],{},[334,6317,6318,6323],{},[337,6319,6320],{},[323,6321,6322],{},"getAllStateStores()"," — every state store keyed by name, matching KS.",[334,6325,6326,6331],{},[337,6327,6328],{},[323,6329,6330],{},"producedTopicNames()"," — the set of topics the driver has produced records to, matching KS.",[429,6333,6334,6477],{"group":645},[433,6335,6337],{"className":435,"code":6336,"filename":649,"language":438,"meta":439,"style":439},"val props = Properties()\nprops[StreamsConfig.APPLICATION_ID_CONFIG] = \"uppercase-test\"\nprops[StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG] = Serdes.String()::class.java\nprops[StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG] = Serdes.String()::class.java\n\n\u002F\u002F The KS constructor idiom, unchanged\nval driver = TopologyTestDriver(builder.build(), props)\n\ninput.pipeInput(\"k1\", \"hello\")\n\ndriver.producedTopicNames()   \u002F\u002F setOf(\"output-topic\")\ndriver.getAllStateStores()    \u002F\u002F all stores by name\n",[323,6338,6339,6353,6363,6383,6400,6404,6409,6427,6431,6447,6451,6464],{"__ignoreMap":439},[443,6340,6341,6343,6346,6348,6351],{"class":445,"line":446},[443,6342,2029],{"class":656},[443,6344,6345],{"class":460}," props ",[443,6347,769],{"class":768},[443,6349,6350],{"class":456}," Properties",[443,6352,775],{"class":460},[443,6354,6355,6358,6360],{"class":445,"line":453},[443,6356,6357],{"class":460},"props[StreamsConfig.APPLICATION_ID_CONFIG] ",[443,6359,769],{"class":768},[443,6361,6362],{"class":473}," \"uppercase-test\"\n",[443,6364,6365,6368,6370,6373,6375,6378,6380],{"class":445,"line":464},[443,6366,6367],{"class":460},"props[StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG] ",[443,6369,769],{"class":768},[443,6371,6372],{"class":460}," Serdes.",[443,6374,796],{"class":456},[443,6376,6377],{"class":460},"()::",[443,6379,713],{"class":456},[443,6381,6382],{"class":460},".java\n",[443,6384,6385,6388,6390,6392,6394,6396,6398],{"class":445,"line":480},[443,6386,6387],{"class":460},"props[StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG] ",[443,6389,769],{"class":768},[443,6391,6372],{"class":460},[443,6393,796],{"class":456},[443,6395,6377],{"class":460},[443,6397,713],{"class":456},[443,6399,6382],{"class":460},[443,6401,6402],{"class":445,"line":486},[443,6403,708],{"emptyLinePlaceholder":707},[443,6405,6406],{"class":445,"line":498},[443,6407,6408],{"class":449},"\u002F\u002F The KS constructor idiom, unchanged\n",[443,6410,6411,6413,6415,6417,6419,6422,6424],{"class":445,"line":542},[443,6412,2029],{"class":656},[443,6414,3446],{"class":460},[443,6416,769],{"class":768},[443,6418,1415],{"class":456},[443,6420,6421],{"class":460},"(builder.",[443,6423,431],{"class":456},[443,6425,6426],{"class":460},"(), props)\n",[443,6428,6429],{"class":445,"line":548},[443,6430,708],{"emptyLinePlaceholder":707},[443,6432,6433,6435,6437,6439,6441,6443,6445],{"class":445,"line":554},[443,6434,2060],{"class":460},[443,6436,638],{"class":456},[443,6438,470],{"class":460},[443,6440,1048],{"class":473},[443,6442,799],{"class":460},[443,6444,1053],{"class":473},[443,6446,477],{"class":460},[443,6448,6449],{"class":445,"line":559},[443,6450,708],{"emptyLinePlaceholder":707},[443,6452,6453,6455,6458,6461],{"class":445,"line":564},[443,6454,3602],{"class":460},[443,6456,6457],{"class":456},"producedTopicNames",[443,6459,6460],{"class":460},"()   ",[443,6462,6463],{"class":449},"\u002F\u002F setOf(\"output-topic\")\n",[443,6465,6466,6468,6471,6474],{"class":445,"line":570},[443,6467,3602],{"class":460},[443,6469,6470],{"class":456},"getAllStateStores",[443,6472,6473],{"class":460},"()    ",[443,6475,6476],{"class":449},"\u002F\u002F all stores by name\n",[433,6478,6480],{"className":1144,"code":6479,"filename":1146,"language":1147,"meta":439,"style":439},"var props = new Properties();\nprops.put(StreamsConfig.APPLICATION_ID_CONFIG, \"uppercase-test\");\nprops.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());\nprops.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());\n\n\u002F\u002F The KS constructor idiom, unchanged\nvar driver = new TopologyTestDriver(builder.build(), props);\n\ninput.pipeInput(\"k1\", \"hello\");\n\ndriver.producedTopicNames();   \u002F\u002F Set.of(\"output-topic\")\ndriver.getAllStateStores();    \u002F\u002F all stores by name\n",[323,6481,6482,6498,6528,6560,6591,6595,6599,6625,6629,6655,6659,6672],{"__ignoreMap":439},[443,6483,6484,6487,6490,6492,6494,6496],{"class":445,"line":446},[443,6485,6486],{"class":724},"var",[443,6488,6489],{"class":1418}," props",[443,6491,1456],{"class":768},[443,6493,1459],{"class":656},[443,6495,6350],{"class":456},[443,6497,1464],{"class":768},[443,6499,6500,6503,6505,6508,6510,6512,6514,6517,6519,6521,6524,6526],{"class":445,"line":453},[443,6501,6502],{"class":1418},"props",[443,6504,357],{"class":768},[443,6506,6507],{"class":456},"put",[443,6509,470],{"class":768},[443,6511,1963],{"class":1418},[443,6513,357],{"class":768},[443,6515,6516],{"class":1418},"APPLICATION_ID_CONFIG",[443,6518,1478],{"class":768},[443,6520,1811],{"class":1490},[443,6522,6523],{"class":473},"uppercase-test",[443,6525,1491],{"class":1490},[443,6527,1576],{"class":768},[443,6529,6530,6532,6534,6536,6538,6540,6542,6545,6547,6549,6551,6553,6555,6558],{"class":445,"line":464},[443,6531,6502],{"class":1418},[443,6533,357],{"class":768},[443,6535,6507],{"class":456},[443,6537,470],{"class":768},[443,6539,1963],{"class":1418},[443,6541,357],{"class":768},[443,6543,6544],{"class":1418},"DEFAULT_KEY_SERDE_CLASS_CONFIG",[443,6546,1478],{"class":768},[443,6548,1713],{"class":1418},[443,6550,357],{"class":768},[443,6552,796],{"class":456},[443,6554,1873],{"class":768},[443,6556,6557],{"class":456},"getClass",[443,6559,1729],{"class":768},[443,6561,6562,6564,6566,6568,6570,6572,6574,6577,6579,6581,6583,6585,6587,6589],{"class":445,"line":480},[443,6563,6502],{"class":1418},[443,6565,357],{"class":768},[443,6567,6507],{"class":456},[443,6569,470],{"class":768},[443,6571,1963],{"class":1418},[443,6573,357],{"class":768},[443,6575,6576],{"class":1418},"DEFAULT_VALUE_SERDE_CLASS_CONFIG",[443,6578,1478],{"class":768},[443,6580,1713],{"class":1418},[443,6582,357],{"class":768},[443,6584,796],{"class":456},[443,6586,1873],{"class":768},[443,6588,6557],{"class":456},[443,6590,1729],{"class":768},[443,6592,6593],{"class":445,"line":486},[443,6594,708],{"emptyLinePlaceholder":707},[443,6596,6597],{"class":445,"line":498},[443,6598,6408],{"class":449},[443,6600,6601,6603,6605,6607,6609,6611,6613,6615,6617,6619,6621,6623],{"class":445,"line":542},[443,6602,6486],{"class":724},[443,6604,1419],{"class":1418},[443,6606,1456],{"class":768},[443,6608,1459],{"class":656},[443,6610,1415],{"class":456},[443,6612,470],{"class":768},[443,6614,1597],{"class":1418},[443,6616,357],{"class":768},[443,6618,431],{"class":456},[443,6620,1720],{"class":768},[443,6622,6489],{"class":460},[443,6624,1576],{"class":768},[443,6626,6627],{"class":445,"line":548},[443,6628,708],{"emptyLinePlaceholder":707},[443,6630,6631,6633,6635,6637,6639,6641,6643,6645,6647,6649,6651,6653],{"class":445,"line":554},[443,6632,2374],{"class":1418},[443,6634,357],{"class":768},[443,6636,638],{"class":456},[443,6638,470],{"class":768},[443,6640,1491],{"class":1490},[443,6642,1804],{"class":473},[443,6644,1491],{"class":1490},[443,6646,1478],{"class":768},[443,6648,1811],{"class":1490},[443,6650,1814],{"class":473},[443,6652,1491],{"class":1490},[443,6654,1576],{"class":768},[443,6656,6657],{"class":445,"line":559},[443,6658,708],{"emptyLinePlaceholder":707},[443,6660,6661,6663,6665,6667,6669],{"class":445,"line":564},[443,6662,4065],{"class":1418},[443,6664,357],{"class":768},[443,6666,6457],{"class":456},[443,6668,3000],{"class":768},[443,6670,6671],{"class":449},"   \u002F\u002F Set.of(\"output-topic\")\n",[443,6673,6674,6676,6678,6680,6682],{"class":445,"line":570},[443,6675,4065],{"class":1418},[443,6677,357],{"class":768},[443,6679,6470],{"class":456},[443,6681,3000],{"class":768},[443,6683,6684],{"class":449},"    \u002F\u002F all stores by name\n",[320,6686,6687,6688,6690,6691,6694,6695,6697,6698,6702],{},"For new StoatFlow tests, prefer ",[323,6689,901],{}," (above) — it skips the ",[323,6692,6693],{},"builder.build()"," step and the ",[323,6696,3260],{}," indirection. The KS-shaped surface exists so ported suites keep passing as-is; the ",[420,6699,6701],{"href":6700},"\u002Fdocs\u002Freference\u002Fks-compatibility-matrix#test-utilities","KS compatibility matrix"," tracks the full test-utils parity.",[403,6704,6706],{"id":6705},"next-steps","Next steps",[331,6708,6709,6717,6724,6737],{},[334,6710,6711,6716],{},[337,6712,6713],{},[420,6714,6715],{"href":111},"Streams builder"," — building the topology you're testing.",[334,6718,6719,6723],{},[337,6720,6721],{},[420,6722,100],{"href":101}," — the store types the accessors above return.",[334,6725,6726,353,6730,6734,6735,357],{},[337,6727,6728],{},[420,6729,125],{"href":126},[337,6731,6732],{},[420,6733,67],{"href":68}," — the time model behind ",[323,6736,3273],{},[334,6738,6739,6743],{},[337,6740,6741],{},[420,6742,140],{"href":141}," — clock-driven sources and how to test them.",[6745,6746,6747],"style",{},"html pre.shiki code .s8zF2, html code.shiki .s8zF2{--shiki-default:#A0ADA0}html pre.shiki code .sySUi, html code.shiki .sySUi{--shiki-default:#59873A}html pre.shiki code .suHK_, html code.shiki .suHK_{--shiki-default:#393A34}html pre.shiki code .spphp, html code.shiki .spphp{--shiki-default:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sbBg2, html code.shiki .sbBg2{--shiki-default:#1E754F}html pre.shiki code .sUxyF, html code.shiki .sUxyF{--shiki-default:#2E8F82}html pre.shiki code .si04Y, html code.shiki .si04Y{--shiki-default:#AB5959}html pre.shiki code .sYZai, html code.shiki .sYZai{--shiki-default:#999999}html pre.shiki code .s-TwI, html code.shiki .s-TwI{--shiki-default:#2F798A}html pre.shiki code .svycV, html code.shiki .svycV{--shiki-default:#B07D48}html pre.shiki code .sSP4y, html code.shiki .sSP4y{--shiki-default:#B5695977}",{"title":439,"searchDepth":453,"depth":453,"links":6749},[6750,6751,6754,6755,6756,6757,6758,6759,6760,6761,6762],{"id":405,"depth":453,"text":406},{"id":595,"depth":453,"text":596,"children":6752},[6753],{"id":1949,"depth":464,"text":1950},{"id":1996,"depth":453,"text":1997},{"id":2708,"depth":453,"text":2709},{"id":3181,"depth":453,"text":3182},{"id":4121,"depth":453,"text":4122},{"id":5009,"depth":453,"text":5010},{"id":5274,"depth":453,"text":5275},{"id":5965,"depth":453,"text":5966},{"id":6251,"depth":453,"text":6252},{"id":6705,"depth":453,"text":6706},"Unit-test a StoatFlow topology in-memory with TopologyTestDriver — pipe records, advance time and watermarks, read state stores, and drive YAML config through StoatFlowTestDriver. No broker required.","md",{},{"icon":108},"how-to",{"title":105,"description":6763},"hub26LEJ9qER-6KT3ImLJnmDt7oUkJPnoNIpT3R1mR8",[6771,6773],{"title":100,"path":101,"stem":102,"description":6772,"icon":103,"children":-1},"Use the Stores factory and Materialized to configure persistent and in-memory key-value, window, session, and versioned stores — and read them back via interactive queries.",{"title":110,"path":111,"stem":112,"description":6774,"icon":113,"children":-1},"Read records into a topology with builder.stream \u002F table \u002F globalTable and Consumed, and write them back out with to() and Produced — serdes, offset reset, watermarks, partitioners, and the fan-out rule.",1783713353038]