Merge pull request into develop from feature/datasource
This commit is contained in:
@@ -42,6 +42,12 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-csv</artifactId>
|
||||||
|
<version>1.14.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.googlecode.lanterna</groupId>
|
<groupId>com.googlecode.lanterna</groupId>
|
||||||
<artifactId>lanterna</artifactId>
|
<artifactId>lanterna</artifactId>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<Student>, 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<CSVRecord> 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<String, Integer> 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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], "Результат должен быть отсортирован");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<Student> 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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user