Skip to content

Commit

Permalink
Start with parsing QueryComponents
Browse files Browse the repository at this point in the history
  • Loading branch information
weelink committed Aug 22, 2019
1 parent 302df0b commit a1383e7
Show file tree
Hide file tree
Showing 25 changed files with 360 additions and 144 deletions.
30 changes: 9 additions & 21 deletions docs/api/FluentSQL.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -1,10 +1,12 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;

using FluentAssertions;
using FluentAssertions.Execution;
using FluentAssertions.Primitives;

using FluentSQL.Compilation.Parser.Nodes;
using FluentSQL.Tests.Compilation.Parser.Extensions;

namespace FluentSQL.Tests.Compilation.Parser.Assertions
{
Expand All @@ -31,13 +33,24 @@ public AndConstraint<AstNodeAssertions> BeEmpty(string because = "", params obje
return new AndConstraint<AstNodeAssertions>(this);
}

public AndWhichConstraint<AstNodeAssertions, T> Contain<T>(string because = "", params object[] becauseArgs) where T : AstNode
public AndWhichConstraint<AstNodeAssertions, IEnumerable<T>> Contain<T>(string because = "", params object[] becauseArgs) where T : AstNode
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => Subject.ChildNodes.OfType<T>())
.Given(() => Subject.Flatten().OfType<T>())
.ForCondition(x => x.Any())
.FailWith("Expected {context:astNode} to contain elements of type {0}", x => typeof(T));
.FailWith("Expected {context:astNode} to contain elements of type {0}, but it contained {1}", x => typeof(T), x => x.Count());

return new AndWhichConstraint<AstNodeAssertions, IEnumerable<T>>(this, Subject.Flatten().OfType<T>());
}

public AndWhichConstraint<AstNodeAssertions, T> ContainSingle<T>(string because = "", params object[] becauseArgs) where T : AstNode
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => Subject.Flatten().OfType<T>())
.ForCondition(x => x.Count() == 1)
.FailWith("Expected {context:astNode} to contain a single element of type {0}, but it contained {1}", x => typeof(T), x => x.Count());

return new AndWhichConstraint<AstNodeAssertions, T>(this, Subject.ChildNodes.OfType<T>());
}
Expand Down
@@ -1,4 +1,6 @@
using FluentSQL.Compilation.Parser.Nodes;
using System.Collections.Generic;

using FluentSQL.Compilation.Parser.Nodes;
using FluentSQL.Tests.Compilation.Parser.Assertions;

namespace FluentSQL.Tests.Compilation.Parser.Extensions
Expand All @@ -9,5 +11,18 @@ public static AstNodeAssertions Should(this AstNode instance)
{
return new AstNodeAssertions(instance);
}

public static IEnumerable<AstNode> Flatten(this AstNode instance)
{
yield return instance;

foreach (AstNode childNode in instance.ChildNodes)
{
foreach (AstNode node in childNode.Flatten())
{
yield return node;
}
}
}
}
}
37 changes: 11 additions & 26 deletions src/FluentSQL.Tests/Compilation/Parser/FromQueryParserTests.cs
@@ -1,14 +1,9 @@
using System.Linq;

using FluentAssertions;

using FluentSQL.Compilation.Parser;
using FluentSQL.Compilation.Parser;
using FluentSQL.Compilation.Parser.Nodes;
using FluentSQL.Databases;
using FluentSQL.Querying;
using FluentSQL.Querying.Statements.Extensions;
using FluentSQL.Tests.Builders;
using FluentSQL.Tests.Compilation.Parser.Builders;
using FluentSQL.Tests.Compilation.Parser.Extensions;
using FluentSQL.Tests.Databases.Builders;
using FluentSQL.Tests.Examples;
Expand All @@ -24,14 +19,15 @@ public class When_parsing_without_an_alias : Specification<QueryParser>
protected override QueryParser EstablishContext()
{
Database database = new DatabaseBuilder().Build();
var customer = new Customer();
Customer customer = null;

QueryContext =
database.Query<string>()
database
.Query<string>()
.From(() => customer)
.QueryContext;

return new QueryParserBuilder().Build();
return new QueryParser();
}

protected override void Because(QueryParser sut)
Expand All @@ -45,13 +41,7 @@ protected override void Because(QueryParser sut)
[Fact]
public void It_should_add_the_from_clause()
{
RootNode.ChildNodes.OfType<FromNode>().Should().ContainSingle();
}

[Fact]
public void It_should_have_no_alias()
{
RootNode.ChildNodes.OfType<FromNode>().Single().Should().NotHaveAnAlias();
RootNode.Should().ContainSingle<FromNode>().Which.Should().NotHaveAnAlias();
}
}

Expand All @@ -60,16 +50,17 @@ public class When_parsing_with_an_alias : Specification<QueryParser>
protected override QueryParser EstablishContext()
{
Database database = new DatabaseBuilder().Build();
var customer = new Customer();
Customer customer = null;

Alias = new RandomStringBuilder().ThatStartsWithLetter.Build();

QueryContext =
database.Query<string>()
database
.Query<string>()
.From(() => customer).As(Alias)
.QueryContext;

return new QueryParserBuilder().Build();
return new QueryParser();
}

protected override void Because(QueryParser sut)
Expand All @@ -85,13 +76,7 @@ protected override void Because(QueryParser sut)
[Fact]
public void It_should_add_the_from_clause()
{
RootNode.ChildNodes.OfType<FromNode>().Should().ContainSingle();
}

[Fact]
public void It_should_have_the_alias()
{
RootNode.ChildNodes.OfType<FromNode>().Single().Should().HaveAlias(Alias);
RootNode.Should().ContainSingle<FromNode>().Which.Should().HaveAlias(Alias);
}
}
}
Expand Down
62 changes: 62 additions & 0 deletions src/FluentSQL.Tests/Compilation/Parser/PropertyParserTests.cs
@@ -0,0 +1,62 @@
using FluentAssertions;

