-module(testament@internal@util). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/testament/internal/util.gleam"). -export([get_test_file_name/1, fold_doc_state/2, collect_test_lines/1, is_doc/1, is_doctest_line/1, split_imports_and_code/2, clean_doc_tests/0, import_from_file_name/1, create_tests_for_markdown_file/2, combine_conf_values/1, verbose_log/2, get_doc_tests_imports_and_code/1, create_tests_for_file/2]). -export_type([doc_state/0, config/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type doc_state() :: {doc_state, boolean(), list(glexer@token:token()), list(list(glexer@token:token()))}. -type config() :: {config, list(binary()), boolean(), boolean(), gleam@dict:dict(binary(), list(binary())), list(binary())}. -file("src/testament/internal/util.gleam", 17). ?DOC(false). -spec get_test_file_name(binary()) -> binary(). get_test_file_name(File) -> _pipe = File, _pipe@1 = gleam@string:replace(_pipe, <<"src"/utf8>>, <<""/utf8>>), _pipe@2 = gleam@string:replace( _pipe@1, <<".md"/utf8>>, <<"_md.gleam"/utf8>> ), _pipe@3 = gleam@string:replace( _pipe@2, <<".gleam"/utf8>>, <<"_doc_test.gleam"/utf8>> ), _pipe@4 = filepath:join(<<"testament"/utf8>>, _pipe@3), filepath:join(<<"test"/utf8>>, _pipe@4). -file("src/testament/internal/util.gleam", 79). ?DOC(false). -spec fold_doc_state(doc_state(), glexer@token:token()) -> doc_state(). fold_doc_state(State, Line) -> case {State, Line} of {{doc_state, false, Lines, _}, {comment_doc, <<":"/utf8, _/binary>>}} -> {doc_state, true, [Line | Lines], erlang:element(4, State)}; {{doc_state, false, Lines, _}, {comment_module, <<":"/utf8, _/binary>>}} -> {doc_state, true, [Line | Lines], erlang:element(4, State)}; {{doc_state, true, Lines@1, _}, {comment_doc, <<":"/utf8, _/binary>>}} -> {doc_state, erlang:element(2, State), [Line | Lines@1], erlang:element(4, State)}; {{doc_state, true, Lines@1, _}, {comment_module, <<":"/utf8, _/binary>>}} -> {doc_state, erlang:element(2, State), [Line | Lines@1], erlang:element(4, State)}; {{doc_state, true, Lines@2, Bodies}, _} -> {doc_state, false, [], gleam@list:prepend(Bodies, lists:reverse(Lines@2))}; {_, _} -> State end. -file("src/testament/internal/util.gleam", 70). ?DOC(false). -spec collect_test_lines(list(glexer@token:token())) -> list(list(glexer@token:token())). collect_test_lines(Tokens) -> State = gleam@list:fold( Tokens, {doc_state, false, [], []}, fun fold_doc_state/2 ), case erlang:element(3, State) of [] -> erlang:element(4, State); _ -> gleam@list:prepend( erlang:element(4, State), lists:reverse(erlang:element(3, State)) ) end. -file("src/testament/internal/util.gleam", 100). ?DOC(false). -spec is_doc(glexer@token:token()) -> boolean(). is_doc(Line) -> case Line of {comment_doc, _} -> true; {comment_module, _} -> true; _ -> false end. -file("src/testament/internal/util.gleam", 108). ?DOC(false). -spec is_doctest_line(glexer@token:token()) -> boolean(). is_doctest_line(Line) -> case Line of {comment_doc, <<":"/utf8, _/binary>>} -> true; {comment_module, <<":"/utf8, _/binary>>} -> true; _ -> false end. -file("src/testament/internal/util.gleam", 116). ?DOC(false). -spec split_imports_and_code({list(binary()), list(binary())}, binary()) -> {list(binary()), list(binary())}. split_imports_and_code(Code, Line) -> case gleam_stdlib:string_starts_with(Line, <<"import"/utf8>>) of true -> gleam@pair:map_first( Code, fun(_capture) -> gleam@list:prepend(_capture, Line) end ); false -> gleam@pair:map_second( Code, fun(_capture@1) -> lists:append(_capture@1, [Line]) end ) end. -file("src/testament/internal/util.gleam", 126). ?DOC(false). -spec clean_doc_tests() -> {ok, nil} | {error, simplifile:file_error()}. clean_doc_tests() -> gleam@result:'try'( simplifile:get_files(<<"src"/utf8>>), fun(Files) -> _pipe = Files, _pipe@1 = gleam@list:map(_pipe, fun get_test_file_name/1), simplifile:delete_all(_pipe@1) end ). -file("src/testament/internal/util.gleam", 133). ?DOC(false). -spec import_from_file_name(binary()) -> binary(). import_from_file_name(File) -> Module@1 = case begin _pipe = File, _pipe@1 = filepath:strip_extension(_pipe), _pipe@2 = filepath:split(_pipe@1), gleam@list:rest(_pipe@2) end of {ok, Module} -> Module; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => (<<<<"could not construct file name for '"/utf8, File/binary>>/binary, "'"/utf8>>), file => <>, module => <<"testament/internal/util"/utf8>>, function => <<"import_from_file_name"/utf8>>, line => 134, value => _assert_fail, start => 3288, 'end' => 3397, pattern_start => 3299, pattern_end => 3309}) end, <<"import "/utf8, (gleam@list:fold(Module@1, <<""/utf8>>, fun filepath:join/2))/binary>>. -file("src/testament/internal/util.gleam", 166). ?DOC(false). -spec do_create_tests(binary(), list(binary()), list(binary())) -> {ok, nil} | {error, simplifile:file_error()}. do_create_tests(Filepath, Imports, Tests) -> case Tests of [] -> {ok, nil}; _ -> Imports@1 = begin _pipe = Imports, _pipe@1 = gleam@list:unique(_pipe), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, Test_file_name = get_test_file_name(Filepath), _ = simplifile_erl:delete(Test_file_name), case begin _pipe@2 = Test_file_name, _pipe@3 = filepath:directory_name(_pipe@2), simplifile:create_directory_all(_pipe@3) end of {ok, nil} -> nil; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"failed to create test doc directory"/utf8>>, file => <>, module => <<"testament/internal/util"/utf8>>, function => <<"do_create_tests"/utf8>>, line => 179, value => _assert_fail, start => 4580, 'end' => 4705, pattern_start => 4591, pattern_end => 4598}) end, case simplifile:append( Test_file_name, <> ) of {ok, nil} -> nil; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"testament/internal/util"/utf8>>, function => <<"do_create_tests"/utf8>>, line => 185, value => _assert_fail@1, start => 4762, 'end' => 4833, pattern_start => 4773, pattern_end => 4780}) end, _pipe@5 = gleam@list:index_map( Tests, fun(Code, Index) -> _pipe@4 = gleam@string:join( [<<<<"\npub fn doc"/utf8, (erlang:integer_to_binary(Index))/binary>>/binary, "_test() {"/utf8>>, Code, <<"}\n"/utf8>>], <<"\n"/utf8>> ), simplifile:append(Test_file_name, _pipe@4) end ), _pipe@6 = gleam@result:all(_pipe@5), gleam@result:replace(_pipe@6, nil) end. -file("src/testament/internal/util.gleam", 155). ?DOC(false). -spec create_tests_for_markdown_file(binary(), list(binary())) -> {ok, nil} | {error, simplifile:file_error()}. create_tests_for_markdown_file(File, Extra_imports) -> File_content@1 = case simplifile:read(File) of {ok, File_content} -> File_content; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => (<<<<"could not read file '"/utf8, File/binary>>/binary, "'"/utf8>>), file => <>, module => <<"testament/internal/util"/utf8>>, function => <<"create_tests_for_markdown_file"/utf8>>, line => 159, value => _assert_fail, start => 4012, 'end' => 4063, pattern_start => 4023, pattern_end => 4039}) end, {Imports, Tests} = testament@internal@markdown:parse_snippets( File_content@1 ), do_create_tests(File, lists:append(Imports, Extra_imports), Tests). -file("src/testament/internal/util.gleam", 210). ?DOC(false). -spec combine_conf_values(list(testament@conf:conf())) -> config(). combine_conf_values(Opts) -> gleam@list:fold( Opts, {config, [], false, false, maps:new(), []}, fun(Cfg, Opt) -> case Opt of {extra_imports, File, Imports} -> {config, erlang:element(2, Cfg), erlang:element(3, Cfg), erlang:element(4, Cfg), gleam@dict:insert( erlang:element(5, Cfg), File, begin _pipe = Imports, _pipe@1 = gleam@list:map( _pipe, fun gleam@string:trim/1 ), gleam@list:map( _pipe@1, fun(_capture) -> gleam@string:append( <<"import "/utf8>>, _capture ) end ) end ), erlang:element(6, Cfg)}; {ignore_files, Files} -> {config, lists:append(erlang:element(2, Cfg), Files), erlang:element(3, Cfg), erlang:element(4, Cfg), erlang:element(5, Cfg), erlang:element(6, Cfg)}; preserve_files -> {config, erlang:element(2, Cfg), erlang:element(3, Cfg), true, erlang:element(5, Cfg), erlang:element(6, Cfg)}; verbose -> {config, erlang:element(2, Cfg), true, erlang:element(4, Cfg), erlang:element(5, Cfg), erlang:element(6, Cfg)}; {markdown, Files@1} -> {config, erlang:element(2, Cfg), erlang:element(3, Cfg), erlang:element(4, Cfg), erlang:element(5, Cfg), lists:append(erlang:element(6, Cfg), Files@1)} end end ). -file("src/testament/internal/util.gleam", 246). ?DOC(false). -spec verbose_log(boolean(), binary()) -> nil. verbose_log(Log, Msg) -> case Log of true -> gleam_stdlib:println(<<"testament: "/utf8, Msg/binary>>); false -> nil end. -file("src/testament/internal/util.gleam", 40). ?DOC(false). -spec get_doc_tests_imports_and_code(binary()) -> {list(binary()), list(binary())}. get_doc_tests_imports_and_code(Code) -> Prefix_len = string:length(<<":"/utf8>>), _pipe = Code, _pipe@1 = glexer:new(_pipe), _pipe@2 = glexer:discard_whitespace(_pipe@1), _pipe@3 = glexer:lex(_pipe@2), _pipe@4 = gleam@list:map(_pipe@3, fun gleam@pair:first/1), _pipe@5 = gleam@list:filter(_pipe@4, fun is_doc/1), _pipe@6 = collect_test_lines(_pipe@5), _pipe@14 = gleam@list:map(_pipe@6, fun(Tokens) -> _pipe@7 = Tokens, _pipe@8 = gleam@list:filter(_pipe@7, fun is_doctest_line/1), _pipe@9 = gleam@list:map(_pipe@8, fun glexer@token:to_source/1), _pipe@10 = gleam@list:map( _pipe@9, fun(_capture) -> gleam_stdlib:crop_string(_capture, <<":"/utf8>>) end ), _pipe@11 = gleam@list:map( _pipe@10, fun(_capture@1) -> gleam@string:drop_start(_capture@1, Prefix_len) end ), _pipe@12 = gleam@list:map(_pipe@11, fun gleam@string:trim/1), _pipe@13 = gleam@list:fold( _pipe@12, {[], []}, fun split_imports_and_code/2 ), gleam@pair:map_second( _pipe@13, fun(_capture@2) -> gleam@string:join(_capture@2, <<"\n"/utf8>>) end ) end), _pipe@17 = gleam@list:fold( _pipe@14, {[], []}, fun(Acc, Block) -> _pipe@15 = Acc, _pipe@16 = gleam@pair:map_first( _pipe@15, fun(_capture@3) -> lists:append(_capture@3, gleam@pair:first(Block)) end ), gleam@pair:map_second( _pipe@16, fun(_capture@4) -> gleam@list:prepend(_capture@4, gleam@pair:second(Block)) end ) end ), gleam@pair:map_first(_pipe@17, fun gleam@list:unique/1). -file("src/testament/internal/util.gleam", 144). ?DOC(false). -spec create_tests_for_file(binary(), list(binary())) -> {ok, nil} | {error, simplifile:file_error()}. create_tests_for_file(File, Extra_imports) -> File_content@1 = case simplifile:read(File) of {ok, File_content} -> File_content; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => (<<<<"could not read file '"/utf8, File/binary>>/binary, "'"/utf8>>), file => <>, module => <<"testament/internal/util"/utf8>>, function => <<"create_tests_for_file"/utf8>>, line => 148, value => _assert_fail, start => 3638, 'end' => 3689, pattern_start => 3649, pattern_end => 3665}) end, {Imports, Tests} = get_doc_tests_imports_and_code(File_content@1), do_create_tests(File, lists:append(Imports, Extra_imports), Tests).