<commit_before>'use strict'

const _ = require('lodash')
const co = require('co')
const pify = require('pify')
const fs = pify(require('fs'), { include: ['readFile'] })
const hookUtils = require('./hook-utils')
const Runner = require.main.require('nightwatch/lib/runner/run')
const ClientManager = require.main.require('nightwatch/lib/runner/clientmanager')
const ClientRunner = require.main.require('nightwatch/lib/runner/cli/clirunner')
const ChildProcess = require.main.require('nightwatch/lib/runner/cli/child-process')
const Utils = require.main.require('nightwatch/lib/util/utils')

process.on('unhandledRejection', (reason, p) => {
  console.error('Unhandled Rejection at: Promise', p, 'reason:', reason)
})

module.exports = class NightwatchApi {
  _startSession (options) {
    this.client = new ClientManager()
    this.client.init(options)
    this.client.api('currentEnv', options.currentEnv)

    patchEmitter(this.client)
  }

  * _closeSession () {
    yield new Promise((resolve, reject) => {
      this.client.get().on('nightwatch:finished', function () {
        resolve()
      })
      this.client.terminate()
    })
  }

  * takeScreenshot (moduleName, testName) {
    const filePath = Utils.getScreenshotFileName(
      {module: moduleName, name: testName},
      true,
      this.client.options.screenshots.path
    )

    yield new Promise((resolve, reject) => {
      console.log('Taking screenshot to ', filePath)
      this.client.get().api.saveScreenshot(filePath, function (result, err) {
        console.log('Screenshot creation result', result, err)
        if (err) return reject(err)
        resolve(result)
      })
      return this.client.get().start()
    })

    const content = yield fs.readFile(filePath, 'base64')
    console.log('Screenshot taken to ', filePath, content)

    return {
      data: new Buffer(content, 'base64'),
      mimeType: 'image/png'
    }
  }

  addTestModulePaths (modulePaths) {
    this.modulePaths = modulePaths
  }

  addPathConverter (convert, revert) {
    const self = this

    hookUtils.addHookBefore(ClientRunner.prototype, 'getTestSource', function () {
      self.originalSettings = _.cloneDeep(this.settings)
      if (this.argv._source.length) {
        this.argv._source[0] = convert(this.argv._source[0])
      } else if (this.argv.test) {
        this.argv.test = convert(this.argv.test)
      } else {
        this.settings.src_folders = this.settings.src_folders || []
        this.settings.src_folders = this.settings.src_folders.concat(self.modulePaths)
      }
      self.nightwatchArgv = this.argv
    })

    hookUtils.addHookBefore(ChildProcess.prototype, 'getArgs', function () {
      const cliArgs = this.args
      const testIndex = cliArgs.indexOf('--test') + 1
      cliArgs[testIndex] = revert(cliArgs[testIndex])
    })
  }

  addHookAfterChildProcesses (hook) {
    hookUtils.addCallbackedHookAfter(ClientRunner.prototype, 'startChildProcesses', 1, hook)
  }

  isRunningInParallel () {
    return process.env.__NIGHTWATCH_PARALLEL_MODE === '1'
  }

  getWorkerIndex () {
    return process.env.__NIGHTWATCH_ENV_KEY.split('_').pop()
  }

  * executeInNightwatchContext (fn, args) {
    yield new Promise((resolve, reject) => {
      const nightwatch = this.client.api()
      this.client.on('error', reject)
      nightwatch.perform(() => {
        try {
          this.client.get().results.lastError = null
          fn.apply(nightwatch, args)
        } catch (err) {
          this.client.removeListener('error', reject)
          return reject(err)
        }
      })
      nightwatch.perform(() => {
        this.client.removeListener('error', reject)
        const lastError = this.client.get().results.lastError
        if (lastError) {
          lastError.stack = [lastError.message, lastError.stack].join('\n')
          return reject(lastError)
        }
        resolve()
      })
      this.client.start()
    })
  }

  addTestRunner (run) {
    const self = this
    const originalRunnerRun = Runner.prototype.run

    Runner.prototype.run = co.wrap(function * () {
      const that = this
      let error
      let originalTerminate
      const originalOptions = _.cloneDeep(this.options)
      const originalAdditionalOpts = _.cloneDeep(this.additionalOpts)
      this.additionalOpts.output_folder = false
      this.options.output = false
      this.options.tag_filter = undefined
      this.options.screenshots.enabled = false

      try {
        const modules = yield new Promise((resolve, reject) => {
          Runner
            .readPaths(that.testSource, that.options)
            .spread(function (modulePaths, fullPaths) {
              resolve(modulePaths)
            }).then(resolve, reject)
        })
        self._startSession(this.options)
        const client = self.client.get()
        originalTerminate = client.terminate
        client.terminate = () => {}
        yield * run(modules)
      } catch (err) {
        error = err
        console.error(err.stack)
      }

      try {
        if (self.client) {
          self.client.get().terminate = originalTerminate
          yield * self._closeSession()
        }
      } catch (err) {
        error = err
        console.error(err.stack)
      }

      if (typeof process.send === 'function') {
        process.send(JSON.stringify({
          type: 'testsuite_finished',
          itemKey: process.env.__NIGHTWATCH_ENV_LABEL,
          moduleKey: 'moduleKey',
          results: {
            completed: {
              ok: 1
            }
          },
          errmessages: []
        }))
      }

      this.additionalOpts = originalAdditionalOpts
      this.options = originalOptions

      if (!self.originalSettings.src_folders || !self.originalSettings.src_folders.length || error) {
        return this.doneCb(null, {})
      }

      return originalRunnerRun.apply(this, arguments)
    })
  }
}

function patchEmitter (emitter) {
  const oldEmit = emitter.emit

  emitter.emit = function () {
    console.log('emit', arguments[0], arguments[1])
    oldEmit.apply(emitter, arguments)
  }
}
<commit_msg>chore(Improve screenshot creation):<commit_after>'use strict'

const _ = require('lodash')
const co = require('co')
const pify = require('pify')
const fs = pify(require('fs'), { include: ['readFile'] })
const hookUtils = require('./hook-utils')
const Runner = require.main.require('nightwatch/lib/runner/run')
const ClientManager = require.main.require('nightwatch/lib/runner/clientmanager')
const ClientRunner = require.main.require('nightwatch/lib/runner/cli/clirunner')
const ChildProcess = require.main.require('nightwatch/lib/runner/cli/child-process')
const Utils = require.main.require('nightwatch/lib/util/utils')
const Protocol = require.main.require('nightwatch/lib/api/protocol')

process.on('unhandledRejection', (reason, p) => {
  console.error('Unhandled Rejection at: Promise', p, 'reason:', reason)
})

module.exports = class NightwatchApi {
  _startSession (options) {
    this.client = new ClientManager()
    this.client.init(options)
    this.client.api('currentEnv', options.currentEnv)
    this.protocol = Protocol(this.client.get())

    patchEmitter(this.client)
  }

  * _closeSession () {
    yield new Promise((resolve, reject) => {
      this.client.get().on('nightwatch:finished', function () {
        resolve()
      })
      this.client.terminate()
    })
  }

  * takeScreenshot (moduleName, testName) {
    const filePath = Utils.getScreenshotFileName(
      {module: moduleName, name: testName},
      true,
      this.client.options.screenshots.path
    )

    yield new Promise((resolve, reject) => {
      console.log('Taking screenshot to ', filePath)
      this.protocol.screenshot(false, (response) => {
        if (response.state !== 'success') {
          reject(new Error('Creating screenshot was not successful. Response was:\n' + require('util').inspect(response)))
        }

        this.client.get().saveScreenshotToFile(filePath, response.value, (err) => {
          if (err) reject(err)
          resolve()
        })
      })
    })

    const content = yield fs.readFile(filePath, 'base64')
    console.log('Screenshot taken to ', filePath, content)

    return {
      data: new Buffer(content, 'base64'),
      mimeType: 'image/png'
    }
  }

  addTestModulePaths (modulePaths) {
    this.modulePaths = modulePaths
  }

  addPathConverter (convert, revert) {
    const self = this

    hookUtils.addHookBefore(ClientRunner.prototype, 'getTestSource', function () {
      self.originalSettings = _.cloneDeep(this.settings)
      if (this.argv._source.length) {
        this.argv._source[0] = convert(this.argv._source[0])
      } else if (this.argv.test) {
        this.argv.test = convert(this.argv.test)
      } else {
        this.settings.src_folders = this.settings.src_folders || []
        this.settings.src_folders = this.settings.src_folders.concat(self.modulePaths)
      }
      self.nightwatchArgv = this.argv
    })

    hookUtils.addHookBefore(ChildProcess.prototype, 'getArgs', function () {
      const cliArgs = this.args
      const testIndex = cliArgs.indexOf('--test') + 1
      cliArgs[testIndex] = revert(cliArgs[testIndex])
    })
  }

  addHookAfterChildProcesses (hook) {
    hookUtils.addCallbackedHookAfter(ClientRunner.prototype, 'startChildProcesses', 1, hook)
  }

  isRunningInParallel () {
    return process.env.__NIGHTWATCH_PARALLEL_MODE === '1'
  }

  getWorkerIndex () {
    return process.env.__NIGHTWATCH_ENV_KEY.split('_').pop()
  }

  * executeInNightwatchContext (fn, args) {
    yield new Promise((resolve, reject) => {
      const nightwatch = this.client.api()
      this.client.on('error', reject)
      nightwatch.perform(() => {
        try {
          this.client.get().results.lastError = null
          fn.apply(nightwatch, args)
        } catch (err) {
          this.client.removeListener('error', reject)
          return reject(err)
        }
      })
      nightwatch.perform(() => {
        this.client.removeListener('error', reject)
        const lastError = this.client.get().results.lastError
        if (lastError) {
          lastError.stack = [lastError.message, lastError.stack].join('\n')
          return reject(lastError)
        }
        resolve()
      })
      this.client.start()
    })
  }

  addTestRunner (run) {
    const self = this
    const originalRunnerRun = Runner.prototype.run

    Runner.prototype.run = co.wrap(function * () {
      const that = this
      let error
      let originalTerminate
      const originalOptions = _.cloneDeep(this.options)
      const originalAdditionalOpts = _.cloneDeep(this.additionalOpts)
      this.additionalOpts.output_folder = false
      this.options.output = false
      this.options.tag_filter = undefined
      this.options.screenshots.enabled = false

      try {
        const modules = yield new Promise((resolve, reject) => {
          Runner
            .readPaths(that.testSource, that.options)
            .spread(function (modulePaths, fullPaths) {
              resolve(modulePaths)
            }).then(resolve, reject)
        })
        self._startSession(this.options)
        const client = self.client.get()
        originalTerminate = client.terminate
        client.terminate = () => {}
        yield * run(modules)
      } catch (err) {
        error = err
        console.error(err.stack)
      }

      try {
        if (self.client) {
          self.client.get().terminate = originalTerminate
          yield * self._closeSession()
        }
      } catch (err) {
        error = err
        console.error(err.stack)
      }

      if (typeof process.send === 'function') {
        process.send(JSON.stringify({
          type: 'testsuite_finished',
          itemKey: process.env.__NIGHTWATCH_ENV_LABEL,
          moduleKey: 'moduleKey',
          results: {
            completed: {
              ok: 1
            }
          },
          errmessages: []
        }))
      }

      this.additionalOpts = originalAdditionalOpts
      this.options = originalOptions

      if (!self.originalSettings.src_folders || !self.originalSettings.src_folders.length || error) {
        return this.doneCb(null, {})
      }

      return originalRunnerRun.apply(this, arguments)
    })
  }
}

function patchEmitter (emitter) {
  const oldEmit = emitter.emit

  emitter.emit = function () {
    console.log('emit', arguments[0], arguments[1])
    oldEmit.apply(emitter, arguments)
  }
}
<|endoftext|>


