diff options
author | Julien Lancelot <julien.lancelot@gmail.com> | 2013-05-22 15:13:36 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@gmail.com> | 2013-05-22 15:13:45 +0200 |
commit | 3342b4980ff6e0f5a4d96ec00e311b2141c1eff3 (patch) | |
tree | 75444a525f107817cb0aa8e05b3f9e73eaa09522 | |
parent | 7dc0d68a5a3cab41afd5dc1c814a6ed4d4900666 (diff) | |
download | sonarqube-3342b4980ff6e0f5a4d96ec00e311b2141c1eff3.tar.gz sonarqube-3342b4980ff6e0f5a4d96ec00e311b2141c1eff3.zip |
SONAR-4301 Replace sql sort on issues by Java sort
8 files changed, 420 insertions, 132 deletions
diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml index ec958e9b814..388bc4bb9cd 100644 --- a/sonar-application/pom.xml +++ b/sonar-application/pom.xml @@ -206,7 +206,7 @@ <configuration> <rules> <requireFilesSize> - <maxsize>58100000</maxsize> + <maxsize>59000000</maxsize> <minsize>54000000</minsize> <files> <file>${project.build.directory}/sonar-${project.version}.zip</file> diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java index 5ffa8a84495..ed15bef6208 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java @@ -45,8 +45,6 @@ import static com.google.common.collect.Maps.newHashMap; */ public class IssueDao implements BatchComponent, ServerComponent { - private final static Integer MAX_RESULT = 10000; - private final MyBatis mybatis; public IssueDao(MyBatis mybatis) { @@ -113,7 +111,7 @@ public class IssueDao implements BatchComponent, ServerComponent { } /** - * The returned IssueDto list contains only the issue id and the project id + * The returned IssueDto list contains only the issue id, the project id and the sort column */ public List<IssueDto> selectIssueAndProjectIds(final IssueQuery query, final Collection<Integer> authorizedRootProjectIds, SqlSession session) { return selectIssueAndProjectIds(query, authorizedRootProjectIds, query.maxResults(), session); @@ -138,24 +136,22 @@ public class IssueDao implements BatchComponent, ServerComponent { } @VisibleForTesting - Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, Boolean asc) { + Collection<IssueDto> selectByIds(Collection<Long> ids) { SqlSession session = mybatis.openSession(); try { - return selectByIds(ids, sort, asc, session); + return selectByIds(ids, session); } finally { MyBatis.closeQuietly(session); } } - public Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, Boolean asc, SqlSession session) { + public Collection<IssueDto> selectByIds(Collection<Long> ids, SqlSession session) { if (ids.isEmpty()) { return Collections.emptyList(); } Object idsPartition = Lists.partition(newArrayList(ids), 1000); Map<String, Object> params = newHashMap(); params.put("ids", idsPartition); - params.put("sort", sort); - params.put("asc", asc); return session.selectList("org.sonar.core.issue.db.IssueMapper.selectByIds", params); } } diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml index f82d0f9e7cf..52ae50afaa3 100644 --- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml @@ -34,37 +34,28 @@ root.kee as projectKey </sql> - <sql id="sortFilter"> - <if test="sort != null"> - order by + <sql id="sortColumn"> + <if test="sort != null">, <choose> <when test="'SEVERITY'.equals(sort.name())"> - i.severity + i.severity as severity </when> <when test="'STATUS'.equals(sort.name())"> - i.status + i.status as status </when> <when test="'ASSIGNEE'.equals(sort.name())"> - i.assignee + i.assignee as assignee </when> <when test="'CREATION_DATE'.equals(sort.name())"> - i.issue_creation_date + i.issue_creation_date as issueCreationDate </when> <when test="'UPDATE_DATE'.equals(sort.name())"> - i.issue_update_date + i.issue_update_date as issueUpdateDate </when> <when test="'CLOSE_DATE'.equals(sort.name())"> - i.issue_close_date + i.issue_close_date as issueCloseDate </when> </choose> - <choose> - <when test="true.equals(asc)"> - asc - </when> - <otherwise> - desc - </otherwise> - </choose> </if> </sql> @@ -153,7 +144,6 @@ and p.id=i.resource_id and i.project_id=root.id </where> - <include refid="sortFilter"/> </select> <select id="selectIssueAndComponentIds" parameterType="map" resultType="Issue"> @@ -163,6 +153,7 @@ <select id="selectIssueAndProjectIds" parameterType="map" resultType="Issue"> select i.id, i.project_id as projectId + <include refid="sortColumn"/> <include refid="selectQueryConditions"/> </select> @@ -286,10 +277,7 @@ and i.issue_creation_date < #{createdBefore} </if> </where> - <if test="sort == null"> - order by i.id - </if> - <include refid="sortFilter"/> + order by i.id </sql> </mapper> diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java index 8418243ce77..73b04ef1796 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java @@ -225,78 +225,6 @@ public class IssueDaoTest extends AbstractDaoTestCase { } @Test - public void should_select_sort_by_severity() { - setupData("shared", "should_select_returned_sorted_result_by_severity"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).asc(true).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getSeverity()).isEqualTo("BLOCKER"); - assertThat(results.get(1).getSeverity()).isEqualTo("MAJOR"); - assertThat(results.get(2).getSeverity()).isEqualTo("MINOR"); - } - - @Test - public void should_select_sort_by_status() { - setupData("shared", "should_select_returned_sorted_result_by_status"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).asc(true).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getStatus()).isEqualTo("CLOSED"); - assertThat(results.get(1).getStatus()).isEqualTo("OPEN"); - assertThat(results.get(2).getStatus()).isEqualTo("REOPEN"); - } - - @Test - public void should_select_sort_by_assignee() { - setupData("shared", "should_select_returned_sorted_result_by_assignee"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).asc(true).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getAssignee()).isEqualTo("arthur"); - assertThat(results.get(1).getAssignee()).isEqualTo("henry"); - assertThat(results.get(2).getAssignee()).isEqualTo("perceval"); - } - - @Test - public void should_select_sort_by_creation_date() { - setupData("shared", "should_select_returned_sorted_result_by_creation_date"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).asc(false).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getId()).isEqualTo(102); - assertThat(results.get(1).getId()).isEqualTo(100); - assertThat(results.get(2).getId()).isEqualTo(101); - } - - @Test - public void should_select_sort_by_update_date() { - setupData("shared", "should_select_returned_sorted_result_by_update_date"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).asc(false).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getId()).isEqualTo(102); - assertThat(results.get(1).getId()).isEqualTo(100); - assertThat(results.get(2).getId()).isEqualTo(101); - } - - @Test - public void should_select_sort_by_close_date() { - setupData("shared", "should_select_returned_sorted_result_by_close_date"); - - IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).asc(false).build(); - List<IssueDto> results = newArrayList(dao.select(query)); - assertThat(results).hasSize(3); - assertThat(results.get(0).getId()).isEqualTo(102); - assertThat(results.get(1).getId()).isEqualTo(100); - assertThat(results.get(2).getId()).isEqualTo(101); - } - - @Test public void should_select_issue_and_component_ids() { setupData("shared", "should_select_issue_and_component_ids"); @@ -313,6 +241,10 @@ public class IssueDaoTest extends AbstractDaoTestCase { List<IssueDto> results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); assertThat(results).hasSize(3); + IssueDto issueDto = results.get(0); + assertThat(issueDto.getId()).isNotNull(); + assertThat(issueDto.getProjectId()).isNotNull(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 2); assertThat(results).hasSize(2); @@ -321,6 +253,35 @@ public class IssueDaoTest extends AbstractDaoTestCase { } @Test + public void should_select_issue_and_project_ids_with_sort_column() { + setupData("shared", "should_select_issue_and_project_ids"); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).build(); + List<IssueDto> results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getAssignee()).isNotNull(); + + query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).build(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getSeverity()).isNotNull(); + + query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).build(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getStatus()).isNotNull(); + + query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).build(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getIssueCreationDate()).isNotNull(); + + query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).build(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getIssueUpdateDate()).isNotNull(); + + query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).build(); + results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000); + assertThat(results.get(0).getIssueCloseDate()).isNotNull(); + } + + @Test public void should_select_open_issues() { setupData("shared", "should_select_open_issues"); @@ -337,10 +298,10 @@ public class IssueDaoTest extends AbstractDaoTestCase { public void should_select_by_ids() { setupData("shared", "should_select_by_ids"); - List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l), IssueQuery.Sort.CREATION_DATE, false)); + List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l))); assertThat(results).hasSize(3); - assertThat(results.get(0).getId()).isEqualTo(102); - assertThat(results.get(1).getId()).isEqualTo(100); - assertThat(results.get(2).getId()).isEqualTo(101); + assertThat(results.get(0).getId()).isEqualTo(100); + assertThat(results.get(1).getId()).isEqualTo(101); + assertThat(results.get(2).getId()).isEqualTo(102); } } diff --git a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java index caea62016a2..1ce627cc59f 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java @@ -106,12 +106,17 @@ public class DefaultIssueFinder implements IssueFinder { // 2. Select the authorized ids of all the issues that match the query List<IssueDto> authorizedIssues = issueDao.selectIssueAndProjectIds(query, rootProjectIds, sqlSession); - // 3. Apply pagination - Paging paging = Paging.create(query.pageSize(), query.pageIndex(), authorizedIssues.size()); - Set<Long> pagedIssueIds = pagedIssueIds(authorizedIssues, paging); + // 3. Sort all authorized issues + Collection<IssueDto> authorizedSortedIssues = new IssuesFinderSort(authorizedIssues, query).sort(); + + // 4. Apply pagination + Paging paging = Paging.create(query.pageSize(), query.pageIndex(), authorizedSortedIssues.size()); + Set<Long> pagedIssueIds = pagedIssueIds(authorizedSortedIssues, paging); + + // 5. Load issues and their related data (rules, components, projects, comments, action plans, ...) and sort then again + Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, sqlSession); + Collection<IssueDto> pagedSortedIssues = new IssuesFinderSort(pagedIssues, query).sort(); - // 4. Load issues and their related data (rules, components, comments, action plans, ...) - Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, query.sort(), query.asc(), sqlSession); Map<String, DefaultIssue> issuesByKey = newHashMap(); List<Issue> issues = newArrayList(); Set<Integer> ruleIds = Sets.newHashSet(); @@ -119,7 +124,7 @@ public class DefaultIssueFinder implements IssueFinder { Set<Integer> projectIds = Sets.newHashSet(); Set<String> actionPlanKeys = Sets.newHashSet(); Set<String> users = Sets.newHashSet(); - for (IssueDto dto : pagedIssues) { + for (IssueDto dto : pagedSortedIssues) { DefaultIssue defaultIssue = dto.toDefaultIssue(); issuesByKey.put(dto.getKee(), defaultIssue); issues.add(defaultIssue); @@ -144,15 +149,15 @@ public class DefaultIssueFinder implements IssueFinder { } return new DefaultResults(issues, - findRules(ruleIds), - findComponents(componentIds), - findProjects(projectIds), - findActionPlans(actionPlanKeys), - findUsers(users), - paging, - false, - authorizedIssues.size() != query.maxResults() - // TODO + findRules(ruleIds), + findComponents(componentIds), + findProjects(projectIds), + findActionPlans(actionPlanKeys), + findUsers(users), + paging, + false, + authorizedIssues.size() != query.maxResults() + // TODO // authorizedIssues.size() != allIssues.size() ); } finally { diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java b/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java new file mode 100644 index 00000000000..086365f974d --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java @@ -0,0 +1,181 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.issue; + +import com.google.common.base.Function; +import com.google.common.collect.Ordering; +import org.sonar.api.issue.IssueQuery; +import org.sonar.api.rule.Severity; +import org.sonar.core.issue.db.IssueDto; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +class IssuesFinderSort { + + private Collection<IssueDto> issues; + private IssueQuery query; + + public IssuesFinderSort(Collection<IssueDto> issues, IssueQuery query) { + this.issues = issues; + this.query = query; + } + + public Collection<IssueDto> sort() { + if (query.sort() != null) { + IssueProcessor issueProcessor; + switch (query.sort()) { + case ASSIGNEE: + issueProcessor = new AssigneeSortIssueProcessor(); + break; + case SEVERITY: + issueProcessor = new SeveritySortIssueProcessor(); + break; + case STATUS: + issueProcessor = new StatusSortIssueProcessor(); + break; + case CREATION_DATE: + issueProcessor = new CreationDateSortIssueProcessor(); + break; + case UPDATE_DATE: + issueProcessor = new UpdateDateSortIssueProcessor(); + break; + case CLOSE_DATE: + issueProcessor = new CloseDateSortIssueProcessor(); + break; + default: + throw new IllegalArgumentException("Cannot sort issues on field : " + query.sort().name()); + } + return issueProcessor.sort(issues, query.asc()); + } + return issues; + } + + abstract static class IssueProcessor { + abstract Function sortFieldFunction(); + + abstract Ordering sortFieldOrdering(boolean ascending); + + final List<IssueDto> sort(Collection<IssueDto> issueDtos, boolean ascending) { + Ordering<IssueDto> ordering = sortFieldOrdering(ascending).onResultOf(sortFieldFunction()); + return ordering.immutableSortedCopy(issueDtos); + } + } + + abstract static class TextSortIssueProcessor extends IssueProcessor { + @Override + Function sortFieldFunction() { + return new Function<IssueDto, String>() { + public String apply(IssueDto issueDto) { + return sortField(issueDto); + } + }; + } + + abstract String sortField(IssueDto issueDto); + + @Override + Ordering sortFieldOrdering(boolean ascending) { + Ordering<String> ordering = Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsLast(); + if (!ascending) { + ordering = ordering.reverse(); + } + return ordering; + } + } + + static class AssigneeSortIssueProcessor extends TextSortIssueProcessor { + @Override + String sortField(IssueDto issueDto) { + return issueDto.getAssignee(); + } + } + + static class StatusSortIssueProcessor extends TextSortIssueProcessor { + @Override + String sortField(IssueDto issueDto) { + return issueDto.getStatus(); + } + } + + static class SeveritySortIssueProcessor extends IssueProcessor { + @Override + Function sortFieldFunction() { + return new Function<IssueDto, Integer>() { + public Integer apply(IssueDto issueDto) { + return Severity.ALL.indexOf(issueDto.getSeverity()); + } + }; + } + + @Override + Ordering sortFieldOrdering(boolean ascending) { + Ordering<Integer> ordering = Ordering.<Integer>natural().nullsLast(); + if (!ascending) { + ordering = ordering.reverse(); + } + return ordering; + } + } + + abstract static class DateSortRowProcessor extends IssueProcessor { + @Override + Function sortFieldFunction() { + return new Function<IssueDto, Date>() { + public Date apply(IssueDto issueDto) { + return sortField(issueDto); + } + }; + } + + abstract Date sortField(IssueDto issueDto); + + @Override + Ordering sortFieldOrdering(boolean ascending) { + Ordering<Date> ordering = Ordering.<Date>natural().nullsLast(); + if (!ascending) { + ordering = ordering.reverse(); + } + return ordering; + } + } + + static class CreationDateSortIssueProcessor extends DateSortRowProcessor { + @Override + Date sortField(IssueDto issueDto) { + return issueDto.getIssueCreationDate(); + } + } + + static class UpdateDateSortIssueProcessor extends DateSortRowProcessor { + @Override + Date sortField(IssueDto issueDto) { + return issueDto.getIssueUpdateDate(); + } + } + + static class CloseDateSortIssueProcessor extends DateSortRowProcessor { + @Override + Date sortField(IssueDto issueDto) { + return issueDto.getIssueCloseDate(); + } + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java index b2dc2fcfe90..fbb71cc901b 100644 --- a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java +++ b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java @@ -50,7 +50,6 @@ import static org.mockito.Matchers.anyCollection; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.*; public class DefaultIssueFinderTest { @@ -82,7 +81,7 @@ public class DefaultIssueFinderTest { .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); IssueQueryResult results = finder.find(query); verify(issueDao).selectIssueAndProjectIds(eq(query), eq(newHashSet(100)), any(SqlSession.class)); @@ -106,7 +105,7 @@ public class DefaultIssueFinderTest { .setProjectKey_unit_test_only("struts") .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(newArrayList(issue1)); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(newArrayList(issue1)); finder.find(query); verify(issueDao).selectIssueAndProjectIds(eq(query), eq(Collections.<Integer>emptySet()), any(SqlSession.class)); @@ -134,7 +133,7 @@ public class DefaultIssueFinderTest { .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); when(issueDao.selectIssueAndProjectIds(eq(query), eq(newHashSet(100)), any(SqlSession.class))).thenReturn(dtoList); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); IssueQueryResult results = finder.find(query); assertThat(results.paging().offset()).isEqualTo(0); @@ -142,7 +141,7 @@ public class DefaultIssueFinderTest { assertThat(results.paging().pages()).isEqualTo(2); // Only one result is expected because the limit is 1 - verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class)); + verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class)); } @Test @@ -178,7 +177,7 @@ public class DefaultIssueFinderTest { .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); IssueQueryResult results = finder.find(query); assertThat(results.issues()).hasSize(2); @@ -206,7 +205,7 @@ public class DefaultIssueFinderTest { .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); IssueQueryResult results = finder.find(query); assertThat(results.issues()).hasSize(2); @@ -233,7 +232,7 @@ public class DefaultIssueFinderTest { .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); IssueQueryResult results = finder.find(query); assertThat(results.issues()).hasSize(2); @@ -260,7 +259,7 @@ public class DefaultIssueFinderTest { .setRuleKey_unit_test_only("squid", "AvoidCycle") .setStatus("OPEN").setResolution("OPEN"); List<IssueDto> dtoList = newArrayList(issue1, issue2); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList); when(actionPlanService.findByKeys(anyCollection())).thenReturn(newArrayList(actionPlan1, actionPlan2)); IssueQueryResult results = finder.find(query); @@ -275,7 +274,7 @@ public class DefaultIssueFinderTest { grantAccessRights(); IssueQuery query = IssueQuery.builder().build(); when(issueDao.selectIssueAndProjectIds(eq(query), anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList()); - when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList()); + when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList()); IssueQueryResult results = finder.find(query); assertThat(results.issues()).isEmpty(); diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java new file mode 100644 index 00000000000..d7a458965fd --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java @@ -0,0 +1,158 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2013 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.issue; + +import org.apache.commons.lang.time.DateUtils; +import org.junit.Test; +import org.sonar.api.issue.IssueQuery; +import org.sonar.core.issue.db.IssueDto; + +import java.util.Date; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; +import static org.fest.assertions.Assertions.assertThat; + +public class IssuesFinderSortTest { + + @Test + public void should_sort_by_assignee() { + IssueDto issue1 = new IssueDto().setId(1L).setAssignee("perceval"); + IssueDto issue2 = new IssueDto().setId(2L).setAssignee("arthur"); + IssueDto issue3 = new IssueDto().setId(3L).setAssignee("vincent"); + IssueDto issue4 = new IssueDto().setId(4L).setAssignee(null); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3, issue4); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).asc(true).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(4); + assertThat(result.get(0).getAssignee()).isEqualTo("arthur"); + assertThat(result.get(1).getAssignee()).isEqualTo("perceval"); + assertThat(result.get(2).getAssignee()).isEqualTo("vincent"); + assertThat(result.get(3).getAssignee()).isNull(); + } + + @Test + public void should_sort_by_status() { + IssueDto issue1 = new IssueDto().setId(1L).setStatus("CLOSED"); + IssueDto issue2 = new IssueDto().setId(2L).setStatus("REOPENED"); + IssueDto issue3 = new IssueDto().setId(3L).setStatus("OPEN"); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).asc(false).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(3); + assertThat(result.get(0).getStatus()).isEqualTo("REOPENED"); + assertThat(result.get(1).getStatus()).isEqualTo("OPEN"); + assertThat(result.get(2).getStatus()).isEqualTo("CLOSED"); + } + + @Test + public void should_sort_by_severity() { + IssueDto issue1 = new IssueDto().setId(1L).setSeverity("INFO"); + IssueDto issue2 = new IssueDto().setId(2L).setSeverity("BLOCKER"); + IssueDto issue3 = new IssueDto().setId(3L).setSeverity("MAJOR"); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).asc(true).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(3); + assertThat(result.get(0).getSeverity()).isEqualTo("INFO"); + assertThat(result.get(1).getSeverity()).isEqualTo("MAJOR"); + assertThat(result.get(2).getSeverity()).isEqualTo("BLOCKER"); + } + + @Test + public void should_sort_by_creation_date() { + Date date = new Date(); + Date date1 = DateUtils.addDays(date, -3); + Date date2 = DateUtils.addDays(date, -2); + Date date3 = DateUtils.addDays(date, -1); + IssueDto issue1 = new IssueDto().setId(1L).setIssueCreationDate(date1); + IssueDto issue2 = new IssueDto().setId(2L).setIssueCreationDate(date3); + IssueDto issue3 = new IssueDto().setId(3L).setIssueCreationDate(date2); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).asc(false).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(3); + assertThat(result.get(0).getIssueCreationDate()).isEqualTo(date3); + assertThat(result.get(1).getIssueCreationDate()).isEqualTo(date2); + assertThat(result.get(2).getIssueCreationDate()).isEqualTo(date1); + } + + @Test + public void should_sort_by_update_date() { + Date date = new Date(); + Date date1 = DateUtils.addDays(date, -3); + Date date2 = DateUtils.addDays(date, -2); + Date date3 = DateUtils.addDays(date, -1); + IssueDto issue1 = new IssueDto().setId(1L).setIssueUpdateDate(date1); + IssueDto issue2 = new IssueDto().setId(2L).setIssueUpdateDate(date3); + IssueDto issue3 = new IssueDto().setId(3L).setIssueUpdateDate(date2); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).asc(false).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(3); + assertThat(result.get(0).getIssueUpdateDate()).isEqualTo(date3); + assertThat(result.get(1).getIssueUpdateDate()).isEqualTo(date2); + assertThat(result.get(2).getIssueUpdateDate()).isEqualTo(date1); + } + + @Test + public void should_sort_by_close_date() { + Date date = new Date(); + Date date1 = DateUtils.addDays(date, -3); + Date date2 = DateUtils.addDays(date, -2); + Date date3 = DateUtils.addDays(date, -1); + IssueDto issue1 = new IssueDto().setId(1L).setIssueCloseDate(date1); + IssueDto issue2 = new IssueDto().setId(2L).setIssueCloseDate(date3); + IssueDto issue3 = new IssueDto().setId(3L).setIssueCloseDate(date2); + List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3); + + IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).asc(false).build(); + IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query); + + List<IssueDto> result = newArrayList(issuesFinderSort.sort()); + + assertThat(result).hasSize(3); + assertThat(result.get(0).getIssueCloseDate()).isEqualTo(date3); + assertThat(result.get(1).getIssueCloseDate()).isEqualTo(date2); + assertThat(result.get(2).getIssueCloseDate()).isEqualTo(date1); + } + +} |