<commit_before>'use strict';

var stream_url = require('stream-url');
var lamp64 = require('swarm-stamp');
var Spec =  require('./Spec');
var Op = require('./Op');
var Syncable = require('./Syncable');
var OpStream =  require('./OpStream');
var util         = require("util");
var EventEmitter = require("events").EventEmitter;

// Host is the world of actual Syncable CRDT objects of various types.
// A (full) Swarm node is Host+Storage+Router.
function Host (options) {
    EventEmitter.call(this);
    // id, router, offset_ms
    this.options = options;
    this.ssn_id = null;
    this.db_id = null;
    this.clock = null;
    this.upstream = null;
    this.syncables = {};
    this.crdts = {};
    if (options.ssn_id) {
        this.ssn_id = options.ssn_id;
    }
    if (options.clock) {
        this.clock = options.clock;
    } else if (this.ssn_id) {
        this.clock = new lamp64.LamportClock(this.ssn_id);
    }
    if (options.db_id) {
        this.db_id = options.db_id;
    }
    if (options.upstream) {
        this.setUpstream(options.upstream);
    }
    if (!Host.multihost) {
        if (Host.localhost) {
            throw new Error('not in multihost mode');
        }
        Host.localhost = this;
    }
}
util.inherits(Host, EventEmitter);
module.exports = Host;
Host.debug = false;

Host.prototype.close = function () {
    if (Host.localhost===this) {
        Host.localhost = null;
    }
};

// mark-and-sweep kind-of distributed garbage collection
Host.prototype.gc = function (criteria) {
};

Host.prototype.setUpstream = function (stream) {
    this.upstream = new OpStream(stream, {
        peer_stamp: 'upstream'
    });
    var hs = this.handshake();
    this.upstream.sendHandshake(hs);
    this.upstream.setContext( new Spec.Parsed( '/Model!'+
        hs.stamp() + '.on' ));
};

Host.prototype.handshake = function () {
    if (!this.ssn_id || !this.db_id) { return null; }
    var key = new Spec('/Swarm+Host').add(this.db_id, '#')
        .add(this.time(),'!').add('.on');
    return new Op(key, '');
};

/**
 * Returns an unique Lamport timestamp on every invocation.
 * Swarm employs 30bit integer Unix-like timestamps starting epoch at
 * 1 Jan 2010. Timestamps are encoded as 5-char base64 tokens; in case
 * several events are generated by the same process at the same second
 * then sequence number is added so a timestamp may be more than 5
 * chars. The id of the Router (+user~session) is appended to the ts.
 */
Host.prototype.time = function () {
    return this.clock ? this.clock.issueTimestamp() : null;
};

// An innner state getter; needs /type#id spec for the object.
Host.prototype.getCRDT = function (obj) {
    if (obj._owner!==this) {
        throw new Error('an alien object');
    }
    return this.crdts[obj.spec().toString()];
};

// Applies a serialized operation (or a batch thereof) to this replica
Host.prototype.write = function (op) {

    var typeid = op.spec.typeid(), self=this;
    var syncable = this.syncables[typeid];
    if (!syncable) {
        throw new Error('syncable not open');
    }

    switch (op.op()) {
    // handshake cycle pseudo ops
    case 'on':
        op.patch && op.patch.forEach(function(op){
            self.write(op);
        });
        break;
    case 'off':
        break;
    case 'state':
        var type_fn = Syncable.types(op.type());
        if (!type_fn) {
            throw new Error('type unknown');
        }
        this.crdts[typeid] = new type_fn.Inner(op.value);
        break;
    case 'error':
        // As all the event/operation processing is asynchronous, we
        // cannot simply throw/catch exceptions over the network.
        // This method allows to send errors back asynchronously.
        // Sort of an asynchronous complaint mailbox :)
        console.error('something failed:', ''+op.spec, op.value);
    break;
    default: // actual ops
        var crdt = this.crdts[typeid];
        if (!crdt) {
            throw new Error('CRDT object was not initialized');
        }
        crdt.write(op);
    }

    crdt.updateSyncable(syncable);

    // NOTE: merged ops, like
    //      !time+src.in text
    // should have their *last* stamp in the spec
    // TODO reactions (Syncable? Inner? here?)
};

// The method must decide whether the source of the operation has
// the rights to perform it. The method may check both the nearest
// source and the original author of the op.
// If this method ever mentions 'this', that is a really bad sign.
// @returns {boolean}
Host.prototype.acl = function (op) {
    return true;
};

// Inner state lifecycle:
// * unknown (outer: default, '')
// * created fresh: constructor, sent
// * arrived : parse, create, rebuild()
// SCHEME
/**
 * Register a syncable object.
 */

// Incorporate a syncable into this replica.
// In case the object is newly created (like `new Model()`), Host
// assigns an id and saves it. For a known-id objects
// (like `new Model('2THjz01+gritzko~cA4')`) the state is queried
// from the storage/uplink. Till the state is received, the object
// is stateless (`syncable.version()===undefined && !syncable.hasState()`)
Host.prototype.adoptSyncable = function (syncable, init_op) {
    var type = syncable._type, on_op;
    var type_fn = Syncable.types[type];
    if (!type_fn || type_fn!==syncable.constructor) {
        throw new Error('not a registered syncable type');
    }
    if (syncable._owner) {
        throw new Error('the syncable belongs to some host already');
    }

    if (!syncable._id) { // it is a new object; let's add it to the system

        var stamp = this.time();
        syncable._id = stamp;
        var typeid = syncable.spec();
        var crdt = new syncable.constructor.Inner(null, syncable); // 0 state
        if (init_op) {
            var stamped_spec = typeid.add(stamp,'!').add(init_op.op(),'.');
            var stamped_op = new Op(stamped_spec, init_op.value);
            crdt.write(stamped_op);
        }
        this.crdts[typeid] = crdt;
        crdt._version = stamp;
        crdt.updateSyncable();

        // the state is sent up in the handshake as the uplink has nothing
        var state_op = new Op('!'+stamp+'.~state', crdt.toString());
        var on_spec = syncable.spec().add('.on');
        on_op = new Op(on_spec, '0', null, [state_op]);

    } else {
        var spec = syncable.spec().toString();
        if (spec in this.syncables) {
            return this.syncables[spec]; // there is such an object already
        }
        // !0 up
        on_op = new Op(syncable.spec().add('.on'), '');
    }

    this.syncables[syncable.spec().typeid()] = syncable;  // OK, remember it
    syncable._owner = this;
    if (this.upstream) {
        this.upstream.write(on_op);
    }

    return syncable;
};

Host.prototype.abandonSyncable = function (obj) {
    var typeid = obj.spec().typeid();
    if (typeid in this.syncables) {
        if (this.syncables[typeid]!==obj) {
            throw new Error('the registered object is different');
        }
        delete this.syncables[typeid];
        if (this.upstream) {
            var off_spec = obj.spec().add('.off');
            var off_op = new Op (off_spec, '');
            this.upstream.write(off_op);
        }
    }
};

// Retrieve an object by its spec (type and id).
// Optionally, invoke a callback once the state is actually available.
Host.prototype.get = function (spec, callback) {
    if (spec.constructor===Function) {
        spec = new Spec.Parsed('/'+spec._type);
    }
    if (spec.constructor!==Spec.Parsed) {
        spec = new Spec.Parsed(spec.toString());
    }
    if (!spec.type()) {
        throw new Error('type not specified');
    }
    var type_fn = Syncable.types[spec.type()];
    if (!type_fn) {
        throw new Error('type unknown: ' + spec.type());
    }
    var object;
    if (spec.id()) {
        var typeid = spec.typeid();
        object = this.syncables[typeid];
        if (!object) {
            object = new type_fn(null, null);
            object._id = spec.id();
            this.adoptSyncable(object);
        }
    } else {
        object = new type_fn(null, this);
    }
    if (callback) {
        object.onInit(callback);
    }
    return object;
};

// author a new operation
Host.prototype.submit = function (syncable, op_name, value) { // TODO sig
    if (syncable._owner!==this) {
        throw new Error('alien op submission');
    }
    var spec = syncable.spec().add(this.time(), '!').add(op_name,'.');
    var op = new Op(spec, value, this.id);
    this.write(op);
    if (this.upstream) {
        this.upstream.write(op);
    }
};

// FIXME  UNIFY CREATION !!!!
//   new -> link -> ...
Host.prototype.create = function (spec) {
    var type = new Spec(spec, '/').type();
    var type_constructor = Syncable.types[type];
    if (!type_constructor) {
        throw new Error('type unknown: ' + spec);
    }
    var stamp = this.time();
    var state = new Spec(type, '/').add(stamp, '#').add('!0.state');
    var op = new Op(state, '', this.id);
    var inner = new type_constructor.Inner(op);
    this.crdts[op.spec.filter('/#')] = inner;
    this.upstream.write(op, this);
    return new type_constructor(stamp, this);
};
<commit_msg>fix(syncable): fix time/version handling in Host.js<commit_after>'use strict';

var stream_url = require('stream-url');
var lamp64 = require('swarm-stamp');
var Spec =  require('./Spec');
var Op = require('./Op');
var Syncable = require('./Syncable');
var OpStream =  require('./OpStream');
var util         = require("util");
var EventEmitter = require("events").EventEmitter;

// Host is the world of actual Syncable CRDT objects of various types.
// A (full) Swarm node is Host+Storage+Router.
function Host (options) {
    EventEmitter.call(this);
    // id, router, offset_ms
    this.options = options;
    this.ssn_id = null;
    this.db_id = null;
    this.clock = null;
    this.upstream = null;
    this.syncables = {};
    this.crdts = {};
    if (options.ssn_id) {
        this.ssn_id = options.ssn_id;
    }
    if (options.clock) {
        this.clock = options.clock;
    } else if (this.ssn_id) {
        this.clock = new lamp64.Clock(this.ssn_id);
    }
    if (options.db_id) {
        this.db_id = options.db_id;
    }
    if (options.upstream) {
        this.setUpstream(options.upstream);
    }
    if (!Host.multihost) {
        if (Host.localhost) {
            throw new Error('not in multihost mode');
        }
        Host.localhost = this;
    }
}
util.inherits(Host, EventEmitter);
module.exports = Host;
Host.debug = false;

