Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv committed Jan 25, 2019
1 parent 1e16d7e commit 898aa41
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 2 deletions.
46 changes: 46 additions & 0 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4820,5 +4820,51 @@ public async System.Threading.Tasks.Task DisposeAsync()
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "MoveNextAsync DisposeAsync Done");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
[WorkItem(32316, "https://github.com/dotnet/roslyn/issues/32316")]
public void PatternBasedDisposal_ReturnsTaskOfInt()
{
string source = @"
using System.Threading.Tasks;
class C
{
public static async Task Main()
{
await foreach (var i in new C())
{
}
System.Console.Write(""Done"");
}
public Enumerator GetAsyncEnumerator()
{
return new Enumerator();
}
public sealed class Enumerator
{
public async System.Threading.Tasks.Task<bool> MoveNextAsync()
{
System.Console.Write(""MoveNextAsync "");
await System.Threading.Tasks.Task.Yield();
return false;
}
public int Current
{
get => throw null;
}
public async System.Threading.Tasks.Task<int> DisposeAsync()
{
System.Console.Write(""DisposeAsync "");
await System.Threading.Tasks.Task.Yield();
return 1;
}
}
}
";
// it's okay to await `Task<int>` even if we don't care about the result
var comp = CreateCompilationWithTasksExtensions(new[] { source, s_IAsyncEnumerable }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "MoveNextAsync DisposeAsync Done");
}
}
}
101 changes: 99 additions & 2 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,18 @@ System.Threading.Tasks.Task<int> M()
// (6,9): error CS0518: Predefined type 'System.IAsyncDisposable' is not defined or imported
// await using (new C())
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await").WithArguments("System.IAsyncDisposable").WithLocation(6, 9),
// (6,9): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<Task<int>>'.
// await using (new C())
Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await").WithArguments("System.Threading.Tasks.Task<int>").WithLocation(6, 9),
// (6,22): error CS8410: 'C': type used in an async using statement must be implicitly convertible to 'System.IAsyncDisposable' or implement a suitable 'DisposeAsync' method.
// await using (new C())
Diagnostic(ErrorCode.ERR_NoConvToIAsyncDisp, "new C()").WithArguments("C").WithLocation(6, 22),
// (9,9): error CS0518: Predefined type 'System.IAsyncDisposable' is not defined or imported
// await using (var x = new C())
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "await").WithArguments("System.IAsyncDisposable").WithLocation(9, 9),
// (9,9): error CS4032: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<Task<int>>'.
// await using (var x = new C())
Diagnostic(ErrorCode.ERR_BadAwaitWithoutAsyncMethod, "await").WithArguments("System.Threading.Tasks.Task<int>").WithLocation(9, 9),
// (9,22): error CS8410: 'C': type used in an async using statement must be implicitly convertible to 'System.IAsyncDisposable' or implement a suitable 'DisposeAsync' method.
// await using (var x = new C())
Diagnostic(ErrorCode.ERR_NoConvToIAsyncDisp, "var x = new C()").WithArguments("C").WithLocation(9, 22),
Expand Down Expand Up @@ -1885,13 +1891,13 @@ public async System.Threading.Tasks.ValueTask DisposeAsync(params int[] x)
{
System.Console.Write($""dispose_start "");
await System.Threading.Tasks.Task.Yield();
System.Console.Write($""dispose_end "");
System.Console.Write($""dispose_end({x.Length}) "");
}
}
";
var comp = CreateCompilationWithTasksExtensions(new[] { source, s_interfaces }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end return");
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end(0) return");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
Expand Down Expand Up @@ -2051,6 +2057,97 @@ public void OnCompleted(System.Action continuation) { }
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end return");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
[WorkItem(32316, "https://github.com/dotnet/roslyn/issues/32316")]
public void TestPatternBasedDisposal_ReturnsTask()
{
string source = @"
public struct C
{
public static async System.Threading.Tasks.Task<int> Main()
{
{
await using var x = new C();
System.Console.Write(""using "");
}
System.Console.Write(""return"");
return 1;
}
public async System.Threading.Tasks.Task DisposeAsync()
{
System.Console.Write($""dispose_start "");
await System.Threading.Tasks.Task.Yield();
System.Console.Write($""dispose_end "");
}
}
";
var comp = CreateCompilationWithTasksExtensions(new[] { source, s_interfaces }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end return");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
[WorkItem(32316, "https://github.com/dotnet/roslyn/issues/32316")]
public void TestPatternBasedDisposal_ReturnsTaskOfBool()
{
string source = @"
public struct C
{
public static async System.Threading.Tasks.Task<int> Main()
{
{
await using var x = new C();
System.Console.Write(""using "");
}
System.Console.Write(""return"");
return 1;
}
public async System.Threading.Tasks.Task<bool> DisposeAsync()
{
System.Console.Write($""dispose_start "");
await System.Threading.Tasks.Task.Yield();
System.Console.Write($""dispose_end "");
return true;
}
}
";
// it's okay to await `Task<bool>` even if we don't care about the result
var comp = CreateCompilationWithTasksExtensions(new[] { source, s_interfaces }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end return");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
[WorkItem(32316, "https://github.com/dotnet/roslyn/issues/32316")]
public void TestPatternBasedDisposal_ReturnsTaskOfInt()
{
string source = @"
public struct C
{
public static async System.Threading.Tasks.Task<int> Main()
{
{
await using var x = new C();
System.Console.Write(""using "");
}
System.Console.Write(""return"");
return 1;
}
public async System.Threading.Tasks.Task<int> DisposeAsync()
{
System.Console.Write($""dispose_start "");
await System.Threading.Tasks.Task.Yield();
System.Console.Write($""dispose_end "");
return 1;
}
}
";
// it's okay to await `Task<int>` even if we don't care about the result
var comp = CreateCompilationWithTasksExtensions(new[] { source, s_interfaces }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "using dispose_start dispose_end return");
}

[ConditionalFact(typeof(WindowsDesktopOnly))]
public void TestInRegularMethod()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ static void Main()
}
}
}";
// Extension methods should just be ignored, rather than rejected after-the-fact. So there should be no error about ambiguities
// Tracked by https://github.com/dotnet/roslyn/issues/32767

CreateCompilation(source).VerifyDiagnostics(
// (20,16): error CS0121: The call is ambiguous between the following methods or properties: 'C2.Dispose(S1)' and 'C3.Dispose(S1)'
// using (S1 c = new S1())
Expand Down Expand Up @@ -673,6 +676,9 @@ static void Main()
}
}
}";
// Extension methods should just be ignored, rather than rejected after-the-fact. So there should be no error about ambiguities
// Tracked by https://github.com/dotnet/roslyn/issues/32767

CreateCompilation(source).VerifyDiagnostics(
// (21,15): error CS0121: The call is ambiguous between the following methods or properties: 'C2.Dispose(S1, int)' and 'C3.Dispose(S1, int)'
// using (S1 s = new S1())
Expand Down

0 comments on commit 898aa41

Please sign in to comment.