<commit_before>$(function() {

  var weekInMinutes = twoWeeksInMilliseconds / 2;

  describe('User', function() {

    describe('Rank Up Exp', function() {

      it('is in range ±2 if cureent rank == 604', function() {
        var user = new User(604, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBeGreaterThanOrEqual(20258 - 2);
        expect(user.getRankUpExp()).toBeLessThanOrEqual(20258 + 2);
      });

      it('is correct if current rank == 158', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        expect(user.getRankUpExp()).toBe(4892);
      });

      it('is correct if current rank == 99', function() {
        var user = new User(99, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBe(1430);
      });

      it('is correct if current rank == 1', function() {
        var user = new User(1, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBe(6);
      });

    });

  });

  describe('Max Lp', function() {

    it('is currect if cureent rank == 158', function() {
      var user = new User(158, 0, 0, 0, 0);
      expect(user.getMaxLP()).toBe(104);
    });

  });

  describe('Token Event', function() {

    it('is defined', function() {
      expect(TokenEvent).toBeDefined();
    });

    describe('Pt Gain', function() {

      it('is correct (normal song: expert level with multiplier 2 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Expert', 2, 'Expert', 4);
        expect(tokenEvent.getPtGainedPerNormalSong()).toBe(54);
      });

      it('is correct (normal song: hard level with multiplier 4 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 4);
        expect(tokenEvent.getPtGainedPerNormalSong()).toBe(64);
      });

      it('is correct (event song: expert level, score S, combo A, multiplier 1 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 1,
        'S', 'A');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(549);
      });

      it('is correct (event song: hard level, score B, combo B, multiplier 2 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Hard', 2,
        'B', 'B');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(448);
      });

      it('is correct (event song: expert level, score S, combo None, multiplier 3 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 3,
        'S', 'None');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(1494);
      });
    });

    describe('Exp Gain', function() {

      it('is correct (normal song: expert level, multiplier 2 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Expert', 2, 'Expert', 4);
        expect(tokenEvent.getExpGainedPerNormalSong()).toBe(166);
      });

      it('is correct (normal song: hard level, multiplier 4 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 4);
        expect(tokenEvent.getExpGainedPerNormalSong()).toBe(184);
      });

      it('is correct (event song: expert level, multiplier 1 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 1,
        'S', 'A');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(83);
      });

      it('is correct (event song: hard level, multiplier 2 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Hard', 2,
        'B', 'B');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(92);
      });

      it('is correct (event song: expert level, multiplier 3 )', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 3,
        'S', 'None');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(249);
      });
    });
  });

  describe('Score Match', function() {

    it('is defined', function() {
      expect(MedelyFestival).toBeDefined();
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var scoreMatch = new ScoreMatch(Date.now() + weekInMinutes,
        'Hard', 'C', '1st');

        scoreMatch.run(0, user);

        expect(user.rank).toBe(159);
        expect(user.exp).toBe(4010);
        expect(user.currentPt).toBe(48428);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct if taget can be archived', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var scoreMatch = new ScoreMatch(Date.now() + weekInMinutes,
        'Hard', 'A', '1st');
        var clonedScoreMatch = scoreMatch.clone();

        var lovecaNeeded = getLovecaNeeded(user, scoreMatch);
        expect(lovecaNeeded).toBe(4);

        scoreMatch.run(lovecaNeeded - 1, user);
        clonedScoreMatch.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct if taget can\'t be archived because of not enough time given', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();
        var anotherClonedUser = user.clone();

        var scoreMatch = new ScoreMatch(Date.now() + 1000 * 60 * 60,
        'Hard', 'A', '1st');
        var clonedScoreMatch = scoreMatch.clone();
        var anotherClonedScoreMatch = scoreMatch.clone();

        var lovecaNeeded = getLovecaNeeded(user, scoreMatch);
        expect(lovecaNeeded).toBe(3);

        scoreMatch.run(lovecaNeeded - 1, user);
        clonedScoreMatch.run(lovecaNeeded, clonedUser);
        anotherClonedScoreMatch.run(lovecaNeeded + 1, anotherClonedUser);

        expect(user.currentPt).not.toBe(clonedUser.currentPt);
        expect(clonedUser.currentPt).toBe(anotherClonedUser.currentPt);
      });
    });

  });

  describe('Medely Festival', function() {

    it('is defined', function() {
      expect(MedelyFestival).toBeDefined();
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var medelyFestival = new MedelyFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        true, true);

        medelyFestival.run(0, user);

        expect(user.rank).toBe(160);
        expect(user.exp).toBe(1439);
        expect(user.currentPt).toBe(54908);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var medelyFestival = new MedelyFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        true, true);
        var clonedMedelyFestival = medelyFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, medelyFestival);
        expect(lovecaNeeded).toBe(3);

        medelyFestival.run(lovecaNeeded - 1, user);
        clonedMedelyFestival.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct if taget can\'t be archived because of not enough time given', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();

        var medelyFestival = new MedelyFestival(Date.now() + 1000 * 60 * 1,
        'Expert', 3, 'S', 'A',
        true, true);
        var clonedMedelyFestival = medelyFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, medelyFestival);
        expect(lovecaNeeded).toBe(0);

        medelyFestival.run(lovecaNeeded, user);
        clonedMedelyFestival.run(lovecaNeeded + 1, clonedUser);

        expect(user.currentPt).toBe(clonedUser.currentPt);
      });

    });

  });

  describe('Challenge Festival', function() {

    it('is defined', function() {
      expect(ChallengeFestival).toBeDefined();
    });

    describe('Pt Gain', function() {

      it('is correct with level expert score S combo A at round 4', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 4, 'S', 'A',
        4, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(455);
      });

      it('is correct with level easy score C combo B at round 5', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Easy', 5, 'C', 'B',
        5, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(47);
      });

      it('is correct with level hard score None combo None at round 3', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Hard', 3, 'None', 'None',
        3, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(170);
      });
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);

        challengeFestival.run(0, user);

        expect(user.rank).toBe(159);
        expect(user.exp).toBe(4457);
        expect(user.currentPt).toBe(52777);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);
        var clonedChallengeFestival = challengeFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, challengeFestival);
        expect(lovecaNeeded).toBe(3);

        challengeFestival.run(lovecaNeeded - 1, user);
        clonedChallengeFestival.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct if taget can\'t be archived because of not enough time given', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();
        var anotherClonedUser = user.clone();

        var challengeFestival = new ChallengeFestival(Date.now() + 1000 * 60 * 1,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);
        var clonedChallengeFestival = challengeFestival.clone();
        var anotherClonedChallengeFestival = challengeFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, challengeFestival);
        expect(lovecaNeeded).toBe(0);

        challengeFestival.run(lovecaNeeded, user);
        clonedChallengeFestival.run(lovecaNeeded + 1, clonedUser);

        expect(user.currentPt).toBe(clonedUser.currentPt);
      });

    });

  });
}());
<commit_msg>Change wording in test description<commit_after>$(function() {

  var weekInMinutes = twoWeeksInMilliseconds / 2;

  describe('User', function() {

    describe('Rank Up Exp', function() {

      it('is in range ±2 (current rank 604)', function() {
        var user = new User(604, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBeGreaterThanOrEqual(20258 - 2);
        expect(user.getRankUpExp()).toBeLessThanOrEqual(20258 + 2);
      });

      it('is correct (current rank 158)', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        expect(user.getRankUpExp()).toBe(4892);
      });

      it('is correct (current rank 99)', function() {
        var user = new User(99, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBe(1430);
      });

      it('is correct (current rank 1)', function() {
        var user = new User(1, 0, 0, 0, 0);
        expect(user.getRankUpExp()).toBe(6);
      });

    });

  });

  describe('Max Lp', function() {

    it('is currect (current rank 158)', function() {
      var user = new User(158, 0, 0, 0, 0);
      expect(user.getMaxLP()).toBe(104);
    });

  });

  describe('Token Event', function() {

    it('is defined', function() {
      expect(TokenEvent).toBeDefined();
    });

    describe('Pt Gain', function() {

      it('is correct (normal song: expert level, multiplier 2)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Expert', 2, 'Expert', 4);
        expect(tokenEvent.getPtGainedPerNormalSong()).toBe(54);
      });

      it('is correct (normal song: hard level, multiplier 4)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 4);
        expect(tokenEvent.getPtGainedPerNormalSong()).toBe(64);
      });

      it('is correct (event song: expert level, score S, combo A, multiplier 1)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 1,
        'S', 'A');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(549);
      });

      it('is correct (event song: hard level, score B, combo B, multiplier 2)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Hard', 2,
        'B', 'B');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(448);
      });

      it('is correct (event song: expert level, score S, combo None, multiplier 3)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 3,
        'S', 'None');
        expect(tokenEvent.getPtGainedPerEventSong()).toBe(1494);
      });
    });

    describe('Exp Gain', function() {

      it('is correct (normal song: expert level, multiplier 2)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Expert', 2, 'Expert', 4);
        expect(tokenEvent.getExpGainedPerNormalSong()).toBe(166);
      });

      it('is correct (normal song: hard level, multiplier 4)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 4);
        expect(tokenEvent.getExpGainedPerNormalSong()).toBe(184);
      });

      it('is correct (event song: expert level, multiplier 1)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 1,
        'S', 'A');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(83);
      });

      it('is correct (event song: hard level, multiplier 2)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Hard', 2,
        'B', 'B');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(92);
      });

      it('is correct (event song: expert level, multiplier 3)', function() {
        var tokenEvent = new TokenEvent(Date.now() + weekInMinutes,
        'Hard', 4, 'Expert', 3,
        'S', 'None');
        expect(tokenEvent.getExpGainedPerEventSong()).toBe(249);
      });
    });
  });

  describe('Score Match', function() {

    it('is defined', function() {
      expect(MedelyFestival).toBeDefined();
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var scoreMatch = new ScoreMatch(Date.now() + weekInMinutes,
        'Hard', 'C', '1st');

        scoreMatch.run(0, user);

        expect(user.rank).toBe(159);
        expect(user.exp).toBe(4010);
        expect(user.currentPt).toBe(48428);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct (archivable)', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var scoreMatch = new ScoreMatch(Date.now() + weekInMinutes,
        'Hard', 'A', '1st');
        var clonedScoreMatch = scoreMatch.clone();

        var lovecaNeeded = getLovecaNeeded(user, scoreMatch);
        expect(lovecaNeeded).toBe(4);

        scoreMatch.run(lovecaNeeded - 1, user);
        clonedScoreMatch.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct (not archivable)', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();
        var anotherClonedUser = user.clone();

        var scoreMatch = new ScoreMatch(Date.now() + 1000 * 60 * 60,
        'Hard', 'A', '1st');
        var clonedScoreMatch = scoreMatch.clone();
        var anotherClonedScoreMatch = scoreMatch.clone();

        var lovecaNeeded = getLovecaNeeded(user, scoreMatch);
        expect(lovecaNeeded).toBe(3);

        scoreMatch.run(lovecaNeeded - 1, user);
        clonedScoreMatch.run(lovecaNeeded, clonedUser);
        anotherClonedScoreMatch.run(lovecaNeeded + 1, anotherClonedUser);

        expect(user.currentPt).not.toBe(clonedUser.currentPt);
        expect(clonedUser.currentPt).toBe(anotherClonedUser.currentPt);
      });
    });

  });

  describe('Medely Festival', function() {

    it('is defined', function() {
      expect(MedelyFestival).toBeDefined();
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var medelyFestival = new MedelyFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        true, true);

        medelyFestival.run(0, user);

        expect(user.rank).toBe(160);
        expect(user.exp).toBe(1439);
        expect(user.currentPt).toBe(54908);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct (archivable)', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var medelyFestival = new MedelyFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        true, true);
        var clonedMedelyFestival = medelyFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, medelyFestival);
        expect(lovecaNeeded).toBe(3);

        medelyFestival.run(lovecaNeeded - 1, user);
        clonedMedelyFestival.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct (not archivable)', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();

        var medelyFestival = new MedelyFestival(Date.now() + 1000 * 60 * 1,
        'Expert', 3, 'S', 'A',
        true, true);
        var clonedMedelyFestival = medelyFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, medelyFestival);
        expect(lovecaNeeded).toBe(0);

        medelyFestival.run(lovecaNeeded, user);
        clonedMedelyFestival.run(lovecaNeeded + 1, clonedUser);

        expect(user.currentPt).toBe(clonedUser.currentPt);
      });

    });

  });

  describe('Challenge Festival', function() {

    it('is defined', function() {
      expect(ChallengeFestival).toBeDefined();
    });

    describe('Pt Gain', function() {

      it('is correct (round 4, expert level, score S, combo A)', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 4, 'S', 'A',
        4, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(455);
      });

      it('is correct (round 5, easy level, score C, combo B)', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Easy', 5, 'C', 'B',
        5, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(47);
      });

      it('is correct (round 4, hard level, score None, combo None)', function() {
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Hard', 3, 'None', 'None',
        3, 0, 0,
        false, false);

        expect(challengeFestival.getPtGainedPerGame()).toBe(170);
      });
    });

    describe('User statue at the end', function() {

      it('is correct', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);

        challengeFestival.run(0, user);

        expect(user.rank).toBe(159);
        expect(user.exp).toBe(4457);
        expect(user.currentPt).toBe(52777);
      });

    });

    describe('Estimated loveca needed', function() {

      it('is correct (archivable)', function() {
        var user = new User(158, 3290, 59, 60000, 20124);
        var clonedUser = user.clone();

        var challengeFestival = new ChallengeFestival(Date.now() + weekInMinutes,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);
        var clonedChallengeFestival = challengeFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, challengeFestival);
        expect(lovecaNeeded).toBe(3);

        challengeFestival.run(lovecaNeeded - 1, user);
        clonedChallengeFestival.run(lovecaNeeded, clonedUser);

        expect(user.currentPt).toBeLessThan(60000 - 1);
        expect(clonedUser.currentPt).toBeGreaterThan(60000);
      });

      it('is correct (not archivable)', function() {
        var user = new User(158, 3290, 59, 1000000, 0);
        var clonedUser = user.clone();
        var anotherClonedUser = user.clone();

        var challengeFestival = new ChallengeFestival(Date.now() + 1000 * 60 * 1,
        'Expert', 3, 'S', 'A',
        1, 0, 0,
        true, true);
        var clonedChallengeFestival = challengeFestival.clone();
        var anotherClonedChallengeFestival = challengeFestival.clone();

        var lovecaNeeded = getLovecaNeeded(user, challengeFestival);
        expect(lovecaNeeded).toBe(0);

        challengeFestival.run(lovecaNeeded, user);
        clonedChallengeFestival.run(lovecaNeeded + 1, clonedUser);

        expect(user.currentPt).toBe(clonedUser.currentPt);
      });

    });

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


