/** * 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. * * Copyright 2012-2015 the original author or authors. */ package org.assertj.swing.driver; import static javax.swing.JOptionPane.ERROR_MESSAGE; import static javax.swing.JOptionPane.INFORMATION_MESSAGE; import static javax.swing.JOptionPane.PLAIN_MESSAGE; import static javax.swing.JOptionPane.QUESTION_MESSAGE; import static javax.swing.JOptionPane.WARNING_MESSAGE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.util.Preconditions.checkNotNull; import static org.assertj.swing.driver.JOptionPaneMessageQuery.messageOf; import static org.assertj.swing.driver.JOptionPaneMessageTypeQuery.messageTypeOf; import static org.assertj.swing.driver.JOptionPaneMessageTypes.messageTypeAsText; import static org.assertj.swing.driver.JOptionPaneOptionsQuery.optionsOf; import static org.assertj.swing.driver.JOptionPaneTitleQuery.titleOf; import static org.assertj.swing.driver.TextAssert.verifyThat; import java.util.regex.Pattern; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.UIManager; import org.assertj.core.description.Description; import org.assertj.swing.annotation.RunsInEDT; import org.assertj.swing.core.Robot; import org.assertj.swing.core.matcher.JButtonMatcher; import org.assertj.swing.internal.annotation.InternalApi; /** * <p> * Supports functional testing of {@code JOptionPane}s. * </p> * * <p> * <b>Note:</b> This class is intended for internal use only. Please use the classes in the package * {@link org.assertj.swing.fixture} in your tests. * </p> * * @author Alex Ruiz */ @InternalApi public class JOptionPaneDriver extends JComponentDriver { private static final String MESSAGE_PROPERTY = "message"; private static final String MESSAGE_TYPE_PROPERTY = "messageType"; private static final String OPTIONS_PROPERTY = "options"; private static final String TITLE_PROPERTY = "title"; /** * Creates a new {@link JOptionPaneDriver}. * * @param robot the robot to use to simulate user input. */ public JOptionPaneDriver(@Nonnull Robot robot) { super(robot); } /** * Asserts that the title in the given {@code JOptionPane} matches the given value. * * @param optionPane the target {@code JOptionPane}. * @param title the title to match. It can be a regular expression. * @throws AssertionError if the {@code JOptionPane} does not have the given title. */ @RunsInEDT public void requireTitle(@Nonnull JOptionPane optionPane, @Nullable String title) { verifyThat(title(optionPane)).as(propertyName(optionPane, TITLE_PROPERTY)).isEqualOrMatches(title); } /** * Asserts that the title in the given {@code JOptionPane} matches the given regular expression pattern. * * @param optionPane the target {@code JOptionPane}. * @param pattern the regular expression pattern to match. * @throws NullPointerException if the given regular expression pattern is {@code null}. * @throws AssertionError if the {@code JOptionPane} does not have the given title. */ @RunsInEDT public void requireTitle(@Nonnull JOptionPane optionPane, @Nonnull Pattern pattern) { verifyThat(title(optionPane)).as(propertyName(optionPane, TITLE_PROPERTY)).matches(pattern); } /** * Returns the title of the given {@code JOptionPane}. * * @param optionPane the target {@code JOptionPane}. * @return the title of the given {@code JOptionPane}. */ @RunsInEDT public @Nullable String title(@Nonnull JOptionPane optionPane) { return titleOf(optionPane); } /** * Asserts that the title of the {@code JOptionPane} matches the given value. If the given value is a regular * expression and the message in the {@code JOptionPane} is not a {@code String}, this method will use the * {@code toString} representation of such message. message in the {@code JOptionPane} is not a {@code String}, this * method will use the {@code toString} representation of such message. * * @param optionPane the target {@code JOptionPane}. * @param message the message to verify. If it is a {@code String}, it can be specified as a regular expression. * @throws AssertionError if the message in the {@code JOptionPane} is not equal to or does not match the given * message. */ @RunsInEDT public void requireMessage(@Nonnull JOptionPane optionPane, @Nullable Object message) { Object actual = messageOf(optionPane); if (message instanceof String && actual != null) { requireMessage(optionPane, (String) message, actual.toString()); return; } assertThat(actual).as(messageProperty(optionPane)).isEqualTo(message); } @RunsInEDT private void requireMessage(@Nonnull JOptionPane optionPane, @Nullable String expected, @Nullable String actual) { verifyThat(actual).as(messageProperty(optionPane)).isEqualOrMatches(expected); } /** * Asserts that the title of the {@code JOptionPane} matches the given regular expression pattern. If the message in * the {@code JOptionPane} is not a {@code String}, this method will use the {@code toString} representation of such * message. * * @param optionPane the target {@code JOptionPane}. * @param pattern the regular expression to match. * @throws NullPointerException if the given regular expression pattern is {@code null}. * @throws AssertionError if the message in the {@code JOptionPaneFixture} does not match the given regular expression * pattern. */ @RunsInEDT public void requireMessage(@Nonnull JOptionPane optionPane, @Nonnull Pattern pattern) { Object actual = messageOf(optionPane); String s = actual == null ? null : actual.toString(); verifyThat(s).as(messageProperty(optionPane)).matches(pattern); } private Description messageProperty(@Nonnull JOptionPane optionPane) { return propertyName(optionPane, MESSAGE_PROPERTY); } /** * Asserts that the {@code JOptionPane} has the given options. * * @param optionPane the target {@code JOptionPane}. * @param options the options to verify. * @throws AssertionError if the {@code JOptionPane} does not have the given options. */ @RunsInEDT public void requireOptions(@Nonnull JOptionPane optionPane, @Nonnull Object[] options) { assertThat(optionsOf(optionPane)).as(propertyName(optionPane, OPTIONS_PROPERTY)).isEqualTo(options); } /** * Finds the "OK" button in the {@code JOptionPane}. This method is independent of locale and platform. * * @param optionPane the target {@code JOptionPane}. * @return the "OK" button. * @throws org.assertj.swing.exception.ComponentLookupException if the a "OK" button cannot be found. */ @RunsInEDT public @Nonnull JButton okButton(@Nonnull JOptionPane optionPane) { return buttonWithTextFromUIManager(optionPane, "OptionPane.okButtonText"); } /** * Finds the "Cancel" button in the {@code JOptionPane}. This method is independent of locale and platform. * * @param optionPane the target {@code JOptionPane}. * @return the "Cancel" button. * @throws org.assertj.swing.exception.ComponentLookupException if the a "Cancel" button cannot be found. */ @RunsInEDT public @Nonnull JButton cancelButton(@Nonnull JOptionPane optionPane) { return buttonWithTextFromUIManager(optionPane, "OptionPane.cancelButtonText"); } /** * Finds the "Yes" button in the {@code JOptionPane}. This method is independent of locale and platform. * * @param optionPane the target {@code JOptionPane}. * @return the "Yes" button. * @throws org.assertj.swing.exception.ComponentLookupException if the a "Yes" button cannot be found. */ @RunsInEDT public @Nonnull JButton yesButton(@Nonnull JOptionPane optionPane) { return buttonWithTextFromUIManager(optionPane, "OptionPane.yesButtonText"); } /** * Finds the "No" button in the {@code JOptionPane}. This method is independent of locale and platform. * * @param optionPane the target {@code JOptionPane}. * @return the "No" button. * @throws org.assertj.swing.exception.ComponentLookupException if the a "No" button cannot be found. */ @RunsInEDT public @Nonnull JButton noButton(@Nonnull JOptionPane optionPane) { return buttonWithTextFromUIManager(optionPane, "OptionPane.noButtonText"); } @RunsInEDT private @Nonnull JButton buttonWithTextFromUIManager(@Nonnull JOptionPane optionPane, @Nonnull String key) { return buttonWithText(optionPane, checkNotNull(UIManager.getString(key))); } /** * Finds a button in the {@code JOptionPane} containing the given text. * * @param optionPane the target {@code JOptionPane}. * @param text the text of the button to find and return. It can be a regular expression. * @return a button containing the given text. * @throws org.assertj.swing.exception.ComponentLookupException if the a button with the given text cannot be found. */ @RunsInEDT public @Nonnull JButton buttonWithText(@Nonnull JOptionPane optionPane, @Nullable String text) { return robot.finder().find(optionPane, JButtonMatcher.withText(text).andShowing()); } /** * Finds a button in the {@code JOptionPane} whose text matches the given regular expression pattern. * * @param optionPane the target {@code JOptionPane}. * @param pattern the regular expression pattern to match. * @return a button containing the given text. * @throws NullPointerException if the given regular expression pattern is {@code null}. * @throws org.assertj.swing.exception.ComponentLookupException if the a button with the given text cannot be found. */ @RunsInEDT public @Nonnull JButton buttonWithText(@Nonnull JOptionPane optionPane, @Nonnull Pattern pattern) { return robot.finder().find(optionPane, JButtonMatcher.withText(pattern).andShowing()); } /** * Asserts that the {@code JOptionPane} is displaying an error message. * * @param optionPane the target {@code JOptionPane}. */ @RunsInEDT public void requireErrorMessage(@Nonnull JOptionPane optionPane) { assertEqualMessageType(optionPane, ERROR_MESSAGE); } /** * Asserts that the {@code JOptionPane} is displaying an information message. * * @param optionPane the target {@code JOptionPane}. */ @RunsInEDT public void requireInformationMessage(@Nonnull JOptionPane optionPane) { assertEqualMessageType(optionPane, INFORMATION_MESSAGE); } /** * Asserts that the {@code JOptionPane} is displaying a warning message. * * @param optionPane the target {@code JOptionPane}. */ @RunsInEDT public void requireWarningMessage(@Nonnull JOptionPane optionPane) { assertEqualMessageType(optionPane, WARNING_MESSAGE); } /** * Asserts that the {@code JOptionPane} is displaying a question. * * @param optionPane the target {@code JOptionPane}. */ @RunsInEDT public void requireQuestionMessage(@Nonnull JOptionPane optionPane) { assertEqualMessageType(optionPane, QUESTION_MESSAGE); } /** * Asserts that the {@code JOptionPane} is displaying a plain message. * * @param optionPane the target {@code JOptionPane}. */ @RunsInEDT public void requirePlainMessage(@Nonnull JOptionPane optionPane) { assertEqualMessageType(optionPane, PLAIN_MESSAGE); } @RunsInEDT private void assertEqualMessageType(@Nonnull JOptionPane optionPane, int expected) { String actualType = actualMessageTypeAsText(optionPane); assertThat(actualType).as(propertyName(optionPane, MESSAGE_TYPE_PROPERTY)).isEqualTo(messageTypeAsText(expected)); } @RunsInEDT private String actualMessageTypeAsText(final @Nonnull JOptionPane optionPane) { return messageTypeAsText(messageTypeOf(optionPane)); } }