...

Source file src/github.com/launchdarkly/go-server-sdk-evaluation/v2/evaluator_base_test.go

Documentation: github.com/launchdarkly/go-server-sdk-evaluation/v2

     1  package evaluation
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/launchdarkly/go-sdk-common/v3/ldattr"
     8  	"github.com/launchdarkly/go-sdk-common/v3/ldcontext"
     9  	"github.com/launchdarkly/go-sdk-common/v3/ldreason"
    10  	"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
    11  	"github.com/launchdarkly/go-server-sdk-evaluation/v2/ldbuilders"
    12  	"github.com/launchdarkly/go-server-sdk-evaluation/v2/ldmodel"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func assertResultDetail(t *testing.T, expected ldreason.EvaluationDetail, result Result) {
    17  	assert.Equal(t, expected, result.Detail)
    18  }
    19  
    20  type simpleDataProvider struct {
    21  	getFlag    func(string) *ldmodel.FeatureFlag
    22  	getSegment func(string) *ldmodel.Segment
    23  }
    24  
    25  func (s *simpleDataProvider) GetFeatureFlag(key string) *ldmodel.FeatureFlag {
    26  	return s.getFlag(key)
    27  }
    28  
    29  func (s *simpleDataProvider) GetSegment(key string) *ldmodel.Segment {
    30  	return s.getSegment(key)
    31  }
    32  
    33  func (s *simpleDataProvider) withStoredFlags(flags ...ldmodel.FeatureFlag) *simpleDataProvider {
    34  	return &simpleDataProvider{
    35  		getFlag: func(key string) *ldmodel.FeatureFlag {
    36  			for _, f := range flags {
    37  				if f.Key == key {
    38  					ff := f
    39  					return &ff
    40  				}
    41  			}
    42  			return s.getFlag(key)
    43  		},
    44  		getSegment: s.getSegment,
    45  	}
    46  }
    47  
    48  func (s *simpleDataProvider) withNonexistentFlag(flagKey string) *simpleDataProvider {
    49  	return &simpleDataProvider{
    50  		getFlag: func(key string) *ldmodel.FeatureFlag {
    51  			if key == flagKey {
    52  				return nil
    53  			}
    54  			return s.getFlag(key)
    55  		},
    56  		getSegment: s.getSegment,
    57  	}
    58  }
    59  
    60  func (s *simpleDataProvider) withStoredSegments(segments ...ldmodel.Segment) *simpleDataProvider {
    61  	return &simpleDataProvider{
    62  		getFlag: s.getFlag,
    63  		getSegment: func(key string) *ldmodel.Segment {
    64  			for _, seg := range segments {
    65  				if seg.Key == key {
    66  					ss := seg
    67  					return &ss
    68  				}
    69  			}
    70  			return s.getSegment(key)
    71  		},
    72  	}
    73  }
    74  
    75  func (s *simpleDataProvider) withNonexistentSegment(segmentKey string) *simpleDataProvider {
    76  	return &simpleDataProvider{
    77  		getFlag: s.getFlag,
    78  		getSegment: func(key string) *ldmodel.Segment {
    79  			if key == segmentKey {
    80  				return nil
    81  			}
    82  			return s.getSegment(key)
    83  		},
    84  	}
    85  }
    86  
    87  func basicDataProvider() *simpleDataProvider {
    88  	return &simpleDataProvider{
    89  		getFlag: func(key string) *ldmodel.FeatureFlag {
    90  			panic(fmt.Errorf("unexpectedly queried feature flag: %s", key))
    91  		},
    92  		getSegment: func(key string) *ldmodel.Segment {
    93  			panic(fmt.Errorf("unexpectedly queried segment: %s", key))
    94  		},
    95  	}
    96  }
    97  
    98  func basicEvaluator() Evaluator {
    99  	return NewEvaluator(basicDataProvider())
   100  }
   101  
   102  func makeClauseToMatchContext(context ldcontext.Context) ldmodel.Clause {
   103  	return ldbuilders.ClauseWithKind(context.Kind(), ldattr.KeyAttr, ldmodel.OperatorIn, ldvalue.String(context.Key()))
   104  }
   105  
   106  func makeClauseToMatchAnyContextOfKind(kind ldcontext.Kind) ldmodel.Clause {
   107  	return ldbuilders.Negate(ldbuilders.ClauseWithKind(kind, ldattr.KeyAttr, ldmodel.OperatorIn, ldvalue.String("")))
   108  }
   109  
   110  func makeClauseToMatchAnyContextOfAnyKind() ldmodel.Clause {
   111  	return ldbuilders.Negate(ldbuilders.Clause(ldattr.KindAttr, ldmodel.OperatorIn, ldvalue.String("")))
   112  }
   113  
   114  func makeFlagToMatchContext(user ldcontext.Context, variationOrRollout ldmodel.VariationOrRollout) ldmodel.FeatureFlag {
   115  	return ldbuilders.NewFlagBuilder("feature").
   116  		On(true).
   117  		OffVariation(1).
   118  		AddRule(ldbuilders.NewRuleBuilder().ID("rule-id").VariationOrRollout(variationOrRollout).
   119  			Clauses(makeClauseToMatchContext(user))).
   120  		FallthroughVariation(0).
   121  		Variations(fallthroughValue, offValue, onValue).
   122  		Build()
   123  }
   124  
   125  func makeRuleToMatchUserKeyPrefix(prefix string, variationOrRollout ldmodel.VariationOrRollout) *ldbuilders.RuleBuilder {
   126  	return ldbuilders.NewRuleBuilder().ID("rule-id").
   127  		VariationOrRollout(variationOrRollout).
   128  		Clauses(ldbuilders.Clause(ldattr.KeyAttr, ldmodel.OperatorStartsWith, ldvalue.String(prefix)))
   129  }
   130  
   131  func makeBooleanFlagWithClauses(clauses ...ldmodel.Clause) ldmodel.FeatureFlag {
   132  	return ldbuilders.NewFlagBuilder("feature").
   133  		On(true).
   134  		AddRule(ldbuilders.NewRuleBuilder().Variation(1).Clauses(clauses...)).
   135  		Variations(ldvalue.Bool(false), ldvalue.Bool(true)).
   136  		FallthroughVariation(0).
   137  		Build()
   138  }
   139  
   140  func makeBooleanFlagToMatchAnyOfSegments(segmentKeys ...string) ldmodel.FeatureFlag {
   141  	return makeBooleanFlagWithClauses(ldbuilders.SegmentMatchClause(segmentKeys...))
   142  }
   143  
   144  func makeBooleanFlagToMatchAllOfSegments(segmentKeys ...string) ldmodel.FeatureFlag {
   145  	var clauses []ldmodel.Clause
   146  	for _, segmentKey := range segmentKeys {
   147  		clauses = append(clauses, ldbuilders.SegmentMatchClause(segmentKey))
   148  	}
   149  	return makeBooleanFlagWithClauses(clauses...)
   150  }
   151  

View as plain text