<commit_before>var path = require('path');
var fs = require('fs');
var assert = require('assert');
var concatStream = require('concat-stream');
var es = require('event-stream');
var gulp = require('gulp');
var changedInPlace = require('./');

describe('gulp-changed-in-place', function () {

  describe('when comparing by sha1 hash', function () {
    it('passes all files on start by default', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: true, cache: {} }))
        .pipe(concatStream(function (buf) {
          assert.equal(2, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          assert.equal('b', path.basename(buf[1].path));
          done();
        }));
    });

    it('does not pass all files on start with `firstPass: false`', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: false, cache: {} }))
        .pipe(concatStream(function (buf) {
          assert.equal(0, buf.length);
          done();
        }));
    });

    it('should only pass through files when they change', function (done) {
      var shas = {};

      shas[path.join(__dirname, 'fixture/a')] = 'not matching sha';
      shas[path.join(__dirname, 'fixture/b')] = 'e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98';

      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: false, cache: shas }))
        .pipe(concatStream(function (buf) {
          assert.equal(1, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          done();
        }));
    });

    it('should update cache before pushing file to stream', function (done) {
      var shas = {};

      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: true, cache: shas }))
        .pipe(es.map(function (file, callback) {
          // imitate gulp.dest without actualy writing files
          // @see https://github.com/gulpjs/vinyl-fs/blob/master/lib/prepareWrite.js#L24
          var targetBase = path.resolve(file.cwd, './build')
          var targetPath = path.resolve(targetBase, file.relative);
          file.base = targetBase;
          file.path = targetPath;
          callback(null, file);
        }))
        .pipe(concatStream(function (files) {
          assert.equal(2, files.length, 'should be 2 files');

          files.map(function (file) {
            assert.equal(undefined, shas[file.path], 'path of changed file should not be in cache');
          });

          done();
        }));
    });

    it('should use paths relative to `basePath`', function (done) {
      var shas = {};
      var basePath = __dirname;

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          basePath: basePath,
          cache: shas
        }))
        .pipe(concatStream(function (files) {

          files.map(function (file) {
            assert.equal(true, shas.hasOwnProperty(path.relative(basePath, file.path)), 'file path should be relative');
          });

          done();
        }));
    });
  });

  describe('when comparing by file modification time: ', function () {
    it('passes all files on start by default', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          cache: {},
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(2, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          assert.equal('b', path.basename(buf[1].path));
          done();
        }));
    });

    it('does not pass all files on start with `firstPass: false`', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: false,
          cache: {},
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(0, buf.length);
          done();
        }));
    });

    it('should only pass through files when their modification time changed', function (done) {
      var times = {};

      var fileA = path.join(__dirname, 'fixture/a');
      var fileB = path.join(__dirname, 'fixture/b');

      var timeNow = Date.now() / 1000;  // https://nodejs.org/docs/latest/api/fs.html#fs_fs_utimes_path_atime_mtime_callback

      var theDate = new Date();
      var currentYear = new Date().getFullYear();
      var yesterYear = currentYear - 1;
      var timeThen = new Date().setFullYear(yesterYear);

      var fileBTime = fs.statSync(fileB).mtime;
      fs.utimesSync(fileA, timeNow, timeNow);

      times[fileA] = timeThen;
      times[fileB] = fileBTime.getTime();

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: false,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(1, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          done();
        }));
    });

    it('should update cache before pushing file to stream', function (done) {
      var times = {};

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(es.map(function (file, callback) {
          // imitate gulp.dest without actualy writing files
          // @see https://github.com/gulpjs/vinyl-fs/blob/master/lib/prepareWrite.js#L24
          var targetBase = path.resolve(file.cwd, './build')
          var targetPath = path.resolve(targetBase, file.relative);
          file.base = targetBase;
          file.path = targetPath;
          callback(null, file);
        }))
        .pipe(concatStream(function (files) {
          assert.equal(2, files.length, 'should be 2 files');

          files.map(function (file) {
            assert.equal(undefined, times[file.path], 'path of changed file should not be in cache');
          });

          done();
        }));
    });

    it('should use paths relative to `basePath`', function (done) {
      var times = {};
      var basePath = __dirname;

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          basePath: basePath,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (files) {

          files.map(function (file) {
            assert.equal(true, times.hasOwnProperty(path.relative(basePath, file.path)), 'file path should be relative');
          });

          done();
        }));
    });
  });
});
<commit_msg>Add missing semicolons. Optimizations.<commit_after>var path = require('path');
var fs = require('fs');
var assert = require('assert');
var concatStream = require('concat-stream');
var es = require('event-stream');
var gulp = require('gulp');
var changedInPlace = require('./');

describe('gulp-changed-in-place', function () {

  describe('when comparing by sha1 hash', function () {
    it('passes all files on start by default', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: true, cache: {} }))
        .pipe(concatStream(function (buf) {
          assert.equal(2, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          assert.equal('b', path.basename(buf[1].path));
          done();
        }));
    });

    it('does not pass all files on start with `firstPass: false`', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: false, cache: {} }))
        .pipe(concatStream(function (buf) {
          assert.equal(0, buf.length);
          done();
        }));
    });

    it('should only pass through files when they change', function (done) {
      var shas = {};

      shas[path.join(__dirname, 'fixture/a')] = 'not matching sha';
      shas[path.join(__dirname, 'fixture/b')] = 'e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98';

      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: false, cache: shas }))
        .pipe(concatStream(function (buf) {
          assert.equal(1, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          done();
        }));
    });

    it('should update cache before pushing file to stream', function (done) {
      var shas = {};

      gulp.src('fixture/*')
        .pipe(changedInPlace({ firstPass: true, cache: shas }))
        .pipe(es.map(function (file, callback) {
          // imitate gulp.dest without actualy writing files
          // @see https://github.com/gulpjs/vinyl-fs/blob/master/lib/prepareWrite.js#L24
          var targetBase = path.resolve(file.cwd, './build');
          var targetPath = path.resolve(targetBase, file.relative);
          file.base = targetBase;
          file.path = targetPath;
          callback(null, file);
        }))
        .pipe(concatStream(function (files) {
          assert.equal(2, files.length, 'should be 2 files');

          files.map(function (file) {
            assert.equal(undefined, shas[file.path], 'path of changed file should not be in cache');
          });

          done();
        }));
    });

    it('should use paths relative to `basePath`', function (done) {
      var shas = {};
      var basePath = __dirname;

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          basePath: basePath,
          cache: shas
        }))
        .pipe(concatStream(function (files) {

          files.map(function (file) {
            assert.equal(true, shas.hasOwnProperty(path.relative(basePath, file.path)), 'file path should be relative');
          });

          done();
        }));
    });
  });

  describe('when comparing by file modification time: ', function () {
    it('passes all files on start by default', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          cache: {},
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(2, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          assert.equal('b', path.basename(buf[1].path));
          done();
        }));
    });

    it('does not pass all files on start with `firstPass: false`', function (done) {
      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: false,
          cache: {},
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(0, buf.length);
          done();
        }));
    });

    it('should only pass through files when their modification time changed', function (done) {
      var times = {};

      var fileA = path.join(__dirname, 'fixture/a');
      var fileB = path.join(__dirname, 'fixture/b');

      var timeNow = Date.now() / 1000;  // https://nodejs.org/docs/latest/api/fs.html#fs_fs_utimes_path_atime_mtime_callback

      var timeThen = new Date();
      timeThen.setFullYear(timeThen.getFullYear() - 1);

      var fileBTime = fs.statSync(fileB).mtime;
      fs.utimesSync(fileA, timeNow, timeNow);

      times[fileA] = timeThen;
      times[fileB] = fileBTime.getTime();

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: false,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (buf) {
          assert.equal(1, buf.length);
          assert.equal('a', path.basename(buf[0].path));
          done();
        }));
    });

    it('should update cache before pushing file to stream', function (done) {
      var times = {};

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(es.map(function (file, callback) {
          // imitate gulp.dest without actualy writing files
          // @see https://github.com/gulpjs/vinyl-fs/blob/master/lib/prepareWrite.js#L24
          var targetBase = path.resolve(file.cwd, './build');
          var targetPath = path.resolve(targetBase, file.relative);
          file.base = targetBase;
          file.path = targetPath;
          callback(null, file);
        }))
        .pipe(concatStream(function (files) {
          assert.equal(2, files.length, 'should be 2 files');

          files.map(function (file) {
            assert.equal(undefined, times[file.path], 'path of changed file should not be in cache');
          });

          done();
        }));
    });

    it('should use paths relative to `basePath`', function (done) {
      var times = {};
      var basePath = __dirname;

      gulp.src('fixture/*')
        .pipe(changedInPlace({
          firstPass: true,
          basePath: basePath,
          cache: times,
          howToDetermineDifference: 'modification-time'
        }))
        .pipe(concatStream(function (files) {

          files.map(function (file) {
            assert.equal(true, times.hasOwnProperty(path.relative(basePath, file.path)), 'file path should be relative');
          });

          done();
        }));
    });
  });
});
<|endoftext|>


<commit_before>import test from 'tape'
import chrono from 'chrono-node'
import wholeMonth from './'
import moment from 'moment'

const parser = new chrono.Chrono
parser.refiners.push(wholeMonth)

