🚧 Attention, peinture fraîche !

Cette page a été traduite par une seule personne et n'a pas été relue et vérifiée par quelqu'un d'autre ! Les informations peuvent par exemple être erronées, être formulées maladroitement, ou contenir d'autres types de fautes.

Tester le jeu de la vie de Conway

Maintenant que nous avons notre implémentation en Rust du jeu de la vie qui s'exécute dans le navigateur web avec JavaScript, nous pouvons voir comment tester nos fonctions WebAssembly générées par Rust.

Nous allons tester notre fonction tick pour s'assurer qu'elle nous donne bien le résultat que nous souhaitons.

Ensuite, nous allons créer des mutateurs et des accesseurs dans notre bloc impl Univers dans le ficher wasm-jeu-de-la-vie/src/lib.rs. Nous allons créer une fonction set_largeur et set_hauteur pour que nous puissions créer des Univers de différentes tailles.


#![allow(unused)]
fn main() {
#[wasm_bindgen]
impl Univers {
    // ...

    /// Définit la largeur de l'univers.
    ///
    /// Cela va tuer toutes les cellules.
    pub fn set_largeur(&mut self, largeur: u32) {
        self.largeur = largeur;
        self.cellules = (0..largeur * self.hauteur).map(|_i| Cellule::Morte).collect();
    }

    /// Définit la hauteur de l'univers.
    ///
    /// Cela va tuer toutes les cellules.
    pub fn set_hauteur(&mut self, hauteur: u32) {
        self.hauteur = hauteur;
        self.cellules = (0..self.largeur * hauteur).map(|_i| Cellule::Morte).collect();
    }

}
}

Nous allons créer un autre bloc impl Univers dans notre fichier wasm-jeu-de-la-vie sans l'attribut #[wasm_bindgen]. Il y a quelques fonctions que nous avons besoin pour tester que nous ne souhaitons pas exposer au JavaScript. Les fonctions WebAssembly générées par Rust ne peut pas retourner des références empruntées. Essayez de compiler le WebAssembly généré par Rust avec l'attribut et constatez les erreurs que vous obtenez.

Nous allons écrire l'implémentation de get_cellules pour obtenir le contenu de cellules d'un Univers. Nous allons aussi écrire une fonction set_cellules pour que nous puissions donner vie à des cellules d'un Univers.


#![allow(unused)]
fn main() {
impl Univers {
    /// Donne toutes les cellules mortes et vivantes de l'univers.
    pub fn get_cellules(&self) -> &[Cellule] {
        &self.cellules
    }

    /// Définit les cellules vivantes de l'univers en lui fournissant la ligne
    /// et la colonne de chacune des cellules dans un tableau.
    pub fn set_cellules(&mut self, cellules: &[(u32, u32)]) {
        for (ligne, colonne) in cellules.iter().cloned() {
            let indice = self.get_index(ligne, colonne);
            self.cellules[indice] = Cellule::Vivante;
        }
    }

}
}

Maintenant nous pouvons créer notre test dans le fichier wasm-jeu-de-la-vie/tests/web.rs.

Avant de nous lancer, nous constatons qu'il existe déjà un test qui fonctionne dans ce fichier. Vous pouvez confirmer que le test du WebAssembly généré par Rust fonctionne en exécutant wasm-pack test --chrome --headless dans le dossier wasm-jeu-de-la-vie. Vous pouvez utiliser les options --firefox, --safari, et --node pour tester votre code dans ces navigateurs.

Dans le fichier wasm-jeu-de-la-vie/tests/web.rs, nous devons importer notre crate wasm_jeu_de_la_vie et le type Univers.


#![allow(unused)]
fn main() {
extern crate wasm_jeu_de_la_vie; // (facultatif en Rust 2018)
use wasm_jeu_de_la_vie::Univers;
}

Dans le fichier wasm-jeu-de-la-vie/tests/web.rs, nous allons ajouter quelques fonctions qui créent des créateurs de vaisseaux spatiaux.

Nous allons en ajouter une pour créer notre vaisseau spatial initial lorsque nous appellerons la fonction tick et nous voulons qu'il soit toujours là après une tick. Nous avons choisi les cellules que nous voulons donner vie pour créer notre vaisseau spatial dans la fonction vaisseau_spatial_initial. La position du vaisseau spatial dans la fonction vaisseau_spatial_attendu dans la tick suivant vaisseau_spatial_initial a été calculée manuellement. Vous pouvez vérifier par vous-même que les cellules du vaisseau spatial initial sont les mêmes que celles attendues après une tick.


#![allow(unused)]
fn main() {
#[cfg(test)]
pub fn vaisseau_spatial_initial() -> Univers {
    let mut univers = Univers::new();
    univers.set_largeur(6);
    univers.set_hauteur(6);
    univers.set_cellules(&[(1,2), (2,3), (3,1), (3,2), (3,3)]);
    univers
}

#[cfg(test)]
pub fn vaisseau_spatial_attendu() -> Univers {
    let mut univers = Univers::new();
    univers.set_largeur(6);
    univers.set_hauteur(6);
    univers.set_cellules(&[(2,1), (2,3), (3,2), (3,3), (4,2)]);
    univers
}
}

Maintenant nous allons écrire l'implémentation de notre fonction test_tick. Pour commencer, nous allons créer une instance de notre vaisseau_spatial_initial() et de notre vaisseau_spatial_attendu(). Ensuite, nous appellerons tick sur univers_initial. Enfin, nous utiliserons la macro assert_eq! pour faire appel à get_cellules() pour s'assurer que univers_initial et univers_attendu ont la même valeur pour leur tableau de Cellules. Nous avons ajouté l'attribut #[wasm_bindgen_test] à notre bloc de code pour que nous puissions tester notre code WebAssembly généré par Rust et utiliser wasm-pack test pour tester le code WebAssembly.


#![allow(unused)]
fn main() {
#[wasm_bindgen_test]
pub fn test_tick() {
    // On crée un petit univers avec un petit vaisseau spatial, pour tester !
    let mut univers_initial = vaisseau_spatial_initial();

    // C'est ce à quoi doit ressembler notre vaisseau spatial après une tick
    // dans notre univers.
    let univers_attendu = vaisseau_spatial_attendu();

    // Appelons `tick` et voyons ensuite si les cellules dans les `Univers` sont
    // les mêmes.
    univers_initial.tick();
    assert_eq!(&univers_initial.get_cells(), &univers_attendu.get_cells());
}
}

Exécutez les tests dans le dossier wasm-jeu-de-la-vie en exécutant wasm-pack test --firefox --headless.