<commit_before>#!/usr/bin/env node

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('xtend')
var mkdirp = require('mkdirp')
var path = require('path')
var rimraf = require('rimraf')
var series = require('run-series')
var test = require('tape')

var TMP = path.join(__dirname, '..', 'tmp')
var STANDARD = path.join(__dirname, '..', 'bin', 'cmd.js')

var URLS = [
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/brandonhorst/coverage-test.git',
  'https://github.com/brandonhorst/empty.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-protocol.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/magnet-uri.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/simple-peer.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/Flet/dailyconnect.git',
  'https://github.com/Flet/exitzero.git',
  'https://github.com/mafintosh/hms-protocol.git',
  'https://github.com/mafintosh/hms.git',
  'https://github.com/mafintosh/json-format-stream.git',
  'https://github.com/mafintosh/level-enumerate.git',
  'https://github.com/mafintosh/level-logs.git',
  'https://github.com/mafintosh/level-temp.git',
  'https://github.com/mafintosh/node-gyp-install.git',
  // 'https://github.com/mafintosh/peerflix.git', // still using standard v2
  'https://github.com/mafintosh/swap-to-level.git',
  'https://github.com/mafintosh/telephone.git',
  'https://github.com/mafintosh/what-line-is-this.git',
  'https://github.com/maxogden/dat-core.git',
  'https://github.com/maxogden/standard-format.git',
  // 'https://github.com/ngoldman/gh-release.git', // still using standard v2
  'https://github.com/ngoldman/magnet-link.git',
  'https://github.com/ngoldman/wireframe.css.git',
  'https://github.com/npm/fstream.git',
  // 'https://github.com/npm/npm.git' // in progress
  'https://github.com/othiym23/packard.git'
]

var MODULES = {}
URLS.forEach(function (url) {
  var name = /\/([^\/]+)\.git$/.exec(url)[1]
  MODULES[name] = url
})

test('clone repos from github', function (t) {
  t.plan(1)
  rimraf.sync(TMP)
  mkdirp.sync(TMP)

  series(Object.keys(MODULES).map(function (name) {
    var url = MODULES[name]
    return function (cb) {
      var args = [ 'clone', '--depth', 1, url, path.join(TMP, name) ]
      // TODO: Start `git` in a way that works on Windows – PR welcome!
      spawn('git', args, {}, cb)
    }
  }), function (err) {
    if (err) throw err
    t.pass('cloned repos')
  })
})

test('lint repos', function (t) {
  t.plan(URLS.length)
  series(Object.keys(MODULES).map(function (name) {
    return function (cb) {
      var cwd = path.join(TMP, name)
      spawn(STANDARD, [], { cwd: cwd }, function (err) {
        t.error(err, name)
        cb(null)
      })
    }
  }))
})

function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', cb)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}
<commit_msg>test: disable dat-core<commit_after>#!/usr/bin/env node

/**
 * Clones several projects that are known to follow "JavaScript Standard Style" and runs
 * the `standard` style checker to verify that it passes without warnings. This helps
 * ensure we don't accidentally introduce new style rules that cause previously "good"
 * code to start failing with new warnings! (And if we do, then that needs to be a MAJOR
 * VERSION BUMP.)
 */

var cp = require('child_process')
var extend = require('xtend')
var mkdirp = require('mkdirp')
var path = require('path')
var rimraf = require('rimraf')
var series = require('run-series')
var test = require('tape')

var TMP = path.join(__dirname, '..', 'tmp')
var STANDARD = path.join(__dirname, '..', 'bin', 'cmd.js')

var URLS = [
  'https://github.com/beatgammit/base64-js.git',
  'https://github.com/brandonhorst/coverage-test.git',
  'https://github.com/brandonhorst/empty.git',
  'https://github.com/feross/bittorrent-dht.git',
  'https://github.com/feross/bittorrent-protocol.git',
  'https://github.com/feross/bittorrent-tracker.git',
  'https://github.com/feross/buffer.git',
  'https://github.com/feross/magnet-uri.git',
  'https://github.com/feross/parse-torrent.git',
  'https://github.com/feross/simple-peer.git',
  'https://github.com/feross/studynotes.git',
  'https://github.com/feross/webtorrent.git',
  'https://github.com/Flet/dailyconnect.git',
  'https://github.com/Flet/exitzero.git',
  'https://github.com/mafintosh/hms-protocol.git',
  'https://github.com/mafintosh/hms.git',
  'https://github.com/mafintosh/json-format-stream.git',
  'https://github.com/mafintosh/level-enumerate.git',
  'https://github.com/mafintosh/level-logs.git',
  'https://github.com/mafintosh/level-temp.git',
  'https://github.com/mafintosh/node-gyp-install.git',
  // 'https://github.com/mafintosh/peerflix.git', // still using standard v2
  'https://github.com/mafintosh/swap-to-level.git',
  'https://github.com/mafintosh/telephone.git',
  'https://github.com/mafintosh/what-line-is-this.git',
  // 'https://github.com/maxogden/dat-core.git', // started failing 5-29-15
  'https://github.com/maxogden/standard-format.git',
  // 'https://github.com/ngoldman/gh-release.git', // still using standard v2
  'https://github.com/ngoldman/magnet-link.git',
  'https://github.com/ngoldman/wireframe.css.git',
  'https://github.com/npm/fstream.git',
  // 'https://github.com/npm/npm.git' // in progress
  'https://github.com/othiym23/packard.git'
]

var MODULES = {}
URLS.forEach(function (url) {
  var name = /\/([^\/]+)\.git$/.exec(url)[1]
  MODULES[name] = url
})

test('clone repos from github', function (t) {
  t.plan(1)
  rimraf.sync(TMP)
  mkdirp.sync(TMP)

  series(Object.keys(MODULES).map(function (name) {
    var url = MODULES[name]
    return function (cb) {
      var args = [ 'clone', '--depth', 1, url, path.join(TMP, name) ]
      // TODO: Start `git` in a way that works on Windows – PR welcome!
      spawn('git', args, {}, cb)
    }
  }), function (err) {
    if (err) throw err
    t.pass('cloned repos')
  })
})

test('lint repos', function (t) {
  t.plan(URLS.length)
  series(Object.keys(MODULES).map(function (name) {
    return function (cb) {
      var cwd = path.join(TMP, name)
      spawn(STANDARD, [], { cwd: cwd }, function (err) {
        t.error(err, name)
        cb(null)
      })
    }
  }))
})

function spawn (command, args, opts, cb) {
  var child = cp.spawn(command, args, extend({ stdio: 'inherit' }, opts))
  child.on('error', cb)
  child.on('close', function (code) {
    if (code !== 0) cb(new Error('non-zero exit code: ' + code))
    else cb(null)
  })
  return child
}
<|endoftext|>


<commit_before>import { Parse }     from 'parse/node';
import * as triggers from '../triggers';

function validateClassNameForTriggers(className) {
  const restrictedClassNames = [ '_Session' ];
  if (restrictedClassNames.indexOf(className) != -1) {
    throw `Triggers are not supported for ${className} class.`;
  }
  return className;
}

function getClassName(parseClass) {
  if (parseClass && parseClass.className) {
    return validateClassNameForTriggers(parseClass.className);
  }
  return validateClassNameForTriggers(parseClass);
}

var ParseCloud = {};
ParseCloud.define = function(functionName, handler, validationHandler) {
  triggers.addFunction(functionName, handler, validationHandler, Parse.applicationId);
};

ParseCloud.job = function(functionName, handler) {
  triggers.addJob(functionName, handler, Parse.applicationId);
};

ParseCloud.beforeSave = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeSave, className, handler, Parse.applicationId);
};

ParseCloud.beforeDelete = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeDelete, className, handler, Parse.applicationId);
};

ParseCloud.afterSave = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterSave, className, handler, Parse.applicationId);
};

ParseCloud.afterDelete = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterDelete, className, handler, Parse.applicationId);
};

ParseCloud.beforeFind = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeFind, className, handler, Parse.applicationId);
};

ParseCloud.afterFind = function(parseClass, handler) {
  const className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterFind, className, handler, Parse.applicationId);
};

ParseCloud._removeAllHooks = () => {
  triggers._unregisterAll();
}

ParseCloud.httpRequest = require("./httpRequest");

module.exports = ParseCloud;
<commit_msg>Adds depreciation notes for Parse.Cloud.useMasterKey(), (#3204)<commit_after>import { Parse }     from 'parse/node';
import * as triggers from '../triggers';

function validateClassNameForTriggers(className) {
  const restrictedClassNames = [ '_Session' ];
  if (restrictedClassNames.indexOf(className) != -1) {
    throw `Triggers are not supported for ${className} class.`;
  }
  return className;
}

function getClassName(parseClass) {
  if (parseClass && parseClass.className) {
    return validateClassNameForTriggers(parseClass.className);
  }
  return validateClassNameForTriggers(parseClass);
}

var ParseCloud = {};
ParseCloud.define = function(functionName, handler, validationHandler) {
  triggers.addFunction(functionName, handler, validationHandler, Parse.applicationId);
};

ParseCloud.job = function(functionName, handler) {
  triggers.addJob(functionName, handler, Parse.applicationId);
};

ParseCloud.beforeSave = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeSave, className, handler, Parse.applicationId);
};

ParseCloud.beforeDelete = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeDelete, className, handler, Parse.applicationId);
};

ParseCloud.afterSave = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterSave, className, handler, Parse.applicationId);
};

ParseCloud.afterDelete = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterDelete, className, handler, Parse.applicationId);
};

ParseCloud.beforeFind = function(parseClass, handler) {
  var className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.beforeFind, className, handler, Parse.applicationId);
};

ParseCloud.afterFind = function(parseClass, handler) {
  const className = getClassName(parseClass);
  triggers.addTrigger(triggers.Types.afterFind, className, handler, Parse.applicationId);
};

ParseCloud._removeAllHooks = () => {
  triggers._unregisterAll();
}

ParseCloud.useMasterKey = () => {
  // eslint-disable-next-line
  console.warn("Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: https://github.com/ParsePlatform/parse-server/wiki/Compatibility-with-Hosted-Parse#cloud-code")
}