<commit_before>UI.say = function(param){
  alert(param.word);
}
<commit_msg>Update say.js<commit_after>UI.addSubObject({
  name:'say',
  mainFn:function(param){
    alert(param.word);
  },
  //isConstructor:false,
  properties:{
    test:'hoi',
  },
});
<|endoftext|>


<commit_before>var Mystique = require('mystique');
var Mongoose = require('mongoose');
var ObjectId = Mongoose.Types.ObjectId;

var getIdForModel = function(model, propertyName) {
  var prop = model.get(propertyName);
  if (prop instanceof ObjectId) {
    return prop;
  }

  return prop.id;
};

var CheckInTransformer = Mystique.Transformer.extend({
  resourceName: 'checkIn',

  mapOut: function(checkIn) {
    return {
      book: getIdForModel(checkIn, 'book'),
      checkedInAt: checkIn.checkedInAt,
      checkedOutAt: checkIn.checkedOutAt,
    };
  },

  mapIn(req) {
    return {
      book: req.body.checkIn.book,
      checkedInAt: req.body.checkIn.checkedInAt,
      checkedOutAt: req.body.checkIn.checkedOutAt,
    };
  },
});

Mystique.registerTransformer('CheckIn', CheckInTransformer);
<commit_msg>Try to get id differently<commit_after>var Mystique = require('mystique');
var Mongoose = require('mongoose');
var ObjectId = Mongoose.Types.ObjectId;

