Skip to content

Commit 552ab7b

Browse files
committed
multi-source providers done, closes #10
1 parent 40ffa05 commit 552ab7b

21 files changed

Lines changed: 266 additions & 84 deletions

TestingContext/Implementation/Filters/IFilter.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
using TestingContextCore.Implementation.ResolutionContext;
66
using TestingContextCore.Implementation.TreeOperation.Nodes;
77

8-
internal interface IFilter : IFailure
8+
internal interface IFilter : IHaveDependencies, IFailure
99
{
10-
IDependency[] Dependencies { get; }
11-
1210
bool MeetsCondition(IResolutionContext context, NodeResolver resolver, out int[] failureWeight, out IFailure failure);
1311
}
1412
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace TestingContextCore.Implementation
2+
{
3+
using TestingContextCore.Implementation.Dependencies;
4+
5+
internal interface IHaveDependencies
6+
{
7+
IDependency[] Dependencies { get; }
8+
}
9+
}

TestingContext/Implementation/Providers/IProvider.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
using TestingContextCore.Implementation.ResolutionContext;
66
using TestingContextCore.Implementation.TreeOperation.Nodes;
77

8-
internal interface IProvider
8+
internal interface IProvider : IHaveDependencies
99
{
10-
IDependency Dependency { get; }
11-
1210
IEnumerable<IResolutionContext> Resolve(IResolutionContext parentContext, INode node);
1311
}
1412
}

TestingContext/Implementation/Providers/Provider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ public Provider(IDependency<TSource> dependency,
1818
{
1919
this.dependency = dependency;
2020
this.sourceFunc = sourceFunc;
21+
Dependencies = new IDependency[] { dependency };
2122
}
2223

23-
public IDependency Dependency => dependency;
24+
public IDependency[] Dependencies { get; }
2425

2526
public IEnumerable<IResolutionContext> Resolve(IResolutionContext parentContext, INode node)
2627
{
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace TestingContextCore.Implementation.Providers
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using TestingContextCore.Implementation.Dependencies;
7+
using TestingContextCore.Implementation.ResolutionContext;
8+
using TestingContextCore.Implementation.TreeOperation.Nodes;
9+
10+
internal class Provider2<TSource1, TSource2, T> : IProvider
11+
{
12+
private readonly IDependency<TSource1> dependency1;
13+
private readonly IDependency<TSource2> dependency2;
14+
private readonly Func<TSource1, TSource2, IEnumerable<T>> sourceFunc;
15+
16+
public Provider2(IDependency<TSource1> dependency1, IDependency<TSource2> dependency2,
17+
Func<TSource1, TSource2, IEnumerable<T>> sourceFunc)
18+
{
19+
this.dependency1 = dependency1;
20+
this.dependency2 = dependency2;
21+
this.sourceFunc = sourceFunc;
22+
Dependencies = new IDependency[] { dependency1, dependency2 };
23+
}
24+
25+
public IDependency[] Dependencies { get; }
26+
27+
public IEnumerable<IResolutionContext> Resolve(IResolutionContext parentContext, INode node)
28+
{
29+
TSource1 sourceValue1;
30+
TSource2 sourceValue2;
31+
if (!dependency1.TryGetValue(parentContext, out sourceValue1)
32+
|| !dependency2.TryGetValue(parentContext, out sourceValue2))
33+
{
34+
return Enumerable.Empty<IResolutionContext>();
35+
}
36+
37+
var source = sourceFunc(sourceValue1, sourceValue2) ?? Enumerable.Empty<T>();
38+
return source
39+
.Select(x => new ResolutionContext<T>(x, node, parentContext))
40+
.Cache();
41+
}
42+
}
43+
}

TestingContext/Implementation/Registrations/ProviderCreator.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using TestingContextCore.Interfaces;
1010
using static Definition;
1111

12-
internal abstract class ProviderCreator<T1> : ICreateProvider<T1>
12+
internal abstract class ProviderCreator<T1>
1313
{
1414
private readonly Definition definition;
1515
private readonly RegistrationStore store;
@@ -22,19 +22,19 @@ protected ProviderCreator(Definition definition, RegistrationStore store)
2222

2323
public void Exists<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
2424
{
25-
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => x.Any(y => y.MeetsConditions), Define<T2>(key)), null);
25+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => x.Any(y => y.MeetsConditions), Define<T2>(key)));
2626
CreateProvider(key, srcFunc);
2727
}
2828

