Compare commits
7 Commits
48fc8580c7
...
f1cdf1cb5f
Author | SHA1 | Date |
---|---|---|
Fabrice PENHOËT | f1cdf1cb5f | |
Fabrice PENHOËT | 188b475c0e | |
Fabrice PENHOËT | 0c842e9d03 | |
Fabrice PENHOËT | 75961dd34a | |
Fabrice PENHOËT | 996540504c | |
Fabrice PENHOËT | fc91c7b665 | |
Fabrice PENHOËT | ae1bc5339b |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "freedatas2html",
|
||||
"version": "0.8.7",
|
||||
"version": "0.8.8",
|
||||
"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",
|
||||
"scripts": {
|
||||
|
|
|
@ -1,38 +1,50 @@
|
|||
const errors = require("./errors.js");
|
||||
const errors=require("./errors.js");
|
||||
import { DatasRenders, DatasRendersSettings } from "./interfaces";
|
||||
import { FreeDatas2HTML } from "./freeDatas2HTML";
|
||||
//import { FreeDatas2HTML } from "./freeDatas2HTML";
|
||||
|
||||
export class Render implements DatasRenders
|
||||
{
|
||||
private _converter: FreeDatas2HTML;
|
||||
public settings: DatasRendersSettings;
|
||||
static readonly defaultSettings =
|
||||
private _fields: string[]=[];
|
||||
public settings: DatasRendersSettings;
|
||||
public datas: {[index: string]:string}[]=[];
|
||||
static readonly defaultSettings=
|
||||
{
|
||||
allBegining:"<table>",
|
||||
allEnding:"</table>",
|
||||
fieldsBegining:"<thead><tr>",
|
||||
fieldsEnding:"</tr></thead>",
|
||||
fieldDisplaying:"<th>#FIELDNAME</th>",
|
||||
linesBegining:"<tbody>",
|
||||
linesEnding:"</tbody>",
|
||||
lineBegining:"<tr>",
|
||||
lineEnding:"</tr>",
|
||||
dataDisplaying:"<td>#VALUE</td>",
|
||||
};
|
||||
allBegining: "<table>",
|
||||
allEnding: "</table>",
|
||||
fieldsBegining: "<thead><tr>",
|
||||
fieldsEnding: "</tr></thead>",
|
||||
fieldDisplaying: "<th>#FIELDNAME</th>",
|
||||
linesBegining: "<tbody>",
|
||||
linesEnding: "</tbody>",
|
||||
lineBegining: "<tr>",
|
||||
lineEnding: "</tr>",
|
||||
dataDisplaying: "<td>#VALUE</td>"
|
||||
};
|
||||
|
||||
// Injection de la classe principale
|
||||
constructor(converter: FreeDatas2HTML, settings:DatasRendersSettings=Render.defaultSettings)
|
||||
constructor(settings: DatasRendersSettings=Render.defaultSettings)
|
||||
{
|
||||
this._converter=converter;
|
||||
this.settings=settings;
|
||||
}
|
||||
|
||||
// Reçoit les données à afficher et retourne le HTML correspondant.
|
||||
public rend2HTML(datas: any[]) : string
|
||||
// Les données fournies peuvent être vides du fait de l'action des filtres ou encore de la pagination...
|
||||
// Par contre, il doit y avoir au moins un nom de champ fourni
|
||||
set fields(fields: string[])
|
||||
{
|
||||
// Il peut n'y avoir aucune donnée (filtres...), mais les noms des champs doivent être connus.
|
||||
if(this._converter.fields === undefined)
|
||||
throw new Error(errors.renderNeedDatas);
|
||||
if(fields.length === 0)
|
||||
throw new Error(errors.renderNeedFields);
|
||||
else
|
||||
this._fields=fields;
|
||||
}
|
||||
|
||||
get fields() : string[]
|
||||
{
|
||||
return this._fields;
|
||||
}
|
||||
|
||||
public rend2HTML() : string
|
||||
{
|
||||
if(this._fields.length === 0)
|
||||
throw new Error(errors.renderNeedFields);
|
||||
else
|
||||
{
|
||||
let datasHTML=this.settings.allBegining;
|
||||
|
@ -40,19 +52,19 @@ export class Render implements DatasRenders
|
|||
if(this.settings.fieldsBegining !== undefined && this.settings.fieldDisplaying !== undefined && this.settings.fieldsEnding !== undefined )
|
||||
{
|
||||
datasHTML+=this.settings.fieldsBegining;
|
||||
for(let field of this._converter.fields)
|
||||
for(let field of this._fields)
|
||||
datasHTML+=this.settings.fieldDisplaying.replace("#FIELDNAME", field);
|
||||
datasHTML+=this.settings.fieldsEnding;
|
||||
}
|
||||
datasHTML+=this.settings.linesBegining;
|
||||
|
||||
// Suivant les objets/lignes, les champs peuvent se trouver dans un ordre différent,
|
||||
// ou encore des champs peuvent manquer ou être en trop.
|
||||
// Seuls les champs de "fields" doivent être traités et en respectant l'ordre de ce tableau.
|
||||
for(let row of datas)
|
||||
|
||||
// Suivant les objets/lignes, les champs peuvent se trouver dans un ordre différent.
|
||||
// Ou encore des champs peuvent manquer, être en trop...
|
||||
// Tous les champs présents dans "fields" doivent être affichés (même si absents d'un enregistrement) et en respectant l'ordre de ce tableau.
|
||||
for(let row of this.datas)
|
||||
{
|
||||
datasHTML+=this.settings.lineBegining;
|
||||
for(let field of this._converter.fields)
|
||||
for(let field of this._fields)
|
||||
{
|
||||
if(row[field] !== undefined)
|
||||
datasHTML+=this.settings.dataDisplaying.replace("#VALUE", row[field]).replace("#FIELDNAME", field);
|
||||
|
|
|
@ -53,10 +53,10 @@ export class Selector implements Selectors
|
|||
}
|
||||
|
||||
// Création du <select> dans le HTML correspondant au filtre
|
||||
public selector2HTML() : void
|
||||
public filter2HTML() : void
|
||||
{
|
||||
if(this._converter === undefined || this._datasViewElt.eltDOM === undefined || this._datasFieldNb === undefined)
|
||||
throw new Error(errors.selector2HTMLFail);
|
||||
throw new Error(errors.filter2HTMLFail);
|
||||
else
|
||||
{
|
||||
this.name=this._converter.fields![this._datasFieldNb]; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur)
|
|
@ -26,7 +26,7 @@ module.exports =
|
|||
remoteSourceHeaderUnallowed: "Le nom d'une des entêtes passées n'est pas autorisé.",
|
||||
remoteSourceNeedUrl: "Merci de fournir une url valide pour la source distante de données.",
|
||||
remoteSourceUrlFail: "L'url fournie ne semble pas valide.",
|
||||
renderNeedDatas: "Il ne peut y avoir de pagination, si les données n'ont pas été récupérées.",
|
||||
renderNeedFields: "Les noms de champs doivent être fournis avant de demander 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.",
|
||||
selectorCheckIsOkFail: "Le test est lancé sur un filtre incorrectement initialisé ou sur un attribut absent de la donnée à tester.",
|
||||
selectorFieldNotFound: "Au moins un des champs devant servir à filtrer les données n'existe pas dans le fichier.",
|
||||
|
|
|
@ -24,7 +24,7 @@ const initialise = async () =>
|
|||
converter.datasViewElt={ id:"datas" };
|
||||
await converter.run();
|
||||
// Adaptation du rendu suivant la taille de l'écran
|
||||
const myRender=new Render(converter);
|
||||
const myRender=new Render();
|
||||
if(window.innerWidth < 800)
|
||||
{
|
||||
myRender.settings=
|
||||
|
@ -61,14 +61,14 @@ const initialise = async () =>
|
|||
|
||||
// Création d'outils permettant de filtrer les données des champs de données
|
||||
let filtre1=new Selector(converter, 3, { id:"filtre1"} );
|
||||
filtre1.selector2HTML();
|
||||
filtre1.filter2HTML();
|
||||
let filtre2=new Selector(converter, 4, { id:"filtre2"} );
|
||||
filtre2.selector2HTML();
|
||||
filtre2.filter2HTML();
|
||||
let filtre3=new Selector(converter, 5, { id:"filtre3"} );
|
||||
filtre3.separator=",";
|
||||
filtre3.selector2HTML();
|
||||
filtre3.filter2HTML();
|
||||
// + Injection des filtres dans le convertisseur
|
||||
converter.datasSelectors=[filtre1,filtre2,filtre3];
|
||||
converter.datasFilters=[filtre1,filtre2,filtre3];
|
||||
|
||||
// Ajout de champs permettant de classer les données
|
||||
// Uniquement avec un rendu tableau (grand écran), car entêtes de colonne nécessaires
|
||||
|
|
|
@ -9,7 +9,7 @@ const initialise = async () =>
|
|||
converter.datasViewElt={ id:"datas" };
|
||||
await converter.run();
|
||||
// Adaptation du rendu suivant la taille de l'écran
|
||||
const myRender=new Render(converter);
|
||||
const myRender=new Render();
|
||||
if(window.innerWidth < 800)
|
||||
{
|
||||
myRender.settings=
|
||||
|
@ -43,8 +43,8 @@ const initialise = async () =>
|
|||
|
||||
// Création d'un filtre par auteur :
|
||||
let filtre1=new Selector(converter, 3, { id:"filtre1"} );
|
||||
filtre1.selector2HTML();
|
||||
converter.datasSelectors=[filtre1];
|
||||
filtre1.filter2HTML();
|
||||
converter.datasFilters=[filtre1];
|
||||
|
||||
// Ajout de champs permettant de classer les données
|
||||
// Uniquement avec un rendu tableau (grand écran), car entêtes de colonne nécessaires
|
||||
|
|
|
@ -10,7 +10,7 @@ const initialise = async () =>
|
|||
converter.datasViewElt={ id:"datas" };
|
||||
await converter.run();
|
||||
// Adaptation du rendu suivant la taille de l'écran
|
||||
const myRender=new Render(converter);
|
||||
const myRender=new Render();
|
||||
if(window.innerWidth < 800)
|
||||
{
|
||||
myRender.settings=
|
||||
|
@ -44,8 +44,8 @@ const initialise = async () =>
|
|||
|
||||
// Création d'un filtre par auteur :
|
||||
let filtre1=new Selector(converter, 0, { id:"filtre1"} );
|
||||
filtre1.selector2HTML();
|
||||
converter.datasSelectors=[filtre1];
|
||||
filtre1.filter2HTML();
|
||||
converter.datasFilters=[filtre1];
|
||||
|
||||
// Ajout de champs permettant de classer les données
|
||||
// Uniquement avec un rendu tableau (grand écran), car entêtes de colonne nécessaires
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
const { compare }=require('natural-orderby');
|
||||
const errors=require("./errors.js");
|
||||
|
||||
import { Counter, Datas, DatasRenders, DOMElement, Paginations, Parsers, ParseErrors, RemoteSources, Selectors, SortingFields, SortingFunctions } from "./interfaces";
|
||||
import { Counter, Datas, DatasRenders, DOMElement, Filters, Paginations, Parsers, ParseErrors, RemoteSources, SortingFields, SortingFunctions } from "./interfaces";
|
||||
import { Pagination} from "./Pagination";
|
||||
import { ParserForCSV} from "./ParserForCSV";
|
||||
import { ParserForHTML} from "./ParserForHTML";
|
||||
import { ParserForJSON} from "./ParserForJSON";
|
||||
import { Render} from "./Render";
|
||||
import { Selector } from "./freeDatas2HTMLSelector";
|
||||
import { Selector } from "./Selector";
|
||||
import { SortingField } from "./SortingField";
|
||||
|
||||
export class FreeDatas2HTML
|
||||
|
@ -26,7 +26,7 @@ export class FreeDatas2HTML
|
|||
// Le nom des champs trouvés dans les données :
|
||||
public fields: string[]|undefined=undefined;
|
||||
// Les données à proprement parler :
|
||||
public datas: {[index: string]:any}[]=[];
|
||||
public datas: {[index: string]:string}[]=[];
|
||||
// Les erreurs rencontrées durant le traitement des données reçues :
|
||||
public parseErrors: ParseErrors[]|undefined;
|
||||
// Doit-on tout arrêter si une erreur est rencontrée durant le traitement ?
|
||||
|
@ -35,7 +35,7 @@ export class FreeDatas2HTML
|
|||
// Les fonctions spécifiques de classement pour certains champs :
|
||||
private _datasSortingFunctions: SortingFunctions[] = [];
|
||||
// Les filtres possible sur certains champs :
|
||||
datasSelectors: Selectors[] = [];
|
||||
datasFilters: Filters[] = [];
|
||||
// Les champs pouvant être classés :
|
||||
datasSortingFields: SortingFields[] = [];
|
||||
// La dernier champ pour lequel le classement a été demandé :
|
||||
|
@ -50,7 +50,7 @@ export class FreeDatas2HTML
|
|||
// Il doit donc déjà avoir été testé
|
||||
constructor(datasType:"CSV"|"HTML"|"JSON", datas2Parse="", datasRemoteSource?:RemoteSources)
|
||||
{
|
||||
this.datasRender=new Render(this);
|
||||
this.datasRender=new Render();
|
||||
switch (datasType)
|
||||
{
|
||||
case "CSV":
|
||||
|
@ -151,9 +151,11 @@ export class FreeDatas2HTML
|
|||
else
|
||||
{
|
||||
// revoir l'intérêt de copier ces 3 attributs ?
|
||||
this.fields=this.parser.parseResults.fields;
|
||||
this.fields=this.parser.parseResults.fields;
|
||||
this.datas=this.parser.parseResults.datas;
|
||||
this.parseErrors=this.parser.parseResults.errors;
|
||||
// Les champs ne bougeront plus donc on peut aussi les passer au moteur de rendu
|
||||
this.datasRender.fields=this.fields;
|
||||
if(this._datasViewElt !== undefined)
|
||||
this.refreshView();
|
||||
return true;
|
||||
|
@ -204,12 +206,12 @@ export class FreeDatas2HTML
|
|||
for (let row in datas)
|
||||
{
|
||||
let visible=true;
|
||||
if(this.datasSelectors.length !== 0)
|
||||
if(this.datasFilters.length !== 0)
|
||||
{
|
||||
let i=0;
|
||||
while(this.datasSelectors[i] !== undefined && visible===true)
|
||||
while(this.datasFilters[i] !== undefined && visible===true)
|
||||
{
|
||||
visible=this.datasSelectors[i].dataIsOk(datas[row]);
|
||||
visible=this.datasFilters[i].dataIsOk(datas[row]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -230,12 +232,13 @@ export class FreeDatas2HTML
|
|||
// Tout réaffichage peut entraîner une modification du nombre de pages (évolution filtres, etc.)
|
||||
if(this.pagination !== undefined)
|
||||
this.pagination.pages2HTML(nbTotal);
|
||||
return this.datasRender.rend2HTML(datas2Display);
|
||||
this.datasRender.datas=datas2Display;
|
||||
return this.datasRender.rend2HTML();
|
||||
}
|
||||
}
|
||||
|
||||
// Permet l'appel des dépendances via un seul script
|
||||
export { Pagination } from "./Pagination";
|
||||
export { Render} from "./Render";
|
||||
export { Selector } from "./freeDatas2HTMLSelector";
|
||||
export { Selector } from "./Selector";
|
||||
export { SortingField } from "./SortingField";
|
|
@ -3,11 +3,13 @@ export interface Counter
|
|||
displayElement?: DOMElement; // peut être undefined si on ne souhaite pas d'affichage automatique dans la page
|
||||
value?: number; // undefined jusqu'à recevoir sa première valeur
|
||||
}
|
||||
export interface DatasRenders // interface à respecter par toute alternative à la classe Render par défaut
|
||||
export interface DatasRenders
|
||||
{
|
||||
rend2HTML(datas: any[]): string;
|
||||
fields: string[];
|
||||
datas: {[index: string]:string}[];
|
||||
rend2HTML(): string;
|
||||
}
|
||||
export interface DatasRendersSettings // interface spécifique à la classe Render par défaut.
|
||||
export interface DatasRendersSettings // interface spécifique à la classe Render par défaut
|
||||
{
|
||||
allBegining: string;
|
||||
allEnding: string;
|
||||
|
@ -25,6 +27,12 @@ export interface DOMElement
|
|||
id: string;
|
||||
eltDOM?: HTMLElement;
|
||||
}
|
||||
export interface Filters
|
||||
{
|
||||
datasViewElt: DOMElement;
|
||||
filter2HTML() : void;
|
||||
dataIsOk(data: any) : boolean;
|
||||
}
|
||||
export interface Paginations
|
||||
{
|
||||
options?: PaginationsOptions;
|
||||
|
@ -82,15 +90,12 @@ export interface RemoteSources extends RemoteSourceSettings
|
|||
{
|
||||
getFetchSettings() : {};
|
||||
}
|
||||
export interface Selectors
|
||||
export interface Selectors extends Filters
|
||||
{
|
||||
datasViewElt: DOMElement;
|
||||
datasFieldNb: number;
|
||||
separator?: string|undefined;
|
||||
name?: string;
|
||||
values?: string[];
|
||||
selector2HTML() : void;
|
||||
dataIsOk(data: any) : boolean;
|
||||
}
|
||||
export interface SortingFields
|
||||
{
|
||||
|
|
|
@ -2,8 +2,9 @@ import { FreeDatas2HTML, Render} from "../src/freeDatas2HTML";
|
|||
const errors=require("../src/errors.js");
|
||||
const fixtures=require("./fixtures.js");
|
||||
|
||||
/// Tests à revoir pour ne pas dépendre du bon fonctionnement de Parser et Render.
|
||||
|
||||
/// EN CHANTIER !!!
|
||||
/// Tests à revoir après avoir fait le tour des autres classes
|
||||
/*
|
||||
describe("Test du script central de FreeDatas2HTML", () =>
|
||||
{
|
||||
let converter: FreeDatas2HTML;
|
||||
|
@ -143,8 +144,9 @@ describe("Test du script central de FreeDatas2HTML", () =>
|
|||
{
|
||||
converter.datasViewElt={ id:"datas" };
|
||||
await converter.run();
|
||||
const render=new Render(converter);
|
||||
const htmlForDatas=render.rend2HTML(converter.datas);
|
||||
const render=new Render();
|
||||
render.datas=converter.datas;
|
||||
const htmlForDatas=render.rend2HTML();
|
||||
// On ne peut comparer directement au contenu du DOM,
|
||||
// car le navigateur change certains caractères (exemple : ">" devient ">")
|
||||
expect(converter.datasHTML).toEqual(htmlForDatas);
|
||||
|
@ -226,4 +228,88 @@ describe("Test du script central de FreeDatas2HTML", () =>
|
|||
|
||||
}); */
|
||||
|
||||
});
|
||||
/*
|
||||
describe("Création et action des sélecteurs liés à la pagination des données.", () =>
|
||||
{
|
||||
beforeEach( () =>
|
||||
{
|
||||
pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50,500] , name: "Choix de pagination :" };
|
||||
pagination.selectedValue=10;
|
||||
pagination.options2HTML();
|
||||
converter.pagination=pagination;
|
||||
//converter.refreshView();
|
||||
});
|
||||
|
||||
it("Si une valeur de pagination par défaut fournie, ne doit pas afficher plus de données.", () =>
|
||||
{
|
||||
let getTR=document.getElementsByTagName("tr");
|
||||
expect(getTR.length).toEqual(pagination.selectedValue+1); // 1er TR sert aux titres
|
||||
});
|
||||
|
||||
it("La manipulation du sélecteur de pagination doit appeler la fonction actualisant l'affichage.", () =>
|
||||
{
|
||||
spyOn(converter, "refreshView");
|
||||
let selectElement=document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement;
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||
selectElement.value="0";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("Si une des options de pagination fournies est sélectionnée, doit afficher le nombre de résultats correspondants.", () =>
|
||||
{
|
||||
let selectElement=document.getElementById("freeDatas2HTMLPaginationSelector") as HTMLInputElement;
|
||||
selectElement.value="2"; // = 20 éléments / page
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
let getTR=document.getElementsByTagName("tr");
|
||||
expect(getTR.length).toEqual(21);
|
||||
selectElement.value="3"; // = 50 éléments / page
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
getTR=document.getElementsByTagName("tr");
|
||||
expect(getTR.length).toEqual(51);
|
||||
selectElement.value="0"; // = pas de Pagination, on affiche les 118 lignes du fichier
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
getTR=document.getElementsByTagName("tr");
|
||||
expect(getTR.length).toEqual(119);
|
||||
});
|
||||
|
||||
it("Si il y a plus de données que le nombre de lignes autorisées par page, un <select> listant les pages doit être affiché.", () =>
|
||||
{
|
||||
let selectElement=document.getElementById("pages").innerHTML;
|
||||
expect(selectElement).toEqual(fixtures.selectorForPages);
|
||||
});
|
||||
|
||||
it("La manipulation du sélecteur de pages doit appeler la fonction actualisant l'affichage.", () =>
|
||||
{
|
||||
spyOn(converter, "refreshView");
|
||||
let selectElement=document.getElementById("freeDatas2HTMLPagesSelector") as HTMLInputElement;
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||
selectElement.value="0";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
});*/
|
|
@ -1,41 +1,54 @@
|
|||
import { FreeDatas2HTML, Render } from "../src/freeDatas2HTML";
|
||||
import { Render } from "../src/Render";
|
||||
const errors=require("../src/errors.js");
|
||||
|
||||
describe("Test du moteur de rendu HTML.", () =>
|
||||
{
|
||||
let converter: FreeDatas2HTML;
|
||||
let render: Render;
|
||||
let datas: any[];
|
||||
const fields=[ "Z", "Élément", "Symbole", "Famille" ] ;
|
||||
// Les champs des différentes lignes ne sont pas forcément dans le même ordre et certains peuvent être absents, vides ou encore en trop...
|
||||
const datas=[{"Z":"1","Élément":"Hydrogène","Symbole":"H","Famille":"Non-métal"},{"Famille":"Gaz noble","Élément":"Hélium","Z":"2","Symbole":"He"},{"Champ ignoré":"Je me champ ignoré !", "Z":"3","Élément":"Lithium","Famille":"Métal alcalin","Symbole":"Li"},{"Z":"4","Élément":"Béryllium","Famille":"","Champ ignoré":"Je me champ ignoré !"}] ;
|
||||
|
||||
beforeEach(() =>
|
||||
{
|
||||
converter=new FreeDatas2HTML("CSV");
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1.csv" });
|
||||
render=new Render(converter);
|
||||
converter.fields=[ "Z", "Élément", "Symbole", "Famille" ] ;
|
||||
// Les champs des différentes lignes ne sont pas forcément dans le même ordre, dans les champs peuvent être vide ou encore en trop...
|
||||
datas=[{"Z":"1","Élément":"Hydrogène","Symbole":"H","Famille":"Non-métal"},{"Famille":"Gaz noble","Élément":"Hélium","Z":"2","Symbole":"He"},{"Champ ignoré":"Je me champ ignoré !", "Z":"3","Élément":"Lithium","Famille":"Métal alcalin","Symbole":"Li"},{"Z":"4","Élément":"Béryllium","Symbole":"Be","Famille":"","Champ ignoré":"Je me champ ignoré !"}] ;
|
||||
render=new Render();
|
||||
});
|
||||
|
||||
it("Doit générer une erreur, si lancé sans fournir une liste des champs.", () =>
|
||||
it("Doit générer une erreur, si une liste de champs vide lui est fournie.", () =>
|
||||
{
|
||||
converter.fields=undefined;
|
||||
expect(() => { return render.rend2HTML(datas) }).toThrowError(errors.renderNeedDatas);
|
||||
expect(() => { return render.fields=[]; } ).toThrowError(errors.renderNeedFields);
|
||||
expect(render.fields).toEqual([]);
|
||||
});
|
||||
|
||||
it("Ne doit pas générer d'erreur, si lancé avec une liste des champs, même s'il n'y a aucune donnée à afficher.", () =>
|
||||
it("Doit accepter toute liste de champs valide.", () =>
|
||||
{
|
||||
expect(() => { return render.rend2HTML([])}).not.toThrowError();
|
||||
render=new Render();
|
||||
expect(() => { return render.fields=[""]; }).not.toThrowError(); // pas normal, mais pas testé par cette classe
|
||||
expect(render.fields).toEqual([""]);
|
||||
expect(() => { return render.fields=["je vois double", "je vois double"]; }).not.toThrowError(); // idem
|
||||
expect(render.fields).toEqual(["je vois double", "je vois double"]);
|
||||
expect(() => { return render.fields=["je me sens seul"]; }).not.toThrowError();
|
||||
expect(render.fields).toEqual(["je me sens seul"]);
|
||||
});
|
||||
|
||||
it("Doit générer une erreur, si lancé sans avoir fourni une liste des champs.", () =>
|
||||
{
|
||||
expect(() => { return render.rend2HTML(); }).toThrowError(errors.renderNeedFields);
|
||||
});
|
||||
|
||||
it("Ne doit pas générer d'erreur, si lancé avec une liste des champs, même s'il n'y a aucune donnée fournie.", () =>
|
||||
{
|
||||
render.fields=fields;
|
||||
expect(() => { return render.rend2HTML(); }).not.toThrowError();
|
||||
});
|
||||
|
||||
it("Doit retourner le code HTML créé en se basant sur la configuration par défaut, avec ou sans données à afficher.", () =>
|
||||
{
|
||||
// La configuration par défaut affiche le nom des champs, même quand il n'y a pas de données :
|
||||
let html=render.rend2HTML([]);
|
||||
render.fields=fields;
|
||||
let html=render.rend2HTML();
|
||||
expect(html).toEqual("<table><thead><tr><th>Z</th><th>Élément</th><th>Symbole</th><th>Famille</th></tr></thead><tbody></tbody></table>");
|
||||
// Avec des données :
|
||||
html=render.rend2HTML(datas);
|
||||
expect(html).toEqual("<table><thead><tr><th>Z</th><th>Élément</th><th>Symbole</th><th>Famille</th></tr></thead><tbody><tr><td>1</td><td>Hydrogène</td><td>H</td><td>Non-métal</td></tr><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td></tr><tr><td>3</td><td>Lithium</td><td>Li</td><td>Métal alcalin</td></tr><tr><td>4</td><td>Béryllium</td><td>Be</td><td></td></tr></tbody></table>");
|
||||
render.datas=datas;
|
||||
html=render.rend2HTML();
|
||||
expect(html).toEqual("<table><thead><tr><th>Z</th><th>Élément</th><th>Symbole</th><th>Famille</th></tr></thead><tbody><tr><td>1</td><td>Hydrogène</td><td>H</td><td>Non-métal</td></tr><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td></tr><tr><td>3</td><td>Lithium</td><td>Li</td><td>Métal alcalin</td></tr><tr><td>4</td><td>Béryllium</td><td></td><td></td></tr></tbody></table>");
|
||||
});
|
||||
|
||||
it("Doit retourner un code HTML correspondant à la configuration fournie, avec ou sans données à afficher.", () =>
|
||||
|
@ -50,10 +63,12 @@ describe("Test du moteur de rendu HTML.", () =>
|
|||
lineEnding:"</ul>",
|
||||
dataDisplaying:"<li><b>#FIELDNAME :</b> #VALUE</li>",
|
||||
};
|
||||
let html=render.rend2HTML([]);
|
||||
render.fields=fields;
|
||||
let html=render.rend2HTML();
|
||||
expect(html).toEqual("<div id=\"test\"><h4>Pas de noms de champs !</h4><div id=\"myDatas\"></div></div>");
|
||||
// Avec des données :
|
||||
html=render.rend2HTML(datas);
|
||||
expect(html).toEqual("<div id=\"test\"><h4>Pas de noms de champs !</h4><div id=\"myDatas\"><ul><li><b>Z :</b> 1</li><li><b>Élément :</b> Hydrogène</li><li><b>Symbole :</b> H</li><li><b>Famille :</b> Non-métal</li></ul><ul><li><b>Z :</b> 2</li><li><b>Élément :</b> Hélium</li><li><b>Symbole :</b> He</li><li><b>Famille :</b> Gaz noble</li></ul><ul><li><b>Z :</b> 3</li><li><b>Élément :</b> Lithium</li><li><b>Symbole :</b> Li</li><li><b>Famille :</b> Métal alcalin</li></ul><ul><li><b>Z :</b> 4</li><li><b>Élément :</b> Béryllium</li><li><b>Symbole :</b> Be</li><li><b>Famille :</b> </li></ul></div></div>");
|
||||
render.datas=datas;
|
||||
html=render.rend2HTML();
|
||||
expect(html).toEqual("<div id=\"test\"><h4>Pas de noms de champs !</h4><div id=\"myDatas\"><ul><li><b>Z :</b> 1</li><li><b>Élément :</b> Hydrogène</li><li><b>Symbole :</b> H</li><li><b>Famille :</b> Non-métal</li></ul><ul><li><b>Z :</b> 2</li><li><b>Élément :</b> Hélium</li><li><b>Symbole :</b> He</li><li><b>Famille :</b> Gaz noble</li></ul><ul><li><b>Z :</b> 3</li><li><b>Élément :</b> Lithium</li><li><b>Symbole :</b> Li</li><li><b>Famille :</b> Métal alcalin</li></ul><ul><li><b>Z :</b> 4</li><li><b>Élément :</b> Béryllium</li><li><b>Symbole :</b> </li><li><b>Famille :</b> </li></ul></div></div>");
|
||||
});
|
||||
});
|
|
@ -66,10 +66,10 @@ describe("Test des filtres de données", () =>
|
|||
|
||||
it("Doit générer un élement <select> listant les valeurs distinctes du champ spécifié, classées dans le bon ordre.", () =>
|
||||
{
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML);
|
||||
selector=new Selector(converter, 4, { id:"selector2" });
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector2").innerHTML).toEqual(fixtures.selector2HTML);
|
||||
});
|
||||
|
||||
|
@ -78,7 +78,7 @@ describe("Test des filtres de données", () =>
|
|||
converter=new FreeDatas2HTML("CSV");
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1-emtyinfield.csv" });
|
||||
await converter.run();
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML);
|
||||
});
|
||||
|
||||
|
@ -89,7 +89,7 @@ describe("Test des filtres de données", () =>
|
|||
await converter.run();
|
||||
selector=new Selector(converter, 5, { id:"selector1" });
|
||||
selector.separator="|";
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithSeparator);
|
||||
});
|
||||
|
||||
|
@ -110,7 +110,7 @@ describe("Test des filtres de données", () =>
|
|||
converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }];
|
||||
selector=new Selector(converter, 4, { id:"selector1" });
|
||||
selector.separator="|";
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithFunction);
|
||||
});
|
||||
|
||||
|
@ -128,7 +128,7 @@ describe("Test des filtres de données", () =>
|
|||
|
||||
it("Doit retourner false, si la donnée testée ne possède pas le champ sur lequel les données sont filtrées.", () =>
|
||||
{
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement.value="4";
|
||||
let data2Test= { // le champ à filtrer ("Famille") est manquant
|
||||
|
@ -142,7 +142,7 @@ describe("Test des filtres de données", () =>
|
|||
|
||||
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée pour le filtre.", () =>
|
||||
{
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement.value="4";
|
||||
let data2Test= {
|
||||
|
@ -157,7 +157,7 @@ describe("Test des filtres de données", () =>
|
|||
|
||||
it("Doit retourner true, si une donnée testée correspond pas à la valeur sélectionnée pour ce filtre.", () =>
|
||||
{
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement.value="4";
|
||||
let data2Test= {
|
||||
|
@ -172,7 +172,7 @@ describe("Test des filtres de données", () =>
|
|||
|
||||
it("Doit toujours retourner true, si aucune valeur sélectionnée dans la liste.", () =>
|
||||
{
|
||||
selector.selector2HTML();
|
||||
selector.filter2HTML();
|
||||
let data2Test= {
|
||||
"Z (numéro atomique)" : "530",
|
||||
"Élément": "Yode",
|
||||
|
@ -186,8 +186,8 @@ describe("Test des filtres de données", () =>
|
|||
it("La manipulation d'un sélecteur doit appeler la fonction actualisant l'affichage, y compris pour supprimer ce filtre (0).", () =>
|
||||
{
|
||||
selector=new Selector(converter, 3, { id:"selector1" });
|
||||
selector.selector2HTML();
|
||||
converter.datasSelectors=[selector];
|
||||
selector.filter2HTML();
|
||||
converter.datasFilters=[selector];
|
||||
spyOn(converter, "refreshView");
|
||||
let selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement.value="4";
|
||||
|
|
Loading…
Reference in New Issue