From bbcf9918d029693bae75de109effe4d6e5f3b192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20PENHO=C3=8BT?= Date: Tue, 21 Sep 2021 17:46:04 +0200 Subject: [PATCH] =?UTF-8?q?Cr=C3=A9ation=20d'une=20classe=20s=C3=A9par?= =?UTF-8?q?=C3=A9e=20pour=20g=C3=A9rer=20la=20pagination.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/errors.js | 4 +- src/freeDatas2HTML.ts | 168 ++++---------------------------- src/freeDatas2HTMLInterfaces.ts | 38 ++++---- src/freeDatas2HTMLPagination.ts | 150 ++++++++++++++++++++++++++++ tests/freeDatas2HTMLSpec.ts | 152 +---------------------------- tests/paginationSpec.ts | 159 ++++++++++++++++++++++++++++++ 6 files changed, 353 insertions(+), 318 deletions(-) create mode 100644 src/freeDatas2HTMLPagination.ts create mode 100644 tests/paginationSpec.ts diff --git a/src/errors.js b/src/errors.js index fa4e826..eaadcd8 100644 --- a/src/errors.js +++ b/src/errors.js @@ -3,11 +3,13 @@ module.exports = datasNotFound : "Aucune donnée n'a été trouvée.", elementNotFound : "Aucun élément HTML n'a été trouvé ayant comme \"id\" : ", needDatasElt: "Merci de fournir un id valide pour l'élément où afficher les données.", - needNaturalNumber: "Merci de fournir un nombre entier supérieur ou égal à zéro pour désigner chaque colonne.", needPagesSelectorElt: "Merci de fournir l'id de l'élément où afficher le sélecteur de pages.", needPaginationByDefaultBeInOptions: "La valeur de pagination par défaut doit faire partie des options proposées.", + needPaginationOptionsValues: "Vous n'avez fourni aucune options possibles pour la pagination.", needPositiveInteger: "Merci de fournir un nombre entier supérieur à zéro pour désigner chaque option de pagination.", needUrl: "Merci de fournir une url valide pour le fichier CSV à parser.", + paginationNeedDatas: "Il ne peut y avoir de pagination, si les données n'ont pas été récupérées.", + pagination2HTMLFail : "Toutes les donnée nécessaires à la création des sélecteurs de pagination n'ont pas été fournies.", parserFail: "La lecture des données du fichier a échoué.", refreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.", selector2HTMLFail: "Le création d'un filtre dans le DOM nécessite l'initialisation de l'élément HTML et du numéro du champs à filter.", diff --git a/src/freeDatas2HTML.ts b/src/freeDatas2HTML.ts index 473f192..66ec8c7 100644 --- a/src/freeDatas2HTML.ts +++ b/src/freeDatas2HTML.ts @@ -2,7 +2,8 @@ const Papa = require("papaparse"); const errors = require("./errors.js"); const { compare }= require('natural-orderby'); -import { DOMElement, Pagination, Selectors, SortingFields, SortingFunctions } from "./freeDatas2HTMLInterfaces"; +import { DOMElement, Paginations, Selectors, SortingFields, SortingFunctions } from "./freeDatas2HTMLInterfaces"; +import { Pagination} from "./freeDatas2HTMLPagination"; import { Selector } from "./freeDatas2HTMLSelector"; import { SortingField } from "./freeDatas2HTMLSortingField"; @@ -39,19 +40,8 @@ export class FreeDatas2HTML datasSortedField: SortingFields|undefined; // La Pagination : - private _Pagination: Pagination|undefined; - - // Fonction utile pour tester les numéros de colonne : - public static isPositiveInteger(nb: number) - { - return (Number.isInteger(nb) === false || nb <= 0) ? false : true; - } - // Fonction utile pour tester les valeurs de Pagination : - public static isNaturalNumber(nb: number) - { - return (Number.isInteger(nb) === false || nb < 0) ? false : true; - } - + pagination: Paginations|undefined; + // Vérifie que l'élément devant afficher les données existe dans le DOM : set datasViewElt(elt: DOMElement) { @@ -80,9 +70,9 @@ export class FreeDatas2HTML this._datasSortingFunctions=[]; for(let i = 0; i < SortingFunctions.length; i++) { - if(FreeDatas2HTML.isNaturalNumber(SortingFunctions[i].datasFieldNb) === false) - console.error(errors.needNaturalNumber); - else + //if(FreeDatas2HTML.isNaturalNumber(SortingFunctions[i].datasFieldNb) === false) // revoir pour tester l'existence du champ + // console.error(errors.needNaturalNumber); // -> à remplacer par un test d'existence de colonne ! + //else this._datasSortingFunctions.push(SortingFunctions[i]); } } @@ -98,73 +88,6 @@ export class FreeDatas2HTML return undefined; } - // Vérifie la cohérence de toutes les options de pagination reçues : - set Pagination(config: Pagination) - { - this._Pagination={}; - // Si une valeur par défaut est fournie ou des valeurs en option, un id valide doit être aussi fourni pour recueillir le sélecteur de pages : - if(config.selectedValue !== undefined || config.options !== undefined) - { - if(config.pages === undefined) - throw new Error(errors.needPagesSelectorElt); - let checkContainerExist=document.getElementById(config.pages.displayElement.id); - if(checkContainerExist === null) - throw new Error(errors.elementNotFound+config.pages.displayElement.id); - else - { - this.Pagination.pages = - { - displayElement: - { - id:config.pages.displayElement.id, - eltDOM: checkContainerExist - }, - name: (config.pages.name) ? config.pages.name : "Pages :", // rendre obligatoire cette option s'il doit y avoir affichage ? - selectedValue:1, // c'est la 1ère page qui est affichée par défaut - } - } - } - // Les options de Pagination proposées à l'utilisateur : - if(config.options !== undefined) - { - // Un élément HTML doit exister pour accueillir les options : - let checkContainerExist=document.getElementById(config.options.displayElement.id); - if(checkContainerExist === null) - throw new Error(errors.elementNotFound+config.options.displayElement.id); - else - { - // Seules des entiers positifs sont possibles - for(let i = 0; i < config.options.values.length; i++) - { - if(FreeDatas2HTML.isPositiveInteger(config.options.values[i]) === false) - throw new Error(errors.needPositiveInteger); - } - this._Pagination.options = - { - displayElement: { id:config.options.displayElement.id, eltDOM:checkContainerExist }, - name: (config.options.name) ? config.options.name : "Pagination :", // idem, rendre obligatoire ? - values:config.options.values - }; - } - } - // Valeur de Pagination par défaut qui doit faire partie des options proposées si elles existent : - if(config.selectedValue !== undefined) - { - if(config.options !== undefined && (config.options.values.indexOf(config.selectedValue) === -1)) - throw new Error(errors.needPaginationByDefaultBeInOptions); - if(FreeDatas2HTML.isPositiveInteger(config.selectedValue)) - this._Pagination.selectedValue=config.selectedValue; - else - throw new Error(errors.needPositiveInteger); - } - } - - // Retourne les options de Pagination actuelles - get Pagination(): Pagination - { - return this._Pagination; - } - // Parse des données distantes (url) fournies en CSV : public async parse(): Promise { @@ -220,37 +143,7 @@ export class FreeDatas2HTML else if(this.stopIfParseErrors && this.parseErrors.length!==0) console.error(this.parseErrors); else - { - let converter=this; - - // Si demandé, création d'une liste de valeurs de Pagination possibles - if(converter.Pagination !==undefined && converter.Pagination.options !==undefined && converter.Pagination.options.values.length > 0) - { - const values=converter.Pagination.options.values; - let selectorsHTML=""; - converter.Pagination.options.displayElement.eltDOM!.innerHTML=selectorsHTML; - let selectElement = document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement; - // Si une Pagination par défaut existe, on la sélectionne : - if(converter.Pagination.selectedValue !== undefined) - { - let indexSelectedValue=converter.Pagination.options.values.indexOf(converter.Pagination.selectedValue)+1; - selectElement.value=""+indexSelectedValue; - } - selectElement.addEventListener('change', function(e) - { - if(selectElement.value === "0") - converter.Pagination.selectedValue=undefined; // = pas de Pagination - else - converter.Pagination.selectedValue=values[Number(selectElement.value)-1]; - // on regénère le HTML : - converter.datasHTML=converter.createDatasHTML(converter.parseMetas!.fields as string[], converter.parseDatas); - converter.refreshView(); - }); - } - + { // Si tout est ok, affichage initial de toutes les données du fichier this.refreshView(); return true; @@ -287,12 +180,12 @@ export class FreeDatas2HTML else datas.sort( (a, b) => compare( {order: fieldOrder} )(a[field], b[field])); } - - // Dois-je prendre en compte une Pagination ? + + // Dois-je prendre en compte une pagination ? let firstData=0; - if (this.Pagination !== undefined && this.Pagination.selectedValue !== undefined && this.Pagination.pages !== undefined && this.Pagination.pages.selectedValue !== undefined) - firstData=this.Pagination.selectedValue*(this.Pagination.pages.selectedValue-1); - let maxData = (this.Pagination !== undefined && this.Pagination.selectedValue !== undefined) ? this.Pagination.selectedValue : datas.length+1; + if (this.pagination !== undefined && this.pagination.selectedValue !== undefined && this.pagination.pages !== undefined && this.pagination.pages.selectedValue !== undefined) + firstData=this.pagination.selectedValue*(this.pagination.pages.selectedValue-1); + let maxData = (this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : datas.length+1; // Création du tableau de données : let datasHTML=""; @@ -308,7 +201,7 @@ export class FreeDatas2HTML let i=0; while(this.datasSelectors[i] !== undefined && visible===true) { - visible=this.datasSelectors[i].dataIsOk(datas[row]); // à revoir car cette fonction est nécessaire ! + visible=this.datasSelectors[i].dataIsOk(datas[row]); i++; } } @@ -329,39 +222,14 @@ export class FreeDatas2HTML nbTotal++; } datasHTML+="
"; - - // Si Pagination définie et tous les enregistrements n'ont pas été affichés, alors création d'un sélecteur de pages - if (this.Pagination !== undefined && this.Pagination.selectedValue !== undefined && this.Pagination.pages !== undefined && nbTotal > this.Pagination.selectedValue) - { - let nbPages=Math.ceil(nbTotal/this.Pagination.selectedValue); - let selectorsHTML=""; - this.Pagination.pages.displayElement.eltDOM!.innerHTML=selectorsHTML; - let selectElement = document.getElementById("freeDatas2HTMLPagesSelector") as HTMLInputElement; - if(this.Pagination.pages.selectedValue !== undefined) - selectElement.value=""+this.Pagination.pages.selectedValue; - let converter=this; - this.Pagination.pages.selectedValue=1; - selectElement.addEventListener('change', function(e) - { - converter.Pagination.pages!.selectedValue=Number(selectElement.value); - converter.datasHTML=converter.createDatasHTML(converter.parseMetas!.fields as string[], converter.parseDatas); - converter.refreshView(); - }); - } - else if(this.Pagination !== undefined && this.Pagination.pages !== undefined) - this.Pagination.pages.displayElement.eltDOM!.innerHTML=""; - + // Tout réaffichage peut entraîner une modification du nombre de pages (évolution filtres, etc.) + if(this.pagination !== undefined) + this.pagination.creaPageSelector(nbTotal); return datasHTML; } } // Permet l'appel des dépendances via un seul script +export { Pagination } from "./freeDatas2HTMLPagination"; export { Selector } from "./freeDatas2HTMLSelector"; export { SortingField } from "./freeDatas2HTMLSortingField"; \ No newline at end of file diff --git a/src/freeDatas2HTMLInterfaces.ts b/src/freeDatas2HTMLInterfaces.ts index f4a4163..31846bd 100644 --- a/src/freeDatas2HTMLInterfaces.ts +++ b/src/freeDatas2HTMLInterfaces.ts @@ -3,6 +3,27 @@ export interface DOMElement id: string; eltDOM?: HTMLElement; } +export interface Paginations +{ + options?: PaginationsOptions; + selectedValue?: number; // on peut utiliser une Pagination sans proposer d'options à l'utilisateur. + pages: PaginationsPages; + rend2HTML(): void; + creaPageSelector(nbTotal:number) : void; +} +export interface PaginationsOptions +{ + displayElement: DOMElement; + name?: string; + values: number[]; +}; +export interface PaginationsPages +{ + displayElement: DOMElement; + name: string; + values?: number[]; + selectedValue?: number; +} export interface Selectors { datasViewElt: DOMElement; @@ -23,21 +44,4 @@ export interface SortingFunctions { datasFieldNb: number; sort(a: any,b: any, order?: "asc"|"desc"): number; // cf. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/sort -} -export interface Pagination -{ - options?: - { - displayElement: DOMElement; - name?: string; // rendre obligatoire ? - values: number[]; - }; - selectedValue?: number; // on peut utiliser une Pagination sans proposer d'options à l'utilisateur. - pages?: - { - displayElement: DOMElement; - name?: string; // rendre obligatoire ? - values?: number[]; - selectedValue?: number; - } } \ No newline at end of file diff --git a/src/freeDatas2HTMLPagination.ts b/src/freeDatas2HTMLPagination.ts new file mode 100644 index 0000000..fbf45c0 --- /dev/null +++ b/src/freeDatas2HTMLPagination.ts @@ -0,0 +1,150 @@ +const errors = require("./errors.js"); +import { DOMElement, Paginations, PaginationsOptions, PaginationsPages } from "./freeDatas2HTMLInterfaces"; +import { FreeDatas2HTML } from "./freeDatas2HTML"; + +export class Pagination implements Paginations +{ + private _converter: FreeDatas2HTML; + // la pagination en cours, qui peut être modifiée/initialisée par l'utilisateur, si des options lui sont proposées : + private _selectedValue: number|undefined; + // les éventuelles options de pagination : + private _options: PaginationsOptions | undefined; + // les pages proposées, si le nombre d'enregistrement est > à la pagination en cours. + private _pages: PaginationsPages; + + public static isPositiveInteger(nb: number) + { + return (Number.isInteger(nb) === false || nb <= 0) ? false : true; + } + + // Injection de la classe principale, mais uniquement si les données ont été importées + // De plus l'élément du DOM devant recevoir la liste des pages doit exister + constructor(converter: FreeDatas2HTML, pagesElt: DOMElement, pagesName: string="Pages") + { + if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined) + throw new Error(errors.paginationNeedDatas); + else + { + let checkContainerExist=document.getElementById(pagesElt.id); + if(checkContainerExist === null) + throw new Error(errors.elementNotFound+pagesElt.id); + else + { + this._converter=converter; + this._pages={ displayElement: { id:pagesElt.id, eltDOM:checkContainerExist }, name: pagesName }; + } + } + } + + set selectedValue(value : number|undefined) + { + if(value === undefined || !Pagination.isPositiveInteger(value)) + throw new Error(errors.needPositiveInteger); + if(this.options !== undefined && this.options.values.indexOf(value) === -1) + throw new Error(errors.needPaginationByDefaultBeInOptions); + this._selectedValue=value; + } + + get selectedValue() : number|undefined + { + return this._selectedValue; + } + + set options(options : PaginationsOptions|undefined) + { + if(options !== undefined) + { + let checkContainerExist=document.getElementById(options.displayElement.id); + if(checkContainerExist === null) + throw new Error(errors.elementNotFound+options.displayElement.id); + else + options.displayElement.eltDOM=checkContainerExist; + if(options.values.length === 0) + throw new Error(errors.needPaginationOptionsValues); + for(let i in options.values) + { + if(!Pagination.isPositiveInteger(options.values[i])) + throw new Error(errors.needPositiveInteger); + } + options.name= (options.name===undefined) ? "Pagination" : options.name ; // on garde la possibilité d'une chaîne vide, si souhaité + this._options=options; + } + } + + get options() : PaginationsOptions|undefined + { + return this._options; + } + + get pages() : PaginationsPages + { + return this._pages; + } + + // Création du "; + for(let j in this._options.values) + selectorsHTML+=""; + selectorsHTML+=""; + this._options.displayElement.eltDOM!.innerHTML=selectorsHTML; // initialiser dans le setter + let selectElement=document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement; + // Si une Pagination par défaut existe, on la sélectionne : + if(this._selectedValue !== undefined) + { + let indexSelectedValue=this._options.values.indexOf(this._selectedValue)+1; + selectElement.value=""+indexSelectedValue; + } + const pagination=this; + selectElement.addEventListener("change", function(e) + { + if(selectElement.value === "0") + pagination._selectedValue=undefined; // = pas de Pagination + else + pagination._selectedValue=pagination._options!.values[Number(selectElement.value)-1]; + // on regénère le HTML : + pagination._converter.refreshView(); + }); + } + } + + // Création du "; + this.pages.values=[1]; + for(let j=2; j <= nbPages; j++) + { + selectorsHTML+=""; + this.pages.values.push(j); + } + selectorsHTML+=""; + this.pages.displayElement.eltDOM!.innerHTML=selectorsHTML; + let selectElement=document.getElementById("freeDatas2HTMLPagesSelector") as HTMLInputElement; + if(this.pages.selectedValue !== undefined) + selectElement.value=""+this.pages.selectedValue; + this.pages.selectedValue=1; + let pagination=this; + selectElement.addEventListener('change', function(e) + { + pagination.pages.selectedValue=Number(selectElement.value); + pagination._converter.refreshView(); + }); + } + else + this.pages.displayElement.eltDOM!.innerHTML=""; + } + else + this.pages.displayElement.eltDOM!.innerHTML=""; + } +} \ No newline at end of file diff --git a/tests/freeDatas2HTMLSpec.ts b/tests/freeDatas2HTMLSpec.ts index d93fd1b..fa31472 100644 --- a/tests/freeDatas2HTMLSpec.ts +++ b/tests/freeDatas2HTMLSpec.ts @@ -2,7 +2,7 @@ import { FreeDatas2HTML, Selector } from "../src/freeDatas2HTML"; const errors=require("../src/errors.js"); const fixtures=require("./fixtures.js"); -xdescribe("Test du script central de FreeDatas2HTML", () => +describe("Test du script central de FreeDatas2HTML", () => { let converter: FreeDatas2HTML; @@ -39,23 +39,7 @@ xdescribe("Test du script central de FreeDatas2HTML", () => expect(() => { return converter.datasSourceUrl=" "; }).toThrowError(errors.needUrl); }); - it("Doit retourner un booléen indiquant si un nombre est naturel ou non.", () => - { - expect(FreeDatas2HTML.isNaturalNumber(-1)).toBeFalse(); - expect(FreeDatas2HTML.isNaturalNumber(1.25)).toBeFalse(); - expect(FreeDatas2HTML.isNaturalNumber(0)).toBeTrue(); - expect(FreeDatas2HTML.isNaturalNumber(1)).toBeTrue(); - }); - - it("Doit retourner un booléen indiquant si un nombre est un entier positif ou non.", () => - { - expect(FreeDatas2HTML.isPositiveInteger(-1)).toBeFalse(); - expect(FreeDatas2HTML.isPositiveInteger(1.25)).toBeFalse(); - expect(FreeDatas2HTML.isPositiveInteger(0)).toBeFalse(); - expect(FreeDatas2HTML.isPositiveInteger(1)).toBeTrue(); - }); - - // Classement des données : + // Fonction spécfique de classement des données : it("Doit me retourner la fonction associée à une colonne, de manière à ce qu'elle soit utilisable pour comparer deux valeurs.", () => { // Fonction volontairement basique, car ce n'est pas la fonction que l'on teste ici, mais le fait que l'on puisse l'utiliser ! @@ -72,58 +56,6 @@ xdescribe("Test du script central de FreeDatas2HTML", () => expect(converter.getSortingFunctionForField(0)).toBeDefined(); expect([7,9,3,5].sort(converter.getSortingFunctionForField(0).sort)).toEqual([9,7,5,3]); }); - - // Pagination : - it("Doit générer une erreur quand aucun élément n'est fourni pour recevoir le sélecteur de pages, alors que cela est nécessaire.", () => - { - expect(() => { return converter.Pagination={ selectedValue:10 }; }).toThrowError(errors.needPagesSelectorElt); - expect(() => { return converter.Pagination={ options: { displayElement: { id:"paginationOptions" }, values: [10,20] }}; }).toThrowError(errors.needPagesSelectorElt); - }); - - it("Doit générer une erreur si l'élément fourni pour recevoir le sélecteur de pages n'existe pas dans le DOM.", () => - { - expect(() => { return converter.Pagination={ selectedValue:10, pages: { displayElement: { id:"dontExist" }} }; }).toThrowError(errors.elementNotFound+"dontExist"); - }); - - it("Doit générer une erreur si l'élément fourni pour recevoir le sélecteur de Pagination n'existe pas dans le DOM.", () => - { - expect(() => { return converter.Pagination={ options: { displayElement: { id:"dontExist" }, values: [10,20] }, pages: { displayElement: { id:"pages" }}}; }).toThrowError(errors.elementNotFound+"dontExist"); - }); - - it("Doit générer une erreur si au moins une des options de Pagination proposée n'est pas un entier positif.", () => - { - expect(() => { return converter.Pagination={ options: { displayElement: { id:"paginationOptions" }, values:[0,10,20] }, pages: { displayElement: { id:"pages" }}}; }).toThrowError(errors.needPositiveInteger); - }); - - it("Doit générer une erreur si la Pagination par défaut n'est pas un entier positif.", () => - { - expect(() => { return converter.Pagination={ selectedValue:0, pages: { displayElement: { id:"pages" }} }; }).toThrowError(errors.needPositiveInteger); - }); - - it("Doit générer une erreur si la Pagination par défaut ne fait pas partie des valeurs proposées en option.", () => - { - expect(() => { return converter.Pagination={ selectedValue:15, options: { displayElement: { id:"paginationOptions" }, values:[10,20,50] }, pages: { displayElement: { id:"pages" }}}; }).toThrowError(errors.needPaginationByDefaultBeInOptions); - }); - - it("Doit accepter une configuration correcte pour la Pagination.", () => - { - let PaginationOk = - { - selectedValue:10, - options: - { - displayElement : { id:"paginationOptions" }, - values: [10,20,50], - name: "Choix de Pagination :" - }, - pages: - { - displayElement : { id:"pages" }, - name: "Page à afficher :" - } - }; - expect(() => { return converter.Pagination=PaginationOk; }).not.toThrowError(); - }); }); describe("Parsage du fichier et création du tableau de données", () => @@ -211,84 +143,4 @@ xdescribe("Test du script central de FreeDatas2HTML", () => }); }); - describe("Création et action des options permettant de paginer les données affichées.", () => - { - beforeEach( () => - { - converter.datasViewElt={ id:"datas" }; - converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv"; - converter.Pagination= - { - selectedValue:10, - options: - { - displayElement : { id:"paginationOptions" }, - values: [10,20,50,500], - name: "Choix de pagination :" - }, - pages: - { - displayElement : { id:"pages" }, - name: "Page à afficher :" - } - } - }); - - it("Si des options de pagination sont fournies, doit générer un élement listant les pages doit être affichés.", async () => - { - await converter.run(); - let btnPaginationElt=document.getElementById("pages").innerHTML; - expect(btnPaginationElt).toEqual(fixtures.selectorForPages); - }); - - it("Si l'utilisateur sélectionne une des pages proposées, l'affichage des résultats doit s'adapter en prenant en compte la pagination sélectionnée.", async () => - { - await converter.run(); - let selectElement = document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement; - selectElement.value="3"; // = 50 éléments / page - selectElement.dispatchEvent(new Event('change')); - selectElement=document.getElementById("freeDatas2HTMLPagesSelector") as HTMLInputElement; - selectElement.value="2"; - selectElement.dispatchEvent(new Event('change')); - let getTableTr=document.getElementsByTagName("tr"); - expect(getTableTr[1].innerHTML).toEqual(fixtures.firstLineForPageSelection1); - expect(getTableTr[50].innerHTML).toEqual(fixtures.lastLineForPageSelection1); - selectElement.value="3"; // troisième page = incomplèet (18 enregistrements) - selectElement.dispatchEvent(new Event('change')); - getTableTr=document.getElementsByTagName("tr"); - expect(getTableTr[1].innerHTML).toEqual(fixtures.firstLineForPageSelection2); - expect(getTableTr[18].innerHTML).toEqual(fixtures.lastLineForPageSelection2); - }); - }); }); \ No newline at end of file diff --git a/tests/paginationSpec.ts b/tests/paginationSpec.ts new file mode 100644 index 0000000..5ac4dcd --- /dev/null +++ b/tests/paginationSpec.ts @@ -0,0 +1,159 @@ +import { FreeDatas2HTML, Pagination } from "../src/freeDatas2HTML"; + +const errors=require("../src/errors.js"); +const fixtures=require("./fixtures.js"); + +describe("Test de la pagination.", () => +{ + let converter: FreeDatas2HTML; + let pagination: Pagination; + + beforeEach( async () => + { + document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML); + converter=new FreeDatas2HTML(); + converter.datasViewElt={ id:"datas" }; + converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv"; + await converter.parse(); + pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :"); + }); + + afterEach( () => + { + document.body.removeChild(document.getElementById("fixture")); + }); + + describe("Test des options de pagination.", () => + { + it("Doit retourner un booléen indiquant si un nombre est un entier positif ou non.", () => + { + expect(Pagination.isPositiveInteger(-1)).toBeFalse(); + expect(Pagination.isPositiveInteger(1.25)).toBeFalse(); + expect(Pagination.isPositiveInteger(0)).toBeFalse(); + expect(Pagination.isPositiveInteger(1)).toBeTrue(); + }); + + it("Doit générer une erreur si la pagination est initialisée sans données à traiter.", () => + { + converter=new FreeDatas2HTML(); + expect(() => { return new Pagination(converter, { id:"pages" }); }).toThrowError(errors.paginationNeedDatas); + }); + + it("Doit générer une erreur si initialisé en fournissant l'id d'un élément n'existant pas pour recevoir la liste des pages.", () => + { + expect(() => { return new Pagination(converter, { id:"dontExist" }); }).toThrowError(errors.elementNotFound+"dontExist"); + }); + + it("Ne doit pas générer d'erreur si initialisé correctement", () => + { + expect(() => { return new Pagination(converter, { id:"pages" }); }).not.toThrowError(); + }); + + it("Doit générer une erreur si l'id fourni pour l'élément devant recevoir le sélecteur de pagination n'existe pas dans le DOM.", () => + { + expect(() => { return pagination.options={ displayElement: { id:"dontExist" }, values: [10,20] }; }).toThrowError(errors.elementNotFound+"dontExist"); + }); + + it("Doit générer une erreur si les options de pagination sont initialisées avec un tableau de valeurs vide.", () => + { + expect(() => { return pagination.options={ displayElement: { id:"paginationOptions" }, values: [] }; }).toThrowError(errors.needPaginationOptionsValues); + }); + + it("Doit générer une erreur si au moins une des options de pagination fournies n'est pas un entier positif.", () => + { + expect(() => { return pagination.options={ displayElement: { id:"paginationOptions" }, values: [0,10,20] }; }).toThrowError(errors.needPositiveInteger); + }); + + it("Ne doit pas générer d'erreur si les options de pagination fournies sont correctes.", () => + { + const test={ displayElement: { id:"paginationOptions" }, values: [10,20,50], name: "La pagination" }; + expect(() => { return pagination.options=test}).not.toThrowError(); + expect(pagination.options).toEqual(test); + }); + + it("Doit générer une erreur si la pagination par défaut n'est pas un entier positif.", () => + { + expect(() => { return pagination.selectedValue=0; }).toThrowError(errors.needPositiveInteger); + }); + + it("Doit générer une erreur si la Pagination par défaut ne fait pas partie des valeurs proposées en option.", () => + { + pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50] }; + expect(() => { return pagination.selectedValue=15; }).toThrowError(errors.needPaginationByDefaultBeInOptions); + }); + + it("Doit accepter une pagination par défaut correcte, avec ou sans options proposées.", () => + { + expect(() => { return pagination.selectedValue=10; }).not.toThrowError(); + pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50] }; + expect(() => { return pagination.selectedValue=10; }).not.toThrowError(); + }); + }); + + describe("Création et action des sélecteurs liés à la pagination des données.", () => + { + beforeEach( async () => + { + pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50,500] , name: "Choix de pagination :" }; + pagination.selectedValue=10; // revoir car n'est pas testé si déclaré avant les options + pagination.rend2HTML(); + converter.pagination=pagination; + await converter.run(); + }); + + it("Si des options de pagination sont fournies, doit générer un élement listant les pages doit être affiché.", () => + { + let selectElement=document.getElementById("pages").innerHTML; + expect(selectElement).toEqual(fixtures.selectorForPages); + }); + + it("Si l'utilisateur sélectionne une des pages proposées, l'affichage des résultats doit s'adapter en prenant en compte la pagination sélectionnée.", () => + { + let selectElement=document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement; + selectElement.value="3"; // = 50 éléments / page + selectElement.dispatchEvent(new Event('change')); + selectElement=document.getElementById("freeDatas2HTMLPagesSelector") as HTMLInputElement; + selectElement.value="2"; + selectElement.dispatchEvent(new Event('change')); + let getTR=document.getElementsByTagName("tr"); + expect(getTR[1].innerHTML).toEqual(fixtures.firstLineForPageSelection1); + expect(getTR[50].innerHTML).toEqual(fixtures.lastLineForPageSelection1); + selectElement.value="3"; // troisième page = incomplète (18 enregistrements) + selectElement.dispatchEvent(new Event('change')); + getTR=document.getElementsByTagName("tr"); + expect(getTR[1].innerHTML).toEqual(fixtures.firstLineForPageSelection2); + expect(getTR[18].innerHTML).toEqual(fixtures.lastLineForPageSelection2); + expect(getTR[50]).toBeUndefined(); + }); + + }); + +}); \ No newline at end of file