test('test single month in the past', t => {
  const ref = new Date('2016-02-03') // Feb 3, 2016
  const dates = parser.parse('Jan')

  const janStart = moment('2016-01-01')
  const janEnd = moment('2016-01-31')

  t.ok(moment(dates[0].start.date()).isSame(janStart, 'day'), 'start jan 1')
  t.ok(moment(dates[0].end.date()).isSame(janEnd, 'day'), 'end jan 31')
  t.end()
})

test('test month range in the past', t => {
  const ref = new Date('2016-03-15') // March 15, 2016
  const dates = parser.parse('Jan - Feb')

  const janStart = moment('2016-01-01')
  const febEnd = moment('2016-02-29')

  t.ok(moment(dates[0].start.date()).isSame(janStart, 'day'), 'start jan 1')
  t.ok(moment(dates[0].end.date()).isSame(febEnd, 'day'), 'end feb 29')
  t.end()
})
<commit_msg>skip tests with specific year<commit_after>import test from 'tape'
import chrono from 'chrono-node'
import wholeMonth from './'
import moment from 'moment'

const parser = new chrono.Chrono
parser.refiners.push(wholeMonth)

const ref = new Date('2016-03-15') // March 15, 2016

test('single month in the past', t => {
  const dates = parser.parse('Jan')

  const janStart = moment('2016-01-01')
  const janEnd = moment('2016-01-31')

  t.ok(moment(dates[0].start.date()).isSame(janStart, 'day'), 'start jan 1')
  t.ok(moment(dates[0].end.date()).isSame(janEnd, 'day'), 'end jan 31')
  t.end()
})

test('month range in the past', t => {
  const dates = parser.parse('Jan - Feb')

  const janStart = moment('2016-01-01')
  const febEnd = moment('2016-02-29')

  t.ok(moment(dates[0].start.date()).isSame(janStart, 'day'), 'start jan 1')
  t.ok(moment(dates[0].end.date()).isSame(febEnd, 'day'), 'end feb 29')
  t.end()
})

test.skip('specific year', t => {
  const dates = parser.parse('Jan 2015 - Feb 2016')

  const janStart = moment('2015-01-01')
  const febEnd = moment('2016-02-29')

  t.ok(moment(dates[0].start.date()).isSame(janStart, 'day'), 'start jan 1')
  t.ok(moment(dates[0].end.date()).isSame(febEnd, 'day'), 'end feb 29')
  t.end()
})
<|endoftext|>


<commit_before>'use strict';

const co = require('co');

co(function *() {
  return yield [
    Promise.resolve('a'),
    {
      a: 0,
      b: Promise.resolve(1),
      c: Promise.resolve(2),
    }
  ];
}).then(console.log);
<commit_msg>Remove test codes<commit_after><|endoftext|>


<commit_before>import postcss from 'postcss';
import test    from 'ava';

import plugin from './';

function run(t, input, output) {
    return postcss([ plugin ]).process(input)
        .then( result => {
            t.deepEqual(result.css, output);
            t.deepEqual(result.warnings().length, 0);
        });
}

test('adds :host-context selector', t => {
    return run(t, 'h3, b {}', ':host-context h3, :host-context b {}');
});

test("doesn't double :host-context selector", t => {
    return run(t, ':host-context a {}',
                  ':host-context a {}');
});
<commit_msg>changed to host from host-context<commit_after>import postcss from 'postcss';
import test    from 'ava';

import plugin from './';

function run(t, input, output) {
    return postcss([ plugin ]).process(input)
        .then( result => {
            t.deepEqual(result.css, output);
            t.deepEqual(result.warnings().length, 0);
        });
}

test('adds :host selector', t => {
    return run(t, 'h3, b {}', ':host h3, :host b {}');
});

test("doesn't double :host selector", t => {
    return run(t, ':host a {}',
                  ':host a {}');
});
<|endoftext|>


<commit_before>/*
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

###############################################################################
# Use the -e option so the script will fail on the first non-zero return code.

# This is a script to automate building a 2.3.0 thru 3.1.0 snapshot of Android
# Cordova for delivery to a product team to integrate. It also automates building
# a runtime sample project and mobilespec for 2.3.0 thru 3.4.0. The manual process for
# this is described in our wiki. It is assumed that the platform/plugman/plugin
# repos have already been tagged with NEW_TAG. If you are just doing a test
# build and not creating a snapshot for product integration, you can get around
# the NEW_TAG check by setting it to "HEAD" in your corimf-settings file.
 */

var build, tests, settings, shelljs, path, fs;

try {
    build = require('./corimf-build.js'),
    tests = require('./corimf-tests.js'),
    settings = require('./corimf-settings.js'),
    path = require('path'),
    shelljs = require('shelljs');
    fs = require ('fs');
} catch (e) {
    console.error('Missing module. Please run "npm install" from this directory:\n\t' +
        path.dirname(__dirname));
    process.exit(2);
}
tests.reportStatus(!build.DisplayScriptInformation(function () {
        build.SetPlatform("android");
        build.DisplayBuildInformation();
        tests.reportStatus(build.RunPreliminaryTests(AndroidPreBuildSpecifics));
        tests.reportStatus(build.BuildProject(AndroidBuildSpecifics));
    }));

// Callback function that is called from corimf-build.js RunPreliminaryTests()
var AndroidPreBuildSpecifics = function () {
    console.log("Checking that we are using compiler for Java 5 or 6, not 7...");
    var VERSION = (shelljs.exec('javac -version 2>&1 | cut -f2 -d.', {
            silent : true
        }).output).replace(/(\r\n|\n|\r)/gm, "");
    if (VERSION >= 5) {
        console.log("Java version " + VERSION + " fully compatible");
        if (settings.BRANCH == "2.6.0esr") {
            console.log("Updating platform to use API 17...");
            tests.reportStatus(shelljs.exec('android update project -p ' + settings.PLATFORM_REPO + path.sep + 'framework -t android-17', {
                    silent : true
                }).code == 0);
            // Work around annoying bug in the bin/build script that assumes API 17
            // is the latest you have installed.
            /*
            console.log("Checking that API 17 is the most recent SDK installed...");
            var API_LEVEL = tests.reportStatus(shelljs.exec("`android list targets | grep 'API level:' | tail -n1 | cut -f2 -d: | tr -d ' '", {
                        silent : true
                    }).code == 0);
            if (API_LEVEL != "17") {
                console.log("Sorry, you need to uninstall the SDK for API $API_LEVEL");
                console.log("  or temporarily disable it by moving it to another directory, because it is");
                console.log("  preventing API 17 from being the most recent API installed.");
                console.log('  (i.e., move $SDK_HOME/sdk/platforms/android-18 $SDK_HOME/sdk/disabled-platforms/android-18 and make sure you have "Android SDK Build Tools" for v17 installed.');
                process.exit(code == 1);
            }
            */
        }

        console.log("Rebuilding the cordova.jar...");
        shelljs.cd(settings.PLATFORM_REPO);
        console.log(process.cwd());
        shelljs.cd('framework');
        console.log(process.cwd());
        tests.reportStatus(shelljs.exec('ant clean', {
                silent : false
            }).code === 0);
        var status = shelljs.exec('ant jar', {silent : false});
        tests.reportStatus(status.code == 0);
        shelljs.cd('..');
        shelljs.cd('..');

    } else {
        console.log("Java version " + VERSION + " not compatible");
        shelljs.exit(2);
    }
    return true;
},

// Callback function that is called from with corimf-build.js BuildProject()
AndroidBuildSpecifics = function (DPO) {
    var majorBranchNum = Number(settings.BRANCH.substring(0,3));

    //build mobilespec project
    if (settings.MOBILESPEC) {
        console.log("Building the project (apk) for mobilespec...");
        shelljs.cd(DPO.MOBILESPEC_DIR);
        if (majorBranchNum > 3.1)
        {
            tests.reportStatus(shelljs.exec(path.join('cordova','build'), {
                    silent : true
                }).code == 0);
        }
        else
        {
            tests.reportStatus(shelljs.exec('ant debug', {
                    silent : true
                }).code == 0);
        }
        shelljs.cd('..');
    }

    //build example project
    console.log("Building the project (apk)...");
    shelljs.cd(DPO.PROJECT_DIR);
    if(majorBranchNum > 3.1 && settings.PROJECT_ONLY) {
        tests.reportStatus(shelljs.exec(path.join('cordova','build'), {
            silent : true
        }).code == 0);
    }
    else{
    tests.reportStatus(shelljs.exec('ant debug', {
            silent : true
        }).code == 0);

    // capture the plugins in a jar for Worklight as a convenience
        if (majorBranchNum >= 3.0) {
            tests.reportStatus(shelljs.exec('jar cvf cordova_plugins.jar -C bin/classes org/apache/cordova', {
                    silent : true
                }).code == 0);
        }
    }
    shelljs.cd('..');
    if (!settings.PROJECT_ONLY) {
        console.log("Creating snapshot content in " + DPO.SNAPSHOT_DIR);
        shelljs.mkdir(DPO.SNAPSHOT_DIR);
        // get the original platform project. Not really needed perhaps.
        tests.reportStatus(shelljs.cp('-Rf', path.join('cordova-android', 'framework') , path.join(DPO.SNAPSHOT_DIR, 'framework')));
        if (shelljs.test('-d', path.join(DPO.SNAPSHOT_DIR,'framework','test'))) {
            // don't need test artifacts
            tests.reportStatus(shelljs.rm('-Rf', path.join(DPO.SNAPSHOT_DIR, 'framework','test')));
        }

        // get the example project, which includes cordova.jar and cordova.js.
        tests.reportStatus(shelljs.cp('-Rf',DPO.PROJECT_DIR , path.join(DPO.SNAPSHOT_DIR, 'example')));
        if (shelljs.test('-d', path.join(DPO.SNAPSHOT_DIR,'example','assets','www','spec'))) {
            // don't need test artifacts
            tests.reportStatus(shelljs.rm('-Rf', path.join(DPO.SNAPSHOT_DIR, 'example','assets','www','spec')));
        }
    }
    return true;
};
<commit_msg>Code order for build-android(minor changes)<commit_after>/*
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

###############################################################################
# Use the -e option so the script will fail on the first non-zero return code.

# This is a script to automate building a 2.3.0 thru 3.1.0 snapshot of Android
# Cordova for delivery to a product team to integrate. It also automates building
# a runtime sample project and mobilespec for 2.3.0 thru 3.4.0. The manual process for
# this is described in our wiki. It is assumed that the platform/plugman/plugin
# repos have already been tagged with NEW_TAG. If you are just doing a test
# build and not creating a snapshot for product integration, you can get around
# the NEW_TAG check by setting it to "HEAD" in your corimf-settings file.
 */