ParseCloud.httpRequest = require("./httpRequest");

module.exports = ParseCloud;
<|endoftext|>


<commit_before>const assert = require('assert')
const Cursor = require('../')
const pg = require('pg')

const text = 'SELECT generate_series as num FROM generate_series(0, 50)'
describe('close', function() {
  beforeEach(function(done) {
    const client = (this.client = new pg.Client())
    client.connect(done)
    client.on('drain', client.end.bind(client))
  })

  it('can close a finished cursor without a callback', function(done) {
    const cursor = new Cursor(text)
    this.client.query(cursor)
    this.client.query('SELECT NOW()', done)
    cursor.read(100, function (err, res) {
      assert.ifError(err)
      cursor.close()
    })
  })

  it('closes cursor early', function(done) {
    const cursor = new Cursor(text)
    this.client.query(cursor)
    this.client.query('SELECT NOW()', done)
    cursor.read(25, function(err) {
      assert.ifError(err)
      cursor.close()
    })
  })

  it('works with callback style', function(done) {
    const cursor = new Cursor(text)
    const client = this.client
    client.query(cursor)
    cursor.read(25, function(err) {
      assert.ifError(err)
      cursor.close(function(err) {
        assert.ifError(err)
        client.query('SELECT NOW()', done)
      })
    })
  })
})
<commit_msg>fix lint issues<commit_after>const assert = require('assert')
const Cursor = require('../')
const pg = require('pg')

const text = 'SELECT generate_series as num FROM generate_series(0, 50)'
describe('close', function() {
  beforeEach(function(done) {
    const client = (this.client = new pg.Client())
    client.connect(done)
    client.on('drain', client.end.bind(client))
  })

  it('can close a finished cursor without a callback', function(done) {
    const cursor = new Cursor(text)
    this.client.query(cursor)
    this.client.query('SELECT NOW()', done)
    cursor.read(100, function(err) {
      assert.ifError(err)
      cursor.close()
    })
  })

  it('closes cursor early', function(done) {
    const cursor = new Cursor(text)
    this.client.query(cursor)
    this.client.query('SELECT NOW()', done)
    cursor.read(25, function(err) {
      assert.ifError(err)
      cursor.close()
    })
  })

  it('works with callback style', function(done) {
    const cursor = new Cursor(text)
    const client = this.client
    client.query(cursor)
    cursor.read(25, function(err) {
      assert.ifError(err)
      cursor.close(function(err) {
        assert.ifError(err)
        client.query('SELECT NOW()', done)
      })
    })
  })
})
<|endoftext|>


<commit_before>const { toString } = require('sanctuary-type-classes')
const { test } = require('tap')
const { tagged, taggedSum } = require('../src/daggy')

const Tuple = tagged('Tuple', ['_1', '_2'])

const List = taggedSum('List', {
  Cons: ['x', 'xs'],
  Nil: []
})

Tuple.prototype.foo = 'foo'
List.prototype.foo = 'foo'

const a = 'a'
const b = 'b'

test('tagged', (t) => {
  const tpl = Tuple(a, b)
  t.throws(
    () => { Tuple(1) },
    new TypeError(`Expected 2 arguments, got 1`),
    'when creating a tagged type with fewer arguments throws error'
  )
  t.throws(
    () => { Tuple(1, 2, 3) },
    new TypeError(`Expected 2 arguments, got 3`),
    'when creating a tagged type with too many arguments throws error'
  )
  t.same(tpl.toString(), `Tuple(${toString(a)}, ${toString(b)})`, 'toString on value should work')
  t.same(Tuple.toString(), `Tuple`, 'toString on type should work')
  t.same(tpl._1, a, 'when checking _1 value should return correct value')
  t.same(tpl._2, b, 'when checking _2 value should return correct value')
  t.same(tpl.constructor, Tuple, 'constructor on value should refer to TypeRep of the value')
  t.ok(Tuple.is(tpl), '`is` on type works')
  t.notOk(Tuple.is({}), '`is` on type works')
  t.same(Tuple.prototype.foo, tpl.foo, 'values in typerep.prototype are accassible from instance values')
  t.ok(Tuple.prototype.isPrototypeOf(tpl), 'prototype chain is correct')
  t.test('build from object', (t) => {
    const tpl = Tuple.from({_2: b, _1: a})
    t.same(tpl._1, a, 'First value on tuple is correct')
    t.same(tpl._2, b, 'Second value on tuple is correct')
    t.throws(
      () => { Tuple.from({ _1: 1 }) },
      new TypeError('Missing field: _2'),
      'when creating a tagged type from an object with a missing field'
    )
    t.end()
  })
  t.test('tag.is() is pre-bound to the rep', (t) => {
    const isTuple = Tuple.is
    const list = List.Nil
    t.doesNotThrow(
      () => { isTuple(tpl) },
      'tag.is() can be assigned to an unbound var and used separate to test instances'
    )
    t.ok(isTuple(tpl), 'tag.is() should correctly identify instances even when used as an unbound var')
    t.notOk(isTuple(list), 'tag.is() should correctly not identify instances of other types even when used as an unbound var')
    t.end()
  })
  t.end()
})

