From 21ca6f55dc781262b7c4ebd9283886f3ef6801df Mon Sep 17 00:00:00 2001 From: Ninja Date: Thu, 2 Nov 2023 01:30:18 +0000 Subject: [PATCH] - refactor 1 --- README.md | 111 ++++++++++++- src/Schemio.Object.SQL/ISQLQuery.cs | 2 - src/Schemio.Object.SQL/SQLEngine.cs | 2 - src/Schemio.Object.SQL/SQLQuery.cs | 5 - src/Schemio.Object.SQL/SQLQueryEngine.cs | 4 - src/Schemio.Object/BaseEntity.cs | 2 - src/Schemio.Object/BaseEntitySchema.cs | 5 +- src/Schemio.Object/BaseQuery.cs | 5 +- src/Schemio.Object/BaseTransformer.cs | 6 +- src/Schemio.Object/ChildrenQueries.cs | 5 +- src/Schemio.Object/CreateSchema.cs | 7 +- src/Schemio.Object/DataProvider.cs | 15 +- .../Helpers/ExtentionMethods.cs | 2 +- .../Helpers/Xml/XDocumentExts.cs | 3 +- src/Schemio.Object/Helpers/Xml/XmlHelper.cs | 2 +- .../Helpers/Xml/XmlSanitizer.cs | 2 +- src/Schemio.Object/IDataContext.cs | 2 +- src/Schemio.Object/IDataContextValidator.cs | 2 +- src/Schemio.Object/IDataProvider.cs | 2 +- src/Schemio.Object/IEntity.cs | 2 +- src/Schemio.Object/IEntitySchema.cs | 4 +- src/Schemio.Object/IPolymorphicQueryResult.cs | 2 +- src/Schemio.Object/IQuery.cs | 5 +- src/Schemio.Object/IQueryBuilder.cs | 2 +- src/Schemio.Object/IQueryEngine.cs | 2 +- src/Schemio.Object/IQueryExecutor.cs | 4 +- src/Schemio.Object/IQueryList.cs | 6 +- src/Schemio.Object/IQueryParameter.cs | 2 +- src/Schemio.Object/IQueryResult.cs | 2 +- src/Schemio.Object/ISchemaPathMatcher.cs | 2 +- src/Schemio.Object/ITransformExecutor.cs | 4 +- src/Schemio.Object/ITransformer.cs | 19 +-- src/Schemio.Object/Impl/EventAggregator.cs | 5 +- src/Schemio.Object/Impl/EventSubscriber.cs | 9 +- src/Schemio.Object/Impl/QueryBuilder.cs | 7 +- src/Schemio.Object/Impl/QueryExecutor.cs | 5 +- src/Schemio.Object/Impl/TransformExecutor.cs | 16 +- .../PathMatchers/JPathMatcher.cs | 5 +- .../PathMatchers/XPathMatcher.cs | 3 +- src/Schemio.Object/QueryComparer.cs | 4 +- src/Schemio.Object/QueryList.cs | 5 +- src/Schemio.Object/XML/XMLDataProvider.cs | 6 +- .../DataProvider.Tests/DataProviderTests.cs | 45 ++++++ .../DataProvider.Tests/QueryBuilderTests.cs | 147 ++++++++++++++++++ .../TransformExecutorTests.cs | 92 +++++++++++ .../CustomerContext.cs | 4 +- .../{ => EntitySetup}/Entities/Address.cs | 4 +- .../Entities/Communication.cs | 4 +- .../{ => EntitySetup}/Entities/Customer.cs | 4 +- .../EntitySetup/Entities/EntityDiagram.cd | 50 ++++++ .../{ => EntitySetup}/Entities/Order.cs | 4 +- .../{ => EntitySetup}/Entities/OrderItem.cs | 4 +- .../EntitySchemas/CustomerSchema.cs | 11 +- .../Queries/CommunicationResult.cs | 14 ++ .../Queries/CustomerCommunicationQuery.cs | 16 +- .../Queries/CustomerOrderItemsQuery.cs | 20 +-- .../Queries/CustomerOrdersQuery.cs | 18 +-- .../EntitySetup/Queries/CustomerParameter.cs | 7 + .../Queries/CustomerQuery.cs | 17 +- .../EntitySetup/Queries/CustomerResult.cs | 9 ++ .../Queries/OrderCollectionResult.cs | 15 ++ .../Queries/OrderItemCollectionResult.cs | 13 ++ .../EntitySetup/Queries/OrderItemParameter.cs | 7 + .../CustomerCommunicationTransform.cs | 6 +- .../Transforms/CustomerOrderItemsTransform.cs | 10 +- .../Transforms/CustomerOrdersTransform.cs | 6 +- .../Transforms/CustomerTransform.cs | 7 +- .../Schemio.Object.Tests.csproj | 1 + tests/Schemio.Object.Tests/UnitTest1.cs | 2 +- 69 files changed, 600 insertions(+), 242 deletions(-) create mode 100644 tests/Schemio.Object.Tests/DataProvider.Tests/DataProviderTests.cs create mode 100644 tests/Schemio.Object.Tests/DataProvider.Tests/QueryBuilderTests.cs create mode 100644 tests/Schemio.Object.Tests/DataProvider.Tests/TransformExecutorTests.cs rename tests/Schemio.Object.Tests/{DataProvider => EntitySetup}/CustomerContext.cs (73%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Entities/Address.cs (81%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Entities/Communication.cs (76%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Entities/Customer.cs (81%) create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Entities/EntityDiagram.cd rename tests/Schemio.Object.Tests/{ => EntitySetup}/Entities/Order.cs (75%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Entities/OrderItem.cs (70%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/EntitySchemas/CustomerSchema.cs (80%) create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/CommunicationResult.cs rename tests/Schemio.Object.Tests/{ => EntitySetup}/Queries/CustomerCommunicationQuery.cs (57%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Queries/CustomerOrderItemsQuery.cs (59%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Queries/CustomerOrdersQuery.cs (58%) create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerParameter.cs rename tests/Schemio.Object.Tests/{ => EntitySetup}/Queries/CustomerQuery.cs (59%) create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerResult.cs create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/OrderCollectionResult.cs create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemCollectionResult.cs create mode 100644 tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemParameter.cs rename tests/Schemio.Object.Tests/{ => EntitySetup}/Transforms/CustomerCommunicationTransform.cs (85%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Transforms/CustomerOrderItemsTransform.cs (81%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Transforms/CustomerOrdersTransform.cs (79%) rename tests/Schemio.Object.Tests/{ => EntitySetup}/Transforms/CustomerTransform.cs (75%) diff --git a/README.md b/README.md index f85412f..2bcbe3c 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,113 @@ [![NuGet version](https://badge.fury.io/nu/Schemio.Object.svg)](https://badge.fury.io/nu/Schemio.Object) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/NinjaRocks/Schemio.Object/blob/master/License.md) [![CI](https://github.com/NinjaRocks/Data2Xml/actions/workflows/CI.yml/badge.svg)](https://github.com/NinjaRocks/Data2Xml/actions/workflows/CI.yml) [![GitHub Release](https://img.shields.io/github/v/release/ninjarocks/Data2Xml?logo=github&sort=semver)](https://github.com/ninjarocks/Data2Xml/releases/latest) [![CodeQL](https://github.com/NinjaRocks/Schemio.Object/actions/workflows/CodeQL.yml/badge.svg)](https://github.com/NinjaRocks/Schemio.Object/actions/workflows/CodeQL.yml) [![.Net Stardard](https://img.shields.io/badge/.Net%20Standard-2.1-blue)](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) -- -### .Net Standard 2.1 Library to map data to Entity using Schema Paths (Like XPath or JsonPath). +Schemio - is a .Net 6 utility to hydrate entities with data conditionally by given list of schema paths mapping to object graph. Support JsonPath and Xpath schema mappings. + +## How to use Schemio? +> Step 1 - To mark the entity to hydrate data using schemio, derive the entity from `IEntity` interface. Bear in mind this is the root entity. +``` + public class Customer : IEntity + { + public int CustomerId { get; set; } + public string CustomerCode { get; set; } + public string CustomerName { get; set; } + public Communication Communication { get; set; } + public Order[] Orders { get; set; } + } +``` +Above, Customer is the entity we want to hydrate with data conditionaly passing in schema paths mapping to object graph. + +> Step 2 - Define schema configuration to map query/transformer pairs to schema paths mapping to the object graph. +Derive schema from `IEntitySchema` where T is entity to hydrate. The query/transformer mappings can be nested to 5 levels down. You could map multiple schema paths to a given query/transformer pair. + + +``` +internal class CustomerSchema : IEntitySchema + { + private IEnumerable> mappings; + + private decimal version; + + public IEnumerable> Mappings => mappings; + public decimal Version => version; + + public CustomerSchema() + { + version = 1; + + // Create an object mapping graph of query and transformer pairs using xpaths. + mappings = CreateSchema.For() + .Map(For.Paths("customer/id", "customer/customercode", "customer/customername"), + customer => customer.Dependents + .Map(For.Paths("customer/communication")) + .Map(For.Paths("customer/orders"), + customerOrders => customerOrders.Dependents + .Map(For.Paths("customer/orders/order/items"))) + ).Complete(); + } + } +``` + +#### Query Class +The purpose of a query class is to execute to fetch data when mapped schema path is included in the context paramer of data provider. +- To define a query for a schema path, you need to implement the query by deriving from `BaseQuery : IQuery where TQueryParameter : IQueryParameter where TQueryResult : IQueryResult` +- You may want to run the query in parent or child mode and define the relevant overrides to resovle the query parameter accordingly. +- In `parent` mode the query parameter is resolved using `context` parameter passed to data provider class. +- In `child` mode, the query parameter is resolved using the `query result` of the `parent query` to which the current query is a child. You could have a maximum of `5` levels of children query nesting when defining the Entity schema. + +> See example Customer query as parent below. +``` +public class CustomerQuery : BaseQuery + { + public override void ResolveParameterInParentMode(IDataContext context) + { + // Executes as root or level 1 query. + var customer = (CustomerContext)context; + QueryParameter = new CustomerParameter + { + CustomerId = customer.CustomerId + }; + } + + public override void ResolveParameterInChildMode(IDataContext context, IQueryResult parentQueryResult) + { + // Does not execute as child to any query. + } + } +``` +> see communication query as child to customer query below. +``` + internal class CustomerCommunicationQuery : BaseQuery + { + public override void ResolveParameterInParentMode(IDataContext context) + { + // Does not execute as root or level 1 queries. + } + + public override void ResolveParameterInChildMode(IDataContext context, IQueryResult parentQueryResult) + { + // Execute as child to customer query. + var customer = (CustomerResult)parentQueryResult; + QueryParameter = new CustomerParameter + { + CustomerId = customer.Id + }; + } + } +``` +The parent/child relationship is achieved via entity schema configuration. see CustomerSchema above. +#### Tranformer Class +The purpose of the transformer is to map the data fetched by the linked query class to relevant schema section of the entity to be data hydrated. +- To define a transformer class for the schema path, you need to derive from `BaseTransformer : ITransformer + where T : IEntity + where TD : IQueryResult` +- The output of the linked query serves as input to the transformer to map data to configured section of the entity in context. + +> Step 3 - Use the DataProvider class to get the entity with hydrated data based on configuration and passed in context paratemer with relevant schema paths. +``` +var + +``` + +## Extending Schemio +> coming soon diff --git a/src/Schemio.Object.SQL/ISQLQuery.cs b/src/Schemio.Object.SQL/ISQLQuery.cs index 426079d..4e861f3 100644 --- a/src/Schemio.Object.SQL/ISQLQuery.cs +++ b/src/Schemio.Object.SQL/ISQLQuery.cs @@ -1,5 +1,3 @@ -using Schemio.Object.Core; - namespace Schemio.Object.SQL { public interface ISQLQuery diff --git a/src/Schemio.Object.SQL/SQLEngine.cs b/src/Schemio.Object.SQL/SQLEngine.cs index e5f1abf..4c01370 100644 --- a/src/Schemio.Object.SQL/SQLEngine.cs +++ b/src/Schemio.Object.SQL/SQLEngine.cs @@ -1,5 +1,3 @@ -using Schemio.Object.Core; - namespace Schemio.Object.SQL { public interface SQLEngine diff --git a/src/Schemio.Object.SQL/SQLQuery.cs b/src/Schemio.Object.SQL/SQLQuery.cs index aab89c0..f186665 100644 --- a/src/Schemio.Object.SQL/SQLQuery.cs +++ b/src/Schemio.Object.SQL/SQLQuery.cs @@ -1,8 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Schemio.Object.Core; - namespace Schemio.Object.SQL { //internal abstract class SQLQuery : IQuery diff --git a/src/Schemio.Object.SQL/SQLQueryEngine.cs b/src/Schemio.Object.SQL/SQLQueryEngine.cs index 57ade88..58e6567 100644 --- a/src/Schemio.Object.SQL/SQLQueryEngine.cs +++ b/src/Schemio.Object.SQL/SQLQueryEngine.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; using System.Data.Common; using System.Data; -using System.Linq; -using Schemio.Object.Core; using Dapper; namespace Schemio.Object.SQL diff --git a/src/Schemio.Object/BaseEntity.cs b/src/Schemio.Object/BaseEntity.cs index 3764800..202c2d2 100644 --- a/src/Schemio.Object/BaseEntity.cs +++ b/src/Schemio.Object/BaseEntity.cs @@ -1,5 +1,3 @@ -using Schemio.Object.Core; - namespace Schemio.Object { //public abstract class BaseEntity : IEntity diff --git a/src/Schemio.Object/BaseEntitySchema.cs b/src/Schemio.Object/BaseEntitySchema.cs index e5d8bf7..429eda8 100644 --- a/src/Schemio.Object/BaseEntitySchema.cs +++ b/src/Schemio.Object/BaseEntitySchema.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { /// /// Implement to configure schema path mappings for an Entity. diff --git a/src/Schemio.Object/BaseQuery.cs b/src/Schemio.Object/BaseQuery.cs index d3343bf..495663e 100644 --- a/src/Schemio.Object/BaseQuery.cs +++ b/src/Schemio.Object/BaseQuery.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { /// /// Implement this base class to create a data provider query. diff --git a/src/Schemio.Object/BaseTransformer.cs b/src/Schemio.Object/BaseTransformer.cs index 2544a61..ca0b753 100644 --- a/src/Schemio.Object/BaseTransformer.cs +++ b/src/Schemio.Object/BaseTransformer.cs @@ -1,5 +1,3 @@ -using Schemio.Object.Core; - namespace Schemio.Object { public abstract class BaseTransformer : ITransformer @@ -7,13 +5,13 @@ public abstract class BaseTransformer : ITransformer where TD : IQueryResult { public IDataContext Context { get; private set; } + public Type SupportedQueryResult => typeof(TD); public void ResolveContext(IDataContext context) => Context = context; public IEntity Run(IQueryResult queryResult, IEntity entity) { - return queryResult.GetType() == typeof(TD) || queryResult is TD - ? Transform((TD)queryResult, (T)entity) : entity; + return Transform((TD)queryResult, (T)entity); } public abstract T Transform(TD queryResult, T entity); diff --git a/src/Schemio.Object/ChildrenQueries.cs b/src/Schemio.Object/ChildrenQueries.cs index 2427810..d934593 100644 --- a/src/Schemio.Object/ChildrenQueries.cs +++ b/src/Schemio.Object/ChildrenQueries.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { public class ChildrenQueries { diff --git a/src/Schemio.Object/CreateSchema.cs b/src/Schemio.Object/CreateSchema.cs index 105fecd..7ec8f97 100644 --- a/src/Schemio.Object/CreateSchema.cs +++ b/src/Schemio.Object/CreateSchema.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { #region Helpers @@ -66,13 +63,11 @@ public IMapOrComplete Map(ISchemaPaths paths, Func)dependents(mapping)).GetMappings) { dep.DependentOn ??= mapping.Query; Add(dep); } - } Add(mapping); diff --git a/src/Schemio.Object/DataProvider.cs b/src/Schemio.Object/DataProvider.cs index 8148ec6..f4daea4 100644 --- a/src/Schemio.Object/DataProvider.cs +++ b/src/Schemio.Object/DataProvider.cs @@ -1,14 +1,25 @@ using Microsoft.Extensions.Logging; +using Schemio.Object.Impl; -namespace Schemio.Object.Core.Impl +namespace Schemio.Object { - public class DataProvider : IDataProvider where T : IEntity + public class DataProvider : IDataProvider where T : IEntity, new() { private readonly ILogger> logger; private readonly IQueryExecutor queryExecutor; private readonly IQueryBuilder queryBuilder; private readonly ITransformExecutor transformExecutor; + public DataProvider( + ILogger> logger, + IEntitySchema entitySchema, + ISchemaPathMatcher schemaPathMatcher, + IQueryEngine[] queryEngines) + : this(logger, new QueryBuilder(entitySchema, schemaPathMatcher), + new QueryExecutor(queryEngines), new TransformExecutor(entitySchema)) + { + } + public DataProvider( ILogger> logger, IQueryBuilder queryBuilder, diff --git a/src/Schemio.Object/Helpers/ExtentionMethods.cs b/src/Schemio.Object/Helpers/ExtentionMethods.cs index 42a9745..0c099fa 100644 --- a/src/Schemio.Object/Helpers/ExtentionMethods.cs +++ b/src/Schemio.Object/Helpers/ExtentionMethods.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core.Helpers +namespace Schemio.Object.Helpers { public static class ExtentionMethods { diff --git a/src/Schemio.Object/Helpers/Xml/XDocumentExts.cs b/src/Schemio.Object/Helpers/Xml/XDocumentExts.cs index a12258b..b9fd172 100644 --- a/src/Schemio.Object/Helpers/Xml/XDocumentExts.cs +++ b/src/Schemio.Object/Helpers/Xml/XDocumentExts.cs @@ -1,7 +1,6 @@ -using System.Linq; using System.Xml.Linq; -namespace Schemio.Object.Core.Helpers.Xml +namespace Schemio.Object.Helpers.Xml { public static class XDocumentExts { diff --git a/src/Schemio.Object/Helpers/Xml/XmlHelper.cs b/src/Schemio.Object/Helpers/Xml/XmlHelper.cs index 85b3330..c0b65c1 100644 --- a/src/Schemio.Object/Helpers/Xml/XmlHelper.cs +++ b/src/Schemio.Object/Helpers/Xml/XmlHelper.cs @@ -2,7 +2,7 @@ using System.Xml; using System.Xml.Serialization; -namespace Schemio.Object.Core.Helpers.Xml +namespace Schemio.Object.Helpers.Xml { public static class XmlHelper { diff --git a/src/Schemio.Object/Helpers/Xml/XmlSanitizer.cs b/src/Schemio.Object/Helpers/Xml/XmlSanitizer.cs index 0717d48..bd964ee 100644 --- a/src/Schemio.Object/Helpers/Xml/XmlSanitizer.cs +++ b/src/Schemio.Object/Helpers/Xml/XmlSanitizer.cs @@ -2,7 +2,7 @@ using System.Text.RegularExpressions; using System.Xml; -namespace Schemio.Object.Core.Helpers.Xml +namespace Schemio.Object.Helpers.Xml { public static class XmlSanitizer { diff --git a/src/Schemio.Object/IDataContext.cs b/src/Schemio.Object/IDataContext.cs index 5dcd921..2b38183 100644 --- a/src/Schemio.Object/IDataContext.cs +++ b/src/Schemio.Object/IDataContext.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IDataContext { diff --git a/src/Schemio.Object/IDataContextValidator.cs b/src/Schemio.Object/IDataContextValidator.cs index 9a434cc..ca36725 100644 --- a/src/Schemio.Object/IDataContextValidator.cs +++ b/src/Schemio.Object/IDataContextValidator.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IDataContextValidator { diff --git a/src/Schemio.Object/IDataProvider.cs b/src/Schemio.Object/IDataProvider.cs index 53bee01..48c21a1 100644 --- a/src/Schemio.Object/IDataProvider.cs +++ b/src/Schemio.Object/IDataProvider.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IDataProvider where T : IEntity { diff --git a/src/Schemio.Object/IEntity.cs b/src/Schemio.Object/IEntity.cs index f6c12fa..f4dc6fb 100644 --- a/src/Schemio.Object/IEntity.cs +++ b/src/Schemio.Object/IEntity.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { /// /// Implement Entity required to be hydrated (using query/transformer). diff --git a/src/Schemio.Object/IEntitySchema.cs b/src/Schemio.Object/IEntitySchema.cs index 5a2ccba..d37e0f3 100644 --- a/src/Schemio.Object/IEntitySchema.cs +++ b/src/Schemio.Object/IEntitySchema.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { /// /// Implement to configure schema path mappings for an Entity. diff --git a/src/Schemio.Object/IPolymorphicQueryResult.cs b/src/Schemio.Object/IPolymorphicQueryResult.cs index c73eaa7..da18ffa 100644 --- a/src/Schemio.Object/IPolymorphicQueryResult.cs +++ b/src/Schemio.Object/IPolymorphicQueryResult.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IPolymorphicQueryResult : IQueryResult { diff --git a/src/Schemio.Object/IQuery.cs b/src/Schemio.Object/IQuery.cs index 3d4335b..cbb8a34 100644 --- a/src/Schemio.Object/IQuery.cs +++ b/src/Schemio.Object/IQuery.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { /// /// Implement IQuery to fetch data using API or database. diff --git a/src/Schemio.Object/IQueryBuilder.cs b/src/Schemio.Object/IQueryBuilder.cs index ebaa4e6..af754c0 100644 --- a/src/Schemio.Object/IQueryBuilder.cs +++ b/src/Schemio.Object/IQueryBuilder.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryBuilder { diff --git a/src/Schemio.Object/IQueryEngine.cs b/src/Schemio.Object/IQueryEngine.cs index 57faf4f..9aa554f 100644 --- a/src/Schemio.Object/IQueryEngine.cs +++ b/src/Schemio.Object/IQueryEngine.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryEngine { diff --git a/src/Schemio.Object/IQueryExecutor.cs b/src/Schemio.Object/IQueryExecutor.cs index fa636b0..7e3bf93 100644 --- a/src/Schemio.Object/IQueryExecutor.cs +++ b/src/Schemio.Object/IQueryExecutor.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryExecutor { diff --git a/src/Schemio.Object/IQueryList.cs b/src/Schemio.Object/IQueryList.cs index ea37d18..bdca13f 100644 --- a/src/Schemio.Object/IQueryList.cs +++ b/src/Schemio.Object/IQueryList.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryList - { + { int QueryDependencyDepth { get; set; } IEnumerable Queries { get; } diff --git a/src/Schemio.Object/IQueryParameter.cs b/src/Schemio.Object/IQueryParameter.cs index 43d599f..b8bc423 100644 --- a/src/Schemio.Object/IQueryParameter.cs +++ b/src/Schemio.Object/IQueryParameter.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryParameter { diff --git a/src/Schemio.Object/IQueryResult.cs b/src/Schemio.Object/IQueryResult.cs index 03bc6ec..122c3c2 100644 --- a/src/Schemio.Object/IQueryResult.cs +++ b/src/Schemio.Object/IQueryResult.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface IQueryResult { diff --git a/src/Schemio.Object/ISchemaPathMatcher.cs b/src/Schemio.Object/ISchemaPathMatcher.cs index ae3893d..909d981 100644 --- a/src/Schemio.Object/ISchemaPathMatcher.cs +++ b/src/Schemio.Object/ISchemaPathMatcher.cs @@ -1,4 +1,4 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { public interface ISchemaPathMatcher { diff --git a/src/Schemio.Object/ITransformExecutor.cs b/src/Schemio.Object/ITransformExecutor.cs index 10aab20..e28a627 100644 --- a/src/Schemio.Object/ITransformExecutor.cs +++ b/src/Schemio.Object/ITransformExecutor.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { public interface ITransformExecutor where TEntity : IEntity { diff --git a/src/Schemio.Object/ITransformer.cs b/src/Schemio.Object/ITransformer.cs index 13c8f8f..61266b3 100644 --- a/src/Schemio.Object/ITransformer.cs +++ b/src/Schemio.Object/ITransformer.cs @@ -1,25 +1,14 @@ -namespace Schemio.Object.Core +namespace Schemio.Object { /// - /// Implement transformer to map data to entity using query result. + /// Implement transformer to map data to entity using supported query result. /// - /// - /// - public interface ITransformer : ITransformer - where TQueryResult : IQueryResult - where TEntity : IEntity - { - //IDataContext Context { get; } - - //void ResolveContext(IDataContext context); - - // TEntity Run(TQueryResult queryResult, TEntity entity); - } - public interface ITransformer { IDataContext Context { get; } + Type SupportedQueryResult { get; } + void ResolveContext(IDataContext context); IEntity Run(IQueryResult queryResult, IEntity entity); diff --git a/src/Schemio.Object/Impl/EventAggregator.cs b/src/Schemio.Object/Impl/EventAggregator.cs index 95c4c87..1f8cc86 100644 --- a/src/Schemio.Object/Impl/EventAggregator.cs +++ b/src/Schemio.Object/Impl/EventAggregator.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; - -namespace Schemio.Object.Core.Impl +namespace Schemio.Object.Impl { public class EventAggregator { diff --git a/src/Schemio.Object/Impl/EventSubscriber.cs b/src/Schemio.Object/Impl/EventSubscriber.cs index 5ee650d..758e70d 100644 --- a/src/Schemio.Object/Impl/EventSubscriber.cs +++ b/src/Schemio.Object/Impl/EventSubscriber.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Schemio.Object.Core.Impl +namespace Schemio.Object.Impl { public class EventSubscriber : ISubscriber { @@ -32,9 +29,7 @@ public void OnEventHandler(IDataContext context, ExecutorResultArgs args) continue; foreach (var query in unresolved.Queries) - { query.ResolveParameterInChildMode(context, queryResult); - } } } @@ -54,9 +49,7 @@ public void OnEventHandler(IDataContext context, ExecutorResultArgs args) continue; foreach (var query in unresolved.Queries) - { query.ResolveParameterInChildMode(context, queryResult); - } } } } diff --git a/src/Schemio.Object/Impl/QueryBuilder.cs b/src/Schemio.Object/Impl/QueryBuilder.cs index 5a111a4..a88c8a5 100644 --- a/src/Schemio.Object/Impl/QueryBuilder.cs +++ b/src/Schemio.Object/Impl/QueryBuilder.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Schemio.Object.Core.Impl +namespace Schemio.Object.Impl { public class QueryBuilder : IQueryBuilder where T : IEntity { @@ -40,7 +37,7 @@ private QueryList GetMappedQueries(IReadOnlyCollection> foreach (var map in maps) { var dependentQueries = - mappings.Where(x => x.Order == (index + 1) && x.DependentOn != null && x.DependentOn.GetType() == map.Query.GetType()).ToList(); + mappings.Where(x => x.Order == index + 1 && x.DependentOn != null && x.DependentOn.GetType() == map.Query.GetType()).ToList(); map.Query.Children ??= new List(); diff --git a/src/Schemio.Object/Impl/QueryExecutor.cs b/src/Schemio.Object/Impl/QueryExecutor.cs index a4bec3c..25f9b49 100644 --- a/src/Schemio.Object/Impl/QueryExecutor.cs +++ b/src/Schemio.Object/Impl/QueryExecutor.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Schemio.Object.Core.Impl +namespace Schemio.Object.Impl { public class QueryExecutor : IQueryExecutor { diff --git a/src/Schemio.Object/Impl/TransformExecutor.cs b/src/Schemio.Object/Impl/TransformExecutor.cs index df5e6f3..19c17a2 100644 --- a/src/Schemio.Object/Impl/TransformExecutor.cs +++ b/src/Schemio.Object/Impl/TransformExecutor.cs @@ -1,15 +1,12 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Schemio.Object.Core.Impl +namespace Schemio.Object.Impl { public class TransformExecutor : ITransformExecutor where T : IEntity, new() { - private readonly IEntitySchema entitySchemaMapping; + private readonly IEntitySchema entitySchema; - public TransformExecutor(IEntitySchema entitySchemaMapping) + public TransformExecutor(IEntitySchema entitySchema) { - this.entitySchemaMapping = entitySchemaMapping; + this.entitySchema = entitySchema; } /// @@ -25,7 +22,7 @@ public T Execute(IDataContext context, IList queryResults) if (queryResults == null || !queryResults.Any()) return entity; - var mappings = entitySchemaMapping.Mappings.ToList(); + var mappings = entitySchema.Mappings.ToList(); // resolve context of each transformer so it is available inside for transformation if required. mappings.ForEach(mapping => mapping.Transformer.ResolveContext(context)); @@ -42,7 +39,8 @@ public T Execute(IDataContext context, IList queryResults) .ToList(); foreach (var queryResult in queryResults) - transformers.ForEach(transformer => transformer.Run(queryResult, entity)); + transformers.Where(transformer => transformer.SupportedQueryResult == queryResult.GetType()).ToList() + .ForEach(supportedtransformer => supportedtransformer.Run(queryResult, entity)); } return entity; diff --git a/src/Schemio.Object/PathMatchers/JPathMatcher.cs b/src/Schemio.Object/PathMatchers/JPathMatcher.cs index 7361732..a4c7f9e 100644 --- a/src/Schemio.Object/PathMatchers/JPathMatcher.cs +++ b/src/Schemio.Object/PathMatchers/JPathMatcher.cs @@ -1,7 +1,4 @@ -using Schemio.Object.Core; -using Schemio.Object.Core.Helpers; -using System.Linq; -using System.Text.RegularExpressions; +using Schemio.Object.Helpers; namespace Schemio.Object.Pathmatchers { diff --git a/src/Schemio.Object/PathMatchers/XPathMatcher.cs b/src/Schemio.Object/PathMatchers/XPathMatcher.cs index 34dd9d9..351625f 100644 --- a/src/Schemio.Object/PathMatchers/XPathMatcher.cs +++ b/src/Schemio.Object/PathMatchers/XPathMatcher.cs @@ -1,5 +1,4 @@ -using Schemio.Object.Core; -using Schemio.Object.Core.Helpers; +using Schemio.Object.Helpers; using System.Text.RegularExpressions; namespace Schemio.Object.PathMatchers diff --git a/src/Schemio.Object/QueryComparer.cs b/src/Schemio.Object/QueryComparer.cs index c011602..d9aeb69 100644 --- a/src/Schemio.Object/QueryComparer.cs +++ b/src/Schemio.Object/QueryComparer.cs @@ -1,6 +1,4 @@ -using System.Collections.Generic; - -namespace Schemio.Object.Core +namespace Schemio.Object { public class QueryComparer : IEqualityComparer { diff --git a/src/Schemio.Object/QueryList.cs b/src/Schemio.Object/QueryList.cs index 7891334..216dea0 100644 --- a/src/Schemio.Object/QueryList.cs +++ b/src/Schemio.Object/QueryList.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Schemio.Object.Core +namespace Schemio.Object { public class QueryList : IQueryList { diff --git a/src/Schemio.Object/XML/XMLDataProvider.cs b/src/Schemio.Object/XML/XMLDataProvider.cs index 9487554..7080649 100644 --- a/src/Schemio.Object/XML/XMLDataProvider.cs +++ b/src/Schemio.Object/XML/XMLDataProvider.cs @@ -1,10 +1,10 @@ -using Microsoft.Extensions.Logging; -using Schemio.Object.Core.Helpers.Xml; +using Microsoft.Extensions.Logging; +using Schemio.Object.Helpers.Xml; using System.Xml; using System.Xml.Linq; using System.Xml.Serialization; -namespace Schemio.Object.Core.XML +namespace Schemio.Object.XML { internal class XMLDataProvider where T : IEntity { diff --git a/tests/Schemio.Object.Tests/DataProvider.Tests/DataProviderTests.cs b/tests/Schemio.Object.Tests/DataProvider.Tests/DataProviderTests.cs new file mode 100644 index 0000000..2165b92 --- /dev/null +++ b/tests/Schemio.Object.Tests/DataProvider.Tests/DataProviderTests.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Moq; +using Schemio.Object.Tests.EntitySetup; +using Schemio.Object.Tests.EntitySetup.Entities; + +namespace Schemio.Object.Tests.DataProvider +{ + [TestFixture] + internal class DataProviderTests + { + private DataProvider _provider; + private Mock>> _logger; + private Mock> _queryBuilder; + private Mock _queryExecutor; + private Mock> _transformExecutor; + + [SetUp] + public void Setup() + { + _logger = new Mock>>(); + _queryBuilder = new Mock>(); + _queryExecutor = new Mock(); + _transformExecutor = new Mock>(); + + _provider = new DataProvider(_logger.Object, _queryBuilder.Object, _queryExecutor.Object, _transformExecutor.Object); + } + + [Test] + public void TestDataProvider() + { + var context = new CustomerContext { CustomerId = 1 }; + + _provider.GetData(context); + + _queryBuilder.Verify(x => x.Build(context), Times.Once); + _queryExecutor.Verify(x => x.Execute(context, It.IsAny()), Times.Once); + _transformExecutor.Verify(x => x.Execute(context, It.IsAny>()), Times.Once); + } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/DataProvider.Tests/QueryBuilderTests.cs b/tests/Schemio.Object.Tests/DataProvider.Tests/QueryBuilderTests.cs new file mode 100644 index 0000000..1b71198 --- /dev/null +++ b/tests/Schemio.Object.Tests/DataProvider.Tests/QueryBuilderTests.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Moq; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup; +using Schemio.Object.Impl; +using Schemio.Object.Tests.EntitySetup.EntitySchemas; +using Schemio.Object.PathMatchers; +using Schemio.Object.Tests.EntitySetup.Queries; + +namespace Schemio.Object.Tests.DataProvider +{ + [TestFixture] + internal class QueryBuilderTests + { + private QueryBuilder _queryBuilder; + + private IEntitySchema _entitySchema; + private ISchemaPathMatcher _schemaPathMatcher; + + [SetUp] + public void Setup() + { + _entitySchema = new CustomerSchema(); + + /*----------------------------------------- * + * + * CreateSchema.For() + .Map(For.Paths("customer/id", "customer/customercode", "customer/customername"), + customer => customer.Dependents + .Map(For.Paths("customer/communication")) + .Map(For.Paths("customer/orders"), + customerOrders => customerOrders.Dependents + .Map(For.Paths("customer/orders/order/items"))) + ) + * + * --------------------------------------- */ + + _schemaPathMatcher = new XPathMatcher(); + _queryBuilder = new QueryBuilder(_entitySchema, _schemaPathMatcher); + } + + [Test] + public void TestQueryBuilderForCorrectParentQueryList() + { + var context = new CustomerContext { CustomerId = 1, Paths = new[] { "customer/customercode" } }; + + var result = _queryBuilder.Build(context); + + Assert.IsNotNull(result); + + // returns parent query with filtered out child communication query. + + Assert.That(result.QueryDependencyDepth == 0); + Assert.That(result.Queries.Count, Is.EqualTo(1)); + Assert.That(result.Queries.ElementAt(0).Children.Count, Is.EqualTo(0)); + + var parentQuery = result.Queries.First(); + Assert.That(parentQuery.GetType() == typeof(CustomerQuery)); + } + + [Test] + public void TestQueryBuilderForCorrectParentQueryListWithOneChildren() + { + var context = new CustomerContext { CustomerId = 1, Paths = new[] { "customer/customercode", "customer/communication" } }; + + var result = _queryBuilder.Build(context); + + Assert.IsNotNull(result); + + // returns parent query with filtered out child communication query. + + Assert.That(result.QueryDependencyDepth == 0); + Assert.That(result.Queries.Count, Is.EqualTo(1)); + Assert.That(result.Queries.ElementAt(0).Children.Count, Is.EqualTo(1)); + + var parentQuery = result.Queries.First(); + Assert.That(parentQuery.GetType() == typeof(CustomerQuery)); + + var childQuery = parentQuery.Children.First(); + Assert.That(childQuery.GetType() == typeof(CustomerCommunicationQuery)); + } + + [Test] + public void TestQueryBuilderForCorrectParentQueryListWithTwoChildren() + { + var context = new CustomerContext { CustomerId = 1, Paths = new[] { "customer/customercode", "customer/communication", "customer/orders" } }; + + var result = _queryBuilder.Build(context); + + Assert.IsNotNull(result); + + // returns parent query with filtered out children - communication & orders query. + + Assert.That(result.QueryDependencyDepth == 0); + Assert.That(result.Queries.Count, Is.EqualTo(1)); + Assert.That(result.Queries.ElementAt(0).Children.Count, Is.EqualTo(2)); + + var parentQuery = result.Queries.First(); + Assert.That(parentQuery.GetType() == typeof(CustomerQuery)); + + var communicationChildQuery = parentQuery.Children.FirstOrDefault(x => x.GetType() == typeof(CustomerCommunicationQuery)); + var ordersChildQuery = parentQuery.Children.FirstOrDefault(x => x.GetType() == typeof(CustomerOrdersQuery)); + + Assert.IsNotNull(communicationChildQuery); + Assert.IsNotNull(ordersChildQuery); + + // nested child query for order item not included as order items are excluded from paths + Assert.That(ordersChildQuery.Children.Count, Is.EqualTo(0)); + } + + [Test] + public void TestQueryBuilderForCorrectParentQueryListWithTwoChildrenAndOneChildFurtherNestedChildQuery() + { + var context = new CustomerContext { CustomerId = 1, Paths = new[] { "customer/customercode", "customer/communication", "customer/orders", "customer/orders/order/items" } }; + + var result = _queryBuilder.Build(context); + + Assert.IsNotNull(result); + + // returns parent query with filtered out children - communication & orders query. + + Assert.That(result.QueryDependencyDepth == 0); + Assert.That(result.Queries.Count, Is.EqualTo(1)); + Assert.That(result.Queries.ElementAt(0).Children.Count, Is.EqualTo(2)); + + var parentQuery = result.Queries.First(); + Assert.That(parentQuery.GetType() == typeof(CustomerQuery)); + + var communicationChildQuery = parentQuery.Children.FirstOrDefault(x => x.GetType() == typeof(CustomerCommunicationQuery)); + var ordersChildQuery = parentQuery.Children.FirstOrDefault(x => x.GetType() == typeof(CustomerOrdersQuery)); + + Assert.IsNotNull(communicationChildQuery); + Assert.IsNotNull(ordersChildQuery); + + // nested child query for order item in order query children as order items are included in paths + Assert.That(ordersChildQuery.Children.Count, Is.EqualTo(1)); + + var orderItemsChildQuery = ordersChildQuery.Children.FirstOrDefault(x => x.GetType() == typeof(CustomerOrderItemsQuery)); + Assert.IsNotNull(orderItemsChildQuery); + } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/DataProvider.Tests/TransformExecutorTests.cs b/tests/Schemio.Object.Tests/DataProvider.Tests/TransformExecutorTests.cs new file mode 100644 index 0000000..2f08ac8 --- /dev/null +++ b/tests/Schemio.Object.Tests/DataProvider.Tests/TransformExecutorTests.cs @@ -0,0 +1,92 @@ +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Impl; +using Schemio.Object.Tests.EntitySetup; +using Schemio.Object.Tests.EntitySetup.Queries; + +namespace Schemio.Object.Tests.DataProvider +{ + [TestFixture] + internal class TransformExecutorTests + { + private TransformExecutor _transformExecutor; + private IEntitySchema _entitySchema; + + private static List<(Type result, int InvocationCount)> TransformerInvocations; + + [SetUp] + public void Setup() + { + _entitySchema = new MockCustomerSchema(); + _transformExecutor = new TransformExecutor(_entitySchema); + TransformerInvocations = new List<(Type result, int InvocationCount)>(); + } + + [Test] + public void TestTransformExecutorForCorrectExecutionOfConfiguredTransforms() + { + var queryList = new List + { + new CustomerResult{Id = 123, CustomerCode= "ABC", CustomerName="Ninja Labs"}, + new CommunicationResult{Id = 123, Email = "ninja@labs.com", Telephone = "0212345689"}, + new OrderCollectionResult(), + new OrderItemCollectionResult() + }; + + var entity = _transformExecutor.Execute(new CustomerContext { CustomerId = 1 }, queryList); + + var customerTransforms = TransformerInvocations.Where(x => x.result == typeof(CustomerResult)); + Assert.That(customerTransforms.Count() == 1); + Assert.That(customerTransforms.ElementAt(0).InvocationCount == 1); + + var communicationTransforms = TransformerInvocations.Where(x => x.result == typeof(CommunicationResult)); + Assert.That(communicationTransforms.Count() == 1); + Assert.That(communicationTransforms.ElementAt(0).InvocationCount == 1); + + var orderCollectionTransforms = TransformerInvocations.Where(x => x.result == typeof(OrderCollectionResult)); + Assert.That(orderCollectionTransforms.Count() == 1); + Assert.That(orderCollectionTransforms.ElementAt(0).InvocationCount == 1); + + var orderItemsCollectionTransforms = TransformerInvocations.Where(x => x.result == typeof(OrderItemCollectionResult)); + Assert.That(orderItemsCollectionTransforms.Count() == 1); + Assert.That(orderItemsCollectionTransforms.ElementAt(0).InvocationCount == 1); + + Assert.IsNotNull(entity); + } + + public class MockTransform : BaseTransformer + where TEntity : IEntity + where TQueryResult : IQueryResult + { + public override TEntity Transform(TQueryResult queryResult, TEntity entity) + { + TransformerInvocations.Add((queryResult.GetType(), 1)); + return entity; + } + } + + internal class MockCustomerSchema : IEntitySchema + { + private IEnumerable> mappings; + + private decimal version; + + public IEnumerable> Mappings => mappings; + public decimal Version => version; + + public MockCustomerSchema() + { + version = 1; + + // Create an object mapping graph of query and transformer pairs using xpaths. + mappings = CreateSchema.For() + .Map>(For.Paths("customer/id", "customer/customercode", "customer/customername"), + customer => customer.Dependents + .Map>(For.Paths("customer/communication")) + .Map>(For.Paths("customer/orders"), + customerOrders => customerOrders.Dependents + .Map>(For.Paths("customer/orders/order/items"))) + ).Complete(); + } + } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/DataProvider/CustomerContext.cs b/tests/Schemio.Object.Tests/EntitySetup/CustomerContext.cs similarity index 73% rename from tests/Schemio.Object.Tests/DataProvider/CustomerContext.cs rename to tests/Schemio.Object.Tests/EntitySetup/CustomerContext.cs index 9411b34..886927e 100644 --- a/tests/Schemio.Object.Tests/DataProvider/CustomerContext.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/CustomerContext.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.DataProvider +namespace Schemio.Object.Tests.EntitySetup { internal class CustomerContext : IDataContext { diff --git a/tests/Schemio.Object.Tests/Entities/Address.cs b/tests/Schemio.Object.Tests/EntitySetup/Entities/Address.cs similarity index 81% rename from tests/Schemio.Object.Tests/Entities/Address.cs rename to tests/Schemio.Object.Tests/EntitySetup/Entities/Address.cs index ec724e4..362e645 100644 --- a/tests/Schemio.Object.Tests/Entities/Address.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/Address.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Entities +namespace Schemio.Object.Tests.EntitySetup.Entities { public class Address { diff --git a/tests/Schemio.Object.Tests/Entities/Communication.cs b/tests/Schemio.Object.Tests/EntitySetup/Entities/Communication.cs similarity index 76% rename from tests/Schemio.Object.Tests/Entities/Communication.cs rename to tests/Schemio.Object.Tests/EntitySetup/Entities/Communication.cs index ac3b404..466e1a8 100644 --- a/tests/Schemio.Object.Tests/Entities/Communication.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/Communication.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Entities +namespace Schemio.Object.Tests.EntitySetup.Entities { public class Communication { diff --git a/tests/Schemio.Object.Tests/Entities/Customer.cs b/tests/Schemio.Object.Tests/EntitySetup/Entities/Customer.cs similarity index 81% rename from tests/Schemio.Object.Tests/Entities/Customer.cs rename to tests/Schemio.Object.Tests/EntitySetup/Entities/Customer.cs index 3e88f20..1817594 100644 --- a/tests/Schemio.Object.Tests/Entities/Customer.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/Customer.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Entities +namespace Schemio.Object.Tests.EntitySetup.Entities { public class Customer : IEntity { diff --git a/tests/Schemio.Object.Tests/EntitySetup/Entities/EntityDiagram.cd b/tests/Schemio.Object.Tests/EntitySetup/Entities/EntityDiagram.cd new file mode 100644 index 0000000..3013839 --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/EntityDiagram.cd @@ -0,0 +1,50 @@ + + + + + + AAEAACAAAAAAAAAAAAAAAAAAQAAAABAAAAAAAAIAAAA= + EntitySetup\Entities\Customer.cs + + + + + + + + + + + QAAAAAAAgAAAAAAIIAAAAAAAABIAAAAAAAAAAAAAAAA= + EntitySetup\Entities\Address.cs + + + + + + AAAAAAAAACAAAAAAAAAAAAAAAAAAAAECAAAAIAAAAAA= + EntitySetup\Entities\Communication.cs + + + + + + + + + EAAAAAAAAAAACAAAAAAAAAAAAAAAAAABAAAAAAAAAAI= + EntitySetup\Entities\Order.cs + + + + + + + + + AAAAAAAAAAAAAAAAgAAAABQAAAAAAAAAAAAAAAAAAAA= + EntitySetup\Entities\OrderItem.cs + + + + \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Entities/Order.cs b/tests/Schemio.Object.Tests/EntitySetup/Entities/Order.cs similarity index 75% rename from tests/Schemio.Object.Tests/Entities/Order.cs rename to tests/Schemio.Object.Tests/EntitySetup/Entities/Order.cs index f1be999..cdc90d2 100644 --- a/tests/Schemio.Object.Tests/Entities/Order.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/Order.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Entities +namespace Schemio.Object.Tests.EntitySetup.Entities { public class Order { diff --git a/tests/Schemio.Object.Tests/Entities/OrderItem.cs b/tests/Schemio.Object.Tests/EntitySetup/Entities/OrderItem.cs similarity index 70% rename from tests/Schemio.Object.Tests/Entities/OrderItem.cs rename to tests/Schemio.Object.Tests/EntitySetup/Entities/OrderItem.cs index cd52fc2..5fa1771 100644 --- a/tests/Schemio.Object.Tests/Entities/OrderItem.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Entities/OrderItem.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Entities +namespace Schemio.Object.Tests.EntitySetup.Entities { public class OrderItem { diff --git a/tests/Schemio.Object.Tests/EntitySchemas/CustomerSchema.cs b/tests/Schemio.Object.Tests/EntitySetup/EntitySchemas/CustomerSchema.cs similarity index 80% rename from tests/Schemio.Object.Tests/EntitySchemas/CustomerSchema.cs rename to tests/Schemio.Object.Tests/EntitySetup/EntitySchemas/CustomerSchema.cs index 909617a..b21e673 100644 --- a/tests/Schemio.Object.Tests/EntitySchemas/CustomerSchema.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/EntitySchemas/CustomerSchema.cs @@ -1,9 +1,8 @@ -using Schemio.Object.Core; -using Schemio.Object.Tests.Entities; -using Schemio.Object.Tests.Queries; -using Schemio.Object.Tests.Transforms; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup.Queries; +using Schemio.Object.Tests.EntitySetup.Transforms; -namespace Schemio.Object.Tests.EntitySchemas +namespace Schemio.Object.Tests.EntitySetup.EntitySchemas { internal class CustomerSchema : IEntitySchema { @@ -25,7 +24,7 @@ public CustomerSchema() .Map(For.Paths("customer/communication")) .Map(For.Paths("customer/orders"), customerOrders => customerOrders.Dependents - .Map(For.Paths("customer/orders/order/Items"))) + .Map(For.Paths("customer/orders/order/items"))) ).Complete(); } } diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/CommunicationResult.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CommunicationResult.cs new file mode 100644 index 0000000..29d720b --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CommunicationResult.cs @@ -0,0 +1,14 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + public class CommunicationResult : IQueryResult + { + public int Id { get; set; } + public string Telephone { get; set; } + public string Email { get; set; } + public string HouseNo { get; set; } + public string City { get; set; } + public string Region { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Queries/CustomerCommunicationQuery.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerCommunicationQuery.cs similarity index 57% rename from tests/Schemio.Object.Tests/Queries/CustomerCommunicationQuery.cs rename to tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerCommunicationQuery.cs index 73ecaa7..3c19b86 100644 --- a/tests/Schemio.Object.Tests/Queries/CustomerCommunicationQuery.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerCommunicationQuery.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Queries +namespace Schemio.Object.Tests.EntitySetup.Queries { internal class CustomerCommunicationQuery : BaseQuery { @@ -19,16 +17,4 @@ public override void ResolveParameterInChildMode(IDataContext context, IQueryRes }; } } - - public class CommunicationResult : IQueryResult - { - public int Id { get; set; } - public string Telephone { get; set; } - public string Email { get; set; } - public string HouseNo { get; set; } - public string City { get; set; } - public string Region { get; set; } - public string PostalCode { get; set; } - public string Country { get; set; } - } } \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Queries/CustomerOrderItemsQuery.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrderItemsQuery.cs similarity index 59% rename from tests/Schemio.Object.Tests/Queries/CustomerOrderItemsQuery.cs rename to tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrderItemsQuery.cs index 1e46ce6..3d032aa 100644 --- a/tests/Schemio.Object.Tests/Queries/CustomerOrderItemsQuery.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrderItemsQuery.cs @@ -1,6 +1,4 @@ -using Schemio.Object.Core; - -namespace Schemio.Object.Tests.Queries +namespace Schemio.Object.Tests.EntitySetup.Queries { internal class CustomerOrderItemsQuery : BaseQuery { @@ -19,20 +17,4 @@ public override void ResolveParameterInChildMode(IDataContext context, IQueryRes }; } } - - public class OrderItemCollectionResult : IQueryResult - { - public List OrderItems { get; set; } - } - - public class OrderItemValue - { - public int OrderId { get; set; } - public (int ItemId, string Name, decimal Cost)[] Items { get; set; } - } - - internal class OrderItemParameter : IQueryParameter - { - public List OrderIds { get; set; } - } } \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Queries/CustomerOrdersQuery.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrdersQuery.cs similarity index 58% rename from tests/Schemio.Object.Tests/Queries/CustomerOrdersQuery.cs rename to tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrdersQuery.cs index aeaf1d4..78e02b6 100644 --- a/tests/Schemio.Object.Tests/Queries/CustomerOrdersQuery.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerOrdersQuery.cs @@ -1,7 +1,4 @@ -using Schemio.Object.Core; -using Schemio.Object.Tests.DataProvider; - -namespace Schemio.Object.Tests.Queries +namespace Schemio.Object.Tests.EntitySetup.Queries { internal class CustomerOrdersQuery : BaseQuery { @@ -20,17 +17,4 @@ public override void ResolveParameterInChildMode(IDataContext context, IQueryRes // Does not execute as child to any query. } } - - public class OrderCollectionResult : IQueryResult - { - public int CustomerId { get; set; } - public OrderValue[] Orders { get; set; } - } - - public class OrderValue - { - public int OrderId { get; set; } - public string OrderNo { get; set; } - public DateTime Date { get; set; } - } } \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerParameter.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerParameter.cs new file mode 100644 index 0000000..7e2a7a0 --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerParameter.cs @@ -0,0 +1,7 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + public class CustomerParameter : IQueryParameter + { + public int CustomerId { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Queries/CustomerQuery.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerQuery.cs similarity index 59% rename from tests/Schemio.Object.Tests/Queries/CustomerQuery.cs rename to tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerQuery.cs index 55400a7..77debdd 100644 --- a/tests/Schemio.Object.Tests/Queries/CustomerQuery.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerQuery.cs @@ -1,7 +1,4 @@ -using Schemio.Object.Core; -using Schemio.Object.Tests.DataProvider; - -namespace Schemio.Object.Tests.Queries +namespace Schemio.Object.Tests.EntitySetup.Queries { public class CustomerQuery : BaseQuery { @@ -20,16 +17,4 @@ public override void ResolveParameterInChildMode(IDataContext context, IQueryRes // Does not execute as child to any query. } } - - public class CustomerResult : IQueryResult - { - public int Id { get; set; } - public string CustomerCode { get; set; } - public string CustomerName { get; set; } - } - - public class CustomerParameter : IQueryParameter - { - public int CustomerId { get; set; } - } } \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerResult.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerResult.cs new file mode 100644 index 0000000..c67dd65 --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/CustomerResult.cs @@ -0,0 +1,9 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + public class CustomerResult : IQueryResult + { + public int Id { get; set; } + public string CustomerCode { get; set; } + public string CustomerName { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderCollectionResult.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderCollectionResult.cs new file mode 100644 index 0000000..7ceb0d6 --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderCollectionResult.cs @@ -0,0 +1,15 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + public class OrderCollectionResult : IQueryResult + { + public int CustomerId { get; set; } + public OrderValue[] Orders { get; set; } + } + + public class OrderValue + { + public int OrderId { get; set; } + public string OrderNo { get; set; } + public DateTime Date { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemCollectionResult.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemCollectionResult.cs new file mode 100644 index 0000000..0f4bcc2 --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemCollectionResult.cs @@ -0,0 +1,13 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + public class OrderItemCollectionResult : IQueryResult + { + public List OrderItems { get; set; } + } + + public class OrderItemValue + { + public int OrderId { get; set; } + public (int ItemId, string Name, decimal Cost)[] Items { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemParameter.cs b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemParameter.cs new file mode 100644 index 0000000..eed9b6e --- /dev/null +++ b/tests/Schemio.Object.Tests/EntitySetup/Queries/OrderItemParameter.cs @@ -0,0 +1,7 @@ +namespace Schemio.Object.Tests.EntitySetup.Queries +{ + internal class OrderItemParameter : IQueryParameter + { + public List OrderIds { get; set; } + } +} \ No newline at end of file diff --git a/tests/Schemio.Object.Tests/Transforms/CustomerCommunicationTransform.cs b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerCommunicationTransform.cs similarity index 85% rename from tests/Schemio.Object.Tests/Transforms/CustomerCommunicationTransform.cs rename to tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerCommunicationTransform.cs index 108c75e..df7b6ca 100644 --- a/tests/Schemio.Object.Tests/Transforms/CustomerCommunicationTransform.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerCommunicationTransform.cs @@ -1,7 +1,7 @@ -using Schemio.Object.Tests.Entities; -using Schemio.Object.Tests.Queries; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup.Queries; -namespace Schemio.Object.Tests.Transforms +namespace Schemio.Object.Tests.EntitySetup.Transforms { public class CustomerCommunicationTransform : BaseTransformer { diff --git a/tests/Schemio.Object.Tests/Transforms/CustomerOrderItemsTransform.cs b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrderItemsTransform.cs similarity index 81% rename from tests/Schemio.Object.Tests/Transforms/CustomerOrderItemsTransform.cs rename to tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrderItemsTransform.cs index bc45a66..d5c780e 100644 --- a/tests/Schemio.Object.Tests/Transforms/CustomerOrderItemsTransform.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrderItemsTransform.cs @@ -1,7 +1,7 @@ -using Schemio.Object.Tests.Entities; -using Schemio.Object.Tests.Queries; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup.Queries; -namespace Schemio.Object.Tests.Transforms +namespace Schemio.Object.Tests.EntitySetup.Transforms { public class CustomerOrderItemsTransform : BaseTransformer { @@ -12,17 +12,13 @@ public override Customer Transform(OrderItemCollectionResult queryResult, Custom foreach (var item in queryResult.OrderItems.Where(x => x.Items != null)) foreach (var order in entity.Orders) - { if (order.OrderId == item.OrderId) - { order.Items = item.Items.Select(x => new OrderItem { ItemId = x.ItemId, Name = x.Name, Cost = x.Cost }).ToArray(); - } - } return entity; } diff --git a/tests/Schemio.Object.Tests/Transforms/CustomerOrdersTransform.cs b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrdersTransform.cs similarity index 79% rename from tests/Schemio.Object.Tests/Transforms/CustomerOrdersTransform.cs rename to tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrdersTransform.cs index 2455ce6..4d69301 100644 --- a/tests/Schemio.Object.Tests/Transforms/CustomerOrdersTransform.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerOrdersTransform.cs @@ -1,7 +1,7 @@ -using Schemio.Object.Tests.Entities; -using Schemio.Object.Tests.Queries; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup.Queries; -namespace Schemio.Object.Tests.Transforms +namespace Schemio.Object.Tests.EntitySetup.Transforms { public class CustomerOrdersTransform : BaseTransformer { diff --git a/tests/Schemio.Object.Tests/Transforms/CustomerTransform.cs b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerTransform.cs similarity index 75% rename from tests/Schemio.Object.Tests/Transforms/CustomerTransform.cs rename to tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerTransform.cs index 514f396..cdc00a7 100644 --- a/tests/Schemio.Object.Tests/Transforms/CustomerTransform.cs +++ b/tests/Schemio.Object.Tests/EntitySetup/Transforms/CustomerTransform.cs @@ -1,8 +1,7 @@ -using Schemio.Object.Core; -using Schemio.Object.Tests.Entities; -using Schemio.Object.Tests.Queries; +using Schemio.Object.Tests.EntitySetup.Entities; +using Schemio.Object.Tests.EntitySetup.Queries; -namespace Schemio.Object.Tests.Transforms +namespace Schemio.Object.Tests.EntitySetup.Transforms { public class CustomerTransform : BaseTransformer { diff --git a/tests/Schemio.Object.Tests/Schemio.Object.Tests.csproj b/tests/Schemio.Object.Tests/Schemio.Object.Tests.csproj index c9fabde..3aa0550 100644 --- a/tests/Schemio.Object.Tests/Schemio.Object.Tests.csproj +++ b/tests/Schemio.Object.Tests/Schemio.Object.Tests.csproj @@ -10,6 +10,7 @@ + diff --git a/tests/Schemio.Object.Tests/UnitTest1.cs b/tests/Schemio.Object.Tests/UnitTest1.cs index c8f2236..8661426 100644 --- a/tests/Schemio.Object.Tests/UnitTest1.cs +++ b/tests/Schemio.Object.Tests/UnitTest1.cs @@ -1,4 +1,4 @@ -namespace Data2Xml.Tests +namespace Schemio.Object.Tests { public class Tests {