Code coverage report for lib/Parser.js

Statements: 97.37% (37 / 38)      Branches: 96% (24 / 25)      Functions: 100% (9 / 9)      Lines: 100% (36 / 36)     

All files » lib/ » Parser.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103              1 1   1   1                   1 59 59 312 312 59 59     59       1   41   38                 38 17   21 21     38                             38     1 2 2     36 36     36     2           1 1 1 1 1 18 18   1      
/*
 * oy
 *
 * Copyright(c) 2013 Artur Cistov
 * MIT Licensed
 */
 
var csv = require('csv');
var tt = require('timeTraveller');
 
var Parser = module.exports = {};
 
Parser.TYPES = [
  { name: 'admin', match: /^Entered and exited|^Topped-up|^Season ticket/ },
  { name: 'bus', match: /^Bus journey, route ([\d]*)$/ },
  { name: 'rail', match: /\[National Rail\]$/ },
  { name: 'overground', match: /\[London Overground\]$/ },
  { name: 'no_touchin', match: /^\[No touch-in\]$/ },
  { name: 'no_touchout', match: /^\[No touch-out\]$/ },
  { name: 'underground', match: /(^[\w\s()&,]*$|\[London Underground\]$)/ }
];
 
Parser.checkType = function(text) {
  var typeName = '', i, type;
  for(i = 0; i < this.TYPES.length; i++) {
    type = this.TYPES[i];
    if(text.match(type.match)) {
      typeName = type.name;
      break;
    }
  }
  return typeName;
};
 
 
Parser.parseRow = function(row) {
 
  if( row[0] && row[0] === 'Note' || !(row instanceof Array) ) { return null; }
 
  var startDate = new Date(Date.parse(row[1] + ' ' + row[2])),
      endDate = row[3] ? new Date(Date.parse(row[1] + ' ' + row[3])) : null,
      duration = endDate ? new tt.TimeSpan(endDate, startDate) : new tt.TimeSpan(startDate, startDate),
      description = (row[4] || '').trim(),
      descriptionData = description.split(' to '),
      from = {},
      to = {},
      journey;
 
  if(descriptionData.length === 1) {
    from = { text: description, type: this.checkType(descriptionData[0]) };
  } else {
    from = { text: descriptionData[0], type: this.checkType(descriptionData[0]) };
    to = { text: descriptionData[1], type: this.checkType(descriptionData[1]) };
  }
 
  journey = {
    note: row[0],
    date: row[1],
    startTime: row[2],
    startDate: startDate,
    endTime: row[3] || null,
    endDate: endDate,
    duration: duration,
    description: description,
    charge: Number(row[5] || 0),
    credit: Number(row[6] || 0),
    balance: Number(row[7] || 0),
    to: to,
    from: from
  };
  return journey;
};
 
Parser.getCSVData = function(input, cb) {
  var rows = [];
  csv()
  .from(input)
  .transform(function(row) {
    row.unshift(row.pop());
    return row;
  })
  .on('record', function(row) {
    rows.push(row);
  })
  .on('end', function() {
    cb(null, rows);
  })
  .on('error', cb);
};
 
 
Parser.parse = function(input, cb) {
  var journeys = [];
  this.getCSVData(input, function(err, rows) {
    Iif(err) { return cb(err); }
    rows.forEach(function(row) {
      var journey = Parser.parseRow(row);
      journeys.push(journey);
    });
    cb(null, journeys);
  });
};