private void BuildClauseLayerOf(ClauseBuilder clauseBuilder, UnifiedNode clauseResult) { clauseBuilder.AggregateAuxiliarySpecified = clauseResult.C_AggregateAuxiliary != null; if (clauseBuilder.AggregateAuxiliarySpecified) { clauseBuilder.AggregateAuxiliary = (bool)clauseResult.C_AggregateAuxiliary; } clauseBuilder.Complementiser = clauseResult.C_Complementizer; clauseBuilder.FormSpecified = clauseResult.C_Form != null; if (clauseBuilder.FormSpecified) { clauseBuilder.Form = (form)clauseResult.C_Form; } clauseBuilder.InterrogativeTypeSpecified = clauseResult.C_InterrogativeType != null; if (clauseBuilder.InterrogativeTypeSpecified) { clauseBuilder.InterrogativeType = (interrogativeType)clauseResult.C_InterrogativeType; } clauseBuilder.Modal = clauseResult.C_Modal; clauseBuilder.NegatedSpecified = clauseResult.C_Negated != null; if (clauseBuilder.NegatedSpecified) { clauseBuilder.Negated = (bool)clauseResult.C_Negated; } clauseBuilder.PassiveSpecified = clauseResult.C_Passive != null; if (clauseBuilder.PassiveSpecified) { clauseBuilder.Passive = (bool)clauseResult.C_Passive; } clauseBuilder.PerfectSpecified = clauseResult.C_Perfect != null; if (clauseBuilder.PerfectSpecified) { clauseBuilder.Perfect = (bool)clauseResult.C_Perfect; } clauseBuilder.PersonSpecified = clauseResult.C_Person != null; if (clauseBuilder.PersonSpecified) { clauseBuilder.Person = (person)clauseResult.C_Person; } clauseBuilder.ProgressiveSpecified = clauseResult.C_Progressive != null; if (clauseBuilder.ProgressiveSpecified) { clauseBuilder.Progressive = (bool)clauseResult.C_Progressive; } clauseBuilder.SuppressGenitiveInGerundSpecified = clauseResult.C_SuppressGenitiveInGerund != null; if (clauseBuilder.SuppressGenitiveInGerundSpecified) { clauseBuilder.SuppressGenitiveInGerund = (bool)clauseResult.C_SuppressGenitiveInGerund; } clauseBuilder.SuppressedComplementiserSpecified = clauseResult.C_SuppressedComplementizer != null; if (clauseBuilder.SuppressedComplementiserSpecified) { clauseBuilder.SuppressedComplementiser = (bool)clauseResult.C_SuppressedComplementizer; } clauseBuilder.TenseSpecified = clauseResult.C_Tense != null; if (clauseBuilder.TenseSpecified) { clauseBuilder.Tense = (tense)clauseResult.C_Tense; } }
public LdClientBigSegmentsTest(ITestOutputHelper testOutput) : base(testOutput) { _testData = TestData.DataSource(); _user = User.WithKey("userkey"); _bigSegment = new SegmentBuilder("segmentkey") .Unbounded(true) .Generation(1) .Build(); _flag = new FeatureFlagBuilder("flagkey") .On(true) .Variations(LdValue.Of(false), LdValue.Of(true)) .FallthroughVariation(0) .Rules( new RuleBuilder().Variation(1).Clauses( ClauseBuilder.ShouldMatchSegment(_bigSegment.Key) ).Build() ) .Build(); _testData.UsePreconfiguredFlag(_flag); _testData.UsePreconfiguredSegment(_bigSegment); _storeMock = new MockBigSegmentStore(); _storeFactory = _storeMock.AsSingletonFactory(); _storeMock.SetupMetadataReturns(new StoreMetadata { LastUpToDate = UnixMillisecondTime.Now }); }
private void UpdateClauseLayerFor(ClauseBuilder clauseBuilder) { LayerClause dbSavedClauseLayer; LayerClause existingClauseLayer = LayerClauses.FirstOrDefault(clauseLayer => clauseLayer.ID.Equals(clauseBuilder.FlexDB_ID)); if (existingClauseLayer != null) { dbSavedClauseLayer = existingClauseLayer; } else { dbSavedClauseLayer = new LayerClause { ID = clauseBuilder.FlexDB_ID }; LayerClauses.InsertOnSubmit(dbSavedClauseLayer); } dbSavedClauseLayer.AggregateAuxiliary = clauseBuilder.AggregateAuxiliarySpecified ? clauseBuilder.AggregateAuxiliary : null; dbSavedClauseLayer.Complementizer = clauseBuilder.Complementiser; dbSavedClauseLayer.Form = clauseBuilder.FormSpecified ? (byte)clauseBuilder.Form : null; dbSavedClauseLayer.InterrogativeType = clauseBuilder.InterrogativeTypeSpecified ? (byte)clauseBuilder.InterrogativeType : null; dbSavedClauseLayer.Modal = clauseBuilder.Modal; dbSavedClauseLayer.Negated = clauseBuilder.NegatedSpecified ? clauseBuilder.Negated : null; dbSavedClauseLayer.Passive = clauseBuilder.PassiveSpecified ? clauseBuilder.Passive : null; dbSavedClauseLayer.Perfect = clauseBuilder.PerfectSpecified ? clauseBuilder.Perfect : null; dbSavedClauseLayer.Person = clauseBuilder.PersonSpecified ? (byte)clauseBuilder.Person : null; dbSavedClauseLayer.Progressive = clauseBuilder.ProgressiveSpecified ? clauseBuilder.Progressive : null; dbSavedClauseLayer.SuppressGenitiveInGerund = clauseBuilder.SuppressGenitiveInGerundSpecified ? clauseBuilder.SuppressGenitiveInGerund : null; dbSavedClauseLayer.SuppressedComplementizer = clauseBuilder.SuppressedComplementiserSpecified ? clauseBuilder.SuppressedComplementiser : null; UpdateLayerClause(dbSavedClauseLayer); }
public void EventTrackingAndReasonAreNotForcedIfFlagIsNotSetForMatchingRule() { var clause0 = ClauseBuilder.ShouldNotMatchUser(user); var clause1 = ClauseBuilder.ShouldMatchUser(user); var rule0 = new RuleBuilder().Id("id0").Variation(1).Clauses(clause0).TrackEvents(true).Build(); var rule1 = new RuleBuilder().Id("id1").Variation(1).Clauses(clause1).TrackEvents(false).Build(); var flag = new FeatureFlagBuilder("flag").Version(1) .On(true) .Rules(rule0, rule1) .OffVariation(0) .Variations(LdValue.Of("off"), LdValue.Of("on")) .Build(); testData.UsePreconfiguredFlag(flag); client.StringVariation("flag", user, "default"); // It matched rule1, which has trackEvents: false, so we don't get the override behavior Assert.Equal(1, eventSink.Events.Count); var e = Assert.IsType <EvaluationEvent>(eventSink.Events[0]); Assert.False(e.TrackEvents); Assert.Null(e.Reason); }
public void BigSegmentStateIsQueriedOnlyOncePerUserEvenIfFlagReferencesMultipleSegments() { var segment1 = new SegmentBuilder("segmentkey1").Unbounded(true).Generation(2).Build(); var segment2 = new SegmentBuilder("segmentkey2").Unbounded(true).Generation(3).Build(); var bigSegments = new MockBigSegmentProvider(); var membership = MockMembership.New().Include(segment2); bigSegments.Membership[baseUser.Key] = membership; var flag = new FeatureFlagBuilder("key").On(true) .Variations(LdValue.Of(false), LdValue.Of(true)) .FallthroughVariation(0) .Rules( new RuleBuilder().Variation(1).Clauses(ClauseBuilder.ShouldMatchSegment(segment1.Key)).Build(), new RuleBuilder().Variation(1).Clauses(ClauseBuilder.ShouldMatchSegment(segment2.Key)).Build() ) .Build(); var evaluator = BasicEvaluator.WithStoredSegments(segment1, segment2).WithBigSegments(bigSegments); var result = evaluator.Evaluate(flag, baseUser, EventFactory.Default); Assert.Equal(LdValue.Of(true), result.Result.Value); Assert.Equal(BigSegmentsStatus.Healthy, result.Result.Reason.BigSegmentsStatus); Assert.Equal(1, bigSegments.MembershipQueryCount); Assert.Equal(new List <string> { MakeBigSegmentRef(segment1), MakeBigSegmentRef(segment2) }, membership.Queries); }
public IQueryable <T> Search(IQueryCollection query, IQueryable <T> results) { var nonSearchable = new List <string> { "max", "offset", "sort", "order" }; var searchParams = query.ToList(); searchParams.RemoveAll(kv => nonSearchable.Contains(kv.Key)); var clauseBuilder = new ClauseBuilder(typeof(T).Name); foreach (var(propName, value) in searchParams) { var property = typeof(T).GetProperty(propName); if (property == null) { throw new KeyNotFoundException( $"Attribute '{propName}' not found in entity '{typeof(T).Name}'"); } var clause = clauseBuilder.GetClause(property, propName, value); if (!string.IsNullOrEmpty(clause)) { results = results.WhereDynamic(x => clause); } } return(results); }
public void ClauseReturnsFalseForMissingAttribute() { var clause = new ClauseBuilder().Attribute("legs").Op("in").Values(LdValue.Of(4)).Build(); var f = new FeatureFlagBuilder("key").BooleanWithClauses(clause).Build(); var user = User.Builder("key").Name("bob").Build(); Assert.Equal(LdValue.Of(false), BasicEvaluator.Evaluate(f, user, EventFactory.Default).Result.Value); }
public void ClauseWithUnknownOperatorDoesNotMatch() { var clause = new ClauseBuilder().Attribute("name").Op("invalidOp").Values(LdValue.Of("Bob")).Build(); var f = new FeatureFlagBuilder("key").BooleanWithClauses(clause).Build(); var user = User.Builder("key").Name("Bob").Build(); Assert.Equal(LdValue.Of(false), BasicEvaluator.Evaluate(f, user, EventFactory.Default).Result.Value); }
public void ClauseCanMatchCustomAttribute() { var clause = new ClauseBuilder().Attribute("legs").Op("in").Values(LdValue.Of(4)).Build(); var f = new FeatureFlagBuilder("key").BooleanWithClauses(clause).Build(); var user = User.Builder("key").Custom("legs", 4).Build(); Assert.Equal(LdValue.Of(true), BasicEvaluator.Evaluate(f, user, EventFactory.Default).Result.Value); }
public void ClauseCanBeNegated() { var clause = new ClauseBuilder().Attribute("name").Op("in").Values(LdValue.Of("Bob")) .Negate(true).Build(); var f = new FeatureFlagBuilder("key").BooleanWithClauses(clause).Build(); var user = User.Builder("key").Name("Bob").Build(); Assert.Equal(LdValue.Of(false), BasicEvaluator.Evaluate(f, user, EventFactory.Default).Result.Value); }
public void MatchingRuleWithZeroRollout() { var clause = new ClauseBuilder().Attribute("email").Op("in").Values(LdValue.Of("*****@*****.**")).Build(); var rule = new SegmentRule(new List <Clause> { clause }, 0, null); var s = new SegmentBuilder("test").Version(1).Rules(rule).Build(); var u = User.Builder("foo").Email("*****@*****.**").Build(); Assert.False(SegmentMatchesUser(s, u)); }
public void FlagReturnsInExperimentForRuleMatchWhenInExperimentVariationButNonExperimentRollout() { var user = User.WithKey("userkey"); var rollout = BuildRollout(RolloutKind.Rollout, false); var rule = new RuleBuilder().Id("id").Rollout(rollout).Clauses(ClauseBuilder.ShouldMatchUser(user)).Build(); var f = FeatureFlagWithRules(rule); var result = BasicEvaluator.Evaluate(f, baseUser, EventFactory.Default); Assert.Equal(EvaluationReasonKind.RuleMatch, result.Result.Reason.Kind); Assert.False(result.Result.Reason.InExperiment); }
public void Test2() { var sql = ClauseBuilder .From <Users>() .Select <Users>(u => u.Id, u => u.Email) .Build(); const string expected = "SELECT Users.Id, Users.Email\r\n" + "FROM Users\r\n"; Assert.Equal(expected, sql); }
public void NonMatchingRuleWithMultipleClauses() { var clause1 = new ClauseBuilder().Attribute("email").Op("in").Values(LdValue.Of("*****@*****.**")).Build(); var clause2 = new ClauseBuilder().Attribute("name").Op("in").Values(LdValue.Of("bill")).Build(); var rule = new SegmentRule(new List <Clause> { clause1, clause2 }, null, null); var s = new SegmentBuilder("test").Version(1).Rules(rule).Build(); var u = User.Builder("foo").Email("*****@*****.**").Name("bob").Build(); Assert.False(SegmentMatchesUser(s, u)); }
public void CanMatchUserBySegment() { var segment = new SegmentBuilder("segment`").Version(1).Included(user.Key).Build(); testData.UsePreconfiguredSegment(segment); var clause = new ClauseBuilder().Op("segmentMatch").Values(LdValue.Of(segment.Key)).Build(); var feature = new FeatureFlagBuilder("feature").BooleanWithClauses(clause).Build(); testData.UsePreconfiguredFlag(feature); Assert.True(client.BoolVariation("feature", user, false)); }
private void BuildPhraseLayersOf(ClauseBuilder clauseBuilder, UnifiedNode clauseResult) { clauseBuilder.DiscourseFunctionSpecified = clauseResult.DiscourseFunction != null; if (clauseBuilder.DiscourseFunctionSpecified) { clauseBuilder.DiscourseFunction = (discourseFunction)clauseResult.DiscourseFunction; } clauseBuilder.AppositiveSpecified = clauseResult.Appositive != null; if (clauseBuilder.AppositiveSpecified) { clauseBuilder.Appositive = (bool)clauseResult.Appositive; } BuildClauseLayerOf(clauseBuilder, clauseResult); }
internal TranslateResult Translate <T>(Expression <T> expression, ClauseType clauseType) { this.clauseBuilder = new ClauseBuilder(); this.parameterBuilder = new ParameterBuilder(); this.clauseType = clauseType; this.Visit(expression); return(new TranslateResult { CommandText = clauseBuilder.GetExpressionText(), Parameters = clauseBuilder.GetExpressionParameters(), }); }
public void Test1() { var sql = ClauseBuilder .From <Users>() .InnerJoin <Users, UsersMetadata, int>(u => u.Id, um => um.UserId) .Select <Users>(u => new object[] { u.Email, }) .Select <UsersMetadata>(um => new object[] { um.UserId }) .Build(); const string expected = "SELECT Users.Email, UsersMetadata.UserId\r\n" + "FROM Users\r\n" + "INNER JOIN UsersMetadata ON Users.Id = UsersMetadata.UserId\r\n"; Assert.Equal(expected, sql); }
public void RuleWithNoVariationOrRolloutReturnsMalformedFlagError() { var user = User.WithKey("userkey"); var clause = ClauseBuilder.ShouldMatchUser(user); var rule = new RuleBuilder().Id("ruleid").Clauses(clause).Build(); var f = FeatureFlagWithRules(rule); var result = BasicEvaluator.Evaluate(f, user, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Null, null, EvaluationReason.ErrorReason(EvaluationErrorKind.MalformedFlag)); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public TranslateResult Translator(object instance, Type type, List <bool> fieldsUsable, ClauseType clauseType, List <Parameter> parameters = null) { clauseBuilder = new ClauseBuilder(); parameterBuilder = new ParameterBuilder(); switch (clauseType) { case ClauseType.SaveWhere: return(TranslateWhere(instance, type, parameters)); case ClauseType.Values: return(TranslateValues(instance, type, parameters)); case ClauseType.ColumnValue: return(TranslateColumnValue(instance, type, fieldsUsable, parameters)); } return(null); }
public void UnmatchedByExcludeRegardlessOfRule() { var clause = ClauseBuilder.ShouldMatchUser(baseUser); var rule = new SegmentRule(new List <Clause> { clause }, 0, null); var segment = new SegmentBuilder("segmentkey").Unbounded(true).Generation(2) .Rules(rule) .Build(); var bigSegments = new MockBigSegmentProvider(); bigSegments.Membership[baseUser.Key] = MockMembership.New().Exclude(segment); var flag = new FeatureFlagBuilder("key").BooleanMatchingSegment(segment.Key).Build(); var evaluator = BasicEvaluator.WithStoredSegments(segment).WithBigSegments(bigSegments); var result = evaluator.Evaluate(flag, baseUser, EventFactory.Default); Assert.Equal(LdValue.Of(false), result.Result.Value); Assert.Equal(BigSegmentsStatus.Healthy, result.Result.Reason.BigSegmentsStatus); }
private void UpdatePhraseLayerFor(ClauseBuilder clauseBuilder) { LayerPhrase dbSavedPhraseLayer; LayerPhrase existingPhraseLayer = LayerPhrases.FirstOrDefault(phraseLayer => phraseLayer.ID.Equals(clauseBuilder.FlexDB_ID)); if (existingPhraseLayer != null) { dbSavedPhraseLayer = existingPhraseLayer; } else { dbSavedPhraseLayer = new LayerPhrase { ID = clauseBuilder.FlexDB_ID }; LayerPhrases.InsertOnSubmit(dbSavedPhraseLayer); } dbSavedPhraseLayer.DiscourseFunction = clauseBuilder.DiscourseFunctionSpecified ? (byte)clauseBuilder.DiscourseFunction : null; dbSavedPhraseLayer.Appositive = clauseBuilder.AppositiveSpecified ? clauseBuilder.Appositive : null; UpdateLayerPhrase(dbSavedPhraseLayer); }
public void EventTrackingAndReasonCanBeForcedForRule() { var clause = ClauseBuilder.ShouldMatchUser(user); var rule = new RuleBuilder().Id("rule-id").Variation(1).Clauses(clause).TrackEvents(true).Build(); var flag = new FeatureFlagBuilder("flag").Version(1) .On(true) .Rules(rule) .OffVariation(0) .Variations(LdValue.Of("off"), LdValue.Of("on")) .Build(); testData.UsePreconfiguredFlag(flag); client.StringVariation("flag", user, "default"); // Note, we did not call StringVariationDetail and the flag is not tracked, but we should still get // tracking and a reason, because the rule-level trackEvents flag is on for the matched rule. Assert.Equal(1, eventSink.Events.Count); var e = Assert.IsType <EvaluationEvent>(eventSink.Events[0]); Assert.True(e.TrackEvents); Assert.Equal(EvaluationReason.RuleMatchReason(0, "rule-id"), e.Reason); }