const Document = @import("attempt_2.zig").Document; const std = @import("std"); const Token = @import("Token.zig"); const expect = std.testing.expect; test "heading_1" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "# hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "#", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "heading_2" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "## hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "##", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "heading_3" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "### hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "###", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "heading_4" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "#### hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "####", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "heading_5" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "##### hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "#####", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "heading_6" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "###### hello this is a heading\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "######", }, Token{ .type = .text, .data = "hello this is a heading", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "header_no_text" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "######\n"; const parsed = [_]Token{ Token{ .type = .heading, .data = "######", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "plain test\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "plain test", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_code" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "`plain test`\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "`", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "`", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_bold" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "!plain test!\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "!", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "!", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_italic" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "*plain test*\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "*", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "*", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_underline" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "_plain test_\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "_", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "_", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_strikethrough" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "~plain test~\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "~", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "~", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_highlighted" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "|plain test|\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "|", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "|", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_&" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "&plain test&\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "&", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "&", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_%" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "%plain test%\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "%", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "%", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_$" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "$plain test$\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "$", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "$", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_#" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "#plain test#\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "#", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "#", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_-" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "-plain test-\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "-", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "-", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_+" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "+plain test+\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "+", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "+", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_=" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "=plain test=\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "=", }, Token{ .type = .text, .data = "plain test", }, Token{ .type = .inline_style, .data = "=", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_espaced" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "\\`plain test`\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "`plain test`", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_with_style_char_in_string" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "+plain something + something else test+\n"; const parsed = [_]Token{ Token{ .type = .inline_style, .data = "+", }, Token{ .type = .text, .data = "plain something + something else test", }, Token{ .type = .inline_style, .data = "+", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_with_space right after" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "+ plain something + something else test+\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "+ plain something + something else test+", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_super_script" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "sometext^2\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "sometext", }, Token{ .type = .sup, .data = "^", }, Token{ .type = .text, .data = "2", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_style_sub_script" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "sometext_2\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "sometext", }, Token{ .type = .sub, .data = "_", }, Token{ .type = .text, .data = "2", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_ordered_number" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "1. ordered list\n2. ordered list\n3. ordered list\n"; const parsed = [_]Token{ Token{ .type = .ordered_list, .data = "1.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "2.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "3.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_ordered_i" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "i. ordered list\nii. ordered list\niii. ordered list\n"; const parsed = [_]Token{ Token{ .type = .ordered_list, .data = "i.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "ii.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "iii.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_ordered_letter" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "a. ordered list\nb. ordered list\nc. ordered list\n"; const parsed = [_]Token{ Token{ .type = .ordered_list, .data = "a.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "b.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .ordered_list, .data = "c.", }, Token{ .type = .text, .data = "ordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_unordered_dashed" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "- unordered list\n- unordered list\n- unordered list\n"; const parsed = [_]Token{ Token{ .type = .unordered_list, .data = "-", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "-", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "-", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_unordered_eq" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "= unordered list\n= unordered list\n= unordered list\n"; const parsed = [_]Token{ Token{ .type = .unordered_list, .data = "=", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "=", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "=", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_unordered_plus" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "+ unordered list\n+ unordered list\n+ unordered list\n"; const parsed = [_]Token{ Token{ .type = .unordered_list, .data = "+", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "+", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "+", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "list_unordered_dot" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "* unordered list\n* unordered list\n* unordered list\n"; const parsed = [_]Token{ Token{ .type = .unordered_list, .data = "*", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "*", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .unordered_list, .data = "*", }, Token{ .type = .text, .data = "unordered list", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_image" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "![figure text](relitive path to image)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "!", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "figure text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "relitive path to image", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_table" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "#[table text](relitive path to tabulated data)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "#", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "table text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "relitive path to tabulated data", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_file" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "$[file text](path to file#starting_line:ending_line)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "$", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "path to file#starting_line:ending_line", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_*" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "*[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "*", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed__" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "_[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "_", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_~" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "~[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "~", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_|" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "|[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "|", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_&" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "&[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "&", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_%" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "%[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "%", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_-" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "-[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "-", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_+" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "+[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "+", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_=" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "=[file text](file_path)\n"; const parsed = [_]Token{ Token{ .type = .embed, .data = "=", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "file_path", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "embed_link" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "/[file text](link to something)\n"; const parsed = [_]Token{ Token{ .type = .link, .data = "/", }, Token{ .type = .bracket_open, .data = "[", }, Token{ .type = .text, .data = "file text", }, Token{ .type = .bracket_close, .data = "]", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .raw_text, .data = "link to something", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "table" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "| col | col | col |\n| --- | --- | --- |\n| row | row | row |\n| row | row | row |\n| row | row | row |\n| row | row | row |\n"; const parsed = [_]Token{ Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " col ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " col ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " col ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .table_row_sep, .data = " --- ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .table_row_sep, .data = " --- ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .table_row_sep, .data = " --- ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .text, .data = " row ", }, Token{ .type = .table_sep, .data = "|", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "quote_arrow" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "> quote\n> quote\n> quote\n"; const parsed = [_]Token{ Token{ .type = .quote, .data = ">", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .quote, .data = ">", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .quote, .data = ">", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "quote_bar" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "| quote\n| quote\n| quote\n"; const parsed = [_]Token{ Token{ .type = .quote, .data = "|", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .quote, .data = "|", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .quote, .data = "|", }, Token{ .type = .text, .data = "quote", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "text_block" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "```\nsome text or code\n```\n"; const parsed = [_]Token{ Token{ .type = .code_block, .data = "```", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .raw_text, .data = "some text or code", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .code_block, .data = "```", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "code_block" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "```lang_name\nsome text or code\n```\n"; const parsed = [_]Token{ Token{ .type = .code_block, .data = "```", }, Token{ .type = .raw_text, .data = "lang_name", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .raw_text, .data = "some text or code", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .code_block, .data = "```", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "passthrough_block" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "```passthrough\nsome text or code\n```\n"; const parsed = [_]Token{ Token{ .type = .code_block, .data = "```", }, Token{ .type = .raw_text, .data = "passthrough", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .raw_text, .data = "some text or code", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .code_block, .data = "```", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "comment" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "// this is a comment\n"; const parsed = [_]Token{ Token{ .type = .comment, .data = "// ", }, Token{ .type = .raw_text, .data = "this is a comment", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "tick_box_empty" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "- [ ] something to check off\n"; const parsed = [_]Token{ Token{ .type = .tickbox, .data = "- [ ]", }, Token{ .type = .text, .data = "something to check off", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "tick_box_checked" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "- [x] something checked off\n"; const parsed = [_]Token{ Token{ .type = .tickbox, .data = "- [x]", }, Token{ .type = .text, .data = "something checked off", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "tick_box_ticked" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "- [/] something ticked off\n"; const parsed = [_]Token{ Token{ .type = .tickbox, .data = "- [/]", }, Token{ .type = .text, .data = "something ticked off", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "tick_box_dashed" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "- [~] something dashed off\n"; const parsed = [_]Token{ Token{ .type = .tickbox, .data = "- [~]", }, Token{ .type = .text, .data = "something dashed off", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_straight_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "---\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "---", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_double_straight_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "===\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "===", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_big_dotted_straight_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "***\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "***", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_small_dotted_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "...\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "...", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_squiggly_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "&&&\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "&&&", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "horizontal_rule_jagged_line" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "^^^\n"; const parsed = [_]Token{ Token{ .type = .rule, .data = "^^^", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "footnote" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "sometext [^1]\n\n[^1]: footnote\n"; const parsed = [_]Token{ Token{ .type = .text, .data = "sometext ", }, Token{ .type = .footnote, .data = "[^1]", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .newline, .data = "\n", }, Token{ .type = .footnote_def, .data = "[^1]:", }, Token{ .type = .text, .data = "footnote", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); } test "inbulit" { std.testing.refAllDecls(@This()); const doc = Document.initDefault(std.testing.allocator); const input = "@.macro(arg, arg2)\n"; const parsed = [_]Token{ Token{ .type = .inbulit, .data = "macro", }, Token{ .type = .bracket_open, .data = "(", }, Token{ .type = .macro_arg, .data = "arg", }, Token{ .type = .arg_sep, .data = ",", }, Token{ .type = .macro_arg, .data = "arg2", }, Token{ .type = .bracket_close, .data = ")", }, Token{ .type = .newline, .data = "\n", }, }; try doc.parse(input, std.testing.allocator); try expect(doc.tokens.items.len >= parsed.len); for (parsed, doc.tokens.items[0..parsed.len]) |expected_token, actual_token| { try expect(expected_token.type == actual_token.type); try expect(std.mem.eql(u8, expected_token.data, actual_token.data)); } doc.deinit(std.testing.allocator); }