Skip to content

Commit d026153

Browse files
authored
Merge pull request #82 from tghamm/feature/housekeeping
Testing Improvements
2 parents 56b041c + 35d0bbb commit d026153

22 files changed

+877
-348
lines changed

.travis.yml

Lines changed: 0 additions & 8 deletions
This file was deleted.

Castle.DynamicLinqQueryBuilder.SystemTextJson/Castle.DynamicLinqQueryBuilder.SystemTextJson.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212
<FileAlignment>512</FileAlignment>
1313
<TargetFrameworkProfile />
1414
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
15-
<Version>1.2.3</Version>
15+
<Version>1.2.4</Version>
1616
<Authors>Grant Hamm</Authors>
1717
<Company>N/A</Company>
1818
<Product>Dynamic Linq Query Builder - System.Text.Json Extension</Product>
1919
<Description>A companion package for those using System.Text.Json</Description>
20-
<Copyright>Copyright Grant Hamm 2021</Copyright>
21-
<PackageLicenseUrl></PackageLicenseUrl>
20+
<Copyright>Copyright Grant Hamm 2022</Copyright>
21+
<PackageLicenseUrl>https://github.com/tghamm/dynamic-linq-query-builder/blob/master/LICENSE.md</PackageLicenseUrl>
2222
<PackageProjectUrl>https://github.com/tghamm/dynamic-linq-query-builder/</PackageProjectUrl>
2323
<RepositoryUrl>https://github.com/tghamm/dynamic-linq-query-builder/</RepositoryUrl>
2424
<RepositoryType>Git</RepositoryType>
2525
<PackageTags>jquery-query-builder generic query generator linq javascript</PackageTags>
26-
<PackageReleaseNotes>Adds support for custom operator functions, improves SQL performance.</PackageReleaseNotes>
26+
<PackageReleaseNotes>Adds support for GUID type.</PackageReleaseNotes>
2727
<LangVersion>latest</LangVersion>
2828
</PropertyGroup>
2929

Castle.DynamicLinqQueryBuilder.SystemTextJson/SystemTextJsonFilterRule.cs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34

45

56
namespace Castle.DynamicLinqQueryBuilder.SystemTextJson
@@ -77,23 +78,28 @@ public object Value
7778

7879
try
7980
{
80-
IEnumerable<JsonElement> array = jsonValue.EnumerateArray();
81+
if (jsonValue.ValueKind == JsonValueKind.Array)
82+
{
83+
var outList = Array.CreateInstance(myType, jsonValue.GetArrayLength());
84+
var enumerator = 0;
8185

82-
var outList = Array.CreateInstance(myType, jsonValue.GetArrayLength());
83-
var enumerator = 0;
86+
foreach (var item in jsonValue.EnumerateArray())
87+
{
88+
object typedItem = GetJsonElementAsType(item);
89+
outList.SetValue(typedItem, enumerator);
90+
enumerator++;
91+
}
8492

85-
foreach (var item in jsonValue.EnumerateArray())
93+
return outList;
94+
}
95+
else
8696
{
87-
object typedItem = GetJsonElementAsType(item);
88-
outList.SetValue(typedItem, enumerator);
89-
enumerator++;
97+
return GetJsonElementAsType(jsonValue);
9098
}
91-
92-
return outList;
9399
}
94100
catch (Exception ex)
95101
{
96-
102+
throw new InvalidCastException("Error converting JsonElement to .Net Type", ex);
97103
}
98104
}
99105

@@ -111,30 +117,37 @@ public object Value
111117

112118
private object GetJsonElementAsType(JsonElement element)
113119
{
120+
Object o = null;
114121
switch (this.Type)
115122
{
116123
case "integer":
117-
return Int32.Parse(element.GetString());
124+
o = element.ValueKind == JsonValueKind.Number
125+
? element.GetInt32()
126+
: Int32.Parse(element.GetString());
118127
break;
119128
case "double":
120-
return element.GetDouble();
129+
o = element.ValueKind == JsonValueKind.Number
130+
? element.GetDouble()
131+
: double.Parse(element.ToString());
121132
break;
122133
case "string":
123-
return element.ToString();
134+
o = element.ToString();
124135
break;
125136
case "date":
126137
case "datetime":
127-
return DateTime.Parse(element.GetString());
138+
o = DateTime.Parse(element.GetString(), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
128139
break;
129140
case "boolean":
130-
return element.GetBoolean();
141+
o = ((element.ValueKind == JsonValueKind.True) || (element.ValueKind == JsonValueKind.False))
142+
? element.GetBoolean()
143+
: bool.Parse(element.ToString());
131144
break;
132145
case "guid":
133-
return element.GetGuid();
146+
o = element.GetGuid();
134147
break;
135-
default:
136-
throw new Exception($"Unexpected data type {this.Type}");
137148
}
149+
150+
return o;
138151
}
139152
}
140153
}

