Skip to content

Commit

Permalink
Merge branch 'refs/heads/main' into add-open-feature-extensions-hosting
Browse files Browse the repository at this point in the history
  • Loading branch information
askpt committed Jul 30, 2024
2 parents bedb2f1 + ccc2f7f commit 0b6ee68
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 42 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
source-url: https://nuget.pkg.github.com/open-feature/index.json

Expand Down Expand Up @@ -68,7 +67,6 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
source-url: https://nuget.pkg.github.com/open-feature/index.json

Expand All @@ -89,7 +87,7 @@ jobs:

- name: Publish NuGet packages (fork)
if: github.event.pull_request.head.repo.fork == true
uses: actions/[email protected].3
uses: actions/[email protected].4
with:
name: nupkgs
path: src/**/*.nupkg
1 change: 0 additions & 1 deletion .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
source-url: https://nuget.pkg.github.com/open-feature/index.json

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
source-url: https://nuget.pkg.github.com/open-feature/index.json

Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
source-url: https://nuget.pkg.github.com/open-feature/index.json

Expand Down
4 changes: 2 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
<PackageVersion Include="SpecFlow" Version="3.9.74" />
<PackageVersion Include="SpecFlow.Tools.MsBuild.Generation" Version="3.9.74" />
<PackageVersion Include="SpecFlow.xUnit" Version="3.9.74" />
<PackageVersion Include="xunit" Version="2.8.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.1" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>

<ItemGroup Condition="'$(OS)' == 'Unix'">
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"rollForward": "latestFeature",
"version": "8.0.301"
"version": "8.0.303"
}
}
2 changes: 1 addition & 1 deletion src/OpenFeature/Extension/ResolutionDetailsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal static class ResolutionDetailsExtensions
public static FlagEvaluationDetails<T> ToFlagEvaluationDetails<T>(this ResolutionDetails<T> details)
{
return new FlagEvaluationDetails<T>(details.FlagKey, details.Value, details.ErrorType, details.Reason,
details.Variant, details.ErrorMessage);
details.Variant, details.ErrorMessage, details.FlagMetadata);
}
}
}
23 changes: 17 additions & 6 deletions src/OpenFeature/Model/EvaluationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,30 @@ namespace OpenFeature.Model
/// <seealso href="https://github.com/open-feature/spec/blob/v0.5.2/specification/sections/03-evaluation-context.md">Evaluation context</seealso>
public sealed class EvaluationContext
{
/// <summary>
/// The index for the "targeting key" property when the EvaluationContext is serialized or expressed as a dictionary.
/// </summary>
internal const string TargetingKeyIndex = "targetingKey";


private readonly Structure _structure;

/// <summary>
/// Internal constructor used by the builder.
/// </summary>
/// <param name="targetingKey">The targeting key</param>
/// <param name="content">The content of the context.</param>
internal EvaluationContext(string? targetingKey, Structure content)
/// <param name="content"></param>
internal EvaluationContext(Structure content)
{
this.TargetingKey = targetingKey;
this._structure = content;
}


/// <summary>
/// Private constructor for making an empty <see cref="EvaluationContext"/>.
/// </summary>
private EvaluationContext()
{
this._structure = Structure.Empty;
this.TargetingKey = string.Empty;
}

/// <summary>
Expand Down Expand Up @@ -89,7 +93,14 @@ public IImmutableDictionary<string, Value> AsDictionary()
/// <summary>
/// Returns the targeting key for the context.
/// </summary>
public string? TargetingKey { get; }
public string? TargetingKey
{
get
{
this._structure.TryGetValue(TargetingKeyIndex, out Value? targetingKey);
return targetingKey?.AsString;
}
}

/// <summary>
/// Return an enumerator for all values
Expand Down
23 changes: 2 additions & 21 deletions src/OpenFeature/Model/EvaluationContextBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ public sealed class EvaluationContextBuilder
{
private readonly StructureBuilder _attributes = Structure.Builder();

internal string? TargetingKey { get; private set; }

/// <summary>
/// Internal to only allow direct creation by <see cref="EvaluationContext.Builder()"/>.
/// </summary>
Expand All @@ -28,7 +26,7 @@ internal EvaluationContextBuilder() { }
/// <returns>This builder</returns>
public EvaluationContextBuilder SetTargetingKey(string targetingKey)
{
this.TargetingKey = targetingKey;
this._attributes.Set(EvaluationContext.TargetingKeyIndex, targetingKey);
return this;
}

Expand Down Expand Up @@ -138,23 +136,6 @@ public EvaluationContextBuilder Set(string key, DateTime value)
/// <returns>This builder</returns>
public EvaluationContextBuilder Merge(EvaluationContext context)
{
string? newTargetingKey = "";

if (!string.IsNullOrWhiteSpace(this.TargetingKey))
{
newTargetingKey = this.TargetingKey;
}

if (!string.IsNullOrWhiteSpace(context.TargetingKey))
{
newTargetingKey = context.TargetingKey;
}

if (!string.IsNullOrWhiteSpace(newTargetingKey))
{
this.TargetingKey = newTargetingKey;
}

foreach (var kvp in context)
{
this.Set(kvp.Key, kvp.Value);
Expand All @@ -169,7 +150,7 @@ public EvaluationContextBuilder Merge(EvaluationContext context)
/// <returns>An immutable <see cref="EvaluationContext"/></returns>
public EvaluationContext Build()
{
return new EvaluationContext(this.TargetingKey, this._attributes.Build());
return new EvaluationContext(this._attributes.Build());
}
}
}
2 changes: 1 addition & 1 deletion src/OpenFeature/OpenFeature.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0;net462</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net8.0;net462</TargetFrameworks>
<RootNamespace>OpenFeature</RootNamespace>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion test/OpenFeature.Benchmarks/OpenFeature.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<RootNamespace>OpenFeature.Benchmark</RootNamespace>
<OutputType>Exe</OutputType>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion test/OpenFeature.E2ETests/OpenFeature.E2ETests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks Condition="$(OS) == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<RootNamespace>OpenFeature.E2ETests</RootNamespace>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion test/OpenFeature.Tests/OpenFeature.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks Condition="$(OS) == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<RootNamespace>OpenFeature.Tests</RootNamespace>
</PropertyGroup>
Expand Down
24 changes: 24 additions & 0 deletions test/OpenFeature.Tests/OpenFeatureClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
Expand All @@ -11,6 +12,7 @@
using NSubstitute.ExceptionExtensions;
using OpenFeature.Constant;
using OpenFeature.Error;
using OpenFeature.Extension;
using OpenFeature.Model;
using OpenFeature.Tests.Internal;
using Xunit;
Expand Down Expand Up @@ -480,5 +482,27 @@ public void Should_Get_And_Set_Context()
client.SetContext(new EvaluationContextBuilder().Set(KEY, VAL).Build());
Assert.Equal(VAL, client.GetContext().GetValue(KEY).AsInteger);
}


[Fact]
public void ToFlagEvaluationDetails_Should_Convert_All_Properties()
{
var fixture = new Fixture();
var flagName = fixture.Create<string>();
var boolValue = fixture.Create<bool>();
var errorType = fixture.Create<ErrorType>();
var reason = fixture.Create<string>();
var variant = fixture.Create<string>();
var errorMessage = fixture.Create<string>();
var flagData = fixture
.CreateMany<KeyValuePair<string, object>>(10)
.ToDictionary(x => x.Key, x => x.Value);
var flagMetadata = new ImmutableMetadata(flagData);

var expected = new ResolutionDetails<bool>(flagName, boolValue, errorType, reason, variant, errorMessage, flagMetadata);
var result = expected.ToFlagEvaluationDetails();

result.Should().BeEquivalentTo(expected);
}
}
}
52 changes: 51 additions & 1 deletion test/OpenFeature.Tests/OpenFeatureEvaluationContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void TryGetValue_WhenCalledWithExistingKey_ReturnsTrueAndExpectedValue()
var key = "testKey";
var expectedValue = new Value("testValue");
var structure = new Structure(new Dictionary<string, Value> { { key, expectedValue } });
var evaluationContext = new EvaluationContext("targetingKey", structure);
var evaluationContext = new EvaluationContext(structure);

