Current section

Files

Jump to
testament src testament internal util.gleam
Raw

src/testament/internal/util.gleam

import filepath
import gleam/dict
import gleam/int
import gleam/io
import gleam/list
import gleam/result
import gleam/string
import simplifile
import testament/conf
import testament/internal/parse
pub fn get_test_file_name(file: String) -> String {
file
|> string.replace("src", "")
|> string.replace(".md", "_md.gleam")
|> string.replace(".gleam", "_doc_test.gleam")
|> filepath.join("testament", _)
|> filepath.join("test", _)
}
pub fn clean_doc_tests() -> Result(Nil, simplifile.FileError) {
use files <- result.try(simplifile.get_files("src"))
files
|> list.map(get_test_file_name)
|> simplifile.delete_all()
}
pub fn import_from_file_name(file: String) -> String {
let assert Ok(module) =
file
|> filepath.strip_extension()
|> filepath.split()
|> list.rest()
as { "could not construct file name for '" <> file <> "'" }
"import " <> list.fold(module, "", filepath.join)
}
pub fn create_tests_for_file(
file: String,
extra_imports: List(parse.Import),
) -> Result(Nil, simplifile.FileError) {
let assert Ok(file_content) = simplifile.read(file)
as { "could not read file '" <> file <> "'" }
let #(imports, tests) = parse.get_doc_tests_imports_and_code(file_content)
let imports =
imports
|> list.append(extra_imports)
|> list.prepend(import_from_file_name(file))
do_create_tests(file, imports, tests)
}
pub fn create_tests_for_markdown_file(
file: String,
extra_imports: List(parse.Import),
) -> Result(Nil, simplifile.FileError) {
let assert Ok(file_content) = simplifile.read(file)
as { "could not read file '" <> file <> "'" }
let #(imports, tests) = parse.parse_markdown_snippets(file_content)
do_create_tests(file, list.append(imports, extra_imports), tests)
}
fn do_create_tests(
filepath: String,
imports: List(parse.Import),
tests: List(parse.CodeBlock),
) -> Result(Nil, simplifile.FileError) {
case tests {
[] -> Ok(Nil)
_ -> {
let imports =
imports
|> list.unique()
|> string.join("\n")
let test_file_name = get_test_file_name(filepath)
let _ = simplifile.delete(test_file_name)
let assert Ok(Nil) =
test_file_name
|> filepath.directory_name()
|> simplifile.create_directory_all()
as "failed to create test doc directory"
let assert Ok(Nil) = simplifile.append(test_file_name, imports <> "\n")
list.index_map(tests, fn(code, index) {
string.join(
["\npub fn doc" <> int.to_string(index) <> "_test() {", code, "}\n"],
"\n",
)
|> simplifile.append(test_file_name, _)
})
|> result.all()
|> result.replace(Nil)
}
}
}
pub type Config {
Config(
ignore_files: List(String),
verbose: Bool,
preserve_files: Bool,
extra_imports: dict.Dict(String, List(String)),
markdown_files: List(String),
)
}
pub fn combine_conf_values(opts: List(conf.Conf)) -> Config {
list.fold(
opts,
Config(
ignore_files: [],
verbose: False,
preserve_files: False,
extra_imports: dict.new(),
markdown_files: [],
),
fn(cfg, opt) {
case opt {
conf.ExtraImports(file, imports) ->
Config(
..cfg,
extra_imports: dict.insert(
cfg.extra_imports,
file,
imports
|> list.map(string.trim)
|> list.map(string.append("import ", _)),
),
)
conf.IgnoreFiles(files) ->
Config(..cfg, ignore_files: list.append(cfg.ignore_files, files))
conf.PreserveFiles -> Config(..cfg, preserve_files: True)
conf.Verbose -> Config(..cfg, verbose: True)
conf.Markdown(files) ->
Config(..cfg, markdown_files: list.append(cfg.markdown_files, files))
}
},
)
}
pub fn verbose_log(log: Bool, msg: String) -> Nil {
case log {
True -> io.println("testament: " <> msg)
False -> Nil
}
}