Test fixes

This commit is contained in:
dragonmacher 2024-11-19 18:07:54 -05:00
parent 9421ec0ab0
commit ac22ed69f2
5 changed files with 112 additions and 207 deletions

View File

@ -4,9 +4,9 @@
* 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.
@ -207,8 +207,7 @@ public class StructureEditorUnlockedCellEdit2Test extends AbstractStructureEdito
assertEquals(model.getDataTypeColumn(), model.getColumn());
// Bad value allows escape.
escape();
escape();
escape(); // cancel editing
waitForSwing();
assertTrue(!model.isEditingField());
assertEquals(1, model.getNumSelectedRows());

View File

@ -4,9 +4,9 @@
* 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.
@ -19,7 +19,6 @@ import static org.junit.Assert.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.Set;
import javax.swing.JTable;
import javax.swing.JTextField;
@ -27,8 +26,6 @@ import javax.swing.table.TableModel;
import org.junit.*;
import docking.ActionContext;
import docking.DefaultActionContext;
import docking.action.DockingActionIf;
import ghidra.app.cmd.memory.*;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
@ -93,58 +90,6 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
assertTrue(action.isEnabled());
}
@Test
public void testOpenProgram() throws Exception {
env.close(program);
program = buildProgram("sdk");
env.open(program);
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) {
String name = action.getName();
if (name.equals("Add Block") || name.equals("Set Image Base") ||
name.equals("Memory Map") || name.equals("Close Window") ||
name.contains("Table")) {
assertActionEnabled(action, getActionContext(), true);
}
else {
assertActionEnabled(action, getActionContext(), false);
}
}
}
@Test
public void testCloseProgram() {
env.close(program);
JTable table = provider.getTable();
assertEquals(0, table.getModel().getRowCount());
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) {
String name = action.getName();
if (name.equals("Memory Map") || name.equals("Close Window") ||
name.equals("Local Menu")) {
continue;
}
assertActionEnabled(action, getActionContext(), false);
}
}
private void assertActionEnabled(DockingActionIf action, ActionContext context,
boolean shouldBeEnabled) {
String text = shouldBeEnabled ? "should be enabled" : "should be disabled";
assertEquals("Action " + text + ", but is not: '" + action.getFullName() + "'",
shouldBeEnabled, action.isEnabledForContext(context));
}
private ActionContext getActionContext() {
ActionContext context = provider.getActionContext(null);
if (context == null) {
return new DefaultActionContext();
}
return context;
}
@Test
public void testBlockNameChanged() throws Exception {
MemoryBlock block = memory.getBlock(program.getMinAddress());

View File

@ -4,9 +4,9 @@
* 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.
@ -124,29 +124,6 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest
}
}
@Test
public void testMultiSelection() {
table.addRowSelectionInterval(0, 1);
assertEquals(2, table.getSelectedRowCount());
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
for (DockingActionIf action : actions) {
String name = action.getName();
if (name.equals("Add Block") || name.equals("Merge Blocks") ||
name.equals("Delete Block") || name.equals("Set Image Base") ||
name.equals("Memory Map") || name.equals("Close Window") ||
name.equals("Make Selection")) {
assertTrue("Action should be enabled for a multi-row selection - '" + name + "'",
action.isEnabled());
}
else {
assertFalse(
"Action should not be enabled for a multi-row selection - '" + name + "'",
action.isEnabled());
}
}
}
@Test
public void testGoToAddress() {
Rectangle rect = table.getCellRect(2, MemoryMapModel.START, true);

View File

@ -4,9 +4,9 @@
* 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.
@ -177,79 +177,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
return previewLabel;
}
// overridden to grab the Escape and enter key events before our parent window gets them
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if (handleEscapeKey(ks, e, condition, pressed)) {
return true;
}
if (handleEnterKey(ks, e, condition, pressed)) {
return true;
}
return super.processKeyBinding(ks, e, condition, pressed);
}
private boolean handleEscapeKey(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if ((condition == JComponent.WHEN_FOCUSED) && (ks.getKeyCode() == KeyEvent.VK_ESCAPE)) {
if (getMatchingWindow().isShowing()) {
hideMatchingWindow();
e.consume();
return true;
}
else if (pressed) {
// do not return after this call so that the event will continue to be processed
fireEditingCancelled();
}
}
return false;
}
private boolean handleEnterKey(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
if ((condition != JComponent.WHEN_FOCUSED) || (ks.getKeyCode() != KeyEvent.VK_ENTER)) {
return false; // enter key not pressed!
}
if (ignoreEnterKeyPress) {
return false;
}
// O.K., if we are consuming key presses, then we only want to do so when the selection
// window is showing. This will close the selection window and not send the Enter event up
// to our parent component.
boolean listShowing = isMatchingListShowing();
if (consumeEnterKeyPress) {
if (listShowing) {
setTextFromListOnEnterPress();
validateChosenItemAgainstText(true);
e.consume();
return true; // don't let our parent see the event
}
else if (pressed) {
validateChosenItemAgainstText(false);
fireEditingStopped();
}
// Return false, even though 'consumeEnterKeyPress' is set, so that our
// parent can process the event.
return false;
}
// When we aren't consuming Enter key presses, then we just take the user's selection
// and signal that editing is finished, while letting our parent component handle the event
if (pressed) {
setTextFromListOnEnterPress();
validateChosenItemAgainstText(listShowing);
fireEditingStopped();
return true;
}
return false;
}
private void validateChosenItemAgainstText(boolean isListShowing) {
//
// If the text differs from that of the chosen item, then the implication is the user has
@ -884,62 +811,117 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
KeyEvent.VK_KP_DOWN)) {
//@formatter:on
if (!getMatchingWindow().isShowing()) {
updateDisplayContents(getText());
event.consume();
}
else { // update the window if it is showing
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_KP_UP) {
decrementListSelection();
}
else {
incrementListSelection();
}
event.consume();
setTextFromSelectedListItemAndKeepMatchingWindowOpen();
}
handleArrowKey(event);
}
else if (keyCode == KeyEvent.VK_ENTER) {
handleEnterKey(event);
}
else if (keyCode == KeyEvent.VK_ESCAPE) {
handleEscapeKey(event);
}
setToolTipText(getToolTipText());
}
private void incrementListSelection() {
int index = list.getSelectedIndex();
int listSize = list.getModel().getSize();
if (index < 0) { // no selection
index = 0;
private void handleEscapeKey(KeyEvent event) {
if (getMatchingWindow().isShowing()) {
hideMatchingWindow();
}
else if (index == listSize - 1) { // last element selected - wrap
index = 0;
else {
fireEditingCancelled();
}
else { // just increment
index++;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
event.consume();
}
private void decrementListSelection() {
int index = list.getSelectedIndex();
int listSize = list.getModel().getSize();
private void handleEnterKey(KeyEvent event) {
if (index < 0) { // no selection
index = 0;
}
else if (index == 0) { // first element - wrap
index = listSize - 1;
}
else { // just decrement
index--;
if (ignoreEnterKeyPress) {
return;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
// O.K., if we are consuming key presses, then we only want to do so when the selection
// window is showing. This will close the selection window and not send the Enter event up
// to our parent component.
boolean listShowing = isMatchingListShowing();
if (consumeEnterKeyPress) {
if (listShowing) {
setTextFromListOnEnterPress();
validateChosenItemAgainstText(true);
event.consume();
return; // don't let our parent see the event
}
validateChosenItemAgainstText(false);
fireEditingStopped();
// Even though 'consumeEnterKeyPress' is set, do not consume the event so that our
// parent can process the event.
return;
}
// When we aren't consuming Enter key presses, then just take the user's selection and
// signal that editing is finished, while letting our parent component handle the event
setTextFromListOnEnterPress();
validateChosenItemAgainstText(listShowing);
fireEditingStopped();
}
}
private void handleArrowKey(KeyEvent event) {
int keyCode = event.getKeyCode();
if (!getMatchingWindow().isShowing()) {
updateDisplayContents(getText());
event.consume();
}
else { // update the window if it is showing
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_KP_UP) {
decrementListSelection();
}
else {
incrementListSelection();
}
event.consume();
setTextFromSelectedListItemAndKeepMatchingWindowOpen();
}
}
private void incrementListSelection() {
int index = list.getSelectedIndex();
int listSize = list.getModel().getSize();
if (index < 0) { // no selection
index = 0;
}
else if (index == listSize - 1) { // last element selected - wrap
index = 0;
}
else { // just increment
index++;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
private void decrementListSelection() {
int index = list.getSelectedIndex();
int listSize = list.getModel().getSize();
if (index < 0) { // no selection
index = 0;
}
else if (index == 0) { // first element - wrap
index = listSize - 1;
}
else { // just decrement
index--;
}
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
// we know the cast is safe because we put the items in the list
protected void setTextFromSelectedListItemAndKeepMatchingWindowOpen() {
T selectedItem = list.getSelectedValue();

View File

@ -4,9 +4,9 @@
* 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.
@ -245,10 +245,12 @@ public abstract class AbstractSortedTableModel<T> extends AbstractGTableModel<T>
protected TableSortingContext<T> createSortingContext(TableSortState newSortState) {
if (!isValidSortState(newSortState)) {
Msg.error(this, """
"Table '%s' sort is invalid. Assuming columns have been removed. \
Setting unsorted.""".formatted(getName()));
newSortState = TableSortState.createUnsortedSortState();
if (!isDisposed) {
Msg.error(this, """
"Table '%s' sort is invalid. Assuming columns have been removed. \
Setting unsorted.""".formatted(getName()));
}
}
return new TableSortingContext<>(newSortState, getComparatorChain(newSortState));