2929
public void DoesNotExist<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
3030
{
31-
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => !x.Any(y => y.MeetsConditions), Define<T2>(key)), null);
31+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => !x.Any(y => y.MeetsConditions), Define<T2>(key)));
3232
CreateProvider(key, srcFunc);
3333
}
3434

3535
public void Each<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
3636
{
37-
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => x.All(y => y.MeetsConditions), Define<T2>(key)), null);
37+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => x.All(y => y.MeetsConditions), Define<T2>(key)));
3838
CreateProvider(key, srcFunc);
3939
}
4040

TestingContext/Implementation/Registrations/Registration1.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56
using System.Linq.Expressions;
67
using TestingContextCore.Implementation.Dependencies;
78
using TestingContextCore.Implementation.Filters;
9+
using TestingContextCore.Implementation.Providers;
10+
using TestingContextCore.Implementation.ResolutionContext;
811
using TestingContextCore.Interfaces;
912
using static Definition;
1013

11-
internal class Registration1<T1> : ProviderCreator<T1>, IFor<T1>, IForAll<T1>
14+
internal class Registration1<T1> : IFor<T1>
1215
{
1316
private readonly IDependency<T1> dependency;
1417
private readonly RegistrationStore store;
1518

16-
public Registration1(IDependency<T1> dependency, RegistrationStore store) : base(dependency.Definition, store)
19+
public Registration1(IDependency<T1> dependency, RegistrationStore store)
1720
{
1821
this.dependency = dependency;
1922
this.store = store;
@@ -35,5 +38,51 @@ public IFor<T1, IEnumerable<T2>> ForAll<T2>(string key)
3538
var second = new CollectionDependency<T2>(Define<T2>(key));
3639
return new Registration2<T1, IEnumerable<T2>>(dependency, second, store);
3740
}
41+
42+
public void Exists<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
43+
{
44+
CreateFilter<T2>(key, x => x.Any(y => y.MeetsConditions));
45+
CreateProvider(key, srcFunc);
46+
}
47+
48+
public void DoesNotExist<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
49+
{
50+
CreateFilter<T2>(key, x => !x.Any(y => y.MeetsConditions));
51+
CreateProvider(key, srcFunc);
52+
}
53+
54+
public void Each<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
55+
{
56+
CreateFilter<T2>(key, x => x.All(y => y.MeetsConditions));
57+
CreateProvider(key, srcFunc);
58+
}
59+
60+
public void Satisfies<T2>(string key, Func<T1, T2> srcFunc)
61+
{
62+
Exists(key, x =>
63+
{
64+
var item = srcFunc(x);
65+
return item == null ? Enumerable.Empty<T2>() : new[] { item };
66+
});
67+
}
68+
69+
public void DoesNotSatisfy<T2>(string key, Func<T1, T2> srcFunc)
70+
{
71+
DoesNotExist(key, x =>
72+
{
73+
var item = srcFunc(x);
74+
return item == null ? Enumerable.Empty<T2>() : new[] { item };
75+
});
76+
}
77+
78+
private void CreateFilter<T2>(string key, Expression<Func<IEnumerable<IResolutionContext>, bool>> func)
79+
{
80+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(func, Define<T2>(key)));
81+
}
82+
83+
private void CreateProvider<T2>(string key, Func<T1, IEnumerable<T2>> srcFunc)
84+
{
85+
store.RegisterProvider(Define<T2>(key), new Provider<T1, T2>(dependency, srcFunc));
86+
}
3887
}
3988
}

