@@ -431,3 +431,191 @@ func Test_parseStringComparisonEvaluationData(t *testing.T) {
431431 })
432432 }
433433}
434+
435+ func TestJSONEvaluator_regexMatchEvaluation (t * testing.T ) {
436+ const source = "testSource"
437+ var sources = []string {source }
438+ ctx := context .Background ()
439+
440+ tests := map [string ]struct {
441+ flags []model.Flag
442+ flagKey string
443+ context map [string ]any
444+ expectedValue string
445+ expectedVariant string
446+ expectedReason string
447+ expectedError error
448+ }{
449+ "two strings provided - match" : {
450+ flags : []model.Flag {{
451+ Key : "headerColor" ,
452+ State : "ENABLED" ,
453+ DefaultVariant : "red" ,
454+ Variants : colorVariants ,
455+ Targeting : []byte (`{
456+ "if": [
457+ {
458+ "regex_match": ["[email protected] ", ".*"] 459+ },
460+ "red", null
461+ ]
462+ }` ),
463+ },
464+ },
465+ flagKey : "headerColor" ,
466+ context : map [string ]any {},
467+ expectedVariant : "red" ,
468+ expectedValue : "#FF0000" ,
469+ expectedReason : model .TargetingMatchReason ,
470+ },
471+ "resolve target property using nested operation - match" : {
472+ flags : []model.Flag {{
473+ Key : "headerColor" ,
474+ State : "ENABLED" ,
475+ DefaultVariant : "red" ,
476+ Variants : colorVariants ,
477+ Targeting : []byte (`{
478+ "if": [
479+ {
480+ "regex_match": [{"var": "email"}, ".*@.*"]
481+ },
482+ "red", null
483+ ]
484+ }` ),
485+ },
486+ },
487+ flagKey : "headerColor" ,
488+ context : map [string ]any {
489+ 490+ },
491+ expectedVariant : "red" ,
492+ expectedValue : "#FF0000" ,
493+ expectedReason : model .TargetingMatchReason ,
494+ },
495+ "two strings provided - no match" : {
496+ flags : []model.Flag {{
497+ Key : "headerColor" ,
498+ State : "ENABLED" ,
499+ DefaultVariant : "red" ,
500+ Variants : colorVariants ,
501+ Targeting : []byte (`{
502+ "if": [
503+ {
504+ "regex_match": ["[email protected] ", ".*FAAS.*"] 505+ },
506+ "red", "green"
507+ ]
508+ }` ),
509+ },
510+ },
511+ flagKey : "headerColor" ,
512+ context : map [string ]any {
513+ 514+ },
515+ expectedVariant : "green" ,
516+ expectedValue : "#00FF00" ,
517+ expectedReason : model .TargetingMatchReason ,
518+ },
519+ "three strings provided - match" : {
520+ flags : []model.Flag {{
521+ Key : "headerColor" ,
522+ State : "ENABLED" ,
523+ DefaultVariant : "red" ,
524+ Variants : colorVariants ,
525+ Targeting : []byte (`{
526+ "if": [
527+ {
528+ "regex_match": ["[email protected] ", ".*FAAS.*", "i"] 529+ },
530+ "red", null
531+ ]
532+ }` ),
533+ },
534+ },
535+ flagKey : "headerColor" ,
536+ context : map [string ]any {},
537+ expectedVariant : "red" ,
538+ expectedValue : "#FF0000" ,
539+ expectedReason : model .TargetingMatchReason ,
540+ },
541+ "resolve target property using nested operation - no match" : {
542+ flags : []model.Flag {{
543+ Key : "headerColor" ,
544+ State : "ENABLED" ,
545+ DefaultVariant : "red" ,
546+ Variants : colorVariants ,
547+ Targeting : []byte (`{
548+ "if": [
549+ {
550+ "regex_match": [{"var": "email"}, "nope"]
551+ },
552+ "red", "green"
553+ ]
554+ }` ),
555+ },
556+ },
557+ flagKey : "headerColor" ,
558+ context : map [string ]any {
559+ 560+ },
561+ expectedVariant : "green" ,
562+ expectedValue : "#00FF00" ,
563+ expectedReason : model .TargetingMatchReason ,
564+ },
565+ "error during parsing - return default" : {
566+ flags : []model.Flag {{
567+ Key : "headerColor" ,
568+ State : "ENABLED" ,
569+ DefaultVariant : "red" ,
570+ Variants : colorVariants ,
571+ Targeting : []byte (`{
572+ "if": [
573+ {
574+ "regex_match": "no-array"
575+ },
576+ "red", "green"
577+ ]
578+ }` ),
579+ },
580+ },
581+ flagKey : "headerColor" ,
582+ context : map [string ]any {
583+ 584+ },
585+ expectedVariant : "green" ,
586+ expectedValue : "#00FF00" ,
587+ expectedReason : model .TargetingMatchReason ,
588+ },
589+ }
590+
591+ const reqID = "default"
592+ for name , tt := range tests {
593+ t .Run (name , func (t * testing.T ) {
594+ log := logger .NewLogger (nil , false )
595+ s , err := store .NewStore (log , sources )
596+ if err != nil {
597+ t .Fatalf ("NewStore failed: %v" , err )
598+ }
599+ je := NewJSON (log , s )
600+ je .store .Update (source , tt .flags , model.Metadata {})
601+
602+ value , variant , reason , _ , err := resolve [string ](ctx , reqID , tt .flagKey , tt .context , je .evaluateVariant )
603+
604+ if value != tt .expectedValue {
605+ t .Errorf ("expected value '%s', got '%s'" , tt .expectedValue , value )
606+ }
607+
608+ if variant != tt .expectedVariant {
609+ t .Errorf ("expected variant '%s', got '%s'" , tt .expectedVariant , variant )
610+ }
611+
612+ if reason != tt .expectedReason {
613+ t .Errorf ("expected reason '%s', got '%s'" , tt .expectedReason , reason )
614+ }
615+
616+ if err != tt .expectedError {
617+ t .Errorf ("expected err '%v', got '%v'" , tt .expectedError , err )
618+ }
619+ })
620+ }
621+ }
0 commit comments