Current section
Files
Jump to
Current section
Files
src/dream_test@gherkin@world.erl
-module(dream_test@gherkin@world).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream_test/gherkin/world.gleam").
-export([scenario_id/1, cleanup/1, put/3, get/2, get_or/3, has/2, delete/2, new_world/1]).
-export_type([world/0, ets_table/0]).
-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(
" Scenario state management for Gherkin tests.\n"
"\n"
" Each scenario gets its own World instance for storing state between steps.\n"
" The World is automatically created before a scenario runs and cleaned up after.\n"
"\n"
" ## How It Works\n"
"\n"
" The World uses ETS (Erlang Term Storage) for mutable storage with process\n"
" isolation. Each scenario gets a unique table that's cleaned up automatically.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" fn have_items(context: StepContext) -> AssertionResult {\n"
" case get_int(context.captures, 0) {\n"
" Ok(count) -> {\n"
" world.put(context.world, \"cart_count\", count)\n"
" AssertionOk\n"
" }\n"
" Error(msg) -> fail_with(msg)\n"
" }\n"
" }\n"
"\n"
" fn check_total(context: StepContext) -> AssertionResult {\n"
" case world.get(context.world, \"cart_count\") {\n"
" Ok(count) -> {\n"
" count\n"
" |> should()\n"
" |> equal(expected)\n"
" |> or_fail_with(\"Cart count mismatch\")\n"
" }\n"
" Error(_) -> fail_with(\"Cart not found in world\")\n"
" }\n"
" }\n"
" ```\n"
"\n"
" ## Type Safety\n"
"\n"
" The World stores values dynamically. When retrieving values, you're\n"
" responsible for ensuring type consistency:\n"
"\n"
" ```gleam\n"
" // Store an Int\n"
" world.put(world, \"count\", 42)\n"
"\n"
" // Retrieve as Int - caller ensures type matches\n"
" case world.get(world, \"count\") {\n"
" Ok(count) -> use_count(count) // count is inferred from usage\n"
" Error(_) -> handle_missing()\n"
" }\n"
" ```\n"
).
-opaque world() :: {world, binary(), ets_table()}.
-type ets_table() :: any().
-file("src/dream_test/gherkin/world.gleam", 248).
?DOC(
" Get the scenario ID for this World.\n"
"\n"
" Useful for debugging and logging.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to query\n"
"\n"
" ## Returns\n"
"\n"
" The scenario ID string.\n"
).
-spec scenario_id(world()) -> binary().
scenario_id(World) ->
erlang:element(2, World).
-file("src/dream_test/gherkin/world.gleam", 105).
?DOC(
" Clean up the World after a scenario completes.\n"
"\n"
" Called automatically by the runner after each scenario.\n"
" Deletes the ETS table and frees resources.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to clean up\n"
).
-spec cleanup(world()) -> nil.
cleanup(World) ->
dream_test_gherkin_world_ffi:delete_table(erlang:element(3, World)).
-file("src/dream_test/gherkin/world.gleam", 132).
?DOC(
" Store a value in the World.\n"
"\n"
" Stores any value by string key. If the key already exists,\n"
" the value is replaced.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to store in\n"
" - `key`: String key for the value\n"
" - `value`: Any value to store\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" world.put(world, \"user\", User(name: \"Alice\", age: 30))\n"
" world.put(world, \"count\", 42)\n"
" world.put(world, \"items\", [\"apple\", \"banana\"])\n"
" ```\n"
).
-spec put(world(), binary(), any()) -> nil.
put(World, Key, Value) ->
dream_test_gherkin_world_ffi:insert(erlang:element(3, World), Key, Value).
-file("src/dream_test/gherkin/world.gleam", 160).
?DOC(
" Retrieve a value from the World.\n"
"\n"
" Returns `Ok(value)` if the key exists, `Error(Nil)` if not found.\n"
" The caller is responsible for ensuring type consistency.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to query\n"
" - `key`: String key to look up\n"
"\n"
" ## Returns\n"
"\n"
" - `Ok(value)`: Key exists, returns the stored value\n"
" - `Error(Nil)`: Key doesn't exist\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" case world.get(world, \"user\") {\n"
" Ok(user) -> process_user(user)\n"
" Error(_) -> handle_missing()\n"
" }\n"
" ```\n"
).
-spec get(world(), binary()) -> {ok, any()} | {error, nil}.
get(World, Key) ->
case dream_test_gherkin_world_ffi:lookup(erlang:element(3, World), Key) of
{some, Value} ->
{ok, Value};
none ->
{error, nil}
end.
-file("src/dream_test/gherkin/world.gleam", 185).
?DOC(
" Retrieve a value or return a default.\n"
"\n"
" Convenience function that returns the stored value if the key exists,\n"
" or the provided default if not found.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to query\n"
" - `key`: String key to look up\n"
" - `default`: Default value to return if key not found\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let count = world.get_or(world, \"count\", 0)\n"
" let items = world.get_or(world, \"items\", [])\n"
" ```\n"
).
-spec get_or(world(), binary(), GZV) -> GZV.
get_or(World, Key, Default) ->
case get(World, Key) of
{ok, Value} ->
Value;
{error, _} ->
Default
end.
-file("src/dream_test/gherkin/world.gleam", 210).
?DOC(
" Check if a key exists in the World.\n"
"\n"
" Returns `True` if the key exists, `False` otherwise.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to query\n"
" - `key`: String key to check\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" case world.has(world, \"user\") {\n"
" True -> io.println(\"User exists\")\n"
" False -> io.println(\"User not found\")\n"
" }\n"
" ```\n"
).
-spec has(world(), binary()) -> boolean().
has(World, Key) ->
case dream_test_gherkin_world_ffi:lookup(erlang:element(3, World), Key) of
{some, _} ->
true;
none ->
false
end.
-file("src/dream_test/gherkin/world.gleam", 232).
?DOC(
" Delete a key from the World.\n"
"\n"
" Removes a key-value pair. If the key doesn't exist, this is a no-op.\n"
"\n"
" ## Parameters\n"
"\n"
" - `world`: The World to modify\n"
" - `key`: String key to delete\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" world.delete(world, \"temporary_data\")\n"
" ```\n"
).
-spec delete(world(), binary()) -> nil.
delete(World, Key) ->
dream_test_gherkin_world_ffi:delete_key(erlang:element(3, World), Key).
-file("src/dream_test/gherkin/world.gleam", 90).
?DOC(
" Create a new World for a scenario.\n"
"\n"
" Called automatically by the runner before each scenario.\n"
" Each World gets a unique ETS table for isolated storage.\n"
"\n"
" ## Parameters\n"
"\n"
" - `scenario_id`: Unique identifier for the scenario\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let world = new_world(\"shopping_cart::adding_items\")\n"
" ```\n"
).
-spec new_world(binary()) -> world().
new_world(Scenario_id) ->
Table_name = <<<<<<"gherkin_world_"/utf8, Scenario_id/binary>>/binary,
"_"/utf8>>/binary,
(dream_test_gherkin_world_ffi:unique_id())/binary>>,
Table = dream_test_gherkin_world_ffi:create_table(Table_name),
{world, Scenario_id, Table}.