diff --git a/package.json b/package.json index f6659b7..ab8e942 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ }, "devDependencies": { "expect.js": "0.3.x", + "lodash": "3.10.x", "mocha": "2.3.x" }, "keywords": [ diff --git a/test/fixtures.js b/test/fixtures.js index a0207b3..39136b6 100644 --- a/test/fixtures.js +++ b/test/fixtures.js @@ -1,4 +1,4 @@ -var extend = require('extend'); +var _ = require('lodash'); var makeSG = module.exports.makeSG = function(sg, time) { time = time || "Oct 20, 2015 11:09:00"; @@ -22,7 +22,9 @@ var makeSGs = module.exports.makeSGs = function(count) { var data = module.exports.data = function(overrides) { overrides = overrides || {}; var sgs = makeSGs(288); - return extend(true, { + return _.defaults( + overrides, + { "sgs" : sgs, "lastSG" : sgs[sgs.length - 1], "conduitSerialNumber" : "0", @@ -83,5 +85,6 @@ var data = module.exports.data = function(overrides) { "medicalDeviceTimeAsString" : "Oct 17, 2015 09:09:14", "lastSGTrend" : "UP_DOUBLE", "lastSensorTime" : 0 - }, overrides); + } + ); }; diff --git a/test/transform.js b/test/transform.js index 0433ce2..a370467 100644 --- a/test/transform.js +++ b/test/transform.js @@ -49,29 +49,64 @@ describe('transform()', function() { ).to.be(0); }); - it('should include active insulin as "iob"', function() { - var pumpStatus = transform( - f.data({'activeInsulin': { - 'datetime' : 'Oct 17, 2015 09:09:14', - 'version' : 1, - 'amount' : 1.275, - 'kind' : 'Insulin' - }}) - ).filter(function(e) { return e['type'] === 'pump_status'; })[0]; - - expect(pumpStatus['iob']).to.be(1.275); + describe('active insulin', function() { + it('should include active insulin as "iob"', function() { + var pumpStatus = transform( + f.data({'activeInsulin': { + 'datetime' : 'Oct 17, 2015 09:09:14', + 'version' : 1, + 'amount' : 1.275, + 'kind' : 'Insulin' + }}) + ).filter(function(e) { return e['type'] === 'pump_status'; })[0]; + + expect(pumpStatus['iob']).to.be(1.275); + }); + + it('should ignore activeInsulin values of -1', function() { + var pumpStatus = transform( + f.data({'activeInsulin': { + 'datetime' : 'Oct 17, 2015 09:09:14', + 'version' : 1, + 'amount' : -1, + 'kind' : 'Insulin' + }}) + ).filter(function(e) { return e['type'] === 'pump_status'; })[0]; + + expect(pumpStatus['iob']).to.be(undefined); + }); }); - it('should ignore activeInsulin values of -1', function() { - var pumpStatus = transform( - f.data({'activeInsulin': { - 'datetime' : 'Oct 17, 2015 09:09:14', - 'version' : 1, - 'amount' : -1, - 'kind' : 'Insulin' - }}) - ).filter(function(e) { return e['type'] === 'pump_status'; })[0]; - - expect(pumpStatus['iob']).to.be(undefined); + describe('trend', function() { + var sgs = [ + [95, 'Oct 20, 2015 08:05:00'], + [105, 'Oct 20, 2015 08:10:00'], + [108, 'Oct 20, 2015 08:15:00'] + ]; + + function transformedSGs(valDatePairs) { + return transform( + f.data({ + 'lastSGTrend': 'UP_DOUBLE', + 'sgs': valDatePairs.map(Function.prototype.apply.bind(f.makeSG, null)) + }) + ).filter(function(e) { return e['type'] === 'sgv'; }); + } + + it('should add the trend to the last sgv', function() { + var sgvs = transformedSGs(sgs); + expect(sgvs.length).to.be(3); + expect(sgvs[sgvs.length - 1]['sgv']).to.be(108); + expect(sgvs[sgvs.length - 1]['direction']).to.be('DoubleUp'); + expect(sgvs[sgvs.length - 1]['trend']).to.be(1); + }); + + it('should not add a trend if the most recent sgv is absent', function() { + var sgvs = transformedSGs(sgs.concat([[0, 'Oct 20, 2015 08:20:00']])); + expect(sgvs.length).to.be(3); + expect(sgvs[sgvs.length - 1]['sgv']).to.be(108); + expect(sgvs[sgvs.length - 1]['direction']).to.be(undefined); + expect(sgvs[sgvs.length - 1]['trend']).to.be(undefined); + }); }); }); diff --git a/transform.js b/transform.js index 98b38bb..6dc40b2 100644 --- a/transform.js +++ b/transform.js @@ -1,11 +1,20 @@ /* jshint node: true */ "use strict"; +var extend = require('extend'); + var logger = require('./logger'); var STALE_DATA_THRESHOLD_MINUTES = 20; var PUMP_STATUS_ENTRY_TYPE = 'pump_status'; var SENSOR_GLUCOSE_ENTRY_TYPE = 'sgv'; +var CARELINK_TREND_TO_NIGHTSCOUT_TREND = { + 'NONE': {'trend': 0, 'direction': 'NONE'}, + 'UP_DOUBLE': {'trend': 1, 'direction': 'DoubleUp'}, + 'UP': {'trend': 2, 'direction': 'SingleUp'}, + 'DOWN': {'trend': 6, 'direction': 'SingleDown'}, + 'DOWN_DOUBLE': {'trend': 7, 'direction': 'DoubleDown'} +}; function parsePumpTime(pumpTimeString, offset) { return Date.parse(pumpTimeString + ' ' + offset); @@ -74,21 +83,31 @@ function pumpStatusEntry(data) { function sgvEntries(data) { var offset = guessPumpOffset(data); - if(data['sgs'] && data['sgs'].length) { - return data['sgs'].filter(function(entry) { - return entry['kind'] === 'SG' && entry['sg'] !== 0; - }).map(function(sgv) { - return addTimeToEntry( - parsePumpTime(sgv['datetime'], offset), - { - 'type': SENSOR_GLUCOSE_ENTRY_TYPE, - 'sgv': sgv['sg'], - } - ); - }); - } else { + if (!data['sgs'] || !data['sgs'].length) { return []; } + + var sgvs = data['sgs'].filter(function(entry) { + return entry['kind'] === 'SG' && entry['sg'] !== 0; + }).map(function(sgv) { + return addTimeToEntry( + parsePumpTime(sgv['datetime'], offset), + { + 'type': SENSOR_GLUCOSE_ENTRY_TYPE, + 'sgv': sgv['sg'], + } + ); + }); + + if(data['sgs'][data['sgs'].length - 1]['sg'] !== 0) { + sgvs[sgvs.length - 1] = extend( + true, + sgvs[sgvs.length - 1], + CARELINK_TREND_TO_NIGHTSCOUT_TREND[data['lastSGTrend']] + ); + } + + return sgvs; } var transform = module.exports = function(data, sgvLimit) {