diff --git a/README.md b/README.md index f9975c76..18dfb8fc 100644 --- a/README.md +++ b/README.md @@ -1,615 +1,151 @@ # Data Lovers -## Índice +## Resumen del proyecto -* [1. Preámbulo](#1-preámbulo) -* [2. Resumen del proyecto](#2-resumen-del-proyecto) -* [3. Objetivos de aprendizaje](#3-objetivos-de-aprendizaje) -* [4. Consideraciones generales](#4-consideraciones-generales) -* [5. Criterios de aceptación mínimos del proyecto](#5-criterios-de-aceptación-mínimos-del-proyecto) -* [6. Hacker edition](#6-hacker-edition) -* [7. Consideraciones técnicas](#7-consideraciones-técnicas) -* [8. Pistas, tips y lecturas complementarias](#8-pistas-tips-y-lecturas-complementarias) -* [9. Checklist](#9-checklist) +Este proyecto tiene como finalidad construir una página web responsive, en la que se interactua con una data ya proporcionada que cuenta con la información de los `251 Pokémon` de la región de Kanto y Johto. La intención es que cualquier usuario interactue en la página tal como lo haría usando una pokedex, en la que se logra visualizar la información deseada de manera precisa y clara, pudiendo interactuar `filtrando, ordenando y obteniendo un cálculo agregado` de la data, para una mejor comprensión de la misma. -*** +## Diseño de la Interfaz de Usuario -## 1. Preámbulo +### Prototipo de baja fidelidad -Según [Forbes](https://www.forbes.com/sites/bernardmarr/2018/05/21/how-much-data-do-we-create-every-day-the-mind-blowing-stats-everyone-should-read), -el 90% de la data que existe hoy ha sido creada durante los últimos dos años. -Cada día generamos 2.5 millones de terabytes de datos, una cifra sin -precedentes. +Desde el prototipo de baja fidelidad buscamos establecer cómo queríamos mostrar la data de los pokemones en la interfaz, quisimos colocarlos dentro de unas columnas y mostrarlos con imágenes en forma de cards. -No obstante, los datos por sí mismos son de poca utilidad. Para que esas -grandes cantidades de datos se conviertan en **información** fácil de leer para -los usuarios, necesitamos entender y procesar estos datos. Una manera simple de -hacerlo es creando _interfaces_ y _visualizaciones_. +Determinamos la posición de la barra de búsqueda y la de los filtrados. +Enlace a nuestro [Excalidraw] https://excalidraw.com/#room=0132c394d322d65e4a26,EZ8riSLZmoiszmN165SZdg -En la siguiente imagen, podrás ver cómo con la data que que se ve en la parte -izquierda se puede construir una interfaz amigable y entendible por las -usuarias, al lado derecho. +![baja fidelidad](src/img/bajaFidelidad.png) -![pokemon-data-to-ui](https://user-images.githubusercontent.com/12631491/218505816-c6d11758-9de4-428f-affb-2a56ea4d68c4.png) +### Prototipo de alta fidelidad -## 2. Resumen del proyecto +Para el prototipo de alta fidelidad nos propusimos un estilo minimalista en escala de grises y una paleta de color pastel, ya que nuestro objetivo era transmitir la información de forma clara y precisa, aprovechamos los colores que corresponden a los tipos Pokémon para darle un acento colorido que lo hiciera atractivo al usuario. -En este proyecto **construirás una _página web_ para visualizar un -_conjunto (set) de datos_** que se adecúe a lo que descubras que tu usuario -necesita. +Investigamos diferentes referencias visuales de diversas pokedex en línea y así llegamos a nuestro prototipo de alta fidelidad. -Como entregable final tendrás una página web que permita **visualizar la data, -filtrarla, ordenarla y hacer algún cálculo agregado**. Con cálculo agregado -nos referimos a distintos cálculos que puedes hacer con la data para mostrar -información aún más relevante para los usuarios (promedio, el valor máximo -o mínimo, etc). +Para bocetarlo consideramos lo siguiente: -Esta vez te proponemos una serie de datos de diferentes _temáticas_ para que -explores y decidas con qué temática te interesa trabajar. Hemos elegido -específicamente estos sets de datos porque creemos que se adecúan bien a esta -etapa de tu aprendizaje. +- Que permita al usuario interactuar para obtener la información que necesita. +- Que fuera **responsive**, es decir, debía visualizarse sin problemas desde distintos +tamaños de pantallas: móviles, tablets y desktops. -Una vez que definas tu área de interés, buscar entender quién es tu usuario -y qué necesita saber o ver exactamente; luego podrás construir la interfaz que -le ayude a interactuar y entender mejor esos datos. +Enlace a nuestro [Figma] https://www.figma.com/file/DtCbPHLUku2wz9R54Xzo3x/dataLovers%2Fcolaborativo?type=design&node-id=0-1&t=R5TqmXOQ5YcmRd3H-0 -Estos son datos que te proponemos: +![alta fidelidad](src/img/altaFidelidad.png) -* [Pokémon](src/data/pokemon/pokemon.json): - En este set encontrarás una lista con los 251 Pokémon de la región de Kanto - y Johto, junto con sus respectivas estadísticas usadas en el juego - [Pokémon GO](http://pokemongolive.com). - - [Investigación con jugadores de Pokémon Go](src/data/pokemon/README.md) +![alta fidelidad1](src/img/altaFidelidad2.png) -* [League of Legends - Challenger leaderboard](src/data/lol/lol.json): - Este set de datos muestra la lista de campeones en una liga del - juego League of Legends (LoL). - - [Investigación con jugadores de LoL](src/data/lol/README.md) +### Testeos de usabilidad -* [Rick and Morty](src/data/rickandmorty/rickandmorty.json). - Este set nos proporciona la lista de los personajes de la serie Rick and - Morty. [API Rick and Morty](https://rickandmortyapi.com). - - [Investigación con seguidores de Rick and Morty](src/data/rickandmorty/README.md) +La mayoría de nuestros testeos ocurrieron durante las demos que tuvimos a lo largo de los sprints, en los cuales las compañeras nos señalaron una serie de características a mejorar. -* [Juegos Olímpicos de Río de Janeiro](src/data/athletes/athletes.json). - Este set nos proporciona la lista de los atletas que ganaron medallas en las - olímpiadas de Río de Janeiro. - - [Investigación con interesados en juegos olímpicos de Río de Janeiro](src/data/athletes/README.md) +- El tamaño de la barra de búsqueda era muy pequeño. +- El texto de nuestros botones en las listas desplegables no era suficientemente legible. +- Inicialmente colocamos el botón de reset al costado derecho de la barra de búsqueda entonces era confuso para el usuario porque parecía que era el botón que enviaba la búsqueda del pokémon por nombre o por número. Lo movimos al extremo derecho y mejoró la legibilidad de la interfaz. +- El padding del tipo de cada pokémon no permitía que fuera legible el tipo, entonces hacía falta agregar más padding para permitir mejor lectura al usuario. +- Que el diseño responsivo se modificara para el celular, ya que nuestro modal pokémon consiste en dos columnas (imagen de pokémon y descripción al costado). Sin embargo, para la versión móvil modificamos un media query que permitiera que la información quedara en una sola columna. +- Al mostrar la gráfica de los porcentajes, las etiquetas de cada tipo eran de un color obscuro y dificultaba su legibilidad, después lo modificamos para que fuera blanco y contrastara con el fondo. -* [Studio Ghibli](src/data/ghibli/ghibli.json). - En este set encontrarás una lista de las animaciones y sus personajes del - [Studio Ghibli](https://ghiblicollection.com/). - - [Investigación con seguidores de las animaciones del Studio Ghibli](src/data/ghibli/README.md) +Gracias al feedback anterior de los usuarios mejoramos la propuesta final. -El objetivo principal de este proyecto es que aprendas a diseñar y construir una -interfaz web donde se pueda visualizar y manipular data, entendiendo lo que el -usuario necesita. +## Historias de Usuario -## 3. Objetivos de aprendizaje +### HU 1. Visualizar todos los pokémon -Reflexiona y luego marca los objetivos que has llegado a entender y aplicar en tu proyecto. Piensa en eso al decidir tu estrategia de trabajo. +Yo, COMO USUARIO pokemón, QUIERO que al ingresar a mi pokédex pueda visualizar todos los pokémon PARA saber cuáles son los que contiene la pokédex. -### HTML +Criterios de Aceptación: -- [ ] **Uso de HTML semántico** +- [✔️] El usuario debe poder visualizar en la pantalla la imagen del pokemon, el nombre, el número de identificación y el tipo, de los 251 pokémones de la BD. +- [✔️] El usuario podrá ver a los 251 pokémones ordenados por su número y en forma de grilla. +- [✔️] La visualización de los pokémones debe poder hacerse fácilmente desde cualquier dispositivo. -
Links