<commit_before>//var BigNumber = require("bignumber.js");

function Packet(id, buffer, start, end)
{
  this.sequenceId = id;
  this.buffer = buffer;
  this.offset = start;
  this.start = start;
  this.end = end;
}

// ==============================
// readers
// ==============================

Packet.prototype.reset = function() {
  this.offset = this.start;
};

Packet.prototype.length = function() {
  return this.end - this.start;
};

Packet.prototype.dump = function() {
  console.log([this.buffer.asciiSlice(this.start, this.end)], this.buffer.slice(this.start, this.end), this.length(), this.sequenceId);
};

Packet.prototype.haveMoreData = function() {
  return this.end > this.offset;
};

Packet.prototype.skip = function(num) {
   if (!num)
     throw "Bad param in skip!"; // for some reason I keep doing skip(0) to indicate "skip one byte which should be 0"
   this.offset += num;
};

Packet.prototype.readInt8 = function()
{
  return this.buffer[this.offset++];
};

Packet.prototype.readInt16 = function()
{
  this.offset += 2;
  return this.buffer.readUInt16LE(this.offset - 2);
};

Packet.prototype.readInt32 = function()
{
  this.offset += 4;
  return this.buffer.readUInt32LE(this.offset - 4);
};

Packet.prototype.isEOF = function() {
  return this.buffer[this.offset] == 0xfe && this.length() < 9;
};

Packet.prototype.readLengthCodedNumber = function() {
   var byte1 = this.readInt8();
   if (byte1 < 0xfb)
     return byte1;
   if (byte1 == 0xfc) {
     return this.readInt8() + (this.readInt8() << 8);
   }
   if (byte1 == 0xfd) {
     return this.readInt8() + (this.readInt8() << 8) + (this.readInt8() << 16);
   }
   if (byte1 == 0xfe) {
     console.trace();
     //throw "Implement 8bytes BigNumber";
   }
   if (byte1 == 0xfb)
     return null;
   throw "Should not reach here: " + byte1;
};

Packet.prototype.readFloat = function() {
  var res = this.buffer.readFloatLE(this.offset);
  this.offset += 4;
  return res;
};

Packet.prototype.readDouble = function() {
  var res = this.buffer.readDoubleLE(this.offset);
  this.offset += 8;
  return res;
};

Packet.prototype.readBuffer = function(len) {
  this.offset += len;
  return this.buffer.slice(this.offset - len, this.offset);
};

// DATE, DATETIME and TIMESTAMP
Packet.prototype.readDateTime = function(convertTtoMs) {
  var length = this.readInt8();
  var y = 0;
  var m = 0;
  var d = 0;
  var H = 0;
  var M = 0;
  var S = 0;
  var ms = 0;
  if (length > 3) {
    y = this.readInt16();
    m = this.readInt8();
    d = this.readInt8();
  }
  if (length > 6) {
    H = this.readInt8();
    M = this.readInt8();
  }
  if (length > 11)
    ms = this.readInt32();
  return new Date(y, m, d, H, M, S, ms);
};

// TIME - value in microseconds. Can be negative
Packet.prototype.readTime = function(convertTtoMs) {
  var length = this.readInt8();
  if (length === 0)
    return 0;

  var result = 0;
  var sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte
  var d = 0;
  var H = 0;
  var M = 0;
  var S = 0;
  var ms = 0;
  if (length > 7) {
    d = this.readInt32();
    H = this.readInt8();
    M = this.readInt8();
    S = this.readInt8();
  }
  if (length > 11)
    ms = this.readInt32();
  return d*86400000 + H*3600000 + M*60000 + S*1000 + ms;
};

Packet.prototype.readLengthCodedString = function() {
  var len = this.readLengthCodedNumber();
  // TODO: check manually first byte here to avoid polymorphic return type?
  //if (len === null)
  //  return null;
  this.offset += len;
  return this.buffer.utf8Slice(this.offset - len, this.offset);
};

Packet.prototype.readNullTerminatedString = function() {
  var start = this.offset;
  var end = this.offset;
  while (this.buffer[end])
    end = end + 1; // TODO: handle OOB check
  this.offset = end + 1;
  return this.buffer.utf8Slice(start, end);
};

// TODO reuse?
Packet.prototype.readString = function(len) {
  this.offset += len;
  return this.buffer.utf8Slice(this.offset - len, this.offset);
};

var minus = '-'.charCodeAt(0);
var plus = '+'.charCodeAt(0);
// TODO: base? sign? parseFloat?
Packet.prototype.parseInt = function(len) {
  var result = 0;
  var end = this.offset + len;
  var sign = 1;
  if (len === 0)
    return 0; // TODO: assert? exception?
  if (this.buffer[this.offset] == minus) {
    this.offset++;
    sign = -1;
  }
  if (this.buffer[this.offset] == plus) {
    this.offset++; // just ignore
  }
  while(this.offset < end) {
    result *= 10;
    result += this.buffer[this.offset] - 48;
    this.offset++;
  }
  return result*sign;
};

// TODO: handle E notation
var dot = '.'.charCodeAt(0);
var exponent = 'e'.charCodeAt(0);
var exponentCapital = 'E'.charCodeAt(0);
Packet.prototype.parseFloat = function(len) {
  var result = 0;
  var end = this.offset + len;
  var factor = 1;
  var pastDot = false;
  var charCode = 0;
  if (len === 0)
    return 0; // TODO: assert? exception?

  if (this.buffer[this.offset] == minus) {
    this.offset++;
    factor = -1;
  }
  if (this.buffer[this.offset] == plus) {
    this.offset++; // just ignore
  }
  while(this.offset < end) {
    charCode = this.buffer[this.offset];
    if (charCode == dot)
    {
      pastDot = true;
      this.offset++;
    } else if (charCode == exponent || charCode == exponentCapital) {
      debugger;
      this.offset++;
      var exponentValue = this.parseInt(end - this.offset);
      return (result/factor)*Math.pow(10, exponentValue);
    } else {
      result *= 10;
      result += this.buffer[this.offset] - 48;
      this.offset++;
      if (pastDot)
        factor = factor*10;
    }
  }
  return result/factor;
};

Packet.prototype.parseLengthCodedInt = function() {
  return this.parseInt(this.readLengthCodedNumber());
};

Packet.prototype.parseLengthCodedFloat = function() {
  return this.parseFloat(this.readLengthCodedNumber());
};

Packet.prototype.isError = function() {
  return this.buffer[this.offset] == 0xff;
};

Packet.prototype.asError = function() {
  this.offset = 1;
  var code = this.readInt8();
  var sqlState = this.readBuffer(7);
  var message = this.buffer.slice(this.offset);
  console.log('SqlState', sqlState.toString(), 'message', message.toString());
  var err = new Error(message.toString());
  err.code = this.code;
  return err;
};

Packet.lengthCodedNumberLength = function(n) {
   if (n < 0xfb)
     return 1;
   if (n < 0xffff)
     return 3;
   if (n < 0xffffff)
     return 5;
   else
     return 9;
};

Packet.prototype.writeInt32 = function(n) {
  this.buffer.writeUInt32LE(n, this.offset);
  this.offset += 4;
};

Packet.prototype.writeInt24 = function(n) {
  this.writeInt8(n & 0xff);
  this.writeInt16(n >> 8);
};

Packet.prototype.writeInt16 = function(n) {
  this.buffer.writeUInt16LE(n, this.offset);
  this.offset += 2;
};

Packet.prototype.writeInt8 = function(n) {
  this.buffer[this.offset] = n;
  this.offset++;
};

Packet.prototype.writeBuffer = function(b) {
  b.copy(this.buffer, this.offset);
  this.offset += b.length;
};

// TODO: refactor following three?
Packet.prototype.writeNullTerminatedString = function(s) {
  this.buffer.write(s, this.offset);
  this.offset += s.length;
  this.writeInt8(0);
};

Packet.prototype.writeString = function(s) {
  var bytes = Buffer.byteLength(s, 'utf8');
  this.buffer.write(s, this.offset, bytes, 'utf8');
  this.offset += bytes;
};

Packet.prototype.writeLengthCodedString = function(s) {
  this.writeLengthCodedNumber(s.length);
  this.buffer.write(s, this.offset);
  this.offset += s.length;
};

Packet.prototype.writeLengthCodedNumber = function(n) {
  // TODO: null
  if (n < 0xfb)
    return this.writeInt8(n);
  if (n < 0xffff) {
    this.writeInt8(0xfc);
    return this.writeInt16(n);
  }
  if (this < 0xffffff) {
    this.writeInt8(0xfd);
    return this.writeInt24(n);
  }
  throw "No bignumbers yet";
};

Packet.prototype.writeHeader = function()
{
  var offset = this.offset;
  this.offset = 0;
  this.writeInt24(this.buffer.length - 4);
  this.writeInt8(this.sequenceId);
  this.offset = offset;
};

// TODO: base toPacket() ?

module.exports = Packet;
<commit_msg>fixed asError using incorrect offset<commit_after>//var BigNumber = require("bignumber.js");

function Packet(id, buffer, start, end)
{
  this.sequenceId = id;
  this.buffer = buffer;
  this.offset = start;
  this.start = start;
  this.end = end;
}

// ==============================
// readers
// ==============================

Packet.prototype.reset = function() {
  this.offset = this.start;
};

Packet.prototype.length = function() {
  return this.end - this.start;
};

Packet.prototype.dump = function() {
  console.log([this.buffer.asciiSlice(this.start, this.end)], this.buffer.slice(this.start, this.end), this.length(), this.sequenceId);
};

Packet.prototype.haveMoreData = function() {
  return this.end > this.offset;
};

Packet.prototype.skip = function(num) {
   if (!num)
     throw "Bad param in skip!"; // for some reason I keep doing skip(0) to indicate "skip one byte which should be 0"
   this.offset += num;
};

Packet.prototype.readInt8 = function()
{
  return this.buffer[this.offset++];
};

Packet.prototype.readInt16 = function()
{
  this.offset += 2;
  return this.buffer.readUInt16LE(this.offset - 2);
};

Packet.prototype.readInt32 = function()
{
  this.offset += 4;
  return this.buffer.readUInt32LE(this.offset - 4);
};

Packet.prototype.isEOF = function() {
  return this.buffer[this.offset] == 0xfe && this.length() < 9;
};

Packet.prototype.readLengthCodedNumber = function() {
   var byte1 = this.readInt8();
   if (byte1 < 0xfb)
     return byte1;
   if (byte1 == 0xfc) {
     return this.readInt8() + (this.readInt8() << 8);
   }
   if (byte1 == 0xfd) {
     return this.readInt8() + (this.readInt8() << 8) + (this.readInt8() << 16);
   }
   if (byte1 == 0xfe) {
     console.trace();
     //throw "Implement 8bytes BigNumber";
   }
   if (byte1 == 0xfb)
     return null;
   throw "Should not reach here: " + byte1;
};

Packet.prototype.readFloat = function() {
  var res = this.buffer.readFloatLE(this.offset);
  this.offset += 4;
  return res;
};

Packet.prototype.readDouble = function() {
  var res = this.buffer.readDoubleLE(this.offset);
  this.offset += 8;
  return res;
};

Packet.prototype.readBuffer = function(len) {
  this.offset += len;
  return this.buffer.slice(this.offset - len, this.offset);
};

// DATE, DATETIME and TIMESTAMP
Packet.prototype.readDateTime = function(convertTtoMs) {
  var length = this.readInt8();
  var y = 0;
  var m = 0;
  var d = 0;
  var H = 0;
  var M = 0;
  var S = 0;
  var ms = 0;
  if (length > 3) {
    y = this.readInt16();
    m = this.readInt8();
    d = this.readInt8();
  }
  if (length > 6) {
    H = this.readInt8();
    M = this.readInt8();
  }
  if (length > 11)
    ms = this.readInt32();
  return new Date(y, m, d, H, M, S, ms);
};

