From a741d06c0032aa25fc87b543974d8e653002d1aa Mon Sep 17 00:00:00 2001
From: Peter Aronoff
Date: Sun, 17 Apr 2016 18:52:54 -0400
Subject: [PATCH] Prepare for split 3.0.0-1
---
CHANGES.md | 11 ++++
README.md | 109 ++++++++++++++++++++++++-------
doc/changes.html | 14 ++++
doc/index.html | 109 ++++++++++++++++++++++++-------
split-3.0.0-1.rockspec | 24 +++++++
src/split.lua | 27 ++++++--
test/test-basics.lua | 14 ++--
test/test-deviant-pattern.lua | 9 ++-
test/test-empty-fields.lua | 22 +++----
test/test-first-and-rest.lua | 95 +++++++++++++++++++++++++++
test/test-information-fields.lua | 8 +--
test/test-iterator.lua | 50 +++++++-------
test/test-utf8.lua | 18 ++---
13 files changed, 401 insertions(+), 109 deletions(-)
create mode 100644 split-3.0.0-1.rockspec
create mode 100644 test/test-first-and-rest.lua
diff --git a/CHANGES.md b/CHANGES.md
index e5b8e42..21d6857 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -29,6 +29,17 @@
+ Change the information variables to functions. These serve the same purpose,
but don't use variable names that Lua explicitly warns users about.
+## *3.0.0-1* (April 24, 2016)
+
++ Clean up tests.
++ Change the name of `spliterator` to `each`. The new name is less silly and
+ hopefully clearer. **NB**: For the moment, `spliterator` is still provided as
+ an alias to `each`. However, in the next major version release (i.e.,
+ 4.0.0-1), `spliterator` will be removed. Please start switching any code that
+ uses `spliterator` to `each`.
++ Add `first_and_rest`, a string equivalent to a function that splits a list
+ into its head and tail.
+
Would you rather view the [documentation][d]?
[d]: /README.md
diff --git a/README.md b/README.md
index 900785b..a871ddb 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
## Synopsis
-A string `split` function and iterator for Lua, which doesn't provide such
-a function in its standard string library. Such a function is clearly useful,
-and [many people have written their own][wiki].
+A string `split` function and iterator for Lua sicne Lua's standard sting
+library doesn't provide such a function. When working with text `split` is very
+useful, and [many people have written a version for Lua][wiki].
[wiki]: http://lua-users.org/wiki/SplitJoin
@@ -14,16 +14,17 @@ and [many people have written their own][wiki].
The delimiter can be a literal string or a Lua pattern. The function returns
a table of items found by splitting the string up into pieces divided by the
- delimiter.
-
- Extra delimiters anywhere in the string will result in empty strings being
- returned as part of the results table.
+ delimiter. If the delimiter is not present in the string, then the result
+ will be a table consisting of one item: the original string parameter. Extra
+ delimiters anywhere in the string will result in empty strings being returned
+ as part of the results table.
The function also provides two shortcuts for common situations. If the
delimiter parameter is an empty string, the function returns a table
- containing every character in the original string as a separate item. If the
- delimiter parameter is `nil`, the function considers this equivalent to the
- Lua pattern `'%s+'` and splits the string on whitespace.
+ containing every character in the original string as a separate item. (I.e.,
+ if the delimiter is the empty string, the function explodes the string.) If
+ the delimiter parameter is `nil`, the function considers this equivalent to
+ the Lua pattern `'%s+'` and splits the string on whitespace.
Examples:
@@ -39,41 +40,95 @@ and [many people have written their own][wiki].
* A special case: empty string delimiter
- A pattern of the empty string is special. It tells the function to
- return each character from the original string as an individual item.
- Think of this as "explode the string".
+ If the delimiter is an empty string, the function returns each
+ character from the original string as an individual item. Think of
+ this as "explode the string".
split('foo', '') -- returns {'f', 'o', 'o'}
- * Another special case: nil delimiter
+ * Another special case: `nil` delimiter
- Passing nothing or an explicit `nil` as the delimiter is a second
- special case. `split` treats this as equivalent to a pattern of `'$s+'`
- and splits on consecutive runs of whitespace.
+ Pass nothing or an explicit `nil` as the delimiter and `split` acts as
+ if the delimiter were `'$s+'`. This makes it easier to split on
+ consecutive runs of whitespace.
split('foo bar buzz') -- returns {'foo', 'bar', 'buzz'}
-+ `spliterator(string, delimiter) => custom iterator`
++ `each(string, delimiter) => custom iterator`
+
+ **NB**: This function was previously called `spliterator`, but I've renamed
+ it to the shorter and less goofy `each`. In order to give people who might
+ rely on the previous name time to switch over, `spliterator` is still
+ provided as an alias for `each`. However, that name will be removed in the
+ next major version release (i.e., 4.0.0) of this module.
- This is an iterator version of the same idea. Everything from above applies,
- except that the function returns a custom iterator to work through results
- rather than a table.
+ This is an iterator version of the same idea as `split`. Everything from
+ above applies, except that the function returns a iterator to work through
+ results rather than a table.
- local spliter = require 'split'.spliterator
+ local split_each = require 'split'.each
- local str = 'foo,bar,bizz,buzz,'
+ local str = 'foo,bar,bizz,buzz'
local count = 1
- for p in spliter(str, ',') do
+ for p in split_each(str, ',') do
print(count .. '. [' .. p .. ']')
count = count + 1
end
++ `first_and_rest(string, delimiter) => string, string (or nil)`
+
+ This function is a string equivalent for a function that divides a list into
+ its head and tail. The head of the string is everything that appears before
+ the first appearance of a specified delimiter; the tail is the rest of the
+ string. `first_and_rest` attempts to split a string into two pieces, and it
+ returns two results using Lua's multiple return. The exact return values vary
+ depending on the string and delimiter.
+
+ In the simplest case, the string contains the delimiter at least once. If so,
+ the first return value will be the portion of the string before the first
+ appearance of the delimiter, and the second return value will be the rest of
+ the string after that delimiter.
+
+ If the delimiter does not appear in the string, however, then there's no
+ possible split. In this case, the first return value will be the entire
+ string, and the second return value will be `nil`. (From Lua's point of view,
+ a second return value of `nil` is equivalent to saying that the function only
+ returns one value.)
+
+ If the second return value is `nil`, there is probably a problem or malformed
+ record. So it will often make sense to test the second return value before
+ proceeding. For example:
+
+ local head, tail = first_and_rest(record, '%s*:%s*')
+ if not tail then
+ -- Signal an error to the caller.
+ else
+ -- Process the record.
+ end
+
+ A second complication is that the strings returned by the function may be
+ empty. If the delimiter is found, but the portion of the string before or
+ after it is zero-length, then an empty string may be returned. The examples
+ below show various possible outcomes.
+
+ first_and_rest('head: tail', ': ') -- returns 'head', 'tail'
+ first_and_rest('head, tail', ': ') -- returns 'head, tail', nil
+ first_and_rest(': tail', ': ') -- returns '', 'tail'
+ first_and_rest('head: ', ': ') -- returns 'head', ''
+
+ Like `split` and `each`, `first_and_rest` accepts `nil` or an empty string as
+ special cases for the delimiter. `nil` is automatically transformed into
+ '%s+', a generic "separated by space" pattern. In the case of an empty string
+ delimiter, `first_and_rest` returns the first character of the input and the
+ rest of the input. (This seems to be the only reasonable interpretation of
+ "exploding" the input string in the context of this function.)
+
## Varia
The module provides four informational functions that return strings. They
should be self-explanatory.
-+ `version() -- 2.0.0-1`
++ `version() -- 3.0.0-1`
+ `author() -- Peter Aronoff`
@@ -86,8 +141,12 @@ should be self-explanatory.
Many of my ideas came from reading [the LuaWiki page on split][wiki]. I thank
all those contributors for their suggestions and examples.
+[Alexey Melnichuk, AKA moteus][moteus] provided the idea and initial code for
+`first_and_rest`.
+
All mistakes are mine. See [version history][c] for release details.
+[moteus]: https://bitbucket.org/moteus
[c]: /CHANGES.md
---
diff --git a/doc/changes.html b/doc/changes.html
index 6eedf6f..b5ce2b0 100644
--- a/doc/changes.html
+++ b/doc/changes.html
@@ -44,6 +44,20 @@ 2.0.0-1 (March 5, 2016)
+3.0.0-1 (April 24, 2016)
+
+
+- Clean up tests.
+- Change the name of
spliterator
to each
. The new name is less silly and
+hopefully clearer. NB: For the moment, spliterator
is still provided as
+an alias to each
. However, in the next major version release (i.e.,
+4.0.0-1), spliterator
will be removed. Please start switching any code that
+uses spliterator
to each
.
+- Add
first_and_rest
, a string equivalent to a function that splits a list
+into its head and tail.
+
+
+
Would you rather view the documentation?
diff --git a/doc/index.html b/doc/index.html
index 71bd16a..d44d7d1 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -12,9 +12,9 @@
The function also provides two shortcuts for common situations. If the
delimiter parameter is an empty string, the function returns a table
-containing every character in the original string as a separate item. If the
-delimiter parameter is nil
, the function considers this equivalent to the
-Lua pattern '%s+'
and splits the string on whitespace.
+containing every character in the original string as a separate item. (I.e.,
+if the delimiter is the empty string, the function explodes the string.) If
+the delimiter parameter is nil
, the function considers this equivalent to
+the Lua pattern '%s+'
and splits the string on whitespace.
Examples:
@@ -49,37 +50,92 @@ Usage
A special case: empty string delimiter
- A pattern of the empty string is special. It tells the function to
- return each character from the original string as an individual item.
- Think of this as “explode the string”.
+ If the delimiter is an empty string, the function returns each
+ character from the original string as an individual item. Think of
+ this as “explode the string”.
split('foo', '') -- returns {'f', 'o', 'o'}
-Another special case: nil delimiter
+Another special case: nil
delimiter
- Passing nothing or an explicit nil
as the delimiter is a second
- special case. split
treats this as equivalent to a pattern of '$s+'
- and splits on consecutive runs of whitespace.
+ Pass nothing or an explicit nil
as the delimiter and split
acts as
+ if the delimiter were '$s+'
. This makes it easier to split on
+ consecutive runs of whitespace.
split('foo bar buzz') -- returns {'foo', 'bar', 'buzz'}
-spliterator(string, delimiter) => custom iterator
+each(string, delimiter) => custom iterator
+
+NB: This function was previously called spliterator
, but I’ve renamed
+it to the shorter and less goofy each
. In order to give people who might
+rely on the previous name time to switch over, spliterator
is still
+provided as an alias for each
. However, that name will be removed in the
+next major version release (i.e., 4.0.0) of this module.
-This is an iterator version of the same idea. Everything from above applies,
-except that the function returns a custom iterator to work through results
-rather than a table.
+This is an iterator version of the same idea as split
. Everything from
+above applies, except that the function returns a iterator to work through
+results rather than a table.
- local spliter = require 'split'.spliterator
+ local split_each = require 'split'.each
- local str = 'foo,bar,bizz,buzz,'
+ local str = 'foo,bar,bizz,buzz'
local count = 1
- for p in spliter(str, ',') do
+ for p in split_each(str, ',') do
print(count .. '. [' .. p .. ']')
count = count + 1
end
+first_and_rest(string, delimiter) => string, string (or nil)
+
+This function is a string equivalent for a function that divides a list into
+its head and tail. The head of the string is everything that appears before
+the first appearance of a specified delimiter; the tail is the rest of the
+string. first_and_rest
attempts to split a string into two pieces, and it
+returns two results using Lua’s multiple return. The exact return values vary
+depending on the string and delimiter.
+
+In the simplest case, the string contains the delimiter at least once. If so,
+the first return value will be the portion of the string before the first
+appearance of the delimiter, and the second return value will be the rest of
+the string after that delimiter.
+
+If the delimiter does not appear in the string, however, then there’s no
+possible split. In this case, the first return value will be the entire
+string, and the second return value will be nil
. (From Lua’s point of view,
+a second return value of nil
is equivalent to saying that the function only
+returns one value.)
+
+If the second return value is nil
, there is probably a problem or malformed
+record. So it will often make sense to test the second return value before
+proceeding. For example:
+
+ local head, tail = first_and_rest(record, '%s*:%s*')
+ if not tail then
+ -- Signal an error to the caller.
+ else
+ -- Process the record.
+ end
+
+
+A second complication is that the strings returned by the function may be
+empty. If the delimiter is found, but the portion of the string before or
+after it is zero-length, then an empty string may be returned. The examples
+below show various possible outcomes.
+
+ first_and_rest('head: tail', ': ') -- returns 'head', 'tail'
+ first_and_rest('head, tail', ': ') -- returns 'head, tail', nil
+ first_and_rest(': tail', ': ') -- returns '', 'tail'
+ first_and_rest('head: ', ': ') -- returns 'head', ''
+
+
+Like split
and each
, first_and_rest
accepts nil
or an empty string as
+special cases for the delimiter. nil
is automatically transformed into
+‘%s+’, a generic “separated by space” pattern. In the case of an empty string
+delimiter, first_and_rest
returns the first character of the input and the
+rest of the input. (This seems to be the only reasonable interpretation of
+“exploding” the input string in the context of this function.)
@@ -89,7 +145,7 @@ Varia
should be self-explanatory.
-version() -- 2.0.0-1
+version() -- 3.0.0-1
author() -- Peter Aronoff
url() -- https://bitbucket.org/telemachus/split
license() -- BSD 3-Clause
@@ -101,6 +157,9 @@ Credits
Many of my ideas came from reading the LuaWiki page on split. I thank
all those contributors for their suggestions and examples.
+Alexey Melnichuk, AKA moteus provided the idea and initial code for
+first_and_rest
.
+
All mistakes are mine. See version history for release details.
diff --git a/split-3.0.0-1.rockspec b/split-3.0.0-1.rockspec
new file mode 100644
index 0000000..10e84bd
--- /dev/null
+++ b/split-3.0.0-1.rockspec
@@ -0,0 +1,24 @@
+package = 'split'
+version = '3.0.0-1'
+source = {
+ url = 'https://bitbucket.org/telemachus/split/downloads/split-v3.0.0-1.tar.gz',
+ dir = 'split'
+}
+description = {
+ summary = 'String split function and iterator for Lua',
+ detailed = [[
+ A string split function and iterator for Lua since the string standard
+ library doesn't come with one.
+ ]],
+ homepage = 'https://bitbucket.org/telemachus/split',
+ license = 'BSD 3-Clause',
+ maintainer = 'Peter Aronoff '
+}
+dependencies = { 'lua >= 5.1' }
+build = {
+ type = 'builtin',
+ modules = {
+ split = 'src/split.lua',
+ },
+ copy_directories = { 'doc' }
+}
diff --git a/src/split.lua b/src/split.lua
index c5572f8..2a1f39f 100644
--- a/src/split.lua
+++ b/src/split.lua
@@ -76,8 +76,8 @@ local split = function (str, delimiter)
return t
end
---- spliterator(str, delimiter)
-local spliterator = function (str, delimiter)
+--- each(str, delimiter)
+local each = function (str, delimiter)
delimiter = delimiter or '%s+'
if delimiter == '' then return gmatch(str, '.') end
if find('', delimiter, 1) then
@@ -109,8 +109,25 @@ local spliterator = function (str, delimiter)
return iter
end
+local first_and_rest = function(str, delimiter)
+ delimiter = delimiter or '%s+'
+ if delimiter == '' then return cut(str, 1, 1), cut(str, 2) end
+ if find('', delimiter, 1) then
+ local msg = fmt('The delimiter (%s) would match the empty string.',
+ delimiter)
+ error(msg)
+ end
+
+ local s, e = find(str, delimiter)
+ if s then
+ return cut(str, 1, s - 1), cut(str, e + 1)
+ else
+ return str
+ end
+end
+
local version = function ()
- return '2.0.0-1'
+ return '3.0.0-1'
end
local author = function ()
@@ -127,7 +144,9 @@ end
return {
split = split,
- spliterator = spliterator,
+ each = each,
+ spliterator = each,
+ first_and_rest = first_and_rest,
version = version,
author = author,
url = url,
diff --git a/test/test-basics.lua b/test/test-basics.lua
index ce3bf9d..2cb776a 100755
--- a/test/test-basics.lua
+++ b/test/test-basics.lua
@@ -11,36 +11,36 @@ t.same(got, {}, "split('', ) should return empty table.")
s = 'foobar'
got = split(s, ',')
-t.is(#got, 1, "Split 'foobar' on commas should have one item.")
-t.is(got[1], 'foobar', "First item should be 'foo'.")
+t.is(#got, 1, "split('foobar', ',') should have one item.")
+t.is(got[1], 'foobar', "First item should be 'foobar'.")
s = 'foo,bar'
got = split(s, ',')
-t.is(#got, 2, "Split 'foo,bar' on commas should have two items.")
+t.is(#got, 2, "split('foo,bar', ',') should have two items.")
t.is(got[1], 'foo', "First item should be 'foo'.")
t.is(got[2], 'bar', "Second item should be 'bar'.")
s = '1 2'
got = split(s, ' ')
-t.is(#got, 2, "Split '1 2' on a literal space should have two items.")
+t.is(#got, 2, "split('1 2', ' ') should have two items.")
t.is(got[1], '1', "First item should be '1'.")
t.is(got[2], '2', "Second item should be '2'.")
s = 'foo bar'
got = split(s, '%s')
-t.is(#got, 2, "Split 'foo bar' on %s should have two items.")
+t.is(#got, 2, "split('foo bar', '%s') should have two items.")
t.is(got[1], 'foo', "First item should be 'foo'.")
t.is(got[2], 'bar', "Second item should be 'bar'.")
s = 'foo bar'
got = split(s, '%s+')
-t.is(#got, 2, "Split 'foo bar' on space pattern [%s+] should have two items.")
+t.is(#got, 2, "split('foo bar', '%s+') should have two items.")
t.is(got[1], 'foo', "First item should be 'foo'.")
t.is(got[2], 'bar', "Second item should be 'bar'.")
s = 'foo\tbar'
got = split(s, '%s+')
-t.is(#got, 2, "Split 'foo\tbar' on %s+ should have two items.")
+t.is(#got, 2, "split('foo\\tbar', '%s+') should have two items.")
t.is(got[1], 'foo', "First item should be 'foo'.")
t.is(got[2], 'bar', "Second item should be 'bar'.")
diff --git a/test/test-deviant-pattern.lua b/test/test-deviant-pattern.lua
index a81770b..6fa3610 100755
--- a/test/test-deviant-pattern.lua
+++ b/test/test-deviant-pattern.lua
@@ -1,11 +1,16 @@
#!/usr/bin/env lua
local t = require 'tapered'
package.path = '../src/?.lua;' .. package.path
-local split = require 'split'.split
+local split = require 'split'
local s
s = ',foo,bar'
-t.boom(split, {s, '%d*'}, 'Should blow up with deviant pattern.')
+t.boom(split.split, {s, '%d*'},
+ 'split() should blow up with deviant pattern.')
+
+s = ',foo,bar'
+t.boom(split.first_and_rest, {s, '%d*'},
+ 'first_and_rest() should blow up with deviant pattern.')
t.done()
diff --git a/test/test-empty-fields.lua b/test/test-empty-fields.lua
index 416f97f..3402a05 100755
--- a/test/test-empty-fields.lua
+++ b/test/test-empty-fields.lua
@@ -7,30 +7,30 @@ local s, got
s = ',foo,bar'
got = split(s, ',')
-t.is(#got, 3, "Split ',foo,bar' should have three fields")
-t.is(got[1], '', 'First item should be empty field')
+t.is(#got, 3, "split(',foo,bar', ',') should have three fields.")
+t.is(got[1], '', 'First item should be empty field.')
t.is(got[2], 'foo', "Second item should be 'foo'.")
t.is(got[3], 'bar', "Third item should be 'bar'.")
s = 'foo,bar,'
got = split(s, ',')
-t.is(#got, 3, "Split 'foo,bar,' should have three fields")
+t.is(#got, 3, "split('foo,bar,', ',') should have three fields.")
t.is(got[1], 'foo', "First item should be 'foo'.")
t.is(got[2], 'bar', "Second item should be 'bar'.")
t.is(got[3], '', 'Third item should be empty.')
s = ',,,'
got = split(s, ',')
-t.is(#got, 4, "Split ',,,' should have four fields")
-t.is(got[1], '', 'First item should be empty field')
-t.is(got[2], '', 'Second item should be empty field')
-t.is(got[3], '', 'Third item should be empty field')
-t.is(got[4], '', 'Fourth item should be empty field')
+t.is(#got, 4, "split(',,,', ',') should have four fields.")
+t.is(got[1], '', 'First item should be empty field.')
+t.is(got[2], '', 'Second item should be empty field.')
+t.is(got[3], '', 'Third item should be empty field.')
+t.is(got[4], '', 'Fourth item should be empty field.')
s = ','
got = split(s, ',')
-t.is(#got, 2, "Split ',' should have two fields")
-t.is(got[1], '', 'First item should be empty field')
-t.is(got[2], '', 'Second item should be empty field')
+t.is(#got, 2, "split(',', ',') should have two fields.")
+t.is(got[1], '', 'First item should be empty field.')
+t.is(got[2], '', 'Second item should be empty field.')
t.done()
diff --git a/test/test-first-and-rest.lua b/test/test-first-and-rest.lua
new file mode 100644
index 0000000..4cd9bf2
--- /dev/null
+++ b/test/test-first-and-rest.lua
@@ -0,0 +1,95 @@
+#!/usr/bin/env lua
+local t = require 'tapered'
+package.path = '../src/?.lua;' .. package.path
+local split_first_and_rest = require 'split'.first_and_rest
+
+local nret = function(...)
+ return select("#", ...), ...
+end
+
+local function split(...)
+ return nret(split_first_and_rest(...))
+end
+
+local s, n, a, b
+
+t.boom(split, {nil, ','},
+ "first_and_rest(nil, ) should throw an error.")
+
+s = ''
+n, a = split(s, ',')
+t.is(n, 1, "first_and_rest('', ) should return empty string.")
+t.is(a, '', "First item should be the empty string.")
+
+s = ',foo,'
+n, a, b = split(s, ',')
+t.is(n, 2, "first_and_rest(',foo,', ',') should have two items.")
+t.is(a, '', "First item should be the empty string.")
+t.is(b, 'foo,', "Second item should be 'foo,'.")
+
+s = ',foo'
+n, a, b = split(s, ',')
+t.is(n, 2, "first_and_rest(',foo', ',') should have two items.")
+t.is(a, '', "First item should be the empty string.")
+t.is(b, 'foo', "Second item should be 'foo'.")
+
+s = 'foo,'
+n, a, b = split(s, ',')
+t.is(n, 2, "first_and_rest('foo,', ',') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, '', "Second item should be the empty string.")
+
+s = 'foobar'
+n, a = split(s, ',')
+t.is(n, 1, "first_and_rest('foobar', ',') should have one item.")
+t.is(a, 'foobar', "First item should be 'foobar'.")
+
+s = 'foobar'
+n, a, b = split(s, '')
+t.is(n, 2, "first_and_rest('foobar', '') should have two items.")
+t.is(a, 'f', "First item should be 'f'.")
+t.is(b, 'oobar', "First item should be 'oobar'.")
+
+s = 'foo,bar'
+n, a, b = split(s, ',')
+t.is(n, 2, "first_and_rest('foo,bar', ',') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar', "Second item should be 'bar'.")
+
+s = '1 2'
+n, a, b = split(s, ' ')
+t.is(n, 2, "first_and_rest('1 2', ' ') should have two items.")
+t.is(a, '1', "First item should be '1'.")
+t.is(b, '2', "Second item should be '2'.")
+
+s = 'foo bar'
+n, a, b = split(s, '%s')
+t.is(n, 2, "first_and_rest('foo bar', '%s') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar', "Second item should be 'bar'.")
+
+s = 'foo bar'
+n, a, b = split(s, '%s+')
+t.is(n, 2, "first_and_rest('foo bar', '%s+') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar', "Second item should be 'bar'.")
+
+s = 'foo bar'
+n, a, b = split(s)
+t.is(n, 2, "first_and_rest('foo bar')—default space pattern—should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar', "Second item should be 'bar'.")
+
+s = 'foo\tbar'
+n, a, b = split(s, '%s+')
+t.is(n, 2, "first_and_rest('foo\\tbar', '%s+') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar', "Second item should be 'bar'.")
+
+s = 'foo bar\tbug daz'
+n, a, b = split(s, '%s+')
+t.is(n, 2, "first_and_rest('foo bar\\tbug daz', '%s+') should have two items.")
+t.is(a, 'foo', "First item should be 'foo'.")
+t.is(b, 'bar\tbug daz', "Second item should be 'bar\\tbug daz'.")
+
+t.done()
diff --git a/test/test-information-fields.lua b/test/test-information-fields.lua
index f240280..a77960a 100644
--- a/test/test-information-fields.lua
+++ b/test/test-information-fields.lua
@@ -3,10 +3,10 @@ local t = require 'tapered'
package.path = '../src/?.lua;' .. package.path
local split = require 'split'
-t.is(split.version(), '2.0.0-1', 'version() returns 2.0.0-1')
-t.is(split.author(), 'Peter Aronoff', 'author() returns Peter Aronoff')
+t.is(split.version(), '3.0.0-1', "version() returns '3.0.0-1'.")
+t.is(split.author(), 'Peter Aronoff', "author() returns 'Peter Aronoff'.")
t.is(split.url(), 'https://bitbucket.org/telemachus/split',
- 'url() returns https://bitbucket.org/telemachus/split')
-t.is(split.license(), 'BSD 3-Clause', 'license() returns BSD 3-Clause')
+ "url() returns 'https://bitbucket.org/telemachus/split'.")
+t.is(split.license(), 'BSD 3-Clause', "license() returns 'BSD 3-Clause'.")
t.done()
diff --git a/test/test-iterator.lua b/test/test-iterator.lua
index 0f4b007..af37f84 100755
--- a/test/test-iterator.lua
+++ b/test/test-iterator.lua
@@ -1,70 +1,76 @@
#!/usr/bin/env lua
package.path = '../src/?.lua;' .. package.path
-local spliter = require 'split'.spliterator
+local split = require 'split'
+local spliter = split.spliterator
+local each = split.each
local t = require 'tapered'
-local str = 'a,foo,bar,bizz,buzz,,b'
-local expected = { 'a', 'foo', 'bar', 'bizz', 'buzz', '', 'b' }
-local actual = {}
-for p in spliter(str, ',') do
+local str, expected, actual
+
+t.same(spliter, each, "spliterator should be an alias for each.")
+
+str = 'a,foo,bar,bizz,buzz,,b'
+expected = { 'a', 'foo', 'bar', 'bizz', 'buzz', '', 'b' }
+actual = {}
+for p in each(str, ',') do
actual[#actual + 1] = p
end
-t.same(actual, expected, 'Build up a table of results from the split iterator')
+t.same(actual, expected, "each(str, ',') should iterate over the string.")
str = 'a foo bar bizz buzz b'
expected = { 'a', 'foo', 'bar', 'bizz', 'buzz', 'b' }
actual = {}
-for p in spliter(str) do
+for p in each(str) do
actual[#actual + 1] = p
end
-t.same(actual, expected, 'Use iterator with nil pattern')
+t.same(actual, expected, "each(str) should properly handle nil delimiter.")
str = 'foo'
expected = { 'f', 'o', 'o' }
actual = {}
-for p in spliter(str, '') do
- print(#actual+1, p)
+for p in each(str, '') do
actual[#actual + 1] = p
end
-t.same(actual, expected, 'Use iterator to explode a string')
+t.same(actual, expected, "each(str, '') should iterate over each character.")
str = 'f.o.o'
expected = { 'f', 'o', 'o' }
actual = {}
-for p in spliter(str, '%.') do
+for p in each(str, '%.') do
actual[#actual + 1] = p
end
-t.same(actual, expected, 'Use iterator with \'%.\' as the pattern')
+t.same(actual, expected, "each(str, '%.') should split on a literal period.")
str = ',foo,bar,bizz,buzz,,'
expected = { 'zzz', 'zzzfoo', 'zzzbar', 'zzzbizz', 'zzzbuzz', 'zzz', 'zzz' }
actual = {}
-for p in spliter(str, ',') do
+for p in each(str, ',') do
actual[#actual + 1] = 'zzz' .. p
end
-t.same(actual, expected, 'Adapt results from the split iterator')
+t.same(actual, expected,
+ "each(str, ',') should be able to change returned items.")
str = ''
expected = {}
actual = {}
-for p in spliter(str, '|') do
+for p in each(str, '|') do
actual[#actual + 1] = p
end
-t.same(actual, expected, "spliter('', '|') should return no results")
+t.same(actual, expected, "each('', '|') should return no results.")
str = 'foobar'
expected = { 'foobar' }
actual = {}
-for p in spliter(str, '|') do
+for p in each(str, '|') do
actual[#actual + 1] = p
end
-t.is(#actual, 1, "spliter('foobar', '|') should yield one item")
-t.same(actual, expected, "spliter('foobar', '|') should return 'foobar'")
+t.is(#actual, 1, "each('foobar', '|') should yield one item.")
+t.same(actual, expected, "each('foobar', '|') should return { 'foobar' }.")
local explode = function (pat)
- for _ in spliter('foo', pat) do
+ for _ in each('foo', pat) do
end
end
-t.boom(explode,{'%d*'}, 'Deviant pattern should throw error in spliterator')
+t.boom(explode,{'%d*'}, "Deviant pattern should throw error in each.")
t.done()
diff --git a/test/test-utf8.lua b/test/test-utf8.lua
index 8a1ba6f..52cf690 100755
--- a/test/test-utf8.lua
+++ b/test/test-utf8.lua
@@ -8,17 +8,17 @@ local s, got
s = 'fōö,bàr,bízz,bũzz'
got = split(s, ',')
t.is(#got, 4, "split('fōö,bàr,bízz,bũzz', ',') returns four items")
-t.is(got[1], 'fōö', "The first item is 'fōö'")
-t.is(got[2], 'bàr', "The second item is 'bàr'")
-t.is(got[3], 'bízz', "The third item is 'bízz'")
-t.is(got[4], 'bũzz', "The fourth item is 'bũzz'")
+t.is(got[1], 'fōö', "The first item should be 'fōö'.")
+t.is(got[2], 'bàr', "The second item should be 'bàr'.")
+t.is(got[3], 'bízz', "The third item should be 'bízz'.")
+t.is(got[4], 'bũzz', "The fourth item should be 'bũzz'.")
s = 'ἄνδραἦμοιἦἔννεπεἦΜοῦσαἦπολύτροπον'
got = split(s, 'ἦ')
t.is(#got, 5,
"split('ἄνδραἦμοιἦἔννεπεἦΜοῦσαἦπολύτροπον', 'ἦ') returns five items")
-t.is(got[1], 'ἄνδρα', "The first item is 'ἄνδρα'")
-t.is(got[2], 'μοι', "The second item is 'μοι'")
-t.is(got[3], 'ἔννεπε', "The third item is 'ἔννεπε'")
-t.is(got[4], 'Μοῦσα', "The fourth item is 'Μοῦσα'")
-t.is(got[5], 'πολύτροπον', "The fifth item is 'πολύτροπον'")
+t.is(got[1], 'ἄνδρα', "The first item should be 'ἄνδρα'.")
+t.is(got[2], 'μοι', "The second item should be 'μοι'.")
+t.is(got[3], 'ἔννεπε', "The third item should be 'ἔννεπε'.")
+t.is(got[4], 'Μοῦσα', "The fourth item should be 'Μοῦσα'.")
+t.is(got[5], 'πολύτροπον', "The fifth item should be 'πολύτροπον'.")