/*jshint expr: true */

var chai = require('chai');
var assert = chai.assert;
var expect = chai.expect;

var _ = require('underscore');

var fx = require('./fixtures');

var BasalUtil = require('../js/data/basalutil');

fx.forEach(testData);

function testData (data) {
  var name = data.name;
  var basal = new BasalUtil(data.json);
  describe(name, function() {
    it('should be an array', function() {
      assert.isArray(data.json);
    });

    it('should be composed of objects', function() {
      data.json.forEach(function(d) {
        assert.typeOf(d, 'object');
      });
    });

    it('should be non-zero in length', function() {
      expect(data.json).to.have.length.above(0);
    });

    describe('basal.actual', function() {
      it('should be an array', function() {
        assert.typeOf(basal.actual, 'array');
      });

      it('should have a non-zero length', function() {
        expect(basal.actual).to.have.length.above(0);
      });

      it('should have a first segment with a start matching the first segment of input data', function() {
        var basals = _.where(data.json, {'type': 'basal-rate-segment'});
        expect(basal.actual[0].start).to.equal(basals[0].start);
      });

      it('should have a last segment with an end matching the last segment of input data', function() {
        var basals = _.where(data.json, {'type': 'basal-rate-segment'});
        var basalLength = basal.actual.length;
        expect(basal.actual[basalLength - 1].end).to.equal(basals[basals.length - 1].end);
      });

      it('should be sorted in sequence', function() {
        var sorted = _.sortBy(basal.actual, function(a) {
          return new Date(a.start).valueOf();
        });
        expect(sorted).to.eql(basal.actual);
      });

      it('should be contiguous from start to end', function() {
        var basalLength = basal.actual.length;
        expect(_.find(basal.actual, function(segment, i, segments) {
          if (i !== (basalLength - 1)) {
            return segment.end !== segments[i + 1].start;
          }
          else {
            return false;
          }
        })).to.be.undefined;
      });

      it('should not have any duplicates', function() {
        expect(_.uniq(basal.actual)).to.be.eql(basal.actual);
      });

      it('should have squashed contiguous identical segments', function() {
        var keysToOmit = ['id', 'start', 'end'];
        basal.actual.forEach(function(segment, i, segments) {
          if ((i < (segments.length - 1)) && segment.type === 'scheduled') {
            expect(_.omit(segment, keysToOmit)).to.not.eql(_.omit(segments[i + 1], keysToOmit));
          }
        });
      });
    });

    describe('basal.undelivered', function() {
      it('should be an array', function() {
        assert.typeOf(basal.undelivered, 'array', 'basal.undelivered is an array');
      });

      it('should have a non-zero length if there is a temp basal in the input data', function() {
        var temps = _.where(data.json, {'deliveryType': 'temp'});
        if (temps.length > 0) {
          expect(basal.undelivered.length).to.be.above(0);
        }
      });

      it('should be sorted in sequence', function() {
        var sorted = _.sortBy(basal.undelivered, function(a) {
          return new Date(a.start).valueOf();
        });
        expect(sorted).to.eql(basal.undelivered);
      });

      it('should not have any duplicates', function() {
        expect(_.uniq(basal.undelivered)).to.be.eql(basal.undelivered);
      });
    });
  });
}
@@ -3514,32 +3514,619 @@
 ered);%0A      %7D);
+%0A%0A      it('should have a total duration equal to the total duration of temp segments from the actual stream', function() %7B%0A        var tempDuration = 0;%0A        _.where(basal.actual, %7B'deliveryType': 'temp'%7D).forEach(function(segment) %7B%0A          tempDuration += Date.parse(segment.end) - Date.parse(segment.start);%0A        %7D);%0A        var undeliveredDuration = 0;%0A        basal.undelivered.forEach(function(segment) %7B%0A          undeliveredDuration += Date.parse(segment.end) - Date.parse(segment.start);%0A        %7D);%0A        expect(undeliveredDuration).to.equal(tempDuration);%0A      %7D);
 %0A    %7D);%0A  %7D);%0A%7D

add test to demonstrate the bug in undelivered segments