// TIME - value in microseconds. Can be negative
Packet.prototype.readTime = function(convertTtoMs) {
  var length = this.readInt8();
  if (length === 0)
    return 0;

  var result = 0;
  var sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte
  var d = 0;
  var H = 0;
  var M = 0;
  var S = 0;
  var ms = 0;
  if (length > 7) {
    d = this.readInt32();
    H = this.readInt8();
    M = this.readInt8();
    S = this.readInt8();
  }
  if (length > 11)
    ms = this.readInt32();
  return d*86400000 + H*3600000 + M*60000 + S*1000 + ms;
};

Packet.prototype.readLengthCodedString = function() {
  var len = this.readLengthCodedNumber();
  // TODO: check manually first byte here to avoid polymorphic return type?
  //if (len === null)
  //  return null;
  this.offset += len;
  return this.buffer.utf8Slice(this.offset - len, this.offset);
};

Packet.prototype.readNullTerminatedString = function() {
  var start = this.offset;
  var end = this.offset;
  while (this.buffer[end])
    end = end + 1; // TODO: handle OOB check
  this.offset = end + 1;
  return this.buffer.utf8Slice(start, end);
};

// TODO reuse?
Packet.prototype.readString = function(len) {
  this.offset += len;
  return this.buffer.utf8Slice(this.offset - len, this.offset);
};

var minus = '-'.charCodeAt(0);
var plus = '+'.charCodeAt(0);
// TODO: base? sign? parseFloat?
Packet.prototype.parseInt = function(len) {
  var result = 0;
  var end = this.offset + len;
  var sign = 1;
  if (len === 0)
    return 0; // TODO: assert? exception?
  if (this.buffer[this.offset] == minus) {
    this.offset++;
    sign = -1;
  }
  if (this.buffer[this.offset] == plus) {
    this.offset++; // just ignore
  }
  while(this.offset < end) {
    result *= 10;
    result += this.buffer[this.offset] - 48;
    this.offset++;
  }
  return result*sign;
};

// TODO: handle E notation
var dot = '.'.charCodeAt(0);
var exponent = 'e'.charCodeAt(0);
var exponentCapital = 'E'.charCodeAt(0);
Packet.prototype.parseFloat = function(len) {
  var result = 0;
  var end = this.offset + len;
  var factor = 1;
  var pastDot = false;
  var charCode = 0;
  if (len === 0)
    return 0; // TODO: assert? exception?

  if (this.buffer[this.offset] == minus) {
    this.offset++;
    factor = -1;
  }
  if (this.buffer[this.offset] == plus) {
    this.offset++; // just ignore
  }
  while(this.offset < end) {
    charCode = this.buffer[this.offset];
    if (charCode == dot)
    {
      pastDot = true;
      this.offset++;
    } else if (charCode == exponent || charCode == exponentCapital) {
      this.offset++;
      var exponentValue = this.parseInt(end - this.offset);
      return (result/factor)*Math.pow(10, exponentValue);
    } else {
      result *= 10;
      result += this.buffer[this.offset] - 48;
      this.offset++;
      if (pastDot)
        factor = factor*10;
    }
  }
  return result/factor;
};

Packet.prototype.parseLengthCodedInt = function() {
  return this.parseInt(this.readLengthCodedNumber());
};

Packet.prototype.parseLengthCodedFloat = function() {
  return this.parseFloat(this.readLengthCodedNumber());
};

Packet.prototype.isError = function() {
  return this.buffer[this.offset] == 0xff;
};

Packet.prototype.asError = function() {
  this.reset();
  this.skip(1);

  var code = this.readInt8();
  var sqlState = this.readBuffer(7);
  var message = this.buffer.slice(this.offset);
  console.log('SqlState', sqlState.toString(), 'message', message.toString());
  var err = new Error(message.toString());
  err.code = this.code;
  return err;
};

Packet.lengthCodedNumberLength = function(n) {
   if (n < 0xfb)
     return 1;
   if (n < 0xffff)
     return 3;
   if (n < 0xffffff)
     return 5;
   else
     return 9;
};

Packet.prototype.writeInt32 = function(n) {
  this.buffer.writeUInt32LE(n, this.offset);
  this.offset += 4;
};

Packet.prototype.writeInt24 = function(n) {
  this.writeInt8(n & 0xff);
  this.writeInt16(n >> 8);
};

Packet.prototype.writeInt16 = function(n) {
  this.buffer.writeUInt16LE(n, this.offset);
  this.offset += 2;
};

Packet.prototype.writeInt8 = function(n) {
  this.buffer[this.offset] = n;
  this.offset++;
};

Packet.prototype.writeBuffer = function(b) {
  b.copy(this.buffer, this.offset);
  this.offset += b.length;
};

// TODO: refactor following three?
Packet.prototype.writeNullTerminatedString = function(s) {
  this.buffer.write(s, this.offset);
  this.offset += s.length;
  this.writeInt8(0);
};

Packet.prototype.writeString = function(s) {
  var bytes = Buffer.byteLength(s, 'utf8');
  this.buffer.write(s, this.offset, bytes, 'utf8');
  this.offset += bytes;
};

Packet.prototype.writeLengthCodedString = function(s) {
  this.writeLengthCodedNumber(s.length);
  this.buffer.write(s, this.offset);
  this.offset += s.length;
};

Packet.prototype.writeLengthCodedNumber = function(n) {
  // TODO: null
  if (n < 0xfb)
    return this.writeInt8(n);
  if (n < 0xffff) {
    this.writeInt8(0xfc);
    return this.writeInt16(n);
  }
  if (this < 0xffffff) {
    this.writeInt8(0xfd);
    return this.writeInt24(n);
  }
  throw "No bignumbers yet";
};

Packet.prototype.writeHeader = function()
{
  var offset = this.offset;
  this.offset = 0;
  this.writeInt24(this.buffer.length - 4);
  this.writeInt8(this.sequenceId);
  this.offset = offset;
};

// TODO: base toPacket() ?

module.exports = Packet;
<|endoftext|>


<commit_before>"use strict";

var Jingle = require('jingle');

var stanza = require('../stanza/jingle');
var rtp = require('../stanza/rtp');
var ice = require('../stanza/iceUdp');

