<commit_before>'use strict'

const test = require('tape');
const fs = require('fs-extra');
const s3renity = require(`${__dirname}/../src/S3renity.js`);

const s3 = new s3renity({
  local_path: `${__dirname}/buckets/`
    // verbose: true
});

const bucket = 's3renity';
const prefix = 'files';
const path = `${__dirname}/buckets/s3renity/${prefix}`;
const outputPrefix = 'output-test';
const outputPath = `${__dirname}/buckets/s3renity/${outputPrefix}`;

test('s3renity.list', t => {

  reset();
  t.plan(1);

  let keys = ['test1', 'test2', 'test3'];
  let answer = keys.map(key => `${prefix}/${key}`);
  keys.forEach(key => fs.writeFileSync(`${path}/${key}`));

  s3.list(bucket, prefix).then(keys => {
    let correct = (keys[0] == answer[0] && keys[1] == answer[1] && keys[2] == answer[2]);
    t.ok(correct, 'list objects');
  });

});

test('s3renity.put', t => {

  reset();
  t.plan(1);

  let body = 'hello world';
  let name = 'test'
  let key = `${prefix}/${name}`;
  let filePath = `${path}/${name}`;

  s3.put(bucket, key, body).then(() => {
      let output = fs.readFileSync(filePath);
      t.ok(output == 'hello world', 'put object');
    })
    .catch(console.error);
});

test('s3renity.get', t => {

  reset();
  t.plan(1);

  let name = 'test';
  let answer = 'hello world';

  fs.writeFileSync(`${path}/${name}`, answer);
  let key = `${prefix}/${name}`;

  s3.get(bucket, key).then(obj => {
    t.ok(obj == answer, 'get object');
  });
});

test('s3renity.delete (single)', t => {

  reset();
  t.plan(1);

  let name = 'test';
  let key = `${prefix}/${name}`;

  fs.writeFileSync(`${path}/${name}`, 'hello world');

  s3.delete(bucket, key).then(() => {
    t.ok(!fs.existsSync(`${path}/${name}`), 'delete single object');
  }).catch(console.error);
});

test('s3renity.delete (batch)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`));

  s3.delete(bucket, keys).then(() => {
    let empty = names.filter(key => fs.existsSync(`${prefix}/${key}`)).length == 0;
    t.ok(empty, 'delete multiple objects');
  }).catch(console.error);
});

test('s3renity.context.forEach (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  let results = [];

  s3.context(bucket, prefix).forEach((obj, key) => {
    results.push(key + obj);
  }).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'forEach sync over 3 objects')
  });
});

test('s3renity.context.forEach (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  let results = [];

  s3.context(bucket, prefix).forEach((obj, key) => {
    return new Promise((success, fail) => {
      results.push(key + obj);
      success();
    })
  }, true).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'forEach sync over 3 objects')
  });
});

test('s3renity.context.map (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix).map((obj, key) => {
    return key + obj;
  }).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let results = [];
    names.forEach(name => {
      results.push(fs.readFileSync(`${path}/${name}`).toString());
    });
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'map sync over 3 objects')
  }).catch(console.error);
});

test('s3renity.context.map (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix).map((obj, key) => {
    return new Promise((success, fail) => {
      success(key + obj);
    });
  }, true).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let results = [];
    names.forEach(name => {
      results.push(fs.readFileSync(`${path}/${name}`).toString());
    });
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'map async over 3 objects')
  }).catch(console.error);
});

test('s3renity.context.output.map (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix)
    .output(bucket, outputPrefix)
    .map((obj, key) => {
      return key + obj;
    }).then(() => {
      let answers = keys.map((key, i) => key + names[i]);
      let results = [];
      names.forEach(name => {
        results.push(fs.readFileSync(`${outputPath}/${name}`).toString());
      });
      let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
      t.ok(success, 'map sync over 3 objects')
    }).catch(console.error);
});

test('s3renity.context.output.map (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix)
    .output(bucket, outputPrefix)
    .map((obj, key) => {
      return new Promise((success, fail) => {
        success(key + obj);
      });
    }, true).then(() => {
      let answers = keys.map((key, i) => key + names[i]);
      let results = [];
      names.forEach(name => {
        results.push(fs.readFileSync(`${outputPath}/${name}`).toString());
      });
      let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
      t.ok(success, 'map async over 3 objects')
    }).catch(console.error);
});
''

test('s3renity.context.reduce (sync)', t => {

  t.plan(1);
  reset();

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1test2test3';

  s3.context(bucket, prefix)
    .reduce((prev, cur, key) => {
      if (!prev) {
        return cur;
      } else {
        return prev + cur;
      }
    })
    .then(result => {
      t.ok(result == answer, 'reduce sync 3 objects');
    }).catch(e => console.error(e.stack));
});

test('s3renity.context.reduce (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1test2test3';

  s3.context(bucket, prefix)
    .reduce((prev, cur, key) => {
      return new Promise((success, fail) => {
        if (!prev) {
          success(cur);
        } else {
          success(prev + cur);
        }
      });
    }, null, true)
    .then(result => {
      t.ok(result == answer, 'reduce async 3 objects');
    }).catch(e => console.error(e.stack));
});

test('s3renity.context.filter (sync)', t => {

});

test('end', t => {
  reset();
  t.end();
})

function reset() {
  fs.removeSync(path);
  fs.removeSync(outputPath);
  fs.mkdirsSync(path);
}
<commit_msg>added tests for filter async + sync<commit_after>'use strict'

const test = require('tape');
const fs = require('fs-extra');
const s3renity = require(`${__dirname}/../src/S3renity.js`);

const s3 = new s3renity({
  local_path: `${__dirname}/buckets/`
    // verbose: true
});

const bucket = 's3renity';
const prefix = 'files';
const path = `${__dirname}/buckets/s3renity/${prefix}`;
const outputPrefix = 'output-test';
const outputPath = `${__dirname}/buckets/s3renity/${outputPrefix}`;

test('s3renity.list', t => {

  reset();
  t.plan(1);

  let keys = ['test1', 'test2', 'test3'];
  let answer = keys.map(key => `${prefix}/${key}`);
  keys.forEach(key => fs.writeFileSync(`${path}/${key}`));

  s3.list(bucket, prefix).then(keys => {
    let correct = (keys[0] == answer[0] && keys[1] == answer[1] && keys[2] == answer[2]);
    t.ok(correct, 'list objects');
  });

});

test('s3renity.put', t => {

  reset();
  t.plan(1);

  let body = 'hello world';
  let name = 'test'
  let key = `${prefix}/${name}`;
  let filePath = `${path}/${name}`;

  s3.put(bucket, key, body).then(() => {
      let output = fs.readFileSync(filePath);
      t.ok(output == 'hello world', 'put object');
    })
    .catch(console.error);
});

test('s3renity.get', t => {

  reset();
  t.plan(1);

  let name = 'test';
  let answer = 'hello world';

  fs.writeFileSync(`${path}/${name}`, answer);
  let key = `${prefix}/${name}`;

  s3.get(bucket, key).then(obj => {
    t.ok(obj == answer, 'get object');
  });
});

test('s3renity.delete (single)', t => {

  reset();
  t.plan(1);

  let name = 'test';
  let key = `${prefix}/${name}`;

  fs.writeFileSync(`${path}/${name}`, 'hello world');

  s3.delete(bucket, key).then(() => {
    t.ok(!fs.existsSync(`${path}/${name}`), 'delete single object');
  }).catch(console.error);
});

test('s3renity.delete (batch)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`));

  s3.delete(bucket, keys).then(() => {
    let empty = names.filter(key => fs.existsSync(`${prefix}/${key}`)).length == 0;
    t.ok(empty, 'delete multiple objects');
  }).catch(console.error);
});

test('s3renity.context.forEach (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  let results = [];

  s3.context(bucket, prefix).forEach((obj, key) => {
    results.push(key + obj);
  }).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'forEach sync over 3 objects')
  });
});

test('s3renity.context.forEach (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  let results = [];

  s3.context(bucket, prefix).forEach((obj, key) => {
    return new Promise((success, fail) => {
      results.push(key + obj);
      success();
    })
  }, true).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'forEach sync over 3 objects')
  });
});

test('s3renity.context.map (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix).map((obj, key) => {
    return key + obj;
  }).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let results = [];
    names.forEach(name => {
      results.push(fs.readFileSync(`${path}/${name}`).toString());
    });
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'map sync over 3 objects')
  }).catch(console.error);
});

test('s3renity.context.map (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix).map((obj, key) => {
    return new Promise((success, fail) => {
      success(key + obj);
    });
  }, true).then(() => {
    let answers = keys.map((key, i) => key + names[i]);
    let results = [];
    names.forEach(name => {
      results.push(fs.readFileSync(`${path}/${name}`).toString());
    });
    let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
    t.ok(success, 'map async over 3 objects')
  }).catch(console.error);
});

test('s3renity.context.output.map (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix)
    .output(bucket, outputPrefix)
    .map((obj, key) => {
      return key + obj;
    }).then(() => {
      let answers = keys.map((key, i) => key + names[i]);
      let results = [];
      names.forEach(name => {
        results.push(fs.readFileSync(`${outputPath}/${name}`).toString());
      });
      let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
      t.ok(success, 'map sync over 3 objects')
    }).catch(console.error);
});

test('s3renity.context.output.map (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));

  s3.context(bucket, prefix)
    .output(bucket, outputPrefix)
    .map((obj, key) => {
      return new Promise((success, fail) => {
        success(key + obj);
      });
    }, true).then(() => {
      let answers = keys.map((key, i) => key + names[i]);
      let results = [];
      names.forEach(name => {
        results.push(fs.readFileSync(`${outputPath}/${name}`).toString());
      });
      let success = answers[0] == results[0] && answers[1] == results[1] && answers[2] == results[2];
      t.ok(success, 'map async over 3 objects')
    }).catch(console.error);
});
''

test('s3renity.context.reduce (sync)', t => {

  t.plan(1);
  reset();

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1test2test3';

  s3.context(bucket, prefix)
    .reduce((prev, cur, key) => {
      if (!prev) {
        return cur;
      } else {
        return prev + cur;
      }
    })
    .then(result => {
      t.ok(result == answer, 'reduce sync 3 objects');
    }).catch(e => console.error(e.stack));
});

