001    /*
002     * Created on Feb 28, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.driver;
017    
018    import static org.fest.assertions.Assertions.assertThat;
019    import static org.fest.swing.driver.AbstractButtonSelectedQuery.isSelected;
020    import static org.fest.swing.driver.ComponentStateValidator.validateIsEnabledAndShowing;
021    import static org.fest.swing.driver.TextAssert.verifyThat;
022    import static org.fest.swing.edt.GuiActionRunner.execute;
023    
024    import java.util.regex.Pattern;
025    
026    import javax.swing.AbstractButton;
027    
028    import org.fest.assertions.Description;
029    import org.fest.swing.annotation.RunsInEDT;
030    import org.fest.swing.core.Robot;
031    import org.fest.swing.edt.GuiQuery;
032    
033    /**
034     * Understands functional testing of <code>{@link AbstractButton}</code>s:
035     * <ul>
036     * <li>user input simulation</li>
037     * <li>state verification</li>
038     * <li>property value query</li>
039     * </ul>
040     * This class is intended for internal use only. Please use the classes in the package
041     * <code>{@link org.fest.swing.fixture}</code> in your tests.
042     *
043     * @author Alex Ruiz
044     * @author Yvonne Wang
045     */
046    public class AbstractButtonDriver extends JComponentDriver implements TextDisplayDriver<AbstractButton> {
047    
048      private static final String SELECTED_PROPERTY = "selected";
049      private static final String TEXT_PROPERTY = "text";
050    
051      /**
052       * Creates a new </code>{@link AbstractButtonDriver}</code>.
053       * @param robot the robot to use to simulate user input.
054       */
055      public AbstractButtonDriver(Robot robot) {
056        super(robot);
057      }
058    
059      /**
060       * Asserts that the text in the given button is equal to or matches the specified <code>String</code>.
061       * @param button the given button.
062       * @param expected the text to match. It can be a regular expression.
063       * @throws AssertionError if the text of the button is not equal to or does not match the given one.
064       */
065      @RunsInEDT
066      public void requireText(AbstractButton button, String expected) {
067        verifyThat(textOf(button)).as(propertyName(button, TEXT_PROPERTY)).isEqualOrMatches(expected);
068      }
069    
070      /**
071       * Asserts that the text in the given button matches the given regular expression pattern.
072       * @param button the given button.
073       * @param pattern the regular expression pattern to match.
074       * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
075       * @throws AssertionError if the text of the button does not match the given regular expression pattern.
076       * @since 1.2
077       */
078      public void requireText(AbstractButton button, Pattern pattern) {
079        verifyThat(textOf(button)).as(propertyName(button, TEXT_PROPERTY)).matches(pattern);
080      }
081    
082      /**
083       * Returns the text of the given button.
084       * @param button the given button.
085       * @return the text of the given button.
086       */
087      @RunsInEDT
088      public String textOf(AbstractButton button) {
089        return AbstractButtonTextQuery.textOf(button);
090      }
091    
092      /**
093       * Selects the given button only it is not already selected.
094       * @param button the target button.
095       * @throws IllegalStateException if the button is disabled.
096       * @throws IllegalStateException if the button is not showing on the screen.
097       */
098      @RunsInEDT
099      public void select(AbstractButton button) {
100        if (validateAndFindIsSelected(button)) return;
101        robot.click(button);
102      }
103    
104      /**
105       * Unselects the given button only if it is selected.
106       * @param button the target button.
107       * @throws IllegalStateException if the button is disabled.
108       * @throws IllegalStateException if the button is not showing on the screen.
109       */
110      @RunsInEDT
111      public void unselect(AbstractButton button) {
112        if (!validateAndFindIsSelected(button)) return;
113        robot.click(button);
114      }
115    
116      @RunsInEDT
117      private static boolean validateAndFindIsSelected(final AbstractButton button) {
118        return execute(new GuiQuery<Boolean>() {
119          protected Boolean executeInEDT() {
120            validateIsEnabledAndShowing(button);
121            return button.isSelected();
122          }
123        });
124      }
125    
126      /**
127       * Verifies that the button is selected.
128       * @param button the given button.
129       * @throws AssertionError if the button is not selected.
130       */
131      @RunsInEDT
132      public void requireSelected(AbstractButton button) {
133        assertThatButtonIsSelected(button, true);
134      }
135    
136      /**
137       * Verifies that the button is not selected.
138       * @param button the given button.
139       * @throws AssertionError if the button is selected.
140       */
141      @RunsInEDT
142      public void requireNotSelected(AbstractButton button) {
143        assertThatButtonIsSelected(button, false);
144      }
145    
146      @RunsInEDT
147      private void assertThatButtonIsSelected(AbstractButton button, boolean selected) {
148        assertThat(isSelected(button)).as(selectedProperty(button)).isEqualTo(selected);
149      }
150    
151      @RunsInEDT
152      private static Description selectedProperty(AbstractButton button) {
153        return propertyName(button, SELECTED_PROPERTY);
154      }
155    }