miso_soup3 Blog

主に ASP.NET 関連について書いています。

Jasmine は async/await と done() による callback の混合をサポートしない

Jasmine (version 3.8 で確認)では、以下のコードような、async(async/await の async)と done() による callback を混合した書き方はサポートしなくなったようです。

it("test", async (done) => {
    await somethingPromise(1000);
    done();
});

実際にこのテストを実行すると、成功扱いになりますが、以下のように警告が出力されます。

DEPRECATION: An asynchronous before/it/after function was defined with the async keyword but also took a done callback. This is not supported and will stop working in the future. Either remove the done callback (recommended) or remove the async keyword. (in spec: test test)

GitHub にて、該当のコミット者によるコメントがありました。

Jasmine doesn't support mixing callback-style and async/await in a single function.

Expectation when using both done and async functions? · Issue #1731 · jasmine/jasmine · GitHub

※サンプルのコードでは、async と done() を混合しなければいけない理由が不明かと思いますが、良いサンプルが思いつけませんでした。

なぜか

上記の GitHub のコメントを参考に、なぜこうなったのかは以下のように理解しました。

Jasmine は、2.7 から async/await をサポートしています。

async/await is supported by Jasmine 2.7 and later.

Asynchronous work

それまでは done() によって非同期のテストが書かれており、必然的に done() が実行されたかどうかでテストの完了を判断していたと思われます。

しかし、async/await をサポートすることによって、it("test", async (done) => {} のようなテストコードの場合、Promise の完了をもってテスト完了と判断するのか、done() の実行をもってテスト完了と判断するのか、コードの読み手は混乱することになると思います。仮に挙動を定めたとしても Jasmine はそれを信頼すべき挙動とは断言したくなかったのでしょうか? そのために、混合をサポートせず冒頭のような警告が出力されるようになったのかと思います。

どうすればよいか

混合を避けて、done() だけで書くか、async/await だけで書くか、どちらかにコードを変更します。このコードは、こちら Continued support for async tests with done callbacks · Issue #1893 · jasmine/jasmine · GitHub を参考にしました。

done() だけを使う場合:

it("test2", (done) => {
    (async () => {
        await somethingPromise(1000);
        await somethingPromise(1000);
        done();
    })();
});

async/await だけを使う場合:

it("test3", async () => {
    await somethingPromise(1000);
    await somethingPromise(1000);
    await expectAsync(somethingPromise(1000)).toBeResolved();
    await expectAsync(somethingErrorPromise(1000)).toBeRejected();
});

このとき、toBeRejectedWith() toBeRejectedWithError() などのメソッドも役に立ちそうです。

今回のコード: Jasmine tests · GitHub

行によって列の意味が異なる CSV のための Viewer(VSCode Extension)

行によって列の意味が異なる CSV の閲覧と編集を補助する VSCode Extension を作成しました。

marketplace.visualstudio.com

使い方: miso.csv-map-viewer-vscode-ext/README.ja.md at main · hhyyg/miso.csv-map-viewer-vscode-ext · GitHub

"行によって列の意味が異なる CSV" とは、例えば以下のように、先頭の列の値によって列の意味が異なる CSV のことです。行によって列の数が異なる特徴があります。

JAHISTC03,2
1,山田太郎,2,20150325,,,,,,,ヤマダタロウ
3,FCユビキャップ(3ホン),,,1
3,FCボウスイワンタッチパッド S 6マイ,,,1
5,20181101,1
11,〇〇薬局,,4,,123-4567,東京都,012345678,1
51,皮フ科,,,,1
55,医師名,皮膚科,1
201,1,オロパタジン塩酸塩錠5mg「JG」,2,錠,4,4490025F2062,1
301,1,1日2回 朝夕食後服用,14,日分,1,1,,1
201,2,アンテベートクリーム0.05%,30,g,4,2646730N1054,1
201,2,ヘパリン類似物質油性クリーム0.3%「日医工」,50,g,4,3339950M1188,1
301,2,かゆい所に塗布,1,調剤,5,1,,1
311,2,1日2回 躯幹,1
311,2,混合,1

これはお薬手帳のデータですが*1 、このような CSVを閲覧や編集するとき、列の数を 1, 2, 3.... と数えて仕様書と見比べたり、値を編集するのが手間です。なので、列の意味を表示してくれる VSCode Extension を作成しました。

左下にカーソル位置の列の意味が表示されています↓

f:id:miso_soup3:20210430222459g:plain

また、コマンドから全体の情報を出力できます↓

f:id:miso_soup3:20210430222735p:plain

拡張機能を使う時は、あらかじめ CSV の仕様を JSON で定義する必要があります。今回のお薬手帳の例は、このように定義しました(一部のみ): https://gist.github.com/hhyyg/eec04d51b9c2dc940b45dc3c34f0021d

*1:例の CSVお薬手帳のデータで、仕様はこちらにて公開されています:JAHIS電子版お薬手帳データフォーマット仕様書Ver.2.3 | 一般社団法人保健医療福祉情報システム工業会 自分はアプリでお薬手帳を管理しており、アプリのエクスポート機能から CSV ファイルを入手しました。また、自分の個人情報を公開したくないため一部情報を変更しています