var build, tests, settings, shelljs, path, fs;

try {
    build = require('./corimf-build.js'),
    tests = require('./corimf-tests.js'),
    settings = require('./corimf-settings.js'),
    path = require('path'),
    shelljs = require('shelljs');
    fs = require('fs');
} catch (e) {
    console.error('Missing module. Please run "npm install" from this directory:\n\t' +
        path.dirname(__dirname));
    process.exit(2);
}
tests.reportStatus(!build.DisplayScriptInformation(function () {
        build.SetPlatform("android");
        build.DisplayBuildInformation();
        tests.reportStatus(build.RunPreliminaryTests(AndroidPreBuildSpecifics));
        tests.reportStatus(build.BuildProject(AndroidBuildSpecifics));
    }));

// Callback function that is called from corimf-build.js RunPreliminaryTests()
var AndroidPreBuildSpecifics = function () {
    console.log("Checking that we are using compiler for Java 5 or 6, not 7...");
    var VERSION = (shelljs.exec('javac -version 2>&1 | cut -f2 -d.', {
            silent : true
        }).output).replace(/(\r\n|\n|\r)/gm, "");
    if (VERSION >= 5) {
        console.log("Java version " + VERSION + " fully compatible");
        if (settings.BRANCH == "2.6.0esr") {
            console.log("Updating platform to use API 17...");
            tests.reportStatus(shelljs.exec('android update project -p ' + settings.PLATFORM_REPO + path.sep + 'framework -t android-17', {
                    silent : true
                }).code == 0);
            // Work around annoying bug in the bin/build script that assumes API 17
            // is the latest you have installed.
            /*
            console.log("Checking that API 17 is the most recent SDK installed...");
            var API_LEVEL = tests.reportStatus(shelljs.exec("`android list targets | grep 'API level:' | tail -n1 | cut -f2 -d: | tr -d ' '", {
            silent : true
            }).code == 0);
            if (API_LEVEL != "17") {
            console.log("Sorry, you need to uninstall the SDK for API $API_LEVEL");
            console.log("  or temporarily disable it by moving it to another directory, because it is");
            console.log("  preventing API 17 from being the most recent API installed.");
            console.log('  (i.e., move $SDK_HOME/sdk/platforms/android-18 $SDK_HOME/sdk/disabled-platforms/android-18 and make sure you have "Android SDK Build Tools" for v17 installed.');
            process.exit(code == 1);
            }
             */
        }

        console.log("Rebuilding the cordova.jar...");
        shelljs.cd(settings.PLATFORM_REPO);
        console.log(process.cwd());
        shelljs.cd('framework');
        console.log(process.cwd());
        tests.reportStatus(shelljs.exec('ant clean', {
                silent : false
            }).code === 0);
        var status = shelljs.exec('ant jar', {
                silent : false
            });
        tests.reportStatus(status.code == 0);
        shelljs.cd('..');
        shelljs.cd('..');

    } else {
        console.log("Java version " + VERSION + " not compatible");
        shelljs.exit(2);
    }
    return true;
},

// Callback function that is called from with corimf-build.js BuildProject()
AndroidBuildSpecifics = function (DPO) {
    var majorBranchNum = Number(settings.BRANCH.substring(0, 3));

    //build mobilespec project
    if (settings.MOBILESPEC) {
        console.log("Building the project (apk) for mobilespec...");
        shelljs.cd(DPO.MOBILESPEC_DIR);
        if (majorBranchNum > 3.1) {
            tests.reportStatus(shelljs.exec(path.join('cordova', 'build'), {
                    silent : true
                }).code == 0);
        } else {
            tests.reportStatus(shelljs.exec('ant debug', {
                    silent : true
                }).code == 0);
        }
        shelljs.cd('..');
    }

    //build example project
    console.log("Building the project (apk)...");
    shelljs.cd(DPO.PROJECT_DIR);
    if (majorBranchNum > 3.1 && settings.PROJECT_ONLY) {
        tests.reportStatus(shelljs.exec(path.join('cordova', 'build'), {
                silent : true
            }).code == 0);
    } else {
        tests.reportStatus(shelljs.exec('ant debug', {
                silent : true
            }).code == 0);

        // capture the plugins in a jar for Worklight as a convenience
        if (majorBranchNum >= 3.0) {
            tests.reportStatus(shelljs.exec('jar cvf cordova_plugins.jar -C bin/classes org/apache/cordova', {
                    silent : true
                }).code == 0);
        }
    }
    shelljs.cd('..');
    if (!settings.PROJECT_ONLY) {
        console.log("Creating snapshot content in " + DPO.SNAPSHOT_DIR);
        shelljs.mkdir(DPO.SNAPSHOT_DIR);
        // get the original platform project. Not really needed perhaps.
        tests.reportStatus(shelljs.cp('-Rf', path.join('cordova-android', 'framework'), path.join(DPO.SNAPSHOT_DIR, 'framework')));
        if (shelljs.test('-d', path.join(DPO.SNAPSHOT_DIR, 'framework', 'test'))) {
            // don't need test artifacts
            tests.reportStatus(shelljs.rm('-Rf', path.join(DPO.SNAPSHOT_DIR, 'framework', 'test')));
        }

        // get the example project, which includes cordova.jar and cordova.js.
        tests.reportStatus(shelljs.cp('-Rf', DPO.PROJECT_DIR, path.join(DPO.SNAPSHOT_DIR, 'example')));
        if (shelljs.test('-d', path.join(DPO.SNAPSHOT_DIR, 'example', 'assets', 'www', 'spec'))) {
            // don't need test artifacts
            tests.reportStatus(shelljs.rm('-Rf', path.join(DPO.SNAPSHOT_DIR, 'example', 'assets', 'www', 'spec')));
        }
    }
    return true;
};<|endoftext|>


<commit_before>var concat = require('concat-stream')
var lamos = require('./')
var pump = require('pump')
var stringToStream = require('string-to-stream')
var tape = require('tape')

var examples = require('./examples').map(function (example) {
  if (example.lamos) {
    example.lamos = example.lamos.join('\n')
  }
  return example
})

tape('parse', function (suite) {
  examples.forEach(function (example) {
    suite.test(example.name, function (test) {
      if (example.js && example.lamos) {
        test.deepEqual(lamos.parse(example.lamos), example.js)
        test.end()
      } else if (example.error) {
        if (example.lamos) {
          test.throws(function () {
            lamos.parse(example.lamos)
          }, new RegExp(example.error))
          test.end()
        } else if (example.js) {
          test.throws(function () {
            lamos.stringify(example.js)
          }, new RegExp(example.error))
          test.end()
        }
      }
    })
  })
})

tape('tokenizer', function (suite) {
  examples.forEach(function (example) {
    if (example.tokens) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(example.lamos),
          lamos.tokenizer(),
          concat(function (tokens) {
            test.deepEqual(tokens, example.tokens)
            test.end()
          })
        )
      })
    } else if (example.error) {
      if (example.lamos) {
        suite.test(example.name, function (test) {
          pump(
            stringToStream(example.lamos),
            lamos.tokenizer(),
            concat(/* istanbul ignore next */ function () {
              test.fail()
              test.end()
            }),
            function (error) {
              test.equal(
                error.message, example.error
              )
              test.end()
            }
          )
        })
      }
    }
  })
})

tape('round trips', function (suite) {
  examples.forEach(function (example) {
    if (example.js && !example.error) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(lamos.stringify(example.js)),
          concat(function (buffer) {
            test.deepEqual(
              lamos.parse(buffer.toString()), example.js
            )
            test.end()
          })
        )
      })
    }
  })
})

tape('stable round trips', function (suite) {
  examples.forEach(function (example) {
    if (example.js && !example.error) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(lamos.stableStringify(example.js)),
          concat(function (buffer) {
            test.deepEqual(
              lamos.parse(buffer.toString()), example.js
            )
            test.end()
          })
        )
      })
    }
  })
})

tape('stable stringify sorting', function (test) {
  test.equal(
    lamos.stableStringify({
      c: 'z',
      b: 'y',
      a: 'x'
    }),
    [
      'a: x',
      'b: y',
      'c: z'
    ].join('\n')
  )
  test.end()
})