test('taggedSum', (t) => {
  const list = List.Cons(a, List.Nil)
  t.throws(
    () => { List.Cons(1) },
    new TypeError(`Expected 2 arguments, got 1`),
    'when creating a taggedSum type with to many arguments throws error'
  )
  t.throws(
    () => { List.Cons(1, 1, 1) },
    new TypeError(`Expected 2 arguments, got 3`),
    'when creating a taggedSum type with to many arguments throws error'
  )
  t.throws(
    () => { List.Nil.cata({}) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if all cases are not handled'
  )
  t.throws(
    () => { list.cata({}) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if all cases are not handled'
  )
  t.throws(
    () => { List.Nil.cata({ Nil: () => false }) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if some cases are not handled'
  )
  t.throws(
    () => { list.cata({ Cons: () => true }) },
    new Error(`Constructors given to cata didn't include: Nil`),
    'throws if some cases are not handled'
  )
  t.same(list.toString(), `List.Cons(${toString(a)}, List.Nil)`, 'toString on value should work')
  t.same(List.toString(), 'List', 'toString on type should work')
  t.same(List.Cons.toString(), 'List.Cons', 'toString on variant constructor should work')
  t.same(List.Nil.toString(), 'List.Nil', 'toString on unit variant should work')
  t.same(list.x, a, 'when checking head value should return correct value')
  t.same(list.xs, List.Nil, 'when checking value value should return correct value')
  t.same(list.xs.constructor, List, 'constructor on value should refer to TypeRep of the value')
  t.same(list.cata({
    Cons: (x, xs) => [x, xs],
    Nil: () => []
  }), [list.x, list.xs], 'cata should work on Cons')
  t.ok(List.Nil.cata({
    Cons: () => false,
    Nil: () => true
  }), 'cata should work on Nil')
  t.ok(List.is(list), '`is` on type works')
  t.notOk(List.is({}), '`is` on type works')
  t.ok(List.Cons.is(list), '`is` on variant works')
  t.notOk(List.Cons.is(list.xs), '`is` on variant works')
  t.notOk(List.Nil.is(list), '`is` on unit value works')
  t.ok(List.Nil.is(list.xs), '`is` on unit value works')
  t.same(List.prototype.foo, list.foo, 'values in typerep.prototype are accassible from instance values')
  t.same(List.prototype.foo, List.Nil.foo, 'values in typerep.prototype are accassible from instance values')
  t.ok(List.prototype.isPrototypeOf(list), 'prototype chain is correct')
  t.ok(List.prototype.isPrototypeOf(List.Nil), 'prototype chain is correct')
  t.test('build from object', (t) => {
    const list = List.Cons.from({xs: List.Nil, x: a})
    const isList = List.is
    const isCons = List.Cons.is
    /* eslint-disable no-multi-spaces, space-in-parens */
    t.strictSame(     List.is(list), true, '`is` on type works')
    t.strictSame(      isList(list), true, '`is` on type works when unbound')
    t.strictSame(List.Cons.is(list), true, '`is` on variant works')
    t.strictSame(      isCons(list), true, '`is` on variant works when unbound')
    /* eslint-enable no-multi-spaces, space-in-parens */
    t.same(list.x, a, 'head value of list works')
    t.same(list.xs, List.Nil, 'tail value of list works')
    t.throws(
      () => { List.Cons.from({x: 1}) },
      new TypeError('Missing field: xs'),
      'when creating a taggedSum from an object with a missing field'
    )
    t.end()
  })
  t.test('pre-bound .is()', (t) => {
    const tpl = Tuple(a, b)
    const isList = List.is
    const isNil = List.Nil.is
    const nilList = List.Nil
    t.test('typeRep.is() is prebound to the typeRep', (t) => {
      t.doesNotThrow(
        () => { isList(list) },
        'typeRep.is() can be assigned to an unbound var and used separately to test instances'
      )
      t.ok(isList(list), 'typeRep.is() should correctly identify instances even when used as an unbound var')
      t.notOk(isList(tpl), 'typeRep.is() should correctly not identify instances of other types even when used as an unbound var')
      t.end()
    })
    t.test('typeRep.tag.is() is prebound to the tag', (t) => {
      t.doesNotThrow(
        () => { isNil(nilList) },
        'typeRep.tag.is() can be assigned to an unbound var and used separately to test instances'
      )
      t.ok(isNil(nilList), 'typeRep.tag.is() should correctly identify instances even when used as an unbound var')
      t.notOk(isNil(tpl), 'typeRep.tag.is() should correctly not identify instances of other types even when used as an unbound var')
      t.end()
    })
    t.end()
  })
  t.end()
})
<commit_msg>Fix typo in test descriptions<commit_after>const { toString } = require('sanctuary-type-classes')
const { test } = require('tap')
const { tagged, taggedSum } = require('../src/daggy')

const Tuple = tagged('Tuple', ['_1', '_2'])

const List = taggedSum('List', {
  Cons: ['x', 'xs'],
  Nil: []
})

Tuple.prototype.foo = 'foo'
List.prototype.foo = 'foo'

const a = 'a'
const b = 'b'

test('tagged', (t) => {
  const tpl = Tuple(a, b)
  t.throws(
    () => { Tuple(1) },
    new TypeError(`Expected 2 arguments, got 1`),
    'when creating a tagged type with fewer arguments throws error'
  )
  t.throws(
    () => { Tuple(1, 2, 3) },
    new TypeError(`Expected 2 arguments, got 3`),
    'when creating a tagged type with too many arguments throws error'
  )
  t.same(tpl.toString(), `Tuple(${toString(a)}, ${toString(b)})`, 'toString on value should work')
  t.same(Tuple.toString(), `Tuple`, 'toString on type should work')
  t.same(tpl._1, a, 'when checking _1 value should return correct value')
  t.same(tpl._2, b, 'when checking _2 value should return correct value')
  t.same(tpl.constructor, Tuple, 'constructor on value should refer to TypeRep of the value')
  t.ok(Tuple.is(tpl), '`is` on type works')
  t.notOk(Tuple.is({}), '`is` on type works')
  t.same(Tuple.prototype.foo, tpl.foo, 'values in typerep.prototype are accessible from instance values')
  t.ok(Tuple.prototype.isPrototypeOf(tpl), 'prototype chain is correct')
  t.test('build from object', (t) => {
    const tpl = Tuple.from({_2: b, _1: a})
    t.same(tpl._1, a, 'First value on tuple is correct')
    t.same(tpl._2, b, 'Second value on tuple is correct')
    t.throws(
      () => { Tuple.from({ _1: 1 }) },
      new TypeError('Missing field: _2'),
      'when creating a tagged type from an object with a missing field'
    )
    t.end()
  })
  t.test('tag.is() is pre-bound to the rep', (t) => {
    const isTuple = Tuple.is
    const list = List.Nil
    t.doesNotThrow(
      () => { isTuple(tpl) },
      'tag.is() can be assigned to an unbound var and used separate to test instances'
    )
    t.ok(isTuple(tpl), 'tag.is() should correctly identify instances even when used as an unbound var')
    t.notOk(isTuple(list), 'tag.is() should correctly not identify instances of other types even when used as an unbound var')
    t.end()
  })
  t.end()
})

test('taggedSum', (t) => {
  const list = List.Cons(a, List.Nil)
  t.throws(
    () => { List.Cons(1) },
    new TypeError(`Expected 2 arguments, got 1`),
    'when creating a taggedSum type with to many arguments throws error'
  )
  t.throws(
    () => { List.Cons(1, 1, 1) },
    new TypeError(`Expected 2 arguments, got 3`),
    'when creating a taggedSum type with to many arguments throws error'
  )
  t.throws(
    () => { List.Nil.cata({}) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if all cases are not handled'
  )
  t.throws(
    () => { list.cata({}) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if all cases are not handled'
  )
  t.throws(
    () => { List.Nil.cata({ Nil: () => false }) },
    new Error(`Constructors given to cata didn't include: Cons`),
    'throws if some cases are not handled'
  )
  t.throws(
    () => { list.cata({ Cons: () => true }) },
    new Error(`Constructors given to cata didn't include: Nil`),
    'throws if some cases are not handled'
  )
  t.same(list.toString(), `List.Cons(${toString(a)}, List.Nil)`, 'toString on value should work')
  t.same(List.toString(), 'List', 'toString on type should work')
  t.same(List.Cons.toString(), 'List.Cons', 'toString on variant constructor should work')
  t.same(List.Nil.toString(), 'List.Nil', 'toString on unit variant should work')
  t.same(list.x, a, 'when checking head value should return correct value')
  t.same(list.xs, List.Nil, 'when checking value value should return correct value')
  t.same(list.xs.constructor, List, 'constructor on value should refer to TypeRep of the value')
  t.same(list.cata({
    Cons: (x, xs) => [x, xs],
    Nil: () => []
  }), [list.x, list.xs], 'cata should work on Cons')
  t.ok(List.Nil.cata({
    Cons: () => false,
    Nil: () => true
  }), 'cata should work on Nil')
  t.ok(List.is(list), '`is` on type works')
  t.notOk(List.is({}), '`is` on type works')
  t.ok(List.Cons.is(list), '`is` on variant works')
  t.notOk(List.Cons.is(list.xs), '`is` on variant works')
  t.notOk(List.Nil.is(list), '`is` on unit value works')
  t.ok(List.Nil.is(list.xs), '`is` on unit value works')
  t.same(List.prototype.foo, list.foo, 'values in typerep.prototype are accessible from instance values')
  t.same(List.prototype.foo, List.Nil.foo, 'values in typerep.prototype are accessible from instance values')
  t.ok(List.prototype.isPrototypeOf(list), 'prototype chain is correct')
  t.ok(List.prototype.isPrototypeOf(List.Nil), 'prototype chain is correct')
  t.test('build from object', (t) => {
    const list = List.Cons.from({xs: List.Nil, x: a})
    const isList = List.is
    const isCons = List.Cons.is
    /* eslint-disable no-multi-spaces, space-in-parens */
    t.strictSame(     List.is(list), true, '`is` on type works')
    t.strictSame(      isList(list), true, '`is` on type works when unbound')
    t.strictSame(List.Cons.is(list), true, '`is` on variant works')
    t.strictSame(      isCons(list), true, '`is` on variant works when unbound')
    /* eslint-enable no-multi-spaces, space-in-parens */
    t.same(list.x, a, 'head value of list works')
    t.same(list.xs, List.Nil, 'tail value of list works')
    t.throws(
      () => { List.Cons.from({x: 1}) },
      new TypeError('Missing field: xs'),
      'when creating a taggedSum from an object with a missing field'
    )
    t.end()
  })
  t.test('pre-bound .is()', (t) => {
    const tpl = Tuple(a, b)
    const isList = List.is
    const isNil = List.Nil.is
    const nilList = List.Nil
    t.test('typeRep.is() is prebound to the typeRep', (t) => {
      t.doesNotThrow(
        () => { isList(list) },
        'typeRep.is() can be assigned to an unbound var and used separately to test instances'
      )
      t.ok(isList(list), 'typeRep.is() should correctly identify instances even when used as an unbound var')
      t.notOk(isList(tpl), 'typeRep.is() should correctly not identify instances of other types even when used as an unbound var')
      t.end()
    })
    t.test('typeRep.tag.is() is prebound to the tag', (t) => {
      t.doesNotThrow(
        () => { isNil(nilList) },
        'typeRep.tag.is() can be assigned to an unbound var and used separately to test instances'
      )
      t.ok(isNil(nilList), 'typeRep.tag.is() should correctly identify instances even when used as an unbound var')
      t.notOk(isNil(tpl), 'typeRep.tag.is() should correctly not identify instances of other types even when used as an unbound var')
      t.end()
    })
    t.end()
  })
  t.end()
})
<|endoftext|>


<commit_before><commit_msg>OPSMN-2401 : Fixed the issue in assigning specimens to list.<commit_after><|endoftext|>


<commit_before>module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: require('../package.json'),
    zip: {
      single: {
        src: ['test_files/file.js'],
        dest: 'actual/single_zip/file.zip'
      },
      multi: {
        src: ['test_files/file.js', 'test_files/file2.js'],
        dest: 'actual/multi_zip/file.zip'
      // },
      // nested: {
      //   // I think I already see the problem -- misuse of **
      //   // src: 'test_files/nested/**',
      //   src: 'test_files/nested/**/*',
      //   dest: 'actual/nested_zip/file.zip'
      }
    },
    unzip: {
      single: {
        src: 'test_files/file.zip',
        dest: 'actual/single_unzip'
      },
      nested: {
        src: 'test_files/nested.zip',
        dest: 'actual/nested_unzip'
      // },
      // nested2: {
      //   src: 'actual/nested_zip/file.zip',
      //   dest: 'actual/nested_zip2'
      }
    },
    test: {
      common: 'zip_test.js'
    }
  });

  // Load local tasks.
  grunt.loadTasks('../tasks');

  // grunt.registerTask('pkg.name', 'aaa', function () {

  //   console.log(this, arguments);
  // });

  // Run project task then tests.
  grunt.registerTask('default', 'zip unzip test');
  // grunt.registerTask('default', 'zip:nested unzip:nested2');
};<commit_msg>Kind of cool -- unzipped files also corrupt -- might be a slick way to check<commit_after>module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: require('../package.json'),
    zip: {
      single: {
        src: ['test_files/file.js'],
        dest: 'actual/single_zip/file.zip'
      },
      multi: {
        src: ['test_files/file.js', 'test_files/file2.js'],
        dest: 'actual/multi_zip/file.zip'
      },
      nested: {
        // I think I already see the problem -- misuse of **
        // src: 'test_files/nested/**',
        src: 'test_files/nested/**/*',
        dest: 'actual/nested_zip/file.zip'
      }
    },
    unzip: {
      single: {
        src: 'test_files/file.zip',
        dest: 'actual/single_unzip'
      },
      nested: {
        src: 'test_files/nested.zip',
        dest: 'actual/nested_unzip'
      },
      nested2: {
        src: 'actual/nested_zip/file.zip',
        dest: 'actual/nested_zip2'
      }
    },
    test: {
      common: 'zip_test.js'
    }
  });

  // Load local tasks.
  grunt.loadTasks('../tasks');

  // grunt.registerTask('pkg.name', 'aaa', function () {

  //   console.log(this, arguments);
  // });

  // Run project task then tests.
  // grunt.registerTask('default', 'zip unzip test');
  grunt.registerTask('default', 'zip:nested unzip:nested2');
};<|endoftext|>


<commit_before>var test = require( 'tape' );

var testIdx = 0;

var sectionRoot = { name: '/' };
var sectionAbout = { name: '/about' };
var sectionInfo = [ { name: '/info' }, { name: '/info2' } ];
var sectionGallery = { name: '/gallery/:image' };
var section404 = { name: '404' };
var router;
var subRouter;
var useURLTimeout;

