]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3755 the perspective Issuable should not be available on Java classes and methods
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 16 Apr 2013 11:24:54 +0000 (13:24 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 16 Apr 2013 11:26:28 +0000 (13:26 +0200)
14 files changed:
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/IssuesDecorator.java
sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuable.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuableFactory.java [deleted file]
sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/source/HighlightableBuilder.java
sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/scan/source/HighlightableBuilderTest.java
sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilder.java
sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java
sonar-core/src/main/java/org/sonar/core/component/ScanPerspectives.java
sonar-core/src/test/java/org/sonar/core/component/PerspectiveBuilderTest.java [new file with mode: 0644]

diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
new file mode 100644 (file)
index 0000000..e22b257
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.issue;
+
+import org.sonar.api.component.Component;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssueBuilder;
+
+import java.util.Collection;
+
+/**
+ * @since 3.6
+ */
+public class DefaultIssuable implements Issuable {
+
+  private final ModuleIssues moduleIssues;
+  private final Component component;
+
+  DefaultIssuable(Component component, ModuleIssues moduleIssues) {
+    this.component = component;
+    this.moduleIssues = moduleIssues;
+  }
+
+  @Override
+  public IssueBuilder newIssue() {
+    return new DefaultIssueBuilder(moduleIssues, component.key());
+  }
+
+  @Override
+  public Collection<Issue> issues() {
+    return moduleIssues.issues(component.key());
+  }
+
+  @Override
+  public Component component() {
+    return component;
+  }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java
new file mode 100644 (file)
index 0000000..01b95a0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.issue;
+
+import org.sonar.api.component.Component;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.resources.Scopes;
+import org.sonar.core.component.PerspectiveBuilder;
+import org.sonar.core.component.ResourceComponent;
+
+import javax.annotation.CheckForNull;
+
+public class IssuableFactory extends PerspectiveBuilder<Issuable> {
+
+  private final ModuleIssues moduleIssues;
+
+  public IssuableFactory(ModuleIssues moduleIssues) {
+    super(Issuable.class);
+    this.moduleIssues = moduleIssues;
+  }
+
+  @CheckForNull
+  @Override
+  protected Issuable loadPerspective(Class<Issuable> perspectiveClass, Component component) {
+    boolean supported = true;
+    if (component instanceof ResourceComponent) {
+      supported = Scopes.isHigherThanOrEquals(((ResourceComponent) component).scope(), Scopes.FILE);
+    }
+    if (supported) {
+      return new DefaultIssuable(component, moduleIssues);
+    }
+    return null;
+  }
+}
index c54d552830f7f57de54eac4fc983a270823c6ae1..280ad46e1e9b138dbbb687fd0660315c69ea122f 100644 (file)
@@ -65,10 +65,12 @@ public class IssuesDecorator implements Decorator {
 
   public void decorate(Resource resource, DecoratorContext context) {
     Issuable issuable = perspectives.as(Issuable.class, resource);
-    Collection<Issue> issues = issuable.issues();
-    computeTotalIssues(context, issues);
-    computeIssuesPerSeverities(context, issues);
-    computeIssuesPerRules(context, issues);
+    if (issuable != null) {
+      Collection<Issue> issues = issuable.issues();
+      computeTotalIssues(context, issues);
+      computeIssuesPerSeverities(context, issues);
+      computeIssuesPerRules(context, issues);
+    }
   }
 
   private void computeTotalIssues(DecoratorContext context, Collection<Issue> issues) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuable.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuable.java
deleted file mode 100644 (file)
index 9744431..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.issue;
-
-import org.sonar.api.component.Component;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.core.issue.DefaultIssueBuilder;
-
-import java.util.Collection;
-
-/**
- * @since 3.6
- */
-public class ScanIssuable implements Issuable {
-
-  private final ModuleIssues moduleIssues;
-  private final Component component;
-
-  ScanIssuable(Component component, ModuleIssues moduleIssues) {
-    this.component = component;
-    this.moduleIssues = moduleIssues;
-  }
-
-  @Override
-  public IssueBuilder newIssue() {
-    return new DefaultIssueBuilder(moduleIssues, component.key());
-  }
-
-  @Override
-  public Collection<Issue> issues() {
-    return moduleIssues.issues(component.key());
-  }
-
-  @Override
-  public Component component() {
-    return component;
-  }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuableFactory.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssuableFactory.java
deleted file mode 100644 (file)
index 91fd9a4..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar 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.
- *
- * Sonar 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 Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
- */
-package org.sonar.batch.issue;
-
-import org.sonar.api.component.Component;
-import org.sonar.api.issue.Issuable;
-import org.sonar.core.component.PerspectiveBuilder;
-
-public class ScanIssuableFactory extends PerspectiveBuilder<Issuable> {
-
-  private final ModuleIssues moduleIssues;
-
-  public ScanIssuableFactory(ModuleIssues moduleIssues) {
-    super(Issuable.class);
-    this.moduleIssues = moduleIssues;
-  }
-
-  @Override
-  protected Issuable loadPerspective(Class<Issuable> perspectiveClass, Component component) {
-    return new ScanIssuable(component, moduleIssues);
-  }
-}
index 855e40be3429b080fcd90e7f408d28c2ad6b4dc3..4970de6ce97759bfa7dadd6d3f3a8cee32588e5e 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.batch.components.TimeMachineConfiguration;
 import org.sonar.batch.events.EventBus;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.batch.index.ResourcePersister;
+import org.sonar.batch.issue.IssuableFactory;
 import org.sonar.batch.issue.ModuleIssues;
 import org.sonar.batch.local.DryRunExporter;
 import org.sonar.batch.phases.PhaseExecutor;
@@ -56,7 +57,6 @@ import org.sonar.batch.scan.filesystem.FileSystemLogger;
 import org.sonar.batch.scan.filesystem.LanguageFilters;
 import org.sonar.batch.scan.filesystem.ModuleFileSystemProvider;
 import org.sonar.core.component.ScanPerspectives;
-import org.sonar.batch.issue.ScanIssuableFactory;
 import org.sonar.batch.scan.source.HighlightableBuilder;
 
 public class ModuleScanContainer extends ComponentContainer {
@@ -121,7 +121,7 @@ public class ModuleScanContainer extends ComponentContainer {
         new ProfileProvider(),
 
         ModuleIssues.class,
-        ScanIssuableFactory.class,
+        IssuableFactory.class,
 
         HighlightableBuilder.class,
         ScanPerspectives.class
index a25c39d114fcdf0c153fc31aab25d3c47e416d34..7b891015d7652d81a860536b645882c1187f372c 100644 (file)
  */
 package org.sonar.batch.scan.source;
 
+import com.google.common.collect.ImmutableSet;
 import org.sonar.api.component.Component;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.scan.source.Highlightable;
 import org.sonar.core.component.PerspectiveBuilder;
+import org.sonar.core.component.ResourceComponent;
+
+import javax.annotation.CheckForNull;
+import java.util.Set;
 
 /**
  * @since 3.6
  */
 public class HighlightableBuilder extends PerspectiveBuilder<Highlightable> {
 
-  private final SyntaxHighlightingCache syntaxHighlightingCache;
+  private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.FILE, Qualifiers.CLASS, Qualifiers.UNIT_TEST_FILE);
+  private final SyntaxHighlightingCache cache;
+
 
-  public HighlightableBuilder(SyntaxHighlightingCache syntaxHighlightingCache) {
+  public HighlightableBuilder(SyntaxHighlightingCache cache) {
     super(Highlightable.class);
-    this.syntaxHighlightingCache = syntaxHighlightingCache;
+    this.cache = cache;
   }
 
+  @CheckForNull
   @Override
   protected Highlightable loadPerspective(Class<Highlightable> perspectiveClass, Component component) {
-    return new DefaultHighlightable(component, syntaxHighlightingCache);
+    boolean supported = SUPPORTED_QUALIFIERS.contains(component.qualifier());
+    if (supported && component instanceof ResourceComponent) {
+      // temporary hack waiting for the removal of JavaClass.
+      // JavaClass has the same qualifier than JavaFile, so they have to distinguished by their scope
+      supported = Scopes.FILE.equals(((ResourceComponent) component).scope());
+    }
+    if (supported) {
+      return new DefaultHighlightable(component, cache);
+    }
+    return null;
   }
 }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java
new file mode 100644 (file)
index 0000000..6abf869
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.index;
+
+import org.junit.Test;
+
+public class CacheTest {
+  @Test
+  public void test_put() throws Exception {
+
+  }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java
new file mode 100644 (file)
index 0000000..6f3187d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.batch.issue;
+
+import org.junit.Test;
+import org.sonar.api.component.Component;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.JavaFile;
+import org.sonar.api.resources.Project;
+import org.sonar.core.component.ResourceComponent;
+import org.sonar.java.api.JavaClass;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class IssuableFactoryTest {
+
+  ModuleIssues moduleIssues = mock(ModuleIssues.class);
+
+  @Test
+  public void file_should_be_issuable() throws Exception {
+    IssuableFactory factory = new IssuableFactory(moduleIssues);
+    Component component = new ResourceComponent(new File("foo/bar.c"));
+    Issuable issuable = factory.loadPerspective(Issuable.class, component);
+
+    assertThat(issuable).isNotNull();
+    assertThat(issuable.component()).isSameAs(component);
+    assertThat(issuable.issues()).isEmpty();
+  }
+
+  @Test
+  public void project_should_be_issuable() throws Exception {
+    IssuableFactory factory = new IssuableFactory(moduleIssues);
+    Component component = new ResourceComponent(new Project("Foo"));
+    Issuable issuable = factory.loadPerspective(Issuable.class, component);
+
+    assertThat(issuable).isNotNull();
+    assertThat(issuable.component()).isSameAs(component);
+    assertThat(issuable.issues()).isEmpty();
+  }
+
+  @Test
+  public void java_file_should_be_issuable() throws Exception {
+    IssuableFactory factory = new IssuableFactory(moduleIssues);
+    Component component = new ResourceComponent(new JavaFile("bar.Foo"));
+    Issuable issuable = factory.loadPerspective(Issuable.class, component);
+
+    assertThat(issuable).isNotNull();
+    assertThat(issuable.component()).isSameAs(component);
+    assertThat(issuable.issues()).isEmpty();
+  }
+
+  @Test
+  public void java_class_should_not_be_issuable() throws Exception {
+    IssuableFactory factory = new IssuableFactory(moduleIssues);
+    Component component = new ResourceComponent(JavaClass.create("bar", "Foo"));
+    Issuable issuable = factory.loadPerspective(Issuable.class, component);
+
+    assertThat(issuable).isNull();
+  }
+}
index 95fccc235dc97aea5f9a135e5a1522c4c959df77..3b8009cd1601baa156674046d821ec139404c32d 100644 (file)
@@ -21,22 +21,47 @@ package org.sonar.batch.scan.source;
 
 import org.junit.Test;
 import org.sonar.api.component.Component;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
 import org.sonar.api.scan.source.Highlightable;
+import org.sonar.core.component.ResourceComponent;
+import org.sonar.java.api.JavaClass;
 
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 
 public class HighlightableBuilderTest {
 
+  SyntaxHighlightingCache cache = mock(SyntaxHighlightingCache.class);
+
   @Test
   public void should_load_default_perspective() throws Exception {
+    Component component = new ResourceComponent(new File("foo/bar.c"));
+
+    HighlightableBuilder builder = new HighlightableBuilder(cache);
+    Highlightable perspective = builder.loadPerspective(Highlightable.class, component);
+
+    assertThat(perspective).isNotNull().isInstanceOf(DefaultHighlightable.class);
+    assertThat(perspective.component()).isSameAs(component);
+  }
+
+  @Test
+  public void project_should_not_be_highlightable() {
+    Component component = new ResourceComponent(new Project("Foo"));
+
+    HighlightableBuilder builder = new HighlightableBuilder(cache);
+    Highlightable perspective = builder.loadPerspective(Highlightable.class, component);
 
-    Component mockComponent = mock(Component.class);
-    SyntaxHighlightingCache highlightingCache = mock(SyntaxHighlightingCache.class);
+    assertThat(perspective).isNull();
+  }
+
+  @Test
+  public void java_class_should_not_be_highlightable() {
+    Component component = new ResourceComponent(JavaClass.create("foo", "Bar"));
 
-    HighlightableBuilder builder = new HighlightableBuilder(highlightingCache);
-    Highlightable perspective = builder.loadPerspective(Highlightable.class, mockComponent);
+    HighlightableBuilder builder = new HighlightableBuilder(cache);
+    Highlightable perspective = builder.loadPerspective(Highlightable.class, component);
 
-    assertThat(perspective).isInstanceOf(DefaultHighlightable.class);
+    assertThat(perspective).isNull();
   }
 }
index 1577ce5dec000b2b2200877e9d3d26d3e0226cfe..8d5967da3c65c75ff13c26ef9c07cbb6e74c99cc 100644 (file)
@@ -24,6 +24,8 @@ import org.sonar.api.ServerComponent;
 import org.sonar.api.component.Component;
 import org.sonar.api.component.Perspective;
 
+import javax.annotation.CheckForNull;
+
 public abstract class PerspectiveBuilder<T extends Perspective> implements BatchComponent, ServerComponent {
 
   private final Class<T> perspectiveClass;
@@ -36,5 +38,6 @@ public abstract class PerspectiveBuilder<T extends Perspective> implements Batch
     return perspectiveClass;
   }
 
+  @CheckForNull
   protected abstract T loadPerspective(Class<T> perspectiveClass, Component component);
 }
index 15063473161db37f31946d0012f0ceebe72754b3..1679509bceb0fda9c56beb4a75fb851777ad7cbc 100644 (file)
@@ -25,26 +25,28 @@ import org.sonar.api.resources.Resource;
 
 import javax.annotation.Nullable;
 
-class ResourceComponent implements Component {
+public class ResourceComponent implements Component {
   private String key;
   private String name;
   private String longName;
   private String qualifier;
+  private String scope;
   private Long snapshotId;
   private Long resourceId;
 
-  ResourceComponent(Resource resource, @Nullable Snapshot snapshot) {
+  public ResourceComponent(Resource resource, @Nullable Snapshot snapshot) {
     this.key = resource.getEffectiveKey();
     this.name = resource.getName();
     this.longName = resource.getLongName();
     this.qualifier = resource.getQualifier();
+    this.scope = resource.getScope();
     if (snapshot != null && snapshot.getId() != null) {
       this.snapshotId = snapshot.getId().longValue();
       this.resourceId = snapshot.getResourceId().longValue();
     }
   }
 
-  ResourceComponent(Resource resource) {
+  public ResourceComponent(Resource resource) {
     this(resource, null);
   }
 
@@ -65,6 +67,10 @@ class ResourceComponent implements Component {
     return qualifier;
   }
 
+  public String scope() {
+    return scope;
+  }
+
   public Long snapshotId() {
     return snapshotId;
   }
index 6cd29abf0040e84ea16a020b47f294059c82bc9b..3b3d818b858ac380c91fc98411372b17cc68d5da 100644 (file)
@@ -53,6 +53,7 @@ public class ScanPerspectives implements ResourcePerspectives, BatchComponent {
     return builder.loadPerspective(perspectiveClass, component);
   }
 
+  @CheckForNull
   public <P extends Perspective> P as(Class<P> perspectiveClass, Resource resource) {
     Resource indexedResource = resourceIndex.getResource(resource);
     if (indexedResource != null) {
diff --git a/sonar-core/src/test/java/org/sonar/core/component/PerspectiveBuilderTest.java b/sonar-core/src/test/java/org/sonar/core/component/PerspectiveBuilderTest.java
new file mode 100644 (file)
index 0000000..d95060d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar 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.
+ *
+ * Sonar 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 Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
+ */
+package org.sonar.core.component;
+
+import org.junit.Test;
+import org.sonar.api.component.Component;
+import org.sonar.api.component.Perspective;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class PerspectiveBuilderTest {
+  @Test
+  public void testGetPerspectiveClass() throws Exception {
+    PerspectiveBuilder<FakePerspective> builder = new PerspectiveBuilder<FakePerspective>(FakePerspective.class) {
+      @Override
+      protected FakePerspective loadPerspective(Class<FakePerspective> perspectiveClass, Component component) {
+        return null;
+      }
+    };
+
+    assertThat(builder.getPerspectiveClass()).isEqualTo(FakePerspective.class);
+  }
+
+  static interface FakePerspective extends Perspective {
+
+  }
+}