Host.prototype.close = function () {
    if (Host.localhost===this) {
        Host.localhost = null;
    }
};

// mark-and-sweep kind-of distributed garbage collection
Host.prototype.gc = function (criteria) {
};

Host.prototype.setUpstream = function (stream) {
    this.upstream = new OpStream(stream, {
        peer_stamp: 'upstream'
    });
    var hs = this.handshake();
    this.upstream.sendHandshake(hs);
    this.upstream.setContext( new Spec.Parsed( '/Model!'+
        hs.stamp() + '.on' ));
};

Host.prototype.handshake = function () {
    if (!this.ssn_id || !this.db_id) { return null; }
    var key = new Spec('/Swarm+Host').add(this.db_id, '#')
        .add(this.time(),'!').add('.on');
    return new Op(key, '');
};

/**
 * Returns an unique Lamport timestamp on every invocation.
 * Swarm employs 30bit integer Unix-like timestamps starting epoch at
 * 1 Jan 2010. Timestamps are encoded as 5-char base64 tokens; in case
 * several events are generated by the same process at the same second
 * then sequence number is added so a timestamp may be more than 5
 * chars. The id of the Router (+user~session) is appended to the ts.
 */
Host.prototype.time = function () {
    return this.clock ? this.clock.issueTimestamp() : null;
};

// An innner state getter; needs /type#id spec for the object.
Host.prototype.getCRDT = function (obj) {
    if (obj._type) {
        if (obj._owner!==this) {
            throw new Error('an alien object');
        }
        return this.crdts[obj.typeid()];
    } else {
        return this.crdts[new Spec.Parsed(obj).typeid()];
    }
};

// Applies a serialized operation (or a batch thereof) to this replica
Host.prototype.write = function (op) {

    var typeid = op.spec.typeid(), self=this;
    var syncable = this.syncables[typeid];
    if (!syncable) {
        throw new Error('syncable not open');
    }

    switch (op.op()) {
    // handshake cycle pseudo ops
    case 'on':
        op.patch && op.patch.forEach(function(op){
            self.write(op);
        });
        break;
    case 'off':
        break;
    case 'state':
        var type_fn = Syncable.types(op.type());
        if (!type_fn) {
            throw new Error('type unknown');
        }
        this.crdts[typeid] = new type_fn.Inner(op.value);
        break;
    case 'error':
        // As all the event/operation processing is asynchronous, we
        // cannot simply throw/catch exceptions over the network.
        // This method allows to send errors back asynchronously.
        // Sort of an asynchronous complaint mailbox :)
        console.error('something failed:', ''+op.spec, op.value);
    break;
    default: // actual ops
        var crdt = this.crdts[typeid];
        if (!crdt) {
            throw new Error('CRDT object was not initialized');
        }
        crdt.write(op);
    }

    crdt.updateSyncable(syncable);
    syncable._version = crdt._version = op.stamp();

    // NOTE: merged ops, like
    //      !time+src.in text
    // should have their *last* stamp in the spec
    // TODO reactions (Syncable? Inner? here?)
};

// The method must decide whether the source of the operation has
// the rights to perform it. The method may check both the nearest
// source and the original author of the op.
// If this method ever mentions 'this', that is a really bad sign.
// @returns {boolean}
Host.prototype.acl = function (op) {
    return true;
};

// Inner state lifecycle:
// * unknown (outer: default, '')
// * created fresh: constructor, sent
// * arrived : parse, create, rebuild()
// SCHEME
/**
 * Register a syncable object.
 */

// Incorporate a syncable into this replica.
// In case the object is newly created (like `new Model()`), Host
// assigns an id and saves it. For a known-id objects
// (like `new Model('2THjz01+gritzko~cA4')`) the state is queried
// from the storage/uplink. Till the state is received, the object
// is stateless (`syncable.version()===undefined && !syncable.hasState()`)
Host.prototype.adoptSyncable = function (syncable, init_op) {
    var type = syncable._type, on_op;
    var type_fn = Syncable.types[type];
    if (!type_fn || type_fn!==syncable.constructor) {
        throw new Error('not a registered syncable type');
    }
    if (syncable._owner) {
        throw new Error('the syncable belongs to some host already');
    }

    if (!syncable._id) { // it is a new object; let's add it to the system

        var stamp = this.time();
        syncable._id = stamp;
        var typeid = syncable.spec();
        var crdt = new syncable.constructor.Inner(null, syncable); // 0 state
        if (init_op) {
            var stamped_spec = typeid.add(stamp,'!').add(init_op.op(),'.');
            var stamped_op = new Op(stamped_spec, init_op.value);
            crdt.write(stamped_op);
        }
        this.crdts[typeid] = crdt;
        crdt._version = stamp;
        crdt.updateSyncable();
        syncable._version = crdt._version = stamp;

        // the state is sent up in the handshake as the uplink has nothing
        var state_op = new Op('!'+stamp+'.~state', crdt.toString());
        var on_spec = syncable.spec().add('.on');
        on_op = new Op(on_spec, '0', null, [state_op]);

    } else {
        var spec = syncable.spec().toString();
        if (spec in this.syncables) {
            return this.syncables[spec]; // there is such an object already
        }
        // !0 up
        on_op = new Op(syncable.spec().add('.on'), '');
    }

    this.syncables[syncable.spec().typeid()] = syncable;  // OK, remember it
    syncable._owner = this;
    if (this.upstream) {
        this.upstream.write(on_op);
    }

    return syncable;
};

Host.prototype.abandonSyncable = function (obj) {
    var typeid = obj.spec().typeid();
    if (typeid in this.syncables) {
        if (this.syncables[typeid]!==obj) {
            throw new Error('the registered object is different');
        }
        delete this.syncables[typeid];
        if (this.upstream) {
            var off_spec = obj.spec().add('.off');
            var off_op = new Op (off_spec, '');
            this.upstream.write(off_op);
        }
    }
};

// Retrieve an object by its spec (type and id).
// Optionally, invoke a callback once the state is actually available.
Host.prototype.get = function (spec, callback) {
    if (spec.constructor===Function) {
        spec = new Spec.Parsed('/'+spec._type);
    }
    if (spec.constructor!==Spec.Parsed) {
        spec = new Spec.Parsed(spec.toString());
    }
    if (!spec.type()) {
        throw new Error('type not specified');
    }
    var type_fn = Syncable.types[spec.type()];
    if (!type_fn) {
        throw new Error('type unknown: ' + spec.type());
    }
    var object;
    if (spec.id()) {
        var typeid = spec.typeid();
        object = this.syncables[typeid];
        if (!object) {
            object = new type_fn(null, null);
            object._id = spec.id();
            this.adoptSyncable(object);
        }
    } else {
        object = new type_fn(null, this);
    }
    if (callback) {
        object.onInit(callback);
    }
    return object;
};

// author a new operation
Host.prototype.submit = function (syncable, op_name, value) { // TODO sig
    if (syncable._owner!==this) {
        throw new Error('alien op submission');
    }
    var spec = syncable.spec().add(this.time(), '!').add(op_name,'.');
    var op = new Op(spec, value, this.id);
    this.write(op);
    if (this.upstream) {
        this.upstream.write(op);
    }
};

// FIXME  UNIFY CREATION !!!!
//   new -> link -> ...
Host.prototype.create = function (spec) {
    var type = new Spec(spec, '/').type();
    var type_constructor = Syncable.types[type];
    if (!type_constructor) {
        throw new Error('type unknown: ' + spec);
    }
    var stamp = this.time();
    var state = new Spec(type, '/').add(stamp, '#').add('!0.state');
    var op = new Op(state, '', this.id);
    var inner = new type_constructor.Inner(op);
    this.crdts[op.spec.filter('/#')] = inner;
    this.upstream.write(op, this);
    return new type_constructor(stamp, this);
};
<|endoftext|>


<commit_before>Later = Npm.require('later');

Later.date.localTime(); // corresponds to SyncedCron.options.utc: true;

var TestEntry = {
  name: 'Test Job',
  schedule: function(parser) {
    return parser.cron('15 10 * * ? *'); // not required
  },
  job: function() {
    return 'ran';
  }
};

Tinytest.add('Syncing works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // added the entry ok
  SyncedCron.add(TestEntry);
  test.equal(_.keys(SyncedCron._entries).length, 1);

  var entry = SyncedCron._entries[TestEntry.name];
  var intendedAt = new Date(); //whatever

  // first run
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1);
  var jobHistory1 = SyncedCron._collection.findOne();
  test.equal(jobHistory1.result, 'ran');

  // second run
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1); // should still be 1
  var jobHistory2 = SyncedCron._collection.findOne();
  test.equal(jobHistory1._id, jobHistory2._id);
});

Tinytest.add('Exceptions work', function(test) {
  SyncedCron._reset();
  SyncedCron.add(_.extend({}, TestEntry, {
      job: function() {
        throw new Meteor.Error('Haha, gotcha!');
      }
    })
  );

  var entry = SyncedCron._entries[TestEntry.name];
  var intendedAt = new Date(); //whatever

  // error without result
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1);
  var jobHistory1 = SyncedCron._collection.findOne();
  test.equal(jobHistory1.result, undefined);
  test.matches(jobHistory1.error, /Haha, gotcha/);
});

Tinytest.add('SyncedCron.nextScheduledAtDate works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // addd 2 entries
  SyncedCron.add(TestEntry);

  var entry2 = _.extend({}, TestEntry, {
    name: 'Test Job2',
    schedule: function(parser) {
      return parser.cron('30 11 * * ? *');
    }
  });
  SyncedCron.add(entry2);

  test.equal(_.keys(SyncedCron._entries).length, 2);

  SyncedCron.start();

  var date = SyncedCron.nextScheduledAtDate(entry2.name);
  var correctDate = Later.schedule(entry2.schedule(Later.parse)).next(1);

  test.equal(date, correctDate);
});