test( 'testing router', function( t ) {

	var tests = [
		function(section, req) {
			t.equal( section, sectionRoot, 'section is /' );
			router.go( '/info' );
		},

		function(section, req) {
			t.equal( section, sectionInfo, 'section is /info' );
			router.go('/about');
		},

		function(section, req) {
			if(global.location) {
				t.notEqual(global.location.hash, '#!/about', 'hash should not be changed with useURL false');
			}

			router.go( '/gallery/snake' );
		},

		function(section, req) {
			t.equal( section, sectionGallery, 'section is /gallery/:image' );
			t.equal( req.params.image, 'snake', 'param was correct' );
			t.equal( req.route, '/gallery/:image', 'route was correct for gallery' );

			router.go( '/something doesnt exist' );
		},

		function(section, req) {
			t.equal( req.route, '404', '404 route had info');
			t.equal( section, section404, 'section is 404' );

			router.go( 'info' );
		},

		function(section, req) {
			t.equal( section, sectionInfo, 'section is info' );

			router.go( '/redirect' );
		},

		function(section, req) {

			t.equal( section, sectionRoot, 'redirect worked' );

			if( global.location ) {

				useURLTimeout = setTimeout( function() {

					t.fail( 'didn\'t go to 404 when going to route with useURL = false' );
					endTests();
				}, 1000 );

				global.location.hash = '#!/about';
			} else {

				endTests();
			}
		},

		function(section, req) {
			clearTimeout( useURLTimeout );

			t.equal( section, section404, 'went to 404 when trying to use url' );

			endTests();
		}
	];

	var endTests = function() {
		t.end();
	};

	reset();

	router = require( '../' )( {

		'/': sectionRoot,
		'/about': { section: sectionAbout, useURL: false },
		'/info': sectionInfo,
		'/gallery/:image':  { section: sectionGallery, duplicate: true },
		'/redirect': '/',
		'404': section404
	});

	router.on('route', function(info) {
		// Using 500ms to not interfere with another test case
		setTimeout(function() {
			tests.shift()(info.section, info.route);
		},500);
	});

	router.init();
});

test('test 404 redirect', function(t) {

	reset();

	router = require( '../' )( {
		'/': sectionRoot,
		'/about': sectionAbout,
		'404': '/about',

		onRoute: function( section, req ) {

			if(req.route === '/') {
				router.go('something that doesnt exist');
			} else {
				t.equal(section, sectionAbout, 'redirected to about');
				t.end();
			}
		}
	});

	router.on('route', function(info) {
		var req = info.route;
		var section = info.section;

		if(req.route === '/') {
			router.go('something that doesnt exist');
		} else {
			t.equal(section, sectionAbout, 'redirected to about');
			t.end();
		}
	});

	router.init();
});

test('test sub sections', function(t) {

	reset();

	var subTests = [
		function(section, req) {
			t.equal(section, '1', 'first section set');

			process.nextTick( function() {
				subRouter.go('/somethingThatDoesntExist');
			});
		},

		function(section, req) {
			t.equal(section, '404', 'sub 404d');

			process.nextTick( function() {
				subRouter.go('/2');
			});
		},

		function(section, req) {
			t.equal(section, '2', 'second section set');

			process.nextTick( function() {
				router.go('/other');
			});
		},

		function(section, req) {
			t.fail('should have not resolved sub section');
		}
	];
	var countInGallery = 0;

	router = require('../')( {
		'/': '/gallery/1',
		'/gallery/*': { section: 'gallery' },
		'/other': { section: 'other' },
		'404': { section: '404' }
	});

	router.on('route', function(parentInfo) {

		var section = parentInfo.section;
		var req = parentInfo.route;

		if(section === 'gallery') {

			subRouter = router.sub( {
				'/1': { section: '1' },
				'/2': { section: '2' },
				'404': { section: '404' }
			});

			subRouter.on('route', function(info) {
				subTests.shift()(info.section, info.route);
			});

			t.equal(++countInGallery, 1, 'been in gallery only once');
			t.ok(subRouter, 'received a sub router');

			subRouter.init();
		} else if(section === 'other') {

			t.pass('went in other parent section and may have destroyed child');
			t.end();
	  } else {

			t.fail('resolved another url for parent: ' + section);
			t.end();
		}
	});

	router.init();
});

function reset() {

	if(router) {
		router.removeAllListeners('route');
		router.destroy();
	}

	if( global.location ) {

		global.location.hash = '';
	}
}<commit_msg>Fixed tests<commit_after>var test = require( 'tape' );

var testIdx = 0;

var sectionRoot = { name: '/' };
var sectionAbout = { name: '/about' };
var sectionInfo = [ { name: '/info' }, { name: '/info2' } ];
var sectionGallery = { name: '/gallery/:image' };
var section404 = { name: '404' };
var router;
var subRouter;
var useURLTimeout;

test( 'testing router', function( t ) {

	var tests = [
		function(section, req) {
			t.equal( section, sectionRoot, 'section is /' );
			router.go( '/info' );
		},

		function(section, req) {
			t.equal( section, sectionInfo, 'section is /info' );
			router.go('/about');
		},

		function(section, req) {
			if(global.location) {
				t.notEqual(global.location.hash, '#!/about', 'hash should not be changed with useURL false');
			}

			router.go( '/gallery/snake' );
		},

		function(section, req) {
			t.equal( section.section, sectionGallery, 'section is /gallery/:image' );
			t.equal( req.params.image, 'snake', 'param was correct' );
			t.equal( req.route, '/gallery/:image', 'route was correct for gallery' );

			router.go( '/something doesnt exist' );
		},

		function(section, req) {
			t.equal( req.route, '404', '404 route had info');
			t.equal( section, section404, 'section is 404' );

			router.go( 'info' );
		},

		function(section, req) {
			t.equal( section, sectionInfo, 'section is info' );

			router.go( '/redirect' );
		},

		function(section, req) {

			t.equal( section, sectionRoot, 'redirect worked' );

			if( global.location ) {

				useURLTimeout = setTimeout( function() {

					t.fail( 'didn\'t go to 404 when going to route with useURL = false' );
					endTests();
				}, 1000 );

				global.location.hash = '#!/about';
			} else {

				endTests();
			}
		},

		function(section, req) {
			clearTimeout( useURLTimeout );

			t.equal( section, section404, 'went to 404 when trying to use url' );

			endTests();
		}
	];

	var endTests = function() {
		t.end();
	};

	reset();

	router = require( '../' )( {

		'/': sectionRoot,
		'/about': { section: sectionAbout, useURL: false },
		'/info': sectionInfo,
		'/gallery/:image':  { section: sectionGallery, duplicate: true },
		'/redirect': '/',
		'404': section404
	});

	router.on('route', function(info) {
		// Using 500ms to not interfere with another test case
		setTimeout(function() {
			tests.shift()(info.section, info.route);
		},500);
	});

	router.init();
});

test('test 404 redirect', function(t) {

	reset();

	router = require( '../' )( {
		'/': sectionRoot,
		'/about': sectionAbout,
		'404': '/about',

		onRoute: function( section, req ) {

			if(req.route === '/') {
				router.go('something that doesnt exist');
			} else {
				t.equal(section, sectionAbout, 'redirected to about');
				t.end();
			}
		}
	});

	router.on('route', function(info) {
		var req = info.route;
		var section = info.section;

		if(req.route === '/') {
			router.go('something that doesnt exist');
		} else {
			t.equal(section, sectionAbout, 'redirected to about');
			t.end();
		}
	});

	router.init();
});

function reset() {

	if(router) {
		router.removeAllListeners('route');
		router.destroy();
	}

	if( global.location ) {

		global.location.hash = '';
	}
}<|endoftext|>


<commit_before>import test from 'ava';
import {transform} from 'babel-core';
import plugin from '../dist/index';

