<commit_before>'use strict'

var Buffer = require('safe-buffer').Buffer
var test = require('tape')
var tentacoli = require('./')
var from = require('from2')
var callback = require('callback-stream')
var Writable = require('stream').Writable
var through = require('through2')
var msgpack = require('msgpack5')

function setup (opts) {
  var sender = tentacoli(opts)
  var receiver = tentacoli(opts)

  sender.pipe(receiver).pipe(sender)

  return {
    sender: sender,
    receiver: receiver
  }
}

test('can issue a request', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'
  var expected = '42'

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.deepEqual(res, expected, 'response matches')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(null, expected)
  })
})

test('can pass through an object', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }
  var expected = { res: '42' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.deepEqual(res, expected, 'response matches')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(null, expected)
  })
})

test('can handle an error response from a request', function (t) {
  t.plan(4)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err, res) {
    t.ok(err instanceof Error, 'there is an error')
    t.equal(err.message, 'something went wrong')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(new Error('something went wrong'))
  })

  s.receiver.on('responseError', function (err) {
    t.ok(err, 'error exists')
  })
})

test('can pass from receiver to sender an object readable stream', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'subscribe' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(['hello', 'streams'])
      }
    })
  })
})

test('can pass from receiver to sender a writable stream', function (t) {
  t.plan(2)

  var s = setup()
  var msg = { cmd: 'publish' }

  s.sender.request(null, function (err, res) {
    t.error(err, 'no error')
    res.streams.writable.end(msg)
  })

  s.receiver.on('request', function (req, reply) {
    var writable = new Writable({ objectMode: true })
    writable._write = function (chunk, enc, cb) {
      t.deepEqual(chunk, msg, 'msg match')
      cb()
    }
    reply(null, {
      streams: {
        writable: writable
      }
    })
  })
})

test('can pass from receiver to sender a transform stream as a writable', function (t) {
  t.plan(2)

  var s = setup()
  var msg = { cmd: 'publish' }

  s.sender.request(null, function (err, res) {
    t.error(err, 'no error')
    res.streams.writable.end(msg)
  })

  s.receiver.on('request', function (req, reply) {
    var writable = new Writable({ objectMode: true })
    writable._write = function (chunk, enc, cb) {
      t.deepEqual(chunk, msg, 'msg match')
    }
    var transform = through.obj()

    transform.pipe(writable)

    reply(null, {
      streams: {
        writable: transform
      }
    })
  })
})

test('can pass from receiver to sender a transform stream as a readable streams', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'subscribe' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(['hello', 'streams']).pipe(through.obj(function (chunk, enc, cb) {
          cb(null, chunk)
        }))
      }
    })
  })
})

test('can pass from sender to receiver an object readable stream', function (t) {
  t.plan(3)

  var s = setup()
  var msg = {
    cmd: 'publish',
    streams: {
      events: from.obj(['hello', 'streams'])
    }
  }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
  })

  s.receiver.on('request', function (req, reply) {
    req.streams.events.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
      reply()
    }))
  })
})

test('can pass from sender to receiver an object writable stream', function (t) {
  t.plan(2)

  var s = setup()
  var writable = new Writable({ objectMode: true })

  writable._write = function (chunk, enc, cb) {
    t.deepEqual(chunk, 'hello', 'chunk match')
    cb()
  }

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
  })

  s.receiver.on('request', function (req, reply) {
    req.streams.events.end('hello')
    reply()
  })
})

test('supports custom encodings', function (t) {
  t.plan(3)

  var s = setup({ codec: msgpack() })
  var msg = { cmd: 'subscribe' }
  var expected = [
    Buffer.from('hello'),
    Buffer.from('streams')
  ]

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, expected, 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(expected).pipe(through.obj(function (chunk, enc, cb) {
          cb(null, chunk)
        }))
      }
    })
  })
})

test('can reply with null', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.notOk(res, 'empty response')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply()
  })
})

test('errors if piping something errors', function (t) {
  t.plan(1)

  var s = setup()
  var writable = new Writable({ objectMode: true })
  var throwErr

  writable.on('pipe', function () {
    throwErr = new Error('something goes wrong')
    throw throwErr
  })

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.request(msg, function (err, res) {
    t.equal(err, throwErr, 'an error happens')
  })

  s.receiver.on('request', function (req, reply) {
    t.fail('it never happens')
  })
})

test('errors if the connection end', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.end()
  })
})

test('errors if the receiver is destroyed', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.destroy(new Error('kaboom'))
  })
})

test('errors if the sender is destroyed with error', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.sender.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy(new Error('kaboom'))
  })
})

test('errors if the sender is destroyed', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy()
  })
})

test('fire and forget - send string', function (t) {
  t.plan(1)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
  })
})

test('fire and forget - send object', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
  })
})

test('fire and forget - can pass from sender to receiver an object readable stream', function (t) {
  t.plan(2)

  var s = setup()
  var msg = {
    cmd: 'publish',
    streams: {
      events: from.obj(['hello', 'streams'])
    }
  }

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    req.streams.events.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })
})

test('fire and forget - can pass from sender to receiver an object writable stream', function (t) {
  t.plan(1)

  var s = setup()
  var writable = new Writable({ objectMode: true })

  writable._write = function (chunk, enc, cb) {
    t.deepEqual(chunk, 'hello', 'chunk match')
    cb()
  }

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    req.streams.events.end('hello')
  })
})

test('fire and forget - should not care if the connection end', function (t) {
  t.plan(1)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.end()
  })
})

test('fire and forget - should not care if the receiver is destroyed', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.destroy(new Error('kaboom'))
  })
})

test('fire and forget - should not care about errors', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy()
  })
})
<commit_msg>Updated test<commit_after>'use strict'

var Buffer = require('safe-buffer').Buffer
var test = require('tape')
var tentacoli = require('./')
var from = require('from2')
var callback = require('callback-stream')
var Writable = require('stream').Writable
var through = require('through2')
var msgpack = require('msgpack5')

function setup (opts) {
  var sender = tentacoli(opts)
  var receiver = tentacoli(opts)

  sender.pipe(receiver).pipe(sender)

  return {
    sender: sender,
    receiver: receiver
  }
}

test('can issue a request', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'
  var expected = '42'

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.deepEqual(res, expected, 'response matches')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(null, expected)
  })
})

test('can pass through an object', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }
  var expected = { res: '42' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.deepEqual(res, expected, 'response matches')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(null, expected)
  })
})

