|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
Roslyn.Diagnostics.Analyzers.ExportedPartsShouldHaveImportingConstructor,
Roslyn.Diagnostics.Analyzers.ExportedPartsShouldHaveImportingConstructorCodeFixProvider>;
using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
Roslyn.Diagnostics.Analyzers.ExportedPartsShouldHaveImportingConstructor,
Roslyn.Diagnostics.Analyzers.ExportedPartsShouldHaveImportingConstructorCodeFixProvider>;
namespace Roslyn.Diagnostics.Analyzers.UnitTests
{
public class ExportedPartsShouldHaveImportingConstructorTests
{
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task SingleExpectedConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task SingleExpectedConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition", true)]
[InlineData("System.Composition", false)]
[InlineData("System.ComponentModel.Composition", true)]
[InlineData("System.ComponentModel.Composition", false)]
public async Task NotInheritedAttribute_CSharpAsync(string mefNamespace, bool reflectionInherited)
{
var source = $@"
using {mefNamespace};
[System.AttributeUsage(System.AttributeTargets.All, Inherited = {(reflectionInherited ? "true" : "false")})]
class NotInheritedExportAttribute : System.Attribute {{ }}
[NotInheritedExport]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
class D : C {{
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition", true)]
[InlineData("System.Composition", false)]
[InlineData("System.ComponentModel.Composition", true)]
[InlineData("System.ComponentModel.Composition", false)]
public async Task NotInheritedAttribute_VisualBasicAsync(string mefNamespace, bool reflectionInherited)
{
var source = $@"
Imports {mefNamespace}
<System.AttributeUsage(System.AttributeTargets.All, Inherited:={reflectionInherited})>
Class NotInheritedExportAttribute
Inherits System.Attribute
End Class
<NotInheritedExport>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
Class D
Inherits C
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/2490")]
[InlineData("System.ComponentModel.Composition")]
public async Task InheritedExportAttribute_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[InheritedExport]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
class D : C {{
}}
";
var fixedSource = $@"
using {mefNamespace};
[InheritedExport]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
class D : C {{
[ImportingConstructor]
public D()
{{
}}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(4, 2, 4, 17).WithArguments("D") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory(Skip = "https://github.com/dotnet/roslyn-analyzers/issues/2490")]
[InlineData("System.ComponentModel.Composition")]
public async Task InheritedExportAttribute_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<InheritedExport>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
Class D
Inherits C
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<InheritedExport>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
Class D
Inherits C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(4, 2, 4, 17).WithArguments("D") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ExportAttributeNotInherited_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
class D : C {{ }}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ExportAttributeNotInherited_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
Class D
Inherits C
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task InstanceAndImplicitStaticConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
private static readonly object _gate = new object();
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task InstanceAndImplicitStaticConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
Private Shared ReadOnly _gate As Object = New Object()
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task InstanceAndExplicitStaticConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
private static readonly object _gate;
static C() {{ _gate = new object(); }}
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task InstanceAndExplicitStaticConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
Private Shared ReadOnly _gate As Object
Shared Sub New()
_gate = New Object()
End Sub
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{ }}
";
var fixedSource = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C()
{{
}}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(4, 2, 4, 8).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(4, 2, 4, 8).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructorAddImport_CSharpAsync(string mefNamespace)
{
var source = $@"
[{mefNamespace}.Export]
class C {{ }}
";
var fixedSource = $@"
using {mefNamespace};
[{mefNamespace}.Export]
class C {{
[ImportingConstructor]
public C()
{{
}}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(2, 2, 2, mefNamespace.Length + 9).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructorAddImport_VisualBasicAsync(string mefNamespace)
{
var source = $@"
<{mefNamespace}.Export>
Class C
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<{mefNamespace}.Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(2, 2, 2, mefNamespace.Length + 9).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructorPlacement_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
private readonly int _value = 0;
private int Value => _value;
}}
";
var fixedSource = $@"
using {mefNamespace};
[Export]
class C {{
private readonly int _value = 0;
[ImportingConstructor]
public C()
{{
}}
private int Value => _value;
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(4, 2, 4, 8).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task ImplicitConstructorPlacement_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
Private ReadOnly _value1 As Integer = 0
Private ReadOnly Property Value
Get
return _value1
End Get
End Property
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<Export>
Class C
Private ReadOnly _value1 As Integer = 0
<ImportingConstructor>
Public Sub New()
End Sub
Private ReadOnly Property Value
Get
return _value1
End Get
End Property
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(4, 2, 4, 8).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MissingAttributeConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
public C() {{ }}
}}
";
var fixedSource = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(6, 5, 6, 19).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MissingAttributeConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
Public Sub New()
End Sub
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(6, 5, 6, 21).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MissingAttributeConstructorAddImport_CSharpAsync(string mefNamespace)
{
var source = $@"
[{mefNamespace}.Export]
class C {{
public C() {{ }}
}}
";
var fixedSource = $@"
using {mefNamespace};
[{mefNamespace}.Export]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(4, 5, 4, 19).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MissingAttributeConstructorAddImport_VisualBasicAsync(string mefNamespace)
{
var source = $@"
<{mefNamespace}.Export>
Class C
Public Sub New()
End Sub
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<{mefNamespace}.Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(4, 5, 4, 21).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task NonPublicConstructor_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
internal C() {{ }}
}}
";
var fixedSource = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C() {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyCS.Diagnostic().WithSpan(6, 6, 6, 26).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task NonPublicConstructor_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Friend Sub New()
End Sub
End Class
";
var fixedSource = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics = { VerifyVB.Diagnostic().WithSpan(6, 6, 6, 26).WithArguments("C") },
},
FixedState =
{
Sources = { fixedSource },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MultipleConstructors_CSharpAsync(string mefNamespace)
{
var source = $@"
using {mefNamespace};
[Export]
class C {{
[ImportingConstructor]
public C() {{ }}
internal C(string x) {{ }}
private C(int x) {{ }}
}}
";
await new VerifyCS.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics =
{
VerifyCS.Diagnostic().WithSpan(9, 5, 9, 29).WithArguments("C"),
VerifyCS.Diagnostic().WithSpan(11, 5, 11, 25).WithArguments("C"),
},
},
FixedState =
{
// No code fix is offered for this case
Sources = { source },
},
}.RunAsync();
}
[Theory]
[InlineData("System.Composition")]
[InlineData("System.ComponentModel.Composition")]
public async Task MultipleConstructors_VisualBasicAsync(string mefNamespace)
{
var source = $@"
Imports {mefNamespace}
<Export>
Class C
<ImportingConstructor>
Public Sub New()
End Sub
Friend Sub New(x as String)
End Sub
Private Sub New(x as Integer)
End Sub
End Class
";
await new VerifyVB.Test
{
TestState =
{
Sources = { source },
AdditionalReferences = { AdditionalMetadataReferences.SystemComponentModelCompositionReference },
ExpectedDiagnostics =
{
VerifyVB.Diagnostic().WithSpan(10, 5, 10, 32).WithArguments("C"),
VerifyVB.Diagnostic().WithSpan(13, 5, 13, 34).WithArguments("C"),
},
},
FixedState =
{
// No code fix is offered for this case
Sources = { source },
},
}.RunAsync();
}
}
}
|