diff options
author | Néstor Salceda <nestor@mono-cvs.ximian.com> | 2008-12-17 19:28:24 +0300 |
---|---|---|
committer | Néstor Salceda <nestor@mono-cvs.ximian.com> | 2008-12-17 19:28:24 +0300 |
commit | f2fc97e7dfc99d682674005876044a12c6e16f1e (patch) | |
tree | 04def68b27186c91530e8434a46e6c5143291f96 /gendarme/rules/Gendarme.Rules.Smells/Test | |
parent | 90522209817e107b570c9acdc02da4536e1dfdbc (diff) |
2008-12-17 Néstor Salceda <nestor.salceda@gmail.com>
* AvoidCodeDuplicatedInSameClassTest.cs: Added more tests in order to
improve the confidence about the code duplicated rules.
svn path=/trunk/mono-tools/; revision=121703
Diffstat (limited to 'gendarme/rules/Gendarme.Rules.Smells/Test')
-rw-r--r-- | gendarme/rules/Gendarme.Rules.Smells/Test/AvoidCodeDuplicatedInSameClassTest.cs | 803 | ||||
-rw-r--r-- | gendarme/rules/Gendarme.Rules.Smells/Test/ChangeLog | 5 |
2 files changed, 695 insertions, 113 deletions
diff --git a/gendarme/rules/Gendarme.Rules.Smells/Test/AvoidCodeDuplicatedInSameClassTest.cs b/gendarme/rules/Gendarme.Rules.Smells/Test/AvoidCodeDuplicatedInSameClassTest.cs index 5645f9fc..9fb0a4a8 100644 --- a/gendarme/rules/Gendarme.Rules.Smells/Test/AvoidCodeDuplicatedInSameClassTest.cs +++ b/gendarme/rules/Gendarme.Rules.Smells/Test/AvoidCodeDuplicatedInSameClassTest.cs @@ -29,8 +29,11 @@ using System; using System.Collections; using System.Reflection; +using System.IO; +using System.Xml; using Gendarme.Framework; +using Gendarme.Framework.Rocks; using Gendarme.Rules.Smells; using Mono.Cecil; using NUnit.Framework; @@ -39,186 +42,760 @@ using Test.Rules.Helpers; namespace Test.Rules.Smells { - public class ClassWithoutCodeDuplicated { - private IList myList; - private IList otherList; + [TestFixture] + public class AvoidCodeDuplicatedInSameClassTest : TypeRuleTestFixture<AvoidCodeDuplicatedInSameClassRule> { + static IList myList; + + class DuplicatedCodeWithForeachLoops { - public IList MyList { - get { - if (myList == null) - myList = new ArrayList (); - return myList; + public void PrintAndAddANewValue () + { + foreach (string value in myList) + Console.WriteLine (value); + myList.Add ("FooReplied"); } + + public void PrintAndRemoveANewValue () + { + foreach (string value in myList) + Console.WriteLine (value); + myList.Remove ("FooReplied"); + } + } + + [Test] + public void FailOnDuplicatedCodeWithForeachLoopsTest () + { + AssertRuleFailure<DuplicatedCodeWithForeachLoops> (1); } - public IList OtherList { - get { - if (otherList == null) - otherList = new ArrayList (); - return otherList; + class DuplicatedCodeInDifferentPlaces { + + public void ShowBannerAndAdd () + { + Console.WriteLine ("Banner"); + Console.WriteLine ("Print"); + myList.Add ("MoreBar"); + } + + public void AddAndShowBanner () + { + myList.Add ("MoreFoo"); + Console.WriteLine ("Banner"); + Console.WriteLine ("Print"); } } - public ClassWithoutCodeDuplicated () + [Test] + public void FailOnDuplicatedCodeInDifferentPlacesTest () { - myList = new ArrayList (); - myList.Add ("Foo"); - myList.Add ("Bar"); - myList.Add ("Baz"); + AssertRuleFailure<DuplicatedCodeInDifferentPlaces> (1); } - private void PrintValuesInList () - { - foreach (string value in myList) { - Console.WriteLine (value); - } + class DuplicatedCodeInForLoop { + + public void PrintUsingAForLoopAndAddAValue () + { + for (int index = 0; index < myList.Count; index++) + Console.WriteLine (myList[index]); + myList.Add ("MoreFoo"); + } + + public void PrintUsingAForLoopAndRemoveAValue () + { + for (int index = 0; index < myList.Count; index++) + Console.WriteLine (myList[index]); + myList.Remove ("MoreFoo"); + } } - private void PrintValuesInListUsingAForLoop () + [Test] + public void FailOnDuplicatedCodeInForLoopTest () { - for (int index = 0; index < myList.Count; index++) { - Console.WriteLine (myList[index]); + AssertRuleFailure<DuplicatedCodeInForLoop> (1); + } + + class DuplicatedCodeInConditional { + + public void IfConditionAndRemove () { + if (myList.Contains ("MoreFoo") & myList.Contains ("MoreBar")) + myList.Remove ("MoreFoo"); + } + + public void IfConditionAndRemoveReplied () { + if (myList.Contains ("MoreFoo") & myList.Contains ("MoreFoo")) + myList.Remove ("MoreFoo"); } } - public void PrintAndAddANewValue () + [Test] + public void FailOnDuplicatedCodeInConditionalTest () { - PrintValuesInList (); - myList.Add ("FooReplied"); + AssertRuleFailure<DuplicatedCodeInConditional> (1); + } + + class NonDuplicatedWithOneInstructionOnly { + public void WriteLine () + { + Console.WriteLine ("Foo"); + } + + public void WriteTheSame () + { + Console.WriteLine ("Foo"); + } } - public void PrintAndRemoveANewValue () + [Test] + public void SuccessOnNonDuplicatedWithOneInstructionOnlyTest () { - PrintValuesInList (); - myList.Remove ("FooReplied"); + AssertRuleSuccess<NonDuplicatedWithOneInstructionOnly> (); + } + + class LazyLoad { + IList otherList; + + public IList MyList { + get { + if (myList == null) + myList = new ArrayList (); + return myList; + } + } + + public IList OtherList { + get { + if (otherList == null) + otherList = new ArrayList (); + return otherList; + } + } } + - public void PrintUsingAForLoopAndRemoveAValueIfNotExists () + [Test] + public void SuccesOnLazyLoadTest () { - PrintValuesInListUsingAForLoop (); - if (!myList.Contains ("Bar")) - myList.Remove ("Bar"); + AssertRuleSuccess<LazyLoad> (); } + + class NonDuplicatedForeachLoop { + void PrintValuesInList () + { + foreach (string value in myList) + Console.WriteLine (value); + } + + public void PrintAndAddANewValue () + { + PrintValuesInList (); + myList.Add ("FooReplied"); + } + + public void PrintAndRemoveANewValue () + { + PrintValuesInList (); + myList.Remove ("FooReplied"); + } + } + + [Test] + public void SuccessOnNonDuplicatedForeachLoopTest () + { + AssertRuleSuccess<NonDuplicatedForeachLoop> (); + } + + class NonDuplicatedForLoop { + + private void PrintValuesInListUsingAForLoop () + { + for (int index = 0; index < myList.Count; index++) + Console.WriteLine (myList[index]); + } + + public void PrintUsingAForLoopAndRemoveAValueIfNotExists () + { + PrintValuesInListUsingAForLoop (); + if (!myList.Contains ("Bar")) + myList.Remove ("Bar"); + } - public void PrintUsingAForLoopAndRemoveAValueIfExists () + public void PrintUsingAForLoopAndRemoveAValueIfExists () + { + PrintValuesInListUsingAForLoop (); + if (myList.Contains ("Bar")) + myList.Remove ("Bar"); + } + } + + [Test] + public void SuccessOnNonDuplicatedForLoopTest () { - PrintValuesInListUsingAForLoop (); - if (myList.Contains ("Bar")) - myList.Remove ("Bar"); + AssertRuleSuccess<NonDuplicatedForLoop> (); } - } - - public class ClassWithCodeDuplicated { - private IList myList; - public ClassWithCodeDuplicated () + //Smaller tests + + class NonDuplicatedCodeIntoForeachLoop { + public void PrintValues () + { + foreach (string value in myList) + Console.WriteLine (value); + } + + public void PrintValuesInSameLine () + { + foreach (string value in myList) + Console.Write (value); + } + } + + + [Test] + public void SuccessOnNonDuplicatedCodeIntoForeachLoopTest () { - myList = new ArrayList (); - myList.Add ("Foo"); - myList.Add ("Bar"); - myList.Add ("Baz"); + AssertRuleSuccess<NonDuplicatedCodeIntoForeachLoop> (); + } + + class NonDuplicatedCodeWithUsingBlock { + public void UsingAndReadStream () + { + using (Stream stream = new FileStream ("sample.txt", FileMode.Open)) + stream.ReadByte (); + } + + public void UsingAndWriteStream () + { + using (Stream stream = new FileStream ("sample.txt", FileMode.Create)) + stream.WriteByte (1); + } } - public void PrintAndAddANewValue () + [Test] + public void SuccessOnNonDuplicatedCodeWithUsingBlockTest () { - foreach (string value in myList) { - Console.WriteLine (value); + AssertRuleSuccess<NonDuplicatedCodeWithUsingBlock> (); + } + + class NonDuplicatedInSwitchs { + Severity severity = Severity.Low; + Confidence confidence = Confidence.Normal; + + //Althoug both are referring to option as argument, it + //isn't the same switch. + public void FirstNonDuplicatedSwitch (string option) + { + switch (option) { + case "AUDIT": + case "AUDIT+": + case "AUDIT-": + severity = Severity.Audit; + break; + case "LOW": + case "LOW+": + case "LOW-": + severity = Severity.Low; + break; + case "MEDIUM": + case "MEDIUM+": + case "MEDIUM-": + severity = Severity.Medium; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + severity = Severity.High; + break; + case "CRITICAL": + case "CRITICAL+": + case "CRITICAL-": + severity = Severity.Critical; + break; + default: + break; + } + } + + public void SecondNonDuplicatedSwitch (string option) + { + switch (option) { + case "LOW": + case "LOW+": + case "LOW-": + confidence = Confidence.Low; + break; + case "NORMAL": + case "NORMAL+": + case "NORMAL-": + confidence = Confidence.Normal; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + confidence = Confidence.High; + break; + case "TOTAL": + case "TOTAL+": + case "TOTAL-": + confidence = Confidence.Total; + break; + default: + break; + } } - myList.Add ("FooReplied"); } - public void PrintAndRemoveANewValue () + [Test] + public void SuccessOnNonDuplicatedInSwitchsTest () { - foreach (string value in myList) { - Console.WriteLine (value); + AssertRuleSuccess<NonDuplicatedInSwitchs> (); + } + + class DuplicatedInSwitchsLoadingByFields { + string option = "LOW"; + Severity severity = Severity.Low; + + public void FirstDuplicatedSwitch () + { + switch (option) { + case "AUDIT": + case "AUDIT+": + case "AUDIT-": + severity = Severity.Audit; + break; + case "LOW": + case "LOW+": + case "LOW-": + severity = Severity.Low; + break; + case "MEDIUM": + case "MEDIUM+": + case "MEDIUM-": + severity = Severity.Medium; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + severity = Severity.High; + break; + case "CRITICAL": + case "CRITICAL+": + case "CRITICAL-": + severity = Severity.Critical; + break; + default: + break; + } + } - myList.Remove ("FooReplied"); - } - - //This two methods contains code duplicated, but by the moment - //the comparer can't detect it, because is a special case and - //for the next improvements I will improve the compararer for - //detect also subsets. - /* - public void ShowBannerAndAdd () + + public void SecondDuplicatedSwitch () + { + switch (option) { + case "AUDIT": + case "AUDIT+": + case "AUDIT-": + severity = Severity.Audit; + break; + case "LOW": + case "LOW+": + case "LOW-": + severity = Severity.Low; + break; + case "MEDIUM": + case "MEDIUM+": + case "MEDIUM-": + severity = Severity.Medium; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + severity = Severity.High; + break; + case "CRITICAL": + case "CRITICAL+": + case "CRITICAL-": + severity = Severity.Critical; + break; + default: + break; + } + } + } + + [Test] + public void FailOnDuplicatedInSwitchsLoadingByFieldsTest () { - Console.WriteLine ("Banner"); - Console.WriteLine ("Print"); - myList.Add ("MoreBar"); + AssertRuleFailure<DuplicatedInSwitchsLoadingByFields> (1); } - public void AddAndShowBanner () - { - myList.Add ("MoreFoo"); - Console.WriteLine ("Banner"); - Console.WriteLine ("Print"); + class NonDuplicatedInSwitchsLoadingByFields { + string option = "LOW"; + Severity severity = Severity.Low; + Confidence confidence = Confidence.Normal; + + //Althoug both are referring to option as argument, it + //isn't the same switch. + public void FirstNonDuplicatedSwitch () + { + switch (option) { + case "AUDIT": + case "AUDIT+": + case "AUDIT-": + severity = Severity.Audit; + break; + case "LOW": + case "LOW+": + case "LOW-": + severity = Severity.Low; + break; + case "MEDIUM": + case "MEDIUM+": + case "MEDIUM-": + severity = Severity.Medium; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + severity = Severity.High; + break; + case "CRITICAL": + case "CRITICAL+": + case "CRITICAL-": + severity = Severity.Critical; + break; + default: + break; + } + } + + public void SecondNonDuplicatedSwitch () + { + switch (option) { + case "LOW": + case "LOW+": + case "LOW-": + confidence = Confidence.Low; + break; + case "NORMAL": + case "NORMAL+": + case "NORMAL-": + confidence = Confidence.Normal; + break; + case "HIGH": + case "HIGH+": + case "HIGH-": + confidence = Confidence.High; + break; + case "TOTAL": + case "TOTAL+": + case "TOTAL-": + confidence = Confidence.Total; + break; + default: + break; + } + } } - */ - public void PrintUsingAForLoopAndAddAValue () + [Test] + public void SuccesOnNonDuplicatedInSwitchsLoadingByFieldsTest () { - for (int index = 0; index < myList.Count; index++) { - Console.WriteLine (myList[index]); + AssertRuleSuccess<NonDuplicatedInSwitchsLoadingByFields> (); + } + + class NonDuplicatedCodeInParameterChecking { + void MethodWithParameters (string x, string y) + { + if ((x == null) || (y == null)) + return; + + char z = 'a'; + } + + void MethodWithParameters (object x, string y) + { + if ((x == null) || (y == null)) + return; + + int f = 2; } - myList.Add ("MoreFoo"); } - - public void PrintUsingAForLoopAndRemoveAValue () + + [Test] + public void SuccessOnNonDuplicatedCodeInParameterChecking () { - for (int index = 0; index < myList.Count; index++) { - Console.WriteLine (myList[index]); + AssertRuleSuccess<NonDuplicatedCodeInParameterChecking> (); + } + + class NonDuplicatedCodeInForeachLoopsReturningBoolean { + bool ForeachComparingTypes () + { + foreach (object obj in myList) { + if (obj.GetType ().Equals (Type.EmptyTypes)) + return true; + } + return false; + } + + bool ForeachComparingValues () + { + foreach (int x in myList) { + if (x % 2 == 0) + return true; + } + return false; } - myList.Remove ("MoreFoo"); } - - public void IfConditionAndRemove () { - if (myList.Contains ("MoreFoo") & myList.Contains ("MoreBar")) - myList.Remove ("MoreFoo"); + + [Test] + public void SuccessOnNonDuplicatedCodeInForeachLoopsReturningBooleanTest () + { + AssertRuleSuccess<NonDuplicatedCodeInForeachLoopsReturningBoolean> (); } + + class FalsePositiveInConsoleRunner { + Runner runner; + + static string GetAttribute (XmlNode node, string name, string defaultValue) + { + XmlAttribute xa = node.Attributes [name]; + if (xa == null) + return defaultValue; + return xa.Value; + } + + IRule GetRule (string name) + { + foreach (IRule rule in runner.Rules) { + if (rule.GetType ().ToString ().Contains (name)) + return rule; + } + return null; + } - public void IfConditionAndRemoveReplied () { - if (myList.Contains ("MoreFoo") & myList.Contains ("MoreFoo")) - myList.Remove ("MoreFoo"); + void SetCustomParameters (XmlNode rules) + { + foreach (XmlElement parameter in rules.SelectNodes ("parameter")) { + string ruleName = GetAttribute (parameter, "rule", String.Empty); + string propertyName = GetAttribute (parameter, "property", String.Empty); + int value = Int32.Parse (GetAttribute (parameter, "value", String.Empty)); + + IRule rule = GetRule (ruleName); + if (rule == null) + throw new XmlException (String.Format ("The rule with name {0} doesn't exist. Review your configuration file.", ruleName)); + PropertyInfo property = rule.GetType ().GetProperty (propertyName); + if (property == null) + throw new XmlException (String.Format ("The property {0} can't be found in the rule {1}. Review your configuration file.", propertyName, ruleName)); + if (!property.CanWrite) + throw new XmlException (String.Format ("The property {0} can't be written in the rule {1}. Review your configuration file", propertyName, ruleName)); + property.GetSetMethod ().Invoke (rule, new object[] {value}); + } + } } - } - - public class UsingProperties { - ArrayList x = new ArrayList (); - ArrayList y = new ArrayList (); - ArrayList z = new ArrayList (); - public int X { - get { return x.Count; } + [Test] + public void SuccessOnFalsePositiveInConsoleRunnerTest () + { + AssertRuleSuccess<FalsePositiveInConsoleRunner> (); } - public int Y { - get { return y.Count; } + class NonDuplicatedCodeCheckingSubsetOfParameters { + ArrayList engine_dependencies = new ArrayList (); + + void Initialize () + { + if (engine_dependencies.Count == 0) + return; + + foreach (object eda in engine_dependencies) + Console.WriteLine (eda); + } + + void TearDown () + { + if ((engine_dependencies == null) || (engine_dependencies.Count == 0)) + return; + + foreach (object eda in engine_dependencies) + Console.Write (eda); + } } - public int Z { - get { return z.Count; } + [Test] + public void SuccessOnNonDuplicatedCodeCheckingSubsetOfParametersTest () + { + AssertRuleSuccess<NonDuplicatedCodeCheckingSubsetOfParameters> (); + } + + class NonDuplicatedCheckingAndReturningDifferentOperations { + ulong mask; + + bool IsSubsetOf (string bitmask) + { + if (bitmask == null) + return false; + return ((mask & bitmask[0]) == mask); + } + + bool Equals (string bitmask) + { + if (bitmask == null) + return false; + return (mask == bitmask[0]); + } } - } - - [TestFixture] - public class AvoidCodeDuplicatedInSameClassTest : TypeRuleTestFixture<AvoidCodeDuplicatedInSameClassRule> { [Test] - public void TestClassWithoutCodeDuplicated () + public void SuccessOnNonDuplicatedCheckingAndReturningDifferentOperationsTest () { - AssertRuleSuccess<ClassWithoutCodeDuplicated> (); + AssertRuleSuccess<NonDuplicatedCheckingAndReturningDifferentOperations> (); } - + + class CheckingIntegersAndStrings { + bool CheckParameters (TypeReference eventType, MethodReference invoke) + { + if (invoke.Parameters.Count == 2) + return true; + + Runner.Report (eventType, Severity.Medium, Confidence.High, "The delegate should have 2 parameters"); + return false; + + } + + bool CheckGenericDelegate (TypeReference type) + { + if (type.FullName == "System.EventHandler`1") + return true; + + Runner.Report (type, Severity.Medium, Confidence.High, "Generic delegates should use EventHandler<TEventArgs>"); + return false; + } + } + + [Test] + public void SuccessOnCheckingIntegersAndStringsTest () + { + AssertRuleSuccess<CheckingIntegersAndStrings> (); + } + + class NonDuplicatedComparingAndReturningNull { + string CheckTwoOptions (TypeReference type) + { + if (type.Implements ("System.Collections.IDictionary") || type.Implements ("System.Collections.Generic.IDictionary`2")) + return null; + return "'Dictionary' should only be used for types implementing IDictionary and IDictionary<TKey,TValue>."; + } + + string CheckThreeOptions (TypeReference type) + { + if (type.Implements ("System.Collections.ICollection") || + type.Implements ("System.Collections.IEnumerable") || + type.Implements ("System.Collections.Generic.ICollection`1")) + return null; + + if (type.Inherits ("System.Collections.Queue") || type.Inherits ("System.Collections.Stack") || + type.Inherits ("System.Data.DataSet") || type.Inherits ("System.Data.DataTable")) + return null; + + return "'Collection' should only be used for implementing ICollection or IEnumerable or inheriting from Queue, Stack, DataSet and DataTable."; + } + } + [Test] - public void TestClassWithCodeDuplicated () + public void SuccessOnNonDuplicatedComparingAndReturningNullTest () { - AssertRuleFailure<ClassWithCodeDuplicated> (3); + AssertRuleSuccess<NonDuplicatedComparingAndReturningNull> (); + } + + class NonDuplicatedCodeComparingStringEmpty { + int IndexOfFirstCorrectChar (string name) + { + return 1; + } + + string CheckStringAndReturn (string name) + { + if (String.IsNullOrEmpty (name)) + return String.Empty; + + if (name.Length == 1) + return name.ToUpperInvariant (); + + int index = IndexOfFirstCorrectChar (name); + return Char.ToUpperInvariant (name [index]) + name.Substring (index + 1); + } + + string CheckStringAndReturnTheOpposite (string name) + { + if (String.IsNullOrEmpty (name)) + return String.Empty; + + if (name.Length == 1) + return name.ToLowerInvariant (); + + int index = IndexOfFirstCorrectChar (name); + return Char.ToLowerInvariant (name [index]) + name.Substring (index + 1); + } + } + + [Test] + public void SuccessOnNonDuplicatedCodeComparingStringEmptyTest () + { + AssertRuleSuccess<NonDuplicatedCodeComparingStringEmpty> (); + } + + class NonDuplicatedCodeWithNonCompatibleTypes { + + public string EngineType { get; internal set; } + + public void SetEngineTypeFromType (Type engineType) + { + if (engineType == null) + throw new ArgumentNullException ("engineType"); + EngineType = engineType.FullName; + } + + public void SetEngineTypeFromString (string engineType) + { + if (engineType == null) + throw new ArgumentNullException ("engineType"); + EngineType = engineType; + } + } + + [Test] + public void SuccessOnNonDuplicatedCodeWithNonCompatibleTypesTest () + { + //Although it seems the same pattern, we are not able to + //extract the code fairly + //If we chains the ctors, we could receive a nullref + //exception. + AssertRuleSuccess<NonDuplicatedCodeWithNonCompatibleTypes> (); + } + + class NonDuplicateCodeWithNonCompatibleTypesInLocals { + public void LocalSimple () + { + MethodDefinition method = null; + if (method == null) + throw new Exception (); + Console.WriteLine (method); + } + + public void OptionEnum () + { + TypeDefinition type = null; + if (type == null) + throw new Exception (); + Console.WriteLine (type); + } } [Test] - public void TestUsingProperties () + public void SuccessOnNonDuplicateCodeWithNonCompatibleTypesInLocals () { - AssertRuleSuccess<UsingProperties> (); + AssertRuleSuccess<NonDuplicateCodeWithNonCompatibleTypesInLocals> (); } } } diff --git a/gendarme/rules/Gendarme.Rules.Smells/Test/ChangeLog b/gendarme/rules/Gendarme.Rules.Smells/Test/ChangeLog index b61f8b81..9d961456 100644 --- a/gendarme/rules/Gendarme.Rules.Smells/Test/ChangeLog +++ b/gendarme/rules/Gendarme.Rules.Smells/Test/ChangeLog @@ -1,3 +1,8 @@ +2008-12-17 Néstor Salceda <nestor.salceda@gmail.com> + + * AvoidCodeDuplicatedInSameClassTest.cs: Added more tests in order to + improve the confidence about the code duplicated rules. + 2008-12-15 Sebastien Pouliot <sebastien@ximian.com> * AvoidLargeClassesTest.cs: Test for DoesNotApply if a type has no |