test('constant boolean unchanged', t => {
  const example = 'var a = true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean and expression reduced', t => {
  const example = 'var a = true && true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean or expression reduced', t => {
  const example = 'var a = false || true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('false boolean or expression reduced', t => {
  const example = 'var a = false || false;';
  const expected = 'var a = false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean mixed expression reduced', t => {
  const example = 'var a = true && false || true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('false boolean mixed expression reduced', t => {
  const example = 'var a = true && (false || false);';
  const expected = 'var a = false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred boolean expression reduced', t => {
  const example = 'var a = true; var b = false || a;';
  const expected = 'var a = true;var b = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('boolean expression with variable partially reduced', t => {
  const example = 'var a = b || true && false;';
  const expected = 'var a = b || false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant number unchanged', t => {
  const example = 'var a = 1;';
  const expected = 'var a = 1;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number addition expression reduced', t => {
  const example = 'var a = 1 + 1;';
  const expected = 'var a = 2;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number subtraction expression reduced', t => {
  const example = 'var a = 1 - 1;';
  const expected = 'var a = 0;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number multiplication expression reduced', t => {
  const example = 'var a = 2 * 2;';
  const expected = 'var a = 4;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number division expression reduced', t => {
  const example = 'var a = 2 / 2;';
  const expected = 'var a = 1;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number mixed expression reduced', t => {
  const example = 'var a = 2 * 2 + 2 * 2;';
  const expected = 'var a = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred number expression reduced', t => {
  const example = 'var a = 2 + 2; var b = a * 2;';
  const expected = 'var a = 4;var b = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library calls reduced', t => {
  const example = 'var a = Math.pow(2, 3);';
  const expected = 'var a = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library Math.random calls not reduced', t => {
  const example = 'var a = Math.random();';
  const expected = 'var a = Math.random();';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number expression with variable partially reduced', t => {
  const example = 'var a = b + 2 * 2;';
  const expected = 'var a = b + 4;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant single quoted string unchanged', t => {
  const example = 'var a = \'a\';';
  const expected = 'var a = \'a\';';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant double quoted string unchanged', t => {
  const example = 'var a = "a";';
  const expected = 'var a = "a";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('single quoted string concat expression reduced', t => {
  const example = 'var a = \'a\' + \'a\';';
  const expected = 'var a = \'aa\';';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('double quoted string concat expression reduced', t => {
  const example = 'var a = "a" + "a";';
  const expected = 'var a = "aa";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred string concat expression reduced', t => {
  const example = 'var a = "a"; var b = a + "a";';
  const expected = 'var a = "a";var b = "aa";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('string libary calls  reduced', t => {
  const example = 'var a = "  a  ".trim();';
  const expected = 'var a = "a";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});
<commit_msg>additional library reduction tests<commit_after>import test from 'ava';
import {transform} from 'babel-core';
import plugin from '../dist/index';

test('constant boolean unchanged', t => {
  const example = 'var a = true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean and expression reduced', t => {
  const example = 'var a = true && true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean or expression reduced', t => {
  const example = 'var a = false || true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('false boolean or expression reduced', t => {
  const example = 'var a = false || false;';
  const expected = 'var a = false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('true boolean mixed expression reduced', t => {
  const example = 'var a = true && false || true;';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('false boolean mixed expression reduced', t => {
  const example = 'var a = true && (false || false);';
  const expected = 'var a = false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred boolean expression reduced', t => {
  const example = 'var a = true; var b = false || a;';
  const expected = 'var a = true;var b = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('boolean expression with variable partially reduced', t => {
  const example = 'var a = b || true && false;';
  const expected = 'var a = b || false;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant number unchanged', t => {
  const example = 'var a = 1;';
  const expected = 'var a = 1;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number addition expression reduced', t => {
  const example = 'var a = 1 + 1;';
  const expected = 'var a = 2;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number subtraction expression reduced', t => {
  const example = 'var a = 1 - 1;';
  const expected = 'var a = 0;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number multiplication expression reduced', t => {
  const example = 'var a = 2 * 2;';
  const expected = 'var a = 4;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number division expression reduced', t => {
  const example = 'var a = 2 / 2;';
  const expected = 'var a = 1;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number mixed expression reduced', t => {
  const example = 'var a = 2 * 2 + 2 * 2;';
  const expected = 'var a = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred number expression reduced', t => {
  const example = 'var a = 2 + 2; var b = a * 2;';
  const expected = 'var a = 4;var b = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library abs calls reduced', t => {
  const example = 'var a = Math.abs(-2);';
  const expected = 'var a = 2;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library cbrt calls reduced', t => {
  const example = 'var a = Math.cbrt(27);';
  const expected = 'var a = 3;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library ceil calls reduced', t => {
  const example = 'var a = Math.ceil(2.1);';
  const expected = 'var a = 3;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library max calls reduced', t => {
  const example = 'var a = Math.max(-1, 2, -2);';
  const expected = 'var a = 2;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library min calls reduced', t => {
  const example = 'var a = Math.min(-1, 2, -2);';
  const expected = 'var a = -2;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library pow calls reduced', t => {
  const example = 'var a = Math.pow(2, 3);';
  const expected = 'var a = 8;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number library Math.random calls not reduced', t => {
  const example = 'var a = Math.random();';
  const expected = 'var a = Math.random();';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('number expression with variable partially reduced', t => {
  const example = 'var a = b + 2 * 2;';
  const expected = 'var a = b + 4;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant single quoted string unchanged', t => {
  const example = 'var a = \'a\';';
  const expected = 'var a = \'a\';';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('constant double quoted string unchanged', t => {
  const example = 'var a = "a";';
  const expected = 'var a = "a";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('single quoted string concat expression reduced', t => {
  const example = 'var a = \'a\' + \'a\';';
  const expected = 'var a = \'aa\';';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('double quoted string concat expression reduced', t => {
  const example = 'var a = "a" + "a";';
  const expected = 'var a = "aa";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('inferred string concat expression reduced', t => {
  const example = 'var a = "a"; var b = a + "a";';
  const expected = 'var a = "a";var b = "aa";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('string libary charAt calls reduced', t => {
  const example = 'var a = "abc".charAt(1);';
  const expected = 'var a = "b";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('string libary trim calls reduced', t => {
  const example = 'var a = "  a  ".trim();';
  const expected = 'var a = "a";';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('string libary includes calls reduced', t => {
  const example = 'var a = "abc".includes("c");';
  const expected = 'var a = true;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});

test('string expression with variable partially reduced', t => {
  const example = 'var a = "a" + "b" + c;';
  const expected = 'var a = "ab" + c;';
  const actual = transform(example, {plugins: [plugin]}).code;
  t.is(actual, expected);
});
<|endoftext|>


<commit_before>import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import stripesConnect from '@folio/stripes-connect/package';
import stripesComponents from '@folio/stripes-components/package';
import stripesLogger from '@folio/stripes-logger/package';

import Pane from '@folio/stripes-components/lib/Pane';
import Headline from '@folio/stripes-components/lib/Headline';
import List from '@folio/stripes-components/lib/List';
import { isVersionCompatible } from '../../discoverServices';
import AboutEnabledModules from './AboutEnabledModules';
import { withModules } from '../Modules';

import stripesCore from '../../../package';
import css from './About.css';

const About = (props) => {
  function renderDependencies(m, interfaces) {
    const base = `${m.module} ${m.version}`;
    if (!interfaces) {
      return base;
    }

    const okapiInterfaces = m.okapiInterfaces;
    if (!okapiInterfaces) {
      return <FormattedMessage id="stripes-core.about.noDependencies" values={{ base }} />;
    }

    const itemFormatter = (key) => {
      const required = okapiInterfaces[key];
      const available = interfaces[key];
      let style = {};
      let text = required;

      if (!available) {
        style = { color: 'red', fontWeight: 'bold' };
      } else if (!isVersionCompatible(available, required)) {
        style = { color: 'orange' };
        text = <FormattedMessage id="stripes-core.about.newerModuleAvailable" values={{ required, available }} />;
      }

      return (

          {key}
          {' '}
          {text}

      );
    };

    return (

        <Headline size="small" faded>
          <FormattedMessage id="stripes-core.about.moduleDependsOn" values={{ module: `${m.module} ${m.version || ''}` }} />
        </Headline>
        <List
          items={Object.keys(okapiInterfaces)}
          itemFormatter={itemFormatter}
          listStyle="bullets"
        />

    );
  }

  function listModules(caption, list, interfaces) {
    const itemFormatter = m => (
{renderDependencies(m, interfaces)}
);
    let headlineMsg;
    switch (caption) {
      case 'app':
        headlineMsg = <FormattedMessage id="stripes-core.about.appModuleCount" values={{ count: list.length }} />;
        break;
      case 'settings':
        headlineMsg = <FormattedMessage id="stripes-core.about.settingsModuleCount" values={{ count: list.length }} />;
        break;
      case 'plugin':
        headlineMsg = <FormattedMessage id="stripes-core.about.pluginModuleCount" values={{ count: list.length }} />;
        break;
      default:
        headlineMsg = <FormattedMessage id="stripes-core.about.moduleTypeCount" values={{ count: list.length, type: caption }} />;
    }
    return (

        <Headline>{headlineMsg}</Headline>

          <List
            listStyle="bullets"
            items={list}
            itemFormatter={itemFormatter}
          />

    );
  }

  const modules = _.get(props.stripes, ['discovery', 'modules']) || {};
  const interfaces = _.get(props.stripes, ['discovery', 'interfaces']) || {};
  const nm = Object.keys(modules).length;
  const ni = Object.keys(interfaces).length;
  const ConnectedAboutEnabledModules = props.stripes.connect(AboutEnabledModules);
  const unknownMsg = <FormattedMessage id="stripes-core.about.unknown" />;
  const numModulesMsg = <FormattedMessage id="stripes-core.about.moduleCount" values={{ count: nm }} />;
  const numInterfacesMsg = <FormattedMessage id="stripes-core.about.interfaceCount" values={{ count: ni }} />;
  return (
    <Pane
      defaultWidth="fill"
      paneTitle={<FormattedMessage id="stripes-core.about.paneTitle" />}
    >

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.userInterface" />
          </Headline>
          <Headline>
            <FormattedMessage id="stripes-core.about.foundation" />
          </Headline>

          <List
            listStyle="bullets"
            items={[
              {
                key: 'stripes-core',
                value: `stripes-core ${stripesCore.version}`,
              },
              {
                key: 'stripes-connect',
                value: `stripes-connect ${stripesConnect.version}`,
              },
              {
                key: 'stripes-components',
                value: `stripes-components ${stripesComponents.version}`,
              },
              {
                key: 'stripes-logger',
                value: `stripes-logger ${stripesLogger.version}`,
              },
            ]}
            itemFormatter={item => (
{item.value}
)}
          />

            {Object.keys(props.modules).map(key => listModules(key, props.modules[key]))}

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.okapiServices" />
          </Headline>
          <Headline>Okapi</Headline>
          <List
            listStyle="bullets"
            itemFormatter={(item, i) => (
{item}
)}
            items={[
              <FormattedMessage id="stripes-core.about.version" values={{ version: _.get(props.stripes, ['discovery', 'okapi']) || unknownMsg }} />,
              <FormattedMessage id="stripes-core.about.forTenant" values={{ tenant: _.get(props.stripes, ['okapi', 'tenant']) || unknownMsg }} />,
              <FormattedMessage id="stripes-core.about.onUrl" values={{ url: _.get(props.stripes, ['okapi', 'url']) || unknownMsg }} />
            ]}
          />

          <Headline>{numModulesMsg}</Headline>
          <ConnectedAboutEnabledModules tenantid={_.get(props.stripes, ['okapi', 'tenant']) || unknownMsg} availableModules={modules} />
          <Headline size="small">
            <FormattedMessage id="stripes-core.about.legendKey" />
          </Headline>
          <FormattedMessage
            id="stripes-core.about.notEnabledModules"
            tagName="p"
            values={{
              span: chunks => {chunks}
            }}
          />

          <Headline>{numInterfacesMsg}</Headline>
          <List
            listStyle="bullets"
            items={Object.keys(interfaces).sort()}
            itemFormatter={key => (

                {`${key} ${interfaces[key]}`}

            )}
          />

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.uiOrServiceDependencies" />
          </Headline>
          <Headline>
            <FormattedMessage id="stripes-core.about.foundation" />
          </Headline>
          {renderDependencies(Object.assign({}, stripesCore.stripes || {}, { module: 'stripes-core' }), interfaces)}

          {Object.keys(props.modules).map(key => listModules(key, props.modules[key], interfaces))}
          <Headline size="small">
            <FormattedMessage id="stripes-core.about.legendKey" />
          </Headline>

            <FormattedMessage
              id="stripes-core.about.key.absentInterfaces"
              values={{
                span: chunks => {chunks}
              }}
            />

            <FormattedMessage
              id="stripes-core.about.key.incompatibleIntf"
              values={{
                span: chunks => {chunks}
              }}
            />

            <FormattedMessage id="stripes-core.about.key.compatible" />

    </Pane>
  );
};

About.propTypes = {
  modules: PropTypes.object,
  stripes: PropTypes.shape({
    discovery: PropTypes.shape({
      modules: PropTypes.object,
      interfaces: PropTypes.object,
    }),
    connect: PropTypes.func,
  }).isRequired,
};

export default withModules(About);
<commit_msg>sort interfaces modules depend on (#908)<commit_after>import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import stripesConnect from '@folio/stripes-connect/package';
import stripesComponents from '@folio/stripes-components/package';
import stripesLogger from '@folio/stripes-logger/package';

import Pane from '@folio/stripes-components/lib/Pane';
import Headline from '@folio/stripes-components/lib/Headline';
import List from '@folio/stripes-components/lib/List';
import { isVersionCompatible } from '../../discoverServices';
import AboutEnabledModules from './AboutEnabledModules';
import { withModules } from '../Modules';

import stripesCore from '../../../package';
import css from './About.css';

const About = (props) => {
  function renderDependencies(m, interfaces) {
    const base = `${m.module} ${m.version}`;
    if (!interfaces) {
      return base;
    }

    const okapiInterfaces = m.okapiInterfaces;
    if (!okapiInterfaces) {
      return <FormattedMessage id="stripes-core.about.noDependencies" values={{ base }} />;
    }

    const itemFormatter = (key) => {
      const required = okapiInterfaces[key];
      const available = interfaces[key];
      let style = {};
      let text = required;

      if (!available) {
        style = { color: 'red', fontWeight: 'bold' };
      } else if (!isVersionCompatible(available, required)) {
        style = { color: 'orange' };
        text = <FormattedMessage id="stripes-core.about.newerModuleAvailable" values={{ required, available }} />;
      }

      return (

          {key}
          {' '}
          {text}

      );
    };

    return (

        <Headline size="small" faded>
          <FormattedMessage id="stripes-core.about.moduleDependsOn" values={{ module: `${m.module} ${m.version || ''}` }} />
        </Headline>
        <List
          items={Object.keys(okapiInterfaces).sort()}
          itemFormatter={itemFormatter}
          listStyle="bullets"
        />

    );
  }

  function listModules(caption, list, interfaces) {
    const itemFormatter = m => (
{renderDependencies(m, interfaces)}
);
    let headlineMsg;
    switch (caption) {
      case 'app':
        headlineMsg = <FormattedMessage id="stripes-core.about.appModuleCount" values={{ count: list.length }} />;
        break;
      case 'settings':
        headlineMsg = <FormattedMessage id="stripes-core.about.settingsModuleCount" values={{ count: list.length }} />;
        break;
      case 'plugin':
        headlineMsg = <FormattedMessage id="stripes-core.about.pluginModuleCount" values={{ count: list.length }} />;
        break;
      default:
        headlineMsg = <FormattedMessage id="stripes-core.about.moduleTypeCount" values={{ count: list.length, type: caption }} />;
    }

    list.sort();

    return (

        <Headline>{headlineMsg}</Headline>

          <List
            listStyle="bullets"
            items={list}
            itemFormatter={itemFormatter}
          />

    );
  }

  const modules = _.get(props.stripes, ['discovery', 'modules']) || {};
  const interfaces = _.get(props.stripes, ['discovery', 'interfaces']) || {};
  const nm = Object.keys(modules).length;
  const ni = Object.keys(interfaces).length;
  const ConnectedAboutEnabledModules = props.stripes.connect(AboutEnabledModules);
  const unknownMsg = <FormattedMessage id="stripes-core.about.unknown" />;
  const numModulesMsg = <FormattedMessage id="stripes-core.about.moduleCount" values={{ count: nm }} />;
  const numInterfacesMsg = <FormattedMessage id="stripes-core.about.interfaceCount" values={{ count: ni }} />;
  return (
    <Pane
      defaultWidth="fill"
      paneTitle={<FormattedMessage id="stripes-core.about.paneTitle" />}
    >

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.userInterface" />
          </Headline>
          <Headline>
            <FormattedMessage id="stripes-core.about.foundation" />
          </Headline>

          <List
            listStyle="bullets"
            items={[
              {
                key: 'stripes-core',
                value: `stripes-core ${stripesCore.version}`,
              },
              {
                key: 'stripes-connect',
                value: `stripes-connect ${stripesConnect.version}`,
              },
              {
                key: 'stripes-components',
                value: `stripes-components ${stripesComponents.version}`,
              },
              {
                key: 'stripes-logger',
                value: `stripes-logger ${stripesLogger.version}`,
              },
            ]}
            itemFormatter={item => (
{item.value}
)}
          />

            {Object.keys(props.modules).map(key => listModules(key, props.modules[key]))}

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.okapiServices" />
          </Headline>
          <Headline>Okapi</Headline>
          <List
            listStyle="bullets"
            itemFormatter={(item, i) => (
{item}
)}
            items={[
              <FormattedMessage id="stripes-core.about.version" values={{ version: _.get(props.stripes, ['discovery', 'okapi']) || unknownMsg }} />,
              <FormattedMessage id="stripes-core.about.forTenant" values={{ tenant: _.get(props.stripes, ['okapi', 'tenant']) || unknownMsg }} />,
              <FormattedMessage id="stripes-core.about.onUrl" values={{ url: _.get(props.stripes, ['okapi', 'url']) || unknownMsg }} />
            ]}
          />

          <Headline>{numModulesMsg}</Headline>
          <ConnectedAboutEnabledModules tenantid={_.get(props.stripes, ['okapi', 'tenant']) || unknownMsg} availableModules={modules} />
          <Headline size="small">
            <FormattedMessage id="stripes-core.about.legendKey" />
          </Headline>
          <FormattedMessage
            id="stripes-core.about.notEnabledModules"
            tagName="p"
            values={{
              span: chunks => {chunks}
            }}
          />

          <Headline>{numInterfacesMsg}</Headline>
          <List
            listStyle="bullets"
            items={Object.keys(interfaces).sort()}
            itemFormatter={key => (

                {`${key} ${interfaces[key]}`}

            )}
          />

          <Headline size="large">
            <FormattedMessage id="stripes-core.about.uiOrServiceDependencies" />
          </Headline>
          <Headline>
            <FormattedMessage id="stripes-core.about.foundation" />
          </Headline>
          {renderDependencies(Object.assign({}, stripesCore.stripes || {}, { module: 'stripes-core' }), interfaces)}

          {Object.keys(props.modules).map(key => listModules(key, props.modules[key], interfaces))}
          <Headline size="small">
            <FormattedMessage id="stripes-core.about.legendKey" />
          </Headline>

            <FormattedMessage
              id="stripes-core.about.key.absentInterfaces"
              values={{
                span: chunks => {chunks}
              }}
            />

            <FormattedMessage
              id="stripes-core.about.key.incompatibleIntf"
              values={{
                span: chunks => {chunks}
              }}
            />

            <FormattedMessage id="stripes-core.about.key.compatible" />

    </Pane>
  );
};

About.propTypes = {
  modules: PropTypes.object,
  stripes: PropTypes.shape({
    discovery: PropTypes.shape({
      modules: PropTypes.object,
      interfaces: PropTypes.object,
    }),
    connect: PropTypes.func,
  }).isRequired,
};

export default withModules(About);
<|endoftext|>


<commit_before>'use strict';

require('chai').should();
const { highlight, encodeURL } = require('hexo-util');

describe('Marked renderer', () => {
  const ctx = {
    config: {
      marked: {}
    }
  };

  const r = require('../lib/renderer').bind(ctx);

  it('default', () => {
    const code = 'console.log("Hello world");';

    const body = [
      '# Hello world',
      '',
      '```',
      code,
      '```',
      '',
      '## Hello world',
      '',
      'hello'
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      '
Hello world
',
      '
' + highlight(code, {gutter: false, wrap: false}) + '
',
      '
Hello world
',
      '
hello
'
    ].join('') + '\n');
  });

  it('should render headings with links', () => {
    const body = [
      '## [hexo-server]',
      '',
      '[hexo-server]: https://github.com/hexojs/hexo-server'
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      '
',
      'hexo-server
'
    ].join(''));
  });

  it('should handle chinese headers properly', () => {
    const body = '# 中文';
    const result = r({text: body});

    result.should.eql('
中文
');
  });

  it('should render headings without headerIds when disabled', () => {
    const body = '## hexo-server';
    ctx.config.marked.headerIds = false;

    const result = r({text: body});

    result.should.eql([
      '
hexo-server
'
    ].join(''));
  });

  // Description List tests

  it('should render description lists with a single space after the colon', () => {
    const result = r({text: 'Description Term
: This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with multiple spaces after the colon', () => {
    const result = r({text: 'Description Term
:    This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with a tab after the colon', () => {
    const result = r({text: 'Description Term
:	This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with a carriage return after the colon', () => {
    const result = r({text: 'Description Term
:\nThis is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should not render regular paragraphs as description lists', () => {
    const result = r({text: 'Description Term
:This is the Description'});
    result.should.eql('
Description Term
:This is the Description
\n');
  });

  it('should encode URL properly', () => {
    const urlA = '/foo/bár.jpg';
    const urlB = 'http://fóo.com/bar.jpg';

    const body = [
      `[foo](${urlA})`,
      `[bar](${urlB})`
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      `<p><a href="${encodeURL(urlA)}">foo</a>`,
      `<a href="${encodeURL(urlB)}">bar</a></p>\n`
    ].join('\n'));
  });

  describe('autolink option tests', () => {
    const ctx = {
      config: {
        marked: {
          autolink: true
        }
      }
    };

    const renderer = require('../lib/renderer');

    const body = [
      'Great website http://hexo.io',
      '',
      '[Hexo](http://hexo.io)'
    ].join('\n');

    it('autolink enabled', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
Great website http://hexo.io
\n',
        '
Hexo
\n'
      ].join(''));
    });

    it('autolink disabled', () => {
      ctx.config.marked.autolink = false;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
Great website http://hexo.io
\n',
        '
Hexo
\n'
      ].join(''));
    });
  });

  describe('modifyAnchors option tests', () => {
    const body = [
      '- [Example](#example)',
      '',
      '# Example'
    ].join('\n');

    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          modifyAnchors: ''
        }
      }
    };

    it('should not modify anchors with default options', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });

    it('should set anchors to upperCase in case of modifyAnchors option is 2', () => {
      ctx.config.marked.modifyAnchors = 2;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });

    it('should set anchors to lowerCase in case of modifyAnchors option is 1', () => {
      ctx.config.marked.modifyAnchors = 1;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });
  });

  describe('prependRoot option tests', () => {
    const body = [
      '![](/bar/baz.jpg)',
      '![foo](/aaa/bbb.jpg)'
    ].join('\n');

    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          prependRoot: false
        },
        root: '/blog/',
        relative_link: false
      }
    };

    it('should not modify image path with default option', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));
    });

    it('should not modify image path when enable relative_link', () => {
      ctx.config.relative_link = true;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));

      ctx.config.relative_link = false;
    });

    it('should prepend image path with root', () => {
      ctx.config.marked.prependRoot = true;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));
      ctx.config.marked.prependRoot = false;
    });
  });

  describe('external_link', () => {
    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          external_link: {
            enable: false
          }
        },
        url: 'http://example.com'
      }
    };

    it('disable', () => {
      const body = '[foo](http://bar.com/)';

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql('
foo
\n');
    });

    it('enable', () => {
      ctx.config.marked.external_link.enable = true;
      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));
    });

    it('exclude - string', () => {
      ctx.config.marked.external_link.exclude = 'bar.com';
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));
    });

    it('exclude - array', () => {
      ctx.config.marked.external_link.exclude = ['bar.com', 'baz.com'];
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));
    });
  });

  describe('nofollow', () => {
    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          nofollow: {
            enable: false
          },
          external_link: {}
        },
        url: 'http://example.com'
      }
    };

    it('disable', () => {
      const body = '[foo](http://bar.com/)';

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql('
foo
\n');
    });

    it('enable', () => {
      ctx.config.marked.nofollow.enable = true;
      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));
    });

    it('exclude - string', () => {
      ctx.config.marked.nofollow.exclude = 'bar.com';
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));

      ctx.config.marked.nofollow.exclude = [];
    });

    it('exclude - array', () => {
      ctx.config.marked.nofollow.exclude = ['bar.com', 'baz.com'];
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));

      ctx.config.marked.nofollow.exclude = [];
    });

    it('nofollow + external_link', () => {
      ctx.config.marked.nofollow.enable = true;
      ctx.config.marked.external_link.enable = true;
      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));
    });

    it('nofollow should not follow external_link.exclude', () => {
      ctx.config.marked.external_link.exclude = 'bar.com';

      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));

      ctx.config.marked.external_link.exclude = [];
    });

    it('external_link should not follow nofollow.exclude', () => {
      ctx.config.marked.nofollow.exclude = 'bar.com';

      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));

      ctx.config.marked.external_link.exclude = [];
    });
  });

  it('should encode image url', () => {
    const urlA = '/foo/bár.jpg';
    const urlB = 'http://fóo.com/bar.jpg';

    const body = [
      `![](${urlA})`,
      `![](${urlB})`
    ].join('\n');

    const renderer = require('../lib/renderer');
    const r = renderer.bind(ctx);

    const result = r({text: body});

    result.should.eql([
      `<p><img src="${encodeURL(urlA)}" alt="">`,
      `<img src="${encodeURL(urlB)}" alt=""></p>\n`
    ].join('\n'));
  });
});
<commit_msg>test(nofollow): simplify config to external_link.nofollow<commit_after>'use strict';

require('chai').should();
const { highlight, encodeURL } = require('hexo-util');

describe('Marked renderer', () => {
  const ctx = {
    config: {
      marked: {}
    }
  };

  const r = require('../lib/renderer').bind(ctx);

  it('default', () => {
    const code = 'console.log("Hello world");';

    const body = [
      '# Hello world',
      '',
      '```',
      code,
      '```',
      '',
      '## Hello world',
      '',
      'hello'
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      '
Hello world
',
      '
' + highlight(code, {gutter: false, wrap: false}) + '
',
      '
Hello world
',
      '
hello
'
    ].join('') + '\n');
  });

  it('should render headings with links', () => {
    const body = [
      '## [hexo-server]',
      '',
      '[hexo-server]: https://github.com/hexojs/hexo-server'
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      '
',
      'hexo-server
'
    ].join(''));
  });

  it('should handle chinese headers properly', () => {
    const body = '# 中文';
    const result = r({text: body});

    result.should.eql('
中文
');
  });

  it('should render headings without headerIds when disabled', () => {
    const body = '## hexo-server';
    ctx.config.marked.headerIds = false;

    const result = r({text: body});

    result.should.eql([
      '
hexo-server
'
    ].join(''));
  });

  // Description List tests

  it('should render description lists with a single space after the colon', () => {
    const result = r({text: 'Description Term
: This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with multiple spaces after the colon', () => {
    const result = r({text: 'Description Term
:    This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with a tab after the colon', () => {
    const result = r({text: 'Description Term
:	This is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should render description lists with a carriage return after the colon', () => {
    const result = r({text: 'Description Term
:\nThis is the Description'});
    result.should.eql('

Description Term

This is the Description

');
  });

  it('should not render regular paragraphs as description lists', () => {
    const result = r({text: 'Description Term
:This is the Description'});
    result.should.eql('
Description Term
:This is the Description
\n');
  });

  it('should encode URL properly', () => {
    const urlA = '/foo/bár.jpg';
    const urlB = 'http://fóo.com/bar.jpg';

    const body = [
      `[foo](${urlA})`,
      `[bar](${urlB})`
    ].join('\n');

    const result = r({text: body});

    result.should.eql([
      `<p><a href="${encodeURL(urlA)}">foo</a>`,
      `<a href="${encodeURL(urlB)}">bar</a></p>\n`
    ].join('\n'));
  });

  describe('autolink option tests', () => {
    const ctx = {
      config: {
        marked: {
          autolink: true
        }
      }
    };

    const renderer = require('../lib/renderer');

    const body = [
      'Great website http://hexo.io',
      '',
      '[Hexo](http://hexo.io)'
    ].join('\n');

    it('autolink enabled', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
Great website http://hexo.io
\n',
        '
Hexo
\n'
      ].join(''));
    });

    it('autolink disabled', () => {
      ctx.config.marked.autolink = false;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
Great website http://hexo.io
\n',
        '
Hexo
\n'
      ].join(''));
    });
  });

  describe('modifyAnchors option tests', () => {
    const body = [
      '- [Example](#example)',
      '',
      '# Example'
    ].join('\n');

    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          modifyAnchors: ''
        }
      }
    };

    it('should not modify anchors with default options', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });

    it('should set anchors to upperCase in case of modifyAnchors option is 2', () => {
      ctx.config.marked.modifyAnchors = 2;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });

    it('should set anchors to lowerCase in case of modifyAnchors option is 1', () => {
      ctx.config.marked.modifyAnchors = 1;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
Example
',
        '
',
        '
Example
'
      ].join('\n'));
    });
  });

  describe('prependRoot option tests', () => {
    const body = [
      '![](/bar/baz.jpg)',
      '![foo](/aaa/bbb.jpg)'
    ].join('\n');

    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          prependRoot: false
        },
        root: '/blog/',
        relative_link: false
      }
    };

    it('should not modify image path with default option', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));
    });

    it('should not modify image path when enable relative_link', () => {
      ctx.config.relative_link = true;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));

      ctx.config.relative_link = false;
    });

    it('should prepend image path with root', () => {
      ctx.config.marked.prependRoot = true;
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
',
        '
\n'
      ].join('\n'));
      ctx.config.marked.prependRoot = false;
    });
  });

  describe('external_link', () => {
    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          external_link: {
            enable: false
          }
        },
        url: 'http://example.com'
      }
    };

    it('disable', () => {
      const body = '[foo](http://bar.com/)';

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql('
foo
\n');
    });

    it('enable', () => {
      ctx.config.marked.external_link.enable = true;
      const body = [
        '[foo](http://bar.com/)',
        '[text](http://example.com/)',
        '[baz](/foo/bar)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'text',
        'baz
\n'
      ].join('\n'));
    });

    it('exclude - string', () => {
      ctx.config.marked.external_link.exclude = 'bar.com';
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));
    });

    it('exclude - array', () => {
      ctx.config.marked.external_link.exclude = ['bar.com', 'baz.com'];
      const body = [
        '[foo](http://foo.com/)',
        '[bar](http://bar.com/)',
        '[baz](http://baz.com/)'
      ].join('\n');

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz
\n'
      ].join('\n'));
    });
  });

  describe('nofollow', () => {
    const renderer = require('../lib/renderer');

    const ctx = {
      config: {
        marked: {
          external_link: {
            enable: false,
            exclude: [],
            nofollow: false
          }
        },
        url: 'http://example.com'
      }
    };

    const body = [
      '[foo](http://foo.com/)',
      '[bar](http://bar.com/)',
      '[baz](http://baz.com/)',
      '[internal](http://example.com/)',
      '[relative](/foo/bar)'
    ].join('\n');

    it('disable', () => {
      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz',
        'internal',
        'relative
\n'
      ].join('\n'));
    });

    it('enable', () => {
      ctx.config.marked.external_link.nofollow = true;

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz',
        'internal',
        'relative
\n'
      ].join('\n'));
    });

    it('exclude - string', () => {
      ctx.config.marked.external_link.exclude = 'bar.com';

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz',
        'internal',
        'relative
\n'
      ].join('\n'));

      ctx.config.marked.external_link.exclude = [];
    });

    it('exclude - array', () => {
      ctx.config.marked.external_link.exclude = ['bar.com', 'baz.com'];

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz',
        'internal',
        'relative
\n'
      ].join('\n'));

      ctx.config.marked.external_link.exclude = [];
    });

    it('nofollow + external_link', () => {
      ctx.config.marked.external_link.nofollow = true;
      ctx.config.marked.external_link.enable = true;

      const r = renderer.bind(ctx);
      const result = r({text: body});

      result.should.eql([
        '
foo',
        'bar',
        'baz',
        'internal',
        'relative
\n'
      ].join('\n'));
    });
  });

  it('should encode image url', () => {
    const urlA = '/foo/bár.jpg';
    const urlB = 'http://fóo.com/bar.jpg';

    const body = [
      `![](${urlA})`,
      `![](${urlB})`
    ].join('\n');

    const renderer = require('../lib/renderer');
    const r = renderer.bind(ctx);

    const result = r({text: body});

    result.should.eql([
      `<p><img src="${encodeURL(urlA)}" alt="">`,
      `<img src="${encodeURL(urlB)}" alt=""></p>\n`
    ].join('\n'));
  });
});
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { isReactElement } from '../../util/validateType'

