diff --git a/src/BccCode.Linq/Server/Filter.cs b/src/BccCode.Linq/Server/Filter.cs index eb17eb7..f49bffe 100644 --- a/src/BccCode.Linq/Server/Filter.cs +++ b/src/BccCode.Linq/Server/Filter.cs @@ -112,10 +112,10 @@ private void _parse(string json) else if (new[] { "_in", "_nin" }.Contains(key)) { var array = JsonConvert.DeserializeObject(value.ToString() ?? string.Empty); - if (array is null || array.Length == 0) + if (array is null) { throw new ArgumentException( - $"JSON filter rule is invalid. Array under {key} is null or empty."); + $"JSON filter rule is invalid. Array under {key} is null."); } deserializedJson[key] = array; diff --git a/tests/BccCode.Linq.Tests/FilterTests.cs b/tests/BccCode.Linq.Tests/FilterTests.cs index b727ad8..a957fb3 100644 --- a/tests/BccCode.Linq.Tests/FilterTests.cs +++ b/tests/BccCode.Linq.Tests/FilterTests.cs @@ -77,11 +77,12 @@ public void should_cast_value_to_decimal_list() } [Fact] - public void should_throw_exception_on_empty_list() + public void should_allow_empty_list_in_in_operator() { var json = @"{ ""StringArrayProp"": { ""_in"": [] } }"; - Assert.Throws(() => new Filter(json)); + var ex = Record.Exception(() => new Filter(json)); + Assert.Null(ex); } [Fact] diff --git a/tests/BccCode.Linq.Tests/Server/FilterToLambdaParserTests.cs b/tests/BccCode.Linq.Tests/Server/FilterToLambdaParserTests.cs index fcb209f..25708bc 100644 --- a/tests/BccCode.Linq.Tests/Server/FilterToLambdaParserTests.cs +++ b/tests/BccCode.Linq.Tests/Server/FilterToLambdaParserTests.cs @@ -44,45 +44,16 @@ public void should_get_correct_result_when_filter_has_one_logical_filter() [Fact] public void should_get_correct_result_when_filter_has_two_logical_filter() { - var jsonRule = "{\r\n" + - " \"_or\": [\r\n" + - " {\r\n" + - " \"age\": {\r\n" + - " \"_gte\": 20" + - "\r\n" + - " }\r\n" + - " },\r\n" + - " {\r\n" + - " \"country\": {" + - "\r\n" + - " \"_eq\": \"P" + - "oland\",\r\n" + - " \"_in\": [\r" + - "\n" + - " \"Greece\"" + - ",\r\n" + - " \"Norway\"" + - "\r\n" + - " ]\r\n" + - " }\r\n" + - " }\r\n" + - " ],\r\n" + - " \"_and\": [\r\n" + - " {\r\n" + - " \"age\": {\r\n" + - " \"_between\"" + - ": [20, 30]\r\n" + - " }\r\n" + - " },\r\n" + - " {\r\n" + - " \"name\": {\r" + - "\n" + - " \"_starts_wi" + - "th\": \"test\"\r\n" + - " }\r\n" + - " }\r\n" + - " ]\r\n" + - "}"; + var jsonRule = @"{ + ""_or"": [ + { ""age"": { ""_gte"": 20 } }, + { ""country"": { ""_eq"": ""Poland"", ""_in"": [ ""Greece"", ""Norway"" ] } } + ], + ""_and"": [ + { ""age"": { ""_between"": [20, 30] } }, + { ""name"": { ""_starts_with"": ""test"" } } + ] + }"; var expected = PeopleList.Where(person => // or @@ -111,4 +82,41 @@ public void should_get_correct_result_when_filtering_nested_object() Assert.Equal(expected.Count, result.Count); } + + [Fact] + public void should_match_using_in_operator() + { + var jsonRule = "{ \"country\": { \"_in\": [\"Poland\", \"Greece\"] } }"; + + var expected = PeopleList.Where(person => new[] { "Poland", "Greece" }.Contains(person.Country)).ToList(); + var f = new Filter(jsonRule); + var exp = FilterToLambdaParser.Parse(f); + var result = PeopleList.Where(exp.Compile()).ToList(); + + Assert.Equal(expected.Count, result.Count); + } + + [Fact] + public void empty_in_array_should_match_no_items() + { + var jsonRule = "{ \"country\": { \"_in\": [] } }"; + + var f = new Filter(jsonRule); + var exp = FilterToLambdaParser.Parse(f); + var result = PeopleList.Where(exp.Compile()).ToList(); + + Assert.Empty(result); + } + + [Fact] + public void empty_nin_array_should_match_all_items() + { + var jsonRule = "{ \"country\": { \"_nin\": [] } }"; + + var f = new Filter(jsonRule); + var exp = FilterToLambdaParser.Parse(f); + var result = PeopleList.Where(exp.Compile()).ToList(); + + Assert.Equal(PeopleList.Count, result.Count); + } }