module.exports = function (client) {
    var jingle = client.jingle = new Jingle();

    jingle.capabilities.forEach(function (cap) {
        client.disco.addFeature(cap);
    });

    var mappedEvents = [
        'outgoing', 'incoming', 'accepted', 'terminated',
        'ringing', 'mute', 'unmute', 'hold', 'resumed'
    ];
    mappedEvents.forEach(function (event) {
        jingle.on(event, function (session, arg1) {
            client.emit('jingle:' + event, session, arg1);
        });
    });

    jingle.on('localStream', function (stream) {
        client.emit('jingle:localstream:added', stream);
    });

    jingle.on('localStreamStopped', function () {
        client.emit('jingle:localstream:removed');
    });

    jingle.on('peerStreamAdded', function (session) {
        client.emit('jingle:remotestream:added', session);
    });

    jingle.on('peerStreamRemoved', function (session) {
        client.emit('jingle:remotestream:removed', session);
    });

    jingle.on('send', function (data) {
        client.sendIq(data);
    });

    client.on('iq:set:jingle', function (data) {
        data = data.toJSON();
        jingle.process(data);
    });

    client.on('unavailable', function (pres) {
        var peer = pres.from.full;
        jingle.endPeerSessions(peer);
    });

    client.call = function (peer) {
        peer = peer.full || peer;
        var sess = jingle.createMediaSession(peer);
        client.sendPresence({to: peer});
        sess.start();
        return sess;
    };

    client.discoverICEServers = function (cb) {
        return this.getServices(client.config.server).then(function (res) {
            var services = res.services.services;
            var discovered = [];

            for (var i = 0; i < services.length; i++) {
                var service = services[i];
                var ice = {};
                if (service.type === 'stun') {
                    ice.url = 'stun:' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                } else if (service.type === 'turn') {
                    ice.url = 'turn:' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    if (service.transport && service.transport !== 'udp') {
                        ice.url += '?transport=' + service.transport;
                    }

                    if (service.username) {
                        ice.username = service.username;
                    }
                    if (service.password) {
                        ice.credential = service.password;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                }
            }

            return discovered;
        }).nodeify(cb);
    };
};
<commit_msg>Update Jingle events to match latest jingle.js<commit_after>"use strict";

var Jingle = require('jingle');

var stanza = require('../stanza/jingle');
var rtp = require('../stanza/rtp');
var ice = require('../stanza/iceUdp');

module.exports = function (client) {
    var jingle = client.jingle = new Jingle();

    jingle.capabilities.forEach(function (cap) {
        client.disco.addFeature(cap);
    });

    var mappedEvents = [
        'outgoing', 'incoming', 'accepted', 'terminated',
        'ringing', 'mute', 'unmute', 'hold', 'resumed'
    ];
    mappedEvents.forEach(function (event) {
        jingle.on(event, function (session, arg1) {
            client.emit('jingle:' + event, session, arg1);
        });
    });

    jingle.on('localStream', function (stream) {
        client.emit('jingle:localstream:added', stream);
    });

    jingle.on('localStreamStopped', function () {
        client.emit('jingle:localstream:removed');
    });

    jingle.on('peerStreamAdded', function (session, stream) {
        client.emit('jingle:remotestream:added', session, stream);
    });

    jingle.on('peerStreamRemoved', function (session, stream) {
        client.emit('jingle:remotestream:removed', session, stream);
    });

    jingle.on('send', function (data) {
        client.sendIq(data);
    });

    client.on('iq:set:jingle', function (data) {
        data = data.toJSON();
        jingle.process(data);
    });

    client.on('unavailable', function (pres) {
        var peer = pres.from.full;
        jingle.endPeerSessions(peer);
    });

    client.call = function (peer) {
        peer = peer.full || peer;
        var sess = jingle.createMediaSession(peer);
        client.sendPresence({to: peer});
        sess.start();
        return sess;
    };

    client.discoverICEServers = function (cb) {
        return this.getServices(client.config.server).then(function (res) {
            var services = res.services.services;
            var discovered = [];

            for (var i = 0; i < services.length; i++) {
                var service = services[i];
                var ice = {};
                if (service.type === 'stun') {
                    ice.url = 'stun:' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                } else if (service.type === 'turn') {
                    ice.url = 'turn:' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    if (service.transport && service.transport !== 'udp') {
                        ice.url += '?transport=' + service.transport;
                    }

                    if (service.username) {
                        ice.username = service.username;
                    }
                    if (service.password) {
                        ice.credential = service.password;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                }
            }

            return discovered;
        }).nodeify(cb);
    };
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function (nitro) {

  var uglify = nitro.require('uglify-js'),
      _ = nitro.tools,
      color = require('../color');

  return function (list, options) {
    options = _.extend({ expand: true }, options || {}, { fromString: true });

    list.forEach(function (f) {
      var o = {}, result;
      o[f.path] = f.src;

      // @TODO imeplemt sourceMap
      // o[f.path] = f.src + f.map ? ( '//# sourceMappingURL=data:application/json;charset=utf-8;base64,' +  ) : '';
      // if( f.map ) console.log('map', typeof f.map );

      try{
        console.log('uglifing', color.yellow(f.path), f.src.split('\n').length );
        result = uglify.minify(o);

        if (result.error) throw result.error;

      } catch(err) {
        var code_lines = f.src.split('\n');

        console.log( '\n' + color.red(err.message) );
        console.log( '\nfile: ' + color.greyBright( f.cwd + ( /\/$/.test(f.cwd) ? '' : '/' ) ) + color.yellow(err.filename) );

        if( err.line ) {
          console.log( color.grey('\n--------------------------------------------------------------------------------') );
          console.log('line: ', color.cyan(err.line) + ' col: ' + color.magenta(err.col) );
          console.log( color.grey('--------------------------------------------------------------------------------\n') );
          console.log( code_lines.slice(err.line - 5, err.line).join('\n') );
        }

        if( err.col ) console.log(' '.repeat(err.col) + color.yellow('^') );
        console.log( color.grey('--------------------------------------------------------------------------------\n') );

        console.log('\n', err );

        throw err;
      }

      if( options.sourceMap ) {
        f.src = result.code.replace(/\n\/\/[^\n]+\.js\.map$/, '');
        f.map = result.map;
      } else {
        f.src = result.code;
      }

    });

    return list;

  };

};
<commit_msg>better uglify logs<commit_after>'use strict';

module.exports = function (nitro) {

  var uglify = nitro.require('uglify-js'),
      _ = nitro.tools,
      color = require('../color');

  return function (list, options) {
    options = _.extend({ expand: true }, options || {}, { fromString: true });

    list.forEach(function (f) {
      var o = {}, result;
      o[f.path] = f.src;

      // @TODO imeplemt sourceMap
      // o[f.path] = f.src + f.map ? ( '//# sourceMappingURL=data:application/json;charset=utf-8;base64,' +  ) : '';
      // if( f.map ) console.log('map', typeof f.map );

      try{
        console.log('uglifing', color.yellow(f.path), f.src.split('\n').length + color.grey(' lines') );
        result = uglify.minify(o);

        if (result.error) throw result.error;
        console.log('compressed', color.magenta(f.src.length) + color.grey(' => ') + color.magenta(result.code.length) );

      } catch(err) {
        var code_lines = f.src.split('\n');

        console.log( '\n' + color.red(err.message) );
        console.log( '\nfile: ' + color.grey( f.cwd + ( /\/$/.test(f.cwd) ? '' : '/' ) ) + color.yellow(err.filename) );

        if( err.line ) {
          console.log( color.grey('\n--------------------------------------------------------------------------------') );
          console.log('line: ', color.cyan(err.line) + ' col: ' + color.magenta(err.col) );
          console.log( color.grey('--------------------------------------------------------------------------------\n') );
          console.log( code_lines.slice(err.line - 5, err.line).join('\n') );
        }

        if( err.col ) console.log(' '.repeat(err.col) + color.yellow('^') );
        console.log( color.grey('--------------------------------------------------------------------------------\n') );

        console.log('\n', err );

        throw err;
      }

      if( options.sourceMap ) {
        f.src = result.code.replace(/\n\/\/[^\n]+\.js\.map$/, '');
        f.map = result.map;
      } else {
        f.src = result.code;
      }

    });

    return list;

  };

};
<|endoftext|>


<commit_before>'use strict';

var Processor = require('../processor');
var Batch = require('../batch');
var LessParser = require('less').Parser;

var processor = new Processor();

processor.getBatches = function(inputPaths) {
	return inputPaths.map(function(inputPath) {
		var outputPath = inputPath.replace(/\.less$/, '.css');
		return new Batch([ inputPath ], [ outputPath ]);
	});
};

processor.process = function(inputs, outputs) {
	var log = this.log;
	var input = inputs[0];
	var output = outputs[0];
	var text = input.data;

	var parser = new LessParser({
		paths: [ '.' ],
		filename: input.path
	});

	parser.parse(text, function (error, tree) {
		if (error) {
			output.reject(error.message + ' [' + error.filename + ':' + error.line + ':' + error.index + ']');
		} else {
			output.resolve(tree.toCSS({ compress: true }));
			log.ok('%s', output.path);
		}
	});

};

module.exports = processor;
<commit_msg>Disabled LESS compression and added some notes<commit_after>'use strict';

var Processor = require('../processor');
var Batch = require('../batch');
var LessParser = require('less').Parser;

var processor = new Processor();

processor.getBatches = function(inputPaths) {
	return inputPaths.map(function(inputPath) {
		var outputPath = inputPath.replace(/\.less$/, '.css');
		return new Batch([ inputPath ], [ outputPath ]);
	});
};

processor.process = function(inputs, outputs) {
	var log = this.log;
	var input = inputs[0];
	var output = outputs[0];
	var text = input.data;

	var parser = new LessParser({
		paths: [ '.' ],
		filename: input.path
	});

	parser.parse(text, function (error, tree) {
		if (error) {
			output.reject(error.message + ' [' + error.filename + ':' + error.line + ':' + error.index + ']');
		} else {
			// Note: For tree.toCSS() options see: https://github.com/less/less.js/blob/master/lib/less/env.js
			// I think compression might be better handled by another processor down the line
			// Once LESS supports sourcemaps when combined with clean-css that might be a better option instead
			output.resolve(tree.toCSS({ compress: false }));
			log.ok('%s', output.path);
		}
	});

};

module.exports = processor;
<|endoftext|>


<commit_before>/* eslint consistent-this: 0 */
'use strict';

var PluginError = require('gulp-util').PluginError;

/**
 * A ConfigurableRecipeFactory lookups or creates recipe function of the signature: `function (done)`.
 *
 * @param stuff
 * @constructor
 */
function ConfigurableRecipeFactory(stuff, registry) {
	this.stuff = stuff;
	this.registry = registry;
}

ConfigurableRecipeFactory.prototype.create = function (taskInfo) {
	var self;

	self = this;
	return pluginRecipe() || taskRecipe() || streamRecipe() || inlineRecipe() || referenceRecipe() || flowRecipe();

	function pluginRecipe() {
		return self.plugin(taskInfo);
	}

	function taskRecipe() {
		return self.task(taskInfo);
	}

	function streamRecipe() {
		return self.stream(taskInfo);
	}

	function inlineRecipe() {
		return self.inline(taskInfo);
	}

	function referenceRecipe() {
		return self.reference(taskInfo);
	}

	function flowRecipe() {
		return self.flow(taskInfo);
	}
};

ConfigurableRecipeFactory.prototype.flow = function (taskInfo) {
	var flows;

	flows = this.stuff.flows;
	return explicit() || implicit();

	function explicit() {
		var recipe;

		recipe = flows.lookup(taskInfo.name);
		if (recipe) {
			if (!taskInfo.visibility && taskInfo.name !== 'watch') {
				taskInfo.visibility = '.';
			}
			return recipe;
		}
	}

	function implicit() {
		if (Array.isArray(taskInfo.task)) {
			return flows.lookup('series');
		}
		return flows.lookup('parallel');
	}
};

ConfigurableRecipeFactory.prototype.inline = function (taskInfo) {
	var task;

	task = taskInfo.task;
	if (typeof taskInfo.task === 'function') {
		delete taskInfo.task;
		return task;
	}
};

ConfigurableRecipeFactory.prototype.noop = function () {
	return function (done) {
		done();
	};
};

ConfigurableRecipeFactory.prototype.plugin = function (taskInfo) {
	var plugin;

	if (typeof taskInfo.plugin === 'string') {
		plugin = require(taskInfo.plugin);
		return runner;
	}

	if (typeof taskInfo.plugin === 'function') {
		plugin = taskInfo.plugin;
		return runner;
	}

	function runner() {
		var context = this;
		var gulp = context.gulp;
		var config = context.config;
		var stream = context.upstream || gulp.src(config.src.globs, config.src.options);

		stream = stream.pipe(plugin(context.options));
		if (config.sprout) {
			stream = stream.pipe(gulp.dest(config.dest.path, config.dest.options));
		}
		return stream;
	}
}

ConfigurableRecipeFactory.prototype.reference = function (taskInfo) {
	var registry, name, recipe, result;

	// TODO: make sure when defined taskInfo.name, reference becomes that name task's child task.
	// if (taskInfo.name) {}

	registry = this.registry;
	name = taskInfo.task;
	if (typeof name === 'string') {
		delete taskInfo.task;
		if (!taskInfo.name && !taskInfo.visibility) {
			taskInfo.visibility = '.';
		}
		recipe = resolved() || pending();
		result = function (done) {
			return recipe.call(this, done);
		};
		result.displayName = name;
		result.description = taskInfo.description || recipe.description;
		return result;
	}

	function resolved() {
		var task;

		task = registry.refer(name);
		if (task) {
			return task.run || task;
		}
	}

	function pending() {
		return function (done) {
			var context, task;

			context = this;
			task = context.gulp.task(name);
			if (typeof task !== 'function') {
				throw new PluginError(__filename, 'referring task not found: ' + name);
			}
			// support for configurable task, or tasks registered directly via gulp.task().
			task = task.run || task;
			return task.call(context, done);
		};
	}
};

/**
 * if there is configurations not being consumed, then treat them as sub-tasks.
 */
ConfigurableRecipeFactory.prototype.stream = function (taskInfo) {
	var recipe;

	recipe = this.stuff.streams.lookup(taskInfo.name);
	if (recipe) {
		if (!taskInfo.visibility) {
			taskInfo.visibility = '.';
		}
		return recipe;
	}
};

/**
 * if there is a matching recipe, use it and ignore any sub-configs.
 */
ConfigurableRecipeFactory.prototype.task = function (taskInfo) {
	return this.stuff.tasks.lookup(taskInfo.name);
};

module.exports = ConfigurableRecipeFactory;
<commit_msg>add todo item<commit_after>/* eslint consistent-this: 0 */
'use strict';

var PluginError = require('gulp-util').PluginError;

/**
 * A ConfigurableRecipeFactory lookups or creates recipe function of the signature: `function (done)`.
 *
 * @param stuff
 * @constructor
 */
function ConfigurableRecipeFactory(stuff, registry) {
	this.stuff = stuff;
	this.registry = registry;
}

ConfigurableRecipeFactory.prototype.create = function (taskInfo) {
	var self;

	self = this;
	return pluginRecipe() || taskRecipe() || streamRecipe() || inlineRecipe() || referenceRecipe() || flowRecipe();

	function pluginRecipe() {
		return self.plugin(taskInfo);
	}

	function taskRecipe() {
		return self.task(taskInfo);
	}

	function streamRecipe() {
		return self.stream(taskInfo);
	}

	function inlineRecipe() {
		return self.inline(taskInfo);
	}

	function referenceRecipe() {
		return self.reference(taskInfo);
	}

	function flowRecipe() {
		return self.flow(taskInfo);
	}
};

ConfigurableRecipeFactory.prototype.flow = function (taskInfo) {
	var flows;

	flows = this.stuff.flows;
	return explicit() || implicit();

	function explicit() {
		var recipe;

		recipe = flows.lookup(taskInfo.name);
		if (recipe) {
			if (!taskInfo.visibility && taskInfo.name !== 'watch') {
				taskInfo.visibility = '.';
			}
			return recipe;
		}
	}

	function implicit() {
		if (Array.isArray(taskInfo.task)) {
			return flows.lookup('series');
		}
		return flows.lookup('parallel');
	}
};

ConfigurableRecipeFactory.prototype.inline = function (taskInfo) {
	var task;

	task = taskInfo.task;
	if (typeof taskInfo.task === 'function') {
		delete taskInfo.task;
		return task;
	}
};

ConfigurableRecipeFactory.prototype.noop = function () {
	return function (done) {
		done();
	};
};

ConfigurableRecipeFactory.prototype.plugin = function (taskInfo) {
	var plugin;

	if (typeof taskInfo.plugin === 'string') {
		plugin = require(taskInfo.plugin);
		return runner;
	}

	if (typeof taskInfo.plugin === 'function') {
		plugin = taskInfo.plugin;
		return runner;
	}

	function runner() {
		var context = this;
		var gulp = context.gulp;
		var config = context.config;
		var stream = context.upstream || gulp.src(config.src.globs, config.src.options);

		stream = stream.pipe(plugin(context.options));
		if (config.sprout) {
			stream = stream.pipe(gulp.dest(config.dest.path, config.dest.options));
		}
		return stream;
	}
};

// TODO: should report "Starting", "Finished" profile information.
ConfigurableRecipeFactory.prototype.reference = function (taskInfo) {
	var registry, name, recipe, result;

	// TODO: make sure when defined taskInfo.name, reference becomes that name task's child task.
	// if (taskInfo.name) {}

	registry = this.registry;
	name = taskInfo.task;
	if (typeof name === 'string') {
		delete taskInfo.task;
		if (!taskInfo.name && !taskInfo.visibility) {
			taskInfo.visibility = '.';
		}
		recipe = resolved() || pending();
		result = function (done) {
			return recipe.call(this, done);
		};
		result.displayName = name;
		result.description = taskInfo.description || recipe.description;
		return result;
	}

	function resolved() {
		var task;

		task = registry.refer(name);
		if (task) {
			return task.run || task;
		}
	}

	function pending() {
		return function (done) {
			var context, task;

			context = this;
			task = context.gulp.task(name);
			if (typeof task !== 'function') {
				throw new PluginError(__filename, 'referring task not found: ' + name);
			}
			// support for configurable task, or tasks registered directly via gulp.task().
			task = task.run || task;
			return task.call(context, done);
		};
	}
};

/**
 * if there is configurations not being consumed, then treat them as sub-tasks.
 */
ConfigurableRecipeFactory.prototype.stream = function (taskInfo) {
	var recipe;

	recipe = this.stuff.streams.lookup(taskInfo.name);
	if (recipe) {
		if (!taskInfo.visibility) {
			taskInfo.visibility = '.';
		}
		return recipe;
	}
};

/**
 * if there is a matching recipe, use it and ignore any sub-configs.
 */
ConfigurableRecipeFactory.prototype.task = function (taskInfo) {
	return this.stuff.tasks.lookup(taskInfo.name);
};

module.exports = ConfigurableRecipeFactory;
<|endoftext|>


<commit_before>var expressions = require('../utils/expressions');

/**
 * Replaces all class and id attributes found in the library. Only tested on *.html files with
 * classes declared in *class= attributes.
 *
 * @param {string} File
 * @returns {string} Minified file
 */
module.exports = function (file, classLibrary, idLibrary) {
	return file.replace(expressions.elementAttribute, function(attributes) {
		var attribute = attributes.split('=');
		return attribute[0] + '=' + attribute[1]
			.replace(expressions.selectorName, function(selectorName) {
				switch (attribute[0]) {
					case 'class':
						return classLibrary.get(selectorName);
					case 'id':
					case 'for':
						return idLibrary.get(selectorName);
					default:
				}
			});
	});
};<commit_msg>making class the default replace for html replacer<commit_after>var expressions = require('../utils/expressions');

/**
 * Replaces all class and id attributes found in the library. Only tested on *.html files with
 * classes declared in *class= attributes.
 *
 * @param {string} File
 * @returns {string} Minified file
 */
module.exports = function (file, classLibrary, idLibrary) {
	return file.replace(expressions.elementAttribute, function(attributes) {
		var attribute = attributes.split('=');
		return attribute[0] + '=' + attribute[1]
			.replace(expressions.selectorName, function(selectorName) {
				switch (attribute[0]) {
					case 'id':
					case 'for':
						return idLibrary.get(selectorName);
					default: //class
						return classLibrary.get(selectorName);
				}
			});
	});
};<|endoftext|>


<commit_before>var util = require('util')

var helper = require('../helper')

var BaseReporter = function (formatError, reportSlow, useColors, browserConsoleLogOptions, adapter) {
  this.adapters = [adapter || process.stdout.write.bind(process.stdout)]

  this.onRunStart = function () {
    this._browsers = []
  }

  this.onBrowserStart = function (browser) {
    this._browsers.push(browser)
  }

  this.renderBrowser = function (browser) {
    var results = browser.lastResult
    var totalExecuted = results.success + results.failed
    var msg = util.format('%s: Executed %d of %d', browser, totalExecuted, results.total)

    if (results.failed) {
      msg += util.format(this.X_FAILED, results.failed)
    }

    if (results.skipped) {
      msg += util.format(' (skipped %d)', results.skipped)
    }

    if (browser.isReady) {
      if (results.disconnected) {
        msg += this.FINISHED_DISCONNECTED
      } else if (results.error) {
        msg += this.FINISHED_ERROR
      } else if (!results.failed) {
        msg += this.FINISHED_SUCCESS
      }

      msg += util.format(' (%s / %s)', helper.formatTimeInterval(results.totalTime),
        helper.formatTimeInterval(results.netTime))
    }

    return msg
  }

  this.renderBrowser = this.renderBrowser.bind(this)

  this.write = function () {
    var msg = util.format.apply(null, Array.prototype.slice.call(arguments))
    var self = this
    this.adapters.forEach(function (adapter) {
      if (!helper.isDefined(adapter.colors)) {
        adapter.colors = useColors
      }
      if (!helper.isDefined(self.EXCLUSIVELY_USE_COLORS) || adapter.colors === self.EXCLUSIVELY_USE_COLORS) {
        return adapter(msg)
      }
    })
  }

  this.writeCommonMsg = this.write

  this.onBrowserError = function (browser, error) {
    this.writeCommonMsg(util.format(this.ERROR, browser) + formatError(error, '  '))
  }

  this.onBrowserLog = function (browser, log, type) {
    if (!browserConsoleLogOptions || !browserConsoleLogOptions.terminal) return
    if (!helper.isString(log)) {
      // TODO(vojta): change util to new syntax (config object)
      log = util.inspect(log, false, undefined, this.USE_COLORS)
    }
    if (this._browsers && this._browsers.length === 1) {
      this.writeCommonMsg(util.format(this.LOG_SINGLE_BROWSER, type.toUpperCase(), log))
    } else {
      this.writeCommonMsg(util.format(this.LOG_MULTI_BROWSER, browser, type.toUpperCase(), log))
    }
  }

  this.onSpecComplete = function (browser, result) {
    if (result.skipped) {
      this.specSkipped(browser, result)
    } else if (result.success) {
      this.specSuccess(browser, result)
    } else {
      this.specFailure(browser, result)
    }

    if (reportSlow && result.time > reportSlow) {
      var specName = result.suite.join(' ') + ' ' + result.description
      var time = helper.formatTimeInterval(result.time)

      this.writeCommonMsg(util.format(this.SPEC_SLOW, browser, time, specName))
    }
  }

  this.specSuccess = this.specSkipped = function () {
  }

  this.specFailure = function (browser, result) {
    var specName = result.suite.join(' ') + ' ' + result.description
    var msg = util.format(this.SPEC_FAILURE, browser, specName)

    result.log.forEach(function (log) {
      msg += formatError(log, '\t')
    })

    this.writeCommonMsg(msg)
  }

  this.onRunComplete = function (browsers, results) {
    if (browsers.length > 1 && !results.error && !results.disconnected) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success)
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success)
      }
    }
  }

  this.USE_COLORS = false
  this.EXCLUSIVELY_USE_COLORS = undefined
  this.LOG_SINGLE_BROWSER = '%s: %s\n'
  this.LOG_MULTI_BROWSER = '%s %s: %s\n'

  this.SPEC_FAILURE = '%s %s FAILED' + '\n'
  this.SPEC_SLOW = '%s SLOW %s: %s\n'
  this.ERROR = '%s ERROR\n'

  this.FINISHED_ERROR = ' ERROR'
  this.FINISHED_SUCCESS = ' SUCCESS'
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'

  this.X_FAILED = ' (%d FAILED)'

  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS\n'
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS\n'
}