test('can handle an error response from a request', function (t) {
  t.plan(4)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err, res) {
    t.ok(err instanceof Error, 'there is an error')
    t.equal(err.message, 'something went wrong')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply(new Error('something went wrong'))
  })

  s.receiver.on('responseError', function (err) {
    t.ok(err, 'error exists')
  })
})

test('can pass from receiver to sender an object readable stream', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'subscribe' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(['hello', 'streams'])
      }
    })
  })
})

test('can pass from receiver to sender a writable stream', function (t) {
  t.plan(2)

  var s = setup()
  var msg = { cmd: 'publish' }

  s.sender.request(null, function (err, res) {
    t.error(err, 'no error')
    res.streams.writable.end(msg)
  })

  s.receiver.on('request', function (req, reply) {
    var writable = new Writable({ objectMode: true })
    writable._write = function (chunk, enc, cb) {
      t.deepEqual(chunk, msg, 'msg match')
      cb()
    }
    reply(null, {
      streams: {
        writable: writable
      }
    })
  })
})

test('can pass from receiver to sender a transform stream as a writable', function (t) {
  t.plan(2)

  var s = setup()
  var msg = { cmd: 'publish' }

  s.sender.request(null, function (err, res) {
    t.error(err, 'no error')
    res.streams.writable.end(msg)
  })

  s.receiver.on('request', function (req, reply) {
    var writable = new Writable({ objectMode: true })
    writable._write = function (chunk, enc, cb) {
      t.deepEqual(chunk, msg, 'msg match')
    }
    var transform = through.obj()

    transform.pipe(writable)

    reply(null, {
      streams: {
        writable: transform
      }
    })
  })
})

test('can pass from receiver to sender a transform stream as a readable streams', function (t) {
  t.plan(3)

  var s = setup()
  var msg = { cmd: 'subscribe' }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(['hello', 'streams']).pipe(through.obj(function (chunk, enc, cb) {
          cb(null, chunk)
        }))
      }
    })
  })
})

test('can pass from sender to receiver an object readable stream', function (t) {
  t.plan(3)

  var s = setup()
  var msg = {
    cmd: 'publish',
    streams: {
      events: from.obj(['hello', 'streams'])
    }
  }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
  })

  s.receiver.on('request', function (req, reply) {
    req.streams.events.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
      reply()
    }))
  })
})

test('can pass from sender to receiver an object writable stream', function (t) {
  t.plan(2)

  var s = setup()
  var writable = new Writable({ objectMode: true })

  writable._write = function (chunk, enc, cb) {
    t.deepEqual(chunk, 'hello', 'chunk match')
    cb()
  }

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
  })

  s.receiver.on('request', function (req, reply) {
    req.streams.events.end('hello')
    reply()
  })
})

test('supports custom encodings', function (t) {
  t.plan(3)

  var s = setup({ codec: msgpack() })
  var msg = { cmd: 'subscribe' }
  var expected = [
    Buffer.from('hello'),
    Buffer.from('streams')
  ]

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    res.streams.result.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, expected, 'is passed through correctly')
    }))
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: {
        result: from.obj(expected).pipe(through.obj(function (chunk, enc, cb) {
          cb(null, chunk)
        }))
      }
    })
  })
})

test('can reply with null', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err, res) {
    t.error(err, 'no error')
    t.notOk(res, 'empty response')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    reply()
  })
})

test('errors if piping something errors', function (t) {
  t.plan(1)

  var s = setup()
  var writable = new Writable({ objectMode: true })
  var throwErr

  writable.on('pipe', function () {
    throwErr = new Error('something goes wrong')
    throw throwErr
  })

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.request(msg, function (err, res) {
    t.equal(err, throwErr, 'an error happens')
  })

  s.receiver.on('request', function (req, reply) {
    t.fail('it never happens')
  })
})

test('errors if the connection end', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.end()
  })
})

test('errors if the receiver is destroyed', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.destroy(new Error('kaboom'))
  })
})

test('errors if the sender is destroyed with error', function (t) {
  t.plan(3)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.sender.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy(new Error('kaboom'))
  })
})

test('errors if the sender is destroyed', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.request(msg, function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy()
  })
})

test('fire and forget - send string', function (t) {
  t.plan(1)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
  })
})

test('fire and forget - send object', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
  })
})

test('fire and forget - can pass from sender to receiver an object readable stream', function (t) {
  t.plan(2)

  var s = setup()
  var msg = {
    cmd: 'publish',
    streams: {
      events: from.obj(['hello', 'streams'])
    }
  }

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    req.streams.events.pipe(callback.obj(function (err, list) {
      t.error(err, 'no error')
      t.deepEqual(list, ['hello', 'streams'], 'is passed through correctly')
    }))
  })
})

test('fire and forget - can pass from sender to receiver an object writable stream', function (t) {
  t.plan(1)

  var s = setup()
  var writable = new Writable({ objectMode: true })

  writable._write = function (chunk, enc, cb) {
    t.deepEqual(chunk, 'hello', 'chunk match')
    cb()
  }

  var msg = {
    cmd: 'subscribe',
    streams: {
      events: writable
    }
  }

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    req.streams.events.end('hello')
  })
})

test('fire and forget - should not care if the connection end', function (t) {
  t.plan(1)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.end()
  })
})

test('fire and forget - should not care if the receiver is destroyed', function (t) {
  t.plan(2)

  var s = setup()
  var msg = 'the answer to life, the universe and everything'

  s.sender.fire(msg)

  s.receiver.on('error', function (err) {
    t.ok(err, 'should error')
  })

  s.receiver.on('request', function (req, reply) {
    t.deepEqual(req, msg, 'request matches')
    s.receiver.destroy(new Error('kaboom'))
  })
})

test('fire and forget - should not care about errors', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'the answer to life, the universe and everything' }

  s.sender.fire(msg)

  s.receiver.on('request', function (req) {
    t.deepEqual(req, msg, 'request matches')
    s.sender.destroy()
  })
})

test('fire and forget - if a writable stream is passed to reply it should be destroyed', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'subscribe' }
  var writable = new Writable({ objectMode: true })

  s.sender.fire(msg)

  writable.on('error', function (err) {
    t.ok(err)
  })

  writable.on('finish', function () {
    t.pass('stream closed')
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: writable
    })
  })
})