class ArrowLeft extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isArrowHover: false
    }
  }

  handleArrowMouseOver() {
    this.setState({ isArrowHover: true })
  }

  handleArrowMouseLeave() {
    this.setState({ isArrowHover: false })
  }

  render() {
    const _left_arrow_style = {
      left: 0,
      fontSize: 30,
      color: 'black',
      position: 'absolute',
      top: this.props.wrapperHeight / 2,
      cursor: 'default',
      userSelect: 'none',
      transition: 'opacity .3s',
      opacity: this.props.wrapperIsHover || this.state.isArrowHover ? 1 : 0
    }
    if (this.props.useLeftArrow) {
      if (isReactElement(this.props.useLeftArrow, 'useLeftArrow')) {
        const cloneProps = {
          style: _left_arrow_style,
          onClick: this.props.handleArrowLeft,
          onMouseOver: this.handleArrowMouseOver.bind(this),
          onMouseLeave: this.handleArrowMouseLeave.bind(this)
        }
        return React.cloneElement(this.props.useLeftArrow, cloneProps)
      }
    }
    return (

    )
  }
}

class ArrowRight extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isArrowHover: false
    }
  }

  handleArrowMouseOver() {
    this.setState({ isArrowHover: true })
  }

  handleArrowMouseLeave() {
    this.setState({ isArrowHover: false })
  }

  render() {
    const _right_arrow_style = {
      right: 0,
      fontSize: 30,
      color: 'black',
      position: 'absolute',
      top: this.props.wrapperHeight / 2,
      cursor: 'default',
      userSelect: 'none',
      transition: 'opacity .3s',
      opacity: this.props.wrapperIsHover || this.state.isArrowHover ? 1 : 0
    }
    if (this.props.useRightArrow) {
      if (isReactElement(this.props.useRightArrow, 'useRightArrow')) {
        const cloneProps = {
          style: _right_arrow_style,
          onClick: this.props.handleArrowRight,
          onMouseOver: this.handleArrowMouseOver.bind(this),
          onMouseLeave: this.handleArrowMouseLeave.bind(this)
        }
        return React.cloneElement(this.props.useRightArrow, cloneProps)
      }
    }
    return (

    )
  }
}