tape('JSON coercion', function (suite) {
  coercion('null', null, 'null')
  coercion('true', true, 'true')
  coercion('false', false, 'false')
  coercion('number', 1.234, '1.234')

  coercionFailure(
    'empty string', [''], 'Cannot serialize empty string.'
  )
  coercionFailure(
    'empty array', [], 'Cannot serialize empty array.'
  )
  coercionFailure(
    'empty object', {}, 'Cannot serialize empty object.'
  )

  function coercion (name, value, lomas) {
    suite.test(name, function (test) {
      test.equal(
        lamos.stringify([value]),
        '- ' + lomas,
        'stringify array'
      )
      test.equal(
        lamos.stableStringify([value]),
        '- ' + lomas,
        'stableStringify array'
      )
      test.equal(
        lamos.stringify({a: value}),
        'a: ' + lomas,
        'stringify object'
      )
      test.equal(
        lamos.stableStringify({a: value}),
        'a: ' + lomas,
        'stableStringify object'
      )
      test.end()
    })
  }

  function coercionFailure (name, js, message) {
    suite.test(name, function (test) {
      test.throws(function () {
        lamos.stringify(js)
      }, message)
      test.throws(function () {
        lamos.stableStringify(js)
      }, message)
      test.end()
    })
  }
})
<commit_msg>Fix streaming error test<commit_after>var concat = require('concat-stream')
var lamos = require('./')
var pump = require('pump')
var stringToStream = require('string-to-stream')
var tape = require('tape')

var examples = require('./examples').map(function (example) {
  if (example.lamos) {
    example.lamos = example.lamos.join('\n')
  }
  return example
})

tape('parse', function (suite) {
  examples.forEach(function (example) {
    suite.test(example.name, function (test) {
      if (example.js && example.lamos) {
        test.deepEqual(lamos.parse(example.lamos), example.js)
        test.end()
      } else if (example.error) {
        if (example.lamos) {
          test.throws(function () {
            lamos.parse(example.lamos)
          }, new RegExp(example.error))
          test.end()
        } else if (example.js) {
          test.throws(function () {
            lamos.stringify(example.js)
          }, new RegExp(example.error))
          test.end()
        }
      }
    })
  })
})

tape('tokenizer', function (suite) {
  examples.forEach(function (example) {
    if (example.tokens) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(example.lamos),
          lamos.tokenizer(),
          concat(function (tokens) {
            test.deepEqual(tokens, example.tokens)
            test.end()
          })
        )
      })
    } else if (example.error) {
      if (example.lamos) {
        suite.test(example.name, function (test) {
          pump(
            stringToStream(example.lamos),
            lamos.tokenizer(),
            concat(function () {}),
            function (error) {
              test.equal(
                error.message, example.error
              )
              test.end()
            }
          )
        })
      }
    }
  })
})

tape('round trips', function (suite) {
  examples.forEach(function (example) {
    if (example.js && !example.error) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(lamos.stringify(example.js)),
          concat(function (buffer) {
            test.deepEqual(
              lamos.parse(buffer.toString()), example.js
            )
            test.end()
          })
        )
      })
    }
  })
})

tape('stable round trips', function (suite) {
  examples.forEach(function (example) {
    if (example.js && !example.error) {
      suite.test(example.name, function (test) {
        pump(
          stringToStream(lamos.stableStringify(example.js)),
          concat(function (buffer) {
            test.deepEqual(
              lamos.parse(buffer.toString()), example.js
            )
            test.end()
          })
        )
      })
    }
  })
})

tape('stable stringify sorting', function (test) {
  test.equal(
    lamos.stableStringify({
      c: 'z',
      b: 'y',
      a: 'x'
    }),
    [
      'a: x',
      'b: y',
      'c: z'
    ].join('\n')
  )
  test.end()
})

tape('JSON coercion', function (suite) {
  coercion('null', null, 'null')
  coercion('true', true, 'true')
  coercion('false', false, 'false')
  coercion('number', 1.234, '1.234')

  coercionFailure(
    'empty string', [''], 'Cannot serialize empty string.'
  )
  coercionFailure(
    'empty array', [], 'Cannot serialize empty array.'
  )
  coercionFailure(
    'empty object', {}, 'Cannot serialize empty object.'
  )

  function coercion (name, value, lomas) {
    suite.test(name, function (test) {
      test.equal(
        lamos.stringify([value]),
        '- ' + lomas,
        'stringify array'
      )
      test.equal(
        lamos.stableStringify([value]),
        '- ' + lomas,
        'stableStringify array'
      )
      test.equal(
        lamos.stringify({a: value}),
        'a: ' + lomas,
        'stringify object'
      )
      test.equal(
        lamos.stableStringify({a: value}),
        'a: ' + lomas,
        'stableStringify object'
      )
      test.end()
    })
  }

  function coercionFailure (name, js, message) {
    suite.test(name, function (test) {
      test.throws(function () {
        lamos.stringify(js)
      }, message)
      test.throws(function () {
        lamos.stableStringify(js)
      }, message)
      test.end()
    })
  }
})
<|endoftext|>


<commit_before>'use strict';

var noop = require('nop');
var readMultipleFiles = require('./');
var test = require('tape');

test('readMultipleFiles()', function(t) {
  t.plan(11);

  readMultipleFiles(['.gitignore', '.gitattributes'], 'hex', function(err, contents) {
    t.deepEqual(
      contents, [
        new Buffer('node_modules\ncoverage\n').toString('hex'),
        new Buffer('* text=auto\n').toString('hex')
      ],
      'should reflect file encoding to the result.'
    );
    t.strictEqual(err, null, 'should read all files without any errors.');
  });

  readMultipleFiles(['./.gitignore'], {encoding: 'base64'}, function(err, contents) {
    t.deepEqual(
      contents, [new Buffer('node_modules\ncoverage\n').toString('base64')],
      'should reflect fs.readFile options to the result.'
    );
    t.strictEqual(err, null, 'should read a file without any errors.');
  });

  readMultipleFiles([], function(err, contents) {
    t.deepEqual(
      contents, [],
      'should pass an empty array to the callback when it takes an empty array.'
    );
    t.strictEqual(
      err, null,
      'should not pass any errors to the callback even if it takes an empty array.'
    );
  });

  readMultipleFiles(['.gitattributes', 'node_modules', 'index.js'], function(err) {
    t.equal(
      err.code, 'EISDIR',
      'should pass an error to the callback when it fails to read files.'
    );
    t.equal(
      arguments.length, 1,
      'should not pass any buffers to the callback when it fails to read files.'
    );
  });

  t.throws(
    readMultipleFiles.bind(null, []), /TypeError.*Last argument/,
    'should throw a type error when the last argument is not a function.'
  );

  t.throws(
    readMultipleFiles.bind(null, 'test.js', noop), /TypeError.*must be an array/,
    'should throw a type error when the first argument is not an array.'
  );

  t.throws(
    readMultipleFiles.bind(null, ['test.js', ['index.js']], noop), /TypeError.*path/,
    'should throw a type error when the first argument contains non-string values.'
  );
});
<commit_msg>update test script<commit_after>'use strict';

var noop = require('nop');
var readMultipleFiles = require('./');
var test = require('tape');

function toHex(str) {
  return new Buffer(str).toString('hex');
}

test('readMultipleFiles()', function(t) {
  t.plan(9);

  t.equal(readMultipleFiles.name, 'readMultipleFiles', 'should have a function name.');

  readMultipleFiles(['.gitignore', '.gitattributes'], 'hex', function(err, contents) {
    t.deepEqual(
      [err, contents],
      [null, [toHex('node_modules\ncoverage\n'), toHex('* text=auto\n')]],
      'should reflect file encoding to all results.'
    );
  });

  readMultipleFiles(['./.gitignore'], {encoding: 'base64'}, function(err, contents) {
    t.deepEqual(
      [err, contents],
      [null, [new Buffer('node_modules\ncoverage\n').toString('base64')]],
      'should support fs.readFile options.'
    );
  });

  readMultipleFiles([], function(err, contents) {
    t.deepEqual(
      [err, contents],
      [null, []],
      'should pass an empty array to the callback when it takes an empty array.'
    );
  });

  readMultipleFiles(['.gitattributes', 'node_modules', 'index.js'], function(err) {
    t.equal(
      err.code, 'EISDIR',
      'should pass an error to the callback when it fails to read files.'
    );
    t.equal(
      arguments.length, 1,
      'should not pass any buffers to the callback when it fails to read files.'
    );
  });

  t.throws(
    readMultipleFiles.bind(null, []),
    /TypeError.*Last argument/,
    'should throw a type error when the last argument is not a function.'
  );

  t.throws(
    readMultipleFiles.bind(null, 'test.js', noop),
    /TypeError.*must be an array/,
    'should throw a type error when the first argument is not an array.'
  );

  t.throws(
    readMultipleFiles.bind(null, ['test.js', ['index.js']], noop),
    /TypeError.*path/,
    'should throw a type error when the array contains non-string values.'
  );
});
<|endoftext|>


<commit_before>/**
 * parse-github-short-url <https://github.com/tunnckoCore/parse-github-short-url>
 *
 * Copyright (c) 2015 Charlike Mike Reagent, contributors.
 * Released under the MIT license.
 */

'use strict';

var assert = require('assert');
var parseUrl = require('./index');

