mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-02-04 05:35:44 +00:00
2527 lines
102 KiB
C#
2527 lines
102 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Xunit;
|
|
using Radzen;
|
|
|
|
namespace Radzen.Blazor.Tests
|
|
{
|
|
public class QueryableExtensionTests
|
|
{
|
|
private class TestItem
|
|
{
|
|
public int Id { get; set; }
|
|
public string Name { get; set; }
|
|
public int Value { get; set; }
|
|
public DateTime Date { get; set; }
|
|
public bool IsActive { get; set; }
|
|
public TestCategory Category { get; set; }
|
|
}
|
|
|
|
private class TestCategory
|
|
{
|
|
public string Name { get; set; }
|
|
public int Priority { get; set; }
|
|
}
|
|
|
|
private List<TestItem> GetTestData()
|
|
{
|
|
return new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "Alice", Value = 100, Date = new DateTime(2023, 1, 1), IsActive = true, Category = new TestCategory { Name = "A", Priority = 1 } },
|
|
new TestItem { Id = 2, Name = "Bob", Value = 200, Date = new DateTime(2023, 6, 1), IsActive = false, Category = new TestCategory { Name = "B", Priority = 2 } },
|
|
new TestItem { Id = 3, Name = "Charlie", Value = 150, Date = new DateTime(2023, 12, 1), IsActive = true, Category = new TestCategory { Name = "A", Priority = 1 } },
|
|
new TestItem { Id = 4, Name = "David", Value = 300, Date = new DateTime(2023, 3, 1), IsActive = false, Category = new TestCategory { Name = "C", Priority = 3 } },
|
|
new TestItem { Id = 5, Name = "Eve", Value = 250, Date = new DateTime(2023, 9, 1), IsActive = true, Category = new TestCategory { Name = "B", Priority = 2 } }
|
|
};
|
|
}
|
|
|
|
// OrderBy tests
|
|
[Fact]
|
|
public void OrderBy_SortsAscending_ByDefault()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.OrderBy("Value").ToList();
|
|
|
|
Assert.Equal(100, result[0].Value);
|
|
Assert.Equal(150, result[1].Value);
|
|
Assert.Equal(200, result[2].Value);
|
|
Assert.Equal(250, result[3].Value);
|
|
Assert.Equal(300, result[4].Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void OrderBy_SortsDescending_WhenSpecified()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.OrderBy("Value desc").ToList();
|
|
|
|
Assert.Equal(300, result[0].Value);
|
|
Assert.Equal(250, result[1].Value);
|
|
Assert.Equal(200, result[2].Value);
|
|
Assert.Equal(150, result[3].Value);
|
|
Assert.Equal(100, result[4].Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void OrderBy_HandlesMultipleProperties()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.OrderBy("Category.Priority, Value desc").ToList();
|
|
|
|
Assert.Equal(1, result[0].Category.Priority);
|
|
Assert.Equal(150, result[0].Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void OrderBy_HandlesNestedProperties()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.OrderBy("Category.Name").ToList();
|
|
|
|
Assert.Equal("A", result[0].Category.Name);
|
|
Assert.Equal("A", result[1].Category.Name);
|
|
Assert.Equal("B", result[2].Category.Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void OrderBy_HandlesLambdaExpression()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.OrderBy("x => x.Value").ToList();
|
|
|
|
Assert.Equal(100, result[0].Value);
|
|
Assert.Equal(150, result[1].Value);
|
|
}
|
|
|
|
// Where tests with FilterDescriptor
|
|
[Fact]
|
|
public void Where_FiltersWithEquals()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "Alice", FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithNotEquals()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "Alice", FilterOperator = FilterOperator.NotEquals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(4, result.Count);
|
|
Assert.DoesNotContain(result, r => r.Name == "Alice");
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContains()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "li", FilterOperator = FilterOperator.Contains }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Collection(result,
|
|
r => Assert.Equal("Alice", r.Name),
|
|
r => Assert.Equal("Charlie", r.Name));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithStartsWith()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "Al", FilterOperator = FilterOperator.StartsWith }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithEndsWith()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "ice", FilterOperator = FilterOperator.EndsWith }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithLessThan()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 200, FilterOperator = FilterOperator.LessThan }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value < 200));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithLessThanOrEquals()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 200, FilterOperator = FilterOperator.LessThanOrEquals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value <= 200));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithGreaterThan()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 200, FilterOperator = FilterOperator.GreaterThan }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value > 200));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithGreaterThanOrEquals()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 200, FilterOperator = FilterOperator.GreaterThanOrEquals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value >= 200));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithIsNull()
|
|
{
|
|
var data = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = null },
|
|
new TestItem { Id = 2, Name = "Test" }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterOperator = FilterOperator.IsNull }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Null(result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithIsNotNull()
|
|
{
|
|
var data = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = null },
|
|
new TestItem { Id = 2, Name = "Test" }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterOperator = FilterOperator.IsNotNull }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.NotNull(result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithIsEmpty()
|
|
{
|
|
var data = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "" },
|
|
new TestItem { Id = 2, Name = "Test" }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterOperator = FilterOperator.IsEmpty }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(string.Empty, result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithIsNotEmpty()
|
|
{
|
|
var data = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "" },
|
|
new TestItem { Id = 2, Name = "Test" }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterOperator = FilterOperator.IsNotEmpty }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Test", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_CombinesFiltersWithAnd()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 150, FilterOperator = FilterOperator.GreaterThan },
|
|
new FilterDescriptor { Property = "IsActive", FilterValue = true, FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(1, result.Count);
|
|
Assert.Equal("Eve", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_CombinesFiltersWithOr()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Value", FilterValue = 100, FilterOperator = FilterOperator.Equals },
|
|
new FilterDescriptor { Property = "Value", FilterValue = 300, FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.Or, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Value == 100);
|
|
Assert.Contains(result, r => r.Value == 300);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_RespectsCaseInsensitivity()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Name", FilterValue = "alice", FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.CaseInsensitive).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_ReturnsAllWhenNoFilters()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>();
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(5, result.Count);
|
|
}
|
|
|
|
// Aggregate function tests
|
|
[Fact]
|
|
public void Sum_CalculatesCorrectly()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var values = data.Select("Value");
|
|
|
|
var result = values.Sum(typeof(int));
|
|
|
|
Assert.Equal(1000, result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Average_CalculatesCorrectly()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.Select(x => x.Value).Average();
|
|
|
|
Assert.Equal(200, result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Min_ReturnsCorrectValue()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.Select(x => x.Value).Min();
|
|
|
|
Assert.Equal(100, result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Max_ReturnsCorrectValue()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.Select(x => x.Value).Max();
|
|
|
|
Assert.Equal(300, result);
|
|
}
|
|
|
|
// FirstOrDefault and LastOrDefault tests
|
|
[Fact]
|
|
public void FirstOrDefault_ReturnsFirstElement()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.FirstOrDefault();
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(1, result.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void FirstOrDefault_ReturnsNullWhenEmpty()
|
|
{
|
|
var data = new List<TestItem>().AsQueryable();
|
|
|
|
var result = data.FirstOrDefault();
|
|
|
|
Assert.Null(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void LastOrDefault_ReturnsLastElement()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.LastOrDefault();
|
|
|
|
Assert.NotNull(result);
|
|
Assert.Equal(5, result.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void LastOrDefault_ReturnsNullWhenEmpty()
|
|
{
|
|
var data = new List<TestItem>().AsQueryable();
|
|
|
|
var result = data.LastOrDefault();
|
|
|
|
Assert.Null(result);
|
|
}
|
|
|
|
// Select tests
|
|
[Fact]
|
|
public void Select_ProjectsProperty()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.Select("Name");
|
|
|
|
Assert.Equal(5, result.Cast<string>().ToList().Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void Select_ProjectsNestedProperty()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = data.Select("Category.Name");
|
|
|
|
Assert.Equal(5, result.Cast<string>().ToList().Count);
|
|
}
|
|
|
|
// Distinct tests
|
|
[Fact]
|
|
public void Distinct_RemovesDuplicates()
|
|
{
|
|
var data = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "Test" },
|
|
new TestItem { Id = 2, Name = "Test" },
|
|
new TestItem { Id = 3, Name = "Other" }
|
|
}.AsQueryable();
|
|
|
|
var names = data.Select("Name");
|
|
var result = names.Distinct();
|
|
|
|
Assert.True(QueryableExtension.ToList(result).Count == 2);
|
|
}
|
|
|
|
// Cast tests
|
|
[Fact]
|
|
public void Cast_ConvertsType()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var values = data.Select("Value");
|
|
|
|
var result = values.Cast(typeof(int));
|
|
|
|
Assert.IsAssignableFrom<IQueryable<int>>(result);
|
|
}
|
|
|
|
// ToList tests
|
|
[Fact]
|
|
public void ToList_ConvertsQueryableToList()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
|
|
var result = QueryableExtension.ToList(data);
|
|
|
|
Assert.IsType<List<TestItem>>(result);
|
|
Assert.Equal(5, result.Count);
|
|
}
|
|
|
|
// IsEnumerable tests
|
|
[Fact]
|
|
public void IsEnumerable_ReturnsTrueForList()
|
|
{
|
|
Assert.True(QueryableExtension.IsEnumerable(typeof(List<int>)));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsEnumerable_ReturnsTrueForArray()
|
|
{
|
|
Assert.True(QueryableExtension.IsEnumerable(typeof(int[])));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsEnumerable_ReturnsFalseForString()
|
|
{
|
|
Assert.False(QueryableExtension.IsEnumerable(typeof(string)));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsEnumerable_ReturnsFalseForInt()
|
|
{
|
|
Assert.False(QueryableExtension.IsEnumerable(typeof(int)));
|
|
}
|
|
|
|
// Complex filtering scenarios
|
|
[Fact]
|
|
public void Where_HandlesNestedPropertyFiltering()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Category.Name", FilterValue = "A", FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.Equal("A", r.Category.Name));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_HandlesDateTimeFiltering()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "Date", FilterValue = new DateTime(2023, 6, 1), FilterOperator = FilterOperator.GreaterThan }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Date > new DateTime(2023, 6, 1)));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_HandlesBooleanFiltering()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor { Property = "IsActive", FilterValue = true, FilterOperator = FilterOperator.Equals }
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.All(result, r => Assert.True(r.IsActive));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_HandlesSecondFilterWithAnd()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = 100,
|
|
FilterOperator = FilterOperator.GreaterThan,
|
|
SecondFilterValue = 300,
|
|
SecondFilterOperator = FilterOperator.LessThan,
|
|
LogicalFilterOperator = LogicalFilterOperator.And
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value > 100 && r.Value < 300));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_HandlesSecondFilterWithOr()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = 150,
|
|
FilterOperator = FilterOperator.LessThan,
|
|
SecondFilterValue = 250,
|
|
SecondFilterOperator = FilterOperator.GreaterThan,
|
|
LogicalFilterOperator = LogicalFilterOperator.Or
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Values less than 150 (100) OR greater than 250 (300) = 2 records
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value < 150 || r.Value > 250));
|
|
}
|
|
|
|
// Collection operator tests - In/NotIn
|
|
[Fact]
|
|
public void Where_SupportsInOperator_WithStringArray()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = new[] { "Alice", "Bob" },
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Name == "Alice");
|
|
Assert.Contains(result, r => r.Name == "Bob");
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_SupportsDoesNotContainOperator_WithStringArray()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = new[] { "Alice", "Bob" },
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.DoesNotContain(result, r => r.Name == "Alice");
|
|
Assert.DoesNotContain(result, r => r.Name == "Bob");
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_SupportsInOperator_WithNumericValues()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = new[] { 100, 200, 300 },
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.All(result, r => Assert.True(r.Value == 100 || r.Value == 200 || r.Value == 300));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithDoesNotContainOperator()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "li",
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
Assert.DoesNotContain(result, r => r.Name == "Alice");
|
|
Assert.DoesNotContain(result, r => r.Name == "Charlie");
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContainsOperator_EmptyString()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Empty string contains returns all items (all strings contain empty string)
|
|
Assert.Equal(5, result.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContainsOperator_SingleValue()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = new[] { "Alice" },
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithDoesNotContainOperator_AllValues()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var allNames = data.Select(x => x.Name).ToArray();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = allNames,
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Empty(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersArrayProperty_WithSpecificValue()
|
|
{
|
|
var testData = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "Item1", Value = 100, Date = DateTime.Now, IsActive = true, Category = new TestCategory { Name = "A", Priority = 1 } },
|
|
new TestItem { Id = 2, Name = "Item2", Value = 200, Date = DateTime.Now, IsActive = false, Category = new TestCategory { Name = "B", Priority = 2 } },
|
|
new TestItem { Id = 3, Name = "Item3", Value = 300, Date = DateTime.Now, IsActive = true, Category = new TestCategory { Name = "C", Priority = 3 } }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "Item1",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(1, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersArrayProperty_WithDoesNotContain()
|
|
{
|
|
var testData = new List<TestItem>
|
|
{
|
|
new TestItem { Id = 1, Name = "Item1", Value = 100, Date = DateTime.Now, IsActive = true, Category = new TestCategory { Name = "A", Priority = 1 } },
|
|
new TestItem { Id = 2, Name = "Item2", Value = 200, Date = DateTime.Now, IsActive = false, Category = new TestCategory { Name = "B", Priority = 2 } },
|
|
new TestItem { Id = 3, Name = "Item3", Value = 300, Date = DateTime.Now, IsActive = true, Category = new TestCategory { Name = "C", Priority = 3 } }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "Item1",
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.DoesNotContain(result, r => r.Name == "Item1");
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContainsOperator_CaseInsensitive()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "ALICE",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.CaseInsensitive).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal("Alice", result[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithMultipleContainsOperators_Combined()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = new[] { "Alice", "Bob" },
|
|
FilterOperator = FilterOperator.Contains
|
|
},
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = 100,
|
|
FilterOperator = FilterOperator.GreaterThanOrEquals
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.All(result, r => Assert.True((r.Name == "Alice" || r.Name == "Bob") && r.Value >= 100));
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContains_OnMultipleProperties()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = new[] { "Alice", "Charlie" },
|
|
FilterOperator = FilterOperator.Contains
|
|
},
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = new[] { 100, 150 },
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Name == "Alice" && r.Value == 100);
|
|
Assert.Contains(result, r => r.Name == "Charlie" && r.Value == 150);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersWithContainsOperator_MultipleValues()
|
|
{
|
|
var data = GetTestData().AsQueryable();
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Value",
|
|
FilterValue = new[] { 100, 150, 200 },
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = data.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(3, result.Count);
|
|
}
|
|
|
|
// Property/FilterProperty tests for collection item filtering
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag5", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "tag1",
|
|
FilterOperator = FilterOperator.Equals
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithContains()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "important", Value = 10 }, new { Name = "urgent", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "normal", Value = 30 }, new { Name = "low", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "important", Value = 50 }, new { Name = "high", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "import",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithStartsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag_alpha", Value = 10 }, new { Name = "tag_beta", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "item_gamma", Value = 30 }, new { Name = "item_delta", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag_epsilon", Value = 50 }, new { Name = "other", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "tag_",
|
|
FilterOperator = FilterOperator.StartsWith
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithEndsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "file.txt", Value = 10 }, new { Name = "doc.pdf", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "image.png", Value = 30 }, new { Name = "photo.jpg", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "data.txt", Value = 50 }, new { Name = "info.doc", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = ".txt",
|
|
FilterOperator = FilterOperator.EndsWith
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithNotEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "active", Value = 10 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "inactive", Value = 20 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "pending", Value = 30 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "inactive",
|
|
FilterOperator = FilterOperator.NotEquals
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithDoesNotContain()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "important-task", Value = 10 }, new { Name = "important-note", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "simple", Value = 30 }, new { Name = "basic", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "important-meeting", Value = 50 }, new { Name = "review", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "important",
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_Numeric_WithGreaterThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 40,
|
|
FilterOperator = FilterOperator.GreaterThan
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(3, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_Numeric_WithLessThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 25,
|
|
FilterOperator = FilterOperator.LessThan
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(1, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_Numeric_WithGreaterThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 50,
|
|
FilterOperator = FilterOperator.GreaterThanOrEquals
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(3, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_Numeric_WithLessThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThanOrEquals
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(1, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithIsNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = (string)null, Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = (string)null, Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNull
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithIsNotNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = (string)null, Value = 10 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotNull
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_CaseInsensitive()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "IMPORTANT", Value = 10 }, new { Name = "urgent", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "normal", Value = 30 }, new { Name = "low", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "Important", Value = 50 }, new { Name = "high", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "important",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.CaseInsensitive).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_MultipleConditions_WithAnd()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 15 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag5", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThan,
|
|
SecondFilterValue = 10,
|
|
SecondFilterOperator = FilterOperator.GreaterThan,
|
|
LogicalFilterOperator = LogicalFilterOperator.And
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Only items with any tag Value < 20 AND any tag Value > 10
|
|
Assert.Single(result);
|
|
Assert.Equal(1, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_MultipleConditions_WithOr()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 70 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag5", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThan,
|
|
SecondFilterValue = 60,
|
|
SecondFilterOperator = FilterOperator.GreaterThan,
|
|
LogicalFilterOperator = LogicalFilterOperator.Or
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Items with tags where Value<20 OR Value>60
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithIsEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsEmpty
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithIsNotEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "", Value = 10 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotEmpty
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_CombinedWithRegularFilter()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Name = "Product1", Tags = new[] { new { Label = "premium", Price = 100 } }.ToList() },
|
|
new { Id = 2, Name = "Product2", Tags = new[] { new { Label = "standard", Price = 50 } }.ToList() },
|
|
new { Id = 3, Name = "Product3", Tags = new[] { new { Label = "premium", Price = 150 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Label",
|
|
FilterValue = "premium",
|
|
FilterOperator = FilterOperator.Equals
|
|
},
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Name",
|
|
FilterValue = "Product1",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(1, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersNestedCollectionItemProperty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new { Category = "A" } } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new { Category = "B" } } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new { Category = "A" } } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta.Category",
|
|
FilterValue = "A",
|
|
FilterOperator = FilterOperator.Equals
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersNestedCollectionItemProperty_WithIn()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new { Category = "A" } } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new { Category = "B" } } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new { Category = "C" } } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta.Category",
|
|
FilterValue = new[] { "A", "C" },
|
|
FilterOperator = FilterOperator.In
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersNestedCollectionItemProperty_WithNotIn()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new { Category = "A" } } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new { Category = "B" } } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new { Category = "C" } } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta.Category",
|
|
FilterValue = new[] { "A" },
|
|
FilterOperator = FilterOperator.NotIn
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersNestedCollectionItemProperty_WithContains()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new { Category = "Alpha" } } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new { Category = "Beta" } } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new { Category = "Alpine" } } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta.Category",
|
|
FilterValue = "Al",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersNestedCollectionItemProperty_WithDoesNotContain()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new { Category = "Entertainment" } } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new { Category = "Sports" } } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new { Category = "Edutainment" } } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta.Category",
|
|
FilterValue = "tain",
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Excludes categories containing "tain" -> Entertainment, Edutainment
|
|
Assert.Single(result);
|
|
Assert.Equal(2, result[0].Id);
|
|
}
|
|
|
|
// Nested collection (Items) with Meta also a collection. Use indexed access to Meta[0].Category
|
|
[Fact]
|
|
public void Where_FiltersDoubleNested_WithIn_OnFirstMeta()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new[] { new { Category = "A" }, new { Category = "X" } }.ToList() } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new[] { new { Category = "B" } }.ToList() } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new[] { new { Category = "C" } }.ToList() } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta[0].Category",
|
|
FilterValue = new[] { "A", "C" },
|
|
FilterOperator = FilterOperator.In
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersDoubleNested_WithNotIn_OnFirstMeta()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new[] { new { Category = "A" } }.ToList() } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new[] { new { Category = "B" } }.ToList() } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new[] { new { Category = "C" } }.ToList() } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta[0].Category",
|
|
FilterValue = new[] { "A" },
|
|
FilterOperator = FilterOperator.NotIn
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersDoubleNested_WithContains_OnFirstMeta()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new[] { new { Category = "Alpha" } }.ToList() } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new[] { new { Category = "Beta" } }.ToList() } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new[] { new { Category = "Alpine" } }.ToList() } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta[0].Category",
|
|
FilterValue = "Al",
|
|
FilterOperator = FilterOperator.Contains
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersDoubleNested_WithDoesNotContain_OnFirstMeta()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Items = new[] { new { Name = "item1", Meta = new[] { new { Category = "Entertainment" } }.ToList() } }.ToList() },
|
|
new { Id = 2, Items = new[] { new { Name = "item2", Meta = new[] { new { Category = "Sports" } }.ToList() } }.ToList() },
|
|
new { Id = 3, Items = new[] { new { Name = "item3", Meta = new[] { new { Category = "Edutainment" } }.ToList() } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Items",
|
|
FilterProperty = "Meta[0].Category",
|
|
FilterValue = "tain",
|
|
FilterOperator = FilterOperator.DoesNotContain
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
Assert.Single(result);
|
|
Assert.Equal(2, result[0].Id);
|
|
}
|
|
|
|
// CollectionFilterMode tests
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag5", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "tag1",
|
|
FilterOperator = FilterOperator.Equals,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has Name == "tag1"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "active", Value = 10 }, new { Name = "active", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "active", Value = 30 }, new { Name = "inactive", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "active", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "active",
|
|
FilterOperator = FilterOperator.Equals,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have Name == "active"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithGreaterThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 60 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 5 }, new { Name = "tag6", Value = 8 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 50,
|
|
FilterOperator = FilterOperator.GreaterThan,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has Value > 50
|
|
Assert.Single(result);
|
|
Assert.Equal(2, result[0].Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithGreaterThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 60 }, new { Name = "tag2", Value = 70 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 60 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 55 }, new { Name = "tag6", Value = 80 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 50,
|
|
FilterOperator = FilterOperator.GreaterThan,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have Value > 50
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithContains()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "important-task", Value = 10 }, new { Name = "review", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "normal", Value = 30 }, new { Name = "basic", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "important-meeting", Value = 50 }, new { Name = "urgent", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "important",
|
|
FilterOperator = FilterOperator.Contains,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag contains "important"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithContains()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "important-task", Value = 10 }, new { Name = "important-note", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "important-meeting", Value = 30 }, new { Name = "basic", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "important-reminder", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "important",
|
|
FilterOperator = FilterOperator.Contains,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags contain "important"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithStartsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "prefix_alpha", Value = 10 }, new { Name = "other_beta", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "prefix_gamma", Value = 30 }, new { Name = "prefix_delta", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "other_epsilon", Value = 50 }, new { Name = "other_zeta", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "prefix_",
|
|
FilterOperator = FilterOperator.StartsWith,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag starts with "prefix_"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithStartsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "prefix_alpha", Value = 10 }, new { Name = "prefix_beta", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "prefix_gamma", Value = 30 }, new { Name = "other_delta", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "prefix_epsilon", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "prefix_",
|
|
FilterOperator = FilterOperator.StartsWith,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags start with "prefix_"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithEndsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "file.txt", Value = 10 }, new { Name = "doc.pdf", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "image.png", Value = 30 }, new { Name = "photo.txt", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "data.csv", Value = 50 }, new { Name = "info.doc", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = ".txt",
|
|
FilterOperator = FilterOperator.EndsWith,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag ends with ".txt"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 2);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithEndsWith()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "file.txt", Value = 10 }, new { Name = "doc.txt", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "image.txt", Value = 30 }, new { Name = "photo.png", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "data.txt", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = ".txt",
|
|
FilterOperator = FilterOperator.EndsWith,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags end with ".txt"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithNotEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "active", Value = 10 }, new { Name = "inactive", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "inactive", Value = 30 }, new { Name = "inactive", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "pending", Value = 50 }, new { Name = "active", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "inactive",
|
|
FilterOperator = FilterOperator.NotEquals,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag is not equal to "inactive"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithNotEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "active", Value = 10 }, new { Name = "pending", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "active", Value = 30 }, new { Name = "inactive", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "pending", Value = 50 }, new { Name = "active", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "inactive",
|
|
FilterOperator = FilterOperator.NotEquals,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags are not equal to "inactive"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithDoesNotContain()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "test-alpha", Value = 10 }, new { Name = "beta", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "test-gamma", Value = 30 }, new { Name = "test-delta", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "epsilon", Value = 50 }, new { Name = "zeta", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "test",
|
|
FilterOperator = FilterOperator.DoesNotContain,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag does not contain "test"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithDoesNotContain()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "alpha", Value = 10 }, new { Name = "beta", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "test-gamma", Value = 30 }, new { Name = "delta", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "epsilon", Value = 50 }, new { Name = "zeta", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterValue = "test",
|
|
FilterOperator = FilterOperator.DoesNotContain,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags do not contain "test"
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithLessThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 50 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 60 }, new { Name = "tag4", Value = 70 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 15 }, new { Name = "tag6", Value = 80 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThan,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has Value < 20
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithLessThan()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 15 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 18 }, new { Name = "tag4", Value = 70 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 5 }, new { Name = "tag6", Value = 12 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThan,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have Value < 20
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithLessThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 20 }, new { Name = "tag2", Value = 50 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 60 }, new { Name = "tag4", Value = 70 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 15 }, new { Name = "tag6", Value = 80 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThanOrEquals,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has Value <= 20
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithLessThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 18 }, new { Name = "tag4", Value = 70 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 5 }, new { Name = "tag6", Value = 12 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 20,
|
|
FilterOperator = FilterOperator.LessThanOrEquals,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have Value <= 20
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithGreaterThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 10 }, new { Name = "tag4", Value = 15 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 60 }, new { Name = "tag6", Value = 30 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 50,
|
|
FilterOperator = FilterOperator.GreaterThanOrEquals,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has Value >= 50
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithGreaterThanOrEquals()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 50 }, new { Name = "tag2", Value = 60 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 55 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 70 }, new { Name = "tag6", Value = 80 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Value",
|
|
FilterValue = 50,
|
|
FilterOperator = FilterOperator.GreaterThanOrEquals,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have Value >= 50
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithIsNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = (string)null, Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = (string)null, Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNull,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has null Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithIsNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = (string)null, Value = 10 }, new { Name = (string)null, Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = (string)null, Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = (string)null, Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNull,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have null Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithIsNotNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = (string)null, Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = (string)null, Value = 30 }, new { Name = (string)null, Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotNull,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has non-null Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithIsNotNull()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = (string)null, Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotNull,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have non-null Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithIsEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsEmpty,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has empty Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithIsEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "", Value = 10 }, new { Name = "", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "", Value = 30 }, new { Name = "tag4", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsEmpty,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have empty Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_Any_WithIsNotEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "", Value = 30 }, new { Name = "", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 }, new { Name = "tag6", Value = 60 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotEmpty,
|
|
CollectionFilterMode = CollectionFilterMode.Any
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where at least one tag has non-empty Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Where_FiltersCollectionItemProperty_WithCollectionFilterMode_All_WithIsNotEmpty()
|
|
{
|
|
var testData = new[]
|
|
{
|
|
new { Id = 1, Tags = new[] { new { Name = "tag1", Value = 10 }, new { Name = "tag2", Value = 20 } }.ToList() },
|
|
new { Id = 2, Tags = new[] { new { Name = "tag3", Value = 30 }, new { Name = "", Value = 40 } }.ToList() },
|
|
new { Id = 3, Tags = new[] { new { Name = "tag5", Value = 50 } }.ToList() }
|
|
}.AsQueryable();
|
|
|
|
var filters = new List<FilterDescriptor>
|
|
{
|
|
new FilterDescriptor
|
|
{
|
|
Property = "Tags",
|
|
FilterProperty = "Name",
|
|
FilterOperator = FilterOperator.IsNotEmpty,
|
|
CollectionFilterMode = CollectionFilterMode.All
|
|
}
|
|
};
|
|
|
|
var result = testData.Where(filters, LogicalFilterOperator.And, FilterCaseSensitivity.Default).ToList();
|
|
|
|
// Should return items where all tags have non-empty Name
|
|
Assert.Equal(2, result.Count);
|
|
Assert.Contains(result, r => r.Id == 1);
|
|
Assert.Contains(result, r => r.Id == 3);
|
|
}
|
|
}
|
|
}
|
|
|