export {
  ArrowLeft,
  ArrowRight
}
<commit_msg>changed arrow icon into svg<commit_after>import React, { Component } from 'react'
import { isReactElement } from '../../util/validateType'

class ArrowLeft extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isArrowHover: false
    }
  }

  handleArrowMouseOver() {
    this.setState({ isArrowHover: true })
  }

  handleArrowMouseLeave() {
    this.setState({ isArrowHover: false })
  }

  render() {
    const _left_arrow_style = {
      left: 0,
      fontSize: 30,
      color: 'black',
      position: 'absolute',
      top: this.props.wrapperHeight / 2,
      cursor: 'default',
      userSelect: 'none',
      transition: 'opacity .3s',
      opacity: this.props.wrapperIsHover || this.state.isArrowHover ? 1 : 0
    }
    if (this.props.useLeftArrow) {
      if (isReactElement(this.props.useLeftArrow, 'useLeftArrow')) {
        const cloneProps = {
          style: _left_arrow_style,
          onClick: this.props.handleArrowLeft,
          onMouseOver: this.handleArrowMouseOver.bind(this),
          onMouseLeave: this.handleArrowMouseLeave.bind(this)
        }
        return React.cloneElement(this.props.useLeftArrow, cloneProps)
      }
    }
    return (

    )
  }
}

