1+ import type { ValidationError } from '../src/types'
12import { describe , expect , test } from 'bun:test'
23import { v } from '../src/validation'
34
@@ -101,6 +102,7 @@ describe('Validation Library', () => {
101102
102103 test ( 'comprehensive password validation with multiple rules' , ( ) => {
103104 const validator = v . password ( )
105+ . field ( 'password' )
104106 . minLength ( 8 )
105107 . maxLength ( 20 )
106108 . hasUppercase ( )
@@ -110,10 +112,11 @@ describe('Validation Library', () => {
110112
111113 const result = validator . validate ( 'weak' )
112114 expect ( result . valid ) . toBe ( false )
113- expect ( result . errors . length ) . toBeGreaterThan ( 0 )
115+ expect ( Object . keys ( result . errors ) ) . toContain ( 'password' )
116+ expect ( result . errors . password ?. length ) . toBeGreaterThan ( 0 )
114117
115118 // Check specific error messages
116- const errorMessages = result . errors . map ( e => e . message )
119+ const errorMessages = result . errors . password ?. map ( ( e : ValidationError ) => e . message ) || [ ]
117120 expect ( errorMessages ) . toContain ( 'Password must be at least 8 characters long' )
118121 expect ( errorMessages ) . toContain ( 'Password must contain at least one uppercase letter' )
119122 expect ( errorMessages ) . toContain ( 'Password must contain at least one number' )
@@ -122,7 +125,7 @@ describe('Validation Library', () => {
122125 // Test a valid password
123126 const validResult = validator . validate ( 'MySecureP@ss123' )
124127 expect ( validResult . valid ) . toBe ( true )
125- expect ( validResult . errors ) . toHaveLength ( 0 )
128+ expect ( Object . keys ( validResult . errors ) ) . toHaveLength ( 0 )
126129 } )
127130
128131 test ( 'alphanumeric password validation' , ( ) => {
@@ -413,16 +416,16 @@ describe('Validation Library', () => {
413416
414417 test ( 'complex object validation' , ( ) => {
415418 const validator = v . object ( ) . shape ( {
416- name : v . string ( ) . min ( 2 ) . max ( 50 ) ,
417- email : v . string ( ) . email ( ) ,
418- age : v . number ( ) . min ( 18 ) . integer ( ) ,
419- website : v . string ( ) . url ( ) . optional ( ) ,
420- tags : v . array < string > ( ) . each ( v . string ( ) ) . optional ( ) ,
419+ name : v . string ( ) . min ( 2 ) . max ( 50 ) . field ( 'name' ) ,
420+ email : v . string ( ) . email ( ) . field ( 'email' ) ,
421+ age : v . number ( ) . min ( 18 ) . integer ( ) . field ( 'age' ) ,
422+ website : v . string ( ) . url ( ) . optional ( ) . field ( 'website' ) ,
423+ tags : v . array < string > ( ) . each ( v . string ( ) ) . optional ( ) . field ( 'tags' ) ,
421424 address : v . object ( ) . shape ( {
422- street : v . string ( ) ,
423- city : v . string ( ) ,
424- zip : v . string ( ) ,
425- } ) . optional ( ) ,
425+ street : v . string ( ) . field ( 'street' ) ,
426+ city : v . string ( ) . field ( 'city' ) ,
427+ zip : v . string ( ) . field ( 'zip' ) ,
428+ } ) . optional ( ) . field ( 'address' ) ,
426429 } )
427430
428431 expect ( validator . test ( {
@@ -452,32 +455,37 @@ describe('Validation Library', () => {
452455 } )
453456
454457 expect ( result . valid ) . toBe ( false )
455- expect ( result . errors ) . toHaveLength ( 5 )
458+ expect ( Object . keys ( result . errors ) . length ) . toBe ( 5 )
456459
457460 // Check specific error messages
458- const errorMessages = result . errors . map ( e => e . message )
459- expect ( errorMessages ) . toContain ( 'name: Must be at least 2 characters long' ) // name too short
460- expect ( errorMessages ) . toContain ( 'email: Must be a valid email address' ) // invalid email
461- expect ( errorMessages ) . toContain ( 'age: Must be at least 18' ) // age too young
462- expect ( errorMessages ) . toContain ( 'website: Must be a valid URL' ) // invalid URL
463- expect ( errorMessages ) . toContain ( 'tags: Each item in array is invalid' ) // invalid array item type
461+ expect ( result . errors . name ?. [ 0 ] . message ) . toBe ( 'Must be at least 2 characters long' )
462+ expect ( result . errors . email ?. [ 0 ] . message ) . toBe ( 'Must be a valid email address' )
463+ expect ( result . errors . age ?. [ 0 ] . message ) . toBe ( 'Must be at least 18' )
464+ expect ( result . errors . website ?. [ 0 ] . message ) . toBe ( 'Must be a valid URL' )
465+ expect ( result . errors . tags ?. [ 0 ] . message ) . toBe ( 'Each item in array is invalid' )
464466 } )
465467 } )
466468
467469 describe ( 'Validation Results' , ( ) => {
468470 test ( 'validate returns detailed results' , ( ) => {
469- const validator = v . string ( ) . min ( 5 ) . max ( 10 )
471+ const validator = v . string ( ) . field ( 'name' ) . min ( 5 ) . max ( 10 )
470472 const result = validator . validate ( 'hi' )
471473 expect ( result . valid ) . toBe ( false )
472- expect ( result . errors ) . toHaveLength ( 1 )
473- expect ( result . errors [ 0 ] . message ) . toBe ( 'Must be at least 5 characters long' )
474+ expect ( Object . keys ( result . errors ) ) . toContain ( 'name' )
475+ expect ( result . errors . name ?. length ) . toBe ( 1 )
476+ expect ( result . errors . name ?. [ 0 ] . message ) . toBe ( 'Must be at least 5 characters long' )
474477 } )
475478
476479 test ( 'multiple validation errors' , ( ) => {
477- const validator = v . string ( ) . min ( 5 ) . max ( 10 ) . alphanumeric ( )
480+ const validator = v . string ( ) . field ( 'username' ) . min ( 5 ) . max ( 10 ) . alphanumeric ( )
478481 const result = validator . validate ( 'hi!' )
479482 expect ( result . valid ) . toBe ( false )
480- expect ( result . errors ) . toHaveLength ( 2 )
483+ expect ( Object . keys ( result . errors ) ) . toContain ( 'username' )
484+ expect ( result . errors . username ?. length ) . toBeGreaterThan ( 1 )
485+
486+ const errorMessages = result . errors . username ?. map ( ( e : ValidationError ) => e . message ) || [ ]
487+ expect ( errorMessages ) . toContain ( 'Must be at least 5 characters long' )
488+ expect ( errorMessages ) . toContain ( 'Must only contain letters and numbers' )
481489 } )
482490 } )
483491
@@ -486,21 +494,20 @@ describe('Validation Library', () => {
486494 const result = v . custom (
487495 ( value : string ) => value . startsWith ( 'test-' ) ,
488496 'Must start with "test-"' ,
489- ) . validate ( 'test -123' )
497+ ) . field ( 'custom' ) . validate ( 'invalid -123' )
490498
491- expect ( result . valid ) . toBe ( true )
492- expect ( result . errors ) . toHaveLength ( 0 )
499+ expect ( result . valid ) . toBe ( false )
500+ expect ( result . errors . custom ?. [ 0 ] . message ) . toBe ( 'Must start with "test-"' )
493501 } )
494502
495503 test ( 'should fail with custom error message' , ( ) => {
496504 const result = v . custom (
497505 ( value : string ) => value . startsWith ( 'test-' ) ,
498506 'Must start with "test-"' ,
499- ) . validate ( 'invalid-123' )
507+ ) . field ( 'custom' ) . validate ( 'invalid-123' )
500508
501509 expect ( result . valid ) . toBe ( false )
502- expect ( result . errors ) . toHaveLength ( 1 )
503- expect ( result . errors [ 0 ] . message ) . toBe ( 'Must start with "test-"' )
510+ expect ( result . errors . custom ?. [ 0 ] . message ) . toBe ( 'Must start with "test-"' )
504511 } )
505512
506513 test ( 'should handle optional values' , ( ) => {
@@ -510,7 +517,6 @@ describe('Validation Library', () => {
510517 ) . optional ( ) . validate ( undefined )
511518
512519 expect ( result . valid ) . toBe ( true )
513- expect ( result . errors ) . toHaveLength ( 0 )
514520 } )
515521 } )
516522
0 commit comments