Skip to content

Commit 201d33f

Browse files
committed
chore: wip
1 parent 58754fe commit 201d33f

File tree

4 files changed

+340
-6
lines changed

4 files changed

+340
-6
lines changed

pkgx.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# https://stacksjs.org/docs/dependency-management
1010

1111
dependencies:
12-
bun.sh: ^1.1.28
12+
bun.sh: ^1.1.29
1313
aws.amazon.com/cli: ^2.17.13
1414
dns.lookup.dog: ^0.1.0
1515
info-zip.org/zip: ^3.0

storage/framework/core/strings/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"scripts": {
5151
"build": "bun --bun build.ts",
5252
"typecheck": "bun --bun tsc --noEmit",
53+
"test": "bun test",
5354
"prepublishOnly": "bun run build"
5455
},
5556
"dependencies": {

storage/framework/core/strings/tests/example.test.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
import { describe, expect, test } from 'bun:test'
2+
import * as caseUtils from '../src/case'
3+
import * as helpers from '../src/helpers'
4+
import * as strings from '../src/index'
5+
import * as is from '../src/is'
6+
import { Str } from '../src/macro'
7+
import * as pluralize from '../src/pluralize'
8+
import * as utils from '../src/utils'
9+
10+
describe('@stacksjs/strings', () => {
11+
describe('Case utilities', () => {
12+
test('capitalize', () => {
13+
expect(caseUtils.capitalize('hello world')).toBe('Hello world')
14+
expect(caseUtils.capitalize('')).toBe('')
15+
})
16+
17+
test('lowercase', () => {
18+
expect(caseUtils.lowercase('HELLO WORLD')).toBe('hello world')
19+
})
20+
21+
test('camelCase', () => {
22+
expect(caseUtils.camelCase('hello world')).toBe('helloWorld')
23+
})
24+
25+
test('capitalCase', () => {
26+
expect(caseUtils.capitalCase('helloWorld')).toBe('Hello World')
27+
})
28+
29+
test('constantCase', () => {
30+
expect(caseUtils.constantCase('helloWorld')).toBe('HELLO_WORLD')
31+
})
32+
33+
test('dotCase', () => {
34+
expect(caseUtils.dotCase('helloWorld')).toBe('hello.world')
35+
})
36+
37+
test('kebabCase', () => {
38+
expect(caseUtils.kebabCase('helloWorld')).toBe('hello-world')
39+
})
40+
41+
test('pascalCase', () => {
42+
expect(caseUtils.pascalCase('hello world')).toBe('HelloWorld')
43+
})
44+
45+
test('pathCase', () => {
46+
expect(caseUtils.pathCase('helloWorld')).toBe('hello/world')
47+
})
48+
49+
test('sentenceCase', () => {
50+
expect(caseUtils.sentenceCase('helloWorld')).toBe('Hello world')
51+
})
52+
53+
test('snakeCase', () => {
54+
expect(caseUtils.snakeCase('helloWorld')).toBe('hello_world')
55+
})
56+
57+
test('titleCase', () => {
58+
expect(caseUtils.titleCase('hello world')).toBe('Hello World')
59+
})
60+
})
61+
62+
describe('Helpers', () => {
63+
test('toString', () => {
64+
expect(helpers.toString({})).toBe('[object Object]')
65+
expect(helpers.toString([])).toBe('[object Array]')
66+
expect(helpers.toString(42)).toBe('[object Number]')
67+
expect(helpers.toString('hello')).toBe('[object String]')
68+
})
69+
})
70+
71+
describe('Validation utilities', () => {
72+
test('isEmail', () => {
73+
expect(is.isEmail('test@example.com')).toBe(true)
74+
expect(is.isEmail('invalid-email')).toBe(false)
75+
})
76+
77+
test('isStrongPassword', () => {
78+
expect(is.isStrongPassword('StrongP@ssw0rd')).toBe(true)
79+
expect(is.isStrongPassword('weak')).toBe(false)
80+
})
81+
82+
test('isAlphanumeric', () => {
83+
expect(is.isAlphanumeric('abc123')).toBe(true)
84+
expect(is.isAlphanumeric('abc 123')).toBe(false)
85+
})
86+
87+
test('validateUsername', () => {
88+
expect(is.validateUsername('johndoe123')).toBe(true)
89+
expect(is.validateUsername('john doe')).toBe(false)
90+
})
91+
92+
test('isURL', () => {
93+
expect(is.isURL('https://example.com')).toBe(true)
94+
expect(is.isURL('not-a-url')).toBe(false)
95+
})
96+
97+
test('isMobilePhone', () => {
98+
expect(is.isMobilePhone('+1234567890')).toBe(true)
99+
expect(is.isMobilePhone('not-a-phone')).toBe(false)
100+
})
101+
102+
test('isAlpha', () => {
103+
expect(is.isAlpha('abcdef')).toBe(true)
104+
expect(is.isAlpha('abc123')).toBe(false)
105+
})
106+
107+
test('isPostalCode', () => {
108+
expect(is.isPostalCode('12345')).toBe(true)
109+
expect(is.isPostalCode('not-a-postal-code')).toBe(false)
110+
})
111+
112+
test('isNumeric', () => {
113+
expect(is.isNumeric('12345')).toBe(true)
114+
expect(is.isNumeric('12a45')).toBe(false)
115+
})
116+
117+
test('isHexColor', () => {
118+
expect(is.isHexColor('#ff0000')).toBe(true)
119+
expect(is.isHexColor('red')).toBe(false)
120+
})
121+
122+
test('isHexadecimal', () => {
123+
expect(is.isHexadecimal('deadbeef')).toBe(true)
124+
expect(is.isHexadecimal('not-hex')).toBe(false)
125+
})
126+
127+
test('isBase64', () => {
128+
expect(is.isBase64('SGVsbG8gV29ybGQ=')).toBe(true)
129+
expect(is.isBase64('not-base64')).toBe(false)
130+
})
131+
132+
test('isUUID', () => {
133+
expect(is.isUUID('550e8400-e29b-41d4-a716-446655440000')).toBe(true)
134+
expect(is.isUUID('not-a-uuid')).toBe(false)
135+
})
136+
137+
test('isJSON', () => {
138+
expect(is.isJSON('{"key": "value"}')).toBe(true)
139+
expect(is.isJSON('not-json')).toBe(false)
140+
})
141+
142+
test('isCreditCard', () => {
143+
expect(is.isCreditCard('4111111111111111')).toBe(true)
144+
expect(is.isCreditCard('not-a-credit-card')).toBe(false)
145+
})
146+
147+
test('isISBN', () => {
148+
expect(is.isISBN('978-3-16-148410-0')).toBe(true)
149+
expect(is.isISBN('not-an-isbn')).toBe(false)
150+
})
151+
152+
test('isIP', () => {
153+
expect(is.isIP('192.168.1.1')).toBe(true)
154+
expect(is.isIP('not-an-ip')).toBe(false)
155+
})
156+
157+
test('isIPRange', () => {
158+
expect(is.isIPRange('192.168.1.1/24')).toBe(true)
159+
expect(is.isIPRange('not-an-ip-range')).toBe(false)
160+
})
161+
162+
test('isMACAddress', () => {
163+
expect(is.isMACAddress('00:14:22:01:23:45')).toBe(true)
164+
expect(is.isMACAddress('not-a-mac-address')).toBe(false)
165+
})
166+
167+
test('isLatLong', () => {
168+
expect(is.isLatLong('40.7128,-74.0060')).toBe(true)
169+
expect(is.isLatLong('not-lat-long')).toBe(false)
170+
})
171+
172+
test('isCurrency', () => {
173+
expect(is.isCurrency('$100.00')).toBe(true)
174+
expect(is.isCurrency('not-currency')).toBe(false)
175+
})
176+
177+
test('isDataURI', () => {
178+
expect(is.isDataURI('data:,Hello%2C%20World!')).toBe(true)
179+
expect(is.isDataURI('not-a-data-uri')).toBe(false)
180+
})
181+
182+
test('isMimeType', () => {
183+
expect(is.isMimeType('application/json')).toBe(true)
184+
expect(is.isMimeType('not-a-mime-type')).toBe(false)
185+
})
186+
187+
test('isJWT', () => {
188+
expect(
189+
is.isJWT(
190+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
191+
),
192+
).toBe(true)
193+
expect(is.isJWT('not-a-jwt')).toBe(false)
194+
})
195+
})
196+
197+
describe('String macros', () => {
198+
test('slash', () => {
199+
expect(Str.slash('C:\\Users\\Chris')).toBe('C:/Users/Chris')
200+
})
201+
202+
test('ensurePrefix', () => {
203+
expect(Str.ensurePrefix('https://', 'google.com')).toBe('https://google.com')
204+
expect(Str.ensurePrefix('https://', 'https://google.com')).toBe('https://google.com')
205+
})
206+
207+
test('ensureSuffix', () => {
208+
expect(Str.ensureSuffix('.js', 'index')).toBe('index.js')
209+
expect(Str.ensureSuffix('.js', 'index.js')).toBe('index.js')
210+
})
211+
212+
test('template', () => {
213+
expect(Str.template('Hello {0}! My name is {1}.', 'Buddy', 'Chris')).toBe('Hello Buddy! My name is Chris.')
214+
})
215+
216+
test('truncate', () => {
217+
expect(Str.truncate('This is a long string', 10)).toBe('This is a...')
218+
})
219+
220+
test('random', () => {
221+
const randomString = Str.random()
222+
expect(randomString).toHaveLength(16)
223+
expect(typeof randomString).toBe('string')
224+
})
225+
226+
test('capitalize', () => {
227+
expect(Str.capitalize('hello world')).toBe('Hello world')
228+
})
229+
230+
test('slug', () => {
231+
expect(Str.slug('Hello World')).toBe('hello-world')
232+
})
233+
234+
test('camelCase', () => {
235+
expect(Str.camelCase('hello world')).toBe('helloWorld')
236+
})
237+
238+
test('kebabCase', () => {
239+
expect(Str.kebabCase('helloWorld')).toBe('hello-world')
240+
})
241+
242+
test('snakeCase', () => {
243+
expect(Str.snakeCase('helloWorld')).toBe('hello_world')
244+
})
245+
})
246+
247+
describe('Pluralization utilities', () => {
248+
test('plural', () => {
249+
expect(pluralize.plural('cat')).toBe('cats')
250+
expect(pluralize.plural('person')).toBe('people')
251+
})
252+
253+
test('singular', () => {
254+
expect(pluralize.singular('cats')).toBe('cat')
255+
expect(pluralize.singular('people')).toBe('person')
256+
})
257+
258+
test('isPlural', () => {
259+
expect(pluralize.isPlural('cats')).toBe(true)
260+
expect(pluralize.isPlural('cat')).toBe(false)
261+
})
262+
263+
test('isSingular', () => {
264+
expect(pluralize.isSingular('cat')).toBe(true)
265+
expect(pluralize.isSingular('cats')).toBe(false)
266+
})
267+
268+
test('addPluralRule', () => {
269+
pluralize.addPluralRule('goose', 'geese')
270+
expect(pluralize.plural('goose')).toBe('geese')
271+
})
272+
273+
test('addSingularRule', () => {
274+
pluralize.addSingularRule('geese', 'goose')
275+
expect(pluralize.singular('geese')).toBe('goose')
276+
})
277+
278+
test('addIrregularRule', () => {
279+
pluralize.addIrregularRule('mouse', 'mice')
280+
expect(pluralize.plural('mouse')).toBe('mice')
281+
expect(pluralize.singular('mice')).toBe('mouse')
282+
})
283+
284+
test('addUncountableRule', () => {
285+
pluralize.addUncountableRule('fish')
286+
expect(pluralize.plural('fish')).toBe('fish')
287+
expect(pluralize.singular('fish')).toBe('fish')
288+
})
289+
})
290+
291+
describe('String utilities', () => {
292+
test('slash', () => {
293+
expect(utils.slash('C:\\Users\\Chris')).toBe('C:/Users/Chris')
294+
})
295+
296+
test('ensurePrefix', () => {
297+
expect(utils.ensurePrefix('https://', 'google.com')).toBe('https://google.com')
298+
expect(utils.ensurePrefix('https://', 'https://google.com')).toBe('https://google.com')
299+
})
300+
301+
test('ensureSuffix', () => {
302+
expect(utils.ensureSuffix('.js', 'index')).toBe('index.js')
303+
expect(utils.ensureSuffix('.js', 'index.js')).toBe('index.js')
304+
})
305+
306+
test('template', () => {
307+
expect(utils.template('Hello {0}! My name is {1}.', 'Buddy', 'Chris')).toBe('Hello Buddy! My name is Chris.')
308+
})
309+
310+
test('truncate', () => {
311+
expect(utils.truncate('This is a long string', 10)).toBe('This is a...')
312+
})
313+
314+
test('random', () => {
315+
const randomString = utils.random()
316+
expect(randomString).toHaveLength(16)
317+
expect(typeof randomString).toBe('string')
318+
})
319+
320+
test('slug', () => {
321+
expect(utils.slug('Hello World')).toBe('hello-world')
322+
})
323+
324+
test('detectIndent', () => {
325+
expect(utils.detectIndent(' hello\n world')).toBe(' ')
326+
})
327+
328+
test('detectNewline', () => {
329+
expect(utils.detectNewline('hello\nworld')).toBe('\n')
330+
expect(utils.detectNewline('hello\r\nworld')).toBe('\r\n')
331+
})
332+
})
333+
334+
test('main module exports', () => {
335+
expect(strings).toBeDefined()
336+
expect(strings.string).toBeDefined()
337+
})
338+
})

0 commit comments

Comments
 (0)