Packages

Native desktop GUI framework for Gleam, powered by Iced

Current section

Files

Jump to
plushie_gleam src plushie@testing@command_processor.erl
Raw

src/plushie@testing@command_processor.erl

-module(plushie@testing@command_processor).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/plushie/testing/command_processor.gleam").
-export([process_commands/4]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Synchronous command processor for test backends.\n"
"\n"
" Executes async, stream, done, and batch commands synchronously so that\n"
" update side effects resolve immediately in tests. Widget ops, window\n"
" ops, timers, and cancel are silently skipped (they need a renderer).\n"
"\n"
" Since execution is synchronous, await_async returns immediately;\n"
" commands have already completed by the time it is called.\n"
).
-file("src/plushie/testing/command_processor.gleam", 111).
-spec batch_process(
plushie@app:app(ABCH, ABCI),
ABCH,
list(plushie@command:command(ABCI)),
integer(),
integer(),
list(plushie@event:event())
) -> {ABCH, list(plushie@event:event())}.
batch_process(App, Model, Commands, Depth, Max_depth, Events) ->
case Commands of
[] ->
{Model, Events};
[Cmd | Rest] ->
{Model@1, Events@1} = do_process(
App,
Model,
Cmd,
Depth,
Max_depth,
Events
),
batch_process(App, Model@1, Rest, Depth, Max_depth, Events@1)
end.
-file("src/plushie/testing/command_processor.gleam", 48).
-spec do_process(
plushie@app:app(ABCA, ABCB),
ABCA,
plushie@command:command(ABCB),
integer(),
integer(),
list(plushie@event:event())
) -> {ABCA, list(plushie@event:event())}.
do_process(App, Model, Cmd, Depth, Max_depth, Events) ->
case Depth > Max_depth of
true ->
{Model, Events};
false ->
case Cmd of
none ->
{Model, Events};
{batch, Commands} ->
batch_process(
App,
Model,
Commands,
Depth,
Max_depth,
Events
);
{done, Value, Mapper} ->
Msg = Mapper(Value),
Update_fn = plushie@app:get_update(App),
{New_model, New_commands} = Update_fn(Model, Msg),
do_process(
App,
New_model,
New_commands,
Depth + 1,
Max_depth,
Events
);
{async, Work, Tag} ->
Result = Work(),
dispatch_async_result(
App,
Model,
Tag,
{ok, Result},
Depth,
Max_depth,
Events
);
{stream, Work@1, Tag@1} ->
Values = plushie_test_ffi:collect_stream_values(Work@1),
{Model@1, Events@1} = drain_stream_values(
App,
Model,
Tag@1,
erlang:element(1, Values),
Depth,
Max_depth,
Events
),
dispatch_async_result(
App,
Model@1,
Tag@1,
{ok, erlang:element(2, Values)},
Depth,
Max_depth,
Events@1
);
_ ->
{Model, Events}
end
end.
-file("src/plushie/testing/command_processor.gleam", 34).
?DOC(
" Process commands synchronously, threading model state through each\n"
" update dispatch. Returns the final model and list of events processed.\n"
"\n"
" `max_depth` controls recursion depth: `None` uses the default limit,\n"
" `Some(n)` uses n.\n"
).
-spec process_commands(
plushie@app:app(ABBT, ABBU),
ABBT,
plushie@command:command(ABBU),
gleam@option:option(integer())
) -> {ABBT, list(plushie@event:event())}.
process_commands(App, Model, Commands, Max_depth) ->
Effective_max = case Max_depth of
{some, N} ->
N;
none ->
100
end,
do_process(App, Model, Commands, 0, Effective_max, []).
-file("src/plushie/testing/command_processor.gleam", 130).
-spec dispatch_async_result(
plushie@app:app(ABCP, any()),
ABCP,
binary(),
{ok, gleam@dynamic:dynamic_()} | {error, gleam@dynamic:dynamic_()},
integer(),
integer(),
list(plushie@event:event())
) -> {ABCP, list(plushie@event:event())}.
dispatch_async_result(App, Model, Tag, Result, Depth, Max_depth, Events) ->
Raw_event = {async, {async_event, Tag, Result}},
Events@1 = [Raw_event | Events],
Msg = plushie@runtime_core:map_event(App, Raw_event),
Update_fn = plushie@app:get_update(App),
{New_model, New_commands} = Update_fn(Model, Msg),
do_process(App, New_model, New_commands, Depth + 1, Max_depth, Events@1).
-file("src/plushie/testing/command_processor.gleam", 148).
-spec dispatch_stream_value(
plushie@app:app(ABCX, any()),
ABCX,
binary(),
gleam@dynamic:dynamic_(),
integer(),
integer(),
list(plushie@event:event())
) -> {ABCX, list(plushie@event:event())}.
dispatch_stream_value(App, Model, Tag, Value, Depth, Max_depth, Events) ->
Raw_event = {stream, {stream_event, Tag, Value}},
Events@1 = [Raw_event | Events],
Msg = plushie@runtime_core:map_event(App, Raw_event),
Update_fn = plushie@app:get_update(App),
{New_model, New_commands} = Update_fn(Model, Msg),
do_process(App, New_model, New_commands, Depth + 1, Max_depth, Events@1).
-file("src/plushie/testing/command_processor.gleam", 166).
-spec drain_stream_values(
plushie@app:app(ABDD, any()),
ABDD,
binary(),
list(gleam@dynamic:dynamic_()),
integer(),
integer(),
list(plushie@event:event())
) -> {ABDD, list(plushie@event:event())}.
drain_stream_values(App, Model, Tag, Values, Depth, Max_depth, Events) ->
case Values of
[] ->
{Model, Events};
[Value | Rest] ->
{Model@1, Events@1} = dispatch_stream_value(
App,
Model,
Tag,
Value,
Depth,
Max_depth,
Events
),
drain_stream_values(
App,
Model@1,
Tag,
Rest,
Depth,
Max_depth,
Events@1
)
end.