契約プログラミング

unittestブロックは、main()に既に記述されているチェックをコピーするだけで簡単に実装できる。以下の追加部分は、2番目のチームが勝った場合のテストのみだ。

int addPoints(int goals1, int goals2,
              ref int points1, ref int points2)
in {
    assert(goals1 >= 0);
    assert(goals2 >= 0);
    assert(points1 >= 0);
    assert(points2 >= 0);

} out (result) {
    assert((result >= 0) && (result <= 2));

} do {
    int winner;

    if (goals1 > goals2) {
        points1 += 3;
        winner = 1;

    } else if (goals1 < goals2) {
        points2 += 3;
        winner = 2;

    } else {
        ++points1;
        ++points2;
        winner = 0;
    }

    return winner;
}

unittest {
    int points1 = 10;
    int points2 = 7;
    int winner;

    // 1番目のチームが勝利
    winner = addPoints(3, 1, points1, points2);
    assert(points1 == 13);
    assert(points2 == 7);
    assert(winner == 1);

    // 引き分け
    winner = addPoints(2, 2, points1, points2);
    assert(points1 == 14);
    assert(points2 == 8);
    assert(winner == 0);

    // 2番目のチームが勝利
    winner = addPoints(0, 1, points1, points2);
    assert(points1 == 14);
    assert(points2 == 11);
    assert(winner == 2);
}

void main() {
    // ...
}
D
contracts.solution.1

この関数には、式ベースの契約が役立つ。

int addPoints(int goals1, int goals2,
              ref int points1, ref int points2)
in (goals1 >= 0)
in (goals2 >= 0)
in (points1 >= 0)
in (points2 >= 0)
out (result; (result >= 0) && (result <= 2)) {
    // ...
}
D