using FluentSQL.Compilation.Parser;
using FluentSQL.Compilation.Parser.Nodes;
using FluentSQL.Databases;
using FluentSQL.Querying;
using FluentSQL.Querying.Statements.Extensions;
using FluentSQL.Tests.Compilation.Parser.Extensions;
using FluentSQL.Tests.Databases.Builders;
using FluentSQL.Tests.Examples;

using Xunit;

namespace FluentSQL.Tests.Compilation.Parser
{
public class PropertyParserTests
{
public class When_parsing_a_property : Specification<QueryParser>
{
protected override QueryParser EstablishContext()
{
Database database = new DatabaseBuilder().Build();
Customer customer = null;

QueryContext =
database
.Query<string>()
.From(() => customer)
.Select(() => customer.Id)
.QueryContext;

return new QueryParser();
}

protected override void Because(QueryParser sut)
{
Node = sut.Parse(QueryContext);
}

[Fact]
public void It_should_have_a_select_node()
{
Node.Should().ContainSingle<SelectNode>();
}

[Fact]
public void It_should_have_a_table_node()
{
Node.Should().ContainSingle<TableNode>().Which.Name.Should().Be(nameof(Customer));
}

[Fact]
public void It_should_have_a_column_node()
{
Node.Should().ContainSingle<ColumnNode>().Which.Name.Should().Be(nameof(Customer.Id));
}

private QueryContext<NoParameters, string> QueryContext { get; set; }
private AstNode Node { get; set; }
}
}
}
3 changes: 1 addition & 2 deletions src/FluentSQL.Tests/Compilation/Parser/QueryParserTests.cs
Expand Up @@ -2,7 +2,6 @@
using FluentSQL.Compilation.Parser.Nodes;
using FluentSQL.Databases;
using FluentSQL.Querying;
using FluentSQL.Tests.Compilation.Parser.Builders;
using FluentSQL.Tests.Compilation.Parser.Extensions;
using FluentSQL.Tests.Databases.Builders;

Expand All @@ -19,7 +18,7 @@ protected override QueryParser EstablishContext()
Database database = new DatabaseBuilder().Build();
QueryContext = database.Query<string>();

return new QueryParserBuilder().Build();
return new QueryParser();
}

protected override void Because(QueryParser sut)
Expand Down
Expand Up @@ -6,7 +6,6 @@
using FluentSQL.Querying;
using FluentSQL.Querying.Statements.Extensions;
using FluentSQL.Tests.Builders;
using FluentSQL.Tests.Compilation.Parser.Builders;
using FluentSQL.Tests.Compilation.Parser.Extensions;
using FluentSQL.Tests.Databases.Builders;
using FluentSQL.Tests.Examples;
Expand Down Expand Up @@ -41,7 +40,7 @@ protected override QueryParser EstablishContext()

QueryContext = first.UnionAll(second).QueryContext;

return new QueryParserBuilder().Build();
return new QueryParser();
}

protected override void Because(QueryParser sut)
Expand All @@ -57,8 +56,8 @@ protected override void Because(QueryParser sut)
[Fact]
public void It_should_contain_both_queries()
{
RootNode.As<UnionAllNode>().First.Should().Contain<FromNode>().Which.Should().HaveAlias(FirstAlias);
RootNode.As<UnionAllNode>().Second.Should().Contain<FromNode>().Which.Should().HaveAlias(SecondAlias);
RootNode.Should().Contain<FromNode>().Which.Should().ContainSingle(x => x.Alias == FirstAlias);
RootNode.Should().Contain<FromNode>().Which.Should().ContainSingle(x => x.Alias == SecondAlias);
}

[Fact]
Expand Down
Expand Up @@ -6,7 +6,6 @@
using FluentSQL.Querying;
using FluentSQL.Querying.Statements.Extensions;
using FluentSQL.Tests.Builders;
using FluentSQL.Tests.Compilation.Parser.Builders;
using FluentSQL.Tests.Compilation.Parser.Extensions;
using FluentSQL.Tests.Databases.Builders;
using FluentSQL.Tests.Examples;
Expand Down Expand Up @@ -40,7 +39,7 @@ protected override QueryParser EstablishContext()

QueryContext = first.Union(second).QueryContext;

return new QueryParserBuilder().Build();
return new QueryParser();
}

protected override void Because(QueryParser sut)
Expand All @@ -56,8 +55,8 @@ protected override void Because(QueryParser sut)
[Fact]
public void It_should_contain_both_queries()
{
RootNode.As<UnionNode>().First.Should().Contain<FromNode>().Which.Should().HaveAlias(FirstAlias);
RootNode.As<UnionNode>().Second.Should().Contain<FromNode>().Which.Should().HaveAlias(SecondAlias);
RootNode.Should().Contain<FromNode>().Which.Should().ContainSingle(x => x.Alias == FirstAlias);
RootNode.Should().Contain<FromNode>().Which.Should().ContainSingle(x => x.Alias == SecondAlias);
}

[Fact]
Expand Down
1 change: 1 addition & 0 deletions src/FluentSQL.Tests/Examples/Customer.cs
Expand Up @@ -4,5 +4,6 @@ public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public int? Reference { get; set; }
}
}
4 changes: 4 additions & 0 deletions src/FluentSQL.Tests/FluentSQL.Tests.csproj
Expand Up @@ -22,4 +22,8 @@
<ProjectReference Include="..\FluentSQL\FluentSQL.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Compilation\Parser\Nodes\" />
</ItemGroup>

</Project>

0 comments on commit a1383e7

Please sign in to comment.