+Definición de Terminado: - * [HTML semántico](https://curriculum.laboratoria.la/es/topics/html/02-html5/02-semantic-html) - * [Semantics - MDN Web Docs Glossary](https://developer.mozilla.org/en-US/docs/Glossary/Semantics#Semantics_in_HTML) -

+- [✔️] El codigo no tiene correcciones de ESLINT. +- [✔️] La función creada para mostrar a los pokemones funciona correctamente. +- [✔️] La HU debe estar desplegada en GitPages para que el usuario pueda iteractuar y aprobarlo. -### CSS +### HU 2. Búsqueda personalizada -- [ ] **Uso de selectores de CSS** +Yo, COMO USUARIO pokémon, QUIERO que exista una barra de búsqueda por nombre o por número de pokémon PARA hacer una búsqueda específica. -
Links

+Criterios de Aceptación: - * [Intro a CSS](https://curriculum.laboratoria.la/es/topics/css/01-css/01-intro-css) - * [CSS Selectors - MDN](https://developer.mozilla.org/es/docs/Web/CSS/CSS_Selectors) -

+- [✔️] El usuario debe identificar el buscador al entrar a la página +- [✔️] El usuario debe poder buscar a los pokemones a través de su nombre o número. +- [✔️] La visualización de los pokemones buscados debe poder hacerse fácilmente desde cualquier dispositivo. +- [✔️] El usuario podrá ver el modal de los pokemon que tengan coincidencia con el inicio de su nombre. -- [ ] **Modelo de caja (box model): borde, margen, padding** +Definición de Terminado: -
Links

+- [✔️] Todos los criterios de aceptación son cumplidos. +- [✔️] El codigo tiene y pasa los test respectivos (como minimo el 70 %). +- [✔️] La HU debe estar desplegado en GitPages para que el usuario pueda interactuar. +- [✔️] El codigo no tiene errores en Eslint. - * [Box Model & Display](https://curriculum.laboratoria.la/es/topics/css/01-css/02-boxmodel-and-display) - * [The box model - MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model) - * [Introduction to the CSS box model - MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model) - * [CSS display - MDN](https://developer.mozilla.org/pt-BR/docs/Web/CSS/display) - * [display - CSS Tricks](https://css-tricks.com/almanac/properties/d/display/) -

+### HU 3. Visualización de pokémon por tipo -- [ ] **Uso de flexbox en CSS** +Yo, COMO USUARIO pokémon, QUIERO que del total de los pokémon pueda filtrar a los pokémon por tipo (eléctrico, agua, fuego, etc) PARA saber cuales pokémon comparten esa característica. -
Links

+Criterios de Aceptación: - * [A Complete Guide to Flexbox - CSS Tricks](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) - * [Flexbox Froggy](https://flexboxfroggy.com/#es) - * [Flexbox - MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) -

+- [✔️] El usuario puede identificar una lista desplegable de nombre "Tipo". +- [✔️] El usuario puede visualizar en la lista desplegable todos los tipos de pokémon que hay en la base de datos. +- [✔️] La lista desplegable debe permitir seleccionar solo un tipo de pokémon. +- [✔️] Al seleccionar el tipo de pokémon el usuario puede visualizar aquellos pokémon que coinciden al menos con ese tipo. -### Web APIs +Definición de Terminado: -- [ ] **Uso de selectores del DOM** +- [✔️] Todos los criterios de aceptación son cumplidos. +- [✔️] El código tiene y pasa los test respectivos. +- [✔️] La HU debe estar desplegado en GitPages para que el usuario pueda iteractuar. +- [✔️] El código no tiene errores en ESLINT. -
Links

+### HU 4. Visualización ordenada ascendente-descendente - * [Manipulación del DOM](https://curriculum.laboratoria.la/es/topics/browser/02-dom/03-1-dom-methods-selection) - * [Introducción al DOM - MDN](https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model/Introduction) - * [Localizando elementos DOM usando selectores - MDN](https://developer.mozilla.org/es/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors) -

+Yo, COMO USUARIO pokémon, QUIERO visualizar por orden ascendente y descendente el nombre y número PARA explorar otras formas el contenido de la pokédex. -- [ ] **Manejo de eventos del DOM (listeners, propagación, delegación)** +Criterios de Aceptación: -
Links

+- [✔️] El usuario puede identificar una lista desplegable de nombre "Ordenar". +- [✔️] El usuario puede visualizar en la lista desplegable el ordenamiento ascendente y descendente por nombre y por número de pokémon. +- [✔️] La lista desplegable debe permitir seleccionar solo un ordenamiento a la vez. +- [✔️] Al seleccionar el ordenamiento correspondiente el usuario puede visualizar la organización de la pokédex de la forma que mejor prefiera. - * [Introducción a eventos - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Events) - * [EventTarget.addEventListener() - MDN](https://developer.mozilla.org/es/docs/Web/API/EventTarget/addEventListener) - * [EventTarget.removeEventListener() - MDN](https://developer.mozilla.org/es/docs/Web/API/EventTarget/removeEventListener) - * [El objeto Event](https://developer.mozilla.org/es/docs/Web/API/Event) -

+Definición de Terminado: -- [ ] **Manipulación dinámica del DOM** +- [✔️] Todos los criterios de aceptación son cumplidos. +- [✔️] El codigo tiene y pasa los test respectivos +- [✔️] La HU debe estar desplegado en GitPages para que el usuario pueda interactuar. +- [✔️] El codigo no tiene errores en Eslint. -
Links

+### HU 5. Visualizar la ficha técnica de cada pokémon. - * [Introducción al DOM](https://developer.mozilla.org/es/docs/Web/API/Document_Object_Model/Introduction) - * [Node.appendChild() - MDN](https://developer.mozilla.org/es/docs/Web/API/Node/appendChild) - * [Document.createElement() - MDN](https://developer.mozilla.org/es/docs/Web/API/Document/createElement) - * [Document.createTextNode()](https://developer.mozilla.org/es/docs/Web/API/Document/createTextNode) - * [Element.innerHTML - MDN](https://developer.mozilla.org/es/docs/Web/API/Element/innerHTML) - * [Node.textContent - MDN](https://developer.mozilla.org/es/docs/Web/API/Node/textContent) -

+Yo, COMO USUARIO pokémon, QUIERO visualizar información más detallada de cada pokémon (peso, altura, resistencia y debilidad) al hacer click sobre cada uno de ellos, PARA tener una mejor estrategia en los combates pokémon. -### JavaScript +Criterios de Aceptación: -- [ ] **Diferenciar entre tipos de datos primitivos y no primitivos** +- [✔️] El usuario puede ver la información detallada del pokemon al hacer *clic* en el área que ocupa este. +- [✔️] El usuario podrá ver la información detallada en una caja emergente (*modal o popup*) +- [✔️] El usuario puede volver a visualizar todos los pokemones al cerrar la caja emergente. +- [✔️] La visualización debe poder hacerse en cualquier dispositivo. -- [ ] **Arrays (arreglos)** +Definición de Terminado: -
Links

+- [✔️] Todos los criterios de aceptación son cumplidos. +- [✔️] La HU debe estar desplegado en GitHub. +- [✔️] El usuario puede volver a visualizar todos los pokemones al cerrar la caja emergente. - * [Arreglos](https://curriculum.laboratoria.la/es/topics/javascript/04-arrays) - * [Array - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/) - * [Array.prototype.sort() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) - * [Array.prototype.forEach() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) - * [Array.prototype.map() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/map) - * [Array.prototype.filter() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) - * [Array.prototype.reduce() - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) -

-- [ ] **Objetos (key, value)** +## Consideraciones Generales -
Links

+- 📍 Este proyecto se realizó en dupla +- 📍 La interfaz del proyecto esta desplegada usando GitHub Pages. - * [Objetos en JavaScript](https://curriculum.laboratoria.la/es/topics/javascript/05-objects/01-objects) -

+## Pruebas Unitarias -- [ ] **Variables (declaración, asignación, ámbito)** +Para las pruebas Unitarias `(tests)`, creamos nuestras propias funciones, estudiamos la documentación de jest, así como la configuración necesaria para ejecutar los tests usando el comando `npm test`. Se cumplió la cobertura minima del **70%** de statements, functions y lines. -
Links

+## Interfaz de Usuario del Proyecto +![desktopPoke](src/img/desktopPoke.jpg) - * [Valores, tipos de datos y operadores](https://curriculum.laboratoria.la/es/topics/javascript/01-basics/01-values-variables-and-types) - * [Variables](https://curriculum.laboratoria.la/es/topics/javascript/01-basics/02-variables) -

- -- [ ] **Uso de condicionales (if-else, switch, operador ternario, lógica booleana)** - -
Links

- - * [Estructuras condicionales y repetitivas](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/01-conditionals-and-loops) - * [Tomando decisiones en tu código — condicionales - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/conditionals) -

- -- [ ] **Uso de bucles/ciclos (while, for, for..of)** - -
Links

- - * [Bucles (Loops)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/02-loops) - * [Bucles e iteración - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Loops_and_iteration) -

- -- [ ] **Funciones (params, args, return)** - -
Links

- - * [Funciones (control de flujo)](https://curriculum.laboratoria.la/es/topics/javascript/02-flow-control/03-functions) - * [Funciones clásicas](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/01-classic) - * [Arrow Functions](https://curriculum.laboratoria.la/es/topics/javascript/03-functions/02-arrow) - * [Funciones — bloques de código reutilizables - MDN](https://developer.mozilla.org/es/docs/Learn/JavaScript/Building_blocks/Functions) -

- -- [ ] **Pruebas unitarias (unit tests)** - -
Links

- - * [Empezando con Jest - Documentación oficial](https://jestjs.io/docs/es-ES/getting-started) -

- -- [ ] **Módulos de ECMAScript (ES Modules)** - -
Links

- - * [import - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/import) - * [export - MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Statements/export) -

- -- [ ] **Uso de linter (ESLINT)** - -- [ ] **Uso de identificadores descriptivos (Nomenclatura y Semántica)** - -- [ ] **Diferenciar entre expresiones (expressions) y sentencias (statements)** - -### Control de Versiones (Git y GitHub) - -- [ ] **Git: Instalación y configuración** - -- [ ] **Git: Control de versiones con git (init, clone, add, commit, status, push, pull, remote)** - -- [ ] **Git: Integración de cambios entre ramas (branch, checkout, fetch, merge, reset, rebase, tag)** - -- [ ] **GitHub: Creación de cuenta y repos, configuración de llaves SSH** - -- [ ] **GitHub: Despliegue con GitHub Pages** - -
Links

- - * [Sitio oficial de GitHub Pages](https://pages.github.com/) -

- -- [ ] **GitHub: Colaboración en Github (branches | forks | pull requests | code review | tags)** - -### Centrado en el usuario - -- [ ] **Diseñar y desarrollar un producto o servicio poniendo a las usuarias en el centro** - -### Diseño de producto - -- [ ] **Crear prototipos de alta fidelidad que incluyan interacciones** - -- [ ] **Seguir los principios básicos de diseño visual** - -### Investigación - -- [ ] **Planear y ejecutar testeos de usabilidad de prototipos en distintos niveles de fidelidad** - -
Links

- - * [Intro a testeos usabilidad](https://coda.io/@bootcamp-laboratoria/contenido-ux/test-de-usabilidad-15) - * [Pruebas con Usuarios 1 — ¿Qué, cuándo y para qué testeamos?](https://eugeniacasabona.medium.com/pruebas-con-usuarios-1-qu%C3%A9-cu%C3%A1ndo-y-para-qu%C3%A9-testeamos-7c3a89b4b5e7) -

- -## 4. Consideraciones generales - -* Este proyecto se debe resolver en duplas. -* El rango de tiempo estimado para completar el proyecto es de 3 a 4 Sprints. -* El proyecto será entregado subiendo tu código a GitHub (commit/push) y la - interfaz será desplegada usando [GitHub Pages](https://pages.github.com/). - -## 5. Criterios de aceptación mínimos del proyecto - -Los criterios para considerar que has completado este proyecto son: - -### Definición del producto - -Documenta brevemente tu trabajo en el archivo `README.md` de tu repositorio, -contándonos cómo fue tu proceso de diseño y cómo crees que el producto resuelve -el problema (o problemas) que tiene tu usuario. - -### Historias de usuario - -Una vez que entiendas las necesidades de tus usuarios, escribe las [Historias -de Usuario](https://es.wikipedia.org/wiki/Historias_de_usuario) que representen -todo lo que el usuario necesita hacer/ver. Las **Historias de Usuario** deben -ser el resultado de tu proceso de investigación o _research_ de tus usuarios. - -Asegúrate de incluir la definición de terminado (_definition of done_) y los -Criterios de Aceptación para cada una. - -En la medida de lo posible, termina una historia de usuario antes de pasar -a la siguiente (Cumple con Definición de Terminado + Criterios de Aceptación). - -### Diseño de la Interfaz de Usuario - -#### Prototipo de baja fidelidad - -Durante tu trabajo deberás haber hecho e iterado bocetos (_sketches_) de tu -solución usando papel y lápiz. Te recomendamos tomar fotos de todas las -iteraciones que hagas, que las subas a tu repositorio y las menciones en tu -`README.md`. - -#### Prototipo de alta fidelidad - -Lo siguiente es diseñar tu Interfaz de Usuario (UI por sus siglas en inglés - -_User Interface_). Para eso debes aprender a utilizar alguna herramienta de -diseño visual. Nosotros te recomendamos [Figma](https://www.figma.com/) que es -una herramienta que funciona en el navegador y, además, puedes crear una cuenta -gratis. Sin embargo, eres libre de utilizar otros editores gráficos como -Illustrator, Photoshop, PowerPoint, Keynote, etc. - -El diseño debe representar el _ideal_ de tu solución. Digamos que es lo que -desearías implementar si tuvieras tiempo ilimitado para trabajar. Además, tu -diseño debe seguir los fundamentos de _visual design_. - -#### Testeos de usabilidad - -Durante el reto deberás hacer _tests_ de usabilidad con distintos usuarios, y -en base a los resultados, deberás iterar tus diseños. Cuéntanos -qué problemas de usabilidad detectaste a través de los _tests_ y cómo los -mejoraste en tu propuesta final. - -### Implementación de la Interfaz de Usuario (HTML/CSS/JS) - -Luego de diseñar tu interfaz de usuario deberás trabajar en su implementación. -**No** es necesario que construyas la interfaz exactamente como la diseñaste. -Tu tiempo de hacking es escaso, así que deberás priorizar - -Como mínimo, tu implementación debe: - -1. Mostrar la data en una interfaz: puede ser un card, una tabla, una lista, - etc. -2. Permitir al usuario interactuar para obtener la infomación que necesita. -3. Ser _responsive_, es decir, debe visualizarse sin problemas desde distintos - tamaños de pantallas: móviles, tablets y desktops. -4. Que la interfaz siga los fundamentos de _visual design_. - -### Pruebas unitarias - -El _boilerplate_ de este proyecto no incluye Pruebas Unitarias (_tests_), así es -que tendrás que escribirlas tú para las funciones encargadas de _procesar_, -_filtrar_ y _ordenar_ la data, así como _calcular_ estadísticas. - -Tus _pruebas unitarias_ deben dar una cobertura del 70% de _statements_ -(_sentencias_), _functions_ (_funciones_), _lines_ (_líneas_), y _branches_ -(_ramas_) del archivo `src/data.js` que contenga tus funciones y está detallado -en la sección de [Consideraciones técnicas](#srcdatajs). - -## 6. Hacker edition - -Las secciones llamadas _Hacker Edition_ son **opcionales**. Si **terminaste** -con todo lo anterior y te queda tiempo, intenta completarlas. Así podrás -profundizar y/o ejercitar más sobre los objetivos de aprendizaje del proyecto. - -Features/características extra sugeridas: - -* En lugar de consumir la data estática brindada en este repositorio, puedes - consumir la data de forma dinámica, cargando un archivo JSON por medio de - `fetch`. La carpeta `src/data` contiene una versión `.js` y una `.json` de - de cada set datos. -* Agregarle a tu interfaz de usuario implementada visualizaciones gráficas. Para - ello te recomendamos explorar librerías de gráficas como - [Chart.js](https://www.chartjs.org/) - o [Google Charts](https://developers.google.com/chart/). -* 100% Coverage - -## 7. Consideraciones técnicas - -La lógica del proyecto debe estar implementada completamente en JavaScript -(ES6), HTML y CSS. En este proyecto NO está permitido usar librerías o -frameworks, solo [vanilla JavaScript](https://medium.com/laboratoria-how-to/vanillajs-vs-jquery-31e623bbd46e), -con la excepción de librerías para hacer gráficas (charts); ver -[_Parte opcional_](#6-hacker-edition) más arriba. - -El _boilerplate_ contiene una estructura de archivos como punto de partida así -como toda la configuración de dependencias: - -```text -. -├── EXTRA.md -├── README.md -├── package.json -├── src -| ├── data (según con qué data trabajes) -| | ├── lol -| | | ├── lol.js -| | | ├── lol.json -| | | └── README.md -| | ├── pokemon -| | | ├── pokemon.js -| | | ├── pokemon.json -| | | └── README.md -| | └── rickandmorty -| | | ├── rickandmorty.js -| | | ├── rickandmorty.json -| | | └── README.md -| | └── athletes -| | | ├── athletes.js -| | | ├── athletes.json -| | | └── README.md -| | └── ghibli -| | | ├── ghibli.js -| | | ├── ghibli.json -| | | └── README.md -| ├── data.js -| ├── index.html -| ├── main.js -| └── style.css -└── test - └── data.spec.js - -directory: 7 file: 20 -``` - -### `src/index.html` - -Como en el proyecto anterior, existe un archivo `index.html`. Como ya sabes, -acá va la página que se mostrará al usuario. También nos sirve para indicar -qué scripts se usarán y unir todo lo que hemos hecho. - -### `src/main.js` - -Recomendamos usar `src/main.js` para todo tu código que tenga que ver con -mostrar los datos en la pantalla. Con esto nos referimos básicamente a la -interacción con el DOM. Operaciones como creación de nodos, registro de -manejadores de eventos (_event listeners_ o _event handlers_), .... - -Esta no es la única forma de dividir tu código, puedes usar más archivos y -carpetas, siempre y cuando la estructura sea clara para tus compañeras. - -En este archivo encontrarás una serie de _imports_ _comentados_. Para _cargar_ -las diferentes fuentes de datos tendrás que _descomentar_ la línea -correspondiente. - -Por ejemplo, si "descomentamos" la siguiente línea: - -```js -// import data from './data/lol/lol.js'; -``` - -La línea quedaría así: - -```js -import data from './data/lol/lol.js'; -``` - -Y ahora tendríamos la variable `data` disponible en el script `src/main.js`. - -### `src/data.js` - -El corazón de este proyecto es la manipulación de datos a través de arreglos -y objetos. - -Te recomendamos que este archivo contenga toda la funcionalidad que corresponda -a obtener, procesar y manipular datos (tus funciones). Por ejemplo: - -* `filterData(data, condition)`: esta función `filter` o filtrar recibiría la - data, y nos retornaría aquellos datos que sí cumplan con la condición. - -* `sortData(data, sortBy, sortOrder)`: esta función `sort` u ordenar - recibe tres parámetros. - El primer parámetro, `data`, nos entrega los datos. - El segundo parámetro, `sortBy`, nos dice con respecto a cuál de los campos de - la data se quiere ordenar. - El tercer parámetro, `sortOrder`, indica si se quiere ordenar de manera - ascendente o descendente. - -* `computeStats(data)`: la función `compute` o calcular, nos permitirá hacer - cálculos estadísticos básicos para ser mostrados de acuerdo a la data - proporcionada. - -Estos nombres de funciones y de parámetros son solamente referenciales, lo que -decidas depende de tu propia implementación. - -Estas funciones deben ser [_puras_](https://medium.com/laboratoria-developers/introducci%C3%B3n-a-la-programaci%C3%B3n-funcional-en-javascript-parte-2-funciones-puras-b99e08c2895d) -e independientes del DOM. Estas funciones serán después usadas desde el archivo -`src/main.js`, al cargar la página, y cada vez que el usuario interactúe (click, -filtrado, ordenado, ...). - -### `src/data` - -En esta carpeta están los datos de las diferentes fuentes. Encontrarás una -carpeta por cada fuente, y dentro de cada carpeta dos archivos: uno con la -extensión `.js` y otro `.json`. Ambos archivos contienen la misma data; la -diferencia es que el `.js` lo usaremos a través de una etiqueta ` +
+
+

POKÉDEX

+
Gotta catch 'em all
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
- + \ No newline at end of file diff --git a/src/main.js b/src/main.js index 71c59f2d..d9f85343 100644 --- a/src/main.js +++ b/src/main.js @@ -1,6 +1,242 @@ -import { example } from './data.js'; -// import data from './data/lol/lol.js'; -import data from './data/pokemon/pokemon.js'; -// import data from './data/rickandmorty/rickandmorty.js'; +import data from "./data/pokemon/pokemon.js"; //Trae la base de datos de pokemon +import { filterByType, searchPokemonByName, sortData, computeTypePercentage } from "./data.js"; + +/*import Chart from 'chart.js/auto'*/ + + +const pokemonList = data.pokemon; +const listaPokemon = document.querySelector("#listaPokemon"); +for (let i = 0; i < data.pokemon.length; i++) { + //Se está iterando por la longitud del data.pokemon + const poke = data.pokemon[i]; // Aumenta cada elemento de mi objeto + mostrarPokemon(poke); // Se crea la función +} +function mostrarPokemon(poke) { + let tipos = poke.type.map((typeElement) => `

${typeElement}

`); //Para mapear los tipos y extraerlos en un arreglo, crear un parrafo con los tipos (typeElement es cada elemento de mi poke.type(es un arreglo)) + tipos = tipos.join("-"); //Para unir los elementos de un arreglo + const div = document.createElement("div"); + div.classList.add("pokemon"); // Se asigna la clase pokemon + //Para crear un fragmento HTML dentro del div creado + // Concatenación con literales de plantilla + //El ciclo for trae los datos de este div con la const poke. + div.innerHTML = ` +
+
+ Pokemon ${poke.name} +
+
+
+

#${poke.num}

+

${poke.name}

+
+
+ ${tipos} +
+
+
+ `; + listaPokemon.append(div); //Se inserta en el id lista pokemon + div.addEventListener("click", () => mostrarModal(poke)); +} +/*console.log(poke.stats["base-attack"]) //Ejemplos para usar el console.log + console.log(poke.resistant[0]) // Ejemplos para usar el console.log + Nota: el parámetro va dentro del console.log*/ +/*addEventListener(accion, funcion )*/ +/*Para filtros*/ +//Función que previamente se importó (del data.js) y para usarla se adaptaron a los valores de mi data.pokemon +const typeDropdown = document.getElementById("typeDropdown"); +typeDropdown.addEventListener("change", () => { + // al evento listener se le da una acción (change) y el otro parámetro es una función. + //En este caso es una arrow function. //arrow function --> () => { }; + const selectedType = typeDropdown.value; //sacado del html + const filteredPokemon = filterByType(pokemonList, selectedType); //la condicion de arriba + clearPokemonList(); //cada que cambie de tipo quiero limpiar la búsqueda + filteredPokemon.forEach((poke) => mostrarPokemon(poke)); +}); +function clearPokemonList() { + listaPokemon.innerHTML = "" +} +//Para la búsqueda de la searchbar +const inputSearch = document.getElementById("searchbar"); //Se obtiene el texto del input +inputSearch.addEventListener("input", () => { + //se agrega un evento con la acción "input" y una arrow function + const searchText = inputSearch.value.toLowerCase(); //convierte el texto a minúsculas + const searchPoke = searchPokemonByName(pokemonList, searchText); //Se declara la función "searchPokemonByName()" + clearPokemonList(); // Limpia la búsqueda + searchPoke.forEach((pokemonList) => mostrarPokemon(pokemonList)); +});//Para el botón reset +const resetButton = document.getElementById('reset-button'); +resetButton.addEventListener('click', function() { + location.reload(); +});//Para el método sort +const sortDropdown = document.getElementById("sortDropdown"); +sortDropdown.addEventListener("change", () => { + const selectedSort = sortDropdown.value; + const sortPokemon = sortData(pokemonList, selectedSort); + clearPokemonList(); + sortPokemon.forEach(pokemon => mostrarPokemon(pokemon)); + /*console.log(sortPokemon)*/ +});//ventana modal opcionB: +function mostrarModal(poke) { + const modal = document.getElementById("modal-content"); + modal.innerHTML = ` +
+ +
+

${poke.name}

+

#${poke.num}

+
+
+
+
+ Pokemon ${poke.name} +
+
+ ${poke.type.map((typeElement) => `

${typeElement}

`).join("")} +
+
+
+
+

About

+

${poke.about}

+
+
+
+

Height

+

${poke.size.height}

+
+
+

Weight

+

${poke.size.weight}

+
+
+
+
+
+
+

Weaknesses

+
${poke.weaknesses.map((typeElement) => `

${typeElement}

`).join("")} +
+
+
+

Resistant

+
+ ${poke.resistant.map((typeElement) => `

${typeElement}

`).join("")} +
+
+
+
+ `; + const closeBtn = modal.querySelector(".close"); + closeBtn.addEventListener("click", () => { + modal.style.display = "none"; + }); + modal.style.display = "flex"; +} +function nuevoGrafico(chartElement, data) { + new Chart (chartElement, { + type: "bar", + data: { + labels: [ + "Dragon", + "Poison", + "Flying", + "Bug", + "Normal", + "Ground", + "Psychic", + "Ice", + "Ghost", + "Grass", + "Fire", + "Water", + "Electric", + "Fighting", + "Rock" + ], + datasets: [ + { + label: "Percentage", + data: data, + backgroundColor: [ + "#7038F8", + "#A43E9E", + "#A891EC", + "#A7B723", + "#AAA67F", + "#DEC16B", + "#FB5584", + "#9AD6DF", + "#70559B", + "#75574C", + "#F57D31", + "#6493EB", + "#F9CF30", + "#C12239", + "#B69E31" + ] + } + ] + }, + options: { + responsive: true, + title: { + display: true, + text: 'Percentage of pokemon by type', + fontSize: 30, + padding: 10, + fontColor: '#F4F5F6', + }, + legend: { + labels: { + fontFamily: 'Lato', + fontColor: '#F4F5F6', + } + }, + scales: { + x: { + ticks: { + color: '#F4F5F6' // Cambia el color de la fuente de las etiquetas en el eje X + } + }, + y: { + ticks: { + color: '#F4F5F6' // Cambia el color de la fuente de las etiquetas en el eje Y + } + } + } + } + }); +} +// Código para calcular el porcentaje de cada tipo de Pokémon referenciando data.js +const typePercentages = [ + computeTypePercentage(pokemonList, "dragon"), + computeTypePercentage(pokemonList, "poison"), + computeTypePercentage(pokemonList, "flying"), + computeTypePercentage(pokemonList, "bug"), + computeTypePercentage(pokemonList, "normal"), + computeTypePercentage(pokemonList, "ground"), + computeTypePercentage(pokemonList, "psychic"), + computeTypePercentage(pokemonList, "ice"), + computeTypePercentage(pokemonList, "ghost"), + computeTypePercentage(pokemonList, "grass"), + computeTypePercentage(pokemonList, "fire"), + computeTypePercentage(pokemonList, "water"), + computeTypePercentage(pokemonList, "electric"), + computeTypePercentage(pokemonList, "fighting"), + computeTypePercentage(pokemonList, "rock") +]; + +const chartElement = document.getElementById("typesGraph"); +nuevoGrafico(chartElement, typePercentages); +const showGraphLink = document.getElementById("show-graph"); +const graphContainer = document.getElementById("graphContainer"); +const mainSection = document.getElementById("todos"); +graphContainer.style.display = "none"; +showGraphLink.addEventListener("click", () => { + if (graphContainer.style.display === "none") { + ((graphContainer.style.display = "block") && (mainSection.style.display = "none")) } else { + ((graphContainer.style.display = "none") && (mainSection.style.display = "block")) + } +}); -console.log(example, data); diff --git a/src/style.css b/src/style.css index e69de29b..c62f7b63 100644 --- a/src/style.css +++ b/src/style.css @@ -0,0 +1,369 @@ +@import url("https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700;800;900&display=swap"); +:root { + --type-normal: #AAA67F; + --type-fire: #F57D31; + --type-water: #6493EB; + --type-grass: #74CB48; + --type-electric: #F9CF30; + --type-ice: #9AD6DF; + --type-fighting: #C12239; + --type-poison: #A43E9E; + --type-ground: #DEC16B; + --type-flying: #A891EC; + --type-psychic: #FB5584; + --type-bug: #A7B723; + --type-rock: #B69E31; + --type-ghost: #70559B; + --type-dark: #75574C; + --type-dragon: #7038F8; + --type-steel: #B7B9D0; + --type-fairy: #E69EAC; +} +.normal { + background-color: var(--type-normal); + padding: 3.5px; + border-radius: 5px; +} +.fire { + background-color: var(--type-fire); + padding: 3.5px; + border-radius: 5px; +} +.water { + background-color: var(--type-water); + padding: 3.5px; + border-radius: 5px; +} +.grass { + background-color: var(--type-grass); + padding: 3.5px; + border-radius: 5px; +} +.electric { + background-color: var(--type-electric); + padding: 3.5px; + border-radius: 5px; +} +.ice { + background-color: var(--type-ice); + padding: 3.5px; + border-radius: 5px; +} +.fighting { + background-color: var(--type-fighting); + padding: 3.5px; + border-radius: 5px; +} +.poison { + background-color: var(--type-poison); + padding: 3.5px; + border-radius: 5px; +} +.ground { + background-color: var(--type-ground); + padding: 3.5px; + border-radius: 5px; +} +.flying { + background-color: var(--type-flying); + padding: 3.5px; + border-radius: 5px; +} +.psychic { + background-color: var(--type-psychic); + padding: 3.5px; + border-radius: 5px; +} +.bug { + background-color: var(--type-bug); + padding: 3.5px; + border-radius: 5px; +} +.rock { + background-color: var(--type-rock); + padding: 3.5px; + border-radius: 5px; +} +.ghost { + background-color: var(--type-ghost); + padding: 3.5px; + border-radius: 5px; +} +.dark { + background-color: var(--type-dark); + padding: 3.5px; + border-radius: 5px; +} +.dragon { + background-color: var(--type-dragon); + padding: 3.5px; + border-radius: 5px; +} +.steel { + background-color: var(--type-steel); + padding: 3.5px; + border-radius: 5px; +} +.fairy { + background-color: var(--type-fairy); + padding: 3.5px; + border-radius: 5px; +} +* { + margin: 0; + padding: 0; + box-sizing: border-box; + color: #F5F5F6; + font-family: "Rubik", sans-serif; +} +body { + min-height: 100vh; + background-color: #454545; +} +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + background-color: #333333; + padding: 1rem; +} +#graphContainer { + display: none; +} +.searchbar input { + border: 1px solid white; + border-radius: 5px; + padding: 8px; + color: white; + background: none; + outline: none; + width: 20vw; + font-size: 1rem; +} +.reset-button { + border: 1px solid white; + border-radius: 5px; + padding: 8px; + color: white; + background: #3A9494; + outline: none; + width: 100px; + font-size: 0.9rem; +} +#show-graph { + border: 1px solid white; + border-radius: 5px; + padding: 8px; + color: white; + background: #9891DC; + outline: none; + width: 100px; + font-size: 0.9rem; +} +.dropdowns select { + border: 1px solid white; + border-radius: 5px; + padding: 8px; + color: white; + background: #454545; + outline: none; + width: 100px; + font-size: 0.9rem; +} +select option:first-child { + display: none; +} +main { + padding: 2rem; + max-width: 1000px; /* revisar más tarde */ + margin: 0 auto; +} +.pokemon-todos { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 2rem; + max-width: 1100px; + padding: 1em 1em; +} + +@media only screen and (max-width: 600px) { + .pokemon-todos { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0.2rem; + } +} + +.pokemon { + border-radius: 1rem; + background-color: #A3A3A3; + box-shadow: 0 0 3rem -1rem rgba(0, 0, 0, 0.25); + padding-block: 1rem; + text-transform: uppercase; + position: relative; + isolation: isolate; + overflow: hidden; +} +.pokemon-imagen { + padding-inline: 1rem; + display: flex; + justify-content: center; +} +.pokemon-imagen img { + width: 100%; + max-width: 7rem; +} +.pokemon-info { + display: flex; + flex-direction: column; + gap: 0.5rem; + padding-inline: 1rem; + align-items: center; + text-align: center; +} +.pokemon-tipos { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + justify-content: center; +} +/*Módulos*/ +.modalTodos { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} +.modal-content { + display: none; /* Ocultar el modal por defecto */ + position: fixed; /* Posición fija en la pantalla */ + z-index: 1; /* Z-index para asegurarse de que esté en la parte superior de los demás elementos */ + background-color: rgba(0, 0, 0, 0.5); /* Fondo oscuro semitransparente */ + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; /* Habilitar desplazamiento si el contenido es demasiado largo */ + align-items: center; + justify-content: center; +} +.pokemonModulos { + position: relative; + background-color: #9B9797; + width: 50%; + border-radius: 1rem; + box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.4); + text-transform: uppercase; + overflow: auto; /* Habilitar desplazamiento interno si el contenido es demasiado largo */ + flex-direction: column; /* Apilar los elementos verticalmente */ +} + +@media only screen and (max-width: 600px) { + .pokemonModulos { + width: 85%; /* Cambia el ancho al 90% para adaptarse a dispositivos móviles */ + max-width: 600px; /* Agrega un ancho máximo para evitar que se vuelva demasiado grande */ + margin: 0 auto; /* Centra horizontalmente el modal */ +} +.encabezadoModulo { + display: flex; + justify-content: space-between; + padding: 2em 1em 1em 1em; +} +span.close { + font-size: 2vw; /* El tamaño del ícono será el 2% del ancho de la ventana */ + padding: 1em; /* El padding será igual a 1 vez el tamaño de la fuente actual */ + position: relative; +} +.containerAbout { + display: flex; + /*flex-direction: column;*/ + border-radius: 1rem; + box-shadow: 0 0 3rem -1rem rgba(0, 0, 0, 0.25); + padding-block: 1rem; + text-transform: initial; +} +@media only screen and (max-width: 600px) { + .containerAbout { + flex-direction: column; + padding: 0.5rem; + } + } + +.lateralIzquierdo { + display: flex; + flex-direction: column; + width: 100%; + text-transform: uppercase; +} +.pokemon-imagen-modulo { + padding-inline: 1rem; + display: flex; + justify-content: center; +} +.pokemon-imagen-modulo img { + width: 160px; + height: 160px; + margin-left: auto; + margin-right: auto; + margin-top: 0.5em; + text-align: center; +} +.details { + padding: 10px; + /* overflow-wrap: break-word; */ + max-width: 100%; +} +.HW { + display: flex; + justify-content: space-around; + padding: 15px; +} +.WR { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + justify-content: space-around; + padding: 1em; + max-width: 100%; +} +.W-types, +.R-types { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + justify-content: space-around; + padding: 1em; + flex-basis: 80%; /* Ajusta el tamaño base para permitir envolver los elementos */ +} +.bold { + font-weight: bold; + font-size: larger; + /*Header*/ +} +.headerPoke { + height: 100%; + text-align: center; + padding: 1em; + font-size: 200%; + background-color: #5C9B9B; + display: flex; + flex-direction: column; + justify-content: center; +} +.headerImg { + background-size: contain; +} +.headerImg img { + max-height: 50%; + max-width: 50%; +} +footer{ + background-color:#5c9b9b; + margin: 1em auto; + padding: 2em; +}.copyright{ + display: flex; + flex-direction: column; + text-align: center; +} \ No newline at end of file diff --git a/test/data.spec.js b/test/data.spec.js index 09b1f23f..fc446287 100644 --- a/test/data.spec.js +++ b/test/data.spec.js @@ -1,23 +1,118 @@ -import { example, anotherExample } from '../src/data.js'; +import { filterByType, searchPokemonByName, sortData } from '../src/data.js'; -describe('example', () => { - it('is a function', () => { - expect(typeof example).toBe('function'); +describe('test unitarios de filterByType', () => { + const pokemonArray = [ + {name: "pikachu", type: ["electric"]}, + {name: "togetic", type: ["fairy", "flying"]}, + {name: "chinchou", type: ["water", "electric"]}, + {name: "cleffa", type:["fairy"]}, + ]; + + it('validar el filtro por tipo electric', () => { + + expect(filterByType(pokemonArray, "electric")).toEqual([ + {name: "pikachu", type: ["electric"]}, + {name: "chinchou", type: ["water", "electric"]}]); }); - it('returns `example`', () => { - expect(example()).toBe('example'); + it('validar el filtro por tipo fairy', () => { + + expect(filterByType(pokemonArray, "fairy")).toEqual([ + {name: "togetic", type: ["fairy", "flying"]}, + {name: "cleffa", type:["fairy"]}]); + }); + + it('validar el filtro por tipo inexistente', () => { + + expect(filterByType(pokemonArray, "inexistente")).toEqual([ + + ]); }); }); -describe('anotherExample', () => { - it('is a function', () => { - expect(typeof anotherExample).toBe('function'); +describe('test unitarios de searchPokemonByName', () => { + const pokemonArray = [ + {name: "suicune", num: "245"}, + {name: "caterpie", num: "010"}, + {name: "charizard", num: "006"}, + {name: "tangela", num: "114"}, + ]; + + it('validar búsqueda por nombre o número', () => { + expect(searchPokemonByName(pokemonArray, "suicune","245" )).toEqual( + [{name: "suicune", num: "245"}]); + }); + + it('validar búsqueda por nombre en mayúsculas', () => { + expect(searchPokemonByName(pokemonArray, "TANGELA")).toEqual( + [{name: "tangela", num: "114"}]); }); - it('returns `anotherExample`', () => { - expect(anotherExample()).toBe('OMG'); + it('validar búsqueda con espacios al inicio', () => { + expect(searchPokemonByName(pokemonArray, " 114")).toEqual( + [{name: "tangela", num: "114"}]); + }); + + it('validar búsqueda por número', () => { + expect(searchPokemonByName(pokemonArray, "1")).toEqual( + [{name: "caterpie", num: "010"}, + {name: "tangela", num: "114"} + ]); + }); + + it('validar búsqueda por signos', () => { + expect(searchPokemonByName(pokemonArray, "#")).toEqual([]); }); }); + + +describe('test unitarios de sortData', () => { + const pokemonArray = [ + {name: "abra", num: "063"}, + {name: "zubat", num: "041"}, + {name: "charizard", num: "006"}, + {name: "celebi", num: "251"}, + ]; + + it('validar el filtro por ascending by name', () => { + + expect(sortData(pokemonArray, "asc")).toEqual([ + {name: "abra", num: "063"}, + {name: "celebi", num: "251"}, + {name: "charizard", num: "006"}, + {name: "zubat", num: "041"}, + ]); + }); + + it('validar el filtro por descending by name', () => { + + expect(sortData(pokemonArray, "desc")).toEqual([ + {name: "zubat", num: "041"}, + {name: "charizard", num: "006"}, + {name: "celebi", num: "251"}, + {name: "abra", num: "063"}, + ]); + }); + + it('validar el filtro por ascending by number', () => { + + expect(sortData(pokemonArray, "numAsc")).toEqual([ + {name: "charizard", num: "006"}, + {name: "zubat", num: "041"}, + {name: "abra", num: "063"}, + {name: "celebi", num: "251"}, + ]); + }); + + it('validar el filtro por descending by number', () => { + + expect(sortData(pokemonArray, "numDesc")).toEqual([ + {name: "celebi", num: "251"}, + {name: "abra", num: "063"}, + {name: "zubat", num: "041"}, + {name: "charizard", num: "006"}, + ]); + }); +}); \ No newline at end of file