<commit_before>import Prefab from './entityPrefab'

// client side class for Playable Characters
export default class Player extends Prefab {
  constructor(game, name, position, spriteKey) {
    // call it's superclass constructor
    super(game, name, position, spriteKey)
    // Send context as first argument!!
    this.anchor.set(0.25, 0.35)
    this.orientation = 4 // down
    this.speed = this.game.playerSpeed
    // TODO create dialogue logic.. maybe
    // this.dialoguesMemory = {}
    this.maxLife = this.game.playerLife
    this.life = this.maxLife
    this.inFight = false
    this.frames = {
        // the third value is the frame to come back to at the end of the animation
        // TODO reassign frame values based on the sprite.
      'attack_right': [0, 4, 9],
      'right': [5, 8],
      'idle_right': [9, 10],
      'attack_up': [11, 15, 20],
      'up': [16, 19],
      'idle_up': [20, 21],
      'attack_down': [22, 26, 31],
      'down': [27, 30],
      'idle_down': [31, 32],
      'attack_left': [33, 37, 42],
      'left': [38, 41],
      'idle_left': [42, 43]
    }
    // TODO reassign these children based on our assets
    // this.addChild(this.weapon = this.this.game.add.sprite(0, 0, 'atlas3'))
    // this.addChild(this.shadow = this.this.game.add.sprite(0, 5, 'atlas1', 'shadow'))
    this.events.onKilled.add(function(player) {
      this.game.displayedPlayers.delete(player.id)
    }, this)
    this.loadControls()
  }
  // changes color of name text if Player is the main Player
  setIsPlayer(flag) {
    this.isPlayer = flag
    if (this.isPlayer) this.nameHolder.addColor('#f4d442', 0)
  }
  // sets the player's name
  setName(name) {
    this.nameHolder.text = name
    this.nameHolder.x = Math.floor(16 - (this.nameHolder.width/2))
  }

  equipWeapon(key) {
    this.weapon.name = key
    this.weapon.frameName = key + '_0' // sets initial weapon animation frame
    this.weapon.absorbProperties(Game.itemsInfo[key]) // assigns stats to weapon
    this.atk = this.weapon.attack
    this.adjustWeapon() // will change weapons position on char sprite
    this.setAnimations(this.weapon)
    if (this.isPlayer) {
      Game.weaponIcon.frameName = this.weapon.icon+'_0' // weapons icon on screen?
      Client.setWeapon(key)
    }
    return true
  }

  adjustWeapon() {
    this.weapon.position.set(this.weapon.offsets.x, this.weapon.offsets.y)
  }

  equipArmor(key) {
    const armorInfo = Game.itemsInfo[key]
    this.def = armorInfo.def
    this.armorName = key
    return true
  }

  loadControls() {
    this.cursors = {}
    this.cursors.up = this.game.input.keyboard.addKey(Phaser.Keyboard.W)
    this.cursors.down = this.game.input.keyboard.addKey(Phaser.Keyboard.S)
    this.cursors.right = this.game.input.keyboard.addKey(Phaser.Keyboard.D)
    this.cursors.left = this.game.input.keyboard.addKey(Phaser.Keyboard.A)
    this.cursors.attack = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR)
    this.cursors.chat = this.game.input.keyboard.addKey(Phaser.Keyboard.TAB)
  }
  // TODO reimplement this fn when we manage life
  updateLife() {
    if (this.life < 0) this.life = 0
    const width = Game.computeLifeBarWidth()
    const tweenWidth = this.game.add.tween(Game.health.getChildAt(0)) // tween for the "body" of the bar
    const tweenEnd = this.game.add.tween(Game.health.getChildAt(1)) // tween for the curved tip
    tweenWidth.to({ width: width }, 200, null, false, 200)
    tweenEnd.to({ x: width }, 200, null, false, 200)
    tweenWidth.start()
    tweenEnd.start()
  }

  die(animate) {
    if (this.tween) this.stopMovement(false)
    this.target = null
    this.life = 0
    if (this.isPlayer) {
      // Game.moveTarget.visible = false
      this.updateLife()
      // setTimeout(Game.displayDeathScroll, Phaser.Timer.SECOND*2)
    }
    if (animate && this.inCamera) {
      this.frameName = 'death_0'
      this.animate('death', false)
      // Game.sounds.play('death')
    }
    this.delayedKill(750)
  }
  respawn() {
    this.revive() // method from the Phaser Sprite class
    this.orientation = this.game.rnd.between(1, 4)
    if (this.isPlayer) {
      this.life = this.maxLife
      this.updateLife()
    }
    this.idle(true)
  }
  update() {
    // so it doesn't float off into space...
    this.body.setZeroVelocity()
    if (this.cursors.up.isDown) {
      this.animations.play('up')
      this.body.moveUp(200)
    }
    if (this.cursors.down.isDown) {
      this.animations.play('down')
      this.body.moveDown(200)
    }
    if (this.cursors.left.isDown) {
      this.animations.play('left')
      this.body.moveLeft(200)
    }
    if (this.cursors.up.isDown) {
      this.animations.play('right')
      this.body.moveRight(200)
    }
    if (this.cursors.attack.isDown && this.orientation === 1) {
      this.animations.play('attack_up')
    }
    if (this.cursors.attack.isDown && this.orientation === 2) {
      this.animations.play('attack_left')
    }
    if (this.cursors.attack.isDown && this.orientation === 3) {
      this.animations.play('attack_right')
    }
    if (this.cursors.attack.isDown && this.orientation === 4) {
      this.animations.play('attack_down')
    }
  }
}
<commit_msg>feat: update player class to take damage<commit_after>import Prefab from './entityPrefab'

// client side class for Playable Characters
export default class Player extends Prefab {
  constructor(game, name, position, spriteKey) {
    // call it's superclass constructor
    super(game, name, position, spriteKey)
    // Send context as first argument!!
    this.anchor.set(0.25, 0.35)
    this.orientation = 4 // down
    this.speed = this.game.playerSpeed
    // TODO create dialogue logic.. maybe
    // this.dialoguesMemory = {}
    this.maxLife = this.game.playerLife
    this.life = this.maxLife
    this.inFight = false
    this.frames = {
        // the third value is the frame to come back to at the end of the animation
        // TODO reassign frame values based on the sprite.
      'attack_right': [0, 4, 9],
      'right': [5, 8],
      'idle_right': [9, 10],
      'attack_up': [11, 15, 20],
      'up': [16, 19],
      'idle_up': [20, 21],
      'attack_down': [22, 26, 31],
      'down': [27, 30],
      'idle_down': [31, 32],
      'attack_left': [33, 37, 42],
      'left': [38, 41],
      'idle_left': [42, 43]
    }
    // TODO reassign these children based on our assets
    // this.addChild(this.weapon = this.this.game.add.sprite(0, 0, 'atlas3'))
    // this.addChild(this.shadow = this.this.game.add.sprite(0, 5, 'atlas1', 'shadow'))
    this.events.onKilled.add(function(player) {
      this.game.displayedPlayers.delete(player.id)
    }, this)
    this.loadControls()
  }
  // changes color of name text if Player is the main Player
  setIsPlayer(flag) {
    this.isPlayer = flag
    if (this.isPlayer) this.nameHolder.addColor('#f4d442', 0)
  }
  // sets the player's name
  setName(name) {
    this.nameHolder.text = name
    this.nameHolder.x = Math.floor(16 - (this.nameHolder.width/2))
  }

  equipWeapon(key) {
    this.weapon.name = key
    this.weapon.frameName = key + '_0' // sets initial weapon animation frame
    this.weapon.absorbProperties(Game.itemsInfo[key]) // assigns stats to weapon
    this.atk = this.weapon.attack
    this.adjustWeapon() // will change weapons position on char sprite
    this.setAnimations(this.weapon)
    if (this.isPlayer) {
      Game.weaponIcon.frameName = this.weapon.icon+'_0' // weapons icon on screen?
      Client.setWeapon(key)
    }
    return true
  }

  adjustWeapon() {
    this.weapon.position.set(this.weapon.offsets.x, this.weapon.offsets.y)
  }

  equipArmor(key) {
    const armorInfo = Game.itemsInfo[key]
    this.def = armorInfo.def
    this.armorName = key
    return true
  }

