Skip to content
Snippets Groups Projects
Commit 4d8863d8 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Split fxml, controller and test

parent 4c06ce9e
Branches
Tags
No related merge requests found
Showing
with 439 additions and 299 deletions
...@@ -10,7 +10,7 @@ public class TodoApp extends Application { ...@@ -10,7 +10,7 @@ public class TodoApp extends Application {
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
Parent parent = FXMLLoader.load(getClass().getResource("Todo.fxml")); Parent parent = FXMLLoader.load(getClass().getResource("TodoModel.fxml"));
stage.setScene(new Scene(parent)); stage.setScene(new Scene(parent));
stage.show(); stage.show();
} }
......
...@@ -10,9 +10,9 @@ import todolist.core.TodoList; ...@@ -10,9 +10,9 @@ import todolist.core.TodoList;
public class TodoItemListCellDragHandler { public class TodoItemListCellDragHandler {
private final TodoList todoList; private TodoList todoList;
public TodoItemListCellDragHandler(TodoList todoList) { public void setTodoList(TodoList todoList) {
this.todoList = todoList; this.todoList = todoList;
} }
......
package todolist.ui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.util.Callback;
import todolist.core.TodoItem;
import todolist.core.TodoList;
import todolist.core.TodoListListener;
public class TodoListController {
@FXML
TextField newTodoItemText;
@FXML
ListView<TodoItem> todoItemsView;
@FXML
Button deleteTodoItemButton;
private Collection<Button> selectionButtons;
private TodoList todoList = null;
public TodoList getTodoList() {
return todoList;
}
/**
* Sets the TodoList managed by this controller.
* The corresponding views will be updated.
*
* @param todoList
*/
public void setTodoList(TodoList todoList) {
if (this.todoList != null) {
this.todoList.removeTodoListListener(todoListListener);
}
this.todoList = todoList;
dragHandler.setTodoList(todoList);
updateView();
if (this.todoList != null) {
this.todoList.addTodoListListener(todoListListener);
}
}
private Callback<TodoList, Void> onTodoListChangedCallback = null;
public void setOnTodoListChangedCallback(Callback<TodoList, Void> onTodoListChangedCallback) {
this.onTodoListChangedCallback = onTodoListChangedCallback;
}
private TodoListListener todoListListener = todoList -> {
if (onTodoListChangedCallback != null) {
onTodoListChangedCallback.call(getTodoList());
}
updateView();
};
private TodoItemListCellDragHandler dragHandler;
@FXML
void initialize() {
selectionButtons = List.of(deleteTodoItemButton);
dragHandler = new TodoItemListCellDragHandler();
todoItemsView.setCellFactory(listView -> {
TodoItemListCell listCell = new TodoItemListCell();
dragHandler.registerHandlers(listCell);
return listCell;
});
todoItemsView.getSelectionModel().selectedItemProperty()
.addListener((prop, oldValue, newValue) -> updateTodoListButtons());
todoItemsView.setEditable(true);
}
protected void updateView() {
List<TodoItem> items = new ArrayList<>();
if (todoList != null) {
items.addAll(getTodoList().getUncheckedTodoItems());
items.addAll(getTodoList().getCheckedTodoItems());
}
TodoItem selectedItem = todoItemsView.getSelectionModel().getSelectedItem();
todoItemsView.getItems().setAll(items);
// keep selection
if (selectedItem != null) {
todoItemsView.getSelectionModel().select(selectedItem);
}
newTodoItemText.setText(null);
updateTodoListButtons();
}
private void updateTodoListButtons() {
boolean disable = todoItemsView.getSelectionModel().getSelectedItem() == null;
for (Button button : selectionButtons) {
button.setDisable(disable);
}
// TODO in progress...
getRowLayoutY(todoItemsView, listCell -> isSelected(todoItemsView, listCell), 0);
// System.out.println(rowLayoutY);
}
private boolean isSelected(ListView<?> listView, ListCell<?> listCell) {
return isSelected(listView, listCell.getItem());
}
private boolean isSelected(ListView<?> listView, Object item) {
return todoItemsView.getSelectionModel().getSelectedItems().contains(item);
}
@SuppressWarnings("unchecked")
private <T> double getRowLayoutY(ListView<T> listView, Predicate<ListCell<T>> test, int num) {
for (Node child : listView.lookupAll(".list-cell")) {
if (child instanceof ListCell) {
ListCell<T> listCell = (ListCell<T>) child;
if (test.test(listCell) && num-- == 0) {
double dy = 0;
Node node = listCell;
while (node != todoItemsView) {
dy += node.getLayoutY();
node = node.getParent();
}
return dy;
}
}
}
return -1;
}
@FXML
void handleNewTodoItemAction() {
TodoItem item = getTodoList().createTodoItem();
item.setText(newTodoItemText.getText());
getTodoList().addTodoItem(item);
todoItemsView.getSelectionModel().select(item);
}
@FXML
void handleDeleteItemAction() {
int index = todoItemsView.getSelectionModel().getSelectedIndex();
TodoItem item = todoItemsView.getItems().get(index);
if (item != null) {
getTodoList().removeTodoItem(item);
selectWithinBounds(index);
}
}
private int selectWithinBounds(int index) {
int maxIndex = todoItemsView.getItems().size() - 1;
if (index > maxIndex) {
index = maxIndex;
}
if (index >= 0) {
todoItemsView.getSelectionModel().select(index);
return index;
}
return -1;
}
@FXML
void handleCheckItemAction() {
TodoItem item = todoItemsView.getSelectionModel().getSelectedItem();
if (item != null) {
// toggle checked flag
item.setChecked(! item.isChecked());
}
}
}
...@@ -12,24 +12,17 @@ import java.nio.charset.StandardCharsets; ...@@ -12,24 +12,17 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Predicate;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell; import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import todolist.core.TodoItem; import todolist.core.TodoItem;
import todolist.core.TodoList; import todolist.core.TodoList;
import todolist.core.TodoListListener;
import todolist.core.TodoModel; import todolist.core.TodoModel;
import todolist.json.TodoPersistence; import todolist.json.TodoPersistence;
public class TodoController { public class TodoModelController {
private static final String todoListWithTwoItems = private static final String todoListWithTwoItems =
"{\"lists\":[{\"name\":\"todo\",\"items\":[{\"text\":\"item1\",\"checked\":false},{\"text\":\"item2\",\"checked\":true,\"deadline\":\"2020-10-01T14:53:11\"}]}]}"; "{\"lists\":[{\"name\":\"todo\",\"items\":[{\"text\":\"item1\",\"checked\":false},{\"text\":\"item2\",\"checked\":true,\"deadline\":\"2020-10-01T14:53:11\"}]}]}";
...@@ -48,13 +41,7 @@ public class TodoController { ...@@ -48,13 +41,7 @@ public class TodoController {
ComboBox<TodoList> todoListsView; ComboBox<TodoList> todoListsView;
@FXML @FXML
TextField newTodoItemText; TodoListController todoListViewController;
@FXML
ListView<TodoItem> todoItemsView;
@FXML
Button deleteTodoItemButton;
private void initializeTodoModel() { private void initializeTodoModel() {
// setter opp data // setter opp data
...@@ -105,15 +92,15 @@ public class TodoController { ...@@ -105,15 +92,15 @@ public class TodoController {
} }
} }
private Collection<Button> selectionButtons;
@FXML @FXML
void initialize() { void initialize() {
initializeTodoModel(); initializeTodoModel();
selectionButtons = List.of(deleteTodoItemButton);
// kobler data til list-controll // kobler data til list-controll
initializeTodoListsView(); initializeTodoListsView();
initializeTodoItemsView(); todoListViewController.setOnTodoListChangedCallback(todoList -> {
autoSaveTodoList();
return null;
});
updateTodoListsView(null); updateTodoListsView(null);
} }
...@@ -135,10 +122,12 @@ public class TodoController { ...@@ -135,10 +122,12 @@ public class TodoController {
return listCell; return listCell;
}); });
todoListsView.setConverter(new StringConverter<TodoList>() { todoListsView.setConverter(new StringConverter<TodoList>() {
@Override @Override
public String toString(TodoList todoList) { public String toString(TodoList todoList) {
return todoList.getName(); return (todoList != null ? todoList.getName() : "???");
} }
@Override @Override
public TodoList fromString(String newName) { public TodoList fromString(String newName) {
TodoList todoList = new TodoList(); // getTodoList() TodoList todoList = new TodoList(); // getTodoList()
...@@ -163,10 +152,14 @@ public class TodoController { ...@@ -163,10 +152,14 @@ public class TodoController {
} }
}); });
todoListsView.getSelectionModel().selectedItemProperty().addListener((prop, oldTodoList, newTodoList) -> { todoListsView.getSelectionModel().selectedItemProperty().addListener((prop, oldTodoList, newTodoList) -> {
updateTodoItemsView(); todoListViewController.setTodoList(getSelectedTodoList());
}); });
} }
TodoList getSelectedTodoList() {
return todoListsView.getSelectionModel().getSelectedItem();
}
protected void updateTodoListsView(TodoList newSelection) { protected void updateTodoListsView(TodoList newSelection) {
List<TodoList> items = new ArrayList<>(); List<TodoList> items = new ArrayList<>();
// dummy element used for creating new ones, with null name // dummy element used for creating new ones, with null name
...@@ -178,129 +171,6 @@ public class TodoController { ...@@ -178,129 +171,6 @@ public class TodoController {
} else { } else {
todoListsView.getSelectionModel().select(todoListsView.getItems().size() > 1 ? 1 : 0); todoListsView.getSelectionModel().select(todoListsView.getItems().size() > 1 ? 1 : 0);
} }
System.out.println("TodoLists: " + todoListsView.getItems());
}
private TodoListListener todoListListener = todoList -> {
autoSaveTodoList();
updateTodoItemsView();
};
// makes class more testable
TodoList getSelectedTodoList() {
return todoListsView.getValue();
}
private void initializeTodoItemsView() {
TodoItemListCellDragHandler dragHandler = new TodoItemListCellDragHandler(getSelectedTodoList());
todoItemsView.setCellFactory(listView -> {
TodoItemListCell listCell = new TodoItemListCell();
dragHandler.registerHandlers(listCell);
return listCell;
});
todoItemsView.getSelectionModel().selectedItemProperty()
.addListener((prop, oldValue, newValue) -> updateTodoListButtons());
todoItemsView.setEditable(true);
}
private TodoList currenTodoList = null;
protected void updateTodoItemsView() {
if (currenTodoList != null) {
currenTodoList.removeTodoListListener(todoListListener);
}
List<TodoItem> items = new ArrayList<>();
currenTodoList = getSelectedTodoList();
if (currenTodoList != null) {
items.addAll(getSelectedTodoList().getUncheckedTodoItems());
items.addAll(getSelectedTodoList().getCheckedTodoItems());
}
TodoItem selectedItem = todoItemsView.getSelectionModel().getSelectedItem();
todoItemsView.getItems().setAll(items);
if (currenTodoList != null) {
currenTodoList.addTodoListListener(todoListListener);
}
// keep selection
if (selectedItem != null) {
todoItemsView.getSelectionModel().select(selectedItem);
}
newTodoItemText.setText(null);
}
private void updateTodoListButtons() {
boolean disable = todoItemsView.getSelectionModel().getSelectedItem() == null;
for (Button button : selectionButtons) {
button.setDisable(disable);
}
// TODO in progress...
getRowLayoutY(todoItemsView, listCell -> isSelected(todoItemsView, listCell), 0);
// System.out.println(rowLayoutY);
}
private boolean isSelected(ListView<?> listView, ListCell<?> listCell) {
return isSelected(listView, listCell.getItem());
}
private boolean isSelected(ListView<?> listView, Object item) {
return todoItemsView.getSelectionModel().getSelectedItems().contains(item);
}
@SuppressWarnings("unchecked")
private <T> double getRowLayoutY(ListView<T> listView, Predicate<ListCell<T>> test, int num) {
for (Node child : listView.lookupAll(".list-cell")) {
if (child instanceof ListCell) {
ListCell<T> listCell = (ListCell<T>) child;
if (test.test(listCell) && num-- == 0) {
double dy = 0;
Node node = listCell;
while (node != todoItemsView) {
dy += node.getLayoutY();
node = node.getParent();
}
return dy;
}
}
}
return -1;
}
@FXML
void handleNewTodoItemAction() {
TodoItem item = getSelectedTodoList().createTodoItem();
item.setText(newTodoItemText.getText());
getSelectedTodoList().addTodoItem(item);
todoItemsView.getSelectionModel().select(item);
}
@FXML
void handleDeleteItemAction() {
int index = todoItemsView.getSelectionModel().getSelectedIndex();
TodoItem item = todoItemsView.getItems().get(index);
if (item != null) {
getSelectedTodoList().removeTodoItem(item);
selectWithinBounds(index);
}
}
private int selectWithinBounds(int index) {
int maxIndex = todoItemsView.getItems().size() - 1;
if (index > maxIndex) {
index = maxIndex;
}
if (index >= 0) {
todoItemsView.getSelectionModel().select(index);
return index;
}
return -1;
}
@FXML
void handleCheckItemAction() {
TodoItem item = todoItemsView.getSelectionModel().getSelectedItem();
if (item != null) {
// toggle checked flag
item.setChecked(! item.isChecked());
}
} }
void autoSaveTodoList() { void autoSaveTodoList() {
......
...@@ -11,14 +11,7 @@ ...@@ -11,14 +11,7 @@
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?> <?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoController"> <VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoListController">
<fx:define>
<String fx:id="userTodoListPath" fx:value="todolist.json"/>
<String fx:id="sampleTodoListResource" fx:value="sample-todolist.json"/>
</fx:define>
<HBox>
<ComboBox fx:id="todoListsView"/>
</HBox>
<HBox> <HBox>
<Button fx:id="newTodoItemButton" onAction="#handleNewTodoItemAction"> <Button fx:id="newTodoItemButton" onAction="#handleNewTodoItemAction">
<graphic> <graphic>
......
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ListView?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoModelController">
<fx:define>
<String fx:id="userTodoListPath" fx:value="todolist.json"/>
<String fx:id="sampleTodoListResource" fx:value="sample-todomodel.json"/>
</fx:define>
<HBox>
<ComboBox fx:id="todoListsView"/>
</HBox>
<fx:include fx:id="todoListView" source="TodoList.fxml"/>
</VBox>
package todolist.ui; package todolist.ui;
import java.util.function.Predicate;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage; import javafx.stage.Stage;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.testfx.framework.junit5.ApplicationTest; import org.testfx.framework.junit5.ApplicationTest;
import todolist.core.TodoItem;
import todolist.core.TodoList;
public class TodoAppTest extends ApplicationTest { public class TodoAppTest extends ApplicationTest {
private TodoController controller; private TodoModelController controller;
private TodoList todoList;
private TodoItem item1, item2;
@Override @Override
public void start(final Stage stage) throws Exception { public void start(final Stage stage) throws Exception {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("TodoTest.fxml")); final FXMLLoader loader = new FXMLLoader(getClass().getResource("TodoModel_test.fxml"));
final Parent root = loader.load(); final Parent root = loader.load();
this.controller = loader.getController(); this.controller = loader.getController();
this.todoList = this.controller.getSelectedTodoList();
stage.setScene(new Scene(root)); stage.setScene(new Scene(root));
stage.show(); stage.show();
} }
...@@ -36,130 +25,15 @@ public class TodoAppTest extends ApplicationTest { ...@@ -36,130 +25,15 @@ public class TodoAppTest extends ApplicationTest {
@BeforeEach @BeforeEach
public void setupItems() { public void setupItems() {
// same as in test-todolist.json (should perhaps read it instead) // same as in test-todolist.json (should perhaps read it instead)
item1 = new TodoItem().checked(true).text("Item 1");
item2 = new TodoItem().checked(false).text("Item 2");
} }
@Test @Test
public void testController_todoList() { public void testController_initial() {
assertNotNull(this.controller); assertNotNull(this.controller);
assertNotNull(this.todoList);
// initial todo items
checkTodoItems(this.todoList, item1, item2);
} }
@Test @Test
public void testTodoListView_initialItems() { public void testSelectedTodoList_initial() {
final ListView<TodoItem> todoListView = lookup("#todoItemsView").query(); assertNotNull(this.controller.getSelectedTodoList());
// initial todo items, note the unchecked one comes first
checkTodoItems(todoListView.getItems(), item2, item1);
}
@Test
public void testNewTodoItem() {
String newItemText = "New item";
clickOn("#newTodoItemText").write(newItemText);
clickOn("#newTodoItemButton");
TodoItem newItem = new TodoItem().text(newItemText);
// item is added last in underlying todo list
checkTodoListItems(item1, item2, newItem);
// item is last of the unchecked items in list view
checkTodoListViewItems(item2, newItem, item1);
// check element is selected
checkSelectedTodoItem(1);
}
@Test
public void testDeleteTodoItem() {
// final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
// todoListView.getSelectionModel().select(1);
TodoItemListCell todoItemListCell = findTodoItemListCell(1);
clickOn(todoItemListCell.lookup(".label"));
clickOn("#deleteTodoItemButton");
// item2 is removed, only item1 is left
checkTodoListItems(item1);
// item2 is removed, only item1 is left
checkTodoListViewItems(item1);
// check remaining item is selected
checkSelectedTodoItem(0);
}
@Test
public void testCheckTodoItemListCell() {
TodoItemListCell todoItemListCell = findTodoItemListCell(cell -> ! cell.getItem().isChecked());
clickOn(todoItemListCell.lookup(".check-box"));
TodoItem newItem2 = item2.withChecked(true);
// item is changed
checkTodoListItems(item1, newItem2);
// items in list view change order
checkTodoListViewItems(item1, newItem2);
}
@Test
public void testDragTodoItem() {
TodoItemListCell sourceTodoItemListCell = findTodoItemListCell(0);
TodoItemListCell targetTodoItemListCell = findTodoItemListCell(1);
drag(sourceTodoItemListCell).dropTo(targetTodoItemListCell);
// item order is changed
checkTodoListItems(item2, item1);
// items in list view do not change order
checkTodoListViewItems(item1, item2);
}
// utility methods
private TodoItemListCell findTodoItemListCell(int num) {
return findTodoItemListCell(cell -> true, num);
}
private TodoItemListCell findTodoItemListCell(Predicate<TodoItemListCell> test) {
return findTodoItemListCell(test, 0);
}
private TodoItemListCell findTodoItemListCell(Predicate<TodoItemListCell> test, int num) {
for (Node node : lookup(".list-cell").queryAll()) {
if (node instanceof TodoItemListCell) {
TodoItemListCell todoItemListCell = (TodoItemListCell) node;
if (test.test(todoItemListCell) && num-- == 0) {
return todoItemListCell;
}
}
}
fail();
return null;
}
private void checkTodoItem(TodoItem item, Boolean checked, String text) {
if (checked != null) {
assertEquals(checked, item.isChecked());
}
if (text != null) {
assertEquals(text, item.getText());
}
}
private void checkTodoListItems(TodoItem... items) {
checkTodoItems(this.todoList, items);
}
private void checkTodoListViewItems(TodoItem... items) {
final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
checkTodoItems(todoListView.getItems(), items);
}
private void checkTodoItems(Iterable<TodoItem> it, TodoItem... items) {
int i = 0;
for (TodoItem item : items) {
assertTrue(i < items.length);
checkTodoItem(item, items[i].isChecked(), items[i].getText());
i++;
}
assertTrue(i == items.length);
}
private void checkSelectedTodoItem(int index) {
final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
assertEquals(index, todoListView.getSelectionModel().getSelectedIndex());
} }
} }
package todolist.ui;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Predicate;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testfx.framework.junit5.ApplicationTest;
import todolist.core.TodoItem;
import todolist.core.TodoList;
import todolist.core.TodoModel;
import todolist.json.TodoPersistence;
public class TodoListControllerTest extends ApplicationTest {
private TodoListController controller;
@Override
public void start(final Stage stage) throws Exception {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("TodoList_test.fxml"));
final Parent root = loader.load();
this.controller = loader.getController();
stage.setScene(new Scene(root));
stage.show();
}
private TodoPersistence todoPersistence = new TodoPersistence();
private TodoList todoList;
private TodoItem item1, item2;
@BeforeEach
public void setupItems() {
TodoModel todoModel = null;
try {
todoModel =
todoPersistence.readTodoModel(new InputStreamReader(getClass().getResourceAsStream("test-todomodel.json")));
} catch (IOException e) {
fail("Couldn't load test-todomodel.json");
}
assertNotNull(todoModel);
assertTrue(todoModel.iterator().hasNext());
this.todoList = todoModel.iterator().next();
this.controller.setTodoList(this.todoList);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// ignore
}
// same as in test-todomodel.json
Iterator<TodoItem> todoItems = todoList.iterator();
item1 = new TodoItem().as(todoItems.next());
item2 = new TodoItem().as(todoItems.next());
}
@Test
public void testController_todoList() {
assertNotNull(this.controller);
assertNotNull(this.todoList);
// initial todo items
checkTodoItems(this.todoList, item1, item2);
}
@Test
public void testTodoListView_initialItems() {
final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
// initial todo items, note the unchecked one comes first
checkTodoItems(todoListView.getItems(), item2, item1);
}
@Test
public void testNewTodoItem() {
String newItemText = "New item";
clickOn("#newTodoItemText").write(newItemText);
clickOn("#newTodoItemButton");
TodoItem newItem = new TodoItem().text(newItemText);
// item is added last in underlying todo list
checkTodoListItems(item1, item2, newItem);
// item is last of the unchecked items in list view
checkTodoListViewItems(item2, newItem, item1);
// check element is selected
checkSelectedTodoItem(1);
}
@Test
public void testDeleteTodoItem() {
// final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
// todoListView.getSelectionModel().select(1);
TodoItemListCell todoItemListCell = findTodoItemListCell(1);
clickOn(todoItemListCell.lookup(".label"));
clickOn("#deleteTodoItemButton");
// item2 is removed, only item1 is left
checkTodoListItems(item1);
// item2 is removed, only item1 is left
checkTodoListViewItems(item1);
// check remaining item is selected
checkSelectedTodoItem(0);
}
@Test
public void testCheckTodoItemListCell() {
TodoItemListCell todoItemListCell = findTodoItemListCell(cell -> ! cell.getItem().isChecked());
clickOn(todoItemListCell.lookup(".check-box"));
TodoItem newItem2 = item2.withChecked(true);
// item is changed
checkTodoListItems(item1, newItem2);
// items in list view change order
checkTodoListViewItems(item1, newItem2);
}
@Test
public void testDragTodoItem() {
TodoItemListCell sourceTodoItemListCell = findTodoItemListCell(0);
TodoItemListCell targetTodoItemListCell = findTodoItemListCell(1);
drag(sourceTodoItemListCell).dropTo(targetTodoItemListCell);
// item order is changed
checkTodoListItems(item2, item1);
// items in list view do not change order
checkTodoListViewItems(item1, item2);
}
// utility methods
private TodoItemListCell findTodoItemListCell(int num) {
return findTodoItemListCell(cell -> true, num);
}
private TodoItemListCell findTodoItemListCell(Predicate<TodoItemListCell> test) {
return findTodoItemListCell(test, 0);
}
private TodoItemListCell findTodoItemListCell(Predicate<TodoItemListCell> test, int num) {
Collection<Node> nodes = lookup(node -> node instanceof TodoItemListCell).queryAll(); // ".list-cell").queryAll();
for (Node node : nodes) {
if (node instanceof TodoItemListCell) {
TodoItemListCell todoItemListCell = (TodoItemListCell) node;
if (test.test(todoItemListCell) && num-- == 0) {
return todoItemListCell;
}
}
}
fail("Didn't find TodoItemListCell #" + num + " in " + nodes);
return null;
}
private void checkTodoItem(TodoItem item, Boolean checked, String text) {
if (checked != null) {
assertEquals(checked, item.isChecked());
}
if (text != null) {
assertEquals(text, item.getText());
}
}
private void checkTodoListItems(TodoItem... items) {
checkTodoItems(this.todoList, items);
}
private void checkTodoListViewItems(TodoItem... items) {
ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
checkTodoItems(todoListView.getItems(), items);
}
private void checkTodoItems(Iterable<TodoItem> it, TodoItem... items) {
int i = 0;
for (TodoItem item : items) {
assertTrue(i < items.length);
checkTodoItem(item, items[i].isChecked(), items[i].getText());
i++;
}
assertTrue(i == items.length);
}
private void checkSelectedTodoItem(int index) {
final ListView<TodoItem> todoListView = lookup("#todoItemsView").query();
assertEquals(index, todoListView.getSelectionModel().getSelectedIndex());
}
}
...@@ -3,21 +3,11 @@ ...@@ -3,21 +3,11 @@
<?import java.lang.String?> <?import java.lang.String?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?> <?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ListView?> <?import javafx.scene.control.ListView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoController"> <VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoListController">
<fx:define>
<!--
<String fx:id="todoListUserHomePath" fx:value="todolist.json"/>
-->
<String fx:id="sampleTodoListResource" fx:value="test-todolist.json"/>
</fx:define>
<HBox>
<ComboBox fx:id="todoListsView"/>
</HBox>
<HBox> <HBox>
<Button fx:id="newTodoItemButton" text="New Item" onAction="#handleNewTodoItemAction"/> <Button fx:id="newTodoItemButton" text="New Item" onAction="#handleNewTodoItemAction"/>
<TextField fx:id="newTodoItemText" promptText="Skriv inn tekst her" onAction="#handleNewTodoItemAction"/> <TextField fx:id="newTodoItemText" promptText="Skriv inn tekst her" onAction="#handleNewTodoItemAction"/>
......
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ListView?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="todolist.ui.TodoModelController">
<fx:define>
<!--
<String fx:id="userTodoListPath" fx:value="todolist.json"/>
-->
<String fx:id="sampleTodoListResource" fx:value="test-todolist.json"/>
</fx:define>
<HBox>
<ComboBox fx:id="todoListsView"/>
</HBox>
<fx:include fx:id="todoListView" source="TodoList_test.fxml"/>
</VBox>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment