From 908bee4d2c017a5c5f4d1a60d076ed15b5be2761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Wed, 25 Dec 2024 23:46:13 +0700 Subject: [PATCH] Allow any term to be used as tag in Kino.Control.tagged_stream/1 --- lib/kino/control.ex | 8 +++++--- test/kino/control_test.exs | 12 +++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/kino/control.ex b/lib/kino/control.ex index 89744ec1..f9f676b6 100644 --- a/lib/kino/control.ex +++ b/lib/kino/control.ex @@ -401,6 +401,8 @@ defmodule Kino.Control do @doc """ Same as `stream/1`, but attaches custom tag to every stream item. + Tags can be arbitrary terms. + ## Example button = Kino.Control.button("Hello") @@ -414,17 +416,17 @@ defmodule Kino.Control do #=> {:hello, %{origin: "client1", type: :click}} #=> {:check, %{origin: "client1", type: :change, value: true}} """ - @spec tagged_stream(keyword(event_source())) :: Enumerable.t() + @spec tagged_stream(list({tag :: term(), event_source()})) :: Enumerable.t() def tagged_stream(entries) when is_list(entries) do {tagged_topics, tagged_intervals} = for entry <- entries, reduce: {[], []} do {tagged_topics, tagged_intervals} -> case entry do - {tag, source} when is_atom(tag) -> + {_tag, source} -> assert_stream_source!(source) _other -> - raise ArgumentError, "expected a keyword list, got: #{inspect(entries)}" + raise ArgumentError, "expected a list of 2-element tuples, got: #{inspect(entries)}" end {tag, source} = entry diff --git a/test/kino/control_test.exs b/test/kino/control_test.exs index 56b2ac53..4bc4a265 100644 --- a/test/kino/control_test.exs +++ b/test/kino/control_test.exs @@ -165,7 +165,7 @@ defmodule Kino.ControlTest do describe "tagged_stream/1" do test "raises on invalid argument" do - assert_raise ArgumentError, "expected a keyword list, got: [0]", fn -> + assert_raise ArgumentError, "expected a list of 2-element tuples, got: [0]", fn -> Kino.Control.tagged_stream([0]) end @@ -191,6 +191,16 @@ defmodule Kino.ControlTest do |> Enum.take(2) assert Enum.sort(events) == [{:click, %{origin: "client1"}}, {:name, %{origin: "client2"}}] + + events = + [{{:click, "button"}, button}, {{:name, "text"}, input}] + |> Kino.Control.tagged_stream() + |> Enum.take(2) + + assert Enum.sort(events) == [ + {{:click, "button"}, %{origin: "client1"}}, + {{:name, "text"}, %{origin: "client2"}} + ] end end