test('fire and forget - if a writable stream is passed to reply it should be destroyed', function (t) {
  t.plan(1)

  var s = setup()
  var msg = { cmd: 'subscribe' }
  const readable = from.obj(['hello', 'streams'])

  s.sender.fire(msg)

  readable.on('close', function () {
    t.pass('stream closed')
  })

  s.receiver.on('request', function (req, reply) {
    reply(null, {
      streams: readable
    })
  })
})
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(fix): 2017-7-17 11:33:31<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-24 01:13:21<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>'use strict'

define([
    'file-saver',
    'src/util/api',
    'src/util/ui',
    './libs'
] , function (fileSaver, API, UI, libs) {

    var SD=libs.SD;

    class Nmr1dManager {
        constructor() {

        }

        handleAction(action) {
            switch (action.name) {
                case 'downloadSVG':
                    var blob = new Blob([action.value+""], {type: "application/jcamp-dx;charset=utf-8"});
                    fileSaver(blob, 'spectra.svg');
                    break;
                case 'toggleNMR1hAdvancedOptions':
                    var advancedOptions1H = ! API.cache("nmr1hAdvancedOptions");
                    API.cache("nmr1hAdvancedOptions", advancedOptions1H);
                    if (advancedOptions1H) {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").full);
                    } else {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").short);
                    }

                    break;
                case 'resetNMR1d':
                case 'resetNMR1d':
                    var type = action.name.replace(/[^0-9]/g,'');

                    type = type + 'd';
                    API.createData('blackNMR' + type, null);
                    API.createData('annotationNMR' + type, null);
                    API.createData('acsNMR' + type, null);
                    break;
                case 'executePeakPicking':
                    // the action may be generated by clicking on a line or clicking on the button to
                    // recalculate the peak picking.
                    console.log('executePeakPicking);')
                    var currentNmr;
                    // if we click on a line, the action will be throw with the current NMR
                    if (action.value.dimension) {
                        currentNmr = action.value;
                        if (currentNmr.dimension>1) {
                            API.createData('blackNMR2d', currentNmr.jcamp.data);
                            // No peak picking currently for 2D
                            API.switchToLayer('nmr2D');
                            return;
                        } else {
                            API.createData('blackNMR1d', currentNmr.jcamp.data);
                            API.switchToLayer('Default layer');
                        }
                    } else { // we click on the button to redo assignment
                        currentNmr = API.getData('currentNmr');
                        if (currentNmr.dimension>1) {
                            if (typeof UI != "undefined") {
                                UI.showNotification('Peak picking can only be applied on 1D spectra','warning');
                            }
                            return;
                        }
                    }
                    console.log('action.value', action.value)
                    if (action.value.integral){//Fired from button
                        this._doAssignment(currentNmr);
                    } else {
                        console.log('currentNmr', currentNmr);
                        if(!currentNmr.range || ! currentNmr.range.length) {
                            this._doAssignment(currentNmr);
                            // } else {
                            // API.setVariable("editedRange",API.getVariable('currentNmr'),["range"]);
                        }
                    }
                    break;
                default:
                    return false;
            }
            return true;
        }

        _doAssignment(currentNmr) {
            var jcamp = currentNmr.getChild(['jcamp', 'data']);
            console.log("doAssignment");
            jcamp.then(function(jcamp) {
                jcamp = String(jcamp.get());
                var ppOptions = API.getData("nmr1hOptions").resurrect();
                var spectrum = SD.NMR.fromJcamp(jcamp);
                var intFN = 0;
                if(ppOptions.integralFn=="peaks"){
                    intFN=1;
                }
                var peakPicking = spectrum.nmrPeakDetection({
                    nH:ppOptions.integral,
                    realTop:true,
                    thresholdFactor:ppOptions.noiseFactor,
                    clean:ppOptions.clean,
                    compile:ppOptions.compile,
                    optimize:ppOptions.optimize,
                    integralFn:intFN,
                    idPrefix:spectrum.getNucleus()+"",
                    gsdOptions:{minMaxRatio:0.001, smoothY:false, broadWidth:0},
                    format:"new"
                });
                currentNmr.setChildSync(['range'], peakPicking);
                // API.setVariable("editedRange",API.getVariable('currentNmr'),["range"]);
                this._createNMRannotations(
                    {
                        nucleus: currentNmr.nucleus[0],
                        observe:Math.round(currentNmr.frequency/10)*10
                    }
                );
            });
        }

        _createNMRannotations(options) {
            console.log('create annoations');
            var peakPicking = JSON.parse(JSON.stringify(API.getData("currentNmrRanges")));

            //Recompile multiplicity
            for (var i=0; i<peakPicking.length; i++){
                var peak = peakPicking[i];
                for (var j=0; j<peak.signal.length; j++){
                    var signal = peak.signal[j];
                    if (signal.j) {
                        signal.multiplicity = "";
                        for (var k=0; k<signal.j.length;k++){
                            signal.multiplicity+=signal.j[k].multiplicity;
                        }
                    }
                }
            }

            API.createData("annotationsNMR1d", SD.GUI.annotations1D(peakPicking, {
                line:1,
                fillColor:"green",
                strokeWidth:0
            }));
            API.createData("acsNMR1d",SD.formatter.toACS(peakPicking, {
                rangeForMultiplet:true,
                nucleus:options.nucleus,
                observe:options.observe
            }));
        }

        initializeNMRAssignment() {
            var promise = Promise.resolve();
            promise = promise.then(() => API.createData('nmr1hOptions', {
                    "noiseFactor": 0.8,
                    "clean": true,
                    "compile": true,
                    "optimize": false,
                    "integralFn": "sum",
                    "integral": 30,
                    "type": "1H"
                })
            );

            promise=promise.then(() => API.createData('nmr1hOndeTemplates', {
                "full": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        },
                        "noiseFactor": {
                            "type": "number",
                            "title": "Mutiplier of the auto-detected noise level",
                            "label": "noiseFactor"
                        },
                        "clean": {
                            "type": "boolean",
                            "title": "Delete signals with integration less than 0.5",
                            "label": "clean"
                        },
                        "compile": {
                            "type": "boolean",
                            "title": "Compile the multiplets",
                            "label": "compile"
                        },
                        "optimize": {
                            "type": "boolean",
                            "title": "Optimize the peaks to fit the spectrum",
                            "label": "optimize"
                        },
                        "integralFn": {
                            "type": "string",
                            "title": "Type of integration",
                            "label": "Integral type",
                            "enum": [
                                "sum",
                                "peaks"
                            ]
                        },
                        "type": {
                            "type": "string",
                            "title": "Nucleus",
                            "label": "Nucleus",
                            "editable": false
                        }
                    }
                },
                "short": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        }
                    }
                }
            }));
            promise=promise.then((nmr1hOndeTemplates) => API.createData('nmr1hOndeTemplate', nmr1hOndeTemplates.short));
            return promise;
        }
    }

    return Nmr1dManager;
});