test('s3renity.context.reduce (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1test2test3';

  s3.context(bucket, prefix)
    .reduce((prev, cur, key) => {
      return new Promise((success, fail) => {
        if (!prev) {
          success(cur);
        } else {
          success(prev + cur);
        }
      });
    }, null, true)
    .then(result => {
      t.ok(result == answer, 'reduce async 3 objects');
    }).catch(e => console.error(e.stack));
});

test('s3renity.context.filter (sync)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1';

  s3.context(bucket, prefix)
  .filter(obj => {
    return obj == 'test1';
  })
  .then(() => {
    t.ok(fs.readdirSync(path) == answer, 'filter 3 files to 1');
  })
  .catch(e => console.error(e.stack));
});

test('s3renity.context.filter (async)', t => {

  reset();
  t.plan(1);

  let names = ['test1', 'test2', 'test3'];
  let keys = names.map(key => `${prefix}/${key}`);
  names.forEach(key => fs.writeFileSync(`${path}/${key}`, key));
  let answer = 'test1';

  s3.context(bucket, prefix)
  .filter(obj => {
    return new Promise((success, fail) => {
      success(obj == 'test1');
    });
  }, true)
  .then(() => {
    t.ok(fs.readdirSync(path) == answer, 'filter 3 files to 1');
  })
  .catch(e => console.error(e.stack));
});

test('end', t => {
  reset();
  t.end();
})

function reset() {
  fs.removeSync(path);
  fs.removeSync(outputPath);
  fs.mkdirsSync(path);
}
<|endoftext|>


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

/**
 * marked tests
 * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
 * https://github.com/chjj/marked
 */

/**
 * Modules
 */

var fs = require('fs')
  , path = require('path')
  , fm = require('front-matter')
  , g2r = require('glob-to-regexp')
  , marked = require('../');

/**
 * Load Tests
 */

function load(options) {
  var dir = __dirname + '/compiled_tests'
    , files = {}
    , list
    , file
    , name
    , content
    , regex
    , skip
    , glob = g2r(options.glob || "*", { extended: true })
    , i
    , j
    , l;

  list = fs
    .readdirSync(dir)
    .filter(function(file) {
      return path.extname(file) !== '.html';
    })
    .sort();

  l = list.length;

  for (i = 0; i < l; i++) {
    name = path.basename(list[i], ".md");
    if (glob.test(name)) {
      file = path.join(dir, list[i]);
      content = fm(fs.readFileSync(file, 'utf8'));

      files[name] = {
        options: content.attributes,
        text: content.body,
        html: fs.readFileSync(file.replace(/[^.]+$/, 'html'), 'utf8')
      };
    }
  }

  if (options.bench || options.time) {
    if (!options.glob) {
      // Change certain tests to allow
      // comparison to older benchmark times.
      fs.readdirSync(__dirname + '/new').forEach(function(name) {
        if (path.extname(name) === '.html') return;
        if (name === 'main.md') return;
        delete files[name];
      });
    }

    if (files['backslash_escapes.md']) {
      files['backslash_escapes.md'] = {
        text: 'hello world \\[how](are you) today'
      };
    }

    if (files['main.md']) {
      files['main.md'].text = files['main.md'].text.replace('* * *\n\n', '');
    }
  }

  return files;
}

/**
 * Test Runner
 */

function runTests(engine, options) {
  if (typeof engine !== 'function') {
    options = engine;
    engine = null;
  }

  var engine = engine || marked
    , options = options || {}
    , files = options.files || load(options)
    , complete = 0
    , failed = 0
    , failures = []
    , keys = Object.keys(files)
    , i = 0
    , len = keys.length
    , filename
    , file
    , opts
    , text
    , html
    , j
    , l;

  if (options.marked) {
    marked.setOptions(options.marked);
  }

main:
  for (; i < len; i++) {
    filename = keys[i];
    file = files[filename];
    opts = Object.keys(file.options);

    if (marked._original) {
      marked.defaults = marked._original;
      delete marked._original;
    }

    if (opts.length) {
      marked._original = marked.defaults;
      marked.defaults = {};
      Object.keys(marked._original).forEach(function(key) {
        marked.defaults[key] = marked._original[key];
      });
      opts.forEach(function(key) {
        if (marked.defaults.hasOwnProperty(key)) {
          marked.defaults[key] = file.options[key];
        }
      });
    }

    try {
      text = engine(file.text).replace(/\s/g, '');
      html = file.html.replace(/\s/g, '');
    } catch (e) {
      console.log('%s failed.', filename);
      throw e;
    }

    j = 0;
    l = html.length;

    for (; j < l; j++) {
      if (text[j] !== html[j]) {
        failed++;
        failures.push(filename);

        text = text.substring(
          Math.max(j - 30, 0),
          Math.min(j + 30, text.length));

        html = html.substring(
          Math.max(j - 30, 0),
          Math.min(j + 30, html.length));

        console.log(
          '\n#%d. %s failed at offset %d. Near: "%s".\n',
          i + 1, filename, j, text);

        console.log('\nGot:\n%s\n', text.trim() || text);
        console.log('\nExpected:\n%s\n', html.trim() || html);

        if (options.stop) {
          break main;
        }

        continue main;
      }
    }

    complete++;
    console.log('#%d. %s completed.', i + 1, filename);
  }

  console.log('%d/%d tests completed successfully.', complete, len);
  if (failed) console.log('%d/%d tests failed.', failed, len);

  return !failed;
}

/**
 * Benchmark a function
 */

function bench(name, files, func) {
  var start = Date.now()
    , times = 1000
    , keys = Object.keys(files)
    , i
    , l = keys.length
    , filename
    , file;

  while (times--) {
    for (i = 0; i < l; i++) {
      filename = keys[i];
      file = files[filename];
      func(file.text);
    }
  }

  console.log('%s completed in %dms.', name, Date.now() - start);
}

/**
 * Benchmark all engines
 */

