Merge branch 'feature/student' into feature/even-only-merge-sort

This commit is contained in:
2026-08-28 12:12:17 +04:00
3 changed files with 267 additions and 0 deletions
@@ -0,0 +1,96 @@
package ru.project.student;
import java.util.Objects;
public class Student {
public static final double MIN_AVERAGE_GRADE = 0.0;
public static final double MAX_AVERAGE_GRADE = 5.0;
public static final int MIN_RECORD_BOOK_NUMBER = 1;
public static final String GROUP_NUMBER_PATTERN = "^[A-Z][0-9]{2}$";
private final String groupNumber;
private final double averageGrade;
private final int recordBookNumber;
public Student(String groupNumber, double averageGrade, int recordBookNumber) {
if (groupNumber == null || !groupNumber.matches(GROUP_NUMBER_PATTERN)) {
throw new IllegalArgumentException(
"Group number must match pattern: " + GROUP_NUMBER_PATTERN);
}
if (averageGrade < MIN_AVERAGE_GRADE || averageGrade > MAX_AVERAGE_GRADE) {
throw new IllegalArgumentException(
"Average grade must be between " + MIN_AVERAGE_GRADE + " and " + MAX_AVERAGE_GRADE);
}
if (recordBookNumber < MIN_RECORD_BOOK_NUMBER) {
throw new IllegalArgumentException(
"Record book number must be at least " + MIN_RECORD_BOOK_NUMBER);
}
this.groupNumber = groupNumber;
this.averageGrade = averageGrade;
this.recordBookNumber = recordBookNumber;
}
public String getGroupNumber() {
return groupNumber;
}
public double getAverageGrade() {
return averageGrade;
}
public int getRecordBookNumber() {
return recordBookNumber;
}
public Student withGroupNumber(String groupNumber) {
return new Student(groupNumber, this.averageGrade, this.recordBookNumber);
}
public Student withAverageGrade(double averageGrade) {
return new Student(this.groupNumber, averageGrade, this.recordBookNumber);
}
public Student withRecordBookNumber(int recordBookNumber) {
return new Student(this.groupNumber, this.averageGrade, recordBookNumber);
}
public static double getMaxAverageGrade() {
return MAX_AVERAGE_GRADE;
}
public static int getMinRecordBookNumber() {
return MIN_RECORD_BOOK_NUMBER;
}
public static String getGroupNumberPattern() {
return GROUP_NUMBER_PATTERN;
}
public String toString() {
return "Student{" +
"groupNumber='" + groupNumber + '\'' +
", averageGrade=" + averageGrade +
", recordBookNumber=" + recordBookNumber +
'}';
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Student student = (Student) obj;
return Double.compare(averageGrade, student.averageGrade) == 0
&& recordBookNumber == student.recordBookNumber
&& Objects.equals(groupNumber, student.groupNumber);
}
@Override
public int hashCode() {
return Objects.hash(groupNumber, averageGrade, recordBookNumber);
}
}
@@ -0,0 +1,26 @@
package ru.project.student;
public class StudentBuilder {
private String groupNumber;
private double averageGrade;
private int recordBookNumber;
public StudentBuilder setGroupNumber(String groupNumber) {
this.groupNumber = groupNumber;
return this;
}
public StudentBuilder setAverageGrade(double averageGrade) {
this.averageGrade = averageGrade;
return this;
}
public StudentBuilder setRecordBookNumber(int recordBookNumber) {
this.recordBookNumber = recordBookNumber;
return this;
}
public Student build() {
return new Student(groupNumber, averageGrade, recordBookNumber);
}
}
@@ -0,0 +1,145 @@
package ru.project.student;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
class StudentTest {
@Test
void testValidStudentCreation() {
Student student = new Student("A12", 4.5, 12345);
assertEquals("A12", student.getGroupNumber());
assertEquals(4.5, student.getAverageGrade());
assertEquals(12345, student.getRecordBookNumber());
}
@Test
void testValidGroupNumbers() {
assertDoesNotThrow(() -> new Student("A12", 4.5, 1));
assertDoesNotThrow(() -> new Student("B32", 4.5, 1));
assertDoesNotThrow(() -> new Student("Z00", 4.5, 1));
}
@Test
void testInvalidGroupNumbers() {
assertThrows(IllegalArgumentException.class, () -> new Student("a12", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("A1", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("A123", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("AA1", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("а1А", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("аа!!а123", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("23фи!12", 4.5, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("№№###*()", 4.5, 1));
}
@Test
void testValidAverageGrades() {
assertDoesNotThrow(() -> new Student("A12", 0.0, 1));
assertDoesNotThrow(() -> new Student("A12", 5.0, 1));
}
@Test
void testInvalidAverageGrades() {
assertThrows(IllegalArgumentException.class, () -> new Student("A12", -1.0, 1));
assertThrows(IllegalArgumentException.class, () -> new Student("A12", 6.0, 1));
}
@Test
void testValidRecordBookNumbers() {
assertDoesNotThrow(() -> new Student("A12", 4.5, 1));
assertDoesNotThrow(() -> new Student("A12", 4.5, 12345));
}
@Test
void testInvalidRecordBookNumbers() {
assertThrows(IllegalArgumentException.class, () -> new Student("A12", 4.5, 0));
assertThrows(IllegalArgumentException.class, () -> new Student("A12", 4.5, -1));
}
@Test
void testWithGroupNumber() {
Student original = new Student("A12", 4.5, 12345);
Student updated = original.withGroupNumber("B32");
assertNotSame(original, updated);
assertEquals("B32", updated.getGroupNumber());
assertEquals(4.5, updated.getAverageGrade());
assertEquals(12345, updated.getRecordBookNumber());
assertEquals("A12", original.getGroupNumber());
}
@Test
void testWithAverageGrade() {
Student original = new Student("A12", 4.5, 12345);
Student updated = original.withAverageGrade(4.8);
assertNotSame(original, updated);
assertEquals(4.8, updated.getAverageGrade());
assertEquals("A12", updated.getGroupNumber());
assertEquals(12345, updated.getRecordBookNumber());
assertEquals(4.5, original.getAverageGrade());
}
@Test
void testWithRecordBookNumber() {
Student original = new Student("A12", 4.5, 12345);
Student updated = original.withRecordBookNumber(99999);
assertNotSame(original, updated);
assertEquals(99999, updated.getRecordBookNumber());
assertEquals("A12", updated.getGroupNumber());
assertEquals(4.5, updated.getAverageGrade());
assertEquals(12345, original.getRecordBookNumber());
}
@Test
void testWithInvalidGroupNumber() {
Student original = new Student("A12", 4.5, 12345);
assertThrows(IllegalArgumentException.class,
() -> original.withGroupNumber("a12"));
assertEquals("A12", original.getGroupNumber()); // не изменился
}
@Test
void testWithInvalidAverageGrade() {
Student original = new Student("A12", 4.5, 12345);
assertThrows(IllegalArgumentException.class,
() -> original.withAverageGrade(6.0));
assertEquals(4.5, original.getAverageGrade());
}
@Test
void testWithInvalidRecordBookNumber() {
Student original = new Student("A12", 4.5, 12345);
assertThrows(IllegalArgumentException.class,
() -> original.withRecordBookNumber(0));
assertEquals(12345, original.getRecordBookNumber());
}
@Test
void testEqualsAndHashCode() {
Student s1 = new Student("A12", 4.5, 12345);
Student s2 = new Student("A12", 4.5, 12345);
Student s3 = new Student("B32", 4.5, 12345);
Student s4 = new Student("A12", 4.8, 12345);
Student s5 = new Student("A12", 4.5, 99999);
assertEquals(s1, s2);
assertEquals(s1.hashCode(), s2.hashCode());
assertNotEquals(s1, s3);
assertNotEquals(s1, s4);
assertNotEquals(s1, s5);
assertNotEquals(s1, null);
assertNotEquals(s1, "some string");
}
}