| /* |
| * Copyright 2017 The Bazel Authors. All rights reserved. |
| * |
| * 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.google.idea.blaze.cpp; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.when; |
| |
| import com.google.common.collect.ImmutableCollection; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.Iterables; |
| import com.google.idea.blaze.base.BlazeTestCase; |
| import com.google.idea.blaze.base.async.executor.BlazeExecutor; |
| import com.google.idea.blaze.base.async.executor.MockBlazeExecutor; |
| import com.google.idea.blaze.base.bazel.BazelBuildSystemProvider; |
| import com.google.idea.blaze.base.bazel.BuildSystemProvider; |
| import com.google.idea.blaze.base.ideinfo.ArtifactLocation; |
| import com.google.idea.blaze.base.ideinfo.CIdeInfo; |
| import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo; |
| import com.google.idea.blaze.base.ideinfo.TargetIdeInfo; |
| import com.google.idea.blaze.base.ideinfo.TargetMap; |
| import com.google.idea.blaze.base.ideinfo.TargetMapBuilder; |
| import com.google.idea.blaze.base.io.VirtualFileSystemProvider; |
| import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder; |
| import com.google.idea.blaze.base.model.primitives.ExecutionRootPath; |
| import com.google.idea.blaze.base.model.primitives.Kind; |
| import com.google.idea.blaze.base.model.primitives.TargetExpression; |
| import com.google.idea.blaze.base.model.primitives.WorkspacePath; |
| import com.google.idea.blaze.base.model.primitives.WorkspaceRoot; |
| import com.google.idea.blaze.base.projectview.ProjectView; |
| import com.google.idea.blaze.base.projectview.ProjectViewSet; |
| import com.google.idea.blaze.base.projectview.section.ListSection; |
| import com.google.idea.blaze.base.projectview.section.sections.DirectoryEntry; |
| import com.google.idea.blaze.base.projectview.section.sections.DirectorySection; |
| import com.google.idea.blaze.base.projectview.section.sections.TargetSection; |
| import com.google.idea.blaze.base.scope.BlazeContext; |
| import com.google.idea.blaze.base.scope.ErrorCollector; |
| import com.google.idea.blaze.base.scope.output.IssueOutput; |
| import com.google.idea.blaze.base.settings.BlazeImportSettings; |
| import com.google.idea.blaze.base.settings.BlazeImportSettingsManager; |
| import com.intellij.mock.MockPsiManager; |
| import com.intellij.openapi.progress.ProgressManager; |
| import com.intellij.openapi.progress.impl.ProgressManagerImpl; |
| import com.intellij.openapi.vfs.LocalFileSystem; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.openapi.vfs.VirtualFileManager; |
| import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile; |
| import com.intellij.psi.PsiManager; |
| import com.jetbrains.cidr.lang.OCLanguageKind; |
| import com.jetbrains.cidr.lang.workspace.OCResolveRootAndConfiguration; |
| import com.jetbrains.cidr.lang.workspace.headerRoots.HeadersSearchRoot; |
| import com.jetbrains.cidr.lang.workspace.headerRoots.IncludedHeadersRoot; |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.stream.Collectors; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** Tests that we group equivalent {@link BlazeResolveConfiguration}s. */ |
| @RunWith(JUnit4.class) |
| public class BlazeResolveConfigurationEquivalenceTest extends BlazeTestCase { |
| private final BlazeContext context = new BlazeContext(); |
| private final ErrorCollector errorCollector = new ErrorCollector(); |
| private final WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root")); |
| |
| private BlazeConfigurationResolver resolver; |
| private BlazeConfigurationResolverResult resolverResult; |
| private LocalFileSystem mockFileSystem; |
| |
| @Override |
| protected void initTest(Container applicationServices, Container projectServices) { |
| super.initTest(applicationServices, projectServices); |
| applicationServices.register(BlazeExecutor.class, new MockBlazeExecutor()); |
| applicationServices.register( |
| CompilerVersionChecker.class, new MockCompilerVersionChecker("1234")); |
| |
| applicationServices.register(ProgressManager.class, new ProgressManagerImpl()); |
| applicationServices.register(VirtualFileManager.class, mock(VirtualFileManager.class)); |
| mockFileSystem = mock(LocalFileSystem.class); |
| applicationServices.register( |
| VirtualFileSystemProvider.class, mock(VirtualFileSystemProvider.class)); |
| when(VirtualFileSystemProvider.getInstance().getSystem()).thenReturn(mockFileSystem); |
| |
| projectServices.register(PsiManager.class, new MockPsiManager(project)); |
| projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager()); |
| |
| BuildSystemProvider buildSystemProvider = new BazelBuildSystemProvider(); |
| registerExtensionPoint(BuildSystemProvider.EP_NAME, BuildSystemProvider.class) |
| .registerExtension(buildSystemProvider); |
| BlazeImportSettingsManager.getInstance(getProject()) |
| .setImportSettings( |
| new BlazeImportSettings("", "", "", "", buildSystemProvider.buildSystem())); |
| |
| context.addOutputSink(IssueOutput.class, errorCollector); |
| |
| resolver = new BlazeConfigurationResolver(project); |
| resolverResult = BlazeConfigurationResolverResult.empty(project); |
| } |
| |
| @Test |
| public void testEmptyConfigurations() { |
| ProjectView projectView = |
| projectView( |
| directories("foo/bar"), targets("//foo/bar:one", "//foo/bar:two", "//foo/bar:three")); |
| TargetMap targetMap = |
| TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:one", |
| Kind.CC_BINARY, |
| sources("foo/bar/one.cc"), |
| defines(), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:two", |
| Kind.CC_BINARY, |
| sources("foo/bar/two.cc"), |
| defines(), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:three", |
| Kind.CC_BINARY, |
| sources("foo/bar/three.cc"), |
| defines(), |
| includes())) |
| .build(); |
| List<BlazeResolveConfiguration> configurations = resolve(projectView, targetMap); |
| assertThat(configurations).hasSize(1); |
| assertThat(get(configurations, "//foo/bar:one and 2 other target(s)")).isNotNull(); |
| for (BlazeResolveConfiguration configuration : configurations) { |
| assertThat(configuration.getProjectHeadersRoots().getRoots()).isEmpty(); |
| assertThat(getHeaders(configuration, OCLanguageKind.CPP)).isEmpty(); |
| assertThat(configuration.getCompilerMacros()).isEqualTo(macros()); |
| } |
| } |
| |
| @Test |
| public void testDefines() { |
| ProjectView projectView = |
| projectView( |
| directories("foo/bar"), targets("//foo/bar:one", "//foo/bar:two", "//foo/bar:three")); |
| TargetMap targetMap = |
| TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:one", |
| Kind.CC_BINARY, |
| sources("foo/bar/one.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:two", |
| Kind.CC_BINARY, |
| sources("foo/bar/two.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:three", |
| Kind.CC_BINARY, |
| sources("foo/bar/three.cc"), |
| defines("DIFFERENT=1"), |
| includes())) |
| .build(); |
| List<BlazeResolveConfiguration> configurations = resolve(projectView, targetMap); |
| assertThat(configurations).hasSize(2); |
| assertThat(get(configurations, "//foo/bar:one and 1 other target(s)").getCompilerMacros()) |
| .isEqualTo(macros("SAME=1")); |
| assertThat(get(configurations, "//foo/bar:three").getCompilerMacros()) |
| .isEqualTo(macros("DIFFERENT=1")); |
| for (BlazeResolveConfiguration configuration : configurations) { |
| assertThat(configuration.getProjectHeadersRoots().getRoots()).isEmpty(); |
| assertThat(getHeaders(configuration, OCLanguageKind.CPP)).isEmpty(); |
| } |
| } |
| |
| @Test |
| public void testIncludes() { |
| ProjectView projectView = |
| projectView( |
| directories("foo/bar"), targets("//foo/bar:one", "//foo/bar:two", "//foo/bar:three")); |
| TargetMap targetMap = |
| TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:one", |
| Kind.CC_BINARY, |
| sources("foo/bar/one.cc"), |
| defines(), |
| includes("foo/same"))) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:two", |
| Kind.CC_BINARY, |
| sources("foo/bar/two.cc"), |
| defines(), |
| includes("foo/same"))) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:three", |
| Kind.CC_BINARY, |
| sources("foo/bar/three.cc"), |
| defines(), |
| includes("foo/different"))) |
| .build(); |
| VirtualFile includeSame = createVirtualFile("/root/foo/same"); |
| VirtualFile includeDifferent = createVirtualFile("/root/foo/different"); |
| List<BlazeResolveConfiguration> configurations = resolve(projectView, targetMap); |
| assertThat(configurations).hasSize(2); |
| assertThat( |
| getHeaders( |
| get(configurations, "//foo/bar:one and 1 other target(s)"), OCLanguageKind.CPP)) |
| .containsExactly(header(includeSame)); |
| assertThat(getHeaders(get(configurations, "//foo/bar:three"), OCLanguageKind.CPP)) |
| .containsExactly(header(includeDifferent)); |
| for (BlazeResolveConfiguration configuration : configurations) { |
| assertThat(configuration.getProjectHeadersRoots().getRoots()).isEmpty(); |
| assertThat(configuration.getCompilerMacros()).isEqualTo(macros()); |
| } |
| } |
| |
| // Test a series of permutations of labels a, b, c, d. |
| // Initial state is {a=1, b=1, c=1, d=0}, and we flip some of the 1 to 0. |
| private TargetMap incrementalUpdateTestCaseInitialTargetMap() { |
| return TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:a", |
| Kind.CC_BINARY, |
| sources("foo/bar/a.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:b", |
| Kind.CC_BINARY, |
| sources("foo/bar/b.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:c", |
| Kind.CC_BINARY, |
| sources("foo/bar/c.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:d", |
| Kind.CC_BINARY, |
| sources("foo/bar/d.cc"), |
| defines("DIFFERENT=1"), |
| includes())) |
| .build(); |
| } |
| |
| // TODO(jvoung): This could be a separate Parameterized test. |
| private static final Map<List<String>, ReusedConfigurationExpectations> |
| permutationsAndExpectations = |
| ImmutableMap.<List<String>, ReusedConfigurationExpectations>builder() |
| .put( |
| ImmutableList.of("a"), |
| // Since we already had a config at 1 and one at 0, flipping any 1 to 0 will |
| // always |
| // result in reuse. The old configurations will get renamed. |
| new ReusedConfigurationExpectations( |
| ImmutableList.of( |
| "//foo/bar:a and 1 other target(s)", "//foo/bar:b and 1 other target(s)"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("b"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of( |
| "//foo/bar:a and 1 other target(s)", "//foo/bar:b and 1 other target(s)"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("c"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of( |
| "//foo/bar:a and 1 other target(s)", "//foo/bar:c and 1 other target(s)"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("a", "b"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:a and 2 other target(s)", "//foo/bar:c"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("b", "c"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:a", "//foo/bar:b and 2 other target(s)"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("a", "c"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:a and 2 other target(s)", "//foo/bar:b"), |
| ImmutableList.of())) |
| .put( |
| ImmutableList.of("a", "b", "c"), |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:a and 3 other target(s)"), ImmutableList.of())) |
| .build(); |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_0() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 0); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_1() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 1); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_2() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 2); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_3() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 3); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_4() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 4); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_5() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 5); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| } |
| |
| @Test |
| public void changeDefines_testIncrementalUpdate_6() { |
| Map.Entry<List<String>, ReusedConfigurationExpectations> testCase = |
| Iterables.get(permutationsAndExpectations.entrySet(), 6); |
| do_changeDefines_testIncrementalUpdate(testCase.getKey(), testCase.getValue()); |
| assertThat(permutationsAndExpectations.size()).isEqualTo(7); |
| } |
| |
| private void do_changeDefines_testIncrementalUpdate( |
| List<String> labelsToFlip, ReusedConfigurationExpectations expectation) { |
| ProjectView projectView = projectView(directories("foo/bar"), targets("//foo/bar:...:all")); |
| List<BlazeResolveConfiguration> configurations = |
| resolve(projectView, incrementalUpdateTestCaseInitialTargetMap()); |
| assertThat(configurations).hasSize(2); |
| assertThat(get(configurations, "//foo/bar:a and 2 other target(s)")).isNotNull(); |
| assertThat(get(configurations, "//foo/bar:d")).isNotNull(); |
| |
| TargetMapBuilder targetMapBuilder = TargetMapBuilder.builder().addTarget(createCcToolchain()); |
| for (String target : ImmutableList.of("a", "b", "c")) { |
| if (labelsToFlip.contains(target)) { |
| targetMapBuilder.addTarget( |
| createCcTarget( |
| String.format("//foo/bar:%s", target), |
| Kind.CC_BINARY, |
| sources(String.format("foo/bar/%s.cc", target)), |
| defines("DIFFERENT=1"), |
| includes())); |
| } else { |
| targetMapBuilder.addTarget( |
| createCcTarget( |
| String.format("//foo/bar:%s", target), |
| Kind.CC_BINARY, |
| sources(String.format("foo/bar/%s.cc", target)), |
| defines("SAME=1"), |
| includes())); |
| } |
| } |
| targetMapBuilder.addTarget( |
| createCcTarget( |
| "//foo/bar:d", |
| Kind.CC_BINARY, |
| sources("foo/bar/d.cc"), |
| defines("DIFFERENT=1"), |
| includes())); |
| List<BlazeResolveConfiguration> newConfigurations = |
| resolve(projectView, targetMapBuilder.build()); |
| assertReusedConfigs(configurations, newConfigurations, expectation); |
| } |
| |
| @Test |
| public void changeDefinesWithSameStructure_testIncrementalUpdate() { |
| ProjectView projectView = projectView(directories("foo/bar"), targets("//foo/bar:...:all")); |
| TargetMap targetMap = incrementalUpdateTestCaseInitialTargetMap(); |
| List<BlazeResolveConfiguration> configurations = resolve(projectView, targetMap); |
| assertThat(configurations).hasSize(2); |
| assertThat(get(configurations, "//foo/bar:a and 2 other target(s)")).isNotNull(); |
| assertThat(get(configurations, "//foo/bar:d")).isNotNull(); |
| |
| targetMap = |
| TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:a", |
| Kind.CC_BINARY, |
| sources("foo/bar/a.cc"), |
| defines("CHANGED=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:b", |
| Kind.CC_BINARY, |
| sources("foo/bar/b.cc"), |
| defines("CHANGED=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:c", |
| Kind.CC_BINARY, |
| sources("foo/bar/c.cc"), |
| defines("CHANGED=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:d", |
| Kind.CC_BINARY, |
| sources("foo/bar/d.cc"), |
| defines("DIFFERENT=1"), |
| includes())) |
| .build(); |
| List<BlazeResolveConfiguration> newConfigurations = resolve(projectView, targetMap); |
| assertThat(newConfigurations).hasSize(2); |
| assertReusedConfigs( |
| configurations, |
| newConfigurations, |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:d"), |
| ImmutableList.of("//foo/bar:a and 2 other target(s)"))); |
| } |
| |
| @Test |
| public void changeDefinesMakeAllSame_testIncrementalUpdate() { |
| ProjectView projectView = projectView(directories("foo/bar"), targets("//foo/bar:...:all")); |
| TargetMap targetMap = incrementalUpdateTestCaseInitialTargetMap(); |
| List<BlazeResolveConfiguration> configurations = resolve(projectView, targetMap); |
| assertThat(configurations).hasSize(2); |
| assertThat(get(configurations, "//foo/bar:a and 2 other target(s)")).isNotNull(); |
| assertThat(get(configurations, "//foo/bar:d")).isNotNull(); |
| |
| targetMap = |
| TargetMapBuilder.builder() |
| .addTarget(createCcToolchain()) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:a", |
| Kind.CC_BINARY, |
| sources("foo/bar/a.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:b", |
| Kind.CC_BINARY, |
| sources("foo/bar/b.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:c", |
| Kind.CC_BINARY, |
| sources("foo/bar/c.cc"), |
| defines("SAME=1"), |
| includes())) |
| .addTarget( |
| createCcTarget( |
| "//foo/bar:d", |
| Kind.CC_BINARY, |
| sources("foo/bar/d.cc"), |
| defines("SAME=1"), |
| includes())) |
| .build(); |
| List<BlazeResolveConfiguration> newConfigurations = resolve(projectView, targetMap); |
| assertThat(newConfigurations).hasSize(1); |
| // What used to be "//foo/bar:a and 2 other target(s)" will be renamed to |
| // "//foo/bar:a and 3 other target(s)" and reused. |
| assertReusedConfigs( |
| configurations, |
| newConfigurations, |
| new ReusedConfigurationExpectations( |
| ImmutableList.of("//foo/bar:a and 3 other target(s)"), ImmutableList.of())); |
| } |
| |
| private static List<ArtifactLocation> sources(String... paths) { |
| return Arrays.stream(paths) |
| .map(path -> ArtifactLocation.builder().setRelativePath(path).setIsSource(true).build()) |
| .collect(Collectors.toList()); |
| } |
| |
| private static List<String> defines(String... defines) { |
| return Arrays.asList(defines); |
| } |
| |
| private static List<ExecutionRootPath> includes(String... paths) { |
| return Arrays.stream(paths).map(ExecutionRootPath::new).collect(Collectors.toList()); |
| } |
| |
| private static TargetIdeInfo.Builder createCcTarget( |
| String label, |
| Kind kind, |
| List<ArtifactLocation> sources, |
| List<String> defines, |
| List<ExecutionRootPath> includes) { |
| TargetIdeInfo.Builder targetInfo = |
| TargetIdeInfo.builder().setLabel(label).setKind(kind).addDependency("//:toolchain"); |
| sources.forEach(targetInfo::addSource); |
| return targetInfo.setCInfo( |
| CIdeInfo.builder() |
| .addSources(sources) |
| .addLocalDefines(defines) |
| .addLocalIncludeDirectories(includes)); |
| } |
| |
| private static TargetIdeInfo.Builder createCcToolchain() { |
| return TargetIdeInfo.builder() |
| .setLabel("//:toolchain") |
| .setKind(Kind.CC_TOOLCHAIN) |
| .setCToolchainInfo( |
| CToolchainIdeInfo.builder().setCppExecutable(new ExecutionRootPath("cc"))); |
| } |
| |
| private static ListSection<DirectoryEntry> directories(String... directories) { |
| return ListSection.builder(DirectorySection.KEY) |
| .addAll( |
| Arrays.stream(directories) |
| .map(directory -> DirectoryEntry.include(WorkspacePath.createIfValid(directory))) |
| .collect(Collectors.toList())) |
| .build(); |
| } |
| |
| private static ListSection<TargetExpression> targets(String... targets) { |
| return ListSection.builder(TargetSection.KEY) |
| .addAll( |
| Arrays.stream(targets).map(TargetExpression::fromString).collect(Collectors.toList())) |
| .build(); |
| } |
| |
| private static ProjectView projectView( |
| ListSection<DirectoryEntry> directories, ListSection<TargetExpression> targets) { |
| return ProjectView.builder().add(directories).add(targets).build(); |
| } |
| |
| private List<BlazeResolveConfiguration> resolve(ProjectView projectView, TargetMap targetMap) { |
| resolverResult = |
| resolver.update( |
| context, |
| workspaceRoot, |
| ProjectViewSet.builder().add(projectView).build(), |
| MockBlazeProjectDataBuilder.builder(workspaceRoot).setTargetMap(targetMap).build(), |
| resolverResult); |
| errorCollector.assertNoIssues(); |
| return resolverResult.getAllConfigurations(); |
| } |
| |
| private static BlazeResolveConfiguration get( |
| List<BlazeResolveConfiguration> configurations, String name) { |
| List<BlazeResolveConfiguration> filteredConfigurations = |
| configurations |
| .stream() |
| .filter(c -> c.getDisplayName(false).equals(name)) |
| .collect(Collectors.toList()); |
| assertWithMessage( |
| String.format( |
| "%s contains %s", |
| configurations |
| .stream() |
| .map(c -> c.getDisplayName(false)) |
| .collect(Collectors.toList()), |
| name)) |
| .that(filteredConfigurations) |
| .hasSize(1); |
| return filteredConfigurations.get(0); |
| } |
| |
| private BlazeCompilerMacros macros(String... defines) { |
| return new BlazeCompilerMacros( |
| project, null, null, ImmutableList.copyOf(defines), ImmutableMap.of()); |
| } |
| |
| private HeadersSearchRoot header(VirtualFile include) { |
| return new IncludedHeadersRoot(project, include, false, true); |
| } |
| |
| private static List<HeadersSearchRoot> getHeaders( |
| BlazeResolveConfiguration configuration, OCLanguageKind languageKind) { |
| return configuration |
| .getLibraryHeadersRoots(new OCResolveRootAndConfiguration(configuration, languageKind)) |
| .getRoots(); |
| } |
| |
| private VirtualFile createVirtualFile(String path) { |
| VirtualFile stub = new StubVirtualFile(); |
| when(mockFileSystem.findFileByIoFile(new File(path))).thenReturn(stub); |
| return stub; |
| } |
| |
| private static void assertReusedConfigs( |
| List<BlazeResolveConfiguration> oldConfigurations, |
| List<BlazeResolveConfiguration> newConfigurations, |
| ReusedConfigurationExpectations expected) { |
| for (String label : expected.reusedLabels) { |
| assertWithMessage(String.format("Checking that %s is reused", label)) |
| .that(get(newConfigurations, label)) |
| .isSameAs(get(oldConfigurations, label)); |
| } |
| for (String label : expected.notReusedLabels) { |
| assertWithMessage(String.format("Checking that %s is NOT reused", label)) |
| .that(get(newConfigurations, label)) |
| .isNotSameAs(get(oldConfigurations, label)); |
| } |
| } |
| |
| private static class ReusedConfigurationExpectations { |
| final ImmutableCollection<String> reusedLabels; |
| final ImmutableCollection<String> notReusedLabels; |
| |
| ReusedConfigurationExpectations( |
| ImmutableCollection<String> reusedLabels, ImmutableCollection<String> notReusedLabels) { |
| this.reusedLabels = reusedLabels; |
| this.notReusedLabels = notReusedLabels; |
| } |
| } |
| } |