Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add diagnostic and code fix verification helpers #131

Closed
wants to merge 9 commits into from

Conversation

sharwell
Copy link
Member

@sharwell sharwell commented Aug 14, 2018

Closes #123

Items to file specific follow-up issues:

@sharwell sharwell requested a review from a team as a code owner August 14, 2018 02:42
* Make CancellationToken optional for RunAsync in test scenarios
* Handle VB compiler diagnostics in the same manner as CS
* Use IsEmpty instead of testing Length
/// <item><description>No diagnostics are reported in the input.</description></item>
/// <item><description>No code fixes are provided for the diagnostics reported in the input.</description></item>
/// <item><description>The code fix applied for the diagnostics does not produce a change in the source file(s).</description></item>
/// <item><description>The maximum number of allowed iterations is exceeded.</description></item>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dotnet/csharplangdesign This is less pleasant than it need to be: dotnet/csharplang#1765

/// <item><description>Otherwise, the default value is treated as the negative of the number of fixable diagnostics appearing in the input source file(s).</description></item>
/// </list>
///
/// <note>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dotnet/csharplangdesign This is an ideal situation where dotnet/csharplang#1767 would help

/// <summary>
/// Gets or sets the number of code fix iterations expected during code fix testing.
/// </summary>
/// <remarks>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dotnet/roslyn-ide @kuhlenh This documentation will never be seen by users because it's in a <remarks> section.

public static DiagnosticResult CompilerError(string errorIdentifier)
=> DiagnosticVerifier<TAnalyzer>.CompilerError(errorIdentifier);

public static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the cancellation token or make it optional? Only keep it if there is a use case for testing cancellation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

➡️ Should be fixed now 👍

public static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, new[] { expected }, cancellationToken);

public static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be IEnumerable<DiagnosticResult. Also cancellation token needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be IEnumerable<DiagnosticResult>

I'll file a follow-up issue to consider this.

private ImmutableArray<FileLinePositionSpan> _spans;
private string _message;

public DiagnosticResult(string id, DiagnosticSeverity severity)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is severity required here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constructor is rarely required. Severity does not need to be specified in any of the three primary locations where this is constructed:

  1. By calling Diagnostic()
  2. By calling CompilerError("CS0000")
  3. Starting with commit 56d48d9, by using markup syntax in the input and/or output

/// <summary>
/// Metadata references used to create test projects.
/// </summary>
public static class MetadataReferences

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty useful helper method that can fit in this class.

Copy link
Member Author

@sharwell sharwell Aug 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

➡️ I'll leave this as a follow-up item. I agree it seems useful.

@JohanLarsson
Copy link

Also try removing the need for async in the asserts. Worth it to do SynchronizationContext gymnastics inside this library to have clean blocking asserts imo. I have never needed to do that but it is perhaps different in different test frameworks. Alternatively expose an async API alongside but it will mean some bloat.

@sharwell
Copy link
Member Author

Remove the cancellation token or make it optional?

Will make CancellationToken in the public API optional.

Also try removing the need for async in the asserts.

I have no intention to pursue a synchronous API for testing inherently asynchronous code, but if you'd like I can bring it to the broader team for consideration.

@jnm2
Copy link

jnm2 commented Aug 14, 2018

@sharwell My understanding is that this is completely CPU-bound work. I've also had some internal resistance to the async ceremony in analyzer tests. Would you consider synchronous APIs out of scope for this unless they were to be implemented at the analysis level?

@sharwell
Copy link
Member Author

sharwell commented Aug 14, 2018

@jnm2 It would be easy to add synchronous support as an extension. For testing StyleCop Analyzers, only one asynchronous method in this library is ever actually called by tests (GenericAnalyzerTest.RunAsync). The rest are rolled up in StyleCopDiagnosticVerifier<TAnalyzer> and StyleCopCodeFixVerifier<TAnalyzer, TCodeFix>. If you prefer a synchronous testing approach, you could make the methods in an equivalent pair of helper classes synchronous.

@@ -46,6 +46,27 @@ public static Task VerifyCSharpFixAsync(string source, DiagnosticResult[] expect
return test.RunAsync(cancellationToken);
}

public static Task VerifyVisualBasicDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken = default)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe code is a better name than source?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Work list of additions and fixes to test infrastructure by StyleCop Analyzers
3 participants