閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

Fluent Assertionsのソースを少し読んでみた

先日のエントリに書いた例ですが、

Add(1, 2).Should().Be(3);
// => Expected Add(1, 2) to be 3, but found 2.

これ、 Add(1, 2) の部分どうやって取ってるんだろう、と思ってソース読んでみました。StackTraceでそこまで取れるのかなぁと思ったんですが、テストコードの実装(*.cs)を直接見ていたみたいです。

CallerIdentifierクラスのDetermineCallerIdentityメソッドが目的のメソッドですが、ここでStackTraceクラスを使ってソースファイルのパス、行番号を取ってきてそれを元にソースファイルからコードを読み込んでいるようです。

確かに手元にソースがある状態でなら、あらゆる情報が取れますね…。

別解として、PowerAssert.Netだとアサーションにラムダを渡すことでLambdaExpressionから処理内容を取り出しているものがありました。

using PowerAssert;

int Add(int x, int y) => 2;

[Test]
public void Test()
{
    PAssert.IsTrue(() => Add(1, 2) == 3);
}

実行結果:

System.Exception : IsTrue failed, expression was:

PowerAssertTests.ParserTest.Add(1, 2) == 3
                                . .     __
                                \ /     |
                                 |      False
                                 2

こちらはテストメソッドがIsTrueだけで覚える事が少なくてシンプルです(Throwsは割愛)。思想の差が面白いですね。

再度、はてなブログの記法をはてな記法からMarkdownにしてみる

最近VSCodeでブログの下書きを書いているけど、これだと当然はてな記法よりMarkdownの方が書きやすいな。VSCode上で色も付くしプレビューもできる。

…もう静的サイトでいいんじゃないの、という気もするけど。

あるいはAPIあるのからブラウザでコピペせず、ここ(VSCode)から直に上げられるようにすればいいのかなぁ。

2000年代はnDiary使ってて、xyzzynDiary-modeで日記書いてHTML生成、FTPでアップまでを全部xyzzy上でやっていたけどあの頃が一番効率が良かった気がする。2020年らしく楽をしていかねばな……。

FluentAssersions

Fluent Assertions

一時流行った(?)流れるメソッド的なアレでテストが書けるライブラリ。もしくはSpec的なやつ。最近のNUnitもこれに近い記法になるけど、冗長じゃないかな? と思っていたけどテストコードより、その結果が重要という感じみたい。失敗した時、なぜ失敗したのかがすぐわかるようでなければ不便でしょ、と。確かに。

using FluentAssertions;
using Xunit;

static int Add(int x, int y) => 2;

[Fact]
public void Test1()
{
    Assert.Equal(3, Add(1, 2));
}

[Fact]
public void Test2()
{
    Add(1, 2).Should().Be(3);
}

あからさまに雑な例ですが、このようなテストを実行したときの結果が以下のようになります。

メッセージ
xUnit.net Assert.Equal() Failure
Expected: 3
Actual: 2
Fluent Assersions Expected Add(1, 2) to be 3, but found 2.

なるほどリッチ。実行速度は50倍くらい遅くなりますが、許容範囲内ですかね?

AssersionScope

AssersionScopeというクラスがあり、普通アサーションに失敗するとそこでテストは終わりますが、このスコープ内にあるうちは続けてテストを行うみたいな機能もあるようです。1つのテストにアサーションを何個も書くなという話ではありますが、これはこれであると嬉しいシーンもあるかも。

using FluentAssertions;
using FluentAssertions.Execution;
using Xunit;

[Fact]
public void Test3()
{
    using var scope = new AssertionScope();

    3.Should().BeLessThan(2);                    // ↑scopeがなければここで終了するが
    (new int[] { 1, 2, 3 }).Should().Contain(0); // ←scopeがあるのでこれも実行される
}

// 実行結果
//   メッセージ: 
//    Expected value to be less than 2, but found 3.
//    Expected collection {1, 2, 3} to contain 0.

10連休だった

あっという間に終わってしまった。睡眠と通院の合間に娯楽フィードに耽溺するだけの週末。

"耽溺"という言葉はこの本に頻出する単語で、なかなか真似したくなりますね。マーダーボットを自称する警備ユニット(ロボット)の日記で、楽しく読みました。ロボットなのにコミュ障で、一人称視点の話だけどそのコミュ障っぷりが大いに共感できてよかった。人の顔が見られない、見られるのはいや、鏡も嫌い、などなど。あらゆるものがネットに繋がった社会で電子戦も多め。

