style: reformat source and tests, fix imports and packages

This commit is contained in:
2026-09-01 15:55:41 +04:00
parent bc0cf4f48b
commit ff83c48650
10 changed files with 792 additions and 810 deletions
@@ -1,15 +1,12 @@
package ru.project.collectors; package ru.project.collectors;
import java.util.stream.Collector; import java.util.stream.Collector;
import ru.project.collection.MyList;
public class MyCollectors public class MyCollectors {
{ private MyCollectors() {}
private MyCollectors() {
} public static <T> Collector<T, MyList<T>, MyList<T>> toMyList() {
return new MyListCollector<>();
public static <T> Collector<T, MyList<T>, MyList<T>> toMyList() }
{
return new MyListCollector<>();
}
} }
@@ -1,43 +1,41 @@
package ru.project.collectors; package ru.project.collectors;
import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collector; import java.util.stream.Collector;
public class MyListCollector <T> implements Collector<T, MyList<T>, MyList<T>> import ru.project.collection.MyLinkedList;
{ import ru.project.collection.MyList;
@Override
public Supplier<MyList<T>> supplier()
{
return () -> new MyLinkedList<>();
}
@Override public class MyListCollector<T> implements Collector<T, MyList<T>, MyList<T>> {
public BiConsumer<MyList<T>, T> accumulator() { @Override
public Supplier<MyList<T>> supplier() {
return () -> new MyLinkedList<>();
}
return (list, element) -> list.add(element); @Override
} public BiConsumer<MyList<T>, T> accumulator() {
@Override return (list, element) -> list.add(element);
public BinaryOperator<MyList<T>> combiner() { }
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override @Override
public Function<MyList<T>, MyList<T>> finisher() public BinaryOperator<MyList<T>> combiner() {
{ return (list1, list2) -> {
return list -> list; list1.addAll(list2);
} return list1;
};
}
@Override @Override
public Set<Collector.Characteristics> characteristics() { public Function<MyList<T>, MyList<T>> finisher() {
return java.util.Set.of( return list -> list;
Collector.Characteristics.IDENTITY_FINISH }
);
} @Override
public Set<Collector.Characteristics> characteristics() {
return java.util.Set.of(Collector.Characteristics.IDENTITY_FINISH);
}
} }
@@ -1,125 +1,132 @@
package ru.project.finder; package ru.project.finder;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
public class StudentOccurrenceIndexFinder import ru.project.collection.MyLinkedList;
{ import ru.project.collection.MyList;
public int[] findOccurrences(MyList<Student> students, Student target) { import ru.project.student.Student;
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);
ExecutorService executor = Executors.newFixedThreadPool(threadCount); public class StudentOccurrenceIndexFinder {
MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>(); public int[] findOccurrences(MyList<Student> 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++) { ExecutorService executor = Executors.newFixedThreadPool(threadCount);
int fromIndex = i * chunkSize; MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>();
int toIndex = Math.min(fromIndex + chunkSize, size);
if (fromIndex >= toIndex) { for (int i = 0; i < threadCount; i++) {
break; int fromIndex = i * chunkSize;
} int toIndex = Math.min(fromIndex + chunkSize, size);
final int start = fromIndex; if (fromIndex >= toIndex) {
final int end = toIndex; break;
}
Future<MyList<Integer>> future = executor.submit(() -> { final int start = fromIndex;
final int end = toIndex;
Future<MyList<Integer>> future =
executor.submit(
() -> {
return findInRange(students, target, start, end); return findInRange(students, target, start, end);
}); });
futures.add(future); futures.add(future);
}
MyList<Integer> allIndices = new MyLinkedList<>();
try {
for (int i = 0; i < futures.size(); i++) {
Future<MyList<Integer>> future = futures.get(i);
MyList<Integer> partialResult = future.get();
if (partialResult != null) {
for (int j = 0; j < partialResult.size(); j++) {
allIndices.add(partialResult.get(j));
}
} }
MyList<Integer> allIndices = new MyLinkedList<>(); }
try { } catch (Exception e) {
for (int i = 0; i < futures.size(); i++) { throw new RuntimeException("Ошибка при поиске", e);
Future<MyList<Integer>> future = futures.get(i); } finally {
MyList<Integer> partialResult = future.get(); executor.shutdown();
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;
} }
private void sortList(MyList<Integer> list) { sortList(allIndices);
if (list.size() <= 1) return;
MyList<Integer> sorted = new MyLinkedList<>(); int[] resultArray = new int[allIndices.size()];
for (int i = 0; i < allIndices.size(); i++) {
for (int i = 0; i < list.size(); i++) { resultArray[i] = allIndices.get(i);
int value = list.get(i);
int insertIndex = 0;
while (insertIndex < sorted.size()) {
if (sorted.get(insertIndex) > value) {
break;
}
insertIndex++;
}
MyList<Integer> 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) { return resultArray;
int processors = Runtime.getRuntime().availableProcessors(); }
return Math.min(processors, size);
}
private int countChunkSize(int size, int threadCount) { private void sortList(MyList<Integer> list) {
if (threadCount == 0) return 0; if (list.size() <= 1) return;
return (size + threadCount - 1) / threadCount;
}
private MyList<Integer> findInRange(MyList<Student> students, Student target, int fromIndex, int toIndex) { MyList<Integer> sorted = new MyLinkedList<>();
MyList<Integer> foundIndices = new MyLinkedList<>();
for (int i = fromIndex; i < toIndex; i++) { for (int i = 0; i < list.size(); i++) {
Student current = students.get(i); int value = list.get(i);
if (current != null && current.equals(target)) { int insertIndex = 0;
foundIndices.add(i); while (insertIndex < sorted.size()) {
} if (sorted.get(insertIndex) > value) {
break;
} }
insertIndex++;
}
return foundIndices; MyList<Integer> 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<Integer> findInRange(
MyList<Student> students, Student target, int fromIndex, int toIndex) {
MyList<Integer> 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;
}
} }
@@ -25,9 +25,9 @@ public class StudentCsvReader implements Iterator<Student> {
private int lineOfFile; private int lineOfFile;
public StudentCsvReader(String absoluteFilePath) { public StudentCsvReader(Path path2) {
lineOfFile = 0; lineOfFile = 0;
Path path = Paths.get(absoluteFilePath); Path path = Paths.get(path2);
if (!path.isAbsolute()) { if (!path.isAbsolute()) {
throw new IllegalArgumentException("File path must be absolute"); throw new IllegalArgumentException("File path must be absolute");
} }
@@ -1,30 +1,30 @@
package ru.project.search; package ru.project.search;
import ru.project.list.MyList; import ru.project.collection.MyLinkedList;
import ru.project.list.MyLinkedList; import ru.project.collection.MyList;
import ru.project.student.Student; import ru.project.student.Student;
public class StudentSearchService { public class StudentSearchService {
private final StudentSearchCriteria criteria; private final StudentSearchCriteria criteria;
public StudentSearchService(StudentSearchCriteria criteria) { public StudentSearchService(StudentSearchCriteria criteria) {
if (criteria == null) { if (criteria == null) {
throw new IllegalArgumentException("Criteria must not be null"); throw new IllegalArgumentException("Criteria must not be null");
}
this.criteria = criteria;
} }
this.criteria = criteria;
}
public MyList<Student> find(MyList<Student> students) { public MyList<Student> find(MyList<Student> students) {
if (students == null) { if (students == null) {
return new MyLinkedList<>(); return new MyLinkedList<>();
}
MyList<Student> 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;
} }
} MyList<Student> 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;
}
}
@@ -1,130 +1,138 @@
package ru.test.maven.spring; package ru.project.collection;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class MyLinkedListTest
{
@Test
public void shouldTestAdd() {
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(10);
list.add(20);
list.add(30);
assertEquals(10, list.get(0)); import org.junit.jupiter.api.Test;
assertEquals(20, list.get(1));
assertEquals(30, list.get(2));
}
@Test
public void shouldTestGet()
{
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(10);
assertEquals(10, list.get(0));
}
@Test
public void shouldTestRemove() {
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(10);
list.add(20);
list.add(30);
list.remove(0);
assertEquals(2, list.size()); public class MyLinkedListTest {
assertEquals(20, list.get(0)); @Test
assertEquals(30, list.get(1)); public void shouldTestAdd() {
} MyLinkedList<Integer> list = new MyLinkedList<>();
@Test list.add(10);
void shouldTestSet() { list.add(20);
MyLinkedList<String> list = new MyLinkedList<>(); list.add(30);
list.add("A");
list.add("B");
list.add("C");
String oldValue = list.set(1, "Z"); assertEquals(10, list.get(0));
assertEquals(20, list.get(1));
assertEquals(30, list.get(2));
}
assertEquals("B", oldValue); @Test
assertEquals("Z", list.get(1)); public void shouldTestGet() {
assertEquals(3, list.size()); MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(10);
assertEquals(10, list.get(0));
}
} @Test
@Test public void shouldTestRemove() {
void shouldTestSize() MyLinkedList<Integer> list = new MyLinkedList<>();
{ list.add(10);
MyLinkedList<Integer> list = new MyLinkedList<>(); list.add(20);
list.add(1); list.add(30);
list.add(2); list.remove(0);
list.add(3);
assertEquals(3, list.size());
}
@Test
void shouldTestisEmpty()
{
MyLinkedList<Integer> list = new MyLinkedList<>();
assertTrue(list.isEmpty());
}
@Test
void shouldTestGet_OutOfBounds_ThrowsException() {
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(1);
assertThrows(IllegalArgumentException.class, () -> list.get(-1)); assertEquals(2, list.size());
assertThrows(IllegalArgumentException.class, () -> list.get(1)); // index == size assertEquals(20, list.get(0));
assertThrows(IllegalArgumentException.class, () -> list.get(5)); // index > size assertEquals(30, list.get(1));
} }
@Test
void shouldTestSet_OutOfBounds_ThrowsException() {
MyLinkedList<Integer> list = new MyLinkedList<>();
list.add(1);
assertThrows(IllegalArgumentException.class, () -> list.set(-1, 99)); @Test
assertThrows(IllegalArgumentException.class, () -> list.set(1, 99)); void shouldTestSet() {
} MyLinkedList<String> list = new MyLinkedList<>();
@Test list.add("A");
void shouldTestRemove_IndexGreaterThanSize_ThrowsException() { list.add("B");
MyLinkedList<String> list = new MyLinkedList<>(); list.add("C");
list.add("man");
assertThrows(IndexOutOfBoundsException.class, () -> list.remove(5));
}
@Test
void shouldTestRemove_NegativeIndex_ThrowsException() {
MyLinkedList<String> list = new MyLinkedList<>();
list.add("1");
list.add("2");
assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1)); String oldValue = list.set(1, "Z");
}
@Test
void shouldTestaddAll_nonEmptySource_toEmptyList_addsAllElementsInOrder() {
MyList<String> list = new MyLinkedList<>();
MyList<String> source = new MyLinkedList<>();
source.add("A");
source.add("B");
source.add("C");
list.addAll(source); assertEquals("B", oldValue);
assertEquals("Z", list.get(1));
assertEquals(3, list.size());
}
assertEquals(3, list.size()); @Test
assertEquals("A", list.get(0)); void shouldTestSize() {
assertEquals("B", list.get(1)); MyLinkedList<Integer> list = new MyLinkedList<>();
assertEquals("C", list.get(2)); list.add(1);
} list.add(2);
list.add(3);
assertEquals(3, list.size());
}
@Test @Test
void shouldTestaddAll_toNonEmptyList_appendsAtEnd() { void shouldTestisEmpty() {
MyList<String> list = new MyLinkedList<>(); MyLinkedList<Integer> list = new MyLinkedList<>();
list.add("X"); assertTrue(list.isEmpty());
list.add("Y"); }
MyList<String> source = new MyLinkedList<>(); @Test
source.add("A"); void shouldTestGet_OutOfBounds_ThrowsException() {
source.add("B"); MyLinkedList<Integer> 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()); @Test
assertEquals("X", list.get(0)); void shouldTestSet_OutOfBounds_ThrowsException() {
assertEquals("Y", list.get(1)); MyLinkedList<Integer> list = new MyLinkedList<>();
assertEquals("A", list.get(2)); list.add(1);
assertEquals("B", list.get(3));
} assertThrows(IllegalArgumentException.class, () -> list.set(-1, 99));
assertThrows(IllegalArgumentException.class, () -> list.set(1, 99));
}
@Test
void shouldTestRemove_IndexGreaterThanSize_ThrowsException() {
MyLinkedList<String> list = new MyLinkedList<>();
list.add("man");
assertThrows(IndexOutOfBoundsException.class, () -> list.remove(5));
}
@Test
void shouldTestRemove_NegativeIndex_ThrowsException() {
MyLinkedList<String> list = new MyLinkedList<>();
list.add("1");
list.add("2");
assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
}
@Test
void shouldTestaddAll_nonEmptySource_toEmptyList_addsAllElementsInOrder() {
MyList<String> list = new MyLinkedList<>();
MyList<String> 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<String> list = new MyLinkedList<>();
list.add("X");
list.add("Y");
MyList<String> 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));
}
} }
@@ -1,64 +1,58 @@
package ru.test.maven.spring; package ru.project.collectors;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import java.util.Set; import java.util.Set;
import java.util.stream.Collector; import java.util.stream.Collector;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.Collections; import org.junit.jupiter.api.Test;
import ru.project.collection.MyList;
public class MyListCollectorTest public class MyListCollectorTest {
{ private final MyListCollector<Integer> collector = new MyListCollector<>();
private final MyListCollector<Integer> collector = new MyListCollector<>();
@Test @Test
void shouldTestCollectInOrderSequential() { void shouldTestCollectInOrderSequential() {
MyList<Integer> result = IntStream.range(0, 10) MyList<Integer> result = IntStream.range(0, 10).boxed().collect(MyCollectors.toMyList());
.boxed()
.collect(MyCollectors.toMyList());
assertEquals(10, result.size());
for (int i = 0; i < result.size(); i++) {
assertEquals(i, (int) result.get(i));
}
assertEquals(10, result.size());
for (int i = 0; i < result.size(); i++) {
assertEquals(i, (int) result.get(i));
} }
}
@Test @Test
void shouldTestCollectInOrderParallel() { void shouldTestCollectInOrderParallel() {
MyList<Integer> result = IntStream.range(0, 100) MyList<Integer> result =
.parallel() IntStream.range(0, 100).parallel().boxed().collect(MyCollectors.toMyList());
.boxed()
.collect(MyCollectors.toMyList());
assertEquals(100, result.size()); assertEquals(100, result.size());
for (int i = 0; i < result.size(); i++) { for (int i = 0; i < result.size(); i++) {
assertEquals(i, (int) result.get(i)); assertEquals(i, (int) result.get(i));
}
} }
}
@Test @Test
void shouldTestHandleEmptyStream() { void shouldTestHandleEmptyStream() {
MyList<Integer> result = IntStream.empty() MyList<Integer> result = IntStream.empty().boxed().collect(MyCollectors.toMyList());
.boxed()
.collect(MyCollectors.toMyList());
assertTrue(result.isEmpty()); assertTrue(result.isEmpty());
}
} @Test
@Test void shouldTestNotUseStandardList() {
void shouldTestNotUseStandardList() { MyList<String> result =
MyList<String> result = IntStream.range(0, 5) IntStream.range(0, 5).mapToObj(i -> "item" + i).collect(MyCollectors.toMyList());
.mapToObj(i -> "item" + i)
.collect(MyCollectors.toMyList());
assertInstanceOf(MyList.class, result); assertInstanceOf(MyList.class, result);
assertFalse(result instanceof java.util.List); assertFalse(result instanceof java.util.List);
} }
@Test
void shouldTestHaveCorrectCharacteristics() {
Set<Collector.Characteristics> characteristics = collector.characteristics();
assertTrue(characteristics.contains(java.util.stream.Collector.Characteristics.IDENTITY_FINISH));
assertFalse(characteristics.contains(java.util.stream.Collector.Characteristics.UNORDERED));
}
@Test
void shouldTestHaveCorrectCharacteristics() {
Set<Collector.Characteristics> characteristics = collector.characteristics();
assertTrue(
characteristics.contains(java.util.stream.Collector.Characteristics.IDENTITY_FINISH));
assertFalse(characteristics.contains(java.util.stream.Collector.Characteristics.UNORDERED));
}
} }
@@ -1,134 +1,137 @@
package ru.project.finder; package ru.project.finder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class StudentOccurrenceIndexFinderTest import org.junit.jupiter.api.BeforeEach;
{ import org.junit.jupiter.api.Test;
private StudentOccurrenceIndexFinder finder; import ru.project.collection.MyLinkedList;
private MyList<Student> students; import ru.project.collection.MyList;
import ru.project.student.Student;
@BeforeEach public class StudentOccurrenceIndexFinderTest {
void setUp() { private StudentOccurrenceIndexFinder finder;
finder = new StudentOccurrenceIndexFinder(); private MyList<Student> students;
students = new MyLinkedList<>();
}
@Test @BeforeEach
void shouldTesfindOccurrences_emptyList_returnsEmptyArray() { void setUp() {
int[] result = finder.findOccurrences(students, new Student("A12", 4.5, 1)); finder = new StudentOccurrenceIndexFinder();
assertEquals(0, result.length); students = new MyLinkedList<>();
} }
@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); // такого нет
int[] result = finder.findOccurrences(students, target); @Test
assertEquals(0, result.length); void shouldTesfindOccurrences_emptyList_returnsEmptyArray() {
} int[] result = finder.findOccurrences(students, new Student("A12", 4.5, 1));
@Test assertEquals(0, result.length);
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));
Student target = new Student("B23", 3.5, 102); @Test
int[] result = finder.findOccurrences(students, target); 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); int[] result = finder.findOccurrences(students, target);
assertEquals(1, result[0]); assertEquals(0, result.length);
} }
@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
Student target = new Student("A12", 4.5, 101); @Test
int[] result = finder.findOccurrences(students, target); 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); Student target = new Student("B23", 3.5, 102);
assertArrayEquals(new int[]{0, 2, 4}, result); int[] result = finder.findOccurrences(students, target);
}
@Test assertEquals(1, result.length);
void shouldTesfindOccurrences_allElementsMatch_returnsAllIndices() { assertEquals(1, result[0]);
Student s = new Student("X99", 5.0, 999); }
students.add(s);
students.add(s);
students.add(s);
int[] result = finder.findOccurrences(students, s); @Test
assertEquals(3, result.length); void shouldTesfindOccurrences_multipleMatches_returnsAllIndicesSorted() {
assertArrayEquals(new int[]{0, 1, 2}, result); // индексы: 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 Student target = new Student("A12", 4.5, 101);
void shouldTesfindOccurrences_differentAverageGrade_noMatch() { int[] result = finder.findOccurrences(students, target);
students.add(new Student("A12", 4.50, 101));
Student target = new Student("A12", 4.51, 101); // отличается балл
int[] result = finder.findOccurrences(students, target); assertEquals(3, result.length);
assertEquals(0, 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)); students.add(new Student("A12", 4.5, 101));
Student target = new Student("B12", 4.5, 101); // другая группа } else {
students.add(new Student(group, grade, 200 + i));
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 for (int i = 1; i < result.length; i++) {
void shouldTesfindOccurrences_differentRecordBookNumber_noMatch() { assertTrue(result[i] > result[i - 1], "Результат должен быть отсортирован");
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], "Результат должен быть отсортирован");
}
} }
}
} }
@@ -6,14 +6,14 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import ru.project.student.Student; import ru.project.student.Student;
class StudentCsvReaderTest { class StudentCsvReaderTest {
@@ -23,17 +23,12 @@ class StudentCsvReaderTest {
// Testing StudentCsvReader // Testing StudentCsvReader
@BeforeAll @BeforeAll
void generateStudentTestFile(){ void generateStudentTestFile() {
studentPath = tempDir.resolve("students.csv"); studentPath = tempDir.resolve("students.csv");
Files.write( Files.write(
studentPath, studentPath,
new String[]{ new String[] {"groupNumber,averageGrade,recordBookNumber", "A21,5.0,331", "A21,4.0,332"},
"groupNumber,averageGrade,recordBookNumber", StandardCharsets.UTF_8);
"A21,5.0,331",
"A21,4.0,332"
},
StandardCharsets.UTF_8
);
} }
@BeforeEach @BeforeEach
@@ -44,14 +39,12 @@ class StudentCsvReaderTest {
@Test @Test
void readerTestRejectRelativePath() { void readerTestRejectRelativePath() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class, () -> new StudentCsvReader(studentPath.toString()));
() -> new StudentCsvReader(studentPath.toString()));
} }
@Test @Test
void readerRejectPathIsDir() { void readerRejectPathIsDir() {
assertThrows( assertThrows(UncheckedIOException.class, () -> new StudentCsvReader(tempDir.toAbsolutePath()));
UncheckedIOException.class, () -> new StudentCsvReader(tempDir.toAbsolutePath()));
} }
@Test @Test
@@ -110,15 +103,10 @@ class StudentCsvReaderTest {
() -> { () -> {
Path path = tempDir.resolve("fewparameters.csv"); Path path = tempDir.resolve("fewparameters.csv");
Files.write( Files.write(
path, path,
new String[]{ new String[] {"groupNumber,averageGrade,recordBookNumber", "A21,5.0"},
"groupNumber,averageGrade,recordBookNumber", StandardCharsets.UTF_8);
"A21,5.0" StudentCsvReader reader = new StudentCsvReader(path.toAbsolutePath().toString());
},
StandardCharsets.UTF_8
);
StudentCsvReader reader =
new StudentCsvReader(path.toAbsolutePath().toString());
Student student = reader.next(); Student student = reader.next();
}); });
} }
@@ -130,16 +118,12 @@ class StudentCsvReaderTest {
() -> { () -> {
Path path = tempDir.resolve("invalid_groupnumber.csv"); Path path = tempDir.resolve("invalid_groupnumber.csv");
Files.write( Files.write(
path, path,
new String[]{ new String[] {
"groupNumber,averageGrade,recordBookNumber", "groupNumber,averageGrade,recordBookNumber", "AAA,5.0,331", "A21,4.0,332"
"AAA,5.0,331", },
"A21,4.0,332" StandardCharsets.UTF_8);
}, StudentCsvReader reader = new StudentCsvReader(path.toAbsolutePath().toString());
StandardCharsets.UTF_8
);
StudentCsvReader reader =
new StudentCsvReader(path.toAbsolutePath().toString());
Student student = reader.next(); Student student = reader.next();
}); });
} }
@@ -151,16 +135,12 @@ class StudentCsvReaderTest {
() -> { () -> {
Path path = tempDir.resolve("invalid_averagegrade.csv"); Path path = tempDir.resolve("invalid_averagegrade.csv");
Files.write( Files.write(
path, path,
new String[]{ new String[] {
"groupNumber,averageGrade,recordBookNumber", "groupNumber,averageGrade,recordBookNumber", "A21,-5.0,331", "A21,4.0,332"
"A21,-5.0,331", },
"A21,4.0,332" StandardCharsets.UTF_8);
}, StudentCsvReader reader = new StudentCsvReader(path.toAbsolutePath().toString());
StandardCharsets.UTF_8
);
StudentCsvReader reader =
new StudentCsvReader(path.toAbsolutePath().toString());
Student student = reader.next(); Student student = reader.next();
}); });
} }
@@ -172,38 +152,30 @@ class StudentCsvReaderTest {
() -> { () -> {
Path path = tempDir.resolve("invalid_recordbooknumber.csv"); Path path = tempDir.resolve("invalid_recordbooknumber.csv");
Files.write( Files.write(
path, path,
new String[]{ new String[] {
"groupNumber,averageGrade,recordBookNumber", "groupNumber,averageGrade,recordBookNumber", "A21,5.0,-331", "A21,4.0,332"
"A21,5.0,-331", },
"A21,4.0,332" StandardCharsets.UTF_8);
}, StudentCsvReader reader = new StudentCsvReader(path.toAbsolutePath().toString());
StandardCharsets.UTF_8
);
StudentCsvReader reader =
new StudentCsvReader(path.toAbsolutePath().toString());
Student student = reader.next(); Student student = reader.next();
}); });
} }
@Test @Test
void testInvalidHeader(){ void testInvalidHeader() {
assertThrows( assertThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
() -> { () -> {
Path path = tempDir.resolve("invalid_header.csv"); Path path = tempDir.resolve("invalid_header.csv");
Files.write( Files.write(
path, path,
new String[]{ new String[] {
"groupNumber,averageGrade,recordBookNomber", "groupNumber,averageGrade,recordBookNomber", "A21,5.0,-331", "A21,4.0,332"
"A21,5.0,-331", },
"A21,4.0,332" StandardCharsets.UTF_8);
}, StudentCsvReader reader = new StudentCsvReader(path.toAbsolutePath().toString());
StandardCharsets.UTF_8 Student student = reader.next();
); });
StudentCsvReader reader =
new StudentCsvReader(path.toAbsolutePath().toString());
Student student = reader.next();
});
} }
} }
@@ -1,314 +1,317 @@
package ru.project.search; 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 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 { class StudentSearchTest {
@Test @Test
void testGroupNumberRangeMatchesInside() { void testGroupNumberRangeMatchesInside() {
StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30"); StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30");
Student student = new Student("B20", 4.5, 123); Student student = new Student("B20", 4.5, 123);
assertTrue(criteria.matches(student)); 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<Student> 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<Student> result = service.find(students);
assertEquals(2, result.size());
assertEquals("A10", result.get(0).getGroupNumber());
assertEquals("C30", result.get(1).getGroupNumber());
}
@Test
void testSearchServiceEmptyResult() {
MyList<Student> 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<Student> result = service.find(students);
assertEquals(0, result.size());
}
@Test
void testSearchServiceEmptyCollection() {
MyList<Student> students = new MyLinkedList<>();
StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
StudentSearchService service = new StudentSearchService(criteria);
MyList<Student> result = service.find(students);
assertEquals(0, result.size());
}
@Test
void testSearchServicePreservesOrder() {
MyList<Student> 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<Student> 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<Student> original = new MyLinkedList<>();
original.add(new Student("A10", 4.5, 1));
original.add(new Student("B20", 3.8, 2));
MyList<Student> copy = new MyLinkedList<>();
for (int i = 0; i < original.size(); i++) {
copy.add(original.get(i));
} }
@Test StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
void testGroupNumberRangeMatchesLowerBoundary() { StudentSearchService service = new StudentSearchService(criteria);
StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30"); service.find(original);
Student student = new Student("A10", 4.5, 123);
assertTrue(criteria.matches(student)); assertEquals(copy.size(), original.size());
for (int i = 0; i < copy.size(); i++) {
assertEquals(copy.get(i).getGroupNumber(), original.get(i).getGroupNumber());
} }
}
@Test @Test
void testGroupNumberRangeMatchesUpperBoundary() { void testSearchServiceWithNullCriteriaThrowsException() {
StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30"); assertThrows(IllegalArgumentException.class, () -> new StudentSearchService(null));
Student student = new Student("C30", 4.5, 123); }
assertTrue(criteria.matches(student));
}
@Test @Test
void testGroupNumberRangeDoesNotMatchOutside() { void testSearchServiceWithCompositeCriteria() {
StudentSearchCriteria criteria = new GroupNumberRangeCriteria("A10", "C30"); MyList<Student> students = new MyLinkedList<>();
Student student = new Student("D00", 4.5, 123); students.add(new Student("A10", 4.5, 1));
assertFalse(criteria.matches(student)); students.add(new Student("B20", 4.5, 2));
} students.add(new Student("C30", 3.5, 3));
@Test CompositeStudentSearchCriteria composite =
void testGroupNumberRangeInvalidMinMaxThrowsException() { new CompositeStudentSearchCriteria(SearchOperation.INTERSECTION);
assertThrows(IllegalArgumentException.class, composite.add(new GroupNumberRangeCriteria("A10", "B20"));
() -> new GroupNumberRangeCriteria("C30", "A10")); composite.add(new AverageGradeRangeCriteria(4.0, 5.0));
}
@Test StudentSearchService service = new StudentSearchService(composite);
void testGroupNumberRangeNullValuesThrowsException() { MyList<Student> result = service.find(students);
assertThrows(IllegalArgumentException.class,
() -> new GroupNumberRangeCriteria(null, "A10"));
assertThrows(IllegalArgumentException.class,
() -> new GroupNumberRangeCriteria("A10", null));
}
@Test assertEquals(2, result.size());
void testAverageGradeRangeMatchesInside() { assertEquals("A10", result.get(0).getGroupNumber());
StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0); assertEquals("B20", result.get(1).getGroupNumber());
Student student = new Student("A12", 4.5, 123); }
assertTrue(criteria.matches(student));
}
@Test @Test
void testAverageGradeRangeMatchesLowerBoundary() { void testSearchServiceWithNullStudentListReturnsEmpty() {
StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0); StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
Student student = new Student("A12", 4.0, 123); StudentSearchService service = new StudentSearchService(criteria);
assertTrue(criteria.matches(student)); MyList<Student> result = service.find(null);
} assertNotNull(result);
assertEquals(0, result.size());
@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<Student> 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<Student> result = service.find(students);
assertEquals(2, result.size());
assertEquals("A10", result.get(0).getGroupNumber());
assertEquals("C30", result.get(1).getGroupNumber());
}
@Test
void testSearchServiceEmptyResult() {
MyList<Student> 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<Student> result = service.find(students);
assertEquals(0, result.size());
}
@Test
void testSearchServiceEmptyCollection() {
MyList<Student> students = new MyLinkedList<>();
StudentSearchCriteria criteria = new AverageGradeRangeCriteria(4.0, 5.0);
StudentSearchService service = new StudentSearchService(criteria);
MyList<Student> result = service.find(students);
assertEquals(0, result.size());
}
@Test
void testSearchServicePreservesOrder() {
MyList<Student> 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<Student> 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<Student> original = new MyLinkedList<>();
original.add(new Student("A10", 4.5, 1));
original.add(new Student("B20", 3.8, 2));
MyList<Student> 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<Student> 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<Student> 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<Student> result = service.find(null);
assertNotNull(result);
assertEquals(0, result.size());
}
}