@@ -34,6 +34,29 @@ function extractTestParams(name, message, test) {
3434 return opts
3535}
3636
37+ const listToArray = list =>
38+ toArray ( list ) . concat ( toArray ( list . refs . values ( ) ) )
39+
40+ const removeFromList = ( value , list ) => {
41+ Ref . isRef ( value ) ? list . refs . delete ( value . key ) : list . delete ( value )
42+ }
43+
44+ const addToList = ( value , list ) => {
45+ Ref . isRef ( value ) ? list . refs . set ( value . key , value ) : list . add ( value )
46+ }
47+
48+ const hasInList = ( value , resolve , list ) => {
49+ if ( list . has ( value ) ) return true ;
50+
51+ let item ; let values = list . refs . values ( )
52+
53+ while ( item = values . next ( ) , ! item . done ) {
54+ if ( resolve ( item . value ) === value )
55+ return true ;
56+ }
57+ return false
58+ }
59+
3760export default function SchemaType ( options = { } ) {
3861 if ( ! ( this instanceof SchemaType ) )
3962 return new SchemaType ( )
@@ -42,8 +65,12 @@ export default function SchemaType(options = {}){
4265 this . _conditions = [ ]
4366 this . _options = { abortEarly : true , recursive : true }
4467 this . _exclusive = Object . create ( null )
68+
4569 this . _whitelist = new Set ( )
70+ this . _whitelist . refs = new Map ( )
71+
4672 this . _blacklist = new Set ( )
73+ this . _blacklist . refs = new Map ( )
4774 this . tests = [ ]
4875 this . transforms = [ ]
4976
@@ -380,23 +407,22 @@ SchemaType.prototype = {
380407 var next = this . clone ( ) ;
381408
382409 enums . forEach ( val => {
383- if ( next . _blacklist . has ( val ) )
384- next . _blacklist . delete ( val )
385- next . _whitelist . add ( val )
410+ addToList ( val , next . _whitelist )
411+ removeFromList ( val , next . _blacklist )
386412 } )
387413
388414 next . _whitelistError = createValidation ( {
389415 message,
390416 name : 'oneOf' ,
391417 test ( value ) {
418+ if ( value === undefined ) return true
392419 let valids = this . schema . _whitelist
393- if ( valids . size && ! ( value === undefined || valids . has ( value ) ) )
394- return this . createError ( {
395- params : {
396- values : toArray ( valids ) . join ( ', ' )
397- }
398- } )
399- return true
420+
421+ return hasInList ( value , this . resolve , valids ) ? true : this . createError ( {
422+ params : {
423+ values : listToArray ( valids ) . join ( ', ' )
424+ }
425+ } )
400426 }
401427 } )
402428
@@ -405,21 +431,20 @@ SchemaType.prototype = {
405431
406432 notOneOf ( enums , message = locale . notOneOf ) {
407433 var next = this . clone ( ) ;
408-
409- enums . forEach ( val => {
410- next . _whitelist . delete ( val )
411- next . _blacklist . add ( val )
434+ enums . forEach ( val => {
435+ addToList ( val , next . _blacklist )
436+ removeFromList ( val , next . _whitelist )
412437 } )
413438
414439 next . _blacklistError = createValidation ( {
415440 message,
416441 name : 'notOneOf' ,
417442 test ( value ) {
418443 let invalids = this . schema . _blacklist
419- if ( invalids . size && invalids . has ( value ) )
444+ if ( hasInList ( value , this . resolve , invalids ) )
420445 return this . createError ( {
421446 params : {
422- values : toArray ( invalids ) . join ( ', ' )
447+ values : listToArray ( invalids ) . join ( ', ' )
423448 }
424449 } )
425450 return true
0 commit comments