class ArrowRight extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isArrowHover: false
    }
  }

  handleArrowMouseOver() {
    this.setState({ isArrowHover: true })
  }

  handleArrowMouseLeave() {
    this.setState({ isArrowHover: false })
  }

  render() {
    const _right_arrow_style = {
      right: 0,
      fontSize: 30,
      color: 'black',
      position: 'absolute',
      top: this.props.wrapperHeight / 2,
      cursor: 'default',
      userSelect: 'none',
      transition: 'opacity .3s',
      opacity: this.props.wrapperIsHover || this.state.isArrowHover ? 1 : 0
    }
    if (this.props.useRightArrow) {
      if (isReactElement(this.props.useRightArrow, 'useRightArrow')) {
        const cloneProps = {
          style: _right_arrow_style,
          onClick: this.props.handleArrowRight,
          onMouseOver: this.handleArrowMouseOver.bind(this),
          onMouseLeave: this.handleArrowMouseLeave.bind(this)
        }
        return React.cloneElement(this.props.useRightArrow, cloneProps)
      }
    }
    return (

    )
  }
}

export {
  ArrowLeft,
  ArrowRight
}
<|endoftext|>


<commit_before>'use strict';
/*jshint asi: true */

var test = require('tape')

var fs = require('fs');
var path = require('path');
var asyncReduce = require('../');

if (typeof window === 'undefined') {
  test('\nreducing files to a hash with their modes', function (t) {
    t.plan(2)
    asyncReduce(
        [ 'test', 'examples', '.travis.yml', 'index.js', 'Readme.md' ]
      , {}
      , function size (acc, file, cb) {
          var p = path.join(__dirname, '..', file);

          fs.stat(p, function (err, stat) {
            if (err) return cb(err);

            acc[file] = stat.mode;
            cb(null, acc);
          });
        }
      , function done (err, acc) {
          t.notOk(err, 'no error')
          t.deepEqual(
              acc
            , { test: 16877,
                examples: 16877,
                '.travis.yml': 33188,
                'index.js': 33188,
                'Readme.md': 33188 }
          )
        }
    )
  })
}

test('\nsimulate reducing files to a hash with their modes', function (t) {
  t.plan(2)
  var sizes = {
    test          :  16877,
    examples      :  16877,
    '.travis.yml' :  33188,
    'index.js'    :  33188,
    'Readme.md'   :  33188 }

  asyncReduce(
      [ 'test', 'examples', '.travis.yml', 'index.js' ]
    , {}
    , function size (acc, file, cb) {
        var fileSize = sizes[file]
        acc[file] = fileSize;
        setTimeout(cb.bind(null, null, acc), 5);
      }
    , function done (err, acc) {
        t.notOk(err, 'no error')
        t.deepEqual(
            acc
          , { test: 16877,
              examples: 16877,
              '.travis.yml': 33188,
              'index.js': 33188 }
        )
      }
  )
})

var validIterator = function (acc, item, cb) {}
var validDone = function (err, acc) {}
var seed = ''

test('\nargument validation', function (t) {
  t.throws(
      function () { asyncReduce(1, seed, validIterator, validDone) }
    , /must be an Array/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, '', validDone) }
    , /iterator must be a function/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, function (item, cb) { /* forgot acc */ }, validDone) }
    , /iterator must take at least 3 arguments/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, validIterator, '') }
    , /done must be a function/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, validIterator, function (acc) { /* forgot err */ }) }
    , /done must take at least 2 arguments/
  )
  t.end()
})
<commit_msg>removing Readme from tests entirely<commit_after>'use strict';
/*jshint asi: true */

var test = require('tape')

var fs = require('fs');
var path = require('path');
var asyncReduce = require('../');

if (typeof window === 'undefined') {
  test('\nreducing files to a hash with their modes', function (t) {
    t.plan(2)
    asyncReduce(
        [ 'test', 'examples', '.travis.yml', 'index.js' ]
      , {}
      , function size (acc, file, cb) {
          var p = path.join(__dirname, '..', file);

          fs.stat(p, function (err, stat) {
            if (err) return cb(err);

            acc[file] = stat.mode;
            cb(null, acc);
          });
        }
      , function done (err, acc) {
          t.notOk(err, 'no error')
          t.deepEqual(
              acc
            , { test: 16877,
                examples: 16877,
                '.travis.yml': 33188,
                'index.js': 33188 }
          )
        }
    )
  })
}

test('\nsimulate reducing files to a hash with their modes', function (t) {
  t.plan(2)
  var sizes = {
    test          :  16877,
    examples      :  16877,
    '.travis.yml' :  33188,
    'index.js'    :  33188 }

  asyncReduce(
      [ 'test', 'examples', '.travis.yml', 'index.js' ]
    , {}
    , function size (acc, file, cb) {
        var fileSize = sizes[file]
        acc[file] = fileSize;
        setTimeout(cb.bind(null, null, acc), 5);
      }
    , function done (err, acc) {
        t.notOk(err, 'no error')
        t.deepEqual(
            acc
          , { test: 16877,
              examples: 16877,
              '.travis.yml': 33188,
              'index.js': 33188 }
        )
      }
  )
})

var validIterator = function (acc, item, cb) {}
var validDone = function (err, acc) {}
var seed = ''

test('\nargument validation', function (t) {
  t.throws(
      function () { asyncReduce(1, seed, validIterator, validDone) }
    , /must be an Array/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, '', validDone) }
    , /iterator must be a function/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, function (item, cb) { /* forgot acc */ }, validDone) }
    , /iterator must take at least 3 arguments/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, validIterator, '') }
    , /done must be a function/
  )
  t.throws(
      function () { asyncReduce([1, 2], seed, validIterator, function (acc) { /* forgot err */ }) }
    , /done must take at least 2 arguments/
  )
  t.end()
})
<|endoftext|>