Skip to content
Permalink
Browse files

Restore lab pipeline

  • Loading branch information...
apobekiaris committed Jul 27, 2019
1 parent a4bf8ab commit 083c6b6b7aac993572ebebd617fe0d778aa591eb
@@ -55,7 +55,7 @@ task Compile -precondition {return $compile } {
InvokeScript{
write-host "Building Tests" -f "Blue"
dotnet restore "$PSScriptRoot\src\Tests\Tests.sln" --source $source
dotnet msbuild "$PSScriptRoot\src\Tests\Tests.sln" "/p:OutDir=$PSScriptRoot\bin"
dotnet msbuild "$PSScriptRoot\src\Tests\Tests.sln" #"/p:OutDir=$PSScriptRoot\bin"
}
}

@@ -1,8 +1,6 @@
using System;
using System.Linq;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Model;
using Fasterflect;
@@ -15,36 +13,10 @@
using Xunit;

namespace Xpand.XAF.Modules.CloneModelView.Tests{
public static class MyRxExtensions{


public static IObservable<T> RetryWithBackoff<T>(this IObservable<T> source,int retryCount = 3,
Func<int, TimeSpan> strategy = null,Func<Exception, bool> retryOnError = null,IScheduler scheduler = null){
strategy = strategy ?? (n =>TimeSpan.FromSeconds(Math.Pow(n, 2))) ;
var attempt = 0;
retryOnError = retryOnError ?? (_ => true);
return Observable.Defer(() => (++attempt == 1 ? source : source.DelaySubscription(strategy(attempt - 1), scheduler))
.Select(item => (true, item, (Exception)null))
.Catch<(bool, T, Exception), Exception>(e =>retryOnError(e)? Observable.Throw<(bool, T, Exception)>(e)
: Observable.Return<(bool, T, Exception)>((false, default, e))))
.Retry(retryCount)
.SelectMany(t => t.Item1
? Observable.Return(t.Item2)
: Observable.Throw<T>(t.Item3));
}

public static IObservable<T> DelaySubscription<T>(this IObservable<T> source,
TimeSpan delay, IScheduler scheduler = null){
if (scheduler == null) return Observable.Timer(delay).SelectMany(_ => source);
return Observable.Timer(delay, scheduler).SelectMany(_ => source);
}
}

[Collection(nameof(CloneModelViewModule))]
public class CloneModelViewTests : BaseTest{
protected async Task Execute(Action action){
await Observable.Defer(() => Observable.Start(action)).RetryWithBackoff(3,retryOnError:exception => true).FirstAsync();
}


[Theory]
[InlineData(CloneViewType.LookupListView, Platform.Win)]
@@ -53,49 +25,45 @@ public class CloneModelViewTests : BaseTest{
[InlineData(CloneViewType.LookupListView,Platform.Web)]
[InlineData(CloneViewType.ListView,Platform.Web)]
[InlineData(CloneViewType.DetailView,Platform.Web)]
internal async Task Clone_Model_View(CloneViewType cloneViewType, Platform platform){
internal void Clone_Model_View(CloneViewType cloneViewType, Platform platform){

await Execute(() => {
var cloneViewId = $"{nameof(Clone_Model_View)}{platform}_{cloneViewType}";

var application = DefaultCloneModelViewModule(info => {
var cloneModelViewAttribute = new CloneModelViewAttribute(cloneViewType, cloneViewId);
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}, platform).Application;
var modelView = application.Model.Views[cloneViewId];
modelView.ShouldNotBeNull();
modelView.GetType().Name.ShouldBe($"Model{cloneViewType.ToString().Replace("Lookup", "")}");
modelView.Id.ShouldBe(cloneViewId);
application.Dispose();
});
var cloneViewId = $"{nameof(Clone_Model_View)}{platform}_{cloneViewType}";

var application = DefaultCloneModelViewModule(info => {
var cloneModelViewAttribute = new CloneModelViewAttribute(cloneViewType, cloneViewId);
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}, platform).Application;
((bool) application.GetPropertyValue("EnableModelCache")).ShouldBe(false);

var modelView = application.Model.Views[cloneViewId];
modelView.ShouldNotBeNull();
modelView.GetType().Name.ShouldBe($"Model{cloneViewType.ToString().Replace("Lookup", "")}");
modelView.Id.ShouldBe(cloneViewId);
application.Dispose();
}

[Theory]
[InlineData(Platform.Web)]
[InlineData(Platform.Win)]
internal async Task Clone_multiple_Model_Views(Platform platform){
await Execute(() => {
var cloneViewId = $"{nameof(Clone_multiple_Model_Views)}{platform}_";
var cloneViewTypes = Enum.GetValues(typeof(CloneViewType)).Cast<CloneViewType>();
var application = DefaultCloneModelViewModule(info => {
foreach (var cloneViewType in cloneViewTypes){
var cloneModelViewAttribute =
new CloneModelViewAttribute(cloneViewType, $"{cloneViewId}{cloneViewType}");
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}
}, platform).Application;
internal void Clone_multiple_Model_Views(Platform platform){
var cloneViewId = $"{nameof(Clone_multiple_Model_Views)}{platform}_";
var cloneViewTypes = Enum.GetValues(typeof(CloneViewType)).Cast<CloneViewType>();
var application = DefaultCloneModelViewModule(info => {
foreach (var cloneViewType in cloneViewTypes){
var viewId = $"{cloneViewId}{cloneViewType}";
var modelView = application.Model.Views[viewId];
modelView.ShouldNotBeNull();
modelView.GetType().Name.ShouldBe($"Model{cloneViewType.ToString().Replace("Lookup", "")}");
modelView.Id.ShouldBe(viewId);
var cloneModelViewAttribute =
new CloneModelViewAttribute(cloneViewType, $"{cloneViewId}{cloneViewType}");
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}
}, platform).Application;
foreach (var cloneViewType in cloneViewTypes){
var viewId = $"{cloneViewId}{cloneViewType}";
var modelView = application.Model.Views[viewId];
modelView.ShouldNotBeNull();
modelView.GetType().Name.ShouldBe($"Model{cloneViewType.ToString().Replace("Lookup", "")}");
modelView.Id.ShouldBe(viewId);
}

application.Dispose();
});
}
application.Dispose(); }

[Theory]
[InlineData(CloneViewType.LookupListView, Platform.Win)]
@@ -104,57 +72,47 @@ public class CloneModelViewTests : BaseTest{
[InlineData(CloneViewType.LookupListView,Platform.Web)]
[InlineData(CloneViewType.ListView,Platform.Web)]
[InlineData(CloneViewType.DetailView,Platform.Web)]
internal async Task Clone_Model_View_and_make_it_default(CloneViewType cloneViewType, Platform platform){
await Execute(() => {
var cloneViewId = $"{nameof(Clone_Model_View_and_make_it_default)}_{cloneViewType}{platform}";
internal void Clone_Model_View_and_make_it_default(CloneViewType cloneViewType, Platform platform){
var cloneViewId = $"{nameof(Clone_Model_View_and_make_it_default)}_{cloneViewType}{platform}";

var application = DefaultCloneModelViewModule(info => {
var cloneModelViewAttribute = new CloneModelViewAttribute(cloneViewType, cloneViewId, true);
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}, platform).Application;
var modelView = application.Model.Views[cloneViewId].AsObjectView;
var application = DefaultCloneModelViewModule(info => {
var cloneModelViewAttribute = new CloneModelViewAttribute(cloneViewType, cloneViewId, true);
info.FindTypeInfo(typeof(CMV)).AddAttribute(cloneModelViewAttribute);
}, platform).Application;
var modelView = application.Model.Views[cloneViewId].AsObjectView;

((IModelView) modelView.ModelClass.GetPropertyValue($"Default{cloneViewType}")).Id
.ShouldBe(cloneViewId);
application.Dispose();
});
}
((IModelView) modelView.ModelClass.GetPropertyValue($"Default{cloneViewType}")).Id
.ShouldBe(cloneViewId);
application.Dispose(); }

[Theory]
[InlineData(CloneViewType.LookupListView, Platform.Win)]
[InlineData(CloneViewType.ListView, Platform.Win)]
[InlineData(CloneViewType.LookupListView,Platform.Web)]
[InlineData(CloneViewType.ListView,Platform.Web)]
internal async Task Clone_Model_ListView_and_change_its_detailview(CloneViewType cloneViewType, Platform platform){
await Execute(() => {
var cloneViewId = $"{nameof(Clone_Model_ListView_and_change_its_detailview)}{platform}_";
var listViewId = $"{cloneViewId}{cloneViewType}";
var detailViewId = $"{cloneViewType}DetailView";
var application = DefaultCloneModelViewModule(info => {
var typeInfo = info.FindTypeInfo(typeof(CMV));
typeInfo.AddAttribute(new CloneModelViewAttribute(CloneViewType.DetailView, detailViewId));
typeInfo.AddAttribute(new CloneModelViewAttribute(cloneViewType, listViewId)
{DetailView = detailViewId});
}, platform).Application;
var modelListView = (IModelListView) application.Model.Views[listViewId];
modelListView.DetailView.Id.ShouldBe(detailViewId);
application.Dispose();
});
}
internal void Clone_Model_ListView_and_change_its_detailview(CloneViewType cloneViewType, Platform platform){
var cloneViewId = $"{nameof(Clone_Model_ListView_and_change_its_detailview)}{platform}_";
var listViewId = $"{cloneViewId}{cloneViewType}";
var detailViewId = $"{cloneViewType}DetailView";
var application = DefaultCloneModelViewModule(info => {
var typeInfo = info.FindTypeInfo(typeof(CMV));
typeInfo.AddAttribute(new CloneModelViewAttribute(CloneViewType.DetailView, detailViewId));
typeInfo.AddAttribute(new CloneModelViewAttribute(cloneViewType, listViewId)
{DetailView = detailViewId});
}, platform).Application;
var modelListView = (IModelListView) application.Model.Views[listViewId];
modelListView.DetailView.Id.ShouldBe(detailViewId);
application.Dispose(); }

private static CloneModelViewModule DefaultCloneModelViewModule(Action<ITypesInfo> customizeTypesInfo,
Platform platform){
private static CloneModelViewModule DefaultCloneModelViewModule(Action<ITypesInfo> customizeTypesInfo,Platform platform){
var application = platform.NewApplication();
application.WhenCustomizingTypesInfo().FirstAsync(info => {
customizeTypesInfo(info);
return true;
})
.Subscribe();
var cloneModelViewModule = new CloneModelViewModule();
cloneModelViewModule.AdditionalExportedTypes.AddRange(new[]{typeof(CMV)});
cloneModelViewModule.RequiredModuleTypes.Add(typeof(ReactiveModule));
application.SetupDefaults(cloneModelViewModule);
return cloneModelViewModule;
application.Modules.Add(new ReactiveModule());
return application.AddModule<CloneModelViewModule>(typeof(CMV));
}
}
}
@@ -15,23 +15,25 @@ public class ModelViewInheritanceTests:BaseTest {
[Theory]
[ClassData(typeof(ModelViewInheritanceTestData))]
internal void Inherit_And_Modify_A_BaseView(ViewType viewType, bool attribute,Platform platform){
ModelViewInheritanceUpdater.Disabled = true;
var models = GetModels(viewType, attribute, platform);
var application = platform.NewApplication();
var modelViewIneritanceModule = CreateModelViewIneritanceModule(viewType, attribute, application);
var testModule1 = new TestModule1{DiffsStore = new StringModelStore(models[0])};
var baseBoTypes = new[]{typeof(ABaseMvi), typeof(TagMvi)};
var boTypes = new[]{typeof(AMvi), typeof(FileMvi)};
testModule1.AdditionalExportedTypes.AddRange(baseBoTypes);
var testModule2 = new TestModule2{DiffsStore = new StringModelStore(models[1])};
testModule2.AdditionalExportedTypes.AddRange(boTypes);
for (int i = 0; i < 30; i++){
ModelViewInheritanceUpdater.Disabled = true;
var models = GetModels(viewType, attribute, platform);
var application = platform.NewApplication();
var modelViewIneritanceModule = CreateModelViewIneritanceModule(viewType, attribute, application);
var testModule1 = new TestModule1{DiffsStore = new StringModelStore(models[0])};
var baseBoTypes = new[]{typeof(ABaseMvi), typeof(TagMvi)};
var boTypes = new[]{typeof(AMvi), typeof(FileMvi)};
testModule1.AdditionalExportedTypes.AddRange(baseBoTypes);
var testModule2 = new TestModule2{DiffsStore = new StringModelStore(models[1])};
testModule2.AdditionalExportedTypes.AddRange(boTypes);

application.SetupDefaults(modelViewIneritanceModule, testModule1, testModule2,
new TestModule3{DiffsStore = new StringModelStore(models[2])});
var inheritAndModifyBaseView = new InheritAndModifyBaseView(application, viewType, attribute);
application.SetupDefaults(modelViewIneritanceModule, testModule1, testModule2,
new TestModule3{DiffsStore = new StringModelStore(models[2])});
var inheritAndModifyBaseView = new InheritAndModifyBaseView(application, viewType, attribute);

inheritAndModifyBaseView.Verify(application.Model);
application.Dispose();
inheritAndModifyBaseView.Verify(application.Model);
application.Dispose();
}
}

private static string[] GetModels(ViewType viewType, bool attribute, Platform platform){
@@ -60,10 +62,11 @@ public class ModelViewInheritanceTests:BaseTest {
private static void CustomizeTypesInfo(ViewType viewType, bool attribute, XafApplication application){
if (attribute){
application.WhenCustomizingTypesInfo()
.Do(_ => {
.FirstAsync(_=> {
_.FindTypeInfo(typeof(AMvi))
.AddAttribute(new ModelMergedDifferencesAttribute($"{nameof(AMvi)}_{viewType}",
$"{nameof(ABaseMvi)}_{viewType}"));
return true;
})
.Subscribe();
}
@@ -1,10 +1,43 @@
using DevExpress.ExpressApp;
using System;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Threading.Tasks;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Xpo;
using Xunit.Abstractions;
using IDisposable = System.IDisposable;

namespace TestsLib{
public static class MyRxExtensions{


public static IObservable<T> RetryWithBackoff<T>(this IObservable<T> source,int retryCount = 3,
Func<int, TimeSpan> strategy = null,Func<Exception, bool> retryOnError = null,IScheduler scheduler = null){
strategy = strategy ?? (n =>TimeSpan.FromSeconds(Math.Pow(n, 2))) ;
var attempt = 0;
retryOnError = retryOnError ?? (_ => true);
return Observable.Defer(() => (++attempt == 1 ? source : source.DelaySubscription(strategy(attempt - 1), scheduler))
.Select(item => (true, item, (Exception)null))
.Catch<(bool, T, Exception), Exception>(e =>retryOnError(e)? Observable.Throw<(bool, T, Exception)>(e)
: Observable.Return<(bool, T, Exception)>((false, default, e))))
.Retry(retryCount)
.SelectMany(t => t.Item1
? Observable.Return(t.Item2)
: Observable.Throw<T>(t.Item3));
}

public static IObservable<T> DelaySubscription<T>(this IObservable<T> source,
TimeSpan delay, IScheduler scheduler = null){
if (scheduler == null) return Observable.Timer(delay).SelectMany(_ => source);
return Observable.Timer(delay, scheduler).SelectMany(_ => source);
}
}

public abstract class BaseTest : IDisposable{

protected async Task Execute(Action action){
await Observable.Defer(() => Observable.Start(action)).RetryWithBackoff(3,retryOnError:exception => true).FirstAsync();
}
public const string NotImplemented = "NotImplemented";
protected BaseTest(ITestOutputHelper output){
Output = output;

0 comments on commit 083c6b6

Please sign in to comment.
You can’t perform that action at this time.