var getIdForModel = function(model, propertyName) {
  var prop = model.get(propertyName);
  if (prop instanceof ObjectId) {
    return prop;
  }

  return prop.get('id');
};

var CheckInTransformer = Mystique.Transformer.extend({
  resourceName: 'checkIn',

  mapOut: function(checkIn) {
    return {
      book: getIdForModel(checkIn, 'book'),
      checkedInAt: checkIn.checkedInAt,
      checkedOutAt: checkIn.checkedOutAt,
    };
  },

  mapIn(req) {
    return {
      book: req.body.checkIn.book,
      checkedInAt: req.body.checkIn.checkedInAt,
      checkedOutAt: req.body.checkIn.checkedOutAt,
    };
  },
});

Mystique.registerTransformer('CheckIn', CheckInTransformer);
<|endoftext|>


<commit_before>'use strict';
var services = angular.module('nestApp.services', []);
services.factory('twitterService', function($q, $rootScope, $timeout) {
   // initialize TwitterAuth service

   var TwitterAuth = false;
   return {
      initialize: function() {
         // Set callback URL to localhost for Developement
         OAuth.setOAuthdURL('http://oauthd-nest.herokuapp.com');
         //initialize OAuth Demon with public key of the application
         OAuth.initialize('GS-2TxCExKLs3_NK3pSCW1AWrw0', {
            cache: true
         });
         //try to create an authorization result when the page loads, this means a returning user won't have to click the twitter button again
         TwitterAuth = OAuth.create('twitter');
      },
      isReady: function() {
         // Return boolean of twitter authorization state
         return (TwitterAuth);
      },
      connectTwitter: function() {
         var defer = $q.defer();
         OAuth.popup('twitter', {
            cache: true
         }, function(error, result) { //cache means to execute the callback if the tokens are already present
            if (!error) {
               TwitterAuth = result;
               defer.resolve();
            } else {
               //do something if there's an error
               defer.reject('Connexion failed', error);
            }
         });
         return defer.promise;
      },
      clearCache: function() {
         // Clear cache on logout to erase authentication token
         OAuth.clearCache('twitter');
         TwitterAuth = false;
      },
      getUser: function() {
         var defer = $q.defer();
         var promise = TwitterAuth.get('/1.1/account/verify_credentials.json').then(function(data) {
            // Calculate time to execute Nest with retrieved data
            setRemainingTime(data);
            // Set rootscope value for followers count
            $rootScope.totalFollowers = data.followers_count;
            //when the data is retrieved resolved the defer object
            defer.resolve(data);
         });
         //return the promise of the defer object
         return defer.promise;
         function setRemainingTime(usr){
            // The total execution time depends on the amount of followers
            // We can execute 15 requests of 200 followers in a 15-minute window
            // Calculate how many minutes will be needed
            var minutes = Math.floor(((usr.followers_count / 12000) - Math.floor(usr.followers_count / 12000)) * 60);
            // Calculate how many hours will be needed
            var hours = Math.floor(usr.followers_count / 12000);
            // Set in rootscop to display while loadingView is active
            $rootScope.remaining = {
               h: hours,
               m: minutes
            };
         }
      },
      blockUser: function(id) {
         var defer = $q.defer();
         var promise = TwitterAuth.post('/1.1/blocks/create.json?user_id='+id).then(function(data) {
            //when the data is retrieved resolved the defer object
            defer.resolve(data);
         }, function(err) {
            // If session has expired
            console.log('waiting...', err);
         });
         //return the promise of the defer object
         return defer.promise;
         function setRemainingTime(usr){
            // The total execution time depends on the amount of followers
            // We can execute 15 requests of 200 followers in a 15-minute window
            // Calculate how many minutes will be needed
            var minutes = Math.floor(((usr.followers_count / 12000) - Math.floor(usr.followers_count / 12000)) * 60);
            // Calculate how many hours will be needed
            var hours = Math.floor(usr.followers_count / 12000);
            // Set in rootscop to display while loadingView is active
            $rootScope.remaining = {
               h: hours,
               m: minutes
            };
         }
      },
      getFollowersActivity: function(usr, cursor) {
         // Initiate empty array that will contain the user's followers
         var followersList = [];
         var usrId = usr.id;
         //create a main defer object using Angular's $q service
         var mainDefer = $q.defer();
         //Form request URL
         var baseURL = '/1.1/followers/list.json?';
         var params = ['count=200', 'user_id=' + usrId, 'skip_status=false'];
         params = params.join('&');
         // Bind the base URL and the query params
         var url = baseURL + params;
         var i = -1; // For dev purposes
         function updateRemainingTime() {
            var hours = $rootScope.remaining.h;
            var minutes = $rootScope.remaining.m;
            minutes--;
            if (hours>0) {
               if (minutes < 0) {
                  minutes = 60 + minutes;
                  hours--;
               }
            }else{
               if (minutes<0) {
                  minutes=0;
                  hours=0;
               }
            }
            $rootScope.remaining.h = hours;
            $rootScope.remaining.m = minutes;
            $rootScope.$apply();
         }
         function getFollowers(cursor) {
            i++; // For dev purposes
            // Update rootscope with current state of the promise
            $rootScope.progressFollowers = followersList.length;
            var defer = $q.defer();
            // console.log('current cursor: ' + cursor); // For dev purposes
            if (cursor || cursor === 0) {
               // console.log('run for cursor defined: ' + cursor); // For dev purposes
               // Replace cursor in URL query params with new cursor
               url = url.replace(/&cursor=[\d]*/gi, "");
               url += '&cursor=' + cursor;
               // console.log(url); // For dev purposes
               // if (i < 0) { // dev
               if (cursor!==0) { // Final condition
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  defer.resolve(data);
                  // Set new cursor according to last page's next_id
                  var newCursor = data.next_cursor;
                  // Update followers list with retrieved values
                  followersList = followersList.concat(data.users);
                  // Update timer
                  updateRemainingTime();
                  // Repeat function asynchronously
                  getFollowers(newCursor);
               }, function(err) {
                  // If session has expired
                  console.log('waiting...');
                  $timeout(getFollowers, 300000); // Wait 5 minutes for new session
               });
            } else {
               // console.log('getFollowersActivity over', followersList.length); // For dev purposes
               // Resolve main pormise
               mainDefer.resolve(followersList);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            // console.log('run for cursor undefined', url); // For dev purposes
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               defer.resolve(data);
               // Set first cursor for paging
               cursor = data.next_cursor;
               // console.log('cursor', cursor); // For dev purposes
               // Update followersList with retrieved values
               followersList = followersList.concat(data.users);
               // Update timer
               updateRemainingTime();
               // Repeat function asynchronously if user has more than 200 followers
               if (usr.followers_count>200) {
                  getFollowers(cursor);
               } else {
                  // Otherwise, resolve main pormise
                  mainDefer.resolve(followersList);
                  return defer.promise;
               }
            }, function(err) {
               console.log('waiting...');
               $timeout(getFollowers, 300000); // Wait 5 minutes for new session
            });
            return defer.promise;
         }
      }
      getFollowers();
      mainDefer.promise.then(function(data) {
         console.log('get followers activity success', data.length); // For dev purposes
      });
      return mainDefer.promise;
   },
   getUserTimeline: function(usr, maxId) {
      var usrId = usr.id;
      var statusesCount = usr.statuses_count;
      var loops = Math.ceil(statusesCount/200);
      if (loops>16) {
         loops=16;
      }
      // Initiate empty array to collect user's tweets
      var timeline = [];
      //create a defer object using Angular's $q service
      var mainDefer = $q.defer();
      //Form request URL
      var baseURL = '/1.1/statuses/user_timeline.json?';
      var params = ['count=200', 'user_id=' + usrId];
      params = params.join('&');
      // Bind base URL and query params
      var url = baseURL + params;
      // set counter
      var i = -1;
      function getTweet(maxId) {
         i++;
         var defer = $q.defer();
         if (maxId) {
            // Replace cursor in URL query params with new cursor
            url = url.replace(/&max_id=[\d]*/gi, "");
            url += '&max_id=' + maxId;
            if (i < loops) { // 16 to get up to 3200 last tweets
            // if (i < 0) { // dev
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  if (data.length>0) {
                     defer.resolve(data);
                     // Set new maxId according to last tweet's id
                     var newMaxId = data[data.length - 1].id;
                     // Set new timeline with retrieved values
                     timeline = timeline.concat(data);
                     // Repeat function asynchronously
                     getTweet(newMaxId);
                  }else{
                     mainDefer.resolve(timeline);
                     return defer.promise;
                  }
               }, function(err) {
                  console.log('waiting…');
                  $timeout(getTweet(), 300000); // Wait 5 minutes for new session
               });
               return defer.promise;
            } else {
               // resolve main promise
               mainDefer.resolve(timeline);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            // console.log('user timelin run for maxId undefined'); // For dev purposes
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               // Check if response array is empty
               if (data.length>0) {
                  defer.resolve(data);
                  // Set first maxId according to last tweet's id
                  maxId = data[data.length - 1].id;
                  // Set new timeline with retrieved values
                  timeline = timeline.concat(data);
                  // Repeat function asynchronously
                  getTweet(maxId);
               }else{
                  mainDefer.resolve(timeline);
                  return defer.promise;
               }
            }, function(err) {
               console.log('waiting…');
               $timeout(getTweet, 300000); // Wait 5 minutes for new session
            });
            return defer.promise;
         }
      }
      getTweet();
      mainDefer.promise.then(function(data) {
         console.log('get user timeline success');
      });
      return mainDefer.promise;
   },
   getMentionsTimeline: function(maxId) {
      // Initiate empty array to collect the mentions timeline
      var timeline = [];
      //create a defer object using Angular's $q service
      var mainDefer = $q.defer();
      //Form request URL
      var baseURL = '/1.1/statuses/mentions_timeline.json?';
      var params = 'count=200';
      // Bind base URL and params
      var url = baseURL + params;
      // set counter
      var i = -1;
      function getTweet(maxId) {
         i++;
         var defer = $q.defer();
         if (maxId) {
            // Replace cursor in URL query params with new cursor
            url = url.replace(/&max_id=[\d]*/gi, "");
            url += '&max_id=' + maxId;
            if (i < 4) { // 4 to get up to 800 last tweets
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  defer.resolve(data);
                  if (data.length>0) {
                     // Set new maxId according to last tweet's id
                     var newMaxId = data[data.length - 1].id;
                     // console.log('new maxId: '+newMaxId);
                     // Set new timeline with retrieved values
                     timeline = timeline.concat(data);
                     //Check timeline's new size (should be +200)
                     console.log('new timeline size : ' + timeline.length);
                     // Repeat function asynchronously
                     getTweet(newMaxId);
                  }else{
                     mainDefer.resolve(timeline);
                     return defer.promise;
                  }
               }, function(err) {
                  console.log('waiting…');
                  $timeout(getTweet, 300000); // Wait 5 minutes for new session
               });
               return defer.promise;
            } else {
               console.log('Final timeline size: ' + timeline.length);
               // Resolve main promise
               mainDefer.resolve(timeline);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            console.log('mentions run for maxId undefined');
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               defer.resolve(data);
               // Check if response array is empty
               if (data.length>0) {
                  // Set first maxId according to last tweet's id
                  maxId = data[data.length - 1].id;
                  // Set new timeline with retrieved values
                  timeline = timeline.concat(data);
                  // Repeat function asynchronously
                  getTweet(maxId);
               }else {
                  mainDefer.resolve(timeline);
                  return defer.promise;
               }

            }, function(err) {
               console.log('waiting…');
               $timeout(getTweet, 300000);
            });
            return defer.promise;
         }
      }
      getTweet();
      mainDefer.promise.then(function(data) {
         console.log('get mentions timeline success');
      });
      return mainDefer.promise;
   }
};
});
<commit_msg>Had to reset OAuth Daemon public key for some reason<commit_after>'use strict';
var services = angular.module('nestApp.services', []);
services.factory('twitterService', function($q, $rootScope, $timeout) {
   // initialize TwitterAuth service

   var TwitterAuth = false;
   return {
      initialize: function() {
         // Set callback URL to localhost for Developement
         OAuth.setOAuthdURL('http://oauthd-nest.herokuapp.com');
         //initialize OAuth Demon with public key of the application
         OAuth.initialize('cRwVCylgrK1I-Ox9TDOEBr3gWUM', {
            cache: true
         });
         //try to create an authorization result when the page loads, this means a returning user won't have to click the twitter button again
         TwitterAuth = OAuth.create('twitter');
      },
      isReady: function() {
         // Return boolean of twitter authorization state
         return (TwitterAuth);
      },
      connectTwitter: function() {
         var defer = $q.defer();
         OAuth.popup('twitter', {
            cache: true
         }, function(error, result) { //cache means to execute the callback if the tokens are already present
            if (!error) {
               TwitterAuth = result;
               defer.resolve();
            } else {
               //do something if there's an error
               defer.reject('Connexion failed', error);
            }
         });
         return defer.promise;
      },
      clearCache: function() {
         // Clear cache on logout to erase authentication token
         OAuth.clearCache('twitter');
         TwitterAuth = false;
      },
      getUser: function() {
         var defer = $q.defer();
         var promise = TwitterAuth.get('/1.1/account/verify_credentials.json').then(function(data) {
            // Calculate time to execute Nest with retrieved data
            setRemainingTime(data);
            // Set rootscope value for followers count
            $rootScope.totalFollowers = data.followers_count;
            //when the data is retrieved resolved the defer object
            defer.resolve(data);
         });
         //return the promise of the defer object
         return defer.promise;
         function setRemainingTime(usr){
            // The total execution time depends on the amount of followers
            // We can execute 15 requests of 200 followers in a 15-minute window
            // Calculate how many minutes will be needed
            var minutes = Math.floor(((usr.followers_count / 12000) - Math.floor(usr.followers_count / 12000)) * 60);
            // Calculate how many hours will be needed
            var hours = Math.floor(usr.followers_count / 12000);
            // Set in rootscop to display while loadingView is active
            $rootScope.remaining = {
               h: hours,
               m: minutes
            };
         }
      },
      blockUser: function(id) {
         var defer = $q.defer();
         var promise = TwitterAuth.post('/1.1/blocks/create.json?user_id='+id).then(function(data) {
            //when the data is retrieved resolved the defer object
            defer.resolve(data);
         }, function(err) {
            // If session has expired
            console.log('waiting...', err);
         });
         //return the promise of the defer object
         return defer.promise;
         function setRemainingTime(usr){
            // The total execution time depends on the amount of followers
            // We can execute 15 requests of 200 followers in a 15-minute window
            // Calculate how many minutes will be needed
            var minutes = Math.floor(((usr.followers_count / 12000) - Math.floor(usr.followers_count / 12000)) * 60);
            // Calculate how many hours will be needed
            var hours = Math.floor(usr.followers_count / 12000);
            // Set in rootscop to display while loadingView is active
            $rootScope.remaining = {
               h: hours,
               m: minutes
            };
         }
      },
      getFollowersActivity: function(usr, cursor) {
         // Initiate empty array that will contain the user's followers
         var followersList = [];
         var usrId = usr.id;
         //create a main defer object using Angular's $q service
         var mainDefer = $q.defer();
         //Form request URL
         var baseURL = '/1.1/followers/list.json?';
         var params = ['count=200', 'user_id=' + usrId, 'skip_status=false'];
         params = params.join('&');
         // Bind the base URL and the query params
         var url = baseURL + params;
         var i = -1; // For dev purposes
         function updateRemainingTime() {
            var hours = $rootScope.remaining.h;
            var minutes = $rootScope.remaining.m;
            minutes--;
            if (hours>0) {
               if (minutes < 0) {
                  minutes = 60 + minutes;
                  hours--;
               }
            }else{
               if (minutes<0) {
                  minutes=0;
                  hours=0;
               }
            }
            $rootScope.remaining.h = hours;
            $rootScope.remaining.m = minutes;
            $rootScope.$apply();
         }
         function getFollowers(cursor) {
            i++; // For dev purposes
            // Update rootscope with current state of the promise
            $rootScope.progressFollowers = followersList.length;
            var defer = $q.defer();
            // console.log('current cursor: ' + cursor); // For dev purposes
            if (cursor || cursor === 0) {
               // console.log('run for cursor defined: ' + cursor); // For dev purposes
               // Replace cursor in URL query params with new cursor
               url = url.replace(/&cursor=[\d]*/gi, "");
               url += '&cursor=' + cursor;
               // console.log(url); // For dev purposes
               // if (i < 0) { // dev
               if (cursor!==0) { // Final condition
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  defer.resolve(data);
                  // Set new cursor according to last page's next_id
                  var newCursor = data.next_cursor;
                  // Update followers list with retrieved values
                  followersList = followersList.concat(data.users);
                  // Update timer
                  updateRemainingTime();
                  // Repeat function asynchronously
                  getFollowers(newCursor);
               }, function(err) {
                  // If session has expired
                  console.log('waiting...');
                  $timeout(getFollowers, 300000); // Wait 5 minutes for new session
               });
            } else {
               // console.log('getFollowersActivity over', followersList.length); // For dev purposes
               // Resolve main pormise
               mainDefer.resolve(followersList);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            // console.log('run for cursor undefined', url); // For dev purposes
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               defer.resolve(data);
               // Set first cursor for paging
               cursor = data.next_cursor;
               // console.log('cursor', cursor); // For dev purposes
               // Update followersList with retrieved values
               followersList = followersList.concat(data.users);
               // Update timer
               updateRemainingTime();
               // Repeat function asynchronously if user has more than 200 followers
               if (usr.followers_count>200) {
                  getFollowers(cursor);
               } else {
                  // Otherwise, resolve main pormise
                  mainDefer.resolve(followersList);
                  return defer.promise;
               }
            }, function(err) {
               console.log('waiting...');
               $timeout(getFollowers, 300000); // Wait 5 minutes for new session
            });
            return defer.promise;
         }
      }
      getFollowers();
      mainDefer.promise.then(function(data) {
         console.log('get followers activity success', data.length); // For dev purposes
      });
      return mainDefer.promise;
   },
   getUserTimeline: function(usr, maxId) {
      var usrId = usr.id;
      var statusesCount = usr.statuses_count;
      var loops = Math.ceil(statusesCount/200);
      if (loops>16) {
         loops=16;
      }
      // Initiate empty array to collect user's tweets
      var timeline = [];
      //create a defer object using Angular's $q service
      var mainDefer = $q.defer();
      //Form request URL
      var baseURL = '/1.1/statuses/user_timeline.json?';
      var params = ['count=200', 'user_id=' + usrId];
      params = params.join('&');
      // Bind base URL and query params
      var url = baseURL + params;
      // set counter
      var i = -1;
      function getTweet(maxId) {
         i++;
         var defer = $q.defer();
         if (maxId) {
            // Replace cursor in URL query params with new cursor
            url = url.replace(/&max_id=[\d]*/gi, "");
            url += '&max_id=' + maxId;
            if (i < loops) { // 16 to get up to 3200 last tweets
            // if (i < 0) { // dev
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  if (data.length>0) {
                     defer.resolve(data);
                     // Set new maxId according to last tweet's id
                     var newMaxId = data[data.length - 1].id;
                     // Set new timeline with retrieved values
                     timeline = timeline.concat(data);
                     // Repeat function asynchronously
                     getTweet(newMaxId);
                  }else{
                     mainDefer.resolve(timeline);
                     return defer.promise;
                  }
               }, function(err) {
                  console.log('waiting…');
                  $timeout(getTweet(), 300000); // Wait 5 minutes for new session
               });
               return defer.promise;
            } else {
               // resolve main promise
               mainDefer.resolve(timeline);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            // console.log('user timelin run for maxId undefined'); // For dev purposes
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               // Check if response array is empty
               if (data.length>0) {
                  defer.resolve(data);
                  // Set first maxId according to last tweet's id
                  maxId = data[data.length - 1].id;
                  // Set new timeline with retrieved values
                  timeline = timeline.concat(data);
                  // Repeat function asynchronously
                  getTweet(maxId);
               }else{
                  mainDefer.resolve(timeline);
                  return defer.promise;
               }
            }, function(err) {
               console.log('waiting…');
               $timeout(getTweet, 300000); // Wait 5 minutes for new session
            });
            return defer.promise;
         }
      }
      getTweet();
      mainDefer.promise.then(function(data) {
         console.log('get user timeline success');
      });
      return mainDefer.promise;
   },
   getMentionsTimeline: function(maxId) {
      // Initiate empty array to collect the mentions timeline
      var timeline = [];
      //create a defer object using Angular's $q service
      var mainDefer = $q.defer();
      //Form request URL
      var baseURL = '/1.1/statuses/mentions_timeline.json?';
      var params = 'count=200';
      // Bind base URL and params
      var url = baseURL + params;
      // set counter
      var i = -1;
      function getTweet(maxId) {
         i++;
         var defer = $q.defer();
         if (maxId) {
            // Replace cursor in URL query params with new cursor
            url = url.replace(/&max_id=[\d]*/gi, "");
            url += '&max_id=' + maxId;
            if (i < 4) { // 4 to get up to 800 last tweets
               // Create promise
               var promise = TwitterAuth.get(url);
               promise.then(function(data) {
                  defer.resolve(data);
                  if (data.length>0) {
                     // Set new maxId according to last tweet's id
                     var newMaxId = data[data.length - 1].id;
                     // console.log('new maxId: '+newMaxId);
                     // Set new timeline with retrieved values
                     timeline = timeline.concat(data);
                     //Check timeline's new size (should be +200)
                     console.log('new timeline size : ' + timeline.length);
                     // Repeat function asynchronously
                     getTweet(newMaxId);
                  }else{
                     mainDefer.resolve(timeline);
                     return defer.promise;
                  }
               }, function(err) {
                  console.log('waiting…');
                  $timeout(getTweet, 300000); // Wait 5 minutes for new session
               });
               return defer.promise;
            } else {
               console.log('Final timeline size: ' + timeline.length);
               // Resolve main promise
               mainDefer.resolve(timeline);
               return defer.promise;
            }
         } else {
            //Execute request for the first time
            console.log('mentions run for maxId undefined');
            // Create promise
            var promise = TwitterAuth.get(url);
            promise.then(function(data) {
               defer.resolve(data);
               // Check if response array is empty
               if (data.length>0) {
                  // Set first maxId according to last tweet's id
                  maxId = data[data.length - 1].id;
                  // Set new timeline with retrieved values
                  timeline = timeline.concat(data);
                  // Repeat function asynchronously
                  getTweet(maxId);
               }else {
                  mainDefer.resolve(timeline);
                  return defer.promise;
               }

            }, function(err) {
               console.log('waiting…');
               $timeout(getTweet, 300000);
            });
            return defer.promise;
         }
      }
      getTweet();
      mainDefer.promise.then(function(data) {
         console.log('get mentions timeline success');
      });
      return mainDefer.promise;
   }
};
});
<|endoftext|>


