- Rust 93.3%
- Shell 6.7%
`check_wall_collision` invertia `vy` sem corrigir `y`. Inverter a velocidade decide para onde a bola vai no frame SEGUINTE; o frame que detectou a colisão já a tinha movido para além da parede, e o estado ao fim dele ficava com a bola fora do campo -- `y = -0.11`, por exemplo. Isso viola o `assert_valid_game_state`, que é a invariante que a própria suíte afirma, e fazia `test_simulate_frames_with_state_changes` falhar ou passar conforme o `vy` sorteado em `Ball::new`. Um teste que falha ao acaso ensina a ignorar teste. A correção prende a bola na parede que ela tocou, além de inverter a direção. Nenhum teste existente fixava `ball.y` depois da colisão -- todos olhavam só para `vy` --, então a suíte inteira continua valendo. Vai junto um teste de regressão com valores fixos: o defeito dependia do acaso, o teste que o pega não pode depender. Este commit também traz a correção do `mutacao()` no hook (--output . e o scratch fora da tmpfs), pelo mesmo motivo dos outros repositórios. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PhdPjHUuVhXaitwT4mG53t |
||
|---|---|---|
| .cargo | ||
| .githooks | ||
| .woodpecker | ||
| src | ||
| tests | ||
| .gitignore | ||
| .mutants-teto | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
Pong
Pong de dois jogadores em terminal, escrito como protótipo de curso de Rust.
O jogador 1 usa W/S, o jogador 2 as setas. ESPAÇO começa e pausa,
ESC sai. Cinco pontos encerram a partida.
cargo run
O que este projeto exercita
- Física simples e determinística: a bola tem posição e velocidade,
e cada quadro é
updateseguido das checagens de colisão. Nada de ponto flutuante escondido em lugar nenhum. - Renderização injetável:
Renderer<W: Write>é genérico sobre a saída. Em produção escreve nostdout; nos testes escreve numVec<u8>, que é conferido byte a byte — inclusive as sequências de escape do terminal. - Aritmética que não estoura:
Game::newe as colisões usamsaturating_sub. Campos menores que a raquete já derrubaram este jogo duas vezes, uma em cada eixo.
cargo test --features visual -- --ignored # inspeção visual na tela
Testes
cargo test # 284 testes
cargo test --test spider # propriedades (proptest)
cargo test --test mutantes # testes nascidos do cargo-mutants
cargo mutants # teto de 4 sobreviventes, todos documentados
Foi a varredura de dimensões de campo em tests/spider que encontrou o
estouro de u16 em check_paddle_collisions. E foi o cargo mutants
que mostrou que 18 mutantes sobreviviam dentro de src/renderer.rs: o
renderer era genérico justamente para poder ser inspecionado, mas nenhum
teste olhava o que ele escrevia.
Verificações antes do commit
O .githooks/pre-commit roda aqui o que o Woodpecker roda no servidor. Ele
é gerado a partir do .woodpecker/pipelines.yml deste repositório, então os
comandos não podem divergir do CI. Ative uma vez por clone -- o hook é
versionado, a configuração que aponta para ele não é:
git config core.hooksPath .githooks
Roda tudo a cada git commit, do mais barato ao mais caro, e para no
primeiro que falhar: lint do pipeline, cargo fmt --check, clippy com -D warnings, build, testes, documentação sem buracos, build release, cobertura
(piso 99%), auditoria de dependências e a perna MSRV 1.90.
O teste de mutação só existe aqui. Ele saiu do pipeline: mutação
recompila o crate uma vez por mutante, e no runner isso eram dezenas de
minutos por push, num passo que ninguém acompanha enquanto espera. O teto
continua em .mutants-teto, versionado -- a regra não afrouxou, mudou de
lugar. É de longe a etapa mais lenta; para pular só ela:
PRE_COMMIT_SEM_MUTACAO=1 git commit ...
Para pular tudo, git commit --no-verify. Um hook que não se pode pular é
um hook que todo mundo desativa.
Licença
GPL-3.0-or-later. Veja LICENSE.