-module(lightspeed@ops@template_harness).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/ops/template_harness.gleam").
-export([run_scenario/1, run_matrix/0, scenario_label/1, pass_fail_label/1, signature/1, scenario/1, outcomes/1, failed_scenarios/1, report_signature/1]).
-export_type([card_assigns/0, card_slots/0, scenario/0, scenario_outcome/0, report/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(" Deterministic M23 template compiler conformance harness.\n").
-type card_assigns() :: {card_assigns, binary(), boolean()}.
-type card_slots() :: {card_slots, binary(), binary()}.
-type scenario() :: compile_success |
missing_assign_diagnostic |
missing_slot_diagnostic |
invalid_attr_type_diagnostic.
-type scenario_outcome() :: {scenario_outcome, scenario(), boolean(), binary()}.
-type report() :: {report, list(scenario_outcome()), integer()}.
-file("src/lightspeed/ops/template_harness.gleam", 283).
-spec count_failed(list(scenario_outcome())) -> integer().
count_failed(Outcomes) ->
case Outcomes of
[] ->
0;
[Outcome | Rest] ->
case erlang:element(3, Outcome) of
true ->
count_failed(Rest);
false ->
1 + count_failed(Rest)
end
end.
-file("src/lightspeed/ops/template_harness.gleam", 294).
-spec bool_to_string(boolean()) -> binary().
bool_to_string(Value) ->
case Value of
true ->
<<"true"/utf8>>;
false ->
<<"false"/utf8>>
end.
-file("src/lightspeed/ops/template_harness.gleam", 232).
-spec card_component() -> fun((card_assigns(), card_slots()) -> lightspeed@component:rendered()).
card_component() ->
lightspeed@component@template:function(
fun(Assigns, Slots) ->
lightspeed@component:html(
<<<<<<<<<<<<<<<<"<article data-highlighted=\""/utf8,
(bool_to_string(
erlang:element(3, Assigns)
))/binary>>/binary,
"\"><h1>"/utf8>>/binary,
(erlang:element(2, Assigns))/binary>>/binary,
"</h1><section>"/utf8>>/binary,
(erlang:element(2, Slots))/binary>>/binary,
"</section><footer>"/utf8>>/binary,
(erlang:element(3, Slots))/binary>>/binary,
"</footer></article>"/utf8>>
)
end
).
-file("src/lightspeed/ops/template_harness.gleam", 263).
-spec compile_card_slots(list({binary(), lightspeed@component:rendered()})) -> {ok,
card_slots()} |
{error, binary()}.
compile_card_slots(Slots) ->
case {lightspeed@component@template_compiler:require_slot(
Slots,
<<"body"/utf8>>
),
lightspeed@component@template_compiler:slot_rendered(
Slots,
<<"footer"/utf8>>
)} of
{{ok, Body}, {some, Footer}} ->
{ok,
{card_slots,
lightspeed@component:to_html(Body),
lightspeed@component:to_html(Footer)}};
{{ok, Body@1}, _} ->
{ok,
{card_slots, lightspeed@component:to_html(Body@1), <<""/utf8>>}};
{{error, Reason}, _} ->
{error, Reason}
end.
-file("src/lightspeed/ops/template_harness.gleam", 248).
-spec compile_card_assigns(
list({binary(), lightspeed@component@template_compiler:attr_value()})
) -> {ok, card_assigns()} | {error, binary()}.
compile_card_assigns(Attrs) ->
case {lightspeed@component@template_compiler:require_string(
Attrs,
<<"title"/utf8>>
),
lightspeed@component@template_compiler:require_bool(
Attrs,
<<"highlighted"/utf8>>
)} of
{{ok, Title}, {ok, Highlighted}} ->
{ok, {card_assigns, Title, Highlighted}};
{{error, Reason}, _} ->
{error, Reason};
{_, {error, Reason@1}} ->
{error, Reason@1}
end.
-file("src/lightspeed/ops/template_harness.gleam", 215).
-spec card_schema() -> lightspeed@component@template_compiler:schema(card_assigns(), card_slots()).
card_schema() ->
lightspeed@component@template_compiler:schema(
<<"card"/utf8>>,
[lightspeed@component@template_compiler:required_string(
<<"title"/utf8>>
),
lightspeed@component@template_compiler:optional_bool(
<<"highlighted"/utf8>>,
{some, false}
)],
[lightspeed@component@template_compiler:required_slot(<<"body"/utf8>>),
lightspeed@component@template_compiler:optional_slot(
<<"footer"/utf8>>
)],
fun compile_card_assigns/1,
fun compile_card_slots/1,
card_component()
).
-file("src/lightspeed/ops/template_harness.gleam", 187).
-spec scenario_invalid_attr_type() -> scenario_outcome().
scenario_invalid_attr_type() ->
Result = lightspeed@component@template_compiler:compile(
card_schema(),
[{<<"title"/utf8>>, {int_attr, 9}}],
[{<<"body"/utf8>>, lightspeed@component:html(<<"<p>x</p>"/utf8>>)}]
),
case Result of
{ok, Compiled} ->
{scenario_outcome,
invalid_attr_type_diagnostic,
false,
lightspeed@component@template_compiler:signature(Compiled)};
{error, Diagnostics} ->
Signature = lightspeed@component@template_compiler:diagnostics_signature(
Diagnostics
),
{scenario_outcome,
invalid_attr_type_diagnostic,
Signature =:= <<"invalid_attribute_type:card:title:expected=string:actual=int"/utf8>>,
Signature}
end.
-file("src/lightspeed/ops/template_harness.gleam", 160).
-spec scenario_missing_slot() -> scenario_outcome().
scenario_missing_slot() ->
Result = lightspeed@component@template_compiler:compile(
card_schema(),
[{<<"title"/utf8>>, {string_attr, <<"Inbox"/utf8>>}}],
[]
),
case Result of
{ok, Compiled} ->
{scenario_outcome,
missing_slot_diagnostic,
false,
lightspeed@component@template_compiler:signature(Compiled)};
{error, Diagnostics} ->
Signature = lightspeed@component@template_compiler:diagnostics_signature(
Diagnostics
),
{scenario_outcome,
missing_slot_diagnostic,
Signature =:= <<"missing_slot:card:body"/utf8>>,
Signature}
end.
-file("src/lightspeed/ops/template_harness.gleam", 137).
-spec scenario_missing_assign() -> scenario_outcome().
scenario_missing_assign() ->
Result = lightspeed@component@template_compiler:compile(
card_schema(),
[],
[]
),
case Result of
{ok, Compiled} ->
{scenario_outcome,
missing_assign_diagnostic,
false,
lightspeed@component@template_compiler:signature(Compiled)};
{error, Diagnostics} ->
Signature = lightspeed@component@template_compiler:diagnostics_signature(
Diagnostics
),
{scenario_outcome,
missing_assign_diagnostic,
Signature =:= <<"missing_attribute:card:title;missing_slot:card:body"/utf8>>,
Signature}
end.
-file("src/lightspeed/ops/template_harness.gleam", 111).
-spec scenario_compile_success() -> scenario_outcome().
scenario_compile_success() ->
Result = lightspeed@component@template_compiler:compile(
card_schema(),
[{<<"title"/utf8>>, {string_attr, <<"Inbox"/utf8>>}}],
[{<<"body"/utf8>>,
lightspeed@component:html(<<"<p>3 notifications</p>"/utf8>>)}]
),
case Result of
{ok, Compiled} ->
{scenario_outcome,
compile_success,
lightspeed@component@template_compiler:html(Compiled) =:= <<"<article data-highlighted=\"false\"><h1>Inbox</h1><section><p>3 notifications</p></section><footer></footer></article>"/utf8>>,
lightspeed@component@template_compiler:signature(Compiled)};
{error, Diagnostics} ->
{scenario_outcome,
compile_success,
false,
lightspeed@component@template_compiler:diagnostics_signature(
Diagnostics
)}
end.
-file("src/lightspeed/ops/template_harness.gleam", 50).
?DOC(" Run one M23 scenario.\n").
-spec run_scenario(scenario()) -> scenario_outcome().
run_scenario(Scenario) ->
case Scenario of
compile_success ->
scenario_compile_success();
missing_assign_diagnostic ->
scenario_missing_assign();
missing_slot_diagnostic ->
scenario_missing_slot();
invalid_attr_type_diagnostic ->
scenario_invalid_attr_type()
end.
-file("src/lightspeed/ops/template_harness.gleam", 36).
?DOC(" Run all M23 conformance scenarios.\n").
-spec run_matrix() -> report().
run_matrix() ->
Outcomes = begin
_pipe = [compile_success,
missing_assign_diagnostic,
missing_slot_diagnostic,
invalid_attr_type_diagnostic],
gleam@list:map(_pipe, fun run_scenario/1)
end,
{report, Outcomes, count_failed(Outcomes)}.
-file("src/lightspeed/ops/template_harness.gleam", 60).
?DOC(" Scenario label.\n").
-spec scenario_label(scenario()) -> binary().
scenario_label(Scenario) ->
case Scenario of
compile_success ->
<<"compile_success"/utf8>>;
missing_assign_diagnostic ->
<<"missing_assign_diagnostic"/utf8>>;
missing_slot_diagnostic ->
<<"missing_slot_diagnostic"/utf8>>;
invalid_attr_type_diagnostic ->
<<"invalid_attr_type_diagnostic"/utf8>>
end.
-file("src/lightspeed/ops/template_harness.gleam", 70).
?DOC(" Pass/fail label.\n").
-spec pass_fail_label(scenario_outcome()) -> binary().
pass_fail_label(Outcome) ->
case erlang:element(3, Outcome) of
true ->
<<"pass"/utf8>>;
false ->
<<"fail"/utf8>>
end.
-file("src/lightspeed/ops/template_harness.gleam", 78).
?DOC(" Scenario signature.\n").
-spec signature(scenario_outcome()) -> binary().
signature(Outcome) ->
erlang:element(4, Outcome).
-file("src/lightspeed/ops/template_harness.gleam", 83).
?DOC(" Scenario accessor.\n").
-spec scenario(scenario_outcome()) -> scenario().
scenario(Outcome) ->
erlang:element(2, Outcome).
-file("src/lightspeed/ops/template_harness.gleam", 88).
?DOC(" Outcomes accessor.\n").
-spec outcomes(report()) -> list(scenario_outcome()).
outcomes(Report) ->
erlang:element(2, Report).
-file("src/lightspeed/ops/template_harness.gleam", 93).
?DOC(" Failed scenario count.\n").
-spec failed_scenarios(report()) -> integer().
failed_scenarios(Report) ->
erlang:element(3, Report).
-file("src/lightspeed/ops/template_harness.gleam", 301).
-spec join_with(binary(), list(binary())) -> binary().
join_with(Separator, Values) ->
case Values of
[] ->
<<""/utf8>>;
[Value] ->
Value;
[Value@1 | Rest] ->
<<<<Value@1/binary, Separator/binary>>/binary,
(join_with(Separator, Rest))/binary>>
end.
-file("src/lightspeed/ops/template_harness.gleam", 98).
?DOC(" Stable report signature.\n").
-spec report_signature(report()) -> binary().
report_signature(Report) ->
Entries = gleam@list:map(
erlang:element(2, Report),
fun(Outcome) ->
<<<<<<<<(scenario_label(erlang:element(2, Outcome)))/binary,
"="/utf8>>/binary,
(pass_fail_label(Outcome))/binary>>/binary,
":"/utf8>>/binary,
(erlang:element(4, Outcome))/binary>>
end
),
join_with(<<";"/utf8>>, Entries).