-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}.