package noventaenovediasdejava.dia01;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class NumeroRacionalTest {
@Test
void test() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual á 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
}
package noventaenovediasdejava.dia01;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual à 0");
}
}
}
package noventaenovediasdejava.dia02;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
}
package noventaenovediasdejava.dia02;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
}
package noventaenovediasdejava.dia03;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
public NumeroRacional formaIrredutivel() {
int numero = Math.abs(this.numerador);
int maximoDivisorComum = Math.abs(this.denominador);
int resto = 0;
do {
if (resto != 0) {
numero = maximoDivisorComum;
maximoDivisorComum = resto;
}
resto = numero % maximoDivisorComum;
} while (resto != 0);
return new NumeroRacional(
this.numerador / maximoDivisorComum,
this.denominador / maximoDivisorComum
);
}
}
package noventaenovediasdejava.dia03;
import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
@ParameterizedTest(name = "[{index}] a forma irredutível de {0} deve ser igual a {1}")
@MethodSource("testarFormaIrredutivelArgs")
void testarFormaIrredutivel(
final NumeroRacional numeroRacionalBase,
final NumeroRacional numeroRacionalNaFormaIrredutivelEsperado
) {
final NumeroRacional numeroRacionalNaFormaIrredutivel = numeroRacionalBase
.formaIrredutivel();
Assertions.assertNotNull(
numeroRacionalNaFormaIrredutivel,
"não deve ser retornado valor/referência nulo"
);
Assertions.assertEquals(
numeroRacionalNaFormaIrredutivelEsperado,
numeroRacionalNaFormaIrredutivel
);
}
static Stream<Arguments> testarFormaIrredutivelArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(12,4),
new NumeroRacional(3,1)
),
Arguments.arguments(
new NumeroRacional(130,78),
new NumeroRacional(5,3)
),
Arguments.arguments(
new NumeroRacional(-130,78),
new NumeroRacional(-5,3)
),
Arguments.arguments(
new NumeroRacional(130,-78),
new NumeroRacional(5,-3)
)
);
}
}
package noventaenovediasdejava.dia04;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
public NumeroRacional formaIrredutivel() {
int numero = Math.abs(this.numerador);
int maximoDivisorComum = Math.abs(this.denominador);
int resto = 0;
do {
if (resto != 0) {
numero = maximoDivisorComum;
maximoDivisorComum = resto;
}
resto = numero % maximoDivisorComum;
} while (resto != 0);
return new NumeroRacional(
this.numerador / maximoDivisorComum,
this.denominador / maximoDivisorComum
);
}
public NumeroRacional somar(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2+N2*D1
// -- + -- = ----------- =
// D1 D2 D1 * D2
int n1 = this.numerador;
int d1 = this.denominador;
int n2 = numeroRacional.numerador;
int d2 = numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
((n1 * d2) + (n2 * d1)),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
}
package noventaenovediasdejava.dia04;
import java.util.stream.Stream;
import noventaenovediasdejava.dia04.NumeroRacional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
@ParameterizedTest(name = "[{index}] a forma irredutível de {0} deve ser igual a {1}")
@MethodSource("testarFormaIrredutivelArgs")
void testarFormaIrredutivel(
final NumeroRacional numeroRacionalBase,
final NumeroRacional numeroRacionalNaFormaIrredutivelEsperado
) {
final NumeroRacional numeroRacionalNaFormaIrredutivel = numeroRacionalBase
.formaIrredutivel();
Assertions.assertNotNull(
numeroRacionalNaFormaIrredutivel,
"não deve ser retornado valor/referência nulo"
);
Assertions.assertEquals(
numeroRacionalNaFormaIrredutivelEsperado,
numeroRacionalNaFormaIrredutivel
);
}
static Stream<Arguments> testarFormaIrredutivelArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(12, 4),
new NumeroRacional(3, 1)
),
Arguments.arguments(
new NumeroRacional(130, 78),
new NumeroRacional(5, 3)
),
Arguments.arguments(
new NumeroRacional(-130, 78),
new NumeroRacional(-5, 3)
),
Arguments.arguments(
new NumeroRacional(130, -78),
new NumeroRacional(5, -3)
)
);
}
@ParameterizedTest(name = "[{index}] {0} + {1} = {2}")
@MethodSource("testarSomarArgs")
void testarSomar(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
final NumeroRacional resultadoAtual =
numeroRacional01.somar(numeroRacional02);
Assertions.
assertNotNull(resultadoAtual,
"não deve retornar valor/referência nula");
Assertions.
assertEquals(
resultadoEsperado,
resultadoAtual
);
}
static Stream<Arguments> testarSomarArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 4),
new NumeroRacional(1, 4),
new NumeroRacional(1, 2)
),
Arguments.arguments(
new NumeroRacional(2, 3),
new NumeroRacional(3, 4),
new NumeroRacional(17, 12)
),
Arguments.arguments(
new NumeroRacional(5, 3),
new NumeroRacional(4, 12),
new NumeroRacional(2, 1)
)
);
}
}
package noventaenovediasdejava.dia05;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
public NumeroRacional formaIrredutivel() {
int numero = Math.abs(this.numerador);
int maximoDivisorComum = Math.abs(this.denominador);
int resto = 0;
do {
if (resto != 0) {
numero = maximoDivisorComum;
maximoDivisorComum = resto;
}
resto = numero % maximoDivisorComum;
} while (resto != 0);
return new NumeroRacional(
this.numerador / maximoDivisorComum,
this.denominador / maximoDivisorComum
);
}
public NumeroRacional somar(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2+N2*D1
// -- + -- = ----------- =
// D1 D2 D1 * D2
int n1 = this.numerador;
int d1 = this.denominador;
int n2 = numeroRacional.numerador;
int d2 = numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
((n1 * d2) + (n2 * d1)),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
public NumeroRacional subtrair(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2-N2*D1
// -- - -- = ----------- =
// D1 D2 D1 * D2
int n1=this.numerador;
int d1=this.denominador;
int n2=numeroRacional.numerador;
int d2=numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
(n1*d2 - n2*d1),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
}
package noventaenovediasdejava.dia05;
import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
@ParameterizedTest(name = "[{index}] a forma irredutível de {0} deve ser igual a {1}")
@MethodSource("testarFormaIrredutivelArgs")
void testarFormaIrredutivel(
final NumeroRacional numeroRacionalBase,
final NumeroRacional numeroRacionalNaFormaIrredutivelEsperado
) {
final NumeroRacional numeroRacionalNaFormaIrredutivel = numeroRacionalBase
.formaIrredutivel();
Assertions.assertNotNull(
numeroRacionalNaFormaIrredutivel,
"não deve ser retornado valor/referência nulo"
);
Assertions.assertEquals(
numeroRacionalNaFormaIrredutivelEsperado,
numeroRacionalNaFormaIrredutivel
);
}
static Stream<Arguments> testarFormaIrredutivelArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(12, 4),
new NumeroRacional(3, 1)
),
Arguments.arguments(
new NumeroRacional(130, 78),
new NumeroRacional(5, 3)
),
Arguments.arguments(
new NumeroRacional(-130, 78),
new NumeroRacional(-5, 3)
),
Arguments.arguments(
new NumeroRacional(130, -78),
new NumeroRacional(5, -3)
)
);
}
@ParameterizedTest(name = "[{index}] {0} + {1} = {2}")
@MethodSource("testarSomarArgs")
void testarSomar(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
final NumeroRacional resultadoAtual =
numeroRacional01.somar(numeroRacional02);
Assertions.
assertNotNull(resultadoAtual,
"não deve retornar valor/referência nula");
Assertions.
assertEquals(
resultadoEsperado,
resultadoAtual
);
}
static Stream<Arguments> testarSomarArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 4),
new NumeroRacional(1, 4),
new NumeroRacional(1, 2)
),
Arguments.arguments(
new NumeroRacional(2, 3),
new NumeroRacional(3, 4),
new NumeroRacional(17, 12)
),
Arguments.arguments(
new NumeroRacional(5, 3),
new NumeroRacional(4, 12),
new NumeroRacional(2, 1)
)
);
}
@ParameterizedTest(name = "[{index}] {0} - {1} = {2}")
@MethodSource("testarSubtrairArgs")
void testarSubtrair(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
){
Assertions.assertEquals(
resultadoEsperado,
numeroRacional01.subtrair(numeroRacional02)
);
}
static Stream<Arguments> testarSubtrairArgs(){
return Stream.of(
Arguments.arguments(
new NumeroRacional(1,2),
new NumeroRacional(3,4),
new NumeroRacional(-1, 4)
)
);
}
}
package noventaenovediasdejava.dia06;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
public NumeroRacional formaIrredutivel() {
int numero = Math.abs(this.numerador);
int maximoDivisorComum = Math.abs(this.denominador);
int resto = 0;
do {
if (resto != 0) {
numero = maximoDivisorComum;
maximoDivisorComum = resto;
}
resto = numero % maximoDivisorComum;
} while (resto != 0);
return new NumeroRacional(
this.numerador / maximoDivisorComum,
this.denominador / maximoDivisorComum
);
}
public NumeroRacional somar(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2+N2*D1
// -- + -- = ----------- =
// D1 D2 D1 * D2
int n1 = this.numerador;
int d1 = this.denominador;
int n2 = numeroRacional.numerador;
int d2 = numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
((n1 * d2) + (n2 * d1)),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
public NumeroRacional subtrair(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2-N2*D1
// -- - -- = ----------- =
// D1 D2 D1 * D2
int n1=this.numerador;
int d1=this.denominador;
int n2=numeroRacional.numerador;
int d2=numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
(n1*d2 - n2*d1),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
public NumeroRacional multiplicar(
final NumeroRacional numeroRacional
) {
// (N1 * N2) / (D1 * D2)
NumeroRacional resultado =
new NumeroRacional(
this.numerador * numeroRacional.numerador,
this.denominador * numeroRacional.denominador
);
return resultado.formaIrredutivel();
}
}
package noventaenovediasdejava.dia06;
import java.util.stream.Stream;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
@ParameterizedTest(name = "[{index}] a forma irredutível de {0} deve ser igual a {1}")
@MethodSource("testarFormaIrredutivelArgs")
void testarFormaIrredutivel(
final NumeroRacional numeroRacionalBase,
final NumeroRacional numeroRacionalNaFormaIrredutivelEsperado
) {
final NumeroRacional numeroRacionalNaFormaIrredutivel = numeroRacionalBase
.formaIrredutivel();
Assertions.assertNotNull(
numeroRacionalNaFormaIrredutivel,
"não deve ser retornado valor/referência nulo"
);
Assertions.assertEquals(
numeroRacionalNaFormaIrredutivelEsperado,
numeroRacionalNaFormaIrredutivel
);
}
static Stream<Arguments> testarFormaIrredutivelArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(12, 4),
new NumeroRacional(3, 1)
),
Arguments.arguments(
new NumeroRacional(130, 78),
new NumeroRacional(5, 3)
),
Arguments.arguments(
new NumeroRacional(-130, 78),
new NumeroRacional(-5, 3)
),
Arguments.arguments(
new NumeroRacional(130, -78),
new NumeroRacional(5, -3)
)
);
}
@ParameterizedTest(name = "[{index}] {0} + {1} = {2}")
@MethodSource("testarSomarArgs")
void testarSomar(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
final NumeroRacional resultadoAtual =
numeroRacional01.somar(numeroRacional02);
Assertions.
assertNotNull(
resultadoAtual,
"não deve retornar valor/referência nula"
);
Assertions.
assertEquals(
resultadoEsperado,
resultadoAtual
);
}
static Stream<Arguments> testarSomarArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 4),
new NumeroRacional(1, 4),
new NumeroRacional(1, 2)
),
Arguments.arguments(
new NumeroRacional(2, 3),
new NumeroRacional(3, 4),
new NumeroRacional(17, 12)
),
Arguments.arguments(
new NumeroRacional(5, 3),
new NumeroRacional(4, 12),
new NumeroRacional(2, 1)
)
);
}
@ParameterizedTest(name = "[{index}] {0} - {1} = {2}")
@MethodSource("testarSubtrairArgs")
void testarSubtrair(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
Assertions.assertEquals(
resultadoEsperado,
numeroRacional01.subtrair(numeroRacional02)
);
}
static Stream<Arguments> testarSubtrairArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 2),
new NumeroRacional(3, 4),
new NumeroRacional(-1, 4)
)
);
}
@ParameterizedTest(name = "[{index}]{0} * {1} = {2}")
@MethodSource("testarMultiplicacaoArgs")
void testarMultiplicacao(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
){
Assertions
.assertEquals(resultadoEsperado,
numeroRacional01.multiplicar(numeroRacional02)
);
}
static Stream<Arguments> testarMultiplicacaoArgs(){
return Stream.of(
Arguments.arguments(
new NumeroRacional(2,3),
new NumeroRacional(6,6),
new NumeroRacional(2,3)
)
);
}
}
package noventaenovediasdejava.dia07;
public record NumeroRacional(Integer numerador, Integer denominador) {
public NumeroRacional {
if (numerador == null) {
throw new IllegalArgumentException("numerador não pode ser nulo");
}
if (denominador == null) {
throw new IllegalArgumentException("denominador não pode ser nulo");
}
if (Integer.valueOf(0).equals(denominador)) {
throw new IllegalArgumentException("denominador não pode ser igual a 0");
}
}
@Override
public String toString() {
return "%s/%s".formatted(this.numerador, this.denominador);
}
public NumeroRacional formaIrredutivel() {
int numero = Math.abs(this.numerador);
int maximoDivisorComum = Math.abs(this.denominador);
int resto = 0;
do {
if (resto != 0) {
numero = maximoDivisorComum;
maximoDivisorComum = resto;
}
resto = numero % maximoDivisorComum;
} while (resto != 0);
return new NumeroRacional(
this.numerador / maximoDivisorComum,
this.denominador / maximoDivisorComum
);
}
public NumeroRacional somar(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2+N2*D1
// -- + -- = ----------- =
// D1 D2 D1 * D2
int n1 = this.numerador;
int d1 = this.denominador;
int n2 = numeroRacional.numerador;
int d2 = numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
((n1 * d2) + (n2 * d1)),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
public NumeroRacional subtrair(final NumeroRacional numeroRacional) {
// N1 N2 N1*D2-N2*D1
// -- - -- = ----------- =
// D1 D2 D1 * D2
int n1 = this.numerador;
int d1 = this.denominador;
int n2 = numeroRacional.numerador;
int d2 = numeroRacional.denominador;
final NumeroRacional resultado =
new NumeroRacional(
(n1 * d2 - n2 * d1),
(d1 * d2)
);
return resultado.formaIrredutivel();
}
public NumeroRacional multiplicar(
final NumeroRacional numeroRacional
) {
// (N1 * N2) / (D1 * D2)
NumeroRacional resultado =
new NumeroRacional(
this.numerador * numeroRacional.numerador,
this.denominador * numeroRacional.denominador
);
return resultado.formaIrredutivel();
}
public NumeroRacional dividir(final NumeroRacional numeroRacional) {
// (N1*D2)/(N2*D1)
NumeroRacional resultado =
new NumeroRacional(
this.numerador * numeroRacional.denominador,
numeroRacional.numerador * this.denominador
);
return resultado.formaIrredutivel();
}
}
package noventaenovediasdejava.dia07;
import java.util.stream.Stream;
import noventaenovediasdejava.dia07.NumeroRacional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@TestMethodOrder(OrderAnnotation.class)
class NumeroRacionalTest {
@Test
@Order(0)
void testarInstanciacao() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, 0),
"não deve aceitar denominador igual a 0"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(null, 1),
"não deve aceitar numerador nulo"
);
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new NumeroRacional(1, null),
"não deve aceitar denominador nulo"
);
}
@Test
@Order(1)
void testarToString() {
var numeroRacional = new NumeroRacional(2, 3);
Assertions.assertEquals("2/3", numeroRacional.toString());
}
@ParameterizedTest(name = "[{index}] a forma irredutível de {0} deve ser igual a {1}")
@MethodSource("testarFormaIrredutivelArgs")
void testarFormaIrredutivel(
final NumeroRacional numeroRacionalBase,
final NumeroRacional numeroRacionalNaFormaIrredutivelEsperado
) {
final NumeroRacional numeroRacionalNaFormaIrredutivel = numeroRacionalBase
.formaIrredutivel();
Assertions.assertNotNull(
numeroRacionalNaFormaIrredutivel,
"não deve ser retornado valor/referência nulo"
);
Assertions.assertEquals(
numeroRacionalNaFormaIrredutivelEsperado,
numeroRacionalNaFormaIrredutivel
);
}
static Stream<Arguments> testarFormaIrredutivelArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(12, 4),
new NumeroRacional(3, 1)
),
Arguments.arguments(
new NumeroRacional(130, 78),
new NumeroRacional(5, 3)
),
Arguments.arguments(
new NumeroRacional(-130, 78),
new NumeroRacional(-5, 3)
),
Arguments.arguments(
new NumeroRacional(130, -78),
new NumeroRacional(5, -3)
)
);
}
@ParameterizedTest(name = "[{index}] {0} + {1} = {2}")
@MethodSource("testarSomarArgs")
void testarSomar(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
final NumeroRacional resultadoAtual =
numeroRacional01.somar(numeroRacional02);
Assertions.
assertNotNull(
resultadoAtual,
"não deve retornar valor/referência nula"
);
Assertions.
assertEquals(
resultadoEsperado,
resultadoAtual
);
}
static Stream<Arguments> testarSomarArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 4),
new NumeroRacional(1, 4),
new NumeroRacional(1, 2)
),
Arguments.arguments(
new NumeroRacional(2, 3),
new NumeroRacional(3, 4),
new NumeroRacional(17, 12)
),
Arguments.arguments(
new NumeroRacional(5, 3),
new NumeroRacional(4, 12),
new NumeroRacional(2, 1)
)
);
}
@ParameterizedTest(name = "[{index}] {0} - {1} = {2}")
@MethodSource("testarSubtrairArgs")
void testarSubtrair(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
Assertions.assertEquals(
resultadoEsperado,
numeroRacional01.subtrair(numeroRacional02)
);
}
static Stream<Arguments> testarSubtrairArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 2),
new NumeroRacional(3, 4),
new NumeroRacional(-1, 4)
)
);
}
@ParameterizedTest(name = "[{index}]{0} * {1} = {2}")
@MethodSource("testarMultiplicacaoArgs")
void testarMultiplicacao(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
Assertions
.assertEquals(
resultadoEsperado,
numeroRacional01.multiplicar(numeroRacional02)
);
}
static Stream<Arguments> testarMultiplicacaoArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(2, 3),
new NumeroRacional(6, 6),
new NumeroRacional(2, 3)
)
);
}
@ParameterizedTest(name = "[{index}] {0} / {1} = {2}")
@MethodSource("testarDividirArgs")
void testarDividir(
final NumeroRacional numeroRacional01,
final NumeroRacional numeroRacional02,
final NumeroRacional resultadoEsperado
) {
Assertions.assertEquals(
resultadoEsperado,
numeroRacional01.dividir(numeroRacional02)
);
}
static Stream<Arguments> testarDividirArgs() {
return Stream.of(
Arguments.arguments(
new NumeroRacional(1, 2),
new NumeroRacional(3, 4),
new NumeroRacional(2, 3)
)
);
}
}
package noventaenovediasdejava.dia08;
public interface JogadorJokenpo {
}
package noventaenovediasdejava.dia08;
public class JogoJokenpo {
public JogoJokenpo(
final JogadorJokenpo jogador01,
final JogadorJokenpo jogador02
) {
if (jogador01 == null && jogador02 == null) {
throw new IllegalArgumentException("jogadores não informados");
}
if (jogador01 != null && jogador02 == null) {
throw new IllegalArgumentException("jogador 02 não informado");
}
if (jogador01 == null && jogador02 != null) {
throw new IllegalArgumentException("jogador 01 não informado");
}
}
}
package noventaenovediasdejava.dia08;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class JogoJokenpoTest {
@Test
void naoDevePermitirInstanciacao() {
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(null, null),
"não deve ser permitido a instanciação do jogo sem jogadores"
);
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(new JogadorJokenpo() {
}, null),
"não deve ser permitido a instanciação do jogo só com o jogador 01"
);
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(
null,
new JogadorJokenpo() {
}
),
"não deve ser permitido a instanciação do jogo só com o jogador 02"
);
}
}
package noventaenovediasdejava.dia09;
public enum MovimentoJokenpo {
PEDRA {
@Override
public boolean ganhaDe(final MovimentoJokenpo movimento) {
return TESOURA.equals(movimento);
}
},
PAPEL {
@Override
public boolean ganhaDe(final MovimentoJokenpo movimento) {
return switch (movimento) {
case PEDRA -> true;
default -> false;
};
}
},
TESOURA {
@Override
public boolean ganhaDe(final MovimentoJokenpo movimento) {
return PAPEL.equals(movimento);
}
};
public abstract boolean ganhaDe(final MovimentoJokenpo movimento);
}
package noventaenovediasdejava.dia09;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class MovimentoJokenpoTest {
@Test
void testeDeEstrutura() {
final var values = MovimentoJokenpo.values();
Assertions.assertEquals(
3,
values.length,
"Só deve ter 3 tipos de movimentos Jokenpô"
);
Assertions.assertEquals("PEDRA", values[0].name());
Assertions.assertEquals("PAPEL", values[1].name());
Assertions.assertEquals("TESOURA", values[2].name());
}
@Test
void testarComportamento() {
Assertions.assertEquals(true,
MovimentoJokenpo.PAPEL
.ganhaDe(MovimentoJokenpo.PEDRA));
Assertions.assertEquals(true,
MovimentoJokenpo.PEDRA
.ganhaDe(MovimentoJokenpo.TESOURA));
Assertions.assertEquals(true,
MovimentoJokenpo.TESOURA
.ganhaDe(MovimentoJokenpo.PAPEL));
}
}
package noventaenovediasdejava.dia10;
@FunctionalInterface
public interface JogadorJokenpo {
MovimentoJokenpo jogar();
}
package noventaenovediasdejava.dia10;
public record JogadaJokenpo(
boolean acabouEmpatada,
JogadorJokenpo vencedor,
JogadorJokenpo perdedor
) {
}
package noventaenovediasdejava.dia10;
public class JogoJokenpo {
private final JogadorJokenpo jogador01;
private final JogadorJokenpo jogador02;
public JogoJokenpo(
final JogadorJokenpo jogador01,
final JogadorJokenpo jogador02
) {
if (jogador01 == null && jogador02 == null) {
throw new IllegalArgumentException("jogadores não informados");
}
if (jogador01 != null && jogador02 == null) {
throw new IllegalArgumentException("jogador 02 não informado");
}
if (jogador01 == null && jogador02 != null) {
throw new IllegalArgumentException("jogador 01 não informado");
}
this.jogador01 = jogador01;
this.jogador02 = jogador02;
}
public JogadaJokenpo executarJogada() {
MovimentoJokenpo movimentoJokenpo01 = this.jogador01.jogar();
MovimentoJokenpo movimentoJokenpo02 = this.jogador02.jogar();
if (movimentoJokenpo01.ganhaDe(movimentoJokenpo02)) {
return new JogadaJokenpo(false, jogador01, jogador02);
}
if (movimentoJokenpo02.ganhaDe(movimentoJokenpo01)) {
return new JogadaJokenpo(false, jogador02, jogador01);
}
return new JogadaJokenpo(true, null, null);
}
}
package noventaenovediasdejava.dia10;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class JogoJokenpoTest {
@Test
void naoDevePermitirInstanciacao() {
final JogadorJokenpo jogador = () -> null;
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(null, null),
"não deve ser permitido a instanciação do jogo sem jogadores"
);
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(jogador, null),
"não deve ser permitido a instanciação do jogo só com o jogador 01"
);
Assertions
.assertThrows(
IllegalArgumentException.class,
() -> new JogoJokenpo(
null, jogador
),
"não deve ser permitido a instanciação do jogo só com o jogador 02"
);
}
@Test
void testeExecutarJogada() {
JogadorJokenpo pietro = () -> MovimentoJokenpo.PEDRA;
JogadorJokenpo max = () -> MovimentoJokenpo.TESOURA;
JogoJokenpo jogo = Assertions
.assertDoesNotThrow(
() -> new JogoJokenpo(pietro, max),
"deveria permitir a criação do Jogo"
);
JogadaJokenpo jogada = jogo.executarJogada();
Assertions.assertEquals(
false,
jogada.acabouEmpatada()
);
Assertions.assertEquals(pietro, jogada.vencedor());
Assertions.assertEquals(max, jogada.perdedor());
}
}
package noventaenovediasdejava.dia11;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.stream.Collectors;
public class JogadorJokenpoRoundingRobin
implements JogadorJokenpo {
private final LinkedList<MovimentoJokenpo> movimentos;
public JogadorJokenpoRoundingRobin() {
this.movimentos = Arrays
.stream(MovimentoJokenpo.values())
.collect(Collectors.toCollection(LinkedList::new));
}
@Override
public MovimentoJokenpo jogar() {
synchronized (this){
final var movimento = this.movimentos.poll();
this.movimentos.add(movimento);
return movimento;
}
}
}
package noventaenovediasdejava.dia11;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class JogadorJokenpoRoundingRobinTest {
@Test
void testeJogar() {
JogadorJokenpo jogador = new JogadorJokenpoRoundingRobin();
final var movimentosJogados =
IntStream.range(0, 600) // criando um range de iteração de 0 à 599
.boxed()
.parallel()
.map(i -> {
try{
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
var movimento = jogador.jogar();
try{
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return Map.of(
String.valueOf(movimento),
new AtomicInteger(1));
})
.collect(Collectors.toList())
.stream()
.reduce(new HashMap<>(), (ac, item) -> {
item.entrySet()
.forEach(entry -> {
ac.computeIfAbsent(
entry.getKey(),
k -> new AtomicInteger(0)
)
.incrementAndGet();
});
return ac;
});
movimentosJogados
.entrySet()
.forEach(System.out::println);
Assertions.assertEquals(
Arrays
.stream(MovimentoJokenpo.values())
.map(String::valueOf)
.sorted()
.collect(Collectors.joining(",")),
movimentosJogados
.keySet()
.stream()
.map(String::valueOf)
.sorted()
.collect(Collectors.joining(",")),
"tipos de movimentos fora do esperado"
);
Arrays.stream(MovimentoJokenpo.values())
.forEach(movimento -> {
Assertions.assertEquals(
200,
movimentosJogados.get(movimento.name()).get(),
"numero de jogadas com %s fora do esperado".formatted(movimento)
);
});
}
}
package noventaenovediasdejava.dia12;
import java.util.Random;
public class JogadorJokenpoRandom implements JogadorJokenpo {
@Override
public MovimentoJokenpo jogar() {
final var movimentosDisponiveis = MovimentoJokenpo.values();
final int index = new Random().nextInt(movimentosDisponiveis.length);
return movimentosDisponiveis[index];
}
}
package noventaenovediasdejava.dia12;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class JogadorJokenpoRandomTest {
@Test
void testarJogar() {
JogadorJokenpo jogador = new JogadorJokenpoRandom();
final var movimentosExecutados =
IntStream.range(0, 10)
.boxed()
.map(tentativa -> {
final var movimento = jogador.jogar();
System.out.println("%s = %s".formatted(tentativa, movimento));
return movimento;
})
.collect(Collectors.toList());
Assertions.assertEquals(
10,
movimentosExecutados
.stream()
.filter(Objects::nonNull)
.count(),
"total de movimentos executados fora do esperado"
);
}
}
package noventaenovediasdejava.dia13;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Objects;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicReference;
public class JogoJokenpoCLI {
public static void main(String[] args) {
EstadoDoJogo estadoAtual = new Inicio();
while (estadoAtual.podeExecutar()) {
estadoAtual = estadoAtual.executar(System.in, System.out);
if (estadoAtual instanceof Sair sair) {
sair.finalizarJogo(System.out);
}
}
}
static interface EstadoDoJogo {
EstadoDoJogo executar(InputStream input, PrintStream output);
default boolean podeExecutar() {
return true;
}
}
static class Inicio implements EstadoDoJogo {
@Override
public EstadoDoJogo executar(
final InputStream input, final PrintStream output
) {
output.println("Bem-vindo ao Jogo Jokenpô!!!");
return new CapturarComandoPlayer01();
}
}
static class CapturarComandoPlayer01 implements EstadoDoJogo {
@Override
public EstadoDoJogo executar(
final InputStream input, final PrintStream output
) {
output.println("Comandos válidos: SAIR, PEDRA, PAPEL ou TESOURA");
var comando = new Scanner(input).next().trim();
if ("SAIR".equalsIgnoreCase(comando)) {
return new Sair();
}
final var movimentoDoPlayer01 =
Arrays.stream(MovimentoJokenpo.values())
.filter(m -> m.name().equalsIgnoreCase(comando))
.findFirst();
if (movimentoDoPlayer01.isEmpty()) {
return new ComandoInvalido(this);
}
return new CapturarComandoPlayer02(movimentoDoPlayer01.get());
}
}
static class CapturarComandoPlayer02 implements EstadoDoJogo {
private final MovimentoJokenpo movimentoPlayer01;
public CapturarComandoPlayer02(final MovimentoJokenpo movimentoPlayer01) {
this.movimentoPlayer01 = movimentoPlayer01;
}
@Override
public EstadoDoJogo executar(
final InputStream input, final PrintStream output
) {
final AtomicReference<MovimentoJokenpo> movimentoCPU = new AtomicReference<>();
JogadorJokenpo player01 = () -> this.movimentoPlayer01;
JogadorJokenpo player02 = () -> {
movimentoCPU.set(new JogadorJokenpoRandom().jogar());
return movimentoCPU.get();
};
JogoJokenpo jogoJokenpo =
new JogoJokenpo(player01, player02);
final var jogada = jogoJokenpo.executarJogada();
if (jogada.acabouEmpatada()) {
output.println("Quase!!! Deu empate!!!");
} else if (Objects.equals(player01, jogada.vencedor())) {
output.println("Wow!!! Você ganhou!!!");
} else {
output.println("Oh no!!! Você perdeu !!!");
}
output.println("CPU jogou: %s\n".formatted(movimentoCPU.get()));
return new CapturarComandoPlayer01();
}
}
static class ComandoInvalido implements EstadoDoJogo {
private final EstadoDoJogo estadoDoJogo;
public ComandoInvalido(final EstadoDoJogo estadoDoJogo) {
this.estadoDoJogo = estadoDoJogo;
}
@Override
public EstadoDoJogo executar(
final InputStream input, final PrintStream output
) {
output.println("Ops!!! Comando inválido!!! Tente novamente!!!");
return this.estadoDoJogo;
}
}
static class Sair implements EstadoDoJogo {
@Override
public EstadoDoJogo executar(final InputStream input, final PrintStream output) {
throw new UnsupportedOperationException();
}
@Override
public boolean podeExecutar() {
return false;
}
public void finalizarJogo(final PrintStream output) {
output.println("Fim de jogo!!!");
}
}
}
package noventaenovediasdejava.dia14;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(OrderAnnotation.class)
public class ContadorTest {
@Test
@Order(1)
void testarContadorUnsafe() throws InterruptedException {
testar(
new ContadorUnsafe(),
50,
1000,
(contador, numeroDeTarefas) ->
Assertions.assertNotEquals(numeroDeTarefas, contador.getValor())
);
}
@Test
@Order(2)
void testarContadorSafe01() throws InterruptedException {
testar(
new ContadorSafe01(),
50,
1000,
(contador, numeroDeTarefas) ->
Assertions.assertEquals(numeroDeTarefas, contador.getValor())
);
}
@Test
@Order(3)
void testarContadorSafe02() throws InterruptedException {
testar(
new ContadorSafe02(),
50,
1000,
(contador, numeroDeTarefas) ->
Assertions.assertEquals(numeroDeTarefas, contador.getValor())
);
}
@Test
@Order(4)
void testarContadorSafe03() throws InterruptedException {
testar(
new ContadorSafe03(),
50,
1000,
(contador, numeroDeTarefas) ->
Assertions.assertEquals(numeroDeTarefas, contador.getValor())
);
}
private void testar(
final Contador contador,
final int numeroDeThreads,
final int numeroDeTarefas,
final BiConsumer<Contador, Integer> asserts
) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(numeroDeThreads);
CountDownLatch countDownLatch = new CountDownLatch(numeroDeTarefas);
for (int tarefas = 0; tarefas < numeroDeTarefas; tarefas++) {
executorService.execute(() -> {
try {
Thread.sleep(50);
contador.incrementar();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
executorService.shutdown();
countDownLatch.await(1, TimeUnit.MINUTES);
asserts.accept(contador, numeroDeTarefas);
}
static interface Contador {
void incrementar();
int getValor();
}
static class ContadorUnsafe implements Contador {
private int valor;
@Override
public void incrementar() {
this.valor++; // this.valor = this.valor + 1
}
@Override
public int getValor() {
return this.valor;
}
}
static class ContadorSafe01 implements Contador {
private int valor;
@Override
public synchronized void incrementar() {
this.valor++; // this.valor = this.valor + 1
}
@Override
public synchronized int getValor() {
return this.valor;
}
}
static class ContadorSafe02 implements Contador {
private int valor;
@Override
public void incrementar() {
synchronized (this) {
this.valor++; // this.valor = this.valor + 1
}
}
@Override
public int getValor() {
synchronized (this) {
return this.valor;
}
}
}
static class ContadorSafe03 implements Contador {
private AtomicInteger valor = new AtomicInteger(0);
@Override
public void incrementar() {
this.valor.incrementAndGet();
}
@Override
public int getValor() {
return this.valor.get();
}
}
}
-
adicionando dependências
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<!-- omitted -->
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<!-- omitted -->
</project>
-
exemplo de implementação
package noventaenovediasdejava.dia15;
import java.time.LocalDate;
@PeriodoValido
public record Periodo(LocalDate inicio, LocalDate fim) {
public static Periodo of(LocalDate inicio, LocalDate fim) {
return new Periodo(inicio, fim);
}
}
package noventaenovediasdejava.dia15;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Constraint(validatedBy = PeriodoValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PeriodoValido {
String message() default "período está inválido";
Class<? extends Payload>[] payload() default {};
Class<?>[] groups() default {};
}
package noventaenovediasdejava.dia15;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PeriodoValidator implements ConstraintValidator<PeriodoValido, Periodo> {
@Override
public boolean isValid(Periodo value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
if (value.inicio() == null) {
return false;
}
if (value.fim() == null) {
return false;
}
return value.inicio().isBefore(value.fim())
|| value.inicio().isEqual(value.fim());
}
}
package noventaenovediasdejava.dia15;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import javax.validation.Validation;
import javax.validation.Validator;
import java.time.LocalDate;
public class PeriodoTest {
@Test
@DisplayName("dado um periodo válido, o validator não deve encontrar violações")
public void test01() {
var violacoes = getValidator()
.validate(Periodo.of(LocalDate.of(2022, 1, 1), LocalDate.now()));
Assertions.assertTrue(violacoes.isEmpty());
}
@Test
@DisplayName("dado um periodo inválido, o validator deve encontrar uma violação")
public void test02() {
var violacoes = getValidator()
.validate(Periodo.of(LocalDate.now(), LocalDate.of(2022, 1, 1)));
Assertions.assertFalse(violacoes.isEmpty());
}
public Validator getValidator() {
return Validation.buildDefaultValidatorFactory().getValidator();
}
}