<commit_before>import React from 'react';

import {
  shallow,
  mount
} from 'enzyme';

import Log from '../Log';

/* global sinon */
const { spy } = sinon;

describe('<Log>', function() {

  describe('entries', function() {

    it('should hide, if collapsed', function() {

      // given
      const {
        tree
      } = createLog({
        expanded: false,
        entries: [
          { category: 'warning', message: 'HE' },
          { category: 'error', message: 'HO' },
          {}
        ]
      });

      // when
      const entries = tree.find('.entries');

      // then
      expect(entries).to.be.empty;
    });

    it('should show, if expanded', function() {

      // given
      const {
        tree
      } = createLog({
        expanded: true,
        entries: [
          { category: 'warning', message: 'HE' },
          { category: 'error', message: 'HO' },
          {}
        ]
      }, mount);

      // when
      const entry = tree.find('.entry');

      // then
      expect(entry.at(0).text()).to.eql('HE  [warning]');
      expect(entry.at(1).text()).to.eql('HO  [error]');
      expect(entry.at(2).text()).to.eql(' ');
    });

  });

  describe('controls', function() {

    it('log toggle', function() {

      const onToggle = spy((expanded) => {
        expect(expanded).to.be.false;
      });

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true,
        onToggle
      }, mount);

      instance.setState({
        focussed: true
      });

      // when
      const button = tree.find('.toggle-button');

      button.simulate('click');

      // then
      expect(onToggle).to.have.been.calledOnce;
    });

    it('log copy', function() {

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true
      }, mount);

      instance.setState({
        focussed: true
      });

      // when
      const button = tree.find('.copy-button');

      // then
      button.simulate('click');
    });

    it('log clear', function() {

      const onToggle = spy((expanded) => {
        expect(expanded).to.be.false;
      });

      const onClear = spy();

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true,
        onToggle,
        onClear
      }, mount);

      instance.setState({
        focussed: true
      });

      // when
      const button = tree.find('.clear-button');

      button.simulate('click');

      // then
      expect(onToggle).to.have.been.calledOnce;
      expect(onClear).to.have.been.calledOnce;
    });

  });

});

