From 069a9154cbf289b4ae49c214f16bbfc6704004a3 Mon Sep 17 00:00:00 2001 From: ThomasEvans Date: Fri, 3 Dec 2021 15:47:48 -0700 Subject: [PATCH] Added tests/testfx, Jacoco, and Lombok. --- app/build.gradle | 37 ++++++++-- .../main/java/edu/isu/cs/cs2263/hw02/App.java | 11 ++- .../edu/isu/cs/cs2263/hw02/data/Course.java | 39 ++-------- .../edu/isu/cs/cs2263/hw02/views/AppView.java | 7 +- .../cs/cs2263/hw02/views/CoursesFormView.java | 4 + .../java/edu/isu/cs/cs2263/hw02/AppTest.java | 74 +++++++++++++++++++ .../edu/isu/cs/cs2263/hw02/CourseTest.java | 65 ++++++++++++++++ 7 files changed, 189 insertions(+), 48 deletions(-) create mode 100644 app/src/test/java/edu/isu/cs/cs2263/hw02/AppTest.java create mode 100644 app/src/test/java/edu/isu/cs/cs2263/hw02/CourseTest.java diff --git a/app/build.gradle b/app/build.gradle index db1cfb6..a29225d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,6 +10,8 @@ plugins { // Apply the application plugin to add support for building a CLI application in Java. id 'application' id 'org.openjfx.javafxplugin' version '0.0.9' + id "io.freefair.lombok" version "6.3.0" + id 'jacoco' } repositories { @@ -19,11 +21,12 @@ repositories { } dependencies { - // Use JUnit Jupiter API for testing. - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' + implementation 'org.junit.jupiter:junit-jupiter:5.7.0' + implementation 'org.junit.jupiter:junit-jupiter:5.7.0' - // Use JUnit Jupiter Engine for testing. - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + // Use JUnit Jupiter API for testing. + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1' // This dependency is used by the application. implementation 'com.google.guava:guava:29.0-jre' @@ -33,6 +36,13 @@ dependencies { implementation 'org.kordamp.ikonli:ikonli-fontawesome5-pack:12.1.0' implementation 'org.kordamp.ikonli:ikonli-materialdesign2-pack:12.1.0' implementation 'org.kordamp.ikonli:ikonli-material2-pack:12.1.0' + + //testfx + implementation 'org.testfx:testfx-core:4.0.16-alpha' + implementation 'org.testfx:testfx-junit5:4.0.16-alpha' + + //log4j2 + implementation group: 'org.apache.logging.log4j', name: 'log4j', version: '2.8.2', ext: 'pom' } application { @@ -40,11 +50,26 @@ application { mainClass = 'edu.isu.cs.cs2263.hw02.App' } -tasks.named('test') { - // Use junit platform for unit tests. +test { useJUnitPlatform() + finalizedBy jacocoTestReport } +jacocoTestReport { + dependsOn test // tests are required to run before generating the report + reports { + xml.required = false + csv.required = false + html.outputLocation = layout.buildDirectory.dir('jacocoHtml') + } +} + +jacoco { + toolVersion = "0.8.7" + reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir') +} + + javafx { version = "17" modules = ['javafx.controls'] diff --git a/app/src/main/java/edu/isu/cs/cs2263/hw02/App.java b/app/src/main/java/edu/isu/cs/cs2263/hw02/App.java index 0699d74..0cf7b74 100644 --- a/app/src/main/java/edu/isu/cs/cs2263/hw02/App.java +++ b/app/src/main/java/edu/isu/cs/cs2263/hw02/App.java @@ -17,6 +17,8 @@ import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.stage.Stage; +import lombok.Getter; +import lombok.Setter; import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.materialdesign2.MaterialDesignF; import org.kordamp.ikonli.materialdesign2.MaterialDesignP; @@ -27,6 +29,7 @@ public class App extends Application { + @Getter @Setter private Vector courses; private AppView currentView; private final Map views; @@ -64,24 +67,28 @@ public void start(Stage primaryStage) throws Exception { primaryStage.setTitle("Course View"); Button display = new Button("Display (dept.)"); + display.setId("displayDepts"); display.setOnAction(event -> { displayList(); }); display.setGraphic(FontIcon.of(MaterialDesignF.FORMAT_LIST_TEXT, 20)); Button newCourse = new Button("New Course"); + newCourse.setId("newCourse"); newCourse.setOnAction(event -> { showCourseForm(); }); newCourse.setGraphic(FontIcon.of(MaterialDesignP.PLAYLIST_PLUS, 20)); Button exit = new Button("Exit"); + exit.setId("exit"); exit.setOnAction(event -> { exit(); }); exit.setGraphic(FontIcon.of(MaterialDesignP.POWER, 20)); depts = new ChoiceBox<>(); + depts.setId("dropDown"); depts.setOnAction(event -> { int selectedIndex = depts.getSelectionModel().getSelectedIndex(); // update the display button @@ -126,10 +133,6 @@ public void start(Stage primaryStage) throws Exception { primaryStage.show(); } - public Vector getCourses() { - return courses; - } - private void setView(String viewName) { mainLayout.getChildren().remove(currentView.getView()); currentView = views.get(viewName); diff --git a/app/src/main/java/edu/isu/cs/cs2263/hw02/data/Course.java b/app/src/main/java/edu/isu/cs/cs2263/hw02/data/Course.java index 42dbb63..2997ac8 100644 --- a/app/src/main/java/edu/isu/cs/cs2263/hw02/data/Course.java +++ b/app/src/main/java/edu/isu/cs/cs2263/hw02/data/Course.java @@ -1,5 +1,10 @@ package edu.isu.cs.cs2263.hw02.data; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter @Setter public class Course { public static final String[] CODES = { "CS", "CHEM", "PHYS", "MATH", "BTNY", "ZOO" }; @@ -10,8 +15,6 @@ public class Course { private int credits; private String code; - public Course() {} - public Course(String name, String code, int number, int credits) { this.name = name; this.code = code; @@ -19,38 +22,6 @@ public Course(String name, String code, int number, int credits) { this.credits = credits; } - public int getNumber() { - return number; - } - - public void setNumber(int number) { - this.number = number; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getCredits() { - return credits; - } - - public void setCredits(int credits) { - this.credits = credits; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - @Override public String toString() { return String.format("%s %d %s (%d)", code, number, name, credits); diff --git a/app/src/main/java/edu/isu/cs/cs2263/hw02/views/AppView.java b/app/src/main/java/edu/isu/cs/cs2263/hw02/views/AppView.java index d2c3758..2855080 100644 --- a/app/src/main/java/edu/isu/cs/cs2263/hw02/views/AppView.java +++ b/app/src/main/java/edu/isu/cs/cs2263/hw02/views/AppView.java @@ -2,9 +2,12 @@ import edu.isu.cs.cs2263.hw02.App; import javafx.scene.Node; +import lombok.Getter; +import lombok.Setter; public abstract class AppView implements IAppView { + @Getter @Setter protected Node view; protected App parent; @@ -12,8 +15,4 @@ public AppView(App parent) { this.parent = parent; initView(); } - - public Node getView() { - return view; - } } diff --git a/app/src/main/java/edu/isu/cs/cs2263/hw02/views/CoursesFormView.java b/app/src/main/java/edu/isu/cs/cs2263/hw02/views/CoursesFormView.java index 201e2e5..25c5a21 100644 --- a/app/src/main/java/edu/isu/cs/cs2263/hw02/views/CoursesFormView.java +++ b/app/src/main/java/edu/isu/cs/cs2263/hw02/views/CoursesFormView.java @@ -15,12 +15,15 @@ import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.TextAlignment; +import lombok.Getter; +import lombok.Setter; import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.materialdesign2.MaterialDesignP; import org.kordamp.ikonli.materialdesign2.MaterialDesignR; public class CoursesFormView extends AppView { + @Getter @Setter private TextField tfName; private Spinner spnNumber; private Spinner spnCredits; @@ -38,6 +41,7 @@ public void initView() { tfName = new TextField(); tfName.setPromptText("Enter a course name..."); tfName.setMinWidth(400); + tfName.setId("newName"); Label lblName = new Label("Name:"); lblName.setTextAlignment(TextAlignment.RIGHT); diff --git a/app/src/test/java/edu/isu/cs/cs2263/hw02/AppTest.java b/app/src/test/java/edu/isu/cs/cs2263/hw02/AppTest.java new file mode 100644 index 0000000..5f2be3d --- /dev/null +++ b/app/src/test/java/edu/isu/cs/cs2263/hw02/AppTest.java @@ -0,0 +1,74 @@ +package edu.isu.cs.cs2263.hw02; + +import javafx.scene.Node; +import javafx.scene.control.ChoiceBox; +import javafx.scene.input.KeyCode; +import javafx.scene.input.MouseButton; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.testfx.api.FxToolkit; +import org.testfx.framework.junit5.*; +import org.junit.jupiter.api.Test; +import javafx.stage.Stage; +import org.testfx.matcher.base.NodeMatchers; + +import java.util.concurrent.TimeoutException; +import static org.testfx.api.FxAssert.verifyThat; +import static org.testfx.assertions.api.Assertions.assertThat; + +class AppTest extends ApplicationTest { + + @BeforeAll + public static void setUpClass() throws Exception { + ApplicationTest.launch(App.class); + } + + @Override + public void start(Stage stage) throws Exception{ + stage.show(); + } + + @AfterEach + public void afterEachTest() throws TimeoutException { + FxToolkit.hideStage(); + release(new KeyCode[]{}); + release(new MouseButton[]{}); + } + + @Test + public void ensureDropDownShows() throws InterruptedException { + clickOn("#dropDown"); + verifyThat("#dropDown", NodeMatchers.isVisible()); + } + + @Test + public void ensureDropDownContents() throws InterruptedException { + clickOn("#dropDown"); + verifyThat("#dropDown", NodeMatchers.hasChild("Computer Science (CS)")); + } + + @Test + public void testSetView(){ + clickOn("#dropDown"); + clickOn("Botany (BTNY)"); + clickOn("Display (dept.)"); + } + + @Test + public void testReset(){ + clickOn("New Course"); + clickOn("#newName"); + write("new one"); + clickOn("Reset"); + } + + @Test + public void testAdd(){ + clickOn("New Course"); + clickOn("#newName"); + write("added name"); + clickOn("Add Course"); + } + +} \ No newline at end of file diff --git a/app/src/test/java/edu/isu/cs/cs2263/hw02/CourseTest.java b/app/src/test/java/edu/isu/cs/cs2263/hw02/CourseTest.java new file mode 100644 index 0000000..95fcc58 --- /dev/null +++ b/app/src/test/java/edu/isu/cs/cs2263/hw02/CourseTest.java @@ -0,0 +1,65 @@ +package edu.isu.cs.cs2263.hw02; + +import edu.isu.cs.cs2263.hw02.data.Course; + +import org.checkerframework.checker.units.qual.C; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class CourseTest { + + Course course; + + @BeforeEach + public void setup(){ + course = new Course("name", "code?", 15, 2); + } + + @Test + public void testSetNumber(){ + course.setNumber(1); + assertEquals(1, course.getNumber()); + } + @Test + public void testGetNumber(){ + assertEquals(15, course.getNumber()); + course.setNumber(25); + assertEquals(25, course.getNumber()); + } + @Test + public void testSetName(){ + course.setName("new name"); + assertEquals("new name", course.getName()); + } + @Test + public void testGetName(){ + assertEquals("name", course.getName()); + course.setName("different name?"); + assertEquals("different name?", course.getName()); + } + @Test + public void testSetCredits(){ + course.setCredits(5); + assertEquals(5, course.getCredits()); + } + @Test + public void testGetCredits(){ + assertEquals(2, course.getCredits()); + course.setCredits(6); + assertEquals(6, course.getCredits()); + } + @Test + public void testSetCode(){ + course.setCode("2033"); + assertEquals("2033", course.getCode()); + } + @Test + public void testGetCode(){ + assertEquals("code?", course.getCode()); + } + +}