Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ packages = [
{ name = "envoy", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "95FD059345AA982E89A0B6E2A3BF1CF43E17A7048DCD85B5B65D3B9E4E39D359" },
{ name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
{ name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" },
{ name = "gleam_stdlib", version = "0.63.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5E216C7D5E8BE22359C9D7DAA2CFBD66039BC12565542F34CD033C5BB57071ED" },
{ name = "gleam_stdlib", version = "0.64.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "EA2E13FC4E65750643E078487D5EF360BEBCA5EBBBA12042FB589C19F53E35C0" },
{ name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" },
{ name = "glexer", version = "2.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "splitter"], otp_app = "glexer", source = "hex", outer_checksum = "40A1FB0919FA080AD6C5809B4C7DBA545841CAAC8168FACDFA0B0667C22475CC" },
{ name = "platform", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "platform", source = "hex", outer_checksum = "8339420A95AD89AAC0F82F4C3DB8DD401041742D6C3F46132A8739F6AEB75391" },
Expand Down
9 changes: 9 additions & 0 deletions example/src/example.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ import gleam/option
///:
///: assert y == {x * 2} + 1
/// ```
/// with implicit assert
/// ```
///: example.add(1, 2)
///:: 3
///: example.add(3, 2)
///:: 5
/// ```
pub fn add(a: Int, b: Int) -> Int {
a + b
}
Expand All @@ -34,6 +41,8 @@ pub type SuperInt {
///: let x = example.super_add(SuperInt(1), SuperInt(2))
///: assert x == Some(SuperInt(3))
///: assert example.super_add(SuperInt(-10), SuperInt(1)) == None
///: example.super_add(SuperInt(1), SuperInt(1))
///:: Some(SuperInt(2))
pub fn super_add(a: SuperInt, b: SuperInt) -> option.Option(SuperInt) {
let sum = a.v + b.v
case sum > 0 {
Expand Down
6 changes: 3 additions & 3 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ packages = [
{ name = "gleam_community_colour", version = "2.0.2", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "E34DD2C896AC3792151EDA939DA435FF3B69922F33415ED3C4406C932FBE9634" },
{ name = "gleam_erlang", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "1124AD3AA21143E5AF0FC5CF3D9529F6DB8CA03E43A55711B60B6B7B3874375C" },
{ name = "gleam_hexpm", version = "3.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "gleam_hexpm", source = "hex", outer_checksum = "AAA7813FFD1F32B12C9C0BA5C0BA451324DAC16B7D76E0540EFA526B5208CDAB" },
{ name = "gleam_http", version = "4.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "DD0271B32C356FB684EC7E9F48B1E835D0480168848581F68983C0CC371405D4" },
{ name = "gleam_http", version = "4.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "FFE29C3832698AC3EF6202922EC534EE19540152D01A7C2D22CB97482E4AF211" },
{ name = "gleam_httpc", version = "5.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "C545172618D07811494E97AAA4A0FB34DA6F6D0061FDC8041C2F8E3BE2B2E48F" },
{ name = "gleam_json", version = "3.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "874FA3C3BB6E22DD2BB111966BD40B3759E9094E05257899A7C08F5DE77EC049" },
{ name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" },
{ name = "gleam_stdlib", version = "0.63.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5E216C7D5E8BE22359C9D7DAA2CFBD66039BC12565542F34CD033C5BB57071ED" },
{ name = "gleam_stdlib", version = "0.64.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "EA2E13FC4E65750643E078487D5EF360BEBCA5EBBBA12042FB589C19F53E35C0" },
{ name = "gleam_time", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "DCDDC040CE97DA3D2A925CDBBA08D8A78681139745754A83998641C8A3F6587E" },
{ name = "gleamsver", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleamsver", source = "hex", outer_checksum = "EA74FDC66BF15CB2CF4F8FF9B6FA01D511712EE2B1F4BE0371076ED3F685EEAE" },
{ name = "glearray", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glearray", source = "hex", outer_checksum = "5E272F7CB278CC05A929C58DEB58F5D5AC6DB5B879A681E71138658D0061C38A" },
Expand All @@ -39,7 +39,7 @@ packages = [
{ name = "splitter", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "splitter", source = "hex", outer_checksum = "05564A381580395DCDEFF4F88A64B021E8DAFA6540AE99B4623962F52976AA9D" },
{ name = "term_size", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "term_size", source = "hex", outer_checksum = "D00BD2BC8FB3EBB7E6AE076F3F1FF2AC9D5ED1805F004D0896C784D06C6645F1" },
{ name = "tom", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "tom", source = "hex", outer_checksum = "74D0C5A3761F7A7D06994755D4D5AD854122EF8E9F9F76A3E7547606D8C77091" },
{ name = "trie_again", version = "1.1.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "trie_again", source = "hex", outer_checksum = "365FE609649F3A098D1D7FC7EA5222EE422F0B3745587BF2AB03352357CA70BB" },
{ name = "trie_again", version = "1.1.4", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "trie_again", source = "hex", outer_checksum = "E3BD66B4E126EF567EA8C4944EAB216413392ADF6C16C36047AF79EE5EF13466" },
{ name = "yamerl", version = "0.10.0", build_tools = ["rebar3"], requirements = [], otp_app = "yamerl", source = "hex", outer_checksum = "346ADB2963F1051DC837A2364E4ACF6EB7D80097C0F53CBDC3046EC8EC4B4E6E" },
]

Expand Down
73 changes: 67 additions & 6 deletions src/testament/internal/parse.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub fn get_doc_tests_imports_and_code(code: String) -> ImportsAndCode {
}

fn collect_test_lines(tokens: List(token.Token)) -> List(List(token.Token)) {
let state = list.fold(tokens, DocState(False, [], []), fold_doc_state)
let state = list.fold(tokens, DocState(False, [], [], 0), fold_doc_state)

case state.lines {
[] -> state.test_bodies
Expand Down Expand Up @@ -103,6 +103,7 @@ pub type DocState {
in: Bool,
lines: List(token.Token),
test_bodies: List(List(token.Token)),
implicit_asserts: Int,
)
}

Expand All @@ -116,21 +117,81 @@ pub fn split_imports_and_code(
}
}

const letters = [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
]

fn prep_implicit_assert(
state: DocState,
lines: List(token.Token),
expected_val: CodeBlock,
) {
let assert [v] = list.sample(letters, 1) as "failed to create implicit_assert"
let name = string.repeat(v, state.implicit_asserts + 1)

let assert #([token.CommentDoc(":" <> prev)], rest) = list.split(lines, 1)
as "improper use of ::"

let prev = token.CommentDoc(": let " <> name <> " =" <> prev)

let line = token.CommentDoc(": assert " <> name <> " == " <> expected_val)

DocState(
..state,
in: True,
lines: [line, prev, ..rest],
implicit_asserts: state.implicit_asserts + 1,
)
}

pub fn fold_doc_state(state: DocState, line: token.Token) -> DocState {
case state, line {
DocState(False, lines, _), token.CommentDoc(":" <> _)
| DocState(False, lines, _), token.CommentModule(":" <> _)
DocState(False, lines, _, _), token.CommentDoc("::" <> expected_val)
| DocState(False, lines, _, _), token.CommentModule("::" <> expected_val)
-> prep_implicit_assert(state, lines, expected_val)

DocState(False, lines, _, _), token.CommentDoc(":" <> _)
| DocState(False, lines, _, _), token.CommentModule(":" <> _)
-> DocState(..state, in: True, lines: [line, ..lines])

DocState(True, lines, _), token.CommentDoc(":" <> _)
| DocState(True, lines, _), token.CommentModule(":" <> _)
DocState(True, lines, _, _), token.CommentDoc("::" <> expected_val)
| DocState(True, lines, _, _), token.CommentModule("::" <> expected_val)
-> prep_implicit_assert(state, lines, expected_val)

DocState(True, lines, _, _), token.CommentDoc(":" <> _)
| DocState(True, lines, _, _), token.CommentModule(":" <> _)
-> DocState(..state, lines: [line, ..lines])

DocState(True, lines, bodies), _ ->
DocState(True, lines, bodies, implicit_asserts), _ ->
DocState(
in: False,
lines: [],
test_bodies: list.prepend(bodies, list.reverse(lines)),
implicit_asserts: implicit_asserts,
)

_, _ -> state
Expand Down
15 changes: 7 additions & 8 deletions src/testament/internal/util.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ pub fn get_test_file_name(file: String) -> String {
pub fn clean_doc_tests() -> Result(Nil, simplifile.FileError) {
use files <- result.try(simplifile.get_files("src"))
files
|> stream.new()
|> stream.map(get_test_file_name)
|> stream.to_list()
|> list.map(get_test_file_name)
|> simplifile.delete_all()
}

Expand Down Expand Up @@ -156,16 +154,16 @@ pub fn combine_unqualified(imports: List(conf.Import)) -> List(String) {
imports
|> list.group(fn(i) { i.module })
|> dict.to_list()
|> list.fold([], fn(acc, i) {
|> stream.new()
|> stream.map(fn(i) {
let #(module, imports) = i

acc
|> list.prepend(conf.Import(
conf.Import(
module: module,
unqualified: list.flat_map(imports, fn(v) { v.unqualified }),
))
)
})
|> list.map(fn(i) {
|> stream.map(fn(i) {
let conf.Import(module, _) = i

let tree =
Expand All @@ -184,4 +182,5 @@ pub fn combine_unqualified(imports: List(conf.Import)) -> List(String) {
|> string_tree.to_string()
}
})
|> stream.to_list()
}
43 changes: 24 additions & 19 deletions test/parse_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -58,43 +58,48 @@ pub fn is_doctest_line_test() {
}

pub fn fold_doc_state_test() {
assert parse.DocState(False, [], [])
assert parse.DocState(False, [], [], 0)
|> parse.fold_doc_state(token.String(": "))
== parse.DocState(False, [], [])
== parse.DocState(False, [], [], 0)

assert parse.DocState(False, [], [])
assert parse.DocState(False, [], [], 0)
|> parse.fold_doc_state(token.CommentDoc(": "))
== parse.DocState(True, [token.CommentDoc(": ")], [])
== parse.DocState(True, [token.CommentDoc(": ")], [], 0)

assert parse.DocState(False, [], [])
assert parse.DocState(False, [], [], 0)
|> parse.fold_doc_state(token.CommentModule(": "))
== parse.DocState(True, [token.CommentModule(": ")], [])
== parse.DocState(True, [token.CommentModule(": ")], [], 0)

assert parse.DocState(True, [], [])
assert parse.DocState(True, [], [], 0)
|> parse.fold_doc_state(token.CommentDoc(": "))
== parse.DocState(True, [token.CommentDoc(": ")], [])
== parse.DocState(True, [token.CommentDoc(": ")], [], 0)

assert parse.DocState(True, [], [])
assert parse.DocState(True, [], [], 0)
|> parse.fold_doc_state(token.CommentModule(": "))
== parse.DocState(True, [token.CommentModule(": ")], [])
== parse.DocState(True, [token.CommentModule(": ")], [], 0)

assert parse.DocState(True, [token.CommentModule(": let x = 2 + 2")], [])
assert parse.DocState(True, [token.CommentModule(": let x = 2 + 2")], [], 0)
|> parse.fold_doc_state(token.CommentModule(": assert x == 4"))
|> parse.fold_doc_state(token.CommentModule("pub fn x"))
== parse.DocState(False, [], [
== parse.DocState(
False,
[],
[
token.CommentModule(": let x = 2 + 2"),
token.CommentModule(": assert x == 4"),
[
token.CommentModule(": let x = 2 + 2"),
token.CommentModule(": assert x == 4"),
],
],
])
0,
)

assert parse.DocState(True, [], [])
assert parse.DocState(True, [], [], 0)
|> parse.fold_doc_state(token.CommentDoc(" "))
== parse.DocState(False, [], [[]])
== parse.DocState(False, [], [[]], 0)

assert parse.DocState(True, [], [])
assert parse.DocState(True, [], [], 0)
|> parse.fold_doc_state(token.CommentModule(" "))
== parse.DocState(False, [], [[]])
== parse.DocState(False, [], [[]], 0)
}

pub fn split_imports_and_code_test() {
Expand Down
Loading