├── .gitignore
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── src
└── str
│ ├── init.lua
│ └── utils.lua
├── str-1.5.0-0.rockspec
└── test.lua
/.gitignore:
--------------------------------------------------------------------------------
1 | *.rock
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | sudo: false
3 |
4 | env:
5 | - LUA="lua=5.1"
6 | - LUA="lua=5.2"
7 | - LUA="lua=5.3"
8 |
9 | before_install:
10 | - pip install hererocks
11 | - hererocks lua_install -r^ --$LUA
12 | - export PATH=$PATH:$PWD/lua_install/bin
13 |
14 | install:
15 | - make install
16 | - make install_dev
17 |
18 | script:
19 | - make test
20 |
21 | notifications:
22 | email:
23 | on_success: change
24 | on_failure: always
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Evandro Leopoldino Gonçalves
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .SILENT:
2 |
3 | test:
4 | LUA_PATH="./src/?.lua;./src/?/init.lua;./src/str/?.lua;;" lua test.lua
5 |
6 | install:
7 | luarocks install luautf8
8 |
9 | install_dev:
10 | luarocks install simple_test
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # str
2 | str
is a string module with useful methods that don't exist in Lua's core
3 | For docs, see: https://evandrolg.github.io/str/
4 |
5 | [](https://travis-ci.org/EvandroLG/str)
7 |
8 | ## Installation
9 | To install str, run:
10 | ```sh
11 | $ luarocks install str
12 | ```
13 |
14 | ## See too:
15 | * [array.lua](http://www.github.com/evandrolg/array.lua)
16 | * [Hash.lua](https://github.com/EvandroLG/Hash.lua)
17 |
18 | ## LICENSE
19 | [MIT](https://github.com/EvandroLG/str/tree/master/LICENSE)
20 |
--------------------------------------------------------------------------------
/src/str/init.lua:
--------------------------------------------------------------------------------
1 | local utf8 = require 'lua-utf8'
2 | local utils = require 'str.utils'
3 |
4 | local str
5 |
6 | str = {
7 | __VERSION = '1.5.0',
8 | __DESCRIPTION = "str is a string module with useful methods that don't exist in Lua's core",
9 | __LICENCE = [[
10 | The MIT License (MIT)
11 |
12 | Copyright (c) 2017 Evandro Leopoldino Gonçalves
13 |
14 | Permission is hereby granted, free of charge, to any person obtaining a copy
15 | of this software and associated documentation files (the "Software"), to deal
16 | in the Software without restriction, including without limitation the rights
17 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | copies of the Software, and to permit persons to whom the Software is
19 | furnished to do so, subject to the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included in all
22 | copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 | SOFTWARE.
31 | ]],
32 |
33 | -- extracts a part of the string and returns a new string
34 | -- @param s {string}
35 | -- @param start {number}
36 | -- @param finish {number | nil}
37 | -- @return {string}
38 | slice = function(s, start, finish)
39 | return string.sub(s, start, finish or #s)
40 | end,
41 |
42 | -- checks whether string starts with the value passed by parameter
43 | -- @param s {string}
44 | -- @param start {number}
45 | -- @return {string}
46 | starts_with = function(s, start)
47 | return string.sub(s, 1, #start) == start
48 | end,
49 |
50 | -- checks whether string ends with the value passed by parameter
51 | -- @param s {string}
52 | -- @param finish {number}
53 | -- @return {string}
54 | ends_with = function(s, finish)
55 | return string.sub(s, -#finish) == finish
56 | end,
57 |
58 | -- returns how many times the substring was found
59 | -- @param s {string}
60 | -- @param substr {string}
61 | -- @return {number}
62 | count = function(s, substr)
63 | local total = 0
64 | local start = nil
65 | local finish = 1
66 |
67 | repeat
68 | start, finish = string.find(s, substr, finish, true)
69 | if start then total = total + 1 end
70 | until start == nil
71 |
72 | return total
73 | end,
74 |
75 | -- splits the string into substring using the specified separator and return them as a table
76 | -- @param s {string}
77 | -- @param pattern {string}
78 | -- @return {table}
79 | split = function(s, pattern)
80 | local output = {}
81 | local fpat = '(.-)' .. pattern
82 | local last_end = 1
83 | local _s, e, cap = s:find(fpat, 1)
84 |
85 | while _s do
86 | if _s ~= 1 or cap ~= '' then
87 | table.insert(output, cap)
88 | end
89 |
90 | last_end = e+1
91 | _s, e, cap = s:find(fpat, last_end)
92 | end
93 |
94 | if last_end <= #s then
95 | cap = s:sub(last_end)
96 | table.insert(output, cap)
97 | end
98 |
99 | return output
100 | end,
101 |
102 | -- returns a new string with trailing whitespace removed
103 | -- @param s {string}
104 | -- @return {string}
105 | trim_right = function(s)
106 | return string.match(s, '(.-)%s*$')
107 | end,
108 |
109 | -- returns a new string with leading whitespace removed
110 | -- @param s {string}
111 | -- @return {string}
112 | trim_left = function(s)
113 | return string.match(s, '[^%s+].*')
114 | end,
115 |
116 | -- returns a copy of string leading and trailing whitespace removed
117 | -- @param s {string}
118 | -- @return {string}
119 | trim = function(s)
120 | return str.trim_right(
121 | str.trim_left(s)
122 | )
123 | end,
124 |
125 | -- returns a new string with the first character converted to uppercase and the remainder to lowercase
126 | -- @param s {string}
127 | -- @return {string}
128 | capitalize = function(s)
129 | if #s == 0 then
130 | return s
131 | end
132 |
133 | local function upperFirst()
134 | return string.upper(
135 | string.sub(s, 1, 1)
136 | )
137 | end
138 |
139 | local function lowerRest()
140 | return string.lower(
141 | string.sub(s, 2)
142 | )
143 | end
144 |
145 | return upperFirst() .. lowerRest()
146 | end,
147 |
148 | -- returns a copy of the string passed as parameter centralized with spaces passed in size parameter
149 | -- @param s {string}
150 | -- @param n {number}
151 | -- @return {string}
152 | center = function(s, n)
153 | local aux = ''
154 |
155 | for i=1, n do
156 | aux = aux .. ' '
157 | end
158 |
159 | return aux .. s .. aux
160 | end,
161 |
162 | -- converts string to slug and returns it as a new string
163 | -- @param s {string}
164 | -- @return {string}
165 | slug = function(s)
166 | local splited = utils.get_list_chars(s)
167 | local output = {}
168 | local accents = [[ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîï
169 | ÙÚÛÜùúûüÑñŠšŸÿýŽž~"\'~^!?.:@#$%&*]]
170 | local accents_out = [[AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiii
171 | UUUUuuuuNnSsYyyZz---------------]]
172 |
173 | for key, value in pairs(splited) do
174 | local index_of = utf8.find(accents, value)
175 |
176 | if index_of then
177 | output[key] = utf8.sub(accents_out, index_of, index_of)
178 | else
179 | output[key] = value
180 | end
181 | end
182 |
183 | return utf8.lower(table.concat(output, ''):gsub('%s', '-'))
184 | end,
185 |
186 | -- checks whether the string has only ascii characters
187 | -- @param s {string}
188 | -- @return {boolean}
189 | is_ascii = function(s)
190 | for i=1, #s do
191 | if string.byte(s:sub(i, i)) > 126 then return false end
192 | end
193 |
194 | return true
195 | end,
196 |
197 | -- checks whether the string has only numbers characters
198 | -- @param s {string}
199 | -- @return {boolean}
200 | is_number = function(s)
201 | return utils.to_bool(
202 | string.find(s, '^%d+$')
203 | )
204 | end,
205 |
206 | -- executes a provided function once for each character of the string
207 | -- @param s {string}
208 | -- @param callback {function}
209 | -- @return {void}
210 | each_char = function(s, callback)
211 | for i=1, #s do
212 | callback(s:sub(i, i), i)
213 | end
214 | end,
215 |
216 | -- passes every byte in string to the given function
217 | -- @param s {string}
218 | -- @param callback {function}
219 | -- @return {void}
220 | each_byte = function(s, callback)
221 | str.each_char(s, function(char, i)
222 | callback(char:byte(), i)
223 | end)
224 | end,
225 |
226 | -- executes a provided function once for each line of the string
227 | -- @param s {string}
228 | -- @param callback {function}
229 | -- @return {void}
230 | each_line = function(s, callback)
231 | for line in string.gmatch(s, '[^\n]+') do
232 | callback(line)
233 | end
234 | end,
235 |
236 | -- returns a table with the byte of every string's character
237 | -- @param s {string}
238 | -- @return {table}
239 | bytes = function(s)
240 | local output = {}
241 |
242 | str.each_char(s, function(s)
243 | table.insert(output, string.byte(s))
244 | end)
245 |
246 | return output
247 | end,
248 |
249 | -- returns a copy of the string passed by parameter without the specified characters
250 | -- @param s {string}
251 | -- @param chars {table}
252 | -- @return {table}
253 | delete = function(s, chars)
254 | local output = s
255 |
256 | for i=1, #chars do
257 | output = output:gsub(chars[i], '')
258 | end
259 |
260 | return output
261 | end,
262 |
263 | -- returns the index within the given string of the last occurrence of the specified value;
264 | -- returns nil if the value is not found
265 | -- @param s {string}
266 | -- @param match {string}
267 | -- @return {table}
268 | find_last = function(s, match)
269 | local i = s:match('.*' .. match .. '()')
270 |
271 | if not i then
272 | return nil
273 | end
274 |
275 | return i - 1
276 | end,
277 |
278 | -- truncates string if it's longer than the given maximum size
279 | -- @param s {string}
280 | -- @param options {table}
281 | -- @return {table}
282 | truncate = function(s, options)
283 | local _options = options or {}
284 | local omission = _options.omission or '...'
285 | local size = _options.size or 30
286 | local separator = _options.separator
287 | local cutted = str.slice(s, 1, size - #omission)
288 |
289 | if separator then
290 | local i = str.find_last(cutted, separator) - 1
291 | return str.slice(s, 1, i) .. omission
292 | end
293 |
294 | return cutted .. omission
295 | end,
296 |
297 | -- converts string to `camel case`
298 | -- @param s {string}
299 | -- @return {string}
300 | camel_case = function(s)
301 | return utils.match_case(s, str.capitalize)
302 | end,
303 |
304 | -- converts string to `kebab case`
305 | -- @param s {string}
306 | -- @return {string}
307 | kebab_case = function(s)
308 | return utils.match_case(s, function(w)
309 | return '-' .. w
310 | end)
311 | end,
312 |
313 | -- converts string to `snake case`
314 | -- @param s {string}
315 | -- @return {string}
316 | snake_case = function(s)
317 | return utils.match_case(s, function(w)
318 | return '_' .. w
319 | end)
320 | end,
321 |
322 | -- determines wether the substring was found within the string
323 | -- @param s {string}
324 | -- @param substr {string}
325 | -- @return {boolean}
326 | includes = function(s, substr)
327 | return utils.includes(s, substr)
328 | end,
329 |
330 | -- converts the characters "&", "<", ">", '"', and "'" in string to their corresponding html entities.
331 | -- @param s {string}
332 | -- @return {string}
333 | escape = function(s)
334 | local match = {
335 | ['<'] = '<',
336 | ['>'] = '>',
337 | ['"'] = '"',
338 | ["'"] = ''',
339 | ['&'] = '&'
340 | }
341 |
342 | local keys = utils.hash_keys(match)
343 | local output = {}
344 |
345 | for i=1, #s do
346 | local char = string.sub(s, i, i)
347 | local is_special = utils.includes_item(char, keys)
348 |
349 | table.insert(output, is_special and match[char] or char)
350 | end
351 |
352 | return table.concat(output, '')
353 | end,
354 |
355 | -- returns the position of the first occurrence of a specific substring
356 | -- @param s {string}
357 | -- @param substr {string}
358 | -- @return {number}
359 | index_of = function(s, substr)
360 | local index = string.find(s, substr, 1, true)
361 | return index or -1
362 | end,
363 |
364 | -- converts the HTML entities `&`, `<`, `>`, `"` and `'` in string to their corresponding characters.
365 | -- @param s {string}
366 | -- @return {string}
367 | unescape = function(s)
368 | local match = {
369 | ['<'] = '<',
370 | ['>'] = '>',
371 | ['"'] = '"',
372 | ['''] = "'",
373 | ['&'] = '&'
374 | }
375 |
376 | local result = s
377 |
378 | for k, v in pairs(match) do
379 | result = str.replace(result, k, v)
380 | end
381 |
382 | return result
383 | end,
384 |
385 | -- returns a new string replacing the specific values from the original string
386 | -- @param s {string}
387 | -- @param substr {string}
388 | -- @param new_substr {string}
389 | -- @return {number}
390 | replace = function(s, substr, new_substr)
391 | local result = string.gsub(s, substr, new_substr)
392 | return result
393 | end
394 | }
395 |
396 | return str
397 |
--------------------------------------------------------------------------------
/src/str/utils.lua:
--------------------------------------------------------------------------------
1 | local utf8 = require 'lua-utf8'
2 |
3 | -- convert value passed by parameter to boolean
4 | -- @param value {*}
5 | -- @return {boolean}
6 | local function to_bool(value)
7 | return not not value
8 | end
9 |
10 | -- return a array-like table with each character from a given string
11 | -- @param s {string}
12 | -- @return {table}
13 | local function get_list_chars(s)
14 | local output = {}
15 |
16 | for k, c in utf8.codes(s) do
17 | table.insert(output, utf8.char(c))
18 | end
19 |
20 | return output
21 | end
22 |
23 | -- convert all characters to lowercase and apply a `transformer` over each word
24 | -- @param s {string}
25 | -- @param transformer {function}
26 | -- @return {table}
27 | local function match_case(s, transformer)
28 | local lower = string.lower(s)
29 | local result = {}
30 | local is_first_word = true
31 |
32 | for w in string.gmatch(lower, '%w+') do
33 | if is_first_word then
34 | table.insert(result, w)
35 | is_first_word = false
36 | else
37 | table.insert(result, transformer(w))
38 | end
39 | end
40 |
41 | return table.concat(result, '')
42 | end
43 |
44 | -- returns an array-line table with the keys from a given hash-like table
45 | -- @param obj {table}
46 | -- @return {table}
47 | local function hash_keys(obj)
48 | local output = {}
49 |
50 | for k in pairs(obj) do
51 | table.insert(output, k)
52 | end
53 |
54 | return output
55 | end
56 |
57 | -- determines wether the substring was found within the string
58 | -- @param s {string}
59 | -- @param substr {string}
60 | -- @return {boolean}
61 | local function includes(s, substr)
62 | for i=1, #s do
63 | local value = string.sub(s, i, i+#substr-1)
64 | if value == substr then return true end
65 | end
66 |
67 | return false
68 | end
69 |
70 | -- determines wether one of the items intot he array was found within the string
71 | -- @param s {string}
72 | -- @param array {table}
73 | -- @return {boolean}
74 | local function includes_item(s, array)
75 | for i, v in pairs(array) do
76 | local result = includes(s, v)
77 | if result then return true end
78 | end
79 |
80 | return false
81 | end
82 |
83 | return {
84 | to_bool = to_bool,
85 | get_list_chars = get_list_chars,
86 | match_case = match_case,
87 | hash_keys = hash_keys,
88 | includes = includes,
89 | includes_item = includes_item
90 | }
91 |
--------------------------------------------------------------------------------
/str-1.5.0-0.rockspec:
--------------------------------------------------------------------------------
1 | package = 'str'
2 | version = '1.5.0-0'
3 |
4 | source = {
5 | url = 'git://github.com/evandrolg/str.git',
6 | tag = 'v1.5.0'
7 | }
8 |
9 | description = {
10 | summary = 'str is an string module with useful methods that do not exist in Lua core',
11 | homepage = 'https://github.com/EvandroLG/str',
12 | maintainer = 'Evandro Leopoldino Gonçalves (@evandrolg) ',
13 | license = 'MIT '
14 | }
15 |
16 | dependencies = {
17 | "lua >= 5.1",
18 | "luautf8 >= 0.1.1-1"
19 | }
20 |
21 | build = {
22 | type = "builtin",
23 | modules = {
24 | ['str'] = "src/str/init.lua",
25 | ['str.utils'] = "src/str/utils.lua"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test.lua:
--------------------------------------------------------------------------------
1 | local test = require 'simple_test'
2 | local str = require 'str'
3 |
4 | test('meta infos', function(a)
5 | a.equal(str.__VERSION, '1.5.0')
6 | a.equal(str.__DESCRIPTION, "str is a string module with useful methods that don't exist in Lua's core")
7 | end)
8 |
9 | test('slice', function(a)
10 | a.equal(
11 | str.slice('lua, javascript, python', 6, 15),
12 | 'javascript'
13 | )
14 |
15 | a.equal(
16 | str.slice('lua, javascript, python', 6),
17 | 'javascript, python'
18 | )
19 | end)
20 |
21 | test('starts_with', function(a)
22 | a.ok(
23 | str.starts_with('lua is a great language', 'lua')
24 | )
25 |
26 | a.not_ok(
27 | str.starts_with('lua is a great language', 'ruby')
28 | )
29 | end)
30 |
31 | test('ends_with', function(a)
32 | a.ok(
33 | str.ends_with('lua is a great language', 'language')
34 | )
35 |
36 | a.not_ok(
37 | str.ends_with('lua is a great language', 'programming')
38 | )
39 | end)
40 |
41 | test('is_ascii', function(a)
42 | a.ok(
43 | str.is_ascii('lua is a great language')
44 | )
45 |
46 | a.not_ok(
47 | str.is_ascii('á')
48 | )
49 | end)
50 |
51 | test('capitalize', function(a)
52 | a.equal(
53 | str.capitalize('lua is a great language'),
54 | 'Lua is a great language'
55 | )
56 | end)
57 |
58 | test('count', function(a)
59 | a.equal(
60 | str.count('lua is a great language. lua is a brazilian language', 'python'),
61 | 0
62 | )
63 |
64 | a.equal(
65 | str.count('lua is a great language. lua is a brazilian language', 'lua'),
66 | 2
67 | )
68 | end)
69 |
70 | test('trim_left', function(a)
71 | a.equal(
72 | str.trim_left(' lua is a great language'),
73 | 'lua is a great language'
74 | )
75 | end)
76 |
77 | test('trim_right', function(a)
78 | a.equal(
79 | str.trim_right('lua is a great language '),
80 | 'lua is a great language'
81 | )
82 | end)
83 |
84 | test('trim', function(a)
85 | a.equal(
86 | str.trim(' lua is a great language '),
87 | 'lua is a great language'
88 | )
89 | end)
90 |
91 | test('is_number', function(a)
92 | a.ok(
93 | str.is_number('12345')
94 | )
95 |
96 | a.not_ok(
97 | str.is_number('1234a5')
98 | )
99 |
100 | a.not_ok(
101 | str.is_number('')
102 | )
103 | end)
104 |
105 | test('center', function(a)
106 | a.equal(
107 | str.center('lua', 3),
108 | ' lua '
109 | )
110 | end)
111 |
112 | test('split', function(a)
113 | a.deep_equal(
114 | str.split('lua is a great language', ' '),
115 | { 'lua', 'is', 'a', 'great', 'language' }
116 | )
117 | end)
118 |
119 | test('slug', function(a)
120 | a.equal(
121 | str.slug('Lua is a great language'),
122 | 'lua-is-a-great-language'
123 | )
124 |
125 | a.equal(
126 | str.slug('Lua é uma ótima linguagem'),
127 | 'lua-e-uma-otima-linguagem'
128 | )
129 | end)
130 |
131 | test('each_char', function(a)
132 | local result = {}
133 | str.each_char('lua', function(char)
134 | table.insert(result, char)
135 | end)
136 |
137 | a.deep_equal(result, { 'l', 'u', 'a' })
138 | end)
139 |
140 | test('each_byte', function(a)
141 | local result = {}
142 | str.each_byte('lua', function(char)
143 | table.insert(result, char)
144 | end)
145 |
146 | a.deep_equal(result, { 108, 117, 97 })
147 | end)
148 |
149 | test('each_line', function(a)
150 | local result = {}
151 | str.each_line('lua\nruby\npython', function(line)
152 | table.insert(result, line)
153 | end)
154 |
155 | a.deep_equal(result, { 'lua', 'ruby', 'python' })
156 | end)
157 |
158 | test('bytes', function(a)
159 | a.deep_equal(str.bytes('lua'), { 108, 117, 97 })
160 | end)
161 |
162 | test('delete', function(a)
163 | a.equal(
164 | str.delete('hello world!', {'h', 'o'}),
165 | 'ell wrld!'
166 | )
167 | end)
168 |
169 | test('truncate', function(a)
170 | local value = string.rep('Lorem ipsum ', 10)
171 |
172 | a.equal(
173 | str.truncate(value),
174 | 'Lorem ipsum Lorem ipsum Lor...'
175 | )
176 |
177 | a.equal(
178 | str.truncate(value, { size = 10 }),
179 | 'Lorem i...'
180 | )
181 |
182 | a.equal(
183 | str.truncate(value, { size = 10, omission = '.' }),
184 | 'Lorem ips.'
185 | )
186 |
187 | a.equal(
188 | str.truncate(value, { separator = ' ' }),
189 | 'Lorem ipsum Lorem ipsum...'
190 | )
191 | end)
192 |
193 | test('find_last', function(a)
194 | local value = 'Lua is great'
195 |
196 | a.equal(
197 | str.find_last(value, 'good'),
198 | nil
199 | )
200 |
201 | a.equal(
202 | str.find_last(value, 'great'),
203 | 12
204 | )
205 | end)
206 |
207 | test('camel_case', function(a)
208 | local expected = 'luaIsGreat'
209 | a.equal(
210 | str.camel_case('Lua is great'),
211 | expected
212 | )
213 |
214 | a.equal(
215 | str.camel_case('Lua-is-great'),
216 | expected
217 | )
218 |
219 | a.equal(
220 | str.camel_case('Lua_is_great'),
221 | expected
222 | )
223 | end)
224 |
225 | test('kebab_case', function(a)
226 | local expected = 'lua-is-great'
227 |
228 | a.equal(
229 | str.kebab_case('Lua is great'),
230 | expected
231 | )
232 |
233 | a.equal(
234 | str.kebab_case('Lua-is-great'),
235 | expected
236 | )
237 |
238 | a.equal(
239 | str.kebab_case('Lua_is_great'),
240 | expected
241 | )
242 | end)
243 |
244 | test('snake_case', function(a)
245 | local expected = 'lua_is_great'
246 |
247 | a.equal(
248 | str.snake_case('Lua is great'),
249 | expected
250 | )
251 |
252 | a.equal(
253 | str.snake_case('Lua-is-great'),
254 | expected
255 | )
256 |
257 | a.equal(
258 | str.snake_case('Lua_is_great'),
259 | expected
260 | )
261 | end)
262 |
263 | test('includes', function(a)
264 | local value = 'Lua is great'
265 |
266 | a.not_ok(
267 | str.includes(value, 'greata')
268 | )
269 |
270 | a.ok(
271 | str.includes(value, 'great')
272 | )
273 |
274 | a.ok(
275 | str.includes(value, 'is')
276 | )
277 |
278 | a.ok(
279 | str.includes(value, 'Lua ')
280 | )
281 | end)
282 |
283 | test('escape', function(a)
284 | a.equal(
285 | str.escape('"tom & jerry" <>'),
286 | '"tom & jerry" <>'
287 | )
288 |
289 | a.equal(
290 | str.escape("'tom & jerry' <>"),
291 | ''tom & jerry' <>'
292 | )
293 | end)
294 |
295 | test('index_of', function(a)
296 | a.equal(
297 | str.index_of('lua and js', 'lua'),
298 | 1
299 | )
300 |
301 | a.equal(
302 | str.index_of('lua and js', 'js'),
303 | 9
304 | )
305 |
306 | a.equal(
307 | str.index_of('lua and js', 'javascript'),
308 | -1
309 | )
310 | end)
311 |
312 | test('unescape', function(a)
313 | a.equal(
314 | str.unescape('"tom & jerry" <>'),
315 | '"tom & jerry" <>'
316 | )
317 |
318 | a.equal(
319 | str.unescape(''tom & jerry' <>'),
320 | "'tom & jerry' <>"
321 | )
322 | end)
323 |
324 | test('replace', function(a)
325 | a.equal(
326 | str.replace('Lua is cute. Lua is cute too', 'cute', 'great'),
327 | 'Lua is great. Lua is great too'
328 | )
329 | end)
330 |
--------------------------------------------------------------------------------