== compare() — o coração da formatação condicional == ok 30 > 20 ok 20 NÃO > 30 ok 20 >= 20 ok 15 <= 20 ok 10 < 20 ok 5 = 5 ok 5 != 6 ok numérico com string "20" ok decimal 19.9 < 20 == entre == ok 25 entre 20 e 30 ok 20 entre 20 e 30 (borda) ok 30 entre 20 e 30 (borda) ok 35 NÃO entre 20 e 30 ok entre invertido tolera == texto == ok LIBERADO = liberado ok contém ok não contém ok texto com > não casa == verdadeiro / falso (ligado-desligado) == ok ON é verdadeiro ok 1 é verdadeiro ok OFF é falso ok 0 é falso ok null é falso ok null NÃO é verdadeiro ok null nunca casa em > == condMatches (fonte -> contexto) == ok água <= 20 ok água NÃO > 20 ok dispositivo 7 ligado ok temp > 30 ok fonte inexistente falha ok fonte vazia falha == allMatch (E / OU) == ok sem condições = passa ok E: true+false = false ok E: true+true = true ok OU: true+false = true ok OU: false+false = false == timeMatches (horário + dias) == ok 19:30 casa ok 19:31 não casa ok dia certo (seg=1) ok dia errado (dom/sáb) ok dias vazio = todos ok hora inválida == sunMatches (pôr do sol + offset) — o caso 'sunset+1h acende as luzes' == ok no alvo (sunset+60min) ok 30s depois (tolerância) ok antes do alvo NÃO ok muito depois NÃO ok offset negativo ok sem sol = não casa == render() — variáveis na mensagem == ok substitui ok variável ausente = vazio ok sem variáveis passa ok múltiplas variáveis ok repete a mesma variável ok mantém % e pontuação ok data_hora global == passageExtras — filtros do InControl (dispositivo / detalhe) == ok sem filtro passa ok dispositivo casa ok dispositivo sem acento ok dispositivo não casa ok detalhe casa ok detalhe não casa ok campo ausente no evento == incontrolAcesso — derivar LIBERADO/NEGADO do texto == ok acesso liberado ok face identificada ok acesso negado ok nao identificada ok sem permissao ok NEGADO vence ok texto vazio ok texto neutro == ESCALONAMENTO: offline por tempo (reusa AlertMatch::offlineFires) == ok 2 min: nenhum degrau ok 6 min: degrau 0 ok 6 min (0 já feito) ok 31 min: 0 e 1 ok 31 min (0 feito): só 1 == ESCALONAMENTO: limiares por nível (reusa AlertMatch::waterTarget) == ok nível 40: fora ok nível 25: degrau 30 ok nível 12: MAIS severo ok nível 12 satisfaz 2 ok 12 (severo feito) → 30 ok ambos feitos: nada ================================================== RESULTADO: OK — 81 teste(s) passaram.