Compare commits
3 Commits
80b90f98a5
...
9a5f82aea5
Author | SHA1 | Date | |
---|---|---|---|
9a5f82aea5 | |||
27564f2d2b | |||
3ea65db323 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "freedatas2html",
|
"name": "freedatas2html",
|
||||||
"version": "0.9.5",
|
"version": "0.9.8",
|
||||||
"description": "Conversion and display of data in different formats (CSV, JSON, HTML) with the possibility of filtering, classifying and paginating the results.",
|
"description": "Conversion and display of data in different formats (CSV, JSON, HTML) with the possibility of filtering, classifying and paginating the results.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -21,6 +21,7 @@ export class FreeDatas2HTML
|
|||||||
// Les options (classement, pagination, filtres...) :
|
// Les options (classement, pagination, filtres...) :
|
||||||
private _datasCounterElt: DOMElement|undefined=undefined;
|
private _datasCounterElt: DOMElement|undefined=undefined;
|
||||||
private _datasSortingFunctions: SortingFunctions[]=[];
|
private _datasSortingFunctions: SortingFunctions[]=[];
|
||||||
|
private _fields2Rend: number[]=[];
|
||||||
public datasFilters: Filters[]=[];
|
public datasFilters: Filters[]=[];
|
||||||
public datasSortingFields: SortingFields[]=[];
|
public datasSortingFields: SortingFields[]=[];
|
||||||
public datasSortedField: SortingFields|undefined;
|
public datasSortedField: SortingFields|undefined;
|
||||||
@ -98,6 +99,11 @@ export class FreeDatas2HTML
|
|||||||
return this._nbDatasValid;
|
return this._nbDatasValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get fields2Rend() : number[]
|
||||||
|
{
|
||||||
|
return this._fields2Rend;
|
||||||
|
}
|
||||||
|
|
||||||
// Vérifie qu'un champ existe bien dans les données parsées.
|
// Vérifie qu'un champ existe bien dans les données parsées.
|
||||||
// Utilisée par les autres classes.
|
// Utilisée par les autres classes.
|
||||||
public checkFieldExist(nb: number) : boolean
|
public checkFieldExist(nb: number) : boolean
|
||||||
@ -108,6 +114,31 @@ export class FreeDatas2HTML
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public realFields2Rend() : string[]
|
||||||
|
{
|
||||||
|
if(this._fields2Rend.length === 0)
|
||||||
|
return this._fields;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const realFields=[];
|
||||||
|
for(let i=0; i < this._fields.length; i++)
|
||||||
|
{
|
||||||
|
if(this._fields2Rend.indexOf(i) !== -1)
|
||||||
|
realFields.push(this._fields[i]);
|
||||||
|
}
|
||||||
|
return realFields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifie qu'un champ faire partie de ceux à afficher.
|
||||||
|
public checkField2Rend(nb: number) : boolean
|
||||||
|
{
|
||||||
|
if(this.realFields2Rend()[nb] === undefined)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Vérifie que les numéros de champs pour lesquels il y a des fonctions de classement spécifiques sont cohérents.
|
// Vérifie que les numéros de champs pour lesquels il y a des fonctions de classement spécifiques sont cohérents.
|
||||||
// ! Ne peut donc être utilisé qu'après avoir parsé les données.
|
// ! Ne peut donc être utilisé qu'après avoir parsé les données.
|
||||||
set datasSortingFunctions(SortingFunctions: SortingFunctions[])
|
set datasSortingFunctions(SortingFunctions: SortingFunctions[])
|
||||||
@ -122,6 +153,24 @@ export class FreeDatas2HTML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vérifie que tous les numéros de champs à afficher sont valides
|
||||||
|
// Un tableau vide signifie que tous les champs parsés seront affichés.
|
||||||
|
set fields2Rend(fields: number[])
|
||||||
|
{
|
||||||
|
if(fields.length === 0)
|
||||||
|
this._fields2Rend=fields;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(let field of fields)
|
||||||
|
{
|
||||||
|
if(! this.checkFieldExist(field))
|
||||||
|
throw new Error(errors.converterFieldNotFound);
|
||||||
|
else
|
||||||
|
this._fields2Rend.push(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Retourne l'éventuelle fonction spécifique de classement associée à un champ
|
// Retourne l'éventuelle fonction spécifique de classement associée à un champ
|
||||||
public getSortingFunctionForField(datasFieldNb: number): SortingFunctions|undefined
|
public getSortingFunctionForField(datasFieldNb: number): SortingFunctions|undefined
|
||||||
{
|
{
|
||||||
@ -147,8 +196,12 @@ export class FreeDatas2HTML
|
|||||||
{
|
{
|
||||||
this._fields=this.parser.parseResults.fields;
|
this._fields=this.parser.parseResults.fields;
|
||||||
this._datas=this.parser.parseResults.datas;
|
this._datas=this.parser.parseResults.datas;
|
||||||
// Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu :
|
// Les champs ne bougeront plus, donc on peut déjà les passer au moteur de rendu.
|
||||||
this.datasRender.fields=this._fields;
|
// Mais en prenant les comptes les éventuels champs à ne pas afficher
|
||||||
|
if(this._fields2Rend.length === 0)
|
||||||
|
this.datasRender.fields=this._fields;
|
||||||
|
else
|
||||||
|
this.datasRender.fields=this.realFields2Rend();
|
||||||
if(this._datasViewElt !== undefined)
|
if(this._datasViewElt !== undefined)
|
||||||
this.refreshView();
|
this.refreshView();
|
||||||
return true;
|
return true;
|
||||||
@ -207,7 +260,7 @@ export class FreeDatas2HTML
|
|||||||
let maxData=(this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : this._datas.length;
|
let maxData=(this.pagination !== undefined && this.pagination.selectedValue !== undefined) ? this.pagination.selectedValue : this._datas.length;
|
||||||
|
|
||||||
// Création du tableau des données à afficher :
|
// Création du tableau des données à afficher :
|
||||||
const datas2Display=[];
|
let datas2Display=[];
|
||||||
let nbVisible=0, nbTotal=0;
|
let nbVisible=0, nbTotal=0;
|
||||||
for (let row in this._datas)
|
for (let row in this._datas)
|
||||||
{
|
{
|
||||||
@ -228,6 +281,25 @@ export class FreeDatas2HTML
|
|||||||
nbTotal++;
|
nbTotal++;
|
||||||
}
|
}
|
||||||
this._nbDatasValid=nbTotal;
|
this._nbDatasValid=nbTotal;
|
||||||
|
|
||||||
|
// Tous les champs doivent-ils être affichés ?
|
||||||
|
// Ne pas enlever les champs cachés plus tôt, car ils peuvent servir à filtrer les données
|
||||||
|
if(this._fields2Rend.length !== 0)
|
||||||
|
{
|
||||||
|
let newDatas2Display=[];
|
||||||
|
for(let row in datas2Display)
|
||||||
|
{
|
||||||
|
let i=0, newData: {[index: string]: string} = {};
|
||||||
|
for(let field in datas2Display[row])
|
||||||
|
{
|
||||||
|
if(this._fields2Rend.indexOf(i) !== -1)
|
||||||
|
newData[field]=datas2Display[row][field];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
newDatas2Display.push(newData);
|
||||||
|
}
|
||||||
|
datas2Display=newDatas2Display;
|
||||||
|
}
|
||||||
return datas2Display;
|
return datas2Display;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,5 +307,6 @@ export class FreeDatas2HTML
|
|||||||
// Permet l'appel des principales classes du module via un seul script :
|
// Permet l'appel des principales classes du module via un seul script :
|
||||||
export { Pagination } from "./Pagination";
|
export { Pagination } from "./Pagination";
|
||||||
export { Render} from "./Render";
|
export { Render} from "./Render";
|
||||||
|
export { SearchEngine } from "./SearchEngine";
|
||||||
export { Selector } from "./Selector";
|
export { Selector } from "./Selector";
|
||||||
export { SortingField } from "./SortingField";
|
export { SortingField } from "./SortingField";
|
131
src/SearchEngine.ts
Normal file
131
src/SearchEngine.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
const errors=require("./errors.js");
|
||||||
|
import { DOMElement, Filters } from "./interfaces";
|
||||||
|
import { FreeDatas2HTML } from "./FreeDatas2HTML";
|
||||||
|
|
||||||
|
export class SearchEngine implements Filters
|
||||||
|
{
|
||||||
|
private _converter: FreeDatas2HTML;
|
||||||
|
private _datasViewElt: DOMElement={ id: "", eltDOM: undefined };
|
||||||
|
private _btnTxt: string="Search";
|
||||||
|
private _fields2Search: string[]=[];
|
||||||
|
public label: string="";
|
||||||
|
public nbCharsForSearch : number=0;
|
||||||
|
public placeholder: string="";
|
||||||
|
public automaticSearch: boolean=false;
|
||||||
|
private _inputValue: string="";
|
||||||
|
|
||||||
|
// Injection de la classe principale, mais uniquement si des données ont été importées
|
||||||
|
constructor(converter: FreeDatas2HTML, elt: DOMElement, fields?: number[])
|
||||||
|
{
|
||||||
|
if(converter.fields.length === 0 || converter.datas.length === 0)
|
||||||
|
throw new Error(errors.filterNeedDatas);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt);
|
||||||
|
this._converter=converter;
|
||||||
|
// Les champs sur lesquels les recherches seront lancées.
|
||||||
|
// Ils doivent se trouver dans les données parsées, mais peuvent ne pas être affichés dans les données.
|
||||||
|
// Un tableau vide est accepté et signifie que les recherches se feront sur tous les champs.
|
||||||
|
if(fields !== undefined && fields.length !== 0)
|
||||||
|
{
|
||||||
|
for(let field of fields)
|
||||||
|
{
|
||||||
|
if(! this._converter.checkFieldExist(field))
|
||||||
|
throw new Error(errors.searchFieldNotFound);
|
||||||
|
else
|
||||||
|
this._fields2Search.push(this.converter.fields[field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this._fields2Search=this._converter.fields;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get converter() : FreeDatas2HTML
|
||||||
|
{
|
||||||
|
return this._converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
get datasViewElt() : DOMElement
|
||||||
|
{
|
||||||
|
return this._datasViewElt;
|
||||||
|
}
|
||||||
|
|
||||||
|
set btnTxt(txt: string)
|
||||||
|
{
|
||||||
|
if(txt.trim() !== "" && txt.length <= 30)
|
||||||
|
this._btnTxt=txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
get btnTxt(): string
|
||||||
|
{
|
||||||
|
return this._btnTxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
get inputValue() : string
|
||||||
|
{
|
||||||
|
return this._inputValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fields2Search() : string[]
|
||||||
|
{
|
||||||
|
return this._fields2Search;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création du champ de recherche dans le DOM.
|
||||||
|
public filter2HTML() : void
|
||||||
|
{
|
||||||
|
if(this.nbCharsForSearch >0 && this.placeholder === "")
|
||||||
|
this.placeholder="Please enter at least NB characters."
|
||||||
|
// Pas de minlength ou de required, car l'envoi d'une recherche vide doit permettre d'annuler le filtre.
|
||||||
|
let html=`<form id="freeDatas2HTMLSearch">`;
|
||||||
|
if(this.label !== "")
|
||||||
|
html+=`<label for="freeDatas2HTMLSearchTxt">${this.label}</label>`;
|
||||||
|
html+=`<input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt"`;
|
||||||
|
if(this.nbCharsForSearch > 0)
|
||||||
|
html+=` placeholder="${this.placeholder.replace("NB", ""+this.nbCharsForSearch)}"`;
|
||||||
|
else if(this.placeholder !== "")
|
||||||
|
html+=` placeholder="${this.placeholder}"`;
|
||||||
|
html+=`> <input type="submit" id="freeDatas2HTMLSearchBtn" value="${this._btnTxt}"></form>`;
|
||||||
|
this. _datasViewElt.eltDOM!.innerHTML=html;// "!" car l'existence de "eltDOM" est testé par le constructeur
|
||||||
|
|
||||||
|
// L'affichage est actualisé quand l'éventuel nombre de caractères est atteint ou quand le champ est vide, car cela permet d'annuler ce filtre.
|
||||||
|
const searchInput=document.getElementById("freeDatas2HTMLSearchTxt") as HTMLInputElement, mySearch=this;
|
||||||
|
searchInput.addEventListener("input", function(e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
mySearch._inputValue=searchInput.value;
|
||||||
|
let searchLength=searchInput.value.length;
|
||||||
|
if(mySearch.automaticSearch && (mySearch.nbCharsForSearch === 0 || ( searchLength === 0) || (searchLength >= mySearch.nbCharsForSearch)))
|
||||||
|
mySearch._converter.refreshView();
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Afficher un message quand le nombre de caractères n'est pas atteint ?
|
||||||
|
const searchBtn=document.getElementById("freeDatas2HTMLSearchBtn") as HTMLInputElement;
|
||||||
|
searchBtn.addEventListener("click", function(e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
let searchLength=searchInput.value.length;
|
||||||
|
if((mySearch.nbCharsForSearch === 0 || ( searchLength === 0) || (searchLength >= mySearch.nbCharsForSearch)))
|
||||||
|
mySearch._converter.refreshView();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public dataIsOk(data: {[index: string]:string}) : boolean
|
||||||
|
{
|
||||||
|
// Pas de valeur sélectionnée = pas de filtre sur ce champ
|
||||||
|
if(this._inputValue.length === 0)
|
||||||
|
return true;
|
||||||
|
// Sinon, on cherche la valeur saisie dans les champs définis :
|
||||||
|
for(let field in data)
|
||||||
|
{
|
||||||
|
if(this._fields2Search.indexOf(field) !== -1)
|
||||||
|
{
|
||||||
|
// Attention, recherche insensible à la casse, mais aux accents, etc.
|
||||||
|
if(data[field].toLowerCase().indexOf(this._inputValue.toLowerCase()) !== -1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -10,19 +10,20 @@ export class SortingField implements SortingFields
|
|||||||
_datasFieldNb: number;
|
_datasFieldNb: number;
|
||||||
_order: "asc"|"desc"|undefined=undefined;
|
_order: "asc"|"desc"|undefined=undefined;
|
||||||
|
|
||||||
// Injection de la classe principale, mais uniquement si les noms des champs ont été importés et affichés correctement
|
// Injection de la classe principale, mais uniquement si les noms des champs ont été importés et affichés correctement.
|
||||||
|
// Attention le numéro de champ concerne les champs effectivement affichés et non ceux issus du parseur.
|
||||||
constructor(converter: FreeDatas2HTML, datasFieldNb: number, fieldsDOMSelector: string="th")
|
constructor(converter: FreeDatas2HTML, datasFieldNb: number, fieldsDOMSelector: string="th")
|
||||||
{
|
{
|
||||||
if(converter.fields.length === 0)
|
if(converter.fields.length === 0)
|
||||||
throw new Error(errors.sortingFieldNeedDatas);
|
throw new Error(errors.sortingFieldNeedDatas);
|
||||||
else if(! converter.checkFieldExist(datasFieldNb))
|
else if(! converter.checkField2Rend(datasFieldNb))
|
||||||
throw new Error(errors.sortingFieldNotFound);
|
throw new Error(errors.sortingFieldNotFound);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const fields=document.querySelectorAll(fieldsDOMSelector);
|
const fields=document.querySelectorAll(fieldsDOMSelector);
|
||||||
if(fields === undefined)
|
if(fields === undefined)
|
||||||
throw new Error(errors.sortingFieldsNotInHTML);
|
throw new Error(errors.sortingFieldsNotInHTML);
|
||||||
else if(fields.length !== converter.fields.length)
|
else if(fields.length !== converter.realFields2Rend().length)
|
||||||
throw new Error(errors.sortingFieldsNbFail);
|
throw new Error(errors.sortingFieldsNbFail);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -29,12 +29,13 @@ module.exports =
|
|||||||
remoteSourceNeedUrl: "Merci de fournir une url valide pour la source distante de données.",
|
remoteSourceNeedUrl: "Merci de fournir une url valide pour la source distante de données.",
|
||||||
remoteSourceUrlFail: "L'url fournie ne semble pas valide.",
|
remoteSourceUrlFail: "L'url fournie ne semble pas valide.",
|
||||||
renderNeedFields: "Les noms de champs doivent être fournis avant de demander l'affichage des données.",
|
renderNeedFields: "Les noms de champs doivent être fournis avant de demander l'affichage des données.",
|
||||||
|
searchFieldNotFound: "Au moins un des champs devant être utilisés par le moteur de recherche n'existe pas dans les 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.",
|
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.",
|
||||||
selectorFieldIsEmpty: "Aucune donnée trouvée pour le champ du filtre",
|
selectorFieldIsEmpty: "Aucune donnée trouvée pour le champ du filtre",
|
||||||
selectorFieldNotFound: "Au moins un des champs devant servir à filtrer les données n'existe pas dans le fichier.",
|
selectorFieldNotFound: "Au moins un des champs devant servir à filtrer les données n'existe pas dans le fichier.",
|
||||||
selectorSelectedIndexNotFound: "La valeur sélectionnée n'a pas été trouvée dans la liste des champs.",
|
selectorSelectedIndexNotFound: "La valeur sélectionnée n'a pas été trouvée dans la liste des champs.",
|
||||||
sortingFieldNeedDatas: "La création d'un champ de classement nécessite la transmission de la liste des champs.",
|
sortingFieldNeedDatas: "La création d'un champ de classement nécessite la transmission de la liste des champs.",
|
||||||
sortingFieldNotFound: "Au moins un des champs devant permettre de classer les données n'existe pas dans le fichier.",
|
sortingFieldNotFound: "Au moins un des champs devant permettre de classer les données n'existe pas dans ceux à afficher.",
|
||||||
sortingFieldsNbFail: "Le nombre de champs trouvés dans le DOM ne correspond pas à celui des données à classer.",
|
sortingFieldsNbFail: "Le nombre de champs trouvés dans le DOM ne correspond pas à celui des données à classer.",
|
||||||
sortingFieldsNotInHTML: "Les champs pouvant servir à classer les données n'ont pas été trouvés dans le DOM.",
|
sortingFieldsNotInHTML: "Les champs pouvant servir à classer les données n'ont pas été trouvés dans le DOM.",
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
module.exports =
|
module.exports =
|
||||||
{
|
{
|
||||||
datasViewEltHTML: '<div id="fixture"><div id="selector1"></div><div id="selector2"></div><div id="paginationOptions"></div><div id="counter"></div><div id="datas"></div><div id="pages"></div></div>',
|
datasViewEltHTML: '<div id="fixture"><div id="selector1"></div><div id="selector2"></div><div id="paginationOptions"></div><div id="counter"></div><div id="datas"></div><div id="pages"></div><div id="mySearch"></div></div>',
|
||||||
selector1HTML: '<label for="freeDatas2HTML_selector1">Famille :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Actinide</option><option value="2">Gaz noble</option><option value="3">gaz rare</option><option value="4">Halogène</option><option value="5">Indéfinie</option><option value="6">Lanthanide</option><option value="7">Métal alcalin</option><option value="8">Métal alcalino-terreux</option><option value="9">Métal de transition</option><option value="10">Métal pauvre</option><option value="11">Métalloïde</option><option value="12">Non-métal</option></select>',
|
selector1HTML: '<label for="freeDatas2HTML_selector1">Famille :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Actinide</option><option value="2">Gaz noble</option><option value="3">gaz rare</option><option value="4">Halogène</option><option value="5">Indéfinie</option><option value="6">Lanthanide</option><option value="7">Métal alcalin</option><option value="8">Métal alcalino-terreux</option><option value="9">Métal de transition</option><option value="10">Métal pauvre</option><option value="11">Métalloïde</option><option value="12">Non-métal</option></select>',
|
||||||
selector2HTML: '<label for="freeDatas2HTML_selector2">Abondance des éléments dans la croûte terrestre (μg/k) :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
selector2HTML: '<label for="freeDatas2HTML_selector2">Abondance des éléments dans la croûte terrestre (μg/k) :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
||||||
selector2HTMLWithLabel: '<label for="freeDatas2HTML_selector2">Abondance des éléments :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
selector2HTMLWithLabel: '<label for="freeDatas2HTML_selector2">Abondance des éléments :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
||||||
|
@ -111,11 +111,18 @@ describe("Tests du script central de FreeDatas2HTML", () =>
|
|||||||
expect(converter.fields).toEqual(converter.parser.parseResults.fields);
|
expect(converter.fields).toEqual(converter.parser.parseResults.fields);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Si le parsage s'est bien déroulé, la liste des champs trouvés doit être transmise au moteur de rendu sans altération.", () =>
|
it("Si le parsage s'est bien déroulé et que tous les champs doivent être affichés, leur liste doit être transmise au moteur de rendu sans altération.", () =>
|
||||||
{
|
{
|
||||||
expect(converter.datasRender.fields).toEqual(converter.parser.parseResults.fields);
|
expect(converter.datasRender.fields).toEqual(converter.parser.parseResults.fields);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Si le parsage s'est bien déroulé et qu'une liste de champs à afficher a été fournie, seuls ceux demandés doivent être transmis au moteur de rendu.", async () =>
|
||||||
|
{
|
||||||
|
converter.fields2Rend=[1,2];
|
||||||
|
await converter.run();
|
||||||
|
expect(converter.datasRender.fields).toEqual([converter.parser.parseResults.fields[1],converter.parser.parseResults.fields[2]]);
|
||||||
|
});
|
||||||
|
|
||||||
it("Si le parsage s'est bien déroulé et qu'un élément HTML est renseigné pour recevoir les données, un premier affichage doit être demandé.", async () =>
|
it("Si le parsage s'est bien déroulé et qu'un élément HTML est renseigné pour recevoir les données, un premier affichage doit être demandé.", async () =>
|
||||||
{
|
{
|
||||||
spyOn(converter, "refreshView");
|
spyOn(converter, "refreshView");
|
||||||
@ -155,7 +162,7 @@ describe("Tests du script central de FreeDatas2HTML", () =>
|
|||||||
converter=new FreeDatas2HTML("CSV");
|
converter=new FreeDatas2HTML("CSV");
|
||||||
const check=converter.checkFieldExist(0);
|
const check=converter.checkFieldExist(0);
|
||||||
expect(converter.checkFieldExist(0)).toBeFalse();
|
expect(converter.checkFieldExist(0)).toBeFalse();
|
||||||
// Dans le cas d'un parsage ne retournant rien, c'est le parseur qui va générer une erreur.
|
// Dans le cas d'un parsage ne retournant rien, c'est le parseur qui doit générer une erreur.
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Doit retourner false si le numéro de champ n'est pas trouvé dans les données.", () =>
|
it("Doit retourner false si le numéro de champ n'est pas trouvé dans les données.", () =>
|
||||||
@ -176,6 +183,23 @@ describe("Tests du script central de FreeDatas2HTML", () =>
|
|||||||
expect(check).toBeTrue();
|
expect(check).toBeTrue();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Doit générer une erreur si tous les champs devant être affichés ne sont pas présents dans les données reçues.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return converter.fields2Rend=[0,2,8]; }).toThrowError(errors.converterFieldNotFound);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit accepter un tableau vide pour la liste de champs à afficher.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return converter.fields2Rend=[]; }).not.toThrowError();
|
||||||
|
expect(converter.fields2Rend.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si tous les champs à afficher sont trouvés dans les données, ils doivent être acceptés.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return converter.fields2Rend=[0,1,2]; }).not.toThrowError();
|
||||||
|
expect(converter.fields2Rend).toEqual([0,1,2]);
|
||||||
|
});
|
||||||
|
|
||||||
it("Doit générer une erreur si une fonction est associée à un champ n'existant pas dans les données.", () =>
|
it("Doit générer une erreur si une fonction est associée à un champ n'existant pas dans les données.", () =>
|
||||||
{
|
{
|
||||||
expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:10, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound);
|
expect(() => { return converter.datasSortingFunctions=[{ datasFieldNb:10, sort:simpleSort }]; }).toThrowError(errors.converterFieldNotFound);
|
||||||
@ -272,6 +296,25 @@ describe("Tests du script central de FreeDatas2HTML", () =>
|
|||||||
await converter.run();
|
await converter.run();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Si une liste de champs à afficher a été renseignée, elle doit être prise en compte.", async () =>
|
||||||
|
{
|
||||||
|
converter=new FreeDatas2HTML("CSV","id,firstname,name,birthday\n1,john,doe,2001/12/25\n2,donald,duck,1934/06/09");
|
||||||
|
converter.datasViewElt={ id:"datas" };
|
||||||
|
await converter.run();
|
||||||
|
converter.fields2Rend=[1,2];
|
||||||
|
converter.refreshView();
|
||||||
|
expect(converter.datas2Rend).toEqual([{ firstname:"john", name:"doe" }, { firstname:"donald", name:"duck" }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Par défaut, tous les champs trouvés doivent être affichés.", async () =>
|
||||||
|
{
|
||||||
|
converter=new FreeDatas2HTML("CSV","id,firstname,name,birthday\n1,john,doe,2001/12/25\n2,donald,duck,1934/06/09");
|
||||||
|
converter.datasViewElt={ id:"datas" };
|
||||||
|
await converter.run();
|
||||||
|
converter.refreshView();
|
||||||
|
expect(converter.datas2Rend).toEqual([{ id:"1", firstname:"john", name:"doe", birthday:"2001/12/25" }, { id:"2", firstname:"donald", name:"duck", birthday:"1934/06/09" }]);
|
||||||
|
});
|
||||||
|
|
||||||
it("Si un champ de classement est activé par l'utilisateur, les données doivent être classées via ce champ.", () =>
|
it("Si un champ de classement est activé par l'utilisateur, les données doivent être classées via ce champ.", () =>
|
||||||
{
|
{
|
||||||
// Compliqué de tester avec spyOn que sort() a été appelée avec la bonne fonction de classement en paramètre
|
// Compliqué de tester avec spyOn que sort() a été appelée avec la bonne fonction de classement en paramètre
|
||||||
|
271
tests/searchEngineSpec.ts
Normal file
271
tests/searchEngineSpec.ts
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
import { FreeDatas2HTML, SearchEngine } from "../src/FreeDatas2HTML";
|
||||||
|
const errors=require("../src/errors.js");
|
||||||
|
const fixtures=require("./fixtures.js");
|
||||||
|
|
||||||
|
describe("Test du moteur de recherche.", () =>
|
||||||
|
{
|
||||||
|
let converter: FreeDatas2HTML;
|
||||||
|
let mySearch: SearchEngine;
|
||||||
|
let searchElement : HTMLInputElement;
|
||||||
|
|
||||||
|
beforeEach( async () =>
|
||||||
|
{
|
||||||
|
document.body.insertAdjacentHTML("afterbegin", fixtures.datasViewEltHTML);
|
||||||
|
converter=new FreeDatas2HTML("CSV");
|
||||||
|
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" });
|
||||||
|
converter.datasViewElt={ id:"datas" };
|
||||||
|
await converter.run();
|
||||||
|
mySearch=new SearchEngine(converter, { id:"mySearch" });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach( () =>
|
||||||
|
{
|
||||||
|
document.body.removeChild(document.getElementById("fixture"));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Test des données de configuration.", () =>
|
||||||
|
{
|
||||||
|
it("Doit avoir créé une instance de SearchEngine", () =>
|
||||||
|
{
|
||||||
|
expect(mySearch).toBeInstanceOf(SearchEngine);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit générer une erreur, si initialisé sans avoir au préalable chargé des données.", async () =>
|
||||||
|
{
|
||||||
|
converter=new FreeDatas2HTML("CSV");
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }); }).toThrowError(errors.filterNeedDatas);
|
||||||
|
converter.parser.datas2Parse="Z (numéro atomique),Élément,Symbole,Famille,Abondance des éléments dans la croûte terrestre (μg/k)";
|
||||||
|
await converter.run();
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }); }).toThrowError(errors.filterNeedDatas);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si une chaîne vide est transmise pour le texte du bouton, elle doit être ignorée.", () =>
|
||||||
|
{
|
||||||
|
mySearch.btnTxt="";
|
||||||
|
expect(mySearch.btnTxt).toEqual("Search");
|
||||||
|
mySearch.btnTxt=" ";
|
||||||
|
expect(mySearch.btnTxt).toEqual("Search");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si une chaîne de + de 30 caractères est transmise pour le texte du bouton, elle doit être ignorée.", () =>
|
||||||
|
{
|
||||||
|
mySearch.btnTxt="Si une chaîne de + de 30 caractères est transmise pour le texte du bouton, elle doit être ignorée.";
|
||||||
|
expect(mySearch.btnTxt).toEqual("Search");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Toute chaîne de caractères valide doit être acceptée comme texte pour le bouton.", () =>
|
||||||
|
{
|
||||||
|
mySearch.btnTxt="a";
|
||||||
|
expect(mySearch.btnTxt).toEqual("a");
|
||||||
|
mySearch.btnTxt=" aaa ";
|
||||||
|
expect(mySearch.btnTxt).toEqual(" aaa ");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit générer une erreur, si au moins un des numéros des champs sur lesquels effectuer les recherches n'existe pas dans les données.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }, [-1,0,2]); }).toThrowError(errors.searchFieldNotFound);
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }, [0,1,10]); }).toThrowError(errors.searchFieldNotFound);
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }, [0,1.1,10]); }).toThrowError(errors.searchFieldNotFound);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si tous numéros des champs sur lesquels effectuer les recherches existent dans les données, ils doivent être acceptés.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }, [0,2,3]); }).not.toThrowError();
|
||||||
|
mySearch=new SearchEngine(converter, { id:"mySearch" }, [0,2,3]);
|
||||||
|
expect(mySearch.fields2Search).toEqual(["Z (numéro atomique)","Symbole","Famille"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Un tableau vide pour les champs sur lesquels effectuer les recherche doit être accepté.", () =>
|
||||||
|
{
|
||||||
|
expect(() => { return new SearchEngine(converter, { id:"mySearch" }, []); }).not.toThrowError();
|
||||||
|
expect(mySearch.fields2Search).toEqual(["Z (numéro atomique)","Élément","Symbole","Famille","Abondance des éléments dans la croûte terrestre (μg/k)"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Création du champ de recherche.", () =>
|
||||||
|
{
|
||||||
|
it("Doit générer un élement <input> et un bouton <submit> dans l'élément HTML indiqué avec les propriétés de base.", () =>
|
||||||
|
{
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt"> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Search"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit prendre en compte l'éventuel label fourni pour le champ de recherche.", () =>
|
||||||
|
{
|
||||||
|
mySearch.label="Qui cherche trouve ?";
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><label for="freeDatas2HTMLSearchTxt">Qui cherche trouve ?</label><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt"> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Search"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit prendre en compte l'éventuel texte personnalisé du bouton de recherche.", () =>
|
||||||
|
{
|
||||||
|
mySearch.btnTxt="Qui cherche trouve ?";
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt"> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Qui cherche trouve ?"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit indiquer l'éventuel nombre de caractères requis pour lancer la recherche.", () =>
|
||||||
|
{
|
||||||
|
mySearch.nbCharsForSearch=2;
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt" placeholder="Please enter at least 2 characters."> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Search"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit indiquer l'éventuel nombre de caractères requis pour lancer la recherche en utilisant un texte personnalisé.", () =>
|
||||||
|
{
|
||||||
|
mySearch.nbCharsForSearch=3;
|
||||||
|
mySearch.placeholder="Saisir NB caractères pour lancer votre recherche.";
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt" placeholder="Saisir 3 caractères pour lancer votre recherche."> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Search"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit accepter un texte d'indication libre, même quand il n'y a pas de nombre de caractères requis.", () =>
|
||||||
|
{
|
||||||
|
mySearch.placeholder="Bonne chance !";
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt" placeholder="Bonne chance !"> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Search"></form>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit prendre en compte l'ensemble des attributs renseignés.", () =>
|
||||||
|
{
|
||||||
|
mySearch.label="Qui cherche trouve ?";
|
||||||
|
mySearch.btnTxt="Qui cherche trouve ?";
|
||||||
|
mySearch.nbCharsForSearch=3;
|
||||||
|
mySearch.placeholder="Saisir NB caractères pour lancer votre recherche.";
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
expect(document.getElementById("mySearch").innerHTML).toEqual(`<form id="freeDatas2HTMLSearch"><label for="freeDatas2HTMLSearchTxt">Qui cherche trouve ?</label><input type="search" id="freeDatas2HTMLSearchTxt" name="freeDatas2HTMLSearchTxt" placeholder="Saisir 3 caractères pour lancer votre recherche."> <input type="submit" id="freeDatas2HTMLSearchBtn" value="Qui cherche trouve ?"></form>`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Lancement de la recherche.", () =>
|
||||||
|
{
|
||||||
|
let searchInput: HTMLInputElement, searchBtn: HTMLInputElement;
|
||||||
|
|
||||||
|
beforeEach( async () =>
|
||||||
|
{
|
||||||
|
mySearch.filter2HTML();
|
||||||
|
searchInput=document.getElementById("freeDatas2HTMLSearchTxt") as HTMLInputElement;
|
||||||
|
searchBtn=document.getElementById("freeDatas2HTMLSearchBtn") as HTMLInputElement;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Le clic sur le bouton SUBMIT doit appeler la fonction actualisant l'affichage.", () =>
|
||||||
|
{
|
||||||
|
spyOn(converter, "refreshView");
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||||
|
searchInput.value="z";
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Le clic sur le bouton SUBMIT doit appeler la fonction actualisant l'affichage, pour peu que le nombre de caractères défini soit saisi.", () =>
|
||||||
|
{
|
||||||
|
spyOn(converter, "refreshView");
|
||||||
|
mySearch.nbCharsForSearch=3;
|
||||||
|
searchInput.value="z";
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).not.toHaveBeenCalled();
|
||||||
|
searchInput.value="zz";
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).not.toHaveBeenCalled();
|
||||||
|
searchInput.value="zzz";
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||||
|
// Il est toujours possible d'annuler la recherche :
|
||||||
|
searchInput.value="";
|
||||||
|
searchBtn.click();
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si demandé, l'actualisation est lancée à chaque saisie, y compris si le champ est vide.", () =>
|
||||||
|
{
|
||||||
|
spyOn(converter, "refreshView");
|
||||||
|
mySearch.automaticSearch=true;
|
||||||
|
searchInput.value="z";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||||
|
searchInput.value="zz";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||||
|
searchInput.value="";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Si demandé, l'actualisation est lancée à chaque saisie, mais avec un minimum de caractères défini.", () =>
|
||||||
|
{
|
||||||
|
spyOn(converter, "refreshView");
|
||||||
|
mySearch.nbCharsForSearch=3;
|
||||||
|
mySearch.automaticSearch=true;
|
||||||
|
searchInput.value="z";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).not.toHaveBeenCalled();
|
||||||
|
searchInput.value="zz";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).not.toHaveBeenCalled();
|
||||||
|
searchInput.value="zzz";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||||
|
searchInput.value="zz";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||||
|
// Il est toujours possible d'annuler la recherche :
|
||||||
|
searchInput.value="";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit toujours retourner true si le champ de recherche est vide.", () =>
|
||||||
|
{
|
||||||
|
mySearch.automaticSearch=true;
|
||||||
|
// Le champ est vide par défaut :
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "nom" : "oui" })).toBeTrue();
|
||||||
|
// Même comportement après un retour :
|
||||||
|
searchInput.value="z";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
searchInput.value="";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "nom" : "oui" })).toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Filtre des données", () =>
|
||||||
|
{
|
||||||
|
beforeEach( async () =>
|
||||||
|
{
|
||||||
|
mySearch.automaticSearch=true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit retourner false, si la donnée testée ne possède aucun des champs sur lesquels est lancée la recherche.", () =>
|
||||||
|
{
|
||||||
|
searchInput.value="lithium";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "nom" : "lithium" })).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur cherchée.", async () =>
|
||||||
|
{
|
||||||
|
searchInput.value="Halogène";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "Famille": "Halogene" })).toBeFalse();// sensible aux accents
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit retourner true, si la valeur recherchée est retrouvée dans la donnée recherchée, sans prendre en compte la casse.", () =>
|
||||||
|
{
|
||||||
|
// Expression exacte :
|
||||||
|
searchInput.value="Halogène";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||||
|
// Expression partielle :
|
||||||
|
searchInput.value="gène";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||||
|
// Insensible à casse :
|
||||||
|
searchInput.value="halo";
|
||||||
|
searchInput.dispatchEvent(new Event("input"));
|
||||||
|
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -31,7 +31,7 @@ describe("Test des champs de classement.", () =>
|
|||||||
expect(() => { return new SortingField(converter, 0); }).toThrowError(errors.sortingFieldNeedDatas);
|
expect(() => { return new SortingField(converter, 0); }).toThrowError(errors.sortingFieldNeedDatas);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Doit générer une erreur, si initialisé avec un numéro du champ de classement n'existant pas dans les données.", () =>
|
it("Doit générer une erreur, si initialisé avec un numéro du champ de classement n'existant dans ceux à afficher.", () =>
|
||||||
{
|
{
|
||||||
expect(() => { return new SortingField(converter, 9); }).toThrowError(errors.sortingFieldNotFound);
|
expect(() => { return new SortingField(converter, 9); }).toThrowError(errors.sortingFieldNotFound);
|
||||||
expect(() => { return new SortingField(converter, -1); }).toThrowError(errors.sortingFieldNotFound);
|
expect(() => { return new SortingField(converter, -1); }).toThrowError(errors.sortingFieldNotFound);
|
||||||
@ -43,7 +43,7 @@ describe("Test des champs de classement.", () =>
|
|||||||
expect(() => { return new SortingField(converter, 0, "th.cols"); }).toThrowError(errors.sortingsFieldNotInHTML);
|
expect(() => { return new SortingField(converter, 0, "th.cols"); }).toThrowError(errors.sortingsFieldNotInHTML);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Doit générer une erreur, si le nombre d'éléments trouvés dans le DOM pour les entêtes est différent du nombre de champs des données.", () =>
|
it("Doit générer une erreur, si le nombre d'éléments trouvés dans le DOM pour les entêtes est différent du nombre de champs à afficher.", () =>
|
||||||
{
|
{
|
||||||
expect(() => { return new SortingField(converter, 0, "td"); }).toThrowError(errors.sortingFieldsNbFail);
|
expect(() => { return new SortingField(converter, 0, "td"); }).toThrowError(errors.sortingFieldsNbFail);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user