You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IssueMetricFormulaFactoryImplTest.java 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.measure.live;
  21. import java.util.Collection;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.Map;
  25. import java.util.Optional;
  26. import java.util.Set;
  27. import org.junit.Rule;
  28. import org.junit.Test;
  29. import org.junit.rules.ExpectedException;
  30. import org.sonar.api.issue.Issue;
  31. import org.sonar.api.measures.CoreMetrics;
  32. import org.sonar.api.measures.Metric;
  33. import org.sonar.api.rule.Severity;
  34. import org.sonar.api.rules.RuleType;
  35. import org.sonar.db.component.ComponentDto;
  36. import org.sonar.db.issue.IssueGroupDto;
  37. import org.sonar.server.measure.DebtRatingGrid;
  38. import org.sonar.server.measure.Rating;
  39. import static java.util.Arrays.asList;
  40. import static org.assertj.core.api.Assertions.assertThat;
  41. public class IssueMetricFormulaFactoryImplTest {
  42. @Rule
  43. public ExpectedException expectedException = ExpectedException.none();
  44. private IssueMetricFormulaFactoryImpl underTest = new IssueMetricFormulaFactoryImpl();
  45. @Test
  46. public void getFormulaMetrics_include_the_dependent_metrics() {
  47. for (IssueMetricFormula formula : underTest.getFormulas()) {
  48. assertThat(underTest.getFormulaMetrics()).contains(formula.getMetric());
  49. for (Metric dependentMetric : formula.getDependentMetrics()) {
  50. assertThat(underTest.getFormulaMetrics()).contains(dependentMetric);
  51. }
  52. }
  53. }
  54. @Test
  55. public void test_violations() {
  56. withNoIssues().assertThatValueIs(CoreMetrics.VIOLATIONS, 0);
  57. with(newGroup(), newGroup().setCount(4)).assertThatValueIs(CoreMetrics.VIOLATIONS, 5);
  58. // exclude resolved
  59. IssueGroupDto resolved = newResolvedGroup(Issue.RESOLUTION_FIXED, Issue.STATUS_RESOLVED);
  60. with(newGroup(), newGroup(), resolved).assertThatValueIs(CoreMetrics.VIOLATIONS, 2);
  61. // include issues on leak
  62. IssueGroupDto onLeak = newGroup().setCount(11).setInLeak(true);
  63. with(newGroup(), newGroup(), onLeak).assertThatValueIs(CoreMetrics.VIOLATIONS, 1 + 1 + 11);
  64. }
  65. @Test
  66. public void test_bugs() {
  67. withNoIssues().assertThatValueIs(CoreMetrics.BUGS, 0);
  68. with(
  69. newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(3),
  70. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(5),
  71. // exclude resolved
  72. newResolvedGroup(RuleType.BUG).setCount(7),
  73. // not bugs
  74. newGroup(RuleType.CODE_SMELL).setCount(11))
  75. .assertThatValueIs(CoreMetrics.BUGS, 3 + 5);
  76. }
  77. @Test
  78. public void test_code_smells() {
  79. withNoIssues().assertThatValueIs(CoreMetrics.CODE_SMELLS, 0);
  80. with(
  81. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3),
  82. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setCount(5),
  83. // exclude resolved
  84. newResolvedGroup(RuleType.CODE_SMELL).setCount(7),
  85. // not code smells
  86. newGroup(RuleType.BUG).setCount(11))
  87. .assertThatValueIs(CoreMetrics.CODE_SMELLS, 3 + 5);
  88. }
  89. @Test
  90. public void test_vulnerabilities() {
  91. withNoIssues().assertThatValueIs(CoreMetrics.VULNERABILITIES, 0);
  92. with(
  93. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setCount(3),
  94. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(5),
  95. // exclude resolved
  96. newResolvedGroup(RuleType.VULNERABILITY).setCount(7),
  97. // not vulnerabilities
  98. newGroup(RuleType.BUG).setCount(11))
  99. .assertThatValueIs(CoreMetrics.VULNERABILITIES, 3 + 5);
  100. }
  101. @Test
  102. public void test_security_hotspots() {
  103. withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 0);
  104. with(
  105. newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.MAJOR).setCount(3),
  106. newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.CRITICAL).setCount(5),
  107. // exclude resolved
  108. newResolvedGroup(RuleType.SECURITY_HOTSPOT).setCount(7),
  109. // not hotspots
  110. newGroup(RuleType.BUG).setCount(11))
  111. .assertThatValueIs(CoreMetrics.SECURITY_HOTSPOTS, 3 + 5);
  112. }
  113. @Test
  114. public void test_security_review_rating() {
  115. withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_REVIEW_RATING, Rating.A);
  116. with(CoreMetrics.SECURITY_HOTSPOTS, 12.0)
  117. .and(CoreMetrics.NCLOC, 1000.0)
  118. .assertThatValueIs(CoreMetrics.SECURITY_REVIEW_RATING, Rating.C);
  119. }
  120. @Test
  121. public void count_unresolved_by_severity() {
  122. withNoIssues()
  123. .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 0)
  124. .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 0)
  125. .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 0)
  126. .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0)
  127. .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0);
  128. with(
  129. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setCount(3),
  130. newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(5),
  131. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(7),
  132. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(11),
  133. // exclude security hotspot
  134. newGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.CRITICAL).setCount(15),
  135. // include leak
  136. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(13),
  137. // exclude resolved
  138. newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setCount(17),
  139. newResolvedGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setCount(19),
  140. newResolvedGroup(RuleType.SECURITY_HOTSPOT).setSeverity(Severity.INFO).setCount(21))
  141. .assertThatValueIs(CoreMetrics.BLOCKER_VIOLATIONS, 11 + 13)
  142. .assertThatValueIs(CoreMetrics.CRITICAL_VIOLATIONS, 7)
  143. .assertThatValueIs(CoreMetrics.MAJOR_VIOLATIONS, 3 + 5)
  144. .assertThatValueIs(CoreMetrics.MINOR_VIOLATIONS, 0)
  145. .assertThatValueIs(CoreMetrics.INFO_VIOLATIONS, 0);
  146. }
  147. @Test
  148. public void count_resolved() {
  149. withNoIssues()
  150. .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 0)
  151. .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 0);
  152. with(
  153. newResolvedGroup(Issue.RESOLUTION_FIXED, Issue.STATUS_RESOLVED).setCount(3),
  154. newResolvedGroup(Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED).setCount(5),
  155. newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_CLOSED).setSeverity(Severity.MAJOR).setCount(7),
  156. newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_CLOSED).setSeverity(Severity.BLOCKER).setCount(11),
  157. newResolvedGroup(Issue.RESOLUTION_REMOVED, Issue.STATUS_CLOSED).setCount(13),
  158. // exclude security hotspot
  159. newResolvedGroup(Issue.RESOLUTION_WONT_FIX, Issue.STATUS_RESOLVED).setCount(15).setRuleType(RuleType.SECURITY_HOTSPOT.getDbConstant()),
  160. // exclude unresolved
  161. newGroup(RuleType.VULNERABILITY).setCount(17),
  162. newGroup(RuleType.BUG).setCount(19))
  163. .assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 5)
  164. .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 7 + 11);
  165. }
  166. @Test
  167. public void count_by_status() {
  168. withNoIssues()
  169. .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 0)
  170. .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 0)
  171. .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 0);
  172. with(
  173. newGroup().setStatus(Issue.STATUS_CONFIRMED).setSeverity(Severity.BLOCKER).setCount(3),
  174. newGroup().setStatus(Issue.STATUS_CONFIRMED).setSeverity(Severity.INFO).setCount(5),
  175. newGroup().setStatus(Issue.STATUS_REOPENED).setCount(7),
  176. newGroup(RuleType.CODE_SMELL).setStatus(Issue.STATUS_OPEN).setCount(9),
  177. newGroup(RuleType.BUG).setStatus(Issue.STATUS_OPEN).setCount(11),
  178. // exclude security hotspot
  179. newGroup(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN).setCount(12),
  180. newResolvedGroup(Issue.RESOLUTION_FALSE_POSITIVE, Issue.STATUS_CLOSED).setCount(13))
  181. .assertThatValueIs(CoreMetrics.CONFIRMED_ISSUES, 3 + 5)
  182. .assertThatValueIs(CoreMetrics.OPEN_ISSUES, 9 + 11)
  183. .assertThatValueIs(CoreMetrics.REOPENED_ISSUES, 7);
  184. }
  185. @Test
  186. public void test_technical_debt() {
  187. withNoIssues().assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 0);
  188. with(
  189. newGroup(RuleType.CODE_SMELL).setEffort(3.0).setInLeak(false),
  190. newGroup(RuleType.CODE_SMELL).setEffort(5.0).setInLeak(true),
  191. // exclude security hotspot
  192. newGroup(RuleType.SECURITY_HOTSPOT).setEffort(9).setInLeak(true),
  193. newGroup(RuleType.SECURITY_HOTSPOT).setEffort(11).setInLeak(false),
  194. // not code smells
  195. newGroup(RuleType.BUG).setEffort(7.0),
  196. // exclude resolved
  197. newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0))
  198. .assertThatValueIs(CoreMetrics.TECHNICAL_DEBT, 3.0 + 5.0);
  199. }
  200. @Test
  201. public void test_reliability_remediation_effort() {
  202. withNoIssues().assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 0);
  203. with(
  204. newGroup(RuleType.BUG).setEffort(3.0),
  205. newGroup(RuleType.BUG).setEffort(5.0).setSeverity(Severity.BLOCKER),
  206. // not bugs
  207. newGroup(RuleType.CODE_SMELL).setEffort(7.0),
  208. // exclude resolved
  209. newResolvedGroup(RuleType.BUG).setEffort(17.0))
  210. .assertThatValueIs(CoreMetrics.RELIABILITY_REMEDIATION_EFFORT, 3.0 + 5.0);
  211. }
  212. @Test
  213. public void test_security_remediation_effort() {
  214. withNoIssues().assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 0);
  215. with(
  216. newGroup(RuleType.VULNERABILITY).setEffort(3.0),
  217. newGroup(RuleType.VULNERABILITY).setEffort(5.0).setSeverity(Severity.BLOCKER),
  218. // not vulnerability
  219. newGroup(RuleType.CODE_SMELL).setEffort(7.0),
  220. // exclude resolved
  221. newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0))
  222. .assertThatValueIs(CoreMetrics.SECURITY_REMEDIATION_EFFORT, 3.0 + 5.0);
  223. }
  224. @Test
  225. public void test_sqale_debt_ratio_and_sqale_rating() {
  226. withNoIssues()
  227. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0)
  228. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  229. // technical_debt not computed
  230. with(CoreMetrics.DEVELOPMENT_COST, 0)
  231. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0)
  232. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  233. with(CoreMetrics.DEVELOPMENT_COST, 20)
  234. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0)
  235. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  236. // development_cost not computed
  237. with(CoreMetrics.TECHNICAL_DEBT, 0)
  238. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0)
  239. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  240. with(CoreMetrics.TECHNICAL_DEBT, 20)
  241. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0)
  242. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  243. // input measures are available
  244. with(CoreMetrics.TECHNICAL_DEBT, 20.0)
  245. .and(CoreMetrics.DEVELOPMENT_COST, 0.0)
  246. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0)
  247. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  248. with(CoreMetrics.TECHNICAL_DEBT, 20.0)
  249. .and(CoreMetrics.DEVELOPMENT_COST, 160.0)
  250. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 12.5)
  251. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.C);
  252. with(CoreMetrics.TECHNICAL_DEBT, 20.0)
  253. .and(CoreMetrics.DEVELOPMENT_COST, 10.0)
  254. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 200.0)
  255. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.E);
  256. // A is 5% --> min debt is exactly 200*0.05=10
  257. with(CoreMetrics.DEVELOPMENT_COST, 200.0)
  258. .and(CoreMetrics.TECHNICAL_DEBT, 10.0)
  259. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 5.0)
  260. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  261. with(CoreMetrics.TECHNICAL_DEBT, 0.0)
  262. .and(CoreMetrics.DEVELOPMENT_COST, 0.0)
  263. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0)
  264. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  265. with(CoreMetrics.TECHNICAL_DEBT, 0.0)
  266. .and(CoreMetrics.DEVELOPMENT_COST, 80.0)
  267. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0);
  268. with(CoreMetrics.TECHNICAL_DEBT, -20.0)
  269. .and(CoreMetrics.DEVELOPMENT_COST, 0.0)
  270. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0)
  271. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  272. // bug, debt can't be negative
  273. with(CoreMetrics.TECHNICAL_DEBT, -20.0)
  274. .and(CoreMetrics.DEVELOPMENT_COST, 80.0)
  275. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0)
  276. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  277. // bug, cost can't be negative
  278. with(CoreMetrics.TECHNICAL_DEBT, 20.0)
  279. .and(CoreMetrics.DEVELOPMENT_COST, -80.0)
  280. .assertThatValueIs(CoreMetrics.SQALE_DEBT_RATIO, 0.0)
  281. .assertThatValueIs(CoreMetrics.SQALE_RATING, Rating.A);
  282. }
  283. @Test
  284. public void test_effort_to_reach_maintainability_rating_A() {
  285. withNoIssues()
  286. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  287. // technical_debt not computed
  288. with(CoreMetrics.DEVELOPMENT_COST, 0.0)
  289. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  290. with(CoreMetrics.DEVELOPMENT_COST, 20.0)
  291. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  292. // development_cost not computed
  293. with(CoreMetrics.TECHNICAL_DEBT, 0.0)
  294. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  295. with(CoreMetrics.TECHNICAL_DEBT, 20.0)
  296. // development cost is considered as zero, so the effort is to reach... zero
  297. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 20.0);
  298. // B to A
  299. with(CoreMetrics.DEVELOPMENT_COST, 200.0)
  300. .and(CoreMetrics.TECHNICAL_DEBT, 40.0)
  301. // B is 5% --> goal is to reach 200*0.05=10 --> effort is 40-10=30
  302. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 40.0 - (200.0 * 0.05));
  303. // E to A
  304. with(CoreMetrics.DEVELOPMENT_COST, 200.0)
  305. .and(CoreMetrics.TECHNICAL_DEBT, 180.0)
  306. // B is 5% --> goal is to reach 200*0.05=10 --> effort is 180-10=170
  307. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 180.0 - (200.0 * 0.05));
  308. // already A
  309. with(CoreMetrics.DEVELOPMENT_COST, 200.0)
  310. .and(CoreMetrics.TECHNICAL_DEBT, 8.0)
  311. // B is 5% --> goal is to reach 200*0.05=10 --> debt is already at 8 --> effort to reach A is zero
  312. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  313. // exactly lower range of B
  314. with(CoreMetrics.DEVELOPMENT_COST, 200.0)
  315. .and(CoreMetrics.TECHNICAL_DEBT, 10.0)
  316. // B is 5% --> goal is to reach 200*0.05=10 --> debt is 10 --> effort to reach A is zero
  317. // FIXME need zero to reach A but effective rating is B !
  318. .assertThatValueIs(CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A, 0.0);
  319. }
  320. @Test
  321. public void test_reliability_rating() {
  322. withNoIssues()
  323. .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A);
  324. with(
  325. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(1),
  326. newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setCount(5),
  327. // excluded, not a bug
  328. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3))
  329. // highest severity of bugs is CRITICAL --> D
  330. .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.D);
  331. with(
  332. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3),
  333. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(5))
  334. // no bugs --> A
  335. .assertThatValueIs(CoreMetrics.RELIABILITY_RATING, Rating.A);
  336. }
  337. @Test
  338. public void test_security_rating() {
  339. withNoIssues()
  340. .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A);
  341. with(
  342. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setCount(1),
  343. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setCount(5),
  344. // excluded, not a vulnerability
  345. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setCount(3))
  346. // highest severity of vulnerabilities is CRITICAL --> D
  347. .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.D);
  348. with(
  349. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setCount(3),
  350. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setCount(5))
  351. // no vulnerabilities --> A
  352. .assertThatValueIs(CoreMetrics.SECURITY_RATING, Rating.A);
  353. }
  354. @Test
  355. public void test_new_bugs() {
  356. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 0.0);
  357. with(
  358. newGroup(RuleType.BUG).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3),
  359. newGroup(RuleType.BUG).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5),
  360. newGroup(RuleType.BUG).setInLeak(true).setSeverity(Severity.MINOR).setCount(7),
  361. // not bugs
  362. newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(9),
  363. newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11))
  364. .assertThatLeakValueIs(CoreMetrics.NEW_BUGS, 5 + 7);
  365. }
  366. @Test
  367. public void test_new_code_smells() {
  368. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 0.0);
  369. with(
  370. newGroup(RuleType.CODE_SMELL).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3),
  371. newGroup(RuleType.CODE_SMELL).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5),
  372. newGroup(RuleType.CODE_SMELL).setInLeak(true).setSeverity(Severity.MINOR).setCount(7),
  373. // not code smells
  374. newGroup(RuleType.BUG).setInLeak(true).setCount(9),
  375. newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(11))
  376. .assertThatLeakValueIs(CoreMetrics.NEW_CODE_SMELLS, 5 + 7);
  377. }
  378. @Test
  379. public void test_new_vulnerabilities() {
  380. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 0.0);
  381. with(
  382. newGroup(RuleType.VULNERABILITY).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3),
  383. newGroup(RuleType.VULNERABILITY).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5),
  384. newGroup(RuleType.VULNERABILITY).setInLeak(true).setSeverity(Severity.MINOR).setCount(7),
  385. // not vulnerabilities
  386. newGroup(RuleType.BUG).setInLeak(true).setCount(9),
  387. newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11))
  388. .assertThatLeakValueIs(CoreMetrics.NEW_VULNERABILITIES, 5 + 7);
  389. }
  390. @Test
  391. public void test_new_security_hotspots() {
  392. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 0.0);
  393. with(
  394. newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(false).setSeverity(Severity.MAJOR).setCount(3),
  395. newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(true).setSeverity(Severity.CRITICAL).setCount(5),
  396. newGroup(RuleType.SECURITY_HOTSPOT).setInLeak(true).setSeverity(Severity.MINOR).setCount(7),
  397. // not hotspots
  398. newGroup(RuleType.BUG).setInLeak(true).setCount(9),
  399. newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(11))
  400. .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_HOTSPOTS, 5 + 7);
  401. }
  402. @Test
  403. public void test_new_violations() {
  404. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 0.0);
  405. with(
  406. newGroup(RuleType.BUG).setInLeak(true).setCount(5),
  407. newGroup(RuleType.CODE_SMELL).setInLeak(true).setCount(7),
  408. newGroup(RuleType.VULNERABILITY).setInLeak(true).setCount(9),
  409. // not in leak
  410. newGroup(RuleType.BUG).setInLeak(false).setCount(11),
  411. newGroup(RuleType.CODE_SMELL).setInLeak(false).setCount(13),
  412. newGroup(RuleType.VULNERABILITY).setInLeak(false).setCount(17))
  413. .assertThatLeakValueIs(CoreMetrics.NEW_VIOLATIONS, 5 + 7 + 9);
  414. }
  415. @Test
  416. public void test_new_blocker_violations() {
  417. withNoIssues()
  418. .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 0.0);
  419. with(
  420. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(3),
  421. newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(5),
  422. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(true).setCount(7),
  423. // not blocker
  424. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9),
  425. // not in leak
  426. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(11),
  427. newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(false).setCount(13))
  428. .assertThatLeakValueIs(CoreMetrics.NEW_BLOCKER_VIOLATIONS, 3 + 5 + 7);
  429. }
  430. @Test
  431. public void test_new_critical_violations() {
  432. withNoIssues()
  433. .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 0.0);
  434. with(
  435. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(3),
  436. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(5),
  437. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(7),
  438. // not CRITICAL
  439. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(true).setCount(9),
  440. // not in leak
  441. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(11),
  442. newGroup(RuleType.BUG).setSeverity(Severity.CRITICAL).setInLeak(false).setCount(13))
  443. .assertThatLeakValueIs(CoreMetrics.NEW_CRITICAL_VIOLATIONS, 3 + 5 + 7);
  444. }
  445. @Test
  446. public void test_new_major_violations() {
  447. withNoIssues()
  448. .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 0.0);
  449. with(
  450. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(true).setCount(3),
  451. newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setInLeak(true).setCount(5),
  452. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MAJOR).setInLeak(true).setCount(7),
  453. // not MAJOR
  454. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9),
  455. // not in leak
  456. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MAJOR).setInLeak(false).setCount(11),
  457. newGroup(RuleType.BUG).setSeverity(Severity.MAJOR).setInLeak(false).setCount(13))
  458. .assertThatLeakValueIs(CoreMetrics.NEW_MAJOR_VIOLATIONS, 3 + 5 + 7);
  459. }
  460. @Test
  461. public void test_new_minor_violations() {
  462. withNoIssues()
  463. .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 0.0);
  464. with(
  465. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MINOR).setInLeak(true).setCount(3),
  466. newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setInLeak(true).setCount(5),
  467. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setInLeak(true).setCount(7),
  468. // not MINOR
  469. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9),
  470. // not in leak
  471. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.MINOR).setInLeak(false).setCount(11),
  472. newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setInLeak(false).setCount(13))
  473. .assertThatLeakValueIs(CoreMetrics.NEW_MINOR_VIOLATIONS, 3 + 5 + 7);
  474. }
  475. @Test
  476. public void test_new_info_violations() {
  477. withNoIssues()
  478. .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 0.0);
  479. with(
  480. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.INFO).setInLeak(true).setCount(3),
  481. newGroup(RuleType.BUG).setSeverity(Severity.INFO).setInLeak(true).setCount(5),
  482. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setInLeak(true).setCount(7),
  483. // not INFO
  484. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.CRITICAL).setInLeak(true).setCount(9),
  485. // not in leak
  486. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.INFO).setInLeak(false).setCount(11),
  487. newGroup(RuleType.BUG).setSeverity(Severity.INFO).setInLeak(false).setCount(13))
  488. .assertThatLeakValueIs(CoreMetrics.NEW_INFO_VIOLATIONS, 3 + 5 + 7);
  489. }
  490. @Test
  491. public void test_new_technical_debt() {
  492. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0);
  493. with(
  494. newGroup(RuleType.CODE_SMELL).setEffort(3.0).setInLeak(true),
  495. // not in leak
  496. newGroup(RuleType.CODE_SMELL).setEffort(5.0).setInLeak(false),
  497. // not code smells
  498. newGroup(RuleType.SECURITY_HOTSPOT).setEffort(9.0).setInLeak(true),
  499. newGroup(RuleType.BUG).setEffort(7.0).setInLeak(true),
  500. // exclude resolved
  501. newResolvedGroup(RuleType.CODE_SMELL).setEffort(17.0).setInLeak(true))
  502. .assertThatLeakValueIs(CoreMetrics.NEW_TECHNICAL_DEBT, 3.0);
  503. }
  504. @Test
  505. public void test_new_reliability_remediation_effort() {
  506. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 0.0);
  507. with(
  508. newGroup(RuleType.BUG).setEffort(3.0).setInLeak(true),
  509. // not in leak
  510. newGroup(RuleType.BUG).setEffort(5.0).setInLeak(false),
  511. // not bugs
  512. newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true),
  513. // exclude resolved
  514. newResolvedGroup(RuleType.BUG).setEffort(17.0).setInLeak(true))
  515. .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_REMEDIATION_EFFORT, 3.0);
  516. }
  517. @Test
  518. public void test_new_security_remediation_effort() {
  519. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 0.0);
  520. with(
  521. newGroup(RuleType.VULNERABILITY).setEffort(3.0).setInLeak(true),
  522. // not in leak
  523. newGroup(RuleType.VULNERABILITY).setEffort(5.0).setInLeak(false),
  524. // not vulnerability
  525. newGroup(RuleType.CODE_SMELL).setEffort(7.0).setInLeak(true),
  526. // exclude resolved
  527. newResolvedGroup(RuleType.VULNERABILITY).setEffort(17.0).setInLeak(true))
  528. .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_REMEDIATION_EFFORT, 3.0);
  529. }
  530. @Test
  531. public void test_new_reliability_rating() {
  532. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.A);
  533. with(
  534. newGroup(RuleType.BUG).setSeverity(Severity.INFO).setCount(3).setInLeak(true),
  535. newGroup(RuleType.BUG).setSeverity(Severity.MINOR).setCount(1).setInLeak(true),
  536. // not in leak
  537. newGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(false),
  538. // not bug
  539. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true),
  540. // exclude resolved
  541. newResolvedGroup(RuleType.BUG).setSeverity(Severity.BLOCKER).setInLeak(true))
  542. // highest severity of bugs on leak period is minor -> B
  543. .assertThatLeakValueIs(CoreMetrics.NEW_RELIABILITY_RATING, Rating.B);
  544. }
  545. @Test
  546. public void test_new_security_rating() {
  547. withNoIssues().assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.A);
  548. with(
  549. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.INFO).setCount(3).setInLeak(true),
  550. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.MINOR).setCount(1).setInLeak(true),
  551. // not in leak
  552. newGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(false),
  553. // not vulnerability
  554. newGroup(RuleType.CODE_SMELL).setSeverity(Severity.BLOCKER).setInLeak(true),
  555. // exclude resolved
  556. newResolvedGroup(RuleType.VULNERABILITY).setSeverity(Severity.BLOCKER).setInLeak(true))
  557. // highest severity of bugs on leak period is minor -> B
  558. .assertThatLeakValueIs(CoreMetrics.NEW_SECURITY_RATING, Rating.B);
  559. }
  560. @Test
  561. public void test_new_sqale_debt_ratio_and_new_maintainability_rating() {
  562. withNoIssues()
  563. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0)
  564. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  565. // technical_debt not computed
  566. withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0)
  567. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0)
  568. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  569. withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 20)
  570. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0)
  571. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  572. // development_cost not computed
  573. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0)
  574. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0)
  575. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  576. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20)
  577. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0)
  578. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  579. // input measures are available
  580. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0)
  581. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0)
  582. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0)
  583. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  584. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0)
  585. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 160.0)
  586. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 12.5)
  587. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.C);
  588. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0)
  589. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 10.0)
  590. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 200.0)
  591. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.E);
  592. // A is 5% --> min debt is exactly 200*0.05=10
  593. withLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 200.0)
  594. .andLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 10.0)
  595. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 5.0)
  596. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  597. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0)
  598. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0)
  599. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0)
  600. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  601. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0)
  602. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 80.0)
  603. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0);
  604. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, -20.0)
  605. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 0.0)
  606. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0)
  607. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  608. // bug, debt can't be negative
  609. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, -20.0)
  610. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, 80.0)
  611. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0)
  612. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  613. // bug, cost can't be negative
  614. withLeak(CoreMetrics.NEW_TECHNICAL_DEBT, 20.0)
  615. .andLeak(CoreMetrics.NEW_DEVELOPMENT_COST, -80.0)
  616. .assertThatLeakValueIs(CoreMetrics.NEW_SQALE_DEBT_RATIO, 0.0)
  617. .assertThatLeakValueIs(CoreMetrics.NEW_MAINTAINABILITY_RATING, Rating.A);
  618. }
  619. private Verifier with(IssueGroupDto... groups) {
  620. return new Verifier(groups);
  621. }
  622. private Verifier withNoIssues() {
  623. return new Verifier(new IssueGroupDto[0]);
  624. }
  625. private Verifier with(Metric metric, double value) {
  626. return new Verifier(new IssueGroupDto[0]).and(metric, value);
  627. }
  628. private Verifier withLeak(Metric metric, double leakValue) {
  629. return new Verifier(new IssueGroupDto[0]).andLeak(metric, leakValue);
  630. }
  631. private class Verifier {
  632. private final IssueGroupDto[] groups;
  633. private final Map<Metric, Double> values = new HashMap<>();
  634. private final Map<Metric, Double> leakValues = new HashMap<>();
  635. private Verifier(IssueGroupDto[] groups) {
  636. this.groups = groups;
  637. }
  638. Verifier and(Metric metric, double value) {
  639. this.values.put(metric, value);
  640. return this;
  641. }
  642. Verifier andLeak(Metric metric, double value) {
  643. this.leakValues.put(metric, value);
  644. return this;
  645. }
  646. Verifier assertThatValueIs(Metric metric, double expectedValue) {
  647. TestContext context = run(metric, false);
  648. assertThat(context.doubleValue).isNotNull().isEqualTo(expectedValue);
  649. return this;
  650. }
  651. Verifier assertThatLeakValueIs(Metric metric, double expectedValue) {
  652. TestContext context = run(metric, true);
  653. assertThat(context.doubleLeakValue).isNotNull().isEqualTo(expectedValue);
  654. return this;
  655. }
  656. Verifier assertThatLeakValueIs(Metric metric, Rating expectedRating) {
  657. TestContext context = run(metric, true);
  658. assertThat(context.ratingLeakValue).isNotNull().isEqualTo(expectedRating);
  659. return this;
  660. }
  661. Verifier assertThatValueIs(Metric metric, Rating expectedValue) {
  662. TestContext context = run(metric, false);
  663. assertThat(context.ratingValue).isNotNull().isEqualTo(expectedValue);
  664. return this;
  665. }
  666. private TestContext run(Metric metric, boolean expectLeakFormula) {
  667. IssueMetricFormula formula = underTest.getFormulas().stream()
  668. .filter(f -> f.getMetric().getKey().equals(metric.getKey()))
  669. .findFirst()
  670. .get();
  671. assertThat(formula.isOnLeak()).isEqualTo(expectLeakFormula);
  672. TestContext context = new TestContext(formula.getDependentMetrics(), values, leakValues);
  673. formula.compute(context, newIssueCounter(groups));
  674. return context;
  675. }
  676. }
  677. private static IssueCounter newIssueCounter(IssueGroupDto... issues) {
  678. return new IssueCounter(asList(issues));
  679. }
  680. private static IssueGroupDto newGroup() {
  681. return newGroup(RuleType.CODE_SMELL);
  682. }
  683. private static IssueGroupDto newGroup(RuleType ruleType) {
  684. IssueGroupDto dto = new IssueGroupDto();
  685. // set non-null fields
  686. dto.setRuleType(ruleType.getDbConstant());
  687. dto.setCount(1);
  688. dto.setEffort(0.0);
  689. dto.setSeverity(Severity.INFO);
  690. dto.setStatus(Issue.STATUS_OPEN);
  691. dto.setInLeak(false);
  692. return dto;
  693. }
  694. private static IssueGroupDto newResolvedGroup(RuleType ruleType) {
  695. return newGroup(ruleType).setResolution(Issue.RESOLUTION_FALSE_POSITIVE).setStatus(Issue.STATUS_CLOSED);
  696. }
  697. private static IssueGroupDto newResolvedGroup(String resolution, String status) {
  698. return newGroup().setResolution(resolution).setStatus(status);
  699. }
  700. private static class TestContext implements IssueMetricFormula.Context {
  701. private final Set<Metric> dependentMetrics;
  702. private Double doubleValue;
  703. private Rating ratingValue;
  704. private Double doubleLeakValue;
  705. private Rating ratingLeakValue;
  706. private final Map<Metric, Double> values;
  707. private final Map<Metric, Double> leakValues;
  708. private TestContext(Collection<Metric> dependentMetrics, Map<Metric, Double> values, Map<Metric, Double> leakValues) {
  709. this.dependentMetrics = new HashSet<>(dependentMetrics);
  710. this.values = values;
  711. this.leakValues = leakValues;
  712. }
  713. @Override
  714. public ComponentDto getComponent() {
  715. throw new UnsupportedOperationException();
  716. }
  717. @Override
  718. public DebtRatingGrid getDebtRatingGrid() {
  719. return new DebtRatingGrid(new double[] {0.05, 0.1, 0.2, 0.5});
  720. }
  721. @Override
  722. public Optional<Double> getValue(Metric metric) {
  723. if (!dependentMetrics.contains(metric)) {
  724. throw new IllegalStateException("Metric " + metric.getKey() + " is not declared as a dependency");
  725. }
  726. if (values.containsKey(metric)) {
  727. return Optional.of(values.get(metric));
  728. }
  729. return Optional.empty();
  730. }
  731. @Override
  732. public Optional<Double> getLeakValue(Metric metric) {
  733. if (!dependentMetrics.contains(metric)) {
  734. throw new IllegalStateException("Metric " + metric.getKey() + " is not declared as a dependency");
  735. }
  736. if (leakValues.containsKey(metric)) {
  737. return Optional.of(leakValues.get(metric));
  738. }
  739. return Optional.empty();
  740. }
  741. @Override
  742. public void setValue(double value) {
  743. this.doubleValue = value;
  744. }
  745. @Override
  746. public void setValue(Rating value) {
  747. this.ratingValue = value;
  748. }
  749. @Override
  750. public void setLeakValue(double value) {
  751. this.doubleLeakValue = value;
  752. }
  753. @Override
  754. public void setLeakValue(Rating value) {
  755. this.ratingLeakValue = value;
  756. }
  757. }
  758. }