// helpers /////////////////////////////////////

function noop() {}

function createLog(options = {}, mountFn=shallow) {

  if (typeof options === 'function') {
    mountFn = options;
    options = {};
  }

  const tree = mountFn(
    <Log
      entries={ options.entries || [] }
      expanded={ options.expanded || false }
      onToggle={ options.onToggle || noop }
      onClear={ options.onClear || noop }
    />
  );

  const instance = tree.instance();

  return {
    tree,
    instance
  };

}<commit_msg>test(client/Log): freeze current behavior *GG*<commit_after>import React from 'react';

import {
  shallow,
  mount
} from 'enzyme';

import Log from '../Log';

/* global sinon */
const { spy, fake } = sinon;

describe('<Log>', function() {

  describe('entries', function() {

    it('should hide, if collapsed', function() {

      // given
      const {
        tree
      } = createLog({
        expanded: false,
        entries: [
          { category: 'warning', message: 'HE' },
          { category: 'error', message: 'HO' },
          {}
        ]
      });

      // when
      const entries = tree.find('.entries');

      // then
      expect(entries).to.be.empty;
    });

    it('should show, if expanded', function() {

      // given
      const {
        tree
      } = createLog({
        expanded: true,
        entries: [
          { category: 'warning', message: 'HE' },
          { category: 'error', message: 'HO' },
          {}
        ]
      }, mount);

      // when
      const entry = tree.find('.entry');

      // then
      expect(entry.at(0).text()).to.eql('HE  [warning]');
      expect(entry.at(1).text()).to.eql('HO  [error]');
      expect(entry.at(2).text()).to.eql(' ');
    });

  });

  describe('focus / hover', function() {

    it('should update state', function() {

      // given
      const {
        instance
      } = createLog({
        expanded: true
      });

      // when
      instance.handleFocus();

      // then
      expect(instance.state.focus).to.be.true;

      // when
      instance.handleBlur();

      // then
      expect(instance.state.focus).to.be.false;

      // when
      instance.handleHover();

      // then
      expect(instance.state.hover).to.be.true;

      // when
      instance.handleOut();

      // then
      expect(instance.state.hover).to.be.false;
    });

  });

  describe('scroll handling', function() {

    it('should check without entries', function() {

      // given
      const {
        instance
      } = createLog({
        expanded: true,
        entries: []
      }, mount);

      // when
      instance.checkFocus();

      // then
      // no error threw :o)
    });

    it('should focus last entry', function() {

      // given
      const {
        instance
      } = createLog({
        expanded: true,
        entries: [
          { category: 'warning', message: 'HE' },
          { category: 'error', message: 'HO' },
          {}
        ]
      }, mount);

      // when
      instance.checkFocus();

      // then
      // no error threw :o)
    });

  });

  describe('controls', function() {

    it('log toggle', function() {

      const onToggle = spy((expanded) => {
        expect(expanded).to.be.false;
      });

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true,
        onToggle
      }, mount);

      instance.handleFocus();

      // when
      const button = tree.find('.toggle-button');

      button.simulate('click');

      // then
      expect(onToggle).to.have.been.calledOnce;
    });

    it('log copy', function() {

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true
      }, mount);

      instance.setState({
        focussed: true
      });

      // when
      const button = tree.find('.copy-button');

      // then
      button.simulate('click');
    });

    it('log clear', function() {

      const onToggle = spy((expanded) => {
        expect(expanded).to.be.false;
      });

      const onClear = spy();

      // given
      const {
        instance,
        tree
      } = createLog({
        expanded: true,
        onToggle,
        onClear
      }, mount);

      instance.handleFocus();

      // when
      const button = tree.find('.clear-button');

      button.simulate('click');

      // then
      expect(onToggle).to.have.been.calledOnce;
      expect(onClear).to.have.been.calledOnce;
    });

  });

  describe('keyboard shortcuts', function() {

    it('should close on <ESC>', function() {

      // given
      const onToggle = spy((expanded) => {
        expect(expanded).to.be.false;
      });

      const {
        instance
      } = createLog({
        expanded: true,
        onToggle
      });

      // when
      instance.handleKeyDown({
        keyCode: 27,
        preventDefault: fake()
      });

      // then
      expect(onToggle).to.have.been.calledOnce;
    });

    it('should select all on <CTRL + A>', function() {

      // given
      const {
        instance
      } = createLog({
        expanded: true
      }, mount);

      const handleCopy = spy(instance, 'handleCopy');

      // when
      //
      instance.handleKeyDown({
        keyCode: 65,
        ctrlKey: true,
        preventDefault: fake()
      });

      // then
      expect(handleCopy).to.have.been.calledOnce;
    });

  });

});

