Skip to content

Commit fbb7863

Browse files
committed
chore: wip
1 parent 201d33f commit fbb7863

File tree

5 files changed

+83
-9
lines changed

5 files changed

+83
-9
lines changed

storage/framework/core/database/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export function getDialect() {
2222

2323
if (driver === 'sqlite') {
2424
const defaultName = appEnv !== 'testing' ? 'database/stacks.sqlite' : 'database/stacks_testing.sqlite'
25-
2625
const path = database.connections?.sqlite.database ?? defaultName
26+
2727
return new BunWorkerDialect({
2828
url: path,
2929
})

storage/framework/core/strings/src/macro.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export const Str = {
2626
return u.truncate(str, length, end)
2727
},
2828

29-
random(length = 16) {
30-
return u.random(length)
29+
random(length = 16, dict?: string) {
30+
return u.random(length, dict)
3131
},
3232

3333
capitalize(str: string) {

storage/framework/core/strings/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ interface SlugOptions {
1111

1212
// port from nanoid
1313
// https://github.com/ai/nanoid
14-
const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
14+
export const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
1515

1616
/**
1717
* Replace backslash to slash

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

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,17 @@ describe('@stacksjs/strings', () => {
5757
test('titleCase', () => {
5858
expect(caseUtils.titleCase('hello world')).toBe('Hello World')
5959
})
60+
61+
test('capitalize edge cases', () => {
62+
expect(caseUtils.capitalize('a')).toBe('A')
63+
expect(caseUtils.capitalize('1hello')).toBe('1hello')
64+
expect(caseUtils.capitalize('ALREADY CAPITALIZED')).toBe('Already capitalized')
65+
})
66+
67+
test('international characters', () => {
68+
expect(caseUtils.capitalize('éléphant')).toBe('Éléphant')
69+
expect(caseUtils.lowercase('CAFÉ')).toBe('café')
70+
})
6071
})
6172

6273
describe('Helpers', () => {
@@ -65,13 +76,20 @@ describe('@stacksjs/strings', () => {
6576
expect(helpers.toString([])).toBe('[object Array]')
6677
expect(helpers.toString(42)).toBe('[object Number]')
6778
expect(helpers.toString('hello')).toBe('[object String]')
79+
expect(helpers.toString(null)).toBe('[object Null]')
80+
expect(helpers.toString(undefined)).toBe('[object Undefined]')
81+
expect(helpers.toString(() => {})).toBe('[object Function]')
82+
expect(helpers.toString(new Date())).toBe('[object Date]')
6883
})
6984
})
7085

7186
describe('Validation utilities', () => {
7287
test('isEmail', () => {
7388
expect(is.isEmail('test@example.com')).toBe(true)
7489
expect(is.isEmail('invalid-email')).toBe(false)
90+
expect(is.isEmail('test@example')).toBe(false)
91+
expect(is.isEmail('test@example.com.uk')).toBe(true)
92+
expect(is.isEmail('test+alias@example.com')).toBe(true)
7593
})
7694

7795
test('isStrongPassword', () => {
@@ -95,7 +113,7 @@ describe('@stacksjs/strings', () => {
95113
})
96114

97115
test('isMobilePhone', () => {
98-
expect(is.isMobilePhone('+1234567890')).toBe(true)
116+
expect(is.isMobilePhone('+12345678900')).toBe(true)
99117
expect(is.isMobilePhone('not-a-phone')).toBe(false)
100118
})
101119

@@ -213,8 +231,12 @@ describe('@stacksjs/strings', () => {
213231
expect(Str.template('Hello {0}! My name is {1}.', 'Buddy', 'Chris')).toBe('Hello Buddy! My name is Chris.')
214232
})
215233

234+
test('template with multiple replacements', () => {
235+
expect(Str.template('{0} {1} {2} {1} {0}', 'a', 'b', 'c')).toBe('a b c b a')
236+
})
237+
216238
test('truncate', () => {
217-
expect(Str.truncate('This is a long string', 10)).toBe('This is a...')
239+
expect(Str.truncate('This is a long string', 10)).toBe('This is...')
218240
})
219241

220242
test('random', () => {
@@ -223,6 +245,13 @@ describe('@stacksjs/strings', () => {
223245
expect(typeof randomString).toBe('string')
224246
})
225247

248+
test('random with custom length and dictionary', () => {
249+
const customDict = 'ABC123'
250+
const result = Str.random(8, customDict)
251+
expect(result).toHaveLength(8)
252+
expect(result).toMatch(new RegExp(`^[${customDict}]+$`))
253+
})
254+
226255
test('capitalize', () => {
227256
expect(Str.capitalize('hello world')).toBe('Hello world')
228257
})
@@ -250,6 +279,11 @@ describe('@stacksjs/strings', () => {
250279
expect(pluralize.plural('person')).toBe('people')
251280
})
252281

282+
test('addPluralRule with invalid input', () => {
283+
pluralize.addPluralRule('', '')
284+
expect(pluralize.plural('')).toBe('')
285+
})
286+
253287
test('singular', () => {
254288
expect(pluralize.singular('cats')).toBe('cat')
255289
expect(pluralize.singular('people')).toBe('person')
@@ -286,6 +320,12 @@ describe('@stacksjs/strings', () => {
286320
expect(pluralize.plural('fish')).toBe('fish')
287321
expect(pluralize.singular('fish')).toBe('fish')
288322
})
323+
324+
test('addUncountableRule does not affect other words', () => {
325+
const originalPlural = pluralize.plural('book')
326+
pluralize.addUncountableRule('data')
327+
expect(pluralize.plural('book')).toBe(originalPlural)
328+
})
289329
})
290330

291331
describe('String utilities', () => {
@@ -308,27 +348,60 @@ describe('@stacksjs/strings', () => {
308348
})
309349

310350
test('truncate', () => {
311-
expect(utils.truncate('This is a long string', 10)).toBe('This is a...')
351+
expect(utils.truncate('This is a long string', 10)).toBe('This is...')
312352
})
313353

314354
test('random', () => {
315-
const randomString = utils.random()
355+
const randomString = Str.random()
316356
expect(randomString).toHaveLength(16)
317357
expect(typeof randomString).toBe('string')
358+
359+
const customLengthString = Str.random(8)
360+
expect(customLengthString).toHaveLength(8)
361+
362+
const customDictString = Str.random(5, 'AB')
363+
expect(customDictString).toHaveLength(5)
364+
expect(customDictString).toMatch(/^[AB]+$/)
318365
})
319366

320367
test('slug', () => {
321368
expect(utils.slug('Hello World')).toBe('hello-world')
322369
})
323370

324371
test('detectIndent', () => {
325-
expect(utils.detectIndent(' hello\n world')).toBe(' ')
372+
const result = utils.detectIndent(' hello\n world')
373+
expect(result.indent).toBe(' ')
326374
})
327375

328376
test('detectNewline', () => {
329377
expect(utils.detectNewline('hello\nworld')).toBe('\n')
330378
expect(utils.detectNewline('hello\r\nworld')).toBe('\r\n')
331379
})
380+
381+
test('detectNewline with no newlines', () => {
382+
expect(utils.detectNewline('hello world')).toBeUndefined()
383+
})
384+
})
385+
386+
describe('Combined utilities', () => {
387+
test('slug and capitalize', () => {
388+
expect(Str.capitalize(Str.slug('hello world'))).toBe('Hello-world')
389+
})
390+
391+
test('camelCase and pluralize', () => {
392+
expect(pluralize.plural(Str.camelCase('test case'))).toBe('testCases')
393+
})
394+
})
395+
396+
describe('Performance tests', () => {
397+
test('random string generation performance', () => {
398+
const start = performance.now()
399+
for (let i = 0; i < 1000; i++) {
400+
utils.random(100)
401+
}
402+
const end = performance.now()
403+
expect(end - start).toBeLessThan(1000) // Should take less than 1 second
404+
})
332405
})
333406

334407
test('main module exports', () => {

storage/framework/ide/dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ ecommerce
9898
edgelambda
9999
elasticloadbalancingv
100100
elbv
101+
éléphant
101102
encrypter
102103
entrypoints
103104
envrc

0 commit comments

Comments
 (0)