// Act
var result = evaluationContext.TryGetValue(key, out var actualValue);
Expand All @@ -169,5 +169,55 @@ public void TryGetValue_WhenCalledWithExistingKey_ReturnsTrueAndExpectedValue()
Assert.True(result);
Assert.Equal(expectedValue, actualValue);
}

[Fact]
public void GetValueOnTargetingKeySetWithTargetingKey_Equals_TargetingKey()
{
// Arrange
var value = "my_targeting_key";
var evaluationContext = EvaluationContext.Builder().SetTargetingKey(value).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Equal(value, actualFromStructure?.AsString);
Assert.Equal(value, actualFromTargetingKey);
}

[Fact]
public void GetValueOnTargetingKeySetWithStructure_Equals_TargetingKey()
{
// Arrange
var value = "my_targeting_key";
var evaluationContext = EvaluationContext.Builder().Set(EvaluationContext.TargetingKeyIndex, new Value(value)).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Equal(value, actualFromStructure?.AsString);
Assert.Equal(value, actualFromTargetingKey);
}

[Fact]
public void GetValueOnTargetingKeySetWithNonStringValue_Equals_Null()
{
// Arrange
var evaluationContext = EvaluationContext.Builder().Set(EvaluationContext.TargetingKeyIndex, new Value(1)).Build();

// Act
var result = evaluationContext.TryGetValue(EvaluationContext.TargetingKeyIndex, out var actualFromStructure);
var actualFromTargetingKey = evaluationContext.TargetingKey;

// Assert
Assert.True(result);
Assert.Null(actualFromStructure?.AsString);
Assert.Null(actualFromTargetingKey);
}
}
}

0 comments on commit 0b6ee68

Please sign in to comment.