// Tests SyncedCron.remove in the process
Tinytest.add('SyncedCron.stop works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // addd 2 entries
  SyncedCron.add(TestEntry);

  var entry2 = _.extend({}, TestEntry, {
    name: 'Test Job2',
    schedule: function(parser) {
      return parser.cron('30 11 * * ? *');
    }
  });
  SyncedCron.add(entry2);

  SyncedCron.start();

  test.equal(_.keys(SyncedCron._entries).length, 2);

  SyncedCron.stop();

  test.equal(_.keys(SyncedCron._entries).length, 0);
});

// Tests SyncedCron.remove in the process
Tinytest.add('SyncedCron.add starts by it self when running', function(test) {
  SyncedCron._reset();

  test.equal(SyncedCron._collection.find().count(), 0);
  test.equal(SyncedCron.running, false);
  Log._intercept(2);

  SyncedCron.start();

  test.equal(SyncedCron.running, true);

  // addd 1 entries
  SyncedCron.add(TestEntry);

  test.equal(_.keys(SyncedCron._entries).length, 1);

  SyncedCron.stop();

  var intercepted = Log._intercepted();
  test.equal(intercepted.length, 2);

  test.equal(SyncedCron.running, false);
  test.equal(_.keys(SyncedCron._entries).length, 0);
});
<commit_msg>Cleaning whitespaces.<commit_after>Later = Npm.require('later');

Later.date.localTime(); // corresponds to SyncedCron.options.utc: true;

var TestEntry = {
  name: 'Test Job',
  schedule: function(parser) {
    return parser.cron('15 10 * * ? *'); // not required
  },
  job: function() {
    return 'ran';
  }
};

Tinytest.add('Syncing works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // added the entry ok
  SyncedCron.add(TestEntry);
  test.equal(_.keys(SyncedCron._entries).length, 1);

  var entry = SyncedCron._entries[TestEntry.name];
  var intendedAt = new Date(); //whatever

  // first run
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1);
  var jobHistory1 = SyncedCron._collection.findOne();
  test.equal(jobHistory1.result, 'ran');

  // second run
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1); // should still be 1
  var jobHistory2 = SyncedCron._collection.findOne();
  test.equal(jobHistory1._id, jobHistory2._id);
});

Tinytest.add('Exceptions work', function(test) {
  SyncedCron._reset();
  SyncedCron.add(_.extend({}, TestEntry, {
      job: function() {
        throw new Meteor.Error('Haha, gotcha!');
      }
    })
  );

  var entry = SyncedCron._entries[TestEntry.name];
  var intendedAt = new Date(); //whatever

  // error without result
  SyncedCron._entryWrapper(entry)(intendedAt);
  test.equal(SyncedCron._collection.find().count(), 1);
  var jobHistory1 = SyncedCron._collection.findOne();
  test.equal(jobHistory1.result, undefined);
  test.matches(jobHistory1.error, /Haha, gotcha/);
});

Tinytest.add('SyncedCron.nextScheduledAtDate works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // addd 2 entries
  SyncedCron.add(TestEntry);

  var entry2 = _.extend({}, TestEntry, {
    name: 'Test Job2',
    schedule: function(parser) {
      return parser.cron('30 11 * * ? *');
    }
  });
  SyncedCron.add(entry2);

  test.equal(_.keys(SyncedCron._entries).length, 2);

  SyncedCron.start();

  var date = SyncedCron.nextScheduledAtDate(entry2.name);
  var correctDate = Later.schedule(entry2.schedule(Later.parse)).next(1);

  test.equal(date, correctDate);
});

// Tests SyncedCron.remove in the process
Tinytest.add('SyncedCron.stop works', function(test) {
  SyncedCron._reset();
  test.equal(SyncedCron._collection.find().count(), 0);

  // addd 2 entries
  SyncedCron.add(TestEntry);

  var entry2 = _.extend({}, TestEntry, {
    name: 'Test Job2',
    schedule: function(parser) {
      return parser.cron('30 11 * * ? *');
    }
  });
  SyncedCron.add(entry2);

  SyncedCron.start();

  test.equal(_.keys(SyncedCron._entries).length, 2);

  SyncedCron.stop();

  test.equal(_.keys(SyncedCron._entries).length, 0);
});

// Tests SyncedCron.remove in the process
Tinytest.add('SyncedCron.add starts by it self when running', function(test) {
  SyncedCron._reset();

  test.equal(SyncedCron._collection.find().count(), 0);
  test.equal(SyncedCron.running, false);
  Log._intercept(2);

  SyncedCron.start();

  test.equal(SyncedCron.running, true);

  // addd 1 entries
  SyncedCron.add(TestEntry);

  test.equal(_.keys(SyncedCron._entries).length, 1);

  SyncedCron.stop();

  var intercepted = Log._intercepted();
  test.equal(intercepted.length, 2);

  test.equal(SyncedCron.running, false);
  test.equal(_.keys(SyncedCron._entries).length, 0);
});
<|endoftext|>


<commit_before>/*global Screw before after describe it expect equal equal_date match psc */

Timeline_ajax_url = "/main/simile-timeline/2.3.0/timeline_ajax/simile-ajax-api.js?bundle=true";
Timeline_urlPrefix = "/main/simile-timeline/2.3.0/timeline_js/";
Timeline_parameters = "bundle=true";

require_spec("spec_helper.js");
require_spec('sync-updater.js');
// TODO: this isn't working
// require_main("simile-timeline/2.3.0/timeline_js/timeline-api.js");
// require_main("simile-timeline/2.3.0/timeline_js/timeline-bundle.js");
require_main("psc-tools/misc.js");
require_main("subject/schedule-structure.js");
require_main("subject/schedule-timeline.js");

Screw.Unit(function () {
  describe("Event conversion", function () {
    describe("For scheduled activities", function () {
      var sa, actualEvent;

      before(function () {
        sa = {
          current_state: {
            'date': '2009-03-01',
            'name': 'canceled'
          },
          activity: { name: 'Activity B', type: 'Other' },
          details: "Something happens first",
          study_segment: "Treatment: X",
          study: "NU 09A0"
        };

        actualEvent = function () {
          var sched = new psc.subject.Schedule({
            "days": {
              "2009-03-01": {
                "activities": [ sa ]
              }
            }
          })
          return psc.subject.ScheduleTimeline.eventForScheduledActivity(
            sched['days']['2009-03-01']['activities'][0]);
        };
      });

      it("generates an instant event", function () {
        expect(actualEvent().durationEvent).to(equal, false);
      });

      it("has the right start", function () {
        expect(actualEvent().start).to(equal_date, new Date(2009, 2, 1));
      });

      it("has a title", function () {
        expect(actualEvent().title).to(equal, "Activity B");
      });

      it("has the segment in the description", function () {
        expect(actualEvent().description).to(match, "Treatment: X");
      });

      it("has the study in the description", function () {
        expect(actualEvent().description).to(match, "NU 09A0");
      });

      it("has an image based on the state", function () {
        expect(actualEvent().image).to(equal, "/images/canceled.png");
      });

      it("the image path is app relative", function () {
        psc.tools.Uris.INTERNAL_URI_BASE_PATH = "/foo";
        expect(actualEvent().image).to(equal, "/foo/images/canceled.png");
      });
    });

    describe("For segments", function () {
      var segment, actualEvent;

      before(function () {
        segment = new psc.subject.ScheduledStudySegment("NU 1402", "Treatment: B");
        segment.addActivity({
          current_state: { 'date': '2009-04-06' }
        });

        actualEvent = function () {
          return psc.subject.ScheduleTimeline.eventForScheduledStudySegment(segment);
        };
      });

      it("is a duration event", function () {
        expect(actualEvent().durationEvent).to(equal, true);
      });

      it("has the right start", function () {
        expect(actualEvent().start).to(equal_utc_date, new Date(Date.UTC(2009, 3, 6)));
      });

      it("has the right end", function () {
        expect(actualEvent().end).to(equal_utc_date, new Date(Date.UTC(2009, 3, 6, 23, 59, 59, 999)));
      });

      it("has a title reflecting the segment name", function () {
        expect(actualEvent().title).to(match, "Treatment: B");
      });

      it("has a title reflecting the study name", function () {
        expect(actualEvent().title).to(match, "NU 1402");
      });
    });
  });
});<commit_msg>Fix test broken in the process of hastily fixing #723.<commit_after>/*global Screw before after describe it expect equal equal_date match psc */

Timeline_ajax_url = "/main/simile-timeline/2.3.0/timeline_ajax/simile-ajax-api.js?bundle=true";
Timeline_urlPrefix = "/main/simile-timeline/2.3.0/timeline_js/";
Timeline_parameters = "bundle=true";

require_spec("spec_helper.js");
require_spec('sync-updater.js');
// TODO: this isn't working
// require_main("simile-timeline/2.3.0/timeline_js/timeline-api.js");
// require_main("simile-timeline/2.3.0/timeline_js/timeline-bundle.js");
require_main("psc-tools/misc.js");
require_main("subject/schedule-structure.js");
require_main("subject/schedule-timeline.js");