describe('parse-github-short-url:', function() {
  describe('should throw', function() {
    it('Error when no arguments', function(done) {
      assert.throws(parseUrl, Error);
      done()
    });

    it('Error when empty string given', function(done) {
      function fixture() {
        parseUrl('')
      }
      assert.throws(fixture, Error);
      done();
    });

    it('TypeError when first argument not String given', function(done) {
      function fixture() {
        parseUrl({})
      }
      assert.throws(fixture, TypeError);
      done();
    });
  });

  describe('should return object with empty fields for missing properties', function(done) {
    it('when string not contain possible pattern', function(done) {
      var expected = {
        user: '',
        username: '',
        org: '',
        organization: '',
        repo: '',
        repository: '',
        branch: ''
      };
      var actual = parseUrl('some string');

      assert.deepEqual(actual, expected);
      done();
    });

    it('when string not a valid `user/repo` pattern', function(done) {
      var expected = {
        user: '',
        username: '',
        org: '',
        organization: '',
        repo: '',
        repository: '',
        branch: ''
      };
      var actual = parseUrl('some tunnckoCore!glob2fp#feature string');

      assert.deepEqual(actual, expected);
      done();
    });
  });

  describe('should work and', function() {
    it('should return object with `user`, `repo` and `branch`', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: 'feature'
      };
      var actual = parseUrl('tunnckoCore/glob2fp#feature');

      assert.deepEqual(actual, expected);
      done()
    });

    it('should return object with `user` and `repo` properties only', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: ''
      };
      var actual = parseUrl('tunnckoCore/glob2fp');

      assert.deepEqual(actual, expected);
      done();
    });

    it('should returned be object and have .constructor.name', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: 'feature'
      };
      var actual = parseUrl('tunnckoCore/glob2fp#feature');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert(actual.constructor);
      assert(actual.constructor.name);
      done()
    });

    it('should .constructor.name be `ParseGithubShorthand`', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'homepage',
        repository: 'homepage',
        branch: 'bigfix'
      };
      var actual = parseUrl('tunnckoCore/homepage#bigfix');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert.strictEqual(actual.constructor.name, 'ParseGithubShorthand');
      done();
    });

    it('should have static method .test', function(done) {
      var expected = {
        user: 'jadejs',
        username: 'jadejs',
        org: 'jadejs',
        organization: 'jadejs',
        repo: 'doctypes',
        repository: 'doctypes',
        branch: 'refactor'
      };
      var actual = parseUrl('jadejs/doctypes#refactor');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(actual), true);
      done();
    });

    it('should have static method .validate', function(done) {
      var expected = {
        user: 'shouldjs',
        username: 'shouldjs',
        org: 'shouldjs',
        organization: 'shouldjs',
        repo: 'format',
        repository: 'format',
        branch: 'refactor'
      };
      var actual = parseUrl('shouldjs/format#refactor');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(actual), true);
      assert.strictEqual(parseUrl.validate(expected), true);
      assert.strictEqual(parseUrl.validate(actual), true);
      done();
    });
  });

  describe('should `.test` method return', function() {
    it('`true` if given is valid `ParseGithubShorthand` object', function(done) {
      var expected = {
        user: 'visionmedia',
        username: 'visionmedia',
        org: 'visionmedia',
        organization: 'visionmedia',
        repo: 'expressjs',
        repository: 'expressjs',
        branch: 'wantfix'
      };
      var actual = parseUrl('visionmedia/expressjs#wantfix');

      assert.deepEqual(actual, expected);
      assert.strictEqual(parseUrl.test(actual), true);
      done();
    });

    it('`false` if given is not valid object', function(done) {
      var fixture = {
        username: 'tunnckoCore',
        repo: 'glob2fp'
      };

      assert.strictEqual(parseUrl.test(fixture), false);
      done();
    });
  });

  describe('should `.validate` method return', function() {
    it('`true` if given object have at least `.user` and `.repo` properties', function(done) {
      var fixture = {
        user: 'visionmedia',
        username: 'visionmedia',
        org: 'visionmedia',
        organization: 'visionmedia',
        repo: 'expressjs',
        repository: 'expressjs',
        branch: 'wantfix'
      };
      var expected = true;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), expected);
      done();
    });

    it('`false` if otherwise', function(done) {
      var fixture = {
        beta: 'tunnckoCore',
        user: 'glob2fp'
      };
      var expected = false;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), false);
      done();
    });
  });
});
<commit_msg>add more tests<commit_after>/**
 * parse-github-short-url <https://github.com/tunnckoCore/parse-github-short-url>
 *
 * Copyright (c) 2015 Charlike Mike Reagent, contributors.
 * Released under the MIT license.
 */

'use strict';

var assert = require('assert');
var parseUrl = require('./index');

describe('parse-github-short-url:', function() {
  describe('should throw', function() {
    it('Error when no arguments', function(done) {
      assert.throws(parseUrl, Error);
      done()
    });

    it('Error when empty string given', function(done) {
      function fixture() {
        parseUrl('')
      }
      assert.throws(fixture, Error);
      done();
    });

    it('TypeError when first argument not String given', function(done) {
      function fixture() {
        parseUrl({})
      }
      assert.throws(fixture, TypeError);
      done();
    });
  });

  describe('should return object with empty fields for missing properties', function(done) {
    it('when string not contain possible pattern', function(done) {
      var expected = {
        user: '',
        username: '',
        org: '',
        organization: '',
        repo: '',
        repository: '',
        branch: ''
      };
      var actual = parseUrl('some string');

      assert.deepEqual(actual, expected);
      done();
    });

    it('when string not a valid `user/repo` pattern', function(done) {
      var expected = {
        user: '',
        username: '',
        org: '',
        organization: '',
        repo: '',
        repository: '',
        branch: ''
      };
      var actual = parseUrl('some tunnckoCore!glob2fp#feature string');

      assert.deepEqual(actual, expected);
      done();
    });
  });

  describe('should work and', function() {
    it('should return object with `user`, `repo` and `branch`', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: 'feature'
      };
      var actual = parseUrl('tunnckoCore/glob2fp#feature');

      assert.deepEqual(actual, expected);
      done()
    });

    it('should return object with `user` and `repo` properties only', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: ''
      };
      var actual = parseUrl('tunnckoCore/glob2fp');

      assert.deepEqual(actual, expected);
      done();
    });

    it('should returned be object and have .constructor.name', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'glob2fp',
        repository: 'glob2fp',
        branch: 'feature'
      };
      var actual = parseUrl('tunnckoCore/glob2fp#feature');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert(actual.constructor);
      assert(actual.constructor.name);
      done()
    });

    it('should .constructor.name be `ParseGithubShorthand`', function(done) {
      var expected = {
        user: 'tunnckoCore',
        username: 'tunnckoCore',
        org: 'tunnckoCore',
        organization: 'tunnckoCore',
        repo: 'homepage',
        repository: 'homepage',
        branch: 'bigfix'
      };
      var actual = parseUrl('tunnckoCore/homepage#bigfix');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert.strictEqual(actual.constructor.name, 'ParseGithubShorthand');
      done();
    });

    it('should have static method .test', function(done) {
      var expected = {
        user: 'jadejs',
        username: 'jadejs',
        org: 'jadejs',
        organization: 'jadejs',
        repo: 'doctypes',
        repository: 'doctypes',
        branch: 'refactor'
      };
      var actual = parseUrl('jadejs/doctypes#refactor');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof actual, 'object');
      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(actual), true);
      done();
    });

    it('should have static method .validate', function(done) {
      var expected = {
        user: 'shouldjs',
        username: 'shouldjs',
        org: 'shouldjs',
        organization: 'shouldjs',
        repo: 'format',
        repository: 'format',
        branch: 'refactor'
      };
      var actual = parseUrl('shouldjs/format#refactor');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(actual), true);
      assert.strictEqual(parseUrl.validate(expected), true);
      assert.strictEqual(parseUrl.validate(actual), true);
      done();
    });
  });

  describe('should `.test` method return', function() {
    it('`true` if given is valid `ParseGithubShorthand` object', function(done) {
      var expected = {
        user: 'visionmedia',
        username: 'visionmedia',
        org: 'visionmedia',
        organization: 'visionmedia',
        repo: 'expressjs',
        repository: 'expressjs',
        branch: 'wantfix'
      };
      var actual = parseUrl('visionmedia/expressjs#wantfix');

      assert.deepEqual(actual, expected);
      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(actual), true);
      done();
    });

    it('`false` if given is not valid object', function(done) {
      var fixture = {
        username: 'tunnckoCore',
        repo: 'glob2fp'
      };

      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(fixture), false);
      done();
    });

    it('`false` no arguments given', function(done) {
      var expected = false;

      assert.strictEqual(typeof parseUrl.test, 'function');
      assert.strictEqual(parseUrl.test(), false);
      assert.strictEqual(parseUrl.test(undefined), false);
      done();
    });
  });

  describe('should `.validate` method return', function() {
    it('`true` if given object have at least `.user` and `.repo` properties', function(done) {
      var fixture = {
        user: 'visionmedia',
        username: 'visionmedia',
        org: 'visionmedia',
        organization: 'visionmedia',
        repo: 'expressjs',
        repository: 'expressjs',
        branch: 'wantfix'
      };
      var expected = true;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), expected);
      done();
    });

    it('`false` if otherwise', function(done) {
      var fixture = {
        beta: 'tunnckoCore',
        user: 'glob2fp'
      };
      var expected = false;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), false);
      done();
    });

    it('`false` if `.user` property is not string', function(done) {
      var fixture = {
        user: false,
        repo: 'repo'
      };
      var expected = false;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), false);
      done();
    });

    it('`false` if `.repo` property is not string', function(done) {
      var fixture = {
        user: 'tunnckoCore',
        repo: false
      };
      var expected = false;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(fixture), false);
      done();
    });

    it('`false` no arguments given', function(done) {
      var expected = false;

      assert.strictEqual(typeof parseUrl.validate, 'function');
      assert.strictEqual(parseUrl.validate(), false);
      assert.strictEqual(parseUrl.validate(undefined), false);
      done();
    });
  });
});
<|endoftext|>


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

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

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-6-13 17:37:09<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

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

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


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

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

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-3 09:37:47<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

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

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