  loadControls() {
    this.cursors = {}
    this.cursors.up = this.game.input.keyboard.addKey(Phaser.Keyboard.W)
    this.cursors.down = this.game.input.keyboard.addKey(Phaser.Keyboard.S)
    this.cursors.right = this.game.input.keyboard.addKey(Phaser.Keyboard.D)
    this.cursors.left = this.game.input.keyboard.addKey(Phaser.Keyboard.A)
    this.cursors.attack = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR)
    this.cursors.chat = this.game.input.keyboard.addKey(Phaser.Keyboard.TAB)
  }
  // TODO reimplement this fn when we manage life
  updateLife() {
    if (this.life < 0) this.life = 0
    const width = Game.computeLifeBarWidth()
    const tweenWidth = this.game.add.tween(Game.health.getChildAt(0)) // tween for the "body" of the bar
    const tweenEnd = this.game.add.tween(Game.health.getChildAt(1)) // tween for the curved tip
    tweenWidth.to({ width: width }, 200, null, false, 200)
    tweenEnd.to({ x: width }, 200, null, false, 200)
    tweenWidth.start()
    tweenEnd.start()
  }
  takeDamage(attack) {
    if (this.life <= 0 || (this.life - attack) <= 0) {
      //  what is animate parameter that should be passed in?
      this.die()
    } else {
      this.life -= attack
      //  updates life HUD
      this.updateLife()
    }
  }
  die(animate) {
    if (this.tween) this.stopMovement(false)
    this.target = null
    this.life = 0
    if (this.isPlayer) {
      // Game.moveTarget.visible = false
      this.updateLife()
      // setTimeout(Game.displayDeathScroll, Phaser.Timer.SECOND*2)
    }
    if (animate && this.inCamera) {
      this.frameName = 'death_0'
      this.animate('death', false)
      // Game.sounds.play('death')
    }
    this.delayedKill(750)
  }
  respawn() {
    this.revive() // method from the Phaser Sprite class
    this.orientation = this.game.rnd.between(1, 4)
    if (this.isPlayer) {
      this.life = this.maxLife
      this.updateLife()
    }
    this.idle(true)
  }
  update() {
    // so it doesn't float off into space...
    this.body.setZeroVelocity()
    if (this.cursors.up.isDown) {
      this.animations.play('up')
      this.body.moveUp(200)
    }
    if (this.cursors.down.isDown) {
      this.animations.play('down')
      this.body.moveDown(200)
    }
    if (this.cursors.left.isDown) {
      this.animations.play('left')
      this.body.moveLeft(200)
    }
    if (this.cursors.up.isDown) {
      this.animations.play('right')
      this.body.moveRight(200)
    }
    if (this.cursors.attack.isDown && this.orientation === 1) {
      this.animations.play('attack_up')
    }
    if (this.cursors.attack.isDown && this.orientation === 2) {
      this.animations.play('attack_left')
    }
    if (this.cursors.attack.isDown && this.orientation === 3) {
      this.animations.play('attack_right')
    }
    if (this.cursors.attack.isDown && this.orientation === 4) {
      this.animations.play('attack_down')
    }
  }
}
<|endoftext|>


<commit_before>"use strict";

var testHelper = require('../test-helper.js');
var uuid = require('uuid');

var expect = chai.expect;
var respoke = testHelper.respoke;
var respokeAdmin = testHelper.respokeAdmin;
var Q = testHelper.respoke.Q;

describe("respoke.Client", function () {
    this.timeout(30000);

    var testEnv = {
        tokens: []
    };

    before(function () {
        return respokeAdmin.apps.get({
            appId: testHelper.config.appId
        }).then(function (app) {
            testEnv.app = app;

            return Q(respokeAdmin.roles.create({
                appId: testHelper.config.appId,
                name: uuid.v4()
            }));
        }).then(function (role) {
            testEnv.role = role;
        });
    });

    after(function () {
        return respokeAdmin.roles.delete({
            roleId: testEnv.role.id
        });
    });

    describe("connecting to Respoke", function () {
        describe("with a valid token", function () {
            var client;
            var token;

            before(function () {
                client = respoke.createClient();

                return respokeAdmin.auth.endpoint({
                    endpointId: uuid.v4(),
                    appId: testHelper.config.appId,
                    roleId: testEnv.role.id
                }).then(function (tokenObject) {
                    token = tokenObject;
                });
            });

            it("succeeds and assigns an endpointId", function (done) {
                client.connect({
                    baseURL: testHelper.baseURL,
                    token: token.tokenId
                }).done(function onSuccess() {
                    expect(client.endpointId).not.to.be.undefined;
                    expect(client.endpointId).to.equal(token.endpointId);
                    done();
                }, function onError(err) {
                    done(err);
                });
            });
        });

        xdescribe("with connectionLimit error", function () {
            it("returns advert with connection limit error", function (done) {
                var clients = [];
                var tokens = [];
                var goal = 16;

                for (var i = 1; i <= goal; i += 1) {
                    clients.push(respoke.createClient({
                        baseURL: testHelper.baseURL,
                        appId: testEnv.app.id
                    }));
                }

                Q.all(clients.map(function () {
                    return Q(respokeAdmin.auth.endpoint({
                        endpointId: 'followee',
                        appId: testHelper.config.appId,
                        roleId: testEnv.role.id
                    })).then(function (token) {
                        tokens.push(token.tokenId);
                    });
                })).then(function () {
                    return Q.all(clients.map(function (client, index) {
                        return client.connect({ token: tokens[index] });
                    }));
                }).then(function () {
                    done(new Error("Clients should not connect successfully past connection limit!"));
                }).catch(function () {
                    done();
                }).done();
            });
        });

        xdescribe("over and over again with fast enough", function () {
            it("eventually hits the rate limit", function (done) {
                done();
            //     done = doneOnceBuilder(done);
            //     var clients = [];
            //     var tokens = [];
            //     var promises = [];
            //     var count = 0;
            //     var goal = 40;
            //     var timeout = 100;

            //     for (var i = 1; i <= goal; i += 1) {
            //         clients.push(respoke.createClient({
            //             baseURL: testHelper.baseURL,
            //             appId: testEnv.app.id
            //         }));
            //     }

            //     clients.forEach(function (client, index) {
            //         var deferred = Q.defer();
            //         promises.push(deferred.promise);

            //         setTimeout(function () {
            //             Q.nfcall(testFixture.createToken, testEnv.httpClient, {
            //                 roleId: testEnv.role.id,
            //                 appId: testEnv.app.id
            //             }).done(function (token) {
            //                 tokens.push(token.tokenId);
            //                 deferred.resolve();
            //             }, function () {
            //                 // handled elsewhere
            //                 deferred.resolve();
            //             });
            //         }, timeout * index);
            //     });

            //     Q.all(promises).done(function () {
            //         clients.forEach(function (client, index) {
            //             if (!tokens[index]) {
            //                 return;
            //             }
            //             client.connect({token: tokens[index]}).done(function () {
            //                 count += 1;
            //                 if (count === clients.length) { // all succeeded
            //                     done(new Error("Didn't hit rate limit."));
            //                 }
            //             }, function (err) {
            //                 if (err.message.indexOf('exceeded') > -1) {
            //                     done();
            //                     return;
            //                 }
            //                 count += 1;
            //                 if (count === clients.length) { // all succeeded
            //                     done(new Error("Didn't hit rate limit."));
            //                 }
            //             });
            //         });
            //     }, function (err) {
            //         done(new Error("Couldn't get enough tokens to attempt the test. " + err.message));
            //     });
            });
        });

        describe("with a made-up token", function () {
            var client;

            before(function () {
                client = respoke.createClient();
            });

            it("fails to connect", function (done) {
                client.connect({
                    baseURL: testHelper.baseURL,
                    token: 'blahblahblahblah'
                }).done(function onSuccess() {
                    done(new Error("Connect with invalid token should not work!"));
                }, function onError() {
                    expect(client.endpointId).to.be.undefined;
                    done();
                });
            });
        });
    });
});
<commit_msg>fix baseURL reference in client specs<commit_after>"use strict";

var testHelper = require('../test-helper.js');
var uuid = require('uuid');

var expect = chai.expect;
var respoke = testHelper.respoke;
var respokeAdmin = testHelper.respokeAdmin;
var Q = testHelper.respoke.Q;