Screw.Unit(function () {
  describe("Event conversion", function () {
    describe("For scheduled activities", function () {
      var sa, actualEvent;

      before(function () {
        sa = {
          current_state: {
            'date': '2009-03-01',
            'name': 'canceled'
          },
          activity: { name: 'Activity B', type: 'Other' },
          details: "Something happens first",
          study_segment: "Treatment: X",
          study: "NU 09A0"
        };

        actualEvent = function () {
          var sched = new psc.subject.Schedule({
            "days": {
              "2009-03-01": {
                "activities": [ sa ]
              }
            }
          })
          return psc.subject.ScheduleTimeline.eventForScheduledActivity(
            sched['days']['2009-03-01']['activities'][0]);
        };
      });

      it("generates an instant event", function () {
        expect(actualEvent().durationEvent).to(equal, false);
      });

      it("has the right start", function () {
        expect(actualEvent().start).to(equal_date, new Date(2009, 2, 1));
      });

      it("has a title", function () {
        expect(actualEvent().title).to(equal, "Activity B");
      });

      it("has the segment in the description", function () {
        expect(actualEvent().description).to(match, "Treatment: X");
      });

      it("has the study in the description", function () {
        expect(actualEvent().description).to(match, "NU 09A0");
      });

      it("has an image based on the state", function () {
        expect(actualEvent().image).to(equal, "/images/canceled.png");
      });

      it("the image path is app relative", function () {
        psc.tools.Uris.INTERNAL_URI_BASE_PATH = "/foo";
        expect(actualEvent().image).to(equal, "/foo/images/canceled.png");
      });
    });

    describe("For segments", function () {
      var segment, actualEvent;

      before(function () {
        actualEvent = function () {
          var sched = new psc.subject.Schedule({
            "days": {
              "2009-04-06": {
              }
            },

            "study_segments": [
              {
                name: "Treatment: B",
                planned: {
                  study: {
                    assigned_identifier: "NU 1402"
                  }
                },
                range: {
                  start_date: "2009-04-06",
                  stop_date: "2009-04-06"
                }
              }
            ]
          });

          return psc.subject.ScheduleTimeline.eventForScheduledStudySegment(sched.study_segments[0]);
        };
      });

      it("is a duration event", function () {
        expect(actualEvent().durationEvent).to(equal, true);
      });

      it("has the right start", function () {
        expect(actualEvent().start).to(equal_utc_date, new Date(Date.UTC(2009, 3, 6)));
      });

      it("has the right end", function () {
        expect(actualEvent().end).to(equal_utc_date, new Date(Date.UTC(2009, 3, 6, 23, 59, 59, 999)));
      });

      it("has a title reflecting the segment name", function () {
        expect(actualEvent().title).to(match, "Treatment: B");
      });

      it("has a title reflecting the study name", function () {
        expect(actualEvent().title).to(match, "NU 1402");
      });
    });
  });
});<|endoftext|>


<commit_before>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

// Unique place to configure the browsers which are used in the different CI jobs in Sauce Labs (SL)
// and BrowserStack (BS).
// If the target is set to null, then the browser is not run anywhere during CI.
// If a category becomes empty (e.g. BS and required), then the corresponding job must be commented
// out in Travis configuration.
var CIconfiguration = {
  'Chrome': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Firefox': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'ChromeBeta': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: false}},
  'ChromeDev': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  // FirefoxBeta and FirefoxDev should be target:'BS' or target:'SL', and required:true
  // Currently deactivated due to https://github.com/angular/angular/issues/7560
  'FirefoxBeta': {unitTest: {target: null, required: true}, e2e: {target: null, required: false}},
  'FirefoxDev': {unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'IE9': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'IE10': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'IE11': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Edge': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.4': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android5': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Safari7': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari8': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari9': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari10': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS7': {unitTest: {target: 'BS', required: true}, e2e: {target: null, required: true}},
  'iOS8': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS9': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS10': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'WindowsPhone': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}}
};

var customLaunchers = {
  'DartiumWithWebPlatform':
      {base: 'Dartium', flags: ['--enable-experimental-web-platform-features']},
  'ChromeNoSandbox': {base: 'Chrome', flags: ['--no-sandbox']},
  'SL_CHROME': {base: 'SauceLabs', browserName: 'chrome', version: '60'},
  'SL_CHROMEBETA': {base: 'SauceLabs', browserName: 'chrome', version: 'beta'},
  'SL_CHROMEDEV': {base: 'SauceLabs', browserName: 'chrome', version: 'dev'},
  'SL_FIREFOX': {base: 'SauceLabs', browserName: 'firefox', version: '54'},
  'SL_FIREFOXBETA':
      {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'beta'},
  'SL_FIREFOXDEV':
      {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'dev'},
  'SL_SAFARI7': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.9', version: '7.0'},
  'SL_SAFARI8': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.10', version: '8.0'},
  'SL_SAFARI9': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.11', version: '9.0'},
  'SL_SAFARI10':
      {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.12', version: '10.0'},
  'SL_IOS7': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '7.1'},
  'SL_IOS8': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '8.4'},
  'SL_IOS9': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '9.3'},
  'SL_IOS10': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '10.0'},
  'SL_IE9':
      {base: 'SauceLabs', browserName: 'internet explorer', platform: 'Windows 2008', version: '9'},
  'SL_IE10': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2012',
    version: '10'
  },
  'SL_IE11':
      {base: 'SauceLabs', browserName: 'internet explorer', platform: 'Windows 8.1', version: '11'},
  'SL_EDGE': {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    platform: 'Windows 10',
    version: '14.14393'
  },
  'SL_ANDROID4.1': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.1'},
  'SL_ANDROID4.2': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.2'},
  'SL_ANDROID4.3': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.3'},
  'SL_ANDROID4.4': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.4'},
  'SL_ANDROID5': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '5.1'},

  'BS_CHROME': {base: 'BrowserStack', browser: 'chrome', os: 'OS X', os_version: 'Yosemite'},
  'BS_FIREFOX': {base: 'BrowserStack', browser: 'firefox', os: 'Windows', os_version: '10'},
  'BS_SAFARI7': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Mavericks'},
  'BS_SAFARI8': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Yosemite'},
  'BS_SAFARI9': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'El Capitan'},
  'BS_SAFARI10': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Sierra'},
  'BS_IOS7': {base: 'BrowserStack', device: 'iPhone 5S', os: 'ios', os_version: '7.0'},
  'BS_IOS8': {base: 'BrowserStack', device: 'iPhone 6', os: 'ios', os_version: '8.3'},
  'BS_IOS9': {base: 'BrowserStack', device: 'iPhone 6S', os: 'ios', os_version: '9.1'},
  'BS_IOS10': {base: 'BrowserStack', device: 'iPhone SE', os: 'ios', os_version: '10.0'},
  'BS_IE9':
      {base: 'BrowserStack', browser: 'ie', browser_version: '9.0', os: 'Windows', os_version: '7'},
  'BS_IE10': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '10.1',
    os: 'Windows',
    os_version: '8'
  },
  'BS_IE11': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '11.0',
    os: 'Windows',
    os_version: '10'
  },
  'BS_EDGE': {base: 'BrowserStack', browser: 'edge', os: 'Windows', os_version: '10'},
  'BS_WINDOWSPHONE':
      {base: 'BrowserStack', device: 'Nokia Lumia 930', os: 'winphone', os_version: '8.1'},
  'BS_ANDROID5': {base: 'BrowserStack', device: 'Google Nexus 5', os: 'android', os_version: '5.0'},
  'BS_ANDROID4.4': {base: 'BrowserStack', device: 'HTC One M8', os: 'android', os_version: '4.4'},
  'BS_ANDROID4.3':
      {base: 'BrowserStack', device: 'Samsung Galaxy S4', os: 'android', os_version: '4.3'},
  'BS_ANDROID4.2':
      {base: 'BrowserStack', device: 'Google Nexus 4', os: 'android', os_version: '4.2'},
  'BS_ANDROID4.1':
      {base: 'BrowserStack', device: 'Google Nexus 7', os: 'android', os_version: '4.1'}
};

var sauceAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {
    return customLaunchers[item].base == 'SauceLabs';
  }),
  'DESKTOP': [
    'SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7',
    'SL_SAFARI8', 'SL_SAFARI9', 'SL_SAFARI10'
  ],
  'MOBILE': [
    'SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5', 'SL_IOS7',
    'SL_IOS8', 'SL_IOS9', 'SL_IOS10'
  ],
  'ANDROID': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5'],
  'IE': ['SL_IE9', 'SL_IE10', 'SL_IE11'],
  'IOS': ['SL_IOS7', 'SL_IOS8', 'SL_IOS9', 'SL_IOS10'],
  'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9', 'SL_SAFARI10'],
  'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'],
  'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false)
};

var browserstackAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {
    return customLaunchers[item].base == 'BrowserStack';
  }),
  'DESKTOP': [
    'BS_CHROME', 'BS_FIREFOX', 'BS_IE9', 'BS_IE10', 'BS_IE11', 'BS_EDGE', 'BS_SAFARI7',
    'BS_SAFARI8', 'BS_SAFARI9', 'BS_SAFARI10'
  ],
  'MOBILE': [
    'BS_ANDROID4.3', 'BS_ANDROID4.4', 'BS_IOS7', 'BS_IOS8', 'BS_IOS9', 'BS_IOS10', 'BS_WINDOWSPHONE'
  ],
  'ANDROID': ['BS_ANDROID4.3', 'BS_ANDROID4.4'],
  'IE': ['BS_IE9', 'BS_IE10', 'BS_IE11'],
  'IOS': ['BS_IOS7', 'BS_IOS8', 'BS_IOS9', 'BS_IOS10'],
  'SAFARI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9', 'BS_SAFARI10'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'BS', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'BS', false)
};

module.exports = {
  customLaunchers: customLaunchers,
  sauceAliases: sauceAliases,
  browserstackAliases: browserstackAliases
};

function buildConfiguration(type, target, required) {
  return Object.keys(CIconfiguration)
      .filter((item) => {
        var conf = CIconfiguration[item][type];
        return conf.required === required && conf.target === target;
      })
      .map((item) => target + '_' + item.toUpperCase());
}
<commit_msg>ci: add Android 6 and 7 (#18803)<commit_after>/**
 * @license
 * Copyright Google Inc. All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */

// Unique place to configure the browsers which are used in the different CI jobs in Sauce Labs (SL)
// and BrowserStack (BS).
// If the target is set to null, then the browser is not run anywhere during CI.
// If a category becomes empty (e.g. BS and required), then the corresponding job must be commented
// out in Travis configuration.
var CIconfiguration = {
  'Chrome': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Firefox': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'ChromeBeta': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: false}},
  'ChromeDev': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  // FirefoxBeta and FirefoxDev should be target:'BS' or target:'SL', and required:true
  // Currently deactivated due to https://github.com/angular/angular/issues/7560
  'FirefoxBeta': {unitTest: {target: null, required: true}, e2e: {target: null, required: false}},
  'FirefoxDev': {unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'IE9': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'IE10': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'IE11': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Edge': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.4': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android5': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android6': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Android7': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Safari7': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari8': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari9': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari10': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS7': {unitTest: {target: 'BS', required: true}, e2e: {target: null, required: true}},
  'iOS8': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS9': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS10': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'WindowsPhone': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}}
};

var customLaunchers = {
  'DartiumWithWebPlatform':
      {base: 'Dartium', flags: ['--enable-experimental-web-platform-features']},
  'ChromeNoSandbox': {base: 'Chrome', flags: ['--no-sandbox']},
  'SL_CHROME': {base: 'SauceLabs', browserName: 'chrome', version: '60'},
  'SL_CHROMEBETA': {base: 'SauceLabs', browserName: 'chrome', version: 'beta'},
  'SL_CHROMEDEV': {base: 'SauceLabs', browserName: 'chrome', version: 'dev'},
  'SL_FIREFOX': {base: 'SauceLabs', browserName: 'firefox', version: '54'},
  'SL_FIREFOXBETA':
      {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'beta'},
  'SL_FIREFOXDEV':
      {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'dev'},
  'SL_SAFARI7': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.9', version: '7.0'},
  'SL_SAFARI8': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.10', version: '8.0'},
  'SL_SAFARI9': {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.11', version: '9.0'},
  'SL_SAFARI10':
      {base: 'SauceLabs', browserName: 'safari', platform: 'OS X 10.12', version: '10.0'},
  'SL_IOS7': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '7.1'},
  'SL_IOS8': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '8.4'},
  'SL_IOS9': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '9.3'},
  'SL_IOS10': {base: 'SauceLabs', browserName: 'iphone', platform: 'OS X 10.10', version: '10.0'},
  'SL_IE9':
      {base: 'SauceLabs', browserName: 'internet explorer', platform: 'Windows 2008', version: '9'},
  'SL_IE10': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2012',
    version: '10'
  },
  'SL_IE11':
      {base: 'SauceLabs', browserName: 'internet explorer', platform: 'Windows 8.1', version: '11'},
  'SL_EDGE': {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    platform: 'Windows 10',
    version: '14.14393'
  },
  'SL_ANDROID4.1': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.1'},
  'SL_ANDROID4.2': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.2'},
  'SL_ANDROID4.3': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.3'},
  'SL_ANDROID4.4': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '4.4'},
  'SL_ANDROID5': {base: 'SauceLabs', browserName: 'android', platform: 'Linux', version: '5.1'},
  'SL_ANDROID6': {
    base: 'SauceLabs',
    browserName: 'Chrome',
    platform: 'Android',
    version: '6.0',
    device: 'Android Emulator'
  },
  'SL_ANDROID7': {
    base: 'SauceLabs',
    browserName: 'Chrome',
    platform: 'Android',
    version: '7.1',
    device: 'Android GoogleAPI Emulator'
  },

  'BS_CHROME': {base: 'BrowserStack', browser: 'chrome', os: 'OS X', os_version: 'Yosemite'},
  'BS_FIREFOX': {base: 'BrowserStack', browser: 'firefox', os: 'Windows', os_version: '10'},
  'BS_SAFARI7': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Mavericks'},
  'BS_SAFARI8': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Yosemite'},
  'BS_SAFARI9': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'El Capitan'},
  'BS_SAFARI10': {base: 'BrowserStack', browser: 'safari', os: 'OS X', os_version: 'Sierra'},
  'BS_IOS7': {base: 'BrowserStack', device: 'iPhone 5S', os: 'ios', os_version: '7.0'},
  'BS_IOS8': {base: 'BrowserStack', device: 'iPhone 6', os: 'ios', os_version: '8.3'},
  'BS_IOS9': {base: 'BrowserStack', device: 'iPhone 6S', os: 'ios', os_version: '9.1'},
  'BS_IOS10': {base: 'BrowserStack', device: 'iPhone SE', os: 'ios', os_version: '10.0'},
  'BS_IE9':
      {base: 'BrowserStack', browser: 'ie', browser_version: '9.0', os: 'Windows', os_version: '7'},
  'BS_IE10': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '10.1',
    os: 'Windows',
    os_version: '8'
  },
  'BS_IE11': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '11.0',
    os: 'Windows',
    os_version: '10'
  },
  'BS_EDGE': {base: 'BrowserStack', browser: 'edge', os: 'Windows', os_version: '10'},
  'BS_WINDOWSPHONE':
      {base: 'BrowserStack', device: 'Nokia Lumia 930', os: 'winphone', os_version: '8.1'},
  'BS_ANDROID7': {base: 'BrowserStack', device: 'Google Pixel', os: 'android', os_version: '7.1'},
  'BS_ANDROID6': {base: 'BrowserStack', device: 'Google Nexus 6', os: 'android', os_version: '6.0'},
  'BS_ANDROID5': {base: 'BrowserStack', device: 'Google Nexus 5', os: 'android', os_version: '5.0'},
  'BS_ANDROID4.4': {base: 'BrowserStack', device: 'HTC One M8', os: 'android', os_version: '4.4'},
  'BS_ANDROID4.3':
      {base: 'BrowserStack', device: 'Samsung Galaxy S4', os: 'android', os_version: '4.3'},
  'BS_ANDROID4.2':
      {base: 'BrowserStack', device: 'Google Nexus 4', os: 'android', os_version: '4.2'},
  'BS_ANDROID4.1':
      {base: 'BrowserStack', device: 'Google Nexus 7', os: 'android', os_version: '4.1'}
};

var sauceAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {
    return customLaunchers[item].base == 'SauceLabs';
  }),
  'DESKTOP': [
    'SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7',
    'SL_SAFARI8', 'SL_SAFARI9', 'SL_SAFARI10'
  ],
  'MOBILE': [
    'SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5',
    'SL_ANDROID6', 'SL_ANDROID7', 'SL_IOS7', 'SL_IOS8', 'SL_IOS9', 'SL_IOS10'
  ],
  'ANDROID': [
    'SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5',
    'SL_ANDROID6', 'SL_ANDROID7'
  ],
  'IE': ['SL_IE9', 'SL_IE10', 'SL_IE11'],
  'IOS': ['SL_IOS7', 'SL_IOS8', 'SL_IOS9', 'SL_IOS10'],
  'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9', 'SL_SAFARI10'],
  'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'],
  'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false)
};

var browserstackAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {
    return customLaunchers[item].base == 'BrowserStack';
  }),
  'DESKTOP': [
    'BS_CHROME', 'BS_FIREFOX', 'BS_IE9', 'BS_IE10', 'BS_IE11', 'BS_EDGE', 'BS_SAFARI7',
    'BS_SAFARI8', 'BS_SAFARI9', 'BS_SAFARI10'
  ],
  'MOBILE': [
    'BS_ANDROID4.3', 'BS_ANDROID4.4', 'BS_ANDROID5', 'BS_ANDROID6', 'BS_ANDROID7', 'BS_IOS7',
    'BS_IOS8', 'BS_IOS9', 'BS_IOS10', 'BS_WINDOWSPHONE'
  ],
  'ANDROID': ['BS_ANDROID4.3', 'BS_ANDROID4.4', 'BS_ANDROID5', 'BS_ANDROID6', 'BS_ANDROID7'],
  'IE': ['BS_IE9', 'BS_IE10', 'BS_IE11'],
  'IOS': ['BS_IOS7', 'BS_IOS8', 'BS_IOS9', 'BS_IOS10'],
  'SAFARI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9', 'BS_SAFARI10'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'BS', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'BS', false)
};

module.exports = {
  customLaunchers: customLaunchers,
  sauceAliases: sauceAliases,
  browserstackAliases: browserstackAliases
};

function buildConfiguration(type, target, required) {
  return Object.keys(CIconfiguration)
      .filter((item) => {
        var conf = CIconfiguration[item][type];
        return conf.required === required && conf.target === target;
      })
      .map((item) => target + '_' + item.toUpperCase());
}
<|endoftext|>


<commit_before>function verifiyKeyword(keywordList, content) {

	for (var i = 0; i < keywordList.length; i++){

		var keyword = Object.keys(keywordList[i])[0];

		if(content.search(keyword) != -1){

			var response = keywordList[i][content];

			return response;
		}
	}
}

module.exports = {
	'verifiyKeyword': verifiyKeyword
};
<commit_msg>Fully fix verify keyword's bug<commit_after>function verifiyKeyword(keywordList, content) {

	for (var i = 0; i < keywordList.length; i++){

		var keyword = Object.keys(keywordList[i])[0];

		var re = new RegExp(keyword, "g");

		if(re.test(content)){

			var response = keywordList[i][content];

			return response;
		}
	}
}

module.exports = {
	'verifiyKeyword': verifiyKeyword
};
<|endoftext|>


<commit_before>/*global console*/
(function (win, doc, undef) {
	var
		func,
		funcName = 'loadScript',
		VERSION = '0.1.0',
		had = Object.prototype.hasOwnProperty.call(win, funcName),
		previous = win[funcName],
		loading = {},
		loaded = {},
		substitutions
	;

	function log(msg) {
		if (typeof console !== 'undefined' && console && console.log) {
			console.log(msg);
		}
	}

	function rewrite(origURL) {
		var i, len = substitutions.length, rule, url = origURL;
		while (++i < len) {
			rule = substitutions[i];
			url = url.replace(rule[0], rule[1]);
		}
		if (url !== origURL) {
			log(funcName + ': rewrite("' + origURL + '")');
			log(' => "' + url + '"');
		}
		return url;
	}

	func = win[funcName] = function (requestURL, callback) {
		var
			el,
			url = rewrite(requestURL),
			needToLoad = !loading[url],
			q = loading[url] = loading[url] || []
		;
		function doCallback() {
			if (callback) {
				callback();
			}
		}
		if (loaded[url]) {
			doCallback();
			return;
		}
		q.push(doCallback);
		function onLoad() {
			while (q.length) {
				q.shift()();
			}
		}
		if (needToLoad) {
			el = doc.createElement('script');
			el.type = 'text/javascript';
			el.charset = 'utf-8';
			if (el.addEventListener) {
				el.addEventListener('load', onLoad, false);
			} else { // IE
				el.attachEvent('onreadystatechange', onLoad);
			}
			if (url !== requestURL) {
				el.setAttribute('data-requested', requestURL);
			}
			el.src = url;
			doc.getElementsByTagName('head')[0].appendChild(el);
		}
	};

	func.VERSION = VERSION;

	func.key = 'loader_rules';

	func.noConflict = function () {
		if (win[name] === func) {
			win[name] = had ? previous : undef;
			if (!had) {
				try {
					delete win[name];
				} catch (ex) {
				}
			}
		}
		return func;
	};
}(window, document));
<commit_msg>Check localStorage for substitutions<commit_after>/*global console*/
(function (win, doc, undef) {
	var
		func,
		funcName = 'loadScript',
		VERSION = '0.1.1',
		had = Object.prototype.hasOwnProperty.call(win, funcName),
		previous = win[funcName],
		loading = {},
		loaded = {},
		substitutions
	;

	function log(msg) {
		if (typeof console !== 'undefined' && console && console.log) {
			console.log(msg);
		}
	}

	function rewrite(origURL) {
		if (!substitutions) {
			try {
				substitutions = JSON.parse(localStorage.getItem(func.key)) || [];
			} catch (ex) {
				substitutions = [];
			}
		}
		var i, len = substitutions.length, rule, url = origURL;
		while (++i < len) {
			rule = substitutions[i];
			url = url.replace(rule[0], rule[1]);
		}
		if (url !== origURL) {
			log(funcName + ': rewrite("' + origURL + '")');
			log(' => "' + url + '"');
		}
		return url;
	}

	func = win[funcName] = function (requestURL, callback) {
		var
			el,
			url = rewrite(requestURL),
			needToLoad = !loading[url],
			q = loading[url] = loading[url] || []
		;
		function doCallback() {
			if (callback) {
				callback();
			}
		}
		if (loaded[url]) {
			doCallback();
			return;
		}
		q.push(doCallback);
		function onLoad() {
			while (q.length) {
				q.shift()();
			}
		}
		if (needToLoad) {
			el = doc.createElement('script');
			el.type = 'text/javascript';
			el.charset = 'utf-8';
			if (el.addEventListener) {
				el.addEventListener('load', onLoad, false);
			} else { // IE
				el.attachEvent('onreadystatechange', onLoad);
			}
			if (url !== requestURL) {
				el.setAttribute('data-requested', requestURL);
			}
			el.src = url;
			doc.getElementsByTagName('head')[0].appendChild(el);
		}
	};

	func.VERSION = VERSION;

	func.key = 'loadScript_substitutions';

	func.noConflict = function () {
		if (win[name] === func) {
			win[name] = had ? previous : undef;
			if (!had) {
				try {
					delete win[name];
				} catch (ex) {
				}
			}
		}
		return func;
	};
}(window, document));
<|endoftext|>


<commit_before>import {
  computed, observable, action,
} from 'mobx';

import BaseOnboarding from './base';
import Nags from '../../../components/onboarding/nags';

import { UiSettings } from 'shared';

const PAY_LATER_CHOICE  = 'PL';

export default class StudentCourseOnboarding extends BaseOnboarding {

  @observable displayPayment = false;

  @computed get nagComponent() {
    if (!this.course.needsPayment) {
      return null;
    }
    if (this.displayPayment) {
      return Nags.makePayment;
    }
    if (this.course.userStudentRecord.mustPayImmediately) {
      return Nags.freeTrialEnded;
    }
    if (!UiSettings.get(PAY_LATER_CHOICE, this.course.id)) {
      return Nags.payNowOrLater;
    }
    return null;
  }

  @action.bound
  payNow() {
    this.displayPayment = true;
  }

  @action.bound
  payLater() {
    UiSettings.set(PAY_LATER_CHOICE, this.course.id, true);
    this.displayPayment = false;
  }

  @action.bound
  onPaymentComplete() {
    this.displayPayment = false;
    this.course.userStudentRecord.markPaid();
  }
}
<commit_msg>don't display while other modals are being shown<commit_after>import {
  computed, observable, action,
} from 'mobx';

import BaseOnboarding from './base';
import Nags from '../../../components/onboarding/nags';

import { UiSettings } from 'shared';

const PAY_LATER_CHOICE  = 'PL';

export default class StudentCourseOnboarding extends BaseOnboarding {

  @observable displayPayment = false;

  @computed get nagComponent() {
    if (this.otherModalsAreDisplaying || !this.course.needsPayment) {
      return null;
    }
    if (this.displayPayment) {
      return Nags.makePayment;
    }
    if (this.course.userStudentRecord.mustPayImmediately) {
      return Nags.freeTrialEnded;
    }
    if (!UiSettings.get(PAY_LATER_CHOICE, this.course.id)) {
      return Nags.payNowOrLater;
    }
    return null;
  }

  @action.bound
  payNow() {
    this.displayPayment = true;
  }

  @action.bound
  payLater() {
    UiSettings.set(PAY_LATER_CHOICE, this.course.id, true);
    this.displayPayment = false;
  }

  @action.bound
  onPaymentComplete() {
    this.displayPayment = false;
    this.course.userStudentRecord.markPaid();
  }
}
<|endoftext|>


<commit_before>define(function (require, exports, module) {
    "use strict";

    var CommandManager      = brackets.getModule("command/CommandManager"),
        MainViewManager     = brackets.getModule("view/MainViewManager"),
        Commands            = brackets.getModule("command/Commands");
    // Orientation
    var VERTICAL_ORIENTATION    = 0,
        HORIZONTAL_ORIENTATION  = 1;
    // by default we use vertical orientation
    var _orientation = VERTICAL_ORIENTATION;

    /*
     * Publicly avaialble function used to create an iframe within the second-panel
     * url: Takes one argument of a url to a blob for the _update() function to use
     *      - if undefined we will not fill the iframe with an src
     */
    function browse(url) {
        //Get current GUI layout
        var result = MainViewManager.getLayoutScheme();

        // If iframe does not exist, then show it
        if(result.rows === 1 && result.columns === 1) {
            setOrientation(_orientation);
        }
        // Call function that is used to create the iframe and fill it with url
        _update(url);
    }

    /*
     * Publicly available function used to change the orientation of the panel
     * orientation: Takes one argument of either VERTICAL_ORIENTATION OR
     * HORIZONTAL_ORIENTATION and uses that to change the layout accordingly
     */
    function setOrientation(orientation) {
        if(orientation === VERTICAL_ORIENTATION) {
            CommandManager.execute(Commands.CMD_SPLITVIEW_VERTICAL);
        }
        else if (orientation === HORIZONTAL_ORIENTATION) {
            CommandManager.execute(Commands.CMD_SPLITVIEW_HORIZONTAL);
        }
    }

    /**
     * Function used to interact with the second-pane
     * In which our iFrame will exists and will be filled
     * with the url that has been passed to this function
     */
    function _update(url) {
        // Empty all contents of #second-pane
        var _panel = $("#second-pane").empty();

        // Create the iFrame for the blob to live in
        var iframeConfig = {
            id: "bramble-iframe-browser",
            frameborder: 0
        };

        // If url has been sent, make the iFrames' src that of the url
        if(url) {
            iframeConfig.src = url;
        }

        //Append iFrame to _panel
        $("<iframe>", iframeConfig).css({"width":"100%", "height":"100%"}).appendTo(_panel);
    }

    // Return reference to iframe element or null if not available.
    function getBrowserIFrame() {
        return document.getElementById("bramble-iframe-browser");
    }

    // Define public API
    exports.browse = browse;
    exports.getBrowserIFrame = getBrowserIFrame;
    // Expose these constants on our module, so callers can use them with setOrientation()
    exports.HORIZONTAL_ORIENTATION = HORIZONTAL_ORIENTATION;
    exports.VERTICAL_ORIENTATION = VERTICAL_ORIENTATION;
    exports.setOrientation = setOrientation;

});
<commit_msg>Split setOrientation into get/set and a method, added show() to public API<commit_after>define(function (require, exports, module) {
    "use strict";

    var CommandManager      = brackets.getModule("command/CommandManager"),
        MainViewManager     = brackets.getModule("view/MainViewManager"),
        Commands            = brackets.getModule("command/Commands");
    // Orientation
    var VERTICAL_ORIENTATION    = 0,
        HORIZONTAL_ORIENTATION  = 1;
    // by default we use vertical orientation
    var _orientation = VERTICAL_ORIENTATION;

    /*
     * Publicly avaialble function used to create an iframe within the second-panel
     * url: Takes one argument of a url to a blob for the _update() function to use
     *      - if undefined we will not fill the iframe with an src
     */
    function browse(url) {
        //Get current GUI layout
        var result = MainViewManager.getLayoutScheme();

        // If iframe does not exist, then show it
        if(result.rows === 1 && result.columns === 1) {
            _show(_orientation);
        }
        // Call function that is used to create the iframe and fill it with url
        _update(url);
    }

    /*
     * Publicly available function used to change the _orientation value of iframe-browser
     * orientation: Takes one argument of either VERTICAL_ORIENTATION OR
     * HORIZONTAL_ORIENTATION and uses that to change the _orientation value accordingly
     */
    function setOrientation(orientation) {
        if(orientation === VERTICAL_ORIENTATION) {
            _orientation = VERTICAL_ORIENTATION;
        }
        else if (orientation === HORIZONTAL_ORIENTATION) {
            _orientation = HORIZONTAL_ORIENTATION;
        }
    }

    /*
     * Publicly available function used to change the layout of the iFrame
     * orientation: Takes one argument of either VERTICAL_ORIENTATION OR
     * HORIZONTAL_ORIENTATION and uses that to change the layout accordingly
     */
    function show() {
        if(_orientation === VERTICAL_ORIENTATION) {
            CommandManager.execute(Commands.CMD_SPLITVIEW_VERTICAL);
        }
        else if(_orientation === HORIZONTAL_ORIENTATION) {
            CommandManager.execute(Commands.CMD_SPLITVIEW_HORIZONTAL);
        }
    }

    /**
     * Function used to interact with the second-pane
     * In which our iFrame will exists and will be filled
     * with the url that has been passed to this function
     */
    function _update(url) {
        // Empty all contents of #second-pane
        var _panel = $("#second-pane").empty();

        // Create the iFrame for the blob to live in
        var iframeConfig = {
            id: "bramble-iframe-browser",
            frameborder: 0
        };

        // If url has been sent, make the iFrames' src that of the url
        if(url) {
            iframeConfig.src = url;
        }

        //Append iFrame to _panel
        $("<iframe>", iframeConfig).css({"width":"100%", "height":"100%"}).appendTo(_panel);
    }

    // Return reference to iframe element or null if not available.
    function getBrowserIFrame() {
        return document.getElementById("bramble-iframe-browser");
    }

    // Define public API
    exports.browse = browse;
    exports.show = show;
    exports.getBrowserIFrame = getBrowserIFrame;
    // Expose these constants on our module, so callers can use them with setOrientation()
    exports.HORIZONTAL_ORIENTATION = HORIZONTAL_ORIENTATION;
    exports.VERTICAL_ORIENTATION = VERTICAL_ORIENTATION;
    exports.setOrientation = setOrientation;

});
<|endoftext|>


<commit_before>Application.Directives.directive("projectTaskBar", projectTaskBarDirective);
function projectTaskBarDirective() {
    return {
        restrict: "E",
        replace: true,
        scope: {
            project: "=project",
            projects: "=projects"
        },
        controller: "projectTaskBarDirectiveController",
        templateUrl: "application/core/projects/project/project-task-bar.html"
    };
}

Application.Controllers.controller("projectTaskBarDirectiveController",
    ["$scope", "current", "$state", "ui",
        "User", "sideboard", "projectState",
        projectTaskBarDirectiveController]);
function projectTaskBarDirectiveController($scope, current, $state, ui, User, sideboard, projectState) {
    $scope.setProject = function (project) {
        current.setProject(project);
        $scope.showProjects = false;
        $state.go("projects.project.home", {id: project.id});
    };

    var panels = [
        "processes",
        "files",
        "samples",
        "reviews",
        "notes",
        "sideboard"
    ];

    function setAllPanels(to, current) {
        panels.forEach(function (panel) {
            if (current != panel) {
                ui.setIsExpanded($scope.project.id, panel, to);
                ui.setPanelState($scope.project.id, panel, to);
            }
        });
    }

    function showAllPanels() {
        panels.forEach(function (panel) {
            //if (panel !== "sideboard") {
                ui.setIsExpanded($scope.project.id, panel, false);
                ui.setPanelState($scope.project.id, panel, true);
                ui.setPanelState($scope.project.id, 'sideboard', false);
                ui.setPanelState($scope.project.id, 'emptyboard', false);

            //}
        });
    }

    $scope.isMinimized = function (panel) {
        return !ui.showPanel($scope.project.id, panel);
    };

    $scope.showPanel = function (panel) {
        return ui.showPanel($scope.project.id, panel);
    };

    $scope.openPanel = function (panel) {
        ui.togglePanelState($scope.project.id, panel);
    };

    $scope.isActive = function (panel) {
        return ui.isExpanded($scope.project.id, panel);
    };

    $scope.toggleExpanded = function (panel) {
        if (panel === 'dashboard') {
            showAllPanels();
        } else {
            console.log('1');
            setAllPanels(false, panel);
            ui.toggleIsExpanded($scope.project.id, panel);
            if (!ui.showPanel($scope.project.id, panel) && ui.isExpanded($scope.project.id, panel)) {
                console.log('2');
                ui.setPanelState($scope.project.id, panel, true);
            } else if (!ui.isExpanded($scope.project.id, panel)) {
                showAllPanels();
                if (panel === "sideboard") {
                    ui.setPanelState($scope.project.id, panel, false);
                }
            }
        }

    };

    $scope.openDrafts = function () {
        ui.togglePanelState($scope.project.id, "drafts");
        if (ui.showPanel($scope.project.id, "drafts")) {
            // Activating drafts. Provwizard shares this ui-view
            // so set it to inactive;
            ui.setPanelState($scope.project.id, "provwizard", false);
            $state.go("projects.project.home.drafts");
        } else {
            // Deactivating the wizard
            $state.go("projects.project.home");
        }
    };

    $scope.openProvWizard = function () {
        ui.togglePanelState($scope.project.id, "provwizard");
        if (ui.showPanel($scope.project.id, "provwizard")) {
            // Activating the wizard. Drafts shares this ui-view
            // so set it to inactive.
            ui.setPanelState($scope.project.id, "drafts", false);
            var state = null;
            var stateID = projectState.add($scope.project.id, state);
            $state.go("projects.project.home.provenance", {sid: stateID});
        } else {
            // Deactivating the wizard
            $state.go("projects.project.home");
        }
    };

    $scope.mcuser = User.attr();
    $scope.list = sideboard.get($scope.project.id);
}
<commit_msg>removed console statements<commit_after>Application.Directives.directive("projectTaskBar", projectTaskBarDirective);
function projectTaskBarDirective() {
    return {
        restrict: "E",
        replace: true,
        scope: {
            project: "=project",
            projects: "=projects"
        },
        controller: "projectTaskBarDirectiveController",
        templateUrl: "application/core/projects/project/project-task-bar.html"
    };
}

Application.Controllers.controller("projectTaskBarDirectiveController",
    ["$scope", "current", "$state", "ui",
        "User", "sideboard", "projectState",
        projectTaskBarDirectiveController]);
function projectTaskBarDirectiveController($scope, current, $state, ui, User, sideboard, projectState) {
    $scope.setProject = function (project) {
        current.setProject(project);
        $scope.showProjects = false;
        $state.go("projects.project.home", {id: project.id});
    };

    var panels = [
        "processes",
        "files",
        "samples",
        "reviews",
        "notes",
        "sideboard"
    ];

    function setAllPanels(to, current) {
        panels.forEach(function (panel) {
            if (current != panel) {
                ui.setIsExpanded($scope.project.id, panel, to);
                ui.setPanelState($scope.project.id, panel, to);
            }
        });
    }

    function showAllPanels() {
        panels.forEach(function (panel) {
            //if (panel !== "sideboard") {
                ui.setIsExpanded($scope.project.id, panel, false);
                ui.setPanelState($scope.project.id, panel, true);
                ui.setPanelState($scope.project.id, 'sideboard', false);
                ui.setPanelState($scope.project.id, 'emptyboard', false);

            //}
        });
    }

    $scope.isMinimized = function (panel) {
        return !ui.showPanel($scope.project.id, panel);
    };

    $scope.showPanel = function (panel) {
        return ui.showPanel($scope.project.id, panel);
    };

    $scope.openPanel = function (panel) {
        ui.togglePanelState($scope.project.id, panel);
    };

    $scope.isActive = function (panel) {
        return ui.isExpanded($scope.project.id, panel);
    };

    $scope.toggleExpanded = function (panel) {
        if (panel === 'dashboard') {
            showAllPanels();
        } else {
            setAllPanels(false, panel);
            ui.toggleIsExpanded($scope.project.id, panel);
            if (!ui.showPanel($scope.project.id, panel) && ui.isExpanded($scope.project.id, panel)) {
                ui.setPanelState($scope.project.id, panel, true);
            } else if (!ui.isExpanded($scope.project.id, panel)) {
                showAllPanels();
                if (panel === "sideboard") {
                    ui.setPanelState($scope.project.id, panel, false);
                }
            }
        }

    };

    $scope.openDrafts = function () {
        ui.togglePanelState($scope.project.id, "drafts");
        if (ui.showPanel($scope.project.id, "drafts")) {
            // Activating drafts. Provwizard shares this ui-view
            // so set it to inactive;
            ui.setPanelState($scope.project.id, "provwizard", false);
            $state.go("projects.project.home.drafts");
        } else {
            // Deactivating the wizard
            $state.go("projects.project.home");
        }
    };

    $scope.openProvWizard = function () {
        ui.togglePanelState($scope.project.id, "provwizard");
        if (ui.showPanel($scope.project.id, "provwizard")) {
            // Activating the wizard. Drafts shares this ui-view
            // so set it to inactive.
            ui.setPanelState($scope.project.id, "drafts", false);
            var state = null;
            var stateID = projectState.add($scope.project.id, state);
            $state.go("projects.project.home.provenance", {sid: stateID});
        } else {
            // Deactivating the wizard
            $state.go("projects.project.home");
        }
    };

    $scope.mcuser = User.attr();
    $scope.list = sideboard.get($scope.project.id);
}
<|endoftext|>


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

// This object manages any window:
function Pr0n_Window(obj, win, config) {
    this.init(obj, win, config);
}

Pr0n_Window.prototype = {
    _pr0n : null,
    _config : null,

    // XUL Elements:
    _window : null,

    _inPrivateBrowsing : false,
    _initialized : false,

    // Init function:
    init : function(obj, win, config) {
        var me       = this;
        this._pr0n   = obj;
        this._window = win;
        this._config = config;

        this._os = Components.classes['@mozilla.org/observer-service;1']
                             .getService(Components.interfaces.nsIObserverService);
        this._os.addObserver(this, 'private-browsing', false);
        this._os.addObserver(this, 'quit-application', false);

        try {
            var pbs = Components.classes['@mozilla.org/privatebrowsing;1']
                                .getService(Components.interfaces.nsIPrivateBrowsingService);
            this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
        } catch(ex) {
            // ignore exceptions in older versions of Firefox
        }

        // Check/Init the toolbar:
        this.initToolbar();
        this.checkToolbar();

        // Loading of the window:
        this._window._Pr0nWindow = this;
        win.addEventListener('load', function() { me.windowOnload(); }, false);
        try { this.windowOnload(); } catch(e) {}
    },

    refresh : function() {
        var toolbarModule = this._window.document.getElementById('Pr0n-Modules');
        if(!toolbarModule)
            return;

        while(toolbarModule.firstChild)
            toolbarModule.removeChild(toolbarModule.firstChild);

        this.initialized = false;
        this.initToolbar();
        this.checkToolbar();

        var obj = this._window.document.getElementById("nav-bar") ||
                  this._window.document.getElementById("addon-bar");
        if (!obj)
            return;

        var button = this._window.document.getElementById("pr0n-toolbarbutton");
        var pr0n = Components.classes["@wepr0n.com/pr0n;1"]
                             .getService().wrappedJSObject;
        if (pr0n.inToolbar()) {
            obj.setAttribute("collapsed", "false");
            obj.insertItem('pr0n-toolbarbutton', null, null, false);

            if (button) {
                button.hidden = false;
                this._window.document.persist(button.id, "collapsed");
            }
        } else if(button) {
            button.hidden = true;
        }
    },

    observe : function (aSubject, aTopic, aData) {
        if (aTopic == 'private-browsing') {
            if (aData == 'enter') {
                this._inPrivateBrowsing = true;
                this.checkToolbar();
            } else if (aData == 'exit') {
                this._inPrivateBrowsing = false;
                this.checkToolbar();
            }
        }

        else if (aTopic == 'quit-application') {
            this._os.removeObserver(this, 'quit-application');
            this._os.removeObserver(this, 'private-browsing');
        }
    },

    windowOnload : function() {
        this._window._Pr0nWindow = this;
        this.initToolbar();
        this.checkToolbar();

        var me = this;
        var win = this._window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
           .getInterface(Components.interfaces.nsIWebNavigation)
           .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
           .rootTreeItem
           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
           .getInterface(Components.interfaces.nsIDOMWindow);

        win.addEventListener("DOMContentLoaded", function(evnt) { me.windowDOMContentLoaded(evnt); }, true);
    },

    windowDOMContentLoaded : function(evnt) {
        var doc = evnt.originalTarget;
        if (doc.location.href == 'about:privatebrowsing') {
            doc.location.href = 'chrome://pr0n/content/home/index.html';
        }
    },

    initToolbar : function() {
        if(this.initialized == true)
            return;

        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        var toolbarModule = this._window.document.getElementById('Pr0n-Modules');
        if(!toolbarModule)
            return;

        // Populating the toolbar:
        var modules = this._pr0n.getModules();
        var first = true;
        for(var i=0; i<modules.length; i++) {
            if(!modules[i].enabled)
                continue;

            var item = modules[i].obj.getNode(this._window.document);
            if(!item)
                continue;

            if (first == true) {
                first = false;
            } else {
                var sep = this._window.document.createElement('toolbarseparator');
                toolbarModule.appendChild(sep);
            }

            if(item instanceof Array) {
                for(var j=0; j<item.length;j++)
                    toolbarModule.appendChild(item[j]);
            }
            else
                toolbarModule.appendChild(item);

        }

        this.initialized = true;
    },

    checkToolbar : function() {
        if (this._inPrivateBrowsing == true)
            this.showToolbar();
        else
            this.hideToolbar();
    },

    showToolbar : function() {
        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        toolbar.hidden = false;
    },

    hideToolbar : function() {
        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        toolbar.hidden = true;
    }
};

// EOF
<commit_msg>urlbar cleared when pr0n is shown.<commit_after>/* See license.txt for terms of usage */

// This object manages any window:
function Pr0n_Window(obj, win, config) {
    this.init(obj, win, config);
}

Pr0n_Window.prototype = {
    _pr0n : null,
    _config : null,

    // XUL Elements:
    _window : null,

    _inPrivateBrowsing : false,
    _initialized : false,

    // Init function:
    init : function(obj, win, config) {
        var me       = this;
        this._pr0n   = obj;
        this._window = win;
        this._config = config;

        this._os = Components.classes['@mozilla.org/observer-service;1']
                             .getService(Components.interfaces.nsIObserverService);
        this._os.addObserver(this, 'private-browsing', false);
        this._os.addObserver(this, 'quit-application', false);

        try {
            var pbs = Components.classes['@mozilla.org/privatebrowsing;1']
                                .getService(Components.interfaces.nsIPrivateBrowsingService);
            this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
        } catch(ex) {
            // ignore exceptions in older versions of Firefox
        }

        // Check/Init the toolbar:
        this.initToolbar();
        this.checkToolbar();

        // Loading of the window:
        this._window._Pr0nWindow = this;
        win.addEventListener('load', function() { me.windowOnload(); }, false);
        try { this.windowOnload(); } catch(e) {}
    },

    refresh : function() {
        var toolbarModule = this._window.document.getElementById('Pr0n-Modules');
        if(!toolbarModule)
            return;

        while(toolbarModule.firstChild)
            toolbarModule.removeChild(toolbarModule.firstChild);

        this.initialized = false;
        this.initToolbar();
        this.checkToolbar();

        var obj = this._window.document.getElementById("nav-bar") ||
                  this._window.document.getElementById("addon-bar");
        if (!obj)
            return;

        var button = this._window.document.getElementById("pr0n-toolbarbutton");
        var pr0n = Components.classes["@wepr0n.com/pr0n;1"]
                             .getService().wrappedJSObject;
        if (pr0n.inToolbar()) {
            obj.setAttribute("collapsed", "false");
            obj.insertItem('pr0n-toolbarbutton', null, null, false);

            if (button) {
                button.hidden = false;
                this._window.document.persist(button.id, "collapsed");
            }
        } else if(button) {
            button.hidden = true;
        }
    },

    observe : function (aSubject, aTopic, aData) {
        if (aTopic == 'private-browsing') {
            if (aData == 'enter') {
                this._inPrivateBrowsing = true;
                this.checkToolbar();
            } else if (aData == 'exit') {
                this._inPrivateBrowsing = false;
                this.checkToolbar();
            }
        }

        else if (aTopic == 'quit-application') {
            this._os.removeObserver(this, 'quit-application');
            this._os.removeObserver(this, 'private-browsing');
        }
    },

    windowOnload : function() {
        this._window._Pr0nWindow = this;
        this.initToolbar();
        this.checkToolbar();

        var me = this;
        var win = this._window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
           .getInterface(Components.interfaces.nsIWebNavigation)
           .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
           .rootTreeItem
           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
           .getInterface(Components.interfaces.nsIDOMWindow);

        win.addEventListener("DOMContentLoaded", function(evnt) { me.windowDOMContentLoaded(evnt); }, true);
    },

    windowDOMContentLoaded : function(evnt) {
        var doc = evnt.originalTarget;
        if (doc.location.href == 'about:privatebrowsing') {
            doc.location.href = 'chrome://pr0n/content/home/index.html';
        } else if (doc.location.href == 'chrome://pr0n/content/home/index.html') {
            var urlbar = this._window.document.getElementById("urlbar");
            urlbar.value = '';
        }
    },

    initToolbar : function() {
        if(this.initialized == true)
            return;

        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        var toolbarModule = this._window.document.getElementById('Pr0n-Modules');
        if(!toolbarModule)
            return;

        // Populating the toolbar:
        var modules = this._pr0n.getModules();
        var first = true;
        for(var i=0; i<modules.length; i++) {
            if(!modules[i].enabled)
                continue;

            var item = modules[i].obj.getNode(this._window.document);
            if(!item)
                continue;

            if (first == true) {
                first = false;
            } else {
                var sep = this._window.document.createElement('toolbarseparator');
                toolbarModule.appendChild(sep);
            }

            if(item instanceof Array) {
                for(var j=0; j<item.length;j++)
                    toolbarModule.appendChild(item[j]);
            }
            else
                toolbarModule.appendChild(item);

        }

        this.initialized = true;
    },

    checkToolbar : function() {
        if (this._inPrivateBrowsing == true)
            this.showToolbar();
        else
            this.hideToolbar();
    },

    showToolbar : function() {
        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        toolbar.hidden = false;
    },

    hideToolbar : function() {
        var toolbar = this._window.document.getElementById('Pr0n-Toolbar');
        if(!toolbar)
            return;

        toolbar.hidden = true;
    }
};

// EOF
<|endoftext|>


<commit_before>let assert = require('chai').assert;

describe('Db Class', function() {
    describe('constructor', function() {
        it.skip('should add a default database', function() {

        });
    });

    describe('use', function() {
        it.skip('should return a database by name', function() {

        });

        it.skip('should return the default database', function() {

        });
    });

    describe('addDb', function() {
        it.skip('should add another db', function() {

        });
    });
});
<commit_msg>'let' issue for node versions below 6<commit_after>'use strict';
let assert = require('chai').assert;

describe('Db Class', function() {
    describe('constructor', function() {
        it.skip('should add a default database', function() {

        });
    });

    describe('use', function() {
        it.skip('should return a database by name', function() {

        });

        it.skip('should return the default database', function() {

        });
    });

    describe('addDb', function() {
        it.skip('should add another db', function() {

        });
    });
});
<|endoftext|>