<commit_msg>Fix bug<commit_after>'use strict'

define([
    'file-saver',
    'src/util/api',
    'src/util/ui',
    './libs'
] , function (fileSaver, API, UI, libs) {

    var SD=libs.SD;

    class Nmr1dManager {
        constructor() {

        }

        handleAction(action) {
            switch (action.name) {
                case 'downloadSVG':
                    var blob = new Blob([action.value+""], {type: "application/jcamp-dx;charset=utf-8"});
                    fileSaver(blob, 'spectra.svg');
                    break;
                case 'toggleNMR1hAdvancedOptions':
                    var advancedOptions1H = ! API.cache("nmr1hAdvancedOptions");
                    API.cache("nmr1hAdvancedOptions", advancedOptions1H);
                    if (advancedOptions1H) {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").full);
                    } else {
                        API.createData("nmr1hOndeTemplate", API.getData("nmr1hOndeTemplates").short);
                    }

                    break;
                case 'resetNMR1d':
                case 'resetNMR1d':
                    var type = action.name.replace(/[^0-9]/g,'');

                    type = type + 'd';
                    API.createData('blackNMR' + type, null);
                    API.createData('annotationNMR' + type, null);
                    API.createData('acsNMR' + type, null);
                    break;
                case 'executePeakPicking':
                    // the action may be generated by clicking on a line or clicking on the button to
                    // recalculate the peak picking.
                    console.log('executePeakPicking);')
                    var currentNmr;
                    // if we click on a line, the action will be throw with the current NMR
                    if (action.value.dimension) {
                        currentNmr = action.value;
                        if (currentNmr.dimension>1) {
                            API.createData('blackNMR2d', currentNmr.jcamp.data);
                            // No peak picking currently for 2D
                            API.switchToLayer('nmr2D');
                            return;
                        } else {
                            API.createData('blackNMR1d', currentNmr.jcamp.data);
                            API.switchToLayer('Default layer');
                        }
                    } else { // we click on the button to redo assignment
                        currentNmr = API.getData('currentNmr');
                        if (currentNmr.dimension>1) {
                            if (typeof UI != "undefined") {
                                UI.showNotification('Peak picking can only be applied on 1D spectra','warning');
                            }
                            return;
                        }
                    }
                    console.log('action.value', action.value)
                    if (action.value.integral){//Fired from button
                        this._doAssignment(currentNmr);
                    } else {
                        console.log('currentNmr', currentNmr);
                        if(!currentNmr.range || ! currentNmr.range.length) {
                            this._doAssignment(currentNmr);
                            // } else {
                            // API.setVariable("editedRange",API.getVariable('currentNmr'),["range"]);
                        }
                    }
                    break;
                default:
                    return false;
            }
            return true;
        }

        _doAssignment(currentNmr) {
            currentNmr.getChild(['jcamp', 'data']).then((jcamp) => {
                jcamp = String(jcamp.get());
                var ppOptions = API.getData("nmr1hOptions").resurrect();
                var spectrum = SD.NMR.fromJcamp(jcamp);
                var intFN = 0;
                if(ppOptions.integralFn=="peaks"){
                    intFN=1;
                }
                var peakPicking = spectrum.nmrPeakDetection({
                    nH:ppOptions.integral,
                    realTop:true,
                    thresholdFactor:ppOptions.noiseFactor,
                    clean:ppOptions.clean,
                    compile:ppOptions.compile,
                    optimize:ppOptions.optimize,
                    integralFn:intFN,
                    idPrefix:spectrum.getNucleus()+"",
                    gsdOptions:{minMaxRatio:0.001, smoothY:false, broadWidth:0},
                    format:"new"
                });
                currentNmr.setChildSync(['range'], peakPicking);
                this._createNMRannotations(
                    {
                        nucleus: currentNmr.nucleus[0],
                        observe:Math.round(currentNmr.frequency/10)*10
                    }
                );
            });
        }

        _createNMRannotations(options) {
            console.log('create annoations');
            var peakPicking = JSON.parse(JSON.stringify(API.getData("currentNmrRanges")));

            //Recompile multiplicity
            for (var i=0; i<peakPicking.length; i++){
                var peak = peakPicking[i];
                for (var j=0; j<peak.signal.length; j++){
                    var signal = peak.signal[j];
                    if (signal.j) {
                        signal.multiplicity = "";
                        for (var k=0; k<signal.j.length;k++){
                            signal.multiplicity+=signal.j[k].multiplicity;
                        }
                    }
                }
            }

            API.createData("annotationsNMR1d", SD.GUI.annotations1D(peakPicking, {
                line:1,
                fillColor:"green",
                strokeWidth:0
            }));
            API.createData("acsNMR1d",SD.formatter.toACS(peakPicking, {
                rangeForMultiplet:true,
                nucleus:options.nucleus,
                observe:options.observe
            }));
        }

        initializeNMRAssignment() {
            var promise = Promise.resolve();
            promise = promise.then(() => API.createData('nmr1hOptions', {
                    "noiseFactor": 0.8,
                    "clean": true,
                    "compile": true,
                    "optimize": false,
                    "integralFn": "sum",
                    "integral": 30,
                    "type": "1H"
                })
            );

            promise=promise.then(() => API.createData('nmr1hOndeTemplates', {
                "full": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        },
                        "noiseFactor": {
                            "type": "number",
                            "title": "Mutiplier of the auto-detected noise level",
                            "label": "noiseFactor"
                        },
                        "clean": {
                            "type": "boolean",
                            "title": "Delete signals with integration less than 0.5",
                            "label": "clean"
                        },
                        "compile": {
                            "type": "boolean",
                            "title": "Compile the multiplets",
                            "label": "compile"
                        },
                        "optimize": {
                            "type": "boolean",
                            "title": "Optimize the peaks to fit the spectrum",
                            "label": "optimize"
                        },
                        "integralFn": {
                            "type": "string",
                            "title": "Type of integration",
                            "label": "Integral type",
                            "enum": [
                                "sum",
                                "peaks"
                            ]
                        },
                        "type": {
                            "type": "string",
                            "title": "Nucleus",
                            "label": "Nucleus",
                            "editable": false
                        }
                    }
                },
                "short": {
                    "type": "object",
                    "properties": {
                        "integral": {
                            "type": "number",
                            "title": "value to fit the spectrum integral",
                            "label": "Integral"
                        }
                    }
                }
            }));
            promise=promise.then((nmr1hOndeTemplates) => API.createData('nmr1hOndeTemplate', nmr1hOndeTemplates.short));
            return promise;
        }
    }

    return Nmr1dManager;
});

