Skip to content

Commit

Permalink
Add matrix tests for clear text comparators and non-ASCII comparison …
Browse files Browse the repository at this point in the history
…values
  • Loading branch information
adams85 committed Oct 26, 2023
1 parent 9d708fc commit 553b7e4
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 57 deletions.
17 changes: 17 additions & 0 deletions src/ConfigCat.Client.Tests/ConfigV5EvaluationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ public class SensitiveTestsDescriptor : IMatrixTestDescriptor
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<SensitiveTestsDescriptor>.GetTests();
}

public class VariationIdTestsDescriptor : IMatrixTestDescriptor, IVariationIdMatrixText
{
// https://app.configcat.com/08d5a03c-feb7-af1e-a1fa-40b3329f8bed/08d774b9-3d05-0027-d5f4-3e76c3dba752/244cf8b0-f604-11e8-b543-f23c917f9d8d
public ConfigLocation ConfigLocation => new ConfigLocation.Cdn("PKDVCLf-Hq-h-kCzMp-L7Q/nQ5qkhRAUEa6beEyyrVLBA");
public string MatrixResultFileName => "testmatrix_variationid.csv";
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<VariationIdTestsDescriptor>.GetTests();
}

private protected override Dictionary<string, Setting> BasicConfig => MatrixTestRunner<BasicTestsDescriptor>.Default.config;

[DataTestMethod]
Expand Down Expand Up @@ -93,4 +101,13 @@ public void SensitiveTests(string configLocation, string settingKey, string expe
MatrixTestRunner<SensitiveTestsDescriptor>.Default.RunTest(this.configEvaluator, this.logger, settingKey, expectedReturnValue,
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}

[DataTestMethod]
[DynamicData(nameof(VariationIdTestsDescriptor.GetTests), typeof(VariationIdTestsDescriptor), DynamicDataSourceType.Method)]
public void VariationIdTests(string configLocation, string settingKey, string expectedReturnValue,
string? userId, string? userEmail, string? userCountry, string? userCustomAttributeName, string? userCustomAttributeValue)
{
MatrixTestRunner<VariationIdTestsDescriptor>.Default.RunTest(this.configEvaluator, this.logger, settingKey, expectedReturnValue,
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}
}
35 changes: 35 additions & 0 deletions src/ConfigCat.Client.Tests/ConfigV6EvaluationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ public class SensitiveTestsDescriptor : IMatrixTestDescriptor
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<SensitiveTestsDescriptor>.GetTests();
}

public class VariationIdTestsDescriptor : IMatrixTestDescriptor, IVariationIdMatrixText
{
//https://app.configcat.com/v2/e7a75611-4256-49a5-9320-ce158755e3ba/08d5a03c-feb7-af1e-a1fa-40b3329f8bed/08dbc4dc-30c6-4969-8e4c-03f6a8764199/244cf8b0-f604-11e8-b543-f23c917f9d8d
public ConfigLocation ConfigLocation => new ConfigLocation.Cdn("configcat-sdk-1/PKDVCLf-Hq-h-kCzMp-L7Q/spQnkRTIPEWVivZkWM84lQ");
public string MatrixResultFileName => "testmatrix_variationid.csv";
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<VariationIdTestsDescriptor>.GetTests();
}

public class AndOrMatrixTestsDescriptor : IMatrixTestDescriptor
{
// https://app.configcat.com/v2/e7a75611-4256-49a5-9320-ce158755e3ba/08dbc325-7f69-4fd4-8af4-cf9f24ec8ac9/08dbc325-9d5e-4988-891c-fd4a45790bd1/08dbc325-9ebd-4587-8171-88f76a3004cb
Expand Down Expand Up @@ -86,6 +94,14 @@ public class SegmentMatrixTestsDescriptor : IMatrixTestDescriptor
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<SegmentMatrixTestsDescriptor>.GetTests();
}

public class UnicodeMatrixTestsDescriptor : IMatrixTestDescriptor
{
// https://app.configcat.com/v2/e7a75611-4256-49a5-9320-ce158755e3ba/08dbc325-7f69-4fd4-8af4-cf9f24ec8ac9/08dbd63c-9774-49d6-8187-5f2aab7bd606/08dbc325-9ebd-4587-8171-88f76a3004cb
public ConfigLocation ConfigLocation => new ConfigLocation.Cdn("configcat-sdk-1/JcPbCGl_1E-K9M-fJOyKyQ/Da6w8dBbmUeMUBhh0iEeQQ");
public string MatrixResultFileName => "testmatrix_unicode.csv";
public static IEnumerable<object?[]> GetTests() => MatrixTestRunner<UnicodeMatrixTestsDescriptor>.GetTests();
}