BaseReporter.decoratorFactory = function (formatError, reportSlow, useColors, browserConsoleLogOptions) {
  console.log('decorator', arguments)
  return function (self) {
    BaseReporter.call(self, formatError, reportSlow, useColors, browserConsoleLogOptions)
  }
}

BaseReporter.decoratorFactory.$inject = [
  'formatError',
  'config.reportSlowerThan',
  'config.colors',
  'config.browserLogOptions'
]

// PUBLISH
module.exports = BaseReporter
<commit_msg>fix(reporter): remove console.log<commit_after>var util = require('util')

var helper = require('../helper')

var BaseReporter = function (formatError, reportSlow, useColors, browserConsoleLogOptions, adapter) {
  this.adapters = [adapter || process.stdout.write.bind(process.stdout)]

  this.onRunStart = function () {
    this._browsers = []
  }

  this.onBrowserStart = function (browser) {
    this._browsers.push(browser)
  }

  this.renderBrowser = function (browser) {
    var results = browser.lastResult
    var totalExecuted = results.success + results.failed
    var msg = util.format('%s: Executed %d of %d', browser, totalExecuted, results.total)

    if (results.failed) {
      msg += util.format(this.X_FAILED, results.failed)
    }

    if (results.skipped) {
      msg += util.format(' (skipped %d)', results.skipped)
    }

    if (browser.isReady) {
      if (results.disconnected) {
        msg += this.FINISHED_DISCONNECTED
      } else if (results.error) {
        msg += this.FINISHED_ERROR
      } else if (!results.failed) {
        msg += this.FINISHED_SUCCESS
      }

      msg += util.format(' (%s / %s)', helper.formatTimeInterval(results.totalTime),
        helper.formatTimeInterval(results.netTime))
    }

    return msg
  }

  this.renderBrowser = this.renderBrowser.bind(this)

  this.write = function () {
    var msg = util.format.apply(null, Array.prototype.slice.call(arguments))
    var self = this
    this.adapters.forEach(function (adapter) {
      if (!helper.isDefined(adapter.colors)) {
        adapter.colors = useColors
      }
      if (!helper.isDefined(self.EXCLUSIVELY_USE_COLORS) || adapter.colors === self.EXCLUSIVELY_USE_COLORS) {
        return adapter(msg)
      }
    })
  }

  this.writeCommonMsg = this.write

  this.onBrowserError = function (browser, error) {
    this.writeCommonMsg(util.format(this.ERROR, browser) + formatError(error, '  '))
  }

  this.onBrowserLog = function (browser, log, type) {
    if (!browserConsoleLogOptions || !browserConsoleLogOptions.terminal) return
    if (!helper.isString(log)) {
      // TODO(vojta): change util to new syntax (config object)
      log = util.inspect(log, false, undefined, this.USE_COLORS)
    }
    if (this._browsers && this._browsers.length === 1) {
      this.writeCommonMsg(util.format(this.LOG_SINGLE_BROWSER, type.toUpperCase(), log))
    } else {
      this.writeCommonMsg(util.format(this.LOG_MULTI_BROWSER, browser, type.toUpperCase(), log))
    }
  }

  this.onSpecComplete = function (browser, result) {
    if (result.skipped) {
      this.specSkipped(browser, result)
    } else if (result.success) {
      this.specSuccess(browser, result)
    } else {
      this.specFailure(browser, result)
    }

    if (reportSlow && result.time > reportSlow) {
      var specName = result.suite.join(' ') + ' ' + result.description
      var time = helper.formatTimeInterval(result.time)

      this.writeCommonMsg(util.format(this.SPEC_SLOW, browser, time, specName))
    }
  }

  this.specSuccess = this.specSkipped = function () {
  }

  this.specFailure = function (browser, result) {
    var specName = result.suite.join(' ') + ' ' + result.description
    var msg = util.format(this.SPEC_FAILURE, browser, specName)

    result.log.forEach(function (log) {
      msg += formatError(log, '\t')
    })

    this.writeCommonMsg(msg)
  }

  this.onRunComplete = function (browsers, results) {
    if (browsers.length > 1 && !results.error && !results.disconnected) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success)
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success)
      }
    }
  }

  this.USE_COLORS = false
  this.EXCLUSIVELY_USE_COLORS = undefined
  this.LOG_SINGLE_BROWSER = '%s: %s\n'
  this.LOG_MULTI_BROWSER = '%s %s: %s\n'

  this.SPEC_FAILURE = '%s %s FAILED' + '\n'
  this.SPEC_SLOW = '%s SLOW %s: %s\n'
  this.ERROR = '%s ERROR\n'

  this.FINISHED_ERROR = ' ERROR'
  this.FINISHED_SUCCESS = ' SUCCESS'
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'

  this.X_FAILED = ' (%d FAILED)'

  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS\n'
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS\n'
}

