From 7810d09da1bf3908ca190d5d1811fd8b58cc549b Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Thu, 7 Jan 2016 11:48:04 +0100 Subject: [PATCH] SONAR-7177 expand the root directory --- .../shared/xoo-sample-with-root-dir/Hello.xoo | 12 ++++++++ .../sonar-project.properties | 5 ++++ .../src/main/xoo/sample/Sample.xoo | 16 ++++++++++ .../src/main/xoo/sample/Sample.xoo.measures | 11 +++++++ .../it/projectServices/ProjectCodeTest.java | 10 +++++++ .../code_page_should_expand_root_dir.html | 30 +++++++++++++++++++ .../src/main/js/apps/code/actions/index.js | 23 ++++++++++++-- .../src/main/js/apps/code/reducers/index.js | 24 ++++++++++++++- .../sonar-web/tests/apps/code/store-test.js | 14 +++++++++ 9 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 it/it-projects/shared/xoo-sample-with-root-dir/Hello.xoo create mode 100644 it/it-projects/shared/xoo-sample-with-root-dir/sonar-project.properties create mode 100644 it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo create mode 100644 it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo.measures create mode 100644 it/it-tests/src/test/resources/projectServices/ProjectCodeTest/code_page_should_expand_root_dir.html diff --git a/it/it-projects/shared/xoo-sample-with-root-dir/Hello.xoo b/it/it-projects/shared/xoo-sample-with-root-dir/Hello.xoo new file mode 100644 index 00000000000..b83c3af128c --- /dev/null +++ b/it/it-projects/shared/xoo-sample-with-root-dir/Hello.xoo @@ -0,0 +1,12 @@ +package com.sonar.it.samples.modules.b1; + +public class HelloB1 { + private int i; + private HelloB1() { + + } + + public void hello() { + System.out.println("hello" + " world"); + } +} \ No newline at end of file diff --git a/it/it-projects/shared/xoo-sample-with-root-dir/sonar-project.properties b/it/it-projects/shared/xoo-sample-with-root-dir/sonar-project.properties new file mode 100644 index 00000000000..35fbcff0e60 --- /dev/null +++ b/it/it-projects/shared/xoo-sample-with-root-dir/sonar-project.properties @@ -0,0 +1,5 @@ +sonar.projectKey=sample-with-root-dir +sonar.projectName=Sample With Root Dir +sonar.projectVersion=1.0-SNAPSHOT +sonar.sources=. +sonar.language=xoo diff --git a/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo b/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo new file mode 100644 index 00000000000..41871e123a3 --- /dev/null +++ b/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo @@ -0,0 +1,16 @@ +package sample; + +public class Sample { + + public Sample(int i) { + int j = i++; + } + + private String myMethod() { + if (foo == bar) { + return "hello"; + } else { + throw new IllegalStateException(); + } + } +} diff --git a/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo.measures b/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo.measures new file mode 100644 index 00000000000..3f73ea8f695 --- /dev/null +++ b/it/it-projects/shared/xoo-sample-with-root-dir/src/main/xoo/sample/Sample.xoo.measures @@ -0,0 +1,11 @@ +ncloc:13 +#Used by dashboard/widgets tests +complexity:3 +complexity_in_classes:3 +classes:1 +comment_lines:3 +public_api:5 +public_undocumented_api:2 +duplicated_files:1 +duplicated_blocks:2 +duplicated_lines:3 diff --git a/it/it-tests/src/test/java/it/projectServices/ProjectCodeTest.java b/it/it-tests/src/test/java/it/projectServices/ProjectCodeTest.java index c29d3278164..875894fd67a 100644 --- a/it/it-tests/src/test/java/it/projectServices/ProjectCodeTest.java +++ b/it/it-tests/src/test/java/it/projectServices/ProjectCodeTest.java @@ -44,6 +44,16 @@ public class ProjectCodeTest { new SeleneseTest(selenese).runOn(orchestrator); } + @Test + public void code_page_should_expand_root_dir() throws Exception { + executeBuild("shared/xoo-sample-with-root-dir", "project-for-code-root-dir", "Project For Code"); + + Selenese selenese = Selenese.builder().setHtmlTestsInClasspath("code_page_should_expand_root_dir", + "/projectServices/ProjectCodeTest/code_page_should_expand_root_dir.html" + ).build(); + new SeleneseTest(selenese).runOn(orchestrator); + } + private void executeBuild(String projectLocation, String projectKey, String projectName) { orchestrator.executeBuild( SonarRunner.create(projectDir(projectLocation)) diff --git a/it/it-tests/src/test/resources/projectServices/ProjectCodeTest/code_page_should_expand_root_dir.html b/it/it-tests/src/test/resources/projectServices/ProjectCodeTest/code_page_should_expand_root_dir.html new file mode 100644 index 00000000000..9d07783bf00 --- /dev/null +++ b/it/it-tests/src/test/resources/projectServices/ProjectCodeTest/code_page_should_expand_root_dir.html @@ -0,0 +1,30 @@ + + + + + + + code_page_should_expand_root_dir + + + + + + + + + + + + + + + + + + + + +
code_page_should_expand_root_dir
open/sonar/code?id=project-for-code-root-dir
waitForTextcss=#content*Hello.xoo*
+ + diff --git a/server/sonar-web/src/main/js/apps/code/actions/index.js b/server/sonar-web/src/main/js/apps/code/actions/index.js index d9edf8eca7b..1d3dfd73561 100644 --- a/server/sonar-web/src/main/js/apps/code/actions/index.js +++ b/server/sonar-web/src/main/js/apps/code/actions/index.js @@ -100,6 +100,23 @@ function getPath (componentKey) { return '/' + encodeURIComponent(componentKey); } +function expandRootDir (components) { + const rootDir = components.find(component => component.qualifier === 'DIR' && component.name === '/'); + if (rootDir) { + return getChildren(rootDir.key, METRICS_WITH_COVERAGE).then(files => { + return _.without([...components, ...files], rootDir); + }); + } else { + return components; + } +} + +function skipRootDir (breadcrumbs) { + return breadcrumbs.filter(component => { + return !(component.qualifier === 'DIR' && component.name === '/'); + }); +} + function retrieveComponentBase (componentKey, candidate) { return candidate ? Promise.resolve(candidate) : @@ -109,13 +126,15 @@ function retrieveComponentBase (componentKey, candidate) { function retrieveComponentChildren (componentKey, candidate) { return candidate && candidate.children ? Promise.resolve(candidate.children) : - getChildren(componentKey, METRICS_WITH_COVERAGE); + getChildren(componentKey, METRICS_WITH_COVERAGE).then(expandRootDir); } function retrieveComponentBreadcrumbs (componentKey, candidate) { return candidate && candidate.breadcrumbs ? Promise.resolve(candidate.breadcrumbs) : - getComponentNavigation(componentKey).then(navigation => navigation.breadcrumbs); + getComponentNavigation(componentKey) + .then(navigation => navigation.breadcrumbs) + .then(skipRootDir); } function retrieveComponent (componentKey, bucket) { diff --git a/server/sonar-web/src/main/js/apps/code/reducers/index.js b/server/sonar-web/src/main/js/apps/code/reducers/index.js index 5e381b02968..2c8b31a1ebb 100644 --- a/server/sonar-web/src/main/js/apps/code/reducers/index.js +++ b/server/sonar-web/src/main/js/apps/code/reducers/index.js @@ -46,6 +46,28 @@ function merge (components, candidate) { return [...(_.without(components, found)), newEntry]; } +function compare (a, b) { + if (a === b) { + return 0; + } + return a > b ? 1 : -1; +} + +function sortChildren (children) { + const QUALIFIERS_ORDER = ['DIR', 'FIL', 'UTS']; + const temp = [...children]; + temp.sort((a, b) => { + const qualifierA = QUALIFIERS_ORDER.indexOf(a.qualifier); + const qualifierB = QUALIFIERS_ORDER.indexOf(b.qualifier); + if (qualifierA !== qualifierB) { + return compare(qualifierA, qualifierB); + } else { + return compare(a.name, b.name); + } + }); + return temp; +} + export const initialState = { fetching: false, @@ -70,7 +92,7 @@ export function current (state = initialState, action) { return { ...state, coverageMetric, baseBreadcrumbs }; case BROWSE: const baseComponent = hasSourceCode(action.component) ? null : action.component; - const components = hasSourceCode(action.component) ? null : _.sortBy(action.children, 'name'); + const components = hasSourceCode(action.component) ? null : sortChildren(action.children); const baseBreadcrumbsLength = state.baseBreadcrumbs.length; const breadcrumbs = action.breadcrumbs.slice(baseBreadcrumbsLength); const sourceViewer = hasSourceCode(action.component) ? action.component : null; diff --git a/server/sonar-web/tests/apps/code/store-test.js b/server/sonar-web/tests/apps/code/store-test.js index f0a809996f7..e8b36a58e4b 100644 --- a/server/sonar-web/tests/apps/code/store-test.js +++ b/server/sonar-web/tests/apps/code/store-test.js @@ -72,6 +72,20 @@ describe('Code :: Store', () => { .to.deep.equal(componentsAfter); }); + it('should sort components by qualifier and then by name', () => { + const component = {}; + const componentsBefore = [ + { key: 'A', name: 'A', qualifier: 'FIL' }, + { key: 'B', name: 'B', qualifier: 'DIR' } + ]; + const componentsAfter = [ + { key: 'B', name: 'B', qualifier: 'DIR' }, + { key: 'A', name: 'A', qualifier: 'FIL' } + ]; + expect(current(initialState, browseAction(component, componentsBefore)).components) + .to.deep.equal(componentsAfter); + }); + it('should not be set for components with source code', () => { const file = { qualifier: 'FIL' }; expect(current(initialState, browseAction(file, exampleComponents)).components) -- 2.39.5