<|endoftext|>


<commit_before>module.exports = function () {

  var path           = require('path'),
      Promise        = require('bluebird'),
      SessionManager = require('../session-manager.js'),
      chaiAsPromised = require('chai-as-promised'),
      log            = require('../log'),
      fs             = require('fs-extra');

  var passed = true;

  this.registerHandler('BeforeFeatures', function (event, callback) {

    log.debug('[chimp][hooks] Starting BeforeFeatures');

    var setupBrowser = Promise.promisify(function (callback) {

      log.debug('[chimp][world] getting browser');
      var configPath = path.resolve(process.cwd(), process.env['chimp.path'], 'chimp.js');

      var _translateLogLevel = function () {
        if (process.env['chimp.log'] === 'info' ||
          process.env['chimp.log'] === 'warn' ||
          process.env['chimp.log'] === 'error') {
          return 'silent'
        }
        return process.env['chimp.log'];
      };

      var browser;

      global.sessionManager = new SessionManager({
        port: process.env['chimp.port'],
        browser: process.env['chimp.browser'],
        deviceName: process.env['chimp.deviceName']
      });

      var setBrowser = function (err, res) {
        global.browser = res;
        chaiAsPromised.transferPromiseness = global.browser.transferPromiseness;
        callback(err, res)
      };

      if (fs.existsSync(configPath)) {
        // load monkey webdriver configuration
        browser = require(configPath)(global.sessionManager, setBrowser);

      } else {
        log.debug('[chimp][world] custom chimp.js not found, loading defaults');
        var webdriverOptions = {
          waitforTimeout: parseInt(process.env['chimp.waitForTimeout']),
          desiredCapabilities: {
            browserName: process.env['chimp.browser'],
            platform: process.env['chimp.platform'],
            name: process.env['chimp.name']
          },
          user: process.env['chimp.user'] || process.env.SAUCE_USERNAME,
          key: process.env['chimp.key'] || process.env.SAUCE_ACCESS_KEY,
          host: process.env['chimp.host'],
          port: process.env['chimp.port'],
          logLevel: _translateLogLevel(),
          screenshotPath: process.env['chimp.screenshotPath']
        };
        log.debug('[chimp][world] webdriverOptions are ', JSON.stringify(webdriverOptions));

        global.sessionManager.remote(webdriverOptions, setBrowser);
      }

    });

    var initBrowser = Promise.promisify(function (callback) {
      log.debug('[chimp][hooks] init browser');
      global.browser.init(function () {

        log.debug('[chimp][hooks] init browser callback');

        global.browser.screenshotsCount = 0;
        global.browser.addCommand('capture', function (name, captureCallback) {
          var location = (global.browser.screenshotsCount++) + '-' + name + '_' + new Date().getTime() + '.png';
          fs.mkdirsSync(process.env['chimp.screenshotsPath']);
          var ssPath = path.join(process.env['chimp.screenshotsPath'], location);
          log.debug('[chimp][hooks] saving screenshot to', ssPath);
          return this.saveScreenshot(ssPath, false,
            function () {
              log.debug('[chimp][hooks] saved screenshot to', ssPath);
              captureCallback();
            });
        });

        global.browser.timeoutsAsyncScript(parseInt(process.env['chimp.timeoutsAsyncScript']), function () {
          log.debug('[chimp][hooks] set timeoutsAsyncScript');
          callback();
        });

        if (process.env['chimp.browser'] === 'phantomjs') {
          global.browser.setViewportSize({
            width: process.env['chimp.phantom_w'] || 1280,
            height: process.env['chimp.phantom_h'] || 1024
          });
        }
      });

    });

    var setupDdp = function (callback) {
      log.debug('[chimp][hooks] setup DDP');
      if (process.env['chimp.ddp']) {
        log.debug('[chimp][hooks] connecting via DDP to', process.env['chimp.ddp']);
        return global.ddp.connect(function (error) {
          if (error) {
            callback(error);
          } else {
            callback();
          }
        });
      } else {
        log.debug('[chimp][hooks] DDP not required');
        // worthless http://en.wiktionary.org/wiki/empty_promise
        Promise.promisify(function () {});
      }
    };

    setupBrowser().then(function () {
      return Promise.all([
        initBrowser(),
        setupDdp()
      ])
    }).then(
      function () {
        log.debug('[chimp][hooks] Finished BeforeFeatures');
        if (this.UserDefinedBeforeFeatures) {
          log.debug('[chimp][hooks] User-defined BeforeFeatures found, calling');
          global.UserDefinedBeforeFeatures.apply(this, [function () {
            callback();
          }]);
        } else {
          log.debug('[chimp][hooks] User-defined BeforeFeatures not found, finishing up');
          callback();
        }
      },
      function (error) {
        log.error('[chimp][hooks] BeforeFeatures hook had error');
        log.error(error);
        process.exit(2);
      }
    )

  });

  /**
   * Store browser test status so we can notify SauceLabs
   *
   * @param {Function} event
   * @param {Function} callback
   */
  this.StepResult(function (event, callback) {
    var stepResult = event.getPayloadItem('stepResult');
    if (process.env['chimp.screenshotsOnError'] !== 'false' && !stepResult.isSuccessful()) {
      log.debug('[chimp][hooks] step failed - capturing screenshot');
      global.browser.capture('step_failed', callback);
    } else {
      callback();
    }

  });

  /**
   * After features have run we close the browser and optionally notify
   * SauceLabs
   *
   * @param {Function} event
   * @param {Function} callback
   */
  this.registerHandler('AfterFeatures', function (event, callback) {
    log.debug('[chimp][hooks] Starting AfterFeatures');

    var done = function () {
      log.debug('[chimp][hooks] Finished AfterFeatures');
      callback();
    };
    if (process.env['chimp.browser'] !== 'phantomjs') {
      log.debug('[chimp][hooks] Ending browser session');

      global.sessionManager.killCurrentSession(function () {
        log.debug('[chimp][hooks] Ended browser sessions');
        done();
      });

    } else {
      done();
    }

  });

  process.on('unhandledRejection', function (reason /*, promise*/) {
    log.error('[chimp] Detected an unhandledRejection. Reason:');
    log.error(reason);
    log.error('[chimp][hooks] Forcibly exiting Cucumber');
    process.send(JSON.stringify(reason));
    process.exit(2);
  });

  process.on('SIGINT', function () {
    log.debug('[chimp][hooks] Received SIGINT process event, ending browser session');
    global.browser.
      end().
      then(function () {
        log.debug('[chimp][hooks] ended browser session');
        process.exit();
      });
  });

};
<commit_msg>Improved error reporting<commit_after>module.exports = function () {

  var path           = require('path'),
      Promise        = require('bluebird'),
      SessionManager = require('../session-manager.js'),
      chaiAsPromised = require('chai-as-promised'),
      log            = require('../log'),
      fs             = require('fs-extra');

  var passed = true;

  this.registerHandler('BeforeFeatures', function (event, callback) {

    log.debug('[chimp][hooks] Starting BeforeFeatures');

    var setupBrowser = Promise.promisify(function (callback) {

      log.debug('[chimp][world] getting browser');
      var configPath = path.resolve(process.cwd(), process.env['chimp.path'], 'chimp.js');

      var _translateLogLevel = function () {
        if (process.env['chimp.log'] === 'info' ||
          process.env['chimp.log'] === 'warn' ||
          process.env['chimp.log'] === 'error') {
          return 'silent'
        }
        return process.env['chimp.log'];
      };

      var browser;

      global.sessionManager = new SessionManager({
        port: process.env['chimp.port'],
        browser: process.env['chimp.browser'],
        deviceName: process.env['chimp.deviceName']
      });

      var setBrowser = function (err, res) {
        global.browser = res;
        chaiAsPromised.transferPromiseness = global.browser.transferPromiseness;
        callback(err, res)
      };

      if (fs.existsSync(configPath)) {
        // load monkey webdriver configuration
        browser = require(configPath)(global.sessionManager, setBrowser);

      } else {
        log.debug('[chimp][world] custom chimp.js not found, loading defaults');
        var webdriverOptions = {
          waitforTimeout: parseInt(process.env['chimp.waitForTimeout']),
          desiredCapabilities: {
            browserName: process.env['chimp.browser'],
            platform: process.env['chimp.platform'],
            name: process.env['chimp.name']
          },
          user: process.env['chimp.user'] || process.env.SAUCE_USERNAME,
          key: process.env['chimp.key'] || process.env.SAUCE_ACCESS_KEY,
          host: process.env['chimp.host'],
          port: process.env['chimp.port'],
          logLevel: _translateLogLevel(),
          screenshotPath: process.env['chimp.screenshotPath']
        };
        log.debug('[chimp][world] webdriverOptions are ', JSON.stringify(webdriverOptions));

        global.sessionManager.remote(webdriverOptions, setBrowser);
      }

    });

    var initBrowser = Promise.promisify(function (callback) {
      log.debug('[chimp][hooks] init browser');
      global.browser.init(function () {

        log.debug('[chimp][hooks] init browser callback');

        global.browser.screenshotsCount = 0;
        global.browser.addCommand('capture', function (name, captureCallback) {
          var location = (global.browser.screenshotsCount++) + '-' + name + '_' + new Date().getTime() + '.png';
          fs.mkdirsSync(process.env['chimp.screenshotsPath']);
          var ssPath = path.join(process.env['chimp.screenshotsPath'], location);
          log.debug('[chimp][hooks] saving screenshot to', ssPath);
          return this.saveScreenshot(ssPath, false,
            function () {
              log.debug('[chimp][hooks] saved screenshot to', ssPath);
              captureCallback();
            });
        });

        global.browser.timeoutsAsyncScript(parseInt(process.env['chimp.timeoutsAsyncScript']), function () {
          log.debug('[chimp][hooks] set timeoutsAsyncScript');
          callback();
        });

        if (process.env['chimp.browser'] === 'phantomjs') {
          global.browser.setViewportSize({
            width: process.env['chimp.phantom_w'] || 1280,
            height: process.env['chimp.phantom_h'] || 1024
          });
        }
      });

    });

    var setupDdp = function (callback) {
      log.debug('[chimp][hooks] setup DDP');
      if (process.env['chimp.ddp']) {
        log.debug('[chimp][hooks] connecting via DDP to', process.env['chimp.ddp']);
        return global.ddp.connect(function (error) {
          if (error) {
            log.error('[chimp][hooks] connecting via DDP error', error);
            callback(error);
          } else {
            log.error('[chimp][hooks] connecting via DDP had no error');
            callback();
          }
        });
      } else {
        log.debug('[chimp][hooks] DDP not required');
        // worthless http://en.wiktionary.org/wiki/empty_promise
        Promise.promisify(function () {});
      }
    };

    setupBrowser().then(function () {
      return Promise.all([
        initBrowser(),
        setupDdp()
      ])
    }).then(
      function () {
        log.debug('[chimp][hooks] Finished BeforeFeatures');
        if (this.UserDefinedBeforeFeatures) {
          log.debug('[chimp][hooks] User-defined BeforeFeatures found, calling');
          global.UserDefinedBeforeFeatures.apply(this, [function () {
            callback();
          }]);
        } else {
          log.debug('[chimp][hooks] User-defined BeforeFeatures not found, finishing up');
          callback();
        }
      },
      function (error) {
        log.error('[chimp][hooks] BeforeFeatures hook had error');
        log.error(error);
        process.exit(2);
      }
    )

  });

  /**
   * Store browser test status so we can notify SauceLabs
   *
   * @param {Function} event
   * @param {Function} callback
   */
  this.StepResult(function (event, callback) {
    var stepResult = event.getPayloadItem('stepResult');
    if (process.env['chimp.screenshotsOnError'] !== 'false' && !stepResult.isSuccessful()) {
      log.debug('[chimp][hooks] step failed - capturing screenshot');
      global.browser.capture('step_failed', callback);
    } else {
      callback();
    }

  });

  /**
   * After features have run we close the browser and optionally notify
   * SauceLabs
   *
   * @param {Function} event
   * @param {Function} callback
   */
  this.registerHandler('AfterFeatures', function (event, callback) {
    log.debug('[chimp][hooks] Starting AfterFeatures');

    var done = function () {
      log.debug('[chimp][hooks] Finished AfterFeatures');
      callback();
    };
    if (process.env['chimp.browser'] !== 'phantomjs') {
      log.debug('[chimp][hooks] Ending browser session');

      global.sessionManager.killCurrentSession(function () {
        log.debug('[chimp][hooks] Ended browser sessions');
        done();
      });

    } else {
      done();
    }

  });

  process.on('unhandledRejection', function (reason /*, promise*/) {
    log.error('[chimp] Detected an unhandledRejection. Reason:');
    log.error(reason);
    log.error('[chimp][hooks] Forcibly exiting Cucumber');
    process.send(JSON.stringify(reason));
    process.exit(2);
  });

  process.on('SIGINT', function () {
    log.debug('[chimp][hooks] Received SIGINT process event, ending browser session');
    global.browser.
      end().
      then(function () {
        log.debug('[chimp][hooks] ended browser session');
        process.exit();
      });
  });

};
<|endoftext|>


