func (c *TestProjectConfig) AddMultiVariationFeatureTest(f entities.Feature, disabledVariationKey, enabledVariationKey string) *TestProjectConfig {
	experimentID := c.getNextID()
	disabledVariationID := c.getNextID()
	enabledVariationID := c.getNextID()
	layerID := c.getNextID()
	disabledVariation := entities.Variation{
		Key:            disabledVariationKey,
		ID:             disabledVariationID,
		FeatureEnabled: false,
	}
	enabledVariation := entities.Variation{
		Key:            enabledVariationKey,
		ID:             enabledVariationID,
		FeatureEnabled: true,
	}
	experiment := entities.Experiment{
		Key:     experimentID,
		LayerID: layerID,
		ID:      experimentID,
		Variations: map[string]entities.Variation{
			disabledVariationID: disabledVariation,
			enabledVariationID:  enabledVariation,
		},
		VariationKeyToIDMap: map[string]string{
			enabledVariationKey: enabledVariationID,
		},
		TrafficAllocation: []entities.Range{
			entities.Range{EntityID: disabledVariationID, EndOfRange: 5000},
			entities.Range{EntityID: disabledVariationID, EndOfRange: 10000},
		},
	}
	c.ExperimentKeyToIDMap[experimentID] = experimentID
	c.ExperimentMap[experimentID] = experiment
	f.FeatureExperiments = []entities.Experiment{experiment}
	c.FeatureMap[f.Key] = f
	return c
}
AddMultiVariationFeatureTest adds the feature and supporting entities to complete modeling of the following:
- Feature test with two variations
- Feature is disabled in first variation, enabled in second variation
- Traffic allocation is 100% first variation, 0% second variation
package optimizelytest
import (
	"errors"
	"fmt"
	"strconv"
	optlyconfig "github.com/optimizely/go-sdk/pkg/config"
	"github.com/optimizely/go-sdk/pkg/entities"
)
type TestProjectConfig struct {
	Datafile             string
	AccountID            string
	ProjectID            string
	Revision             string
	ExperimentKeyToIDMap map[string]string
	AudienceMap          map[string]entities.Audience
	AttributeMap         map[string]entities.Attribute
	EventMap             map[string]entities.Event
	AttributeKeyToIDMap  map[string]string
	ExperimentMap        map[string]entities.Experiment
	FeatureMap           map[string]entities.Feature
	GroupMap             map[string]entities.Group
	RolloutMap           map[string]entities.Rollout
	nextID               int
	AnonymizeIP          bool
	BotFiltering         bool
	sendFlagDecisions    bool
	sdkKey               string
	environmentKey       string
}
func (c *TestProjectConfig) GetDatafile() string {
	return c.Datafile
}
func (c *TestProjectConfig) GetProjectID() string {
	return c.ProjectID
}
func (c *TestProjectConfig) GetRevision() string {
	return c.Revision
}
func (c *TestProjectConfig) GetAccountID() string {
	return c.AccountID
}
func (c *TestProjectConfig) GetAnonymizeIP() bool {
	return c.AnonymizeIP
}
func (c *TestProjectConfig) GetAttributes() (attributeList []entities.Attribute) {
	for _, attribute := range c.AttributeMap {
		attributeList = append(attributeList, attribute)
	}
	return attributeList
}
func (c *TestProjectConfig) GetAttributeID(key string) string {
	return c.AttributeKeyToIDMap[key]
}
func (c *TestProjectConfig) GetBotFiltering() bool {
	return c.BotFiltering
}
func (c *TestProjectConfig) GetSdkKey() string {
	return c.sdkKey
}
func (c *TestProjectConfig) GetEnvironmentKey() string {
	return c.environmentKey
}
func (c *TestProjectConfig) GetEvents() (eventList []entities.Event) {
	for _, event := range c.EventMap {
		eventList = append(eventList, event)
	}
	return eventList
}
func (c *TestProjectConfig) GetEventByKey(eventKey string) (entities.Event, error) {
	if event, ok := c.EventMap[eventKey]; ok {
		return event, nil
	}
	errMessage := fmt.Sprintf("Event with key %s not found", eventKey)
	return entities.Event{}, errors.New(errMessage)
}
func (c *TestProjectConfig) GetFeatureByKey(featureKey string) (entities.Feature, error) {
	if feature, ok := c.FeatureMap[featureKey]; ok {
		return feature, nil
	}
	errMessage := fmt.Sprintf("Feature with key %s not found", featureKey)
	return entities.Feature{}, errors.New(errMessage)
}
func (c *TestProjectConfig) GetVariableByKey(featureKey, variableKey string) (entities.Variable, error) {
	var variable entities.Variable
	var err = fmt.Errorf("variable with key %s not found", featureKey)
	if feature, ok := c.FeatureMap[featureKey]; ok {
		if variable, ok = feature.VariableMap[featureKey]; ok {
			return variable, nil
		}
	}
	return variable, err
}
func (c *TestProjectConfig) GetAttributeByKey(key string) (entities.Attribute, error) {
	if attributeID, ok := c.AttributeKeyToIDMap[key]; ok {
		return c.AttributeMap[attributeID], nil
	}
	errMessage := fmt.Sprintf(`Attribute with key "%s" not found`, key)
	return entities.Attribute{}, errors.New(errMessage)
}
func (c *TestProjectConfig) GetFeatureList() (featureList []entities.Feature) {
	for _, feature := range c.FeatureMap {
		featureList = append(featureList, feature)
	}
	return featureList
}
func (c *TestProjectConfig) GetExperimentList() (experimentList []entities.Experiment) {
	for _, experiment := range c.ExperimentMap {
		experimentList = append(experimentList, experiment)
	}
	return experimentList
}
func (c *TestProjectConfig) GetRolloutList() (rolloutList []entities.Rollout) {
	for _, rollout := range c.RolloutMap {
		rolloutList = append(rolloutList, rollout)
	}
	return rolloutList
}
func (c *TestProjectConfig) GetAudienceList() (audienceList []entities.Audience) {
	for _, audience := range c.AudienceMap {
		audienceList = append(audienceList, audience)
	}
	return audienceList
}
func (c *TestProjectConfig) GetAudienceByID(audienceID string) (entities.Audience, error) {
	if audience, ok := c.AudienceMap[audienceID]; ok {
		return audience, nil
	}
	errMessage := fmt.Sprintf(`Audience with ID "%s" not found`, audienceID)
	return entities.Audience{}, errors.New(errMessage)
}
func (c *TestProjectConfig) GetAudienceMap() map[string]entities.Audience {
	return c.AudienceMap
}
func (c *TestProjectConfig) GetExperimentByKey(experimentKey string) (entities.Experiment, error) {
	if experimentID, ok := c.ExperimentKeyToIDMap[experimentKey]; ok {
		experiment := c.ExperimentMap[experimentID]
		return experiment, nil
	}
	errMessage := fmt.Sprintf(`Experiment with key "%s" not found`, experimentKey)
	return entities.Experiment{}, errors.New(errMessage)
}
func (c *TestProjectConfig) GetGroupByID(groupID string) (entities.Group, error) {
	if group, ok := c.GroupMap[groupID]; ok {
		return group, nil
	}
	errMessage := fmt.Sprintf(`Group with ID "%s" not found`, groupID)
	return entities.Group{}, errors.New(errMessage)
}
func (c *TestProjectConfig) AddEvent(e entities.Event) *TestProjectConfig {
	c.EventMap[e.Key] = e
	return c
}
func (c *TestProjectConfig) AddFeature(f entities.Feature) *TestProjectConfig {
	c.FeatureMap[f.Key] = f
	return c
}
func (c *TestProjectConfig) AddFeatureTest(f entities.Feature) *TestProjectConfig {
	experimentID := c.getNextID()
	variationID := c.getNextID()
	layerID := c.getNextID()
	variation := entities.Variation{
		Key:            variationID,
		ID:             variationID,
		FeatureEnabled: true,
	}
	experiment := entities.Experiment{
		Key:                 experimentID,
		LayerID:             layerID,
		ID:                  experimentID,
		Variations:          map[string]entities.Variation{variationID: variation},
		VariationKeyToIDMap: map[string]string{variation.Key: variationID},
		TrafficAllocation: []entities.Range{
			entities.Range{EntityID: variationID, EndOfRange: 10000},
		},
	}
	f.FeatureExperiments = []entities.Experiment{experiment}
	c.FeatureMap[f.Key] = f
	c.ExperimentMap[experiment.Key] = experiment
	return c
}
func (c *TestProjectConfig) AddFeatureRollout(f entities.Feature) *TestProjectConfig {
	experimentID := c.getNextID()
	rolloutID := c.getNextID()
	variationID := c.getNextID()
	layerID := c.getNextID()
	variation := entities.Variation{
		Key:            variationID,
		ID:             variationID,
		FeatureEnabled: true,
	}
	experiment := entities.Experiment{
		Key:                 experimentID,
		LayerID:             layerID,
		ID:                  experimentID,
		Variations:          map[string]entities.Variation{variationID: variation},
		VariationKeyToIDMap: map[string]string{variation.Key: variationID},
		TrafficAllocation: []entities.Range{
			entities.Range{EntityID: variationID, EndOfRange: 10000},
		},
	}
	rollout := entities.Rollout{
		ID:          rolloutID,
		Experiments: []entities.Experiment{experiment},
	}
	c.RolloutMap[rolloutID] = rollout
	f.Rollout = rollout
	c.FeatureMap[f.Key] = f
	return c
}
func (c *TestProjectConfig) AddDisabledFeatureRollout(f entities.Feature) *TestProjectConfig {
	c.AddFeatureRollout(f)
	variations := c.FeatureMap[f.Key].Rollout.Experiments[0].Variations
	for _, variation := range variations {
		variation.FeatureEnabled = false
		variations[variation.ID] = variation
	}
	return c
}
func (c *TestProjectConfig) AddFeatureTestWithCustomVariableValue(feature entities.Feature, variable entities.Variable, customValue string) *TestProjectConfig {
	c.AddFeatureRollout(feature)
	c.AddFeatureTest(feature)
	variations := c.FeatureMap[feature.Key].FeatureExperiments[0].Variations
	customVariableValues := map[string]entities.VariationVariable{
		variable.ID: {
			ID:    variable.ID,
			Value: customValue,
		},
	}
	for _, variation := range variations {
		variation.Variables = customVariableValues
		variations[variation.ID] = variation
	}
	return c
}
func (c *TestProjectConfig) AddExperiment(experimentKey string, variations []entities.Variation) {
	experimentID := c.getNextID()
	layerID := c.getNextID()
	variationMap := map[string]entities.Variation{}
	variationKeyTOIDMap := make(map[string]string)
	trafficAllocation := []entities.Range{}
	for i, variation := range variations {
		variationMap[variation.ID] = variation
		variationKeyTOIDMap[variation.Key] = variation.ID
		endOfRange := 10000 / len(variations) * (i + 1)
		trafficAllocation = append(trafficAllocation, entities.Range{EntityID: variation.ID, EndOfRange: endOfRange})
	}
	experiment := entities.Experiment{
		Key:                 experimentKey,
		ID:                  experimentID,
		LayerID:             layerID,
		Variations:          variationMap,
		VariationKeyToIDMap: variationKeyTOIDMap,
		TrafficAllocation:   trafficAllocation,
	}
	c.ExperimentKeyToIDMap[experimentKey] = experimentID
	c.ExperimentMap[experimentID] = experiment
}
func (c *TestProjectConfig) CreateVariation(varKey string) entities.Variation {
	variationID := c.getNextID()
	variation := entities.Variation{
		Key: varKey,
		ID:  variationID,
	}
	return variation
}
func (c *TestProjectConfig) ConvertVariation(v entities.Variation) optlyconfig.OptimizelyVariation {
	variation := optlyconfig.OptimizelyVariation{
		Key:          v.Key,
		ID:           v.ID,
		VariablesMap: map[string]optlyconfig.OptimizelyVariable{},
	}
	return variation
}