Skip to content
This repository has been archived by the owner on Jul 12, 2020. It is now read-only.

Commit

Permalink
Add string.split implementation (#190)
Browse files Browse the repository at this point in the history
* init

* remove .history files

* fix bad test and add Roblox's internal tests

* change formatting to please linter
  • Loading branch information
Validark authored and LPGhatguy committed Apr 16, 2019
1 parent 6346da9 commit a69e245
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/libs/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local names = {
"math",
"string",
}

local libs = {}
Expand All @@ -8,4 +9,4 @@ for _, name in ipairs(names) do
libs[name] = import("./" .. name)
end

return libs
return libs
36 changes: 36 additions & 0 deletions lib/libs/string.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
local rbxString = {}

for key, value in pairs(string) do
rbxString[key] = value
end

rbxString.split = function(str, sep)
local result = {}

if sep == "" then
for i = 1, #str do
result[i] = str:sub(i, i)
end
else
if sep == nil then
sep = ","
end

local count = 1
local pos = 1
local a, b = str:find(sep, pos, true)

while a do
result[count] = str:sub(pos, a - 1)
count = count + 1
pos = b + 1
a, b = str:find(sep, pos, true)
end

result[count] = str:sub(pos)
end

return result
end

return rbxString
98 changes: 98 additions & 0 deletions lib/libs/string_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
local string = import("./string")

describe("libs.string", function()
describe("split", function()
it("should be a function", function()
assert.is_function(string.split)
end)

it("should return an array of comma separated strings if sep is nil", function()
assert.are.same({"Hello", "world", "and", "lemur"}, string.split("Hello,world,and,lemur"))
end)

it("should return an array of all characters in a string if sep is the empty string", function()
assert.are.same({
"H",
"e",
"l",
"l",
"o",
",",
"w",
"o",
"r",
"l",
"d",
",",
"a",
"n",
"d",
",",
"l",
"e",
"m",
"u",
"r",
}, string.split("Hello,world,and,lemur", ""))
end)

it("should return an empty table if the string and sep is the empty string", function()
assert.are.same({}, string.split("", ""))
end)

it("should return the original string in a table if no sep is matched", function()
assert.are.same({"Hello, world"}, string.split("Hello, world", "K"))
assert.are.same({""}, string.split("", " "))
end)

it("should return empty strings at the front and back when seps are present there", function()
assert.are.same({"", "Validark", "Osyris", "Vorlias", ""}, string.split("/Validark/Osyris/Vorlias/", "/"))
assert.are.same({"", "Validark", "Osyris", "Vorlias"}, string.split("/Validark/Osyris/Vorlias", "/"))
assert.are.same({"Validark", "Osyris", "Vorlias", ""}, string.split("Validark/Osyris/Vorlias/", "/"))
assert.are.same({"Validark", "Osyris", "Vorlias"}, string.split("Validark/Osyris/Vorlias", "/"))
end)

it("should allow multi-character separators", function()
assert.are.same({"Hello", "world"}, string.split("Hello, world", ", "))
end)

it("should literally interpret Lua character classes", function()
assert.are.same({"Hello, world"}, string.split("Hello, world", "%l"))
assert.are.same({"Hel", "o, world"}, string.split("Hel%lo, world", "%l"))
end)

it("should match Roblox's internal tests", function()
-- Provided by tiffany352 at https://github.com/LPGhatguy/lemur/pull/190
local char = string.char
local ZWJ = char(0xe2, 0x80, 0x8d)
assert.are.same({ "" }, string.split("", ","))
assert.are.same({ "foo", "", "bar" }, string.split("foo,,bar", ","))
assert.are.same({ "", "foo" }, string.split(",foo", ","))
assert.are.same({ "foo", "" }, string.split("foo,", ","))
assert.are.same({ "", "" }, string.split(",", ","))
assert.are.same({ "", "", "" }, string.split(",,", ","))
assert.are.same({ "" }, string.split("", "~~~"))
assert.are.same({ "~~" }, string.split("~~", "~~~"))
assert.are.same({ "~~ ~~" }, string.split("~~ ~~", "~~~"))
assert.are.same({ "foo", "bar" }, string.split("foo~~~bar", "~~~"))
assert.are.same({ "foo", "", "bar" }, string.split("foo~~~~~~bar", "~~~"))
assert.are.same({ "", "foo" }, string.split("~~~foo", "~~~"))
assert.are.same({ "foo", "" }, string.split("foo~~~", "~~~"))
assert.are.same({ "", "" }, string.split("~~~", "~~~"))
assert.are.same({ "", "", "" }, string.split("~~~~~~", "~~~"))
assert.are.same({ "", "", "O" }, string.split("OOOOO", "OO"))
assert.are.same({ " ws " }, string.split(" ws ", ","))
assert.are.same({ "foo ", " bar" }, string.split("foo , bar", ","))
assert.are.same({ "我很高兴", "你呢?" }, string.split("我很高兴,你呢?", ""))
assert.are.same({ "👩", "👩", "👧", "👧" }, string.split("👩‍👩‍👧‍👧", ZWJ))
assert.are.same({ "foo", "bar" }, string.split("foo\0bar", "\0"))
assert.are.same({ "foo", "bar", "" }, string.split("foo\0bar\0", "\0"))
assert.are.same({ "foo", "bar" }, string.split("foo\0\0bar", "\0\0"))
assert.are.same({ "foo\0" }, string.split("foo\0", "\0\0"))
assert.are.same({ "foo", "\0" }, string.split("foo\0\0\0", "\0\0"))
assert.are.same({ }, string.split("", ""))
assert.are.same({ "a", "b", "c" }, string.split("abc", ""))
assert.are.same({ char(0xef), char(0xbc), char(0x9f) }, string.split("", ""))
end)
end)
end)

0 comments on commit a69e245

Please sign in to comment.