diff --git a/README.md b/README.md
index d507dbe..1b5ca77 100644
--- a/README.md
+++ b/README.md
@@ -20,19 +20,13 @@ curl http://localhost:8080/list
### Append to list
```bash
- curl --header "Content-Type: application/json" --request POST --data '[0.5, 0.6]' http://localhost:8080/list
+ curl --header "Content-Type: application/json" --request POST --data '[{"value": 0.5, "metadata": ""}, {"value": 0.6, "metadata": ""}]' http://localhost:8080/list
```
-### Append to list with verbose output
+### Append to list (malformed body)
```bash
- curl --verbose --header "Content-Type: application/json" --request POST --data '[0.5, 0.6]' http://localhost:8080/list
-```
-
-### Append to list with verbose output (malformed body)
-
-```bash
- curl --verbose --header "Content-Type: application/json" --request POST --data '[0.5, 0.6' http://localhost:8080/list
+ curl --header "Content-Type: application/json" --request POST --data '[{"value": 0.5; "metadata": ""}]' http://localhost:8080/list
```
### Clear list
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..fa94c3e
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+
+
+ de.unibayreuth.se.teaching.list
+ parent
+ 0.5.0
+
+
+ api
+
+
+
+ de.unibayreuth.se.teaching.list
+ business
+ ${project.version}
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ ${springdoc.openapi.version}
+
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/api/src/main/java/de/unibayreuth/se/teaching/list/api/controller/ListController.java b/api/src/main/java/de/unibayreuth/se/teaching/list/api/controller/ListController.java
new file mode 100644
index 0000000..c80b7cc
--- /dev/null
+++ b/api/src/main/java/de/unibayreuth/se/teaching/list/api/controller/ListController.java
@@ -0,0 +1,59 @@
+package de.unibayreuth.se.teaching.list.api.controller;
+
+import de.unibayreuth.se.teaching.list.api.dto.ListElementDto;
+import de.unibayreuth.se.teaching.list.business.ports.ListService;
+import de.unibayreuth.se.teaching.list.business.ports.Value;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+@Controller
+@RequiredArgsConstructor
+public class ListController {
+ private final ListService listService;
+
+ @GetMapping(value = "/list")
+ public ResponseEntity> getList() {
+ return ResponseEntity.ok(listService.get().stream()
+ // this::toDto is short for "apply that method to all elements in the stream"
+ // in this case: map(element -> toDto(element)
+ .map(this::toDto)
+ .toList()
+ );
+ }
+
+ @PostMapping(value = "/list")
+ public ResponseEntity> appendList(@RequestBody List elements) {
+ listService.append(elements.stream()
+ .map(this::toValue)
+ .toList()
+ );
+ // ResponseEntity.ok(...) is a shortcut for "create a response entity with status 200 (OK) and the provided body
+ return ResponseEntity.ok(listService.get().stream()
+ .map(this::toDto)
+ .toList());
+ }
+
+ /**
+ * Mapper function to convert a Value to a ListElementDto.
+ * @param value the Value object (from the business layer) to map to a ListElementDto
+ * @return the mapped ListElementDto
+ */
+ private ListElementDto toDto(Value value) {
+ return new ListElementDto(value.getDoubleValue(), "");
+ }
+
+ /**
+ * Mapper function to convert a ListElementDto to a Value.
+ * @param dto the ListElementDto object to map to a Value object (for the business layer)
+ * @return the mapped Value object
+ */
+ private Value toValue(ListElementDto dto) {
+ return new Value(dto.value());
+ }
+}
diff --git a/api/src/main/java/de/unibayreuth/se/teaching/list/api/dto/ListElementDto.java b/api/src/main/java/de/unibayreuth/se/teaching/list/api/dto/ListElementDto.java
new file mode 100644
index 0000000..8cf0fd9
--- /dev/null
+++ b/api/src/main/java/de/unibayreuth/se/teaching/list/api/dto/ListElementDto.java
@@ -0,0 +1,11 @@
+package de.unibayreuth.se.teaching.list.api.dto;
+
+/**
+ * Data transfer object for list elements, to be used in the list controller API endpoints.
+ *
+ * @param value The value of the list element.
+ * @param metadata Metadata of the list element (to showcase the DTO might look different from the internal data model).
+ */
+public record ListElementDto(double value, String metadata) {
+
+}
diff --git a/application/pom.xml b/application/pom.xml
new file mode 100644
index 0000000..44e128d
--- /dev/null
+++ b/application/pom.xml
@@ -0,0 +1,48 @@
+
+ 4.0.0
+
+
+ de.unibayreuth.se.teaching.list
+ parent
+ 0.5.0
+
+
+ application
+
+
+
+ de.unibayreuth.se.teaching.list
+ business
+ ${project.version}
+
+
+ de.unibayreuth.se.teaching.list
+ api
+ ${project.version}
+
+
+
+ org.springframework.boot
+ spring-boot-testcontainers
+
+
+ org.testcontainers
+ postgresql
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/unibayreuth/se/teaching/list/Application.java b/application/src/main/java/de/unibayreuth/se/teaching/list/Application.java
similarity index 81%
rename from src/main/java/de/unibayreuth/se/teaching/list/Application.java
rename to application/src/main/java/de/unibayreuth/se/teaching/list/Application.java
index 1f9c3c2..7d2b475 100644
--- a/src/main/java/de/unibayreuth/se/teaching/list/Application.java
+++ b/application/src/main/java/de/unibayreuth/se/teaching/list/Application.java
@@ -3,6 +3,9 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+/**
+ * Main class to start the Spring Boot application in production.
+ */
@SpringBootApplication
public class Application {
public static void main(String[] args) {
diff --git a/application/src/main/resources/application.yaml b/application/src/main/resources/application.yaml
new file mode 100644
index 0000000..89694f6
--- /dev/null
+++ b/application/src/main/resources/application.yaml
@@ -0,0 +1,15 @@
+spring:
+ application:
+ name: se24-demo
+ #datasource:
+ # driver-class-name: org.postgresql.Driver
+ #flyway:
+ # enabled: true
+ # locations: classpath:db/migration
+ # validate-on-migrate: true
+
+#springdoc:
+# api-docs:
+# path: /api-docs
+# swagger-ui:
+# path: /swagger-ui.html
diff --git a/business/pom.xml b/business/pom.xml
new file mode 100644
index 0000000..b4024d5
--- /dev/null
+++ b/business/pom.xml
@@ -0,0 +1,30 @@
+
+ 4.0.0
+
+
+ de.unibayreuth.se.teaching.list
+ parent
+ 0.5.0
+
+
+ business
+
+
+ de.unibayreuth.se.teaching.list.business.impl.CucumberListTestRunner
+
+
+
+
+
+
+ maven-surefire-plugin
+ ${maven.plugin.surefire.version}
+
+ ${maven.cucumber.testsuite}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/unibayreuth/se/teaching/list/DoublyLinkedList.java b/business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedList.java
similarity index 95%
rename from src/main/java/de/unibayreuth/se/teaching/list/DoublyLinkedList.java
rename to business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedList.java
index d4dfea2..06c81bd 100644
--- a/src/main/java/de/unibayreuth/se/teaching/list/DoublyLinkedList.java
+++ b/business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedList.java
@@ -1,4 +1,4 @@
-package de.unibayreuth.se.teaching.list;
+package de.unibayreuth.se.teaching.list.business.impl;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -6,13 +6,15 @@
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
/**
- * Doubly linked list
+ * Our doubly linked list implementation from previous assignments.
*/
@Getter
@Setter
@Slf4j
+@Component
public class DoublyLinkedList {
private Element start;
private Element end;
@@ -137,7 +139,7 @@ public boolean isEmpty() {
}
/**
- * Add an element at the correct position in a sorted list
+ * Insert an element at the correct position in a sorted list
* @param e Element to insert into the sorted list
*/
public void insert(Element e) {
diff --git a/business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/ListServiceImpl.java b/business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/ListServiceImpl.java
new file mode 100644
index 0000000..4f4342d
--- /dev/null
+++ b/business/src/main/java/de/unibayreuth/se/teaching/list/business/impl/ListServiceImpl.java
@@ -0,0 +1,32 @@
+package de.unibayreuth.se.teaching.list.business.impl;
+
+import de.unibayreuth.se.teaching.list.business.ports.ListService;
+import de.unibayreuth.se.teaching.list.business.ports.Value;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class ListServiceImpl implements ListService {
+ private final DoublyLinkedList list;
+
+ @Override
+ public List get() {
+ return Arrays.stream(list.asArray())
+ // Our list uses the primitive type "double" but streams require the reference type "Double."
+ // Related concept: Autoboxing (https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
+ .boxed()
+ .map(Value::new) // same shortcut as used in the controller, here: call constructor with value as argument
+ .toList();
+ }
+
+ @Override
+ public void append(List valuesToAppend) {
+ valuesToAppend.forEach(
+ value -> list.append(value.getDoubleValue())
+ );
+ }
+}
diff --git a/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/ListService.java b/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/ListService.java
new file mode 100644
index 0000000..d736070
--- /dev/null
+++ b/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/ListService.java
@@ -0,0 +1,11 @@
+package de.unibayreuth.se.teaching.list.business.ports;
+
+import java.util.List;
+
+/**
+ * Interface for the implementation of the list service that the business layer provides as a port.
+ */
+public interface ListService {
+ List get();
+ void append(List valuesToAppend);
+}
diff --git a/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/Value.java b/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/Value.java
new file mode 100644
index 0000000..5b40ab0
--- /dev/null
+++ b/business/src/main/java/de/unibayreuth/se/teaching/list/business/ports/Value.java
@@ -0,0 +1,12 @@
+package de.unibayreuth.se.teaching.list.business.ports;
+
+import lombok.Data;
+
+/**
+ * Class which stores the value of a list element.
+ */
+@Data
+public class Value {
+ private final Double doubleValue;
+ private Long longValue; // example for a derived value that the business layer might provide
+}
diff --git a/src/test/java/de/unibayreuth/se/teaching/list/CucumberSteps.java b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberDoublyLinkedListSteps.java
similarity index 72%
rename from src/test/java/de/unibayreuth/se/teaching/list/CucumberSteps.java
rename to business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberDoublyLinkedListSteps.java
index f91270e..39d5d36 100644
--- a/src/test/java/de/unibayreuth/se/teaching/list/CucumberSteps.java
+++ b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberDoublyLinkedListSteps.java
@@ -1,18 +1,20 @@
-package de.unibayreuth.se.teaching.list;
+package de.unibayreuth.se.teaching.list.business.impl;
import io.cucumber.java.Before;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
+import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
-import static org.junit.jupiter.api.Assertions.*;
-
-public class CucumberSteps {
- private static final Logger logger = LoggerFactory.getLogger(CucumberSteps.class);
+/**
+ * Step definitions for the Cucumber tests of the doubly-linked list.
+ */
+public class CucumberDoublyLinkedListSteps {
+ private static final Logger logger = LoggerFactory.getLogger(CucumberDoublyLinkedListSteps.class);
private DoublyLinkedList list;
private double value;
@@ -24,20 +26,11 @@ public void initialization() {
list = new DoublyLinkedList();
}
+ // Given -----------------------------------------------------------------------
+
@Given("^an empty list$")
public void anEmptyList() {
- assertTrue(list.isEmpty());
- }
-
- @When("^I append an element with value (\\d+.\\d+)$")
- public void iAppendAnElementWithValue(double value) {
- this.value = value;
- list.append(value);
- }
-
- @Then("^the list should contain that element$")
- public void theListShouldContainThatElement() {
- assertArrayEquals(new double[]{value}, list.asArray());
+ Assertions.assertTrue(list.isEmpty());
}
@Given("^I have elements with the following values in my list:$")
@@ -46,21 +39,36 @@ public void iHaveElementsWithTheFollowingValuesInMyList(List values) {
arrayFromValues = values.stream().mapToDouble(Double::doubleValue).toArray();
}
+ // When -----------------------------------------------------------------------
+
+ @When("^I append an element with value (\\d+.\\d+)$")
+ public void iAppendAnElementWithValue(double value) {
+ this.value = value;
+ list.append(value);
+ }
+
@When("^I convert the list to an array$")
public void iConvertTheListToAnArray() {
arrayFromList = list.asArray();
}
- @Then("^the array should contain the same elements in the same order$")
- public void theArrayShouldContainTheSameElementsInTheSameOrder() {
- assertArrayEquals(arrayFromValues, arrayFromList);
- }
-
@When("^I invert the list$")
public void iInvertTheList() {
logger.info("%s not implemented yet.".formatted(Thread.currentThread().getStackTrace()[1].getMethodName()));
}
+ // Then -----------------------------------------------------------------------
+
+ @Then("^the list should contain that element$")
+ public void theListShouldContainThatElement() {
+ Assertions.assertArrayEquals(new double[]{value}, list.asArray());
+ }
+
+ @Then("^the array should contain the same elements in the same order$")
+ public void theArrayShouldContainTheSameElementsInTheSameOrder() {
+ Assertions.assertArrayEquals(arrayFromValues, arrayFromList);
+ }
+
@Then("^the list should contain the elements in the following order:$")
public void theListShouldContainTheElementsInTheFollowingOrder(List values) {
logger.info("%s not implemented yet.".formatted(Thread.currentThread().getStackTrace()[1].getMethodName()));
@@ -68,6 +76,6 @@ public void theListShouldContainTheElementsInTheFollowingOrder(List valu
@Then("the list should contain {int} element(s)")
public void theListShouldContainElement(int count) {
- assertEquals(count, list.getLength());
+ Assertions.assertEquals(count, list.getLength());
}
}
diff --git a/src/test/java/de/unibayreuth/se/teaching/list/CucumberTestRunner.java b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberListTestRunner.java
similarity index 62%
rename from src/test/java/de/unibayreuth/se/teaching/list/CucumberTestRunner.java
rename to business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberListTestRunner.java
index b4133ac..39cf12e 100644
--- a/src/test/java/de/unibayreuth/se/teaching/list/CucumberTestRunner.java
+++ b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/CucumberListTestRunner.java
@@ -1,11 +1,14 @@
-package de.unibayreuth.se.teaching.list;
+package de.unibayreuth.se.teaching.list.business.impl;
import io.cucumber.junit.platform.engine.Constants;
import org.junit.platform.suite.api.*;
+/**
+ * Test runner for the Cucumber tests of the double-linked list.
+ */
@Suite
@SelectPackages("de.unibayreuth.se.teaching.list")
@ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME,value = "pretty, html:target/cucumber-report/cucumber.html")
-public class CucumberTestRunner {
+public class CucumberListTestRunner {
}
\ No newline at end of file
diff --git a/src/test/java/de/unibayreuth/se/teaching/list/DoublyLinkedListTest.java b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedListTest.java
similarity index 61%
rename from src/test/java/de/unibayreuth/se/teaching/list/DoublyLinkedListTest.java
rename to business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedListTest.java
index 3e42fb6..f5dbf77 100644
--- a/src/test/java/de/unibayreuth/se/teaching/list/DoublyLinkedListTest.java
+++ b/business/src/test/java/de/unibayreuth/se/teaching/list/business/impl/DoublyLinkedListTest.java
@@ -1,10 +1,12 @@
-package de.unibayreuth.se.teaching.list;
+package de.unibayreuth.se.teaching.list.business.impl;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.*;
-
+/**
+ * Unit tests for the doubly linked list.
+ */
class DoublyLinkedListTest {
private DoublyLinkedList list;
@@ -16,108 +18,108 @@ void setUp() {
@Test
void testAppendElement() {
// given: the list is empty...
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
var element = new DoublyLinkedList.Element(0.9);
// when: appending an element
list.append(element);
// then: the list has one element...
- assertEquals(1, list.getLength());
+ Assertions.assertEquals(1, list.getLength());
// ...and the new element is the start and end of the list
- assertEquals(element, list.getStart());
- assertEquals(element, list.getEnd());
+ Assertions.assertEquals(element, list.getStart());
+ Assertions.assertEquals(element, list.getEnd());
// ...and the start and end pointers do not have predecessors or successors
- assertNull(list.getStart().getPrev());
- assertNull(list.getStart().getNext());
- assertNull(list.getEnd().getPrev());
- assertNull(list.getEnd().getNext());
+ Assertions.assertNull(list.getStart().getPrev());
+ Assertions.assertNull(list.getStart().getNext());
+ Assertions.assertNull(list.getEnd().getPrev());
+ Assertions.assertNull(list.getEnd().getNext());
}
@Test
void testInsertNewMinimum() {
// given: the list as four sorted elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
list.append(new double[]{0.2, 0.4, 0.5, 0.8});
// when: inserting a new element with a value smaller than the minimum of the list
list.insert(new DoublyLinkedList.Element(0.1));
// then: the new element is the start of the list
- assertArrayEquals(new double[]{0.1, 0.2, 0.4, 0.5, 0.8}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{0.1, 0.2, 0.4, 0.5, 0.8}, list.asArray());
}
@Test
void testInsertNewMaximum() {
// given: the list as four sorted elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
list.append(new double[]{0.2, 0.4, 0.5, 0.8});
// when: inserting a new element with a value greater than the maximum of the list
list.insert(new DoublyLinkedList.Element(0.9));
// then: the new element is the end of the list
- assertArrayEquals(new double[]{0.2, 0.4, 0.5, 0.8, 0.9}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{0.2, 0.4, 0.5, 0.8, 0.9}, list.asArray());
}
@Test
void testInsertNeitherMinimumNorMaximum() {
// given: the list as four sorted elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
list.append(new double[]{0.2, 0.4, 0.5, 0.8});
// when: inserting a new element with a value between the minimum and the maximum of the list
list.insert(new DoublyLinkedList.Element(0.6));
// then: the new element is placed in the right position
- assertArrayEquals(new double[]{0.2, 0.4, 0.5, 0.6, 0.8}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{0.2, 0.4, 0.5, 0.6, 0.8}, list.asArray());
}
@Test
void testAppendElementFromOtherList() {
// give: an empty list and another list with three elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
DoublyLinkedList otherList = new DoublyLinkedList();
otherList.append(new double[]{0.9, 0.5, 0.4});
// when: appending the first element from the other list
// then: expect an exception to be raised
var firstElement = otherList.getStart();
- assertThrows(IllegalArgumentException.class, () -> list.append(firstElement));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> list.append(firstElement));
// when: appending the second element from the other list
// then: expect an exception to be raised
var secondElement = otherList.getStart().getNext();
- assertThrows(IllegalArgumentException.class, () -> list.append(secondElement));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> list.append(secondElement));
// when: appending the third element from the other list
// then: expect an exception to be raised
var lastElement = otherList.getEnd();
- assertThrows(IllegalArgumentException.class, () -> list.append(lastElement));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> list.append(lastElement));
}
@Test
void testAppendOneElementByValue() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// when: appending a new element
list.append(0.9);
// then: the list has one element...
- assertEquals(1, list.getLength());
+ Assertions.assertEquals(1, list.getLength());
// ...and the new element is the start and end of the list
- assertEquals(0.9, list.getStart().getValue());
- assertEquals(0.9, list.getEnd().getValue());
+ Assertions.assertEquals(0.9, list.getStart().getValue());
+ Assertions.assertEquals(0.9, list.getEnd().getValue());
// ...and the start and end pointers do not have predecessors or successors
- assertNull(list.getStart().getPrev());
- assertNull(list.getStart().getNext());
- assertNull(list.getEnd().getPrev());
- assertNull(list.getEnd().getNext());
+ Assertions.assertNull(list.getStart().getPrev());
+ Assertions.assertNull(list.getStart().getNext());
+ Assertions.assertNull(list.getEnd().getPrev());
+ Assertions.assertNull(list.getEnd().getNext());
}
@Test
void testAppendTwoElementsByValue() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// when: appending two new elements
list.append(0.9);
list.append(0.5);
// then: the list has two elements...
- assertEquals(2, list.getLength());
+ Assertions.assertEquals(2, list.getLength());
// ...and the first element is the start and the second element is the end of the list
- assertEquals(0.9, list.getStart().getValue());
- assertEquals(0.5, list.getEnd().getValue());
+ Assertions.assertEquals(0.9, list.getStart().getValue());
+ Assertions.assertEquals(0.5, list.getEnd().getValue());
// ...and they are correctly linked
- assertEquals(0.5, list.getStart().getNext().getValue());
- assertEquals(0.9, list.getEnd().getPrev().getValue());
+ Assertions.assertEquals(0.5, list.getStart().getNext().getValue());
+ Assertions.assertEquals(0.9, list.getEnd().getPrev().getValue());
// ...and the start and end pointers are correctly set
testBeginEndPointers(list);
}
@@ -125,19 +127,19 @@ void testAppendTwoElementsByValue() {
@Test
void testAppendThreeElementsByValue() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// when: appending three new elements
list.append(0.9);
list.append(0.5);
list.append(0.4);
// then: the list has three elements...
- assertEquals(3, list.getLength());
+ Assertions.assertEquals(3, list.getLength());
// ...and the first element is the start and the third element is the end of the list
- assertEquals(0.9, list.getStart().getValue());
- assertEquals(0.4, list.getEnd().getValue());
+ Assertions.assertEquals(0.9, list.getStart().getValue());
+ Assertions.assertEquals(0.4, list.getEnd().getValue());
// ...and all elements are correctly linked
- assertEquals(0.5, list.getStart().getNext().getValue());
- assertEquals(0.5, list.getEnd().getPrev().getValue());
+ Assertions.assertEquals(0.5, list.getStart().getNext().getValue());
+ Assertions.assertEquals(0.5, list.getEnd().getPrev().getValue());
// ...and the start and end pointers are correctly set
testBeginEndPointers(list);
}
@@ -145,91 +147,91 @@ void testAppendThreeElementsByValue() {
@Test
void testEmptyListToArray() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// then: the array representation of the list is equal to an empty array
- assertArrayEquals(new double[]{}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{}, list.asArray());
list.append(0.9);
list.append(0.5);
list.append(0.4);
- assertArrayEquals(new double[]{0.9, 0.5, 0.4}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{0.9, 0.5, 0.4}, list.asArray());
}
@Test
void testListToArray() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// when: appending three elements
list.append(0.9);
list.append(0.5);
list.append(0.4);
// then: the array representation of the list is equal to the array with the elements in the same order
- assertArrayEquals(new double[]{0.9, 0.5, 0.4}, list.asArray());
+ Assertions.assertArrayEquals(new double[]{0.9, 0.5, 0.4}, list.asArray());
}
@Test
void testAppendArray() {
// given: the list is empty
- assertEquals(0, list.getLength());
+ Assertions.assertEquals(0, list.getLength());
// when: appending an array with three elements
double[] data = new double[]{0.9, 0.5, 0.4};
list.append(data);
// then: the array representation of the list is equal to the appended array
- assertArrayEquals(data, list.asArray());
+ Assertions.assertArrayEquals(data, list.asArray());
}
@Test
void testIsEmptyOnEmptyList() {
// given: the list is empty
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
// then: the array representation of the list is equal to an empty array
- assertEquals(0, list.asArray().length);
+ Assertions.assertEquals(0, list.asArray().length);
}
@Test
void testIsEmptyOnNonEmptyList() {
// given: the list has three elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
list.append(0.9);
list.append(0.5);
list.append(0.4);
// then: the list is not empty
- assertFalse(list.isEmpty());
+ Assertions.assertFalse(list.isEmpty());
// when: clearing the list
list.clear();
// then: the list is empty again
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
}
@Test
void testAppendOtherList() {
// give: an empty list and another list with three elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
var data = new double[]{0.9, 0.5, 0.4};
DoublyLinkedList otherList = new DoublyLinkedList();
otherList.append(data);
// when: appending the other list
list.append(otherList);
// then: expect the list to contain the elements of the other list in the same order
- assertArrayEquals(data, list.asArray());
+ Assertions.assertArrayEquals(data, list.asArray());
}
@Test
void testToStringEmptyList() {
// given: the list is empty
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
// then: the string representation of the list is "Empty."
- assertEquals("Empty.", list.toString());
+ Assertions.assertEquals("Empty.", list.toString());
}
@Test
void testToStringNonEmptyList() {
// given: the list has three elements
- assertTrue(list.isEmpty());
+ Assertions.assertTrue(list.isEmpty());
list.append(0.9);
list.append(0.5);
list.append(0.4);
// then: the string representation of the list is "0.9<->0.5<->0.4"
- assertEquals("0.9<->0.5<->0.4", list.toString());
+ Assertions.assertEquals("0.9<->0.5<->0.4", list.toString());
}
/**
@@ -237,9 +239,9 @@ void testToStringNonEmptyList() {
* @param list List to test
*/
private static void testBeginEndPointers(DoublyLinkedList list) {
- assertNull(list.getStart().getPrev());
- assertSame(list.getStart().getNext().getPrev(), list.getStart());
- assertNull(list.getEnd().getNext());
- assertSame(list.getEnd().getPrev().getNext(), list.getEnd());
+ Assertions.assertNull(list.getStart().getPrev());
+ Assertions.assertSame(list.getStart().getNext().getPrev(), list.getStart());
+ Assertions.assertNull(list.getEnd().getNext());
+ Assertions.assertSame(list.getEnd().getPrev().getNext(), list.getEnd());
}
}
diff --git a/src/test/resources/de/unibayreuth/se/teaching/list/append-to-list.feature b/business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/append-to-list.feature
similarity index 100%
rename from src/test/resources/de/unibayreuth/se/teaching/list/append-to-list.feature
rename to business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/append-to-list.feature
diff --git a/src/test/resources/de/unibayreuth/se/teaching/list/invert-list.feature b/business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/invert-list.feature
similarity index 100%
rename from src/test/resources/de/unibayreuth/se/teaching/list/invert-list.feature
rename to business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/invert-list.feature
diff --git a/src/test/resources/de/unibayreuth/se/teaching/list/list-to-array.feature b/business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/list-to-array.feature
similarity index 100%
rename from src/test/resources/de/unibayreuth/se/teaching/list/list-to-array.feature
rename to business/src/test/resources/de/unibayreuth/se/teaching/list/business/impl/list-to-array.feature
diff --git a/lombok.config b/lombok.config
new file mode 100644
index 0000000..bd85f8b
--- /dev/null
+++ b/lombok.config
@@ -0,0 +1,4 @@
+# Copy the Qualifier annotation from the instance variables to the constructor
+# see https://github.com/rzwitserloot/lombok/issues/745
+lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
+lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Value
diff --git a/pom.xml b/pom.xml
index 0255ef5..1de0caf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,29 +10,39 @@
List
- de.unibayreuth.se.teaching
- list
- 0.4.0
+ de.unibayreuth.se.teaching.list
+ parent
+ 0.5.0
https://github.com/se-ubt/se24-assignment4
+ pom
+
+
+ business
+
+ api
+ application
+
+
21
UTF-8
UTF-8
+ de.unibayreuth.se.teaching.list.Application
${java.version}
${java.version}
- de.unibayreuth.se.teaching.list.Main
- de.unibayreuth.se.teaching.list.CucumberTestRunner
3.13.0
3.2.5
+
+ 3.4.1
3.3.2
@@ -46,6 +56,9 @@
3.11.0.3922
+
+ 3.2.5
+
5.11.0-M1
@@ -59,6 +72,14 @@
1.18.32
+
+ 0.2.0
+
+ 1.6.0.Beta2
+
+ 10.13.0
+
+ 2.5.0
@@ -70,6 +91,25 @@
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
org.junit.jupiter
junit-jupiter-api
@@ -88,12 +128,6 @@
${hamcrest.version}
test
-
- org.projectlombok
- lombok
- ${lombok.version}
- provided
-
io.cucumber
cucumber-java
@@ -106,19 +140,6 @@
${cucumber.version}
test
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
- org.springframework.boot
- spring-boot-starter-test
-
@@ -133,14 +154,33 @@
-proc:full
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${lombok.mapstruct.version}
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ ${spring.boot.version}
+
+
maven-surefire-plugin
${maven.plugin.surefire.version}
-
- ${maven.cucumber.testsuite}
-
org.apache.maven.plugins
@@ -174,6 +214,23 @@
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+ true
+
+ **/application-*.yaml
+
+
+
org.jacoco
jacoco-maven-plugin
@@ -208,18 +265,6 @@
sonar-maven-plugin
${maven.plugin.sonar.scanner.version}
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
- org.projectlombok
- lombok
-
-
-
-
diff --git a/src/main/java/de/unibayreuth/se/teaching/list/Main.java b/src/main/java/de/unibayreuth/se/teaching/list/Main.java
deleted file mode 100644
index a55fa4b..0000000
--- a/src/main/java/de/unibayreuth/se/teaching/list/Main.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.unibayreuth.se.teaching.list;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Main class for demo purposes.
- */
-public class Main {
- private static final Logger logger = LoggerFactory.getLogger(Main.class);
-
- public static void main(String[] args) {
-
- // Create list and add some values...
- DoublyLinkedList list = new DoublyLinkedList();
- list.append(new double[]{0.5, 4.2, 3.3, 0.9});
-
- logger.info("The list contains the following elements:");
- String listAsString = list.toString();
- logger.info(listAsString);
- }
-}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
deleted file mode 100644
index 3c508a6..0000000
--- a/src/main/resources/application.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-spring:
- application:
- name: se24-linked-list