Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .coverage_history
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9846341092347483
0.9849253731343284
2 changes: 1 addition & 1 deletion .github/badges/branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package dev.sorn.fmp4j.exceptions;

public class FmpInvalidPartException extends FmpException {
public FmpInvalidPartException(String message, Object... args) {
super(message, args);
}
}
77 changes: 77 additions & 0 deletions src/main/java/dev/sorn/fmp4j/types/FmpPart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package dev.sorn.fmp4j.types;

import static java.lang.Integer.parseInt;
import static java.lang.String.valueOf;
import static java.util.Objects.compare;

import dev.sorn.fmp4j.exceptions.FmpInvalidPartException;
import java.io.Serial;

public final class FmpPart implements Comparable<FmpPart>, FmpValueObject<Integer> {
public static final int MIN_VALUE = 0;
public static final int MAX_VALUE = 1000;

@Serial
private static final long serialVersionUID = 1L;

private final int value;

private FmpPart(int value) {
this.value = value;
}

public static FmpPart part(String value) {
try {
return part(parseInt(value));
} catch (NumberFormatException e) {
throw new FmpInvalidPartException("[%s] is not a valid integer value", value);
}
}

public static FmpPart part(int value) {
if (value < MIN_VALUE) {
throw new FmpInvalidPartException("[%d] is below the minimum allowed value [%d]", value, MIN_VALUE);
}
if (value > MAX_VALUE) {
throw new FmpInvalidPartException("[%d] exceeds the maximum allowed value [%d]", value, MAX_VALUE);
}
return new FmpPart(value);
}

@Override
public Integer value() {
return value;
}

@Override
public String toString() {
return valueOf(value);
}

@Override
public int hashCode() {
return value;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof FmpPart that)) {
return false;
}
return this.value == that.value;
}

@Override
public int compareTo(FmpPart that) {
if (that == null) {
throw new FmpInvalidPartException("'that.value' is required");
}
return compare(this.value, that.value, Integer::compareTo);
}
}
190 changes: 190 additions & 0 deletions src/test/java/dev/sorn/fmp4j/types/FmpPartTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package dev.sorn.fmp4j.types;

import static dev.sorn.fmp4j.types.FmpPart.MAX_VALUE;
import static dev.sorn.fmp4j.types.FmpPart.MIN_VALUE;
import static dev.sorn.fmp4j.types.FmpPart.part;
import static java.lang.String.format;
import static java.lang.String.valueOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import dev.sorn.fmp4j.exceptions.FmpInvalidPartException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class FmpPartTest {
@ParameterizedTest
@ValueSource(ints = {0, 1000, 954, 241, 741, 2, 15})
void valid_part(int part) {
// given // when
var p = part(part);

// then
assertEquals(part, p.value());
}

@Test
void below_minimum_part() {
// given
var p = -1;

// when // then
var e = assertThrows(FmpInvalidPartException.class, () -> part(p));
assertEquals(format("[%d] is below the minimum allowed value [%d]", p, MIN_VALUE), e.getMessage());
}

@Test
void exceeds_maximum_year() {
// given
var p = 1001;

// when // then
var e = assertThrows(FmpInvalidPartException.class, () -> part(p));
assertEquals(format("[%d] exceeds the maximum allowed value [%d]", p, MAX_VALUE), e.getMessage());
}

@Test
void string_value_not_int() {
// given
var p = "199X";

// when // then
var e = assertThrows(FmpInvalidPartException.class, () -> part(p));
assertEquals(format("[%s] is not a valid integer value", p), e.getMessage());
}

@ParameterizedTest
@ValueSource(ints = {1000, 999, 998, 10, 9})
void toString_returns_value(int part) {
// given // when
var p = part(part);

// then
assertEquals(p.toString(), valueOf(part));
}

@Test
void hashCode_value() {
// given
var part = 999;
var p = part(part);

// when
var hc = p.hashCode();

// then
assertEquals(part, hc);
}

@Test
void equals_same_true() {
// given
var p = part(1);

// when
var eq = p.equals(p);

assertTrue(eq);
}

@Test
void equals_identical_true() {
// given
var p1 = part(1000);
var p2 = part(1000);

// when
var eq = p1.equals(p2);

assertTrue(eq);
}

@Test
void equals_null_false() {
// given
var p1 = part(1000);
var p2 = (FmpPart) null;

// when
var eq = p1.equals(p2);

assertFalse(eq);
}

@Test
void equals_different_false() {
// given
var p1 = part(1000);
var p2 = part(999);

// when
var eq = p1.equals(p2);

assertFalse(eq);
}

@Test
void equals_wrong_instance_false() {
// given
var p1 = part(999);
var p2 = 999;

// when
var eq = p1.equals(p2);

assertFalse(eq);
}

@Test
void compareTo_null_throws() {
// given
var p1 = part("999");
var p2 = (FmpPart) null;

// when // then
var e = assertThrows(FmpInvalidPartException.class, () -> p1.compareTo(p2));
assertEquals("'that.value' is required", e.getMessage());
}

@Test
void compareTo_less_than() {
// given
var p1 = part("1");
var p2 = part("999");

// when
int cmp = p1.compareTo(p2);

// then
assertEquals(-1, cmp);
}

@Test
void compareTo_greater_than() {
// given
var p1 = part("999");
var p2 = part("1");

// when
int cmp = p1.compareTo(p2);

// then
assertEquals(1, cmp);
}

@Test
void compareTo_equal() {
// given
var p1 = part("1");
var p2 = part("1");

// when
int cmp = p1.compareTo(p2);

// then
assertEquals(0, cmp);
}
}