2021-10-28 17:50:57 +02:00
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." , ( ) = >
{
2022-02-21 11:49:27 +01:00
expect ( ( ) = > { return mySearch = new SearchEngine ( converter , { id : "mySearch" } , [ 0 , 2 , 3 ] ) ; } ) . not . toThrowError ( ) ;
2021-10-28 17:50:57 +02:00
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é." , ( ) = >
{
2022-02-21 11:49:27 +01:00
expect ( ( ) = > { return mySearch = new SearchEngine ( converter , { id : "mySearch" } , [ ] ) ; } ) . not . toThrowError ( ) ;
2021-10-28 17:50:57 +02:00
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 ) ;
} ) ;
2022-02-21 11:49:27 +01:00
2021-10-28 17:50:57 +02:00
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 ) ;
2022-02-21 11:49:27 +01:00
// Les espaces entourant la valeur saisie doivent être ignorés dans le décompte des caractères :
searchInput . value = " zz" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( converter . refreshView ) . toHaveBeenCalledTimes ( 2 ) ;
searchInput . value = "zz " ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( converter . refreshView ) . toHaveBeenCalledTimes ( 2 ) ;
searchInput . value = " zz " ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( converter . refreshView ) . toHaveBeenCalledTimes ( 2 ) ;
2021-10-28 17:50:57 +02:00
} ) ;
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 ( ) ;
2022-02-21 11:49:27 +01:00
// Y compris si il y a seulement des espaces :
searchInput . value = " " ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "nom" : "oui" } ) ) . toBeTrue ( ) ;
2021-10-28 17:50:57 +02:00
} ) ;
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 ( ) = >
{
2022-02-21 15:51:53 +01:00
searchInput . value = "Hallogène" ;
2021-10-28 17:50:57 +02:00
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
2022-02-21 15:51:53 +01:00
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeFalse ( ) ;
2021-10-28 17:50:57 +02:00
} ) ;
2022-02-21 11:49:27 +01:00
it ( "Doit retourner true, si la valeur recherchée est trouvée dans la donnée recherchée, sans prendre en compte la casse, ni les espaces entourant la saisie." , ( ) = >
2021-10-28 17:50:57 +02:00
{
// 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 ( ) ;
2022-02-21 11:49:27 +01:00
// Espace entourant la saisie ignorés :
searchInput . value = " halo " ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeTrue ( ) ;
2022-02-21 15:51:53 +01:00
// Par défaut, la recherche doit être tolérante à la casse, à la présence ou non d'accent et ignorer les caractères n'étant ni des lettres, ni des chiffres
searchInput . value = "Halogene" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeTrue ( ) ;
searchInput . value = "halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeTrue ( ) ;
searchInput . value = "#Halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeTrue ( ) ;
2021-10-28 17:50:57 +02:00
} ) ;
2022-02-21 15:51:53 +01:00
it ( "Si demandé doit traiter les données avant de les comparer de manière à prendre en compte les accents, majuscules ou caractères spéciaux." , ( ) = >
{
// Sensible à casse :
mySearch . searchMode . caseOff = false ;
searchInput . value = "halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeFalse ( ) ;
searchInput . value = "Halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "halogène" } ) ) . toBeFalse ( ) ;
// Sensible aux accents :
mySearch . searchMode . accentOff = false ;
searchInput . value = "Halogene" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeFalse ( ) ;
searchInput . value = "Halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogene" } ) ) . toBeFalse ( ) ;
// Prise en compte des caractères spéciaux :
mySearch . searchMode . specialCharsOff = false ;
searchInput . value = "Halogène^" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeFalse ( ) ;
searchInput . value = "Halogène" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Ha+logène" } ) ) . toBeFalse ( ) ;
// Ignore les caractères spéciaux, sauf ceux en liste blanche :
mySearch . searchMode . specialCharsOff = true ;
mySearch . searchMode . specialCharsWhiteList = "^+" ;
expect ( mySearch . dataIsOk ( { "Famille" : "Ha+logène" } ) ) . toBeFalse ( ) ;
searchInput . value = "Halogène^" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "Halogène" } ) ) . toBeFalse ( ) ;
} ) ;
2022-02-21 16:56:19 +01:00
it ( "Si demandé doit cherché l'expression en entier et non chacun des mots séparément." , async ( ) = >
{
// Cas normal, ok si tous les mots sont trouvés séparément :
searchInput . value = "gaz noble" ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "le gaz est noble" } ) ) . toBeTrue ( ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "noble est le gaz" } ) ) . toBeTrue ( ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "gaz" , "Symbole" : "noble" } ) ) . toBeTrue ( ) ;
// Il faut trouvé au moins une fois l'expression entière dans un des champs :
mySearch . searchMode . separatedWords = false ;
searchInput . dispatchEvent ( new Event ( "input" ) ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "gaz noble" } ) ) . toBeTrue ( ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "gaz noble" , "Symbole" : "He" } ) ) . toBeTrue ( ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "le gaz est noble" } ) ) . toBeFalse ( ) ;
expect ( mySearch . dataIsOk ( { "Famille" : "gaz" , "Symbole" : "noble" } ) ) . toBeFalse ( ) ;
} ) ;
2022-02-21 15:51:53 +01:00
2021-10-28 17:50:57 +02:00
} ) ;
} ) ;
} ) ;