Add Streamlit CEP search app with robust validation
- Implemented CEPValidator class with comprehensive validation - Sanitizes input (removes non-numeric characters) - Validates 8-digit format - Detects invalid CEPs (all same digits) - Formats CEP in XXXXX-XXX pattern - Integrated ViaCEPAPI with automatic retry system - Up to 3 retry attempts on network failures - Configurable 10-second timeout - Comprehensive error handling (timeout, connection, HTTP errors) - Created intuitive Streamlit interface - Responsive layout with visual feedback - Sidebar with examples and documentation - Formatted address display in columns - User-friendly error messages - Added test suite for CEP validation - 13 test cases covering valid and invalid scenarios - All tests passing - Included complete documentation (README.md, SKILL.md) - Added .gitignore and requirements.txt
This commit is contained in:
parent
c74d647e56
commit
a1db3e57ce
|
|
@ -0,0 +1,40 @@
|
|||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Virtual Environment
|
||||
venv/
|
||||
env/
|
||||
ENV/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Streamlit
|
||||
.streamlit/
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
# 📮 App Streamlit de Busca de CEP
|
||||
|
||||
Um aplicativo web profissional desenvolvido com Streamlit para buscar informações de endereço através do CEP brasileiro, com validação robusta e integração com a API ViaCEP.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## ✨ Recursos
|
||||
|
||||
- ✅ **Validação Robusta de CEP**
|
||||
- Valida formato (8 dígitos)
|
||||
- Remove caracteres especiais automaticamente
|
||||
- Detecta CEPs inválidos
|
||||
- Aceita formato com ou sem hífen
|
||||
|
||||
- 🔄 **Sistema de Retry Automático**
|
||||
- Até 3 tentativas em caso de falha
|
||||
- Timeout configurável (10 segundos)
|
||||
- Tratamento de erros de conexão
|
||||
|
||||
- 📊 **Interface Intuitiva**
|
||||
- Layout responsivo e moderno
|
||||
- Feedback visual em tempo real
|
||||
- Exemplos integrados na sidebar
|
||||
- Mensagens de erro amigáveis
|
||||
|
||||
- 🚀 **Integração com ViaCEP**
|
||||
- API pública brasileira
|
||||
- Dados completos de endereço
|
||||
- Informações de IBGE, DDD, GIA e SIAFI
|
||||
|
||||
## 🚀 Início Rápido
|
||||
|
||||
### Pré-requisitos
|
||||
|
||||
- Python 3.8 ou superior
|
||||
- pip (gerenciador de pacotes Python)
|
||||
|
||||
### Instalação
|
||||
|
||||
1. Clone o repositório ou baixe os arquivos
|
||||
|
||||
2. Instale as dependências:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Executar o Aplicativo
|
||||
|
||||
```bash
|
||||
streamlit run app.py
|
||||
```
|
||||
|
||||
O aplicativo será aberto automaticamente no navegador em `http://localhost:8501`
|
||||
|
||||
## 📖 Como Usar
|
||||
|
||||
1. **Digite um CEP** no campo de entrada
|
||||
- Formatos aceitos: `12345-678` ou `12345678`
|
||||
|
||||
2. **Clique em "Buscar"** para consultar o endereço
|
||||
|
||||
3. **Visualize os resultados** organizados em colunas:
|
||||
- Informações do endereço (logradouro, complemento, bairro)
|
||||
- Localização (cidade, estado, códigos)
|
||||
|
||||
4. **Use "Limpar"** para fazer uma nova busca
|
||||
|
||||
## 🎯 Exemplos de CEPs Válidos
|
||||
|
||||
| CEP | Endereço |
|
||||
|-----|----------|
|
||||
| `01310-100` | Av. Paulista - São Paulo/SP |
|
||||
| `20040-020` | Centro - Rio de Janeiro/RJ |
|
||||
| `30130-010` | Centro - Belo Horizonte/MG |
|
||||
| `40020-000` | Centro - Salvador/BA |
|
||||
| `80010-000` | Centro - Curitiba/PR |
|
||||
|
||||
## 🏗️ Arquitetura
|
||||
|
||||
### Classes Principais
|
||||
|
||||
#### `CEPValidator`
|
||||
Responsável pela validação e formatação de CEP:
|
||||
- `sanitize_cep()`: Remove caracteres não numéricos
|
||||
- `validate_format()`: Valida formato do CEP
|
||||
- `format_cep()`: Formata CEP no padrão XXXXX-XXX
|
||||
|
||||
#### `ViaCEPAPI`
|
||||
Gerencia a integração com a API ViaCEP:
|
||||
- `search_cep()`: Busca informações do endereço
|
||||
- Sistema de retry automático
|
||||
- Tratamento completo de erros
|
||||
|
||||
### Validações Implementadas
|
||||
|
||||
```python
|
||||
✅ CEP com 8 dígitos
|
||||
✅ Apenas números após sanitização
|
||||
✅ Rejeita CEPs com todos dígitos iguais
|
||||
✅ Aceita formatos: XXXXX-XXX ou XXXXXXXX
|
||||
```
|
||||
|
||||
### Tratamento de Erros
|
||||
|
||||
- ⏱️ **Timeout**: Mensagem amigável após timeout de conexão
|
||||
- 🔌 **Conexão**: Detecção de problemas de rede
|
||||
- ❌ **HTTP**: Tratamento de erros de status HTTP
|
||||
- ⚠️ **CEP não encontrado**: Validação de existência do CEP
|
||||
- 🔧 **Formato inválido**: Validação antes da consulta
|
||||
|
||||
## 📊 Dados Retornados
|
||||
|
||||
O aplicativo exibe as seguintes informações quando o CEP é encontrado:
|
||||
|
||||
- **CEP**: Código postal formatado
|
||||
- **Logradouro**: Nome da rua/avenida
|
||||
- **Complemento**: Informações adicionais
|
||||
- **Bairro**: Nome do bairro
|
||||
- **Cidade**: Nome da cidade (localidade)
|
||||
- **Estado**: UF (sigla do estado)
|
||||
- **IBGE**: Código do município
|
||||
- **DDD**: Código de área telefônico
|
||||
- **GIA**: Guia de Informação e Apuração (SP)
|
||||
- **SIAFI**: Sistema Integrado de Administração Financeira
|
||||
|
||||
## 🛠️ Tecnologias
|
||||
|
||||
- **[Streamlit](https://streamlit.io/)** - Framework para aplicativos web em Python
|
||||
- **[Requests](https://requests.readthedocs.io/)** - Biblioteca HTTP para Python
|
||||
- **[ViaCEP](https://viacep.com.br/)** - API pública de consulta de CEP
|
||||
|
||||
## 📝 Estrutura de Arquivos
|
||||
|
||||
```
|
||||
cep-search-app/
|
||||
├── app.py # Aplicativo principal
|
||||
├── requirements.txt # Dependências do projeto
|
||||
├── SKILL.md # Documentação da skill
|
||||
└── README.md # Este arquivo
|
||||
```
|
||||
|
||||
## 🔒 Segurança
|
||||
|
||||
- Validação de entrada antes de fazer requisições
|
||||
- Sanitização de dados do usuário
|
||||
- Timeout para evitar travamentos
|
||||
- Tratamento seguro de exceções
|
||||
|
||||
## 🤝 Contribuindo
|
||||
|
||||
Contribuições são bem-vindas! Sinta-se à vontade para:
|
||||
- Reportar bugs
|
||||
- Sugerir novas funcionalidades
|
||||
- Enviar pull requests
|
||||
|
||||
## 📄 Licença
|
||||
|
||||
Este projeto está sob a licença MIT.
|
||||
|
||||
## 🙏 Créditos
|
||||
|
||||
- Dados fornecidos pela API [ViaCEP](https://viacep.com.br/)
|
||||
- Desenvolvido com [Streamlit](https://streamlit.io/)
|
||||
|
||||
## 📞 Suporte
|
||||
|
||||
Se encontrar algum problema ou tiver dúvidas:
|
||||
1. Verifique se o CEP está correto
|
||||
2. Confirme sua conexão com a internet
|
||||
3. Verifique se as dependências estão instaladas corretamente
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
Desenvolvido com ❤️ usando Streamlit
|
||||
</div>
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
name: cep-search-app
|
||||
description: App Streamlit de busca de CEP com validação robusta e integração com ViaCEP. Use quando precisar criar ou modificar aplicativos de busca de endereço por CEP brasileiro.
|
||||
---
|
||||
|
||||
# App Streamlit de Busca de CEP
|
||||
|
||||
Este é um aplicativo Streamlit profissional para busca de informações de endereço através do CEP brasileiro, com validação robusta e integração com a API ViaCEP.
|
||||
|
||||
## Recursos
|
||||
|
||||
- **Validação Robusta**: Valida formato do CEP, remove caracteres especiais e detecta CEPs inválidos
|
||||
- **Integração com ViaCEP**: Busca automática de endereços através da API ViaCEP
|
||||
- **Retry Automático**: Sistema de retry com até 3 tentativas em caso de falha de rede
|
||||
- **Tratamento de Erros**: Tratamento completo de erros com mensagens amigáveis
|
||||
- **Interface Intuitiva**: Layout responsivo com feedback visual para o usuário
|
||||
- **Exemplos Integrados**: Sidebar com exemplos de CEPs válidos
|
||||
|
||||
## Como Usar
|
||||
|
||||
### Instalação
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Executar o Aplicativo
|
||||
|
||||
```bash
|
||||
streamlit run app.py
|
||||
```
|
||||
|
||||
O aplicativo será aberto automaticamente no navegador em `http://localhost:8501`
|
||||
|
||||
## Funcionalidades
|
||||
|
||||
### Validação de CEP
|
||||
|
||||
O aplicativo valida:
|
||||
- Formato do CEP (8 dígitos)
|
||||
- Remove automaticamente caracteres não numéricos
|
||||
- Detecta CEPs inválidos (ex: 00000000)
|
||||
- Aceita formato com ou sem hífen (XXXXX-XXX ou XXXXXXXX)
|
||||
|
||||
### Busca de Endereço
|
||||
|
||||
Retorna informações completas:
|
||||
- CEP formatado
|
||||
- Logradouro
|
||||
- Complemento
|
||||
- Bairro
|
||||
- Cidade
|
||||
- Estado (UF)
|
||||
- Código IBGE
|
||||
- DDD
|
||||
- GIA (se disponível)
|
||||
- SIAFI (se disponível)
|
||||
|
||||
### Tratamento de Erros
|
||||
|
||||
- Timeout de conexão
|
||||
- Erros de rede
|
||||
- CEP não encontrado
|
||||
- Validação de formato
|
||||
- Mensagens de erro amigáveis
|
||||
|
||||
## Estrutura do Código
|
||||
|
||||
- `CEPValidator`: Classe para validação e formatação de CEP
|
||||
- `ViaCEPAPI`: Classe para integração com a API ViaCEP
|
||||
- `display_address()`: Função para exibir informações formatadas
|
||||
- `main()`: Função principal do aplicativo
|
||||
|
||||
## Tecnologias Utilizadas
|
||||
|
||||
- **Streamlit**: Framework para criação de aplicativos web
|
||||
- **Requests**: Biblioteca para requisições HTTP
|
||||
- **ViaCEP API**: API pública brasileira de consulta de CEP
|
||||
|
||||
## Exemplos de CEPs Válidos
|
||||
|
||||
- `01310-100` - Av. Paulista, São Paulo/SP
|
||||
- `20040-020` - Centro, Rio de Janeiro/RJ
|
||||
- `30130-010` - Centro, Belo Horizonte/MG
|
||||
- `40020-000` - Centro, Salvador/BA
|
||||
- `80010-000` - Centro, Curitiba/PR
|
||||
|
||||
## Créditos
|
||||
|
||||
Dados fornecidos por [ViaCEP](https://viacep.com.br/)
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
"""
|
||||
App Streamlit de Busca de CEP
|
||||
Aplicativo para buscar informações de endereço através do CEP brasileiro
|
||||
com validação robusta e integração com a API ViaCEP.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
import requests
|
||||
import re
|
||||
from typing import Optional, Dict, Any
|
||||
import time
|
||||
|
||||
|
||||
class CEPValidator:
|
||||
"""Classe para validação de CEP brasileiro."""
|
||||
|
||||
@staticmethod
|
||||
def sanitize_cep(cep: str) -> str:
|
||||
"""
|
||||
Remove caracteres não numéricos do CEP.
|
||||
|
||||
Args:
|
||||
cep: String do CEP a ser sanitizado
|
||||
|
||||
Returns:
|
||||
CEP contendo apenas dígitos
|
||||
"""
|
||||
return re.sub(r'\D', '', cep)
|
||||
|
||||
@staticmethod
|
||||
def validate_format(cep: str) -> bool:
|
||||
"""
|
||||
Valida o formato do CEP.
|
||||
|
||||
Args:
|
||||
cep: String do CEP a ser validado
|
||||
|
||||
Returns:
|
||||
True se o formato é válido, False caso contrário
|
||||
"""
|
||||
# Remove caracteres não numéricos
|
||||
clean_cep = CEPValidator.sanitize_cep(cep)
|
||||
|
||||
# CEP deve ter exatamente 8 dígitos
|
||||
if len(clean_cep) != 8:
|
||||
return False
|
||||
|
||||
# Verifica se contém apenas dígitos
|
||||
if not clean_cep.isdigit():
|
||||
return False
|
||||
|
||||
# Verifica se não é um CEP inválido (todos os dígitos iguais)
|
||||
if len(set(clean_cep)) == 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def format_cep(cep: str) -> str:
|
||||
"""
|
||||
Formata o CEP no padrão XXXXX-XXX.
|
||||
|
||||
Args:
|
||||
cep: String do CEP a ser formatado
|
||||
|
||||
Returns:
|
||||
CEP formatado
|
||||
"""
|
||||
clean_cep = CEPValidator.sanitize_cep(cep)
|
||||
return f"{clean_cep[:5]}-{clean_cep[5:]}"
|
||||
|
||||
|
||||
class ViaCEPAPI:
|
||||
"""Classe para interação com a API ViaCEP."""
|
||||
|
||||
BASE_URL = "https://viacep.com.br/ws"
|
||||
TIMEOUT = 10
|
||||
MAX_RETRIES = 3
|
||||
|
||||
@staticmethod
|
||||
def search_cep(cep: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Busca informações de endereço através do CEP.
|
||||
|
||||
Args:
|
||||
cep: String do CEP a ser buscado
|
||||
|
||||
Returns:
|
||||
Dicionário com informações do endereço ou None em caso de erro
|
||||
"""
|
||||
clean_cep = CEPValidator.sanitize_cep(cep)
|
||||
url = f"{ViaCEPAPI.BASE_URL}/{clean_cep}/json/"
|
||||
|
||||
for attempt in range(ViaCEPAPI.MAX_RETRIES):
|
||||
try:
|
||||
response = requests.get(url, timeout=ViaCEPAPI.TIMEOUT)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
|
||||
# ViaCEP retorna {"erro": true} quando o CEP não existe
|
||||
if data.get("erro"):
|
||||
return None
|
||||
|
||||
return data
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
if attempt < ViaCEPAPI.MAX_RETRIES - 1:
|
||||
time.sleep(1)
|
||||
continue
|
||||
st.error("⏱️ Tempo de espera excedido. Tente novamente.")
|
||||
return None
|
||||
|
||||
except requests.exceptions.ConnectionError:
|
||||
if attempt < ViaCEPAPI.MAX_RETRIES - 1:
|
||||
time.sleep(1)
|
||||
continue
|
||||
st.error("🔌 Erro de conexão. Verifique sua internet.")
|
||||
return None
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
st.error(f"❌ Erro HTTP: {e}")
|
||||
return None
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"❌ Erro na requisição: {e}")
|
||||
return None
|
||||
|
||||
except ValueError:
|
||||
st.error("❌ Erro ao processar resposta da API.")
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def display_address(data: Dict[str, Any]) -> None:
|
||||
"""
|
||||
Exibe as informações de endereço formatadas.
|
||||
|
||||
Args:
|
||||
data: Dicionário com informações do endereço
|
||||
"""
|
||||
st.success("✅ CEP encontrado!")
|
||||
|
||||
# Criar colunas para melhor visualização
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.markdown("### 📍 Informações do Endereço")
|
||||
st.markdown(f"**CEP:** {data.get('cep', 'N/A')}")
|
||||
st.markdown(f"**Logradouro:** {data.get('logradouro', 'N/A')}")
|
||||
st.markdown(f"**Complemento:** {data.get('complemento', 'N/A')}")
|
||||
st.markdown(f"**Bairro:** {data.get('bairro', 'N/A')}")
|
||||
|
||||
with col2:
|
||||
st.markdown("### 🏙️ Localização")
|
||||
st.markdown(f"**Cidade:** {data.get('localidade', 'N/A')}")
|
||||
st.markdown(f"**Estado:** {data.get('uf', 'N/A')}")
|
||||
st.markdown(f"**IBGE:** {data.get('ibge', 'N/A')}")
|
||||
st.markdown(f"**DDD:** {data.get('ddd', 'N/A')}")
|
||||
|
||||
# Informações adicionais se disponíveis
|
||||
if data.get('gia'):
|
||||
st.markdown(f"**GIA:** {data.get('gia')}")
|
||||
|
||||
if data.get('siafi'):
|
||||
st.markdown(f"**SIAFI:** {data.get('siafi')}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Função principal do aplicativo."""
|
||||
|
||||
# Configuração da página
|
||||
st.set_page_config(
|
||||
page_title="Busca de CEP",
|
||||
page_icon="📮",
|
||||
layout="centered",
|
||||
initial_sidebar_state="collapsed"
|
||||
)
|
||||
|
||||
# Título e descrição
|
||||
st.title("📮 Busca de CEP")
|
||||
st.markdown("""
|
||||
Busque informações de endereço através do CEP brasileiro.
|
||||
Digite um CEP válido no formato **XXXXX-XXX** ou **XXXXXXXX**.
|
||||
""")
|
||||
|
||||
# Sidebar com informações
|
||||
with st.sidebar:
|
||||
st.header("ℹ️ Sobre")
|
||||
st.markdown("""
|
||||
Este aplicativo permite buscar informações de endereço através do CEP.
|
||||
|
||||
**Recursos:**
|
||||
- ✅ Validação robusta de CEP
|
||||
- 🔄 Retry automático em caso de falha
|
||||
- 📊 Interface intuitiva
|
||||
- 🚀 Integração com ViaCEP
|
||||
|
||||
**Formato aceito:**
|
||||
- 12345-678
|
||||
- 12345678
|
||||
""")
|
||||
|
||||
st.header("📋 Exemplos")
|
||||
st.code("01310-100 # Av. Paulista, SP")
|
||||
st.code("20040-020 # Centro, RJ")
|
||||
st.code("30130-010 # Centro, BH")
|
||||
|
||||
# Formulário de busca
|
||||
with st.form(key="cep_form", clear_on_submit=False):
|
||||
cep_input = st.text_input(
|
||||
"Digite o CEP:",
|
||||
max_chars=9,
|
||||
placeholder="Ex: 01310-100",
|
||||
help="Digite o CEP com ou sem hífen"
|
||||
)
|
||||
|
||||
col1, col2, col3 = st.columns([1, 1, 2])
|
||||
with col1:
|
||||
search_button = st.form_submit_button("🔍 Buscar", use_container_width=True)
|
||||
with col2:
|
||||
clear_button = st.form_submit_button("🗑️ Limpar", use_container_width=True)
|
||||
|
||||
# Processar busca
|
||||
if search_button and cep_input:
|
||||
# Validar formato
|
||||
if not CEPValidator.validate_format(cep_input):
|
||||
st.error("❌ CEP inválido! Digite um CEP válido com 8 dígitos.")
|
||||
st.info("💡 Exemplos válidos: 01310-100, 01310100")
|
||||
else:
|
||||
# Mostrar CEP formatado
|
||||
formatted_cep = CEPValidator.format_cep(cep_input)
|
||||
st.info(f"🔎 Buscando informações para o CEP: **{formatted_cep}**")
|
||||
|
||||
# Buscar na API
|
||||
with st.spinner("Consultando API..."):
|
||||
result = ViaCEPAPI.search_cep(cep_input)
|
||||
|
||||
# Exibir resultado
|
||||
if result:
|
||||
display_address(result)
|
||||
else:
|
||||
st.warning("⚠️ CEP não encontrado. Verifique se o CEP está correto.")
|
||||
|
||||
elif search_button and not cep_input:
|
||||
st.warning("⚠️ Por favor, digite um CEP para buscar.")
|
||||
|
||||
# Rodapé
|
||||
st.markdown("---")
|
||||
st.markdown(
|
||||
"<div style='text-align: center; color: gray;'>"
|
||||
"Desenvolvido com Streamlit | Dados fornecidos por ViaCEP"
|
||||
"</div>",
|
||||
unsafe_allow_html=True
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
streamlit>=1.31.0
|
||||
requests>=2.31.0
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
"""
|
||||
Script de teste para validação de CEP
|
||||
Demonstra as funcionalidades de validação implementadas
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Adiciona o diretório ao path para importar as classes
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
# Importa apenas as classes necessárias para teste sem rodar o Streamlit
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class CEPValidator:
|
||||
"""Classe para validação de CEP brasileiro."""
|
||||
|
||||
@staticmethod
|
||||
def sanitize_cep(cep: str) -> str:
|
||||
"""Remove caracteres não numéricos do CEP."""
|
||||
return re.sub(r'\D', '', cep)
|
||||
|
||||
@staticmethod
|
||||
def validate_format(cep: str) -> bool:
|
||||
"""Valida o formato do CEP."""
|
||||
clean_cep = CEPValidator.sanitize_cep(cep)
|
||||
|
||||
if len(clean_cep) != 8:
|
||||
return False
|
||||
|
||||
if not clean_cep.isdigit():
|
||||
return False
|
||||
|
||||
if len(set(clean_cep)) == 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def format_cep(cep: str) -> str:
|
||||
"""Formata o CEP no padrão XXXXX-XXX."""
|
||||
clean_cep = CEPValidator.sanitize_cep(cep)
|
||||
return f"{clean_cep[:5]}-{clean_cep[5:]}"
|
||||
|
||||
|
||||
def test_cep_validation():
|
||||
"""Testa a validação de CEP com vários casos."""
|
||||
|
||||
test_cases = [
|
||||
# (CEP de entrada, esperado válido, descrição)
|
||||
("01310-100", True, "CEP válido com hífen"),
|
||||
("01310100", True, "CEP válido sem hífen"),
|
||||
("12345-678", True, "CEP válido formato padrão"),
|
||||
("12345678", True, "CEP válido 8 dígitos"),
|
||||
("1234567", False, "CEP com 7 dígitos"),
|
||||
("123456789", False, "CEP com 9 dígitos"),
|
||||
("00000000", False, "CEP com todos dígitos iguais"),
|
||||
("11111-111", False, "CEP com todos dígitos iguais"),
|
||||
("abcd-efgh", False, "CEP com letras"),
|
||||
("", False, "CEP vazio"),
|
||||
("12345", False, "CEP muito curto"),
|
||||
("20040-020", True, "CEP Rio de Janeiro"),
|
||||
("30130-010", True, "CEP Belo Horizonte"),
|
||||
]
|
||||
|
||||
print("=" * 70)
|
||||
print("TESTE DE VALIDAÇÃO DE CEP")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
for cep, expected_valid, description in test_cases:
|
||||
is_valid = CEPValidator.validate_format(cep)
|
||||
status = "✅ PASSOU" if is_valid == expected_valid else "❌ FALHOU"
|
||||
|
||||
if is_valid == expected_valid:
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
print(f"{status} | {description}")
|
||||
print(f" Entrada: '{cep}'")
|
||||
print(f" Esperado: {'Válido' if expected_valid else 'Inválido'}")
|
||||
print(f" Resultado: {'Válido' if is_valid else 'Inválido'}")
|
||||
|
||||
if is_valid:
|
||||
formatted = CEPValidator.format_cep(cep)
|
||||
sanitized = CEPValidator.sanitize_cep(cep)
|
||||
print(f" Sanitizado: '{sanitized}'")
|
||||
print(f" Formatado: '{formatted}'")
|
||||
|
||||
print()
|
||||
|
||||
print("=" * 70)
|
||||
print(f"RESULTADO FINAL: {passed} passou, {failed} falhou de {len(test_cases)} testes")
|
||||
print("=" * 70)
|
||||
|
||||
return failed == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_cep_validation()
|
||||
sys.exit(0 if success else 1)
|
||||
Loading…
Reference in New Issue