Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Dealing w/ the proper async returns. Closes GH-5
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremydmiller committed Dec 16, 2016
1 parent a8e74b5 commit b24bb54
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 58 deletions.
38 changes: 34 additions & 4 deletions src/Jasper.Testing/Codegen/CompilationContext.cs
Expand Up @@ -17,12 +17,25 @@ public class CompilationContext
public CompilationContext()
{
theChain = new HandlerChain($"Handler{++_number}",
typeof(IMainInputHandler));
typeof(IInputHandler));
}

protected string theGeneratedCode
{
get
{
var config = new GenerationConfig("Jasper.Testing.Codegen.Generated");
config.Assemblies.Add(GetType().GetTypeInfo().Assembly);

var @set = new HandlerSet<MainInput, HandlerChain>(config, "input");

@set.Add(theChain);

return @set.GenerateCode();
}
}

private IHandler<MainInput> generate()
private IInputHandler generate()
{
var config = new GenerationConfig("Jasper.Testing.Codegen.Generated");
config.Assemblies.Add(GetType().GetTypeInfo().Assembly);
Expand All @@ -31,9 +44,12 @@ private IHandler<MainInput> generate()

@set.Add(theChain);

var code = @set.GenerateCode();
Console.WriteLine(code);

var type = @set.CompileAll().Single();

return (IHandler<MainInput>) Activator.CreateInstance(type);
return (IInputHandler) Activator.CreateInstance(type);
}

protected Task<MainInput> afterRunning()
Expand All @@ -45,7 +61,7 @@ protected Task<MainInput> afterRunning()
}
}

public interface IMainInputHandler : IHandler<MainInput>
public interface IInputHandler : IHandler<MainInput>
{

}
Expand All @@ -59,9 +75,23 @@ public void Touch()
WasTouched = true;
}

public void DoSync()
{

}

public Task TouchAsync()
{
return Task.Factory.StartNew(Touch);
}

public Task DifferentAsync()
{
DifferentWasCalled = true;
return Task.CompletedTask;
}

public bool DifferentWasCalled { get; set; }
}

}
43 changes: 43 additions & 0 deletions src/Jasper.Testing/Codegen/HandlerGenerationTests.cs
@@ -0,0 +1,43 @@
using Jasper.Codegen;
using Shouldly;
using Xunit;

namespace Jasper.Testing.Codegen
{
public class HandlerGenerationTests: CompilationContext
{
private AsyncMode theAsyncMode => new HandlerGeneration(theChain, new GenerationConfig("Something"), "input")
.AsyncMode;

[Fact]
public void detects_that_it_is_all_sync()
{
theChain.Call<MainInput>(x => x.DoSync());

theAsyncMode.ShouldBe(AsyncMode.ReturnCompletedTask);

theChain.Call<MainInput>(x => x.Touch());

theAsyncMode.ShouldBe(AsyncMode.ReturnCompletedTask);
}

[Fact]
public void detects_chain_as_async_task_if_multiple_asyncs()
{
theChain.Call<MainInput>(x => x.DoSync());
theChain.Call<MainInput>(x => x.TouchAsync());
theChain.Call<MainInput>(x => x.DifferentAsync());

theAsyncMode.ShouldBe(AsyncMode.AsyncTask);
}

[Fact]
public void use_async_task_if_one_async_that_is_not_last()
{
theChain.Call<MainInput>(x => x.DoSync());
theChain.Call<MainInput>(x => x.TouchAsync());

theAsyncMode.ShouldBe(AsyncMode.ReturnFromLastNode);
}
}
}
51 changes: 51 additions & 0 deletions src/Jasper.Testing/Codegen/ReflectionExtensionsTester.cs
@@ -0,0 +1,51 @@
using System.Threading.Tasks;
using Baseline.Reflection;
using Jasper.Codegen;
using Shouldly;
using Xunit;