<commit_before>/**
 * VTK-Web Widget Library.
 *
 * This module extend jQuery object to add support for graphical components
 * related to File Browsing.
 *
 * @class jQuery.vtk.ui.FileBrowser
 */
(function ($) {

    // =======================================================================
    // ==== Defaults constant values =========================================
    // =======================================================================
    var pathSeparator = '/',
    directives = {
         '.vtk-directory': {
            'directory <-': {
                '@path': function(arg) {
                    return pathToStr(arg.item.path);
                },
                '@class+': function(arg) {
                    return (arg.item.path.length === 1) ? ' active' : '';
                },
                '.vtk-label': 'directory.label',
                'li.vtk-files': {
                    'file <- directory.files': {
                        'div': 'file.label'
                    }
                },
                'li.vtk-dirs': {
                    'dir <- directory.dirs': {
                        'div': 'dir'
                    }
                },
                'li.vtk-path': {
                    'i <- directory.path': {
                        'div': 'i'
                    }//,
                    // filter : function(a) {
                    //     return a.pos < (a.items.length - 1);
                    // }
                }
            }
        }
    },
    fileBrowserGenerator = null;

    $.fn.fileBrowser = function(options) {
        // Handle data with default values
        var opts = $.extend({},$.fn.fileBrowser.defaults, options);

        // Compile template only once
        if(fileBrowserGenerator === null) {
            template = $(opts.template);
            fileBrowserGenerator = template.compile(directives);
        }

        return this.each(function() {
            var me = $(this).empty().addClass('vtk-filebrowser'),
            container = $('<div/>');
            me.append(container);
            me.data('file-list', opts.data);
            me.data('session', opts.session);

            // Generate HTML
            container.render(opts.data, fileBrowserGenerator);

            // Initialize pipelineBrowser (Visibility + listeners)
            initializeListener(me);
        });
    };

    $.fn.updateFileBrowser = function(activeDirectory) {

        return this.each(function() {
            var me = $(this).empty(),
            data = me.data('file-list'),
            container = $('<div/>');
            me.append(container);

            // Generate HTML
            container.render(data, fileBrowserGenerator);

            // Initialize pipelineBrowser (Visibility + listeners)
            initializeListener(me, activeDirectory);
        });
    };

    $.fn.fileBrowser.defaults = {
        template: "#vtk-templates > .vtkweb-widget-filebrowser > div",
        session: null,
        data: [
            { 'label': 'Root', 'path': ['Root'], 'files': [
                {'label': 'can.ex2', 'size': 2345},
                {'label': 'diskout.ex2', 'size': 23345},
            ], 'dirs': ['Cosmo', 'Ensight']},
            { 'label': 'Cosmo',
              'path': ['Root','Cosmo'],
              'files': [
                {'label': 'can.ex2', 'size': 2345},
                {'label': 'diskout.ex2', 'size': 23345},
              ],
              'dirs': ['a','b','c'] },
            { 'label': 'Ensight',
              'path': ['Root','Ensight'],
              'files': [
                {'label': 'can.case', 'size': 2345},
                {'label': 'diskout.case', 'size': 23345},
              ],
              'dirs': [] },
            { 'label': 'a',
               'path': ['Root','Cosmo', 'a'],
               'files': [
                {'label': 'x', 'size': 2345},
                {'label': 'y', 'size': 23345},
               ],
               'dirs': []}
        ]
    };

    // =======================================================================

    function strToPath(pathId) {
        var path = pathId.split(pathSeparator);
        return path.slice(1, path.length);
    }

    // =======================================================================

    function getParent(path) {
        return path.slice(0, path.length - 2);
    }

    // =======================================================================

    function getPath(parentPath, child) {
        return [].concat(parentPath).concat(child);
    }

    // =======================================================================

    function pathToStr(path) {
        //console.log(path);
        var str = pathSeparator + path.join(pathSeparator);
        return str;
    }

    // =======================================================================

    function getRelativePath(parentPath, fileName) {
        return '.' + pathToStr(getPath(parentPath, fileName).slice(1));
    }

    // =======================================================================

    function initializeListener(container, activePath) {
        $('.action', container).click(function(){
            var me = $(this), item = $('div', me), pathStr = me.closest('.vtk-directory').attr('path'), type = me.closest('ul').attr('type');

            if(type === 'path') {
                // Find out the panel to show
                var newPath = pathToStr(strToPath(pathStr).slice(0, me.index() + 1)),
                selector = '.vtk-directory[path="' + newPath + '"]';
                var newActive = $(selector , container).addClass('active');
                if(newActive.length === 1) {
                     $('.vtk-directory', container).removeClass('active');
                     newActive.addClass('active');
                }
            } else if(type === 'dir') {
                // Swicth active panel
                var str = '.vtk-directory[path="' + pathStr + pathSeparator + item.html() + '"]';
                var newActive = $(str, container);
                if(newActive.length === 1) {
                    $('.vtk-directory', container).removeClass('active');
                    newActive.addClass('active');
                    container.trigger({
                        type: 'directory-click',
                        path: pathStr,
                        name: me.text(),
                        relativePath: getRelativePath(pathStr, me.text())
                    });
                } else {
                    if(container.data('session')) {
                        var relativePath = (pathStr + '/' + me.text());
                        container.data('session').call('vtk:listServerDirectory', relativePath.substring(1)).then(function(newFiles){
                            container.data('file-list').push(newFiles);
                            container.updateFileBrowser(relativePath);
                        });

                    }
                    container.trigger({
                        type: 'directory-not-found',
                        path: pathStr,
                        name: me.text(),
                        relativePath: getRelativePath(pathStr, me.text())
                    });
                }
            } else if(type === 'files') {
                container.trigger({
                    type: 'file-click',
                    path: pathStr,
                    name: me.text(),
                    relativePath: getRelativePath(pathStr, me.text())
                });
            }
        });
        if(activePath) {
            $('.vtk-directory',container).removeClass('active');
            $('.vtk-directory[path="' + activePath + '"]',container).addClass('active');
        }

    }

}(jQuery));<commit_msg>Fix vtkWeb file widget relative path info<commit_after>/**
 * VTK-Web Widget Library.
 *
 * This module extend jQuery object to add support for graphical components
 * related to File Browsing.
 *
 * @class jQuery.vtk.ui.FileBrowser
 */
