View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.gui;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static org.mockito.ArgumentMatchers.any;
24  import static org.mockito.ArgumentMatchers.startsWith;
25  import static org.mockito.Mockito.doCallRealMethod;
26  import static org.mockito.Mockito.mockConstruction;
27  import static org.mockito.Mockito.mockStatic;
28  import static org.mockito.Mockito.when;
29  
30  import java.awt.Component;
31  import java.awt.Window;
32  import java.io.File;
33  import java.io.IOException;
34  import java.util.Arrays;
35  
36  import javax.swing.JButton;
37  import javax.swing.JComboBox;
38  import javax.swing.JFileChooser;
39  import javax.swing.JOptionPane;
40  import javax.swing.JTextArea;
41  import javax.swing.filechooser.FileFilter;
42  
43  import org.junit.jupiter.api.AfterEach;
44  import org.junit.jupiter.api.BeforeEach;
45  import org.junit.jupiter.api.Test;
46  import org.mockito.MockedConstruction;
47  import org.mockito.MockedStatic;
48  
49  import com.puppycrawl.tools.checkstyle.AbstractGuiTestSupport;
50  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
51  
52  public class MainFrameTest extends AbstractGuiTestSupport {
53  
54      private static final String TEST_FILE_NAME = "InputMainFrame.java";
55      private static final String NON_EXISTENT_FILE_NAME = "non-existent.file";
56  
57      private MainFrame mainFrame;
58  
59      @Override
60      protected String getPackageLocation() {
61          return "com/puppycrawl/tools/checkstyle/gui/mainframe";
62      }
63  
64      @BeforeEach
65      public void prepare() {
66          mainFrame = new MainFrame();
67      }
68  
69      @AfterEach
70      public void tearDown() {
71          Arrays.stream(mainFrame.getOwnedWindows())
72                  .forEach(Window::dispose);
73      }
74  
75      @Test
76      public void testOpenFile() throws IOException {
77          mainFrame.openFile(new File(getPath(TEST_FILE_NAME)));
78          assertWithMessage("Unexpected frame title")
79                  .that(mainFrame.getTitle())
80                  .isEqualTo("Checkstyle GUI : " + TEST_FILE_NAME);
81      }
82  
83      /**
84       * Test for opening a non-existent file.
85       * {@code JOptionPane} is mocked to prevent showing a modal message box.
86       *
87       * @throws IOException if I/O exception occurs while forming the path.
88       */
89      @Test
90      public void testOpenNonExistentFile() throws IOException {
91          final File file = new File(getPath(NON_EXISTENT_FILE_NAME));
92          try (MockedStatic<JOptionPane> optionPane = mockStatic(JOptionPane.class)) {
93              mainFrame.openFile(file);
94              optionPane.verify(() -> {
95                  JOptionPane.showMessageDialog(any(Component.class),
96                          startsWith("FileNotFoundException occurred while opening file"));
97              });
98          }
99          final MainFrameModel model = TestUtil.getInternalState(mainFrame, "model");
100         assertWithMessage("Unexpected current file")
101                 .that(model.getCurrentFile())
102                 .isEqualTo(file);
103     }
104 
105     @Test
106     public void testChangeMode() {
107         final JComboBox<MainFrameModel.ParseMode> modesCombobox =
108                 findComponentByName(mainFrame, "modesCombobox");
109         modesCombobox.setSelectedIndex(MainFrameModel.ParseMode.JAVA_WITH_COMMENTS.ordinal());
110         final MainFrameModel model = TestUtil.getInternalState(mainFrame, "model");
111         final MainFrameModel.ParseMode parseMode = TestUtil.getInternalState(model, "parseMode");
112         assertWithMessage("Unexpected parse mode")
113                 .that(parseMode)
114                 .isEqualTo(MainFrameModel.ParseMode.JAVA_WITH_COMMENTS);
115     }
116 
117     /**
118      * Test for opening a file with the "Open File" button.
119      * {@code JFileChooser} is mocked to prevent showing a modal dialog box.
120      *
121      * @throws IOException if I/O exception occurs while forming the path.
122      */
123     @Test
124     public void testOpenFileButton() throws IOException {
125         final JButton openFileButton = findComponentByName(mainFrame, "openFileButton");
126         final File testFile = new File(getPath(TEST_FILE_NAME));
127         try (MockedConstruction<JFileChooser> mocked = mockConstruction(
128                 JFileChooser.class, (mock, context) -> {
129                     when(mock.showOpenDialog(mainFrame)).thenReturn(JFileChooser.APPROVE_OPTION);
130                     when(mock.getSelectedFile()).thenReturn(testFile);
131                 })) {
132             openFileButton.doClick();
133         }
134         assertWithMessage("Unexpected frame title")
135                 .that(mainFrame.getTitle())
136                 .isEqualTo("Checkstyle GUI : " + TEST_FILE_NAME);
137     }
138 
139     /**
140      * Test for the {@link FileFilter} passed to {@code JFileChooser} to gain 100% coverage.
141      * {@code JFileChooser} is mocked to obtain an instance of {@code JavaFileFilter} class.
142      */
143     @Test
144     public void testFileFilter() {
145         final JButton openFileButton = findComponentByName(mainFrame, "openFileButton");
146         try (MockedConstruction<JFileChooser> mocked = mockConstruction(
147                 JFileChooser.class, (mock, context) -> {
148                     when(mock.showOpenDialog(mainFrame)).thenReturn(JFileChooser.CANCEL_OPTION);
149                     when(mock.getFileFilter()).thenCallRealMethod();
150                     doCallRealMethod().when(mock).setFileFilter(any(FileFilter.class));
151                 })) {
152             openFileButton.doClick();
153 
154             final FileFilter fileFilter = mocked.constructed().get(0).getFileFilter();
155             assertWithMessage("The file should be accepted")
156                     .that(fileFilter.accept(new File(TEST_FILE_NAME)))
157                     .isTrue();
158             assertWithMessage("Unexpected frame title")
159                     .that(fileFilter.getDescription())
160                     .isEqualTo("Java Source File");
161         }
162     }
163 
164     @Test
165     public void testExpandButton() {
166         final JButton expandButton = findComponentByName(mainFrame, "expandButton");
167         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
168         expandButton.doClick();
169         assertWithMessage("The XPath text area should be visible")
170                 .that(xpathTextArea.isVisible())
171                 .isTrue();
172         expandButton.doClick();
173         assertWithMessage("The XPath text area should be hidden")
174                 .that(xpathTextArea.isVisible())
175                 .isFalse();
176     }
177 
178     @Test
179     public void testFindNodeButton() throws IOException {
180         mainFrame.openFile(new File(getPath(TEST_FILE_NAME)));
181         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
182         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
183         findNodeButton.doClick();
184         assertWithMessage("Unexpected XPath text area text")
185                 .that(xpathTextArea.getText())
186                 .isEqualTo("No elements matching XPath query 'Xpath' found.");
187     }
188 
189 }