<commit_before>'use strict';

var ohm = require('..');
var pexprs = require('../src/pexprs');
var test = require('tape');

require('../src/pexprs-toArgumentNameList');

var makeGrammar = require('./testUtil').makeGrammar;

// --------------------------------------------------------------------
// Tests
// --------------------------------------------------------------------

test('definitionInterval', function(t) {
  var g = makeGrammar([
    'G {',
    '  foo = bar',
    '  bar = "a" | "b" -- baz',
    '}'
  ]);

  function definitionLoc(grammar, ruleName) {
    var interval = grammar.ruleBodies[ruleName].definitionInterval;
    return [interval.startIdx, interval.endIdx];
  }
  t.deepEqual(definitionLoc(g, 'foo'), [6, 15], 'regular rule');
  t.deepEqual(definitionLoc(g, 'bar'), [18, 40]);
  t.deepEqual(definitionLoc(g, 'bar_baz'), [30, 40], 'inline rule');

  var g2 = makeGrammar([
    'G2 <: G {',
    '  foo += bar',
    '  bar := "a" | "b" -- baz',
    '}'
  ], {G: g});
  t.deepEqual(definitionLoc(g2, 'foo'), [12, 22], 'extended rule');
  t.deepEqual(definitionLoc(g2, 'bar'), [25, 48], 'overridden rule');
  t.deepEqual(definitionLoc(g2, 'bar_baz'), [38, 48], 'inline rule in overridden rule');

  t.end();
});

test('rule invocation interval', function(t) {
  var g = makeGrammar([
    'G {',
    '  foo = bar',
    '  beep = letter bar',
    '  bar = "a" | "blah" | "a".."z" -- baz',
    '}'
  ]);

  function fromLoc(pexpr) {
    return [pexpr.interval.startIdx, pexpr.interval.endIdx];
  }
  var fooBody = g.ruleBodies.foo;
  var beepBody = g.ruleBodies.beep;
  var barBody = g.ruleBodies.bar;
  t.deepEqual(fromLoc(fooBody), [12, 15], 'regular rule application');
  t.deepEqual(fromLoc(beepBody.factors[1]), [32, 35]);

  t.deepEqual(fromLoc(beepBody.factors[0]), [25, 31], 'built-in rule application');
  t.deepEqual(fromLoc(barBody.terms[0]), [44, 47], 'primitive (string)');
  t.deepEqual(fromLoc(barBody.terms[1]), [50, 56], 'another string');

  var barBazBody = g.ruleBodies.bar_baz;
  t.deepEqual(fromLoc(barBazBody), [59, 67], 'primitive (range)');
  t.deepEqual(fromLoc(beepBody), [25, 35], 'works for seq');
  t.deepEqual(fromLoc(barBody), [44, 74], 'works for alt');
  t.end();
});

test('toDisplayString', function(t) {
  var g = ohm.grammar('G { start = "ab" | letter* | "a".."z" }');
  var seq = g.ruleBodies.start;
  t.equal(seq.toDisplayString(), '"ab" | letter* | "a".."z"');
  t.equal(seq.terms[0].toDisplayString(), '"ab"');

  var many = seq.terms[1];
  t.equal(many.toDisplayString(), 'letter*');
  t.equal(many.expr.toDisplayString(), 'letter');

  t.equal(seq.terms[2].toDisplayString(), '"a".."z"');

  t.end();
});

test('toString', function(t) {
  var g = makeGrammar([
    'G {',
    '  start = ~(2 | 3?) $(&"a" b #a) [c {e: $b, ...} {g: $("a".."z")}]',
    '  a = "a"',
    '  b = "b"',
    '  c = 3',
    '}'
    ]);
  var e = g.ruleBodies.start;
  t.equal(e.toString(), '(~(2 | 3?) $((&"a" b #(a))) [(c {"e": $(b), ...} {"g": $("a".."z")})])');
  t.end();
});

test.only('toArgumentNameList', function(t) {
  var g =  makeGrammar([
    'G {',
    ' Start = &((foo bars foo)+)',
    ' foo = "ab" | letter* | "a".."z"',
    ' bars = ~"a" (letter "b"| digit "b") foo? "+"',
    ' plus = foo "+" bars',
    ' MoreOpts = ("+" Start)?',
    ' }'
    ]);

  var iter = g.ruleBodies.Start;
  t.deepEqual(iter.toArgumentNameList(1), ['foo_1s', 'barses', 'foo_2s']);

  var alt = g.ruleBodies.foo;
  t.deepEqual(alt.toArgumentNameList(1), ['_ab_or_letters_or_a_to_z']);
  t.deepEqual(alt.terms[0].toArgumentNameList(1), ['_ab']);

  var many = alt.terms[1];
  t.deepEqual(many.toArgumentNameList(1), ['letters']);
  t.deepEqual(many.expr.toArgumentNameList(1), ['letter']);

  var range = alt.terms[2];
  t.deepEqual(range.toArgumentNameList(1), ['a_to_z']);

  var seq = g.ruleBodies.bars;
  t.deepEqual(seq.toArgumentNameList(1), ['letter_or_digit', '_b', 'optFoo', '$4']);
  t.deepEqual(seq.factors[2].toArgumentNameList(1), ['optFoo']);
  t.deepEqual(seq.factors[3].toArgumentNameList(1), ['$1']);

  var plus = g.ruleBodies.plus;
  t.deepEqual(plus.toArgumentNameList(1), ['foo', '$2', 'bars']);

  var opts = g.ruleBodies.MoreOpts;
  t.deepEqual(opts.toArgumentNameList(1), ['opt$1', 'optStart']);

  t.end();
});

test('getExprType', function(t) {
  var g = makeGrammar([
    'G {',
    '  str = listOf<alnum*, ",">',
    '  Str2 = Maybe<"ab">',
    '  Str3 = MaybeTwice<"ab">',
    '  Val = ListOf<String, null>',
    '  Val2 = Maybe<Boolean>',
    '  Val3 = MaybeTwice<Number>',
    '  Maybe<x> = x  -- some',
    '           |    -- none',
    '  MaybeTwice<exp> = Maybe<exp> Maybe<exp>',
    '  nothing = ',
    '  nil = null',
    '  leftRecStr = leftRecStr | str',
    '  leftRecVal = leftRecVal | 3',
    '  leftRecAny = leftRecAny | nothing',
    '}'
  ]);
  function getExprType(ruleName) {
    return g.ruleBodies[ruleName].getExprType(g);
  }
  t.equal(getExprType('str'), pexprs.TYPE_STRING);
  t.equal(getExprType('Str2'), pexprs.TYPE_STRING);
  t.equal(getExprType('Str3'), pexprs.TYPE_STRING);
  t.equal(getExprType('leftRecStr'), pexprs.TYPE_STRING);

  t.equal(getExprType('Val'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Val2'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Val3'), pexprs.TYPE_VALUE);
  t.equal(getExprType('leftRecVal'), pexprs.TYPE_VALUE);

  t.equal(getExprType('nothing'), pexprs.TYPE_ANY);
  t.equal(getExprType('end'), pexprs.TYPE_ANY);
  t.equal(getExprType('any'), pexprs.TYPE_STRING);
  t.equal(getExprType('leftRecAny'), pexprs.TYPE_ANY);

  t.equal(getExprType('String'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Number'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Boolean'), pexprs.TYPE_VALUE);

  t.equal(getExprType('letter'), pexprs.TYPE_STRING, 'letter');
  t.equal(getExprType('nil'), pexprs.TYPE_VALUE, 'null');

  t.throws(function() { ohm.grammar('G2 <: G { x = "a" null }', {G: g}); });
  t.throws(function() { ohm.grammar('G2 <: G { x = Str2 Val2 }', {G: g}); });

  t.end();
});
<commit_msg>Remove `test.only` on toArgumentNameList test.<commit_after>'use strict';

var ohm = require('..');
var pexprs = require('../src/pexprs');
var test = require('tape');

require('../src/pexprs-toArgumentNameList');

var makeGrammar = require('./testUtil').makeGrammar;

// --------------------------------------------------------------------
// Tests
// --------------------------------------------------------------------

test('definitionInterval', function(t) {
  var g = makeGrammar([
    'G {',
    '  foo = bar',
    '  bar = "a" | "b" -- baz',
    '}'
  ]);

  function definitionLoc(grammar, ruleName) {
    var interval = grammar.ruleBodies[ruleName].definitionInterval;
    return [interval.startIdx, interval.endIdx];
  }
  t.deepEqual(definitionLoc(g, 'foo'), [6, 15], 'regular rule');
  t.deepEqual(definitionLoc(g, 'bar'), [18, 40]);
  t.deepEqual(definitionLoc(g, 'bar_baz'), [30, 40], 'inline rule');

  var g2 = makeGrammar([
    'G2 <: G {',
    '  foo += bar',
    '  bar := "a" | "b" -- baz',
    '}'
  ], {G: g});
  t.deepEqual(definitionLoc(g2, 'foo'), [12, 22], 'extended rule');
  t.deepEqual(definitionLoc(g2, 'bar'), [25, 48], 'overridden rule');
  t.deepEqual(definitionLoc(g2, 'bar_baz'), [38, 48], 'inline rule in overridden rule');

  t.end();
});

test('rule invocation interval', function(t) {
  var g = makeGrammar([
    'G {',
    '  foo = bar',
    '  beep = letter bar',
    '  bar = "a" | "blah" | "a".."z" -- baz',
    '}'
  ]);

  function fromLoc(pexpr) {
    return [pexpr.interval.startIdx, pexpr.interval.endIdx];
  }
  var fooBody = g.ruleBodies.foo;
  var beepBody = g.ruleBodies.beep;
  var barBody = g.ruleBodies.bar;
  t.deepEqual(fromLoc(fooBody), [12, 15], 'regular rule application');
  t.deepEqual(fromLoc(beepBody.factors[1]), [32, 35]);

  t.deepEqual(fromLoc(beepBody.factors[0]), [25, 31], 'built-in rule application');
  t.deepEqual(fromLoc(barBody.terms[0]), [44, 47], 'primitive (string)');
  t.deepEqual(fromLoc(barBody.terms[1]), [50, 56], 'another string');

  var barBazBody = g.ruleBodies.bar_baz;
  t.deepEqual(fromLoc(barBazBody), [59, 67], 'primitive (range)');
  t.deepEqual(fromLoc(beepBody), [25, 35], 'works for seq');
  t.deepEqual(fromLoc(barBody), [44, 74], 'works for alt');
  t.end();
});