(function ($) {

    // =======================================================================
    // ==== Defaults constant values =========================================
    // =======================================================================
    var pathSeparator = '/',
    directives = {
         '.vtk-directory': {
            'directory <-': {
                '@path': function(arg) {
                    return pathToStr(arg.item.path);
                },
                '@class+': function(arg) {
                    return (arg.item.path.length === 1) ? ' active' : '';
                },
                '.vtk-label': 'directory.label',
                'li.vtk-files': {
                    'file <- directory.files': {
                        'div': 'file.label'
                    }
                },
                'li.vtk-dirs': {
                    'dir <- directory.dirs': {
                        'div': 'dir'
                    }
                },
                'li.vtk-path': {
                    'i <- directory.path': {
                        'div': 'i'
                    }//,
                    // filter : function(a) {
                    //     return a.pos < (a.items.length - 1);
                    // }
                }
            }
        }
    },
    fileBrowserGenerator = null;

    $.fn.fileBrowser = function(options) {
        // Handle data with default values
        var opts = $.extend({},$.fn.fileBrowser.defaults, options);

        // Compile template only once
        if(fileBrowserGenerator === null) {
            template = $(opts.template);
            fileBrowserGenerator = template.compile(directives);
        }

        return this.each(function() {
            var me = $(this).empty().addClass('vtk-filebrowser'),
            container = $('<div/>');
            me.append(container);
            me.data('file-list', opts.data);
            me.data('session', opts.session);

            // Generate HTML
            container.render(opts.data, fileBrowserGenerator);

            // Initialize pipelineBrowser (Visibility + listeners)
            initializeListener(me);
        });
    };

    $.fn.updateFileBrowser = function(activeDirectory) {

        return this.each(function() {
            var me = $(this).empty(),
            data = me.data('file-list'),
            container = $('<div/>');
            me.append(container);

            // Generate HTML
            container.render(data, fileBrowserGenerator);

            // Initialize pipelineBrowser (Visibility + listeners)
            initializeListener(me, activeDirectory);
        });
    };

    $.fn.fileBrowser.defaults = {
        template: "#vtk-templates > .vtkweb-widget-filebrowser > div",
        session: null,
        data: [
            { 'label': 'Root', 'path': ['Root'], 'files': [
                {'label': 'can.ex2', 'size': 2345},
                {'label': 'diskout.ex2', 'size': 23345},
            ], 'dirs': ['Cosmo', 'Ensight']},
            { 'label': 'Cosmo',
              'path': ['Root','Cosmo'],
              'files': [
                {'label': 'can.ex2', 'size': 2345},
                {'label': 'diskout.ex2', 'size': 23345},
              ],
              'dirs': ['a','b','c'] },
            { 'label': 'Ensight',
              'path': ['Root','Ensight'],
              'files': [
                {'label': 'can.case', 'size': 2345},
                {'label': 'diskout.case', 'size': 23345},
              ],
              'dirs': [] },
            { 'label': 'a',
               'path': ['Root','Cosmo', 'a'],
               'files': [
                {'label': 'x', 'size': 2345},
                {'label': 'y', 'size': 23345},
               ],
               'dirs': []}
        ]
    };

    // =======================================================================

    function strToPath(pathId) {
        var path = pathId.split(pathSeparator);
        return path.slice(1, path.length);
    }

    // =======================================================================

    function getParent(path) {
        return path.slice(0, path.length - 2);
    }

    // =======================================================================

    function getPath(parentPath, child) {
        return [].concat(parentPath).concat(child);
    }

    // =======================================================================

    function pathToStr(path) {
        //console.log(path);
        var str = pathSeparator + path.join(pathSeparator);
        return str;
    }

    // =======================================================================

    function getRelativePath(parentPath, fileName) {
        return '.' + pathToStr(getPath(parentPath, fileName).slice(1));
    }

    // =======================================================================

    function initializeListener(container, activePath) {
        $('.action', container).click(function(){
            var me = $(this), item = $('div', me), pathStr = me.closest('.vtk-directory').attr('path'), type = me.closest('ul').attr('type');

            if(type === 'path') {
                // Find out the panel to show
                var newPath = pathToStr(strToPath(pathStr).slice(0, me.index() + 1)),
                selector = '.vtk-directory[path="' + newPath + '"]';
                var newActive = $(selector , container).addClass('active');
                if(newActive.length === 1) {
                     $('.vtk-directory', container).removeClass('active');
                     newActive.addClass('active');
                }
            } else if(type === 'dir') {
                // Swicth active panel
                var str = '.vtk-directory[path="' + pathStr + pathSeparator + item.html() + '"]';
                var newActive = $(str, container);
                if(newActive.length === 1) {
                    $('.vtk-directory', container).removeClass('active');
                    newActive.addClass('active');
                    container.trigger({
                        type: 'directory-click',
                        path: pathStr,
                        name: me.text(),
                        relativePath: getRelativePath(strToPath(pathStr), me.text())
                    });
                } else {
                    if(container.data('session')) {
                        var relativePath = (pathStr + '/' + me.text());
                        container.data('session').call('vtk:listServerDirectory', relativePath.substring(1)).then(function(newFiles){
                            container.data('file-list').push(newFiles);
                            container.updateFileBrowser(relativePath);
                        });

                    }
                    container.trigger({
                        type: 'directory-not-found',
                        path: pathStr,
                        name: me.text(),
                        relativePath: getRelativePath(strToPath(pathStr), me.text())
                    });
                }
            } else if(type === 'files') {
                container.trigger({
                    type: 'file-click',
                    path: pathStr,
                    name: me.text(),
                    relativePath: getRelativePath(strToPath(pathStr), me.text())
                });
            }
        });
        if(activePath) {
            $('.vtk-directory',container).removeClass('active');
            $('.vtk-directory[path="' + activePath + '"]',container).addClass('active');
        }

    }

}(jQuery));<|endoftext|>