| /* |
| * Copyright 2012-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.testutil; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| import com.facebook.buck.shell.ShellStep; |
| import com.facebook.buck.step.ExecutionContext; |
| import com.facebook.buck.step.Step; |
| import com.google.common.base.Function; |
| import com.google.common.base.Joiner; |
| import com.google.common.collect.FluentIterable; |
| import com.google.common.collect.ImmutableList; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import javax.annotation.Nullable; |
| |
| /** |
| * Additional assertions that delegate to JUnit assertions, but with better error messages. |
| */ |
| public final class MoreAsserts { |
| |
| private MoreAsserts() {} |
| |
| /** |
| * @see #assertIterablesEquals(Iterable, Iterable) |
| */ |
| public static <T extends List<?>> void assertListEquals( |
| List<?> expected, |
| List<?> observed) { |
| assertIterablesEquals(expected, observed); |
| } |
| |
| /** |
| * @see #assertIterablesEquals(String, Iterable, Iterable) |
| */ |
| public static <T extends List<?>> void assertListEquals( |
| String userMessage, |
| List<?> expected, |
| List<?> observed) { |
| assertIterablesEquals(userMessage, expected, observed); |
| } |
| |
| /** |
| * Equivalent to {@link org.junit.Assert#assertEquals(Object, Object)} except if the assertion |
| * fails, the message includes information about where the iterables differ. |
| */ |
| public static <T extends Iterable<?>> void assertIterablesEquals( |
| Iterable<?> expected, |
| Iterable<?> observed) { |
| assertIterablesEquals(null /* userMessage */, expected, observed); |
| } |
| |
| /** |
| * Equivalent to {@link org.junit.Assert#assertEquals(String, Object, Object)} except if the |
| * assertion fails, the message includes information about where the iterables differ. |
| */ |
| public static <T extends Iterable<?>> void assertIterablesEquals( |
| String userMessage, |
| Iterable<?> expected, |
| Iterable<?> observed) { |
| // The traditional assertEquals() method should be fine if either List is null. |
| if (expected == null || observed == null) { |
| assertEquals(userMessage, expected, observed); |
| return; |
| } |
| |
| // Compare each item in the list, one at a time. |
| Iterator<?> expectedIter = expected.iterator(); |
| Iterator<?> observedIter = observed.iterator(); |
| int index = 0; |
| while (expectedIter.hasNext()) { |
| if (!observedIter.hasNext()) { |
| fail(prefixWithUserMessage(userMessage, "Item " + index + " does not exist in the " + |
| "observed list")); |
| } |
| Object expectedItem = expectedIter.next(); |
| Object observedItem = observedIter.next(); |
| assertEquals( |
| prefixWithUserMessage(userMessage, "Item " + index + " in the lists should match."), |
| expectedItem, |
| observedItem); |
| ++index; |
| } |
| if (observedIter.hasNext()) { |
| fail(prefixWithUserMessage(userMessage, "Extraneous item " + index + " in the observed list")); |
| } |
| } |
| |
| public static <Item, Container extends Iterable<Item>> void assertContainsOne( |
| Container container, |
| Item expectedItem) { |
| assertContainsOne(/* userMessage */ null, container, expectedItem); |
| } |
| |
| public static <Item, Container extends Iterable<Item>> void assertContainsOne( |
| String userMessage, |
| Container container, |
| Item expectedItem) { |
| int seen = 0; |
| for (Item item : container) { |
| if (expectedItem.equals(item)) { |
| seen++; |
| } |
| } |
| if (seen < 1) { |
| failWith(userMessage, "Item '" + expectedItem + "' not found in container, " + |
| "expected to find one."); |
| } |
| if (seen > 1) { |
| failWith( |
| userMessage, |
| "Found " + Integer.valueOf(seen) + " occurrences of '" + expectedItem + |
| "' in container, expected to find only one."); |
| } |
| } |
| |
| /** |
| * Asserts that every {@link com.facebook.buck.step.Step} in the observed list is a {@link com.facebook.buck.shell.ShellStep} whose shell |
| * command arguments match those of the corresponding entry in the expected list. |
| */ |
| public static void assertShellCommands( |
| String userMessage, |
| List<String> expected, |
| List<Step> observed, |
| ExecutionContext context) { |
| Iterator<String> expectedIter = expected.iterator(); |
| Iterator<Step> observedIter = observed.iterator(); |
| Joiner joiner = Joiner.on(" "); |
| while (expectedIter.hasNext() && observedIter.hasNext()) { |
| String expectedShellCommand = expectedIter.next(); |
| Step observedStep = observedIter.next(); |
| if (!(observedStep instanceof ShellStep)) { |
| failWith(userMessage, "Observed command must be a shell command: " + observedStep); |
| } |
| ShellStep shellCommand = (ShellStep) observedStep; |
| String observedShellCommand = joiner.join(shellCommand.getShellCommand(context)); |
| assertEquals(userMessage, expectedShellCommand, observedShellCommand); |
| } |
| |
| if (expectedIter.hasNext()) { |
| failWith(userMessage, "Extra expected command: " + expectedIter.next()); |
| } |
| |
| if (observedIter.hasNext()) { |
| failWith(userMessage,"Extra observed command: " + observedIter.next()); |
| } |
| } |
| |
| /** |
| * Invokes the {@link Step#getDescription(ExecutionContext)} method on each of the observed steps |
| * to create a list of strings and compares it to the expected value. |
| */ |
| public static void assertSteps( |
| String userMessage, |
| List<String> expectedStepDescriptions, |
| List<Step> observedSteps, |
| final ExecutionContext executionContext) { |
| ImmutableList<String> commands = FluentIterable |
| .from(observedSteps) |
| .transform(new Function<Step, String>() { |
| @Override |
| public String apply(Step step) { |
| return step.getDescription(executionContext); |
| } |
| }) |
| .toList(); |
| assertListEquals( |
| userMessage, |
| expectedStepDescriptions, |
| commands); |
| } |
| |
| private static String prefixWithUserMessage(@Nullable String userMessage, String message) { |
| return (userMessage == null ? "" : userMessage + " ") + message; |
| } |
| |
| private static void failWith(@Nullable String userMessage, String message) { |
| fail(prefixWithUserMessage(userMessage, message)); |
| } |
| } |