// helpers /////////////////////////////////////

function noop() {}

function createLog(options = {}, mountFn=shallow) {

  if (typeof options === 'function') {
    mountFn = options;
    options = {};
  }

  const tree = mountFn(
    <Log
      entries={ options.entries || [] }
      expanded={ options.expanded || false }
      onToggle={ options.onToggle || noop }
      onClear={ options.onClear || noop }
    />
  );

  const instance = tree.instance();

  return {
    tree,
    instance
  };

}<|endoftext|>


<commit_before>// Given a set of non-negative integers, and a value sum,
// determine if there is a subset of the given set with sum equal to given sum.

// Examples: set = [3, 34, 4, 12, 5, 2], sum = 9
// Output:  True  //There is a subset (4, 5) with sum 9.

function subSetSum( nums, target ){
  var list = [];
  backtrack( list, [], nums, 0);
  return list;
}

function backtrack( list, tempList, nums, start ){
    list.push( tempList );
    for( var i = start; i < nums.length; i++ ){
      tempList.push( nums[i] );
      backtrack( list, tempList, nums, i+1 );
      tempList.pop();
    }
}

var set = [ [1, 2] ];
console.log(subSetSum( set ))

<commit_msg>add 1st timed soluton - scope is off on result<commit_after>// Given a set of non-negative integers, and a value sum,
// determine if there is a subset of the given set with sum equal to given sum.

