diff options
author | HJ <thechairman@thechairman.info> | 2024-02-03 15:10:00 -0500 |
---|---|---|
committer | HJ <thechairman@thechairman.info> | 2024-02-03 15:10:00 -0500 |
commit | 0c869b2782aeecb92dff232b46a499a3821f9f2c (patch) | |
tree | 8010032bf495ad120a4d586a7a96ebc9139e3f32 /aoc2023/build/packages/adglent/src | |
parent | 96a3c5c179d8d3fff24eb2953e45f8dd15e2714c (diff) | |
download | gleam_aoc-0c869b2782aeecb92dff232b46a499a3821f9f2c.tar.gz gleam_aoc-0c869b2782aeecb92dff232b46a499a3821f9f2c.zip |
cleanup
Diffstat (limited to 'aoc2023/build/packages/adglent/src')
59 files changed, 0 insertions, 5440 deletions
diff --git a/aoc2023/build/packages/adglent/src/adglent.app.src b/aoc2023/build/packages/adglent/src/adglent.app.src deleted file mode 100644 index aa44f8b..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.app.src +++ /dev/null @@ -1,45 +0,0 @@ -{application, adglent, [ - {vsn, "1.2.0"}, - {applications, [gap, - gleam_community_ansi, - gleam_erlang, - gleam_http, - gleam_httpc, - gleam_otp, - gleam_stdlib, - gleeunit, - glint, - simplifile, - snag, - tom]}, - {description, "Advent of code helper - automating setup of tests, solution template and problem input"}, - {modules, [adglent, - adglent@day, - adglent@init, - priv@aoc_client, - priv@errors, - priv@prompt, - priv@template, - priv@templates@solution, - priv@templates@test_main, - priv@templates@testfile_gleeunit, - priv@templates@testfile_showtime, - priv@toml, - showtime, - showtime@internal@common@cli, - showtime@internal@common@common_event_handler, - showtime@internal@common@test_result, - showtime@internal@common@test_suite, - showtime@internal@erlang@discover, - showtime@internal@erlang@event_handler, - showtime@internal@erlang@module_handler, - showtime@internal@erlang@runner, - showtime@internal@reports@compare, - showtime@internal@reports@formatter, - showtime@internal@reports@styles, - showtime@internal@reports@table, - showtime@tests@meta, - showtime@tests@should, - showtime@tests@test]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/adglent/src/adglent.erl b/aoc2023/build/packages/adglent/src/adglent.erl deleted file mode 100644 index e9df2b7..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.erl +++ /dev/null @@ -1,55 +0,0 @@ --module(adglent). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([inspect/1, get_input/1, get_test_folder/1, start_arguments/0, get_part/0]). --export_type([example/1, problem/0, charlist/0]). - --type example(OFF) :: {example, binary(), OFF}. - --type problem() :: first | second. - --type charlist() :: any(). - --spec inspect(any()) -> binary(). -inspect(Value) -> - Inspected_value = gleam@string:inspect(Value), - case begin - _pipe = Inspected_value, - gleam@string:starts_with(_pipe, <<"\""/utf8>>) - end of - true -> - _pipe@1 = Inspected_value, - _pipe@2 = gleam@string:drop_left(_pipe@1, 1), - gleam@string:drop_right(_pipe@2, 1); - - false -> - Inspected_value - end. - --spec get_input(binary()) -> {ok, binary()} | {error, simplifile:file_error()}. -get_input(Day) -> - simplifile:read( - <<<<"src/day"/utf8, Day/binary>>/binary, "/input.txt"/utf8>> - ). - --spec get_test_folder(binary()) -> binary(). -get_test_folder(Day) -> - <<"test/day"/utf8, Day/binary>>. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun unicode:characters_to_binary/1). - --spec get_part() -> {ok, problem()} | {error, nil}. -get_part() -> - case start_arguments() of - [<<"1"/utf8>>] -> - {ok, first}; - - [<<"2"/utf8>>] -> - {ok, second}; - - _ -> - {error, nil} - end. diff --git a/aoc2023/build/packages/adglent/src/adglent.gleam b/aoc2023/build/packages/adglent/src/adglent.gleam deleted file mode 100644 index 077d49d..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.gleam +++ /dev/null @@ -1,56 +0,0 @@ -import simplifile.{type FileError} -import gleam/list -import gleam/string - -pub type Example(a) { - Example(input: String, answer: a) -} - -pub fn inspect(value: a) -> String { - let inspected_value = string.inspect(value) - case - inspected_value - |> string.starts_with("\"") - { - True -> - inspected_value - |> string.drop_left(1) - |> string.drop_right(1) - False -> inspected_value - } -} - -pub fn get_input(day: String) -> Result(String, FileError) { - simplifile.read("src/day" <> day <> "/input.txt") -} - -pub fn get_test_folder(day: String) -> String { - "test/day" <> day -} - -pub type Problem { - First - Second -} - -pub fn get_part() -> Result(Problem, Nil) { - case start_arguments() { - ["1"] -> Ok(First) - ["2"] -> Ok(Second) - _ -> Error(Nil) - } -} - -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(to_string) -} - -type Charlist - -/// Transform a charlist to a string -@external(erlang, "unicode", "characters_to_binary") -fn to_string(a: Charlist) -> String - -@external(erlang, "init", "get_plain_arguments") -fn get_start_arguments() -> List(Charlist) diff --git a/aoc2023/build/packages/adglent/src/adglent/day.gleam b/aoc2023/build/packages/adglent/src/adglent/day.gleam deleted file mode 100644 index 69e4ccc..0000000 --- a/aoc2023/build/packages/adglent/src/adglent/day.gleam +++ /dev/null @@ -1,126 +0,0 @@ -import adglent -import gleam/string -import gleam/result -import priv/template -import priv/templates/testfile_gleeunit -import priv/templates/testfile_showtime -import priv/templates/solution -import priv/toml -import priv/aoc_client -import priv/errors -import simplifile - -pub fn main() { - let day = - case adglent.start_arguments() { - [day] -> Ok(day) - args -> Error("Expected day - found: " <> string.join(args, ", ")) - } - |> errors.map_error("Error when parsing command args") - |> errors.print_error - |> errors.assert_ok - - let aoc_toml = - simplifile.read("aoc.toml") - |> errors.map_error("Could not read aoc.toml") - |> errors.print_error - |> errors.assert_ok - - let aoc_toml_version = toml.get_int(aoc_toml, ["version"]) - let year = - toml.get_string(aoc_toml, ["year"]) - |> errors.map_error("Could not read \"year\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - let session = - toml.get_string(aoc_toml, ["session"]) - |> errors.map_error("Could not read \"session\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - - let showtime = case aoc_toml_version { - Ok(2) -> { - toml.get_bool(aoc_toml, ["showtime"]) - |> errors.map_error("Could not read \"showtime\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - } - _ -> - toml.get_string(aoc_toml, ["showtime"]) - |> result.map(fn(bool_string) { - case bool_string { - "True" -> True - _ -> False - } - }) - |> errors.map_error("Could not read \"showtime\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - } - - let test_folder = adglent.get_test_folder(day) - let test_file = test_folder <> "/day" <> day <> "_test.gleam" - - simplifile.create_directory_all(test_folder) - |> errors.map_error("Could not create folder \"" <> test_folder <> "\"") - |> errors.print_error - |> errors.assert_ok - - let testfile_template = case showtime { - True -> testfile_showtime.template - False -> testfile_gleeunit.template - } - - template.render(testfile_template, [#("day", day)]) - |> create_file_if_not_present(test_file) - |> errors.print_result - |> errors.assert_ok - - let solutions_folder = "src/day" <> day - let solution_file = solutions_folder <> "/solve.gleam" - - simplifile.create_directory_all(solutions_folder) - |> errors.map_error("Could not create folder \"" <> solutions_folder <> "\"") - |> errors.print_error - |> errors.assert_ok - - template.render(solution.template, [#("day", day)]) - |> create_file_if_not_present(solution_file) - |> errors.print_result - |> errors.assert_ok - - create_file_if_not_present("input.txt", solutions_folder <> "/.gitignore") - |> errors.print_result - |> errors.assert_ok - - let input = - aoc_client.get_input(year, day, session) - |> errors.map_error("Error when fetching input") - |> errors.print_error - |> errors.assert_ok - - input - |> string.trim - |> create_file_if_not_present(solutions_folder <> "/input.txt") - |> errors.print_result - |> errors.assert_ok -} - -fn create_file_if_not_present( - content: String, - path: String, -) -> Result(String, String) { - case simplifile.is_file(path) { - True -> { - Ok(path <> " already exists - skipped") - } - False -> { - use _ <- result.try( - simplifile.create_file(path) - |> errors.map_messages("Created " <> path, "Could not create " <> path), - ) - simplifile.write(content, to: path) - |> errors.map_messages("Wrote " <> path, "Could not write to " <> path) - } - } -} diff --git a/aoc2023/build/packages/adglent/src/adglent/init.gleam b/aoc2023/build/packages/adglent/src/adglent/init.gleam deleted file mode 100644 index 42eb833..0000000 --- a/aoc2023/build/packages/adglent/src/adglent/init.gleam +++ /dev/null @@ -1,110 +0,0 @@ -import priv/prompt -import priv/template -import priv/templates/test_main -import priv/errors -import priv/toml -import simplifile -import gleam/string -import gleam/list -import gleam/result -import gleam/bool - -const aoc_toml_template = " -version = {{ version }} -year = \"{{ year }}\" -session = \"{{ session }}\" -showtime = {{ showtime }} -" - -pub fn main() { - let year = prompt.value("Year", "2023", False) - let session = prompt.value("Session Cookie", "", False) - let use_showtime = prompt.confirm("Use showtime", False) - - let aoc_toml_file = "aoc.toml" - let overwrite = case simplifile.create_file(aoc_toml_file) { - Ok(_) -> True - Error(simplifile.Eexist) -> - prompt.confirm("aoc.toml exits - overwrite", False) - _ -> panic as "Could not create aoc.toml" - } - case overwrite { - True -> { - template.render( - aoc_toml_template, - [ - #("version", "2"), - #("year", year), - #("session", session), - #( - "showtime", - bool.to_string(use_showtime) - |> string.lowercase, - ), - ], - ) - |> simplifile.write(to: aoc_toml_file) - |> errors.map_messages( - "aoc.toml - written", - "Error when writing aoc.toml", - ) - } - - False -> Ok("aoc.toml - skipped") - } - |> errors.print_result - - let gleam_toml = - simplifile.read("gleam.toml") - |> errors.map_error("Could not read gleam.toml") - |> errors.print_error - |> errors.assert_ok - - let name = - toml.get_string(gleam_toml, ["name"]) - |> errors.map_error("Could not read \"name\" from gleam.toml") - |> errors.print_error - |> errors.assert_ok - - let test_main_file = "test/" <> name <> "_test.gleam" - - case use_showtime { - True -> { - template.render(test_main.template, []) - |> simplifile.write(to: test_main_file) - |> errors.map_messages( - "Wrote " <> test_main_file, - "Could not write to " <> test_main_file, - ) - } - False -> Ok("Using existing (gleeunit) " <> test_main_file) - } - |> errors.print_result - |> errors.assert_ok - - case simplifile.is_file(".gitignore") { - True -> { - use gitignore <- result.try( - simplifile.read(".gitignore") - |> result.map_error(fn(err) { - "Could not read .gitignore: " <> string.inspect(err) - }), - ) - let aoc_toml_ignored = - string.split(gitignore, "\n") - |> list.find(fn(line) { line == "aoc.toml" }) - case aoc_toml_ignored { - Error(_) -> { - simplifile.append("\naoc.toml", to: ".gitignore") - |> errors.map_messages( - ".gitignore written", - "Error when writing .gitignore", - ) - } - Ok(_) -> Ok(".gitignore - skipped (already configured)") - } - } - False -> Error("Could not find .gitignore") - } - |> errors.print_result -} diff --git a/aoc2023/build/packages/adglent/src/adglent@day.erl b/aoc2023/build/packages/adglent/src/adglent@day.erl deleted file mode 100644 index b80368f..0000000 --- a/aoc2023/build/packages/adglent/src/adglent@day.erl +++ /dev/null @@ -1,278 +0,0 @@ --module(adglent@day). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec create_file_if_not_present(binary(), binary()) -> {ok, binary()} | - {error, binary()}. -create_file_if_not_present(Content, Path) -> - case simplifile:is_file(Path) of - true -> - {ok, <<Path/binary, " already exists - skipped"/utf8>>}; - - false -> - gleam@result:'try'( - begin - _pipe = simplifile:create_file(Path), - priv@errors:map_messages( - _pipe, - <<"Created "/utf8, Path/binary>>, - <<"Could not create "/utf8, Path/binary>> - ) - end, - fun(_) -> _pipe@1 = simplifile:write(Path, Content), - priv@errors:map_messages( - _pipe@1, - <<"Wrote "/utf8, Path/binary>>, - <<"Could not write to "/utf8, Path/binary>> - ) end - ) - end. - --spec main() -> binary(). -main() -> - Day@1 = begin - _pipe = case adglent:start_arguments() of - [Day] -> - {ok, Day}; - - Args -> - {error, - <<"Expected day - found: "/utf8, - (gleam@string:join(Args, <<", "/utf8>>))/binary>>} - end, - _pipe@1 = priv@errors:map_error( - _pipe, - <<"Error when parsing command args"/utf8>> - ), - _pipe@2 = priv@errors:print_error(_pipe@1), - priv@errors:assert_ok(_pipe@2) - end, - Aoc_toml = begin - _pipe@3 = simplifile:read(<<"aoc.toml"/utf8>>), - _pipe@4 = priv@errors:map_error( - _pipe@3, - <<"Could not read aoc.toml"/utf8>> - ), - _pipe@5 = priv@errors:print_error(_pipe@4), - priv@errors:assert_ok(_pipe@5) - end, - Aoc_toml_version = priv@toml:get_int(Aoc_toml, [<<"version"/utf8>>]), - Year = begin - _pipe@6 = priv@toml:get_string(Aoc_toml, [<<"year"/utf8>>]), - _pipe@7 = priv@errors:map_error( - _pipe@6, - <<"Could not read \"year\" from aoc.toml"/utf8>> - ), - _pipe@8 = priv@errors:print_error(_pipe@7), - priv@errors:assert_ok(_pipe@8) - end, - Session = begin - _pipe@9 = priv@toml:get_string(Aoc_toml, [<<"session"/utf8>>]), - _pipe@10 = priv@errors:map_error( - _pipe@9, - <<"Could not read \"session\" from aoc.toml"/utf8>> - ), - _pipe@11 = priv@errors:print_error(_pipe@10), - priv@errors:assert_ok(_pipe@11) - end, - Showtime = case Aoc_toml_version of - {ok, 2} -> - _pipe@12 = priv@toml:get_bool(Aoc_toml, [<<"showtime"/utf8>>]), - _pipe@13 = priv@errors:map_error( - _pipe@12, - <<"Could not read \"showtime\" from aoc.toml"/utf8>> - ), - _pipe@14 = priv@errors:print_error(_pipe@13), - priv@errors:assert_ok(_pipe@14); - - _ -> - _pipe@15 = priv@toml:get_string(Aoc_toml, [<<"showtime"/utf8>>]), - _pipe@16 = gleam@result:map( - _pipe@15, - fun(Bool_string) -> case Bool_string of - <<"True"/utf8>> -> - true; - - _ -> - false - end end - ), - _pipe@17 = priv@errors:map_error( - _pipe@16, - <<"Could not read \"showtime\" from aoc.toml"/utf8>> - ), - _pipe@18 = priv@errors:print_error(_pipe@17), - priv@errors:assert_ok(_pipe@18) - end, - Test_folder = adglent:get_test_folder(Day@1), - Test_file = <<<<<<Test_folder/binary, "/day"/utf8>>/binary, Day@1/binary>>/binary, - "_test.gleam"/utf8>>, - _pipe@19 = simplifile:create_directory_all(Test_folder), - _pipe@20 = priv@errors:map_error( - _pipe@19, - <<<<"Could not create folder \""/utf8, Test_folder/binary>>/binary, - "\""/utf8>> - ), - _pipe@21 = priv@errors:print_error(_pipe@20), - priv@errors:assert_ok(_pipe@21), - Testfile_template = case Showtime of - true -> - <<" -import gleam/list -import showtime/tests/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -"/utf8>>; - - false -> - <<" -import gleam/list -import gleeunit/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -"/utf8>> - end, - _pipe@22 = priv@template:render( - Testfile_template, - [{<<"day"/utf8>>, Day@1}] - ), - _pipe@23 = create_file_if_not_present(_pipe@22, Test_file), - _pipe@24 = priv@errors:print_result(_pipe@23), - priv@errors:assert_ok(_pipe@24), - Solutions_folder = <<"src/day"/utf8, Day@1/binary>>, - Solution_file = <<Solutions_folder/binary, "/solve.gleam"/utf8>>, - _pipe@25 = simplifile:create_directory_all(Solutions_folder), - _pipe@26 = priv@errors:map_error( - _pipe@25, - <<<<"Could not create folder \""/utf8, Solutions_folder/binary>>/binary, - "\""/utf8>> - ), - _pipe@27 = priv@errors:print_error(_pipe@26), - priv@errors:assert_ok(_pipe@27), - _pipe@28 = priv@template:render( - <<" -import adglent.{First, Second} -import gleam/io - -pub fn part1(input: String) { - todo as \"Implement solution to part 1\" -} - -pub fn part2(input: String) { - todo as \"Implement solution to part 2\" -} - -pub fn main() { - let assert Ok(part) = adglent.get_part() - let assert Ok(input) = adglent.get_input(\"{{ day }}\") - case part { - First -> - part1(input) - |> adglent.inspect - |> io.println - Second -> - part2(input) - |> adglent.inspect - |> io.println - } -} -"/utf8>>, - [{<<"day"/utf8>>, Day@1}] - ), - _pipe@29 = create_file_if_not_present(_pipe@28, Solution_file), - _pipe@30 = priv@errors:print_result(_pipe@29), - priv@errors:assert_ok(_pipe@30), - _pipe@31 = create_file_if_not_present( - <<"input.txt"/utf8>>, - <<Solutions_folder/binary, "/.gitignore"/utf8>> - ), - _pipe@32 = priv@errors:print_result(_pipe@31), - priv@errors:assert_ok(_pipe@32), - Input = begin - _pipe@33 = priv@aoc_client:get_input(Year, Day@1, Session), - _pipe@34 = priv@errors:map_error( - _pipe@33, - <<"Error when fetching input"/utf8>> - ), - _pipe@35 = priv@errors:print_error(_pipe@34), - priv@errors:assert_ok(_pipe@35) - end, - _pipe@36 = Input, - _pipe@37 = gleam@string:trim(_pipe@36), - _pipe@38 = create_file_if_not_present( - _pipe@37, - <<Solutions_folder/binary, "/input.txt"/utf8>> - ), - _pipe@39 = priv@errors:print_result(_pipe@38), - priv@errors:assert_ok(_pipe@39). diff --git a/aoc2023/build/packages/adglent/src/adglent@init.erl b/aoc2023/build/packages/adglent/src/adglent@init.erl deleted file mode 100644 index fb28101..0000000 --- a/aoc2023/build/packages/adglent/src/adglent@init.erl +++ /dev/null @@ -1,142 +0,0 @@ --module(adglent@init). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec main() -> {ok, binary()} | {error, binary()}. -main() -> - Year = priv@prompt:value(<<"Year"/utf8>>, <<"2023"/utf8>>, false), - Session = priv@prompt:value(<<"Session Cookie"/utf8>>, <<""/utf8>>, false), - Use_showtime = priv@prompt:confirm(<<"Use showtime"/utf8>>, false), - Aoc_toml_file = <<"aoc.toml"/utf8>>, - Overwrite = case simplifile:create_file(Aoc_toml_file) of - {ok, _} -> - true; - - {error, eexist} -> - priv@prompt:confirm(<<"aoc.toml exits - overwrite"/utf8>>, false); - - _ -> - erlang:error(#{gleam_error => panic, - message => <<"Could not create aoc.toml"/utf8>>, - module => <<"adglent/init"/utf8>>, - function => <<"main"/utf8>>, - line => 29}) - end, - _pipe@3 = case Overwrite of - true -> - _pipe@1 = priv@template:render( - <<" -version = {{ version }} -year = \"{{ year }}\" -session = \"{{ session }}\" -showtime = {{ showtime }} -"/utf8>>, - [{<<"version"/utf8>>, <<"2"/utf8>>}, - {<<"year"/utf8>>, Year}, - {<<"session"/utf8>>, Session}, - {<<"showtime"/utf8>>, - begin - _pipe = gleam@bool:to_string(Use_showtime), - gleam@string:lowercase(_pipe) - end}] - ), - _pipe@2 = simplifile:write(Aoc_toml_file, _pipe@1), - priv@errors:map_messages( - _pipe@2, - <<"aoc.toml - written"/utf8>>, - <<"Error when writing aoc.toml"/utf8>> - ); - - false -> - {ok, <<"aoc.toml - skipped"/utf8>>} - end, - priv@errors:print_result(_pipe@3), - Gleam_toml = begin - _pipe@4 = simplifile:read(<<"gleam.toml"/utf8>>), - _pipe@5 = priv@errors:map_error( - _pipe@4, - <<"Could not read gleam.toml"/utf8>> - ), - _pipe@6 = priv@errors:print_error(_pipe@5), - priv@errors:assert_ok(_pipe@6) - end, - Name = begin - _pipe@7 = priv@toml:get_string(Gleam_toml, [<<"name"/utf8>>]), - _pipe@8 = priv@errors:map_error( - _pipe@7, - <<"Could not read \"name\" from gleam.toml"/utf8>> - ), - _pipe@9 = priv@errors:print_error(_pipe@8), - priv@errors:assert_ok(_pipe@9) - end, - Test_main_file = <<<<"test/"/utf8, Name/binary>>/binary, - "_test.gleam"/utf8>>, - _pipe@12 = case Use_showtime of - true -> - _pipe@10 = priv@template:render( - <<" -import showtime - -pub fn main() { - showtime.main() -} -"/utf8>>, - [] - ), - _pipe@11 = simplifile:write(Test_main_file, _pipe@10), - priv@errors:map_messages( - _pipe@11, - <<"Wrote "/utf8, Test_main_file/binary>>, - <<"Could not write to "/utf8, Test_main_file/binary>> - ); - - false -> - {ok, <<"Using existing (gleeunit) "/utf8, Test_main_file/binary>>} - end, - _pipe@13 = priv@errors:print_result(_pipe@12), - priv@errors:assert_ok(_pipe@13), - _pipe@17 = case simplifile:is_file(<<".gitignore"/utf8>>) of - true -> - gleam@result:'try'( - begin - _pipe@14 = simplifile:read(<<".gitignore"/utf8>>), - gleam@result:map_error( - _pipe@14, - fun(Err) -> - <<"Could not read .gitignore: "/utf8, - (gleam@string:inspect(Err))/binary>> - end - ) - end, - fun(Gitignore) -> - Aoc_toml_ignored = begin - _pipe@15 = gleam@string:split(Gitignore, <<"\n"/utf8>>), - gleam@list:find( - _pipe@15, - fun(Line) -> Line =:= <<"aoc.toml"/utf8>> end - ) - end, - case Aoc_toml_ignored of - {error, _} -> - _pipe@16 = simplifile:append( - <<".gitignore"/utf8>>, - <<"\naoc.toml"/utf8>> - ), - priv@errors:map_messages( - _pipe@16, - <<".gitignore written"/utf8>>, - <<"Error when writing .gitignore"/utf8>> - ); - - {ok, _} -> - {ok, - <<".gitignore - skipped (already configured)"/utf8>>} - end - end - ); - - false -> - {error, <<"Could not find .gitignore"/utf8>>} - end, - priv@errors:print_result(_pipe@17). diff --git a/aoc2023/build/packages/adglent/src/adglent_ffi.erl b/aoc2023/build/packages/adglent/src/adglent_ffi.erl deleted file mode 100644 index a6a92e6..0000000 --- a/aoc2023/build/packages/adglent/src/adglent_ffi.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(adglent_ffi). - --export([get_line/1]). - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. diff --git a/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam b/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam deleted file mode 100644 index e18bafa..0000000 --- a/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam +++ /dev/null @@ -1,37 +0,0 @@ -import gleam/result.{try} -import gleam/httpc -import gleam/http/request -import gleam/int -import gleam/string - -pub fn get_input( - year: String, - day: String, - session: String, -) -> Result(String, String) { - let url = "https://adventofcode.com/" <> year <> "/day/" <> day <> "/input" - use request <- try( - request.to(url) - |> result.map_error(fn(error) { - "Could not create request for \"" <> url <> "\": " <> string.inspect( - error, - ) - }), - ) - - // Send the HTTP request to the server - use response <- try( - request - |> request.prepend_header("Accept", "application/json") - |> request.prepend_header("Cookie", "session=" <> session <> ";") - |> httpc.send - |> result.map_error(fn(error) { - "Error when requesting \"" <> url <> "\": " <> string.inspect(error) - }), - ) - - case response.status { - status if status >= 200 && status < 300 -> Ok(response.body) - status -> Error(int.to_string(status) <> " - " <> response.body) - } -} diff --git a/aoc2023/build/packages/adglent/src/priv/errors.gleam b/aoc2023/build/packages/adglent/src/priv/errors.gleam deleted file mode 100644 index 14c35ca..0000000 --- a/aoc2023/build/packages/adglent/src/priv/errors.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/result -import gleam/string -import gleam/io - -pub fn map_messages( - result: Result(a, b), - success_message: String, - error_message: String, -) -> Result(String, String) { - result - |> result.map_error(fn(error) { - "Error - " <> error_message <> ": " <> string.inspect(error) - }) - |> result.replace(success_message) -} - -pub fn map_error( - result: Result(a, b), - error_message: String, -) -> Result(a, String) { - result - |> result.map_error(fn(error) { - error_message <> ": " <> string.inspect(error) - }) -} - -pub fn print_result(result: Result(String, String)) { - result - |> result.unwrap_both - |> io.println - result -} - -pub fn print_error(result: Result(a, String)) { - result - |> result.map_error(fn(err) { - io.println(err) - err - }) -} - -pub fn assert_ok(result: Result(a, String)) { - let assert Ok(value) = - result - |> result.map_error(fn(err) { - halt(1) - err - }) - value -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil diff --git a/aoc2023/build/packages/adglent/src/priv/prompt.gleam b/aoc2023/build/packages/adglent/src/priv/prompt.gleam deleted file mode 100644 index 6cee35a..0000000 --- a/aoc2023/build/packages/adglent/src/priv/prompt.gleam +++ /dev/null @@ -1,38 +0,0 @@ -import gleam/result -import gleam/string - -pub fn confirm(message: String, auto_accept: Bool) -> Bool { - auto_accept || case - get_line(message <> "? (Y/N): ") - |> result.unwrap("n") - |> string.trim() - { - "Y" | "y" -> True - _ -> False - } -} - -pub fn value(message: String, default: String, auto_accept: Bool) -> String { - case get_value_of_default(message, default, auto_accept) { - "" -> default - value -> value - } -} - -fn get_value_of_default(message: String, default: String, auto_accept: Bool) { - case auto_accept { - True -> default - False -> - get_line(message <> "? (" <> default <> "): ") - |> result.unwrap("") - |> string.trim() - } -} - -pub type GetLineError { - Eof - NoData -} - -@external(erlang, "adglent_ffi", "get_line") -pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) diff --git a/aoc2023/build/packages/adglent/src/priv/template.gleam b/aoc2023/build/packages/adglent/src/priv/template.gleam deleted file mode 100644 index e946888..0000000 --- a/aoc2023/build/packages/adglent/src/priv/template.gleam +++ /dev/null @@ -1,18 +0,0 @@ -import gleam/list -import gleam/string - -pub fn render( - template: String, - substitutions: List(#(String, String)), -) -> String { - substitutions - |> list.fold( - template, - fn(template, substitution) { - let #(name, value) = substitution - template - |> string.replace("{{ " <> name <> " }}", value) - }, - ) - |> string.trim <> "\n" -} diff --git a/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam b/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam deleted file mode 100644 index 96085c3..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam +++ /dev/null @@ -1,27 +0,0 @@ -pub const template = " -import adglent.{First, Second} -import gleam/io - -pub fn part1(input: String) { - todo as \"Implement solution to part 1\" -} - -pub fn part2(input: String) { - todo as \"Implement solution to part 2\" -} - -pub fn main() { - let assert Ok(part) = adglent.get_part() - let assert Ok(input) = adglent.get_input(\"{{ day }}\") - case part { - First -> - part1(input) - |> adglent.inspect - |> io.println - Second -> - part2(input) - |> adglent.inspect - |> io.println - } -} -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam b/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam deleted file mode 100644 index 27548d3..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam +++ /dev/null @@ -1,7 +0,0 @@ -pub const template = " -import showtime - -pub fn main() { - showtime.main() -} -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam b/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam deleted file mode 100644 index a1d56f6..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam +++ /dev/null @@ -1,41 +0,0 @@ -pub const template = " -import gleam/list -import gleeunit/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam b/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam deleted file mode 100644 index 699feb2..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam +++ /dev/null @@ -1,41 +0,0 @@ -pub const template = " -import gleam/list -import showtime/tests/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -" diff --git a/aoc2023/build/packages/adglent/src/priv/toml.gleam b/aoc2023/build/packages/adglent/src/priv/toml.gleam deleted file mode 100644 index 7042833..0000000 --- a/aoc2023/build/packages/adglent/src/priv/toml.gleam +++ /dev/null @@ -1,52 +0,0 @@ -import tom -import gleam/result - -pub type TomError { - TomParseError(error: tom.ParseError) - TomGetError(error: tom.GetError) -} - -pub fn get_string( - toml_content: String, - key_path: List(String), -) -> Result(String, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_string(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} - -pub fn get_bool( - toml_content: String, - key_path: List(String), -) -> Result(Bool, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_bool(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} - -pub fn get_int( - toml_content: String, - key_path: List(String), -) -> Result(Int, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_int(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} diff --git a/aoc2023/build/packages/adglent/src/priv@aoc_client.erl b/aoc2023/build/packages/adglent/src/priv@aoc_client.erl deleted file mode 100644 index 1acb9b5..0000000 --- a/aoc2023/build/packages/adglent/src/priv@aoc_client.erl +++ /dev/null @@ -1,61 +0,0 @@ --module(priv@aoc_client). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_input/3]). - --spec get_input(binary(), binary(), binary()) -> {ok, binary()} | - {error, binary()}. -get_input(Year, Day, Session) -> - Url = <<<<<<<<"https://adventofcode.com/"/utf8, Year/binary>>/binary, - "/day/"/utf8>>/binary, - Day/binary>>/binary, - "/input"/utf8>>, - gleam@result:'try'( - begin - _pipe = gleam@http@request:to(Url), - gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<<<"Could not create request for \""/utf8, Url/binary>>/binary, - "\": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ) - end, - fun(Request) -> - gleam@result:'try'( - begin - _pipe@1 = Request, - _pipe@2 = gleam@http@request:prepend_header( - _pipe@1, - <<"Accept"/utf8>>, - <<"application/json"/utf8>> - ), - _pipe@3 = gleam@http@request:prepend_header( - _pipe@2, - <<"Cookie"/utf8>>, - <<<<"session="/utf8, Session/binary>>/binary, ";"/utf8>> - ), - _pipe@4 = gleam@httpc:send(_pipe@3), - gleam@result:map_error( - _pipe@4, - fun(Error@1) -> - <<<<<<"Error when requesting \""/utf8, Url/binary>>/binary, - "\": "/utf8>>/binary, - (gleam@string:inspect(Error@1))/binary>> - end - ) - end, - fun(Response) -> case erlang:element(2, Response) of - Status when (Status >= 200) andalso (Status < 300) -> - {ok, erlang:element(4, Response)}; - - Status@1 -> - {error, - <<<<(gleam@int:to_string(Status@1))/binary, - " - "/utf8>>/binary, - (erlang:element(4, Response))/binary>>} - end end - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/priv@errors.erl b/aoc2023/build/packages/adglent/src/priv@errors.erl deleted file mode 100644 index 978c675..0000000 --- a/aoc2023/build/packages/adglent/src/priv@errors.erl +++ /dev/null @@ -1,74 +0,0 @@ --module(priv@errors). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([map_messages/3, map_error/2, print_result/1, print_error/1, assert_ok/1]). - --spec map_messages({ok, any()} | {error, any()}, binary(), binary()) -> {ok, - binary()} | - {error, binary()}. -map_messages(Result, Success_message, Error_message) -> - _pipe = Result, - _pipe@1 = gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<<<"Error - "/utf8, Error_message/binary>>/binary, ": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ), - gleam@result:replace(_pipe@1, Success_message). - --spec map_error({ok, NIB} | {error, any()}, binary()) -> {ok, NIB} | - {error, binary()}. -map_error(Result, Error_message) -> - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<Error_message/binary, ": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ). - --spec print_result({ok, binary()} | {error, binary()}) -> {ok, binary()} | - {error, binary()}. -print_result(Result) -> - _pipe = Result, - _pipe@1 = gleam@result:unwrap_both(_pipe), - gleam@io:println(_pipe@1), - Result. - --spec print_error({ok, NIK} | {error, binary()}) -> {ok, NIK} | - {error, binary()}. -print_error(Result) -> - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Err) -> - gleam@io:println(Err), - Err - end - ). - --spec assert_ok({ok, NIO} | {error, binary()}) -> NIO. -assert_ok(Result) -> - _assert_subject = begin - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Err) -> - erlang:halt(1), - Err - end - ) - end, - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"priv/errors"/utf8>>, - function => <<"assert_ok"/utf8>>, - line => 43}) - end, - Value. diff --git a/aoc2023/build/packages/adglent/src/priv@prompt.erl b/aoc2023/build/packages/adglent/src/priv@prompt.erl deleted file mode 100644 index 0277f14..0000000 --- a/aoc2023/build/packages/adglent/src/priv@prompt.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(priv@prompt). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_line/1, confirm/2, value/3]). --export_type([get_line_error/0]). - --type get_line_error() :: eof | no_data. - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Prompt) -> - adglent_ffi:get_line(Prompt). - --spec confirm(binary(), boolean()) -> boolean(). -confirm(Message, Auto_accept) -> - Auto_accept orelse case begin - _pipe = adglent_ffi:get_line(<<Message/binary, "? (Y/N): "/utf8>>), - _pipe@1 = gleam@result:unwrap(_pipe, <<"n"/utf8>>), - gleam@string:trim(_pipe@1) - end of - <<"Y"/utf8>> -> - true; - - <<"y"/utf8>> -> - true; - - _ -> - false - end. - --spec get_value_of_default(binary(), binary(), boolean()) -> binary(). -get_value_of_default(Message, Default, Auto_accept) -> - case Auto_accept of - true -> - Default; - - false -> - _pipe = adglent_ffi:get_line( - <<<<<<Message/binary, "? ("/utf8>>/binary, Default/binary>>/binary, - "): "/utf8>> - ), - _pipe@1 = gleam@result:unwrap(_pipe, <<""/utf8>>), - gleam@string:trim(_pipe@1) - end. - --spec value(binary(), binary(), boolean()) -> binary(). -value(Message, Default, Auto_accept) -> - case get_value_of_default(Message, Default, Auto_accept) of - <<""/utf8>> -> - Default; - - Value -> - Value - end. diff --git a/aoc2023/build/packages/adglent/src/priv@template.erl b/aoc2023/build/packages/adglent/src/priv@template.erl deleted file mode 100644 index 6a5d0bf..0000000 --- a/aoc2023/build/packages/adglent/src/priv@template.erl +++ /dev/null @@ -1,25 +0,0 @@ --module(priv@template). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([render/2]). - --spec render(binary(), list({binary(), binary()})) -> binary(). -render(Template, Substitutions) -> - <<(begin - _pipe = Substitutions, - _pipe@2 = gleam@list:fold( - _pipe, - Template, - fun(Template@1, Substitution) -> - {Name, Value} = Substitution, - _pipe@1 = Template@1, - gleam@string:replace( - _pipe@1, - <<<<"{{ "/utf8, Name/binary>>/binary, " }}"/utf8>>, - Value - ) - end - ), - gleam@string:trim(_pipe@2) - end)/binary, - "\n"/utf8>>. diff --git a/aoc2023/build/packages/adglent/src/priv@templates@solution.erl b/aoc2023/build/packages/adglent/src/priv@templates@solution.erl deleted file mode 100644 index 7e36387..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@solution.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@solution). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl b/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl deleted file mode 100644 index ca6b127..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@test_main). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl b/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl deleted file mode 100644 index 2f5a41e..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@testfile_gleeunit). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl b/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl deleted file mode 100644 index bbbc8b2..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@testfile_showtime). diff --git a/aoc2023/build/packages/adglent/src/priv@toml.erl b/aoc2023/build/packages/adglent/src/priv@toml.erl deleted file mode 100644 index 6c41fbf..0000000 --- a/aoc2023/build/packages/adglent/src/priv@toml.erl +++ /dev/null @@ -1,83 +0,0 @@ --module(priv@toml). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_string/2, get_bool/2, get_int/2]). --export_type([tom_error/0]). - --type tom_error() :: {tom_parse_error, tom:parse_error()} | - {tom_get_error, tom:get_error()}. - --spec get_string(binary(), list(binary())) -> {ok, binary()} | - {error, tom_error()}. -get_string(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_string(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). - --spec get_bool(binary(), list(binary())) -> {ok, boolean()} | - {error, tom_error()}. -get_bool(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_bool(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). - --spec get_int(binary(), list(binary())) -> {ok, integer()} | - {error, tom_error()}. -get_int(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_int(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime.erl b/aoc2023/build/packages/adglent/src/showtime.erl deleted file mode 100644 index 721bad4..0000000 --- a/aoc2023/build/packages/adglent/src/showtime.erl +++ /dev/null @@ -1,155 +0,0 @@ --module(showtime). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec mk_runner( - fun((gleam@option:option(list(binary())), list(binary()), showtime@internal@common@cli:capture()) -> OBY), - glint:command_input() -) -> OBY. -mk_runner(Func, Command) -> - _assert_subject = begin - _pipe = erlang:element(3, Command), - _pipe@1 = glint@flag:get_strings(_pipe, <<"modules"/utf8>>), - gleam@result:map(_pipe@1, fun(Modules) -> case Modules of - [] -> - none; - - Modules@1 -> - {some, Modules@1} - end end) - end, - {ok, Module_list} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 91}) - end, - _assert_subject@1 = begin - _pipe@2 = erlang:element(3, Command), - glint@flag:get_strings(_pipe@2, <<"ignore"/utf8>>) - end, - {ok, Ignore_tags} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 100}) - end, - _assert_subject@2 = begin - _pipe@3 = erlang:element(3, Command), - _pipe@4 = glint@flag:get_string(_pipe@3, <<"capture"/utf8>>), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(Arg) -> gleam@string:lowercase(Arg) end - ), - gleam@result:map(_pipe@5, fun(Arg@1) -> case Arg@1 of - <<"no"/utf8>> -> - no; - - <<"yes"/utf8>> -> - yes; - - <<"mixed"/utf8>> -> - mixed - end end) - end, - {ok, Capture_output} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 104}) - end, - Func(Module_list, Ignore_tags, Capture_output). - --spec start_with_args( - list(binary()), - fun((gleam@option:option(list(binary())), list(binary()), showtime@internal@common@cli:capture()) -> any()) -) -> nil. -start_with_args(Args, Func) -> - Modules_flag = begin - _pipe = glint@flag:string_list(), - _pipe@1 = glint@flag:default(_pipe, []), - glint@flag:description( - _pipe@1, - <<"Run only tests in the modules in this list"/utf8>> - ) - end, - Ignore_flag = begin - _pipe@2 = glint@flag:string_list(), - _pipe@3 = glint@flag:default(_pipe@2, []), - glint@flag:description( - _pipe@3, - <<"Ignore tests that are have tags matching a tag in this list"/utf8>> - ) - end, - Capture_flag = begin - _pipe@4 = glint@flag:string(), - _pipe@5 = glint@flag:default(_pipe@4, <<"no"/utf8>>), - _pipe@6 = glint@flag:constraint( - _pipe@5, - glint@flag@constraint:one_of( - [<<"yes"/utf8>>, <<"no"/utf8>>, <<"mixed"/utf8>>] - ) - ), - glint@flag:description( - _pipe@6, - <<"Capture output: no (default) - output when tests are run, yes - output is captured and shown in report, mixed - output when run and in report"/utf8>> - ) - end, - _pipe@7 = glint:new(), - _pipe@12 = glint:add( - _pipe@7, - [], - begin - _pipe@8 = glint:command( - fun(_capture) -> mk_runner(Func, _capture) end - ), - _pipe@9 = glint:flag(_pipe@8, <<"modules"/utf8>>, Modules_flag), - _pipe@10 = glint:flag(_pipe@9, <<"ignore"/utf8>>, Ignore_flag), - _pipe@11 = glint:flag(_pipe@10, <<"capture"/utf8>>, Capture_flag), - glint:description(_pipe@11, <<"Runs test"/utf8>>) - end - ), - _pipe@13 = glint:with_pretty_help(_pipe@12, glint:default_pretty_help()), - glint:run(_pipe@13, Args). - --spec main() -> nil. -main() -> - start_with_args( - gleam@erlang:start_arguments(), - fun(Module_list, Ignore_tags, Capture) -> - Test_event_handler = showtime@internal@erlang@event_handler:start(), - Test_module_handler = showtime@internal@erlang@module_handler:start( - Test_event_handler, - fun showtime@internal@erlang@discover:collect_test_functions/1, - fun showtime@internal@erlang@runner:run_test_suite/4, - Ignore_tags, - Capture - ), - Test_event_handler(start_test_run), - Modules = showtime@internal@erlang@discover:collect_modules( - Test_module_handler, - Module_list - ), - Test_event_handler( - {end_test_run, - begin - _pipe = Modules, - gleam@list:length(_pipe) - end} - ), - nil - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime.gleam b/aoc2023/build/packages/adglent/src/showtime.gleam deleted file mode 100644 index f0401c9..0000000 --- a/aoc2023/build/packages/adglent/src/showtime.gleam +++ /dev/null @@ -1,116 +0,0 @@ -import glint.{type CommandInput, flag} -import glint/flag -import glint/flag/constraint.{one_of} -import gleam/result -import gleam/string -import showtime/internal/common/cli.{Mixed, No, Yes} -@target(erlang) -import gleam/list -@target(erlang) -import gleam/option.{None, Some} -@target(erlang) -import gleam/erlang.{start_arguments} -@target(erlang) -import showtime/internal/common/test_suite.{EndTestRun, StartTestRun} -@target(erlang) -import showtime/internal/erlang/event_handler -@target(erlang) -import showtime/internal/erlang/module_handler -@target(erlang) -import showtime/internal/erlang/runner -@target(erlang) -import showtime/internal/erlang/discover.{ - collect_modules, collect_test_functions, -} - -// @target(javascript) -// import gleam/io - -@target(erlang) -pub fn main() { - use module_list, ignore_tags, capture <- start_with_args(start_arguments()) - // Start event handler which will collect test-results and eventually - // print test report - let test_event_handler = event_handler.start() - // Start module handler which receives msg about modules to test and - // runs the test-suite for the module - let test_module_handler = - module_handler.start( - test_event_handler, - collect_test_functions, - runner.run_test_suite, - ignore_tags, - capture, - ) - - test_event_handler(StartTestRun) - // Collect modules and notify the module handler to start the test-suites - let modules = collect_modules(test_module_handler, module_list) - test_event_handler(EndTestRun( - modules - |> list.length(), - )) - Nil -} - -fn start_with_args(args, func) { - let modules_flag = - flag.string_list() - |> flag.default([]) - |> flag.description("Run only tests in the modules in this list") - - let ignore_flag = - flag.string_list() - |> flag.default([]) - |> flag.description( - "Ignore tests that are have tags matching a tag in this list", - ) - - let capture_flag = - flag.string() - |> flag.default("no") - |> flag.constraint(one_of(["yes", "no", "mixed"])) - |> flag.description( - "Capture output: no (default) - output when tests are run, yes - output is captured and shown in report, mixed - output when run and in report", - ) - - glint.new() - |> glint.add( - at: [], - do: glint.command(mk_runner(func, _)) - |> glint.flag("modules", modules_flag) - |> glint.flag("ignore", ignore_flag) - |> glint.flag("capture", capture_flag) - |> glint.description("Runs test"), - ) - |> glint.with_pretty_help(glint.default_pretty_help()) - |> glint.run(args) -} - -fn mk_runner(func, command: CommandInput) { - let assert Ok(module_list) = - command.flags - |> flag.get_strings("modules") - |> result.map(fn(modules) { - case modules { - [] -> None - modules -> Some(modules) - } - }) - let assert Ok(ignore_tags) = - command.flags - |> flag.get_strings("ignore") - - let assert Ok(capture_output) = - command.flags - |> flag.get_string("capture") - |> result.map(fn(arg) { string.lowercase(arg) }) - |> result.map(fn(arg) { - case arg { - "no" -> No - "yes" -> Yes - "mixed" -> Mixed - } - }) - func(module_list, ignore_tags, capture_output) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam deleted file mode 100644 index 1c03211..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam +++ /dev/null @@ -1,5 +0,0 @@ -pub type Capture { - Yes - No - Mixed -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam deleted file mode 100644 index b90af14..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam +++ /dev/null @@ -1,101 +0,0 @@ -import gleam/map.{type Map} -import showtime/internal/common/test_suite.{ - type TestEvent, type TestRun, CompletedTestRun, EndTest, EndTestRun, - EndTestSuite, OngoingTestRun, StartTest, StartTestRun, StartTestSuite, -} - -pub type TestState { - NotStarted - Running - Finished(num_modules: Int) -} - -pub type HandlerState { - HandlerState( - test_state: TestState, - num_done: Int, - events: Map(String, Map(String, TestRun)), - ) -} - -// This is the common event-handler (shared between erlang/JS targets) -// The main strategy is to collect the test-results in a map of maps: -// module_name -> -// test_name -> test_result -// It will also keep track of if it is running (i.e. did it receive the EndTestRun) -// so that the caller can determine when to print test-results -pub fn handle_event( - msg: TestEvent, - system_time: fn() -> Int, - state: HandlerState, -) { - let test_state = state.test_state - let num_done = state.num_done - let events = state.events - let #(updated_test_state, updated_num_done, updated_events) = case msg { - StartTestRun -> #(Running, num_done, events) - StartTestSuite(module) -> { - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(_) -> events - Error(_) -> - events - |> map.insert(module.name, map.new()) - } - #(test_state, num_done, new_events) - } - StartTest(module, test) -> { - let current_time = system_time() - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(module_events) -> { - let maybe_test_event = map.get(module_events, test.name) - case maybe_test_event { - Error(_) -> - events - |> map.insert( - module.name, - module_events - |> map.insert(test.name, OngoingTestRun(test, current_time)), - ) - Ok(_) -> events - } - } - Error(_) -> events - } - #(test_state, num_done, new_events) - } - EndTest(module, test, result) -> { - let current_time = system_time() - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(module_events) -> { - let maybe_test_run = - module_events - |> map.get(test.name) - let updated_module_events = case maybe_test_run { - Ok(OngoingTestRun(test_function, started_at)) -> - module_events - |> map.insert( - test.name, - CompletedTestRun( - test_function, - current_time - started_at, - result, - ), - ) - Error(_) -> module_events - } - events - |> map.insert(module.name, updated_module_events) - } - Error(_) -> events - } - #(test_state, num_done, new_events) - } - EndTestSuite(_) -> #(test_state, num_done + 1, events) - EndTestRun(num_modules) -> #(Finished(num_modules), num_done, events) - _ -> #(Running, num_done, events) - } - HandlerState(updated_test_state, updated_num_done, updated_events) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam deleted file mode 100644 index a1d6bd9..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam +++ /dev/null @@ -1,119 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/map.{type Map} - -// These are all the types used for test-results -// NOTE: These are heavily used in the erlang/js ffi:s -// so any changes here are likely to break the ffi:s unless -// the corresponding change is introduced there -// -// Futhermore this has some erlang related names that should -// probably be cleaned up, but it is used by both the ffi:s - -// Currently only one reason, but could be possible to support -// more reasons in the future -pub type IgnoreReason { - Ignore -} - -// This is the return value from running the test-function -// or ignored if the test was ignored -pub type TestReturn { - TestFunctionReturn(value: Dynamic, output_buffer: List(String)) - Ignored(reason: IgnoreReason) -} - -// All data about an exception in the test function is captured -// in this type. -// This is also where the data about the assertions will end up (in reason) -pub type Exception { - ErlangException( - class: Class, - reason: Reason, - stacktrace: TraceList, - output_buffer: List(String), - ) -} - -// Alias for the test-result which is either a TestResult (passed test, ignored or a test-definition) -// or an Exception (failed test) -pub type TestResult = - Result(TestReturn, Exception) - -// Reason is either an assert equal (which is if the error was produced by gleeunit should) -// TODO: Add other asserts -// or it is a gleam error meaning that is was produced by showtime should -// TODO: Rename GleamError to ShowtimeError -pub type Reason { - AssertEqual(details: List(ReasonDetail)) - AssertNotEqual(details: List(ReasonDetail)) - AssertMatch(details: List(ReasonDetail)) - GleamError(details: GleamErrorDetail) - GleamAssert(value: Dynamic, line_no: Int) - GenericException(value: Dynamic) -} - -// ReasonDetail is the union-type used in erlang-exceptions where the reason -// is a list of such details -pub type ReasonDetail { - Module(name: String) - ReasonLine(line_no: Int) - Expression(expression: String) - Expected(value: Dynamic) - Value(value: Dynamic) - Pattern(pattern: String) -} - -// Gleam error detail is produced by showtime should and will hold all the information -// about the assertion (both expected and got) -pub type GleamErrorDetail { - LetAssert( - module: String, - function: String, - line_no: Int, - message: String, - value: Dynamic, - ) -} - -// Class is a part of standard erlang exceptions, but also used on js-side -// TODO: Extend to include a JS specific constructor -pub type Class { - ErlangError - Exit - Throw -} - -// The trace list is part of the standard erlang exception, but is also -// emulated on js-side. -// TODO: Maybe we need a js-version that contain some js-specific trace-elements -pub type TraceList { - TraceList(traces: List(Trace)) -} - -// Trace are the elements in the trace list in an erlang exception -// TODO: Maybe add a js-specific trace (since arity is not really a js attribute) -pub type Trace { - Trace(function: String, arity: Arity, extra_info: List(ExtraInfo)) - TraceModule( - module: String, - function: String, - arity: Arity, - extra_info: List(ExtraInfo), - ) -} - -// Extra info holds information about the file and line -// as well as some dynamic data in a map -// This is currently not used in the reporter -pub type ExtraInfo { - ErrorInfo(error_info: Map(Dynamic, Dynamic)) - File(filename: String) - Line(line_no: Int) -} - -// Arity is the erlang type for arity -// Can be either a number, or a list of arguments -pub type Arity { - Num(arity: Int) - ArgList(arg_list: List(Dynamic)) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam deleted file mode 100644 index eb58d64..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam +++ /dev/null @@ -1,63 +0,0 @@ -import gleam/option.{type Option} -import showtime/internal/common/test_result.{type TestResult} -import showtime/internal/common/cli.{type Capture} - -// The state (and result) of a test function -pub type TestRun { - OngoingTestRun(test_function: TestFunction, started_at: Int) - CompletedTestRun( - test_function: TestFunction, - total_time: Int, - result: TestResult, - ) -} - -// A test module (found by discovery) -pub type TestModule { - TestModule(name: String, path: Option(String)) -} - -// A test function -pub type TestFunction { - TestFunction(name: String) -} - -// A test suite is a test module together with the test functions -// that were collected from that module -pub type TestSuite { - TestSuite(module: TestModule, tests: List(TestFunction)) -} - -// Test event for the event handler -pub type TestEvent { - StartTestRun - StartTestSuite(test_module: TestModule) - StartTest(test_module: TestModule, test_function: TestFunction) - EndTest( - test_module: TestModule, - test_function: TestFunction, - result: TestResult, - ) - EndTestSuite(test_module: TestModule) - EndTestRun(num_modules: Int) -} - -// Interface for the module handler -pub type TestModuleHandler = - fn(TestModule) -> Nil - -// Interface for the event handler -pub type TestEventHandler = - fn(TestEvent) -> Nil - -// Interface for the module collector -pub type ModuleCollector = - fn(TestModuleHandler) -> List(TestModule) - -// Interface for the function collector -pub type TestFunctionCollector = - fn(TestModule) -> TestSuite - -// Interface for the test runner -pub type TestRunner = - fn(TestSuite, TestEventHandler, List(String), Capture) -> Nil diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam deleted file mode 100644 index ecb752d..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam +++ /dev/null @@ -1,167 +0,0 @@ -@target(erlang) -import gleam/io -@target(erlang) -import gleam/dynamic.{type Dynamic} -@target(erlang) -import gleam/list -@target(erlang) -import gleam/string -@target(erlang) -import gleam/int -@target(erlang) -import gleam/option.{type Option, None, Some} -@target(erlang) -import gleam/erlang/atom.{type Atom} -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestModule, type TestModuleHandler, type TestSuite, TestFunction, - TestModule, TestSuite, -} -import simplifile - -// Module collector for erlang -// Will search the test folder for files ending with _test and notify -// the module handler about each module it finds -@target(erlang) -pub fn collect_modules( - test_module_handler: TestModuleHandler, - only_modules: Option(List(String)), -) -> List(TestModule) { - collect_modules_in_folder("./test", test_module_handler, only_modules) -} - -@target(erlang) -fn collect_modules_in_folder( - path: String, - test_module_handler: TestModuleHandler, - only_modules: Option(List(String)), -) { - let module_prefix = get_module_prefix(path) - let assert Ok(files) = simplifile.read_directory(path) - let test_modules_in_folder = - files - |> list.filter(string.ends_with(_, "_test.gleam")) - |> list.filter_map(fn(test_module_file) { - let module_name = - module_prefix <> { - test_module_file - |> string.replace(".gleam", "") - } - case only_modules { - Some(only_modules_list) -> { - let module_in_list = - only_modules_list - |> list.any(fn(only_module_name) { - only_module_name == module_name - |> string.replace("@", "/") - }) - case module_in_list { - True -> { - let test_module = TestModule(module_name, Some(test_module_file)) - test_module_handler(test_module) - Ok(test_module) - } - - False -> Error(Nil) - } - } - None -> { - let test_module = TestModule(module_name, Some(test_module_file)) - test_module_handler(test_module) - Ok(test_module) - } - } - }) - let test_modules_in_subfolders = - files - |> list.map(fn(filename) { path <> "/" <> filename }) - |> list.filter(fn(file) { simplifile.is_directory(file) }) - |> list.fold( - [], - fn(modules, subfolder) { - modules - |> list.append(collect_modules_in_folder( - subfolder, - test_module_handler, - only_modules, - )) - }, - ) - test_modules_in_folder - |> list.append(test_modules_in_subfolders) -} - -@target(erlang) -fn get_module_prefix(path) { - let path_without_test = - path - |> string.replace("./test", "") - - let path_without_leading_slash = case - string.starts_with(path_without_test, "/") - { - True -> string.drop_left(path_without_test, 1) - False -> path_without_test - } - let module_prefix = - path_without_leading_slash - |> string.replace("/", "@") - case string.length(module_prefix) { - 0 -> module_prefix - _ -> module_prefix <> "@" - } -} - -// Test function collector for erlang -// Uses erlang `apply` to run `module_info` for the test module -// and collects all the exports ending with _test into a `TestSuite` -@target(erlang) -pub fn collect_test_functions(module: TestModule) -> TestSuite { - let test_functions: List(#(Atom, Int)) = - apply( - atom.create_from_string(module.name), - atom.create_from_string("module_info"), - [dynamic.from(atom.create_from_string("exports"))], - ) - |> dynamic.unsafe_coerce() - - let test_functions_filtered = - test_functions - |> list.map(fn(entry) { - let assert #(name, arity) = entry - #( - name - |> atom.to_string(), - arity, - ) - }) - |> list.filter_map(fn(entry) { - let assert #(name, arity) = entry - case string.ends_with(name, "_test") { - True -> - case arity { - 0 -> Ok(name) - _ -> { - io.println( - "WARNING: function \"" <> name <> "\" has arity: " <> int.to_string( - arity, - ) <> " - cannot be used as test (needs to be 0)", - ) - Error("Wrong arity") - } - } - False -> Error("Non matching name") - } - }) - |> list.filter(string.ends_with(_, "_test")) - |> list.map(fn(function_name) { TestFunction(function_name) }) - TestSuite(module, test_functions_filtered) -} - -@target(erlang) -@external(erlang, "erlang", "apply") -fn apply( - module module: Atom, - function function: Atom, - args args: List(Dynamic), -) -> Dynamic diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam deleted file mode 100644 index 62a9caf..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam +++ /dev/null @@ -1,91 +0,0 @@ -@target(erlang) -import gleam/io -@target(erlang) -import gleam/otp/actor.{Continue, Stop} -@target(erlang) -import gleam/erlang/process.{type Subject, Normal} -@target(erlang) -import gleam/map -@target(erlang) -import showtime/internal/common/test_suite.{type TestEvent, EndTestRun} -@target(erlang) -import showtime/internal/common/common_event_handler.{ - Finished, HandlerState, NotStarted, handle_event, -} -@target(erlang) -import showtime/internal/reports/formatter.{create_test_report} -@target(erlang) -import gleam/erlang.{Millisecond} -@target(erlang) -import gleam/option.{None} - -@target(erlang) -type EventHandlerMessage { - EventHandlerMessage(test_event: TestEvent, reply_to: Subject(Int)) -} - -// Starts an actor that receives test events and forwards the to the event handler -// When handler updates the state to `Finished` the actor will wait until handler -// reports that all modules are done and the stop -@target(erlang) -pub fn start() { - let assert Ok(subject) = - actor.start( - #(NotStarted, 0, map.new()), - fn(msg: EventHandlerMessage, state) { - let EventHandlerMessage(test_event, reply_to) = msg - let #(test_state, num_done, events) = state - let updated_state = - handle_event( - test_event, - system_time, - HandlerState(test_state, num_done, events), - ) - case updated_state { - HandlerState(Finished(num_modules), num_done, events) if num_done == num_modules -> { - let #(test_report, num_failed) = create_test_report(events) - io.println(test_report) - process.send(reply_to, num_failed) - Stop(Normal) - } - HandlerState(test_state, num_done, events) -> - Continue(#(test_state, num_done, events), None) - } - }, - ) - let parent_subject = process.new_subject() - - let selector = - process.new_selector() - |> process.selecting(parent_subject, fn(x) { x }) - - // Returns a callback that can receive test events - fn(test_event: TestEvent) { - case test_event { - EndTestRun(..) -> { - // When EndTestRun has been received the callback will wait until the - // actor has stopped - // TODO: Use a timeout? - process.send(subject, EventHandlerMessage(test_event, parent_subject)) - let num_failed = process.select_forever(selector) - case num_failed > 0 { - True -> halt(1) - False -> halt(0) - } - } - - // Normally just send the test event to the actor - _ -> - process.send(subject, EventHandlerMessage(test_event, parent_subject)) - } - } -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn system_time() { - erlang.system_time(Millisecond) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam deleted file mode 100644 index 88cc251..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam +++ /dev/null @@ -1,43 +0,0 @@ -@target(erlang) -import gleam/otp/actor.{Continue} -@target(erlang) -import gleam/erlang/process -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestEventHandler, type TestFunctionCollector, type TestModule, - type TestRunner, EndTestSuite, StartTestSuite, -} -@target(erlang) -import showtime/internal/common/cli.{type Capture} -@target(erlang) -import gleam/option.{None} - -@target(erlang) -pub fn start( - test_event_handler: TestEventHandler, - test_function_collector: TestFunctionCollector, - run_test_suite: TestRunner, - ignore_tags: List(String), - capture: Capture, -) { - let assert Ok(subject) = - actor.start( - Nil, - fn(module: TestModule, state) { - process.start( - fn() { - let test_suite = test_function_collector(module) - test_event_handler(StartTestSuite(module)) - run_test_suite(test_suite, test_event_handler, ignore_tags, capture) - test_event_handler(EndTestSuite(module)) - }, - False, - ) - Continue(state, None) - }, - ) - fn(test_module: TestModule) { - process.send(subject, test_module) - Nil - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam deleted file mode 100644 index ebbf426..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam +++ /dev/null @@ -1,59 +0,0 @@ -@target(erlang) -import gleam/list -@target(erlang) -import gleam/erlang/atom.{type Atom} -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestEventHandler, type TestSuite, EndTest, StartTest, -} -@target(erlang) -import showtime/internal/common/test_result.{type TestResult} -@target(erlang) -import showtime/internal/common/cli.{type Capture} - -// Runs all tests in a test suite -@target(erlang) -pub fn run_test_suite( - test_suite: TestSuite, - test_event_handler: TestEventHandler, - ignore_tags: List(String), - capture: Capture, -) { - test_suite.tests - |> list.each(fn(test) { - test_event_handler(StartTest(test_suite.module, test)) - let result = - run_test(test_suite.module.name, test.name, ignore_tags, capture) - test_event_handler(EndTest(test_suite.module, test, result)) - }) -} - -// Wrapper around the ffi function that converts names to atoms -@target(erlang) -pub fn run_test( - module_name: String, - test_name: String, - ignore_tags: List(String), - capture: Capture, -) -> TestResult { - let result = - run_test_ffi( - atom.create_from_string(module_name), - atom.create_from_string(test_name), - ignore_tags, - capture, - ) - result -} - -// Calls ffi for running a test function -// The ffi will take care of mapping the result and exception to the data-types -// used in gleam -@target(erlang) -@external(erlang, "showtime_ffi", "run_test") -fn run_test_ffi( - module module: Atom, - function function: Atom, - ignore_tags ignore_tags: List(String), - capture capture: Capture, -) -> TestResult diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam deleted file mode 100644 index 5ccddee..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam +++ /dev/null @@ -1,42 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/string -import showtime/internal/reports/styles.{expected_highlight, got_highlight} -import gap.{compare_lists, compare_strings} -import gap/styling.{from_comparison, highlight, to_styled_comparison} - -pub fn compare(expected: Dynamic, got: Dynamic) -> #(String, String) { - let expected_as_list = - expected - |> dynamic.list(dynamic.dynamic) - let got_as_list = - got - |> dynamic.list(dynamic.dynamic) - let expected_as_string = - expected - |> dynamic.string() - let got_as_string = - got - |> dynamic.string() - case expected_as_list, got_as_list, expected_as_string, got_as_string { - Ok(expected_list), Ok(got_list), _, _ -> { - let comparison = - compare_lists(expected_list, got_list) - |> from_comparison() - |> highlight(expected_highlight, got_highlight, fn(item) { item }) - |> to_styled_comparison() - #(comparison.first, comparison.second) - } - _, _, Ok(expected_string), Ok(got_string) -> { - let comparison = - compare_strings(expected_string, got_string) - |> from_comparison() - |> highlight(expected_highlight, got_highlight, fn(item) { item }) - |> to_styled_comparison() - #(comparison.first, comparison.second) - } - _, _, _, _ -> #( - expected_highlight(string.inspect(expected)), - got_highlight(string.inspect(got)), - ) - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam deleted file mode 100644 index 8c1a6ac..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam +++ /dev/null @@ -1,480 +0,0 @@ -import gleam/io -import gleam/int -import gleam/list -import gleam/string -import gleam/option.{type Option, None, Some} -import gleam/map.{type Map} -import gleam/dynamic.{type Dynamic} -import showtime/internal/common/test_result.{ - type GleamErrorDetail, type ReasonDetail, type Trace, AssertEqual, AssertMatch, - AssertNotEqual, Expected, Expression, GenericException, GleamAssert, - GleamError, Ignored, LetAssert, Pattern, Trace, TraceModule, Value, -} -import showtime/internal/common/test_suite.{type TestRun, CompletedTestRun} -import showtime/tests/should.{type Assertion, Eq, Fail, IsError, IsOk, NotEq} -import showtime/internal/reports/styles.{ - error_style, expected_highlight, failed_style, function_style, got_highlight, - heading_style, ignored_style, not_style, passed_style, stacktrace_style, -} -import showtime/internal/reports/compare.{compare} -import showtime/internal/reports/table.{ - AlignLeft, AlignLeftOverflow, AlignRight, Content, Separator, StyledContent, - Table, align_table, to_string, -} -import showtime/tests/meta.{type Meta} - -type GleeUnitAssertionType { - GleeUnitAssertEqual(message: String) - GleeUnitAssertNotEqual(message: String) - GleeUnitAssertMatch(message: String) -} - -type ModuleAndTest { - ModuleAndTestRun(module_name: String, test_run: TestRun) -} - -type UnifiedError { - UnifiedError( - meta: Option(Meta), - reason: String, - message: String, - expected: String, - got: String, - line: Option(Int), - stacktrace: List(Trace), - ) -} - -pub fn create_test_report(test_results: Map(String, Map(String, TestRun))) { - let all_test_runs = - test_results - |> map.values() - |> list.flat_map(map.values) - let failed_test_runs = - test_results - |> map.to_list() - |> list.flat_map(fn(entry) { - let #(module_name, test_module_results) = entry - test_module_results - |> map.values() - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(_test_function, _, result) -> - case result { - Error(_) -> Ok(ModuleAndTestRun(module_name, test_run)) - Ok(Ignored(_)) -> Error(Nil) - Ok(_) -> Error(Nil) - } - _ -> { - test_run - |> io.debug() - Error(Nil) - } - } - }) - }) - - let ignored_test_runs = - test_results - |> map.to_list() - |> list.flat_map(fn(entry) { - let #(module_name, test_module_results) = entry - test_module_results - |> map.values() - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(test_function, _, result) -> - case result { - Ok(Ignored(reason)) -> - Ok(#(module_name <> "." <> test_function.name, reason)) - _ -> Error(Nil) - } - _ -> Error(Nil) - } - }) - }) - - let failed_tests_report = - failed_test_runs - |> list.filter_map(fn(module_and_test_run) { - case module_and_test_run.test_run { - CompletedTestRun(test_function, _total_time, result) -> - case result { - Error(exception) -> - case exception.reason { - AssertEqual(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertEqual("Assert equal"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - AssertNotEqual(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertNotEqual("Assert not equal"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - AssertMatch(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertMatch("Assert match"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - GleamError(reason) -> - Ok(format_reason( - gleam_error_to_unified(reason, exception.stacktrace.traces), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - // GleamAssert(value) -> Error(Nil) - GleamAssert(value, line_no) -> - Ok(format_reason( - UnifiedError( - None, - "gleam assert", - "Assert failed", - "Patterns should match", - error_style(string.inspect(value)), - Some(line_no), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - GenericException(value) -> - Ok(format_reason( - UnifiedError( - None, - "generic exception", - "Test function threw an exception", - "Exception in test function", - error_style(string.inspect(value)), - None, - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - other -> { - io.println("Other: " <> string.inspect(other)) - panic - Error(Nil) - } - } - _ -> Error(Nil) - } - _ -> Error(Nil) - } - }) - |> list.fold([], fn(rows, test_rows) { list.append(rows, test_rows) }) - - let all_test_execution_time_reports = - all_test_runs - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(test_function, total_time, _) -> - Ok(test_function.name <> ": " <> int.to_string(total_time) <> " ms") - _ -> Error(Nil) - } - }) - let _execution_times_report = - all_test_execution_time_reports - |> string.join("\n") - - let all_tests_count = - all_test_runs - |> list.length() - let ignored_tests_count = - ignored_test_runs - |> list.length() - let failed_tests_count = - failed_test_runs - |> list.length() - - let passed = - passed_style( - int.to_string(all_tests_count - failed_tests_count - ignored_tests_count) <> " passed", - ) - let failed = failed_style(int.to_string(failed_tests_count) <> " failed") - let ignored = case ignored_tests_count { - 0 -> "" - _ -> ", " <> ignored_style(int.to_string(ignored_tests_count) <> " ignored") - } - - let failed_tests_table = - Table(None, failed_tests_report) - |> align_table() - |> to_string() - - let test_report = - "\n" <> failed_tests_table <> "\n" <> passed <> ", " <> failed <> ignored - #(test_report, failed_tests_count) -} - -fn erlang_error_to_unified( - error_details: List(ReasonDetail), - assertion_type: GleeUnitAssertionType, - stacktrace: List(Trace), -) { - error_details - |> list.fold( - UnifiedError( - None, - "not_set", - assertion_type.message, - "", - "", - None, - stacktrace, - ), - fn(unified, reason) { - case reason { - Expression(expression) -> UnifiedError(..unified, reason: expression) - Expected(value) -> - case assertion_type { - GleeUnitAssertEqual(_messaged) -> - UnifiedError( - ..unified, - expected: expected_highlight(string.inspect(value)), - ) - _ -> unified - } - Value(value) -> - case assertion_type { - GleeUnitAssertNotEqual(_message) -> - UnifiedError( - ..unified, - expected: not_style("not ") <> string.inspect(value), - got: got_highlight(string.inspect(value)), - ) - _ -> - UnifiedError(..unified, got: got_highlight(string.inspect(value))) - } - Pattern(pattern) -> - case pattern { - "{ ok , _ }" -> - UnifiedError(..unified, expected: expected_highlight("Ok(_)")) - "{ error , _ }" -> - UnifiedError(..unified, expected: expected_highlight("Error(_)")) - _ -> unified - } - _ -> unified - } - }, - ) -} - -fn gleam_error_to_unified( - gleam_error: GleamErrorDetail, - stacktrace: List(Trace), -) -> UnifiedError { - case gleam_error { - LetAssert(_module, _function, _line_no, _message, value) -> { - let result: Result(Dynamic, Assertion(Dynamic, Dynamic)) = - dynamic.unsafe_coerce(value) - let assert Error(assertion) = result - case assertion { - Eq(got, expected, meta) -> { - let #(expected, got) = compare(expected, got) - UnifiedError( - meta, - "assert", - "Assert equal", - expected, - got, - None, - stacktrace, - ) - } - NotEq(got, expected, meta) -> - UnifiedError( - meta, - "assert", - "Assert not equal", - not_style("not ") <> string.inspect(expected), - string.inspect(got), - None, - stacktrace, - ) - IsOk(got, meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - expected_highlight("Ok(_)"), - got_highlight(string.inspect(got)), - None, - stacktrace, - ) - IsError(got, meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - expected_highlight("Error(_)"), - got_highlight(string.inspect(got)), - None, - stacktrace, - ) - Fail(meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - got_highlight("should.fail()"), - got_highlight("N/A - test always expected to fail"), - None, - stacktrace, - ) - } - } - } -} - -fn format_reason( - error: UnifiedError, - module: String, - function: String, - output_buffer: List(String), -) { - let meta = case error.meta { - Some(meta) -> - Some([ - AlignRight(StyledContent(heading_style("Description")), 2), - Separator(": "), - AlignLeft(Content(meta.description), 0), - ]) - - None -> None - } - - let stacktrace = - error.stacktrace - |> list.map(fn(trace) { - case trace { - Trace(function, _, _) if function == "" -> "(anonymous)" - TraceModule(module, function, _, _) if function == "" -> - module <> "." <> "(anonymous)" - Trace(function, _, _) -> function - TraceModule(module, function, _, _) -> module <> "." <> function - } - }) - let stacktrace_rows = case stacktrace { - [] -> [] - [first, ..rest] -> { - let first_row = - Some([ - AlignRight(StyledContent(heading_style("Stacktrace")), 2), - Separator(": "), - AlignLeft(StyledContent(stacktrace_style(first)), 0), - ]) - let rest_rows = - rest - |> list.map(fn(row) { - Some([ - AlignRight(Content(""), 2), - Separator(" "), - AlignLeft(StyledContent(stacktrace_style(row)), 0), - ]) - }) - [first_row, ..rest_rows] - } - } - - let output_rows = case - output_buffer - |> list.reverse() - |> list.map(fn(row) { string.trim_right(row) }) - { - [] -> [] - [first, ..rest] -> { - let first_row = - Some([ - AlignRight(StyledContent(heading_style("Output")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(stacktrace_style(first)), 0), - ]) - let rest_rows = - rest - |> list.map(fn(row) { - Some([ - AlignRight(Content(""), 2), - Separator(" "), - AlignLeftOverflow(StyledContent(stacktrace_style(row)), 0), - ]) - }) - [first_row, ..rest_rows] - } - } - - let line = - error.line - |> option.map(fn(line) { ":" <> int.to_string(line) }) - |> option.unwrap("") - - let arrow = - string.join( - list.repeat( - "-", - string.length(module) + 1 + { - string.length(function) + string.length(line) - } / 2, - ), - "", - ) <> "⌄" - let standard_table_rows = [ - Some([ - AlignRight(StyledContent(error_style("Failed")), 2), - Separator(": "), - AlignLeft(Content(arrow), 0), - ]), - Some([ - AlignRight(StyledContent(heading_style("Test")), 2), - Separator(": "), - AlignLeft( - StyledContent(module <> "." <> function_style(function <> line)), - 0, - ), - ]), - meta, - Some([ - AlignRight(StyledContent(heading_style("Expected")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(error.expected), 0), - ]), - Some([ - AlignRight(StyledContent(heading_style("Got")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(error.got), 0), - ]), - ] - standard_table_rows - |> list.append(stacktrace_rows) - |> list.append(output_rows) - |> list.append([ - Some([ - AlignRight(Content(""), 0), - AlignRight(Content(""), 0), - AlignRight(Content(""), 0), - ]), - ]) - |> list.filter_map(fn(row) { option.to_result(row, Nil) }) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam deleted file mode 100644 index b051dd3..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam +++ /dev/null @@ -1,84 +0,0 @@ -import gleam_community/ansi -import gleam/list -import gleam/string -import gleam/bit_array - -pub fn passed_style(text) { - bold_green(text) -} - -pub fn failed_style(text) { - bold_red(text) -} - -pub fn ignored_style(text) { - bold_yellow(text) -} - -pub fn error_style(text) { - bold_red(text) -} - -pub fn expected_highlight(text) { - bold_green(text) -} - -pub fn got_highlight(text) { - bold_red(text) -} - -pub fn not_style(text) { - ansi.bold(text) -} - -pub fn module_style(text: String) { - ansi.cyan(text) -} - -pub fn heading_style(text: String) { - ansi.cyan(text) -} - -pub fn function_style(text: String) { - bold_cyan(text) -} - -pub fn stacktrace_style(text: String) { - text -} - -fn bold_red(text: String) { - ansi.bold(ansi.red(text)) -} - -fn bold_green(text) { - ansi.bold(ansi.green(text)) -} - -fn bold_yellow(text) { - ansi.bold(ansi.yellow(text)) -} - -fn bold_cyan(text) { - ansi.bold(ansi.cyan(text)) -} - -pub fn strip_style(text) { - let #(new_text, _) = - text - |> string.to_graphemes() - |> list.fold( - #("", False), - fn(acc, char) { - let #(str, removing) = acc - let bit_char = bit_array.from_string(char) - case bit_char, removing { - <<0x1b>>, _ -> #(str, True) - <<0x6d>>, True -> #(str, False) - _, True -> #(str, True) - _, False -> #(str <> char, False) - } - }, - ) - new_text -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam deleted file mode 100644 index f8bc00c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam +++ /dev/null @@ -1,148 +0,0 @@ -import gleam/list -import gleam/string -import gleam/int -import gleam/option.{type Option} -import showtime/internal/reports/styles.{strip_style} - -pub type Content { - Content(unstyled_text: String) - StyledContent(styled_text: String) -} - -pub type Col { - AlignRight(content: Content, margin: Int) - AlignLeft(content: Content, margin: Int) - AlignRightOverflow(content: Content, margin: Int) - AlignLeftOverflow(content: Content, margin: Int) - Separator(char: String) - Aligned(content: String) -} - -pub type Table { - Table(header: Option(String), rows: List(List(Col))) -} - -pub fn to_string(table: Table) -> String { - let rows = - table.rows - |> list.map(fn(row) { - row - |> list.filter_map(fn(col) { - case col { - Separator(char) -> Ok(char) - Aligned(content) -> Ok(content) - _ -> Error(Nil) - } - }) - |> string.join("") - }) - |> string.join("\n") - let header = - table.header - |> option.map(fn(header) { header <> "\n" }) - |> option.unwrap("") - header <> rows -} - -pub fn align_table(table: Table) -> Table { - let cols = - table.rows - |> list.transpose() - let col_width = - cols - |> list.map(fn(col) { - col - |> list.map(fn(content) { - case content { - AlignRight(Content(unstyled), _) -> unstyled - AlignRight(StyledContent(styled), _) -> strip_style(styled) - AlignLeft(Content(unstyled), _) -> unstyled - AlignLeft(StyledContent(styled), _) -> strip_style(styled) - AlignLeftOverflow(_, _) -> "" - AlignRightOverflow(_, _) -> "" - Separator(char) -> char - Aligned(content) -> content - } - }) - |> list.fold(0, fn(max, str) { int.max(max, string.length(str)) }) - }) - let aligned_col = - cols - |> list.zip(col_width) - |> list.map(fn(col_and_width) { - let #(col, width) = col_and_width - col - |> list.map(fn(content) { - case content { - AlignRight(Content(unstyled), margin) -> - Aligned(pad_left( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignRight(StyledContent(styled), margin) -> - Aligned(pad_left( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignRightOverflow(Content(unstyled), margin) -> - Aligned(pad_left( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignRightOverflow(StyledContent(styled), margin) -> - Aligned(pad_left( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignLeft(Content(unstyled), margin) -> - Aligned(pad_right( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignLeft(StyledContent(styled), margin) -> - Aligned(pad_right( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignLeftOverflow(Content(unstyled), margin) -> - Aligned(pad_right( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignLeftOverflow(StyledContent(styled), margin) -> - Aligned(pad_right( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - Separator(char) -> Separator(char) - Aligned(content) -> Aligned(content) - } - }) - }) - let aligned_rows = - aligned_col - |> list.transpose() - Table(..table, rows: aligned_rows) -} - -fn pad_left(str: String, num: Int, char: String) { - let padding = - list.repeat(char, num) - |> string.join("") - padding <> str -} - -fn pad_right(str: String, num: Int, char: String) { - let padding = - list.repeat(char, num) - |> string.join("") - str <> padding -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam deleted file mode 100644 index cbba414..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam +++ /dev/null @@ -1,3 +0,0 @@ -pub type Meta { - Meta(description: String, tags: List(String)) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam deleted file mode 100644 index 71578c7..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam +++ /dev/null @@ -1,113 +0,0 @@ -import gleam/option.{type Option, None, Some} -import showtime/tests/meta.{type Meta} - -pub type Assertion(t, e) { - Eq(a: t, b: t, meta: Option(Meta)) - NotEq(a: t, b: t, meta: Option(Meta)) - IsOk(a: Result(t, e), meta: Option(Meta)) - IsError(a: Result(t, e), meta: Option(Meta)) - Fail(meta: Option(Meta)) -} - -pub fn equal(a: t, b: t) { - evaluate(Eq(a, b, None)) -} - -pub fn equal_meta(a: t, b: t, meta: Meta) { - evaluate(Eq(a, b, Some(meta))) -} - -pub fn not_equal(a: t, b: t) { - evaluate(NotEq(a, b, None)) -} - -pub fn not_equal_meta(a: t, b: t, meta: Meta) { - evaluate(NotEq(a, b, Some(meta))) -} - -pub fn be_ok(a: Result(o, e)) { - evaluate(IsOk(a, None)) - let assert Ok(value) = a - value -} - -pub fn be_ok_meta(a: Result(o, e), meta: Meta) { - evaluate(IsOk(a, Some(meta))) -} - -pub fn be_error(a: Result(o, e)) { - evaluate(IsError(a, None)) - let assert Error(value) = a - value -} - -pub fn be_error_meta(a: Result(o, e), meta: Meta) { - evaluate(IsError(a, Some(meta))) -} - -pub fn fail() { - evaluate(Fail(None)) -} - -pub fn fail_meta(meta: Meta) { - evaluate(Fail(Some(meta))) -} - -pub fn be_true(a: Bool) { - a - |> equal(True) -} - -pub fn be_true_meta(a: Bool, meta: Meta) { - a - |> equal_meta(True, meta) -} - -pub fn be_false(a: Bool) { - a - |> equal(False) -} - -pub fn be_false_meta(a: Bool, meta: Meta) { - a - |> equal_meta(False, meta) -} - -@external(erlang, "showtime_ffi", "gleam_error") -fn gleam_error(value: Result(Nil, Assertion(a, b))) -> Nil - -pub fn evaluate(assertion) -> Nil { - case assertion { - Eq(a, b, _meta) -> - case a == b { - True -> Nil - False -> { - gleam_error(Error(assertion)) - } - } - NotEq(a, b, _meta) -> - case a != b { - True -> Nil - False -> { - gleam_error(Error(assertion)) - } - } - IsOk(a, _meta) -> - case a { - Ok(_) -> Nil - Error(_) -> { - gleam_error(Error(assertion)) - } - } - IsError(a, _meta) -> - case a { - Error(_) -> Nil - Ok(_) -> { - gleam_error(Error(assertion)) - } - } - Fail(_meta) -> { - gleam_error(Error(assertion)) - } - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam deleted file mode 100644 index 730f943..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam +++ /dev/null @@ -1,57 +0,0 @@ -import showtime/tests/should -import showtime/tests/meta.{type Meta} -import gleam/io - -pub type Test { - Test(meta: Meta, test_function: fn() -> Nil) -} - -pub type MetaShould(t) { - MetaShould(equal: fn(t, t) -> Nil, not_equal: fn(t, t) -> Nil) -} - -pub fn test(meta: Meta, test_function: fn(Meta) -> Nil) { - Test(meta, fn() { test_function(meta) }) -} - -pub fn with_meta(meta: Meta, test_function: fn(MetaShould(a)) -> Nil) { - Test( - meta, - fn() { - test_function(MetaShould( - fn(a, b) { equal(a, b, meta) }, - fn(a, b) { not_equal(a, b, meta) }, - )) - }, - ) -} - -pub fn equal(a: t, b: t, meta: Meta) { - io.debug(a) - io.debug(b) - should.equal_meta(a, b, meta) -} - -pub fn not_equal(a: t, b: t, meta: Meta) { - should.equal_meta(a, b, meta) -} - -pub fn be_ok(a: Result(o, e), meta: Meta) { - should.be_ok_meta(a, meta) -} - -pub fn be_error(a: Result(o, e), meta: Meta) { - should.be_error_meta(a, meta) -} - -pub fn fail(meta: Meta) { - should.fail_meta(meta) -} - -pub fn be_true(a: Bool, meta: Meta) { - should.be_true_meta(a, meta) -} - -pub fn be_false(a: Bool, meta: Meta) { - should.be_false_meta(a, meta) -} diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl deleted file mode 100644 index f2d2396..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(showtime@internal@common@cli). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([capture/0]). - --type capture() :: yes | no | mixed. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl deleted file mode 100644 index b0a6d7a..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl +++ /dev/null @@ -1,131 +0,0 @@ --module(showtime@internal@common@common_event_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([handle_event/3]). --export_type([test_state/0, handler_state/0]). - --type test_state() :: not_started | running | {finished, integer()}. - --type handler_state() :: {handler_state, - test_state(), - integer(), - gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@internal@common@test_suite:test_run()))}. - --spec handle_event( - showtime@internal@common@test_suite:test_event(), - fun(() -> integer()), - handler_state() -) -> handler_state(). -handle_event(Msg, System_time, State) -> - Test_state = erlang:element(2, State), - Num_done = erlang:element(3, State), - Events = erlang:element(4, State), - {Updated_test_state, Updated_num_done, Updated_events} = case Msg of - start_test_run -> - {running, Num_done, Events}; - - {start_test_suite, Module} -> - Maybe_module_events = gleam@map:get( - Events, - erlang:element(2, Module) - ), - New_events = case Maybe_module_events of - {ok, _} -> - Events; - - {error, _} -> - _pipe = Events, - gleam@map:insert( - _pipe, - erlang:element(2, Module), - gleam@map:new() - ) - end, - {Test_state, Num_done, New_events}; - - {start_test, Module@1, Test} -> - Current_time = System_time(), - Maybe_module_events@1 = gleam@map:get( - Events, - erlang:element(2, Module@1) - ), - New_events@1 = case Maybe_module_events@1 of - {ok, Module_events} -> - Maybe_test_event = gleam@map:get( - Module_events, - erlang:element(2, Test) - ), - case Maybe_test_event of - {error, _} -> - _pipe@1 = Events, - gleam@map:insert( - _pipe@1, - erlang:element(2, Module@1), - begin - _pipe@2 = Module_events, - gleam@map:insert( - _pipe@2, - erlang:element(2, Test), - {ongoing_test_run, Test, Current_time} - ) - end - ); - - {ok, _} -> - Events - end; - - {error, _} -> - Events - end, - {Test_state, Num_done, New_events@1}; - - {end_test, Module@2, Test@1, Result} -> - Current_time@1 = System_time(), - Maybe_module_events@2 = gleam@map:get( - Events, - erlang:element(2, Module@2) - ), - New_events@2 = case Maybe_module_events@2 of - {ok, Module_events@1} -> - Maybe_test_run = begin - _pipe@3 = Module_events@1, - gleam@map:get(_pipe@3, erlang:element(2, Test@1)) - end, - Updated_module_events = case Maybe_test_run of - {ok, {ongoing_test_run, Test_function, Started_at}} -> - _pipe@4 = Module_events@1, - gleam@map:insert( - _pipe@4, - erlang:element(2, Test@1), - {completed_test_run, - Test_function, - Current_time@1 - Started_at, - Result} - ); - - {error, _} -> - Module_events@1 - end, - _pipe@5 = Events, - gleam@map:insert( - _pipe@5, - erlang:element(2, Module@2), - Updated_module_events - ); - - {error, _} -> - Events - end, - {Test_state, Num_done, New_events@2}; - - {end_test_suite, _} -> - {Test_state, Num_done + 1, Events}; - - {end_test_run, Num_modules} -> - {{finished, Num_modules}, Num_done, Events}; - - _ -> - {running, Num_done, Events} - end, - {handler_state, Updated_test_state, Updated_num_done, Updated_events}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl deleted file mode 100644 index b7b73be..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl +++ /dev/null @@ -1,54 +0,0 @@ --module(showtime@internal@common@test_result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([ignore_reason/0, test_return/0, exception/0, reason/0, reason_detail/0, gleam_error_detail/0, class/0, trace_list/0, trace/0, extra_info/0, arity_/0]). - --type ignore_reason() :: ignore. - --type test_return() :: {test_function_return, - gleam@dynamic:dynamic_(), - list(binary())} | - {ignored, ignore_reason()}. - --type exception() :: {erlang_exception, - class(), - reason(), - trace_list(), - list(binary())}. - --type reason() :: {assert_equal, list(reason_detail())} | - {assert_not_equal, list(reason_detail())} | - {assert_match, list(reason_detail())} | - {gleam_error, gleam_error_detail()} | - {gleam_assert, gleam@dynamic:dynamic_(), integer()} | - {generic_exception, gleam@dynamic:dynamic_()}. - --type reason_detail() :: {module, binary()} | - {reason_line, integer()} | - {expression, binary()} | - {expected, gleam@dynamic:dynamic_()} | - {value, gleam@dynamic:dynamic_()} | - {pattern, binary()}. - --type gleam_error_detail() :: {let_assert, - binary(), - binary(), - integer(), - binary(), - gleam@dynamic:dynamic_()}. - --type class() :: erlang_error | exit | throw. - --type trace_list() :: {trace_list, list(trace())}. - --type trace() :: {trace, binary(), arity_(), list(extra_info())} | - {trace_module, binary(), binary(), arity_(), list(extra_info())}. - --type extra_info() :: {error_info, - gleam@map:map_(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_())} | - {file, binary()} | - {line, integer()}. - --type arity_() :: {num, integer()} | {arg_list, list(gleam@dynamic:dynamic_())}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl deleted file mode 100644 index 6a56de8..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(showtime@internal@common@test_suite). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([test_run/0, test_module/0, test_function/0, test_suite/0, test_event/0]). - --type test_run() :: {ongoing_test_run, test_function(), integer()} | - {completed_test_run, - test_function(), - integer(), - {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}}. - --type test_module() :: {test_module, binary(), gleam@option:option(binary())}. - --type test_function() :: {test_function, binary()}. - --type test_suite() :: {test_suite, test_module(), list(test_function())}. - --type test_event() :: start_test_run | - {start_test_suite, test_module()} | - {start_test, test_module(), test_function()} | - {end_test, - test_module(), - test_function(), - {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}} | - {end_test_suite, test_module()} | - {end_test_run, integer()}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl deleted file mode 100644 index f0548aa..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl +++ /dev/null @@ -1,230 +0,0 @@ --module(showtime@internal@erlang@discover). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([collect_modules/2, collect_test_functions/1]). - --spec get_module_prefix(binary()) -> binary(). -get_module_prefix(Path) -> - Path_without_test = begin - _pipe = Path, - gleam@string:replace(_pipe, <<"./test"/utf8>>, <<""/utf8>>) - end, - Path_without_leading_slash = case gleam@string:starts_with( - Path_without_test, - <<"/"/utf8>> - ) of - true -> - gleam@string:drop_left(Path_without_test, 1); - - false -> - Path_without_test - end, - Module_prefix = begin - _pipe@1 = Path_without_leading_slash, - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"@"/utf8>>) - end, - case gleam@string:length(Module_prefix) of - 0 -> - Module_prefix; - - _ -> - <<Module_prefix/binary, "@"/utf8>> - end. - --spec collect_modules_in_folder( - binary(), - fun((showtime@internal@common@test_suite:test_module()) -> nil), - gleam@option:option(list(binary())) -) -> list(showtime@internal@common@test_suite:test_module()). -collect_modules_in_folder(Path, Test_module_handler, Only_modules) -> - Module_prefix = get_module_prefix(Path), - _assert_subject = simplifile:read_directory(Path), - {ok, Files} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_modules_in_folder"/utf8>>, - line => 40}) - end, - Test_modules_in_folder = begin - _pipe = Files, - _pipe@1 = gleam@list:filter( - _pipe, - fun(_capture) -> - gleam@string:ends_with(_capture, <<"_test.gleam"/utf8>>) - end - ), - gleam@list:filter_map( - _pipe@1, - fun(Test_module_file) -> - Module_name = <<Module_prefix/binary, - (begin - _pipe@2 = Test_module_file, - gleam@string:replace( - _pipe@2, - <<".gleam"/utf8>>, - <<""/utf8>> - ) - end)/binary>>, - case Only_modules of - {some, Only_modules_list} -> - Module_in_list = begin - _pipe@3 = Only_modules_list, - gleam@list:any( - _pipe@3, - fun(Only_module_name) -> - Only_module_name =:= begin - _pipe@4 = Module_name, - gleam@string:replace( - _pipe@4, - <<"@"/utf8>>, - <<"/"/utf8>> - ) - end - end - ) - end, - case Module_in_list of - true -> - Test_module = {test_module, - Module_name, - {some, Test_module_file}}, - Test_module_handler(Test_module), - {ok, Test_module}; - - false -> - {error, nil} - end; - - none -> - Test_module@1 = {test_module, - Module_name, - {some, Test_module_file}}, - Test_module_handler(Test_module@1), - {ok, Test_module@1} - end - end - ) - end, - Test_modules_in_subfolders = begin - _pipe@5 = Files, - _pipe@6 = gleam@list:map( - _pipe@5, - fun(Filename) -> - <<<<Path/binary, "/"/utf8>>/binary, Filename/binary>> - end - ), - _pipe@7 = gleam@list:filter( - _pipe@6, - fun(File) -> simplifile:is_directory(File) end - ), - gleam@list:fold( - _pipe@7, - [], - fun(Modules, Subfolder) -> _pipe@8 = Modules, - gleam@list:append( - _pipe@8, - collect_modules_in_folder( - Subfolder, - Test_module_handler, - Only_modules - ) - ) end - ) - end, - _pipe@9 = Test_modules_in_folder, - gleam@list:append(_pipe@9, Test_modules_in_subfolders). - --spec collect_modules( - fun((showtime@internal@common@test_suite:test_module()) -> nil), - gleam@option:option(list(binary())) -) -> list(showtime@internal@common@test_suite:test_module()). -collect_modules(Test_module_handler, Only_modules) -> - collect_modules_in_folder( - <<"./test"/utf8>>, - Test_module_handler, - Only_modules - ). - --spec collect_test_functions(showtime@internal@common@test_suite:test_module()) -> showtime@internal@common@test_suite:test_suite(). -collect_test_functions(Module) -> - Test_functions = begin - _pipe = erlang:apply( - erlang:binary_to_atom(erlang:element(2, Module)), - erlang:binary_to_atom(<<"module_info"/utf8>>), - [gleam@dynamic:from(erlang:binary_to_atom(<<"exports"/utf8>>))] - ), - gleam@dynamic:unsafe_coerce(_pipe) - end, - Test_functions_filtered = begin - _pipe@1 = Test_functions, - _pipe@3 = gleam@list:map( - _pipe@1, - fun(Entry) -> - {Name, Arity} = case Entry of - {_, _} -> Entry; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_test_functions"/utf8>>, - line => 131}) - end, - {begin - _pipe@2 = Name, - erlang:atom_to_binary(_pipe@2) - end, - Arity} - end - ), - _pipe@4 = gleam@list:filter_map( - _pipe@3, - fun(Entry@1) -> - {Name@1, Arity@1} = case Entry@1 of - {_, _} -> Entry@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_test_functions"/utf8>>, - line => 139}) - end, - case gleam@string:ends_with(Name@1, <<"_test"/utf8>>) of - true -> - case Arity@1 of - 0 -> - {ok, Name@1}; - - _ -> - gleam@io:println( - <<<<<<<<"WARNING: function \""/utf8, - Name@1/binary>>/binary, - "\" has arity: "/utf8>>/binary, - (gleam@int:to_string(Arity@1))/binary>>/binary, - " - cannot be used as test (needs to be 0)"/utf8>> - ), - {error, <<"Wrong arity"/utf8>>} - end; - - false -> - {error, <<"Non matching name"/utf8>>} - end - end - ), - _pipe@5 = gleam@list:filter( - _pipe@4, - fun(_capture) -> - gleam@string:ends_with(_capture, <<"_test"/utf8>>) - end - ), - gleam@list:map( - _pipe@5, - fun(Function_name) -> {test_function, Function_name} end - ) - end, - {test_suite, Module, Test_functions_filtered}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl deleted file mode 100644 index d72ce2c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(showtime@internal@erlang@event_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([start/0]). --export_type([event_handler_message/0]). - --type event_handler_message() :: {event_handler_message, - showtime@internal@common@test_suite:test_event(), - gleam@erlang@process:subject(integer())}. - --spec system_time() -> integer(). -system_time() -> - os:system_time(millisecond). - --spec start() -> fun((showtime@internal@common@test_suite:test_event()) -> nil). -start() -> - _assert_subject = gleam@otp@actor:start( - {not_started, 0, gleam@map:new()}, - fun(Msg, State) -> - {event_handler_message, Test_event, Reply_to} = Msg, - {Test_state, Num_done, Events} = State, - Updated_state = showtime@internal@common@common_event_handler:handle_event( - Test_event, - fun system_time/0, - {handler_state, Test_state, Num_done, Events} - ), - case Updated_state of - {handler_state, {finished, Num_modules}, Num_done@1, Events@1} when Num_done@1 =:= Num_modules -> - {Test_report, Num_failed} = showtime@internal@reports@formatter:create_test_report( - Events@1 - ), - gleam@io:println(Test_report), - gleam@erlang@process:send(Reply_to, Num_failed), - {stop, normal}; - - {handler_state, Test_state@1, Num_done@2, Events@2} -> - {continue, {Test_state@1, Num_done@2, Events@2}, none} - end - end - ), - {ok, Subject} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/event_handler"/utf8>>, - function => <<"start"/utf8>>, - line => 32}) - end, - Parent_subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - gleam@erlang@process:selecting(_pipe, Parent_subject, fun(X) -> X end) - end, - fun(Test_event@1) -> case Test_event@1 of - {end_test_run, _} -> - gleam@erlang@process:send( - Subject, - {event_handler_message, Test_event@1, Parent_subject} - ), - Num_failed@1 = gleam_erlang_ffi:select(Selector), - case Num_failed@1 > 0 of - true -> - erlang:halt(1); - - false -> - erlang:halt(0) - end; - - _ -> - gleam@erlang@process:send( - Subject, - {event_handler_message, Test_event@1, Parent_subject} - ) - end end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl deleted file mode 100644 index a6959f5..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(showtime@internal@erlang@module_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([start/5]). - --spec start( - fun((showtime@internal@common@test_suite:test_event()) -> nil), - fun((showtime@internal@common@test_suite:test_module()) -> showtime@internal@common@test_suite:test_suite()), - fun((showtime@internal@common@test_suite:test_suite(), fun((showtime@internal@common@test_suite:test_event()) -> nil), list(binary()), showtime@internal@common@cli:capture()) -> nil), - list(binary()), - showtime@internal@common@cli:capture() -) -> fun((showtime@internal@common@test_suite:test_module()) -> nil). -start( - Test_event_handler, - Test_function_collector, - Run_test_suite, - Ignore_tags, - Capture -) -> - _assert_subject = gleam@otp@actor:start( - nil, - fun(Module, State) -> - gleam@erlang@process:start( - fun() -> - Test_suite = Test_function_collector(Module), - Test_event_handler({start_test_suite, Module}), - Run_test_suite( - Test_suite, - Test_event_handler, - Ignore_tags, - Capture - ), - Test_event_handler({end_test_suite, Module}) - end, - false - ), - {continue, State, none} - end - ), - {ok, Subject} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/module_handler"/utf8>>, - function => <<"start"/utf8>>, - line => 23}) - end, - fun(Test_module) -> - gleam@erlang@process:send(Subject, Test_module), - nil - end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl deleted file mode 100644 index 702fb75..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl +++ /dev/null @@ -1,46 +0,0 @@ --module(showtime@internal@erlang@runner). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([run_test/4, run_test_suite/4]). - --spec run_test( - binary(), - binary(), - list(binary()), - showtime@internal@common@cli:capture() -) -> {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}. -run_test(Module_name, Test_name, Ignore_tags, Capture) -> - Result = showtime_ffi:run_test( - erlang:binary_to_atom(Module_name), - erlang:binary_to_atom(Test_name), - Ignore_tags, - Capture - ), - Result. - --spec run_test_suite( - showtime@internal@common@test_suite:test_suite(), - fun((showtime@internal@common@test_suite:test_event()) -> nil), - list(binary()), - showtime@internal@common@cli:capture() -) -> nil. -run_test_suite(Test_suite, Test_event_handler, Ignore_tags, Capture) -> - _pipe = erlang:element(3, Test_suite), - gleam@list:each( - _pipe, - fun(Test) -> - Test_event_handler( - {start_test, erlang:element(2, Test_suite), Test} - ), - Result = run_test( - erlang:element(2, erlang:element(2, Test_suite)), - erlang:element(2, Test), - Ignore_tags, - Capture - ), - Test_event_handler( - {end_test, erlang:element(2, Test_suite), Test, Result} - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl deleted file mode 100644 index d2969b2..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl +++ /dev/null @@ -1,61 +0,0 @@ --module(showtime@internal@reports@compare). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compare/2]). - --spec compare(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> {binary(), - binary()}. -compare(Expected, Got) -> - Expected_as_list = begin - _pipe = Expected, - (gleam@dynamic:list(fun gleam@dynamic:dynamic/1))(_pipe) - end, - Got_as_list = begin - _pipe@1 = Got, - (gleam@dynamic:list(fun gleam@dynamic:dynamic/1))(_pipe@1) - end, - Expected_as_string = begin - _pipe@2 = Expected, - gleam@dynamic:string(_pipe@2) - end, - Got_as_string = begin - _pipe@3 = Got, - gleam@dynamic:string(_pipe@3) - end, - case {Expected_as_list, Got_as_list, Expected_as_string, Got_as_string} of - {{ok, Expected_list}, {ok, Got_list}, _, _} -> - Comparison = begin - _pipe@4 = gap:compare_lists(Expected_list, Got_list), - _pipe@5 = gap@styling:from_comparison(_pipe@4), - _pipe@6 = gap@styling:highlight( - _pipe@5, - fun showtime@internal@reports@styles:expected_highlight/1, - fun showtime@internal@reports@styles:got_highlight/1, - fun(Item) -> Item end - ), - gap@styling:to_styled_comparison(_pipe@6) - end, - {erlang:element(2, Comparison), erlang:element(3, Comparison)}; - - {_, _, {ok, Expected_string}, {ok, Got_string}} -> - Comparison@1 = begin - _pipe@7 = gap:compare_strings(Expected_string, Got_string), - _pipe@8 = gap@styling:from_comparison(_pipe@7), - _pipe@9 = gap@styling:highlight( - _pipe@8, - fun showtime@internal@reports@styles:expected_highlight/1, - fun showtime@internal@reports@styles:got_highlight/1, - fun(Item@1) -> Item@1 end - ), - gap@styling:to_styled_comparison(_pipe@9) - end, - {erlang:element(2, Comparison@1), erlang:element(3, Comparison@1)}; - - {_, _, _, _} -> - {showtime@internal@reports@styles:expected_highlight( - gleam@string:inspect(Expected) - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got) - )} - end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl deleted file mode 100644 index faea091..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl +++ /dev/null @@ -1,749 +0,0 @@ --module(showtime@internal@reports@formatter). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([create_test_report/1]). --export_type([glee_unit_assertion_type/0, module_and_test/0, unified_error/0]). - --type glee_unit_assertion_type() :: {glee_unit_assert_equal, binary()} | - {glee_unit_assert_not_equal, binary()} | - {glee_unit_assert_match, binary()}. - --type module_and_test() :: {module_and_test_run, - binary(), - showtime@internal@common@test_suite:test_run()}. - --type unified_error() :: {unified_error, - gleam@option:option(showtime@tests@meta:meta()), - binary(), - binary(), - binary(), - binary(), - gleam@option:option(integer()), - list(showtime@internal@common@test_result:trace())}. - --spec erlang_error_to_unified( - list(showtime@internal@common@test_result:reason_detail()), - glee_unit_assertion_type(), - list(showtime@internal@common@test_result:trace()) -) -> unified_error(). -erlang_error_to_unified(Error_details, Assertion_type, Stacktrace) -> - _pipe = Error_details, - gleam@list:fold( - _pipe, - {unified_error, - none, - <<"not_set"/utf8>>, - erlang:element(2, Assertion_type), - <<""/utf8>>, - <<""/utf8>>, - none, - Stacktrace}, - fun(Unified, Reason) -> case Reason of - {expression, Expression} -> - erlang:setelement(3, Unified, Expression); - - {expected, Value} -> - case Assertion_type of - {glee_unit_assert_equal, _} -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - gleam@string:inspect(Value) - ) - ); - - _ -> - Unified - end; - - {value, Value@1} -> - case Assertion_type of - {glee_unit_assert_not_equal, _} -> - erlang:setelement( - 6, - erlang:setelement( - 5, - Unified, - <<(showtime@internal@reports@styles:not_style( - <<"not "/utf8>> - ))/binary, - (gleam@string:inspect(Value@1))/binary>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Value@1) - ) - ); - - _ -> - erlang:setelement( - 6, - Unified, - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Value@1) - ) - ) - end; - - {pattern, Pattern} -> - case Pattern of - <<"{ ok , _ }"/utf8>> -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - <<"Ok(_)"/utf8>> - ) - ); - - <<"{ error , _ }"/utf8>> -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - <<"Error(_)"/utf8>> - ) - ); - - _ -> - Unified - end; - - _ -> - Unified - end end - ). - --spec gleam_error_to_unified( - showtime@internal@common@test_result:gleam_error_detail(), - list(showtime@internal@common@test_result:trace()) -) -> unified_error(). -gleam_error_to_unified(Gleam_error, Stacktrace) -> - case Gleam_error of - {let_assert, _, _, _, _, Value} -> - Result = gleam@dynamic:unsafe_coerce(Value), - {error, Assertion} = case Result of - {error, _} -> Result; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/reports/formatter"/utf8>>, - function => <<"gleam_error_to_unified"/utf8>>, - line => 293}) - end, - case Assertion of - {eq, Got, Expected, Meta} -> - {Expected@1, Got@1} = showtime@internal@reports@compare:compare( - Expected, - Got - ), - {unified_error, - Meta, - <<"assert"/utf8>>, - <<"Assert equal"/utf8>>, - Expected@1, - Got@1, - none, - Stacktrace}; - - {not_eq, Got@2, Expected@2, Meta@1} -> - {unified_error, - Meta@1, - <<"assert"/utf8>>, - <<"Assert not equal"/utf8>>, - <<(showtime@internal@reports@styles:not_style( - <<"not "/utf8>> - ))/binary, - (gleam@string:inspect(Expected@2))/binary>>, - gleam@string:inspect(Got@2), - none, - Stacktrace}; - - {is_ok, Got@3, Meta@2} -> - {unified_error, - Meta@2, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:expected_highlight( - <<"Ok(_)"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got@3) - ), - none, - Stacktrace}; - - {is_error, Got@4, Meta@3} -> - {unified_error, - Meta@3, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:expected_highlight( - <<"Error(_)"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got@4) - ), - none, - Stacktrace}; - - {fail, Meta@4} -> - {unified_error, - Meta@4, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:got_highlight( - <<"should.fail()"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - <<"N/A - test always expected to fail"/utf8>> - ), - none, - Stacktrace} - end - end. - --spec format_reason(unified_error(), binary(), binary(), list(binary())) -> list(list(showtime@internal@reports@table:col())). -format_reason(Error, Module, Function, Output_buffer) -> - Meta@1 = case erlang:element(2, Error) of - {some, Meta} -> - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Description"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, {content, erlang:element(2, Meta)}, 0}]}; - - none -> - none - end, - Stacktrace = begin - _pipe = erlang:element(8, Error), - gleam@list:map(_pipe, fun(Trace) -> case Trace of - {trace, Function@1, _, _} when Function@1 =:= <<""/utf8>> -> - <<"(anonymous)"/utf8>>; - - {trace_module, Module@1, Function@2, _, _} when Function@2 =:= <<""/utf8>> -> - <<<<Module@1/binary, "."/utf8>>/binary, - "(anonymous)"/utf8>>; - - {trace, Function@3, _, _} -> - Function@3; - - {trace_module, Module@2, Function@4, _, _} -> - <<<<Module@2/binary, "."/utf8>>/binary, - Function@4/binary>> - end end) - end, - Stacktrace_rows = case Stacktrace of - [] -> - []; - - [First | Rest] -> - First_row = {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Stacktrace"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - First - )}, - 0}]}, - Rest_rows = begin - _pipe@1 = Rest, - gleam@list:map( - _pipe@1, - fun(Row) -> - {some, - [{align_right, {content, <<""/utf8>>}, 2}, - {separator, <<" "/utf8>>}, - {align_left, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - Row - )}, - 0}]} - end - ) - end, - [First_row | Rest_rows] - end, - Output_rows = case begin - _pipe@2 = Output_buffer, - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:map( - _pipe@3, - fun(Row@1) -> gleam@string:trim_right(Row@1) end - ) - end of - [] -> - []; - - [First@1 | Rest@1] -> - First_row@1 = {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Output"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - First@1 - )}, - 0}]}, - Rest_rows@1 = begin - _pipe@4 = Rest@1, - gleam@list:map( - _pipe@4, - fun(Row@2) -> - {some, - [{align_right, {content, <<""/utf8>>}, 2}, - {separator, <<" "/utf8>>}, - {align_left_overflow, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - Row@2 - )}, - 0}]} - end - ) - end, - [First_row@1 | Rest_rows@1] - end, - Line@1 = begin - _pipe@5 = erlang:element(7, Error), - _pipe@6 = gleam@option:map( - _pipe@5, - fun(Line) -> <<":"/utf8, (gleam@int:to_string(Line))/binary>> end - ), - gleam@option:unwrap(_pipe@6, <<""/utf8>>) - end, - Arrow = <<(gleam@string:join( - gleam@list:repeat( - <<"-"/utf8>>, - (gleam@string:length(Module) + 1) + ((gleam@string:length( - Function - ) - + gleam@string:length(Line@1)) - div 2) - ), - <<""/utf8>> - ))/binary, - "⌄"/utf8>>, - Standard_table_rows = [{some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:error_style( - <<"Failed"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, {content, Arrow}, 0}]}, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Test"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, - {styled_content, - <<<<Module/binary, "."/utf8>>/binary, - (showtime@internal@reports@styles:function_style( - <<Function/binary, Line@1/binary>> - ))/binary>>}, - 0}]}, - Meta@1, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Expected"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, erlang:element(5, Error)}, - 0}]}, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Got"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, erlang:element(6, Error)}, - 0}]}], - _pipe@7 = Standard_table_rows, - _pipe@8 = gleam@list:append(_pipe@7, Stacktrace_rows), - _pipe@9 = gleam@list:append(_pipe@8, Output_rows), - _pipe@10 = gleam@list:append( - _pipe@9, - [{some, - [{align_right, {content, <<""/utf8>>}, 0}, - {align_right, {content, <<""/utf8>>}, 0}, - {align_right, {content, <<""/utf8>>}, 0}]}] - ), - gleam@list:filter_map( - _pipe@10, - fun(Row@3) -> gleam@option:to_result(Row@3, nil) end - ). - --spec create_test_report( - gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@internal@common@test_suite:test_run())) -) -> {binary(), integer()}. -create_test_report(Test_results) -> - All_test_runs = begin - _pipe = Test_results, - _pipe@1 = gleam@map:values(_pipe), - gleam@list:flat_map(_pipe@1, fun gleam@map:values/1) - end, - Failed_test_runs = begin - _pipe@2 = Test_results, - _pipe@3 = gleam@map:to_list(_pipe@2), - gleam@list:flat_map( - _pipe@3, - fun(Entry) -> - {Module_name, Test_module_results} = Entry, - _pipe@4 = Test_module_results, - _pipe@5 = gleam@map:values(_pipe@4), - gleam@list:filter_map(_pipe@5, fun(Test_run) -> case Test_run of - {completed_test_run, _, _, Result} -> - case Result of - {error, _} -> - {ok, - {module_and_test_run, - Module_name, - Test_run}}; - - {ok, {ignored, _}} -> - {error, nil}; - - {ok, _} -> - {error, nil} - end; - - _ -> - _pipe@6 = Test_run, - gleam@io:debug(_pipe@6), - {error, nil} - end end) - end - ) - end, - Ignored_test_runs = begin - _pipe@7 = Test_results, - _pipe@8 = gleam@map:to_list(_pipe@7), - gleam@list:flat_map( - _pipe@8, - fun(Entry@1) -> - {Module_name@1, Test_module_results@1} = Entry@1, - _pipe@9 = Test_module_results@1, - _pipe@10 = gleam@map:values(_pipe@9), - gleam@list:filter_map( - _pipe@10, - fun(Test_run@1) -> case Test_run@1 of - {completed_test_run, Test_function, _, Result@1} -> - case Result@1 of - {ok, {ignored, Reason}} -> - {ok, - {<<<<Module_name@1/binary, - "."/utf8>>/binary, - (erlang:element( - 2, - Test_function - ))/binary>>, - Reason}}; - - _ -> - {error, nil} - end; - - _ -> - {error, nil} - end end - ) - end - ) - end, - Failed_tests_report = begin - _pipe@11 = Failed_test_runs, - _pipe@12 = gleam@list:filter_map( - _pipe@11, - fun(Module_and_test_run) -> - case erlang:element(3, Module_and_test_run) of - {completed_test_run, Test_function@1, _, Result@2} -> - case Result@2 of - {error, Exception} -> - case erlang:element(3, Exception) of - {assert_equal, Reason_details} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details, - {glee_unit_assert_equal, - <<"Assert equal"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {assert_not_equal, Reason_details@1} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details@1, - {glee_unit_assert_not_equal, - <<"Assert not equal"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {assert_match, Reason_details@2} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details@2, - {glee_unit_assert_match, - <<"Assert match"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {gleam_error, Reason@1} -> - {ok, - format_reason( - gleam_error_to_unified( - Reason@1, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {gleam_assert, Value, Line_no} -> - {ok, - format_reason( - {unified_error, - none, - <<"gleam assert"/utf8>>, - <<"Assert failed"/utf8>>, - <<"Patterns should match"/utf8>>, - showtime@internal@reports@styles:error_style( - gleam@string:inspect( - Value - ) - ), - {some, Line_no}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - )}, - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {generic_exception, Value@1} -> - {ok, - format_reason( - {unified_error, - none, - <<"generic exception"/utf8>>, - <<"Test function threw an exception"/utf8>>, - <<"Exception in test function"/utf8>>, - showtime@internal@reports@styles:error_style( - gleam@string:inspect( - Value@1 - ) - ), - none, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - )}, - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - Other -> - gleam@io:println( - <<"Other: "/utf8, - (gleam@string:inspect(Other))/binary>> - ), - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"showtime/internal/reports/formatter"/utf8>>, - function => <<"create_test_report"/utf8>>, - line => 178}), - {error, nil} - end; - - _ -> - {error, nil} - end; - - _ -> - {error, nil} - end - end - ), - gleam@list:fold( - _pipe@12, - [], - fun(Rows, Test_rows) -> gleam@list:append(Rows, Test_rows) end - ) - end, - All_test_execution_time_reports = begin - _pipe@13 = All_test_runs, - gleam@list:filter_map(_pipe@13, fun(Test_run@2) -> case Test_run@2 of - {completed_test_run, Test_function@2, Total_time, _} -> - {ok, - <<<<<<(erlang:element(2, Test_function@2))/binary, - ": "/utf8>>/binary, - (gleam@int:to_string(Total_time))/binary>>/binary, - " ms"/utf8>>}; - - _ -> - {error, nil} - end end) - end, - _ = begin - _pipe@14 = All_test_execution_time_reports, - gleam@string:join(_pipe@14, <<"\n"/utf8>>) - end, - All_tests_count = begin - _pipe@15 = All_test_runs, - gleam@list:length(_pipe@15) - end, - Ignored_tests_count = begin - _pipe@16 = Ignored_test_runs, - gleam@list:length(_pipe@16) - end, - Failed_tests_count = begin - _pipe@17 = Failed_test_runs, - gleam@list:length(_pipe@17) - end, - Passed = showtime@internal@reports@styles:passed_style( - <<(gleam@int:to_string( - (All_tests_count - Failed_tests_count) - Ignored_tests_count - ))/binary, - " passed"/utf8>> - ), - Failed = showtime@internal@reports@styles:failed_style( - <<(gleam@int:to_string(Failed_tests_count))/binary, " failed"/utf8>> - ), - Ignored = case Ignored_tests_count of - 0 -> - <<""/utf8>>; - - _ -> - <<", "/utf8, - (showtime@internal@reports@styles:ignored_style( - <<(gleam@int:to_string(Ignored_tests_count))/binary, - " ignored"/utf8>> - ))/binary>> - end, - Failed_tests_table = begin - _pipe@18 = {table, none, Failed_tests_report}, - _pipe@19 = showtime@internal@reports@table:align_table(_pipe@18), - showtime@internal@reports@table:to_string(_pipe@19) - end, - Test_report = <<<<<<<<<<<<"\n"/utf8, Failed_tests_table/binary>>/binary, - "\n"/utf8>>/binary, - Passed/binary>>/binary, - ", "/utf8>>/binary, - Failed/binary>>/binary, - Ignored/binary>>, - {Test_report, Failed_tests_count}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl deleted file mode 100644 index ec6230c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl +++ /dev/null @@ -1,93 +0,0 @@ --module(showtime@internal@reports@styles). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([not_style/1, module_style/1, heading_style/1, stacktrace_style/1, failed_style/1, error_style/1, got_highlight/1, passed_style/1, expected_highlight/1, ignored_style/1, function_style/1, strip_style/1]). - --spec not_style(binary()) -> binary(). -not_style(Text) -> - gleam_community@ansi:bold(Text). - --spec module_style(binary()) -> binary(). -module_style(Text) -> - gleam_community@ansi:cyan(Text). - --spec heading_style(binary()) -> binary(). -heading_style(Text) -> - gleam_community@ansi:cyan(Text). - --spec stacktrace_style(binary()) -> binary(). -stacktrace_style(Text) -> - Text. - --spec bold_red(binary()) -> binary(). -bold_red(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:red(Text)). - --spec failed_style(binary()) -> binary(). -failed_style(Text) -> - bold_red(Text). - --spec error_style(binary()) -> binary(). -error_style(Text) -> - bold_red(Text). - --spec got_highlight(binary()) -> binary(). -got_highlight(Text) -> - bold_red(Text). - --spec bold_green(binary()) -> binary(). -bold_green(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:green(Text)). - --spec passed_style(binary()) -> binary(). -passed_style(Text) -> - bold_green(Text). - --spec expected_highlight(binary()) -> binary(). -expected_highlight(Text) -> - bold_green(Text). - --spec bold_yellow(binary()) -> binary(). -bold_yellow(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:yellow(Text)). - --spec ignored_style(binary()) -> binary(). -ignored_style(Text) -> - bold_yellow(Text). - --spec bold_cyan(binary()) -> binary(). -bold_cyan(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:cyan(Text)). - --spec function_style(binary()) -> binary(). -function_style(Text) -> - bold_cyan(Text). - --spec strip_style(binary()) -> binary(). -strip_style(Text) -> - {New_text, _} = begin - _pipe = Text, - _pipe@1 = gleam@string:to_graphemes(_pipe), - gleam@list:fold( - _pipe@1, - {<<""/utf8>>, false}, - fun(Acc, Char) -> - {Str, Removing} = Acc, - Bit_char = gleam_stdlib:identity(Char), - case {Bit_char, Removing} of - {<<16#1b>>, _} -> - {Str, true}; - - {<<16#6d>>, true} -> - {Str, false}; - - {_, true} -> - {Str, true}; - - {_, false} -> - {<<Str/binary, Char/binary>>, false} - end - end - ) - end, - New_text. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl deleted file mode 100644 index 35dbba3..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl +++ /dev/null @@ -1,229 +0,0 @@ --module(showtime@internal@reports@table). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_string/1, align_table/1]). --export_type([content/0, col/0, table/0]). - --type content() :: {content, binary()} | {styled_content, binary()}. - --type col() :: {align_right, content(), integer()} | - {align_left, content(), integer()} | - {align_right_overflow, content(), integer()} | - {align_left_overflow, content(), integer()} | - {separator, binary()} | - {aligned, binary()}. - --type table() :: {table, gleam@option:option(binary()), list(list(col()))}. - --spec to_string(table()) -> binary(). -to_string(Table) -> - Rows = begin - _pipe = erlang:element(3, Table), - _pipe@3 = gleam@list:map(_pipe, fun(Row) -> _pipe@1 = Row, - _pipe@2 = gleam@list:filter_map(_pipe@1, fun(Col) -> case Col of - {separator, Char} -> - {ok, Char}; - - {aligned, Content} -> - {ok, Content}; - - _ -> - {error, nil} - end end), - gleam@string:join(_pipe@2, <<""/utf8>>) end), - gleam@string:join(_pipe@3, <<"\n"/utf8>>) - end, - Header@1 = begin - _pipe@4 = erlang:element(2, Table), - _pipe@5 = gleam@option:map( - _pipe@4, - fun(Header) -> <<Header/binary, "\n"/utf8>> end - ), - gleam@option:unwrap(_pipe@5, <<""/utf8>>) - end, - <<Header@1/binary, Rows/binary>>. - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(Str, Num, Char) -> - Padding = begin - _pipe = gleam@list:repeat(Char, Num), - gleam@string:join(_pipe, <<""/utf8>>) - end, - <<Padding/binary, Str/binary>>. - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(Str, Num, Char) -> - Padding = begin - _pipe = gleam@list:repeat(Char, Num), - gleam@string:join(_pipe, <<""/utf8>>) - end, - <<Str/binary, Padding/binary>>. - --spec align_table(table()) -> table(). -align_table(Table) -> - Cols = begin - _pipe = erlang:element(3, Table), - gleam@list:transpose(_pipe) - end, - Col_width = begin - _pipe@1 = Cols, - gleam@list:map(_pipe@1, fun(Col) -> _pipe@2 = Col, - _pipe@3 = gleam@list:map( - _pipe@2, - fun(Content) -> case Content of - {align_right, {content, Unstyled}, _} -> - Unstyled; - - {align_right, {styled_content, Styled}, _} -> - showtime@internal@reports@styles:strip_style( - Styled - ); - - {align_left, {content, Unstyled@1}, _} -> - Unstyled@1; - - {align_left, {styled_content, Styled@1}, _} -> - showtime@internal@reports@styles:strip_style( - Styled@1 - ); - - {align_left_overflow, _, _} -> - <<""/utf8>>; - - {align_right_overflow, _, _} -> - <<""/utf8>>; - - {separator, Char} -> - Char; - - {aligned, Content@1} -> - Content@1 - end end - ), - gleam@list:fold( - _pipe@3, - 0, - fun(Max, Str) -> - gleam@int:max(Max, gleam@string:length(Str)) - end - ) end) - end, - Aligned_col = begin - _pipe@4 = Cols, - _pipe@5 = gleam@list:zip(_pipe@4, Col_width), - gleam@list:map( - _pipe@5, - fun(Col_and_width) -> - {Col@1, Width} = Col_and_width, - _pipe@6 = Col@1, - gleam@list:map(_pipe@6, fun(Content@2) -> case Content@2 of - {align_right, {content, Unstyled@2}, Margin} -> - {aligned, - pad_left( - Unstyled@2, - (Width + Margin) - gleam@string:length( - Unstyled@2 - ), - <<" "/utf8>> - )}; - - {align_right, {styled_content, Styled@2}, Margin@1} -> - {aligned, - pad_left( - Styled@2, - (Width + Margin@1) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@2 - ) - ), - <<" "/utf8>> - )}; - - {align_right_overflow, - {content, Unstyled@3}, - Margin@2} -> - {aligned, - pad_left( - Unstyled@3, - (Width + Margin@2) - gleam@string:length( - Unstyled@3 - ), - <<" "/utf8>> - )}; - - {align_right_overflow, - {styled_content, Styled@3}, - Margin@3} -> - {aligned, - pad_left( - Styled@3, - (Width + Margin@3) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@3 - ) - ), - <<" "/utf8>> - )}; - - {align_left, {content, Unstyled@4}, Margin@4} -> - {aligned, - pad_right( - Unstyled@4, - (Width + Margin@4) - gleam@string:length( - Unstyled@4 - ), - <<" "/utf8>> - )}; - - {align_left, {styled_content, Styled@4}, Margin@5} -> - {aligned, - pad_right( - Styled@4, - (Width + Margin@5) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@4 - ) - ), - <<" "/utf8>> - )}; - - {align_left_overflow, - {content, Unstyled@5}, - Margin@6} -> - {aligned, - pad_right( - Unstyled@5, - (Width + Margin@6) - gleam@string:length( - Unstyled@5 - ), - <<" "/utf8>> - )}; - - {align_left_overflow, - {styled_content, Styled@5}, - Margin@7} -> - {aligned, - pad_right( - Styled@5, - (Width + Margin@7) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@5 - ) - ), - <<" "/utf8>> - )}; - - {separator, Char@1} -> - {separator, Char@1}; - - {aligned, Content@3} -> - {aligned, Content@3} - end end) - end - ) - end, - Aligned_rows = begin - _pipe@7 = Aligned_col, - gleam@list:transpose(_pipe@7) - end, - erlang:setelement(3, Table, Aligned_rows). diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl b/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl deleted file mode 100644 index c975467..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(showtime@tests@meta). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([meta/0]). - --type meta() :: {meta, binary(), list(binary())}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@should.erl b/aoc2023/build/packages/adglent/src/showtime@tests@should.erl deleted file mode 100644 index 29906b4..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@should.erl +++ /dev/null @@ -1,143 +0,0 @@ --module(showtime@tests@should). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([evaluate/1, equal/2, equal_meta/3, not_equal/2, not_equal_meta/3, be_ok/1, be_ok_meta/2, be_error/1, be_error_meta/2, fail/0, fail_meta/1, be_true/1, be_true_meta/2, be_false/1, be_false_meta/2]). --export_type([assertion/2]). - --type assertion(MXP, MXQ) :: {eq, - MXP, - MXP, - gleam@option:option(showtime@tests@meta:meta())} | - {not_eq, MXP, MXP, gleam@option:option(showtime@tests@meta:meta())} | - {is_ok, - {ok, MXP} | {error, MXQ}, - gleam@option:option(showtime@tests@meta:meta())} | - {is_error, - {ok, MXP} | {error, MXQ}, - gleam@option:option(showtime@tests@meta:meta())} | - {fail, gleam@option:option(showtime@tests@meta:meta())}. - --spec evaluate(assertion(any(), any())) -> nil. -evaluate(Assertion) -> - case Assertion of - {eq, A, B, _} -> - case A =:= B of - true -> - nil; - - false -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {not_eq, A@1, B@1, _} -> - case A@1 /= B@1 of - true -> - nil; - - false -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {is_ok, A@2, _} -> - case A@2 of - {ok, _} -> - nil; - - {error, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {is_error, A@3, _} -> - case A@3 of - {error, _} -> - nil; - - {ok, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {fail, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end. - --spec equal(MXR, MXR) -> nil. -equal(A, B) -> - evaluate({eq, A, B, none}). - --spec equal_meta(MXT, MXT, showtime@tests@meta:meta()) -> nil. -equal_meta(A, B, Meta) -> - evaluate({eq, A, B, {some, Meta}}). - --spec not_equal(MXV, MXV) -> nil. -not_equal(A, B) -> - evaluate({not_eq, A, B, none}). - --spec not_equal_meta(MXX, MXX, showtime@tests@meta:meta()) -> nil. -not_equal_meta(A, B, Meta) -> - evaluate({not_eq, A, B, {some, Meta}}). - --spec be_ok({ok, MXZ} | {error, any()}) -> MXZ. -be_ok(A) -> - evaluate({is_ok, A, none}), - {ok, Value} = case A of - {ok, _} -> A; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/tests/should"/utf8>>, - function => <<"be_ok"/utf8>>, - line => 30}) - end, - Value. - --spec be_ok_meta({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_ok_meta(A, Meta) -> - evaluate({is_ok, A, {some, Meta}}). - --spec be_error({ok, any()} | {error, MYK}) -> MYK. -be_error(A) -> - evaluate({is_error, A, none}), - {error, Value} = case A of - {error, _} -> A; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/tests/should"/utf8>>, - function => <<"be_error"/utf8>>, - line => 40}) - end, - Value. - --spec be_error_meta({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_error_meta(A, Meta) -> - evaluate({is_error, A, {some, Meta}}). - --spec fail() -> nil. -fail() -> - evaluate({fail, none}). - --spec fail_meta(showtime@tests@meta:meta()) -> nil. -fail_meta(Meta) -> - evaluate({fail, {some, Meta}}). - --spec be_true(boolean()) -> nil. -be_true(A) -> - _pipe = A, - equal(_pipe, true). - --spec be_true_meta(boolean(), showtime@tests@meta:meta()) -> nil. -be_true_meta(A, Meta) -> - _pipe = A, - equal_meta(_pipe, true, Meta). - --spec be_false(boolean()) -> nil. -be_false(A) -> - _pipe = A, - equal(_pipe, false). - --spec be_false_meta(boolean(), showtime@tests@meta:meta()) -> nil. -be_false_meta(A, Meta) -> - _pipe = A, - equal_meta(_pipe, false, Meta). diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@test.erl b/aoc2023/build/packages/adglent/src/showtime@tests@test.erl deleted file mode 100644 index 2f23b9f..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@test.erl +++ /dev/null @@ -1,57 +0,0 @@ --module(showtime@tests@test). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([test/2, equal/3, not_equal/3, with_meta/2, be_ok/2, be_error/2, fail/1, be_true/2, be_false/2]). --export_type([test/0, meta_should/1]). - --type test() :: {test, showtime@tests@meta:meta(), fun(() -> nil)}. - --type meta_should(NDO) :: {meta_should, - fun((NDO, NDO) -> nil), - fun((NDO, NDO) -> nil)}. - --spec test(showtime@tests@meta:meta(), fun((showtime@tests@meta:meta()) -> nil)) -> test(). -test(Meta, Test_function) -> - {test, Meta, fun() -> Test_function(Meta) end}. - --spec equal(NDT, NDT, showtime@tests@meta:meta()) -> nil. -equal(A, B, Meta) -> - gleam@io:debug(A), - gleam@io:debug(B), - showtime@tests@should:equal_meta(A, B, Meta). - --spec not_equal(NDV, NDV, showtime@tests@meta:meta()) -> nil. -not_equal(A, B, Meta) -> - showtime@tests@should:equal_meta(A, B, Meta). - --spec with_meta(showtime@tests@meta:meta(), fun((meta_should(any())) -> nil)) -> test(). -with_meta(Meta, Test_function) -> - {test, - Meta, - fun() -> - Test_function( - {meta_should, - fun(A, B) -> equal(A, B, Meta) end, - fun(A@1, B@1) -> not_equal(A@1, B@1, Meta) end} - ) - end}. - --spec be_ok({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_ok(A, Meta) -> - showtime@tests@should:be_ok_meta(A, Meta). - --spec be_error({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_error(A, Meta) -> - showtime@tests@should:be_error_meta(A, Meta). - --spec fail(showtime@tests@meta:meta()) -> nil. -fail(Meta) -> - showtime@tests@should:fail_meta(Meta). - --spec be_true(boolean(), showtime@tests@meta:meta()) -> nil. -be_true(A, Meta) -> - showtime@tests@should:be_true_meta(A, Meta). - --spec be_false(boolean(), showtime@tests@meta:meta()) -> nil. -be_false(A, Meta) -> - showtime@tests@should:be_false_meta(A, Meta). diff --git a/aoc2023/build/packages/adglent/src/showtime_ffi.erl b/aoc2023/build/packages/adglent/src/showtime_ffi.erl deleted file mode 100644 index 3259623..0000000 --- a/aoc2023/build/packages/adglent/src/showtime_ffi.erl +++ /dev/null @@ -1,187 +0,0 @@ --module(showtime_ffi). - --export([run_test/4, functions/0, capture_output/1, gleam_error/1]). - -gleam_error(Value) -> - erlang:error(#{ - gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => Value, - module => <<"this/is/not/used"/utf8>>, - function => <<"gleam_error"/utf8>>, - % Not used - line => 0 - }). - -start_output_capture(Capture) -> - OldGroupLeader = group_leader(), - CapturePid = spawn(showtime_ffi, capture_output, [{[], {OldGroupLeader, Capture}}]), - group_leader(CapturePid, self()), - {CapturePid, OldGroupLeader}. - -stop_output_capture({CapturePid, OldGroupLeader}) -> - group_leader(OldGroupLeader, self()), - CapturePid ! {capture_done, self()}, - receive - Buffer -> - Buffer - end. - -capture_output({Buffer, {OldGroupLeader, Capture}}) -> - receive - {io_request, From, ReplyAs, {put_chars, unicode, BitString}} -> - case Capture of - yes -> - From ! {io_reply, ReplyAs, ok}, - capture_output({[BitString | Buffer], {OldGroupLeader, Capture}}); - mixed -> - OldGroupLeader ! {io_request, From, ReplyAs, {put_chars, unicode, BitString}}, - capture_output({[BitString | Buffer], {OldGroupLeader, Capture}}); - no -> - OldGroupLeader ! {io_request, From, ReplyAs, {put_chars, unicode, BitString}}, - capture_output({Buffer, {OldGroupLeader, Capture}}) - end; - {capture_done, SenderPid} -> - SenderPid ! Buffer; - OtherMessage -> - OldGroupLeader ! OtherMessage, - capture_output({Buffer, {OldGroupLeader, Capture}}) - end. - -run_test(Module, Function, IgnoreTags, Capture) -> - OutputCapture = start_output_capture(Capture), - try - Result = apply(Module, Function, []), - {ResultType, FinalResult} = - case Result of - {test, {meta, _Description, Tags}, TestFun} -> - case - lists:any( - fun(Tag) -> - lists:any(fun(IgnoreTag) -> IgnoreTag == Tag end, IgnoreTags) - end, - Tags - ) - of - true -> - {ignored, ignore}; - false -> - {test_function_return, TestFun()} - end; - DirectResult -> - {test_function_return, DirectResult} - end, - OutputCaptureBuffer = stop_output_capture(OutputCapture), - case ResultType of - ignored -> {ok, {ResultType, FinalResult}}; - _ -> {ok, {ResultType, FinalResult, OutputCaptureBuffer}} - end - catch - Class:Reason:Stacktrace -> - GleamReason = - case Reason of - {Assertion, ReasonList} -> - ErlangReasonList = - lists:map( - fun(ReasonDetail) -> - case ReasonDetail of - {line, LineNo} -> - {reason_line, LineNo}; - {expression, List} -> - {expression, list_to_binary(List)}; - {module, ModuleAtom} -> - {module, atom_to_binary(ModuleAtom)}; - {pattern, Pattern} -> - {pattern, list_to_binary(Pattern)}; - Other -> - Other - end - end, - ReasonList - ), - GleamAssertionType = - case Assertion of - assertEqual -> - assert_equal; - assertNotEqual -> - assert_not_equal; - assertMatch -> - assert_match; - OtherAssertionType -> - OtherAssertionType - end, - {GleamAssertionType, ErlangReasonList}; - #{ - function := GleamFunction, - gleam_error := GleamError, - line := Line, - message := Message, - module := GleamModule, - value := Value - } -> - case Value of - {error, {OkValue, _, _, _}} when OkValue == not_eq; OkValue == eq -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - {error, {OkValue, _, _}} when OkValue == is_ok; OkValue == is_error -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - {error, {OkValue, _}} when OkValue == fail -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - _ -> - {gleam_assert, Value, Line} - end; - OtherReason -> - {generic_exception, OtherReason} - end, - GleamClass = - case Class of - error -> - erlang_error; - Other -> - Other - end, - GleamTraceList = - lists:map( - fun(Trace) -> - case Trace of - {ModuleName, FunctionName, Arity, ExtraInfoList} -> - {trace_module, atom_to_binary(ModuleName), - atom_to_binary(FunctionName), map_arity(Arity), - map_extra_info_list(ExtraInfoList)}; - {FunctionName, Arity, ExtraInfoList} -> - {trace, atom_to_binary(FunctionName), map_arity(Arity), - map_extra_info_list(ExtraInfoList)} - end - end, - Stacktrace - ), - OutputCaptureBufferCatch = stop_output_capture(OutputCapture), - {error, - {erlang_exception, GleamClass, GleamReason, {trace_list, GleamTraceList}, - OutputCaptureBufferCatch}} - end. - -map_extra_info_list(ExtraInfoList) -> - lists:map( - fun(ExtraInfo) -> - case ExtraInfo of - {file, FileNameList} -> {file, list_to_binary(FileNameList)}; - Other -> Other - end - end, - ExtraInfoList - ). - -map_arity(Arity) -> - if - is_list(Arity) -> - {arg_list, Arity}; - is_integer(Arity) -> - {num, Arity} - end. - -functions() -> - Funs = module_info(exports), - Funs. |