16.1 Introducción
En el tema anterior generamos una lista de tareas con tres archivos: index.html, styles.css y app.js. La aplicación mostró un flujo principal, pero todavía no realizamos una revisión sistemática.
Revisar no consiste únicamente en buscar errores de sintaxis. Debemos comprender la estructura, verificar que cada requisito tenga una implementación, reconocer supuestos y anticipar situaciones que la primera demostración podría ocultar.
En este tema conservaremos el código original. Registraremos hallazgos y prepararemos hipótesis que luego comprobaremos mediante pruebas manuales.
16.2 Preservar el punto de partida
Antes de revisar necesitamos identificar exactamente qué versión analizamos. Si modificamos mientras leemos, podemos perder la relación entre un hallazgo y el código que lo produjo.
Conviene conservar:
- La solicitud inicial enviada a la IA.
- Los criterios de aceptación.
- Los tres archivos sin modificaciones posteriores.
- La fecha y el entorno utilizado.
- Las primeras observaciones de ejecución.
Un sistema de control de versiones permite guardar este estado y comparar correcciones futuras. Sin esa herramienta, podemos crear una copia claramente identificada y evitar sobrescribir el único ejemplar.
16.3 Revisar por capas
Leer todos los archivos al mismo tiempo dificulta mantener una pregunta clara. Podemos organizar la revisión en capas:
| Capa | Pregunta principal |
|---|---|
| Alcance | ¿El cambio corresponde con lo solicitado? |
| Estructura | ¿Los elementos y archivos tienen responsabilidades claras? |
| Datos | ¿Cómo se representa y modifica una tarea? |
| Flujo | ¿Qué ocurre desde la acción hasta la actualización visual? |
| Errores | ¿Qué entradas y estados inesperados se contemplan? |
| Calidad | ¿Es accesible, seguro, claro y mantenible? |
Una observación puede pertenecer a varias capas. El orden sirve para no confundir preferencias de estilo con defectos funcionales.
16.4 Comparar alcance e implementación
La solicitud inicial pedía agregar, completar, eliminar y contar tareas, impedir entradas vacías y mantener los datos en memoria. No pedía editar, filtrar ni conservar después de recargar.
| Requisito | Evidencia en el código | Estado de revisión |
|---|---|---|
| Agregar con botón o Enter | Evento submit del formulario. |
Implementado; falta probar ambos caminos. |
| Rechazar texto vacío | trim() y retorno anticipado. |
Implementado; no ofrece mensaje visible. |
| Completar y descompletar | Casilla que modifica completada. |
Implementado; falta verificar contador y aspecto. |
| Eliminar una tarea | Filtrado por identificador. | Implementado; falta probar tareas repetidas. |
| Contar pendientes | Filtro de elementos no completados. | Implementado; revisar singular y plural. |
| Datos en memoria | Arreglo sin almacenamiento. | Cumple el alcance; no es un defecto. |
Esta tabla convierte impresiones en afirmaciones que podremos comprobar. También evita marcar como error una función que nunca fue solicitada.
16.5 Revisión de index.html
El documento utiliza elementos adecuados para su función:
<html lang="es">declara el idioma.<main>contiene el propósito principal.- Existe un único título de nivel uno.
- El campo tiene una etiqueta asociada mediante
foreid. - El botón pertenece a un formulario y tiene tipo
submit. - La lista dinámica utiliza
<ul>. - El contador anuncia cambios mediante
aria-live="polite".
El script aparece al final del cuerpo. Por eso los elementos ya existen cuando JavaScript intenta seleccionarlos, aunque no utilice el atributo defer.
Como mejora posible, el campo podría incorporar una longitud máxima acordada. No conviene inventar ese límite durante la revisión: primero debe convertirse en requisito.
16.6 Revisión de styles.css
Los estilos son independientes del comportamiento y utilizan clases con nombres relacionados con el contenido. La página limita su ancho, se adapta a pantallas pequeñas y ofrece foco visible.
Aspectos favorables:
box-sizing: border-boxsimplifica el cálculo de tamaños.- El campo puede reducir su ancho gracias a
min-width: 0. - Los textos largos pueden cortarse mediante
overflow-wrap. - La tarea completada no depende solo del color: también utiliza tachado.
- La consulta de medios reorganiza el formulario en pantallas estrechas.
:focus-visibleayuda a reconocer el control activo.
La revisión visual deberá comprobar contraste, ampliación, textos largos y foco real. Leer los valores CSS permite anticipar, pero no demuestra, la experiencia final.
16.7 Modelo de datos de una tarea
Cada tarea se representa mediante un objeto con tres propiedades:
{
id: 1,
texto: "Estudiar JavaScript",
completada: false
}
Esta representación permite distinguir tareas con el mismo texto, mostrar su contenido y conservar su estado.
El identificador aumenta con proximoId. Como los datos viven solo durante la sesión, no necesita coordinarse con una base externa. Si más adelante se agrega almacenamiento, será necesario revisar cómo se recupera y evita la repetición de identificadores.
16.8 Flujo para agregar una tarea
Seguimos el evento desde la acción hasta la pantalla:
- La persona envía el formulario con el botón o Enter.
preventDefault()evita que el navegador recargue la página.- Se lee el campo y
trim()elimina espacios de los extremos. - Si el resultado está vacío, se devuelve el foco y termina el evento.
- Se agrega un objeto al arreglo
tareas. - Se incrementa el próximo identificador.
- Se limpia el campo y se vuelve a enfocar.
renderizarTareas()reconstruye la lista y el contador.
El flujo cubre el caso principal y la entrada vacía. La ausencia de un mensaje de validación es un hallazgo: una persona puede no comprender por qué no ocurrió nada, especialmente si el campo contenía espacios.
16.9 Flujo para completar y eliminar
Cada elemento crea sus propios controles y eventos. La casilla modifica el mismo objeto de tarea que fue utilizado para construirla. El botón de eliminación crea un nuevo arreglo sin el identificador seleccionado.
tareas = tareas.filter(item => item.id !== tarea.id);
El uso del identificador es importante. Si se eliminara por texto, dos tareas llamadas “Comprar pan” podrían confundirse.
Después de cada acción se reconstruye toda la lista. Para una aplicación pequeña resulta simple y suficiente. Con miles de elementos podría generar trabajo innecesario, pero optimizar ahora agregaría complejidad sin una necesidad medida.
16.10 Validación y mensajes para la persona usuaria
La validación actual impide incorporar una cadena vacía. Es correcta para el requisito mínimo, pero la respuesta ante el error es silenciosa.
| Entrada | Comportamiento del código | Pregunta de revisión |
|---|---|---|
| Cadena vacía | No agrega y devuelve el foco. | ¿La persona comprende qué debe corregir? |
| Solo espacios | trim() la convierte en vacía. |
¿Se anuncia el mismo error? |
| Espacios en extremos | Los elimina antes de guardar. | ¿Coincide con lo esperado? |
| Texto muy largo | Lo acepta sin límite. | ¿Necesitamos una restricción definida? |
| Texto repetido | Lo acepta como una tarea distinta. | ¿Las repeticiones están permitidas? |
Las dos últimas preguntas pertenecen al producto. No deberíamos cambiar el comportamiento hasta acordar una respuesta.
16.11 Accesibilidad de los elementos dinámicos
La casilla y el botón reciben nombres accesibles construidos con el texto de la tarea:
casilla.setAttribute("aria-label", `Completar ${tarea.texto}`);
botonEliminar.setAttribute("aria-label", `Eliminar ${tarea.texto}`);
Esto permite distinguir controles cuando existen varias tareas. Sin embargo, al marcar la casilla el texto “Completar” no cambia a “Marcar como pendiente”. Debemos probar cómo se anuncia el estado junto con la propiedad nativa checked.
También revisaremos navegación por teclado, orden de foco, anuncio del contador y comprensión del rechazo de una tarea vacía. La revisión identifica estas preguntas; la prueba manual proporcionará evidencia.
16.12 Seguridad y tratamiento del texto
El contenido escrito por la persona se asigna mediante textContent:
texto.textContent = tarea.texto;
El navegador lo representa como texto y no lo interpreta como HTML. Esta elección es preferible a construir una cadena e insertarla con innerHTML.
La aplicación no envía datos a un servidor ni utiliza almacenamiento, por lo que su superficie actual es limitada. Si agregamos persistencia, sincronización o cuentas, será necesario validar nuevamente límites, permisos, exposición y tratamiento de errores.
No debemos declarar que la aplicación es “segura” en términos absolutos. Podemos documentar qué riesgo concreto reduce la operación observada.
16.13 Claridad y mantenimiento
Los nombres están en español y describen su función. Las operaciones principales se separan en actualizarContador, crearElementoTarea y renderizarTareas.
Algunas decisiones facilitan el mantenimiento:
- HTML, CSS y JavaScript están separados.
- No existen dependencias externas.
- El estado se concentra en un único arreglo.
- La representación visual se reconstruye desde ese estado.
- Las clases CSS siguen una convención consistente.
La función crearElementoTarea reúne creación de nodos, atributos y eventos. Para el tamaño actual resulta legible. Solo convendría dividirla si crece o aparecen responsabilidades reutilizables.
16.14 Clasificar los hallazgos
No todas las observaciones tienen la misma prioridad. Podemos utilizar cuatro categorías:
| Categoría | Hallazgo del proyecto | Acción |
|---|---|---|
| Defecto probable | El contador muestra “1 tareas pendientes”. | Confirmar manualmente y corregir singular/plural. |
| Problema de experiencia | La entrada vacía se rechaza sin explicación. | Probar y diseñar un mensaje accesible. |
| Decisión pendiente | No existe límite de longitud ni regla sobre duplicados. | Acordar requisito antes de modificar. |
| Fuera de alcance | Las tareas no sobreviven a una recarga. | No tratar como error; considerar en la mejora. |
| Optimización futura | Se reconstruye toda la lista en cada acción. | Medir solo si aumenta el volumen. |
Clasificar evita corregir preferencias antes que defectos y ayuda a mantener el alcance del proyecto.
16.15 Informe y plan de prueba
La revisión produce un informe breve que diferencia evidencia, hipótesis y decisiones:
- Confirmado por lectura: existe implementación para todos los requisitos iniciales.
- Hallazgo probable: el contador no contempla singular.
- Riesgo de experiencia: la entrada inválida no muestra explicación.
- Preguntas: longitud máxima y tareas duplicadas.
- Fuera de alcance: persistencia, edición y filtros.
- Pendiente de evidencia: teclado, pantalla pequeña, textos largos y consola.
El próximo paso no será corregir inmediatamente. Diseñaremos casos manuales que confirmen o refuten cada hipótesis sobre la aplicación ejecutada.
16.16 Actividad de comprensión
Utilizá la versión del proyecto que generaste en el tema 15 y realizá tu propia revisión sin modificar los archivos.
- Relacioná cada criterio de aceptación con funciones y líneas concretas.
- Seguí con palabras el flujo para agregar, completar y eliminar.
- Identificá las decisiones tomadas por la IA sin indicación explícita.
- Revisá semántica HTML, foco, nombres accesibles y adaptación visual.
- Buscá operaciones que incorporen texto de la persona.
- Clasificá cada observación como defecto, riesgo, decisión, mejora o elemento fuera de alcance.
- Convertí al menos cinco observaciones en casos para probar manualmente.
Guardá el informe junto con la versión inicial. En el tema siguiente utilizaremos esos casos para recorrer la aplicación y registrar resultados observados.