-module(testament). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/testament.gleam"). -export([main/0, test_main_with_opts/2, test_main/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/testament.gleam", 16). -spec main() -> nil. main() -> case erlang:element(4, argv:load()) of [<<"clean"/utf8>>] -> _ = testament@internal@util:clean_doc_tests(), nil; [<<"clean"/utf8>>, <<"all"/utf8>>] -> _ = testament@internal@util:clean_doc_tests(), _ = simplifile_erl:delete( filepath:join(<<"test"/utf8>>, <<"testament"/utf8>>) ), nil; [<<"-h"/utf8>>] -> gleam_stdlib:println( <<"📖 Testament Doc tests for gleam! ✨ - `clean`: delete doc test files - `clean all`: delete all doc test files (useful after code reorgs) 'test/**/*_doc_test.gleam' - `help`: prints this help message ----------------------- Usage: Write some beautiful gleam code with Doc Comments ```gleam ////Example Module ////```gleam ////: assert 1 + 1 == 2 ////``` ///adds two Ints ///```gleam ///: assert example.add(1, 2) == 3 ///: assert example.add(1, -1) == 0 /// ``` pub fn add(a: Int, b: Int) -> Int { a + b } ``` Add testament to your test's main function ```gleam import gleeunit import testament pub fn main() -> Nil { testament.test_main(gleeunit.main) } ``` Enjoy ```bash gleam test Compiling example Compiled in 0.44s Running example_test.main . 1 tests, no failures ``` "/utf8>> ); [<<"h"/utf8>>] -> gleam_stdlib:println( <<"📖 Testament Doc tests for gleam! ✨ - `clean`: delete doc test files - `clean all`: delete all doc test files (useful after code reorgs) 'test/**/*_doc_test.gleam' - `help`: prints this help message ----------------------- Usage: Write some beautiful gleam code with Doc Comments ```gleam ////Example Module ////```gleam ////: assert 1 + 1 == 2 ////``` ///adds two Ints ///```gleam ///: assert example.add(1, 2) == 3 ///: assert example.add(1, -1) == 0 /// ``` pub fn add(a: Int, b: Int) -> Int { a + b } ``` Add testament to your test's main function ```gleam import gleeunit import testament pub fn main() -> Nil { testament.test_main(gleeunit.main) } ``` Enjoy ```bash gleam test Compiling example Compiled in 0.44s Running example_test.main . 1 tests, no failures ``` "/utf8>> ); [<<"--help"/utf8>>] -> gleam_stdlib:println( <<"📖 Testament Doc tests for gleam! ✨ - `clean`: delete doc test files - `clean all`: delete all doc test files (useful after code reorgs) 'test/**/*_doc_test.gleam' - `help`: prints this help message ----------------------- Usage: Write some beautiful gleam code with Doc Comments ```gleam ////Example Module ////```gleam ////: assert 1 + 1 == 2 ////``` ///adds two Ints ///```gleam ///: assert example.add(1, 2) == 3 ///: assert example.add(1, -1) == 0 /// ``` pub fn add(a: Int, b: Int) -> Int { a + b } ``` Add testament to your test's main function ```gleam import gleeunit import testament pub fn main() -> Nil { testament.test_main(gleeunit.main) } ``` Enjoy ```bash gleam test Compiling example Compiled in 0.44s Running example_test.main . 1 tests, no failures ``` "/utf8>> ); [<<"help"/utf8>>] -> gleam_stdlib:println( <<"📖 Testament Doc tests for gleam! ✨ - `clean`: delete doc test files - `clean all`: delete all doc test files (useful after code reorgs) 'test/**/*_doc_test.gleam' - `help`: prints this help message ----------------------- Usage: Write some beautiful gleam code with Doc Comments ```gleam ////Example Module ////```gleam ////: assert 1 + 1 == 2 ////``` ///adds two Ints ///```gleam ///: assert example.add(1, 2) == 3 ///: assert example.add(1, -1) == 0 /// ``` pub fn add(a: Int, b: Int) -> Int { a + b } ``` Add testament to your test's main function ```gleam import gleeunit import testament pub fn main() -> Nil { testament.test_main(gleeunit.main) } ``` Enjoy ```bash gleam test Compiling example Compiled in 0.44s Running example_test.main . 1 tests, no failures ``` "/utf8>> ); _ -> gleam_stdlib:print_error(<<"Unknown command"/utf8>>), shellout_ffi:os_exit(1) end. -file("src/testament.gleam", 66). ?DOC( "Add testament to your test's main function and you're good to go!\n" "You can use gleeunit or any other testing framework.\n" "- Config options [here](https://hexdocs.pm/testament/testament/conf.html)\n" " ```gleam\n" " import gleeunit\n" " import testament\n" " import testament/conf\n" "\n" " pub fn main() -> Nil {\n" " testament.test_main_with_opts(gleeunit.main, [conf.IgnoreFiles([\"src/example.gleam\"])])\n" " }\n" " ```\n" ). -spec test_main_with_opts(fun(() -> nil), list(testament@conf:conf())) -> nil. test_main_with_opts(Run_tests, Opts) -> Cfg = testament@internal@util:combine_conf_values(Opts), case envoy_ffi:get(<<"TESTAMENT_WITH_DOCS"/utf8>>) of {ok, _} -> Run_tests(); {error, _} -> testament@internal@util:verbose_log( erlang:element(3, Cfg), <<"reading src directory"/utf8>> ), Files@1 = case simplifile:get_files(<<"src"/utf8>>) of {ok, Files} -> Files; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"could not read 'src' directory"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 74, value => _assert_fail, start => 1768, 'end' => 1818, pattern_start => 1779, pattern_end => 1788}) end, Files@2 = gleam@list:filter( Files@1, fun(F) -> gleam_stdlib:string_ends_with(F, <<".gleam"/utf8>>) andalso not gleam@list:contains( erlang:element(2, Cfg), F ) end ), case gleam@list:try_each( Files@2, fun(File) -> testament@internal@util:verbose_log( erlang:element(3, Cfg), <<"creating doc tests for: "/utf8, File/binary>> ), Imports = begin _pipe = gleam_stdlib:map_get( erlang:element(5, Cfg), File ), _pipe@1 = gleam@result:unwrap(_pipe, []), _pipe@2 = gleam@list:prepend( _pipe@1, {import, testament@internal@util:import_from_file_name( File ), []} ), testament@internal@util:combine_unqualified(_pipe@2) end, testament@internal@util:create_tests_for_file(File, Imports) end ) of {ok, nil} -> nil; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"failed to read source files"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 83, value => _assert_fail@1, start => 2029, 'end' => 2454, pattern_start => 2040, pattern_end => 2047}) end, case gleam@list:try_each( erlang:element(6, Cfg), fun(File@1) -> testament@internal@util:verbose_log( erlang:element(3, Cfg), <<"creating doc tests for: "/utf8, File@1/binary>> ), Imports@1 = begin _pipe@3 = gleam_stdlib:map_get( erlang:element(5, Cfg), File@1 ), _pipe@4 = gleam@result:unwrap(_pipe@3, []), testament@internal@util:combine_unqualified(_pipe@4) end, testament@internal@util:create_tests_for_markdown_file( File@1, Imports@1 ) end ) of {ok, nil} -> nil; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"failed to read source files"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 98, value => _assert_fail@2, start => 2521, 'end' => 2889, pattern_start => 2532, pattern_end => 2539}) end, testament@internal@util:verbose_log( erlang:element(3, Cfg), <<"compiling doc tests"/utf8>> ), Args = case platform:runtime() of erlang -> [<<"erlang"/utf8>>]; bun -> lists:append( [<<"javascript"/utf8>>, <<"--runtime"/utf8>>], [<<"bun"/utf8>>] ); deno -> lists:append( [<<"javascript"/utf8>>, <<"--runtime"/utf8>>], [<<"deno"/utf8>>] ); node -> lists:append( [<<"javascript"/utf8>>, <<"--runtime"/utf8>>], [<<"node"/utf8>>] ); _ -> erlang:error(#{gleam_error => panic, message => <<"testament: invalid runtime or target"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 118}) end, Args@1 = lists:append([<<"test"/utf8>>, <<"--target"/utf8>>], Args), testament@internal@util:verbose_log( erlang:element(3, Cfg), <<<<"running '"/utf8, (gleam@string:join( [<<"gleam"/utf8>> | Args@1], <<" "/utf8>> ))/binary>>/binary, "'"/utf8>> ), Res = shellout:command( <<"gleam"/utf8>>, Args@1, <<"."/utf8>>, [let_be_stderr, let_be_stdout, {set_environment, [{<<"TESTAMENT_WITH_DOCS"/utf8>>, <<"1"/utf8>>}]}] ), case erlang:element(4, Cfg) of false -> testament@internal@util:verbose_log( erlang:element(3, Cfg), <<"deleting generated doc tests"/utf8>> ), case simplifile_erl:delete( filepath:join(<<"test"/utf8>>, <<"testament"/utf8>>) ) of {ok, nil} -> nil; _assert_fail@3 -> erlang:error(#{gleam_error => let_assert, message => <<"failed to clean doc test"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 139, value => _assert_fail@3, start => 3860, 'end' => 3946, pattern_start => 3871, pattern_end => 3878}) end, nil; _ -> case shellout:command( <<"gleam"/utf8>>, [<<"format"/utf8>>, <<"test/testament"/utf8>>], <<"."/utf8>>, [] ) of {ok, _} -> nil; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"failed to format generated tests"/utf8>>, file => <>, module => <<"testament"/utf8>>, function => <<"test_main_with_opts"/utf8>>, line => 146, value => _assert_fail@4, start => 4039, 'end' => 4134, pattern_start => 4050, pattern_end => 4055}) end, nil end, case Res of {error, {Code, _}} -> shellout_ffi:os_exit(Code); {ok, _} -> nil end end. -file("src/testament.gleam", 50). ?DOC( "Add testament to your test's main function and you're good to go!\n" "You can use gleeunit or any other testing framework\n" " ```gleam\n" " import gleeunit\n" " import testament\n" " \n" " pub fn main() -> Nil {\n" " testament.test_main(gleeunit.main)\n" " }\n" " ```\n" ). -spec test_main(fun(() -> nil)) -> nil. test_main(Run_tests) -> test_main_with_opts(Run_tests, []).