internal void When_public_event_is_undocumented_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithDocumentationComments() .InGlobalScope(@" namespace N.M { public class C { public event EventHandler E; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_internal_interface_is_undocumented_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithDocumentationComments() .InGlobalScope(@" namespace N.M { internal interface [|I|] { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Missing XML comment for internally visible type or member 'N.M.I'."); }
internal void When_internal_interface_is_documented_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithDocumentationComments() .InGlobalScope(@" namespace N.M { /// <summary /> internal interface I { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_static_class_has_public_nonextension_method_and_name_ends_with_Extensions_it_must_be_reported () { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" static class SomeExtensions { public static void [|M|](string s) { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Class 'SomeExtensions' contains public non-extension method 'M'."); }
internal void When_string_parameter_is_read_from_in_constructor_expression_body_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { public C(string p) => N(p); void N(string s) { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_variable_name_contains_a_digit_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { void M() { string [|str12|] = ""A""; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Variable 'str12' contains one or more digits in its name."); }
internal void When_string_parameter_is_written_to_in_constructor_body_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { public C(string [|p|]) { p += ""X""; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "The value of parameter 'p' is overwritten in its method body."); }
internal void When_returning_null_for_return_type_List_of_int_it_must_be_reported() { ParsedSourceCode source = new TypeSourceCodeBuilder() .Using(typeof(List <>).Namespace) .InGlobalScope(@" class C { public List<int> M() { return [|null|]; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "null is returned from method 'C.M()' which has return type of string, collection or task."); }
private void When_declaring_method_return_value_of_non_fakeable_type_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(IFileSystem).Assembly) .Using(typeof(File).Namespace) .InGlobalScope(@" class C { private MemoryStream ms() { throw new System.NotImplementedException(); } public BinaryReader br() { throw new System.NotImplementedException(); } internal IOException ex() { throw new System.NotImplementedException(); } } ") .Build(); // Act and assert VerifyFileSystemDiagnostic(source); }
internal void When_parameter_of_type_dynamic_is_assigned_to_explicitly_cast_string_constant_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(DynamicAttribute).Assembly) .InGlobalScope(@" class C { void M(ref dynamic d) { d = (dynamic)""A""; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_shorter_method_overload_is_abstract_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" abstract class C { protected abstract void M(); protected virtual void M(string s) { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_partial_static_class_name_does_not_end_with_Extensions_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" static partial class [|C|] { } static partial class C { } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Class 'C' should be non-static or its name should be suffixed with 'Extensions'."); }
internal void When_parameter_of_type_dynamic_is_assigned_to_an_Object_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(DynamicAttribute).Assembly) .InGlobalScope(@" class C { void M(object p, out dynamic d) { d = p; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
private void When_declaring_property_of_non_fakeable_type_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(IFileSystem).Assembly) .Using(typeof(File).Namespace) .InGlobalScope(@" class C { private MemoryStream ms { get; set; } public BinaryReader br { get; set; } internal IOException ex { get; set; } } ") .Build(); // Act and assert VerifyFileSystemDiagnostic(source); }
internal void When_method_contains_eight_fixed_statements_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .Using(typeof(IEnumerable).Namespace) .InGlobalScope(@" class C { unsafe void [|M|]() { fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } fixed (char* p = Environment.MachineName) { } } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Method 'C.M()' contains 8 statements, which exceeds the maximum of seven statements."); }
internal void When_constructor_parameter_has_out_modifier_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { C(out string [|p|]) { p = default; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Parameter 'p' is declared as ref or out."); }
internal void When_namespace_name_starts_with_assembly_name_but_does_not_match_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InAssemblyNamed("Some.Scope2.Example") .InGlobalScope(@" namespace Some { namespace [|Scope|] { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Namespace 'Some.Scope' does not match with assembly name 'Some.Scope2.Example'."); }
internal void When_returning_null_for_async_return_type_ValueTask_of_Exception_it_must_be_skipped() { ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(ValueTask <>).Assembly) .Using(typeof(ValueTask <>).Namespace) .InGlobalScope(@" class C { public async ValueTask<Exception> M() { return null; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_method_returns_generic_ICollection_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .Using(typeof(ICollection <>).Namespace) .InGlobalScope(@" class C { ICollection<string> M() { throw new NotImplementedException(); } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_returning_from_async_ValueTask_method_it_must_be_skipped() { ParsedSourceCode source = new TypeSourceCodeBuilder() .WithReference(typeof(ValueTask).Assembly) .Using(typeof(ValueTask).Namespace) .InGlobalScope(@" class C { public async ValueTask M() { return; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_variable_name_consists_of_single_letter_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { void Method() { string [|s|] = ""A""; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Variable 's' should have a more descriptive name."); }
internal void When_method_contains_eight_switch_statements_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { void [|M|](int i) { switch (i) { } switch (i) { } switch (i) { } switch (i) { } switch (i) { } switch (i) { } switch (i) { } switch (i) { } } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Method 'C.M(int)' contains 8 statements, which exceeds the maximum of seven statements."); }
internal void When_partial_method_implementation_is_missing_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" partial class C { partial void M(); protected virtual void M(string s) { } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
internal void When_public_method_return_type_is_nullable_bool_and_name_does_not_start_with_a_verb_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" public class C { public bool? [|ThisIsVisible|]() { throw new NotImplementedException(); } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "The name of public boolean method 'ThisIsVisible' should start with a verb."); }
When_parameter_order_in_generic_explicitly_implemented_overloads_is_not_consistent_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" public interface I<T> { T M(); T M(string value); T M(int index, string value); T M(string value, int index, bool flag); } public class C : I<bool> { bool I<bool>.M() { var iface = (I<bool>)this; return iface.M(string.Empty); } bool I<bool>.M(string value) { var iface = (I<bool>)this; return iface.M(-1, value); } bool I<bool>.M(int index, string value) { var iface = (I<bool>)this; return iface.M(value, index, false); } bool I<bool>.M(string value, int index, bool flag) { throw new NotImplementedException(); } } ") .Build(); VerifyGuidelineDiagnostic(source); }
internal void When_method_returns_null_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .Using(typeof(IEnumerable).Namespace) .InGlobalScope(@" class C { IEnumerable M() { return null; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source); }
private void When_missing_assembly_reference_it_must_be_skipped() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .Using(typeof(File).Namespace) .InGlobalScope(@" class C { void M() { var stream = File.Create(null); } } ") .Build(); // Act and assert VerifyFileSystemDiagnostic(source); }
internal void When_static_class_contains_public_static_property_and_name_ends_with_Extensions_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" static class SomeExtensions { public static int [|P|] { get; set; } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Extension method container class 'SomeExtensions' contains public member 'P', which is not an extension method."); }
internal void When_method_returns_array_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InGlobalScope(@" class C { int[] [|M|]() { throw new NotImplementedException(); } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "Return type in signature for 'C.M()' should be a collection interface instead of a concrete type."); }
internal void When_file_declares_multiple_classes_it_must_be_reported() { // Arrange ParsedSourceCode source = new TypeSourceCodeBuilder() .InFileNamed("Example.cs") .InGlobalScope(@" namespace N1 { class C { class Nested { } } class [|C2|] { } } class [|C3|] { } namespace N2.N3 { class [|C4|] { class Nested { } } } ") .Build(); // Act and assert VerifyGuidelineDiagnostic(source, "File 'Example.cs' contains additional type 'N1.C2'.", "File 'Example.cs' contains additional type 'C3'.", "File 'Example.cs' contains additional type 'N2.N3.C4'."); }