import gleam/string import gleeunit/should import string_width.{ Bottom, Center, Left, Middle, Right, Size, Top, align, limit, padding, position, scroll, soft_wrap, stack_horizontal, stack_vertical, tabs_to_spaces, } pub fn limit_test() { limit("Hello World", Size(1, 10), "...") |> should.equal("Hello W...") limit("Hello World", Size(2, 10), "...") |> should.equal("Hello\nWorld") limit("Hello World", Size(2, 5), "...") |> should.equal("Hello\nWorld") limit("Hello World!", Size(3, 5), "...") |> should.equal("Hello\nWorld\n!") limit("How are you doing?", Size(1, 8), "…") |> should.equal("How are…") limit("Hello brave new world", Size(4, 5), "") |> should.equal("Hello\nbrave\nnew\nworld") limit( "Lorem ipsum dolor sit amet\nIs a common placeholder string", to: Size(3, 20), ellipsis: "...", ) |> should.equal("Lorem ipsum dolor\nsit amet\nIs a common place...") } pub fn limit_overflow_overflow_test() { limit("VeryLongIdentifier", Size(2, 8), "...") |> should.equal("VeryLong\nIdent...") limit("a very longidentifier\nfollowed by some more.", Size(4, 8), "...") |> should.equal("a very l\nongident\nifier\nfollo...") } pub fn limit_cluster_test() { limit( "πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦", Size(1, 12), "…", ) |> should.equal("πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦β€¦") limit( "πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦ πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦ πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦", Size(1, 12), "…", ) |> should.equal("πŸ‘©β€πŸ‘©β€πŸ‘¦β€πŸ‘¦β€¦") } pub fn limit_tabs_test() { // this needs to wrap twice, since after putting hi no a new line, the tab // would expand to 6 spaces limit("oh hello, hi\tmark", Size(500, 10), "") |> should.equal("oh hello,\nhi\nmark") let options = string_width.new() |> string_width.at_tab_offset(9) string_width.limit_with( "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident hic.\t\taliquid harum perferendis", to: Size(rows: 500, columns: 40), ellipsis: "", using: options, ) |> should.equal( "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident\nhic.\t\taliquid harum perferendis", ) } pub fn limit_shy_test() { limit( "an ex\u{ad}tra\u{ad}ordi\u{ad}na\u{ad}ri\u{ad}ly long eng\u{ad}lish word", Size(10, 10), ellipsis: "", ) |> should.equal("an extra-\nordinarily\nlong eng-\nlish word") limit("extra\u{ad}ordinarily", Size(rows: 3, columns: 5), ellipsis: "") |> should.equal("extra\nordin\narily") limit("extra\u{ad}ordinarily", Size(3, 7), ellipsis: "") |> should.equal("extra-\nordinar\nily") } pub fn soft_wrap_test() { soft_wrap("Hello World", Size(2, 10), "...", fn(_) { " " }) |> should.equal("Hello\n World") soft_wrap("Hello World", Size(3, 5), "...", fn(_) { " " }) |> should.equal("Hello\n Wor\n ld") soft_wrap( "Lorem ipsum dolor sit amet\nIs a common placeholder string", to: Size(3, 20), ellipsis: "...", to_indent: fn(_) { " " }, ) |> should.equal("Lorem ipsum dolor\n sit amet\nIs a common place...") } pub fn tabs_to_spaces_test() { tabs_to_spaces("hello\tworld") |> should.equal("hello world") tabs_to_spaces("\t") |> should.equal(string.repeat(" ", 8)) tabs_to_spaces("\t\t") |> should.equal(string.repeat(" ", 16)) tabs_to_spaces("\t\t\t") |> should.equal(string.repeat(" ", 24)) tabs_to_spaces("\t\t \t") |> should.equal(string.repeat(" ", 24)) tabs_to_spaces("xx\txx\txx\t\t") |> should.equal("xx xx xx ") } pub fn tabs_to_spaces_with_test() { let options = string_width.new() |> string_width.with_tab_width(4) string_width.tabs_to_spaces_with("hi\tcutie~", options) |> should.equal("hi cutie~") } pub fn position_test() { position("X", in: Size(3, 3), align: Left, place: Top, with: "o") |> should.equal("Xoo\nooo\nooo") position("X", in: Size(3, 3), align: Center, place: Top, with: "o") |> should.equal("oXo\nooo\nooo") position("X", in: Size(3, 3), align: Right, place: Top, with: "o") |> should.equal("ooX\nooo\nooo") position("X", in: Size(3, 3), align: Left, place: Middle, with: "o") |> should.equal("ooo\nXoo\nooo") position("X", in: Size(3, 3), align: Center, place: Middle, with: "o") |> should.equal("ooo\noXo\nooo") position("X", in: Size(3, 3), align: Right, place: Middle, with: "o") |> should.equal("ooo\nooX\nooo") position("X", in: Size(3, 3), align: Left, place: Bottom, with: "o") |> should.equal("ooo\nooo\nXoo") position("X", in: Size(3, 3), align: Center, place: Bottom, with: "o") |> should.equal("ooo\nooo\noXo") position("X", in: Size(3, 3), align: Right, place: Bottom, with: "o") |> should.equal("ooo\nooo\nooX") position( "XXX", in: Size(rows: 3, columns: 10), align: Center, place: Middle, with: ".", ) |> should.equal("..........\n...XXX....\n..........") position("Trans\nrights\nare\nhuman\nrights", Size(0, 7), Right, Top, " ") |> should.equal(" Trans \n rights\n are \n human \n rights") } pub fn padding_test() { padding("o", 1, 1, 1, 1, with: "x") |> should.equal("xxx\nxox\nxxx") padding("o\n", 1, 1, 1, 1, with: "x") |> should.equal("xxx\nxox\nxxx") padding("hello", 0, 0, 0, right: -1, with: "") |> should.equal("hell") padding("Trans\nrights!", top: 2, right: 5, bottom: 1, left: 1, with: "-") |> should.equal( "-------------\n-------------\n-Trans-------\n-rights!-----\n-------------", ) padding("", 0, 0, 0, 0, " ") |> should.equal("") padding("", 1, 1, 1, 1, "-") |> should.equal("--\n--") padding("x", 1, 1, 1, 1, " ") |> should.equal(" \n x \n ") padding("hello", 0, -1, 0, 0, "") |> should.equal("hell") padding("hello", 0, 0, 0, -1, "") |> should.equal("ello") padding("hello", 0, -1, 0, -1, "") |> should.equal("ell") padding("hello", 0, -10, 0, -10, "") |> should.equal("") padding("hello", 1, -10, 1, -10, "") |> should.equal("\n\n") padding("hi", -1, 0, 0, 0, "") |> should.equal("") padding("hi", -1, 0, -1, 0, "") |> should.equal("") } pub fn padding_lone_ansi_test() { // I can't decide what is better here; I guess just a ANSI sequence should not // count for anything? padding("x\n\u{1b}[m", 1, 1, 1, 1, "-") |> should.equal("---\n-x-\n-\u{1b}[m--") padding("\u{1b}[m\nx", 1, 1, 1, 1, "-") |> should.equal("---\n-\u{1b}[m--\n-x-\n---") padding("\u{1b}[m", 1, 1, 1, 1, "-") |> should.equal("--\n-\u{1b}[m-") padding("\u{1b}[m", -10, -10, -10, -10, "-") |> should.equal("\u{1b}[m") } pub fn scroll_test() { scroll("wibble", 0, 0, Size(0, 0), " ") |> should.equal("") scroll("wibble", 0, 0, Size(1, 0), " ") |> should.equal("") scroll("wibble", top: 0, left: 2, view: Size(rows: 1, columns: 2), with: " ") |> should.equal("bb") scroll("Hello\nhow are you?", top: 0, left: 4, view: Size(3, 3), with: "-") |> should.equal("o--\nare\n---") "Hello\nHow are you today?\nDid you know:\nLucy says trans rights!" |> scroll(top: 2, left: 10, view: Size(3, 5), with: "-") |> should.equal("ow:--\ntrans\n-----") } pub fn scroll_offscreen_test() { scroll("wibble", -5, 0, Size(2, 10), " ") |> should.equal(" \n ") scroll("wibble\nwobble", 5, 0, Size(2, 10), " ") |> should.equal(" \n ") } pub fn align_test() { align("", to: 10, align: Left, with: " ") |> should.equal(" ") align("hello", to: 10, align: Left, with: " ") |> should.equal("hello ") align("12345", to: 8, align: Right, with: "0") |> should.equal("00012345") align(" Welcome ", to: 20, align: Center, with: "==") |> should.equal("====== Welcome ======") align("Trans\nrights\nare\nhuman\nrights", to: 7, align: Right, with: " ") |> should.equal(" Trans\n rights\n are\n human\n rights") } pub fn inline_styles_test() { string_width.inline_styles("") |> should.equal("") string_width.inline_styles("hello") |> should.equal("hello") string_width.inline_styles("hel\u{1b}[mlo") |> should.equal("hel\u{1b}[mlo") string_width.inline_styles("\u{1b}[31mhello\nworld") |> should.equal( "\u{1b}[31mhello" <> "\u{1b}[m\n" <> "\u{1b}[31mworld" <> "\u{1b}[m", ) string_width.inline_styles("\u{1b}[31mhell\u{1b}[0mo,\nworld!") |> should.equal("\u{1b}[31mhell\u{1b}[0mo,\nworld!") } pub fn stack_vertical_test() { ["Hello!", "I hope you are feeling fantastic today!"] |> stack_vertical(Center, gap: 1, with: " ") |> should.equal( " Hello! \n" <> " \n" <> "I hope you are feeling fantastic today!", ) stack_vertical([], Center, 0, "") |> should.equal("") stack_vertical([""], Center, 0, "") |> should.equal("") stack_vertical(["", ""], Center, 0, "") |> should.equal("\n") } pub fn stack_horizontal_test() { [ "--color", "Enable color support.\nThis option is enabled by default in a terminal.", ] |> stack_horizontal(place: Top, gap: 4, with: " ") |> should.equal( "--color Enable color support. \n" <> " This option is enabled by default in a terminal.", ) stack_horizontal([], Middle, 0, "") |> should.equal("") stack_horizontal([""], Middle, 1, " ") |> should.equal("") stack_horizontal(["", ""], Middle, 1, " ") |> should.equal(" ") }