Skip to content

Commit

Permalink
Support custom path of a test file (#1609)
Browse files Browse the repository at this point in the history
  • Loading branch information
josefpihrt authored Feb 22, 2025
1 parent 4376224 commit 41da36d
Show file tree
Hide file tree
Showing 11 changed files with 452 additions and 29 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Support custom path of a test file ([PR](https://github.com/dotnet/roslynator/pull/1609))
- It's possible to specify a directory path and/or a file name.

## [4.13.0] - 2025-02-09

### Fixed
Expand Down
18 changes: 17 additions & 1 deletion src/Tests/Testing.Common/Testing/AdditionalFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ public readonly struct AdditionalFile
/// <summary>
/// Initializes a new instance of <see cref="AdditionalFile"/>
/// </summary>
public AdditionalFile(string source, string? expectedSource = null)
public AdditionalFile(string source, string? expectedSource = null, string? directoryPath = null, string? name = null)
{
Source = source ?? throw new ArgumentNullException(nameof(source));
ExpectedSource = expectedSource;

FileSystemVerifier.VerifyDirectoryPath(directoryPath);
DirectoryPath = directoryPath;

FileSystemVerifier.VerifyFileName(name);
Name = name;
}

/// <summary>
Expand All @@ -33,6 +39,16 @@ public AdditionalFile(string source, string? expectedSource = null)
/// </summary>
public string? ExpectedSource { get; }

/// <summary>
/// Gets the relative directory path.
/// </summary>
public string? DirectoryPath { get; }

/// <summary>
/// Gets the file name.
/// </summary>
public string? Name { get; }

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay => Source;

Expand Down
18 changes: 10 additions & 8 deletions src/Tests/Testing.Common/Testing/CodeVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ private void VerifyAnnotations(
}

internal static (Document document, ImmutableArray<ExpectedDocument> expectedDocuments)
CreateDocument(Solution solution, string source, ImmutableArray<AdditionalFile> additionalFiles, TestOptions options, DiagnosticDescriptor? descriptor = null)
CreateDocument(Solution solution, string source, string? directoryPath, string? fileName, ImmutableArray<AdditionalFile> additionalFiles, TestOptions options, DiagnosticDescriptor? descriptor = null)
{
const string DefaultProjectName = "TestProject";

Expand All @@ -315,7 +315,7 @@ internal static (Document document, ImmutableArray<ExpectedDocument> expectedDoc
.AddProject(projectInfo)
.GetProject(projectId)!;

string directoryPath = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
string baseDirectoryPath = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
? "z:"
: "/";

Expand All @@ -336,7 +336,7 @@ internal static (Document document, ImmutableArray<ExpectedDocument> expectedDoc
TextDocument configFile = project.AddAnalyzerConfigDocument(
".editorconfig",
SourceText.From(StringBuilderCache.GetStringAndFree(sb)),
filePath: Path.Combine(directoryPath, ".editorconfig"));
filePath: Path.Combine(baseDirectoryPath, ".editorconfig"));

project = configFile.Project;
}
Expand All @@ -348,10 +348,12 @@ internal static (Document document, ImmutableArray<ExpectedDocument> expectedDoc
project = project.WithCompilationOptions(newCompilationOptions);
}

string documentName = fileName ?? options.DocumentName;

Document document = project.AddDocument(
options.DocumentName,
documentName,
SourceText.From(source),
filePath: Path.Combine(directoryPath, options.DocumentName));
filePath: Path.Combine(baseDirectoryPath, (directoryPath is not null) ? Path.Combine(directoryPath, documentName) : documentName));

ImmutableArray<ExpectedDocument>.Builder? expectedDocuments = null;

Expand All @@ -362,12 +364,12 @@ internal static (Document document, ImmutableArray<ExpectedDocument> expectedDoc

for (int i = 0; i < additionalFiles.Length; i++)
{
string documentName = AppendNumberToFileName(options.DocumentName, i + 2);
string additionalDocumentName = additionalFiles[i].Name ?? AppendNumberToFileName(options.DocumentName, i + 2);

Document additionalDocument = project.AddDocument(
documentName,
additionalDocumentName,
SourceText.From(additionalFiles[i].Source),
filePath: Path.Combine(directoryPath, documentName));
filePath: Path.Combine(baseDirectoryPath, (directoryPath is not null) ? Path.Combine(directoryPath, additionalDocumentName) : additionalDocumentName));

string? expectedSource = additionalFiles[i].ExpectedSource;

Expand Down
43 changes: 38 additions & 5 deletions src/Tests/Testing.Common/Testing/CompilerDiagnosticFixTestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,20 @@ public CompilerDiagnosticFixTestData(
string diagnosticId,
string source,
IEnumerable<AdditionalFile>? additionalFiles = null,
string? equivalenceKey = null)
string? equivalenceKey = null,
string? directoryPath = null,
string? fileName = null)
{
DiagnosticId = diagnosticId ?? throw new ArgumentNullException(nameof(diagnosticId));
Source = source ?? throw new ArgumentNullException(nameof(source));
AdditionalFiles = additionalFiles?.ToImmutableArray() ?? ImmutableArray<AdditionalFile>.Empty;
EquivalenceKey = equivalenceKey;

FileSystemVerifier.VerifyDirectoryPath(directoryPath);
DirectoryPath = directoryPath;

FileSystemVerifier.VerifyFileName(fileName);
FileName = fileName;
}

#pragma warning disable CS0618 // Type or member is obsolete
Expand All @@ -36,11 +44,20 @@ public CompilerDiagnosticFixTestData(
public CompilerDiagnosticFixTestData(
string source,
IEnumerable<AdditionalFile>? additionalFiles = null,
string? equivalenceKey = null)
string? equivalenceKey = null,
string? directoryPath = null,
string? fileName = null)
{
Source = source ?? throw new ArgumentNullException(nameof(source));
AdditionalFiles = additionalFiles?.ToImmutableArray() ?? ImmutableArray<AdditionalFile>.Empty;
EquivalenceKey = equivalenceKey;

FileSystemVerifier.VerifyDirectoryPath(directoryPath);
DirectoryPath = directoryPath;

FileSystemVerifier.VerifyFileName(fileName);
FileName = fileName;

DiagnosticId = null!;
}

Expand All @@ -49,7 +66,9 @@ internal CompilerDiagnosticFixTestData(CompilerDiagnosticFixTestData other)
diagnosticId: other.DiagnosticId,
source: other.Source,
additionalFiles: other.AdditionalFiles,
equivalenceKey: other.EquivalenceKey)
equivalenceKey: other.EquivalenceKey,
directoryPath: other.DirectoryPath,
fileName: other.FileName)
{
}
#pragma warning restore CS0618 // Type or member is obsolete
Expand All @@ -75,6 +94,16 @@ internal CompilerDiagnosticFixTestData(CompilerDiagnosticFixTestData other)
/// </summary>
public string? EquivalenceKey { get; }

/// <summary>
/// Gets the relative directory path.
/// </summary>
public string? DirectoryPath { get; }

/// <summary>
/// Gets the file name.
/// </summary>
public string? FileName { get; }

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay => $"{Source}";

Expand All @@ -86,12 +115,16 @@ public CompilerDiagnosticFixTestData Update(
string diagnosticId,
string source,
IEnumerable<AdditionalFile> additionalFiles,
string equivalenceKey)
string equivalenceKey,
string directoryPath,
string fileName)
{
return new(
diagnosticId: diagnosticId,
source: source,
additionalFiles: additionalFiles,
equivalenceKey: equivalenceKey);
equivalenceKey: equivalenceKey,
directoryPath: directoryPath,
fileName: fileName);
}
}
63 changes: 61 additions & 2 deletions src/Tests/Testing.Common/Testing/CompilerDiagnosticFixVerifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,39 @@ await VerifyFixAsync(
cancellationToken);
}