TestingContext/Implementation/Registrations/Registration2.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
namespace TestingContextCore.Implementation.Registrations
22
{
33
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
46
using System.Linq.Expressions;
57
using TestingContextCore.Implementation.Dependencies;
68
using TestingContextCore.Implementation.Filters;
9+
using TestingContextCore.Implementation.Providers;
10+
using TestingContextCore.Implementation.ResolutionContext;
711
using TestingContextCore.Interfaces;
12+
using static Definition;
813

9-
internal class Registration2<T1, T2> :IFor<T1, T2>
14+
internal class Registration2<T1, T2> : IFor<T1, T2>
1015
{
1116
private readonly IDependency<T1> dependency1;
1217
private readonly IDependency<T2> dependency2;
@@ -23,5 +28,51 @@ public void IsTrue(Expression<Func<T1, T2, bool>> filter, string key = null)
2328
{
2429
store.RegisterFilter(new Filter2<T1, T2>(dependency1, dependency2, filter, key), key);
2530
}
31+
32+
public void Exists<T3>(string key, Func<T1, T2, IEnumerable<T3>> srcFunc)
33+
{
34+
CreateFilter<T3>(key, x => x.Any(y => y.MeetsConditions));
35+
CreateProvider(key, srcFunc);
36+
}
37+
38+
public void DoesNotExist<T3>(string key, Func<T1, T2, IEnumerable<T3>> srcFunc)
39+
{
40+
CreateFilter<T3>(key, x => !x.Any(y => y.MeetsConditions));
41+
CreateProvider(key, srcFunc);
42+
}
43+
44+
public void Each<T3>(string key, Func<T1, T2, IEnumerable<T3>> srcFunc)
45+
{
46+
CreateFilter<T3>(key, x => x.All(y => y.MeetsConditions));
47+
CreateProvider(key, srcFunc);
48+
}
49+
50+
public void Satisfies<T3>(string key, Func<T1, T2, T3> srcFunc)
51+
{
52+
Exists(key, (x, y) =>
53+
{
54+
var item = srcFunc(x, y);
55+
return item == null ? Enumerable.Empty<T3>() : new[] { item };
56+
});
57+
}
58+
59+
public void DoesNotSatisfy<T3>(string key, Func<T1, T2, T3> srcFunc)
60+
{
61+
DoesNotExist(key, (x, y) =>
62+
{
63+
var item = srcFunc(x, y);
64+
return item == null ? Enumerable.Empty<T3>() : new[] { item };
65+
});
66+
}
67+
68+
private void CreateFilter<T3>(string key, Expression<Func<IEnumerable<IResolutionContext>, bool>> func)
69+
{
70+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(func, Define<T3>(key)));
71+
}
72+
73+
private void CreateProvider<T3>(string key, Func<T1, T2, IEnumerable<T3>> srcFunc)
74+
{
75+
store.RegisterProvider(Define<T2>(key), new Provider2<T1, T2, T3>(dependency1, dependency2, srcFunc));
76+
}
2677
}
2778
}

TestingContext/Implementation/Registrations/RegistrationExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static void RegisterFilter(this RegistrationStore store, IFilter filter,
1111
store.Filters.Add(filter);
1212
}
1313

14-
public static void RegisterCollectionValidityFilter(this RegistrationStore store, IFilter filter, string key)
14+
public static void RegisterCollectionValidityFilter(this RegistrationStore store, IFilter filter)
1515
{
1616
PreRegister(store);
1717
store.CollectionValidityFilters.Add(filter);

TestingContext/Implementation/Registrations/RootRegistration.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Linq;
56
using TestingContextCore.Implementation.Dependencies;
7+
using TestingContextCore.Implementation.Filters;
8+
using TestingContextCore.Implementation.Providers;
69
using TestingContextCore.Interfaces;
710
using static Definition;
811

9-
internal class RootRegistration : ProviderCreator<TestingContext> , IForRoot
12+
internal class RootRegistration : IForRoot
1013
{
1114
private readonly RegistrationStore store;
1215

1316
public RootRegistration(RegistrationStore store)
14-
: base(store.RootDefinition, store)
1517
{
1618
this.store = store;
1719
}
@@ -21,19 +23,25 @@ public IFor<T1> For<T1>(string key)
2123
return new Registration1<T1>(new SingleDependency<T1>(Define<T1>(key)), store);
2224
}
2325

24-
public IForAll<IEnumerable<T1>> ForAll<T1>(string key)
26+
public IFor<IEnumerable<T1>> ForAll<T1>(string key)
2527
{
2628
return new Registration1<IEnumerable<T1>>(new CollectionDependency<T1>(Define<T1>(key)), store);
2729
}
2830

29-
public void Items<T2>(string key, Func<IEnumerable<T2>> srcFunc)
31+
public void Items<T>(string key, Func<IEnumerable<T>> srcFunc)
3032
{
31-
Exists(key, x => srcFunc());
33+
store.RegisterCollectionValidityFilter(new CollectionValidityFilter(x => x.Any(y => y.MeetsConditions), Define<T>(key)));
34+
var dependency = new SingleDependency<TestingContext>(store.RootDefinition);
35+
store.RegisterProvider(Define<T>(key), new Provider<TestingContext, T>(dependency, x => srcFunc()));
3236
}
3337

34-
public void Item<T2>(string key, Func<T2> srcFunc)
38+
public void Item<T>(string key, Func<T> srcFunc)
3539
{
36-
Satisfies(key, x => srcFunc());
40+
Items<T>(key, () =>
41+
{
42+
var item = srcFunc();
43+
return item == null ? Enumerable.Empty<T>() : new[] { item };
44+
});
3745
}
3846
}
3947
}

0 commit comments

Comments
 (0)