<commit_before>on('ready', function() {
    if (!_.has(state, 'Supernotes')) {
        state.Supernotes = {
            sheet: 'Default',
            template: 'default',
            title: 'name',
            theText: '',
            sendToPlayers: true

        };
        message = 'Welcome to Supernotes! If this is your first time running it, the script is set to use the Default Roll Template. You can choose a different sheet template below, as well as decide whether you want the script to display a "Send to Players" footer at the end of every GM message. It is currently set to true.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)';
        sendChat('Supernotes', '/w gm &{template:' + state.Supernotes.template + '}{{' + state.Supernotes.title + '=' + 'Config' + '}} {{' + state.Supernotes.theText + '=' + message + '}}');
    }
});

on('ready', () => {

    const decodeUnicode = (str) => str.replace(/%u[0-9a-fA-F]{2,4}/g, (m) => String.fromCharCode(parseInt(m.slice(2), 16)));

    const version = '0.0.4';
    log('Supernotes v' + version + ' is ready!  Please set lines 3-5 to work with the roll templates your sheet of choice');

    on('chat:message', function(msg) {
        if ('api' === msg.type && msg.content.match(/^!(gm|pc)note/) && playerIsGM(msg.playerid)) {
            let match = msg.content.match(/^!gmnote-(.*)$/);

            //define command
            let command = msg.content.split(/\s+--/)[0];

            let messagePrefix = '/w gm ';
            if (command === '!pcnote') {
                messagePrefix = '';
            }

            //define option
            let option = msg.content.split(/\s+--/)[1];

            const template = state.Supernotes.template;
            const title = state.Supernotes.title;
            const theText = state.Supernotes.theText;
            const sendToPlayers = state.Supernotes.sendToPlayers;

            if (option !== undefined && option.includes('config')) {
                let templateChoice = option.split('|')[1]

                if (templateChoice === undefined) {
                    message = 'Current sheet template:
' + state.Supernotes.sheet + '
Send to Players:
' + state.Supernotes.sendToPlayers + '

Choose a template for Supernotes to use.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)'
                    sendChat('Supernotes', messagePrefix + '&{template:' + template + '}{{' + title + '=' + 'Config' + '}} {{' + theText + '=' + message + '}}');
                }

                switch (templateChoice) {
                    case 'default':
                        state.Supernotes.sheet = 'Default';
                        state.Supernotes.template = 'default';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = '';
                        sendChat('Supernotes', '/w gm Supernotes set to Default roll template');
                        break;
                    case 'dnd5e':
                        state.Supernotes.sheet = 'D&D 5th Edition by Roll20';
                        state.Supernotes.template = 'npcaction';
                        state.Supernotes.title = 'rname';
                        state.Supernotes.theText = 'description';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case '5eshaped':
                        state.Supernotes.sheet = 'DnD 5e Shaped';
                        state.Supernotes.template = '5e-shaped';
                        state.Supernotes.title = 'title';
                        state.Supernotes.theText = 'text_big';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pfcommunity':
                        state.Supernotes.sheet = 'Pathfinder Community';
                        state.Supernotes.template = 'pf_generic';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = 'description';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pfofficial':
                        state.Supernotes.sheet = 'Pathfinder by Roll20';
                        state.Supernotes.template = 'npc';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = 'descflag=1}} {{desc';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pf2e':
                        state.Supernotes.sheet = 'Pathefinder 2e';
                        state.Supernotes.template = 'rolls';
                        state.Supernotes.title = 'header';
                        state.Supernotes.theText = 'notes_show=[[1]]}} {{notes';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'starfinder':
                        state.Supernotes.sheet = 'Starfinder';
                        state.Supernotes.template = 'sf_generic';
                        state.Supernotes.title = 'title';
                        state.Supernotes.theText = 'buttons0';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'sendtoPlayers':
                        if (state.Supernotes.sendToPlayers) {
                            state.Supernotes.sendToPlayers = false
                        } else {
                            state.Supernotes.sendToPlayers = true
                        };
                        sendChat('Supernotes', '/w gm Send to Players set to ' + state.Supernotes.sendToPlayers);
                        break;
                }
            } else {
                if (option !== undefined && option.includes('help')) {
                    message = 'Supernotes pulls the contents from a token's GM Notes field. If the token represents a character, you can optionally pull in the Bio or GM notes from the character, as well as the avatar, or extract just the image from the bio field. The user can decide whether to whisper the notes to the GM or broadcast them to all players. Finally, there is the option to add a footer to notes whispered to the GM. This footer creates a chat button to give the option of sending the notes on to the players.
This script as written is optimized for the D&D 5th Edition by Roll20 sheet, but can be adapted easily suing the Configuration section below.

Commands:
!gmnote whispers the note to the GM
!pcnote sends the note to all players

Paramaters

--token Pulls notes from the selected token's gm notes field. This is optional. If it is missing, the script assumes --token

--charnote Pulls notes from the gm notes field of the character assigned to a token.

--bio Pulls notes from the bio field of the character assigned to a token.

--avatar Pulls the image from the avatar field of the character assigned to a token.

--image Pulls first image from the bio field of the character assigned to a token, if any exists. Otherwise returns notice that no artwork is available

--help Displays help.

--config Returns a configuration dialog box that allows you to set which sheet's roll template to use, and to toggle the "Send to Players" footer.

Configuration
When first installed, Supernotes is configured for the default roll template. It will display a config dialog box at startup that will allow you to choose a roll template based on your character sheet of choice, as well as the option  to toggle whether you want the "Send to Players" footer button to appear.
You will need to edit the code of the script to create a custom configuration. The pre-installed sheets are:

Default Template
D&D 5th Edition by Roll20
5e Shaped
Pathfinder by Roll20
Pathfinder Community
Pathfinder 2e by Roll20
Starfinder
';
                    sendChat('Supernotes', messagePrefix + '&{template:' + template + '}{{' + title + '=' + 'Supernotes Help' + '}} {{' + theText + '=' + message + '}}');

                } else {

                    if ((option !== 'bio' && option !== 'charnote' && option !== 'avatar' && option !== 'image') || (option === undefined)) {
                        //|| (option === undefined
                        option = 'token';
                    }

                    let playerButton = '';
                    if (sendToPlayers && command === '!gmnote') {
                        playerButton = '\n[Send to Players](!pcnote --' + option + ')';
                    }

                    let regex;
                    if (match && match[1]) {
                        regex = new RegExp(`^${match[1]}`, 'i');
                    }

                    let message = '';
                    let whom = '';

                    if (option === 'avatar') {
                        (msg.selected || [])
                        .map(o => getObj('graphic', o._id))
                            .filter(g => undefined !== g)
                            .map(t => getObj('character', t.get('represents')))
                            .filter(c => undefined !== c)
                            .forEach(c => {
                                message = "";
                                log('avatar = ' + c.get('avatar'));
                                whom = c.get('name');
                                sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');
                            });
                    } else {

                        if (option === 'image') {

                            (msg.selected || [])
                            .map(o => getObj('graphic', o._id))
                                .filter(g => undefined !== g)
                                .map(t => getObj('character', t.get('represents')))
                                .filter(c => undefined !== c)
                                .forEach(c => c.get('bio', (val) => {
                                    if (null !== val && 'null' !== val && val.length > 0) {
                                        if (regex) {
                                            message = _.filter(
                                                decodeUnicode(val).split(/(?:[\n\r]+|
)/),
                                                (l) => regex.test(l.replace(/<[^>]*>/g, ''))
                                            ).join('\r');
                                        } else {
                                            message = decodeUnicode(val);
                                        }
                                        artwork = message.match(/\/g)

                                        if (artwork) {
                                            message = artwork;
                                        } else {
                                            message = 'No artwork exists for this character.';
                                        }

                                        whom = c.get('name');
                                        //Sends the final message
                                        sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                                    }
                                }));
                        } else {

                            if ((option === 'bio') || (option === 'charnote')) {
                                let suboption = (option === 'charnote') ? 'gmnotes' : 'bio';

                                (msg.selected || [])
                                .map(o => getObj('graphic', o._id))
                                    .filter(g => undefined !== g)
                                    .map(t => getObj('character', t.get('represents')))
                                    .filter(c => undefined !== c)
                                    .forEach(c => c.get(suboption, (val) => {
                                        if (null !== val && 'null' !== val && val.length > 0) {
                                            if (regex) {
                                                message = _.filter(
                                                    decodeUnicode(val).split(/(?:[\n\r]+|
)/),
                                                    (l) => regex.test(l.replace(/<[^>]*>/g, ''))
                                                ).join('\r');
                                            } else {
                                                message = decodeUnicode(val);
                                            }
                                            whom = c.get('name');
                                            //Sends the final message
                                            sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                                        }
                                    }));
                            } else {
                                (msg.selected || [])
                                .map(o => getObj('graphic', o._id))
                                    .filter(g => undefined !== g)
                                    .filter((o) => o.get('gmnotes').length > 0)
                                    .forEach(o => {
                                        if (regex) {
                                            message = _.filter(decodeURIComponent(decodeUnicode(o.get('gmnotes'))).split(/(?:[\n\r]+|
)/), (l) => regex.test(l)).join('\r');
                                        } else {
                                            message = decodeURIComponent(decodeUnicode(o.get('gmnotes')));
                                        }
                                        whom = o.get('name');

                                    });
                                //Sends the final message
                                sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                            }

                            [
                                `### REPORT###`,
                                `THE MESSAGE =${message}`,
                                `command = ${command}`,
                                `option = ${option}`,
                                `messagePrefix = ${messagePrefix}`,
                                `message =${message}`
                            ].forEach(m => log(m));
                        }
                    }
                }
            }
        }
    });
});
<commit_msg>Update Supernotes.js<commit_after>on('ready', function() {
    if (!_.has(state, 'Supernotes')) {
        state.Supernotes = {
            sheet: 'Default',
            template: 'default',
            title: 'name',
            theText: '',
            sendToPlayers: true

        };
        message = 'Welcome to Supernotes! If this is your first time running it, the script is set to use the Default Roll Template. You can choose a different sheet template below, as well as decide whether you want the script to display a "Send to Players" footer at the end of every GM message. It is currently set to true.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)';
        sendChat('Supernotes', '/w gm &{template:' + state.Supernotes.template + '}{{' + state.Supernotes.title + '=' + 'Config' + '}} {{' + state.Supernotes.theText + '=' + message + '}}');
    }
});

