<commit_before>
var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var request = require('supertest');
var send = require('..')
var should = require('should');

// test server

var fixtures = path.join(__dirname, 'fixtures');
var app = http.createServer(function(req, res){
  function error(err) {
    res.statusCode = err.status;
    res.end(http.STATUS_CODES[err.status]);
  }

  function redirect() {
    res.statusCode = 301;
    res.setHeader('Location', req.url + '/');
    res.end('Redirecting to ' + req.url + '/');
  }

  send(req, req.url, {root: fixtures})
  .on('error', error)
  .on('directory', redirect)
  .pipe(res);
});

describe('send.mime', function(){
  it('should be exposed', function(){
    assert(send.mime);
  })
})

describe('send(file).pipe(res)', function(){
  it('should stream the file contents', function(done){
    request(app)
    .get('/name.txt')
    .expect('Content-Length', '4')
    .expect(200, 'tobi', done)
  })

  it('should decode the given path as a URI', function(done){
    request(app)
    .get('/some%20thing.txt')
    .expect(200, 'hey', done)
  })

  it('should serve files with dots in name', function(done){
    request(app)
    .get('/do..ts.txt')
    .expect(200, '...', done)
  })

  it('should treat a malformed URI as a bad request', function(done){
    request(app)
    .get('/some%99thing.txt')
    .expect(400, 'Bad Request', done)
  })

  it('should 400 on NULL bytes', function(done){
    request(app)
    .get('/some%00thing.txt')
    .expect(400, 'Bad Request', done)
  })

  it('should treat an ENAMETOOLONG as a 404', function(done){
    var path = Array(100).join('foobar');
    request(app)
    .get('/' + path)
    .expect(404, done);
  })

  it('should handle headers already sent error', function(done){
    var app = http.createServer(function(req, res){
      res.write('0');
      send(req, req.url, {root: fixtures})
      .on('error', function(err){ res.end(' - ' + err.message) })
      .pipe(res);
    });
    request(app)
    .get('/nums')
    .expect(200, '0 - Can\'t set headers after they are sent.', done);
  })

  it('should support HEAD', function(done){
    request(app)
    .head('/name.txt')
    .expect('Content-Length', '4')
    .expect(200, '', done)
  })

  it('should add an ETag header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('etag', /^W\/"[^"]+"$/)
    .end(done);
  })

  it('should add a Date header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('date', /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/, done)
  })

  it('should add a Last-Modified header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('last-modified', /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/, done)
  })

  it('should add a Accept-Ranges header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('Accept-Ranges', 'bytes', done)
  })

  it('should 404 if the file does not exist', function(done){
    request(app)
    .get('/meow')
    .expect(404, 'Not Found', done)
  })

  it('should 301 if the directory exists', function(done){
    request(app)
    .get('/pets')
    .expect('Location', '/pets/')
    .expect(301, 'Redirecting to /pets/', done)
  })

  it('should not override content-type', function(done){
    var app = http.createServer(function(req, res){
      res.setHeader('Content-Type', 'application/x-custom')
      send(req, req.url, {root: fixtures}).pipe(res)
    });
    request(app)
    .get('/nums')
    .expect('Content-Type', 'application/x-custom', done);
  })

  it('should set Content-Type via mime map', function(done){
    request(app)
    .get('/name.txt')
    .expect('Content-Type', 'text/plain; charset=UTF-8')
    .expect(200, function(err){
      if (err) return done(err)
      request(app)
      .get('/tobi.html')
      .expect('Content-Type', 'text/html; charset=UTF-8')
      .expect(200, done)
    });
  })

  it('should 404 if file disappears after stat, before open', function(done){
    var app = http.createServer(function(req, res){
      send(req, req.url, {root: 'test/fixtures'})
      .on('file', function(){
        // simulate file ENOENT after on open, after stat
        var fn = this.send;
        this.send = function(path, stat){
          path += '__xxx_no_exist';
          fn.call(this, path, stat);
        };
      })
      .pipe(res);
    });

    request(app)
    .get('/name.txt')
    .expect(404, done);
  })

  describe('when no "directory" listeners are present', function(){
    it('should respond with a redirect', function(done){
      var app = http.createServer(function(req, res){
        send(req, req.url, {root: 'test/fixtures'})
        .pipe(res);
      });<commit_msg>tests: add file error test<commit_after>
var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var request = require('supertest');
var send = require('..')
var should = require('should');

// test server

var fixtures = path.join(__dirname, 'fixtures');
var app = http.createServer(function(req, res){
  function error(err) {
    res.statusCode = err.status;
    res.end(http.STATUS_CODES[err.status]);
  }

  function redirect() {
    res.statusCode = 301;
    res.setHeader('Location', req.url + '/');
    res.end('Redirecting to ' + req.url + '/');
  }

  send(req, req.url, {root: fixtures})
  .on('error', error)
  .on('directory', redirect)
  .pipe(res);
});

describe('send.mime', function(){
  it('should be exposed', function(){
    assert(send.mime);
  })
})

describe('send(file).pipe(res)', function(){
  it('should stream the file contents', function(done){
    request(app)
    .get('/name.txt')
    .expect('Content-Length', '4')
    .expect(200, 'tobi', done)
  })

  it('should decode the given path as a URI', function(done){
    request(app)
    .get('/some%20thing.txt')
    .expect(200, 'hey', done)
  })

  it('should serve files with dots in name', function(done){
    request(app)
    .get('/do..ts.txt')
    .expect(200, '...', done)
  })

  it('should treat a malformed URI as a bad request', function(done){
    request(app)
    .get('/some%99thing.txt')
    .expect(400, 'Bad Request', done)
  })

  it('should 400 on NULL bytes', function(done){
    request(app)
    .get('/some%00thing.txt')
    .expect(400, 'Bad Request', done)
  })

  it('should treat an ENAMETOOLONG as a 404', function(done){
    var path = Array(100).join('foobar');
    request(app)
    .get('/' + path)
    .expect(404, done);
  })

  it('should handle headers already sent error', function(done){
    var app = http.createServer(function(req, res){
      res.write('0');
      send(req, req.url, {root: fixtures})
      .on('error', function(err){ res.end(' - ' + err.message) })
      .pipe(res);
    });
    request(app)
    .get('/nums')
    .expect(200, '0 - Can\'t set headers after they are sent.', done);
  })

  it('should support HEAD', function(done){
    request(app)
    .head('/name.txt')
    .expect('Content-Length', '4')
    .expect(200, '', done)
  })

  it('should add an ETag header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('etag', /^W\/"[^"]+"$/)
    .end(done);
  })

  it('should add a Date header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('date', /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/, done)
  })

  it('should add a Last-Modified header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('last-modified', /^\w{3}, \d+ \w+ \d+ \d+:\d+:\d+ \w+$/, done)
  })

  it('should add a Accept-Ranges header field', function(done){
    request(app)
    .get('/name.txt')
    .expect('Accept-Ranges', 'bytes', done)
  })

  it('should 404 if the file does not exist', function(done){
    request(app)
    .get('/meow')
    .expect(404, 'Not Found', done)
  })

  it('should 301 if the directory exists', function(done){
    request(app)
    .get('/pets')
    .expect('Location', '/pets/')
    .expect(301, 'Redirecting to /pets/', done)
  })

  it('should not override content-type', function(done){
    var app = http.createServer(function(req, res){
      res.setHeader('Content-Type', 'application/x-custom')
      send(req, req.url, {root: fixtures}).pipe(res)
    });
    request(app)
    .get('/nums')
    .expect('Content-Type', 'application/x-custom', done);
  })

  it('should set Content-Type via mime map', function(done){
    request(app)
    .get('/name.txt')
    .expect('Content-Type', 'text/plain; charset=UTF-8')
    .expect(200, function(err){
      if (err) return done(err)
      request(app)
      .get('/tobi.html')
      .expect('Content-Type', 'text/html; charset=UTF-8')
      .expect(200, done)
    });
  })

  it('should 404 if file disappears after stat, before open', function(done){
    var app = http.createServer(function(req, res){
      send(req, req.url, {root: 'test/fixtures'})
      .on('file', function(){
        // simulate file ENOENT after on open, after stat
        var fn = this.send;
        this.send = function(path, stat){
          path += '__xxx_no_exist';
          fn.call(this, path, stat);
        };
      })
      .pipe(res);
    });

    request(app)
    .get('/name.txt')
    .expect(404, done);
  })

  it('should 500 on file stream error', function(done){
    var app = http.createServer(function(req, res){
      send(req, req.url, {root: 'test/fixtures'})
      .on('stream', function(stream){
        // simulate file error
        process.nextTick(function(){
          stream.emit('error', new Error('boom!'));
        });
      })
      .pipe(res);
    });

    request(app)
    .get('/name.txt')
    .expect(500, done);
  })

  describe('when no "directory" listeners are present', function(){
    it('should respond with a redirect', function(done){
      var app = http.createServer(function(req, res){
        send(req, req.url, {root: 'test/fixtures'})
        .pipe(res);
      });
{'fraction_non_alphanumeric': 0.1969, 'fraction_numerical': 0.0154, 'mean_word_length': 2.9296660117878193, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3042804', 'n_tokens_mistral': 3543, 'n_tokens_neox': 3362, 'n_words': 813}