@quenty/string 3.3.7 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.4.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/string@3.4.0...@quenty/string@3.4.1) (2026-08-14)
7
+
8
+ **Note:** Version bump only for package @quenty/string
9
+
10
+ # [3.4.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/string@3.3.7...@quenty/string@3.4.0) (2026-07-23)
11
+
12
+ ### Features
13
+
14
+ - Add unit tests to string package ([f15f2f2](https://github.com/Quenty/NevermoreEngine/commit/f15f2f2892d782bed552a882e31f3b5d07975184))
15
+
6
16
  ## [3.3.7](https://github.com/Quenty/NevermoreEngine/compare/@quenty/string@3.3.6...@quenty/string@3.3.7) (2026-05-30)
7
17
 
8
18
  **Note:** Version bump only for package @quenty/string
@@ -0,0 +1,10 @@
1
+ {
2
+ "targets": {
3
+ "test": {
4
+ "universeId": 9716264427,
5
+ "placeId": 100668032156705,
6
+ "project": "test/default.project.json",
7
+ "scriptTemplate": "test/scripts/Server/ServerMain.server.lua"
8
+ }
9
+ }
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/string",
3
- "version": "3.3.7",
3
+ "version": "3.4.1",
4
4
  "description": "This module provides utility functions for strings",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,11 +25,16 @@
25
25
  "scripts": {
26
26
  "preinstall": "npx only-allow pnpm"
27
27
  },
28
+ "dependencies": {
29
+ "@quenty/loader": "10.11.1",
30
+ "@quenty/nevermore-test-runner": "1.5.1",
31
+ "@quentystudios/jest-lua": "3.10.0-quenty.2"
32
+ },
28
33
  "contributors": [
29
34
  "Quenty"
30
35
  ],
31
36
  "publishConfig": {
32
37
  "access": "public"
33
38
  },
34
- "gitHead": "598b2b62b36bdcbdbbd56f7db10c399831cc6eba"
39
+ "gitHead": "f084360c3729ea424d49d9bc42f8f0d1c128fa82"
35
40
  }
@@ -102,10 +102,10 @@ end
102
102
 
103
103
  --[=[
104
104
  Checks if a string is empty or nil
105
- @param str string
105
+ @param str string?
106
106
  @return boolean
107
107
  ]=]
108
- function String.isEmptyOrWhitespaceOrNil(str: string): boolean
108
+ function String.isEmptyOrWhitespaceOrNil(str: string?): boolean
109
109
  return type(str) ~= "string" or str == "" or String.isWhitespace(str)
110
110
  end
111
111
 
@@ -0,0 +1,235 @@
1
+ --!strict
2
+ --[[
3
+ @class String.spec.lua
4
+ ]]
5
+
6
+ local require = require(script.Parent.loader).load(script)
7
+
8
+ local Jest = require("Jest")
9
+ local String = require("String")
10
+
11
+ local describe = Jest.Globals.describe
12
+ local expect = Jest.Globals.expect
13
+ local it = Jest.Globals.it
14
+
15
+ describe("String.trim", function()
16
+ it("trims leading and trailing whitespace by default", function()
17
+ expect(String.trim(" hello ")).toEqual("hello")
18
+ end)
19
+
20
+ it("trims tabs and newlines", function()
21
+ expect(String.trim("\t\nhello world\n\t")).toEqual("hello world")
22
+ end)
23
+
24
+ it("leaves interior whitespace untouched", function()
25
+ expect(String.trim(" a b ")).toEqual("a b")
26
+ end)
27
+
28
+ it("returns an empty string for all-whitespace input", function()
29
+ expect(String.trim(" ")).toEqual("")
30
+ end)
31
+
32
+ it("is a no-op when there is nothing to trim", function()
33
+ expect(String.trim("hello")).toEqual("hello")
34
+ end)
35
+
36
+ it("trims a custom pattern", function()
37
+ expect(String.trim("xxhelloxx", "x")).toEqual("hello")
38
+ end)
39
+ end)
40
+
41
+ describe("String.trimFront", function()
42
+ it("trims only the leading whitespace by default", function()
43
+ expect(String.trimFront(" hello ")).toEqual("hello ")
44
+ end)
45
+
46
+ it("leaves a string without a leading match untouched", function()
47
+ expect(String.trimFront("hello ")).toEqual("hello ")
48
+ end)
49
+
50
+ it("trims a custom leading pattern", function()
51
+ expect(String.trimFront("xxhello", "x")).toEqual("hello")
52
+ end)
53
+ end)
54
+
55
+ describe("String.toCamelCase", function()
56
+ it("converts snake_case to UpperCamelCase", function()
57
+ expect(String.toCamelCase("hello_world")).toEqual("HelloWorld")
58
+ end)
59
+
60
+ it("converts YELL_CASE to UpperCamelCase", function()
61
+ expect(String.toCamelCase("YELL_CASE")).toEqual("YellCase")
62
+ end)
63
+
64
+ it("converts space separated words to UpperCamelCase", function()
65
+ expect(String.toCamelCase("hello world")).toEqual("HelloWorld")
66
+ end)
67
+
68
+ it("capitalizes the first letter of a single lowercase word", function()
69
+ expect(String.toCamelCase("hello")).toEqual("Hello")
70
+ end)
71
+
72
+ it("strips remaining punctuation", function()
73
+ expect(String.toCamelCase("foo-bar")).toEqual("Foobar")
74
+ end)
75
+ end)
76
+
77
+ describe("String.toLowerCamelCase", function()
78
+ it("converts snake_case to lowerCamelCase", function()
79
+ expect(String.toLowerCamelCase("hello_world")).toEqual("helloWorld")
80
+ end)
81
+
82
+ it("converts YELL_CASE to lowerCamelCase", function()
83
+ expect(String.toLowerCamelCase("YELL_CASE")).toEqual("yellCase")
84
+ end)
85
+
86
+ it("keeps the first letter lowercase", function()
87
+ expect(String.toLowerCamelCase("hello")).toEqual("hello")
88
+ end)
89
+ end)
90
+
91
+ describe("String.uppercaseFirstLetter", function()
92
+ it("uppercases the first letter", function()
93
+ expect(String.uppercaseFirstLetter("hello")).toEqual("Hello")
94
+ end)
95
+
96
+ it("leaves an already-uppercase first letter untouched", function()
97
+ expect(String.uppercaseFirstLetter("Hello")).toEqual("Hello")
98
+ end)
99
+
100
+ it("is a no-op when the first character is not a letter", function()
101
+ expect(String.uppercaseFirstLetter("123abc")).toEqual("123abc")
102
+ end)
103
+ end)
104
+
105
+ describe("String.toPrivateCase", function()
106
+ it("prefixes with an underscore and lowercases the first letter", function()
107
+ expect(String.toPrivateCase("MyThing")).toEqual("_myThing")
108
+ end)
109
+
110
+ it("preserves the remainder of the string", function()
111
+ expect(String.toPrivateCase("SomeValue")).toEqual("_someValue")
112
+ end)
113
+ end)
114
+
115
+ describe("String.checkNumOfCharacterInString", function()
116
+ it("counts the occurrences of a character", function()
117
+ expect(String.checkNumOfCharacterInString("hello", "l")).toEqual(2)
118
+ end)
119
+
120
+ it("returns 0 when the character is absent", function()
121
+ expect(String.checkNumOfCharacterInString("hello", "z")).toEqual(0)
122
+ end)
123
+
124
+ it("counts every character in the string", function()
125
+ expect(String.checkNumOfCharacterInString("aaaa", "a")).toEqual(4)
126
+ end)
127
+ end)
128
+
129
+ describe("String.isWhitespace", function()
130
+ it("returns true for a string of only whitespace", function()
131
+ expect(String.isWhitespace(" ")).toEqual(true)
132
+ end)
133
+
134
+ it("returns false for a string with non-whitespace", function()
135
+ expect(String.isWhitespace("a b")).toEqual(false)
136
+ end)
137
+
138
+ it("returns false for an empty string", function()
139
+ expect(String.isWhitespace("")).toEqual(false)
140
+ end)
141
+ end)
142
+
143
+ describe("String.isEmptyOrWhitespaceOrNil", function()
144
+ it("returns true for nil", function()
145
+ expect(String.isEmptyOrWhitespaceOrNil(nil)).toEqual(true)
146
+ end)
147
+
148
+ it("returns true for an empty string", function()
149
+ expect(String.isEmptyOrWhitespaceOrNil("")).toEqual(true)
150
+ end)
151
+
152
+ it("returns true for a whitespace-only string", function()
153
+ expect(String.isEmptyOrWhitespaceOrNil(" \t")).toEqual(true)
154
+ end)
155
+
156
+ it("returns false for a string with content", function()
157
+ expect(String.isEmptyOrWhitespaceOrNil("hello")).toEqual(false)
158
+ end)
159
+ end)
160
+
161
+ describe("String.elipseLimit", function()
162
+ it("truncates and appends an ellipsis when over the limit", function()
163
+ expect(String.elipseLimit("hello world", 8)).toEqual("hello...")
164
+ end)
165
+
166
+ it("leaves a string at or under the limit untouched", function()
167
+ expect(String.elipseLimit("hello", 8)).toEqual("hello")
168
+ end)
169
+
170
+ it("produces a result of exactly the limit length", function()
171
+ expect(#String.elipseLimit("abcdefghij", 8)).toEqual(8)
172
+ end)
173
+ end)
174
+
175
+ describe("String.removePrefix", function()
176
+ it("removes a matching prefix", function()
177
+ expect(String.removePrefix("foobar", "foo")).toEqual("bar")
178
+ end)
179
+
180
+ it("returns the string unchanged when the prefix does not match", function()
181
+ expect(String.removePrefix("foobar", "xyz")).toEqual("foobar")
182
+ end)
183
+ end)
184
+
185
+ describe("String.removePostfix", function()
186
+ it("removes a matching postfix", function()
187
+ expect(String.removePostfix("foobar", "bar")).toEqual("foo")
188
+ end)
189
+
190
+ it("returns the string unchanged when the postfix does not match", function()
191
+ expect(String.removePostfix("foobar", "xyz")).toEqual("foobar")
192
+ end)
193
+ end)
194
+
195
+ describe("String.startsWith", function()
196
+ it("returns true when the string starts with the prefix", function()
197
+ expect(String.startsWith("foobar", "foo")).toEqual(true)
198
+ end)
199
+
200
+ it("returns false when the string does not start with the prefix", function()
201
+ expect(String.startsWith("foobar", "bar")).toEqual(false)
202
+ end)
203
+ end)
204
+
205
+ describe("String.endsWith", function()
206
+ it("returns true when the string ends with the postfix", function()
207
+ expect(String.endsWith("foobar", "bar")).toEqual(true)
208
+ end)
209
+
210
+ it("returns false when the string does not end with the postfix", function()
211
+ expect(String.endsWith("foobar", "foo")).toEqual(false)
212
+ end)
213
+ end)
214
+
215
+ describe("String.addCommas", function()
216
+ it("adds commas to a large number", function()
217
+ expect(String.addCommas(1000000)).toEqual("1,000,000")
218
+ end)
219
+
220
+ it("leaves numbers under a thousand unchanged", function()
221
+ expect(String.addCommas(123)).toEqual("123")
222
+ end)
223
+
224
+ it("handles negative numbers", function()
225
+ expect(String.addCommas(-1234567)).toEqual("-1,234,567")
226
+ end)
227
+
228
+ it("accepts a string number", function()
229
+ expect(String.addCommas("1234567")).toEqual("1,234,567")
230
+ end)
231
+
232
+ it("uses a custom separator", function()
233
+ expect(String.addCommas(1234, ".")).toEqual("1.234")
234
+ end)
235
+ end)
@@ -0,0 +1,3 @@
1
+ return {
2
+ testMatch = { "**/*.spec" },
3
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "node_modules",
3
+ "globIgnorePaths": [ "**/.package-lock.json" ],
4
+ "tree": {
5
+ "$path": { "optional": "../node_modules" }
6
+ }
7
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "StringTest",
3
+ "globIgnorePaths": [
4
+ "**/.package-lock.json",
5
+ "**/.pnpm",
6
+ "**/.pnpm-workspace-state-v1.json",
7
+ "**/.modules.yaml",
8
+ "**/.ignored",
9
+ "**/.ignored_*"
10
+ ],
11
+ "tree": {
12
+ "$className": "DataModel",
13
+ "ServerScriptService": {
14
+ "$properties": {
15
+ "LoadStringEnabled": true
16
+ },
17
+ "string": {
18
+ "$path": ".."
19
+ },
20
+ "Script": {
21
+ "$path": "scripts/Server"
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,14 @@
1
+ --!nonstrict
2
+ --[[
3
+ @class ServerMain
4
+ ]]
5
+
6
+ local ServerScriptService = game:GetService("ServerScriptService")
7
+
8
+ local root = ServerScriptService.string
9
+ local loader = root:FindFirstChild("LoaderUtils", true).Parent
10
+ local require = require(loader).bootstrapGame(root)
11
+
12
+ local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
13
+
14
+ NevermoreTestRunnerUtils.runTestsIfNeededAsync(root)