|
| 1 | +import { describe, expect, it } from 'vitest'; |
| 2 | +import * as v from 'valibot'; |
| 3 | + |
| 4 | +import { zk, vk } from '../../src'; |
| 5 | + |
| 6 | +const testSlug = (slug: string, shouldPass: boolean) => { |
| 7 | + // Zod |
| 8 | + const zodResult = zk.slug().safeParse(slug); |
| 9 | + expect(zodResult.success).toBe(shouldPass); |
| 10 | + |
| 11 | + // Valibot |
| 12 | + const valibotResult = v.safeParse(vk.slug(), slug); |
| 13 | + expect(valibotResult.success).toBe(shouldPass); |
| 14 | +}; |
| 15 | + |
| 16 | +describe('slug', () => { |
| 17 | + describe('valid slugs', () => { |
| 18 | + const validCases = [ |
| 19 | + { slug: 'valid-slug', desc: 'basic slug' }, |
| 20 | + { slug: 'another-valid-slug-123', desc: 'with numbers' }, |
| 21 | + { slug: 'slug-with-multiple-parts', desc: 'multiple parts' }, |
| 22 | + { slug: 'a', desc: 'single letter' }, |
| 23 | + { slug: 'z-0-9', desc: 'mixed letters and numbers' }, |
| 24 | + { slug: '123', desc: 'only numbers' }, |
| 25 | + { slug: '1', desc: 'single digit' }, |
| 26 | + { |
| 27 | + slug: 'very-long-slug-with-many-parts-and-numbers-123', |
| 28 | + desc: 'long slug', |
| 29 | + }, |
| 30 | + ]; |
| 31 | + |
| 32 | + it.each(validCases)('should pass - %s ("%s")', ({ slug }) => { |
| 33 | + testSlug(slug, true); |
| 34 | + }); |
| 35 | + }); |
| 36 | + |
| 37 | + describe('invalid slugs', () => { |
| 38 | + const invalidCases = [ |
| 39 | + { slug: 'Invalid-Slug', desc: 'uppercase letters' }, |
| 40 | + { slug: 'invalid_slug', desc: 'underscores' }, |
| 41 | + { slug: 'invalid slug', desc: 'spaces' }, |
| 42 | + { slug: 'invalid@slug!', desc: 'special characters' }, |
| 43 | + { slug: '', desc: 'empty string' }, |
| 44 | + { slug: '-leading-hyphen', desc: 'leading hyphen' }, |
| 45 | + { slug: 'trailing-hyphen-', desc: 'trailing hyphen' }, |
| 46 | + { slug: 'double--hyphen', desc: 'consecutive hyphens' }, |
| 47 | + { slug: 'with/slash', desc: 'slash' }, |
| 48 | + { slug: 'with.dot', desc: 'dot' }, |
| 49 | + { slug: 'with..dot', desc: 'consecutive dots' }, |
| 50 | + { slug: '-', desc: 'single hyphen' }, |
| 51 | + { slug: 'Café', desc: 'unicode characters' }, |
| 52 | + { slug: 'سلام', desc: 'non-latin characters' }, |
| 53 | + { slug: ' leading-space', desc: 'leading space' }, |
| 54 | + { slug: 'trailing-space ', desc: 'trailing space' }, |
| 55 | + ]; |
| 56 | + |
| 57 | + it.each(invalidCases)('should fail - %s ("%s")', ({ slug }) => { |
| 58 | + testSlug(slug, false); |
| 59 | + }); |
| 60 | + }); |
| 61 | +}); |
0 commit comments