mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 10:00:06 +08:00
306 lines
12 KiB
Lua
306 lines
12 KiB
Lua
local strings = require "plenary.strings"
|
|
local eq = assert.are.same
|
|
|
|
describe("strings", function()
|
|
describe("strdisplaywidth", function()
|
|
for _, case in ipairs {
|
|
{ str = "abcde", expected = { single = 5, double = 5 } },
|
|
-- This space below is a tab (U+0009)
|
|
{ str = "abc de", expected = { single = 10, double = 10 } },
|
|
{ str = "アイウエオ", expected = { single = 10, double = 10 } },
|
|
{ str = "├─┤", expected = { single = 3, double = 6 } },
|
|
{ str = 123, expected = { single = 3, double = 3 } },
|
|
} do
|
|
for _, ambiwidth in ipairs { "single", "double" } do
|
|
local item = type(case.str) == "string" and '"%s"' or "%s"
|
|
local msg = ("ambiwidth = %s, " .. item .. " -> %d"):format(ambiwidth, case.str, case.expected[ambiwidth])
|
|
local original = vim.o.ambiwidth
|
|
vim.o.ambiwidth = ambiwidth
|
|
it("lua: " .. msg, function()
|
|
eq(case.expected[ambiwidth], strings.strdisplaywidth(case.str))
|
|
end)
|
|
it("vim: " .. msg, function()
|
|
eq(case.expected[ambiwidth], vim.fn.strdisplaywidth(case.str))
|
|
end)
|
|
vim.o.ambiwidth = original
|
|
end
|
|
end
|
|
end)
|
|
|
|
describe("strcharpart", function()
|
|
for _, case in ipairs {
|
|
{ args = { "abcde", 2 }, expected = "cde" },
|
|
{ args = { "abcde", 2, 2 }, expected = "cd" },
|
|
{ args = { "アイウエオ", 2, 2 }, expected = "ウエ" },
|
|
{ args = { "├───┤", 2, 2 }, expected = "──" },
|
|
} do
|
|
local msg = ('("%s", %d, %s) -> "%s"'):format(case.args[1], case.args[2], tostring(case.args[3]), case.expected)
|
|
it("lua: " .. msg, function()
|
|
eq(case.expected, strings.strcharpart(unpack(case.args)))
|
|
end)
|
|
it("vim: " .. msg, function()
|
|
eq(case.expected, vim.fn.strcharpart(unpack(case.args)))
|
|
end)
|
|
end
|
|
end)
|
|
|
|
describe("truncate", function()
|
|
for _, case in ipairs {
|
|
-- truncations from the right
|
|
{ args = { "abcde", 6, nil, 1 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 5, nil, 1 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 4, nil, 1 }, expected = { single = "abc…", double = "ab…" } },
|
|
{
|
|
args = { "アイウエオ", 11, nil, 1 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 10, nil, 1 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 9, nil, 1 },
|
|
expected = { single = "アイウエ…", double = "アイウ…" },
|
|
},
|
|
{ args = { "アイウエオ", 8, nil, 1 }, expected = { single = "アイウ…", double = "アイウ…" } },
|
|
{ args = { "├─┤", 7, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 6, nil, 1 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 5, nil, 1 }, expected = { single = "├─┤", double = "├…" } },
|
|
{ args = { "├─┤", 4, nil, 1 }, expected = { single = "├─┤", double = "├…" } },
|
|
{ args = { "├─┤", 3, nil, 1 }, expected = { single = "├─┤", double = "…" } },
|
|
{ args = { "├─┤", 2, nil, 1 }, expected = { single = "├…", double = "…" } },
|
|
-- truncations from the left
|
|
{ args = { "abcde", 6, nil, -1 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 5, nil, -1 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 4, nil, -1 }, expected = { single = "…cde", double = "…de" } },
|
|
{
|
|
args = { "アイウエオ", 11, nil, -1 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 10, nil, -1 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 9, nil, -1 },
|
|
expected = { single = "…イウエオ", double = "…ウエオ" },
|
|
},
|
|
{ args = { "アイウエオ", 8, nil, -1 }, expected = { single = "…ウエオ", double = "…ウエオ" } },
|
|
{ args = { "├─┤", 7, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 6, nil, -1 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 5, nil, -1 }, expected = { single = "├─┤", double = "…┤" } },
|
|
{ args = { "├─┤", 4, nil, -1 }, expected = { single = "├─┤", double = "…┤" } },
|
|
{ args = { "├─┤", 3, nil, -1 }, expected = { single = "├─┤", double = "…" } },
|
|
{ args = { "├─┤", 2, nil, -1 }, expected = { single = "…┤", double = "…" } },
|
|
-- truncations from the middle
|
|
{ args = { "abcde", 6, nil, 0 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 5, nil, 0 }, expected = { single = "abcde", double = "abcde" } },
|
|
{ args = { "abcde", 4, nil, 0 }, expected = { single = "a…de", double = "a…e" } },
|
|
{
|
|
args = { "アイウエオ", 11, nil, 0 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 10, nil, 0 },
|
|
expected = { single = "アイウエオ", double = "アイウエオ" },
|
|
},
|
|
{
|
|
args = { "アイウエオ", 9, nil, 0 },
|
|
expected = { single = "アイ…エオ", double = "ア…エオ" },
|
|
},
|
|
{ args = { "アイウエオ", 8, nil, 0 }, expected = { single = "ア…エオ", double = "ア…エオ" } },
|
|
{ args = { "├─┤", 7, nil, 0 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 6, nil, 0 }, expected = { single = "├─┤", double = "├─┤" } },
|
|
{ args = { "├─┤", 5, nil, 0 }, expected = { single = "├─┤", double = "…┤" } },
|
|
{ args = { "├─┤", 4, nil, 0 }, expected = { single = "├─┤", double = "…┤" } },
|
|
{ args = { "├─┤", 3, nil, 0 }, expected = { single = "├─┤", double = "…" } },
|
|
{ args = { "├─┤", 2, nil, 0 }, expected = { single = "…┤", double = "…" } },
|
|
} do
|
|
for _, ambiwidth in ipairs { "single", "double" } do
|
|
local msg = ("ambiwidth = %s, direction = %s, [%s, %d] -> %s"):format(
|
|
ambiwidth,
|
|
(case.args[4] > 0) and "right" or (case.args[4] < 0) and "left" or "middle",
|
|
case.args[1],
|
|
case.args[2],
|
|
case.expected[ambiwidth]
|
|
)
|
|
it(msg, function()
|
|
local original = vim.o.ambiwidth
|
|
vim.o.ambiwidth = ambiwidth
|
|
eq(case.expected[ambiwidth], strings.truncate(unpack(case.args)))
|
|
vim.o.ambiwidth = original
|
|
end)
|
|
end
|
|
end
|
|
end)
|
|
|
|
describe("align_str", function()
|
|
for _, case in ipairs {
|
|
{ args = { "abcde", 8 }, expected = { single = "abcde ", double = "abcde " } },
|
|
{ args = { "アイウ", 8 }, expected = { single = "アイウ ", double = "アイウ " } },
|
|
{ args = { "├─┤", 8 }, expected = { single = "├─┤ ", double = "├─┤ " } },
|
|
{ args = { "abcde", 8, true }, expected = { single = " abcde", double = " abcde" } },
|
|
{ args = { "アイウ", 8, true }, expected = { single = " アイウ", double = " アイウ" } },
|
|
{ args = { "├─┤", 8, true }, expected = { single = " ├─┤", double = " ├─┤" } },
|
|
} do
|
|
for _, ambiwidth in ipairs { "single", "double" } do
|
|
local msg = ('ambiwidth = %s, [%s, %d, %s] -> "%s"'):format(
|
|
ambiwidth,
|
|
case.args[1],
|
|
case.args[2],
|
|
tostring(case.args[3]),
|
|
case.expected[ambiwidth]
|
|
)
|
|
it(msg, function()
|
|
local original = vim.o.ambiwidth
|
|
vim.o.ambiwidth = ambiwidth
|
|
eq(case.expected[ambiwidth], strings.align_str(unpack(case.args)))
|
|
vim.o.ambiwidth = original
|
|
end)
|
|
end
|
|
end
|
|
end)
|
|
|
|
describe("dedent", function()
|
|
local function lines(t)
|
|
return table.concat(t, "\n")
|
|
end
|
|
for _, case in ipairs {
|
|
{
|
|
msg = "empty string",
|
|
tabstop = 8,
|
|
args = { "" },
|
|
expected = "",
|
|
},
|
|
{
|
|
msg = "in case tabs are longer than spaces",
|
|
tabstop = 8,
|
|
args = {
|
|
lines {
|
|
" <Tab><Tab> -> 13 spaces",
|
|
" 5 spaces -> 0 space",
|
|
},
|
|
},
|
|
expected = lines {
|
|
" <Tab><Tab> -> 13 spaces",
|
|
"5 spaces -> 0 space",
|
|
},
|
|
},
|
|
{
|
|
msg = "in case tabs are shorter than spaces",
|
|
tabstop = 2,
|
|
args = {
|
|
lines {
|
|
" <Tab><Tab> -> 0 space",
|
|
" 5spaces -> 1 space",
|
|
},
|
|
},
|
|
expected = lines {
|
|
"<Tab><Tab> -> 0 space",
|
|
" 5spaces -> 1 space",
|
|
},
|
|
},
|
|
{
|
|
msg = "ignores empty lines",
|
|
tabstop = 2,
|
|
args = {
|
|
lines {
|
|
"",
|
|
"",
|
|
"",
|
|
" 8 spaces -> 3 spaces",
|
|
"",
|
|
"",
|
|
" 5 spaces -> 0 space",
|
|
"",
|
|
"",
|
|
"",
|
|
},
|
|
},
|
|
expected = lines {
|
|
"",
|
|
"",
|
|
"",
|
|
" 8 spaces -> 3 spaces",
|
|
"",
|
|
"",
|
|
"5 spaces -> 0 space",
|
|
"",
|
|
"",
|
|
"",
|
|
},
|
|
},
|
|
{
|
|
msg = "no indent",
|
|
tabstop = 2,
|
|
args = {
|
|
lines {
|
|
" <Tab> -> 2 spaces",
|
|
"Here is no indent.",
|
|
" 4 spaces will remain",
|
|
},
|
|
},
|
|
expected = lines {
|
|
" <Tab> -> 2 spaces",
|
|
"Here is no indent.",
|
|
" 4 spaces will remain",
|
|
},
|
|
},
|
|
{
|
|
msg = "leave_indent = 4",
|
|
tabstop = 2,
|
|
args = {
|
|
lines {
|
|
" <Tab> -> 6 spaces",
|
|
"0 indent -> 4 spaces",
|
|
" 4 spaces -> 8 spaces",
|
|
},
|
|
4,
|
|
},
|
|
expected = lines {
|
|
" <Tab> -> 6 spaces",
|
|
" 0 indent -> 4 spaces",
|
|
" 4 spaces -> 8 spaces",
|
|
},
|
|
},
|
|
{
|
|
msg = "typical usecase: <Tab> to 5 spaces",
|
|
tabstop = 4,
|
|
args = {
|
|
lines {
|
|
"",
|
|
" Chapter 1",
|
|
"",
|
|
" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed",
|
|
" do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
"",
|
|
" Ut enim ad minim veniam, quis nostrud exercitation ullamco",
|
|
" laboris nisi ut aliquip ex ea commodo consequat.",
|
|
"",
|
|
},
|
|
5,
|
|
},
|
|
expected = lines {
|
|
"",
|
|
" Chapter 1",
|
|
"",
|
|
" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed",
|
|
" do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
"",
|
|
" Ut enim ad minim veniam, quis nostrud exercitation ullamco",
|
|
" laboris nisi ut aliquip ex ea commodo consequat.",
|
|
"",
|
|
},
|
|
},
|
|
} do
|
|
local msg = ("tabstop = %d, %s"):format(case.tabstop, case.msg)
|
|
it(msg, function()
|
|
local original = vim.bo.tabstop
|
|
vim.bo.tabstop = case.tabstop
|
|
eq(case.expected, strings.dedent(unpack(case.args)))
|
|
vim.bo.tabstop = original
|
|
end)
|
|
end
|
|
end)
|
|
end)
|