| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 | var assert = require('assert');var hpack = require('../');var fixtures = require('./fixtures');describe('hpack/decompressor', function() {  var decomp;  beforeEach(function() {    decomp = hpack.decompressor.create({      table: {        maxSize: 1024      }    });  });  describe('indexed field', function() {    it('should fail on 0-index', function(cb) {      decomp.write(new Buffer([ 0b10000000 ]));      decomp.execute(function(err) {        assert(/zero index/i.test(err.message), err.message);        cb();      });    });    it('should fetch entry from static table', function() {      decomp.write(new Buffer([ 0b10000000 | 2 ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, ':method');      assert.equal(field.value, 'GET');    });    it('should fetch entry from the end of the static table', function() {      decomp.write(new Buffer([ 0b10000000 | 61 ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, 'www-authenticate');      assert.equal(field.value, '');    });    it('should fail on OOB-index', function(cb) {      decomp.write(new Buffer([ 0b11000000 ]));      decomp.execute(function(err) {        assert(/field oob/i.test(err.message), err.message);        cb();      });    });  });  describe('literal field', function() {    it('should lookup name in the table (incremental)', function() {      var value = new Buffer('localhost');      var header = new Buffer([        0b01000000 | 38,  // 38th element from static table        value.length      ]);      decomp.write(Buffer.concat([ header, value ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, 'host');      assert.equal(field.value, 'localhost');      decomp.write(new Buffer([ 0b10000000 | 62 ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, 'host');      assert.equal(field.value, 'localhost');    });    it('should lookup name in the table (not-incremental)', function(cb) {      var value = new Buffer('localhost');      var header = new Buffer([        0b00001111,        0b00000000 | 23,        value.length      ]);      decomp.write(Buffer.concat([ header, value ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, 'host');      assert.equal(field.value, 'localhost');      decomp.write(new Buffer([ 0b10000000 | 62 ]));      decomp.execute(function(err) {        assert(/field oob/i.test(err.message), err.message);        cb();      });    });    it('should evict header field from the table', function() {      var value = new Buffer('localhost');      var header = new Buffer([        0b01000000 | 38,  // 38th element from static table        value.length      ]);      for (var i = 0; i < 1000; i++) {        decomp.write(Buffer.concat([ header, value ]));        decomp.execute();        var field = decomp.read();        assert.equal(field.name, 'host');        assert.equal(field.value, 'localhost');      }      assert(decomp._table.size < decomp._table.maxSize);      assert.equal(decomp._table.dynamic.length, 22);    });  });  describe('update size', function() {    it('should evict header field from the table', function() {      var value = new Buffer('localhost');      var header = new Buffer([        0b01000000 | 38,  // 38th element from static table        value.length      ]);      decomp.write(Buffer.concat([ header, value ]));      decomp.execute();      var field = decomp.read();      assert.equal(field.name, 'host');      assert.equal(field.value, 'localhost');      assert.equal(decomp._table.dynamic.length, 1);      decomp.write(new Buffer([        0b00100000      ]));      decomp.execute();      assert.equal(decomp._table.dynamic.length, 0);    });  });  describe('spec examples', function() {    var decomp;    beforeEach(function() {      decomp = hpack.decompressor.create({        table: {          maxSize: 256        }      });    });    var tests = fixtures.specExamples;    tests.forEach(function(test, i) {      var prev = tests[i - 1];      it('should give expected output on ' + test.id, function() {        var startFrom = test.continuation ? prev.decomp : decomp;        if (!startFrom)          throw new Error('Previous test failed');        decomp = startFrom;        decomp.write(new Buffer(test.input.replace(/ /g, ''), 'hex'));        decomp.execute();        var output = [];        for (;;) {          var chunk = decomp.read();          if (!chunk)            break;          output.push([ chunk.name, chunk.value ]);        }        assert.deepEqual(output, test.output);        // Verify table contents        assert.deepEqual(decomp._table.dynamic.map(function(header) {          return [ header.name, header.value, header.totalSize ];        }).reverse(), test.table);        // Verify table size        var expectedSize = test.table.reduce(function(acc, item) {          return acc + item[2];        }, 0);        assert.equal(decomp._table.size, expectedSize);        test.decomp = decomp;      });    });  });});
 |