diff --git a/app/pom.xml b/app/pom.xml
index 5afca24..3555da9 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -42,6 +42,12 @@
test
+
+ org.apache.commons
+ commons-csv
+ 1.14.1
+
+
com.googlecode.lanterna
lanterna
diff --git a/app/src/main/java/ru/project/collectors/MyCollectors.java b/app/src/main/java/ru/project/collectors/MyCollectors.java
index d0d7cf5..83b7ae8 100644
--- a/app/src/main/java/ru/project/collectors/MyCollectors.java
+++ b/app/src/main/java/ru/project/collectors/MyCollectors.java
@@ -1,15 +1,12 @@
package ru.project.collectors;
+
import java.util.stream.Collector;
+import ru.project.collection.MyList;
-public class MyCollectors
-{
- private MyCollectors() {
+public class MyCollectors {
+ private MyCollectors() {}
- }
-
- public static Collector, MyList> toMyList()
- {
- return new MyListCollector<>();
-
- }
+ public static Collector, MyList> toMyList() {
+ return new MyListCollector<>();
+ }
}
diff --git a/app/src/main/java/ru/project/collectors/MyListCollector.java b/app/src/main/java/ru/project/collectors/MyListCollector.java
index bb168e4..c5958b0 100644
--- a/app/src/main/java/ru/project/collectors/MyListCollector.java
+++ b/app/src/main/java/ru/project/collectors/MyListCollector.java
@@ -1,43 +1,41 @@
package ru.project.collectors;
-import java.util.Collections;
+
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
-public class MyListCollector implements Collector, MyList>
-{
- @Override
- public Supplier> supplier()
- {
- return () -> new MyLinkedList<>();
- }
+import ru.project.collection.MyLinkedList;
+import ru.project.collection.MyList;
- @Override
- public BiConsumer, T> accumulator() {
+public class MyListCollector implements Collector, MyList> {
+ @Override
+ public Supplier> supplier() {
+ return () -> new MyLinkedList<>();
+ }
- return (list, element) -> list.add(element);
- }
+ @Override
+ public BiConsumer, T> accumulator() {
- @Override
- public BinaryOperator> combiner() {
- return (list1, list2) -> {
- list1.addAll(list2);
- return list1;
- };
- }
+ return (list, element) -> list.add(element);
+ }
- @Override
- public Function, MyList> finisher()
- {
- return list -> list;
- }
+ @Override
+ public BinaryOperator> combiner() {
+ return (list1, list2) -> {
+ list1.addAll(list2);
+ return list1;
+ };
+ }
- @Override
- public Set characteristics() {
- return java.util.Set.of(
- Collector.Characteristics.IDENTITY_FINISH
- );
- }
+ @Override
+ public Function, MyList> finisher() {
+ return list -> list;
+ }
+
+ @Override
+ public Set characteristics() {
+ return java.util.Set.of(Collector.Characteristics.IDENTITY_FINISH);
+ }
}
diff --git a/app/src/main/java/ru/project/finder/StudentOccurrenceIndexFinder.java b/app/src/main/java/ru/project/finder/StudentOccurrenceIndexFinder.java
index 7e7c3d2..45ac263 100644
--- a/app/src/main/java/ru/project/finder/StudentOccurrenceIndexFinder.java
+++ b/app/src/main/java/ru/project/finder/StudentOccurrenceIndexFinder.java
@@ -1,125 +1,132 @@
package ru.project.finder;
+
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-public class StudentOccurrenceIndexFinder
-{
- public int[] findOccurrences(MyList students, Student target) {
- if (students == null) {
- throw new IllegalArgumentException();
- }
- if (target == null) {
- throw new IllegalArgumentException();
- }
- if (students.isEmpty()) {
- return new int[0];
- }
- int size = students.size();
- int threadCount = calculateThreadCount(size);
- int chunkSize = countChunkSize(size, threadCount);
+import ru.project.collection.MyLinkedList;
+import ru.project.collection.MyList;
+import ru.project.student.Student;
- ExecutorService executor = Executors.newFixedThreadPool(threadCount);
- MyList>> futures = new MyLinkedList<>();
+public class StudentOccurrenceIndexFinder {
+ public int[] findOccurrences(MyList students, Student target) {
+ if (students == null) {
+ throw new IllegalArgumentException();
+ }
+ if (target == null) {
+ throw new IllegalArgumentException();
+ }
+ if (students.isEmpty()) {
+ return new int[0];
+ }
+ int size = students.size();
+ int threadCount = calculateThreadCount(size);
+ int chunkSize = countChunkSize(size, threadCount);
- for (int i = 0; i < threadCount; i++) {
- int fromIndex = i * chunkSize;
- int toIndex = Math.min(fromIndex + chunkSize, size);
+ ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+ MyList>> futures = new MyLinkedList<>();
- if (fromIndex >= toIndex) {
- break;
- }
+ for (int i = 0; i < threadCount; i++) {
+ int fromIndex = i * chunkSize;
+ int toIndex = Math.min(fromIndex + chunkSize, size);
- final int start = fromIndex;
- final int end = toIndex;
+ if (fromIndex >= toIndex) {
+ break;
+ }
- Future> future = executor.submit(() -> {
+ final int start = fromIndex;
+ final int end = toIndex;
+
+ Future> future =
+ executor.submit(
+ () -> {
return findInRange(students, target, start, end);
- });
- futures.add(future);
+ });
+ futures.add(future);
+ }
+ MyList allIndices = new MyLinkedList<>();
+ try {
+ for (int i = 0; i < futures.size(); i++) {
+ Future> future = futures.get(i);
+ MyList partialResult = future.get();
+
+ if (partialResult != null) {
+ for (int j = 0; j < partialResult.size(); j++) {
+ allIndices.add(partialResult.get(j));
+ }
}
- MyList allIndices = new MyLinkedList<>();
- try {
- for (int i = 0; i < futures.size(); i++) {
- Future> future = futures.get(i);
- MyList partialResult = future.get();
-
- if (partialResult != null) {
- for (int j = 0; j < partialResult.size(); j++) {
- allIndices.add(partialResult.get(j));
- }
- }
- }
- } catch (Exception e) {
- throw new RuntimeException("Ошибка при поиске", e);
- } finally {
- executor.shutdown();
- }
-
- sortList(allIndices);
-
- int[] resultArray = new int[allIndices.size()];
- for (int i = 0; i < allIndices.size(); i++) {
- resultArray[i] = allIndices.get(i);
- }
-
- return resultArray;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Ошибка при поиске", e);
+ } finally {
+ executor.shutdown();
}
- private void sortList(MyList list) {
- if (list.size() <= 1) return;
+ sortList(allIndices);
- MyList sorted = new MyLinkedList<>();
-
- for (int i = 0; i < list.size(); i++) {
- int value = list.get(i);
- int insertIndex = 0;
- while (insertIndex < sorted.size()) {
- if (sorted.get(insertIndex) > value) {
- break;
- }
- insertIndex++;
- }
-
- MyList temp = new MyLinkedList<>();
- for (int k = 0; k < insertIndex; k++) {
- temp.add(sorted.get(k));
- }
- temp.add(value);
- for (int k = insertIndex; k < sorted.size(); k++) {
- temp.add(sorted.get(k));
- }
- sorted = temp;
- }
-
- while (!list.isEmpty()) {
- list.remove(0);
- }
-
- for (int i = 0; i < sorted.size(); i++) {
- list.add(sorted.get(i));
- }
+ int[] resultArray = new int[allIndices.size()];
+ for (int i = 0; i < allIndices.size(); i++) {
+ resultArray[i] = allIndices.get(i);
}
- private int calculateThreadCount(int size) {
- int processors = Runtime.getRuntime().availableProcessors();
- return Math.min(processors, size);
- }
+ return resultArray;
+ }
- private int countChunkSize(int size, int threadCount) {
- if (threadCount == 0) return 0;
- return (size + threadCount - 1) / threadCount;
- }
+ private void sortList(MyList list) {
+ if (list.size() <= 1) return;
- private MyList findInRange(MyList students, Student target, int fromIndex, int toIndex) {
- MyList foundIndices = new MyLinkedList<>();
+ MyList sorted = new MyLinkedList<>();
- for (int i = fromIndex; i < toIndex; i++) {
- Student current = students.get(i);
- if (current != null && current.equals(target)) {
- foundIndices.add(i);
- }
+ for (int i = 0; i < list.size(); i++) {
+ int value = list.get(i);
+ int insertIndex = 0;
+ while (insertIndex < sorted.size()) {
+ if (sorted.get(insertIndex) > value) {
+ break;
}
+ insertIndex++;
+ }
- return foundIndices;
+ MyList temp = new MyLinkedList<>();
+ for (int k = 0; k < insertIndex; k++) {
+ temp.add(sorted.get(k));
+ }
+ temp.add(value);
+ for (int k = insertIndex; k < sorted.size(); k++) {
+ temp.add(sorted.get(k));
+ }
+ sorted = temp;
}
+
+ while (!list.isEmpty()) {
+ list.remove(0);
+ }
+
+ for (int i = 0; i < sorted.size(); i++) {
+ list.add(sorted.get(i));
+ }
+ }
+
+ private int calculateThreadCount(int size) {
+ int processors = Runtime.getRuntime().availableProcessors();
+ return Math.min(processors, size);
+ }
+
+ private int countChunkSize(int size, int threadCount) {
+ if (threadCount == 0) return 0;
+ return (size + threadCount - 1) / threadCount;
+ }
+
+ private MyList findInRange(
+ MyList students, Student target, int fromIndex, int toIndex) {
+ MyList foundIndices = new MyLinkedList<>();
+
+ for (int i = fromIndex; i < toIndex; i++) {
+ Student current = students.get(i);
+ if (current != null && current.equals(target)) {
+ foundIndices.add(i);
+ }
+ }
+
+ return foundIndices;
+ }
}
diff --git a/app/src/main/java/ru/project/io/StudentCsvReader.java b/app/src/main/java/ru/project/io/StudentCsvReader.java
new file mode 100644
index 0000000..db2a4a9
--- /dev/null
+++ b/app/src/main/java/ru/project/io/StudentCsvReader.java
@@ -0,0 +1,88 @@
+package ru.project.io;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
+import ru.project.student.Student;
+import ru.project.student.StudentBuilder;
+ public class StudentCsvReader implements Iterator, AutoCloseable {
+ private static final String GROUP_NUMBER = "groupNumber";
+ private static final String AVERAGE_GRADE = "averageGrade";
+ private static final String RECORD_BOOK_NUMBER = "recordBookNumber";
+ private final CSVParser parser;
+ private final Iterator records;
+ private int lineOfFile=0;
+ public StudentCsvReader(Path path) {
+ if (!path.isAbsolute()) {
+ throw new IllegalArgumentException("File path must be absolute");
+ }
+ try {
+ CSVFormat format = CSVFormat.DEFAULT.builder()
+ .setHeader()
+ .setSkipHeaderRecord(true)
+ .get();
+ this.parser = CSVParser.parse(path, StandardCharsets.UTF_8, format);
+ validateHeader(parser.getHeaderMap());
+ this.records = parser.iterator();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ @Override
+ public boolean hasNext() {
+ return records.hasNext();
+ }
+ @Override
+ public Student next() {
+ if (!records.hasNext()) {
+ throw new NoSuchElementException("No more records at line " + (lineOfFile + 1));
+ }
+ lineOfFile++;
+ CSVRecord record = records.next();
+ if (record.size() != 3) {
+ throw new IllegalArgumentException(
+ "Problem at line " + lineOfFile + ". Expected 3 columns, but got " + record.size());
+ }
+ String groupNumber = record.get(GROUP_NUMBER);
+ String averageGradeStr = record.get(AVERAGE_GRADE);
+ String recordBookNumberStr = record.get(RECORD_BOOK_NUMBER);
+ double averageGrade;
+ int recordBookNumber;
+ try {
+ averageGrade = Double.parseDouble(averageGradeStr);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "Problem at line " + lineOfFile + ": cannot parse averageGrade '" + averageGradeStr + "' as double", e);
+ }
+ try {
+ recordBookNumber = Integer.parseInt(recordBookNumberStr);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(
+ "Problem at line " + lineOfFile + ": cannot parse recordBookNumber '" + recordBookNumberStr + "' as int", e);
+ }
+ return new StudentBuilder()
+ .setGroupNumber(groupNumber)
+ .setAverageGrade(averageGrade)
+ .setRecordBookNumber(recordBookNumber)
+ .build();
+ }
+ @Override
+ public void close() throws IOException {
+ parser.close();
+ }
+ private static void validateHeader(Map headerMap) {
+ String[] expected = {GROUP_NUMBER, AVERAGE_GRADE, RECORD_BOOK_NUMBER};
+ if (headerMap.size() != expected.length
+ || !headerMap.keySet().containsAll(Arrays.asList(expected))) {
+ throw new IllegalArgumentException("Invalid CSV header");
+ }
+ }
+ }
diff --git a/app/src/main/java/ru/project/search/StudentSearchService.java b/app/src/main/java/ru/project/search/StudentSearchService.java
index 4ced3c9..dc3a366 100644
--- a/app/src/main/java/ru/project/search/StudentSearchService.java
+++ b/app/src/main/java/ru/project/search/StudentSearchService.java
@@ -1,30 +1,30 @@
package ru.project.search;
-import ru.project.list.MyList;
-import ru.project.list.MyLinkedList;
+import ru.project.collection.MyLinkedList;
+import ru.project.collection.MyList;
import ru.project.student.Student;
public class StudentSearchService {
- private final StudentSearchCriteria criteria;
+ private final StudentSearchCriteria criteria;
- public StudentSearchService(StudentSearchCriteria criteria) {
- if (criteria == null) {
- throw new IllegalArgumentException("Criteria must not be null");
- }
- this.criteria = criteria;
+ public StudentSearchService(StudentSearchCriteria criteria) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("Criteria must not be null");
}
+ this.criteria = criteria;
+ }
- public MyList find(MyList students) {
- if (students == null) {
- return new MyLinkedList<>();
- }
- MyList result = new MyLinkedList<>();
- for (int i = 0; i < students.size(); i++) {
- Student s = students.get(i);
- if (criteria.matches(s)) {
- result.add(s);
- }
- }
- return result;
+ public MyList find(MyList students) {
+ if (students == null) {
+ return new MyLinkedList<>();
}
-}
\ No newline at end of file
+ MyList result = new MyLinkedList<>();
+ for (int i = 0; i < students.size(); i++) {
+ Student s = students.get(i);
+ if (criteria.matches(s)) {
+ result.add(s);
+ }
+ }
+ return result;
+ }
+}
diff --git a/app/src/test/java/ru/project/collection/MyLinkedListTest.java b/app/src/test/java/ru/project/collection/MyLinkedListTest.java
index 6c43673..8137964 100644
--- a/app/src/test/java/ru/project/collection/MyLinkedListTest.java
+++ b/app/src/test/java/ru/project/collection/MyLinkedListTest.java
@@ -1,130 +1,138 @@
-package ru.test.maven.spring;
-import org.junit.jupiter.api.Test;
+package ru.project.collection;
+
import static org.junit.jupiter.api.Assertions.*;
-public class MyLinkedListTest
-{
- @Test
- public void shouldTestAdd() {
- MyLinkedList list = new MyLinkedList<>();
- list.add(10);
- list.add(20);
- list.add(30);
- assertEquals(10, list.get(0));
- assertEquals(20, list.get(1));
- assertEquals(30, list.get(2));
- }
- @Test
- public void shouldTestGet()
- {
- MyLinkedList list = new MyLinkedList<>();
- list.add(10);
- assertEquals(10, list.get(0));
- }
- @Test
- public void shouldTestRemove() {
- MyLinkedList list = new MyLinkedList<>();
- list.add(10);
- list.add(20);
- list.add(30);
- list.remove(0);
+import org.junit.jupiter.api.Test;
- assertEquals(2, list.size());
- assertEquals(20, list.get(0));
- assertEquals(30, list.get(1));
- }
- @Test
- void shouldTestSet() {
- MyLinkedList list = new MyLinkedList<>();
- list.add("A");
- list.add("B");
- list.add("C");
+public class MyLinkedListTest {
+ @Test
+ public void shouldTestAdd() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(10);
+ list.add(20);
+ list.add(30);
- String oldValue = list.set(1, "Z");
+ assertEquals(10, list.get(0));
+ assertEquals(20, list.get(1));
+ assertEquals(30, list.get(2));
+ }
- assertEquals("B", oldValue);
- assertEquals("Z", list.get(1));
- assertEquals(3, list.size());
+ @Test
+ public void shouldTestGet() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(10);
+ assertEquals(10, list.get(0));
+ }
- }
- @Test
- void shouldTestSize()
- {
- MyLinkedList list = new MyLinkedList<>();
- list.add(1);
- list.add(2);
- list.add(3);
- assertEquals(3, list.size());
- }
- @Test
- void shouldTestisEmpty()
- {
- MyLinkedList list = new MyLinkedList<>();
- assertTrue(list.isEmpty());
- }
- @Test
- void shouldTestGet_OutOfBounds_ThrowsException() {
- MyLinkedList list = new MyLinkedList<>();
- list.add(1);
+ @Test
+ public void shouldTestRemove() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(10);
+ list.add(20);
+ list.add(30);
+ list.remove(0);
- assertThrows(IllegalArgumentException.class, () -> list.get(-1));
- assertThrows(IllegalArgumentException.class, () -> list.get(1)); // index == size
- assertThrows(IllegalArgumentException.class, () -> list.get(5)); // index > size
- }
- @Test
- void shouldTestSet_OutOfBounds_ThrowsException() {
- MyLinkedList list = new MyLinkedList<>();
- list.add(1);
+ assertEquals(2, list.size());
+ assertEquals(20, list.get(0));
+ assertEquals(30, list.get(1));
+ }
- assertThrows(IllegalArgumentException.class, () -> list.set(-1, 99));
- assertThrows(IllegalArgumentException.class, () -> list.set(1, 99));
- }
- @Test
- void shouldTestRemove_IndexGreaterThanSize_ThrowsException() {
- MyLinkedList list = new MyLinkedList<>();
- list.add("man");
- assertThrows(IndexOutOfBoundsException.class, () -> list.remove(5));
- }
- @Test
- void shouldTestRemove_NegativeIndex_ThrowsException() {
- MyLinkedList list = new MyLinkedList<>();
- list.add("1");
- list.add("2");
+ @Test
+ void shouldTestSet() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add("A");
+ list.add("B");
+ list.add("C");
- assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
- }
- @Test
- void shouldTestaddAll_nonEmptySource_toEmptyList_addsAllElementsInOrder() {
- MyList list = new MyLinkedList<>();
- MyList source = new MyLinkedList<>();
- source.add("A");
- source.add("B");
- source.add("C");
+ String oldValue = list.set(1, "Z");
- list.addAll(source);
+ assertEquals("B", oldValue);
+ assertEquals("Z", list.get(1));
+ assertEquals(3, list.size());
+ }
- assertEquals(3, list.size());
- assertEquals("A", list.get(0));
- assertEquals("B", list.get(1));
- assertEquals("C", list.get(2));
- }
+ @Test
+ void shouldTestSize() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(1);
+ list.add(2);
+ list.add(3);
+ assertEquals(3, list.size());
+ }
- @Test
- void shouldTestaddAll_toNonEmptyList_appendsAtEnd() {
- MyList list = new MyLinkedList<>();
- list.add("X");
- list.add("Y");
+ @Test
+ void shouldTestisEmpty() {
+ MyLinkedList list = new MyLinkedList<>();
+ assertTrue(list.isEmpty());
+ }
- MyList source = new MyLinkedList<>();
- source.add("A");
- source.add("B");
+ @Test
+ void shouldTestGet_OutOfBounds_ThrowsException() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(1);
- list.addAll(source);
+ assertThrows(IllegalArgumentException.class, () -> list.get(-1));
+ assertThrows(IllegalArgumentException.class, () -> list.get(1)); // index == size
+ assertThrows(IllegalArgumentException.class, () -> list.get(5)); // index > size
+ }
- assertEquals(4, list.size());
- assertEquals("X", list.get(0));
- assertEquals("Y", list.get(1));
- assertEquals("A", list.get(2));
- assertEquals("B", list.get(3));
- }
+ @Test
+ void shouldTestSet_OutOfBounds_ThrowsException() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add(1);
+
+ assertThrows(IllegalArgumentException.class, () -> list.set(-1, 99));
+ assertThrows(IllegalArgumentException.class, () -> list.set(1, 99));
+ }
+
+ @Test
+ void shouldTestRemove_IndexGreaterThanSize_ThrowsException() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add("man");
+ assertThrows(IndexOutOfBoundsException.class, () -> list.remove(5));
+ }
+
+ @Test
+ void shouldTestRemove_NegativeIndex_ThrowsException() {
+ MyLinkedList list = new MyLinkedList<>();
+ list.add("1");
+ list.add("2");
+
+ assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
+ }
+
+ @Test
+ void shouldTestaddAll_nonEmptySource_toEmptyList_addsAllElementsInOrder() {
+ MyList list = new MyLinkedList<>();
+ MyList source = new MyLinkedList<>();
+ source.add("A");
+ source.add("B");
+ source.add("C");
+
+ list.addAll(source);
+
+ assertEquals(3, list.size());
+ assertEquals("A", list.get(0));
+ assertEquals("B", list.get(1));
+ assertEquals("C", list.get(2));
+ }
+
+ @Test
+ void shouldTestaddAll_toNonEmptyList_appendsAtEnd() {
+ MyList list = new MyLinkedList<>();
+ list.add("X");
+ list.add("Y");
+
+ MyList source = new MyLinkedList<>();
+ source.add("A");
+ source.add("B");
+
+ list.addAll(source);
+
+ assertEquals(4, list.size());
+ assertEquals("X", list.get(0));
+ assertEquals("Y", list.get(1));
+ assertEquals("A", list.get(2));
+ assertEquals("B", list.get(3));
+ }
}
diff --git a/app/src/test/java/ru/project/collectors/MyListCollectorTest.java b/app/src/test/java/ru/project/collectors/MyListCollectorTest.java
index 3ca8d21..35abcbc 100644
--- a/app/src/test/java/ru/project/collectors/MyListCollectorTest.java
+++ b/app/src/test/java/ru/project/collectors/MyListCollectorTest.java
@@ -1,64 +1,58 @@
-package ru.test.maven.spring;
-import org.junit.jupiter.api.Test;
+package ru.project.collectors;
+
import static org.junit.jupiter.api.Assertions.*;
+
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.IntStream;
-import java.util.Collections;
+import org.junit.jupiter.api.Test;
+import ru.project.collection.MyList;
-public class MyListCollectorTest
-{
- private final MyListCollector collector = new MyListCollector<>();
+public class MyListCollectorTest {
+ private final MyListCollector collector = new MyListCollector<>();
- @Test
- void shouldTestCollectInOrderSequential() {
- MyList result = IntStream.range(0, 10)
- .boxed()
- .collect(MyCollectors.toMyList());
-
- assertEquals(10, result.size());
- for (int i = 0; i < result.size(); i++) {
- assertEquals(i, (int) result.get(i));
- }
+ @Test
+ void shouldTestCollectInOrderSequential() {
+ MyList result = IntStream.range(0, 10).boxed().collect(MyCollectors.toMyList());
+ assertEquals(10, result.size());
+ for (int i = 0; i < result.size(); i++) {
+ assertEquals(i, (int) result.get(i));
}
+ }
- @Test
- void shouldTestCollectInOrderParallel() {
- MyList result = IntStream.range(0, 100)
- .parallel()
- .boxed()
- .collect(MyCollectors.toMyList());
+ @Test
+ void shouldTestCollectInOrderParallel() {
+ MyList result =
+ IntStream.range(0, 100).parallel().boxed().collect(MyCollectors.toMyList());
- assertEquals(100, result.size());
- for (int i = 0; i < result.size(); i++) {
- assertEquals(i, (int) result.get(i));
- }
+ assertEquals(100, result.size());
+ for (int i = 0; i < result.size(); i++) {
+ assertEquals(i, (int) result.get(i));
}
+ }
- @Test
- void shouldTestHandleEmptyStream() {
- MyList result = IntStream.empty()
- .boxed()
- .collect(MyCollectors.toMyList());
+ @Test
+ void shouldTestHandleEmptyStream() {
+ MyList result = IntStream.empty().boxed().collect(MyCollectors.toMyList());
- assertTrue(result.isEmpty());
+ assertTrue(result.isEmpty());
+ }
- }
- @Test
- void shouldTestNotUseStandardList() {
- MyList result = IntStream.range(0, 5)
- .mapToObj(i -> "item" + i)
- .collect(MyCollectors.toMyList());
+ @Test
+ void shouldTestNotUseStandardList() {
+ MyList result =
+ IntStream.range(0, 5).mapToObj(i -> "item" + i).collect(MyCollectors.toMyList());
- assertInstanceOf(MyList.class, result);
- assertFalse(result instanceof java.util.List);
- }
- @Test
- void shouldTestHaveCorrectCharacteristics() {
- Set characteristics = collector.characteristics();
- assertTrue(characteristics.contains(java.util.stream.Collector.Characteristics.IDENTITY_FINISH));
- assertFalse(characteristics.contains(java.util.stream.Collector.Characteristics.UNORDERED));
- }
+ assertInstanceOf(MyList.class, result);
+ assertFalse(result instanceof java.util.List);
+ }
+ @Test
+ void shouldTestHaveCorrectCharacteristics() {
+ Set characteristics = collector.characteristics();
+ assertTrue(
+ characteristics.contains(java.util.stream.Collector.Characteristics.IDENTITY_FINISH));
+ assertFalse(characteristics.contains(java.util.stream.Collector.Characteristics.UNORDERED));
+ }
}
diff --git a/app/src/test/java/ru/project/finder/StudentOccurrenceIndexFinderTest.java b/app/src/test/java/ru/project/finder/StudentOccurrenceIndexFinderTest.java
index b61ed58..3e5c710 100644
--- a/app/src/test/java/ru/project/finder/StudentOccurrenceIndexFinderTest.java
+++ b/app/src/test/java/ru/project/finder/StudentOccurrenceIndexFinderTest.java
@@ -1,134 +1,137 @@
package ru.project.finder;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
import static org.junit.jupiter.api.Assertions.*;
-public class StudentOccurrenceIndexFinderTest
-{
- private StudentOccurrenceIndexFinder finder;
- private MyList students;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import ru.project.collection.MyLinkedList;
+import ru.project.collection.MyList;
+import ru.project.student.Student;
- @BeforeEach
- void setUp() {
- finder = new StudentOccurrenceIndexFinder();
- students = new MyLinkedList<>();
- }
+public class StudentOccurrenceIndexFinderTest {
+ private StudentOccurrenceIndexFinder finder;
+ private MyList students;
- @Test
- void shouldTesfindOccurrences_emptyList_returnsEmptyArray() {
- int[] result = finder.findOccurrences(students, new Student("A12", 4.5, 1));
- assertEquals(0, result.length);
- }
- @Test
- void shouldTesfindOccurrences_noMatches_returnsEmptyArray() {
- students.add(new Student("A12", 4.0, 101));
- students.add(new Student("B23", 3.5, 102));
- Student target = new Student("C34", 4.8, 103); // такого нет
+ @BeforeEach
+ void setUp() {
+ finder = new StudentOccurrenceIndexFinder();
+ students = new MyLinkedList<>();
+ }
- int[] result = finder.findOccurrences(students, target);
- assertEquals(0, result.length);
- }
- @Test
- void shouldTesfindOccurrences_singleMatch_returnsCorrectIndex() {
- students.add(new Student("A12", 4.0, 101));
- students.add(new Student("B23", 3.5, 102)); // target здесь
- students.add(new Student("C34", 4.8, 103));
+ @Test
+ void shouldTesfindOccurrences_emptyList_returnsEmptyArray() {
+ int[] result = finder.findOccurrences(students, new Student("A12", 4.5, 1));
+ assertEquals(0, result.length);
+ }
- Student target = new Student("B23", 3.5, 102);
- int[] result = finder.findOccurrences(students, target);
+ @Test
+ void shouldTesfindOccurrences_noMatches_returnsEmptyArray() {
+ students.add(new Student("A12", 4.0, 101));
+ students.add(new Student("B23", 3.5, 102));
+ Student target = new Student("C34", 4.8, 103); // такого нет
- assertEquals(1, result.length);
- assertEquals(1, result[0]);
- }
- @Test
- void shouldTesfindOccurrences_multipleMatches_returnsAllIndicesSorted() {
- // индексы: 0, 2, 4 — должны вернуться в порядке возрастания
- students.add(new Student("A12", 4.5, 101)); // match
- students.add(new Student("B23", 3.8, 102));
- students.add(new Student("A12", 4.5, 101)); // match
- students.add(new Student("C34", 4.0, 103));
- students.add(new Student("A12", 4.5, 101)); // match
+ int[] result = finder.findOccurrences(students, target);
+ assertEquals(0, result.length);
+ }
- Student target = new Student("A12", 4.5, 101);
- int[] result = finder.findOccurrences(students, target);
+ @Test
+ void shouldTesfindOccurrences_singleMatch_returnsCorrectIndex() {
+ students.add(new Student("A12", 4.0, 101));
+ students.add(new Student("B23", 3.5, 102)); // target здесь
+ students.add(new Student("C34", 4.8, 103));
- assertEquals(3, result.length);
- assertArrayEquals(new int[]{0, 2, 4}, result);
- }
+ Student target = new Student("B23", 3.5, 102);
+ int[] result = finder.findOccurrences(students, target);
- @Test
- void shouldTesfindOccurrences_allElementsMatch_returnsAllIndices() {
- Student s = new Student("X99", 5.0, 999);
- students.add(s);
- students.add(s);
- students.add(s);
+ assertEquals(1, result.length);
+ assertEquals(1, result[0]);
+ }
- int[] result = finder.findOccurrences(students, s);
- assertEquals(3, result.length);
- assertArrayEquals(new int[]{0, 1, 2}, result);
- }
+ @Test
+ void shouldTesfindOccurrences_multipleMatches_returnsAllIndicesSorted() {
+ // индексы: 0, 2, 4 — должны вернуться в порядке возрастания
+ students.add(new Student("A12", 4.5, 101)); // match
+ students.add(new Student("B23", 3.8, 102));
+ students.add(new Student("A12", 4.5, 101)); // match
+ students.add(new Student("C34", 4.0, 103));
+ students.add(new Student("A12", 4.5, 101)); // match
- @Test
- void shouldTesfindOccurrences_differentAverageGrade_noMatch() {
- students.add(new Student("A12", 4.50, 101));
- Student target = new Student("A12", 4.51, 101); // отличается балл
+ Student target = new Student("A12", 4.5, 101);
+ int[] result = finder.findOccurrences(students, target);
- int[] result = finder.findOccurrences(students, target);
- assertEquals(0, result.length);
- }
+ assertEquals(3, result.length);
+ assertArrayEquals(new int[] {0, 2, 4}, result);
+ }
+
+ @Test
+ void shouldTesfindOccurrences_allElementsMatch_returnsAllIndices() {
+ Student s = new Student("X99", 5.0, 999);
+ students.add(s);
+ students.add(s);
+ students.add(s);
+
+ int[] result = finder.findOccurrences(students, s);
+ assertEquals(3, result.length);
+ assertArrayEquals(new int[] {0, 1, 2}, result);
+ }
+
+ @Test
+ void shouldTesfindOccurrences_differentAverageGrade_noMatch() {
+ students.add(new Student("A12", 4.50, 101));
+ Student target = new Student("A12", 4.51, 101); // отличается балл
+
+ int[] result = finder.findOccurrences(students, target);
+ assertEquals(0, result.length);
+ }
+
+ @Test
+ void shouldTesfindOccurrences_differentGroupNumber_noMatch() {
+ students.add(new Student("A12", 4.5, 101));
+ Student target = new Student("B12", 4.5, 101); // другая группа
+
+ int[] result = finder.findOccurrences(students, target);
+ assertEquals(0, result.length);
+ }
+
+ @Test
+ void shouldTesfindOccurrences_differentRecordBookNumber_noMatch() {
+ students.add(new Student("A12", 4.5, 101));
+ Student target = new Student("A12", 4.5, 102); // другой номер зачетки
+
+ int[] result = finder.findOccurrences(students, target);
+ assertEquals(0, result.length);
+ }
+
+ @Test
+ void shouldTesfindOccurrences_nullList_throwsException() {
+ Student target = new Student("A12", 4.5, 101);
+ assertThrows(IllegalArgumentException.class, () -> finder.findOccurrences(null, target));
+ }
+
+ @Test
+ void shouldTesfindOccurrences_nullTarget_throwsException() {
+ assertThrows(IllegalArgumentException.class, () -> finder.findOccurrences(students, null));
+ }
+
+ @Test
+ void shouldTesfindOccurrences_resultIsSorted() {
+ String[] validGroups = {"A00", "A01", "B12", "C99", "X55"};
+
+ for (int i = 0; i < 50; i++) {
+ String group = validGroups[i % validGroups.length];
+ double grade = (3.0 + (i % 3)) / 2.0;
+ if (i % 3 == 0) {
- @Test
- void shouldTesfindOccurrences_differentGroupNumber_noMatch() {
students.add(new Student("A12", 4.5, 101));
- Student target = new Student("B12", 4.5, 101); // другая группа
-
- int[] result = finder.findOccurrences(students, target);
- assertEquals(0, result.length);
+ } else {
+ students.add(new Student(group, grade, 200 + i));
+ }
}
+ Student target = new Student("A12", 4.5, 101);
+ int[] result = finder.findOccurrences(students, target);
- @Test
- void shouldTesfindOccurrences_differentRecordBookNumber_noMatch() {
- students.add(new Student("A12", 4.5, 101));
- Student target = new Student("A12", 4.5, 102); // другой номер зачетки
-
- int[] result = finder.findOccurrences(students, target);
- assertEquals(0, result.length);
- }
-
-
- @Test
- void shouldTesfindOccurrences_nullList_throwsException() {
- Student target = new Student("A12", 4.5, 101);
- assertThrows(IllegalArgumentException.class, () -> finder.findOccurrences(null, target));
- }
-
-
- @Test
- void shouldTesfindOccurrences_nullTarget_throwsException() {
- assertThrows(IllegalArgumentException.class, () -> finder.findOccurrences(students, null));
- }
- @Test
- void shouldTesfindOccurrences_resultIsSorted() {
- String[] validGroups = {"A00", "A01", "B12", "C99", "X55"};
-
- for (int i = 0; i < 50; i++) {
- String group = validGroups[i % validGroups.length];
- double grade = (3.0 + (i % 3)) / 2.0;
- if (i % 3 == 0) {
-
- students.add(new Student("A12", 4.5, 101));
- } else {
- students.add(new Student(group, grade, 200 + i));
- }
- }
- Student target = new Student("A12", 4.5, 101);
- int[] result = finder.findOccurrences(students, target);
-
-
- for (int i = 1; i < result.length; i++) {
- assertTrue(result[i] > result[i - 1], "Результат должен быть отсортирован");
- }
+ for (int i = 1; i < result.length; i++) {
+ assertTrue(result[i] > result[i - 1], "Результат должен быть отсортирован");
}
+ }
}
diff --git a/app/src/test/java/ru/project/io/StudentCsvReaderTest.java b/app/src/test/java/ru/project/io/StudentCsvReaderTest.java
new file mode 100644
index 0000000..3541f35
--- /dev/null
+++ b/app/src/test/java/ru/project/io/StudentCsvReaderTest.java
@@ -0,0 +1,118 @@
+package ru.project.io;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.NoSuchElementException;
+import java.util.Spliterators;
+import java.util.stream.StreamSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import ru.project.student.Student;
+import ru.project.collection.MyList;
+import ru.project.collectors.MyCollectors;
+import static org.junit.jupiter.api.Assertions.*;
+class StudentCsvReaderTest {
+ @TempDir
+ Path tempDir;
+ @Test
+ void shouldTestreadValidCsvIntoMyList() throws IOException {
+ Path csv = tempDir.resolve("students.csv");
+ String content = String.join("\n",
+ "groupNumber,averageGrade,recordBookNumber",
+ "M10,4.5,12345",
+ "B05,3.8,12346"
+ );
+ Files.writeString(csv, content, StandardCharsets.UTF_8);
+ try (var reader = new StudentCsvReader(csv.toAbsolutePath())) {
+ var studentStream = StreamSupport.stream(
+ Spliterators.spliteratorUnknownSize(reader, 0),
+ false
+ );
+ MyList students = studentStream
+ .collect(MyCollectors.toMyList());
+ assertEquals(2, students.size());
+ assertEquals("M10", students.get(0).getGroupNumber());
+ assertEquals(4.5, students.get(0).getAverageGrade(), 0.0);
+ assertEquals(12345, students.get(0).getRecordBookNumber());
+ assertEquals("B05", students.get(1).getGroupNumber());
+ assertEquals(3.8, students.get(1).getAverageGrade(), 0.0);
+ assertEquals(12346, students.get(1).getRecordBookNumber());
+ }
+ }
+ @Test
+ void shouldTestinvalidHeaderThrowsException() throws IOException {
+ Path csv = tempDir.resolve("bad-header.csv");
+ String content = """
+ badGroup,badGrade,badBook
+ M101,4.5,12345
+ """;
+ Files.writeString(csv, content, StandardCharsets.UTF_8);
+ IllegalArgumentException ex = assertThrows(
+ IllegalArgumentException.class,
+ () -> new StudentCsvReader(csv.toAbsolutePath())
+ );
+ assertTrue(ex.getMessage().contains("Invalid CSV header"));
+ }
+ @Test
+ void shouldTestwrongColumnCountThrowsException() throws IOException {
+ Path csv = tempDir.resolve("wrong-columns.csv");
+ String content = """
+ groupNumber,averageGrade,recordBookNumber
+ M101,4.5
+ """;
+ Files.writeString(csv, content, StandardCharsets.UTF_8);
+ try (var reader = new StudentCsvReader(csv.toAbsolutePath())) {
+ assertTrue(reader.hasNext());
+
+ IllegalArgumentException ex = assertThrows(
+ IllegalArgumentException.class,
+ reader::next
+ );
+ assertTrue(ex.getMessage().contains("Expected 3 columns"));
+ }
+ }
+ @Test
+ void shouldTestparseErrorThrowsExceptionWithDetails() throws IOException {
+ Path csv = tempDir.resolve("parse-error.csv");
+ String content = """
+ groupNumber,averageGrade,recordBookNumber
+ M101,not-a-number,12345
+ """;
+ Files.writeString(csv, content, StandardCharsets.UTF_8);
+ try (var reader = new StudentCsvReader(csv.toAbsolutePath())) {
+ assertTrue(reader.hasNext());
+
+ IllegalArgumentException ex = assertThrows(
+ IllegalArgumentException.class,
+ reader::next
+ );
+ assertTrue(ex.getMessage().contains("cannot parse averageGrade"));
+ }
+ }
+ @Test
+ void shouldTestemptyDataAfterHeaderThrowsNoSuchElement() throws IOException {
+ Path csv = tempDir.resolve("empty-data.csv");
+ String content = """
+ groupNumber,averageGrade,recordBookNumber
+ """;
+ Files.writeString(csv, content, StandardCharsets.UTF_8);
+
+ // ИСПРАВЛЕНО: добавлен try-with-resources
+ try (var reader = new StudentCsvReader(csv.toAbsolutePath())) {
+ assertFalse(reader.hasNext());
+
+ assertThrows(NoSuchElementException.class, reader::next);
+ }
+ }
+ @Test
+ void shouldTestrelativePathThrowsException() {
+ Path relative = Path.of("relative-path.csv");
+
+ IllegalArgumentException ex = assertThrows(
+ IllegalArgumentException.class,
+ () -> new StudentCsvReader(relative)
+ );
+ assertTrue(ex.getMessage().contains("absolute"));
+ }
+ }
\ No newline at end of file
diff --git a/app/src/test/java/ru/project/search/StudentSearchTest.java b/app/src/test/java/ru/project/search/StudentSearchTest.java
index d12bd9c..db43fa1 100644
--- a/app/src/test/java/ru/project/search/StudentSearchTest.java
+++ b/app/src/test/java/ru/project/search/StudentSearchTest.java
@@ -1,314 +1,317 @@
package ru.project.search;
-import org.junit.jupiter.api.Test;
-import ru.project.list.MyList;
-import ru.project.list.MyLinkedList;
-import ru.project.student.Student;
-
import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
+import ru.project.collection.MyLinkedList;
+import ru.project.collection.MyList;
+import ru.project.student.Student;
+
class StudentSearchTest {
- @Test
- void testGroupNumberRangeMatchesInside() {
- StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
- Student student = new Student("B20", 4.5, 123);
- assertTrue(criteria.matches(student));
+ @Test
+ void testGroupNumberRangeMatchesInside() {
+ StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
+ Student student = new Student("B20", 4.5, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testGroupNumberRangeMatchesLowerBoundary() {
+ StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
+ Student student = new Student("A10", 4.5, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testGroupNumberRangeMatchesUpperBoundary() {
+ StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
+ Student student = new Student("C30", 4.5, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testGroupNumberRangeDoesNotMatchOutside() {
+ StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
+ Student student = new Student("D00", 4.5, 123);
+ assertFalse(criteria.matches(student));
+ }
+
+ @Test
+ void testGroupNumberRangeInvalidMinMaxThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> new GroupNumberRangeCriteria("C30", "A10"));
+ }
+
+ @Test
+ void testGroupNumberRangeNullValuesThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> new GroupNumberRangeCriteria(null, "A10"));
+ assertThrows(IllegalArgumentException.class, () -> new GroupNumberRangeCriteria("A10", null));
+ }
+
+ @Test
+ void testAverageGradeRangeMatchesInside() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ Student student = new Student("A12", 4.5, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testAverageGradeRangeMatchesLowerBoundary() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ Student student = new Student("A12", 4.0, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testAverageGradeRangeMatchesUpperBoundary() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ Student student = new Student("A12", 5.0, 123);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testAverageGradeRangeDoesNotMatchBelow() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ Student student = new Student("A12", 3.9, 123);
+ assertFalse(criteria.matches(student));
+ }
+
+ @Test
+ void testAverageGradeRangeDoesNotMatchAbove() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ Student student = new Student("A12", 5.1, 123);
+ assertFalse(criteria.matches(student));
+ }
+
+ @Test
+ void testAverageGradeRangeInvalidMinMaxThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> new AverageGradeRangeCriteria(5.0, 4.0));
+ }
+
+ @Test
+ void testRecordBookNumberRangeMatchesInside() {
+ StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
+ Student student = new Student("A12", 4.5, 150);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testRecordBookNumberRangeMatchesLowerBoundary() {
+ StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
+ Student student = new Student("A12", 4.5, 100);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testRecordBookNumberRangeMatchesUpperBoundary() {
+ StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
+ Student student = new Student("A12", 4.5, 200);
+ assertTrue(criteria.matches(student));
+ }
+
+ @Test
+ void testRecordBookNumberRangeDoesNotMatchBelow() {
+ StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
+ Student student = new Student("A12", 4.5, 99);
+ assertFalse(criteria.matches(student));
+ }
+
+ @Test
+ void testRecordBookNumberRangeDoesNotMatchAbove() {
+ StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
+ Student student = new Student("A12", 4.5, 201);
+ assertFalse(criteria.matches(student));
+ }
+
+ @Test
+ void testRecordBookNumberRangeInvalidMinMaxThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> new RecordBookNumberRangeCriteria(200, 100));
+ }
+
+ @Test
+ void testCompositeIntersectionEmptyReturnsTrue() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
+ Student student = new Student("A12", 4.5, 123);
+ assertTrue(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeUnionEmptyReturnsFalse() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.UNION);
+ Student student = new Student("A12", 4.5, 123);
+ assertFalse(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeIntersectionAllTrue() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
+ composite.add(new GroupNumberRangeCriteria("A10", "C30"));
+ composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
+ Student student = new Student("B20", 4.5, 123);
+ assertTrue(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeIntersectionOneFalse() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
+ composite.add(new GroupNumberRangeCriteria("A10", "C30"));
+ composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
+ Student student = new Student("B20", 3.5, 123);
+ assertFalse(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeUnionOneTrue() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.UNION);
+ composite.add(new GroupNumberRangeCriteria("A10", "C30"));
+ composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
+ Student student = new Student("D00", 4.5, 123);
+ assertTrue(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeUnionAllFalse() {
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.UNION);
+ composite.add(new GroupNumberRangeCriteria("A10", "C30"));
+ composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
+ Student student = new Student("D00", 3.5, 123);
+ assertFalse(composite.matches(student));
+ }
+
+ @Test
+ void testCompositeWithNestedComposite() {
+ CompositeStudentSearchCriteria outer =
+ new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
+ outer.add(new GroupNumberRangeCriteria("A10", "C30"));
+
+ CompositeStudentSearchCriteria inner =
+ new CompositeStudentSearchCriteria(SearchOperation.UNION);
+ inner.add(new AverageGradeRangeCriteria(4.0, 5.0));
+ inner.add(new RecordBookNumberRangeCriteria(100, 200));
+
+ outer.add(inner);
+
+ Student student = new Student("B20", 4.5, 150);
+ assertTrue(outer.matches(student));
+ student = new Student("B20", 3.5, 150);
+ assertFalse(outer.matches(student));
+ student = new Student("D00", 4.5, 150);
+ assertFalse(outer.matches(student));
+ }
+
+ @Test
+ void testSearchServiceWithSingleCriteria() {
+ MyList students = new MyLinkedList<>();
+ students.add(new Student("A10", 4.5, 1));
+ students.add(new Student("B20", 3.8, 2));
+ students.add(new Student("C30", 4.9, 3));
+
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ MyList result = service.find(students);
+
+ assertEquals(2, result.size());
+ assertEquals("A10", result.get(0).getGroupNumber());
+ assertEquals("C30", result.get(1).getGroupNumber());
+ }
+
+ @Test
+ void testSearchServiceEmptyResult() {
+ MyList students = new MyLinkedList<>();
+ students.add(new Student("A10", 3.5, 1));
+ students.add(new Student("B20", 3.8, 2));
+
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ MyList result = service.find(students);
+
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ void testSearchServiceEmptyCollection() {
+ MyList students = new MyLinkedList<>();
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ MyList result = service.find(students);
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ void testSearchServicePreservesOrder() {
+ MyList students = new MyLinkedList<>();
+ students.add(new Student("Z00", 4.5, 1));
+ students.add(new Student("A10", 4.5, 2));
+ students.add(new Student("M30", 4.5, 3));
+
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ MyList result = service.find(students);
+
+ assertEquals(3, result.size());
+ assertEquals("Z00", result.get(0).getGroupNumber());
+ assertEquals("A10", result.get(1).getGroupNumber());
+ assertEquals("M30", result.get(2).getGroupNumber());
+ }
+
+ @Test
+ void testSearchServiceDoesNotModifyOriginal() {
+ MyList original = new MyLinkedList<>();
+ original.add(new Student("A10", 4.5, 1));
+ original.add(new Student("B20", 3.8, 2));
+
+ MyList copy = new MyLinkedList<>();
+ for (int i = 0; i < original.size(); i++) {
+ copy.add(original.get(i));
}
- @Test
- void testGroupNumberRangeMatchesLowerBoundary() {
- StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
- Student student = new Student("A10", 4.5, 123);
- assertTrue(criteria.matches(student));
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ service.find(original);
+
+ assertEquals(copy.size(), original.size());
+ for (int i = 0; i < copy.size(); i++) {
+ assertEquals(copy.get(i).getGroupNumber(), original.get(i).getGroupNumber());
}
+ }
- @Test
- void testGroupNumberRangeMatchesUpperBoundary() {
- StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
- Student student = new Student("C30", 4.5, 123);
- assertTrue(criteria.matches(student));
- }
+ @Test
+ void testSearchServiceWithNullCriteriaThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> new StudentSearchService(null));
+ }
- @Test
- void testGroupNumberRangeDoesNotMatchOutside() {
- StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
- Student student = new Student("D00", 4.5, 123);
- assertFalse(criteria.matches(student));
- }
+ @Test
+ void testSearchServiceWithCompositeCriteria() {
+ MyList students = new MyLinkedList<>();
+ students.add(new Student("A10", 4.5, 1));
+ students.add(new Student("B20", 4.5, 2));
+ students.add(new Student("C30", 3.5, 3));
- @Test
- void testGroupNumberRangeInvalidMinMaxThrowsException() {
- assertThrows(IllegalArgumentException.class,
- () -> new GroupNumberRangeCriteria("C30", "A10"));
- }
+ CompositeStudentSearchCriteria composite =
+ new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
+ composite.add(new GroupNumberRangeCriteria("A10", "B20"));
+ composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
- @Test
- void testGroupNumberRangeNullValuesThrowsException() {
- assertThrows(IllegalArgumentException.class,
- () -> new GroupNumberRangeCriteria(null, "A10"));
- assertThrows(IllegalArgumentException.class,
- () -> new GroupNumberRangeCriteria("A10", null));
- }
+ StudentSearchService service = new StudentSearchService(composite);
+ MyList result = service.find(students);
- @Test
- void testAverageGradeRangeMatchesInside() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- Student student = new Student("A12", 4.5, 123);
- assertTrue(criteria.matches(student));
- }
+ assertEquals(2, result.size());
+ assertEquals("A10", result.get(0).getGroupNumber());
+ assertEquals("B20", result.get(1).getGroupNumber());
+ }
- @Test
- void testAverageGradeRangeMatchesLowerBoundary() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- Student student = new Student("A12", 4.0, 123);
- assertTrue(criteria.matches(student));
- }
-
- @Test
- void testAverageGradeRangeMatchesUpperBoundary() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- Student student = new Student("A12", 5.0, 123);
- assertTrue(criteria.matches(student));
- }
-
- @Test
- void testAverageGradeRangeDoesNotMatchBelow() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- Student student = new Student("A12", 3.9, 123);
- assertFalse(criteria.matches(student));
- }
-
- @Test
- void testAverageGradeRangeDoesNotMatchAbove() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- Student student = new Student("A12", 5.1, 123);
- assertFalse(criteria.matches(student));
- }
-
- @Test
- void testAverageGradeRangeInvalidMinMaxThrowsException() {
- assertThrows(IllegalArgumentException.class,
- () -> new AverageGradeRangeCriteria(5.0, 4.0));
- }
-
- @Test
- void testRecordBookNumberRangeMatchesInside() {
- StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
- Student student = new Student("A12", 4.5, 150);
- assertTrue(criteria.matches(student));
- }
-
- @Test
- void testRecordBookNumberRangeMatchesLowerBoundary() {
- StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
- Student student = new Student("A12", 4.5, 100);
- assertTrue(criteria.matches(student));
- }
-
- @Test
- void testRecordBookNumberRangeMatchesUpperBoundary() {
- StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
- Student student = new Student("A12", 4.5, 200);
- assertTrue(criteria.matches(student));
- }
-
- @Test
- void testRecordBookNumberRangeDoesNotMatchBelow() {
- StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
- Student student = new Student("A12", 4.5, 99);
- assertFalse(criteria.matches(student));
- }
-
- @Test
- void testRecordBookNumberRangeDoesNotMatchAbove() {
- StudentSearchCriteria criteria = new RecordBookNumberRangeCriteria(100, 200);
- Student student = new Student("A12", 4.5, 201);
- assertFalse(criteria.matches(student));
- }
-
- @Test
- void testRecordBookNumberRangeInvalidMinMaxThrowsException() {
- assertThrows(IllegalArgumentException.class,
- () -> new RecordBookNumberRangeCriteria(200, 100));
- }
-
- @Test
- void testCompositeIntersectionEmptyReturnsTrue() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
- Student student = new Student("A12", 4.5, 123);
- assertTrue(composite.matches(student));
- }
-
- @Test
- void testCompositeUnionEmptyReturnsFalse() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.UNION);
- Student student = new Student("A12", 4.5, 123);
- assertFalse(composite.matches(student));
- }
-
- @Test
- void testCompositeIntersectionAllTrue() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
- composite.add(new GroupNumberRangeCriteria("A10", "C30"));
- composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
- Student student = new Student("B20", 4.5, 123);
- assertTrue(composite.matches(student));
- }
-
- @Test
- void testCompositeIntersectionOneFalse() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
- composite.add(new GroupNumberRangeCriteria("A10", "C30"));
- composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
- Student student = new Student("B20", 3.5, 123);
- assertFalse(composite.matches(student));
- }
-
- @Test
- void testCompositeUnionOneTrue() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.UNION);
- composite.add(new GroupNumberRangeCriteria("A10", "C30"));
- composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
- Student student = new Student("D00", 4.5, 123);
- assertTrue(composite.matches(student));
- }
-
- @Test
- void testCompositeUnionAllFalse() {
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.UNION);
- composite.add(new GroupNumberRangeCriteria("A10", "C30"));
- composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
- Student student = new Student("D00", 3.5, 123);
- assertFalse(composite.matches(student));
- }
-
- @Test
- void testCompositeWithNestedComposite() {
- CompositeStudentSearchCriteria outer = new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
- outer.add(new GroupNumberRangeCriteria("A10", "C30"));
-
- CompositeStudentSearchCriteria inner = new CompositeStudentSearchCriteria(SearchOperation.UNION);
- inner.add(new AverageGradeRangeCriteria(4.0, 5.0));
- inner.add(new RecordBookNumberRangeCriteria(100, 200));
-
- outer.add(inner);
-
- Student student = new Student("B20", 4.5, 150);
- assertTrue(outer.matches(student));
- student = new Student("B20", 3.5, 150);
- assertFalse(outer.matches(student));
- student = new Student("D00", 4.5, 150);
- assertFalse(outer.matches(student));
- }
-
- @Test
- void testSearchServiceWithSingleCriteria() {
- MyList students = new MyLinkedList<>();
- students.add(new Student("A10", 4.5, 1));
- students.add(new Student("B20", 3.8, 2));
- students.add(new Student("C30", 4.9, 3));
-
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- MyList result = service.find(students);
-
- assertEquals(2, result.size());
- assertEquals("A10", result.get(0).getGroupNumber());
- assertEquals("C30", result.get(1).getGroupNumber());
- }
-
- @Test
- void testSearchServiceEmptyResult() {
- MyList students = new MyLinkedList<>();
- students.add(new Student("A10", 3.5, 1));
- students.add(new Student("B20", 3.8, 2));
-
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- MyList result = service.find(students);
-
- assertEquals(0, result.size());
- }
-
- @Test
- void testSearchServiceEmptyCollection() {
- MyList students = new MyLinkedList<>();
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- MyList result = service.find(students);
- assertEquals(0, result.size());
- }
-
- @Test
- void testSearchServicePreservesOrder() {
- MyList students = new MyLinkedList<>();
- students.add(new Student("Z00", 4.5, 1));
- students.add(new Student("A10", 4.5, 2));
- students.add(new Student("M30", 4.5, 3));
-
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- MyList result = service.find(students);
-
- assertEquals(3, result.size());
- assertEquals("Z00", result.get(0).getGroupNumber());
- assertEquals("A10", result.get(1).getGroupNumber());
- assertEquals("M30", result.get(2).getGroupNumber());
- }
-
- @Test
- void testSearchServiceDoesNotModifyOriginal() {
- MyList original = new MyLinkedList<>();
- original.add(new Student("A10", 4.5, 1));
- original.add(new Student("B20", 3.8, 2));
-
- MyList copy = new MyLinkedList<>();
- for (int i = 0; i < original.size(); i++) {
- copy.add(original.get(i));
- }
-
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- service.find(original);
-
- assertEquals(copy.size(), original.size());
- for (int i = 0; i < copy.size(); i++) {
- assertEquals(copy.get(i).getGroupNumber(), original.get(i).getGroupNumber());
- }
- }
-
- @Test
- void testSearchServiceWithNullCriteriaThrowsException() {
- assertThrows(IllegalArgumentException.class,
- () -> new StudentSearchService(null));
- }
-
- @Test
- void testSearchServiceWithCompositeCriteria() {
- MyList students = new MyLinkedList<>();
- students.add(new Student("A10", 4.5, 1));
- students.add(new Student("B20", 4.5, 2));
- students.add(new Student("C30", 3.5, 3));
-
- CompositeStudentSearchCriteria composite = new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
- composite.add(new GroupNumberRangeCriteria("A10", "B20"));
- composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
-
- StudentSearchService service = new StudentSearchService(composite);
- MyList result = service.find(students);
-
- assertEquals(2, result.size());
- assertEquals("A10", result.get(0).getGroupNumber());
- assertEquals("B20", result.get(1).getGroupNumber());
- }
-
- @Test
- void testSearchServiceWithNullStudentListReturnsEmpty() {
- StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
- StudentSearchService service = new StudentSearchService(criteria);
- MyList result = service.find(null);
- assertNotNull(result);
- assertEquals(0, result.size());
- }
-}
\ No newline at end of file
+ @Test
+ void testSearchServiceWithNullStudentListReturnsEmpty() {
+ StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
+ StudentSearchService service = new StudentSearchService(criteria);
+ MyList result = service.find(null);
+ assertNotNull(result);
+ assertEquals(0, result.size());
+ }
+}