BaseReporter.decoratorFactory = function (formatError, reportSlow, useColors, browserConsoleLogOptions) {
  return function (self) {
    BaseReporter.call(self, formatError, reportSlow, useColors, browserConsoleLogOptions)
  }
}

BaseReporter.decoratorFactory.$inject = [
  'formatError',
  'config.reportSlowerThan',
  'config.colors',
  'config.browserLogOptions'
]

// PUBLISH
module.exports = BaseReporter
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var tty = require('tty')
  , diff = require('diff')
  , ms = require('../ms');

/**
 * Save timer references to avoid Sinon interfering (see GH-237).
 */

var Date = global.Date
  , setTimeout = global.setTimeout
  , setInterval = global.setInterval
  , clearTimeout = global.clearTimeout
  , clearInterval = global.clearInterval;

/**
 * Check if both stdio streams are associated with a tty.
 */

var isatty = tty.isatty(1) && tty.isatty(2);

/**
 * Expose `Base`.
 */

exports = module.exports = Base;

/**
 * Enable coloring by default.
 */

exports.useColors = isatty;

/**
 * Default color map.
 */

exports.colors = {
    'pass': 90
  , 'fail': 31
  , 'bright pass': 92
  , 'bright fail': 91
  , 'bright yellow': 93
  , 'pending': 36
  , 'suite': 0
  , 'error title': 0
  , 'error message': 31
  , 'error stack': 90
  , 'checkmark': 32
  , 'fast': 90
  , 'medium': 33
  , 'slow': 31
  , 'green': 32
  , 'light': 90
  , 'diff gutter': 90
  , 'diff added': 42
  , 'diff removed': 41
};

/**
 * Default symbol map.
 */

exports.symbols = {
  ok: '✓',
  err: '✖',
  dot: '․'
};

// With node.js on Windows: use symbols available in terminal default fonts
if ('win32' == process.platform) {
  exports.symbols.ok = '\u221A';
  exports.symbols.err = '\u00D7';
  exports.symbols.dot = '.';
}

/**
 * Color `str` with the given `type`,
 * allowing colors to be disabled,
 * as well as user-defined color
 * schemes.
 *
 * @param {String} type
 * @param {String} str
 * @return {String}
 * @api private
 */

var color = exports.color = function(type, str) {
  if (!exports.useColors) return str;
  return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
};

/**
 * Expose term window size, with some
 * defaults for when stderr is not a tty.
 */

exports.window = {
  width: isatty
    ? process.stdout.getWindowSize
      ? process.stdout.getWindowSize(1)[0]
      : tty.getWindowSize()[1]
    : 75
};

/**
 * Expose some basic cursor interactions
 * that are common among reporters.
 */

exports.cursor = {
  hide: function(){
    process.stdout.write('\u001b[?25l');
  },

  show: function(){
    process.stdout.write('\u001b[?25h');
  },

  deleteLine: function(){
    process.stdout.write('\u001b[2K');
  },

  beginningOfLine: function(){
    process.stdout.write('\u001b[0G');
  },

  CR: function(){
    exports.cursor.deleteLine();
    exports.cursor.beginningOfLine();
  }
};

/**
 * Outut the given `failures` as a list.
 *
 * @param {Array} failures
 * @api public
 */

exports.list = function(failures){
  console.error();
  failures.forEach(function(test, i){
    // format
    var fmt = color('error title', '  %s) %s:\n')
      + color('error message', '     %s')
      + color('error stack', '\n%s\n');

    // msg
    var err = test.err
      , message = err.message || ''
      , stack = err.stack || message
      , index = stack.indexOf(message) + message.length
      , msg = stack.slice(0, index)
      , actual = err.actual
      , expected = err.expected
      , escape = true;

    // explicitly show diff
    if (err.showDiff) {
      escape = false;
      err.actual = actual = JSON.stringify(actual, null, 2);
      err.expected = expected = JSON.stringify(expected, null, 2);
    }

    // actual / expected diff
    if ('string' == typeof actual && 'string' == typeof expected) {
      msg = errorDiff(err, 'Words', escape);

      // linenos
      var lines = msg.split('\n');
      if (lines.length > 4) {
        var width = String(lines.length).length;
        msg = lines.map(function(str, i){
          return pad(++i, width) + ' |' + ' ' + str;
        }).join('\n');
      }

      // legend
      msg = '\n'
        + color('diff removed', 'actual')
        + ' '
        + color('diff added', 'expected')
        + '\n\n'
        + msg
        + '\n';

      // indent
      msg = msg.replace(/^/gm, '      ');

      fmt = color('error title', '  %s) %s:\n%s')
        + color('error stack', '\n%s\n');
    }

    // indent stack trace without msg
    stack = stack.slice(index ? index + 1 : index)
      .replace(/^/gm, '  ');

    console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
  });
};

/**
 * Initialize a new `Base` reporter.
 *
 * All other reporters generally
 * inherit from this reporter, providing
 * stats such as test duration, number
 * of tests passed / failed etc.
 *
 * @param {Runner} runner
 * @api public
 */

function Base(runner) {
  var self = this
    , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
    , failures = this.failures = [];

  if (!runner) return;
  this.runner = runner;

  runner.stats = stats;

  runner.on('start', function(){
    stats.start = new Date;
  });

  runner.on('suite', function(suite){
    stats.suites = stats.suites || 0;
    suite.root || stats.suites++;
  });

  runner.on('test end', function(test){
    stats.tests = stats.tests || 0;
    stats.tests++;
  });

  runner.on('pass', function(test){
    stats.passes = stats.passes || 0;

    var medium = test.slow() / 2;
    test.speed = test.duration > test.slow()
      ? 'slow'
      : test.duration > medium
        ? 'medium'
        : 'fast';

    stats.passes++;
  });

  runner.on('fail', function(test, err){
    stats.failures = stats.failures || 0;
    stats.failures++;
    test.err = err;
    failures.push(test);
  });

  runner.on('end', function(){
    stats.end = new Date;
    stats.duration = new Date - stats.start;
  });

  runner.on('pending', function(){
    stats.pending++;
  });
}

/**
 * Output common epilogue used by many of
 * the bundled reporters.
 *
 * @api public
 */

Base.prototype.epilogue = function(){
  var stats = this.stats;
  var tests;
  var fmt;

  console.log();

  // passes
  fmt = color('bright pass', ' ')
    + color('green', ' %d passing')
    + color('light', ' (%s)');

  console.log(fmt,
    stats.passes || 0,
    ms(stats.duration));

  // pending
  if (stats.pending) {
    fmt = color('pending', ' ')
      + color('pending', ' %d pending');

    console.log(fmt, stats.pending);
  }

  // failures
  if (stats.failures) {
    fmt = color('fail', '  %d failing');

    console.error(fmt,
      stats.failures);

    Base.list(this.failures);
    console.error();
  }

  console.log();
};

/**
 * Pad the given `str` to `len`.
 *
 * @param {String} str
 * @param {String} len
 * @return {String}
 * @api private
 */

function pad(str, len) {
  str = String(str);
  return Array(len - str.length + 1).join(' ') + str;
}

/**
 * Return a character diff for `err`.
 *
 * @param {Error} err
 * @return {String}
 * @api private
 */

function errorDiff(err, type, escape) {
  return diff['diff' + type](err.actual, err.expected).map(function(str){
    if (escape) {
      str.value = str.value
        .replace(/\t/g, '<tab>')
        .replace(/\r/g, '<CR>')
        .replace(/\n/g, '<LF>\n');
    }
    if (str.added) return colorLines('diff added', str.value);
    if (str.removed) return colorLines('diff removed', str.value);
    return str.value;
  }).join('');
}

/**
 * Color lines for `str`, using the color `name`.
 *
 * @param {String} name
 * @param {String} str
 * @return {String}
 * @api private
 */

function colorLines(name, str) {
  return str.split('\n').map(function(str){
    return color(name, str);
  }).join('\n');
}
<commit_msg>add "Uncaught " prefix to uncaught exceptions<commit_after>
/**
 * Module dependencies.
 */

var tty = require('tty')
  , diff = require('diff')
  , ms = require('../ms');

/**
 * Save timer references to avoid Sinon interfering (see GH-237).
 */

var Date = global.Date
  , setTimeout = global.setTimeout
  , setInterval = global.setInterval
  , clearTimeout = global.clearTimeout
  , clearInterval = global.clearInterval;

/**
 * Check if both stdio streams are associated with a tty.
 */

var isatty = tty.isatty(1) && tty.isatty(2);

/**
 * Expose `Base`.
 */

exports = module.exports = Base;

/**
 * Enable coloring by default.
 */

exports.useColors = isatty;

/**
 * Default color map.
 */

exports.colors = {
    'pass': 90
  , 'fail': 31
  , 'bright pass': 92
  , 'bright fail': 91
  , 'bright yellow': 93
  , 'pending': 36
  , 'suite': 0
  , 'error title': 0
  , 'error message': 31
  , 'error stack': 90
  , 'checkmark': 32
  , 'fast': 90
  , 'medium': 33
  , 'slow': 31
  , 'green': 32
  , 'light': 90
  , 'diff gutter': 90
  , 'diff added': 42
  , 'diff removed': 41
};

/**
 * Default symbol map.
 */

exports.symbols = {
  ok: '✓',
  err: '✖',
  dot: '․'
};

// With node.js on Windows: use symbols available in terminal default fonts
if ('win32' == process.platform) {
  exports.symbols.ok = '\u221A';
  exports.symbols.err = '\u00D7';
  exports.symbols.dot = '.';
}

/**
 * Color `str` with the given `type`,
 * allowing colors to be disabled,
 * as well as user-defined color
 * schemes.
 *
 * @param {String} type
 * @param {String} str
 * @return {String}
 * @api private
 */

var color = exports.color = function(type, str) {
  if (!exports.useColors) return str;
  return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
};

/**
 * Expose term window size, with some
 * defaults for when stderr is not a tty.
 */

exports.window = {
  width: isatty
    ? process.stdout.getWindowSize
      ? process.stdout.getWindowSize(1)[0]
      : tty.getWindowSize()[1]
    : 75
};

/**
 * Expose some basic cursor interactions
 * that are common among reporters.
 */

exports.cursor = {
  hide: function(){
    process.stdout.write('\u001b[?25l');
  },

  show: function(){
    process.stdout.write('\u001b[?25h');
  },

  deleteLine: function(){
    process.stdout.write('\u001b[2K');
  },

  beginningOfLine: function(){
    process.stdout.write('\u001b[0G');
  },

  CR: function(){
    exports.cursor.deleteLine();
    exports.cursor.beginningOfLine();
  }
};

/**
 * Outut the given `failures` as a list.
 *
 * @param {Array} failures
 * @api public
 */

