Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Karma で XHR で Binary File を読み込む Unit Test を書く / TypeScript による Alembic の読み込み 3

More than 5 years have passed since last update.

前回

Karma で XHR で Binary File 読み込む時の問題 / TypeScript による Alembic の読み込み 2

Karma Web-Server からの Binary File Read は危険.

XHR を利用して Karma に用意されている Web-Server から Binary File を arraybuffer を読み込むと、問題が起こる事が分かった. 実際にどういった事がおこるかは前回を参照.

さらに、前回は先頭の 1 byte が被害を受けている様に書いたが、最上位ビットが立っている全ての byte が被害にあう様だ. 状況からいって、何らかのエンコード処理を強制的に受けているっぽい. さすがにこれは場当たり的な対応では回避できないので、根本的な対応が必要になった.

XHR の宛先だけを変える.

Alembic の読み込み処理を作りたいので、Binary File を扱う部分は変えられない. 必然的に、XHR は必要になる. また、Unit Test も外せないし Karma+Jasmine+PhantomJS の組み合わせは、今実装している内容にはとても良い.

なので、現状の環境は維持しつつ、XHR に対して正しく返答してくれる先を用意する事にした. 具体的には、Karma とは別に XHR に返答してくれる Web-Server を事前にたてておき、Unit Test での XHR はそちらに送る事で、XHR で Binary File を受け取りつつ現状の Test 環境を維持できると考えた.

XHR の宛先を立てる.

現状、gulp を用いた build 環境を構築しているので、gulp で使える用途にあった module を探した. いくつか選択肢があったが、人気が高そうだった gulp-connect を使う事にした.
https://www.npmjs.com/package/gulp-connect

gulp-connect は、gulp API のコンセプトとあっていないという事から deprecated になっている様だ. 現在は gulp API にあわせて書き直された gulp-webserver というのもあるらしい.
https://www.npmjs.com/package/gulp-webserver

ただ、そもそも karma が gulp API にそっていないし、karma の現状の呼び出し方から考えると明示的に Server を止められた方が良いと思うため、今回は gulp-connect を利用している.

また、XHR に返答して貰わないといけないので、CORS (Cross-origin resource sharing) に対応している必要がある. 下記の module を利用する事で、gulp-connect でたてた Web-Server を CORS に対応させる事ができる.
https://www.npmjs.com/package/cors

gulp task を作る.

もともと、karma を起動している直前で、gulp-connect を利用して Unit Test で利用したい Binary File を管理する Web-Server をたて、全ての Test が終了したら Web-Server を落とす、という task を用意したい. 下記の様に task を書く事で実現できた.

gulp.task('test', ['compile-spec-typescript'], function(done) {
    connect.server({
        root: 'spec',
        port: 8000,
        middleware: function() {
            return [cors()];
        }
    });

    karma.server.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, function(exitCode) {
        connect.serverClose();
        done();
    })
})

それぞれの module のおかげで、とても簡潔にかける. すばらしい !!

ちなみに、karma の呼び出し方が現在は非推奨な形にしているのはわざと. 推奨されている書き方だと、Test に失敗した場合に例外が発生して、それ以降の Test が何故かキャンセルされてしまう. 非推奨の形だと、ちゃんと Test 自体は継続してくれるので、こうしている….

Unit Test から XHR を送る.

http://localhost:8000 として XHR を受け取る Web-Server をたてたので、宛先をそれに合わせて書き換える. 下記の様に書く事で問題なく動作した.

describe('File read test using XMLHttpRequest', function() {
    var request = new XMLHttpRequest();

    beforeAll(function (done) {
        request.open('GET', 'http://localhost:8000/assets/test.bin', true);

        request.responseType = 'arraybuffer';
        request.addEventListener('loadend', function () {
            done();
        });

        request.send();
    })

    it('Read binary files?', function() {
        expect(request.status).toBe(200);
        expect(request.response).toEqual(jasmine.any(ArrayBuffer));

        var buffer = <ArrayBuffer>request.response;
        expect(buffer.byteLength).toBe(8);
    })
})

現在、jasmine 2.0 を利用しているので beforeAll で XHR を発行して同期をとっているが、jasmine 1.0 の場合は runs/waitFor を使って発行する事になると思う.

上記では Test していないが、もちろん内容も正しく帰ってくるようになり、アドホックな対応も書く必要がなくなった.

という訳で

つづく…

次回こそ Alembic の中身に…. っていうか、HDF5 って凄くめんどくさい. Ogawa に完全以降してから始めれば良かったかも….

wokia
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away