/*
* Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.ide.intellij;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import com.facebook.buck.ide.intellij.model.ContentRoot;
import com.facebook.buck.ide.intellij.model.IjLibrary;
import com.facebook.buck.ide.intellij.model.IjModule;
import com.facebook.buck.ide.intellij.model.IjModuleType;
import com.facebook.buck.ide.intellij.model.ModuleIndexEntry;
import com.facebook.buck.ide.intellij.model.folders.ExcludeFolder;
import com.facebook.buck.ide.intellij.model.folders.IjFolder;
import com.facebook.buck.ide.intellij.model.folders.IjSourceFolder;
import com.facebook.buck.ide.intellij.model.folders.SourceFolder;
import com.facebook.buck.jvm.core.JavaPackageFinder;
import com.facebook.buck.jvm.java.DefaultJavaPackageFinder;
import com.facebook.buck.jvm.java.JavaLibraryBuilder;
import com.facebook.buck.jvm.java.JavaTestBuilder;
import com.facebook.buck.jvm.java.PrebuiltJarBuilder;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.FakeSourcePath;
import com.facebook.buck.rules.TargetNode;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.timing.FakeClock;
import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
public class IjProjectDataPreparerTest {
private FakeProjectFilesystem filesystem;
private JavaPackageFinder javaPackageFinder;
@Before
public void setUp() {
filesystem = new FakeProjectFilesystem();
javaPackageFinder =
DefaultJavaPackageFinder.createDefaultJavaPackageFinder(
ImmutableSet.of("/java/", "/javatests/"));
}
@Test
public void testWriteModule() throws Exception {
TargetNode<?, ?> guavaTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//third_party/guava:guava"))
.addSrc(Paths.get("third_party/guava/src/Collections.java"))
.build();
TargetNode<?, ?> baseTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:base"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/example/base/Base.java"))
.build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(ImmutableSet.of(guavaTargetNode, baseTargetNode));
IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode);
IjProjectTemplateDataPreparer dataPreparer =
new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);
ContentRoot contentRoot = dataPreparer.getContentRoot(baseModule);
assertEquals("file://$MODULE_DIR$", contentRoot.getUrl());
IjSourceFolder baseSourceFolder = contentRoot.getFolders().first();
assertEquals("sourceFolder", baseSourceFolder.getType());
assertFalse(baseSourceFolder.getIsTestSource());
assertEquals("com.example.base", baseSourceFolder.getPackagePrefix());
assertEquals("file://$MODULE_DIR$", baseSourceFolder.getUrl());
assertThat(
dataPreparer.getDependencies(baseModule),
contains(
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)),
hasProperty(
"data",
equalTo(
Optional.of(
DependencyEntryData.builder()
.setName("third_party_guava")
.setScope(IjDependencyListBuilder.Scope.COMPILE)
.setExported(false)
.build()))))));
}
@Test
@SuppressWarnings("unchecked")
public void testDependencies() throws Exception {
TargetNode<?, ?> hamcrestTargetNode =
PrebuiltJarBuilder.createBuilder(
BuildTargetFactory.newInstance("//third-party/hamcrest:hamcrest"))
.setBinaryJar(Paths.get("third-party/hamcrest/hamcrest.jar"))
.build();
TargetNode<?, ?> guavaTargetNode =
PrebuiltJarBuilder.createBuilder(
BuildTargetFactory.newInstance("//third-party/guava:guava"))
.setBinaryJar(Paths.get("third-party/guava/guava.jar"))
.build();
TargetNode<?, ?> baseTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:base"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/example/base/Base.java"))
.build();
TargetNode<?, ?> baseGenruleTarget =
GenruleBuilder.newGenruleBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:genrule"))
.setOut("out")
.build();
TargetNode<?, ?> baseInlineTestsTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:tests"))
.addDep(hamcrestTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/example/base/TestBase.java"))
.addSrcTarget(baseGenruleTarget.getBuildTarget())
.build();
TargetNode<?, ?> baseTestsTargetNode =
JavaTestBuilder.createBuilder(
BuildTargetFactory.newInstance("//javatests/com/example/base:base"))
.addDep(baseTargetNode.getBuildTarget())
.addDep(hamcrestTargetNode.getBuildTarget())
.addSrc(Paths.get("javatests/com/example/base/Base.java"))
.build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(
ImmutableSet.of(
hamcrestTargetNode,
guavaTargetNode,
baseTargetNode,
baseGenruleTarget,
baseInlineTestsTargetNode,
baseTestsTargetNode),
ImmutableMap.of(
baseInlineTestsTargetNode, new FakeSourcePath("buck-out/baseInlineTests.jar")),
Functions.constant(Optional.empty()));
IjLibrary hamcrestLibrary =
IjModuleGraphTest.getLibraryForTarget(moduleGraph, hamcrestTargetNode);
IjLibrary guavaLibrary = IjModuleGraphTest.getLibraryForTarget(moduleGraph, guavaTargetNode);
IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode);
IjModule baseTestModule =
IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTestsTargetNode);
IjProjectTemplateDataPreparer dataPreparer =
new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);
assertEquals(
IjModuleGraphTest.getModuleForTarget(moduleGraph, baseInlineTestsTargetNode),
IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode));
DependencyEntryData.Builder dependencyEntryBuilder =
DependencyEntryData.builder().setExported(false);
assertThat(
dataPreparer.getDependencies(baseModule),
contains(
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
hasProperty(
"data",
equalTo(
Optional.of(
dependencyEntryBuilder
.setName(guavaLibrary.getName())
.setScope(IjDependencyListBuilder.Scope.COMPILE)
.build())))),
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
hasProperty(
"data",
equalTo(
Optional.of(
dependencyEntryBuilder
.setName(hamcrestLibrary.getName())
.setScope(IjDependencyListBuilder.Scope.COMPILE)
.build())))),
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
hasProperty(
"data",
equalTo(
Optional.of(
DependencyEntryData.builder()
.setExported(true)
.setName("library_java_com_example_base_tests")
.setScope(IjDependencyListBuilder.Scope.PROVIDED)
.build()))))));
assertThat(
dataPreparer.getDependencies(baseTestModule),
contains(
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)),
hasProperty(
"data",
equalTo(
Optional.of(
dependencyEntryBuilder
.setName(baseModule.getName())
.setScope(IjDependencyListBuilder.Scope.TEST)
.build())))),
allOf(
hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
hasProperty(
"data",
equalTo(
Optional.of(
dependencyEntryBuilder
.setName(hamcrestLibrary.getName())
.setScope(IjDependencyListBuilder.Scope.TEST)
.build()))))));
}
@Test
public void testEmptyRootModule() throws Exception {
Path baseTargetSrcFilePath = Paths.get("java/com/example/base/Base.java");
TargetNode<?, ?> baseTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:base"))
.addSrc(baseTargetSrcFilePath)
.build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(ImmutableSet.of(baseTargetNode));
IjProjectTemplateDataPreparer dataPreparer =
new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);
assertThat(
dataPreparer.getModulesToBeWritten(),
containsInAnyOrder(
IjModule.builder()
.setModuleBasePath(Paths.get("java/com/example/base"))
.setTargets(ImmutableSet.of(baseTargetNode.getBuildTarget()))
.addFolders(
new SourceFolder(
Paths.get("java/com/example/base"),
true,
ImmutableSortedSet.of(baseTargetSrcFilePath)))
.setModuleType(IjModuleType.JAVA_MODULE)
.build(),
IjModule.builder()
.setModuleBasePath(Paths.get(""))
.setTargets(ImmutableSet.of())
.setModuleType(IjModuleType.UNKNOWN_MODULE)
.build()));
}
@Test
public void testModuleIndex() throws Exception {
TargetNode<?, ?> guavaTargetNode =
PrebuiltJarBuilder.createBuilder(
BuildTargetFactory.newInstance("//third-party/guava:guava"))
.setBinaryJar(Paths.get("third-party/guava/guava.jar"))
.build();
TargetNode<?, ?> baseTargetNode =
JavaLibraryBuilder.createBuilder(
BuildTargetFactory.newInstance("//java/com/example/base:base"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/example/base/Base.java"))
.build();
TargetNode<?, ?> baseTestsTargetNode =
JavaTestBuilder.createBuilder(
BuildTargetFactory.newInstance("//javatests/com/example/base:base"))
.addDep(baseTargetNode.getBuildTarget())
.addSrc(Paths.get("javatests/com/example/base/Base.java"))
.build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(
ImmutableSet.of(guavaTargetNode, baseTargetNode, baseTestsTargetNode));
IjProjectTemplateDataPreparer dataPreparer =
new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);
// Libraries don't go into the index.
assertEquals(
ImmutableSet.of(
ModuleIndexEntry.builder()
.setFileUrl("file://$PROJECT_DIR$/project_root.iml")
.setFilePath(Paths.get("project_root.iml"))
.build(),
ModuleIndexEntry.builder()
.setGroup("modules")
.setFileUrl("file://$PROJECT_DIR$/java/com/example/base/java_com_example_base.iml")
.setFilePath(Paths.get("java/com/example/base/java_com_example_base.iml"))
.build(),
ModuleIndexEntry.builder()
.setGroup("modules")
.setFileUrl(
"file://$PROJECT_DIR$/javatests/com/example/base/javatests_com_example_base.iml")
.setFilePath(Paths.get("javatests/com/example/base/javatests_com_example_base.iml"))
.build()),
dataPreparer.getModuleIndexEntries());
}
@Test
public void testExcludePaths() throws Exception {
/**
* Fake filesystem structure .idea |- misc.xml .git |- HEAD java |- com |- BUCK |- data |-
* wsad.txt |- src |- BUCK |- Source.java |- foo |- Foo.java |- src2 |- Code.java |- org |- bar
* |- Bar.java lib |- BUCK |- guava.jar
*/
ImmutableSet<Path> paths =
ImmutableSet.of(
Paths.get(".idea/misc.xml"),
Paths.get(".git/HEAD"),
Paths.get("java/com/BUCK"),
Paths.get("java/com/data/wsad.txt"),
Paths.get("java/com/src/BUCK"),
Paths.get("java/com/src/Source.java"),
Paths.get("java/com/src/foo/Foo.java"),
Paths.get("java/org/bar/Bar.java"),
Paths.get("lib/BUCK"),
Paths.get("lib/guava.jar"));
FakeProjectFilesystem filesystemForExcludesTest =
new FakeProjectFilesystem(new FakeClock(0), Paths.get(".").toAbsolutePath(), paths);
TargetNode<?, ?> guavaTargetNode =
PrebuiltJarBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:guava"))
.setBinaryJar(Paths.get("lib/guava.jar"))
.build();
TargetNode<?, ?> srcTargetNode =
JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com/src:src"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/src/Source.java"))
.build();
TargetNode<?, ?> src2TargetNode =
JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com:src2"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(Paths.get("java/com/src2/Code.java"))
.build();
TargetNode<?, ?> rootTargetNode =
JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//:root")).build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(
ImmutableSet.of(guavaTargetNode, srcTargetNode, src2TargetNode, rootTargetNode));
IjModule srcModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, srcTargetNode);
IjModule src2Module = IjModuleGraphTest.getModuleForTarget(moduleGraph, src2TargetNode);
IjModule rootModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, rootTargetNode);
IjProjectTemplateDataPreparer dataPreparer =
new IjProjectTemplateDataPreparer(
javaPackageFinder, moduleGraph, filesystemForExcludesTest);
assertEquals(
ImmutableSet.of(Paths.get("java/com/src/foo")),
distillExcludeFolders(dataPreparer.createExcludes(srcModule)));
assertEquals(
ImmutableSet.of(Paths.get("java/com/data")),
distillExcludeFolders(dataPreparer.createExcludes(src2Module)));
// In this case it's fine to exclude "lib" as there is no source code there.
assertEquals(
ImmutableSet.of(Paths.get(".git"), Paths.get("java/org"), Paths.get("lib")),
distillExcludeFolders(dataPreparer.createExcludes(rootModule)));
}
@Test
public void testCreatePackageLookupPahtSet() {
TargetNode<?, ?> guavaTargetNode =
PrebuiltJarBuilder.createBuilder(BuildTargetFactory.newInstance("//lib:guava"))
.setBinaryJar(Paths.get("lib/guava.jar"))
.build();
Path sourcePath = Paths.get("java/com/src/Source.java");
Path subSourcePath = Paths.get("java/com/src/subpackage/SubSource.java");
TargetNode<?, ?> srcTargetNode =
JavaLibraryBuilder.createBuilder(BuildTargetFactory.newInstance("//java/com/src:src"))
.addDep(guavaTargetNode.getBuildTarget())
.addSrc(sourcePath)
.addSrc(subSourcePath)
.build();
IjModuleGraph moduleGraph =
IjModuleGraphTest.createModuleGraph(ImmutableSet.of(guavaTargetNode, srcTargetNode));
assertThat(
IjProjectTemplateDataPreparer.createPackageLookupPathSet(moduleGraph),
containsInAnyOrder(subSourcePath, sourcePath));
}
private static ImmutableSet<Path> distillExcludeFolders(ImmutableSet<IjFolder> folders) {
Preconditions.checkArgument(
!FluentIterable.from(folders).anyMatch(input -> !(input instanceof ExcludeFolder)));
return FluentIterable.from(folders).uniqueIndex(IjFolder::getPath).keySet();
}
}