private protected override Dictionary<string, Setting> BasicConfig => MatrixTestRunner<BasicTestsDescriptor>.Default.config;

[DataTestMethod]
Expand Down Expand Up @@ -133,6 +149,15 @@ public void SensitiveTests(string configLocation, string settingKey, string expe
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}

[DataTestMethod]
[DynamicData(nameof(VariationIdTestsDescriptor.GetTests), typeof(VariationIdTestsDescriptor), DynamicDataSourceType.Method)]
public void VariationIdTests(string configLocation, string settingKey, string expectedReturnValue,
string? userId, string? userEmail, string? userCountry, string? userCustomAttributeName, string? userCustomAttributeValue)
{
MatrixTestRunner<VariationIdTestsDescriptor>.Default.RunTest(this.configEvaluator, this.logger, settingKey, expectedReturnValue,
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}

[DataTestMethod]
[DynamicData(nameof(AndOrMatrixTestsDescriptor.GetTests), typeof(AndOrMatrixTestsDescriptor), DynamicDataSourceType.Method)]
public void AndOrMatrixTests(string configLocation, string settingKey, string expectedReturnValue,
Expand Down Expand Up @@ -169,6 +194,16 @@ public void SegmentMatrixTests(string configLocation, string settingKey, string
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}


[DataTestMethod]
[DynamicData(nameof(UnicodeMatrixTestsDescriptor.GetTests), typeof(UnicodeMatrixTestsDescriptor), DynamicDataSourceType.Method)]
public void UnicodeMatrixTests(string configLocation, string settingKey, string expectedReturnValue,
string? userId, string? userEmail, string? userCountry, string? userCustomAttributeName, string? userCustomAttributeValue)
{
MatrixTestRunner<UnicodeMatrixTestsDescriptor>.Default.RunTest(this.configEvaluator, this.logger, settingKey, expectedReturnValue,
userId, userEmail, userCountry, userCustomAttributeName, userCustomAttributeValue);
}

[TestMethod]
public void CircularDependencyTest()
{
Expand Down
6 changes: 6 additions & 0 deletions src/ConfigCat.Client.Tests/MatrixTestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ protected override bool AssertValue<T>(string expected, Func<string, T> parse, T
Assert.AreEqual(parse(expected), actual, $"config: {DescriptorInstance.ConfigLocation.GetRealLocation()} | keyName: {keyName} | userId: {userId}");
return true;
}

protected override bool AssertVariationId(string expected, string? actual, string keyName, string? userId)
{
Assert.AreEqual(expected, actual, $"config: {DescriptorInstance.ConfigLocation.GetRealLocation()} | keyName: {keyName} | userId: {userId}");
return true;
}
}
58 changes: 36 additions & 22 deletions src/ConfigCat.Client.Tests/MatrixTestRunnerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ public interface IMatrixTestDescriptor
public string MatrixResultFileName { get; }
}

public interface IVariationIdMatrixText { }

public class MatrixTestRunnerBase<TDescriptor> where TDescriptor : IMatrixTestDescriptor, new()
{
public static readonly TDescriptor DescriptorInstance = new();

private readonly bool isVariationIdMatrixTest;
internal readonly Dictionary<string, Setting> config;

public MatrixTestRunnerBase()
{
this.isVariationIdMatrixTest = DescriptorInstance is IVariationIdMatrixText;
this.config = DescriptorInstance.ConfigLocation.FetchConfigCached().Settings;
}

Expand Down Expand Up @@ -79,37 +83,47 @@ public MatrixTestRunnerBase()

protected virtual bool AssertValue<T>(string expected, Func<string, T> parse, T actual, string keyName, string? userId) => true;

protected virtual bool AssertVariationId(string expected, string? actual, string keyName, string? userId) => true;

internal bool RunTest(IRolloutEvaluator evaluator, LoggerWrapper logger, string settingKey, string expectedReturnValue, User? user = null)
{
if (settingKey.StartsWith("bool", StringComparison.OrdinalIgnoreCase))
if (this.isVariationIdMatrixTest)
{
var actual = evaluator.Evaluate(this.config, settingKey, false, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => bool.Parse(e), actual, settingKey, user?.Identifier);
var actual = evaluator.Evaluate(this.config, settingKey, (object?)null, user, null, logger).VariationId;
return AssertVariationId(expectedReturnValue, actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("double", StringComparison.OrdinalIgnoreCase))
else
{
var actual = evaluator.Evaluate(this.config, settingKey, double.NaN, user, null, logger).Value;
if (settingKey.StartsWith("bool", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, false, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => double.Parse(e, CultureInfo.InvariantCulture), actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("integer", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, int.MinValue, user, null, logger).Value;
return AssertValue(expectedReturnValue, static e => bool.Parse(e), actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("double", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, double.NaN, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => int.Parse(e, CultureInfo.InvariantCulture), actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("string", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, string.Empty, user, null, logger).Value;
return AssertValue(expectedReturnValue, static e => double.Parse(e, CultureInfo.InvariantCulture), actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("integer", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, int.MinValue, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => e, actual, settingKey, user?.Identifier);
}
else
{
var actual = evaluator.Evaluate(this.config, settingKey, (object?)null, user, null, logger).Value;
return AssertValue(expectedReturnValue, static e => int.Parse(e, CultureInfo.InvariantCulture), actual, settingKey, user?.Identifier);
}
else if (settingKey.StartsWith("string", StringComparison.OrdinalIgnoreCase))
{
var actual = evaluator.Evaluate(this.config, settingKey, string.Empty, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => e, Convert.ToString(actual, CultureInfo.InvariantCulture), settingKey, user?.Identifier);
return AssertValue(expectedReturnValue, static e => e, actual, settingKey, user?.Identifier);
}
else
{
var actual = evaluator.Evaluate(this.config, settingKey, (object?)null, user, null, logger).Value;

return AssertValue(expectedReturnValue, static e => e, Convert.ToString(actual, CultureInfo.InvariantCulture), settingKey, user?.Identifier);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@ INFO [5000] Evaluating 'allinone' for User '{"Identifier":"12345","Email":"joe@e
Evaluating targeting rules and applying the first match if any:
- IF User.Email EQUALS '<hashed value>' => true
AND User.Email NOT EQUALS '<hashed value>' => false, skipping the remaining AND conditions
THEN '1' => no match
THEN '1h' => no match
- IF User.Email EQUALS '[email protected]' => true
AND User.Email NOT EQUALS '[email protected]' => false, skipping the remaining AND conditions
THEN '1c' => no match
- IF User.Email IS ONE OF [<1 hashed value>] => true
AND User.Email IS NOT ONE OF [<1 hashed value>] => false, skipping the remaining AND conditions
THEN '2' => no match
THEN '2h' => no match
- IF User.Email IS ONE OF ['[email protected]'] => true
AND User.Email IS NOT ONE OF ['[email protected]'] => false, skipping the remaining AND conditions
THEN '2c' => no match
- IF User.Email STARTS WITH ANY OF [<1 hashed value>] => true
AND User.Email NOT STARTS WITH ANY OF [<1 hashed value>] => false, skipping the remaining AND conditions
THEN '3' => no match
THEN '3h' => no match
- IF User.Email STARTS WITH ANY OF ['joe@'] => true
AND User.Email NOT STARTS WITH ANY OF ['joe@'] => false, skipping the remaining AND conditions
THEN '3c' => no match
- IF User.Email ENDS WITH ANY OF [<1 hashed value>] => true
AND User.Email NOT ENDS WITH ANY OF [<1 hashed value>] => false, skipping the remaining AND conditions
THEN '4' => no match
THEN '4h' => no match
- IF User.Email ENDS WITH ANY OF ['@example.com'] => true
AND User.Email NOT ENDS WITH ANY OF ['@example.com'] => false, skipping the remaining AND conditions
THEN '4c' => no match
- IF User.Email CONTAINS ANY OF ['e@e'] => true
AND User.Email NOT CONTAINS ANY OF ['e@e'] => false, skipping the remaining AND conditions
THEN '5' => no match
Expand All @@ -38,5 +50,8 @@ INFO [5000] Evaluating 'allinone' for User '{"Identifier":"12345","Email":"joe@e
THEN '12' => no match
- IF User.Country ARRAY CONTAINS ANY OF [<1 hashed value>] => true
AND User.Country ARRAY NOT CONTAINS ANY OF [<1 hashed value>] => false, skipping the remaining AND conditions
THEN '13' => no match
THEN '13h' => no match
- IF User.Country ARRAY CONTAINS ANY OF ['USA'] => true
AND User.Country ARRAY NOT CONTAINS ANY OF ['USA'] => false, skipping the remaining AND conditions
THEN '13c' => no match
Returning 'default'.
Loading

0 comments on commit 553b7e4

Please sign in to comment.