exports.list = function(failures){
  console.error();
  failures.forEach(function(test, i){
    // format
    var fmt = color('error title', '  %s) %s:\n')
      + color('error message', '     %s')
      + color('error stack', '\n%s\n');

    // msg
    var err = test.err
      , message = err.message || ''
      , stack = err.stack || message
      , index = stack.indexOf(message) + message.length
      , msg = stack.slice(0, index)
      , actual = err.actual
      , expected = err.expected
      , escape = true;

    // uncaught
    if (err.uncaught) {
      msg = 'Uncaught ' + msg;
    }

    // explicitly show diff
    if (err.showDiff) {
      escape = false;
      err.actual = actual = JSON.stringify(actual, null, 2);
      err.expected = expected = JSON.stringify(expected, null, 2);
    }

    // actual / expected diff
    if ('string' == typeof actual && 'string' == typeof expected) {
      msg = errorDiff(err, 'Words', escape);

      // linenos
      var lines = msg.split('\n');
      if (lines.length > 4) {
        var width = String(lines.length).length;
        msg = lines.map(function(str, i){
          return pad(++i, width) + ' |' + ' ' + str;
        }).join('\n');
      }

      // legend
      msg = '\n'
        + color('diff removed', 'actual')
        + ' '
        + color('diff added', 'expected')
        + '\n\n'
        + msg
        + '\n';

      // indent
      msg = msg.replace(/^/gm, '      ');

      fmt = color('error title', '  %s) %s:\n%s')
        + color('error stack', '\n%s\n');
    }

    // indent stack trace without msg
    stack = stack.slice(index ? index + 1 : index)
      .replace(/^/gm, '  ');

    console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
  });
};

/**
 * Initialize a new `Base` reporter.
 *
 * All other reporters generally
 * inherit from this reporter, providing
 * stats such as test duration, number
 * of tests passed / failed etc.
 *
 * @param {Runner} runner
 * @api public
 */

function Base(runner) {
  var self = this
    , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
    , failures = this.failures = [];

  if (!runner) return;
  this.runner = runner;

  runner.stats = stats;

  runner.on('start', function(){
    stats.start = new Date;
  });

  runner.on('suite', function(suite){
    stats.suites = stats.suites || 0;
    suite.root || stats.suites++;
  });

  runner.on('test end', function(test){
    stats.tests = stats.tests || 0;
    stats.tests++;
  });

  runner.on('pass', function(test){
    stats.passes = stats.passes || 0;

    var medium = test.slow() / 2;
    test.speed = test.duration > test.slow()
      ? 'slow'
      : test.duration > medium
        ? 'medium'
        : 'fast';

    stats.passes++;
  });

  runner.on('fail', function(test, err){
    stats.failures = stats.failures || 0;
    stats.failures++;
    test.err = err;
    failures.push(test);
  });

  runner.on('end', function(){
    stats.end = new Date;
    stats.duration = new Date - stats.start;
  });

  runner.on('pending', function(){
    stats.pending++;
  });
}

/**
 * Output common epilogue used by many of
 * the bundled reporters.
 *
 * @api public
 */

Base.prototype.epilogue = function(){
  var stats = this.stats;
  var tests;
  var fmt;

  console.log();

  // passes
  fmt = color('bright pass', ' ')
    + color('green', ' %d passing')
    + color('light', ' (%s)');

  console.log(fmt,
    stats.passes || 0,
    ms(stats.duration));

  // pending
  if (stats.pending) {
    fmt = color('pending', ' ')
      + color('pending', ' %d pending');

    console.log(fmt, stats.pending);
  }

  // failures
  if (stats.failures) {
    fmt = color('fail', '  %d failing');

    console.error(fmt,
      stats.failures);

    Base.list(this.failures);
    console.error();
  }

  console.log();
};

/**
 * Pad the given `str` to `len`.
 *
 * @param {String} str
 * @param {String} len
 * @return {String}
 * @api private
 */

function pad(str, len) {
  str = String(str);
  return Array(len - str.length + 1).join(' ') + str;
}

/**
 * Return a character diff for `err`.
 *
 * @param {Error} err
 * @return {String}
 * @api private
 */

function errorDiff(err, type, escape) {
  return diff['diff' + type](err.actual, err.expected).map(function(str){
    if (escape) {
      str.value = str.value
        .replace(/\t/g, '<tab>')
        .replace(/\r/g, '<CR>')
        .replace(/\n/g, '<LF>\n');
    }
    if (str.added) return colorLines('diff added', str.value);
    if (str.removed) return colorLines('diff removed', str.value);
    return str.value;
  }).join('');
}

/**
 * Color lines for `str`, using the color `name`.
 *
 * @param {String} name
 * @param {String} str
 * @return {String}
 * @api private
 */

function colorLines(name, str) {
  return str.split('\n').map(function(str){
    return color(name, str);
  }).join('\n');
}
<|endoftext|>


<commit_before>'use strict';
var chalk = require('chalk');

var CHECK = chalk.green('\u2713'),
    XMARK = chalk.red('\u2718'),
    EXCLAMATION = chalk.bold.yellow('!');

module.exports = function(runner) {
    var browserSuites, failed, passed, skipped;

    function reportSuccess(data) {
        report(CHECK, data.stateName, data.browserId);
    }

    function reportFail(data) {
        report(XMARK, data.stateName, data.browserId);
    }

    function reportWarn(data) {
        report(EXCLAMATION, data.stateName, data.browserId);
    }

    function report(mark, stateName, browserId) {
        var fullSuiteName = browserSuites[browserId].join(' ');
        console.log('%s %s ' + chalk.underline('%s') + ' ' + chalk.yellow('[%s]'),
            mark,
            fullSuiteName,
            stateName,
            browserId
        );
    }

    runner.on('begin', function(data) {
        failed = passed = skipped = 0;
        browserSuites = {};
        data.browserIds.forEach(function(browserId) {
            browserSuites[browserId] = [];
        });
    });

    runner.on('beginSuite', function(data) {
        browserSuites[data.browserId].push(data.suiteName);
    });

    runner.on('endSuite', function(data) {
        browserSuites[data.browserId].pop();
    });

     //for test command
    runner.on('endTest', function(result) {
        if (result.equal) {
            reportSuccess(result);
            passed++;
        } else {
            reportFail(result);
            failed++;
        }
    });

    //for gather command
    runner.on('capture', function(data) {
        reportSuccess(data);
        passed++;
    });

    runner.on('error', function(error) {
        reportFail(error);

        if (error.originalError) {
            error = error.originalError;
        }
        console.error(error.stack || error.message);

        failed++;
    });

    /**
     * @param {NoRefImageError} error
     */
    runner.on('warning', function(error) {
        reportWarn(error);
        console.warn(error.message);

        skipped++;
    });

    runner.on('end', function() {
        var total = failed + passed + skipped;
        console.log('Total: %s Passed: %s Failed: %s Skipped: %s',
                    chalk.underline(total),
                    chalk.green(passed),
                    chalk.red(failed),
                    chalk.cyan(skipped));
    });
};
<commit_msg>Fix jscs error<commit_after>'use strict';
var chalk = require('chalk');

var CHECK = chalk.green('\u2713'),
    XMARK = chalk.red('\u2718'),
    EXCLAMATION = chalk.bold.yellow('!');

module.exports = function(runner) {
    var browserSuites, failed, passed, skipped;

    function reportSuccess(data) {
        report(CHECK, data.stateName, data.browserId);
    }

    function reportFail(data) {
        report(XMARK, data.stateName, data.browserId);
    }

    function reportWarn(data) {
        report(EXCLAMATION, data.stateName, data.browserId);
    }

    function report(mark, stateName, browserId) {
        var fullSuiteName = browserSuites[browserId].join(' ');
        console.log('%s %s ' + chalk.underline('%s') + ' ' + chalk.yellow('[%s]'),
            mark,
            fullSuiteName,
            stateName,
            browserId
        );
    }

    runner.on('begin', function(data) {
        failed = passed = skipped = 0;
        browserSuites = {};
        data.browserIds.forEach(function(browserId) {
            browserSuites[browserId] = [];
        });
    });

    runner.on('beginSuite', function(data) {
        browserSuites[data.browserId].push(data.suiteName);
    });

    runner.on('endSuite', function(data) {
        browserSuites[data.browserId].pop();
    });

    //for test command
    runner.on('endTest', function(result) {
        if (result.equal) {
            reportSuccess(result);
            passed++;
        } else {
            reportFail(result);
            failed++;
        }
    });

    //for gather command
    runner.on('capture', function(data) {
        reportSuccess(data);
        passed++;
    });

    runner.on('error', function(error) {
        reportFail(error);

        if (error.originalError) {
            error = error.originalError;
        }
        console.error(error.stack || error.message);

        failed++;
    });

    /**
     * @param {NoRefImageError} error
     */
    runner.on('warning', function(error) {
        reportWarn(error);
        console.warn(error.message);

        skipped++;
    });

    runner.on('end', function() {
        var total = failed + passed + skipped;
        console.log('Total: %s Passed: %s Failed: %s Skipped: %s',
                    chalk.underline(total),
                    chalk.green(passed),
                    chalk.red(failed),
                    chalk.cyan(skipped));
    });
};
<|endoftext|>


<commit_before>const request = require('./promise-request')
const Url = require('./url')
const { Seat, Area, AreaInfo, Floor } = require('../classes')

/**
 * 获取楼层状态的状态
 * @param {Number} floor 楼层的编号
 */
async function getFloorStatus(floor = 3) {
  let { response, body } = await request(Url.Floor(floor), {
    json: true
  })

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when get floor status`);
  }

  return new Floor(body);
}

/**
 * 获取自习区域的状态
 * @param {AreaInfo} area 自习区域信息
 */
async function getAreaStatus(area) {
  const now = new Date;

  let { response, body } = await request(Url.Area(area), {
    json: true
  })

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when get area status`)
  }

  return new Area(body)
}

/**
 * 预约座位
 * @param {Seat} seat 座位
 * @param {UserInfo} userInfo 用户信息
 * @param {Jar} jar Cookie 罐
 * @return
 */
async function book(seat, userInfo, jar) {
  const url = 'http://58.194.172.92:85/api.php/spaces/${seat.id}/book';

  let { response, body } = await request(url, {
    method: 'POST',
    form: {
      'access_token': userInfo.accessToken,
      'userid': userInfo.id,
      segment,
      'type': 1
    },
    headers: { cookie: jar.toString() },
    json: true
  });

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when book the seat`);
  }

  return body;
}

module.exports = {
  getFloorStatus,
  getAreaStatus,
  book
}<commit_msg>Remove some imports, functions return raw data now<commit_after>const request = require('./promise-request')
const Url = require('./url')

/**
 * 获取楼层状态的状态
 * @param {Number} floor 楼层的编号
 */
async function getFloorStatus(floor = 3) {
  let { response, body } = await request(Url.Floor(floor), {
    json: true
  })

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when get floor status`);
  }

  return body
}

/**
 * 获取自习区域的状态
 * @param {AreaInfo} area 自习区域信息
 */