// Examples: set = [3, 34, 4, 12, 5, 2], sum = 9
// Output:  True  //There is a subset (4, 5) with sum 9.

var combinationSum = function(candidates, target) {
    var result = [];

    function backtrack( start, sum, buildUp ){
        if( sum === target ){
            result.push(buildUp);
        } else if( sum < target ){
            for( var i = start; i < candidates.length; i++ ){
                buildUp.push( candidates[i] );
                sum += candidates[i];
                backtrack( i, sum, buildUp );
                sum -= candidates[i];
                buildUp.pop();
            }
        }
    }
    backtrack( 0, 0, [] );
    return result;
};

var set = [3, 34, 4, 12, 5, 2]
console.log(combinationSum( set, 3 ))

<|endoftext|>


<commit_before>/*
 Copyright (c) 2013-2017 by Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL

 Permission to use this software for any purpose without fee is hereby granted, provided
 that the above copyright notice and this permission notice appear in all copies.

 Permission to copy and/or edit this software or parts of it for any purpose is permitted,
 provided that the following points are followed.
 - The above copyright notice and this permission notice appear in all copies
 - Within two (2) days after modification is proven working, any modifications are send back
   to the original authors to be inspected with the goal of inclusion in the official software
 - Any edited version are only test versions and not permitted to be run as a final product
 - Any edited version aren't to be distributed
 - Any edited version have the prerelease version set to something that can be distinguished
   from a version used in the original software

 TERMS OF REPRODUCTION USE

 Failure to follow these terms will result in me getting very angry at you
 and having your software tweaked or removed if possible. Either way, you're
 still an idiot for not following such a basic rule.
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS
 BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 * @Author:    Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL (Member. on Plug.dj)

 * [NOTE]: THERE IS NOTHING HERE FOR YOU! COPYING ANY PART OF THIS SCRIPT AND USING "IT" or "AS" (yours)
 *         WELL SERIOUSLY GET YOU TO FACE THE CONSEQUENCES!
 */

var path = 'http://pastebin.com/raw.php?i=';

function message(contents) {
        var msg = '
Plugwoot™  '+ contents +'
';
        $('#chat-messages').append(msg);
}

var scriptFail = window.setTimeout(function() {
  message('Sorry plugwoot is updating! :(');
  }, 2000);

$.getScript(path/*+'NPqKyJwy'*/, function() {
 message("version "+ PlugStation.version +" is now available!");
 console.log("Plugwoot "+ PlugStation.version +" - Created by ๖ۣۜĐل - ɴᴇᴏɴ - TFL");
 window.clearTimeout(scriptFail);
 });
<commit_msg>Update Plugwoot.js<commit_after>/*
 Copyright (c) 2013-2017 by Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL

 Permission to use this software for any purpose without fee is hereby granted, provided
 that the above copyright notice and this permission notice appear in all copies.

 Permission to copy and/or edit this software or parts of it for any purpose is permitted,
 provided that the following points are followed.
 - The above copyright notice and this permission notice appear in all copies
 - Within two (2) days after modification is proven working, any modifications are send back
   to the original authors to be inspected with the goal of inclusion in the official software
 - Any edited version are only test versions and not permitted to be run as a final product
 - Any edited version aren't to be distributed
 - Any edited version have the prerelease version set to something that can be distinguished
   from a version used in the original software

 TERMS OF REPRODUCTION USE

 Failure to follow these terms will result in me getting very angry at you
 and having your software tweaked or removed if possible. Either way, you're
 still an idiot for not following such a basic rule.
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS
 BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

 * @Author:    Tawi Jordan - ๖ۣۜĐJ - ɴᴇᴏɴ - TFL (Member. on Plug.dj)

 * [NOTE]: THERE IS NOTHING HERE FOR YOU! COPYING ANY PART OF THIS SCRIPT AND USING "IT" or "AS" (yours)
 *         WELL SERIOUSLY GET YOU TO FACE THE CONSEQUENCES!
 */

var path = 'http://pastebin.com/raw.php?i=';

function message(contents) {
        var msg = '
Plugwoot™  '+ contents +'
';
        $('#chat-messages').append(msg);
}

var scriptFail = window.setTimeout(function() {
  //message("Oops! Something went wrong!")
  message('Sorry plugwoot is updating! :(');
  }, 2000);

$.getScript(path/*+'NPqKyJwy'*/, function() {
 message("version "+ PlugStation.version +" is now available!");
 console.log("Plugwoot "+ PlugStation.version +" - Created by ๖ۣۜĐل - ɴᴇᴏɴ - TFL");
 window.clearTimeout(scriptFail);
 });
<|endoftext|>


<commit_before>//A script to migrate all SQLite databases when the database schema has changed.

const path=require("path");
const fs=require("fs-extra");
const sqlite3 = require('sqlite3').verbose(); //https://www.npmjs.com/package/sqlite3

const blankPath=path.join(__dirname, "dictTemplates/blank.sqlite");
migrateDBs(path.join(__dirname, "../data/dicts/"));
//migrateDBs(path.join(__dirname, "../website/dictTemplates/"));

function migrateDBs(dirPath){
  var filenames=fs.readdirSync(dirPath).filter(filename => /\.sqlite$/.test(filename) && filename!=path.basename(blankPath));
  var count=filenames.length;
  console.log(`${count} databases to do`);
  filenames.map(filename => {
    var filepath=path.join(dirPath, filename);
    migrateDB(filepath, function(){
      console.log(`${--count} databases remaining`);
    });
  });
}