on('ready', () => {

    const decodeUnicode = (str) => str.replace(/%u[0-9a-fA-F]{2,4}/g, (m) => String.fromCharCode(parseInt(m.slice(2), 16)));

    const version = '0.0.5';
    log('Supernotes v' + version + ' is ready!  To set the template of choice or to toggle the send to players option, Use the command !gmnote --config');

    on('chat:message', function(msg) {
        if ('api' === msg.type && msg.content.match(/^!(gm|pc)note\b/) && playerIsGM(msg.playerid)) {
            let match = msg.content.match(/^!gmnote-(.*)$/);

            //define command
            let command = msg.content.split(/\s+--/)[0];

            let messagePrefix = '/w gm ';
            if (command === '!pcnote') {
                messagePrefix = '';
            }

            //define option
            let option = msg.content.split(/\s+--/)[1];

            const template = state.Supernotes.template;
            const title = state.Supernotes.title;
            const theText = state.Supernotes.theText;
            const sendToPlayers = state.Supernotes.sendToPlayers;

            if (option !== undefined && option.includes('config')) {
                let templateChoice = option.split('|')[1]

                if (templateChoice === undefined) {
                    message = 'Current sheet template:
' + state.Supernotes.sheet + '
Send to Players:
' + state.Supernotes.sendToPlayers + '

Choose a template for Supernotes to use.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)'
                    sendChat('Supernotes', messagePrefix + '&{template:' + template + '}{{' + title + '=' + 'Config' + '}} {{' + theText + '=' + message + '}}');
                }

                switch (templateChoice) {
                    case 'default':
                        state.Supernotes.sheet = 'Default';
                        state.Supernotes.template = 'default';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = '';
                        sendChat('Supernotes', '/w gm Supernotes set to Default roll template');
                        break;
                    case 'dnd5e':
                        state.Supernotes.sheet = 'D&D 5th Edition by Roll20';
                        state.Supernotes.template = 'npcaction';
                        state.Supernotes.title = 'rname';
                        state.Supernotes.theText = 'description';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case '5eshaped':
                        state.Supernotes.sheet = 'DnD 5e Shaped';
                        state.Supernotes.template = '5e-shaped';
                        state.Supernotes.title = 'title';
                        state.Supernotes.theText = 'text_big';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pfcommunity':
                        state.Supernotes.sheet = 'Pathfinder Community';
                        state.Supernotes.template = 'pf_generic';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = 'description';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pfofficial':
                        state.Supernotes.sheet = 'Pathfinder by Roll20';
                        state.Supernotes.template = 'npc';
                        state.Supernotes.title = 'name';
                        state.Supernotes.theText = 'descflag=1}} {{desc';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'pf2e':
                        state.Supernotes.sheet = 'Pathefinder 2e';
                        state.Supernotes.template = 'rolls';
                        state.Supernotes.title = 'header';
                        state.Supernotes.theText = 'notes_show=[[1]]}} {{notes';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'starfinder':
                        state.Supernotes.sheet = 'Starfinder';
                        state.Supernotes.template = 'sf_generic';
                        state.Supernotes.title = 'title';
                        state.Supernotes.theText = 'buttons0';
                        sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet);
                        break;
                    case 'sendtoPlayers':
                        if (state.Supernotes.sendToPlayers) {
                            state.Supernotes.sendToPlayers = false
                        } else {
                            state.Supernotes.sendToPlayers = true
                        };
                        sendChat('Supernotes', '/w gm Send to Players set to ' + state.Supernotes.sendToPlayers);
                        break;
                }
            } else {
                if (option !== undefined && option.includes('help')) {
                    message = 'Supernotes pulls the contents from a token's GM Notes field. If the token represents a character, you can optionally pull in the Bio or GM notes from the character, as well as the avatar, or extract just the image from the bio field. The user can decide whether to whisper the notes to the GM or broadcast them to all players. Finally, there is the option to add a footer to notes whispered to the GM. This footer creates a chat button to give the option of sending the notes on to the players.
This script as written is optimized for the D&D 5th Edition by Roll20 sheet, but can be adapted easily suing the Configuration section below.

Commands:
!gmnote whispers the note to the GM
!pcnote sends the note to all players

Paramaters

--token Pulls notes from the selected token's gm notes field. This is optional. If it is missing, the script assumes --token

--charnote Pulls notes from the gm notes field of the character assigned to a token.

--bio Pulls notes from the bio field of the character assigned to a token.

--avatar Pulls the image from the avatar field of the character assigned to a token.

--image Pulls first image from the bio field of the character assigned to a token, if any exists. Otherwise returns notice that no artwork is available

--help Displays help.

--config Returns a configuration dialog box that allows you to set which sheet's roll template to use, and to toggle the "Send to Players" footer.

Configuration
When first installed, Supernotes is configured for the default roll template. It will display a config dialog box at startup that will allow you to choose a roll template based on your character sheet of choice, as well as the option  to toggle whether you want the "Send to Players" footer button to appear.
You will need to edit the code of the script to create a custom configuration. The pre-installed sheets are:

Default Template
D&D 5th Edition by Roll20
5e Shaped
Pathfinder by Roll20
Pathfinder Community
Pathfinder 2e by Roll20
Starfinder
';
                    sendChat('Supernotes', messagePrefix + '&{template:' + template + '}{{' + title + '=' + 'Supernotes Help' + '}} {{' + theText + '=' + message + '}}');

                } else {

                    if ((option !== 'bio' && option !== 'charnote' && option !== 'avatar' && option !== 'image') || (option === undefined)) {
                        //|| (option === undefined
                        option = 'token';
                    }

                    let playerButton = '';
                    if (sendToPlayers && command === '!gmnote') {
                        playerButton = '\n[Send to Players](!pcnote --' + option + ')';
                    }

                    let regex;
                    if (match && match[1]) {
                        regex = new RegExp(`^${match[1]}`, 'i');
                    }

                    let message = '';
                    let whom = '';

                    if (option === 'avatar') {
                        (msg.selected || [])
                        .map(o => getObj('graphic', o._id))
                            .filter(g => undefined !== g)
                            .map(t => getObj('character', t.get('represents')))
                            .filter(c => undefined !== c)
                            .forEach(c => {
                                message = "";
                                log('avatar = ' + c.get('avatar'));
                                whom = c.get('name');
                                sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');
                            });
                    } else {

                        if (option === 'image') {

                            (msg.selected || [])
                            .map(o => getObj('graphic', o._id))
                                .filter(g => undefined !== g)
                                .map(t => getObj('character', t.get('represents')))
                                .filter(c => undefined !== c)
                                .forEach(c => c.get('bio', (val) => {
                                    if (null !== val && 'null' !== val && val.length > 0) {
                                        if (regex) {
                                            message = _.filter(
                                                decodeUnicode(val).split(/(?:[\n\r]+|
)/),
                                                (l) => regex.test(l.replace(/<[^>]*>/g, ''))
                                            ).join('\r');
                                        } else {
                                            message = decodeUnicode(val);
                                        }
                                        artwork = message.match(/\/g)

                                        if (artwork) {
                                            message = artwork;
                                        } else {
                                            message = 'No artwork exists for this character.';
                                        }

                                        whom = c.get('name');
                                        //Sends the final message
                                        sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                                    }
                                }));
                        } else {

                            if ((option === 'bio') || (option === 'charnote')) {
                                let suboption = (option === 'charnote') ? 'gmnotes' : 'bio';

                                (msg.selected || [])
                                .map(o => getObj('graphic', o._id))
                                    .filter(g => undefined !== g)
                                    .map(t => getObj('character', t.get('represents')))
                                    .filter(c => undefined !== c)
                                    .forEach(c => c.get(suboption, (val) => {
                                        if (null !== val && 'null' !== val && val.length > 0) {
                                            if (regex) {
                                                message = _.filter(
                                                    decodeUnicode(val).split(/(?:[\n\r]+|
)/),
                                                    (l) => regex.test(l.replace(/<[^>]*>/g, ''))
                                                ).join('\r');
                                            } else {
                                                message = decodeUnicode(val);
                                            }
                                            whom = c.get('name');
                                            //Sends the final message
                                            sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                                        }
                                    }));
                            } else {
                                (msg.selected || [])
                                .map(o => getObj('graphic', o._id))
                                    .filter(g => undefined !== g)
                                    .filter((o) => o.get('gmnotes').length > 0)
                                    .forEach(o => {
                                        if (regex) {
                                            message = _.filter(decodeURIComponent(decodeUnicode(o.get('gmnotes'))).split(/(?:[\n\r]+|
)/), (l) => regex.test(l)).join('\r');
                                        } else {
                                            message = decodeURIComponent(decodeUnicode(o.get('gmnotes')));
                                        }
                                        whom = o.get('name');

                                    });
                                //Sends the final message
                                sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + playerButton + '}}');

                            }

                            [
                                `### REPORT###`,
                                `THE MESSAGE =${message}`,
                                `command = ${command}`,
                                `option = ${option}`,
                                `messagePrefix = ${messagePrefix}`,
                                `message =${message}`
                            ].forEach(m => log(m));
                        }
                    }
                }
            }
        }
    });
});
<|endoftext|>