describe("respoke.Client", function () {
    this.timeout(30000);

    var testEnv = {
        tokens: []
    };

    before(function () {
        return respokeAdmin.apps.get({
            appId: testHelper.config.appId
        }).then(function (app) {
            testEnv.app = app;

            return Q(respokeAdmin.roles.create({
                appId: testHelper.config.appId,
                name: uuid.v4()
            }));
        }).then(function (role) {
            testEnv.role = role;
        });
    });

    after(function () {
        return respokeAdmin.roles.delete({
            roleId: testEnv.role.id
        });
    });

    describe("connecting to Respoke", function () {
        describe("with a valid token", function () {
            var client;
            var token;

            before(function () {
                client = respoke.createClient();

                return respokeAdmin.auth.endpoint({
                    endpointId: uuid.v4(),
                    appId: testHelper.config.appId,
                    roleId: testEnv.role.id
                }).then(function (tokenObject) {
                    token = tokenObject;
                });
            });

            it("succeeds and assigns an endpointId", function (done) {
                client.connect({
                    baseURL: testHelper.config.baseURL,
                    token: token.tokenId
                }).done(function onSuccess() {
                    expect(client.endpointId).not.to.be.undefined;
                    expect(client.endpointId).to.equal(token.endpointId);
                    done();
                }, function onError(err) {
                    done(err);
                });
            });
        });

        xdescribe("with connectionLimit error", function () {
            it("returns advert with connection limit error", function (done) {
                var clients = [];
                var tokens = [];
                var goal = 16;

                for (var i = 1; i <= goal; i += 1) {
                    clients.push(respoke.createClient({
                        baseURL: testHelper.config.baseURL,
                        appId: testEnv.app.id
                    }));
                }

                Q.all(clients.map(function () {
                    return Q(respokeAdmin.auth.endpoint({
                        endpointId: 'followee',
                        appId: testHelper.config.appId,
                        roleId: testEnv.role.id
                    })).then(function (token) {
                        tokens.push(token.tokenId);
                    });
                })).then(function () {
                    return Q.all(clients.map(function (client, index) {
                        return client.connect({ token: tokens[index] });
                    }));
                }).then(function () {
                    done(new Error("Clients should not connect successfully past connection limit!"));
                }).catch(function () {
                    done();
                }).done();
            });
        });

        xdescribe("over and over again with fast enough", function () {
            it("eventually hits the rate limit", function (done) {
                done();
            //     done = doneOnceBuilder(done);
            //     var clients = [];
            //     var tokens = [];
            //     var promises = [];
            //     var count = 0;
            //     var goal = 40;
            //     var timeout = 100;

            //     for (var i = 1; i <= goal; i += 1) {
            //         clients.push(respoke.createClient({
            //             baseURL: testHelper.config.baseURL,
            //             appId: testEnv.app.id
            //         }));
            //     }

            //     clients.forEach(function (client, index) {
            //         var deferred = Q.defer();
            //         promises.push(deferred.promise);

            //         setTimeout(function () {
            //             Q.nfcall(testFixture.createToken, testEnv.httpClient, {
            //                 roleId: testEnv.role.id,
            //                 appId: testEnv.app.id
            //             }).done(function (token) {
            //                 tokens.push(token.tokenId);
            //                 deferred.resolve();
            //             }, function () {
            //                 // handled elsewhere
            //                 deferred.resolve();
            //             });
            //         }, timeout * index);
            //     });

            //     Q.all(promises).done(function () {
            //         clients.forEach(function (client, index) {
            //             if (!tokens[index]) {
            //                 return;
            //             }
            //             client.connect({token: tokens[index]}).done(function () {
            //                 count += 1;
            //                 if (count === clients.length) { // all succeeded
            //                     done(new Error("Didn't hit rate limit."));
            //                 }
            //             }, function (err) {
            //                 if (err.message.indexOf('exceeded') > -1) {
            //                     done();
            //                     return;
            //                 }
            //                 count += 1;
            //                 if (count === clients.length) { // all succeeded
            //                     done(new Error("Didn't hit rate limit."));
            //                 }
            //             });
            //         });
            //     }, function (err) {
            //         done(new Error("Couldn't get enough tokens to attempt the test. " + err.message));
            //     });
            });
        });

        describe("with a made-up token", function () {
            var client;

            before(function () {
                client = respoke.createClient();
            });

            it("fails to connect", function (done) {
                client.connect({
                    baseURL: testHelper.config.baseURL,
                    token: 'blahblahblahblah'
                }).done(function onSuccess() {
                    done(new Error("Connect with invalid token should not work!"));
                }, function onError() {
                    expect(client.endpointId).to.be.undefined;
                    done();
                });
            });
        });
    });
});
<|endoftext|>


<commit_before>/*
 * Inspired by https://gist.github.com/wadey/442463
 */