namespace Jasper.Testing.Codegen
{
public class ReflectionExtensionsTester
{
[Fact]
public void not_async()
{
ReflectionHelper.GetMethod<ReflectionExtensionsTester>(x => x.Go())
.IsAsync().ShouldBeFalse();

ReflectionHelper.GetMethod<ReflectionExtensionsTester>(x => x.IsTrue())
.IsAsync().ShouldBeFalse();
}

[Fact]
public void is_async()
{
ReflectionHelper.GetMethod<ReflectionExtensionsTester>(x => x.DoAsync())
.IsAsync().ShouldBeTrue();

ReflectionHelper.GetMethod<ReflectionExtensionsTester>(x => x.IsTrueAsync())
.IsAsync().ShouldBeTrue();
}

public void Go()
{

}

public bool IsTrue()
{
return true;
}

public Task DoAsync()
{
return Task.CompletedTask;
}

public Task<bool> IsTrueAsync()
{
return Task.FromResult(true);
}
}
}
62 changes: 62 additions & 0 deletions src/Jasper.Testing/Codegen/simple_method_calls_in_handler_chain.cs
@@ -0,0 +1,62 @@
using System.Threading.Tasks;
using Jasper.Codegen;
using Shouldly;
using Xunit;

namespace Jasper.Testing.Codegen
{
public class simple_method_calls_in_handler_chain : CompilationContext
{
[Fact]
public async Task generate_with_async_handler()
{
theChain.Call<MainInput>(x => x.TouchAsync());

var input = await afterRunning();

input.WasTouched.ShouldBeTrue();

theGeneratedCode.ShouldContain("public Task Handle(");
}

[Fact]
public async Task generate_with_multiple_async_handler()
{
theChain.Call<MainInput>(x => x.TouchAsync());
theChain.Call<MainInput>(x => x.DifferentAsync());

var input = await afterRunning();

input.WasTouched.ShouldBeTrue();

theGeneratedCode.ShouldContain("public async Task Handle(");
}

[Fact]
public async Task generate_with_sync_handler()
{
theChain.Call<MainInput>(x => x.Touch());

var input = await afterRunning();

input.WasTouched.ShouldBeTrue();

theGeneratedCode.ShouldContain("return Task.CompletedTask;");
}


[Fact]
public async Task generate_with_mixed_sync_and_async_handler()
{
theChain.Call<MainInput>(x => x.DifferentAsync());
theChain.Call<MainInput>(x => x.Touch());

var input = await afterRunning();

input.WasTouched.ShouldBeTrue();
input.DifferentWasCalled.ShouldBeTrue();
}


}
}
5 changes: 5 additions & 0 deletions src/Jasper/Codegen/Compilation/SourceWriter.cs
Expand Up @@ -71,6 +71,11 @@ private void StartBlock()

public void FinishBlock(string extra = null)
{
if (IndentionLevel == 0)
{
throw new InvalidOperationException("Not currently in a code block");
}

IndentionLevel--;

if (extra.IsEmpty())
Expand Down
6 changes: 5 additions & 1 deletion src/Jasper/Codegen/Compilation/SourceWriterExtensions.cs
@@ -1,3 +1,4 @@

namespace Jasper.Codegen.Compilation
{
public static class SourceWriterExtensions
Expand All @@ -7,6 +8,9 @@ public static void Namespace(this ISourceWriter writer, string @namespace)
writer.Write($"BLOCK:namespace {@namespace}");
}


public static void Using<T>(this ISourceWriter writer)
{
writer.Write($"using {typeof(T).Namespace};");
}
}
}
6 changes: 3 additions & 3 deletions src/Jasper/Codegen/Frame.cs
Expand Up @@ -21,11 +21,11 @@ protected Frame(bool isAsync)
IsAsync = isAsync;
}

public abstract void GenerateCode(HandlerGeneration chain, ISourceWriter writer);
public abstract void GenerateCode(HandlerGeneration generation, ISourceWriter writer);

// Going to say that other policies will deal w/ the existence of wrappers
// Go find necessary variables, add any necessary wrappers
public virtual void ResolveVariables(HandlerChain chain)
public virtual void ResolveVariables(HandlerGeneration chain)
{
// nothing
}
Expand All @@ -34,6 +34,6 @@ public virtual void ResolveVariables(HandlerChain chain)
// including dependents
// Use a visitor to find that?


public virtual bool CanReturnTask() => false;
}
}

0 comments on commit b24bb54

Please sign in to comment.