<commit_before>import path from 'path';
import test from 'ava';
import imageminSvgo from './';
import Vinyl from 'vinyl';

test('optimize a SVG', t => {
	t.plan(1);

	const stream = imageminSvgo()();

	stream.on('data', data => {
		t.is(data.contents.toString(), '<svg><style></style></svg>');
	});

	stream.end(new Vinyl({contents: new Buffer('<svg><style> circle {} </style></svg>')}));
});

test('support SVGO options', t => {
	t.plan(1);

	const stream = imageminSvgo({
		plugins: [{
			removeStyleElement: true
		}]
	})();

	stream.on('data', data => {
		t.is(data.contents.toString(), '<svg/>');
	});

	stream.end(new Vinyl({contents: new Buffer('<svg><style>  circle {} </style></svg>')}));
});

test('error on corrupt SVG', t => {
	t.plan(2);

	const stream = imageminSvgo()();

	stream.on('error', err => {
		t.ok(err);
		t.is(err.fileName, path.normalize('/corrupt.svg'));
	});

	stream.end(new Vinyl({
		path: path.normalize('/corrupt.svg'),
		contents: new Buffer('<svg>style><</style></svg>')
	}));
});
<commit_msg>upgrade to latest AVA<commit_after>import path from 'path';
import test from 'ava';
import imageminSvgo from './';
import Vinyl from 'vinyl';

test('optimize a SVG', t => {
	t.plan(1);

	const stream = imageminSvgo()();

	stream.on('data', data => {
		t.is(data.contents.toString(), '<svg><style></style></svg>');
	});

	stream.end(new Vinyl({contents: new Buffer('<svg><style> circle {} </style></svg>')}));
});

test('support SVGO options', t => {
	t.plan(1);

	const stream = imageminSvgo({
		plugins: [{
			removeStyleElement: true
		}]
	})();

	stream.on('data', data => {
		t.is(data.contents.toString(), '<svg/>');
	});

	stream.end(new Vinyl({contents: new Buffer('<svg><style>  circle {} </style></svg>')}));
});

test('error on corrupt SVG', t => {
	t.plan(2);

	const stream = imageminSvgo()();

	stream.on('error', err => {
		t.truthy(err);
		t.is(err.fileName, path.normalize('/corrupt.svg'));
	});

	stream.end(new Vinyl({
		path: path.normalize('/corrupt.svg'),
		contents: new Buffer('<svg>style><</style></svg>')
	}));
});
<|endoftext|>


<commit_before> 'use strict';

app.controller('party/profile', [
  '$scope', 'displayService', 'party', 'pageService','constantService',
  function ($scope, display, party, page, constants) {

    var getUsers = function(volumes){
      var tempUsers = _(volumes).pluck('access').flatten().value();
      var users = {
        sponsors: _.filter(tempUsers, function(u){
          //placeholder value.
          return u.party.institution === true;
        }),
        labGroupMembers: _.filter(tempUsers, function(u){
          //placeholder value
          return u.party.permission === 3;
        }),

        nonGroupAffiliates: _.filter(tempUsers, function(u){
          // placeholder value
          return u.party.permission === 3;
        }),

        dataOwnerVolumes: _.filter(tempUsers, function(u){
          // placeholder value
          return u.party.permission === 5;
        }),

      };

      return users;
    };

    $scope.clickVolume = function(volume) {
      $scope.volumes = _.map($scope.volumes, function(v){
        v.isSelected = '';
        return v;
      });

      for(var i = 0; i < $scope.users.sponsors.length; i += 1){
        $scope.users.sponsors[i].isSelected = '';
        for(var j = 0; j < volume.access.length; j += 1){
          if($scope.users.sponsors[i].id === volume.access[j].party.id){
            $scope.users.sponsors[i].isSelected = 'userSelected';
          }
        }
      }
    };

    // This should take in a user, then select volumes on each thing.
    $scope.clickUser = function(user){
      for(var i = 0; i < $scope.volumes.length; i += 1) {
        $scope.volumes[i].isSelected = '';
        for(var j = 0; j < $scope.volumes[i].access.length; j += 1){
          if($scope.volumes[i].access[j].id == user.party.id){
            $scope.volumes[i].isSelected = 'volumeSelected';
          }
        }
      }
    };

    $scope.party = party;
    $scope.volumes = party.volumes;
    $scope.users = getUsers($scope.volumes);
    console.log($scope.users);
    $scope.page = page;
    $scope.profile = page.$location.path() === '/profile';
    display.title = party.name;
  }
]);
<commit_msg>Add basic filtering for users.<commit_after> 'use strict';

app.controller('party/profile', [
  '$scope', 'displayService', 'party', 'pageService','constantService',
  function ($scope, display, party, page, constants) {

    var getUsers = function(volumes){

      var users = {};

      users.sponsors = [];
      users.labGroupMembers = [];
      users.nonGroupAffiliates = [];
      users.otherCollaborators = [];

      _(volumes).pluck('access').flatten().each(function(v){
        if(v.children > 0 ){
          users.sponsors.push(v);
        } else if(v.parents && v.parents.length > 0 && v.party.members && v.party.members.length > 0) {
          users.labGroupMembers.push(v);
        } else if(v.parents && v.parents.length > 0){
         users.nonGroupAffiliates.push(v);
        } else {
          users.otherCollaborators.push(v);
        }

      }).value();

      return users;
    };

    $scope.clickVolume = function(volume) {
      $scope.volumes = _.map($scope.volumes, function(v){
        v.isSelected = '';
        return v;
      });

      for(var i = 0; i < $scope.users.sponsors.length; i += 1){
        $scope.users.sponsors[i].isSelected = '';
        for(var j = 0; j < volume.access.length; j += 1){
          if($scope.users.sponsors[i].id === volume.access[j].party.id){
            $scope.users.sponsors[i].isSelected = 'userSelected';
          }
        }
      }
    };

    // This should take in a user, then select volumes on each thing.
    $scope.clickUser = function(user){
      for(var i = 0; i < $scope.volumes.length; i += 1) {
        $scope.volumes[i].isSelected = '';
        for(var j = 0; j < $scope.volumes[i].access.length; j += 1){
          if($scope.volumes[i].access[j].id == user.party.id){
            $scope.volumes[i].isSelected = 'volumeSelected';
          }
        }
      }
    };

    var getVolumes = function(v) {

      return v;
    };

    $scope.party = party;
    $scope.volumes = party.volumes;
    $scope.users = getUsers($scope.volumes);
    console.log($scope.users);
    $scope.page = page;
    $scope.profile = page.$location.path() === '/profile';
    display.title = party.name;
  }
]);
<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var sv2bts = require('./').sv2bts;

test('sv2bts', function(t) {
  t.equal(sv2bts('Z'), 'iii');
  t.equal(sv2bts('Z0'), 'iii000');
  t.equal(sv2bts('ZA'), 'iii001');
  t.equal(sv2bts('MI'), '111100');

  t.end();
});
<commit_msg>Add tests for limits of 5-trit trytes (QZ to DM)<commit_after>'use strict';

var test = require('tape');
var sv2bts = require('./').sv2bts;

test('sv2bts', function(t) {
  t.equal(sv2bts('Z'), 'iii');
  t.equal(sv2bts('Z0'), 'iii000');
  t.equal(sv2bts('ZA'), 'iii001');
  t.equal(sv2bts('MI'), '111100');
  t.end();
});

test('5-trit limits', function(t) {
  t.equal(sv2bts('QZ'), '0iiiii'); // might remove leading zeros here?
  t.equal(sv2bts('DM'), '011111');
  t.end();
});
<|endoftext|>