function migrateDB(newPath, next){
  var dbName=path.basename(newPath);
  //console.log(`${dbName} BEGINS`);

  //rename old database to ".old" and open it:
  var oldPath=newPath+".old";
  fs.moveSync(newPath, oldPath);
  var oldDB=new sqlite3.Database(oldPath, sqlite3.OPEN_READONLY, function(){oldDB.run('PRAGMA journal_mode=OFF')});

  //create new database and open it:
  fs.copySync(blankPath, newPath);
  var newDB=new sqlite3.Database(newPath, sqlite3.OPEN_READWRITE, function(){newDB.run('PRAGMA journal_mode=OFF')});

  //migrate tables from old database to new database:
  migrateConfigs(function(){
    migrateEntries(function(){
      migrateHistory(function(){
        migrateSearchables(function(){
          oldDB.close();
          newDB.close();
          //console.log(`${dbName} ENDS`);
          if(next) next();
        })
      })
    })
  });

  function migrateConfigs(next){
    //console.log(`${dbName} [configs] BEGINS`);
    oldDB.each("select id, json from configs", function(err, row){
      newDB.serialize(function(){
        newDB.run("delete from configs where id=$id", {$id: row.id});
        newDB.run("insert into configs(id, json) values($id, $json)", {
          $id: row.id,
          $json: row.json
        });
      });
    }, function(){
      //console.log(`${dbName} [configs] ENDS`);
      next();
    });
  };

  function migrateEntries(next){
    //console.log(`${dbName} [entries] BEGINS`);
    oldDB.each("select id, xml, title, sortkey, needs_resave from entries", function(err, row){
      newDB.run("insert into entries(id, doctype, xml, title, sortkey, needs_resave) values($id, $doctype, $xml, $title, $sortkey, $needs_resave)", {
        $id: row.id,
        $doctype: getDoctype(row.xml),
        $xml: row.xml,
        $title: row.title,
        $sortkey: row.sortkey,
        $needs_resave: row.needs_resave
      });
    }, function(){
      //console.log(`${dbName} [entries] ENDS`);
      next();
    });
  };

  function migrateHistory(next){
    //console.log(`${dbName} [history] BEGINS`);
    oldDB.each("select id, entry_id, action, [when], email, xml, historiography from history", function(err, row){
      newDB.run("insert into history(id, entry_id, action, [when], email, xml, historiography) values($id, $entry_id, $action, $when, $email, $xml, $historiography)", {
        $id: row.id,
        $entry_id: row.entry_id,
        $action: row.action,
        $when: row.when,
        $email: row.email,
        $xml: row.xml,
        $historiography: row.historiography
      });
    }, function(){
      //console.log(`${dbName} [history] ENDS`);
      next();
    });
  };

  function migrateSearchables(next){
    //console.log(`${dbName} [searchables] BEGINS`);
    oldDB.each("select id, entry_id, txt, level from searchables", function(err, row){
      newDB.run("insert into searchables(id, entry_id, txt, level) values($id, $entry_id, $txt, $level)", {
        $id: row.id,
        $entry_id: row.entry_id,
        $txt: row.txt,
        $level: row.level,
      });
    }, function(){
      //console.log(`${dbName} [searchables] ENDS`);
      next();
    });
  };
};

function getDoctype(xml){
  var ret="";
  xml.replace(/^\<([^\>\/\s]+)/, function(found, $1){ ret=$1 });
  return ret;
}
<commit_msg>tweaks<commit_after>//A script to migrate all SQLite databases when the database schema has changed.

const path=require("path");
const fs=require("fs-extra");
const sqlite3 = require('sqlite3').verbose(); //https://www.npmjs.com/package/sqlite3

const blankPath=path.join(__dirname, "dictTemplates/blank.sqlite");
//migrateDBs(path.join(__dirname, "../data/dicts/"));
//migrateDBs(path.join(__dirname, "../website/dictTemplates/"));
migrateDB(path.join(__dirname, "../data/dicts/zdpcsy6gx.sqlite"), function(){});

function migrateDBs(dirPath){
  var filenames=fs.readdirSync(dirPath).filter(filename => /\.sqlite$/.test(filename) && filename!=path.basename(blankPath));
  var count=filenames.length;
  console.log(`${count} databases to do`);
  filenames.map(filename => {
    var filepath=path.join(dirPath, filename);
    migrateDB(filepath, function(){
      console.log(`${--count} databases remaining`);
    });
  });
}

function migrateDB(newPath, next){
  var dbName=path.basename(newPath);
  //console.log(`${dbName} BEGINS`);

  //rename old database to ".old" and open it:
  var oldPath=newPath+".old";
  fs.moveSync(newPath, oldPath);
  var oldDB=new sqlite3.Database(oldPath, sqlite3.OPEN_READONLY, function(){oldDB.run('PRAGMA journal_mode=OFF')});

  //create new database and open it:
  fs.copySync(blankPath, newPath);
  var newDB=new sqlite3.Database(newPath, sqlite3.OPEN_READWRITE, function(){newDB.run('PRAGMA journal_mode=OFF')});

  //migrate tables from old database to new database:
  migrateConfigs(function(){
    migrateEntries(function(){
      migrateHistory(function(){
        migrateSearchables(function(){
          oldDB.close();
          newDB.close();
          //console.log(`${dbName} ENDS`);
          if(next) next();
        })
      })
    })
  });

  function migrateConfigs(next){
    //console.log(`${dbName} [configs] BEGINS`);
    oldDB.each("select id, json from configs", function(err, row){
      newDB.serialize(function(){
        newDB.run("delete from configs where id=$id", {$id: row.id});
        newDB.run("insert into configs(id, json) values($id, $json)", {
          $id: row.id,
          $json: row.json
        });
      });
    }, function(){
      //console.log(`${dbName} [configs] ENDS`);
      next();
    });
  };

  function migrateEntries(next){
    //console.log(`${dbName} [entries] BEGINS`);
    oldDB.each("select id, xml, title, sortkey, needs_resave from entries", function(err, row){
      newDB.run("insert into entries(id, doctype, xml, title, sortkey, needs_resave) values($id, $doctype, $xml, $title, $sortkey, $needs_resave)", {
        $id: row.id,
        $doctype: getDoctype(row.xml),
        $xml: row.xml,
        $title: row.title,
        $sortkey: row.sortkey,
        $needs_resave: row.needs_resave
      });
    }, function(){
      //console.log(`${dbName} [entries] ENDS`);
      next();
    });
  };

  function migrateHistory(next){
    //console.log(`${dbName} [history] BEGINS`);
    oldDB.each("select id, entry_id, action, [when], email, xml, historiography from history", function(err, row){
      newDB.run("insert into history(id, entry_id, action, [when], email, xml, historiography) values($id, $entry_id, $action, $when, $email, $xml, $historiography)", {
        $id: row.id,
        $entry_id: row.entry_id,
        $action: row.action,
        $when: row.when,
        $email: row.email,
        $xml: row.xml,
        $historiography: row.historiography
      });
    }, function(){
      //console.log(`${dbName} [history] ENDS`);
      next();
    });
  };

  function migrateSearchables(next){
    //console.log(`${dbName} [searchables] BEGINS`);
    oldDB.each("select id, entry_id, txt, level from searchables", function(err, row){
      newDB.run("insert into searchables(id, entry_id, txt, level) values($id, $entry_id, $txt, $level)", {
        $id: row.id,
        $entry_id: row.entry_id,
        $txt: row.txt,
        $level: row.level,
      });
    }, function(){
      //console.log(`${dbName} [searchables] ENDS`);
      next();
    });
  };
};

function getDoctype(xml){
  var ret="";
  xml.replace(/^\<([^\>\/\s]+)/, function(found, $1){ ret=$1 });
  return ret;
}
<|endoftext|>