async function getAreaStatus(area) {
  const now = new Date;

  let { response, body } = await request(Url.Area(area), {
    json: true
  })

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when get area status`)
  }

  return body
}

/**
 * 预约座位
 * @param {Seat} seat 座位
 * @param {UserInfo} userInfo 用户信息
 * @param {Jar} jar Cookie 罐
 * @return
 */
async function book(seat, userInfo, jar) {
  const url = 'http://58.194.172.92:85/api.php/spaces/${seat.id}/book';

  let { response, body } = await request(url, {
    method: 'POST',
    form: {
      'access_token': userInfo.accessToken,
      'userid': userInfo.id,
      segment,
      'type': 1
    },
    headers: { cookie: jar.toString() },
    json: true
  });

  if (response.statusCode !== 200) {
    throw new Error(`Bad status code ${response.status} when book the seat`);
  }

  return body
}

module.exports = {
  getFloorStatus,
  getAreaStatus,
  book
}<|endoftext|>


<commit_before>'use strict'

const normalize = require('normalize-path')
const debugLog = require('debug')('lint-staged:resolveGitRepo')
const fs = require('fs')
const path = require('path')
const { promisify } = require('util')

const execGit = require('./execGit')
const { readFile } = require('./file')

const fsLstat = promisify(fs.lstat)

/**
 * Resolve path to the .git directory, with special handling for
 * submodules and worktrees
 */
const resolveGitConfigDir = async (gitDir) => {
  const defaultDir = normalize(path.join(gitDir, '.git'))
  const stats = await fsLstat(defaultDir)
  // If .git is a directory, use it
  if (stats.isDirectory()) return defaultDir
  // Otherwise .git is a file containing path to real location
  const file = (await readFile(defaultDir)).toString()
  return path.resolve(gitDir, file.replace(/^gitdir: /, '')).trim()
}

/**
 * Resolve git directory and possible submodule paths
 */
const resolveGitRepo = async (cwd) => {
  try {
    debugLog('Resolving git repo from `%s`', cwd)

    // Unset GIT_DIR before running any git operations in case it's pointing to an incorrect location
    debugLog('Unset GIT_DIR (was `%s`)', process.env.GIT_DIR)
    delete process.env.GIT_DIR
    debugLog('Unset GIT_WORK_TREE (was `%s`)', process.env.GIT_WORK_TREE)
    delete process.env.GIT_WORK_TREE

    const gitDir = normalize(await execGit(['rev-parse', '--show-toplevel'], { cwd }))
    const gitConfigDir = normalize(await resolveGitConfigDir(gitDir))

    debugLog('Resolved git directory to be `%s`', gitDir)
    debugLog('Resolved git config directory to be `%s`', gitConfigDir)

    return { gitDir, gitConfigDir }
  } catch (error) {
    debugLog('Failed to resolve git repo with error:', error)
    return { error, gitDir: null, gitConfigDir: null }
  }
}

module.exports = resolveGitRepo
<commit_msg>fix: detect git repo root correctly on cygwin (#1026)<commit_after>'use strict'

const normalize = require('normalize-path')
const debugLog = require('debug')('lint-staged:resolveGitRepo')
const fs = require('fs')
const path = require('path')
const { promisify } = require('util')

const execGit = require('./execGit')
const { readFile } = require('./file')

const fsLstat = promisify(fs.lstat)

/**
 * Resolve path to the .git directory, with special handling for
 * submodules and worktrees
 */
const resolveGitConfigDir = async (gitDir) => {
  const defaultDir = normalize(path.join(gitDir, '.git'))
  const stats = await fsLstat(defaultDir)
  // If .git is a directory, use it
  if (stats.isDirectory()) return defaultDir
  // Otherwise .git is a file containing path to real location
  const file = (await readFile(defaultDir)).toString()
  return path.resolve(gitDir, file.replace(/^gitdir: /, '')).trim()
}

const determineGitDir = (cwd, relativeDir) => {
  if (relativeDir) {
    // the current working dir is inside the git top-level directory
    return normalize(cwd.substring(0, cwd.lastIndexOf(relativeDir)))
  } else {
    // the current working dir is the top-level git directory
    return normalize(cwd)
  }
}

/**
 * Resolve git directory and possible submodule paths
 */
const resolveGitRepo = async (cwd = process.cwd()) => {
  try {
    debugLog('Resolving git repo from `%s`', cwd)

    // Unset GIT_DIR before running any git operations in case it's pointing to an incorrect location
    debugLog('Unset GIT_DIR (was `%s`)', process.env.GIT_DIR)
    delete process.env.GIT_DIR
    debugLog('Unset GIT_WORK_TREE (was `%s`)', process.env.GIT_WORK_TREE)
    delete process.env.GIT_WORK_TREE

    // read the path of the current directory relative to the top-level directory
    // don't read the toplevel directly, it will lead to an posix conform path on non posix systems (cygwin)
    const gitRel = normalize(await execGit(['rev-parse', '--show-prefix']))
    const gitDir = determineGitDir(cwd, gitRel)
    const gitConfigDir = normalize(await resolveGitConfigDir(gitDir))

    debugLog('Resolved git directory to be `%s`', gitDir)
    debugLog('Resolved git config directory to be `%s`', gitConfigDir)

    return { gitDir, gitConfigDir }
  } catch (error) {
    debugLog('Failed to resolve git repo with error:', error)
    return { error, gitDir: null, gitConfigDir: null }
  }
}

module.exports = resolveGitRepo
<|endoftext|>


<commit_before>'use strict';

const debug = require('debug')('ResponseParser');
const RemoUserHelper = require('../lib/remoUserHelper');
const remoUserHelper = new RemoUserHelper();

module.exports = class ResponseParser {
  /**
   * Creates an object from the response to make sure we assign to real properties
   * @param  {Array} responses responses from the form
   * @return {Array}           descriptive responses as objects
   */
  static create(responses) {
    debug('Creating responses..');
    const groupedByEvents = responses.map((response) => {
      const eventResponse = ResponseParser.getGeneralEventInfo(response);
      eventResponse.nps = response[3];
      eventResponse.profession = response[4];
      return eventResponse;
    }).reduce(groupByEvent, {});

    const events = convertObjectToArray(groupedByEvents);
    const allScores = events.reduce((acc, value) => {
      return acc.concat(value.scores);
    }, []);
    const scoredEvents = scoreEvents(events);
    const totals = {
      totalResponses: responses.length,
      totalEvents: scoredEvents.length,
      overallNPS: calculateNPS(allScores)
    };

    return {
      totals,
      events: scoredEvents
    };
  }

  static getGeneralEventInfo(response) {
    return {
      key: response[1] + '_' + response[2],
      eventName: response[0],
      eventDate: response[2],
      organizerName: response[1],
      organizerUrl: remoUserHelper.getRepUrlByFullName(response[1])
    };
  }
}

function groupByEvent(acc, response) {
  const npsScoreCopy = JSON.parse(JSON.stringify(response.nps));

  acc[response.key] = acc[response.key] || response;

  if (!acc[response.key].scores) {
    delete acc[response.key].nps;
  }

  acc[response.key].scores = acc[response.key].scores || [];
  acc[response.key].scores.push(parseInt(npsScoreCopy, 10));

  const professionCopy = JSON.parse(JSON.stringify(response.profession));
  if (!acc[response.key].professions) {
    delete acc[response.key].profession;
  }

  acc[response.key].professions = acc[response.key].professions || {};
  const professions = acc[response.key].professions;
  if (professions[professionCopy] !== undefined) {
    professions[professionCopy] += 1;
  } else {
    professions[professionCopy] = 1;
  }

  return acc;
}

function convertObjectToArray(object) {
  return Object.keys(object).map((key) => {
    return object[key];
  });
}

function scoreEvents(events) {
  return events.map((event) => {
    event.nps = calculateNPS(event.scores);
    delete event.scores;
    return event;
  });
}

function calculateNPS(scores) {
  const numberOfScores = scores.length;
  let promoters = 0;
  let detractors = 0;

  for (let score of scores) {
    if (score >= 7) {
      promoters++;
    } else if (score <= 4) {
      detractors++;
    }
  }

  const promoterRatio = promoters / numberOfScores;
  const detractorRatio = detractors / numberOfScores;

  const nps = Math.round((promoterRatio - detractorRatio) * 100);
  return nps;
}
<commit_msg>Sanitize responses + add event type summary<commit_after>'use strict';

const debug = require('debug')('ResponseParser');
const RemoUserHelper = require('../lib/remoUserHelper');
const remoUserHelper = new RemoUserHelper();

module.exports = class ResponseParser {
  /**
   * Creates an object from the response to make sure we assign to real properties
   * @param  {Array} responses responses from the form
   * @return {Array}           descriptive responses as objects
   */
  static create(responses) {
    debug('Creating responses..');
    const groupedByEvents = responses.map((response) => {
      const eventResponse = ResponseParser.getGeneralEventInfo(response);
      eventResponse.nps = response[3];
      eventResponse.profession = response[4];
      return eventResponse;
    })
    .map(sanitizeResponse)
    .reduce(groupByEvent, {});

    const events = convertObjectToArray(groupedByEvents);
    const allScores = events.reduce((acc, value) => {
      return acc.concat(value.scores);
    }, []);
    const scoredEvents = scoreEvents(events);
    const totals = {
      totalResponses: responses.length,
      totalEvents: scoredEvents.length,
      overallNPS: calculateNPS(allScores),
      typeOfEvents: getTypeSummary(events)
    };

    return {
      totals,
      events: scoredEvents
    };
  }

  static getGeneralEventInfo(response) {
    return {
      key: response[1] + '_' + response[2],
      eventName: response[0],
      eventDate: response[2],
      organizerName: response[1],
      organizerUrl: remoUserHelper.getRepUrlByFullName(response[1])
    };
  }
}

function sanitizeResponse(response) {
  if (!response.profession) {
    response.profession = '';
  }

  return response;
}

function groupByEvent(acc, response) {
  const npsScoreCopy = JSON.parse(JSON.stringify(response.nps));

  acc[response.key] = acc[response.key] || response;

  if (!acc[response.key].scores) {
    delete acc[response.key].nps;
  }

  acc[response.key].scores = acc[response.key].scores || [];
  acc[response.key].scores.push(parseInt(npsScoreCopy, 10));

  const professionCopy = JSON.parse(JSON.stringify(response.profession));
  if (!acc[response.key].professions) {
    delete acc[response.key].profession;
  }

  acc[response.key].professions = acc[response.key].professions || {};
  const professions = acc[response.key].professions;
  if (professions[professionCopy] !== undefined) {
    professions[professionCopy] += 1;
  } else {
    professions[professionCopy] = 1;
  }

  return acc;
}

function convertObjectToArray(object) {
  return Object.keys(object).map((key) => {
    return object[key];
  });
}

function scoreEvents(events) {
  return events.map((event) => {
    event.nps = calculateNPS(event.scores);
    delete event.scores;
    return event;
  });
}

function calculateNPS(scores) {
  const numberOfScores = scores.length;
  let promoters = 0;
  let detractors = 0;

  for (let score of scores) {
    if (score >= 7) {
      promoters++;
    } else if (score <= 4) {
      detractors++;
    }
  }

  const promoterRatio = promoters / numberOfScores;
  const detractorRatio = detractors / numberOfScores;

  const nps = Math.round((promoterRatio - detractorRatio) * 100);
  return nps;
}

function getTypeSummary(responses) {
  return responses.reduce((acc, response) => {
    if (acc[response.eventName] !== undefined) {
      acc[response.eventName] += 1;
    } else {
      acc[response.eventName] = 1;
    }

    return acc;
  }, {});
}
<|endoftext|>


<commit_before>if (typeof Handlebars !== 'undefined') {
  Handlebars.registerHelper('renderPage', function(name, options) {
    if (! _.isString(name))
      name = Meteor.Router.page();

    if (Template[name])
      return new Handlebars.SafeString(Template[name](this));
  });

  Handlebars.registerHelper('currentPage', function() {
    return Meteor.Router.page();
  });
}
<commit_msg>Blaze compatibility<commit_after>if (typeof Handlebars !== 'undefined') {
  if(typeof(UI) !== 'undefined') {
  	//Blaze Code

  	UI.body.helpers({
		renderPage: function(name, options) {
			var name = Meteor.Router.page();
			return Template[name];
		}
	});
  }else{
	  Handlebars.registerHelper('renderPage', function(name, options) {
	    if (! _.isString(name))
	      name = Meteor.Router.page();

	    if (Template[name])
	      return new Handlebars.SafeString(Template[name](this));
	  });
  }

  Handlebars.registerHelper('currentPage', function() {
    return Meteor.Router.page();
  });
}
<|endoftext|>