🦀

Rust 🦀 と Wasm のチュートリアル(テスト編)

2023/01/22に公開

本記事は、筆者がRustとWasmを学ぶために以下のドキュメントを読み進めた過程を記すものです。今回はWebAssembly関数のテストの章を進めていきます。
https://rustwasm.github.io/docs/book/game-of-life/testing.html

ライフゲームが正しく機能しているかのテストを行います。ただ、セルの宇宙が大きすぎるとテストがしにくいので、宇宙のサイズをJavaScript側から変更できるようにします。

ドキュメントのソースコードでは、セルを定義したCell構造体で扱っていますが、私はエクササイズの問題でセルを1bitで表現できるように変更しているので、それに合わせて書き換える必要があります。

pug fn reset_cells(&mut self){
    let size = (width * self.height) as usize;
	self.cells = FixedBitSet::with_capacity(size);
	for i in 0..size { 
		self.cells.set(i, false);
	}
}

pub fn set_width(&mut self, width: u32){
	self.widht = width;
	self.reset_cells();
}
pub fn set_height(&mut self, height: u32){
	self.height = height;
	self.reset_cells();
}

JavaScript側に公開したくない関数は、#[wasm_bindgen]アトリビュートのないimpl Universeに実装します。

impl Universe {

    pub fn get_cells(&self) -> &FixedBitSet {
        &self.cells
    }

    pub fn set_cells(&mut self, cells: &[(u32, u32)]) {
        for (row, col) in cells.iter().cloned() {
            let idx = self.get_index(row, col);
            self.cells.set(idx, true);
        }
    }
}

プロジェクトルートフォルダのtests/web.rsの中にテストコードがあります。
以下のコードを実行するとテストが行えます。

wasm-pack test --firefox --headless

wasm_game_of_lifeをテストできるように書き加えていきます。

extern crate wasm_game_of_life;
use wasm_game_of_life::Universe;

今回のテストは、宇宙船のテストです。初期の宇宙船から一つ時間を進めた宇宙船の形が正しいかどうかをテストします。

pub fn input_spaceship() -> Universe {
    let mut universe = Universe::new();
    universe.set_width(6);
    universe.set_height(6);
    universe.set_cells(&[(1,2), (2,3), (3,1), (3,2), (3,3)]);
    universe
}

#[cfg(test)]
pub fn expected_spaceship() -> Universe {
    let mut universe = Universe::new();
    universe.set_width(6);
    universe.set_height(6);
    universe.set_cells(&[(2,1), (2,3), (3,2), (3,3), (4,2)]);
    universe
}


pub fn test_tick() {

    let mut input_uv = input_spaceship();
    let expected_uv = expected_spaceship();

    input_uv.tick();
    assert_eq!(&input_uv.get_cells(),&expected_uv.get_cells());
}

テストコマンドを実行してみます。

`wasm-pack test --firefox --headless`.

テストをパスしてくれました。

running 1 test 
test web::test_tick ... ok
test result: ok. 1 passed; 0 failed; 0 ignored

Discussion