最近AIに萌えるっぽい。なんなら人間がいないAI同士の掛け合いだけでも楽しめる。まぁ、「そういう設定」のただの掛け合いなんですけど、設定がおいしいのです。

あと、そろそろ少しWebGLも触っておこうかなと思ったけど、例によって教科書読んだり下から追おうとするとモチベーションが続かないのでthree.jsを軽く触って遊んでいました。OpenGLとかの経験があれば、割と似たノリでやっていけそうな感じ。お手軽で面白いです。

古のglu/glut系の関数は大体標準もしくはサンプル漁れば出てくる感じ。ティーポットもあるよ(OpenGLは10年くらい前に触っていたので幼少期の記憶並に薄く、古いのだ…)。

ただ結構破壊的変更が多いみたいでソース検索して貼り付けるとクラスがなかったりdeprecatedだとログに出てきたりすることが結構ありました。後者はログに移行先も出てくるのでそれほど困りませんでしたが。今年はこれも飯の種になるといいなぁ。

ギガを使わない生活

これは11月の話で、12月は連休もありさらに節約して0.96GBに抑えることができました。基本電車内でTwitterせずにダウンロード済みの本を読むようにすればそれほど通信せずに済むのですが、しかしたかが1000円のために禁欲するのもなぁ……という気もします。もう少し細かい刻みで金額が変わるといいんですけどね。

ネットは固定回線含めて、従量制になっていくのかと思っていたら5G以後は定額が普通になっていくみたいな話を見てちょっと意外に感じていますが、ヘビーユーザにひとりあたりの通信量がかさ上げされて設定される定額料金が高めになるとそれはそれでキツいかなぁという気も。まぁ、ユーザ的には定額ないし天井がある方が安心はできるんですが。

TypeScriptの"String Literal Types"や"Index types"が面白い

window.addEventListener('mousemove', e => {
    // ここで、eの型はMouseEvent型になる
});
window.addEventListener('keydown', e => {
    // ここで、eの型はKeyboardEvent型になる
});

みたいな感じでメソッドの引数の値に応じて、コールバック関数に渡される型を変えられたりする。

上記の例はIndex typesというのを使っているみたいだけど、初めて見る仕組みでちょっと感動しました。型を明示的に書けば同じ効果は得られるんですが、短くなるしこれでインテリセンスも効くのでかなり楽ができます。

文字列が未対応のものであればエラー扱いにもできるみたいでいいですね。

今年買ってよかったもの・十三機兵防衛圏

特に思いつかないなぁと思ったけど、ひとつあった。十三機兵防衛圏、PS4のゲームだけど、これは今年一番のゲームです。SF好きな人は買いましょう。

十三機兵防衛圏 - PS4

十三機兵防衛圏 - PS4

  • 作者:
  • 出版社/メーカー: アトラス
  • 発売日: 2019/11/28
  • メディア: Video Game

SF要素てんこ盛りのアドベンチャー+タワーディフェンスのゲーム。ゲームをはじめるといきなり崩壊編と呼ばれるタワーディフェンスと同時に物語が始まる。チュートリアルステージをいくつかクリアすると追想編と呼ばれるアドベンチャーパートが遊べるようになり、そこで崩壊編の操作キャラクターの回想が見られる。この時点ではプレイヤーにはほとんど情報が開示されておらず、また操作キャラもほどんと情報を持っていない状態ではじまり(お約束?の記憶喪失のキャラもいる)、主人公達と同じ目線で物語の謎を追っていくことになるんだけど、これがめちゃくちゃ面白い。

崩壊編の名の通りいきなり世界の危機から始まるけど、なぜ"それ"が起こったのか。13人(!)もいる主人公の過去、関係が各々の視点で徐々に開示されていくのだけど、この情報の出し方がうまくて、すぐに引き込まれて続きが気になって仕方無い。途中で「ああ、そういうアレか」と納得したと思ったらひっくり返されるみたいなことも多く、またAの視点で見えた伏線とBの現状が噛み合って無くないか?みたいな謎もプレイすると出てきて、辞め時がなくなります。

タワーディフェンスパートも爽快感あって、またノーマルだとほどよい難易度という感じでこちらも楽しかったです。プレイ時間は45時間くらい、後半は一気にプレイしてクリアしましたが、気持ちよく終われてたいへんよいゲームでした。ザッピングはないけど「街 〜運命の交差点〜」なんかを連想しました。群像劇で視点だけでなく時系列も飛びまくるので作るのは本当に大変だったろうな…と思います。追うのも少し大変かもしれませんが、それに見合う快感は得られるし、その複雑なところを究明編など見て追いかけるのもまた楽しいので、ぜひ。