diff --git a/.gitignore b/.gitignore index 2db5af1..cde7348 100644 --- a/.gitignore +++ b/.gitignore @@ -30,16 +30,20 @@ appsettings.Development.json *.sln.ide/ # Rider -src/.idea/**/workspace.xml -src/.idea/**/tasks.xml -src/.idea/dictionaries -src/.idea/**/dataSources/ -src/.idea/**/dataSources.ids -src/.idea/**/dataSources.xml -src/.idea/**/dataSources.local.xml -src/.idea/**/sqlDataSources.xml -src/.idea/**/dynamic.xml -src/.idea/**/uiDesigner.xml +**/.idea/**/workspace.xml +**/.idea/**/tasks.xml +**/.idea/shelf/* +**/.idea/dictionaries +**/.idea/**/dataSources/ +**/.idea/**/dataSources.ids +**/.idea/**/dataSources.xml +**/.idea/**/dataSources.local.xml +**/.idea/**/sqlDataSources.xml +**/.idea/**/dynamic.xml +**/.idea/**/*.iml +**/.idea/**/contentModel.xml +**/.idea/**/modules.xml + ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. diff --git a/CHANGELOG.md b/CHANGELOG.md index a048668..c21d04f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ +### New in 0.9.0 (Released 2018/09/11) + +- [__#21__](/~https://github.com/spectresystems/spectre.query/issues/21) Can't parse integer/decimal followed by a closing parenthesis + ### New in 0.8.0 (Released 2018/09/11) - [__#18__](/~https://github.com/spectresystems/spectre.query/issues/18) Support querying of collections -- [__#21__](/~https://github.com/spectresystems/spectre.query/issues/21) Can't parse integer/decimal followed by a closing parenthesis ### New in 0.7.0 (Released 2018/08/21) diff --git a/src/.idea/.idea.Spectre.Query/.idea/.name b/src/.idea/.idea.Spectre.Query/.idea/.name new file mode 100644 index 0000000..bfa9bd4 --- /dev/null +++ b/src/.idea/.idea.Spectre.Query/.idea/.name @@ -0,0 +1 @@ +Spectre.Query \ No newline at end of file diff --git a/src/.idea/.idea.Spectre.Query/.idea/indexLayout.xml b/src/.idea/.idea.Spectre.Query/.idea/indexLayout.xml new file mode 100644 index 0000000..27ba142 --- /dev/null +++ b/src/.idea/.idea.Spectre.Query/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/.idea/.idea.Spectre.Query/.idea/vcs.xml b/src/.idea/.idea.Spectre.Query/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/src/.idea/.idea.Spectre.Query/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/.idea/.idea.Spectre.Query/riderModule.iml b/src/.idea/.idea.Spectre.Query/riderModule.iml new file mode 100644 index 0000000..e57fc2c --- /dev/null +++ b/src/.idea/.idea.Spectre.Query/riderModule.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Spectre.Query.Tests/Infrastructure/IssueAttribute.cs b/src/Spectre.Query.Tests/Infrastructure/IssueAttribute.cs new file mode 100644 index 0000000..28a16a5 --- /dev/null +++ b/src/Spectre.Query.Tests/Infrastructure/IssueAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace Spectre.Query.Tests.Infrastructure +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class IssueAttribute : Attribute + { + public string Url { get; } + + public IssueAttribute(string url) + { + Url = url; + } + } +} \ No newline at end of file diff --git a/src/Spectre.Query.Tests/QueryProviderTests.cs b/src/Spectre.Query.Tests/QueryProviderTests.cs index fbf4238..dc4c7be 100644 --- a/src/Spectre.Query.Tests/QueryProviderTests.cs +++ b/src/Spectre.Query.Tests/QueryProviderTests.cs @@ -46,10 +46,7 @@ await TestQueryRunner.Execute("Foo = 1", DefaultSeeder, options => options.Configure(document => { document.Map("Foo", e => e.DocumentId); - document.Map(invoice => - { - invoice.Map("Foo", e => e.Cancelled); - }); + document.Map(invoice => { invoice.Map("Foo", e => e.Cancelled); }); }); }); }); @@ -66,16 +63,14 @@ public async Task Should_Throw_If_Trying_To_Map_Navigational_Property_Directly() // Given, When var result = await Record.ExceptionAsync(async () => { - await TestQueryRunner.Execute("Foo = 'Contoso'", DefaultSeeder, options => - { - options.Configure(document => + await TestQueryRunner.Execute("Foo = 'Contoso'", DefaultSeeder, + options => { - document.Map(invoice => + options.Configure(document => { - invoice.Map("Foo", e => e.Company); + document.Map(invoice => { invoice.Map("Foo", e => e.Company); }); }); }); - }); }); // Then @@ -90,16 +85,14 @@ public async Task Should_Throw_If_Trying_To_Map_Non_Entity_Type_Property() // Given, When var result = await Record.ExceptionAsync(async () => { - await TestQueryRunner.Execute("Foo = 'Contoso'", DefaultSeeder, options => - { - options.Configure(document => + await TestQueryRunner.Execute("Foo = 'Contoso'", DefaultSeeder, + options => { - document.Map(invoice => + options.Configure(document => { - invoice.Map("Foo", e => e.Dummy); + document.Map(invoice => { invoice.Map("Foo", e => e.Dummy); }); }); }); - }); }); // Then @@ -275,6 +268,19 @@ public async Task Should_Throw_If_Decimal_Has_Invalid_Format(string query) .ShouldBeOfType() .And().Message.ShouldBe("Invalid number format."); } + + [Theory] + [Issue("/~https://github.com/spectresystems/spectre.query/issues/21")] + [InlineData("(Discount = 20)", new int[] { 4 })] + [InlineData("(Discount = 20.0)", new int[] { 4 })] + public async Task Should_Parse_Number_Followed_By_Parenthesis(string query, int[] expected) + { + // Given, When + var result = await TestQueryRunner.Execute(query, DefaultSeeder); + + // Then + result.ShouldContainEntities(expected); + } } } -} +} \ No newline at end of file diff --git a/src/Spectre.Query.sln.DotSettings b/src/Spectre.Query.sln.DotSettings new file mode 100644 index 0000000..47a1ca1 --- /dev/null +++ b/src/Spectre.Query.sln.DotSettings @@ -0,0 +1,4 @@ + + DO_NOT_SHOW + DO_NOT_SHOW + DO_NOT_SHOW \ No newline at end of file diff --git a/src/Spectre.Query/Internal/Expressions/Tokenization/Tokenizer.cs b/src/Spectre.Query/Internal/Expressions/Tokenization/Tokenizer.cs index 39cee2b..4d74559 100644 --- a/src/Spectre.Query/Internal/Expressions/Tokenization/Tokenizer.cs +++ b/src/Spectre.Query/Internal/Expressions/Tokenization/Tokenizer.cs @@ -135,10 +135,14 @@ private Token ReadNumber(int position, bool negative) accumulator.Append(ReadInteger()); } - // More non-whitespace tokens? - if (_buffer.CanRead && !char.IsWhiteSpace(_buffer.Peek())) + if (_buffer.CanRead) { - throw new InvalidOperationException("Invalid number format."); + // More non-whitespace tokens? + var next = _buffer.Peek(); + if (!char.IsWhiteSpace(next) && next != ')') + { + throw new InvalidOperationException("Invalid number format."); + } } var value = accumulator.ToString();