Skip to content

Instantly share code, notes, and snippets.

@rafaelpontezup
Created September 9, 2024 20:57
Show Gist options
  • Save rafaelpontezup/188a8a43bf158fa7306d9d1a53cdfbaa to your computer and use it in GitHub Desktop.
Save rafaelpontezup/188a8a43bf158fa7306d9d1a53cdfbaa to your computer and use it in GitHub Desktop.
Palindromo: exemplo de implementação e testes em Java
package br.com.zup.hackton.palindromo;
import org.apache.commons.lang3.StringUtils;
/**
* Algumas palavras e frases:
*
* ana, arara, mussum, mirim, ovo, reviver, socos, salas, ralar, e2e, 1-a-1
* anotaram a data da maratona
* socorram-me subi no onibus em marrocos
*
* https://codepen.io/jeffreypoland/pen/iuItG
* https://gist.github.com/marufsiddiqui/9938268
* https://gist.github.com/rponte/893494
* https://www.baeldung.com/java-remove-accents-from-text
*/
public class Palindromo {
/**
* Passos importantes para conduzir:
*
* - Passo-1: implementa SOMENTE algoritimo para Palavra;
* - Passo-2: implementa SOMENTE algoritimo para Palavra com case-insensitive;
* - Passo-3: implementa algoritimo para Frase com espaços em branco e outros caracteres;
* -- TDD - aplicar e explicar --
* - Passo-4: implementa algoritimo para lidar com acentuação;
* - 4.1. ou remove os acentos ANTES do replaceAll()
* - 4.2. ou remove os acentos DEPOIS do replaceAll() mas trocando para regex "[^\\p{L}\\p{N}]"
* - Passo-5: implementa validação para texto nulo ou vazio;
*/
public boolean isPalidromo(String texto) {
if (texto == null || texto.isBlank()) {
return false;
}
texto = texto.toLowerCase(); // passo 2
texto = StringUtils.stripAccents(texto); // passo 4 (apache-commons-text)
texto = texto.replaceAll("[^a-zA-Z0-9]", ""); // passo 3
// passo 4
// texto = texto.replaceAll("[^\\p{L}\\p{N}]", ""); // passo 4
// texto = StringUtils.stripAccents(texto);
// passo 1
int tamanho = texto.length();
for (int i=0; i < tamanho; i++) {
int finalDoTexto = (tamanho - 1 - i);
if (texto.charAt(i) != texto.charAt(finalDoTexto)) {
return false;
}
}
return true;
// passo 1: refactoring
// return texto.equals(new StringBuilder(texto).reverse().toString());
}
}
package br.com.zup.hackton.palindromo;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PalindromoTest {
/**
* Cenário Happy-path
*
* Usa exemplos de palavras como estas:
* - ana, arara, mussum, mirim, ovo, reviver, socos, salas, ralar
*/
@Test
@DisplayName("deve ser um palindromo")
public void t1() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertTrue(palindromo.isPalidromo("ana"));
assertTrue(palindromo.isPalidromo("arara"));
assertTrue(palindromo.isPalidromo("mussum"));
assertTrue(palindromo.isPalidromo("mirim"));
assertTrue(palindromo.isPalidromo("ovo"));
assertTrue(palindromo.isPalidromo("reviver"));
assertTrue(palindromo.isPalidromo("socos"));
assertTrue(palindromo.isPalidromo("salas"));
assertTrue(palindromo.isPalidromo("ralar"));
assertTrue(palindromo.isPalidromo("e2e"));
assertTrue(palindromo.isPalidromo("1-a-1"));
}
/**
* Cenário de palavras óbvias que NÃO são palindromos
*/
@Test
@DisplayName("não deve ser um palindromo")
public void t2() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertFalse(palindromo.isPalidromo("rafael"));
assertFalse(palindromo.isPalidromo("guilhaume"));
assertFalse(palindromo.isPalidromo("hackaton"));
assertFalse(palindromo.isPalidromo("java"));
}
/**
* Cenário Happy-path 2
*
* Usa exemplos de frase como estas:
* - Anotaram a data da maratona
* - Socorram-me subi no onibus em Marrocos
*/
@Test
@DisplayName("deve ser um palindromo quando texto for uma frase")
public void t3() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertTrue(palindromo.isPalidromo("anotaram a data da maratona"));
assertTrue(palindromo.isPalidromo("socorram-me subi no onibus em marrocos"));
}
/**
* Cenário de case-insensitive
*/
@Test
@DisplayName("deve ser um palindromo quando texto possuir letras minusculas e maiusculas")
public void t4() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertTrue(palindromo.isPalidromo("Ana"));
assertTrue(palindromo.isPalidromo("ovO"));
assertTrue(palindromo.isPalidromo("ARarA"));
assertTrue(palindromo.isPalidromo("reVivER"));
assertTrue(palindromo.isPalidromo("socorram-me subi no onibus em marrocos"));
}
/**
* Cenário de caracteres acentuados
*/
@Test
@DisplayName("deve ser um palindromo quando texto possuir caracteres acentuados")
public void t5() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertTrue(palindromo.isPalidromo("ána"));
assertTrue(palindromo.isPalidromo("ôvo"));
assertTrue(palindromo.isPalidromo("ôvó"));
assertTrue(palindromo.isPalidromo("Socorram-me subi no ônibus em Marrocos"));
}
/**
* TDD - Test-Driven Development
*
* Cenário de validação básica (não confie no seu usuário)
*/
@Test
@DisplayName("não deve ser um palindromo quando texto for nulo ou vazio")
public void t7() {
// cenário
Palindromo palindromo = new Palindromo();
// ação e validação
assertFalse(palindromo.isPalidromo(null));
assertFalse(palindromo.isPalidromo(""));
assertFalse(palindromo.isPalidromo("".repeat(100)));
}
}
<!-- ***** -->
<!-- Apache Commons Text -->
<!-- StringUtils.stripAccents(input); -->
<!-- ***** -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.3</version>
</dependency>
@rponte
Copy link

rponte commented Sep 17, 2024

Palindromo

  1. Explicar o que é palindromo;
    • 1.1. Mostrar exemplos de palavras e frase;
  2. Criar classe Palindromo com método isPalindromo(String texto);
  3. Implementar lógica inicial para palavra;
    • 3.1. Escrever algoritimo mais simples possível sem se preocupar com validação, frases ou caracteres especiais;
  4. Como testar nosso código?
    • 4.1. Explicar diferença entre teste manual e automatizado;
    • 4.2. Implementar teste "semi-automatizado": escrever no método main() do projeto
    • 4.3. Imprimir resultado no console;
    • 4.4. Explicar que embora simples ela ainda precisa de um ser humano olhando a saida do console;
  5. Criar primeiro teste automatizado: happy-path para palavras
    • 5.1. Explicar que usuaremos o jUnit;
    • 5.2. Criar classe PalindromoTest;
    • 5.3. Criar cenário happy-path para lista de palavras;
    • 5.4. Criar método de testes e explicar anotações @Test e @DisplayName;
    • 5.5. Explicar template de testes: cenário-ação-validação;
    • 5.6. Implementar cada bloco do teste;
  6. Cenário alternativo não deve ser palindromo
  7. Cenário alternativo (happy-path) "deve ser palindromo quando texto for uma frase"
  8. Cenário alternativo "deve ser um palindromo quando texto possuir letras minusculas e maiusculas"
  9. Praticando TDD - Test Driven Development
    • 9.1. Cenário alternativo "não deve ser um palindromo quando texto for nulo ou vazio"
    • 9.2. Cenário alternativo deve ser um palindromo quando texto possuir caracteres acentuados

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment