Current section

Files

Jump to
dream_test src dream_test@gherkin@discover.erl
Raw

src/dream_test@gherkin@discover.erl

-module(dream_test@gherkin@discover).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream_test/gherkin/discover.gleam").
-export([features/1, with_registry/2, to_suite/2, load/1, list_files/1]).
-export_type([feature_discovery/0, load_result/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(
" Feature discovery and loading for Gherkin tests.\n"
"\n"
" Provides a builder pattern for discovering `.feature` files and\n"
" converting them to TestSuites without manual file parsing.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import dream_test/gherkin/discover\n"
" import dream_test/gherkin/steps.{new_registry, step}\n"
" import dream_test/runner\n"
"\n"
" pub fn main() {\n"
" let steps = new_registry()\n"
" |> step(\"I have {int} items\", have_items)\n"
" |> step(\"I add {int} items\", add_items)\n"
"\n"
" discover.features(\"features/*.feature\")\n"
" |> discover.with_registry(steps)\n"
" |> discover.to_suite(\"my_features\")\n"
" |> runner.run_suite()\n"
" }\n"
" ```\n"
"\n"
" ## Glob Patterns\n"
"\n"
" Uses Erlang's `filelib:wildcard/1` for pattern matching:\n"
"\n"
" - `features/*.feature` — all `.feature` files in `features/`\n"
" - `test/**/*.feature` — recursive search in `test/`\n"
" - `*.feature` — all `.feature` files in current directory\n"
"\n"
).
-opaque feature_discovery() :: {feature_discovery,
binary(),
gleam@option:option(dream_test@gherkin@steps:step_registry()),
list(dream_test@gherkin@types:feature()),
list(binary())}.
-type load_result() :: {load_result,
list(dream_test@gherkin@types:feature()),
list(binary())}.
-file("src/dream_test/gherkin/discover.gleam", 98).
?DOC(
" Start discovering features matching a glob pattern.\n"
"\n"
" ## Parameters\n"
"\n"
" - `pattern`: Glob pattern for `.feature` files\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" discover.features(\"features/**/*.feature\")\n"
" |> discover.with_registry(steps)\n"
" |> discover.to_suite(\"my_tests\")\n"
" ```\n"
).
-spec features(binary()) -> feature_discovery().
features(Pattern) ->
{feature_discovery, Pattern, none, [], []}.
-file("src/dream_test/gherkin/discover.gleam", 111).
?DOC(
" Attach a step registry to the discovery.\n"
"\n"
" The registry contains all step definitions needed to execute the features.\n"
"\n"
" ## Parameters\n"
"\n"
" - `discovery`: The feature discovery builder\n"
" - `registry`: Step registry with step definitions\n"
).
-spec with_registry(
feature_discovery(),
dream_test@gherkin@steps:step_registry()
) -> feature_discovery().
with_registry(Discovery, Registry) ->
{feature_discovery,
erlang:element(2, Discovery),
{some, Registry},
erlang:element(4, Discovery),
erlang:element(5, Discovery)}.
-file("src/dream_test/gherkin/discover.gleam", 223).
-spec parse_feature_file(binary()) -> {ok, dream_test@gherkin@types:feature()} |
{error, binary()}.
parse_feature_file(Path) ->
_pipe = dream_test@gherkin@parser:parse_file(Path),
gleam@result:map_error(
_pipe,
fun(E) -> <<<<Path/binary, ": "/utf8>>/binary, E/binary>> end
).
-file("src/dream_test/gherkin/discover.gleam", 202).
-spec load_all_features(list(binary())) -> load_result().
load_all_features(Files) ->
Results = gleam@list:map(Files, fun parse_feature_file/1),
Features = begin
_pipe = Results,
gleam@list:filter_map(_pipe, fun(R) -> case R of
{ok, F} ->
{ok, F};
{error, _} ->
{error, nil}
end end)
end,
Errors = begin
_pipe@1 = Results,
gleam@list:filter_map(_pipe@1, fun(R@1) -> case R@1 of
{ok, _} ->
{error, nil};
{error, E} ->
{ok, E}
end end)
end,
{load_result, Features, Errors}.
-file("src/dream_test/gherkin/discover.gleam", 247).
-spec parse_error_runner() -> dream_test@types:assertion_result().
parse_error_runner() ->
{assertion_failed,
{assertion_failure,
<<"parse"/utf8>>,
<<"Failed to parse feature file (see test name for details)"/utf8>>,
none}}.
-file("src/dream_test/gherkin/discover.gleam", 228).
-spec error_to_suite_item(binary()) -> dream_test@types:test_suite_item().
error_to_suite_item(Error) ->
Error_test = {test_case,
{single_test_config,
<<"Parse Error: "/utf8, Error/binary>>,
[<<"Parse Error"/utf8>>, Error],
[<<"parse-error"/utf8>>],
unit,
fun parse_error_runner/0,
none,
[],
[]}},
{suite_test, Error_test}.
-file("src/dream_test/gherkin/discover.gleam", 198).
-spec discover_files(binary()) -> list(binary()).
discover_files(Pattern) ->
dream_test_gherkin_discover_ffi:wildcard(Pattern).
-file("src/dream_test/gherkin/discover.gleam", 137).
?DOC(
" Build a TestSuite from discovered features.\n"
"\n"
" Discovers all matching files, parses them, and creates a combined TestSuite.\n"
" Parse errors are collected but don't prevent other features from running.\n"
"\n"
" ## Parameters\n"
"\n"
" - `discovery`: The configured feature discovery\n"
" - `suite_name`: Name for the combined test suite\n"
"\n"
" ## Returns\n"
"\n"
" A TestSuite containing all successfully parsed features.\n"
" If there are parse errors, they're reported as failed tests.\n"
"\n"
" ## Panics\n"
"\n"
" Panics if `with_registry()` was not called.\n"
).
-spec to_suite(feature_discovery(), binary()) -> dream_test@types:test_suite().
to_suite(Discovery, Suite_name) ->
Registry = case erlang:element(3, Discovery) of
{some, R} ->
R;
none ->
erlang:error(#{gleam_error => panic,
message => <<"FeatureDiscovery requires a registry. Call with_registry() first."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"dream_test/gherkin/discover"/utf8>>,
function => <<"to_suite"/utf8>>,
line => 141})
end,
Files = discover_files(erlang:element(2, Discovery)),
Load_result = load_all_features(Files),
Suite_items = gleam@list:map(
erlang:element(2, Load_result),
fun(Feature) ->
Config = {feature_config, Feature, Registry},
Feature_suite = dream_test@gherkin@feature:to_test_suite(
Suite_name,
Config
),
{suite_group, Feature_suite}
end
),
Error_items = gleam@list:map(
erlang:element(3, Load_result),
fun error_to_suite_item/1
),
All_items = lists:append(Suite_items, Error_items),
{test_suite, Suite_name, [Suite_name], [], [], All_items}.
-file("src/dream_test/gherkin/discover.gleam", 181).
?DOC(
" Load features and return detailed results.\n"
"\n"
" Use this when you need access to parse errors for custom handling.\n"
"\n"
" ## Parameters\n"
"\n"
" - `discovery`: The feature discovery builder\n"
"\n"
" ## Returns\n"
"\n"
" LoadResult with lists of successfully parsed features and errors.\n"
).
-spec load(feature_discovery()) -> load_result().
load(Discovery) ->
Files = discover_files(erlang:element(2, Discovery)),
load_all_features(Files).
-file("src/dream_test/gherkin/discover.gleam", 190).
?DOC(
" Get the list of files matching the discovery pattern.\n"
"\n"
" Useful for debugging or custom file handling.\n"
).
-spec list_files(feature_discovery()) -> list(binary()).
list_files(Discovery) ->
discover_files(erlang:element(2, Discovery)).