function TweetParser(tweet) {

	var text = tweet.text;
	var indexMap = [];
	var textChanged = false;

	var escapeHTML = function(text) {
		return $('
').text(text).html();
	};

	var parseHashtags = function() {
		if(typeof(tweet.entities.hashtags) == 'undefined')
			return;

		textChanged = true;
		var hashtag;
		for (var i = 0; i < tweet.entities.hashtags.length; i++) {
			hashtag = tweet.entities.hashtags[i];
			indexMap[hashtag.indices[0]] = {
				end : hashtag.indices[1],
				content : '#'
						+ escapeHTML(hashtag.text) + ''
			};
		}
	};

	var parseSymbols = function() {
		if(typeof(tweet.entities.symbols) == 'undefined')
			return;

		textChanged = true;
		var symbol;
		for (var i = 0; i < tweet.entities.symbols.length; i++) {
			symbol = tweet.entities.symbols[i];
			indexMap[symbol.indices[0]] = {
				end : symbol.indices[1],
				content : '$'
						+ escapeHTML(symbol.text) + ''
			};
		}
	};

	var parseUrls = function() {
		if(typeof(tweet.entities.urls) == 'undefined')
			return;

		textChanged = true;
		var url;
		for (var i = 0; i < tweet.entities.urls.length; i++) {
			url = tweet.entities.urls[i];
			indexMap[url.indices[0]] = {
				end : url.indices[1],
				content : ''
						+ escapeHTML(url.display_url) + ''
			};
		}
	};

	var parseUserMentions = function() {
		if(typeof(tweet.entities.user_mentions) == 'undefined')
			return;

		textChanged = true;
		var mention;
		for (var i = 0; i < tweet.entities.user_mentions.length; i++) {
			mention = tweet.entities.user_mentions[i];
			indexMap[mention.indices[0]] = {
				end : mention.indices[1],
				content : '@'
						+ escapeHTML(mention.screen_name) + ''
			};
		}
	};

	var parseMedia = function() {
		if(typeof(tweet.entities.media) == 'undefined')
			return;

		textChanged = true;
		var media;
		for (var i = 0; i < tweet.entities.media.length; i++) {
			media = tweet.entities.media[i];
			indexMap[media.indices[0]] = {
				end : media.indices[1],
				content : ''
			};
		}
	};

	this.parse = function() {
		parseHashtags();
		parseSymbols();
		parseUrls();
		parseUserMentions();
		parseMedia();
		return this.getText();
	};

	this.getText = function() {
		if (textChanged) {
			var result = '';
			var lastEnd = 0;
			for (var i = 0; i < tweet.text.length; i++) {
				var index = indexMap[i];
				if (index) {
					var start = i;
					var end = index.end;
					if (start > lastEnd)
						result += tweet.text.substring(lastEnd, start);
					result += index.content;
					i = end - 1;
					lastEnd = end;
				}
			}

			if (i > lastEnd)
				result += tweet.text.substr(lastEnd);

			text = result;
		}
		var div = document.createElement('div');
		var info = document.createElement('div');
		var author = document.createElement('a');
		var datetime = document.createElement('div');
		var tweetText = document.createElement('div');
		$(div).addClass('tweet');
		$(info).addClass('tweetInfo').appendTo(div);
		$(author).attr('href', 'https://twitter.com/' + tweet.user.name).html(tweet.user.name).addClass('tweetAuthor').appendTo(info);
		$(datetime).html(new Date(tweet.created_at).toLocaleTimeString()).addClass('tweetDateTime').appendTo(info);
		$(tweetText).html(text).addClass('tweetText').appendTo(div);
		return div;
	};

}<commit_msg>Author Link Bug<commit_after>/*
 * Inspired by https://gist.github.com/wadey/442463
 */

function TweetParser(tweet) {

	var text = tweet.text;
	var indexMap = [];
	var textChanged = false;

	var escapeHTML = function(text) {
		return $('
').text(text).html();
	};

	var parseHashtags = function() {
		if(typeof(tweet.entities.hashtags) == 'undefined')
			return;

		textChanged = true;
		var hashtag;
		for (var i = 0; i < tweet.entities.hashtags.length; i++) {
			hashtag = tweet.entities.hashtags[i];
			indexMap[hashtag.indices[0]] = {
				end : hashtag.indices[1],
				content : '#'
						+ escapeHTML(hashtag.text) + ''
			};
		}
	};

	var parseSymbols = function() {
		if(typeof(tweet.entities.symbols) == 'undefined')
			return;

		textChanged = true;
		var symbol;
		for (var i = 0; i < tweet.entities.symbols.length; i++) {
			symbol = tweet.entities.symbols[i];
			indexMap[symbol.indices[0]] = {
				end : symbol.indices[1],
				content : '$'
						+ escapeHTML(symbol.text) + ''
			};
		}
	};

	var parseUrls = function() {
		if(typeof(tweet.entities.urls) == 'undefined')
			return;

		textChanged = true;
		var url;
		for (var i = 0; i < tweet.entities.urls.length; i++) {
			url = tweet.entities.urls[i];
			indexMap[url.indices[0]] = {
				end : url.indices[1],
				content : ''
						+ escapeHTML(url.display_url) + ''
			};
		}
	};

	var parseUserMentions = function() {
		if(typeof(tweet.entities.user_mentions) == 'undefined')
			return;

		textChanged = true;
		var mention;
		for (var i = 0; i < tweet.entities.user_mentions.length; i++) {
			mention = tweet.entities.user_mentions[i];
			indexMap[mention.indices[0]] = {
				end : mention.indices[1],
				content : '@'
						+ escapeHTML(mention.screen_name) + ''
			};
		}
	};

	var parseMedia = function() {
		if(typeof(tweet.entities.media) == 'undefined')
			return;

		textChanged = true;
		var media;
		for (var i = 0; i < tweet.entities.media.length; i++) {
			media = tweet.entities.media[i];
			indexMap[media.indices[0]] = {
				end : media.indices[1],
				content : ''
			};
		}
	};

	this.parse = function() {
		parseHashtags();
		parseSymbols();
		parseUrls();
		parseUserMentions();
		parseMedia();
		return this.getText();
	};

	this.getText = function() {
		if (textChanged) {
			var result = '';
			var lastEnd = 0;
			for (var i = 0; i < tweet.text.length; i++) {
				var index = indexMap[i];
				if (index) {
					var start = i;
					var end = index.end;
					if (start > lastEnd)
						result += tweet.text.substring(lastEnd, start);
					result += index.content;
					i = end - 1;
					lastEnd = end;
				}
			}

			if (i > lastEnd)
				result += tweet.text.substr(lastEnd);

			text = result;
		}
		var div = document.createElement('div');
		var info = document.createElement('div');
		var author = document.createElement('a');
		var datetime = document.createElement('div');
		var tweetText = document.createElement('div');
		$(div).addClass('tweet');
		$(info).addClass('tweetInfo').appendTo(div);
		$(author).attr('href', 'https://twitter.com/' + tweet.user.screen_name).html(tweet.user.name).addClass('tweetAuthor').appendTo(info);
		$(datetime).html(new Date(tweet.created_at).toLocaleTimeString()).addClass('tweetDateTime').appendTo(info);
		$(tweetText).html(text).addClass('tweetText').appendTo(div);
		return div;
	};

}<|endoftext|>


<commit_before>'se strict';
const n = require('numeric');

module.exports = {
  defaultLambda: 0.0,

  objective(w, xVals, yVals, lambda) {
    const localLambda = lambda || this.defaultLambda;
    return n.sum(n.pow(n.sub(yVals, n.dot(xVals, w)), 2)) +
      (localLambda * n.dot(w, w) * 0.5);
  },

  oneShot(xVals, yVals, initialMVals) {
    const localInitialMVals = initialMVals || n.random(n.dim(xVals[0]));
    console.log('xVals are:',xVals);
    console.log('yVals are:',yVals);
    console.log('localInitialMVals are:',localInitialMVals);
    return n.uncmin(w => this.objective(w, xVals, yVals), localInitialMVals).solution;
  },
}
<commit_msg>set defualt lamda to 1<commit_after>'use strict';
const n = require('numeric');

module.exports = {
  defaultLambda: 1,

  objective(w, xVals, yVals, lambda) {
    const localLambda = lambda || this.defaultLambda;
    return n.sum(n.pow(n.sub(yVals, n.dot(xVals, w)), 2)) +
      (localLambda * n.dot(w, w) * 0.5);
  },

  oneShot(xVals, yVals, initialMVals) {
    const localInitialMVals = initialMVals || n.random(n.dim(xVals[0]));
    console.log('xVals are:',xVals);
    console.log('yVals are:',yVals);
    console.log('localInitialMVals are:',localInitialMVals);
    return n.uncmin(w => this.objective(w, xVals, yVals), localInitialMVals,0.0001).solution;
  },
}
<|endoftext|>


<commit_before>import {exec} from "child_process";
import inquirer from "inquirer";
import Logger from "./logger";

const messageBeforeAskingAutoInstall = `
  The provided configuration specified a plugin which can't be found .
  It's certainly because you didn't install it with npm before running Codemetrics.

  I can try to do it for you.
`;

module.exports = handlePlugin;

/**
 * This handler can check and install missing
 * plugins in order to provide a valide component
 * in the main runner
  // TODO provide silent option
  //TODO Test if url, give the ability to install a plugin out of npm ?
 */
// -> Auto install
//
function handlePlugin(plugin, type) {

  return isPluginValide(plugin) ?
    Promise.resolve(plugin) :
    searchForAPackage(plugin, type) ;
}

function searchForAPackage(plugin, type) {
  var promisePlugin;

  var pkgName = "codemetrics-" + type + "-" + plugin.name;

  try {
    const plugin = require(pkgName);

    //plugin.name = worker.name || plugin.name;

    promisePlugin = Promise.resolve(plugin);

  } catch (e) {
    // TODO Check if error is only for the package that codemetrics wants to require
    if (e.code === "MODULE_NOT_FOUND") {
      Logger.warning(`The ${plugin.name} ${type} ( ${pkgName} ) cannot be found.`);
      Logger.warning(messageBeforeAskingAutoInstall);

      promisePlugin = askForAutoInstall(pkgName)
        .then(() => installPackage(pkgName))
        .then(() => handlePlugin(plugin, type));
      //.then((plugin) => resolve(plugin))
      //.catch((message) => reject(message)

    } else {
      promisePlugin = Promise.reject({
        msg: "Plugin initialisation error",
        errorMsg: e
      });
    }
  }

  return promisePlugin;
}

function askForAutoInstall(pkgName) {

  return new Promise(function(resolve, reject) {
    inquirer.prompt([{
      type: "confirm",
      name: "autoinstall",
      message: "Do you want to install " + pkgName + " from npm ?",
      default: true
    }], function(response) {
      if (response.autoinstall) {
        resolve();
      } else {
        reject({
          msg: "Sorry I can't continue. You should provide a valid plugin..."
        });
      }
    });

  });
}

/**
 * The plugin must have a worker function
 * the worker must be a runnable function
 * @param  {[type]}  plugin [description]
 * @return {Boolean}        [description]
 */
function isPluginValide(plugin){
  /*if (plugin.worker && typeof(plugin.worker) === "function") {
    const worker = plugin.worker(plugin.options);

    if (worker.run && typeof(worker.run) === "function") {
      return true;

    } else {
      return false;
    }

  } else {
    return false;
  }*/

  //warn if name not present
  if(plugin.run) {
    if(typeof(plugin.run) === "function") {
      return true;
    } else {
      //TODO raison
      return false;
    }
  } else {
    //TODO raison
    return false;
  }
}

function installPackage(pkgName) {
  Logger.info("Trying to install from npm :  npm install " + pkgName);

  return new Promise(function(resolve, reject) {
    exec("npm install " + pkgName, function(error, stdout) {

      //TODO handle code error from npm
      if (error) {
        reject({
          msg: error
        });
      } else {
        Logger.debug(stdout);
        Logger.notice(pkgName + " install in progress...");
        resolve(stdout);
      }
    });
  });
}<commit_msg>plugin helper can correctly read plugins<commit_after>import {exec} from "child_process";
import inquirer from "inquirer";
import Logger from "./logger";

const messageBeforeAskingAutoInstall = `
  The provided configuration specified a plugin which can't be found .
  It's certainly because you didn't install it with npm before running Codemetrics.

  I can try to do it for you.
`;

module.exports = handlePlugin;

/**
 * This handler can check and install missing
 * plugins in order to provide a valide component
 * in the main runner
  // TODO provide silent option
  //TODO Test if url, give the ability to install a plugin out of npm ?
 */
// -> Auto install
//
function handlePlugin(plugin, type) {

  return isPluginValide(plugin) ?
    Promise.resolve(plugin) :
    searchForAPackage(plugin, type)
    .then(handlePlugin);
}

function searchForAPackage(plugin, type) {
  var promisePlugin;
  const pkgName = "codemetrics-" + type + "-" + plugin.name;
  Logger.debug("Search for "+pkgName);

  try {
    const pluginInstance = require(pkgName)();
    pluginInstance.name = pluginInstance.name || plugin.name;
    promisePlugin = Promise.resolve(pluginInstance);

  } catch (e) {
    // TODO Check if error is only for the package that codemetrics wants to require
    if (e.code === "MODULE_NOT_FOUND") {
      Logger.warning(`The ${plugin.name} ${type} ( ${pkgName} ) cannot be found.`);
      Logger.warning(messageBeforeAskingAutoInstall);

      promisePlugin = askForAutoInstall(pkgName)
        .then(() => installPackage(pkgName))
        .then(() => handlePlugin(plugin, type));
      //.then((plugin) => resolve(plugin))
      //.catch((message) => reject(message)

    } else {
      promisePlugin = Promise.reject({
        msg: "Plugin initialisation error",
        errorMsg: e
      });
    }
  }

  return promisePlugin;
}

function askForAutoInstall(pkgName) {

  return new Promise(function(resolve, reject) {
    inquirer.prompt([{
      type: "confirm",
      name: "autoinstall",
      message: "Do you want to install " + pkgName + " from npm ?",
      default: true
    }], function(response) {
      if (response.autoinstall) {
        resolve();
      } else {
        reject({
          msg: "Sorry I can't continue. You should provide a valid plugin..."
        });
      }
    });

  });
}

/**
 * The plugin must have a worker function
 * the worker must be a runnable function
 * @param  {[type]}  plugin [description]
 * @return {Boolean}        [description]
 */
function isPluginValide(plugin){
  //todo warn if name not present ?
  if(plugin.run) {
    if(typeof(plugin.run) === "function") {
      Logger.debug("\n Plugin "+plugin.name+" have a runnable function");
      return true;
    } else {
      Logger.debug("\n Plugin "+plugin.name+" : runnable property is not a function");
      //TODO raison
      return false;
    }
  } else {
    //TODO raison
    Logger.debug("\n Plugin "+plugin.name+" : runnable function not found");

    return false;
  }
}

function installPackage(pkgName) {
  Logger.info("Trying to install from npm :  npm install " + pkgName);

  return new Promise(function(resolve, reject) {
    exec("npm install " + pkgName, function(error, stdout) {

      //TODO handle code error from npm
      if (error) {
        reject({
          msg: error
        });
      } else {
        Logger.debug(stdout);
        Logger.notice(pkgName + " install in progress...");
        resolve(stdout);
      }
    });
  });
}<|endoftext|>


<commit_before>var BindableObject = require("../").Object,
expect = require("expect.js");

describe("bindable object", function() {

  var bindable, binding;

  it("can be created", function() {
    bindable = new BindableObject({
      name: {
        first: "craig",
        last: "con"
      },
      location: {
        city: "San Francisco"
      }
    });
  });

  it("can do perform a deep bind2", function(next) {
    bindable.bind("f.g.h.i", function(value) {
      expect(value).to.be(1);
      next();
    }).once().now();

    bindable.set("f.g.h", { i: 1 });
  });

  it("can reset an object", function() {
    var obj = new BindableObject({
      a:1,
      b:2,
      c:3
    })

    obj.reset({c:4,d:5});
    expect(obj.get("a")).to.be(undefined)
    expect(obj.get("b")).to.be(undefined)
    expect(obj.get("c")).to.be(4)
    expect(obj.get("d")).to.be(5)
  })

  it("can bind to location.zip", function(next) {

    bindable.bind("location.zip", function(value) {
      expect(value).not.to.be(undefined);
      next();
    }).once().now();

    bindable.set("location.zip", "94102");
  });

  it("can do perform a deep bind", function(next) {
    bindable.bind("a.b.c.d.e", function(value) {
      expect(value).to.be(1);
      next();
    }).once().now();

    bindable.set("a", { b: {c: { d: { e: 1 }}}})
  });

  it("can bind to a property", function() {

    bindable.bind("name", "name2").once().now();
    expect(bindable.get("name2.first")).to.be("craig");

    bindable.bind("doesntexist", "doesntexist2").once()
    expect(bindable.get("doesntexist2")).to.be(undefined);

    bindable.set("doesntexist", 5)
    expect(bindable.get("doesntexist2")).to.be(5);
  });

  it("previous name binding is not bound anymore", function() {
    bindable.set("doesntexist", 6);
    expect(bindable.get("doesntexist2")).to.be(5);
  })

  it("can be bound both ways", function() {
    bindable.bind("age", "age2").bothWays().limit(2)
    bindable.set("age", 5);
  });

  it("age should be 5", function() {
    expect(bindable.get("age")).to.be(5);
  });

  it("age2 should be 5", function() {
    expect(bindable.get("age2")).to.be(5);
    bindable.set("age2", 6);
  });

  it("age should be 6", function() {
    expect(bindable.get("age")).to.be(6);
  });

  it("age2 should be 6", function() {
    expect(bindable.get("age2")).to.be(6);
  });

  it("previous age binding is not bound anymore", function() {
    bindable.set("age2", 8);
    expect(bindable.get("age")).to.be(6);
  });

  it("previous age2 binding is not bound anymore", function() {
    bindable.set("age", 7);
    expect(bindable.get("age2")).to.be(8);
  });

  it("can be bound multiple times", function() {
    bindable.bind("count").to("count2").to("count3").once().now();
    bindable.set("count", 99);
    expect(bindable.get("count")).to.be(99);
    expect(bindable.get("count2")).to.be(99);
    expect(bindable.get("count3")).to.be(99);
  });

  it("can listen for multiple change events", function() {
    var bindable = new BindableObject({
      person: new BindableObject({
        name: new BindableObject({
          first: "craig",
          last: "craig"
        })
      })
    });

    var pn, binding = bindable.bind("person.name.first").to(function(value) {
      pn = value;
    }).now();

    bindable.set("person.name.first", "jake");
    expect(pn).to.be("jake");
    bindable.set("person.name", new BindableObject({ first: "josh" }));
    bindable.set("person.name.first", "jeff");
    expect(pn).to.be("jeff");
  })

  it("can be bound to a binding", function() {
    binding = bindable.bind("fish", "fish2").now();
    binding._from.set("fish", "sauce");
  });

  it("fish2 should be sauce", function() {
    expect(bindable.get("fish2")).to.be("sauce")
  });

  it("can bind fish2 the other way", function() {
    binding.bothWays().once();
    bindable.set("fish2", "sticks");
  });

  it("fish should be sticks", function() {
    expect(bindable.get("fish")).to.be("sticks")
    bindable.set("fish2", "sauce");
  });

  it("fish should still be sticks", function() {
    expect(bindable.get("fish")).to.be("sticks")
  });

  it("can transform one finding type to another synchronously", function() {

    bindable.set("name", "craig").bind("name").map(function(value) {
      return value.toUpperCase();
    }).to("name2").once().now();

    expect(bindable.get("name2")).to.be("CRAIG");
  });

  it("can perform multiple mappings", function() {
    var bindable = new BindableObject({
      name: "Craig"
    });

    bindable.bind("name").map(function(name) {
      return String(name).toLowerCase();
    }).to("nameLowerCase").
    map(function(name) {
      return String(name).toUpperCase()
    }).
    to("nameUpperCase").
    now();

    expect(bindable.get("nameLowerCase")).to.be("craig");
    expect(bindable.get("nameUpperCase")).to.be("CRAIG");
  });

  it("can form an undefined mapping", function() {
    var bindable = new BindableObject({
    });

    bindable.bind("name").map(function(name) {
      return name || "Craig";
    }).to("name2").now();

    expect(bindable.get("name2")).to.be("Craig");
  })

  it("can transform an object to and from", function() {
    var binding = bindable.set("name", "chris").bind("name").map({
      to: function(name) {
        return name.toUpperCase();
      },
      from: function(name) {
        return name.toLowerCase();
      }
    }).to("name2").bothWays().now();

    expect(bindable.get("name2")).to.be("CHRIS");
    bindable.set("name2", "LIAM");
    expect(bindable.get("name")).to.be("liam");

    binding.dispose();
  });

  it("can bind to a sub-binding", function() {

    var subBindable = new BindableObject({
      "first": "craig",
      "last": "craig"
    });

    var changedLast, binding;

    bindable.set({
      name: subBindable
    });

    binding = bindable.bind("name.last", function(value) {
      changedLast = value;
    }).once();

    bindable.set("name.last", "jefferds");
    expect(changedLast).to.be("jefferds");
    expect(subBindable.get("last")).to.be("jefferds");
    binding.dispose()
  });

  it("can bind to a sub-binding 2", function() {

    var subBindable = new BindableObject({
      "first": "craig",
      "last": "craig"
    });

    var changedLast;

    bindable.set({
      name: subBindable
    });

    bindable.bind("name.last", function(value) {
      changedLast = value;
    }).once();

    bindable.set("name.last", "jefferds");
    expect(changedLast).to.be("jefferds");
  });

  it("can bind to a sub-binding 3", function() {
    var b1 = new BindableObject({
      name: {
        first: "craig"
      }
    });

    var b2 = new BindableObject({
      person: b1
    });

    var b3 = new BindableObject({
      person: b1
    });

    b3.bind("person.name.last", "lastName");
    b2.set("person", b1);
    b2.set("person.name.last", "bubu");

    expect(b3.get("lastName")).to.be("bubu");
  });

  it("can bind to a property where a bindable object is wrapping around another", function() {
    var bindable = new BindableObject(new BindableObject({
        name: "craig"
    }));

    var newName1, newName2;

    bindable.bind("name", function(value) {
      newName1 = value;
    });

    bindable.context().bind("name", function(value) {
      newName2 = value;
    });
    bindable.context().set("name", "jake");
    expect(newName1).to.be("jake");
    expect(newName2).to.be("jake");
  });

  it("bindings are disposed when an bindable is", function() {
    var bindable = new BindableObject({
      name: "craig"
    }),
    newName;

    bindable.bind("name", function(value) {
      newName = value;
    })

    //sanity
    bindable.set("name", "sam");
    expect(newName).to.be("sam");

    bindable.dispose();
    bindable.set("name", "liam");
    expect(newName).to.be("sam");
  });

  it("can set data without overriding the original data object", function() {
    var bindable = new BindableObject({
      name: "craig"
    });
    bindable.set("data", { name: "john" });
    bindable.set("data.last", "blarg");
    expect(bindable.get("name")).to.be("craig");
    expect(bindable.get("data.name")).to.be("john");
    bindable.set("data.name", "mike");
    expect(bindable.get("data.name")).to.be("mike");

  });

  it("can bind to an object", function() {
    var bindable = new BindableObject({
      name: "craig"
    }), name;

    bindable.bind({
      from: "name",
      to: [
        function(value) {
          name = value;
        },
        "someName"
      ]
    }).now();

    expect(bindable.get("someName")).to.be("craig");
    expect(name).to.be("craig");
  })

  it("can set null key and not fail", function() {
    bindable.set(null, 0);
  });

  it("can set a bindable object to a bindable object", function() {
    var bindable = new BindableObject(new BindableObject({ name: "craig" }));
    expect(bindable.toObject("name")).to.be("craig");
  });

  it("can get an object of a nested bindable object", function() {
    var bindable = new BindableObject(new BindableObject({ name: "craig" }));
    expect(bindable.toObject().name).to.be("craig");
  });

  it("can set 0 and not be undefined", function() {
    var bindable = new BindableObject({ count: 0 });
    expect(bindable.get("count")).not.to.be(undefined);
  });

  it("can pass the old value to the second param", function() {
    var bindable = new BindableObject({name:"craig"});

    var i = 0;
    bindable.bind("name").to(function(value, oldValue) {

      if(i++ == 0) {
        expect(value).to.be("craig");
        expect(oldValue).to.be(undefined);
      } else {
        expect(value).to.be("john");
        expect(oldValue).to.be("craig");
      }

    }).limit(2).now();

    bindable.set("name", "john");
  })

  it("can bind to a boolean value", function(next) {
    var bindable = new BindableObject({
      form: {
        isValid: false
      }
    })

    bindable.bind("form.isValid").to(function(value) {
      expect(value).to.be(false);
      next()
    }).now();

  });

  it("can bind to a computed property", function() {
    var bindable = new BindableObject({
      firstName: "Jake",
      lastName: "Anderson"
    });

    bindable.bind("firstName, lastName").
      map(function(firstName, lastName) {
        return [firstName, lastName].join(" ");
      }).to("fullName").now();

    expect(bindable.get("fullName")).to.be("Jake Anderson");
    bindable.set("firstName", "John");
    expect(bindable.get("fullName")).to.be("John Anderson");
  });

  it("can bind a computed property both ways", function() {
    var bindable = new BindableObject({
      firstName: "Jake",
      lastName: "Anderson"
    });

    bindable.bind("firstName, lastName").
      map({
        to: function(firstName, lastName) {
          return [firstName, lastName].join(" ");
        },
        from: function(fullName) {
          return fullName.split(" ");
        }
      }).to("fullName").bothWays().now();

    bindable.set("fullName", "John Doe");
    expect(bindable.get("firstName")).to.be("John");
    expect(bindable.get("lastName")).to.be("Doe");
  });

  it("can bind an undefined value the other way", function() {
    var bindable = new BindableObject({
      firstName: "Craig"
    });

    bindable.bind("firstName", "firstName2").bothWays().now();

    expect(bindable.get("firstName2")).to.be("Craig");

    //control
    bindable.set("firstName2", "John");
    expect(bindable.get("firstName")).to.be("John");
    bindable.set("firstName2", undefined);
    expect(bindable.get("firstName")).to.be(undefined);
  })

  it("value isn't undefined if get('') is calling from bindable obj", function() {
    var bindable = new BindableObject({});
    bindable.control = "hello";
    bindable.name = false;
    bindable.name2 = 0;
    expect(bindable.get("control")).to.be("hello");
    expect(bindable.get("name")).to.be(false);
    expect(bindable.get("name2")).to.be(0);
  })

  //TODO - this should eventually apss
  if(false)
  it("can bind an undefined property and still get triggered", function() {
    var bindable = new BindableObject({ name: "Craig" }),
    a, b = 0;

    bindable.bind("name").to(function(value) {
      a = value;
    }).now().to(function(value) {
      b = value;
    });

    bindable.set("name", undefined)

    expect(a).to.be("Craig");
    expect(b).to.be(undefined);
  });

  describe("with delays", function() {

    it("can be added to a map", function() {
      var bo = new BindableObject({
      });

      bo.bind("a, b").delay(1).map(function(a, b) {
        expect(a).to.be(true);
        expect(b).to.be(true);
        return a && b;
      }).to(function(v) {
        expect(v).to.be(true);
      });

      bo.set("a", true);
      bo.set("b", true);

    })
  });

});<commit_msg>change @data to @__context - needs to be super private<commit_after>var BindableObject = require("../").Object,
expect = require("expect.js");

describe("bindable object", function() {

  var bindable, binding;

  it("can be created", function() {
    bindable = new BindableObject({
      name: {
        first: "craig",
        last: "con"
      },
      location: {
        city: "San Francisco"
      }
    });
  });

  it("can do perform a deep bind2", function(next) {
    bindable.bind("f.g.h.i", function(value) {
      expect(value).to.be(1);
      next();
    }).once().now();

    bindable.set("f.g.h", { i: 1 });
  });

  it("can reset an object", function() {
    var obj = new BindableObject({
      a:1,
      b:2,
      c:3
    })

    obj.reset({c:4,d:5});
    expect(obj.get("a")).to.be(undefined)
    expect(obj.get("b")).to.be(undefined)
    expect(obj.get("c")).to.be(4)
    expect(obj.get("d")).to.be(5)
  })

  it("can bind to location.zip", function(next) {

    bindable.bind("location.zip", function(value) {
      expect(value).not.to.be(undefined);
      next();
    }).once().now();

    bindable.set("location.zip", "94102");
  });

  it("can do perform a deep bind", function(next) {
    bindable.bind("a.b.c.d.e", function(value) {
      expect(value).to.be(1);
      next();
    }).once().now();

    bindable.set("a", { b: {c: { d: { e: 1 }}}})
  });

  it("can bind to a property", function() {

    bindable.bind("name", "name2").once().now();
    expect(bindable.get("name2.first")).to.be("craig");

    bindable.bind("doesntexist", "doesntexist2").once()
    expect(bindable.get("doesntexist2")).to.be(undefined);

    bindable.set("doesntexist", 5)
    expect(bindable.get("doesntexist2")).to.be(5);
  });

  it("previous name binding is not bound anymore", function() {
    bindable.set("doesntexist", 6);
    expect(bindable.get("doesntexist2")).to.be(5);
  })

  it("can be bound both ways", function() {
    bindable.bind("age", "age2").bothWays().limit(2)
    bindable.set("age", 5);
  });

  it("age should be 5", function() {
    expect(bindable.get("age")).to.be(5);
  });

  it("age2 should be 5", function() {
    expect(bindable.get("age2")).to.be(5);
    bindable.set("age2", 6);
  });

  it("age should be 6", function() {
    expect(bindable.get("age")).to.be(6);
  });

  it("age2 should be 6", function() {
    expect(bindable.get("age2")).to.be(6);
  });

  it("previous age binding is not bound anymore", function() {
    bindable.set("age2", 8);
    expect(bindable.get("age")).to.be(6);
  });

  it("previous age2 binding is not bound anymore", function() {
    bindable.set("age", 7);
    expect(bindable.get("age2")).to.be(8);
  });

  it("can be bound multiple times", function() {
    bindable.bind("count").to("count2").to("count3").once().now();
    bindable.set("count", 99);
    expect(bindable.get("count")).to.be(99);
    expect(bindable.get("count2")).to.be(99);
    expect(bindable.get("count3")).to.be(99);
  });

  it("can listen for multiple change events", function() {
    var bindable = new BindableObject({
      person: new BindableObject({
        name: new BindableObject({
          first: "craig",
          last: "craig"
        })
      })
    });

    var pn, binding = bindable.bind("person.name.first").to(function(value) {
      pn = value;
    }).now();

    bindable.set("person.name.first", "jake");
    expect(pn).to.be("jake");
    bindable.set("person.name", new BindableObject({ first: "josh" }));
    bindable.set("person.name.first", "jeff");
    expect(pn).to.be("jeff");
  })

  it("can be bound to a binding", function() {
    binding = bindable.bind("fish", "fish2").now();
    binding._from.set("fish", "sauce");
  });

  it("fish2 should be sauce", function() {
    expect(bindable.get("fish2")).to.be("sauce")
  });

  it("can bind fish2 the other way", function() {
    binding.bothWays().once();
    bindable.set("fish2", "sticks");
  });

  it("fish should be sticks", function() {
    expect(bindable.get("fish")).to.be("sticks")
    bindable.set("fish2", "sauce");
  });

  it("fish should still be sticks", function() {
    expect(bindable.get("fish")).to.be("sticks")
  });

  it("can transform one finding type to another synchronously", function() {

    bindable.set("name", "craig").bind("name").map(function(value) {
      return value.toUpperCase();
    }).to("name2").once().now();

    expect(bindable.get("name2")).to.be("CRAIG");
  });

  it("can perform multiple mappings", function() {
    var bindable = new BindableObject({
      name: "Craig"
    });

    bindable.bind("name").map(function(name) {
      return String(name).toLowerCase();
    }).to("nameLowerCase").
    map(function(name) {
      return String(name).toUpperCase()
    }).
    to("nameUpperCase").
    now();

    expect(bindable.get("nameLowerCase")).to.be("craig");
    expect(bindable.get("nameUpperCase")).to.be("CRAIG");
  });

  it("can form an undefined mapping", function() {
    var bindable = new BindableObject({
    });

    bindable.bind("name").map(function(name) {
      return name || "Craig";
    }).to("name2").now();

    expect(bindable.get("name2")).to.be("Craig");
  })

  it("can transform an object to and from", function() {
    var binding = bindable.set("name", "chris").bind("name").map({
      to: function(name) {
        return name.toUpperCase();
      },
      from: function(name) {
        return name.toLowerCase();
      }
    }).to("name2").bothWays().now();

    expect(bindable.get("name2")).to.be("CHRIS");
    bindable.set("name2", "LIAM");
    expect(bindable.get("name")).to.be("liam");

    binding.dispose();
  });

  it("can bind to a sub-binding", function() {

    var subBindable = new BindableObject({
      "first": "craig",
      "last": "craig"
    });

    var changedLast, binding;

    bindable.set({
      name: subBindable
    });

    binding = bindable.bind("name.last", function(value) {
      changedLast = value;
    }).once();

    bindable.set("name.last", "jefferds");
    expect(changedLast).to.be("jefferds");
    expect(subBindable.get("last")).to.be("jefferds");
    binding.dispose()
  });

  it("can bind to a sub-binding 2", function() {

    var subBindable = new BindableObject({
      "first": "craig",
      "last": "craig"
    });

    var changedLast;

    bindable.set({
      name: subBindable
    });

    bindable.bind("name.last", function(value) {
      changedLast = value;
    }).once();

    bindable.set("name.last", "jefferds");
    expect(changedLast).to.be("jefferds");
  });

  it("can bind to a sub-binding 3", function() {
    var b1 = new BindableObject({
      name: {
        first: "craig"
      }
    });

    var b2 = new BindableObject({
      person: b1
    });

    var b3 = new BindableObject({
      person: b1
    });

    b3.bind("person.name.last", "lastName");
    b2.set("person", b1);
    b2.set("person.name.last", "bubu");

    expect(b3.get("lastName")).to.be("bubu");
  });

  it("can bind to a property where a bindable object is wrapping around another", function() {
    var bindable = new BindableObject(new BindableObject({
        name: "craig"
    }));

    var newName1, newName2;

    bindable.bind("name", function(value) {
      newName1 = value;
    });

    bindable.context().bind("name", function(value) {
      newName2 = value;
    });
    bindable.context().set("name", "jake");
    expect(newName1).to.be("jake");
    expect(newName2).to.be("jake");
  });

  it("bindings are disposed when an bindable is", function() {
    var bindable = new BindableObject({
      name: "craig"
    }),
    newName;

    bindable.bind("name", function(value) {
      newName = value;
    })

    //sanity
    bindable.set("name", "sam");
    expect(newName).to.be("sam");

    bindable.dispose();
    bindable.set("name", "liam");
    expect(newName).to.be("sam");
  });

  it("can set data without overriding the original data object", function() {
    var bindable = new BindableObject({
      name: "craig"
    });
    bindable.set("data", { name: "john" });
    bindable.set("data.last", "blarg");
    expect(bindable.get("name")).to.be("craig");
    expect(bindable.get("data.name")).to.be("john");
    bindable.set("data.name", "mike");
    expect(bindable.get("data.name")).to.be("mike");

  });

  it("can bind to an object", function() {
    var bindable = new BindableObject({
      name: "craig"
    }), name;

    bindable.bind({
      from: "name",
      to: [
        function(value) {
          name = value;
        },
        "someName"
      ]
    }).now();

    expect(bindable.get("someName")).to.be("craig");
    expect(name).to.be("craig");
  })

  it("can set null key and not fail", function() {
    bindable.set(null, 0);
  });

  it("can set a bindable object to a bindable object", function() {
    var bindable = new BindableObject(new BindableObject({ name: "craig" }));
    expect(bindable.toObject("name")).to.be("craig");
  });

  it("can get an object of a nested bindable object", function() {
    var bindable = new BindableObject(new BindableObject({ name: "craig" }));
    expect(bindable.toObject().name).to.be("craig");
  });

  it("can set 0 and not be undefined", function() {
    var bindable = new BindableObject({ count: 0 });
    expect(bindable.get("count")).not.to.be(undefined);
  });

  it("can pass the old value to the second param", function() {
    var bindable = new BindableObject({name:"craig"});

    var i = 0;
    bindable.bind("name").to(function(value, oldValue) {

      if(i++ == 0) {
        expect(value).to.be("craig");
        expect(oldValue).to.be(undefined);
      } else {
        expect(value).to.be("john");
        expect(oldValue).to.be("craig");
      }

    }).limit(2).now();

    bindable.set("name", "john");
  })

  it("can bind to a boolean value", function(next) {
    var bindable = new BindableObject({
      form: {
        isValid: false
      }
    })

    bindable.bind("form.isValid").to(function(value) {
      expect(value).to.be(false);
      next()
    }).now();

  });

  it("can bind to a computed property", function() {
    var bindable = new BindableObject({
      firstName: "Jake",
      lastName: "Anderson"
    });

    bindable.bind("firstName, lastName").
      map(function(firstName, lastName) {
        return [firstName, lastName].join(" ");
      }).to("fullName").now();

    expect(bindable.get("fullName")).to.be("Jake Anderson");
    bindable.set("firstName", "John");
    expect(bindable.get("fullName")).to.be("John Anderson");
  });

  it("can bind a computed property both ways", function() {
    var bindable = new BindableObject({
      firstName: "Jake",
      lastName: "Anderson"
    });

    bindable.bind("firstName, lastName").
      map({
        to: function(firstName, lastName) {
          return [firstName, lastName].join(" ");
        },
        from: function(fullName) {
          return fullName.split(" ");
        }
      }).to("fullName").bothWays().now();

    bindable.set("fullName", "John Doe");
    expect(bindable.get("firstName")).to.be("John");
    expect(bindable.get("lastName")).to.be("Doe");
  });

  it("can bind an undefined value the other way", function() {
    var bindable = new BindableObject({
      firstName: "Craig"
    });

    bindable.bind("firstName", "firstName2").bothWays().now();

    expect(bindable.get("firstName2")).to.be("Craig");

    //control
    bindable.set("firstName2", "John");
    expect(bindable.get("firstName")).to.be("John");
    bindable.set("firstName2", undefined);
    expect(bindable.get("firstName")).to.be(undefined);
  })

  it("value isn't undefined if get('') is calling from bindable obj", function() {
    var bindable = new BindableObject({});
    bindable.control = "hello";
    bindable.name = false;
    bindable.name2 = 0;
    expect(bindable.get("control")).to.be("hello");
    expect(bindable.get("name")).to.be(false);
    expect(bindable.get("name2")).to.be(0);
  })

  //TODO - this should eventually apss
  if(false)
  it("can bind an undefined property and still get triggered", function() {
    var bindable = new BindableObject({ name: "Craig" }),
    a, b = 0;

    bindable.bind("name").to(function(value) {
      a = value;
    }).now().to(function(value) {
      b = value;
    });

    bindable.set("name", undefined)

    expect(a).to.be("Craig");
    expect(b).to.be(undefined);
  });

  it("cannot reference a property on the bindable object if the context isn't the bindable property", function() {
    var bindable = new BindableObject();
    bindable.name = "craig";
    expect(bindable.get("name")).to.be(undefined);
  })

  describe("with delays", function() {

    it("can be added to a map", function() {
      var bo = new BindableObject({
      });

      bo.bind("a, b").delay(1).map(function(a, b) {
        expect(a).to.be(true);
        expect(b).to.be(true);
        return a && b;
      }).to(function(v) {
        expect(v).to.be(true);
      });

      bo.set("a", true);
      bo.set("b", true);

    })
  });

});<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name stock-adjustment-creation.stockAdjustmentCreationService
     *
     * @description
     * Responsible for search and submit stock adjustments.
     */
    angular
        .module('stock-adjustment-creation')
        .service('stockAdjustmentCreationService', service);

    service.$inject = [
        '$filter', '$resource', 'stockmanagementUrlFactory', 'openlmisDateFilter', 'messageService', 'productNameFilter'
    ];

    function service($filter, $resource, stockmanagementUrlFactory, openlmisDateFilter,
                     messageService, productNameFilter) {
        var resource = $resource(stockmanagementUrlFactory('/api/stockEvents'));

        this.search = search;

        this.submitAdjustments = submitAdjustments;

        function search(keyword, items, hasLot) {
            var result = [];

            if (_.isEmpty(keyword)) {
                result = items;
            } else {
                keyword = keyword.trim();
                result = _.filter(items, function(item) {
                    var hasStockOnHand = !(_.isNull(item.stockOnHand) || _.isUndefined(item.stockOnHand));
                    var hasQuantity = !(_.isNull(item.quantity) || _.isUndefined(item.quantity));
                    var searchableFields = [
                        item.orderable.productCode,
                        productNameFilter(item.orderable),
                        hasStockOnHand ? item.stockOnHand.toString() : '',
                        item.reason && item.reason.name ? item.reason.name : '',
                        safeGet(item.reasonFreeText),
                        hasQuantity ? item.quantity.toString() : '',
                        getLot(item, hasLot),
                        item.lot ? openlmisDateFilter(item.lot.expirationDate) : '',
                        item.assignment ? item.assignment.name : '',
                        safeGet(item.srcDstFreeText),
                        openlmisDateFilter(item.occurredDate)
                    ];
                    return _.any(searchableFields, function(field) {
                        if (field === undefined) {
                            return false;
                        }
                        return field.toLowerCase().contains(keyword.toLowerCase());
                    });
                });
            }

            return result;
        }

        function submitAdjustments(programId, facilityId, lineItems, adjustmentType) {
            var event = {
                programId: programId,
                facilityId: facilityId
            };
            event.lineItems = _.map(lineItems, function(item) {
                return angular.merge({
                    orderableId: item.orderable.id,
                    lotId: item.lot ? item.lot.id : null,
                    quantity: item.quantity,
                    extraData: {
                        vvmStatus: item.vvmStatus
                    },
                    occurredDate: item.occurredDate,
                    reasonId: item.reason ? item.reason.id : null,
                    reasonFreeText: item.reasonFreeText
                }, buildSourceDestinationInfo(item, adjustmentType));
            });
            return resource.save(event).$promise;
        }

        function buildSourceDestinationInfo(item, adjustmentType) {
            var res = {};
            if (adjustmentType.state === 'receive') {
                res.sourceId = item.assignment.node.id;
                res.sourceFreeText = item.srcDstFreeText;
            } else if (adjustmentType.state === 'issue') {
                res.destinationId = item.assignment.node.id;
                res.destinationFreeText = item.srcDstFreeText;
            }
            return res;
        }

        function safeGet(value) {
            return value || '';
        }

        function getLot(item, hasLot) {
            return item.lot ?
                item.lot.lotCode :
                (hasLot ? messageService.get('orderableGroupService.noLotDefined') : '');
        }
    }
})();
<commit_msg>OLMIS-6752: Fixed filtering date on the Adjustments screen<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name stock-adjustment-creation.stockAdjustmentCreationService
     *
     * @description
     * Responsible for search and submit stock adjustments.
     */
    angular
        .module('stock-adjustment-creation')
        .service('stockAdjustmentCreationService', service);

    service.$inject = [
        '$filter', '$resource', 'stockmanagementUrlFactory', 'openlmisDateFilter',
        'messageService', 'productNameFilter', 'dateUtils'
    ];

    function service($filter, $resource, stockmanagementUrlFactory, openlmisDateFilter,
                     messageService, productNameFilter, dateUtils) {
        var resource = $resource(stockmanagementUrlFactory('/api/stockEvents'));

        this.search = search;

        this.submitAdjustments = submitAdjustments;

        function search(keyword, items, hasLot) {
            var result = [];

            if (_.isEmpty(keyword)) {
                result = items;
            } else {
                keyword = keyword.trim();
                result = _.filter(items, function(item) {
                    var hasStockOnHand = !(_.isNull(item.stockOnHand) || _.isUndefined(item.stockOnHand));
                    var hasQuantity = !(_.isNull(item.quantity) || _.isUndefined(item.quantity));
                    var searchableFields = [
                        item.orderable.productCode,
                        productNameFilter(item.orderable),
                        hasStockOnHand ? item.stockOnHand.toString() : '',
                        item.reason && item.reason.name ? item.reason.name : '',
                        safeGet(item.reasonFreeText),
                        hasQuantity ? item.quantity.toString() : '',
                        getLot(item, hasLot),
                        item.lot ? openlmisDateFilter(item.lot.expirationDate) : '',
                        item.assignment ? item.assignment.name : '',
                        safeGet(item.srcDstFreeText),
                        openlmisDateFilter(dateUtils.toDate(item.occurredDate))
                    ];
                    return _.any(searchableFields, function(field) {
                        if (field === undefined) {
                            return false;
                        }
                        return field.toLowerCase().contains(keyword.toLowerCase());
                    });
                });
            }

            return result;
        }

        function submitAdjustments(programId, facilityId, lineItems, adjustmentType) {
            var event = {
                programId: programId,
                facilityId: facilityId
            };
            event.lineItems = _.map(lineItems, function(item) {
                return angular.merge({
                    orderableId: item.orderable.id,
                    lotId: item.lot ? item.lot.id : null,
                    quantity: item.quantity,
                    extraData: {
                        vvmStatus: item.vvmStatus
                    },
                    occurredDate: item.occurredDate,
                    reasonId: item.reason ? item.reason.id : null,
                    reasonFreeText: item.reasonFreeText
                }, buildSourceDestinationInfo(item, adjustmentType));
            });
            return resource.save(event).$promise;
        }

        function buildSourceDestinationInfo(item, adjustmentType) {
            var res = {};
            if (adjustmentType.state === 'receive') {
                res.sourceId = item.assignment.node.id;
                res.sourceFreeText = item.srcDstFreeText;
            } else if (adjustmentType.state === 'issue') {
                res.destinationId = item.assignment.node.id;
                res.destinationFreeText = item.srcDstFreeText;
            }
            return res;
        }

        function safeGet(value) {
            return value || '';
        }

        function getLot(item, hasLot) {
            return item.lot ?
                item.lot.lotCode :
                (hasLot ? messageService.get('orderableGroupService.noLotDefined') : '');
        }
    }
})();
<|endoftext|>