function runBench(options) {
  var options = options || {}
    , files = load(options);

  // Non-GFM, Non-pedantic
  marked.setOptions({
    gfm: false,
    tables: false,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked', files, marked);

  // GFM
  marked.setOptions({
    gfm: true,
    tables: false,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked (gfm)', files, marked);

  // Pedantic
  marked.setOptions({
    gfm: false,
    tables: false,
    breaks: false,
    pedantic: true,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked (pedantic)', files, marked);

  // showdown
  try {
    bench('showdown (reuse converter)', files, (function() {
      var Showdown = require('showdown');
      var convert = new Showdown.Converter();
      return function(text) {
        return convert.makeHtml(text);
      };
    })());
    bench('showdown (new converter)', files, (function() {
      var Showdown = require('showdown');
      return function(text) {
        var convert = new Showdown.Converter();
        return convert.makeHtml(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench showdown. (Error: %s)', e.message);
  }

  // markdown-it
  try {
    bench('markdown-it', files, (function() {
      var MarkdownIt = require('markdown-it');
      var md = new MarkdownIt();
      return function(text) {
        return md.render(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench markdown-it. (Error: %s)', e.message);
  }

  // markdown.js
  try {
    bench('markdown.js', files, (function() {
      var markdown = require('markdown').markdown;
      return function(text) {
        return markdown.toHTML(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench markdown.js. (Error: %s)', e.message);
  }

  return true;
}

/**
 * A simple one-time benchmark
 */

function time(options) {
  var options = options || {}
    , files = load(options);
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked', files, marked);

  return true;
}

/**
 * Markdown Test Suite Fixer
 *   This function is responsible for "fixing"
 *   the markdown test suite. There are
 *   certain aspects of the suite that
 *   are strange or might make tests
 *   fail for reasons unrelated to
 *   conformance.
 */

function fix() {
  ['compiled_tests', 'original', 'new'].forEach(function(dir) {
    try {
      fs.mkdirSync(path.resolve(__dirname, dir), 0o755);
    } catch (e) {
      ;
    }
  });

  // rm -rf tests
  fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(function(file) {
    fs.unlinkSync(path.resolve(__dirname, 'compiled_tests', file));
  });

  // cp -r original tests
  fs.readdirSync(path.resolve(__dirname, 'original')).forEach(function(file) {
    var text = fs.readFileSync(path.resolve(__dirname, 'original', file));

    if (file === 'hard_wrapped_paragraphs_with_list_like_lines.md') {
      text = '---\ngfm: false\n---\n' + text;
    }

    fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file), text);
  });

  // node fix.js
  var dir = __dirname + '/compiled_tests';

  fs.readdirSync(dir).filter(function(file) {
    return path.extname(file) === '.html';
  }).forEach(function(file) {
    var file = path.join(dir, file)
      , html = fs.readFileSync(file, 'utf8');

    // fix unencoded quotes
    html = html
      .replace(/='([^\n']*)'(?=[^<>\n]*>)/g, '=&__APOS__;$1&__APOS__;')
      .replace(/="([^\n"]*)"(?=[^<>\n]*>)/g, '=&__QUOT__;$1&__QUOT__;')
      .replace(/"/g, '"')
      .replace(/'/g, ''')
      .replace(/&__QUOT__;/g, '"')
      .replace(/&__APOS__;/g, '\'');

    // add heading id's
    html = html.replace(/<(h[1-6])>([^<]+)<\/\1>/g, function(s, h, text) {
      var id = text
        .replace(/'/g, '\'')
        .replace(/"/g, '"')
        .replace(/>/g, '>')
        .replace(/</g, '<')
        .replace(/&/g, '&');

      id = id.toLowerCase().replace(/[^\w]+/g, '-');

      return '<' + h + ' id="' + id + '">' + text + '</' + h + '>';
    });

    fs.writeFileSync(file, html);
  });

  // turn
 into

  fs.readdirSync(dir).forEach(function(file) {
    var file = path.join(dir, file)
      , text = fs.readFileSync(file, 'utf8');

    text = text.replace(/(<|<)hr\s*\/(>|>)/g, '$1hr$2');

    fs.writeFileSync(file, text);
  });

  // markdown does some strange things.
  // it does not encode naked `>`, marked does.
  (function() {
    var file = dir + '/amps_and_angles_encoding.html';
    var html = fs.readFileSync(file, 'utf8')
      .replace('6 > 5.', '6 > 5.');

    fs.writeFileSync(file, html);
  })();

  // cp new/* tests/
  fs.readdirSync(path.resolve(__dirname, 'new')).forEach(function(file) {
    fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
      fs.readFileSync(path.resolve(__dirname, 'new', file)));
  });
}

/**
 * Argument Parsing
 */

function parseArg(argv) {
  var argv = process.argv.slice(2)
    , options = {}
    , opt = ""
    , orphans = []
    , arg;

  function getarg() {
    var arg = argv.shift();

    if (arg.indexOf('--') === 0) {
      // e.g. --opt
      arg = arg.split('=');
      if (arg.length > 1) {
        // e.g. --opt=val
        argv.unshift(arg.slice(1).join('='));
      }
      arg = arg[0];
    } else if (arg[0] === '-') {
      if (arg.length > 2) {
        // e.g. -abc
        argv = arg.substring(1).split('').map(function(ch) {
          return '-' + ch;
        }).concat(argv);
        arg = argv.shift();
      } else {
        // e.g. -a
      }
    } else {
      // e.g. foo
    }

    return arg;
  }

  while (argv.length) {
    arg = getarg();
    switch (arg) {
      case '-f':
      case '--fix':
      case 'fix':
        if (options.fix !== false) {
          options.fix = true;
        }
        break;
      case '--no-fix':
      case 'no-fix':
        options.fix = false;
        break;
      case '-b':
      case '--bench':
        options.bench = true;
        break;
      case '-s':
      case '--stop':
        options.stop = true;
        break;
      case '-t':
      case '--time':
        options.time = true;
        break;
      case '--glob':
        arg = argv.shift();
        options.glob = arg.replace(/^=/, '');
        break;
      default:
        if (arg.indexOf('--') === 0) {
          opt = camelize(arg.replace(/^--(no-)?/, ''));
          if (!marked.defaults.hasOwnProperty(opt)) {
            continue;
          }
          options.marked = options.marked || {};
          if (arg.indexOf('--no-') === 0) {
            options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
              ? null
              : false;
          } else {
            options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
              ? argv.shift()
              : true;
          }
        } else {
          orphans.push(arg);
        }
        break;
    }
  }

  return options;
}

/**
 * Helpers
 */

function camelize(text) {
  return text.replace(/(\w)-(\w)/g, function(_, a, b) {
    return a + b.toUpperCase();
  });
}

/**
 * Main
 */

function main(argv) {
  var opt = parseArg();

  if (opt.fix !== false) {
    fix();
  }

  if (opt.fix) {
    // only run fix
    return;
  }

  if (opt.bench) {
    return runBench(opt);
  }

  if (opt.time) {
    return time(opt);
  }

  return runTests(opt);
}

/**
 * Execute
 */

if (!module.parent) {
  process.title = 'marked';
  process.exit(main(process.argv.slice()) ? 0 : 1);
} else {
  exports = main;
  exports.main = main;
  exports.runTests = runTests;
  exports.runBench = runBench;
  exports.load = load;
  exports.bench = bench;
  module.exports = exports;
}
<commit_msg>disable gfm for old markdown.pl test case<commit_after>#!/usr/bin/env node

/**
 * marked tests
 * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
 * https://github.com/chjj/marked
 */

/**
 * Modules
 */

var fs = require('fs')
  , path = require('path')
  , fm = require('front-matter')
  , g2r = require('glob-to-regexp')
  , marked = require('../');

/**
 * Load Tests
 */

function load(options) {
  var dir = __dirname + '/compiled_tests'
    , files = {}
    , list
    , file
    , name
    , content
    , regex
    , skip
    , glob = g2r(options.glob || "*", { extended: true })
    , i
    , j
    , l;

  list = fs
    .readdirSync(dir)
    .filter(function(file) {
      return path.extname(file) !== '.html';
    })
    .sort();

  l = list.length;

  for (i = 0; i < l; i++) {
    name = path.basename(list[i], ".md");
    if (glob.test(name)) {
      file = path.join(dir, list[i]);
      content = fm(fs.readFileSync(file, 'utf8'));

      files[name] = {
        options: content.attributes,
        text: content.body,
        html: fs.readFileSync(file.replace(/[^.]+$/, 'html'), 'utf8')
      };
    }
  }

  if (options.bench || options.time) {
    if (!options.glob) {
      // Change certain tests to allow
      // comparison to older benchmark times.
      fs.readdirSync(__dirname + '/new').forEach(function(name) {
        if (path.extname(name) === '.html') return;
        if (name === 'main.md') return;
        delete files[name];
      });
    }

    if (files['backslash_escapes.md']) {
      files['backslash_escapes.md'] = {
        text: 'hello world \\[how](are you) today'
      };
    }

    if (files['main.md']) {
      files['main.md'].text = files['main.md'].text.replace('* * *\n\n', '');
    }
  }

  return files;
}

/**
 * Test Runner
 */

function runTests(engine, options) {
  if (typeof engine !== 'function') {
    options = engine;
    engine = null;
  }

  var engine = engine || marked
    , options = options || {}
    , files = options.files || load(options)
    , complete = 0
    , failed = 0
    , failures = []
    , keys = Object.keys(files)
    , i = 0
    , len = keys.length
    , filename
    , file
    , opts
    , text
    , html
    , j
    , l;

  if (options.marked) {
    marked.setOptions(options.marked);
  }

main:
  for (; i < len; i++) {
    filename = keys[i];
    file = files[filename];
    opts = Object.keys(file.options);

    if (marked._original) {
      marked.defaults = marked._original;
      delete marked._original;
    }

    if (opts.length) {
      marked._original = marked.defaults;
      marked.defaults = {};
      Object.keys(marked._original).forEach(function(key) {
        marked.defaults[key] = marked._original[key];
      });
      opts.forEach(function(key) {
        if (marked.defaults.hasOwnProperty(key)) {
          marked.defaults[key] = file.options[key];
        }
      });
    }

    try {
      text = engine(file.text).replace(/\s/g, '');
      html = file.html.replace(/\s/g, '');
    } catch (e) {
      console.log('%s failed.', filename);
      throw e;
    }

    j = 0;
    l = html.length;

    for (; j < l; j++) {
      if (text[j] !== html[j]) {
        failed++;
        failures.push(filename);

        text = text.substring(
          Math.max(j - 30, 0),
          Math.min(j + 30, text.length));

        html = html.substring(
          Math.max(j - 30, 0),
          Math.min(j + 30, html.length));

        console.log(
          '\n#%d. %s failed at offset %d. Near: "%s".\n',
          i + 1, filename, j, text);

        console.log('\nGot:\n%s\n', text.trim() || text);
        console.log('\nExpected:\n%s\n', html.trim() || html);

        if (options.stop) {
          break main;
        }

        continue main;
      }
    }

    complete++;
    console.log('#%d. %s completed.', i + 1, filename);
  }

  console.log('%d/%d tests completed successfully.', complete, len);
  if (failed) console.log('%d/%d tests failed.', failed, len);

  return !failed;
}

/**
 * Benchmark a function
 */

function bench(name, files, func) {
  var start = Date.now()
    , times = 1000
    , keys = Object.keys(files)
    , i
    , l = keys.length
    , filename
    , file;

  while (times--) {
    for (i = 0; i < l; i++) {
      filename = keys[i];
      file = files[filename];
      func(file.text);
    }
  }

  console.log('%s completed in %dms.', name, Date.now() - start);
}

/**
 * Benchmark all engines
 */

function runBench(options) {
  var options = options || {}
    , files = load(options);

  // Non-GFM, Non-pedantic
  marked.setOptions({
    gfm: false,
    tables: false,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked', files, marked);

  // GFM
  marked.setOptions({
    gfm: true,
    tables: false,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked (gfm)', files, marked);

  // Pedantic
  marked.setOptions({
    gfm: false,
    tables: false,
    breaks: false,
    pedantic: true,
    sanitize: false,
    smartLists: false
  });
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked (pedantic)', files, marked);

  // showdown
  try {
    bench('showdown (reuse converter)', files, (function() {
      var Showdown = require('showdown');
      var convert = new Showdown.Converter();
      return function(text) {
        return convert.makeHtml(text);
      };
    })());
    bench('showdown (new converter)', files, (function() {
      var Showdown = require('showdown');
      return function(text) {
        var convert = new Showdown.Converter();
        return convert.makeHtml(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench showdown. (Error: %s)', e.message);
  }

  // markdown-it
  try {
    bench('markdown-it', files, (function() {
      var MarkdownIt = require('markdown-it');
      var md = new MarkdownIt();
      return function(text) {
        return md.render(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench markdown-it. (Error: %s)', e.message);
  }

  // markdown.js
  try {
    bench('markdown.js', files, (function() {
      var markdown = require('markdown').markdown;
      return function(text) {
        return markdown.toHTML(text);
      };
    })());
  } catch (e) {
    console.log('Could not bench markdown.js. (Error: %s)', e.message);
  }

  return true;
}

/**
 * A simple one-time benchmark
 */

function time(options) {
  var options = options || {}
    , files = load(options);
  if (options.marked) {
    marked.setOptions(options.marked);
  }
  bench('marked', files, marked);

  return true;
}

/**
 * Markdown Test Suite Fixer
 *   This function is responsible for "fixing"
 *   the markdown test suite. There are
 *   certain aspects of the suite that
 *   are strange or might make tests
 *   fail for reasons unrelated to
 *   conformance.
 */

function fix() {
  ['compiled_tests', 'original', 'new'].forEach(function(dir) {
    try {
      fs.mkdirSync(path.resolve(__dirname, dir), 0o755);
    } catch (e) {
      ;
    }
  });

  // rm -rf tests
  fs.readdirSync(path.resolve(__dirname, 'compiled_tests')).forEach(function(file) {
    fs.unlinkSync(path.resolve(__dirname, 'compiled_tests', file));
  });

  // cp -r original tests
  fs.readdirSync(path.resolve(__dirname, 'original')).forEach(function(file) {
    var text = fs.readFileSync(path.resolve(__dirname, 'original', file));

    if (path.extname(file) === '.md') {
      text = '---\ngfm: false\n---\n' + text;
    }

    fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file), text);
  });

  // node fix.js
  var dir = __dirname + '/compiled_tests';

  fs.readdirSync(dir).filter(function(file) {
    return path.extname(file) === '.html';
  }).forEach(function(file) {
    var file = path.join(dir, file)
      , html = fs.readFileSync(file, 'utf8');

    // fix unencoded quotes
    html = html
      .replace(/='([^\n']*)'(?=[^<>\n]*>)/g, '=&__APOS__;$1&__APOS__;')
      .replace(/="([^\n"]*)"(?=[^<>\n]*>)/g, '=&__QUOT__;$1&__QUOT__;')
      .replace(/"/g, '"')
      .replace(/'/g, ''')
      .replace(/&__QUOT__;/g, '"')
      .replace(/&__APOS__;/g, '\'');

    // add heading id's
    html = html.replace(/<(h[1-6])>([^<]+)<\/\1>/g, function(s, h, text) {
      var id = text
        .replace(/'/g, '\'')
        .replace(/"/g, '"')
        .replace(/>/g, '>')
        .replace(/</g, '<')
        .replace(/&/g, '&');

      id = id.toLowerCase().replace(/[^\w]+/g, '-');

      return '<' + h + ' id="' + id + '">' + text + '</' + h + '>';
    });

    fs.writeFileSync(file, html);
  });

  // turn
 into

  fs.readdirSync(dir).forEach(function(file) {
    var file = path.join(dir, file)
      , text = fs.readFileSync(file, 'utf8');

    text = text.replace(/(<|<)hr\s*\/(>|>)/g, '$1hr$2');

    fs.writeFileSync(file, text);
  });

  // markdown does some strange things.
  // it does not encode naked `>`, marked does.
  (function() {
    var file = dir + '/amps_and_angles_encoding.html';
    var html = fs.readFileSync(file, 'utf8')
      .replace('6 > 5.', '6 > 5.');

    fs.writeFileSync(file, html);
  })();

  // cp new/* tests/
  fs.readdirSync(path.resolve(__dirname, 'new')).forEach(function(file) {
    fs.writeFileSync(path.resolve(__dirname, 'compiled_tests', file),
      fs.readFileSync(path.resolve(__dirname, 'new', file)));
  });
}

/**
 * Argument Parsing
 */

function parseArg(argv) {
  var argv = process.argv.slice(2)
    , options = {}
    , opt = ""
    , orphans = []
    , arg;

  function getarg() {
    var arg = argv.shift();

    if (arg.indexOf('--') === 0) {
      // e.g. --opt
      arg = arg.split('=');
      if (arg.length > 1) {
        // e.g. --opt=val
        argv.unshift(arg.slice(1).join('='));
      }
      arg = arg[0];
    } else if (arg[0] === '-') {
      if (arg.length > 2) {
        // e.g. -abc
        argv = arg.substring(1).split('').map(function(ch) {
          return '-' + ch;
        }).concat(argv);
        arg = argv.shift();
      } else {
        // e.g. -a
      }
    } else {
      // e.g. foo
    }

    return arg;
  }

  while (argv.length) {
    arg = getarg();
    switch (arg) {
      case '-f':
      case '--fix':
      case 'fix':
        if (options.fix !== false) {
          options.fix = true;
        }
        break;
      case '--no-fix':
      case 'no-fix':
        options.fix = false;
        break;
      case '-b':
      case '--bench':
        options.bench = true;
        break;
      case '-s':
      case '--stop':
        options.stop = true;
        break;
      case '-t':
      case '--time':
        options.time = true;
        break;
      case '--glob':
        arg = argv.shift();
        options.glob = arg.replace(/^=/, '');
        break;
      default:
        if (arg.indexOf('--') === 0) {
          opt = camelize(arg.replace(/^--(no-)?/, ''));
          if (!marked.defaults.hasOwnProperty(opt)) {
            continue;
          }
          options.marked = options.marked || {};
          if (arg.indexOf('--no-') === 0) {
            options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
              ? null
              : false;
          } else {
            options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
              ? argv.shift()
              : true;
          }
        } else {
          orphans.push(arg);
        }
        break;
    }
  }

  return options;
}

/**
 * Helpers
 */

function camelize(text) {
  return text.replace(/(\w)-(\w)/g, function(_, a, b) {
    return a + b.toUpperCase();
  });
}

/**
 * Main
 */

function main(argv) {
  var opt = parseArg();

  if (opt.fix !== false) {
    fix();
  }

  if (opt.fix) {
    // only run fix
    return;
  }

  if (opt.bench) {
    return runBench(opt);
  }

  if (opt.time) {
    return time(opt);
  }

  return runTests(opt);
}

/**
 * Execute
 */

if (!module.parent) {
  process.title = 'marked';
  process.exit(main(process.argv.slice()) ? 0 : 1);
} else {
  exports = main;
  exports.main = main;
  exports.runTests = runTests;
  exports.runBench = runBench;
  exports.load = load;
  exports.bench = bench;
  module.exports = exports;
}
<|endoftext|>


<commit_before>var test = require('assert-tap').test;
var process = require('process');
var path = require('path');
var exec = require('child_process').exec;

require('./uncaught.js');
require('./shutdown.js');

test('check coverage', function t(assert) {
    getCoverage(function onCoverage(err, out) {
        assert.ifError(err);

        if (out) {
            console.warn('Code coverage is not 100%');
            console.log(out.report);
            console.log('SUGGESTED FIX: get 100% code coverage');
            process.exit(1);
        } else {
            assert.ok(true);
            assert.end();
        }
    });
});

function getCoverage(cb) {
    var cmd = path.join(__dirname, '..', 'node_modules',
        '.bin', 'istanbul');
    exec(cmd + ' check-coverage --statements=100', {
        cwd: path.join(__dirname, '..')
    }, onCmd);

    function onCmd(err, stdout, stderr) {
        if (!err) {
            return cb(null);
        }

        var reportCmd = cmd + ' report text';
        exec(reportCmd, {
            cwd: path.join(__dirname, '..')
        }, onReport);

        function onReport(err2, stdout2, stderr2) {
            cb(err2, {
                checkCoverage: stdout + stderr,
                report: stdout2 + stderr2
            });
        }
    }
}
<commit_msg>i meant 100% branch coverage<commit_after>var test = require('assert-tap').test;
var process = require('process');
var path = require('path');
var exec = require('child_process').exec;

require('./uncaught.js');
require('./shutdown.js');

test('check coverage', function t(assert) {
    getCoverage(function onCoverage(err, out) {
        assert.ifError(err);

        if (out) {
            console.warn('Code coverage is not 100%');
            console.log(out.report);
            console.log('SUGGESTED FIX: get 100% code coverage');
            process.exit(1);
        } else {
            assert.ok(true);
            assert.end();
        }
    });
});

function getCoverage(cb) {
    var cmd = path.join(__dirname, '..', 'node_modules',
        '.bin', 'istanbul');
    exec(cmd + ' check-coverage --branches=100', {
        cwd: path.join(__dirname, '..')
    }, onCmd);

    function onCmd(err, stdout, stderr) {
        if (!err) {
            return cb(null);
        }

        var reportCmd = cmd + ' report text';
        exec(reportCmd, {
            cwd: path.join(__dirname, '..')
        }, onReport);

        function onReport(err2, stdout2, stderr2) {
            cb(err2, {
                checkCoverage: stdout + stderr,
                report: stdout2 + stderr2
            });
        }
    }
}
<|endoftext|>


<commit_before>var test = require('tape')
var range = require('../')

function reverse(t, opts) {
  var _opts = JSON.parse(JSON.stringify(opts))
  var opts = range(opts)
  if(opts.reverse) {
    t.ok(opts.start   == _opts.end)
    t.ok(opts.end     == _opts.start)
  }
  else {
    t.ok(opts.start   == _opts.start)
    t.ok(opts.end     == _opts.end)
  }
  t.ok(opts.reverse == _opts.reverse)

}

function ordered(t, opts, reverse) {
  var opts = range(opts)
  //don't change order if there is only start OR end,
  //but not both.

  console.log([!!opts.reverse,'===', opts.start, '>', opts.end].join(' '))
  t.ok(!!opts.reverse === opts.start > opts.end,
    [opts.start, opts.reverse ? '>' : '<', opts.end].join(' ')
  )
}

test('set correct order', function (t) {
  ordered = ordered.bind(null, t)
  ordered({start: 'a', end: 'z'})
  ordered({start: 'v', end: 'e'})
  ordered({start: 'e', end: 'v', reverse: true})
  ordered({start: 'v', end: 'e', reverse: true})
  t.end()
})

//{start: 'v'} and {end: 'v'} are both valid orders,
//from start: 'v' to the end of the db,
//and end: 'v' from the start of the db to 'v'.
//so don't fix them.

test("don't change order", function (t) {
  reverse = reverse.bind(null, t)
  reverse({start: 'v',           reverse: true})
  reverse({            end: 'v', reverse: true})
  reverse({            end: 'v'               })
  reverse({start: 'v'                         })
  t.end()
})

test('alais min and max to start and end', function (t) {

  function alias(fixable, fixed) {
    range(fixable)
    t.equal(fixable.start,   fixed.start,   'start')
    t.equal(fixable.end,     fixed.end,     'end')
    t.equal(fixable.reverse, fixed.reverse, 'reverse')
  }

  alias({min: 'a', max: 'z'}, {start: 'a', end: 'z'})
  alias({min: 'a', max: 'z', reverse: true}, {start: 'z', end: 'a', reverse: true})
  alias({max: 'z'}, {end: 'z'})
  alias({max: 'z', reverse: true}, {start: 'z', reverse: true})
  alias({min: 'a'}, {start: 'a'})
  alias({min: 'a', reverse: true}, {end: 'a', reverse: true})

  t.end()
})
<commit_msg>make test work without relying on side effects<commit_after>var test = require('tape')
var range = require('../')

function reverse(t, opts) {
  var _opts = JSON.parse(JSON.stringify(opts))
  var opts = range(opts)
  if(opts.reverse) {
    t.ok(opts.start   == _opts.end)
    t.ok(opts.end     == _opts.start)
  }
  else {
    t.ok(opts.start   == _opts.start)
    t.ok(opts.end     == _opts.end)
  }
  t.ok(opts.reverse == _opts.reverse)

}

function ordered(t, opts, reverse) {
  var opts = range(opts)
  //don't change order if there is only start OR end,
  //but not both.

  console.log([!!opts.reverse,'===', opts.start, '>', opts.end].join(' '))
  t.ok(!!opts.reverse === opts.start > opts.end,
    [opts.start, opts.reverse ? '>' : '<', opts.end].join(' ')
  )
}

test('set correct order', function (t) {
  ordered = ordered.bind(null, t)
  ordered({start: 'a', end: 'z'})
  ordered({start: 'v', end: 'e'})
  ordered({start: 'e', end: 'v', reverse: true})
  ordered({start: 'v', end: 'e', reverse: true})
  t.end()
})

//{start: 'v'} and {end: 'v'} are both valid orders,
//from start: 'v' to the end of the db,
//and end: 'v' from the start of the db to 'v'.
//so don't fix them.

test("don't change order", function (t) {
  reverse = reverse.bind(null, t)
  reverse({start: 'v',           reverse: true})
  reverse({            end: 'v', reverse: true})
  reverse({            end: 'v'               })
  reverse({start: 'v'                         })
  t.end()
})

test('alais min and max to start and end', function (t) {

  function alias(fixable, fixed) {
    fixable = range(fixable)
    t.equal(fixable.start,   fixed.start,   'start')
    t.equal(fixable.end,     fixed.end,     'end')
    t.equal(fixable.reverse, fixed.reverse, 'reverse')
  }

  alias({min: 'a', max: 'z'}, {start: 'a', end: 'z'})
  alias({min: 'a', max: 'z', reverse: true}, {start: 'z', end: 'a', reverse: true})
  alias({max: 'z'}, {end: 'z'})
  alias({max: 'z', reverse: true}, {start: 'z', reverse: true})
  alias({min: 'a'}, {start: 'a'})
  alias({min: 'a', reverse: true}, {end: 'a', reverse: true})

  t.end()
})
<|endoftext|>


<commit_before>
import React, { Component } from 'react'
import { Router, Route } from '..'
import assert from './assert'

function Index({ children }) {
  return

Index

    {children}

}

function Users({ children }) {
  return

Users

    {children}

}

function User({ params: { id } }) {
  return
user {id}

}

function Pets({ children }) {
  return

Pets

    {children}

}

function Pet({ params: { id } }) {
  return
pet {id}

}

function NotFound() {
  return
Not Found

}

// Simple index route
assert(<Router location="/">
  <Route path="/" component={Index} />
</Router>, <Index />)

// Nested route
assert(<Router location="/pets">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets} />
  </Route>
</Router>, <Index><Pets /></Index>)

// Deeply nested route
assert(<Router location="/pets/12">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":id" component={Pet} />
    </Route>
  </Route>
</Router>, <Index><Pets><Pet params={{ id: 12 }}></Pet></Pets></Index>)

// Many deeply nested route
assert(<Router location="/users/5">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":id" component={Pet} />
    </Route>

    <Route path="users" component={Users}>
      <Route path=":id" component={User} />
    </Route>
  </Route>
</Router>, <Index><Users><User params={{ id: 5 }}></User></Users></Index>)

// Catch-all
assert(<Router location="/something">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":id" component={Pet} />
    </Route>

    <Route path="users" component={Users}>
      <Route path=":id" component={User} />
    </Route>
  </Route>

  <Route path="*" component={NotFound} />
</Router>, <NotFound />)

// Nested route but index route
assert(<Router location="/">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets} />
  </Route>
</Router>, <Index />)

// Shallow routes
assert(<Router location="/">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
</Router>, <Index />)

assert(<Router location="/users">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
</Router>, <Users />)

assert(<Router location="/user/5">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
  <Route path="/user/:id" component={User} />
</Router>, <User params={{ id: 5 }} />)
<commit_msg>add deeply nested param test<commit_after>
import React, { Component } from 'react'
import { Router, Route } from '..'
import assert from './assert'

function Index({ children }) {
  return

Index

    {children}

}

function Users({ children }) {
  return

Users

    {children}

}

function User({ children, params: { userId } }) {
  return

User {userId}

    {children}

}

function Pets({ children }) {
  return

Pets

    {children}

}

function Pet({ params: { petId } }) {
  return
pet {petId}

}

function NotFound() {
  return
Not Found

}

// Simple index route
assert(<Router location="/">
  <Route path="/" component={Index} />
</Router>, <Index />)

// Nested route
assert(<Router location="/pets">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets} />
  </Route>
</Router>, <Index><Pets /></Index>)

// Deeply nested route
assert(<Router location="/pets/12">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":petId" component={Pet} />
    </Route>
  </Route>
</Router>, <Index><Pets><Pet params={{ petId: 12 }}></Pet></Pets></Index>)

// Many deeply nested route
assert(<Router location="/users/5">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":petId" component={Pet} />
    </Route>

    <Route path="users" component={Users}>
      <Route path=":userId" component={User} />
    </Route>
  </Route>
</Router>, <Index><Users><User params={{ userId: 5 }}></User></Users></Index>)

// Catch-all
assert(<Router location="/something">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets}>
      <Route path=":petId" component={Pet} />
    </Route>

    <Route path="users" component={Users}>
      <Route path=":userId" component={User} />
    </Route>
  </Route>

  <Route path="*" component={NotFound} />
</Router>, <NotFound />)

// Nested route but index route
assert(<Router location="/">
  <Route path="/" component={Index}>
    <Route path="pets" component={Pets} />
  </Route>
</Router>, <Index />)

// Shallow routes
assert(<Router location="/">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
</Router>, <Index />)

assert(<Router location="/users">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
</Router>, <Users />)

assert(<Router location="/user/5">
  <Route path="/" component={Index} />
  <Route path="/users" component={Users} />
  <Route path="/user/:userId" component={User} />
</Router>, <User params={{ userId: 5 }} />)

// Many nested routes and params
assert(<Router location="/users/5/pets/2">
  <Route path="/" component={Index}>
    <Route path="users" component={Users}>
      <Route path=":userId" component={User}>
        <Route path="pets" component={Pets}>
          <Route path=":petId" component={Pet} />
        </Route>
      </Route>
    </Route>
  </Route>
</Router>, <Index>
  <Users>
    <User params={{ userId: 5 }}>
      <Pets>
        <Pet params={{ petId: 2 }}>
        </Pet>
      </Pets>
    </User>
  </Users>
</Index>)
<|endoftext|>


<commit_before>import TransformBindAttrToAttributes from 'transform-bind-attr-to-attributes';

export function initialize() {
  console.log('registered!');
  Ember.HTMLBars.registerPlugin('ast', TransformBindAttrToAttributes);
}

export default {
  name: 'register-bind-attr',
  initialize: initialize
}
<commit_msg>Removing rogue logger<commit_after>import TransformBindAttrToAttributes from 'transform-bind-attr-to-attributes';

export function initialize() {
  Ember.HTMLBars.registerPlugin('ast', TransformBindAttrToAttributes);
}

export default {
  name: 'register-bind-attr',
  initialize: initialize
}
<|endoftext|>


<commit_before>import test from 'ava';
import autoRetry from '../src/index';

test('autoRetry resolves successfully', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.resolve('success');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().then((result) => {
        t.true(result === 'success');
        t.true(timesFunctionWasCalled === 1);
        return;
    });
});

test('autoRetry resolves successfully after rejection', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        if (timesFunctionWasCalled < 2) {
            return Promise.reject('failed');
        }
        return Promise.resolve('success');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().then((result) => {
        t.true(result === 'success');
        t.true(timesFunctionWasCalled === 2);
        return;
    }).catch(console.warn);
});

test('autoRetry rejects eventually', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.reject('failed');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().catch((result) => {
        t.true(result === 'failed');
        t.true(timesFunctionWasCalled === 3);
        return;
    });
});

test('autoRetry responds to custom options', (t) => {
    let timesFunctionWasCalled = 0;
    const rejectedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.reject('failed');
    };

    const options = { maxRetries: 1, logRetries: true, backoffBase: 50 };
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch((result) => {
        t.true(result === 'failed');
        t.true(timesFunctionWasCalled === 2);
    });
});

test.serial('autoRetry logs default message', (t) => {
    const origLog = console.log;

    let logMessage;

    console.log = (message) => {
        logMessage = message;
    };

    const options = { maxRetries: 1, logRetries: true, backoffBase: 50 };
    const rejectedFunction = () => Promise.reject('failed');
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch(() => {
        t.regex(logMessage, /^\[auto-retry] rejectedFunction was rejected\. Retrying #1 after \d+ms\.$/);
    }).then(() => {
        console.log = origLog;
        return undefined;
    });
});

test('autoRetry calls onRetry callback', (t) => {
    let timesFunctionWasCalled = 0;
    let callbackRetryCount;
    let callbackDelay;
    const onRetry = (retryCount, delay) => {
        timesFunctionWasCalled++;
        callbackRetryCount = retryCount;
        callbackDelay = delay;
    };

    const options = { maxRetries: 1, backoffBase: 50, onRetry };
    const rejectedFunction = () => Promise.reject('failed');
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch(() => {
        t.true(timesFunctionWasCalled === 1);
        t.true(callbackRetryCount === 1);
        t.true(typeof callbackDelay === 'number');
    });
});
<commit_msg>Fix test<commit_after>import test from 'ava';
import autoRetry from '../src/index';

test('autoRetry resolves successfully', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.resolve('success');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().then((result) => {
        t.true(result === 'success');
        t.true(timesFunctionWasCalled === 1);
        return;
    });
});

test('autoRetry resolves successfully after rejection', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        if (timesFunctionWasCalled < 2) {
            return Promise.reject('failed');
        }
        return Promise.resolve('success');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().then((result) => {
        t.true(result === 'success');
        t.true(timesFunctionWasCalled === 2);
        return;
    }).catch(console.warn);
});

test('autoRetry rejects eventually', (t) => {
    let timesFunctionWasCalled = 0;
    const resolvedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.reject('failed');
    };

    const resolvedFunctionWithRetry = autoRetry(resolvedFunction);
    return resolvedFunctionWithRetry().catch((result) => {
        t.true(result === 'failed');
        t.true(timesFunctionWasCalled === 3);
        return;
    });
});

test('autoRetry responds to custom options', (t) => {
    let timesFunctionWasCalled = 0;
    const rejectedFunction = () => {
        timesFunctionWasCalled++;
        return Promise.reject('failed');
    };

    const options = { maxRetries: 1, logRetries: true, backoffBase: 50 };
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch((result) => {
        t.true(result === 'failed');
        t.true(timesFunctionWasCalled === 2);
    });
});

test.serial('autoRetry logs default message', (t) => {
    const origLog = console.log;

    let logMessage;

    console.log = (message) => {
        logMessage = message;
    };

    const options = { maxRetries: 1, logRetries: true, backoffBase: 50 };
    const rejectedFunction = () => Promise.reject('failed');
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch(() => {
        t.regex(logMessage, /^\[auto-retry] function was rejected\. Retrying #1 after \d+ms\.$/);
    }).then(() => {
        console.log = origLog;
        return undefined;
    });
});

test('autoRetry calls onRetry callback', (t) => {
    let timesFunctionWasCalled = 0;
    let callbackRetryCount;
    let callbackDelay;
    const onRetry = (retryCount, delay) => {
        timesFunctionWasCalled++;
        callbackRetryCount = retryCount;
        callbackDelay = delay;
    };

    const options = { maxRetries: 1, backoffBase: 50, onRetry };
    const rejectedFunction = () => Promise.reject('failed');
    const rejectedFunctionWithRetry = autoRetry(rejectedFunction, options);
    return rejectedFunctionWithRetry().catch(() => {
        t.true(timesFunctionWasCalled === 1);
        t.true(callbackRetryCount === 1);
        t.true(typeof callbackDelay === 'number');
    });
});
<|endoftext|>


<commit_before>import _ from 'intl'
import ActionButton from 'action-button'
import ActionToggle from 'action-toggle'
import GenericInput from 'json-schema-input'
import Icon from 'icon'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import React, { Component } from 'react'
import size from 'lodash/size'
import { addSubscriptions } from 'utils'
import { generateUiSchema } from 'xo-json-schema-input'
import { lastly } from 'promise-toolbox'
import { Row, Col } from 'grid'
import {
  configurePlugin,
  disablePluginAutoload,
  enablePluginAutoload,
  loadPlugin,
  purgePluginConfiguration,
  subscribePlugins,
  unloadPlugin
} from 'xo'

class Plugin extends Component {
  constructor (props) {
    super(props)
    const { configurationSchema } = props

    // Don't update input with schema in edit mode!
    // It's always the same!
    this.state = {
      configurationSchema,
      uiSchema: generateUiSchema(configurationSchema)
    }
    this.formId = `form-${props.id}`
  }

  componentWillReceiveProps (nextProps) {
    // Don't update input with schema in edit mode!
    if (!this.state.edit) {
      const { configurationSchema } = nextProps

      this.setState({
        configurationSchema,
        uiSchema: generateUiSchema(configurationSchema)
      })

      if (this.refs.pluginInput) {
        // TODO: Compare values!!!
        // `|| undefined` because old configs can be null.
        this.refs.pluginInput.value = nextProps.configuration || undefined
      }
    }
  }

  _updateExpanded = () => {
    this.setState({
      expanded: !this.state.expanded
    })
  }

  _setAutoload = (event) => {
    if (this._updateAutoload) {
      return
    }

    this._updateAutoload = true

    const method = event.target.checked ? enablePluginAutoload : disablePluginAutoload

    method(this.props.id)::lastly(() => {
      this._updateAutoload = false
    })
  }

  _updateLoad = () => {
    const { props } = this
    const { id } = props

    const method = (!props.loaded && loadPlugin) || (!props.unloadable && unloadPlugin)

    if (method) {
      return method(id)
    }
  }

  _saveConfiguration = async () => {
    try {
      await configurePlugin(this.props.id, this.refs.pluginInput.value)

      this.setState({
        edit: false
      })
    } catch (_) { }
  }

  _deleteConfiguration = async () => {
    try {
      await purgePluginConfiguration(this.props.id)
      this.refs.pluginInput.value = undefined
    } catch (_) { }
  }

  _edit = () => {
    this.setState({
      edit: true
    })
  }

  _cancelEdit = () => {
    this.setState({
      edit: false
    })
  }

  _applyPredefinedConfiguration = () => {
    const configName = this.refs.selectPredefinedConfiguration.value
    this.refs.pluginInput.value = this.props.configurationPresets[configName]
  }

  render () {
    const {
      props,
      state
    } = this
    const { expanded, edit } = state
    const {
      configurationPresets,
      loaded
    } = props
    const { formId } = this

    return (

        <Row>
          <Col mediumSize={8}>

              <ActionToggle disabled={loaded && props.unloadable} value={loaded} handler={this._updateLoad} />

                {` ${props.name} `}

                {`(v${props.version}) `}

                  {_('autoloadPlugin')} <input type='checkbox' checked={props.autoload} onChange={this._setAutoload} />

          </Col>
          <Col mediumSize={4}>

              <button type='button' className='btn btn-primary' onClick={this._updateExpanded}>
                <Icon icon={expanded ? 'minus' : 'plus'} />
              </button>

          </Col>
        </Row>
        {expanded &&
          <form id={formId}>
            {size(configurationPresets) > 0 && (

                <legend>{_('pluginConfigurationPresetTitle')}</legend>

{_('pluginConfigurationChoosePreset')}

                  <select className='form-control' disabled={!edit} ref='selectPredefinedConfiguration'>
                    {map(configurationPresets, (_, name) => (
                      <option key={name} value={name}>
                        {name}
                      </option>
                    ))}
                  </select>

                    <button
                      className='btn btn-primary'
                      disabled={!edit}
                      onClick={this._applyPredefinedConfiguration}
                      type='button'
                    >
                      {_('applyPluginPreset')}
                    </button>

            )}
            <GenericInput
              disabled={!edit}
              label='Configuration'
              schema={state.configurationSchema}
              uiSchema={state.uiSchema}
              required
              ref='pluginInput'
              defaultValue={props.configuration || undefined}
            />

                  <ActionButton disabled={!edit} type='submit' form={formId} icon='save' className='btn-primary' handler={this._saveConfiguration}>
                    {_('savePluginConfiguration')}
                  </ActionButton>

                  <ActionButton disabled={!edit} icon='delete' className='btn-danger' handler={this._deleteConfiguration}>
                    {_('deletePluginConfiguration')}
                  </ActionButton>

                {!edit ? (

                    <button type='button' className='btn btn-primary' onClick={this._edit}>
                      {_('editPluginConfiguration')}
                    </button>

                ) : (

                    <button type='button' className='btn btn-primary' onClick={this._cancelEdit}>
                      {_('cancelPluginEdition')}
                    </button>

                )}

          </form>
        }

    )
  }
}

@addSubscriptions({
  plugins: subscribePlugins
})
export default class Plugins extends Component {
  render () {
    if (isEmpty(this.props.plugins)) {
      return
{_('noPlugins')}

    }

    return (

          {map(this.props.plugins, (plugin, key) =>

              <Plugin {...plugin} />

          )}

    )
  }
}
<commit_msg>fix(settings/plugins): unloading<commit_after>import _ from 'intl'
import ActionButton from 'action-button'
import ActionToggle from 'action-toggle'
import GenericInput from 'json-schema-input'
import Icon from 'icon'
import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map'
import React, { Component } from 'react'
import size from 'lodash/size'
import { addSubscriptions } from 'utils'
import { generateUiSchema } from 'xo-json-schema-input'
import { lastly } from 'promise-toolbox'
import { Row, Col } from 'grid'
import {
  configurePlugin,
  disablePluginAutoload,
  enablePluginAutoload,
  loadPlugin,
  purgePluginConfiguration,
  subscribePlugins,
  unloadPlugin
} from 'xo'

class Plugin extends Component {
  constructor (props) {
    super(props)
    const { configurationSchema } = props

    // Don't update input with schema in edit mode!
    // It's always the same!
    this.state = {
      configurationSchema,
      uiSchema: generateUiSchema(configurationSchema)
    }
    this.formId = `form-${props.id}`
  }

  componentWillReceiveProps (nextProps) {
    // Don't update input with schema in edit mode!
    if (!this.state.edit) {
      const { configurationSchema } = nextProps

      this.setState({
        configurationSchema,
        uiSchema: generateUiSchema(configurationSchema)
      })

      if (this.refs.pluginInput) {
        // TODO: Compare values!!!
        // `|| undefined` because old configs can be null.
        this.refs.pluginInput.value = nextProps.configuration || undefined
      }
    }
  }

  _updateExpanded = () => {
    this.setState({
      expanded: !this.state.expanded
    })
  }

  _setAutoload = (event) => {
    if (this._updateAutoload) {
      return
    }

    this._updateAutoload = true

    const method = event.target.checked ? enablePluginAutoload : disablePluginAutoload

    method(this.props.id)::lastly(() => {
      this._updateAutoload = false
    })
  }

  _updateLoad = () => {
    const { props } = this

    if (!props.loaded) {
      return loadPlugin(props.id)
    }
    if (props.unloadable !== false) {
      return unloadPlugin(props.id)
    }
  }

  _saveConfiguration = async () => {
    try {
      await configurePlugin(this.props.id, this.refs.pluginInput.value)

      this.setState({
        edit: false
      })
    } catch (_) { }
  }

  _deleteConfiguration = async () => {
    try {
      await purgePluginConfiguration(this.props.id)
      this.refs.pluginInput.value = undefined
    } catch (_) { }
  }

  _edit = () => {
    this.setState({
      edit: true
    })
  }

  _cancelEdit = () => {
    this.setState({
      edit: false
    })
  }

  _applyPredefinedConfiguration = () => {
    const configName = this.refs.selectPredefinedConfiguration.value
    this.refs.pluginInput.value = this.props.configurationPresets[configName]
  }

  render () {
    const {
      props,
      state
    } = this
    const { expanded, edit } = state
    const {
      configurationPresets,
      loaded
    } = props
    const { formId } = this

    return (

        <Row>
          <Col mediumSize={8}>

              <ActionToggle
                disabled={loaded && props.unloadable === false}
                handler={this._updateLoad}
                value={loaded}
              />

                {` ${props.name} `}

                {`(v${props.version}) `}

                  {_('autoloadPlugin')} <input type='checkbox' checked={props.autoload} onChange={this._setAutoload} />

          </Col>
          <Col mediumSize={4}>

              <button type='button' className='btn btn-primary' onClick={this._updateExpanded}>
                <Icon icon={expanded ? 'minus' : 'plus'} />
              </button>

          </Col>
        </Row>
        {expanded &&
          <form id={formId}>
            {size(configurationPresets) > 0 && (

                <legend>{_('pluginConfigurationPresetTitle')}</legend>

{_('pluginConfigurationChoosePreset')}

                  <select className='form-control' disabled={!edit} ref='selectPredefinedConfiguration'>
                    {map(configurationPresets, (_, name) => (
                      <option key={name} value={name}>
                        {name}
                      </option>
                    ))}
                  </select>

                    <button
                      className='btn btn-primary'
                      disabled={!edit}
                      onClick={this._applyPredefinedConfiguration}
                      type='button'
                    >
                      {_('applyPluginPreset')}
                    </button>

            )}
            <GenericInput
              disabled={!edit}
              label='Configuration'
              schema={state.configurationSchema}
              uiSchema={state.uiSchema}
              required
              ref='pluginInput'
              defaultValue={props.configuration || undefined}
            />

                  <ActionButton disabled={!edit} type='submit' form={formId} icon='save' className='btn-primary' handler={this._saveConfiguration}>
                    {_('savePluginConfiguration')}
                  </ActionButton>

                  <ActionButton disabled={!edit} icon='delete' className='btn-danger' handler={this._deleteConfiguration}>
                    {_('deletePluginConfiguration')}
                  </ActionButton>

                {!edit ? (

                    <button type='button' className='btn btn-primary' onClick={this._edit}>
                      {_('editPluginConfiguration')}
                    </button>

                ) : (

                    <button type='button' className='btn btn-primary' onClick={this._cancelEdit}>
                      {_('cancelPluginEdition')}
                    </button>

                )}

          </form>
        }

    )
  }
}

@addSubscriptions({
  plugins: subscribePlugins
})
export default class Plugins extends Component {
  render () {
    if (isEmpty(this.props.plugins)) {
      return
{_('noPlugins')}

    }

    return (

          {map(this.props.plugins, (plugin, key) =>

              <Plugin {...plugin} />

          )}

    )
  }
}
<|endoftext|>


<commit_before>/*jslint node:true indent:2 nomen:true */
/*globals describe, it, beforeEach */
'use strict';

var jSend = require('../'),
  httpMocks = require('node-mocks-http'),
  assert = require('assert'),
  _ = require('lodash'),
  functionCalled,
  req,
  res,
  next;

function setFunctionCalled() {
  functionCalled = true;
}

function getResponseData() {
  return JSON.parse(res._getData());
}

beforeEach(function () {
  functionCalled = false;
  req = httpMocks.createRequest();
  res = httpMocks.createResponse();
  next = function () { return; };
});

describe('jSend', function () {
  it('should exist', function () {
    assert(jSend);
  });
  it('should be a function', function () {
    assert(typeof jSend === 'function');
  });
  it('should call third parameter "next" function as callback', function () {
    next = setFunctionCalled;
    jSend(req, res, next);
    assert(functionCalled);
  });
  it('should add jSend to res object', function () {
    jSend(req, res, next);
    assert(res.jSend);
  });
  describe('res.jSend', function () {
    beforeEach(function () {
      jSend(req, res, next);
    });
    it('should be a function', function () {
      assert(typeof res.jSend === 'function');
    });
    it('should call res.json when invoked', function () {
      res.json = setFunctionCalled;
      res.jSend();
      assert(functionCalled);
    });
    it('should send object to res.json when invoked', function (done) {
      res.json = function (object) {
        assert(_(object).isObject());
        done();
      };
      res.jSend();
    });
    it('should send response with status set to "success"', function () {
      res.jSend();
      assert.equal(getResponseData().status, 'success');
    });
    it('should send response with data set to null', function () {
      res.jSend();
      assert(getResponseData().data === null);
    });
    it('should send response with data set to res.jSend parameter', function () {
      var data = [ 'this', 'is', 'a', 'test' ];
      res.jSend(data);
      assert.deepEqual(getResponseData().data, data);
    });
    it('should send response code of 200', function () {
      res.jSend();
      assert.equal(res.statusCode, 200);
    });
  });
});
<commit_msg>[RED] a test: should return 201 code if request was a 'POST'<commit_after>/*jslint node:true indent:2 nomen:true */
/*globals describe, it, beforeEach */
'use strict';

var jSend = require('../'),
  httpMocks = require('node-mocks-http'),
  assert = require('assert'),
  _ = require('lodash'),
  functionCalled,
  req,
  res,
  next;

function setFunctionCalled() {
  functionCalled = true;
}

function getResponseData() {
  return JSON.parse(res._getData());
}

beforeEach(function () {
  functionCalled = false;
  req = httpMocks.createRequest();
  res = httpMocks.createResponse();
  next = function () { return; };
});

describe('jSend', function () {
  it('should exist', function () {
    assert(jSend);
  });
  it('should be a function', function () {
    assert(typeof jSend === 'function');
  });
  it('should call third parameter "next" function as callback', function () {
    next = setFunctionCalled;
    jSend(req, res, next);
    assert(functionCalled);
  });
  it('should add jSend to res object', function () {
    jSend(req, res, next);
    assert(res.jSend);
  });
  describe('res.jSend', function () {
    beforeEach(function () {
      jSend(req, res, next);
    });
    it('should be a function', function () {
      assert(typeof res.jSend === 'function');
    });
    it('should call res.json when invoked', function () {
      res.json = setFunctionCalled;
      res.jSend();
      assert(functionCalled);
    });
    it('should send object to res.json when invoked', function (done) {
      res.json = function (object) {
        assert(_(object).isObject());
        done();
      };
      res.jSend();
    });
    it('should send response with status set to "success"', function () {
      res.jSend();
      assert.equal(getResponseData().status, 'success');
    });
    it('should send response with data set to null', function () {
      res.jSend();
      assert(getResponseData().data === null);
    });
    it('should send response with data set to res.jSend parameter', function () {
      var data = [ 'this', 'is', 'a', 'test' ];
      res.jSend(data);
      assert.deepEqual(getResponseData().data, data);
    });
    it('should send response code of 200', function () {
      res.jSend();
      assert.equal(res.statusCode, 200);
    });
    it('should send response code of 201 if request was a POST', function () {
      req.method = 'POST';
      res.jSend();
      assert.equal(res.statusCode, 201);
    });
  });
});
<|endoftext|>


<commit_before>var templater = require("./../src/templater.js"),
    chai = require("chai"),
    assert = chai.assert;

/**
* Basic tests.
*/
describe("Basic Tests", function() {
  it("should return a function when called with a template", function() {
    var template = templater("A string.");

    assert.equal(typeof template, "function");
  });

  it("should replace values in template with respective values in context (non-function)", function() {
    var template = templater("{{name}}"),
    context = {
      name: "Paul"
    };

    assert.equal(template(context), "Paul");
  });

  it("should replace values in template with respective values in context (function)", function() {
    var template = templater("{{number}}"),
    context = {
      number: function() {
        return 2 + 2;
      }
    };

    assert.equal(template(context), 4);
  });

  it("should not replace values in template that don't exist in the context (undefined)", function() {
    var template = templater("Hi, I'm {{name}}. I'm {{age}} years old."),
    context = {
      age: 21
    };

    assert.equal(template(context), "Hi, I'm {{name}}. I'm 21 years old.");
  });

  it("should not replace values in template that don't exist in the context (case-sensitive)", function() {
    var template = templater("Hi, I'm {{Name}}. I'm {{age}} years old."),
    context = {
      name: "Paul",
      age: 21
    };

    assert.equal(template(context), "Hi, I'm {{Name}}. I'm 21 years old.");
  });

  it("should escape certain characters when replacing template expressions", function() {
    var template = templater("{{foo}}"),
    context = {
      foo: "<html> tag with 'single' & \"double\" quotes"
    };

    assert.equal(template(context), "<html> tag with 'single' & "double" quotes");
  });
});

/**
* Conditional tests.
*/
describe("Conditional Tests", function() {
  it("renders conditional body if the arguments are truthy", function() {
    var template = templater([
      "{{#if (name, age)}}",
      "Hi, I'm {{name}}, I'm {{age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      name: "Paul",
      age: 21
    };

    assert.equal(template(context), "Hi, I'm Paul, I'm 21 years old.");
  });

  it("doesn't render conditional body if one or more of the args are falsy", function() {
    var template = templater([
      "{{#if (name, age)}}",
      "Hi, I'm {{name}}, I'm {{age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      name: "Paul",
      age: 0
    };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of truthy arguments", function() {
    var template = templater([
      "{{#if !(name, age)}}",
      "Hi, I'm {{name}}, I'm {{age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      name: "Paul",
      age: 21
    };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of falsy arguments", function() {
    var template = templater([
      "{{#if !(name, age)}}",
      "Hi, I'm {{name}}, I'm {{age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      name: "Paul"
    };

    assert.equal(template(context), "Hi, I'm Paul, I'm {{age}} years old.");
  });
});

/**
* Nested properties.
*/
describe("Nested Properties", function() {
  it("should replace values in template with respective values in context", function() {
    var template = templater("{{person.name}}, {{person.age}}"),
    context = {
      person: {
        name: "Paul",
        age: 21
      }
    };

    assert.equal(template(context), "Paul, 21");
  });

  it("should replace values in template with respective values in context (array)", function() {
    var template = templater("{{people.0.name}}, {{people.0.age}}"),
    context = {
      people: [
        {
          name: "Paul",
          age: 21
        }
      ]
    };

    assert.equal(template(context), "Paul, 21");
  });

  it("should not replace values in template that don't exist in the context", function() {
    var template = templater("Hi, I'm {{person.name}}. I'm {{person.age}} years old."),
    context = {
      person: {
        age: 21
      }
    };

    assert.equal(template(context), "Hi, I'm {{person.name}}. I'm 21 years old.");
  });

  it("should replace values in template with respective values in context (function)", function() {
    var template = templater("{{exp.x}} + {{exp.y}} = {{exp.z}}"),
    context = {
      exp: {
        x: 2,
        y: 2,
        z: function() {
          return 2 + 2;
        }
      }
    };

    assert.equal(template(context), "2 + 2 = 4");
  });
});

/**
* Conditional (nested property) tests.
*/
describe("Conditional (Nested Property) Tests", function() {
  it("renders conditional body if the arguments are truthy", function() {
    var template = templater([
      "{{#if (person.name, person.age)}}",
      "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      person: {
        name: "Paul",
        age: 21
      }
    };

    assert.equal(template(context), "Hi, I'm Paul, I'm 21 years old.");
  });

  it("doesn't render conditional body if one or more of the args are falsy", function() {
    var template = templater([
      "{{#if (person.name, person.age)}}",
      "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      person: {
        name: "Paul",
        age: 0
      }
    };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of truthy arguments", function() {
    var template = templater([
      "{{#if !(person.name, person.age)}}",
      "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      person: {
        name: "Paul",
        age: 21
      }
    };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of falsy arguments", function() {
    var template = templater([
      "{{#if !(person.name, person.age)}}",
      "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
      "{{/if}}"
    ].join("")),
    context = {
      person: {
        name: "Paul"
      }
    };

    assert.equal(template(context), "Hi, I'm Paul, I'm {{person.age}} years old.");
  });
});
<commit_msg>Correct indentation on comma-delimitted variables<commit_after>var templater = require("../src/templater"),
    chai = require("chai"),
    assert = chai.assert;

/**
* Basic tests.
*/
describe("Basic Tests", function() {
  it("should return a function when called with a template", function() {
    var template = templater("A string.");

    assert.equal(typeof template, "function");
  });

  it("should replace values in template with respective values in context (non-function)", function() {
    var template = templater("{{name}}"),
        context = {
          name: "Paul"
        };

    assert.equal(template(context), "Paul");
  });

  it("should replace values in template with respective values in context (function)", function() {
    var template = templater("{{number}}"),
        context = {
          number: function() {
            return 2 + 2;
          }
        };

    assert.equal(template(context), 4);
  });

  it("should not replace values in template that don't exist in the context (undefined)", function() {
    var template = templater("Hi, I'm {{name}}. I'm {{age}} years old."),
        context = {
          age: 21
        };

    assert.equal(template(context), "Hi, I'm {{name}}. I'm 21 years old.");
  });

  it("should not replace values in template that don't exist in the context (case-sensitive)", function() {
    var template = templater("Hi, I'm {{Name}}. I'm {{age}} years old."),
        context = {
          name: "Paul",
          age: 21
        };

    assert.equal(template(context), "Hi, I'm {{Name}}. I'm 21 years old.");
  });

  it("should escape certain characters when replacing template expressions", function() {
    var template = templater("{{foo}}"),
        context = {
          foo: "<html> tag with 'single' & \"double\" quotes"
        };

    assert.equal(template(context), "<html> tag with 'single' & "double" quotes");
  });
});

/**
* Conditional tests.
*/
describe("Conditional Tests", function() {
  it("renders conditional body if the arguments are truthy", function() {
    var template = templater([
          "{{#if (name, age)}}",
          "Hi, I'm {{name}}, I'm {{age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          name: "Paul",
          age: 21
        };

    assert.equal(template(context), "Hi, I'm Paul, I'm 21 years old.");
  });

  it("doesn't render conditional body if one or more of the args are falsy", function() {
    var template = templater([
          "{{#if (name, age)}}",
          "Hi, I'm {{name}}, I'm {{age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          name: "Paul",
          age: 0
        };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of truthy arguments", function() {
    var template = templater([
          "{{#if !(name, age)}}",
          "Hi, I'm {{name}}, I'm {{age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          name: "Paul",
          age: 21
        };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of falsy arguments", function() {
    var template = templater([
          "{{#if !(name, age)}}",
          "Hi, I'm {{name}}, I'm {{age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          name: "Paul"
        };

    assert.equal(template(context), "Hi, I'm Paul, I'm {{age}} years old.");
  });
});

/**
* Nested properties.
*/
describe("Nested Properties", function() {
  it("should replace values in template with respective values in context", function() {
    var template = templater("{{person.name}}, {{person.age}}"),
        context = {
          person: {
            name: "Paul",
            age: 21
          }
        };

    assert.equal(template(context), "Paul, 21");
  });

  it("should replace values in template with respective values in context (array)", function() {
    var template = templater("{{people.0.name}}, {{people.0.age}}"),
        context = {
          people: [
            {
              name: "Paul",
              age: 21
            }
          ]
        };

    assert.equal(template(context), "Paul, 21");
  });

  it("should not replace values in template that don't exist in the context", function() {
    var template = templater("Hi, I'm {{person.name}}. I'm {{person.age}} years old."),
        context = {
          person: {
            age: 21
          }
        };

    assert.equal(template(context), "Hi, I'm {{person.name}}. I'm 21 years old.");
  });

  it("should replace values in template with respective values in context (function)", function() {
    var template = templater("{{exp.x}} + {{exp.y}} = {{exp.z}}"),
        context = {
          exp: {
            x: 2,
            y: 2,
            z: function() {
              return 2 + 2;
            }
          }
        };

    assert.equal(template(context), "2 + 2 = 4");
  });
});

/**
* Conditional (nested property) tests.
*/
describe("Conditional (Nested Property) Tests", function() {
  it("renders conditional body if the arguments are truthy", function() {
    var template = templater([
          "{{#if (person.name, person.age)}}",
          "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          person: {
            name: "Paul",
            age: 21
          }
        };

    assert.equal(template(context), "Hi, I'm Paul, I'm 21 years old.");
  });

  it("doesn't render conditional body if one or more of the args are falsy", function() {
    var template = templater([
          "{{#if (person.name, person.age)}}",
          "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          person: {
            name: "Paul",
            age: 0
          }
        };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of truthy arguments", function() {
    var template = templater([
          "{{#if !(person.name, person.age)}}",
          "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          person: {
            name: "Paul",
            age: 21
          }
        };

    assert.equal(template(context), "");
  });

  it("inverts (nots) the evaluation of falsy arguments", function() {
    var template = templater([
          "{{#if !(person.name, person.age)}}",
          "Hi, I'm {{person.name}}, I'm {{person.age}} years old.",
          "{{/if}}"
        ].join("")),
        context = {
          person: {
            name: "Paul"
          }
        };

    assert.equal(template(context), "Hi, I'm Paul, I'm {{person.age}} years old.");
  });
});
<|endoftext|>


<commit_before>angular.module('schemaForm').config(
    ['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider',
        function(schemaFormProvider,  schemaFormDecoratorsProvider, sfPathProvider) {

          var download = function(name, schema, options) {
            if (schema.type === 'string' && schema.format === 'download') {
              var f = schemaFormProvider.stdFormObj(name, schema, options);
              f.key  = options.path;
              f.type = 'download';
              options.lookup[sfPathProvider.stringify(options.path)] = f;
              return f;
            }
          };

          schemaFormProvider.defaults.string.unshift(download);
          //Add to the bootstrap directive
          schemaFormDecoratorsProvider.addMapping(
              'bootstrapDecorator',
              'download',
              'directives/decorators/bootstrap/download/angular-schema-form-download.html'
          );
          schemaFormDecoratorsProvider.createDirective(
              'download',
              'directives/decorators/bootstrap/download/angular-schema-form-download.html'
          );
        }
    ])
<commit_msg>Update angular-schema-form-download.js<commit_after>angular.module('schemaForm').config(
    ['schemaFormProvider', 'schemaFormDecoratorsProvider', 'sfPathProvider',
        function(schemaFormProvider,  schemaFormDecoratorsProvider, sfPathProvider) {

          var download = function(name, schema, options) {
            if (schema.type === 'string' && schema.format === 'download') {
              var f = schemaFormProvider.stdFormObj(name, schema, options);
              f.key  = options.path;
              f.type = 'download';
              options.lookup[sfPathProvider.stringify(options.path)] = f;
              return f;
            }
          };

          schemaFormProvider.defaults.string.unshift(download);
          //Add to the bootstrap directive
          schemaFormDecoratorsProvider.addMapping(
              'bootstrapDecorator',
              'download',
              'directives/decorators/bootstrap/download/angular-schema-form-download.html'
          );
          schemaFormDecoratorsProvider.createDirective(
              'download',
              'directives/decorators/bootstrap/download/angular-schema-form-download.html'
          );
        }
    ]);
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import SpellIcon from 'common/SpellIcon';

class Talent extends React.Component {
  static propTypes = {
    talent: PropTypes.number,
  };
  static contextTypes = {
    config: PropTypes.object,
  };

  render() {
    const { talent } = this.props;
    if (!talent) {
      return No talent selected.;
    }

    if (!SPELLS[talent]) {
      return Talent not recognized: {talent};
    }

    const talentDescriptions = this.context.config.talentDescriptions;

    return (

          <SpellIcon id={talent} />

            <SpellLink id={talent} />

            {talentDescriptions.descriptions[talent]}

    );
  }
}

class Talents extends React.Component {
  static propTypes = {
    combatant: PropTypes.shape({
      lv15Talent: PropTypes.number,
      lv30Talent: PropTypes.number,
      lv45Talent: PropTypes.number,
      lv60Talent: PropTypes.number,
      lv75Talent: PropTypes.number,
      lv90Talent: PropTypes.number,
      lv100Talent: PropTypes.number,
    }).isRequired,
  };
  static contextTypes = {
    config: PropTypes.object,
  };

  render() {
    const { combatant } = this.props;

    if (!combatant) {
      return
Loading...
;
    }

    const talentDescriptions = this.context.config.talentDescriptions;
    console.log(this.context.config)

    return (

            <Talent talent={combatant.lv15Talent} />

            <Talent talent={combatant.lv30Talent} />

            <Talent talent={combatant.lv45Talent} />

            <Talent talent={combatant.lv60Talent} />

            <Talent talent={combatant.lv75Talent} />

            <Talent talent={combatant.lv90Talent} />

            <Talent talent={combatant.lv100Talent} />

          {talentDescriptions.attribution && (

              {talentDescriptions.attribution}

          )}

    );
  }
}

export default Talents;
<commit_msg>Fix build<commit_after>import React from 'react';
import PropTypes from 'prop-types';

import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import SpellIcon from 'common/SpellIcon';

class Talent extends React.Component {
  static propTypes = {
    talent: PropTypes.number,
  };
  static contextTypes = {
    config: PropTypes.object,
  };

  render() {
    const { talent } = this.props;
    if (!talent) {
      return No talent selected.;
    }

    if (!SPELLS[talent]) {
      return Talent not recognized: {talent};
    }

    const talentDescriptions = this.context.config.talentDescriptions;

    return (

          <SpellIcon id={talent} />

            <SpellLink id={talent} />

            {talentDescriptions.descriptions[talent]}

    );
  }
}

class Talents extends React.Component {
  static propTypes = {
    combatant: PropTypes.shape({
      lv15Talent: PropTypes.number,
      lv30Talent: PropTypes.number,
      lv45Talent: PropTypes.number,
      lv60Talent: PropTypes.number,
      lv75Talent: PropTypes.number,
      lv90Talent: PropTypes.number,
      lv100Talent: PropTypes.number,
    }).isRequired,
  };
  static contextTypes = {
    config: PropTypes.object,
  };

  render() {
    const { combatant } = this.props;

    if (!combatant) {
      return
Loading...
;
    }

    const talentDescriptions = this.context.config.talentDescriptions;

    return (

            <Talent talent={combatant.lv15Talent} />

            <Talent talent={combatant.lv30Talent} />

            <Talent talent={combatant.lv45Talent} />

            <Talent talent={combatant.lv60Talent} />

            <Talent talent={combatant.lv75Talent} />

            <Talent talent={combatant.lv90Talent} />

            <Talent talent={combatant.lv100Talent} />

          {talentDescriptions.attribution && (

              {talentDescriptions.attribution}

          )}

    );
  }
}

export default Talents;
<|endoftext|>