Current section

Files

Jump to
white_bread lib white_bread.ex
Raw

lib/white_bread.ex

defmodule WhiteBread do
alias WhiteBread.Runners.FeatureRunner
# Features are capped to one hour. In practise the scenario's should be
# controlling the time out
@max_feature_run_time 1000 * 60 * 60
def run(context, path, options \\ []) do
tags = options |> Keyword.get(:tags)
async = options |> Keyword.get(:async, false)
roles = options |> Keyword.get(:roles)
features = path
|> WhiteBread.Feature.Finder.find_in_path
|> read_in_feature_files
|> parse_features
|> filter_features(tags: tags, roles: roles)
results = features
|> run_all_features(context, async: async)
|> results_as_map
|> output_result
results
end
defp results_as_map(results) do
%{
successes: results |> Enum.filter(&feature_success?/1),
failures: results |> Enum.filter(&feature_failure?/1)
}
end
defp output_result(result_map) do
WhiteBread.Outputer.report({:final_results, result_map})
result_map
end
defp read_in_feature_files(file_paths) do
file_paths |> Stream.map(&({&1, File.read!(&1)}))
end
defp parse_features(feature_texts) do
feature_texts
|> Enum.map(&parse_task/1)
|> Enum.map(&Task.await/1)
end
defp parse_task({file_name, feature_text}) do
Task.async(fn -> Gherkin.Parser.parse_feature(feature_text, file_name) end)
end
defp filter_features(features, tags: tags, roles: roles) do
features
|> filter_features_with_roles(roles)
|> filter_features_with_tags(tags)
end
defp filter_features_with_tags(features, nil), do: features
defp filter_features_with_tags(features, tags) do
features
|> WhiteBread.Tags.FeatureFilterer.get_for_tags(tags)
end
defp filter_features_with_roles(features, nil), do: features
defp filter_features_with_roles(features, roles) do
features
|> WhiteBread.Roles.FeatureFilterer.get_for_roles(roles)
end
defp run_all_features(features, context, async: true) do
features
|> Enum.map(&run_feature_async(&1, context))
|> Enum.map(&Task.await(&1, @max_feature_run_time))
end
defp run_all_features(features, context, async: false) do
features
|> Enum.map(&run_feature(&1, context))
end
defp run_feature(feature, context) do
{feature, FeatureRunner.run(feature, context, async: false)}
end
defp run_feature_async(feature, context) do
Task.async fn ->
{feature, FeatureRunner.run(feature, context, async: true)}
end
end
defp feature_success?({_feature, %{failures: failures}}) do
failures == []
end
defp feature_failure?({_feature, %{failures: failures}}) do
failures != []
end
end