/// <summary>
/// Verifies that specified source will produce compiler diagnostic.
/// </summary>
/// <param name="file">Source file where diagnostic's location is marked with <c>[|</c> and <c>|]</c> tokens.</param>
public async Task VerifyFixAsync(
TestFile file,
IEnumerable<AdditionalFile>? additionalFiles = null,
string? equivalenceKey = null,
TestOptions? options = null,
CancellationToken cancellationToken = default)
{
if (file is null)
throw new ArgumentNullException(nameof(file));

if (file.ExpectedSource is null)
throw new ArgumentException("Expected source is required.", nameof(file));

var expected = ExpectedTestState.Parse(file.ExpectedSource);

var data = new CompilerDiagnosticFixTestData(
file.Source,
additionalFiles,
equivalenceKey: equivalenceKey,
directoryPath: file.DirectoryPath,
fileName: file.Name);

await VerifyFixAsync(
data,
expected,
options,
cancellationToken);
}

/// <summary>
/// Verifies that specified source will produce compiler diagnostic.
/// </summary>
Expand All @@ -103,7 +136,7 @@ public async Task VerifyFixAsync(

using (Workspace workspace = new AdhocWorkspace())
{
(Document document, ImmutableArray<ExpectedDocument> expectedDocuments) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options);
(Document document, ImmutableArray<ExpectedDocument> expectedDocuments) = CreateDocument(workspace.CurrentSolution, data.Source, directoryPath: data.DirectoryPath, fileName: data.FileName, data.AdditionalFiles, options);

Project project = document.Project;

Expand Down Expand Up @@ -251,6 +284,32 @@ await VerifyNoFixAsync(
cancellationToken);
}

