diff --git a/Build.ps1 b/Build.ps1 index 8717611..fab3228 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -3,8 +3,8 @@ echo "build: Build started" Push-Location $PSScriptRoot if(Test-Path .\artifacts) { - echo "build: Cleaning .\artifacts" - Remove-Item .\artifacts -Force -Recurse + echo "build: Cleaning ./artifacts" + Remove-Item ./artifacts -Force -Recurse } & dotnet restore --no-cache @@ -18,7 +18,7 @@ $buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($c echo "build: Package version suffix is $suffix" echo "build: Build version suffix is $buildSuffix" -foreach ($src in ls src/*) { +foreach ($src in gci src/*) { Push-Location $src echo "build: Packaging project in $src" @@ -26,16 +26,16 @@ foreach ($src in ls src/*) { & dotnet build -c Release --version-suffix=$buildSuffix if($suffix) { - & dotnet pack -c Release --include-source --no-build -o ..\..\artifacts --version-suffix=$suffix + & dotnet pack -c Release --include-source --no-build -o ../../artifacts --version-suffix=$suffix } else { - & dotnet pack -c Release --include-source --no-build -o ..\..\artifacts + & dotnet pack -c Release --include-source --no-build -o ../../artifacts } if($LASTEXITCODE -ne 0) { exit 1 } Pop-Location } -foreach ($test in ls test/*.Tests) { +foreach ($test in gci test/*.Tests) { Push-Location $test echo "build: Testing project in $test" diff --git a/appveyor.yml b/appveyor.yml index 449311f..b81b089 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,8 @@ version: '{build}' skip_tags: true -image: Visual Studio 2019 +image: Visual Studio 2022 build_script: -- ps: ./Build.ps1 +- pwsh: ./Build.ps1 artifacts: - path: artifacts/Serilog.*.nupkg deploy: diff --git a/src/Serilog.Expressions/Expressions/Runtime/RuntimeOperators.cs b/src/Serilog.Expressions/Expressions/Runtime/RuntimeOperators.cs index e2424b6..6dca9c0 100644 --- a/src/Serilog.Expressions/Expressions/Runtime/RuntimeOperators.cs +++ b/src/Serilog.Expressions/Expressions/Runtime/RuntimeOperators.cs @@ -374,6 +374,11 @@ public static LogEventPropertyValue IsDefined(LogEventPropertyValue? value) return ScalarBoolean(structure.Properties.Any(e => Coerce.IsTrue(pred(e.Value)))); } + if (items is DictionaryValue dictionary) + { + return ScalarBoolean(dictionary.Elements.Any(e => Coerce.IsTrue(pred(e.Value)))); + } + return null; } @@ -391,6 +396,11 @@ public static LogEventPropertyValue IsDefined(LogEventPropertyValue? value) { return ScalarBoolean(structure.Properties.All(e => Coerce.IsTrue(pred(e.Value)))); } + + if (items is DictionaryValue dictionary) + { + return ScalarBoolean(dictionary.Elements.All(e => Coerce.IsTrue(pred(e.Value)))); + } return null; } diff --git a/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv b/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv index 9e0d832..fd37807 100644 --- a/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv +++ b/test/Serilog.Expressions.Tests/Cases/expression-evaluation-cases.asv @@ -197,6 +197,18 @@ User.Name ⇶ 'nblumhardt' // Wildcards [1,2,3][?] > 2 ⇶ true [1,2,3][*] > 2 ⇶ false +{k:'test'}[?] = 'test' ⇶ true +{k:'test'}[?] like 'test' ⇶ true +{k:'test'}[?] like 'TEST' ⇶ false +{k:'test'}[?] like 'TEST' ci ⇶ true +{k:'test'}[?] like '%TES%' ci ⇶ true +{k:'test'}[?] = 'none' ⇶ false +test_dict({k:'test'})[?] = 'test' ⇶ true +test_dict({k:'test'})[?] like 'test' ⇶ true +test_dict({k:'test'})[?] like 'TEST' ⇶ false +test_dict({k:'test'})[?] like 'TEST' ci ⇶ true +test_dict({k:'test'})[?] like '%TES%' ci ⇶ true +test_dict({k:'test'})[?] = 'none' ⇶ false // Text and regex ismatch('foo', 'f') ⇶ true diff --git a/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs b/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs index 78cd943..bb2e21c 100644 --- a/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs +++ b/test/Serilog.Expressions.Tests/ExpressionEvaluationTests.cs @@ -27,8 +27,9 @@ public void ExpressionsAreCorrectlyEvaluated(string expr, string result) }))); var frFr = CultureInfo.GetCultureInfoByIetfLanguageTag("fr-FR"); - var actual = SerilogExpression.Compile(expr, formatProvider: frFr)(evt); - var expected = SerilogExpression.Compile(result)(evt); + var testHelpers = new TestHelperNameResolver(); + var actual = SerilogExpression.Compile(expr, formatProvider: frFr, testHelpers)(evt); + var expected = SerilogExpression.Compile(result, nameResolver: testHelpers)(evt); if (expected is null) { diff --git a/test/Serilog.Expressions.Tests/Serilog.Expressions.Tests.csproj b/test/Serilog.Expressions.Tests/Serilog.Expressions.Tests.csproj index bceeccc..2638af0 100644 --- a/test/Serilog.Expressions.Tests/Serilog.Expressions.Tests.csproj +++ b/test/Serilog.Expressions.Tests/Serilog.Expressions.Tests.csproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 true diff --git a/test/Serilog.Expressions.Tests/Support/TestHelperNameResolver.cs b/test/Serilog.Expressions.Tests/Support/TestHelperNameResolver.cs new file mode 100644 index 0000000..3887d61 --- /dev/null +++ b/test/Serilog.Expressions.Tests/Support/TestHelperNameResolver.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using Serilog.Events; + +namespace Serilog.Expressions.Tests.Support; + +public class TestHelperNameResolver: NameResolver +{ + public override bool TryResolveFunctionName(string name, [MaybeNullWhen(false)] out MethodInfo implementation) + { + if (name == "test_dict") + { + implementation = GetType().GetMethod(nameof(TestDict))!; + return true; + } + + implementation = null; + return false; + } + + public static LogEventPropertyValue? TestDict(LogEventPropertyValue? value) + { + if (value is not StructureValue sv) + return null; + + return new DictionaryValue(sv.Properties.Select(kv => + KeyValuePair.Create(new ScalarValue(kv.Name), kv.Value))); + } +}