AtomのSpecをjasmine2で動かす


いまだにAtomは、Specにjasmine1.3と使っています。
jasmineを覚えようと思いましたが、古い仕様を覚える気にはならないので最新バージョンを使える方法を調べました。
この記事では、CoffeeScriptを使わずにJavaScriptを使います。

カスタムテストランナーとしてatom-jasmine2-test-runnerを登録

現状、jasmine2を動かすには、カスタムテストランナーとしてjasmine2を動かせるランナーを作って渡してやる必要があるようです。
自作のランナーを作成するのは大変なので既存のランナーを使います。
npmパッケージにatom-jasmine2-test-runnerがありますのでそれを使います。

一番簡単な使い方は、package.jsonに以下を記述することです。

package.json
{
  "name": "my-package",
  // ...
  "atomTestRunner": "atom-jasmine2-test-runner",
  "devDependencies": {
    "atom-jasmine2-test-runner": "^1.1.2"
  }
}

package.jsonを上記のように更新したら、一度Atomを終了して再度Dev modeで開きなおしてください。
一度終了させるのは、atom-jasmine2-test-runnerのドキュメントにもあるようにpackage.jsonの内容がキャッシュされていて反映されない場合があるからです。
また、Dev modeで開くのは"devDependencies"を更新するためです。

Dev modeで開きなおしたらCommand PaletteからUpdate Package Dependencies: Updateを実行し、外部依存関係を更新します。
これでjasmine2が動くようになります。

動作テスト

動作テストとして、specフォルダに以下のようなファイルを作ってやります。
(jasmineのintroduction.jsから取ってきましたが、ちょっと実行時間が長いです)
作成したらCommand PaletteからWindow: Run Package Specsを実行することでSpecが動きます。
正常に終了したらjasmine2が動いています。

spec/my-package-spec.js
describe("Asynchronous specs", function() {
  var value;

  beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
  });

  it("should support async execution of test preparation and expectations", function(done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });

  describe("long asynchronous specs", function() {
    beforeEach(function(done) {
      done();
    }, 1000);

    it("takes a long time", function(done) {
      setTimeout(function() {
        done();
      }, 9000);
    }, 10000);

    afterEach(function(done) {
      done();
    }, 1000);
  });

  describe("A spec using done.fail", function() {
    var foo = function(x, callBack1, callBack2) {
      if (x) {
        setTimeout(callBack1, 0);
      } else {
        setTimeout(callBack2, 0);
      }
    };

    it("should not call the second callBack", function(done) {
      foo(true,
        done,
        function() {
          done.fail("Second callback has been called");
        }
      );
    });
  });
});

パッケージをアクティベートする

参考: How do I activate a package in specs?

no activateCommands

アクティベートコマンドが登録されていない場合は、以下のようになります。

describe("package activation", () => {
  beforeEach((done) => {
    atom.package.activatePackage("package-name").then(done);
  });
  it("do some tests", () => {
    expect(true).toEqual(true);
  });
});

have activateCommands

登録されている場合は、以下のようになります。
ここでは、package-name:toggleでアクティベートされるとします。

describe("package activation", () => {
  beforeEach((done) => {
    let workspaceElement = atom.views.getView(atom.workspace);
    let activationPromise = atom.packages.activatePackage("package-name");
    atom.commands.dispatch(workspaceElement, "package-name:toggle");
    activationPromise.then(done);
  });

  it("do some tests", () => {
    expect(true).toEqual(true);
  });
});