/testability-explorer/src/test/java/com/google/test/metric/CyclomaticComplexityTest.java

http://testability-explorer.googlecode.com/ · Java · 270 lines · 224 code · 31 blank · 15 comment · 14 complexity · 6942c7639fe99d51070cd8cb856f901e MD5 · raw file

  1. /*
  2. * Copyright 2007 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.google.test.metric;
  17. import static java.util.Arrays.asList;
  18. import java.util.List;
  19. public class CyclomaticComplexityTest extends AutoFieldClearTestCase {
  20. private final ClassRepository repo = new JavaClassRepository();
  21. private ClassInfo classInfo;
  22. @Override
  23. protected void setUp() throws Exception {
  24. super.setUp();
  25. classInfo = repo.getClass(CyclomaticMethods.class.getCanonicalName());
  26. }
  27. public static class CyclomaticMethods {
  28. public void emptyMethod_1() {
  29. }
  30. public void simpleMethod_1() {
  31. int i = 0;
  32. i += 1;
  33. }
  34. public void ifMethod_2() {
  35. int a = 0;
  36. if (a < 0) {
  37. a++;
  38. } else {
  39. a--;
  40. }
  41. }
  42. public void ifMethodNoElse_2() {
  43. int a = 0;
  44. if (a < 0) {
  45. a++;
  46. }
  47. }
  48. public void tryCatch_2() {
  49. int a = 0;
  50. try {
  51. a++;
  52. } catch (RuntimeException e) {
  53. a++;
  54. }
  55. }
  56. public void tryCatchFinally_2() {
  57. int a = 0;
  58. try {
  59. a++;
  60. } catch (RuntimeException e) {
  61. a++;
  62. } finally {
  63. a++;
  64. }
  65. }
  66. public void emptySwitch_2() {
  67. int a = 0;
  68. switch (a) {
  69. case 0:
  70. a = 0;
  71. }
  72. }
  73. public void emptySwitch_5() {
  74. int a = 0;
  75. switch (a) {
  76. case 0:
  77. a = 0;
  78. break;
  79. case 1:
  80. a = 1;
  81. break;
  82. case 2:
  83. a = 2;
  84. break;
  85. case 4:
  86. a = 4;
  87. break;
  88. default:
  89. }
  90. }
  91. public void switchImplementWithLookUp_3() {
  92. int a = 0;
  93. switch (a) {
  94. case 0:
  95. a = 0;
  96. break;
  97. case 9999:
  98. a = 9999;
  99. break;
  100. default:
  101. a = -1;
  102. }
  103. }
  104. public void switchWithDefault_2() {
  105. int a = 0;
  106. switch (a) {
  107. case 0:
  108. a = 0;
  109. break;
  110. default:
  111. }
  112. }
  113. }
  114. public void testVerifyAllMethodsCyclomaticComplexity() throws Exception {
  115. String errors = "";
  116. for (MethodInfo method : classInfo.getMethods()) {
  117. String name = method.getName();
  118. int _Index = name.lastIndexOf('_');
  119. if (_Index > 0) {
  120. long expectedCC = Long.parseLong(name.substring(_Index + 1, name.indexOf('(')));
  121. long actualCC = method.getLinesOfComplexity().size() + 1;
  122. if (expectedCC != actualCC) {
  123. errors += "\n" + method.getName()
  124. + " should have Cyclomatic Complexity of "
  125. + expectedCC + " but was " + actualCC;
  126. }
  127. }
  128. }
  129. assertTrue(errors, errors.length() == 0);
  130. }
  131. public static class LineNumbersForConditionals {
  132. int a=0;
  133. boolean flag;
  134. public void method() {
  135. a = flag ? 1 : 2;
  136. a = !flag ? 3 : 4;
  137. }
  138. public void tryCatch() {
  139. try {
  140. a = 1;
  141. } catch (RuntimeException e) {
  142. a = 2;
  143. } finally {
  144. a = 3;
  145. }
  146. }
  147. public void tryCatchCatch() {
  148. try {
  149. a = 1;
  150. } catch (RuntimeException e) {
  151. a = 2;
  152. } catch (Exception e) {
  153. a = 2;
  154. } finally {
  155. a = 3;
  156. }
  157. }
  158. public void nestedTryCatch() {
  159. try {
  160. try {
  161. a = 1;
  162. } catch (RuntimeException e) {
  163. a = 2;
  164. } finally {
  165. a = 3;
  166. }
  167. } catch (RuntimeException e) {
  168. a = 2;
  169. } finally {
  170. a = 3;
  171. }
  172. }
  173. public void tableSwitchMethod() {
  174. switch (a) {
  175. case 1:
  176. a = 1;
  177. break;
  178. default:
  179. a = 2;
  180. break;
  181. }
  182. }
  183. public void lookupSwitchMethod() {
  184. switch (a) {
  185. case 1:
  186. a = 1;
  187. break;
  188. case 1000:
  189. a = 2;
  190. break;
  191. default:
  192. a = 3;
  193. break;
  194. }
  195. }
  196. }
  197. public void testLineNumbersForConditionals() throws Exception {
  198. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  199. MethodInfo methodInfo = classInfo.getMethod("void method()");
  200. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  201. int firstExpectedComplexityLine = methodInfo.getStartingLineNumber();
  202. assertEquals(asList(firstExpectedComplexityLine, firstExpectedComplexityLine + 1), linesOfComplexity);
  203. }
  204. public void testLineNumbersForTryCatch() throws Exception {
  205. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  206. MethodInfo methodInfo = classInfo.getMethod("void tryCatch()");
  207. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  208. int firstExpectedComplexityLine = methodInfo.getStartingLineNumber();
  209. assertEquals(asList(firstExpectedComplexityLine + 1), linesOfComplexity);
  210. }
  211. public void testLineNumbersForNestedTryCatch() throws Exception {
  212. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  213. MethodInfo methodInfo = classInfo.getMethod("void nestedTryCatch()");
  214. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  215. int methodLine = methodInfo.getStartingLineNumber();
  216. assertEquals(asList(methodLine + 1, methodLine + 6), linesOfComplexity);
  217. }
  218. public void testLineNumbersForTryCatchCatch() throws Exception {
  219. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  220. MethodInfo methodInfo = classInfo.getMethod("void tryCatchCatch()");
  221. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  222. int methodLine = methodInfo.getStartingLineNumber();
  223. assertEquals(asList(methodLine + 1, methodLine + 3), linesOfComplexity);
  224. }
  225. public void testLineNumbersForTableSwitch() throws Exception {
  226. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  227. MethodInfo methodInfo = classInfo.getMethod("void tableSwitchMethod()");
  228. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  229. int methodLine = methodInfo.getStartingLineNumber();
  230. assertEquals(asList(methodLine + 2), linesOfComplexity);
  231. }
  232. public void testLineNumbersForLookupSwitch() throws Exception {
  233. ClassInfo classInfo = repo.getClass(LineNumbersForConditionals.class.getCanonicalName());
  234. MethodInfo methodInfo = classInfo.getMethod("void lookupSwitchMethod()");
  235. List<Integer> linesOfComplexity = methodInfo.getLinesOfComplexity();
  236. int methodLine = methodInfo.getStartingLineNumber();
  237. assertEquals(asList(methodLine + 2, methodLine + 5), linesOfComplexity);
  238. }
  239. }