diff --git a/CLAUDE.md b/CLAUDE.md
index 3ccddff..22d5aa0 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -440,6 +440,16 @@ The project implements two separate analyzers for enforcing global usings, follo
- Best for: Library projects, projects with many third-party dependencies
- Implementation: `GlobalUsingsCommonAnalyzer.cs` + `GlobalUsingsCommonCodeFixProvider.cs`
+**Automatic Mutual Exclusivity:**
+
+By default, ATC220 excludes namespaces that ATC221 handles (configured via `dotnet_diagnostic.ATC220.exclude_common_namespaces`, default `true`). This means both rules can be enabled simultaneously without producing duplicate warnings:
+- ATC220 flags **non-common** namespaces (third-party, custom)
+- ATC221 flags **common** namespaces (System, Microsoft, Atc)
+
+ATC220 reads ATC221's `namespace_prefixes` setting to determine which namespaces to skip, so custom prefix configurations stay in sync.
+
+To make ATC220 flag ALL namespaces (original behavior), set `exclude_common_namespaces = false` in `.editorconfig`.
+
**Why Two Separate Analyzers?**
While these analyzers could theoretically be merged into one with different rule IDs, they are kept separate to:
@@ -493,6 +503,19 @@ dotnet_diagnostic.ATC210.max_line_length = 100
The configuration uses the standard Roslyn `.editorconfig` option naming convention: `dotnet_diagnostic.{RULE_ID}.option_name`
+#### Exclude Common Namespaces (ATC220)
+
+ATC220 supports excluding common namespaces to avoid overlap with ATC221:
+
+```editorconfig
+[*.cs]
+# Exclude common namespaces handled by ATC221 (default: true)
+dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+```
+
+- **Default value**: true (common namespaces are excluded)
+- When true, ATC220 reads ATC221's `namespace_prefixes` to determine which namespaces to skip
+
#### Reading Configuration in Analyzers
To read custom `.editorconfig` options in an analyzer, use the `AnalyzerConfigOptionsExtensions` helper:
diff --git a/docs/rules/ATC220.md b/docs/rules/ATC220.md
index 6fa276e..fc8500f 100644
--- a/docs/rules/ATC220.md
+++ b/docs/rules/ATC220.md
@@ -34,52 +34,44 @@ Centralizing all namespace imports in GlobalUsings.cs provides several benefits:
This is the most aggressive global usings policy, suitable for projects where you want absolutely minimal boilerplate.
-## 🔀 ATC220 vs ATC221: Which Rule to Use?
+## 🔀 ATC220 and ATC221: Working Together
-Both ATC220 and ATC221 enforce global usings, but they differ in scope and strictness:
+Both ATC220 and ATC221 enforce global usings, but they differ in scope:
| Aspect | ATC220 (Strict) | ATC221 (Lenient) |
|--------|----------------|------------------|
-| **Policy** | All namespaces | Only System/Microsoft/Atc |
-| **Flags** | Every using directive | Only common framework usings |
+| **Policy** | Non-common namespaces (by default) | Only System/Microsoft/Atc |
+| **Flags** | Third-party and custom using directives | Only common framework usings |
| **Third-party libs** | Must be in GlobalUsings.cs | Can stay in individual files |
-| **Use when** | You want zero using statements in code files | You want flexibility for third-party dependencies |
-| **Best for** | Highly controlled codebases, internal projects | Projects with many third-party libraries |
+| **Best for** | Catching all remaining non-common usings | Centralizing common framework usings |
-### When to Use ATC220 (This Rule)
+### Automatic Mutual Exclusivity
-Choose ATC220 if you want:
+By default, both rules can be enabled simultaneously **without producing duplicate warnings**. ATC220 automatically excludes namespaces that ATC221 handles (System, Microsoft, Atc), so each using directive triggers at most one warning.
-- **Maximum consistency**: Every file looks identical (no using statements at all)
-- **Zero exceptions**: All usings centralized, no local decisions needed
-- **Internal projects**: Where you control all dependencies
-- **Minimal boilerplate**: Absolutely cleanest possible code files
+| Scenario | ATC220 fires on | ATC221 fires on |
+|----------|----------------|----------------|
+| Both enabled (default) | Third-party/custom namespaces | System/Microsoft/Atc |
+| Only ATC220 (`exclude_common_namespaces = false`) | Everything | n/a |
+| Only ATC221 | n/a | System/Microsoft/Atc |
-### When to Use ATC221 Instead
-
-Choose ATC221 if you want:
-
-- **Flexibility**: Allow third-party usings to remain in individual files
-- **Context clarity**: See third-party dependencies where they're used
-- **Migration friendliness**: Easier to adopt incrementally
-- **Library projects**: Where different files may use different third-party packages
-
-### Configuration Example
-
-You can enable only one rule at a time in your `.editorconfig`:
+### Configuration Examples
```ini
-# Use strict policy (all usings must be global)
+# Both enabled (default) - no overlap, each rule covers its own scope
+dotnet_diagnostic.ATC220.severity = warning
+dotnet_diagnostic.ATC221.severity = warning
+
+# Use ATC220 for ALL namespaces (disable ATC221 and the exclusion)
dotnet_diagnostic.ATC220.severity = warning
+dotnet_diagnostic.ATC220.exclude_common_namespaces = false
dotnet_diagnostic.ATC221.severity = none
-# OR use lenient policy (only System/Microsoft/Atc must be global)
+# Use only ATC221 for common namespaces
dotnet_diagnostic.ATC220.severity = none
dotnet_diagnostic.ATC221.severity = warning
```
-**Note**: It's recommended to enable only one of these rules to avoid conflicting guidance.
-
## 📝 Examples
### Scenario 1: All namespaces should be in GlobalUsings.cs
@@ -113,7 +105,20 @@ public class Sample
## ⚙️ Configuration
-This rule is not configurable. It applies to all using directives.
+Configure in `.editorconfig`:
+
+```ini
+[*.cs]
+# Exclude common namespaces handled by ATC221 (default: true)
+# Set to false if you want ATC220 to flag ALL namespaces (use with ATC221 disabled)
+dotnet_diagnostic.ATC220.exclude_common_namespaces = true
+```
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `exclude_common_namespaces` | `true` | When true, skips namespaces matching ATC221's configured prefixes (System, Microsoft, Atc) to avoid duplicate diagnostics |
+
+When `exclude_common_namespaces` is `true` (default), ATC220 reads ATC221's `namespace_prefixes` setting to determine which namespaces to skip. If you customize ATC221's prefixes, ATC220 automatically respects that.
## 🔧 Code Fix
diff --git a/docs/rules/ATC221.md b/docs/rules/ATC221.md
index ba2887d..38ccfe5 100644
--- a/docs/rules/ATC221.md
+++ b/docs/rules/ATC221.md
@@ -37,53 +37,44 @@ Centralizing common namespace imports in GlobalUsings.cs provides several benefi
This is particularly useful for large projects where the same namespaces (like `System.Linq`, `System.Collections.Generic`) are used throughout the codebase.
-## 🔀 ATC220 vs ATC221: Which Rule to Use?
+## 🔀 ATC220 and ATC221: Working Together
-Both ATC220 and ATC221 enforce global usings, but they differ in scope and strictness:
+Both ATC220 and ATC221 enforce global usings, but they differ in scope:
| Aspect | ATC220 (Strict) | ATC221 (Lenient) |
|--------|----------------|------------------|
-| **Policy** | All namespaces | Only System/Microsoft/Atc |
-| **Flags** | Every using directive | Only common framework usings |
+| **Policy** | Non-common namespaces (by default) | Only System/Microsoft/Atc |
+| **Flags** | Third-party and custom using directives | Only common framework usings |
| **Third-party libs** | Must be in GlobalUsings.cs | Can stay in individual files |
-| **Use when** | You want zero using statements in code files | You want flexibility for third-party dependencies |
-| **Best for** | Highly controlled codebases, internal projects | Projects with many third-party libraries |
+| **Best for** | Catching all remaining non-common usings | Centralizing common framework usings |
-### When to Use ATC221 (This Rule)
+### Automatic Mutual Exclusivity
-Choose ATC221 if you want:
+By default, both rules can be enabled simultaneously **without producing duplicate warnings**. ATC220 automatically excludes namespaces that ATC221 handles (System, Microsoft, Atc), so each using directive triggers at most one warning.
-- **Flexibility**: Allow third-party usings to remain in individual files
-- **Context clarity**: See third-party dependencies where they're used (Xunit, FluentAssertions, etc.)
-- **Migration friendliness**: Easier to adopt incrementally in existing projects
-- **Library projects**: Where different files may use different third-party packages
-- **Balanced approach**: Centralize framework usings while keeping context for external dependencies
+| Scenario | ATC220 fires on | ATC221 fires on |
+|----------|----------------|----------------|
+| Both enabled (default) | Third-party/custom namespaces | System/Microsoft/Atc |
+| Only ATC220 (`exclude_common_namespaces = false`) | Everything | n/a |
+| Only ATC221 | n/a | System/Microsoft/Atc |
-### When to Use ATC220 Instead
-
-Choose ATC220 if you want:
-
-- **Maximum consistency**: Every file looks identical (no using statements at all)
-- **Zero exceptions**: All usings centralized, no local decisions needed
-- **Internal projects**: Where you control all dependencies
-- **Minimal boilerplate**: Absolutely cleanest possible code files
-
-### Configuration Example
-
-You can enable only one rule at a time in your `.editorconfig`:
+### Configuration Examples
```ini
-# Use lenient policy (only System/Microsoft/Atc must be global)
+# Both enabled (default) - no overlap, each rule covers its own scope
+dotnet_diagnostic.ATC220.severity = warning
+dotnet_diagnostic.ATC221.severity = warning
+
+# Use only ATC221 for common namespaces
dotnet_diagnostic.ATC220.severity = none
dotnet_diagnostic.ATC221.severity = warning
-# OR use strict policy (all usings must be global)
+# Use ATC220 for ALL namespaces (disable ATC221 and the exclusion)
dotnet_diagnostic.ATC220.severity = warning
+dotnet_diagnostic.ATC220.exclude_common_namespaces = false
dotnet_diagnostic.ATC221.severity = none
```
-**Note**: It's recommended to enable only one of these rules to avoid conflicting guidance.
-
## 📝 Examples
### Scenario 1: System namespaces should be in GlobalUsings.cs
diff --git a/sample/Atc.Analyzer.Sample.Atc220/InvalidExamples.cs b/sample/Atc.Analyzer.Sample.Atc220/InvalidExamples.cs
index d1de3de..db85c6e 100644
--- a/sample/Atc.Analyzer.Sample.Atc220/InvalidExamples.cs
+++ b/sample/Atc.Analyzer.Sample.Atc220/InvalidExamples.cs
@@ -1,11 +1,13 @@
namespace Atc.Analyzer.Sample.Atc220;
-// These usings SHOULD be moved to GlobalUsings.cs and will trigger ATC220
+// These usings SHOULD be moved to GlobalUsings.cs
+// By default, ATC220 skips common namespaces (System/Microsoft/Atc) to avoid overlap with ATC221
+// System.Linq and System.Text are flagged by ATC221, while Xunit is flagged by ATC220
#pragma warning disable ATC220, ATC221
-using System.Linq; // ATC220: Should be in GlobalUsings.cs
-using System.Text; // ATC220: Should be in GlobalUsings.cs
-using Xunit; // ATC220: Should be in GlobalUsings.cs (ALL namespaces)
+using System.Linq; // ATC221: Should be in GlobalUsings.cs (common namespace)
+using System.Text; // ATC221: Should be in GlobalUsings.cs (common namespace)
+using Xunit; // ATC220: Should be in GlobalUsings.cs (non-common namespace)
#pragma warning disable CA1303
#pragma warning disable CA1822
diff --git a/sample/Atc.Analyzer.Sample.Atc221/InvalidExamples.cs b/sample/Atc.Analyzer.Sample.Atc221/InvalidExamples.cs
index fb68f5b..afbdaef 100644
--- a/sample/Atc.Analyzer.Sample.Atc221/InvalidExamples.cs
+++ b/sample/Atc.Analyzer.Sample.Atc221/InvalidExamples.cs
@@ -1,7 +1,8 @@
namespace Atc.Analyzer.Sample.Atc221;
// These usings SHOULD be moved to GlobalUsings.cs and will trigger ATC221
-#pragma warning disable ATC220, ATC221
+// ATC220 automatically skips these common namespaces (System/Microsoft/Atc) by default
+#pragma warning disable ATC221
using System.IO; // ATC221: Should be in GlobalUsings.cs
using System.Linq; // ATC221: Should be in GlobalUsings.cs
diff --git a/sample/Atc.Analyzer.Sample.Atc221/ValidExamples.cs b/sample/Atc.Analyzer.Sample.Atc221/ValidExamples.cs
index cc51a0c..aa2f1aa 100644
--- a/sample/Atc.Analyzer.Sample.Atc221/ValidExamples.cs
+++ b/sample/Atc.Analyzer.Sample.Atc221/ValidExamples.cs
@@ -1,9 +1,9 @@
namespace Atc.Analyzer.Sample.Atc221;
-#pragma warning disable ATC220
+#pragma warning disable ATC220 // ATC220 still flags third-party namespaces like Xunit
// No usings from System/Microsoft/Atc here - they're in GlobalUsings.cs
-using Xunit; // Third-party namespace - this is OK
+using Xunit; // Third-party namespace - OK for ATC221, but ATC220 flags non-common namespaces
#pragma warning disable CA1303
#pragma warning disable CA1822
diff --git a/src/Atc.Analyzer/Extensions/AnalyzerConfigOptionsExtensions.cs b/src/Atc.Analyzer/Extensions/AnalyzerConfigOptionsExtensions.cs
index 7f2ce55..b09389a 100644
--- a/src/Atc.Analyzer/Extensions/AnalyzerConfigOptionsExtensions.cs
+++ b/src/Atc.Analyzer/Extensions/AnalyzerConfigOptionsExtensions.cs
@@ -120,6 +120,38 @@ public int GetMinChainLength(string ruleId)
return Math.Max(MinMinCount, Math.Min(MaxMinCount, length));
}
+ ///
+ /// Gets whether common namespaces should be excluded from the specified rule.
+ /// When true, namespaces matching ATC221's configured prefixes are skipped to avoid duplicate diagnostics.
+ ///
+ /// The rule identifier (e.g., "ATC220").
+ ///
+ /// True if common namespaces should be excluded (default), false otherwise.
+ ///
+ ///
+ /// Configure in .editorconfig using:
+ ///
+ /// dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ ///
+ ///
+ public bool GetExcludeCommonNamespaces(string ruleId)
+ {
+ if (options is null)
+ {
+ return true;
+ }
+
+ var key = $"dotnet_diagnostic.{ruleId}.exclude_common_namespaces";
+
+ if (!options.TryGetValue(key, out var value) ||
+ string.IsNullOrWhiteSpace(value))
+ {
+ return true;
+ }
+
+ return !value.Equals("false", StringComparison.OrdinalIgnoreCase);
+ }
+
///
/// Gets the configured namespace prefixes for the specified rule from .editorconfig.
///
diff --git a/src/Atc.Analyzer/Rules/Style/GlobalUsingsAllAnalyzer.cs b/src/Atc.Analyzer/Rules/Style/GlobalUsingsAllAnalyzer.cs
index acfbdfc..51ef101 100644
--- a/src/Atc.Analyzer/Rules/Style/GlobalUsingsAllAnalyzer.cs
+++ b/src/Atc.Analyzer/Rules/Style/GlobalUsingsAllAnalyzer.cs
@@ -28,6 +28,7 @@ public override void Initialize(AnalysisContext context)
context.RegisterSyntaxNodeAction(AnalyzeUsingDirective, SyntaxKind.UsingDirective);
}
+ [SuppressMessage("Design", "MA0051:Method is too long", Justification = "OK.")]
private static void AnalyzeUsingDirective(SyntaxNodeAnalysisContext context)
{
if (context.Node.SyntaxTree.IsAutoGeneratedFile())
@@ -76,6 +77,19 @@ private static void AnalyzeUsingDirective(SyntaxNodeAnalysisContext context)
return;
}
+ // Check if common namespaces should be excluded (deferred to ATC221)
+ var options = context.Options.AnalyzerConfigOptionsProvider.GetOptions(context.Node.SyntaxTree);
+ var excludeCommon = options.GetExcludeCommonNamespaces(RuleIdentifierConstants.Style.GlobalUsingsAll);
+
+ if (excludeCommon)
+ {
+ var commonPrefixes = options.GetNamespacePrefixes(RuleIdentifierConstants.Style.GlobalUsingsCommon);
+ if (commonPrefixes.Any(prefix => namespaceName!.StartsWith(prefix, StringComparison.Ordinal)))
+ {
+ return;
+ }
+ }
+
// All non-static, non-alias using directives should be global
var diagnostic = Diagnostic.Create(
Rule,
diff --git a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerNoDiagnosticTests.cs b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerNoDiagnosticTests.cs
index c5f364c..5fe1be4 100644
--- a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerNoDiagnosticTests.cs
+++ b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerNoDiagnosticTests.cs
@@ -118,4 +118,49 @@ public static void DoSomething()
await AnalyzerVerifier.VerifyAnalyzerAsync(code);
}
+
+ [Fact]
+ public async Task NoDiagnostic_SystemNamespace_DefaultExcludesCommon()
+ {
+ const string code = """
+ using System;
+
+ public class Sample
+ {
+ public static void DoSomething()
+ {
+ }
+ }
+ """;
+
+ await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_MicrosoftNamespace_DefaultExcludesCommon()
+ {
+ const string code = """
+ using Microsoft.Extensions.Logging;
+
+ public class Sample
+ {
+ }
+ """;
+
+ await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_AtcNamespace_DefaultExcludesCommon()
+ {
+ const string code = """
+ using Atc.Utilities;
+
+ public class Sample
+ {
+ }
+ """;
+
+ await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ }
}
\ No newline at end of file
diff --git a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerReportsDiagnosticTests.cs b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerReportsDiagnosticTests.cs
index d358ce2..42e273c 100644
--- a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerReportsDiagnosticTests.cs
+++ b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllAnalyzerReportsDiagnosticTests.cs
@@ -6,11 +6,12 @@ namespace Atc.Analyzer.Tests.Rules.Style;
[SuppressMessage("", "AsyncFixer01:The method does not need to use async/await", Justification = "OK - Test code")]
[SuppressMessage("", "SA1135::The method does not need to use async/await", Justification = "OK - Test code")]
+[SuppressMessage("", "S2699:Add at least one assertion to this test case", Justification = "OK - RunAsync is the assertion")]
[SuppressMessage("Naming", "MA0048:File name must match type name", Justification = "OK - Partial class")]
public sealed partial class GlobalUsingsAllAnalyzerTests
{
[Fact]
- public async Task ReportsDiagnostic_SystemNamespace()
+ public async Task ReportsDiagnostic_SystemNamespace_WhenExcludeCommonDisabled()
{
const string code = """
[|using System;|]
@@ -23,11 +24,27 @@ public static void DoSomething()
}
""";
- await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ var test = new CSharpAnalyzerTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = code,
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.TestState.AnalyzerConfigFiles.Add((
+ "/.editorconfig",
+ """
+ root = true
+
+ [*]
+ dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ """));
+
+ await test.RunAsync();
}
[Fact]
- public async Task ReportsDiagnostic_SystemCollectionsGeneric()
+ public async Task ReportsDiagnostic_SystemCollectionsGeneric_WhenExcludeCommonDisabled()
{
const string code = """
[|using System.Collections.Generic;|]
@@ -38,7 +55,23 @@ public class Sample
}
""";
- await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ var test = new CSharpAnalyzerTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = code,
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.TestState.AnalyzerConfigFiles.Add((
+ "/.editorconfig",
+ """
+ root = true
+
+ [*]
+ dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ """));
+
+ await test.RunAsync();
}
[Fact]
@@ -70,7 +103,7 @@ public class Sample
}
[Fact]
- public async Task ReportsDiagnostic_MicrosoftNamespace()
+ public async Task ReportsDiagnostic_MicrosoftNamespace_WhenExcludeCommonDisabled()
{
const string code = """
[|using Microsoft.Extensions.Logging;|]
@@ -80,11 +113,27 @@ public class Sample
}
""";
- await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ var test = new CSharpAnalyzerTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = code,
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.TestState.AnalyzerConfigFiles.Add((
+ "/.editorconfig",
+ """
+ root = true
+
+ [*]
+ dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ """));
+
+ await test.RunAsync();
}
[Fact]
- public async Task ReportsDiagnostic_AtcNamespace()
+ public async Task ReportsDiagnostic_AtcNamespace_WhenExcludeCommonDisabled()
{
const string code = """
[|using Atc.Utilities;|]
@@ -94,11 +143,43 @@ public class Sample
}
""";
+ var test = new CSharpAnalyzerTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = code,
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.TestState.AnalyzerConfigFiles.Add((
+ "/.editorconfig",
+ """
+ root = true
+
+ [*]
+ dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ """));
+
+ await test.RunAsync();
+ }
+
+ [Fact]
+ public async Task ReportsDiagnostic_MultipleNamespaces_OnlyNonCommon()
+ {
+ const string code = """
+ using System;
+ [|using Xunit;|]
+ [|using MyCompany.Utilities;|]
+
+ public class Sample
+ {
+ }
+ """;
+
await AnalyzerVerifier.VerifyAnalyzerAsync(code);
}
[Fact]
- public async Task ReportsDiagnostic_MultipleNamespaces()
+ public async Task ReportsDiagnostic_AllNamespaces_WhenExcludeCommonDisabled()
{
const string code = """
[|using System;|]
@@ -110,6 +191,22 @@ public class Sample
}
""";
- await AnalyzerVerifier.VerifyAnalyzerAsync(code);
+ var test = new CSharpAnalyzerTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = code,
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.TestState.AnalyzerConfigFiles.Add((
+ "/.editorconfig",
+ """
+ root = true
+
+ [*]
+ dotnet_diagnostic.ATC220.exclude_common_namespaces = false
+ """));
+
+ await test.RunAsync();
}
}
\ No newline at end of file
diff --git a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllCodeFixProviderTests.cs b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllCodeFixProviderTests.cs
index 7555dbf..0093638 100644
--- a/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllCodeFixProviderTests.cs
+++ b/test/Atc.Analyzer.Tests/Rules/Style/GlobalUsingsAllCodeFixProviderTests.cs
@@ -5,10 +5,11 @@ namespace Atc.Analyzer.Tests.Rules.Style;
#pragma warning restore SA1135 // Using directives must be qualified
[SuppressMessage("", "AsyncFixer01:The method does not need to use async/await", Justification = "OK - Test code")]
+[SuppressMessage("", "S2699:Add at least one assertion to this test case", Justification = "OK - RunAsync is the assertion")]
public sealed class GlobalUsingsAllCodeFixProviderTests
{
[Fact]
- public Task FixUsing_MoveSystemNamespaceToGlobalUsings()
+ public async Task FixUsing_MoveSystemNamespaceToGlobalUsings()
{
const string source = """
using System;
@@ -40,7 +41,18 @@ public static void DoSomething()
.WithSpan(1, 1, 1, 14),
};
- return CodeFixVerifier.VerifyCodeFixAsync(source, expected, fixedSource);
+ var test = new CSharpCodeFixTest
+ {
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
+ TestCode = source.NormalizeLineEndings(),
+ FixedCode = fixedSource.NormalizeLineEndings(),
+ CompilerDiagnostics = CompilerDiagnostics.None,
+ };
+
+ test.ExpectedDiagnostics.AddRange(expected);
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", "root = true\n\n[*]\nend_of_line = lf\ndotnet_diagnostic.ATC220.exclude_common_namespaces = false\n"));
+
+ await test.RunAsync();
}
[Fact]
@@ -207,7 +219,7 @@ public class Sample
test.FixedState.Sources.Add(("GlobalUsings.cs", fixedGlobalUsingsSource.NormalizeLineEndings()));
test.ExpectedDiagnostics.AddRange(expected);
- test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", "root = true\n\n[*]\nend_of_line = lf\n"));
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", "root = true\n\n[*]\nend_of_line = lf\ndotnet_diagnostic.ATC220.exclude_common_namespaces = false\n"));
await test.RunAsync();
@@ -266,7 +278,7 @@ public class Sample
test.FixedState.Sources.Add(("GlobalUsings.cs", fixedGlobalUsingsSource.NormalizeLineEndings()));
test.ExpectedDiagnostics.AddRange(expected);
- test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", "root = true\n\n[*]\nend_of_line = lf\n"));
+ test.TestState.AnalyzerConfigFiles.Add(("/.editorconfig", "root = true\n\n[*]\nend_of_line = lf\ndotnet_diagnostic.ATC220.exclude_common_namespaces = false\n"));
await test.RunAsync();