Jasmine の matcher で遊んでいるので

最近仕事とは別に JavaScript のテストフレームワーク Jasmine で遊んでいます。
理解を深める目的で、日本語化しながらちまちまテスト書いてみている(丸コピーして日本語化して自分用に追記してる)ので、ちょっと公開してみたり。
bitbucketのプライベートリポジトリに他のやつのテストを書くついでに書いたので、そっちで公開できないからベタで張り付けちゃうという暴挙。

JasmineSpec.js


/**
* Jasmine のテストの書き方のテスト
*/
describe('Jasmine の機能テスト', function() {
var obj01 = null;

/**
* 全体用初期化
* どのitメソッド呼び出しの前にも呼ばれる
*/
beforeEach(function() {
obj01 = [1, 2, 3, 4, 5];
obj02 = [1, 2, 3, 4, 5, 6];
});

/**
* 全体用後片付け
*/
afterEach(function() {
obj01 = null;
// obj02 = null; // あえて初期化しない
});

/**
* describe 自体も入れ子にできる
* (全体が describe で囲まれているのを忘れないで)
*/
describe('describe 自体を入れ子にできる', function() {
it('block', function() {
expect(obj01.length).toEqual(5);
expect(obj02.length).toEqual(6);
});
});

/**
* describe はテスト結果のブロッキングをしてくれる
*/
describe('describe はテスト結果をブロッキングして表示してくれる', function() {
// it の第一引数のテキストが同じであっても影響はでない
it('block', function() {
// 自身のネスト内にEachがあればソレが使われる

// そのため、元の情報は失われる
expect(obj01.length).not.toEqual(5);

// 内部のEach(下を参照)で上書きしたから
expect(obj01.length).toEqual(4);

// 外のEachも呼ばれているので
expect(obj02.length).toEqual(6);
});

// describe 内では順序は関係がない
beforeEach(function() {
obj01 = [1, 2, 3, 4];
});
});

/**
* assert に相当するのはexpect メソッドと Matcher メソッド
*/
describe('Matcher紹介', function() {

describe('.toBe()は', function() {
it('===と同じ', function() {
// obj01 === obj01 当然同じもの
expect(obj01).toBe(obj01);
});
it('オブジェクトとして同じかどうか', function() {
// obj01 === obj02 コピーしたら同じもの
var obj02 = obj01;
expect(obj01).toBe(obj02);
});
it('中身が同じだけではだめ', function() {
// obj01 !== obj03 中身は同じでもオブジェクトが違う
var obj03 = [1, 2, 3, 4, 5];
expect(obj01).not.toBe(obj03);
// 中の値が同じであることは toEqual()で確認できる(後述)
expect(obj01).toEqual(obj03);
});
});


describe('.toEqual()は', function() {
it('===と同じ動きをする', function() {
expect(123).toEqual(123);
});
it('typeが違うとマッチしない。==とは違うということ', function() {
expect(123).not.toEqual('123');
});
it('中の値が同じなら異なるオブジェクトも同じとして扱う', function() {
obj01 = [1, 2, 3];
obj02 = [1, 2, 3];

// 中の値が同じなので
expect(obj01).toEqual(obj02);

// ちなみに toBeだと異なる(別のオブジェクトなので)
expect(obj01).not.toBe(obj02);
});
});


describe('.toMatch()は', function() {
var str;
beforeEach(function() {
str = 'This is test case';
});
it('正規表現でマッチ', function() {
expect(str).toMatch(/test/);
});
it('なので大文字小文字を区別する', function() {
// マッチしないから .not
expect(str).not.toMatch(/TEST/);
});
it('ただし演算子は使える', function() {
// i は大文字小文字を無視
expect(str).toMatch(/TEST/i);
});
it('日本語にもマッチする', function() {
str = 'これはテストケースです';
expect(str).toMatch(/テスト/);
});
});


describe('.toBeDefined()は', function() {
it('定義されていることを期待する', function() {
var a = {
foo: 'foo'
};
// 定義されているのでマッチ
expect(a.foo).toBeDefined();
// 定義されていないのでマッチ
expect(a.bar).not.toBeDefined();
});
it('var で宣言しなくても大丈夫', function() {
def = 'OK';
expect(def).toBeDefined();
});
it('そのタイミングで変数としてイキならOK', function() {
expect(obj01).toBeDefined();
// さて、このobj01の中身は?(やってみよう)
});
});

describe('.toBeUndefined()は', function() {
it('定義されていないことを期待する', function() {
var a = {
foo: 'foo'
};

expect(a.foo).not.toBeUndefined();
expect(a.bar).toBeUndefined();
expect(undefined).toBeUndefined();
});
it('変数のスコープに注意', function() {
// def はvarなしで呼ばれた(上のdescribe)
expect(def).not.toBeUndefined();
});
it('undefinedにした変数もundef', function() {
var def = undefined;
expect(def).toBeUndefined();
});
});

describe('.toBeNull()は', function() {
it('nullであることを期待する', function() {
expect(null).toBeNull();
});
it('nullが代入された変数', function() {
var a = null;
var foo = 'foo';

expect(a).toBeNull();
expect(foo).not.toBeNull();
});
it('何も代入していない変数はundefined', function() {
var a;
expect(a).not.toBeNull();
});
});

describe('.toBeTruthy()は', function() {
it('TRUEと判断される値(状態)であることを期待する', function() {
var a, foo = 'foo';

expect(foo).toBeTruthy();
expect(a).not.toBeTruthy();
});
it('例えば true', function() {
var a = true;
expect(a).toBeTruthy();
});
it('例えば 1', function() {
var a = 1;
expect(a).toBeTruthy();
});
});

describe('.toBeFalsy()は', function() {
it('FALSEと判断される値(状態)であることを期待する', function() {
var a, foo = 'foo';

expect(a).toBeFalsy(); // 値がないので
expect(foo).not.toBeFalsy();
});
it('例えば false', function() {
var a = false;
expect(a).toBeFalsy();
});
it('例えば NaN', function() {
var a = NaN;
expect(a).toBeFalsy();
});
it('例えば 0 (zero)', function() {
var a = 0;
expect(a).toBeFalsy();
});
it('例えば "" (空)', function() {
var a = '';
expect(a).toBeFalsy();
});
});

describe('.toContain()は', function() {
it('値が含まれていることを期待する', function() {
var a = ['foo', 'bar', 'baz'];

expect(a).toContain('bar');
expect(a).not.toContain('quux');
});
it('変数もうまく動く', function() {
var a1 = 'A1';
var a2 = 'A2';
var a3 = 'A3';
var a = [a1, a2, a3];

expect(a).toContain('A1');
expect(a).toContain(a2);
});
it('文字列もうまく動く', function() {
var a = 'abcdefg';

expect(a).toContain('a');
expect(a).not.toContain('z');
});
});

describe('.toBeLessThan()は', function() {
it('より小さいことを期待する', function() {
var pi = 3.1415926, e = 2.78;

expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
it('文字は文字コード順', function() {
var a = 'a', b = 'b';

expect(a).toBeLessThan(b);
expect(b).not.toBeLessThan(a);
});
});

describe('.toBeGreaterThan()は', function() {
it('より大きいことを期待する', function() {
var pi = 3.1415926, e = 2.78;

expect(pi).toBeGreaterThan(e);
expect(e).not.toBeGreaterThan(pi);
});
it('文字は文字コード順', function() {
var a = 'a', b = 'b';

expect(b).toBeGreaterThan(a);
expect(a).not.toBeGreaterThan(b);
});
it('真偽値を比較してみると', function() {
// true が大きい
expect(true).toBeGreaterThan(false);
expect(false).not.toBeGreaterThan(true);
});
});

describe('.toBeCloseTo()は', function() {
it('数学的に近い値であることを期待する', function() {
var pi = 3.1415926, e = 2.78;

expect(pi).not.toBeCloseTo(e, 0.1);
expect(pi).toBeCloseTo(e, 0);

var r2 = 1.41421356;
expect(r2).not.toBeCloseTo(1.5, 0);
expect(r2).toBeCloseTo(1.5, 0.1);
expect(r2).toBeCloseTo(1.5, 0.2);

var x = 1000.1;
expect(x).toBeCloseTo(1000, 0.1);
});
});

describe('.toThrow()は', function() {
it('exception が throw されることを期待する', function() {
var foo = function() {
return 1 + 2;
};
var bar = function() {
// a が宣言されていないのでエラーが発生する
return a + 1;
};

expect(foo).not.toThrow();
expect(bar).toThrow();
});
});
});

/**
* 処理しない
* 一時的に処理しないようにすることができる
*/
describe('処理しないこともできる', function() {
it('xdescribe と xit は処理されない', function() {
expect(123).toEqual(123);
});
xdescribe('このdescribeは処理されない', function() {
it('親が処理されないと入れ子の処理もされない', function() {
expect(123).toEqual(123);
});
});
describe('このdescribeは処理される', function() {
xit('が、ここは処理されない', function() {
expect(123).toEqual(123);
});
it('ここは処理される', function() {
expect(123).toEqual(123);
});
});
});

});

skipのxdescribeとxitまでやったら、次はスパイなんだけど、まだよく把握できてないので、とりあえずここまで。
.toBeCloseTo()がイマイチよくわかんない。

もっと使いこなせるようにじゃんじゃん写経せねば。というところ。