/// <summary>
/// Verifies that specified source will not produce compiler diagnostic.
/// </summary>
public async Task VerifyNoFixAsync(
TestFile file,
IEnumerable<AdditionalFile>? additionalFiles = null,
string? equivalenceKey = null,
TestOptions? options = null,
CancellationToken cancellationToken = default)
{
if (file is null)
throw new ArgumentNullException(nameof(file));

var data = new CompilerDiagnosticFixTestData(
file.Source,
additionalFiles: additionalFiles,
equivalenceKey: equivalenceKey,
directoryPath: file.DirectoryPath,
fileName: file.Name);

await VerifyNoFixAsync(
data,
options,
cancellationToken);
}

/// <summary>
/// Verifies that specified source will not produce compiler diagnostic.
/// </summary>
Expand All @@ -271,7 +330,7 @@ public async Task VerifyNoFixAsync(

using (Workspace workspace = new AdhocWorkspace())
{
(Document document, ImmutableArray<ExpectedDocument> _) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options);
(Document document, ImmutableArray<ExpectedDocument> _) = CreateDocument(workspace.CurrentSolution, data.Source, directoryPath: data.DirectoryPath, fileName: data.FileName, data.AdditionalFiles, options);

Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!;

Expand Down
35 changes: 32 additions & 3 deletions src/Tests/Testing.Common/Testing/DiagnosticTestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ public DiagnosticTestData(
string? diagnosticMessage = null,
IFormatProvider? formatProvider = null,
string? equivalenceKey = null,
bool alwaysVerifyAdditionalLocations = false)
bool alwaysVerifyAdditionalLocations = false,
string? directoryPath = null,
string? fileName = null)
{
Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor));
Source = source ?? throw new ArgumentNullException(nameof(source));
Expand All @@ -41,6 +43,12 @@ public DiagnosticTestData(
EquivalenceKey = equivalenceKey;
AlwaysVerifyAdditionalLocations = alwaysVerifyAdditionalLocations;

FileSystemVerifier.VerifyDirectoryPath(directoryPath);
DirectoryPath = directoryPath;

FileSystemVerifier.VerifyFileName(fileName);
FileName = fileName;

if (Spans.Length > 1
&& !AdditionalSpans.IsEmpty)
{
Expand All @@ -60,7 +68,9 @@ public DiagnosticTestData(
string? diagnosticMessage = null,
IFormatProvider? formatProvider = null,
string? equivalenceKey = null,
bool alwaysVerifyAdditionalLocations = false)
bool alwaysVerifyAdditionalLocations = false,
string? directoryPath = null,
string? fileName = null)
{
Source = source ?? throw new ArgumentNullException(nameof(source));
Spans = spans?.ToImmutableArray() ?? ImmutableArray<TextSpan>.Empty;
Expand All @@ -70,6 +80,13 @@ public DiagnosticTestData(
FormatProvider = formatProvider;
EquivalenceKey = equivalenceKey;
AlwaysVerifyAdditionalLocations = alwaysVerifyAdditionalLocations;

FileSystemVerifier.VerifyDirectoryPath(directoryPath);
DirectoryPath = directoryPath;

FileSystemVerifier.VerifyFileName(fileName);
FileName = fileName;

Descriptor = null!;

if (Spans.Length > 1
Expand All @@ -89,7 +106,9 @@ internal DiagnosticTestData(DiagnosticTestData other)
diagnosticMessage: other.DiagnosticMessage,
formatProvider: other.FormatProvider,
equivalenceKey: other.EquivalenceKey,
alwaysVerifyAdditionalLocations: other.AlwaysVerifyAdditionalLocations)
alwaysVerifyAdditionalLocations: other.AlwaysVerifyAdditionalLocations,
directoryPath: other.DirectoryPath,
fileName: other.FileName)
{
}
#pragma warning restore CS0618 // Type or member is obsolete
Expand Down Expand Up @@ -143,6 +162,16 @@ internal DiagnosticTestData(DiagnosticTestData other)
/// </summary>
public bool AlwaysVerifyAdditionalLocations { get; }

/// <summary>
/// Gets the relative directory path.
/// </summary>
public string? DirectoryPath { get; }

/// <summary>
/// Gets the file name.
/// </summary>
public string? FileName { get; }

internal ImmutableArray<Diagnostic> GetDiagnostics(DiagnosticDescriptor descriptor, SyntaxTree tree)
{
if (Spans.IsEmpty)
Expand Down
Loading

0 comments on commit 41da36d

Please sign in to comment.