Castle.DynamicLinqQueryBuilder.Tests.sln

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 25 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,32 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<Import Project="..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" />
4-
<Import Project="..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" />
5-
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
63
<PropertyGroup>
7-
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
8-
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
9-
<ProjectGuid>{AA125B72-F684-4DF0-803D-7CE45C0B915F}</ProjectGuid>
10-
<OutputType>Library</OutputType>
11-
<AppDesignerFolder>Properties</AppDesignerFolder>
12-
<RootNamespace>Castle.DynamicLinqQueryBuilder.Tests</RootNamespace>
13-
<AssemblyName>Castle.DynamicLinqQueryBuilder.Tests</AssemblyName>
14-
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
15-
<FileAlignment>512</FileAlignment>
16-
<NuGetPackageImportStamp>
17-
</NuGetPackageImportStamp>
18-
</PropertyGroup>
19-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
20-
<DebugSymbols>true</DebugSymbols>
21-
<DebugType>full</DebugType>
22-
<Optimize>false</Optimize>
23-
<OutputPath>bin\Debug\</OutputPath>
24-
<DefineConstants>DEBUG;TRACE</DefineConstants>
25-
<ErrorReport>prompt</ErrorReport>
26-
<WarningLevel>4</WarningLevel>
27-
<LangVersion>latest</LangVersion>
28-
</PropertyGroup>
29-
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
30-
<DebugType>pdbonly</DebugType>
31-
<Optimize>true</Optimize>
32-
<OutputPath>bin\Release\</OutputPath>
33-
<DefineConstants>TRACE</DefineConstants>
34-
<ErrorReport>prompt</ErrorReport>
35-
<WarningLevel>4</WarningLevel>
4+
<TargetFramework>net6.0</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
368
<LangVersion>latest</LangVersion>
379
</PropertyGroup>
10+
3811
<ItemGroup>
39-
<Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
40-
<HintPath>..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
41-
</Reference>
42-
<Reference Include="System" />
43-
<Reference Include="System.Core" />
44-
<Reference Include="System.Runtime.Serialization" />
45-
<Reference Include="System.Xml.Linq" />
46-
<Reference Include="System.Data.DataSetExtensions" />
47-
<Reference Include="Microsoft.CSharp" />
48-
<Reference Include="System.Data" />
49-
<Reference Include="System.Net.Http" />
50-
<Reference Include="System.Xml" />
51-
</ItemGroup>
52-
<ItemGroup>
53-
<Compile Include="CustomOperatorsTests.cs" />
54-
<Compile Include="ExceptionAssert.cs" />
55-
<Compile Include="JsonNetFilterRuleTests.cs" />
56-
<Compile Include="QueryBuilderFilterRuleTests.cs" />
57-
<Compile Include="Tests.cs" />
58-
<Compile Include="Properties\AssemblyInfo.cs" />
59-
</ItemGroup>
60-
<ItemGroup>
61-
<None Include="packages.config" />
62-
</ItemGroup>
63-
<ItemGroup>
64-
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
12+
<PackageReference Include="altcover" Version="8.2.835" />
13+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" />
14+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.2">
15+
<PrivateAssets>all</PrivateAssets>
16+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
17+
</PackageReference>
18+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.2" />
19+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2">
20+
<PrivateAssets>all</PrivateAssets>
21+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
22+
</PackageReference>
23+
<PackageReference Include="NUnit" Version="3.12.0" />
24+
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
25+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
6526
</ItemGroup>
27+
6628
<ItemGroup>
67-
<ProjectReference Include="..\Castle.DynamicLinqQueryBuilder\Castle.DynamicLinqQueryBuilder.csproj">
68-
<Project>{c73ea60c-7046-4665-8a79-0e2aa85c43ec}</Project>
69-
<Name>Castle.DynamicLinqQueryBuilder</Name>
70-
</ProjectReference>
29+
<ProjectReference Include="..\Castle.DynamicLinqQueryBuilder.SystemTextJson\Castle.DynamicLinqQueryBuilder.SystemTextJson.csproj" />
7130
</ItemGroup>
72-
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
73-
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
74-
<PropertyGroup>
75-
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
76-
</PropertyGroup>
77-
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.12.0\build\net35\NUnit3TestAdapter.props'))" />
78-
<Error Condition="!Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.11.0\build\NUnit.props'))" />
79-
</Target>
80-
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
81-
Other similar extension points exist, see Microsoft.Common.targets.
82-
<Target Name="BeforeBuild">
83-
</Target>
84-
<Target Name="AfterBuild">
85-
</Target>
86-
-->
87-
</Project>
31+
32+
</Project>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics.CodeAnalysis;
4+
using System.Linq;
5+
using System.Linq.Expressions;
6+
using Castle.DynamicLinqQueryBuilder.Tests.Helpers;
7+
using NUnit.Framework;
8+
9+
namespace Castle.DynamicLinqQueryBuilder.Tests.CustomOperators
10+
{
11+
public class MyRecord {
12+
public string UserHostAddress { get; set; }
13+
}
14+
15+
public class InIpRangeOperator : IFilterOperator
16+
{
17+
public string Operator => "in_ip_range";
18+
19+
public Expression GetExpression(Type type, IFilterRule rule, Expression propertyExp, BuildExpressionOptions options)
20+
{
21+
22+
return Expression.Call(this.GetType().GetMethod("ContainsIP"), new[] { propertyExp, Expression.Constant(rule.Value) });
23+
24+
}
25+
public static bool ContainsIP(string ip, string[] ranges) {
26+
return true; //TODO: implement custom ip range validation
27+
}
28+
}
29+
30+
[ExcludeFromCodeCoverage]
31+
[TestFixture]
32+
public class CustomOperatorsTests
33+
{
34+
[Test]
35+
public void CustomInOperator_Test() {
36+
var rec = new MyRecord();
37+
38+
rec.UserHostAddress = "8.10.8.13";
39+
40+
var records = new List<MyRecord>() { rec };
41+
42+
var myFilter = new QueryBuilderFilterRule()
43+
{
44+
Condition = "and",
45+
Rules = new List<QueryBuilderFilterRule>()
46+
{
47+
new QueryBuilderFilterRule()
48+
{
49+
Condition = "and",
50+
Field = "UserHostAddress",
51+
Operator = "in_ip_range",
52+
Type = "string",
53+
Value = new [] { "10.10.10.*" }
54+
}
55+
}
56+
};
57+
var options = new BuildExpressionOptions();
58+
options.Operators = new List<IFilterOperator>() { new InIpRangeOperator()};
59+
var result = records.AsQueryable().BuildQuery<MyRecord>(myFilter, options).ToList();
60+
var len = result.Count;
61+
Assert.AreEqual(1, len);
62+
}
63+
64+
[Test]
65+
public void UnknownOperator_Test1()
66+
{
67+
var rec = new MyRecord();
68+
69+
rec.UserHostAddress = "8.10.8.13";
70+
71+
var records = new List<MyRecord>() { rec };
72+
73+
var myFilter = new QueryBuilderFilterRule()
74+
{
75+
Condition = "and",
76+
Rules = new List<QueryBuilderFilterRule>()
77+
{
78+
new QueryBuilderFilterRule()
79+
{
80+
Condition = "and",
81+
Field = "UserHostAddress",
82+
Operator = "in_ip_range",
83+
Type = "string",
84+
Value = new [] { "10.10.10.*" }
85+
}
86+
}
87+
};
88+
89+
ExceptionAssert.Throws<Exception>(() =>
90+
{
91+
var result = records.AsQueryable().BuildQuery<MyRecord>(myFilter).ToList();
92+
});
93+
}
94+
95+
[Test]
96+
public void UnknownOperator_Test2()
97+
{
98+
var rec = new MyRecord();
99+
100+
rec.UserHostAddress = "8.10.8.13";
101+
102+
var records = new List<MyRecord>() { rec };
103+
104+
var myFilter = new QueryBuilderFilterRule()
105+
{
106+
Condition = "and",
107+
Rules = new List<QueryBuilderFilterRule>()
108+
{
109+
new QueryBuilderFilterRule()
110+
{
111+
Condition = "and",
112+
Field = "UserHostAddress",
113+
Operator = "in_ip_range_spelledwrong",
114+
Type = "string",
115+
Value = new [] { "10.10.10.*" }
116+
}
117+
}
118+
};
119+
var options = new BuildExpressionOptions();
120+
options.Operators = new List<IFilterOperator>() { new InIpRangeOperator() };
121+
ExceptionAssert.Throws<Exception>(() =>
122+
{
123+
var result = records.AsQueryable().BuildQuery<MyRecord>(myFilter, options).ToList();
124+
});
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)