18/29Bloque opcional · El paquete Composer de convencionesArch tests de Pest y código compartido desde un paquete Composer
0%Tu lecturaQuedan 20 min
Lección 18 de 29· Bloque opcional · El paquete Composer de convenciones
Arch tests de Pest y código compartido desde un paquete Composer
20 min de lecturaClaude Code 2.1
Hola, bienvenido. En esta lección vamos a llevar al paquete de convenciones el ViewModel de helpdesk y los 18 arch tests del proyecto. Así, todos los repos del equipo van a comprobar las mismas convenciones con los mismos tests, y una convención que cambia llegará a cada repo junto con el test que la comprueba, en la misma versión del paquete.
En la lección anterior movimos al paquete los documentos que explican las convenciones. Pero lo que de verdad hace cumplir una convención es su arch test, y en el equipo de Marta los arch tests también se copiaron de repo en repo. Un repo tenía 12 y otro 19, porque los que se añadieron después de la copia nunca llegaron al primero. Y hubo un caso peor: cuando el equipo decidió que los servicios tenían que ser readonly, alguien lo cambió en el documento de convención y en algunos repos, pero no en los tests de otros 2, que siguieron aceptando servicios que la convención ya no permitía.
Tu proyecto trae 2 piezas que no dependen de nada propio de helpdesk. Una es el ViewModel de app/ViewModels/ViewModel.php, del que extienden los ViewModels de cada vista. La otra son los 18 arch tests de tests/Architecture/ArchTest.php. Las 2 van a pasar al paquete: el ViewModel, como código que cada repo usa en producción, y los arch tests, como una clase que cada repo llama con una sola línea y que conserva el nombre de cada test.
01
El ViewModel en el paquete
Vamos a crear las 2 carpetas nuevas del paquete, en la pestaña conventions:
Terminal
$ mkdir -p src/ViewModels src/Testing
Vamos a crear el ViewModel en conventions/src/ViewModels/ViewModel.php. Es el mismo de tu proyecto, con el namespace del paquete:
El autoload PSR-4 que escribimos en composer.json en la lección anterior ya cubre src/, así que no hay nada que añadir. Es el código que anunciamos en la lección anterior al instalar el paquete en require: cada ViewModel de cada proyecto extiende esta clase, así que tiene que estar también en producción.
El documento de ViewModels del paquete tiene que decir el namespace nuevo, y vamos a aprovechar para cambiar una regla: los ViewModels dejan de recibir el Request y reciben solo los datos que necesitan, que el controller lee de la petición. Así no dependen de HTTP y se prueban pasándoles los datos. Vamos a cambiarlo en conventions/resources/docs/architecture/viewmodels.md:
144Los Resources solo existen en contexto API. En web no hay Resources:
145el ViewModel entrega los datos a Blade.
146
147## Cuándo usar ViewModel
148
149- La vista/respuesta necesita **más de un tipo de dato** → ViewModel siempre.
150- Respuesta API simple de un solo tipo → puede bastar un Resource directo.
151- Listados con filtros/ordenación/paginación → ViewModel de listado: cuando el caso lo pide, ahí se aplica el pipeline de filtros sobre el builder (ver .ai/docs/architecture/filters.md).
152- Formularios create+edit → un único ViewModel Upsert (mismo formulario, con o sin modelo).
144Los Resources solo existen en contexto API. En web no hay Resources:
145el ViewModel entrega los datos a Blade.
146
147## Cuándo usar ViewModel
148
149- La vista/respuesta necesita **más de un tipo de dato** → ViewModel siempre.
150- Respuesta API simple de un solo tipo → puede bastar un Resource directo.
151- Listados con filtros/ordenación/paginación → ViewModel de listado: cuando el caso lo pide, ahí se aplica el pipeline de filtros sobre el builder (ver .ai/docs/architecture/filters.md).
152- Formularios create+edit → un único ViewModel Upsert (mismo formulario, con o sin modelo).
157- Clase `final` que **extiende**`Cursosdesarrolloweb\Conventions\ViewModels\ViewModel` (hay arch test).
158- Un método público = un dato expuesto. Helpers en `private`.
159- Solo lecturas: nunca escribe, nunca llama Actions.
160- Nada de lógica de negocio: solo dar forma a datos para presentación.
161
162## ❌ Incorrecto
163
164```php
165// Controller montando arrays a mano para la vista
166return view('dashboard', [
167 'totalOrders' => Order::count(), // query en el controller
168 'recent' => Order::latest()->get(), // sin límite, sin scope
169]);
170
171// ViewModel implementando Arrayable por su cuenta, sin la base
172final class DashboardViewModel implements Arrayable { ... }
173```
Del namespace son 5 líneas: el título del apartado, el namespace en el código de la clase, las 2 menciones de la clase en el texto y el use del ejemplo. El resto es la regla nueva: el apartado que dice cómo recibe sus datos un ViewModel y los 3 ejemplos de código.
Lo que queda de esta lección
02Los 18 arch tests como una clase del paquete
03Por qué no un preset de Pest
04La 1.1.0 del paquete
05Los arch tests del paquete en helpdesk
06Los arch tests propios del repo
07La prueba: 3 incumplimientos a propósito
Sigue leyendo con tu suscripciónEl curso completo, con su proyecto final, el certificado y el foro, está incluido en la suscripción.Ver los planes¿Ya tienes cuenta? Entra
Usamos cookies propias necesarias para que la plataforma funcione y, solo con tu permiso, cookies de analítica para entender cómo se usa la web. No usamos cookies publicitarias.
Más información.
Preferencias de cookies
Elige qué cookies quieres permitir. Puedes cambiarlo cuando quieras.
NecesariasImprescindibles para iniciar sesión, recordar tu sesión y proteger los formularios. No se pueden desactivar.
Siempre activas
Google Analytics, para medir de forma agregada cómo se usa la plataforma y mejorarla.