test('toDisplayString', function(t) {
  var g = ohm.grammar('G { start = "ab" | letter* | "a".."z" }');
  var seq = g.ruleBodies.start;
  t.equal(seq.toDisplayString(), '"ab" | letter* | "a".."z"');
  t.equal(seq.terms[0].toDisplayString(), '"ab"');

  var many = seq.terms[1];
  t.equal(many.toDisplayString(), 'letter*');
  t.equal(many.expr.toDisplayString(), 'letter');

  t.equal(seq.terms[2].toDisplayString(), '"a".."z"');

  t.end();
});

test('toString', function(t) {
  var g = makeGrammar([
    'G {',
    '  start = ~(2 | 3?) $(&"a" b #a) [c {e: $b, ...} {g: $("a".."z")}]',
    '  a = "a"',
    '  b = "b"',
    '  c = 3',
    '}'
    ]);
  var e = g.ruleBodies.start;
  t.equal(e.toString(), '(~(2 | 3?) $((&"a" b #(a))) [(c {"e": $(b), ...} {"g": $("a".."z")})])');
  t.end();
});

test('toArgumentNameList', function(t) {
  var g =  makeGrammar([
    'G {',
    ' Start = &((foo bars foo)+)',
    ' foo = "ab" | letter* | "a".."z"',
    ' bars = ~"a" (letter "b"| digit "b") foo? "+"',
    ' plus = foo "+" bars',
    ' MoreOpts = ("+" Start)?',
    ' }'
    ]);

  var iter = g.ruleBodies.Start;
  t.deepEqual(iter.toArgumentNameList(1), ['foo_1s', 'barses', 'foo_2s']);

  var alt = g.ruleBodies.foo;
  t.deepEqual(alt.toArgumentNameList(1), ['_ab_or_letters_or_a_to_z']);
  t.deepEqual(alt.terms[0].toArgumentNameList(1), ['_ab']);

  var many = alt.terms[1];
  t.deepEqual(many.toArgumentNameList(1), ['letters']);
  t.deepEqual(many.expr.toArgumentNameList(1), ['letter']);

  var range = alt.terms[2];
  t.deepEqual(range.toArgumentNameList(1), ['a_to_z']);

  var seq = g.ruleBodies.bars;
  t.deepEqual(seq.toArgumentNameList(1), ['letter_or_digit', '_b', 'optFoo', '$4']);
  t.deepEqual(seq.factors[2].toArgumentNameList(1), ['optFoo']);
  t.deepEqual(seq.factors[3].toArgumentNameList(1), ['$1']);

  var plus = g.ruleBodies.plus;
  t.deepEqual(plus.toArgumentNameList(1), ['foo', '$2', 'bars']);

  var opts = g.ruleBodies.MoreOpts;
  t.deepEqual(opts.toArgumentNameList(1), ['opt$1', 'optStart']);

  t.end();
});

test('getExprType', function(t) {
  var g = makeGrammar([
    'G {',
    '  str = listOf<alnum*, ",">',
    '  Str2 = Maybe<"ab">',
    '  Str3 = MaybeTwice<"ab">',
    '  Val = ListOf<String, null>',
    '  Val2 = Maybe<Boolean>',
    '  Val3 = MaybeTwice<Number>',
    '  Maybe<x> = x  -- some',
    '           |    -- none',
    '  MaybeTwice<exp> = Maybe<exp> Maybe<exp>',
    '  nothing = ',
    '  nil = null',
    '  leftRecStr = leftRecStr | str',
    '  leftRecVal = leftRecVal | 3',
    '  leftRecAny = leftRecAny | nothing',
    '}'
  ]);
  function getExprType(ruleName) {
    return g.ruleBodies[ruleName].getExprType(g);
  }
  t.equal(getExprType('str'), pexprs.TYPE_STRING);
  t.equal(getExprType('Str2'), pexprs.TYPE_STRING);
  t.equal(getExprType('Str3'), pexprs.TYPE_STRING);
  t.equal(getExprType('leftRecStr'), pexprs.TYPE_STRING);

  t.equal(getExprType('Val'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Val2'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Val3'), pexprs.TYPE_VALUE);
  t.equal(getExprType('leftRecVal'), pexprs.TYPE_VALUE);

  t.equal(getExprType('nothing'), pexprs.TYPE_ANY);
  t.equal(getExprType('end'), pexprs.TYPE_ANY);
  t.equal(getExprType('any'), pexprs.TYPE_STRING);
  t.equal(getExprType('leftRecAny'), pexprs.TYPE_ANY);

  t.equal(getExprType('String'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Number'), pexprs.TYPE_VALUE);
  t.equal(getExprType('Boolean'), pexprs.TYPE_VALUE);

  t.equal(getExprType('letter'), pexprs.TYPE_STRING, 'letter');
  t.equal(getExprType('nil'), pexprs.TYPE_VALUE, 'null');

  t.throws(function() { ohm.grammar('G2 <: G { x = "a" null }', {G: g}); });
  t.throws(function() { ohm.grammar('G2 <: G { x = Str2 Val2 }', {G: g}); });

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


<commit_before>/* jshint -W097 */// jshint strict:false
/*jslint node: true */
var expect = require('chai').expect;
var setup  = require(__dirname + '/lib/setup');

var objects = null;
var states  = null;
var onStateChanged = null;
var onObjectChanged = null;
var sendToID = 1;

var adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.')+1);

function checkConnectionOfAdapter(cb, counter) {
    counter = counter || 0;
    console.log('Try check #' + counter);
    if (counter > 30) {
        if (cb) cb('Cannot check connection');
        return;
    }

    states.getState('system.adapter.' + adapterShortName + '.0.alive', function (err, state) {
        if (err) console.error(err);
        if (state && state.val) {
            if (cb) cb();
        } else {
            setTimeout(function () {
                checkConnectionOfAdapter(cb, counter + 1);
            }, 1000);
        }
    });
}

function checkValueOfState(id, value, cb, counter) {
    counter = counter || 0;
    if (counter > 20) {
        if (cb) cb('Cannot check value Of State ' + id);
        return;
    }

    states.getState(id, function (err, state) {
        if (err) console.error(err);
        if (value === null && !state) {
            if (cb) cb();
        } else
        if (state && (value === undefined || state.val === value)) {
            if (cb) cb();
        } else {
            setTimeout(function () {
                checkValueOfState(id, value, cb, counter + 1);
            }, 500);
        }
    });
}

function sendTo(target, command, message, callback) {
    onStateChanged = function (id, state) {
        if (id === 'messagebox.system.adapter.test.0') {
            callback(state.message);
        }
    };

    states.pushMessage('system.adapter.' + target, {
        command:    command,
        message:    message,
        from:       'system.adapter.test.0',
        callback: {
            message: message,
            id:      sendToID++,
            ack:     false,
            time:    (new Date()).getTime()
        }
    });
}

describe('Test ' + adapterShortName + ' adapter', function() {
    before('Test ' + adapterShortName + ' adapter: Start js-controller', function (_done) {
        this.timeout(600000); // because of first install from npm

        setup.setupController(function () {
            var config = setup.getAdapterConfig();
            // enable adapter
            config.common.enabled  = true;
            config.common.loglevel = 'debug';

            //config.native.serialport = '/dev/ttyS';

            config.native.sensors = [
                {
                    "sid": "18",
                    "usid": "1",
                    "stype": "emonTH",
                    "name": "example emonTH"
                },
                {
                    "sid": "0",
                    "usid": "2",
                    "stype": "LaCrosseBMP180",
                    "name": "example superjee"
                },
                {
                    "sid": "56",
                    "usid": "3",
                    "stype": "LaCrosseDTH",
                    "name": "example LaCrosseDTH"
                },
                {
                    "sid": "22",
                    "usid": "4",
                    "stype": "LaCrosseDTH",
                    "name": "example LaCrosseDTH"
                },
                {
                    "sid": "60",
                    "usid": "5",
                    "stype": "LaCrosseWS",
                    "name": "example LaCrosseWS"
                },
                {
                    "sid": "188",
                    "usid": "6",
                    "stype": "EC3000",
                    "name": "example EC3000"
                },
                {
                    "sid": "5451",
                    "usid": "7",
                    "stype": "EMT7110",
                    "name": "example EMT7110"
                },
                {
                    "sid": "1",
                    "usid": "8",
                    "stype": "level",
                    "name": "example level"
                }
    ]

            setup.setAdapterConfig(config.common, config.native);

            setup.startController(true, function(id, obj) {}, function (id, state) {
                    if (onStateChanged) onStateChanged(id, state);
                },
                function (_objects, _states) {
                    objects = _objects;
                    states  = _states;
                    _done();
                });
        });
    });

/*
    ENABLE THIS WHEN ADAPTER RUNS IN DEAMON MODE TO CHECK THAT IT HAS STARTED SUCCESSFULLY
*/
    it('Test ' + adapterShortName + ' adapter: Check if adapter started', function (done) {
        this.timeout(60000);
        checkConnectionOfAdapter(function (res) {
            if (res) console.log(res);
            expect(res).not.to.be.equal('Cannot check connection');
            objects.setObject('system.adapter.test.0', {
                    common: {

                    },
                    type: 'instance'
                },
                function () {
                    states.subscribeMessage('system.adapter.test.0');
                    done();
                });
        });
    });
/**/

/*
    PUT YOUR OWN TESTS HERE USING
    it('Testname', function ( done) {
        ...
    });

    You can also use "sendTo" method to send messages to the started adapter
*/
    it('Test ' + adapterShortName + ' adapter: Objects must exist for avg', done => {
        setTimeout(function(){
            objects.getObject(adapterShortName + '.0.LaCrosse_4.temp', (err, obj) => {
                if (err) console.error('avg dayMin '+err);
                expect(obj).to.exist;
                expect(obj).to.be.ok;
                    objects.getObject(adapterShortName + '.0.LaCrosse_4.humid', (err, obj) => {
                        if (err) console.error('avg dayMax ' + err);
                        expect(obj).to.exist;
                        expect(obj).to.be.ok;
                        done();
                    });
                    });
                }, 1000);
        }).timeout(5000);

   it('Test ' + adapterShortName + ' adapter: Check existence of LaCrosseDTH', function (done) {
        this.timeout(90000);
        setTimeout(function () {
            states.getState(adapterShortName+'.0.LaCrosse_4.temp', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "jeelink.0.LaCrosse_4.temp" not set');
                }
                else {
                    console.log('jeelink.0.LaCrosse_4.temp          ... ' + state.val);
                    expect(state.val).to.exist;
                    //expect(state.val).to.be.equal(17.5);
                    done();
                }
            });
        }, 70000);
    });
    it('Test ' + adapterShortName + ' adapter: Check existence of LaCrosseDMP180', function (done) {
        this.timeout(90000);
        setTimeout(function () {
            states.getState(adapterShortName+'.0.LaCrosse_2.temp', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "jeelink.0.LaCrosse_2.temp" not set');
                }
                else {
                    console.log('jeelink.0.LaCrosse_2.temp          ... ' + state.val);
                    expect(state.val).to.exist;
                    //expect(state.val).to.be.equal(17.5);
                    done();
                }
            });
        }, 70000);
    });

    after('Test ' + adapterShortName + ' adapter: Stop js-controller', function (done) {
        this.timeout(10000);

        setup.stopController(function (normalTerminated) {
            console.log('Adapter normal terminated: ' + normalTerminated);
            done();
        });
    });
});
<commit_msg>Update testAdapter.js<commit_after>/* jshint -W097 */// jshint strict:false
/*jslint node: true */
var expect = require('chai').expect;
var setup  = require(__dirname + '/lib/setup');

const EventEmitter = require('events')
const proxyquire = require('proxyquire')

// create reader with serialport stub
const SerialPort = proxyquire('../jeelink.js', { 'serialport': EventEmitter })

var objects = null;
var states  = null;
var onStateChanged = null;
var onObjectChanged = null;
var sendToID = 1;

var adapterShortName = setup.adapterName.substring(setup.adapterName.indexOf('.')+1);

function checkConnectionOfAdapter(cb, counter) {
    counter = counter || 0;
    console.log('Try check #' + counter);
    if (counter > 30) {
        if (cb) cb('Cannot check connection');
        return;
    }

    states.getState('system.adapter.' + adapterShortName + '.0.alive', function (err, state) {
        if (err) console.error(err);
        if (state && state.val) {
            if (cb) cb();
        } else {
            setTimeout(function () {
                checkConnectionOfAdapter(cb, counter + 1);
            }, 1000);
        }
    });
}

function checkValueOfState(id, value, cb, counter) {
    counter = counter || 0;
    if (counter > 20) {
        if (cb) cb('Cannot check value Of State ' + id);
        return;
    }

    states.getState(id, function (err, state) {
        if (err) console.error(err);
        if (value === null && !state) {
            if (cb) cb();
        } else
        if (state && (value === undefined || state.val === value)) {
            if (cb) cb();
        } else {
            setTimeout(function () {
                checkValueOfState(id, value, cb, counter + 1);
            }, 500);
        }
    });
}

function sendTo(target, command, message, callback) {
    onStateChanged = function (id, state) {
        if (id === 'messagebox.system.adapter.test.0') {
            callback(state.message);
        }
    };

    states.pushMessage('system.adapter.' + target, {
        command:    command,
        message:    message,
        from:       'system.adapter.test.0',
        callback: {
            message: message,
            id:      sendToID++,
            ack:     false,
            time:    (new Date()).getTime()
        }
    });
}

describe('Test ' + adapterShortName + ' adapter', function() {
    before('Test ' + adapterShortName + ' adapter: Start js-controller', function (_done) {
        this.timeout(600000); // because of first install from npm

        setup.setupController(function () {
            var config = setup.getAdapterConfig();
            // enable adapter
            config.common.enabled  = true;
            config.common.loglevel = 'debug';

            //config.native.serialport = '/dev/ttyS';

            config.native.sensors = [
                {
                    "sid": "18",
                    "usid": "1",
                    "stype": "emonTH",
                    "name": "example emonTH"
                },
                {
                    "sid": "0",
                    "usid": "2",
                    "stype": "LaCrosseBMP180",
                    "name": "example superjee"
                },
                {
                    "sid": "56",
                    "usid": "3",
                    "stype": "LaCrosseDTH",
                    "name": "example LaCrosseDTH"
                },
                {
                    "sid": "22",
                    "usid": "4",
                    "stype": "LaCrosseDTH",
                    "name": "example LaCrosseDTH"
                },
                {
                    "sid": "60",
                    "usid": "5",
                    "stype": "LaCrosseWS",
                    "name": "example LaCrosseWS"
                },
                {
                    "sid": "188",
                    "usid": "6",
                    "stype": "EC3000",
                    "name": "example EC3000"
                },
                {
                    "sid": "5451",
                    "usid": "7",
                    "stype": "EMT7110",
                    "name": "example EMT7110"
                },
                {
                    "sid": "1",
                    "usid": "8",
                    "stype": "level",
                    "name": "example level"
                }
    ]

            setup.setAdapterConfig(config.common, config.native);

            setup.startController(true, function(id, obj) {}, function (id, state) {
                    if (onStateChanged) onStateChanged(id, state);
                },
                function (_objects, _states) {
                    objects = _objects;
                    states  = _states;
                    _done();
                });
        });
    });

/*
    ENABLE THIS WHEN ADAPTER RUNS IN DEAMON MODE TO CHECK THAT IT HAS STARTED SUCCESSFULLY
*/
    it('Test ' + adapterShortName + ' adapter: Check if adapter started', function (done) {
        this.timeout(60000);
        checkConnectionOfAdapter(function (res) {
            if (res) console.log(res);
            expect(res).not.to.be.equal('Cannot check connection');
            objects.setObject('system.adapter.test.0', {
                    common: {

                    },
                    type: 'instance'
                },
                function () {
                    states.subscribeMessage('system.adapter.test.0');
                    done();
                });
        });
    });
/**/

/*
    PUT YOUR OWN TESTS HERE USING
    it('Testname', function ( done) {
        ...
    });

    You can also use "sendTo" method to send messages to the started adapter
*/
    it('Test ' + adapterShortName + ' adapter: Objects must exist for avg', done => {
        setTimeout(function(){
            objects.getObject(adapterShortName + '.0.LaCrosse_4.temp', (err, obj) => {
                if (err) console.error('avg dayMin '+err);
                expect(obj).to.exist;
                expect(obj).to.be.ok;
                    objects.getObject(adapterShortName + '.0.LaCrosse_4.humid', (err, obj) => {
                        if (err) console.error('avg dayMax ' + err);
                        expect(obj).to.exist;
                        expect(obj).to.be.ok;
                        done();
                    });
                    });
                }, 1000);
        }).timeout(5000);

   it('Test ' + adapterShortName + ' adapter: Check existence of LaCrosseDTH', function (done) {
        this.timeout(90000);
        setTimeout(function () {
            states.getState(adapterShortName+'.0.LaCrosse_4.temp', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "jeelink.0.LaCrosse_4.temp" not set');
                }
                else {
                    console.log('jeelink.0.LaCrosse_4.temp          ... ' + state.val);
                    expect(state.val).to.exist;
                    //expect(state.val).to.be.equal(17.5);
                    done();
                }
            });
        }, 70000);
    });
    it('Test ' + adapterShortName + ' adapter: Check existence of LaCrosseDMP180', function (done) {
        this.timeout(90000);
        setTimeout(function () {
            states.getState(adapterShortName+'.0.LaCrosse_2.temp', function (err, state) {
                if (err) console.error(err);
                expect(state).to.exist;
                if (!state) {
                    console.error('state "jeelink.0.LaCrosse_2.temp" not set');
                }
                else {
                    console.log('jeelink.0.LaCrosse_2.temp          ... ' + state.val);
                    expect(state.val).to.exist;
                    //expect(state.val).to.be.equal(17.5);
                    done();
                }
            });
        }, 70000);
    });

    after('Test ' + adapterShortName + ' adapter: Stop js-controller', function (done) {
        this.timeout(10000);

        setup.stopController(function (normalTerminated) {
            console.log('Adapter normal terminated: ' + normalTerminated);
            done();
        });
    });
});
<|endoftext|>


<commit_before>var promisify = require('promisify-node');
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var temp = require('temp').track();
var ghslug = promisify(require('github-slug'));
var rewire = require('rewire');
var offline = rewire('../lib/offline');

function checkWrite(expected, unexpected, end) {
  return new Promise(function(resolve, reject) {
    var nextExpected = expected.shift();
    var nextUnexpected = unexpected.shift();

    var output = '';
    write = process.stdout.write;
    process.stdout.write = function(chunk, encoding, fd) {
      write.apply(process.stdout, arguments);
      output += chunk;

      if (nextExpected && output.indexOf(nextExpected) !== -1) {
        nextExpected = expected.shift();
      }

      if (nextUnexpected && output.indexOf(nextUnexpected) !== -1) {
        process.stdout.write = write;
        reject(new Error('Unexpected warning (' + nextUnexpected + ') has been printed'));
        return;
      }

      if (output.indexOf(end) !== -1) {
        process.stdout.write = write;
        if (!nextExpected) {
          resolve();
        } else {
          reject(new Error('Expected warning (' + nextExpected + ') hasn\'t been printed'));
        }
      }
    };
  });
}

describe('Offline', function() {
  var oldWd = process.cwd();

  afterEach(function() {
    process.chdir(oldWd);
    offline.__set__('ghslug', ghslug);
  });

  it('should create offline-worker.js in the destination directory', function() {
    var dir = temp.mkdirSync('oghliner');

    return offline({
      rootDir: dir,
    }).then(function() {
      assert.doesNotThrow(fs.accessSync.bind(fs, path.join(dir, 'offline-worker.js')));
    });
  });

  it('should not fail if the destination directory already contains a offline-worker.js file', function() {
    var dir = temp.mkdirSync('oghliner');

    fs.writeFileSync(path.join(dir, 'offline-worker.js'), 'something');

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content, 'something');
    });
  });

  it('should use importScript in the service worker if the importScripts option is defined', function() {
    var dir = temp.mkdirSync('oghliner');

    return offline({
      rootDir: dir,
      importScripts: [ 'a-script.js', ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('importScripts("a-script.js");'), -1);
    });
  });

  it('should use the GitHub slug as the cache ID if it is available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    offline.__set__('ghslug', function(path) {
      return new Promise(function(resolve, reject) {
        resolve('mozilla/oghliner');
      });
    });

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('mozilla/oghliner'), -1);
    });
  });

  it('should use the app name from package.json as the cache ID if the GitHub slug is not available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(rootDir, 'package.json'), JSON.stringify({
      name: 'test_name',
    }));

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_name'), -1);
    });
  });

  it('should not fail if both the GitHub slug and package.json are not available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      assert.doesNotThrow(fs.accessSync.bind(fs, path.join(dir, 'offline-worker.js')));
    });
  });

  it('should cache files in rootDir', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should not cache files in rootDir that do not match fileGlobs', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
      fileGlobs: [
        'test_file_1.js',
        'test_file_3.js',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.equal(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should cache files in a subdirectory of rootDir', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);
    var subDir = path.join(dir, 'subdir');
    fs.mkdirSync(subDir);

    fs.writeFileSync(path.join(subDir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(subDir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(subDir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should cache large files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_1.js is bigger than 2 MiB',
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });

  it('should not cache excluded files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [
      'test_file_1.js is bigger than 2 MiB',
    ], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
      fileGlobs: [
        '!(test_file_1.js)',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.equal(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });

  it('should not warn about explicitly included files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [
      'test_file_1.js is bigger than 2 MiB',
    ], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
      fileGlobs: [
        '*',
        'test_file_1.js',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });
});
<commit_msg>Test importScripts with an entry that isn't a file and with an entry that doesn't exist<commit_after>var promisify = require('promisify-node');
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var temp = require('temp').track();
var ghslug = promisify(require('github-slug'));
var rewire = require('rewire');
var offline = rewire('../lib/offline');

function checkWrite(expected, unexpected, end) {
  return new Promise(function(resolve, reject) {
    var nextExpected = expected.shift();
    var nextUnexpected = unexpected.shift();

    var output = '';
    write = process.stdout.write;
    process.stdout.write = function(chunk, encoding, fd) {
      write.apply(process.stdout, arguments);
      output += chunk;

      if (nextExpected && output.indexOf(nextExpected) !== -1) {
        nextExpected = expected.shift();
      }

      if (nextUnexpected && output.indexOf(nextUnexpected) !== -1) {
        process.stdout.write = write;
        reject(new Error('Unexpected warning (' + nextUnexpected + ') has been printed'));
        return;
      }

      if (output.indexOf(end) !== -1) {
        process.stdout.write = write;
        if (!nextExpected) {
          resolve();
        } else {
          reject(new Error('Expected warning (' + nextExpected + ') hasn\'t been printed'));
        }
      }
    };
  });
}

describe('Offline', function() {
  var oldWd = process.cwd();

  afterEach(function() {
    process.chdir(oldWd);
    offline.__set__('ghslug', ghslug);
  });

  it('should create offline-worker.js in the destination directory', function() {
    var dir = temp.mkdirSync('oghliner');

    return offline({
      rootDir: dir,
    }).then(function() {
      assert.doesNotThrow(fs.accessSync.bind(fs, path.join(dir, 'offline-worker.js')));
    });
  });

  it('should not fail if the destination directory already contains a offline-worker.js file', function() {
    var dir = temp.mkdirSync('oghliner');

    fs.writeFileSync(path.join(dir, 'offline-worker.js'), 'something');

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content, 'something');
    });
  });

  it('should use importScript in the service worker if the importScripts option is defined', function() {
    var dir = temp.mkdirSync('oghliner');
    fs.writeFileSync(path.join(dir, 'a-script.js'), 'data');

    return offline({
      rootDir: dir,
      importScripts: [ 'a-script.js', ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('importScripts("a-script.js");'), -1);
    });
  });

  it('should fail if an entry in importScript is a directory', function() {
    var dir = temp.mkdirSync('oghliner');
    fs.mkdirSync(path.join(dir, 'subDir'));

    return offline({
      rootDir: dir,
      importScripts: [ 'subDir', ],
    }).then(function() {
      assert(false);
    }, function() {
      assert(true);
    });
  });

  it('should fail if a file in importScript doesn\'t exist', function() {
    var dir = temp.mkdirSync('oghliner');

    return offline({
      rootDir: dir,
      importScripts: [ 'a-script.js', ],
    }).then(function() {
      assert(false);
    }, function() {
      assert(true);
    });
  });

  it('should use the GitHub slug as the cache ID if it is available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    offline.__set__('ghslug', function(path) {
      return new Promise(function(resolve, reject) {
        resolve('mozilla/oghliner');
      });
    });

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('mozilla/oghliner'), -1);
    });
  });

  it('should use the app name from package.json as the cache ID if the GitHub slug is not available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(rootDir, 'package.json'), JSON.stringify({
      name: 'test_name',
    }));

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_name'), -1);
    });
  });

  it('should not fail if both the GitHub slug and package.json are not available', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      assert.doesNotThrow(fs.accessSync.bind(fs, path.join(dir, 'offline-worker.js')));
    });
  });

  it('should cache files in rootDir', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should not cache files in rootDir that do not match fileGlobs', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
      fileGlobs: [
        'test_file_1.js',
        'test_file_3.js',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.equal(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should cache files in a subdirectory of rootDir', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);
    var subDir = path.join(dir, 'subdir');
    fs.mkdirSync(subDir);

    fs.writeFileSync(path.join(subDir, 'test_file_1.js'), 'test_file_1');
    fs.writeFileSync(path.join(subDir, 'test_file_2.js'), 'test_file_2');
    fs.writeFileSync(path.join(subDir, 'test_file_3.js'), 'test_file_3');

    process.chdir(rootDir);

    return offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });
  });

  it('should cache large files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_1.js is bigger than 2 MiB',
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });

  it('should not cache excluded files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [
      'test_file_1.js is bigger than 2 MiB',
    ], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
      fileGlobs: [
        '!(test_file_1.js)',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.equal(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });

  it('should not warn about explicitly included files', function() {
    var rootDir = temp.mkdirSync('oghliner');
    var dir = path.join(rootDir, 'dist');
    fs.mkdirSync(dir);

    var content = new Buffer(4 * 1024 * 1024);

    fs.writeFileSync(path.join(dir, 'test_file_1.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_2.js'), content);
    fs.writeFileSync(path.join(dir, 'test_file_3.js'), content);

    process.chdir(rootDir);

    var checkWarnings = checkWrite([
      'test_file_2.js is bigger than 2 MiB',
      'test_file_3.js is bigger than 2 MiB',
    ], [
      'test_file_1.js is bigger than 2 MiB',
    ], 'Total precache size');

    var offlinePromise = offline({
      rootDir: dir,
      fileGlobs: [
        '*',
        'test_file_1.js',
      ],
    }).then(function() {
      var content = fs.readFileSync(path.join(dir, 'offline-worker.js'), 'utf8');
      assert.notEqual(content.indexOf('test_file_1.js'), -1);
      assert.notEqual(content.indexOf('test_file_2.js'), -1);
      assert.notEqual(content.indexOf('test_file_3.js'), -1);
    });

    return Promise.all([ checkWarnings, offlinePromise ]);
  });
});
<|endoftext|>


<commit_before>'use strict';

// we test on 1920 x 1080 by default

var Eyes = require('eyes.protractor').Eyes;
var eyes = new Eyes();
eyes.setApiKey(process.env.APPLITOOLS_KEY);

describe('cloudify-ui layout', function(){
    var init = false;

    function isInitialized()
    {
        if(!init){
            init = true;
            return false;
        }
        else{
            return true
        }
    }

    beforeEach(function(){
        if(!isInitialized()){
            eyes.setMatchLevel('Layout');
            eyes.open(browser, 'Cloudify UI', 'Sanity Suite', {width: 1920, height: 1080});
        }
    });

    it('shows blueprints', function() {
        browser.get('/');
        eyes.checkWindow('Blueprints Page');
    });

    it('checks login layout', function(){
        browser.get('/#/login');
        eyes.checkWindow('Login Page');
    });

    //______________________________________________________________________________________________________________________________________
    //                                                    ~~~~~~~~ ATTENTION ~~~~~~~~
    //We have no indication of how to know when the last test ran, so remember to keep this test the last of all test so it could close eyes
    it('should close Applitools eyes', function(){
        eyes.close();
    });
});
<commit_msg>Update example_spec.js<commit_after>'use strict';

// we test on 1920 x 1080 by default

var Eyes = require('eyes.protractor').Eyes;
var eyes = new Eyes();
eyes.setApiKey(process.env.APPLITOOLS_KEY);

describe('cloudify-ui layout', function(){
    var init = false;

    beforeEach(function(){
        if(!init){
            init = true;
            eyes.setMatchLevel('Layout');
            eyes.open(browser, 'Cloudify UI', 'Sanity Suite', {width: 1920, height: 1080});
        }
    });

    it('shows blueprints', function() {
        browser.get('/');
        eyes.checkWindow('Blueprints Page');
    });

    it('checks login layout', function(){
        browser.get('/#/login');
        eyes.checkWindow('Login Page');
    });

    //______________________________________________________________________________________________________________________________________
    //                                                    ~~~~~~~~ ATTENTION ~~~~~~~~
    //We have no indication of how to know when the last test ran, so remember to keep this test the last of all test so it could close eyes
    it('should close Applitools eyes', function(){
        eyes.close();
    });
});
<|endoftext|>


<commit_before>import { pipe } from 'lodash/fp';

export const buildRoutes = inputRoutes =>
  inputRoutes.reduce((acc, route) => {
    const category = route.category || 'Other';
    const initialArrayVal = acc[category] || [];
    return {
      ...acc,
      [category]: [...initialArrayVal, route]
    };
  }, {});

export const compareRoutes = (routeA, routeB) => {
  if (!routeA.component && routeB.component) {
    return -1;
  }
  if (!routeB.component && routeA.component) {
    return 1;
  }
  if ((routeA.category || 'Other') < (routeB.category || 'Other')) {
    return -1;
  }
  if ((routeA.category || 'Other') > (routeB.category || 'Other')) {
    return 1;
  }
  if (routeA.title < routeB.title) {
    return -1;
  }

  return 1;
};

export const applyHighlighting = highlightedElement => routeList => {
  return routeList.map((route, index) => ({
    ...route,
    highlighted: index === highlightedElement
  }));
};

const sort = fn => arr => arr.sort(fn);

export const generateRouteList = highlightedElement =>
  pipe(
    sort(compareRoutes),
    applyHighlighting(highlightedElement),
    buildRoutes,
    Object.entries
  );
<commit_msg>docs(headerUtils): Keep eslint happy about the headerUtils file (#597)<commit_after>import { pipe } from 'lodash/fp';

const OTHER_CATEGORY = 'Other';

export const buildRoutes = inputRoutes =>
  inputRoutes.reduce((acc, route) => {
    const category = route.category || OTHER_CATEGORY;
    const initialArrayVal = acc[category] || [];
    return {
      ...acc,
      [category]: [...initialArrayVal, route]
    };
  }, {});

export const compareRoutes = (routeA, routeB) => {
  const routeACategory = routeA.category || OTHER_CATEGORY;
  const routeBCategory = routeB.category || OTHER_CATEGORY;
  if (!routeA.component && routeB.component) {
    return -1;
  }
  if (!routeB.component && routeA.component) {
    return 1;
  }
  if (routeACategory < routeBCategory) {
    return -1;
  }
  if (routeACategory > routeBCategory) {
    return 1;
  }
  if (routeA.title < routeB.title) {
    return -1;
  }

  return 1;
};

export const applyHighlighting = highlightedElement => routeList => {
  return routeList.map((route, index) => ({
    ...route,
    highlighted: index === highlightedElement
  }));
};

const sort = fn => arr => arr.sort(fn);

export const generateRouteList = highlightedElement =>
  pipe(
    sort(compareRoutes),
    applyHighlighting(highlightedElement),
    buildRoutes,
    Object.entries
  );
<|endoftext|>


<commit_before>'use strict';

var _ = require('underscore');
var flat = require('flat');
var fs = require('fs');
var merge = require('merge');
var path = require('path');

var log = require('./Log').getLogger('Config');

var opts = require('optimist').argv;

var env = Object.keys(opts).filter(function(name) {
  return opts[name] === true;
});

var envVars = {};
Object.keys(process.env).forEach(function(key) {
  if (key.match(/^sphere_/i)) {
    envVars[key.substring(7).replace(/_/g, '.')] = process.env[key];
  }
});

if (envVars.debug === 'true') {
  env.push('debug');
}

if (env.length) {
  //log.info('Environments:', env.join(', '));
}

/**
 * Configuration environments can be provided on the cli without a value ('--cloud-production')
 * A configuration file is loaded for each environment from common and the current module.
 *
 * Note: Only use alphanumeric characters for config property names
 *
 * Ordering of configuration searching:
 *
 * 1. Command-line arguments (nested using period)
 *
 * ```./start.sh --mqtt.port 1884```
 *
 * 2. Environment vars (must start with "sphere_", nested using underscore)
 * ```sphere_mqtt_port=1884 ./start.sh```
 *
 * 3. Home directory environment config
 * ```~/.sphere/[ENVIRONMENT].json```
 *
 * 4. Home directory default config
 * ```~/.sphere/default.json```
 *
 * 5. CWD (module) environment config
 * ```[CWD]/config/[ENVIRONMENT].json```
 *
 * 6. CWD (module) default config
 * ```[CWD]/config/default.json```
 *
 * 7. sphere-common environment config
 * ```sphere-common/config/[ENVIRONMENT].json```
 *
 * 8. sphere-common default config
 * ```sphere-common/config/default.json```
 *
 * 9. sphere-common credentials config
 * ```sphere-common/config/credentials.json```
 *
 * TODO: Support underscore nesting in CLI args
 */

// Configuration sources from are listed from least important (sphere-common/config/default.json) to most (CLI args)
// TODO: Correct ordering?
var configFiles = [];

function getUserHome() {
  return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
}

function addIfExists(path) {
  if (fs.existsSync(path)) {
    configFiles.push(path);
  }
}

// sphere-common default config
addIfExists(path.join(__dirname, '..', '..', 'config', 'default.json'));

// sphere-common credentials config
addIfExists(path.join(__dirname, '..', '..', 'config', 'credentials.json'));

// sphere-common environment(s) config
env.forEach(function(e){
  addIfExists(path.join(__dirname, '..', '..', 'config', e + '.json'));
});

// current module default config
addIfExists(path.join(process.cwd(), 'config', 'default.json'));

// current module environment(s) config
env.forEach(function(e){
  addIfExists(path.join(process.cwd(), 'config', e + '.json'));
});

// home directory default config
addIfExists(path.join(getUserHome(), '.sphere', 'default.json'));

// home directory environment(s) config
env.forEach(function(e){
  addIfExists(path.join(getUserHome(), '.sphere', e + '.json'));
});

// credentials file
addIfExists(path.join('/','etc', 'opt', 'ninja', 'credentials.json'));
addIfExists('/data/etc/opt/ninja/credentials.json');

// Read the config files
var sources = configFiles.map(function(path) {
  try {
    return require(path);
  } catch(e) {
    var c = {};
    c['Failed Reading ' + path] = e.message;
    return c;
  }
});

// env vars (if starting with "sphere_")
sources.push(envVars);

// cli overrides
sources.push(opts);

var merged = merge.apply(null, sources.map(flat.flatten));
for (var prop in merged) {
  if (merged[prop] === 'false') {
    merged[prop] = false;
  } else if (merged[prop] === 'true') {
    merged[prop] = true;
  }
}

var config = flat.unflatten(merged);
config.sources = configFiles;
config.env = env;
config.installDirectory = path.join(__dirname, '..', '..');

function makeUnwritable(o) {
  Object.freeze(o);
  Object.keys(o).forEach(function(key) {
    if (typeof o[key] === 'object') makeUnwritable(o[key]);
  });
  return o;
}

module.exports = makeUnwritable(config);
<commit_msg>Don't attempt unless getUserHome() is defined.<commit_after>'use strict';

var _ = require('underscore');
var flat = require('flat');
var fs = require('fs');
var merge = require('merge');
var path = require('path');

var log = require('./Log').getLogger('Config');

var opts = require('optimist').argv;

var env = Object.keys(opts).filter(function(name) {
  return opts[name] === true;
});

var envVars = {};
Object.keys(process.env).forEach(function(key) {
  if (key.match(/^sphere_/i)) {
    envVars[key.substring(7).replace(/_/g, '.')] = process.env[key];
  }
});

if (envVars.debug === 'true') {
  env.push('debug');
}

if (env.length) {
  //log.info('Environments:', env.join(', '));
}

/**
 * Configuration environments can be provided on the cli without a value ('--cloud-production')
 * A configuration file is loaded for each environment from common and the current module.
 *
 * Note: Only use alphanumeric characters for config property names
 *
 * Ordering of configuration searching:
 *
 * 1. Command-line arguments (nested using period)
 *
 * ```./start.sh --mqtt.port 1884```
 *
 * 2. Environment vars (must start with "sphere_", nested using underscore)
 * ```sphere_mqtt_port=1884 ./start.sh```
 *
 * 3. Home directory environment config
 * ```~/.sphere/[ENVIRONMENT].json```
 *
 * 4. Home directory default config
 * ```~/.sphere/default.json```
 *
 * 5. CWD (module) environment config
 * ```[CWD]/config/[ENVIRONMENT].json```
 *
 * 6. CWD (module) default config
 * ```[CWD]/config/default.json```
 *
 * 7. sphere-common environment config
 * ```sphere-common/config/[ENVIRONMENT].json```
 *
 * 8. sphere-common default config
 * ```sphere-common/config/default.json```
 *
 * 9. sphere-common credentials config
 * ```sphere-common/config/credentials.json```
 *
 * TODO: Support underscore nesting in CLI args
 */

// Configuration sources from are listed from least important (sphere-common/config/default.json) to most (CLI args)
// TODO: Correct ordering?
var configFiles = [];

function getUserHome() {
  return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
}

function addIfExists(path) {
  if (fs.existsSync(path)) {
    configFiles.push(path);
  }
}

// sphere-common default config
addIfExists(path.join(__dirname, '..', '..', 'config', 'default.json'));

// sphere-common credentials config
addIfExists(path.join(__dirname, '..', '..', 'config', 'credentials.json'));

// sphere-common environment(s) config
env.forEach(function(e){
  addIfExists(path.join(__dirname, '..', '..', 'config', e + '.json'));
});

// current module default config
addIfExists(path.join(process.cwd(), 'config', 'default.json'));

// current module environment(s) config
env.forEach(function(e){
  addIfExists(path.join(process.cwd(), 'config', e + '.json'));
});

uh = getUserHome()
if uh {
  // home directory default config
  addIfExists(path.join(getUserHome(), '.sphere', 'default.json'));

  // home directory environment(s) config
  env.forEach(function(e){
    addIfExists(path.join(getUserHome(), '.sphere', e + '.json'));
  });
}

// credentials file
addIfExists(path.join('/','etc', 'opt', 'ninja', 'credentials.json'));
addIfExists('/data/etc/opt/ninja/credentials.json');

// Read the config files
var sources = configFiles.map(function(path) {
  try {
    return require(path);
  } catch(e) {
    var c = {};
    c['Failed Reading ' + path] = e.message;
    return c;
  }
});

// env vars (if starting with "sphere_")
sources.push(envVars);

// cli overrides
sources.push(opts);

var merged = merge.apply(null, sources.map(flat.flatten));
for (var prop in merged) {
  if (merged[prop] === 'false') {
    merged[prop] = false;
  } else if (merged[prop] === 'true') {
    merged[prop] = true;
  }
}

var config = flat.unflatten(merged);
config.sources = configFiles;
config.env = env;
config.installDirectory = path.join(__dirname, '..', '..');

function makeUnwritable(o) {
  Object.freeze(o);
  Object.keys(o).forEach(function(key) {
    if (typeof o[key] === 'object') makeUnwritable(o[key]);
  });
  return o;
}

module.exports = makeUnwritable(config);
<|endoftext|>


<commit_before>var byline = require("byline");

module.exports = function(stream, source)
{
    return stream = stream.pipe(byline.createStream()).on("data", function(line)
    {
        /* Cut the string into RegEx. this is my last resort. */
        var line = line.toString(), match, hashes = [];
        var regex = new RegExp("(?:%3A)(([0-9A-Fa-f]){40})", "g");
        while (match = regex.exec(line)) hashes.push(match[1]);
        if (hashes) hashes.forEach(function(hash) { stream.emit("infoHash", hash, source.addon) });
    });
};
<commit_msg>importers/generic: fix regex match<commit_after>var byline = require("byline");

module.exports = function(stream, source)
{
    return stream = stream.pipe(byline.createStream()).on("data", function(line)
    {
        /* Cut the string into RegEx. this is my last resort. */
        var line = line.toString(), match, hashes = [];
        var regex = new RegExp("(?:%3A)?(([0-9A-Fa-f]){40})", "g");
        while (match = regex.exec(line)) hashes.push(match[1]);
        if (hashes) hashes.forEach(function(hash) { stream.emit("infoHash", hash, source.addon) });
    });
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import DocumentTitle from 'react-document-title';
import { SignupForm } from 'components';

export default class Signup extends Component {
  render() {
    return (
      <DocumentTitle title="Signup">

            <SignupForm onSubmit={this.handleSignup} />

      </DocumentTitle>
    );
  }
}
<commit_msg>Tiny refactor<commit_after>import React, { Component } from 'react';
import DocumentTitle from 'react-document-title';
import { SignupForm } from 'components';

export default class Signup extends Component {
  render() {
    return (
      <DocumentTitle title="Signup">

            <SignupForm />

      </DocumentTitle>
    );
  }
}
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
var sourceMap = {};

// ************************************************************************************************
Firebug.Lite.Proxy =
{
    // jsonp callbacks
    _callbacks: {},

    /**
     * Load a resource, either locally (directly) or externally (via proxy) using
     * synchronous XHR calls. Loading external resources requires the proxy plugin to
     * be installed and configured (see /plugin/proxy/proxy.php).
     */
    load: function(url)
    {
        var resourceDomain = getDomain(url);
        var isLocalResource =
            // empty domain means local URL
            !resourceDomain ||
            // same domain means local too
            resourceDomain ==  Firebug.context.window.location.host; // TODO: xxxpedro context

        return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
    },

    /**
     * Load a resource using JSONP technique.
     */
    loadJSONP: function(url, callback)
    {
        var script = createGlobalElement("script"),
            doc = Firebug.context.document,

            uid = "" + new Date().getTime(),
            callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,

            jsonpURL = url.indexOf("?") != -1 ?
                    url + "&" + callbackName :
                    url + "?" + callbackName;

        Firebug.Lite.Proxy._callbacks[uid] = function(data)
        {
            if (callback)
                callback(data);

            script.parentNode.removeChild(script);
            delete Firebug.Lite.Proxy._callbacks[uid];
        };

        script.src = jsonpURL;

        if (doc.documentElement)
            doc.documentElement.appendChild(script);
    },

    /**
     * Load a resource using YQL (not reliable).
     */
    YQL: function(url, callback)
    {
        var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
                encodeURIComponent(url) + "%22&format=xml";

        this.loadJSONP(yql, function(data)
        {
            var source = data.results[0];

            // clean up YQL bogus elements
            var match = /<body>\s+<p>([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
            if (match)
                source = match[1];

            console.log(source);
        });
    }
};

// ************************************************************************************************

var fetchResource = function(url)
{
    if (sourceMap.hasOwnProperty(url))
        return sourceMap[url];

    // Getting the native XHR object so our calls won't be logged in the Console Panel
    var xhr = FBL.getNativeXHRObject();
    xhr.open("get", url, false);
    xhr.send();

    var source = sourceMap[url] = xhr.responseText;
    return source;
};

var fetchProxyResource = function(url)
{
    if (sourceMap.hasOwnProperty(url))
        return sourceMap[url];

    var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
    var response = fetchResource(proxyURL);

    try
    {
        var data = eval("(" + response + ")");
    }
    catch(E)
    {
        return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
    }

    var source = data ? data.contents : "";
    return source;
};

// ************************************************************************************************
}});
<commit_msg>[flexBox &lite1.4] handling disableResourceFetching option<commit_after>/* See license.txt for terms of usage */

FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
var sourceMap = {};

// ************************************************************************************************
Firebug.Lite.Proxy =
{
    // jsonp callbacks
    _callbacks: {},

    /**
     * Load a resource, either locally (directly) or externally (via proxy) using
     * synchronous XHR calls. Loading external resources requires the proxy plugin to
     * be installed and configured (see /plugin/proxy/proxy.php).
     */
    load: function(url)
    {
        var resourceDomain = getDomain(url);
        var isLocalResource =
            // empty domain means local URL
            !resourceDomain ||
            // same domain means local too
            resourceDomain ==  Firebug.context.window.location.host; // TODO: xxxpedro context

        return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
    },

    /**
     * Load a resource using JSONP technique.
     */
    loadJSONP: function(url, callback)
    {
        var script = createGlobalElement("script"),
            doc = Firebug.context.document,

            uid = "" + new Date().getTime(),
            callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,

            jsonpURL = url.indexOf("?") != -1 ?
                    url + "&" + callbackName :
                    url + "?" + callbackName;

        Firebug.Lite.Proxy._callbacks[uid] = function(data)
        {
            if (callback)
                callback(data);

            script.parentNode.removeChild(script);
            delete Firebug.Lite.Proxy._callbacks[uid];
        };

        script.src = jsonpURL;

        if (doc.documentElement)
            doc.documentElement.appendChild(script);
    },

    /**
     * Load a resource using YQL (not reliable).
     */
    YQL: function(url, callback)
    {
        var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
                encodeURIComponent(url) + "%22&format=xml";

        this.loadJSONP(yql, function(data)
        {
            var source = data.results[0];

            // clean up YQL bogus elements
            var match = /<body>\s+<p>([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
            if (match)
                source = match[1];

            console.log(source);
        });
    }
};

// ************************************************************************************************

Firebug.Lite.Proxy.fetchResourceDisabledMessage =
    "/* Firebug Lite resource fetching is disabled.\n" +
    "To enabled it set the Firebug Lite option \"disableResourceFetching\" to \"false\".\n" +
    "More info at http://getfirebug.com/firebuglite#Options */";

var fetchResource = function(url)
{
    if (Firebug.disableResourceFetching)
    {
        var source = sourceMap[url] = Firebug.Lite.Proxy.fetchResourceDisabledMessage;
        return source;
    }

    if (sourceMap.hasOwnProperty(url))
        return sourceMap[url];

    // Getting the native XHR object so our calls won't be logged in the Console Panel
    var xhr = FBL.getNativeXHRObject();
    xhr.open("get", url, false);
    xhr.send();

    var source = sourceMap[url] = xhr.responseText;
    return source;
};

var fetchProxyResource = function(url)
{
    if (sourceMap.hasOwnProperty(url))
        return sourceMap[url];

    var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
    var response = fetchResource(proxyURL);

    try
    {
        var data = eval("(" + response + ")");
    }
    catch(E)
    {
        return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
    }

    var source = data ? data.contents : "";
    return source;
};

// ************************************************************************************************
}});
<|endoftext|>


<commit_before>const EventEmitter = require('events');
const { strToIv } = require('./utils');

class FileReceiver extends EventEmitter {
  constructor() {
    super();
    this.salt = strToIv(location.pathname.slice(10, -1));
  }

  download() {
    return Promise.all([
      new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();

        xhr.onprogress = e => {
          if (e.lengthComputable) {
            let percentComplete = Math.floor(e.loaded / e.total * 100);
            this.emit('progress', percentComplete);
          }
        };

        xhr.onload = function(e) {

          if (xhr.status === 404) {
            reject(new Error('The file has expired, or has already been deleted.'));
          }

          let blob = new Blob([this.response]);
          let fileReader = new FileReader();
          fileReader.onload = function() {
            resolve({
              data: this.result,
              fname: xhr
                .getResponseHeader('Content-Disposition')
                .match(/filename="(.+)"/)[1]
            });
          };

          fileReader.readAsArrayBuffer(blob);
        };

        xhr.open('get', '/assets' + location.pathname.slice(0, -1), true);
        xhr.responseType = 'blob';
        xhr.send();
      }),
      window.crypto.subtle.importKey(
        'jwk',
        {
          kty: 'oct',
          k: location.hash.slice(1),
          alg: 'A128CBC',
          ext: true
        },
        {
          name: 'AES-CBC'
        },
        true,
        ['encrypt', 'decrypt']
      )
    ])
    .then(([fdata, key]) => {
      let salt = this.salt;
      return Promise.all([
        window.crypto.subtle.decrypt(
          {
            name: 'AES-CBC',
            iv: salt
          },
          key,
          fdata.data
        ),
        new Promise((resolve, reject) => {
          resolve(fdata.fname);
        })
      ]);
    });
  }
}

module.exports = FileReceiver;
<commit_msg>added return<commit_after>const EventEmitter = require('events');
const { strToIv } = require('./utils');

class FileReceiver extends EventEmitter {
  constructor() {
    super();
    this.salt = strToIv(location.pathname.slice(10, -1));
  }

  download() {
    return Promise.all([
      new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();

        xhr.onprogress = e => {
          if (e.lengthComputable) {
            let percentComplete = Math.floor(e.loaded / e.total * 100);
            this.emit('progress', percentComplete);
          }
        };

        xhr.onload = function(e) {

          if (xhr.status === 404) {
            reject(new Error('The file has expired, or has already been deleted.'));
            return;
          }

          let blob = new Blob([this.response]);
          let fileReader = new FileReader();
          fileReader.onload = function() {
            resolve({
              data: this.result,
              fname: xhr
                .getResponseHeader('Content-Disposition')
                .match(/filename="(.+)"/)[1]
            });
          };

          fileReader.readAsArrayBuffer(blob);
        };

        xhr.open('get', '/assets' + location.pathname.slice(0, -1), true);
        xhr.responseType = 'blob';
        xhr.send();
      }),
      window.crypto.subtle.importKey(
        'jwk',
        {
          kty: 'oct',
          k: location.hash.slice(1),
          alg: 'A128CBC',
          ext: true
        },
        {
          name: 'AES-CBC'
        },
        true,
        ['encrypt', 'decrypt']
      )
    ])
    .then(([fdata, key]) => {
      let salt = this.salt;
      return Promise.all([
        window.crypto.subtle.decrypt(
          {
            name: 'AES-CBC',
            iv: salt
          },
          key,
          fdata.data
        ),
        new Promise((resolve, reject) => {
          resolve(fdata.fname);
        })
      ]);
    });
  }
}

module.exports = FileReceiver;
<|endoftext|>


<commit_before>export default {
	port: 8000,
	output: 'data',
	logentriesToken: 'aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa', // replace with logentries token
	webhookSecret: '',
	smtp: {
		host: '',
		port: '',
	},
	smtpAuth: {
		user: '',
		pass: '',
	},
	smtpTo: {
		email: '',
	},
	smtpFrom: {
		email: '',
	},
	tasks: {
		v1: {
			google: {
				cdnRoot: 'https://ajax.googleapis.com/ajax/libs',
			},
			bootstrap: {
				cdnRoot: 'https://maxcdn.bootstrapcdn.com',
				gitPath: 'home/bootstrap-cdn',
				filePath: 'public',
			},
			jquery: {
				cdnRoot: 'https://code.jquery.com',
				gitPath: 'home/codeorigin.jquery.com',
				filePath: 'cdn',
			},
			jsdelivr: {
				cdnRoot: 'https://cdn.jsdelivr.net',
				gitPath: 'home/jsdelivr',
				filePath: 'files',
			},
			cdnjs: {
				cdnRoot: 'https://cdnjs.cloudflare.com/ajax/libs',
				gitPath: 'home/cdnjs',
				filePath: 'ajax/libs',
			},
		},
		v2: {
			google: {
				cdnRoot: 'https://ajax.googleapis.com/ajax/libs',
			},
			bootstrap: {
				cdnRoot: 'https://maxcdn.bootstrapcdn.com',
				gitPath: 'home/bootstrap-cdn',
				filePath: 'public',
			},
			jquery: {
				cdnRoot: 'https://code.jquery.com',
				gitPath: 'home/codeorigin.jquery.com',
				filePath: 'cdn',
			},
			jsdelivr: {
				cdnRoot: 'https://cdn.jsdelivr.net',
				gitPath: 'home/jsdelivr',
				filePath: 'files',
			},
			cdnjs: {
				cdnRoot: 'https://cdnjs.cloudflare.com/ajax/libs',
				gitPath: 'home/cdnjs',
				filePath: 'ajax/libs',
			},
		},
	}
};
<commit_msg>Remove cdnRoot from v1 config<commit_after>export default {
	port: 8000,
	output: 'data',
	logentriesToken: 'aaaaaaaa-1111-1111-1111-aaaaaaaaaaaa', // replace with logentries token
	webhookSecret: '',
	smtp: {
		host: '',
		port: '',
	},
	smtpAuth: {
		user: '',
		pass: '',
	},
	smtpTo: {
		email: '',
	},
	smtpFrom: {
		email: '',
	},
	tasks: {
		v1: {
			google: {},
			bootstrap: {
				gitPath: 'home/bootstrap-cdn',
				filePath: 'public',
			},
			jquery: {
				gitPath: 'home/codeorigin.jquery.com',
				filePath: 'cdn',
			},
			jsdelivr: {
				gitPath: 'home/jsdelivr',
				filePath: 'files',
			},
			cdnjs: {
				gitPath: 'home/cdnjs',
				filePath: 'ajax/libs',
			},
		},
		v2: {
			google: {
				cdnRoot: 'https://ajax.googleapis.com/ajax/libs',
			},
			bootstrap: {
				cdnRoot: 'https://maxcdn.bootstrapcdn.com',
				gitPath: 'home/bootstrap-cdn',
				filePath: 'public',
			},
			jquery: {
				cdnRoot: 'https://code.jquery.com',
				gitPath: 'home/codeorigin.jquery.com',
				filePath: 'cdn',
			},
			jsdelivr: {
				cdnRoot: 'https://cdn.jsdelivr.net',
				gitPath: 'home/jsdelivr',
				filePath: 'files',
			},
			cdnjs: {
				cdnRoot: 'https://cdnjs.cloudflare.com/ajax/libs',
				gitPath: 'home/cdnjs',
				filePath: 'ajax/libs',
			},
		},
	}
};
<|endoftext|>


<commit_before>// Copyright 2019, University of Colorado Boulder

/**
 * A trait for subtypes of Node. Meant for Nodes with a value that "run" on a NumberProperty and handles formatting,
 * mapping, and aria-valuetext updating.
 *
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */

define( require => {
  'use strict';

  // modules
  const extend = require( 'PHET_CORE/extend' );
  const inheritance = require( 'PHET_CORE/inheritance' );
  const Node = require( 'SCENERY/nodes/Node' );
  const StringUtils = require( 'PHETCOMMON/util/StringUtils' );
  const sun = require( 'SUN/sun' );
  const timer = require( 'AXON/timer' );
  const Util = require( 'DOT/Util' );

  const AccessibleValueHandler = {

    /**
     * Implement functionality for a number spinner.
     * @public
     * @trait
     *
     * @param {function} type - The type (constructor) whose prototype that is modified.
     */
    mixInto: type => {
      assert && assert( _.includes( inheritance( type ), Node ), 'must be mixed into a Node' );

      const proto = type.prototype;

      extend( proto, {

        /**
         * This should be called in the constructor to initialize the accessible input features for the node.
         *
         * @param {Property.<number>} valueProperty
         * @param {Object} [options] - note, does not mutate the Node
         *
         * @protected
         */
        initializeAccessibleValueHandler( valueProperty, options ) {

          // ensure that the client does not set both a custom text pattern and a text creation function
          assert && assert(
            !( options.a11yValuePattern && options.a11yCreateValueChangeAriaValueText ),
            'cannot set both a11yValuePattern and a11yCreateValueChangeAriaValueText in options'
          );

          // verify that a11yValuePattern includes '{{value}}', and that is the only key in the pattern
          if ( assert && options.a11yValuePattern ) {
            assert( options.a11yValuePattern.match( /\{\{[^\{\}]+\}\}/g ).length === 1,
              'a11yValuePattern only accepts a single \'value\' key'
            );
            assert( options.a11yValuePattern.indexOf( '{{value}}' ) >= 0,
              'a11yValuePattern must contain a key of \'value\''
            );
          }

          options = _.extend( {

            // {boolean} - If true, set the aria-valuenow attribute to the accessible element. aria-valuenow is
            // exclusively a value, and required for certain elements. aria-valuetext can contain values and
            // other descriptive text.
            a11yProvideValueNow: true,
            a11yValuePattern: '{{value}}', // {string} if you want units or additional content, add to pattern
            a11yDecimalPlaces: 0, // number of decimal places for the value when formatted and read by assistive technology

            /**
             * Map the valueProperty value to another number that will be read by the assistive device on
             * valueProperty changes.
             * @param {number} value
             * @returns {number}
             */
            a11yMapValue: _.identity,

            /**
             * Custom aria-valuetext creation function, called when the valueProperty changes. Used in replacement of
             * the simpler/easier option: a11yValuePattern.
             * This string is read by AT every time the slider value changes.
             *
             * @param {string} formattedValue - mapped value fixed to the provided decimal places
             * @param {number} newValue - the new value, unformatted
             * @param {number} previousValue - just the "oldValue" from the property listener
             * @returns {string} - aria-valuetext to be set to the primarySibling
             */
            a11yCreateValueChangeAriaValueText: _.identity,

            /**
             * By default there will be nothing special provided on focus, just the previous value set on Property change.
             * If a specific aria-valuetext is desired when the interactive DOM element is focused, then use this option
             * to provide the proper "on focus" text. If provided, this will be called independently of the "on change"
             * valuetext updates. As a result, you can use either a11yCreateValueChangeAriaValueText or a11yValuePattern
             * with this.
             *
             * The string that this function returns is set as aria-valuetext when the component is constructed and when
             * blurred (setting the right text for next focus). If you need it to change more often, you must manually
             * keep the on focus value text up to date, see updateOnFocusAriaValueText).
             *
             * {null|function}
             * There are no parameters to this function
             * @returns {string} - aria-valuetext to be set to the primarySibling
             */
            a11yCreateOnFocusAriaValueText: null
          }, options );

          // @private {Property.<number>}
          this._valueProperty = valueProperty;

          // @public (read-only a11y) - precision for the output value to be read by an assistive device
          this.a11yDecimalPlaces = options.a11yDecimalPlaces;

          // @private - {null|function} see options for doc
          this.a11yCreateOnFocusAriaValueText = options.a11yCreateOnFocusAriaValueText;

          // when the property changes, be sure to update the accessible input value and aria-valuetext which is read
          // by assistive technology when the value changes
          const valuePropertyListener = ( value, oldValue ) => {
            const mappedValue = options.a11yMapValue( value );

            // format the value text for reading
            const formattedValue = Util.toFixedNumber( mappedValue, this.a11yDecimalPlaces );

            // create the final string from optional parameters. This looks messy, but in reality you can only supply
            // the valuePattern OR the create function, so this works as an "either or" situation.
            this.ariaValueText = StringUtils.fillIn( options.a11yValuePattern, {
              value: options.a11yCreateValueChangeAriaValueText( formattedValue, value, oldValue )
            } );

            // only supply aria-valuenow if provided by option
            options.a11yProvideValueNow && this.setAccessibleAttribute( 'aria-valuenow', value );
          };
          this._valueProperty.link( valuePropertyListener );

          const valueHandlerListener = {

            // When not providing a timeout, we would often get this change for the previously focused element even
            // though it wasn't the active element of the screen. Perhaps this is just a bug/problem with how AT monitor
            // for aria-valuetext updating.
            focus: () => { timer.setTimeout( () => this.updateOnFocusAriaValueText(), 0 );}
          };
          this.addInputListener( valueHandlerListener );

          // update for the first focus now
          this.updateOnFocusAriaValueText();

          // @private - called by disposeAccessibleValueHandler to prevent memory leaks
          this._disposeAccessibleValueHandler = () => {
            this.removeInputListener( valueHandlerListener );
            this._valueProperty.unlink( valuePropertyListener );
          };
        },

        /**
         * @public
         * Update the aria-valuetext for the next time that this element is focused.
         */
        updateOnFocusAriaValueText() {
          if ( this.a11yCreateOnFocusAriaValueText ) {
            this.ariaValueText = this.a11yCreateOnFocusAriaValueText();
          }
        },

        /**
         * Call when disposing the type that this trait is mixed into.
         * @public
         */
        disposeAccessibleValueHandler() {
          this._disposeAccessibleValueHandler();
        }
      } );
    }
  };

  sun.register( 'AccessibleValueHandler', AccessibleValueHandler );

  return AccessibleValueHandler;
} );
<commit_msg>aria-valuenow is no longer optional, see #497<commit_after>// Copyright 2019, University of Colorado Boulder

/**
 * A trait for subtypes of Node. Meant for Nodes with a value that "run" on a NumberProperty and handles formatting,
 * mapping, and aria-valuetext updating.
 *
 * @author Michael Kauzmann (PhET Interactive Simulations)
 */

define( require => {
  'use strict';

  // modules
  const extend = require( 'PHET_CORE/extend' );
  const inheritance = require( 'PHET_CORE/inheritance' );
  const Node = require( 'SCENERY/nodes/Node' );
  const StringUtils = require( 'PHETCOMMON/util/StringUtils' );
  const sun = require( 'SUN/sun' );
  const timer = require( 'AXON/timer' );
  const Util = require( 'DOT/Util' );

  const AccessibleValueHandler = {

    /**
     * Implement functionality for a number spinner.
     * @public
     * @trait
     *
     * @param {function} type - The type (constructor) whose prototype that is modified.
     */
    mixInto: type => {
      assert && assert( _.includes( inheritance( type ), Node ), 'must be mixed into a Node' );

      const proto = type.prototype;

      extend( proto, {

        /**
         * This should be called in the constructor to initialize the accessible input features for the node.
         *
         * @param {Property.<number>} valueProperty
         * @param {Object} [options] - note, does not mutate the Node
         *
         * @protected
         */
        initializeAccessibleValueHandler( valueProperty, options ) {

          // ensure that the client does not set both a custom text pattern and a text creation function
          assert && assert(
            !( options.a11yValuePattern && options.a11yCreateValueChangeAriaValueText ),
            'cannot set both a11yValuePattern and a11yCreateValueChangeAriaValueText in options'
          );

          // verify that a11yValuePattern includes '{{value}}', and that is the only key in the pattern
          if ( assert && options.a11yValuePattern ) {
            assert( options.a11yValuePattern.match( /\{\{[^\{\}]+\}\}/g ).length === 1,
              'a11yValuePattern only accepts a single \'value\' key'
            );
            assert( options.a11yValuePattern.indexOf( '{{value}}' ) >= 0,
              'a11yValuePattern must contain a key of \'value\''
            );
          }

          options = _.extend( {

            a11yValuePattern: '{{value}}', // {string} if you want units or additional content, add to pattern
            a11yDecimalPlaces: 0, // number of decimal places for the value when formatted and read by assistive technology

            /**
             * Map the valueProperty value to another number that will be read by the assistive device on
             * valueProperty changes.
             * @param {number} value
             * @returns {number}
             */
            a11yMapValue: _.identity,

            /**
             * Custom aria-valuetext creation function, called when the valueProperty changes. Used in replacement of
             * the simpler/easier option: a11yValuePattern.
             * This string is read by AT every time the slider value changes.
             *
             * @param {string} formattedValue - mapped value fixed to the provided decimal places
             * @param {number} newValue - the new value, unformatted
             * @param {number} previousValue - just the "oldValue" from the property listener
             * @returns {string} - aria-valuetext to be set to the primarySibling
             */
            a11yCreateValueChangeAriaValueText: _.identity,

            /**
             * By default there will be nothing special provided on focus, just the previous value set on Property change.
             * If a specific aria-valuetext is desired when the interactive DOM element is focused, then use this option
             * to provide the proper "on focus" text. If provided, this will be called independently of the "on change"
             * valuetext updates. As a result, you can use either a11yCreateValueChangeAriaValueText or a11yValuePattern
             * with this.
             *
             * The string that this function returns is set as aria-valuetext when the component is constructed and when
             * blurred (setting the right text for next focus). If you need it to change more often, you must manually
             * keep the on focus value text up to date, see updateOnFocusAriaValueText).
             *
             * {null|function}
             * There are no parameters to this function
             * @returns {string} - aria-valuetext to be set to the primarySibling
             */
            a11yCreateOnFocusAriaValueText: null
          }, options );

          // @private {Property.<number>}
          this._valueProperty = valueProperty;

          // @public (read-only a11y) - precision for the output value to be read by an assistive device
          this.a11yDecimalPlaces = options.a11yDecimalPlaces;

          // @private - {null|function} see options for doc
          this.a11yCreateOnFocusAriaValueText = options.a11yCreateOnFocusAriaValueText;

          // when the property changes, be sure to update the accessible input value and aria-valuetext which is read
          // by assistive technology when the value changes
          const valuePropertyListener = ( value, oldValue ) => {
            const mappedValue = options.a11yMapValue( value );
            assert && assert( typeof mappedValue === 'number', 'a11yMapValue must return a number' );

            // format the value text for reading
            const formattedValue = Util.toFixedNumber( mappedValue, this.a11yDecimalPlaces );

            // create the final string from optional parameters. This looks messy, but in reality you can only supply
            // the valuePattern OR the create function, so this works as an "either or" situation.
            this.ariaValueText = StringUtils.fillIn( options.a11yValuePattern, {
              value: options.a11yCreateValueChangeAriaValueText( formattedValue, value, oldValue )
            } );

            // set the aria-valuenow attribute in case the AT requires it to read the value correctly, some may
            // fall back on this from aria-valuetext see
            // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-valuetext_attribute#Possible_effects_on_user_agents_and_assistive_technology
            this.setAccessibleAttribute( 'aria-valuenow', formattedValue );
          };
          this._valueProperty.link( valuePropertyListener );

          const valueHandlerListener = {

            // When not providing a timeout, we would often get this change for the previously focused element even
            // though it wasn't the active element of the screen. Perhaps this is just a bug/problem with how AT monitor
            // for aria-valuetext updating.
            focus: () => { timer.setTimeout( () => this.updateOnFocusAriaValueText(), 0 );}
          };
          this.addInputListener( valueHandlerListener );

          // update for the first focus now
          this.updateOnFocusAriaValueText();

          // @private - called by disposeAccessibleValueHandler to prevent memory leaks
          this._disposeAccessibleValueHandler = () => {
            this.removeInputListener( valueHandlerListener );
            this._valueProperty.unlink( valuePropertyListener );
          };
        },

        /**
         * @public
         * Update the aria-valuetext for the next time that this element is focused.
         */
        updateOnFocusAriaValueText() {
          if ( this.a11yCreateOnFocusAriaValueText ) {
            this.ariaValueText = this.a11yCreateOnFocusAriaValueText();
          }
        },

        /**
         * Call when disposing the type that this trait is mixed into.
         * @public
         */
        disposeAccessibleValueHandler() {
          this._disposeAccessibleValueHandler();
        }
      } );
    }
  };

  sun.register( 'AccessibleValueHandler', AccessibleValueHandler );

  return AccessibleValueHandler;
} );
<|endoftext|>