Bruno Predot

Merge branch 'release/0.3.1'

0.3.1:
- ajout fichier de test MovieGender.spec.ts.
- ajout fichier de test ScoreAndVote.spec.ts.
0.3.0:
- Installation vuelidate et vuelidate/validator.
- Ajout composant SkeletonMovieDetailLoader.
... ...
... ... @@ -26,7 +26,8 @@ watch(
});
}
});
}, { immediate: true }
},
{ immediate: true },
);
//#endregion
</script>
... ...
... ... @@ -105,7 +105,7 @@ function handleMessageEvent(event: string) {
@blur="v$.rating.$touch"
@input="v$.rating.$touch"
/>
<!-- <pre>{{ errormessages }}</pre>-->
<!-- <pre>{{ errormessages }}</pre>-->
<ui-components-tiny-mce-field-editor
:error-message="v$?.message?.$errors[0]?.$message ? (v$.message.$errors[0].$message as string) : ''"
:model-value="formData.message"
... ...
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import { describe, expect, it } from "vitest";
import { mount } from "@vue/test-utils";
import HelloWorld from './HelloWorld.vue'
import HelloWorld from "./HelloWorld.vue";
describe('HelloWorld', () => {
it('component renders Hello world properly', () => {
const wrapper = mount(HelloWorld)
expect(wrapper.text()).toContain('Hello world')
})
})
describe("HelloWorld", () => {
it("component renders Hello world properly", () => {
const wrapper = mount(HelloWorld);
expect(wrapper.text()).toContain("Hello world");
});
});
... ...
<script setup lang="ts">
</script>
<script setup lang="ts"></script>
<template>
<p>Hello world</p>
</template>
<style scoped lang="scss">
</style>
\ No newline at end of file
<style scoped lang="scss"></style>
... ...
... ... @@ -20,12 +20,7 @@ defineProps({
<template>
<section class="w-full md:w-1/3 lg:w-1/4">
<div class="rounded-lg overflow-hidden shadow-lg bg-gray-800">
<v-img
v-if="src"
:alt="title"
:src="`https://image.tmdb.org/t/p/w500${src}`"
class="w-full h-auto"
/>
<v-img v-if="src" :alt="title" :src="`https://image.tmdb.org/t/p/w500${src}`" class="w-full h-auto" />
<div v-else class="aspect-[2/3] bg-gray-700 flex items-center justify-center">
<FilmIcon :size="64" class="text-gray-500" />
</div>
... ... @@ -33,6 +28,4 @@ defineProps({
</section>
</template>
<style scoped>
</style>
\ No newline at end of file
<style scoped></style>
... ...
... ... @@ -6,7 +6,7 @@ import { useDebounceFn } from "@vueuse/core";
//#endregion
//#region --Emits--.
const emit = defineEmits(['event:search', 'event:clear_search']);
const emit = defineEmits(["event:search", "event:clear_search"]);
//#endregion
//#region --Props--.
... ... @@ -29,12 +29,12 @@ const searchQuery = ref("");
* Debounced function
*/
const handleSearchEvent = useDebounceFn(() => {
emit('event:search', searchQuery.value);
emit("event:search", searchQuery.value);
}, 500);
function handleClearSearchEvent() {
searchQuery.value = '';
emit('event:clear_search')
searchQuery.value = "";
emit("event:clear_search");
}
//#endregion
</script>
... ...
<script setup lang="ts">
</script>
<script setup lang="ts"></script>
<template>
<v-container class="bg-gray-900">
<v-row class="bg-gray-900" >
<v-row class="bg-gray-900">
<v-col cols="12" sm="4">
<v-skeleton-loader
class="mx-auto border bg-gray-800"
... ... @@ -27,6 +25,4 @@
</v-container>
</template>
<style scoped>
</style>
\ No newline at end of file
<style scoped></style>
... ...
{
"name": "nuxt-app",
"version": "0.3.0",
"version": "0.3.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nuxt-app",
"version": "0.3.0",
"version": "0.3.1",
"hasInstallScript": true,
"dependencies": {
"@nuxt/eslint": "^1.3.0",
... ...
{
"name": "nuxt-app",
"version": "0.3.0",
"version": "0.3.1",
"private": true,
"type": "module",
"scripts": {
... ...
//#region --Import--.
import { describe, expect, it } from "vitest";
import { mount } from "@vue/test-utils";
import MovieGender from "../../components/details/MovieGender.vue";
import type { Genre } from "~/interfaces/movie";
//#endregion
describe("MovieGender", () => {
it("affiche correctement les genres", () => {
// Données de test.
const genres: Genre[] = [
{ id: 1, name: "Action" },
{ id: 2, name: "Comédie" },
{ id: 3, name: "Drame" },
];
// Monter le composant avec sa props.
const wrapper = mount(MovieGender, {
props: {
genres,
},
});
// Vérifier que tous les genres sont affichés.
const spanElements = wrapper.findAll("span");
// spanElements.length doit être égal aux données de test (genres.length).
expect(spanElements.length).toBe(genres.length);
// Vérifier le contenu affiché de chaque élément.
spanElements.forEach((spanElement, index) => {
// Sur chaque itération d'élément (span), vérification que le nom du genre correspondant soit bien affiché.
expect(spanElement.text()).toContain(genres[index].name);
expect(spanElement.text()).toBe(genres[index].name);
});
});
it("affiche correctement un seul genre", () => {
// Données de test.
const genres: Genre[] = [{ id: 1, name: "Horreur" }];
// Monter le composant avec sa props.
const wrapper = mount(MovieGender, {
props: {
genres,
},
});
// Vérifier que le genre soit affiché.
const spanElements = wrapper.findAll("span");
// spanElements.length doit être égal aux données de test (ici 1).
expect(spanElements.length).toBe(genres.length);
// Vérifier le contenu affiché de l'élément.
expect(spanElements[0].text()).toContain(genres[0].name);
expect(spanElements[0].text()).toBe(genres[0].name);
});
it("ne rend aucun élément span quand la liste est vide", () => {
// Données de test volontairement vide.
const genres: Genre[] = [];
// Monter le composant avec sa props.
const wrapper = mount(MovieGender, {
props: {
genres,
},
});
// spanElements.length doit être égal à 0.
const spanElements = wrapper.findAll("span");
expect(spanElements.length).toBe(0);
});
});
... ...
//#region --Import--.
import { describe, expect, it } from "vitest";
import { mount } from "@vue/test-utils";
import ScoreAndVote from "../../components/details/ScoreAndVote.vue";
//#endregion
describe("ScoreAndVote", () => {
it("affiche correctement le score", () => {
// Monter le composant avec ses props.
const wrapper = mount(ScoreAndVote, {
props: {
score: 7,
nbVote: 100,
},
});
// Trouver l'élément qui contient le score.
const scoreElement = wrapper.find(".bg-primary");
// Vérifier que le score est affiché correctement.
expect(scoreElement.text()).contain("7");
});
it("affiche exactement le score avec une décimale", () => {
// Monter le composant avec ses props.
const wrapper = mount(ScoreAndVote, {
props: {
score: 8.5,
nbVote: 100,
},
});
// Trouver l'élément qui contient le score.
const scoreElement = wrapper.find(".bg-primary");
// Vérifier que le score est affiché correctement.
expect(scoreElement.text()).toBe("8.5");
});
it("arrondit correctement le score à une décimale", () => {
// Tester avec un score qui a plus d'une décimale.
const wrapper = mount(ScoreAndVote, {
props: {
score: 7.654,
nbVote: 100,
},
});
// Trouver l'élément qui contient le score.
const scoreElement = wrapper.find(".bg-primary");
// Arrondi à une décimale.
expect(scoreElement.text()).toBe("7.7");
});
it("affiche correctement le paragraphe", () => {
// Monter le composant avec ses props.
const wrapper = mount(ScoreAndVote, {
props: {
score: 7.654,
nbVote: 100,
},
});
// Trouver l'élément qui contient le paragraphe.
const paragrapheElement = wrapper.find("p");
expect(paragrapheElement.text()).toBe("Note TMDB");
});
it("affiche correctement le nombre de vote sans formatage si inférieur à 1000", () => {
// Monter le composant avec ses props.
const wrapper = mount(ScoreAndVote, {
props: {
score: 7.654,
nbVote: 855,
},
});
// Trouver l'élément qui contient le nombre de votes.
const voteElement = wrapper.find("div");
// Vérifier si la div contient le nombre.
expect(voteElement.text()).toContain("855");
// Vérifier si le texte de la div correspond exactement.
expect(voteElement.text()).toBe("855 votes");
});
it("affiche correctement le nombre de vote formaté en 'k' si supérieur ou égal à 1000", () => {
// Monter le composant avec ses props.
const wrapper = mount(ScoreAndVote, {
props: {
score: 9,
nbVote: 1477,
},
});
// Trouver l'élément qui contient le nombre de votes.
const voteElement = wrapper.find("div");
// Vérifier si la div contient le nombre.
expect(voteElement.text()).toContain("1.5");
// Vérifier si le texte de la div correspond exactement.
expect(voteElement.text()).toBe("1.5k votes");
});
});
... ...
... ... @@ -5,7 +5,7 @@ export default {
plugins: [vue()],
test: {
globals: true,
environment: "jsdom",
environment: "happy-dom",
// Additional test configurations can be added here
},
}
\ No newline at end of file
... ...
import { defineVitestConfig } from '@nuxt/test-utils/config'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath } from 'node:url'
export default defineVitestConfig({
/**
... ... @@ -7,15 +9,30 @@ export default defineVitestConfig({
*/
test: {
environment: 'nuxt',
globals: true,
// you can optionally set Nuxt-specific environment options
// environmentOptions: {
// nuxt: {
// rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
// domEnvironment: 'happy-dom', // 'happy-dom' (default) or 'jsdom'
// overrides: {
// // other Nuxt config you want to pass
// }
// }
// }
environmentOptions: {
nuxt: {
rootDir: fileURLToPath(new URL('./', import.meta.url)),
domEnvironment: 'happy-dom', // 'happy-dom' (default) or 'jsdom'
overrides: {
// other Nuxt config you want to pass
},
mock: {
intersectionObserver: true,
indexedDb: true,
}
},
},
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
}
},
resolve: {
alias: {
'~': fileURLToPath(new URL('./', import.meta.url)),
'@': fileURLToPath(new URL('./', import.meta.url)),
}
}
})
... ...