<commit_before>var game = function(){
	var i, j,
	//returns a random val of an array
	randArray = function(arr){
		return arr[Math.floor(Math.random()*arr.length)];
	},
	checkGame = function(){
		g.status  = (ref.indexOf(false) !== -1) || g.move("R",true) || g.move("L",true) || g.move("U",true) || g.move("D",true) ? 1 : 0;
	},
	randomFill = function(){
		var rand = Math.floor(Math.random()*ref.length);
		if(!ref[rand]){
			g.board[parseInt(rand/len)][rand%(len)] = randArray([2,2,2,4]);
			ref[rand] = true;
		}else{
			return randomFill();
		}
		if(ref.indexOf(false) === -1)checkGame();
	},
	len,
	ref = [],
	g = {
		status : 1,
		points : 0,
		board :[],
		direction : "",
		init : function(size,fill){
			len = size || 4;
			this.board = new Array(len);
			for (i=0;i<len;i++){
				this.board[i] = new Array(len);
				for (j = 0; j < len; j++){
					this.board[i][j] = -1;
					ref.push(false);
				}
			}
			for(i=0;i<fill;i++)randomFill();
		},
		move : function(side,ck){
			if(!/[LURD]/.test(side))
				throw  SyntaxError("This function only accepts the values R,L,U,D. I got \""+side+"\", and thats a problem.");
			this.direction = side;
			var mv = {};
			mv[side] = true;
			var i,j, mvd = false;
			var h = 0;//horizontal
			var v = 0;//vertical
			for((i = mv.D ? len -1 : 0); (mv.D ? (i >= 0) : (i < len) );mv.D ? i-- : i++){
				for((j = mv.R ? len -1 : 0); ( mv.R ? (j >= 0) : (j < len) ); mv.R ? j-- : j++){
					if(this.board[i][j] === -1){
						h = mv.L ? 1 : mv.R ?  -1 : 0;
						v = mv.U ? 1 : mv.D ?  -1 : 0;
						while(this.board[i+v] && this.board[i+v][j+h]){
							if(this.board[i+v][j+h] !== -1){
								this.board[i][j] = this.board[i+v][j+h];
								ref[i*len+j] = true;
								this.board[i+v][j+h] = -1;
								ref[((i+v)*len)+(j+h)] = false;
								mvd = true;
								break;
							}
							mv.L ? ++h : mv.R ?  --h : "";
							mv.U ? ++v : mv.D ?  --v : "";
						}
					}
					if(this.board[i][j] !== -1){
						h = mv.L ? 1 : mv.R ?  -1 : 0;
						v = mv.U ? 1 : mv.D ?  -1 : 0;
						while(this.board[i+v] && this.board[i+v][j+h]){
							if(this.board[i][j] === this.board[i+v][j+h]){
								if(ck)return true;
								this.board[i][j] *= 2;
								this.points += this.board[i][j];
								ref[i*len+j] = true;
								this.board[i+v][j+h] = -1;
								ref[((i+v)*len)+(j+h)] = false;
								mvd = true;
								break;
							}
							if(this.board[i+v][j+h] !== -1)break;
							mv.L ? ++h : mv.R ?  --h : "";
							mv.U ? ++v : mv.D ?  --v : "";
						}
					}
				}
			}
			if(mvd)randomFill();
			else if(ck)return false;
		}
	};
	return g;
};
<commit_msg>fill may be empty<commit_after>var game = function(){
	var i, j,
	//returns a random val of an array
	randArray = function(arr){
		return arr[Math.floor(Math.random()*arr.length)];
	},
	checkGame = function(){
		g.status  = (ref.indexOf(false) !== -1) || g.move("R",true) || g.move("L",true) || g.move("U",true) || g.move("D",true) ? 1 : 0;
	},
	randomFill = function(){
		var rand = Math.floor(Math.random()*ref.length);
		if(!ref[rand]){
			g.board[parseInt(rand/len)][rand%(len)] = randArray([2,2,2,4]);
			ref[rand] = true;
		}else{
			return randomFill();
		}
		if(ref.indexOf(false) === -1)checkGame();
	},
	len,
	ref = [],
	g = {
		status : 1,
		points : 0,
		board :[],
		direction : "",
		init : function(size,fill){
			len = size || 4;
			if(typeof fill === "undefined") fill = 2;//if 0 leave it
			this.board = new Array(len);
			for (i=0;i<len;i++){
				this.board[i] = new Array(len);
				for (j = 0; j < len; j++){
					this.board[i][j] = -1;
					ref.push(false);
				}
			}
			for(i=0;i<fill;i++)randomFill();
		},
		move : function(side,ck){
			if(!/[LURD]/.test(side))
				throw  SyntaxError("This function only accepts the values R,L,U,D. I got \""+side+"\", and thats a problem.");
			this.direction = side;
			var mv = {};
			mv[side] = true;
			var i,j, mvd = false;
			var h = 0;//horizontal
			var v = 0;//vertical
			for((i = mv.D ? len -1 : 0); (mv.D ? (i >= 0) : (i < len) );mv.D ? i-- : i++){
				for((j = mv.R ? len -1 : 0); ( mv.R ? (j >= 0) : (j < len) ); mv.R ? j-- : j++){
					if(this.board[i][j] === -1){
						h = mv.L ? 1 : mv.R ?  -1 : 0;
						v = mv.U ? 1 : mv.D ?  -1 : 0;
						while(this.board[i+v] && this.board[i+v][j+h]){
							if(this.board[i+v][j+h] !== -1){
								this.board[i][j] = this.board[i+v][j+h];
								ref[i*len+j] = true;
								this.board[i+v][j+h] = -1;
								ref[((i+v)*len)+(j+h)] = false;
								mvd = true;
								break;
							}
							mv.L ? ++h : mv.R ?  --h : "";
							mv.U ? ++v : mv.D ?  --v : "";
						}
					}
					if(this.board[i][j] !== -1){
						h = mv.L ? 1 : mv.R ?  -1 : 0;
						v = mv.U ? 1 : mv.D ?  -1 : 0;
						while(this.board[i+v] && this.board[i+v][j+h]){
							if(this.board[i][j] === this.board[i+v][j+h]){
								if(ck)return true;
								this.board[i][j] *= 2;
								this.points += this.board[i][j];
								ref[i*len+j] = true;
								this.board[i+v][j+h] = -1;
								ref[((i+v)*len)+(j+h)] = false;
								mvd = true;
								break;
							}
							if(this.board[i+v][j+h] !== -1)break;
							mv.L ? ++h : mv.R ?  --h : "";
							mv.U ? ++v : mv.D ?  --v : "";
						}
					}
				}
			}
			if(mvd)randomFill();
			else if(ck)return false;
		}
	};
	return g;
};
<|endoftext|>


<commit_before>(function(){
'use strict';
window.addEventListener('load',init,false);
var canvas=null,ctx=null;
var lastPress=null;
var pause=true;
var gameover=true;
var score=0;
var dir=0;

var KEY_SPACE=32;
var KEY_ENTER=13;
var KEY_LEFT=37;
var KEY_UP=38;
var KEY_RIGHT=39;
var KEY_DOWN=40;

///////////////////////////////////////////////

var pressing=[];

var player=new Rectangle(100,290,10,10,3);

var shots=[];
var enemies=[];

function random(max){
    return ~~(Math.random()*max);
}

function reset(){
      score=0;
        player.x=100;
        player.y=290;
        shots.length=0;
        enemies.length=0;
        enemies.push(new Rectangle(10,0,10,10,2));
        gameover=false;
        player.timer=0;
        player.health=3;
}

function init(){
    canvas=document.getElementById('canvas');
    ctx=canvas.getContext('2d');
    run();
    repaint();
}

function run(){
    setTimeout(run,50);
    act();
}

function repaint(){
    requestAnimationFrame(repaint);
    paint(ctx);
}

function act(){
    if(!pause){
       if(gameover){
        reset();
       }
        //if(pressing[KEY_UP])
          //  y-=10;
        if(pressing[KEY_RIGHT])
            player.x+=10;
        //if(pressing[KEY_DOWN])
          //  y+=10;
        if(pressing[KEY_LEFT])
            player.x-=10;

        // Queremos mantenerlo dentro de la pantalla
        if(player.x>canvas.width-player.width)
            player.x=canvas.width-player.width;
        if(player.x<0)
            player.x=0;

        //Disparos
        if(lastPress==KEY_SPACE){
            shots.push(new Rectangle(player.x+3,player.y,5,5));
            lastPress=null;
        }

        //Mueve los disparos.
        for(var i=0,l=shots.length;i<l;i++){
            shots[i].y-=10;
            if(shots[i].y<0){
                shots.splice(i--,1);
                l--;
            }
        }
        //Movemos los enemigos
        for(var i=0;i<enemies.length;i++){
            if (enemies[i].timer>0) {//Quito el timer de los enemigos dañados
                enemies[i].timer--;
            }
            //Compruebo si los disparos coinciden con los enemigos
            for(var j=0,l=shots.length;j<l;j++){
                if(shots[j].intersects(enemies[i])){
                    score++;
                    enemies[i].health--;
                    if(enemies[i].health<1){
                        enemies[i].x=random(canvas.width/10)*10;
                        enemies[i].y=0;
                        enemies[i].health=2;
                        enemies.push(new Rectangle(random(canvas.width/10)*10,0,10,10));//Genero otra nave enemiga
                    }else{
                        enemies[i].timer=1;//Xa mostrar el efecto de dañado
                    }
                shots.splice(j--,1);//1 xq elimina un elemento del array
                l--;
                }

            }//Fin del for de los shots
            enemies[i].y+=10;//La velocidad a la que bajan las naves
            if(enemies[i].y>canvas.height){//Si llega hasta abajo lo vuelvo a colocar arriba(no lo elimino del array)
                enemies[i].x=random(canvas.width/10)*10;
                enemies[i].y=0;
                enemies[i].health=2;
            }
            if(player.intersects(enemies[i])&&player.timer<1){//Si una nave choca con nosotros
                player.health--;
                player.timer=20;
            }
            /*
            si el disparo y la nave enemiga están uno enfrente del otro, al siguiente turno el disparo subirá a la posición de la nave,
            y la nave bajará su cuadro correspondiente,
            posteriormente se efectuará el análusis de colisión, pero para entonces, ninguno de los dos objetos estará colisionando:
            leo la colisión de ambos objetos dos veces: una justo antes de mover la nave enemiga, y la otra posterior a dicho movimiento
            */
              for(var j=0,l=shots.length;j<l;j++){
                if(shots[j].intersects(enemies[i])){
                    score++;
                    enemies[i].health--;
                    if(enemies[i].health<1){
                        enemies[i].x=random(canvas.width/10)*10;
                        enemies[i].y=0;
                        enemies[i].health=2;
                        enemies.push(new Rectangle(random(canvas.width/10)*10,0,10,10));//Genero otra nave enemiga
                    }else{
                        enemies[i].timer=1;//Xa mostrar el efecto de dañado
                    }
                    shots.splice(j--,1);//1 xq elimina un elemento del array
                    l--;
                }
            }
        }//Fin del for de los enemigos
    if(player.health<1){
        gameover=true;
        pause=true;
    }
     if(player.timer>0){
        player.timer--;
    }
}
    // Pause/Unpause
    if(lastPress==KEY_ENTER){
        pause=!pause;
        lastPress=null;
    }
}

function paint(ctx){
    ctx.fillStyle='#000';
    ctx.fillRect(0,0,canvas.width,canvas.height);
    //Pinto mi personaje
    ctx.fillStyle='#0f0';
    if(player.timer%2==0){
        player.fill(ctx); //Activo y desactivo el coolor
    }
    //Pinto los disparos
    ctx.fillStyle='#f00';
    for(var l=0;l<shots.length;l++){
        shots[l].fill(ctx);
    }
    //Pinto los enemigos
    for(var i=0;i<enemies.length;i++){
        if(enemies[i].timer%2==0)
            ctx.fillStyle='#00f';//lo pinto de azul
        else{
            ctx.fillStyle='#fff';
        }
        enemies[i].fill(ctx);
    }
    //Pinto la puntuación
    ctx.fillStyle='#fff';
    ctx.fillText('Score: '+score,0,20);
    //Pinto la vida
    ctx.fillText('health'+player.health,100,20);
    //ctx.fillText('Last Press: '+lastPress,0,20);
    if(pause){
        ctx.textAlign='center';
        if(gameover)
            ctx.fillText('GAME OVER',100,150);
        else
            ctx.fillText('PAUSE',100,75);
        ctx.textAlign='left';
    }
}

//Mientras tengamos pulsado la tecla de dirección se moverá
document.addEventListener('keydown',function(evt){
    lastPress=evt.keyCode;
    pressing[evt.keyCode]=true;
},false);
//Cuando dejemos de pulsar se parará
document.addEventListener('keyup',function(evt){
    pressing[evt.keyCode]=false;
},false);

function Rectangle(x,y,width,height,health){
        this.x=(x==null)?0:x;
        this.y=(y==null)?0:y;
        this.width=(width==null)?0:width;
        this.height=(height==null)?this.width:height;
        this.health=(health==null)?1:health;
        this.timer=0;
    }
//Con prototype añadimos la funcion intersects a la clase Rectangle
    Rectangle.prototype.intersects=function(rect){
        if(rect!=null){
            return(this.x<rect.x+rect.width&&
                this.x+this.width>rect.x&&
                this.y<rect.y+rect.height&&
                this.y+this.height>rect.y);
        }
    }
    //Con prototype añadimos la funcion fill a la clase Rectangle
    Rectangle.prototype.fill=function(ctx){
        ctx.fillRect(this.x,this.y,this.width,this.height);
    }

window.requestAnimationFrame=(function(){
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(callback){window.setTimeout(callback,17);};
    })();
})();   <commit_msg>+mejoras y sus textos<commit_after>(function(){
'use strict';
window.addEventListener('load',init,false);
var canvas=null,ctx=null;
var lastPress=null;
var pause=true;
var gameover=true;
var score=0;
var dir=0;

var KEY_SPACE=32;
var KEY_ENTER=13;
var KEY_LEFT=37;
var KEY_UP=38;
var KEY_RIGHT=39;
var KEY_DOWN=40;

///////////////////////////////////////////////

var pressing=[];

var player=new Rectangle(100,290,10,10,0,3);

var shots=[];
var enemies=[];
///////////////////////////////////

var powerups=[];

var multishot=1;

var messages=[];

function random(max){
    return ~~(Math.random()*max);
}

function reset(){
      score=0;
        player.x=100;
        player.y=290;
        shots.length=0;
        enemies.length=0;
        enemies.push(new Rectangle(10,0,10,10,0,2));
        gameover=false;
        player.timer=0;
        player.health=3;
        multishot=1;
        messages.length=0;
}

function init(){
    canvas=document.getElementById('canvas');
    ctx=canvas.getContext('2d');
    run();
    repaint();
}

function run(){
    setTimeout(run,50);
    act();
}

function repaint(){
    requestAnimationFrame(repaint);
    paint(ctx);
}

function act(){
    if(!pause){
       if(gameover){
        reset();
       }
        //if(pressing[KEY_UP])
          //  y-=10;
        if(pressing[KEY_RIGHT])
            player.x+=10;
        //if(pressing[KEY_DOWN])
          //  y+=10;
        if(pressing[KEY_LEFT])
            player.x-=10;

        // Queremos mantenerlo dentro de la pantalla
        if(player.x>canvas.width-player.width)
            player.x=canvas.width-player.width;
        if(player.x<0)
            player.x=0;

        //Disparos
        if(lastPress==KEY_SPACE){
            if(multishot==3){
                shots.push(new Rectangle(player.x-3,player.y+2,5,5));
                shots.push(new Rectangle(player.x+3,player.y,5,5));
                shots.push(new Rectangle(player.x+9,player.y+2,5,5));
            }else if(multishot==2){
                shots.push(new Rectangle(player.x,player.y,5,5));
                shots.push(new Rectangle(player.x+5,player.y,5,5));
            }else{
                 shots.push(new Rectangle(player.x+3,player.y,5,5));
            }

            lastPress=null;
        }

        //Mueve los disparos.
        for(var i=0,l=shots.length;i<l;i++){
            shots[i].y-=10;
            if(shots[i].y<0){
                shots.splice(i--,1);
                l--;
            }
        }

        //Muevo los mensajes
        for(var i=0,l=messages.length;i<l;i++){
            messages[i].y-=2;
            if(messages[i].y<260){
                    messages.splice(i--,1);
                    l--;
                }
        }
        //Muevo las mejoras
        for(var i=0,l=powerups.length;i<l;i++){
            powerups[i].y+=10;
            if(powerups[i].y>canvas.height){
                powerups.splice(i--,1);
                l--;
                continue;
            }
            if(player.intersects(powerups[i])){
                if(powerups[i].type==1){//Si es de tipo multidisparo
                    if(multishot<3){//Como maximo que tenga +3 de tiro si consigue mas le damos mas puntos
                        multishot++;
                        messages.push(new Message('MULTI',player.x,player.y));
                    }else{
                        score+=5;
                        messages.push(new Message('+5',player.x,player.y));
                    }
                }else{
                    score+=5;
                        messages.push(new Message('+5',player.x,player.y));
                }
                powerups.splice(i--,1);
                l--;
            }
        }
        //Movemos los enemigos
        for(var i=0;i<enemies.length;i++){
            if (enemies[i].timer>0) {//Quito el timer de los enemigos dañados
                enemies[i].timer--;
            }
            //Compruebo si los disparos coinciden con los enemigos
            for(var j=0,l=shots.length;j<l;j++){
                if(shots[j].intersects(enemies[i])){
                    score++;
                    enemies[i].health--;
                    if(enemies[i].health<1){
                        enemies[i].x=random(canvas.width/10)*10;
                        enemies[i].y=0;
                        enemies[i].health=2;
                        enemies.push(new Rectangle(random(canvas.width/10)*10,0,10,10,0,2));//Genero otra nave enemiga
                    }else{
                        enemies[i].timer=1;//Xa mostrar el efecto de dañado
                    }
                shots.splice(j--,1);//1 xq elimina un elemento del array
                l--;
                }

            }//Fin del for de los shots
            enemies[i].y+=10;//La velocidad a la que bajan las naves
            if(enemies[i].y>canvas.height){//Si llega hasta abajo lo vuelvo a colocar arriba(no lo elimino del array)
                enemies[i].x=random(canvas.width/10)*10;
                enemies[i].y=0;
                enemies[i].health=2;
            }
            if(player.intersects(enemies[i])&&player.timer<1){//Si una nave choca con nosotros
                player.health--;
                player.timer=20;
            }
            /*
            si el disparo y la nave enemiga están uno enfrente del otro, al siguiente turno el disparo subirá a la posición de la nave,
            y la nave bajará su cuadro correspondiente,
            posteriormente se efectuará el análusis de colisión, pero para entonces, ninguno de los dos objetos estará colisionando:
            leo la colisión de ambos objetos dos veces: una justo antes de mover la nave enemiga, y la otra posterior a dicho movimiento
            */
              for(var j=0,l=shots.length;j<l;j++){
                if(shots[j].intersects(enemies[i])){
                    score++;
                    enemies[i].health--;
                    if(enemies[i].health<1){//Al matar un enemigo
                        var r=random(20);//4/20 mejora de puntos y 1/20 multidisparos
                        if(r<5){
                            if(r==0){
                                powerups.push(new Rectangle(enemies[i].x,enemies[i].y,10,10,1));//Tipo 1 xa multidisparo
                            }
                            else{
                                powerups.push(new Rectangle(enemies[i].x,enemies[i].y,10,10,0));
                            }
                        }
                        enemies[i].x=random(canvas.width/10)*10;
                        enemies[i].y=0;
                        enemies[i].health=2;
                        enemies.push(new Rectangle(random(canvas.width/10)*10,0,10,10,0,2));//Genero otra nave enemiga
                    }else{
                        enemies[i].timer=1;//Xa mostrar el efecto de dañado
                    }
                    shots.splice(j--,1);//1 xq elimina un elemento del array
                    l--;
                }
            }
        }//Fin del for de los enemigos
    if(player.health<1){
        gameover=true;
        pause=true;
    }
     if(player.timer>0){
        player.timer--;
    }
}
    // Pause/Unpause
    if(lastPress==KEY_ENTER){
        pause=!pause;
        lastPress=null;
    }
}

function paint(ctx){
    ctx.fillStyle='#000';
    ctx.fillRect(0,0,canvas.width,canvas.height);
    //Pinto mi personaje
    ctx.fillStyle='#0f0';
    if(player.timer%2==0){
        player.fill(ctx); //Activo y desactivo el coolor
    }
    //Pinto los mensajes
    ctx.fillStyle='#fff';
    for(var i=0;i<messages.length;i++){
        ctx.fillText(messages[i].string,messages[i].x,messages[i].y);
    }
    //Pinto los disparos
    ctx.fillStyle='#f00';
    for(var l=0;l<shots.length;l++){
        shots[l].fill(ctx);
    }
    //Pinto los enemigos
    for(var i=0;i<enemies.length;i++){
        if(enemies[i].timer%2==0)
            ctx.fillStyle='#00f';//lo pinto de azul
        else{
            ctx.fillStyle='#fff';
        }
        enemies[i].fill(ctx);
    }
    //Pinto las mejoras
    for(var i=0;i<powerups.length;i++){
        if(powerups[i].type==0){//multidisparo de naranja
            ctx.fillStyle='#cc6';
        }else{
            ctx.fillStyle='#f90';
        }
        powerups[i].fill(ctx);
    }
    //Pinto la puntuación
    ctx.fillStyle='#fff';
    ctx.fillText('Score: '+score,0,20);
    //Pinto la vida
    ctx.fillText('health'+player.health,100,20);
    //ctx.fillText('Last Press: '+lastPress,0,20);
    if(pause){
        ctx.textAlign='center';
        if(gameover)
            ctx.fillText('GAME OVER',100,150);
        else
            ctx.fillText('PAUSE',100,75);
        ctx.textAlign='left';
    }
}

//Mientras tengamos pulsado la tecla de dirección se moverá
document.addEventListener('keydown',function(evt){
    lastPress=evt.keyCode;
    pressing[evt.keyCode]=true;
},false);
//Cuando dejemos de pulsar se parará
document.addEventListener('keyup',function(evt){
    pressing[evt.keyCode]=false;
},false);

function Message(string,x,y){
    this.string=(string==null)?'?':string;
    this.x=(x==null)?0:x;
    this.y=(y==null)?0:y;
}

function Rectangle(x,y,width,height,type,health){
        this.x=(x==null)?0:x;
        this.y=(y==null)?0:y;
        this.width=(width==null)?0:width;
        this.height=(height==null)?this.width:height;
        this.type=(type==null)?1:type;
        this.health=(health==null)?1:health;
        this.timer=0;
    }
//Con prototype añadimos la funcion intersects a la clase Rectangle
    Rectangle.prototype.intersects=function(rect){
        if(rect!=null){
            return(this.x<rect.x+rect.width&&
                this.x+this.width>rect.x&&
                this.y<rect.y+rect.height&&
                this.y+this.height>rect.y);
        }
    }
    //Con prototype añadimos la funcion fill a la clase Rectangle
    Rectangle.prototype.fill=function(ctx){
        ctx.fillRect(this.x,this.y,this.width,this.height);
    }

window.requestAnimationFrame=(function(){
    return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(callback){window.setTimeout(callback,17);};
    })();
})();   <|endoftext|>


<commit_before>$(document).ready(function(){
	var socket = io.connect();
	socket.on('chat', function(data) {					// Add chat data to content
		$('#content').append(
				$('

').append(
						$('').text('[' + getTime(data) + '] '),
						$('').text(typeof(data.name) != 'undefined' ? data.name + ': ' : ''),
						$('').text(data.text))
		);
		window.scrollTo(0,document.body.scrollHeight);	// Scroll to bottom
	});
	function send(){									// Send data to server
		var name = $('#name').val();
		var text = $('#text').val();
		socket.emit('chat', {name: name, text: text});
		$('#text').val('');
	}
	$('#send').click(send);								// Mouse klick on button
	$('#text').keypress(function(evt) {					// Enter key pressed
		if (evt.which == 13) {
			send();
		}
	});
});

function getTime(data) {								// get time format HH:MM:SS
	var date = new Date(data.time);
	return	date.getHours().toString().lpad("0", 2)		+ ":" +
			date.getMinutes().toString().lpad("0", 2)	+ ":" +
			date.getSeconds().toString().lpad("0", 2);
}

String.prototype.lpad = function(padString, length) {	// add leading padding characters
	var string = this;
	while (string.length < length) {
		string = padString + string;
	}
	return string;
};
<commit_msg>Delete chatclient2.js<commit_after><|endoftext|>


<commit_before>var browserSync = require('browser-sync');
var Spider = require('node-spider');
var assert = require('assert');
var config = require('./config.js');
var _ = require('lodash');

function length(obj) {
  var size = 0, key;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) size++;
  }
  return size;
}

/**
 * Export closure, so that checkLinks can be used in gulp without
 * creating an anynomous function.
 *
 * @module.exports
 * @param {string} start URL where crawler should start looking for links.
 * @return {function} checkLinks Calling checkLinks will start crawling.
 */
module.exports = function(start) {
  /**
  * checkLinks crawls all pages and check that href and src attributes does
  * have a HTTP 200 response. It checks links outside the start domain, but
  * does _not_ crawl pages outside start.
  *
  * @param {function} cb Called when all links have been checked.
  */
  return function checkLinks(cb){
    console.log('Checking all links found at ' + start);

    if (start.search('http://localhost') === 0) {
      // we need to start a web server
      browserSync.init({
        server: { baseDir: config.buildRoot },
        open: false
      }, crawl);
    } else {
      crawl();
    }
    function crawl(){
      var resources = {};  // dict of referrers {link: [referrer1, referrer2, ..], link2..}
      resources[start] = ['start'];
      var failed = [];  // list of failed links
      var ok = 0;  // number of OK links
      var broken = 0;  // number of broken links

      var opts = {
        concurrent: 5,
        done: done,
        error: error,
        headers: { 'user-agent': 'codeclub_lesson_builder' },
        timeout: 5000
      };  // spider options

      // text spider for HTML, CSS, etc
      textSpider = new Spider(opts);

      // HEAD requests on external sites and binary files
      headOpts = _.assign({}, opts);
      headOpts.method = 'HEAD';
      headSpider = new Spider(headOpts);

      // let's go! :-)
      textSpider.queue(start, parseResponse);

      /**
       * on OK link
       */
      function parseResponse(doc){
        // check status code
        var code = doc.res.statusCode;
        if (code != 200) {
          process.stdout.write('x'); // give some feedback
          broken += 1;
          failed.push({u:doc.url, c:code});
          return;
        } else {
          ok += 1;
          process.stdout.write('.'); // give some feedback
        }

        // do not parse binary files
        if (!/text|javascript|css|json|xml/i.test(doc.res.headers['content-type'])) {
          return;
        }

        // only crawl links below start (not other domains)
        if (doc.url.search(start) === 0) {

          // all elements with href set
          doc.$('*[href]').each(queueUrl('href'));

          // all elements with src set
          doc.$('*[src]').each(queueUrl('src'));
        }

        /**
         * queueUrl closure
         */
        function queueUrl(type){
          return function(i, elem){
            var href = elem.attr(type);
            // do not add mailto and javascript links
            if (href.search(/^(mailto|javascript)/) === 0) {
              return;
            }
            // do not check #-link explicit
            var url = doc.resolve(href).split('#')[0];
            // already added
            if (url in resources) {
              // add referrer
              resources[url].push(doc.url);
              return;
            }
            // external sites or binaries
            if (url.search(start) !==0 ||
                url.search(/\.(jpg|png|gif|zip)$/) === 0) {
              headSpider.queue(url, parseResponse);
            } else {  // text, e.g., HTML, CSS, etc
              textSpider.queue(url, parseResponse);
            }
            // store referrer
            resources[url] = [doc.url];
          }
        }
      };

      /**
       * on broken link
       */
      function error(url, err) {
          process.stdout.write('!'); // give some feedback
          broken += 1;
          failed.push({u:url, c:err});
      }

      /**
       * print results and exit
       */
      function done() {
        // wait until both spiders are done
        if (textSpider.active.length !== 0 || headSpider.active.length !== 0) {
          return
        }

        console.log('\nLink check done');
        console.log('---------------');
        console.log('Links OK:', ok);
        console.log('Links broken:', broken);
        console.log('---------------');

        failed.forEach(function(fail){
          console.log('Code', fail.c, 'for', fail.u, 'in');
          resources[fail.u].forEach(function(ref){
            console.log(' -', ref);
          });
        });

        assert.equal(ok+broken, length(resources));

        if (broken !== 0) {
          // avoid error trace
          process.exit(1);
        } else {
          cb();
        }
        browserSync.exit();
      }
    } // crawl end
  };
};
<commit_msg>checklinks queueUrl: use doc.$(this) to force cheerio obj<commit_after>var browserSync = require('browser-sync');
var Spider = require('node-spider');
var assert = require('assert');
var config = require('./config.js');
var _ = require('lodash');

function length(obj) {
  var size = 0, key;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) size++;
  }
  return size;
}

/**
 * Export closure, so that checkLinks can be used in gulp without
 * creating an anynomous function.
 *
 * @module.exports
 * @param {string} start URL where crawler should start looking for links.
 * @return {function} checkLinks Calling checkLinks will start crawling.
 */
module.exports = function(start) {
  /**
  * checkLinks crawls all pages and check that href and src attributes does
  * have a HTTP 200 response. It checks links outside the start domain, but
  * does _not_ crawl pages outside start.
  *
  * @param {function} cb Called when all links have been checked.
  */
  return function checkLinks(cb){
    console.log('Checking all links found at ' + start);

    if (start.search('http://localhost') === 0) {
      // we need to start a web server
      browserSync.init({
        server: { baseDir: config.buildRoot },
        open: false
      }, crawl);
    } else {
      crawl();
    }
    function crawl(){
      var resources = {};  // dict of referrers {link: [referrer1, referrer2, ..], link2..}
      resources[start] = ['start'];
      var failed = [];  // list of failed links
      var ok = 0;  // number of OK links
      var broken = 0;  // number of broken links

      var opts = {
        concurrent: 5,
        done: done,
        error: error,
        headers: { 'user-agent': 'codeclub_lesson_builder' },
        timeout: 5000
      };  // spider options

      // text spider for HTML, CSS, etc
      textSpider = new Spider(opts);

      // HEAD requests on external sites and binary files
      headOpts = _.assign({}, opts);
      headOpts.method = 'HEAD';
      headSpider = new Spider(headOpts);

      // let's go! :-)
      textSpider.queue(start, parseResponse);

      /**
       * on OK link
       */
      function parseResponse(doc){
        // check status code
        var code = doc.res.statusCode;
        if (code != 200) {
          process.stdout.write('x'); // give some feedback
          broken += 1;
          failed.push({u:doc.url, c:code});
          return;
        } else {
          ok += 1;
          process.stdout.write('.'); // give some feedback
        }

        // do not parse binary files
        if (!/text|javascript|css|json|xml/i.test(doc.res.headers['content-type'])) {
          return;
        }

        // only crawl links below start (not other domains)
        if (doc.url.search(start) === 0) {

          // all elements with href set
          doc.$('*[href]').each(queueUrl('href'));

          // all elements with src set
          doc.$('*[src]').each(queueUrl('src'));
        }

        /**
         * queueUrl closure
         */
        function queueUrl(type){
          return function(){
            var href = doc.$(this).attr(type);
            // do not add mailto and javascript links
            if (href.search(/^(mailto|javascript)/) === 0) {
              return;
            }
            // do not check #-link explicit
            var url = doc.resolve(href).split('#')[0];
            // already added
            if (url in resources) {
              // add referrer
              resources[url].push(doc.url);
              return;
            }
            // external sites or binaries
            if (url.search(start) !==0 ||
                url.search(/\.(jpg|png|gif|zip)$/) === 0) {
              headSpider.queue(url, parseResponse);
            } else {  // text, e.g., HTML, CSS, etc
              textSpider.queue(url, parseResponse);
            }
            // store referrer
            resources[url] = [doc.url];
          }
        }
      };

      /**
       * on broken link
       */
      function error(url, err) {
          process.stdout.write('!'); // give some feedback
          broken += 1;
          failed.push({u:url, c:err});
      }

      /**
       * print results and exit
       */
      function done() {
        // wait until both spiders are done
        if (textSpider.active.length !== 0 || headSpider.active.length !== 0) {
          return
        }

        console.log('\nLink check done');
        console.log('---------------');
        console.log('Links OK:', ok);
        console.log('Links broken:', broken);
        console.log('---------------');

        failed.forEach(function(fail){
          console.log('Code', fail.c, 'for', fail.u, 'in');
          resources[fail.u].forEach(function(ref){
            console.log(' -', ref);
          });
        });

        assert.equal(ok+broken, length(resources));

        if (broken !== 0) {
          // avoid error trace
          process.exit(1);
        } else {
          cb();
        }
        browserSync.exit();
      }
    } // crawl end
  };
};
<|endoftext|>


<commit_before>// cross-browser preventdefault function
function MyPreventDefault(ev){
  if (ev.preventDefault) { ev.preventDefault(); } else { ev.returnValue = false; }
}

// get delta date in sec,min,day,month,year
function getDeltaDate(from, to){
    var dFrom = new Date(from);
    var dTo = new Date(to);

    var year = 0;
    var month = 0;
    var hours = 0;
    var days = 0;
    var minutes = 0;
    var seconds = 0;

    seconds = dTo.getSeconds() - dFrom.getSeconds();
    if( seconds < 0 ){
        seconds += 60;
        minutes--;
    }
    minutes += dTo.getMinutes() - dFrom.getMinutes();
    if( minutes < 0 ){
        minutes += 60;
        hours--;
    }
    hours += dTo.getHours() - dFrom.getHours();
    if( hours < 0 ){
        hours += 24;
        days--;
    }
    days += dTo.getDate() - dFrom.getDate();
    if( days < 0 ){
        days += 30; //посчитать количество дней в месяце From
        month--;
    }
    month += dTo.getMonth() - dFrom.getMonth();
    if( month < 0 ){
        month += 24;
        year--;
    }
    year += dTo.getFullYear() - dFrom.getFullYear();

    var res =
        (
            (year > 0)?
                year+( (year>4)?'л ':'г ' )
                :''
        ) + (
            (month > 0)?
                month+'м '
                :''
        ) + (
            (days > 0)?
                days+'д '
                :''
        ) + hours + ':' + minutes;

    return res;
}
<commit_msg>функция предзагрузки картинок<commit_after>// cross-browser preventdefault function
function MyPreventDefault(ev){
  if (ev.preventDefault) { ev.preventDefault(); } else { ev.returnValue = false; }
}

// get delta date in sec,min,day,month,year
function getDeltaDate(from, to){
    var dFrom = new Date(from);
    var dTo = new Date(to);

    var year = 0;
    var month = 0;
    var hours = 0;
    var days = 0;
    var minutes = 0;
    var seconds = 0;

    seconds = dTo.getSeconds() - dFrom.getSeconds();
    if( seconds < 0 ){
        seconds += 60;
        minutes--;
    }
    minutes += dTo.getMinutes() - dFrom.getMinutes();
    if( minutes < 0 ){
        minutes += 60;
        hours--;
    }
    hours += dTo.getHours() - dFrom.getHours();
    if( hours < 0 ){
        hours += 24;
        days--;
    }
    days += dTo.getDate() - dFrom.getDate();
    if( days < 0 ){
        days += 30; //посчитать количество дней в месяце From
        month--;
    }
    month += dTo.getMonth() - dFrom.getMonth();
    if( month < 0 ){
        month += 24;
        year--;
    }
    year += dTo.getFullYear() - dFrom.getFullYear();

    var res =
        (
            (year > 0)?
                year+( (year>4)?'л ':'г ' )
                :''
        ) + (
            (month > 0)?
                month+'м '
                :''
        ) + (
            (days > 0)?
                days+'д '
                :''
        ) + hours + ':' + minutes;

    return res;
}

/*
$.preloadImages(["first_image.jpg","second_image.jpg"], function () {
    alert('Обе картинки загружены.');
});
*/
$.preloadImages = function () {
    if (typeof arguments[arguments.length - 1] == 'function') {
        var callback = arguments[arguments.length - 1];
    } else {
        var callback = false;
    }
    if (typeof arguments[0] == 'object') {
        var images = arguments[0];
        var n = images.length;
    } else {
        var images = arguments;
        var n = images.length - 1;
    }
    var not_loaded = n;
    for (var i = 0; i < n; i++) {
        jQuery(new Image()).attr('src', images[i]).load(function() {
            if (--not_loaded < 1 && typeof callback == 'function') {
                callback();
            }
        });
    }
}
<|endoftext|>


<commit_before>'use strict';

const crypto = require('crypto');

class S3 {
  constructor(serverless,options,provider){
    this.serverless = serverless;
    this.provider   = provider;
    this.options    = options;
  }

  getId(event) {
    const eventTypes = event.existingS3.event || ['s3:ObjectCreated:*'];
    const rules      = event.existingS3.rules ? event.existingS3.rules.sort( (a,b) => Object.keys(a) - Object.keys(b) ) : [];
    const md5Data    = `${event.arn}_${eventTypes.join('OR').replace(/[\.\:\*]/g,'')}_${rules.map(rule => JSON.stringify(rule)).join('-')}`;
    const md5        = crypto.createHash('md5').update(md5Data).digest("hex");
    return `exS3-v2--${md5}`;
  }

  getLambdaNotifications(bucket){
    return this.provider.request('S3', 'getBucketNotificationConfiguration', { Bucket: bucket })
      .then( results => {
        return {bucket,results:results.LambdaFunctionConfigurations};
      })
  }

  putLambdaNotification(bucketConfig){
    const payload = {
      Bucket: bucketConfig.name,
      NotificationConfiguration: {
        LambdaFunctionConfigurations: bucketConfig.events.map( event => {
          /*
           * Filters are optional in the configuration.
           */
          let filter = undefined;

          if(event.existingS3.rules && event.existingS3.rules.length !== 0) {
            filter = {
              Key: {
                FilterRules: event.existingS3.rules.map( rule => {
                  const key = Object.keys(rule)[0];
                  return {
                    Name: key,
                    Value: rule[key]
                  }
                })
              }
            }
          }

          /*
           * Default to object creation, or accept the one or more event types provided.
           */
          const bucketEventTypes = event.existingS3.event || ['s3:ObjectCreated:*'];

          /*
           * http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketNotificationConfiguration-property
           */
          return {
            Events: bucketEventTypes,
            LambdaFunctionArn: event.arn,
            Filter: filter,
            Id: this.getId(event)
          }
        })
      }
    }

    console.log("putLambdaNotification payload",JSON.stringify(payload,' ',4));

    return this.provider.request('S3', 'putBucketNotificationConfiguration', payload)
      .catch( error => {
         if(this.options['continue-on-error']) {
          this.serverless.cli.log(`\t ERROR: ${payload.Bucket} ${error.message}`);
        } else {
          return Promise.reject(`${payload.Bucket} ${error.message}`);
        }
      });
  }
}

module.exports = S3;<commit_msg>Remove console.log<commit_after>'use strict';

const crypto = require('crypto');

class S3 {
  constructor(serverless,options,provider){
    this.serverless = serverless;
    this.provider   = provider;
    this.options    = options;
  }

  getId(event) {
    const eventTypes = event.existingS3.event || ['s3:ObjectCreated:*'];
    const rules      = event.existingS3.rules ? event.existingS3.rules.sort( (a,b) => Object.keys(a) - Object.keys(b) ) : [];
    const md5Data    = `${event.arn}_${eventTypes.join('OR').replace(/[\.\:\*]/g,'')}_${rules.map(rule => JSON.stringify(rule)).join('-')}`;
    const md5        = crypto.createHash('md5').update(md5Data).digest("hex");
    return `exS3-v2--${md5}`;
  }

  getLambdaNotifications(bucket){
    return this.provider.request('S3', 'getBucketNotificationConfiguration', { Bucket: bucket })
      .then( results => {
        return {bucket,results:results.LambdaFunctionConfigurations};
      })
  }

  putLambdaNotification(bucketConfig){
    const payload = {
      Bucket: bucketConfig.name,
      NotificationConfiguration: {
        LambdaFunctionConfigurations: bucketConfig.events.map( event => {
          /*
           * Filters are optional in the configuration.
           */
          let filter = undefined;

          if(event.existingS3.rules && event.existingS3.rules.length !== 0) {
            filter = {
              Key: {
                FilterRules: event.existingS3.rules.map( rule => {
                  const key = Object.keys(rule)[0];
                  return {
                    Name: key,
                    Value: rule[key]
                  }
                })
              }
            }
          }

          /*
           * Default to object creation, or accept the one or more event types provided.
           */
          const bucketEventTypes = event.existingS3.event || ['s3:ObjectCreated:*'];

          /*
           * http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketNotificationConfiguration-property
           */
          return {
            Events: bucketEventTypes,
            LambdaFunctionArn: event.arn,
            Filter: filter,
            Id: this.getId(event)
          }
        })
      }
    }

    return this.provider.request('S3', 'putBucketNotificationConfiguration', payload)
      .catch( error => {
         if(this.options['continue-on-error']) {
          this.serverless.cli.log(`\t ERROR: ${payload.Bucket} ${error.message}`);
        } else {
          return Promise.reject(`${payload.Bucket} ${error.message}`);
        }
      });
  }
}

module.exports = S3;
<|endoftext|>


<commit_before>'use strict'

const test = require('ava')
const sinon = require('sinon')
const initFakeServer = require('./_initFakeServer')

const endpointsSpec = require('../endpointsSpec')

test.beforeEach(initFakeServer)

test('should throw error if http response code is not in 200 group', t => {
  let getStatusEndpoint = endpointsSpec.endpoints.getStatus
  t.context.catchExpectedRequest(getStatusEndpoint, 500)
  return t.throws(t.context.glvrd.checkStatus(), Error)
})

test('should give an error request if there was too many requests sent', t => {
  /*
   * Main idea here is to empower client app with knowlendge about errors,
   * so they can provide full feedback to user instead of silently freezing
   */
  let errorFromServer = endpointsSpec.errorsForCover.too_many_requests
  let requestStub = sinon.stub(t.context.glvrd, 'req')
  requestStub.returns(errorFromServer)

  // TODO Change approach and use t.throws() instead
  t.context.glvrd.proofread('test').catch(err =>
    t.is(err, errorFromServer))
})

test.todo('should retry request if glvrd is busy')

test.todo('should throw error if error received in generic requests')

test.todo('should throw error if there is no correct json object')

test.todo('should throw error if there is empty response')

test.todo('should throw error if there is no answer more that timeout')
<commit_msg>test(index): Tested passing `busy` error to client<commit_after>'use strict'

const test = require('ava')
const sinon = require('sinon')
const initFakeServer = require('./_initFakeServer')

const endpointsSpec = require('../endpointsSpec')

test.beforeEach(initFakeServer)

test('should throw error if http response code is not in 200 group', t => {
  let getStatusEndpoint = endpointsSpec.endpoints.getStatus
  t.context.catchExpectedRequest(getStatusEndpoint, 500)
  return t.throws(t.context.glvrd.checkStatus(), Error)
})

test('should throw error if there was too many requests sent', t => {
  /*
   * Main idea here is to empower client app with knowlendge about errors,
   * so they can provide full feedback to user instead of silently freezing
   */
  let errorFromServer = endpointsSpec.errorsForCover.too_many_requests
  let requestStub = sinon.stub(t.context.glvrd, 'req')
  requestStub.returns(errorFromServer)

  // TODO Change approach and use t.throws() instead
  t.context.glvrd.proofread('test').catch(err =>
    t.is(err, errorFromServer))
})

test('should throw error if glvrd is busy', t => {
  let errorFromServer = endpointsSpec.errorsForCover.busy
  let requestStub = sinon.stub(t.context.glvrd, 'req')
  requestStub.returns(errorFromServer)

  // TODO Change approach and use t.throws() instead
  t.context.glvrd.proofread('test').catch(err =>
    t.is(err, errorFromServer))
})

test.todo('should throw error if error received in generic requests')

test.todo('should throw error if there is no correct json object')

test.todo('should throw error if there is empty response')

test.todo('should throw error if there is no answer more that timeout')
<|endoftext|>


<commit_before>var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var through = require('through2');
var trim = require('./lib/trim');

var pluginName = 'include-js';
var magenta = gutil.colors.magenta;

function error(context, err) {
  context.emit('error', new gutil.PluginError(pluginName, err));
}

// ignore _* files
// for each file, scan for INCLUDE('filepath')
// read file contents, continue scanning, check for circular
// cache _* files

function include(options) {

  options = options || {};
  if (options.cache === undefined) options.cache = false;
  if (options.keyword === undefined) options.keyword = 'INCLUDE';
  if (options.ext === undefined) options.ext = 'js';

  return through.obj(function(file, enc, cb) {
    var context = this;

    if (file.isNull()) {
      this.push(file);
      return cb();
    }

    if (file.isStream()) {
      error(context, new Error('Streaming not supported'));
      return cb();
    }

    // ignore _* files
    var filename = path.basename(file.path);
    if (filename[0] === '_') {
      return cb();
    }

    function exec(s, stack) {
      var result = '';
      var r = new RegExp('(//[^\r\n]*)?' + options.keyword + ' *\\( *[\'"]([^\'"]*)[\'"] *\\)');
      var m = r.exec(s);
      while (m) {
        isCmt = m[1];
        relpath = m[2];
        result += s.slice(0, m.index) + (isCmt? '' : read(relpath, stack || []));
        s = s.slice(m.index + m[0].length);
        m = r.exec(s);
      }
      return result + s;
    }

    function read(relpath, stack, inline) {
      var basename = path.basename(relpath);
      basename = basename[0] === '_'? basename : '_' + basename;
      basename = path.extname(basename) === options.ext? basename : basename + '.' + options.ext;

      var filepath = path.join(file.base || file.cwd, path.dirname(relpath), basename);
      var newStack = stack.concat([relpath]);

      if (stack.indexOf(relpath) >= 0) {
        error(context, new Error('Circular ' + magenta(newStack.join(', '))));
        return '';
      }

      var str = fs.readFileSync(filepath, {encoding: 'utf8'});
      str = exec(str, newStack);
      return trim(str);
    }

    var str = file.contents.toString();
    try {
      file.contents = new Buffer(exec(str));

    } catch (e) {
      e.filename = file.path;
      error(context, e);
    }

    this.push(file);
    cb();
  });
}

module.exports = include;
<commit_msg>Inline INCLUDE<commit_after>var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var through = require('through2');
var trim = require('./lib/trim');

var pluginName = 'include-js';
var magenta = gutil.colors.magenta;

function error(context, err) {
  context.emit('error', new gutil.PluginError(pluginName, err));
}

// ignore _* files
// for each file, scan for INCLUDE('filepath')
// read file contents, continue scanning, check for circular
// cache _* files

function include(options) {

  options = options || {};
  if (options.cache === undefined) options.cache = false;
  if (options.keyword === undefined) options.keyword = 'INCLUDE';
  if (options.ext === undefined) options.ext = 'js';

  return through.obj(function(file, enc, cb) {
    var context = this;

    if (file.isNull()) {
      this.push(file);
      return cb();
    }

    if (file.isStream()) {
      error(context, new Error('Streaming not supported'));
      return cb();
    }

    // ignore _* files
    var filename = path.basename(file.path);
    if (filename[0] === '_') {
      return cb();
    }

    function exec(s, stack) {
      var result = '';
      var r = new RegExp('(//[^\r\n]*)?([^\\s]+\\s*)?' + options.keyword + '\\s*\\( *[\'"]([^\'"]*)[\'"]\\s*\\)');
      var m = r.exec(s);
      while (m) {
        isCmt = m[1];
        inline = m[2] || '';
        relpath = m[3];
        result += s.slice(0, m.index) + (isCmt? '' : inline + read(relpath, stack || [], inline));
        s = s.slice(m.index + m[0].length);
        m = r.exec(s);
      }
      return result + s;
    }

    function read(relpath, stack, inline) {
      var basename = path.basename(relpath);
      basename = basename[0] === '_'? basename : '_' + basename;
      basename = path.extname(basename) === options.ext? basename : basename + '.' + options.ext;

      var filepath = path.join(file.base || file.cwd, path.dirname(relpath), basename);
      var newStack = stack.concat([relpath]);

      if (stack.indexOf(relpath) >= 0) {
        error(context, new Error('Circular ' + magenta(newStack.join(', '))));
        return '';
      }

      var str = fs.readFileSync(filepath, {encoding: 'utf8'});
      str = exec(str, newStack);
      return inline? trim(str) : str;
    }

    var str = file.contents.toString();
    try {
      file.contents = new Buffer(exec(str));

    } catch (e) {
      e.filename = file.path;
      error(context, e);
    }

    this.push(file);
    cb();
  });
}

module.exports = include;
<|endoftext|>


<commit_before>/*globals define, describe, beforeEach*/
define(['app'], function (app) {
    'use strict';

    describe('The main app module', function () {
        var content;
        //Arrange
        beforeEach(function () {
            content = document.createElement('div');
            //prepare DOM
            content.id = 'content';
            content.style.display = 'none';
            document.body.appendChild(content);
            spyOn(app, 'init').and.callThrough();
            spyOn(app, 'altInit').and.callThrough();
            //Act
            app.init();
            app.altInit();
        });

        //Assert
        it('is not null', function () {
            expect(app).not.toBeNull();
        });

        it('initializes the Shell only once', function () {
            expect(app.init).toHaveBeenCalled();
            expect(app.init.calls.count(1));
        });

        it('initializes Master-Detail only once', function () {
            expect(app.altInit).toHaveBeenCalled();
            expect(app.altInit.calls.count(1));
        });

        afterEach(function () {
            document.body.removeChild(content);
        });
    });

    describe('The main App component', function () {
        var appCom;
        //Arrange
        beforeEach(function () {
            jQuery.sap.require('advarics.util.Formatter');
            jQuery.sap.require('advarics.settings.Globals');
            jQuery.sap.require('advarics.util.Logger');
            jQuery.sap.require('advarics.components.apps.App');
            //Act
            appCom = new advarics.components.apps.App();
            spyOn(appCom, 'init').and.callThrough();
            spyOn(appCom, 'createContent').and.callThrough();
            appCom.init();
            appCom.createContent();
        });
        //Assert
        it('is not null', function () {
            expect(appCom).not.toBeNull();
        });

        it('initializes the AppRouter only once', function () {
            expect(appCom.init).toHaveBeenCalled();
            expect(appCom.init.calls.count(1));
            expect(appCom._router).not.toBeNull();
        });

        it('initializes the i18n Model', function () {
            expect(sap.ui.getCore().getModel('i18n')).not.toBeNull();
        });

        it('initalizes the "Northwind"-OData-Model', function () {
            expect(sap.ui.getCore().getModel('northwind')).not.toBeNull();
        });

        it('initializes the Device Model', function () {
            expect(sap.ui.getCore().getModel('device')).not.toBeNull();
        });

        it('creates the initial page only once', function () {
            expect(appCom.createContent).toHaveBeenCalled();
            expect(appCom.createContent.calls.count(1));
        });

        afterEach(function () {
            appCom.destroy();
            sap.ui.getCore().getModel('i18n').destroy();
            sap.ui.getCore().getModel('northwind').destroy();
            sap.ui.getCore().getModel('device').destroy();
        });

    });
});<commit_msg>update tests<commit_after>/*globals define, describe, beforeEach*/
define(['app'], function (app) {
    'use strict';

    describe('The main app module', function () {
        var content;
        //Arrange
        beforeEach(function () {
            content = document.createElement('div');
            //prepare DOM
            content.id = 'content';
            content.style.display = 'none';
            document.body.appendChild(content);
            spyOn(app, 'init').and.callThrough();
            spyOn(app, 'altInit').and.callThrough();
            //Act
            app.init();
            app.altInit();
        });

        //Assert
        it('is not null', function () {
            expect(app).not.toBeNull();
        });

        it('should initialize the Shell only once', function () {
            expect(app.init).toHaveBeenCalled();
            expect(app.init.calls.count(1));
        });

        it('should initialize Master-Detail only once', function () {
            expect(app.altInit).toHaveBeenCalled();
            expect(app.altInit.calls.count(1));
        });

        afterEach(function () {
            document.body.removeChild(content);
        });
    });

    describe('The main App component', function () {
        var appCom;
        //Arrange
        beforeEach(function () {
            jQuery.sap.require('advarics.util.Formatter');
            jQuery.sap.require('advarics.settings.Globals');
            jQuery.sap.require('advarics.util.Logger');
            jQuery.sap.require('advarics.components.apps.App');
            //Act
            appCom = new advarics.components.apps.App();
            spyOn(appCom, 'init').and.callThrough();
            spyOn(appCom, 'createContent').and.callThrough();
            appCom.init();
            appCom.createContent();
        });
        //Assert
        it('is not null', function () {
            expect(appCom).not.toBeNull();
        });

        it('should initialize the AppRouter only once', function () {
            expect(appCom.init).toHaveBeenCalled();
            expect(appCom.init.calls.count(1));
            expect(appCom._router).not.toBeNull();
        });

        it('should initialize the i18n Model', function () {
            expect(sap.ui.getCore().getModel('i18n')).not.toBeNull();
        });

        it('should initialize the "Northwind"-OData-Model', function () {
            expect(sap.ui.getCore().getModel('northwind')).not.toBeNull();
        });

        it('should initialize the Device Model', function () {
            expect(sap.ui.getCore().getModel('device')).not.toBeNull();
        });

        it('should create the initial page only once', function () {
            expect(appCom.createContent).toHaveBeenCalled();
            expect(appCom.createContent.calls.count(1));
        });

        afterEach(function () {
            appCom.destroy();
            sap.ui.getCore().getModel('i18n').destroy();
            sap.ui.getCore().getModel('northwind').destroy();
            sap.ui.getCore().getModel('device').destroy();
        });

    });
});<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var assert = require('yeoman-generator').assert;
var helpers = require('yeoman-generator').test;
var os = require('os');

describe('techtonic:app', function () {
  before(function (done) {
    helpers.run(path.join(__dirname, '../generators/app'))
      .withOptions({ skipInstall: true })
      .withPrompts({ someOption: true })
      .on('end', done);
  });

  it('creates files', function () {
    assert.file([
      'package.json',
      'Gruntfile.js',
      'README.md',
      'LICENSE'
    ]);
  });
});
<commit_msg>Minor code style changes<commit_after>'use strict';

var path = require('path');
var assert = require('yeoman-generator').assert;
var helpers = require('yeoman-generator').test;
var os = require('os');

describe('techtonic:app', function() {
  before(function(done) {
    helpers.run(path.join(__dirname, '../generators/app'))
      .withOptions({skipInstall: true})
      .withPrompts({someOption: true})
      .on('end', done);
  });

  it('creates files', function() {
    assert.file([
      'package.json',
      'Gruntfile.js',
      'README.md',
      'LICENSE'
    ]);
  });
});
<|endoftext|>


<commit_before>var should = require('should')
var del = require('del')

var TEMP = 'test/temp'
var EXAMPLE = 'example/frontbase'
var EXAMPLE_DIST = EXAMPLE + '/dist'
var NODE_DIR = EXAMPLE + '/node_modules'

var cleanup = function() {
	del.sync([TEMP, EXAMPLE_DIST, NODE_DIR])
}

describe('Mango class', function() {
	var Mango = require('../lib/mango')
	var Config = require('../lib/helpers/config')

	describe('should create a new instance', function() {

		it('with no arguments', function() {
			new Mango()
		})

		it('with only the folder argument', function() {
			new Mango(process.cwd())
		})

		it('with a folder argument and an empty object as the config parameter', function() {
			new Mango(process.cwd(), {})
		})

	})

	describe('should in a temp directory', function() {

		before(cleanup)

		it('init a template', function(done) {
			this.timeout(15000)
			var pkg = require('../package')
			var config = new Config('example/frontbase')
			var mango2 = new Mango(TEMP, config.get())
			mango2.init(pkg.config.default_fork_repo, done)
		})

		after(cleanup)
	})

	describe('should in the example directory', function() {
		var mango

		before(cleanup)

		it('read the configuration file', function() {
			var config = new Config('example/frontbase')
			mango = new Mango(EXAMPLE, config.get())
		})

		it('install dependencies', function(done) {
			this.timeout(60000)
			mango.install(done)
		})

		it('run the production build task', function(done) {
			this.timeout(15000)
			mango.build([], done)
		})

		// it('run development mode task', function() {
		// 	mango.dev()
		// })

		after(cleanup)
	})

})<commit_msg>test-lib: rise production timeout up to 2 minutes<commit_after>var should = require('should')
var del = require('del')

var TEMP = 'test/temp'
var EXAMPLE = 'example/frontbase'
var EXAMPLE_DIST = EXAMPLE + '/dist'
var NODE_DIR = EXAMPLE + '/node_modules'

var cleanup = function() {
	del.sync([TEMP, EXAMPLE_DIST, NODE_DIR])
}

describe('Mango class', function() {
	var Mango = require('../lib/mango')
	var Config = require('../lib/helpers/config')

	describe('should create a new instance', function() {

		it('with no arguments', function() {
			new Mango()
		})

		it('with only the folder argument', function() {
			new Mango(process.cwd())
		})

		it('with a folder argument and an empty object as the config parameter', function() {
			new Mango(process.cwd(), {})
		})

	})

	describe('should in a temp directory', function() {

		before(cleanup)

		it('init a template', function(done) {
			this.timeout(15000)
			var pkg = require('../package')
			var config = new Config('example/frontbase')
			var mango2 = new Mango(TEMP, config.get())
			mango2.init(pkg.config.default_fork_repo, done)
		})

		after(cleanup)
	})

	describe('should in the example directory', function() {
		var mango

		before(cleanup)

		it('read the configuration file', function() {
			var config = new Config('example/frontbase')
			mango = new Mango(EXAMPLE, config.get())
		})

		it('install dependencies', function(done) {
			this.timeout(60000)
			mango.install(done)
		})

		it('run the production build task', function(done) {
			this.timeout(120000)
			mango.build([], done)
		})

		// it('run development mode task', function() {
		// 	mango.dev()
		// })

		after(cleanup)
	})

})<|endoftext|>


<commit_before>'use strict';

const test = require('ava');
const bashParser = require('../src');
const mkloc = require('./_utils').mkloc2;
const utils = require('./_utils');

/* eslint-disable camelcase */
test('syntax error contains line number', async t => {
	const error = t.throws(() => bashParser('ecoh\necho <'));
	t.is(error.message, 'Parse error on line 2: Unexpected \'EOF\'');
});

test('AST can include loc', t => {
	const result = bashParser('echo', {insertLOC: true});
	// utils.logResults(result)
	utils.checkResults(t, result.commands[0].name, {
		type: 'Word',
		text: 'echo',
		loc: mkloc(1, 1, 1, 4, 0, 3)
	});
});

test('subshell can include loc', t => {
	const result = bashParser('(echo)', {insertLOC: true});
	// utils.logResults(result);
	utils.checkResults(t, result, {
		type: 'Script',
		commands: [
			{
				type: 'Subshell',
				list: {
					type: 'CompoundList',
					commands: [
						{
							type: 'Command',
							name: {
								text: 'echo',
								type: 'Word',
								loc: mkloc(1, 2, 1, 5, 1, 4)
							},
							loc: mkloc(1, 2, 1, 5, 1, 4)
						}
					],
					loc: mkloc(1, 2, 1, 5, 1, 4)
				},
				loc: mkloc(1, 1, 1, 6, 0, 5)
			}
		],
		loc: mkloc(1, 1, 1, 6, 0, 5)
	});
});

test('double command with only name', t => {
	const result = bashParser('echo; ciao;', {insertLOC: true});
	// utils.logResults(result);
	utils.checkResults(t, result, {
		type: 'Script',
		loc: mkloc(1, 1, 1, 10, 0, 9),
		commands: [
			{
				type: 'Command',
				name: {
					type: 'Word',
					text: 'echo',
					loc: mkloc(1, 1, 1, 4, 0, 3)
				},
				loc: mkloc(1, 1, 1, 4, 0, 3)
			},
			{
				type: 'Command',
				name: {
					type: 'Word',
					text: 'ciao',
					loc: mkloc(1, 7, 1, 10, 6, 9)
				},
				loc: mkloc(1, 7, 1, 10, 6, 9)
			}
		]
	});
});

test('loc are composed by all tokens', t => {
	const result = bashParser('echo 42', {insertLOC: true});
	// console.log(JSON.stringify(result, null, 4));
	utils.checkResults(t, result.commands[0], {
		type: 'Command',
		name: {
			type: 'Word',
			text: 'echo',
			loc: mkloc(1, 1, 1, 4, 0, 3)
		},
		loc: mkloc(1, 1, 1, 7, 0, 6),
		suffix: [{
			type: 'Word',
			text: '42',
			loc: mkloc(1, 6, 1, 7, 5, 6)
		}]
	});
});

test('loc works with multiple newlines', t => {
	const result = bashParser('\n\n\necho 42', {insertLOC: true});
	utils.checkResults(t, result.commands[0], {
		type: 'Command',
		name: {
			type: 'Word',
			text: 'echo',
			loc: mkloc(4, 1, 4, 4, 3, 6)
		},
		loc: mkloc(4, 1, 4, 7, 3, 9),
		suffix: [{
			type: 'Word',
			text: '42',
			loc: mkloc(4, 6, 4, 7, 8, 9)
		}]
	});
});

test('loc with LINEBREAK_IN statement', t => {
	const cmd =
`for x
	in ; do
	echo $x;
done
`;

	const result = bashParser(cmd, {insertLOC: true});
	// utils.logResults(result)
	const expected = {
		type: 'For',
		name: {
			text: 'x',
			type: 'Name',
			loc: {
				start: {
					col: 5,
					row: 1,
					char: 4
				},
				end: {
					col: 5,
					row: 1,
					char: 4
				}
			}
		},
		do: {
			type: 'CompoundList',
			commands: [
				{
					type: 'Command',
					name: {
						text: 'echo',
						type: 'Word',
						loc: {
							start: {
								col: 2,
								row: 3,
								char: 16
							},
							end: {
								col: 5,
								row: 3,
								char: 19
							}
						}
					},
					loc: {
						start: {
							col: 2,
							row: 3,
							char: 16
						},
						end: {
							col: 8,
							row: 3,
							char: 22
						}
					},
					suffix: [
						{
							text: '$x',
							expansion: [
								{
									loc: {
										start: 0,
										end: 1
									},
									parameter: 'x',
									type: 'ParameterExpansion'
								}
							],
							type: 'Word',
							loc: {
								start: {
									col: 7,
									row: 3,
									char: 21
								},
								end: {
									col: 8,
									row: 3,
									char: 22
								}
							}
						}
					]
				}
			],
			loc: {
				start: {
					col: 7,
					row: 2,
					char: 12
				},
				end: {
					col: 4,
					row: 4,
					char: 28
				}
			}
		},
		loc: {
			start: {
				col: 1,
				row: 1,
				char: 0
			},
			end: {
				col: 4,
				row: 4,
				char: 28
			}
		}
	};

	utils.checkResults(t, result.commands[0], expected);
});

test('loc in multi line commands', t => {
	const result = bashParser('echo;\nls;\n', {insertLOC: true});
	// utils.logResults(result);
	utils.checkResults(t, result, {
		loc: mkloc(1, 1, 2, 2, 0, 7),
		type: 'Script',
		commands: [{
			type: 'Command',
			name: {type: 'Word', text: 'echo', loc: mkloc(1, 1, 1, 4, 0, 3)},
			loc: mkloc(1, 1, 1, 4, 0, 3)
		}, {
			type: 'Command',
			name: {type: 'Word', text: 'ls', loc: mkloc(2, 1, 2, 2, 6, 7)},
			loc: mkloc(2, 1, 2, 2, 6, 7)
		}]
	});
});
<commit_msg>fixed<commit_after>"use strict";

const test = require("ava");
const bashParser = require("../src");
const mkloc = require("./_utils").mkloc2;
const utils = require("./_utils");

/* eslint-disable camelcase */
test("syntax error contains line number", async t => {
	const error = t.throws(() => bashParser("ecoh\necho <"));
	t.true(
		error.message.startsWith(
			"Error: Parse error on line 2: Unexpected 'EOF'"
		)
	);
});

test("AST can include loc", t => {
	const result = bashParser("echo", { insertLOC: true });
	// utils.logResults(result)
	utils.checkResults(t, result.commands[0].name, {
		type: "Word",
		text: "echo",
		loc: mkloc(1, 1, 1, 4, 0, 3)
	});
});

test("subshell can include loc", t => {
	const result = bashParser("(echo)", { insertLOC: true });
	// utils.logResults(result);
	utils.checkResults(t, result, {
		type: "Script",
		commands: [
			{
				type: "Subshell",
				list: {
					type: "CompoundList",
					commands: [
						{
							type: "Command",
							name: {
								text: "echo",
								type: "Word",
								loc: mkloc(1, 2, 1, 5, 1, 4)
							},
							loc: mkloc(1, 2, 1, 5, 1, 4)
						}
					],
					loc: mkloc(1, 2, 1, 5, 1, 4)
				},
				loc: mkloc(1, 1, 1, 6, 0, 5)
			}
		],
		loc: mkloc(1, 1, 1, 6, 0, 5)
	});
});

test("double command with only name", t => {
	const result = bashParser("echo; ciao;", { insertLOC: true });
	// utils.logResults(result);
	utils.checkResults(t, result, {
		type: "Script",
		loc: mkloc(1, 1, 1, 10, 0, 9),
		commands: [
			{
				type: "Command",
				name: {
					type: "Word",
					text: "echo",
					loc: mkloc(1, 1, 1, 4, 0, 3)
				},
				loc: mkloc(1, 1, 1, 4, 0, 3)
			},
			{
				type: "Command",
				name: {
					type: "Word",
					text: "ciao",
					loc: mkloc(1, 7, 1, 10, 6, 9)
				},
				loc: mkloc(1, 7, 1, 10, 6, 9)
			}
		]
	});
});

test("loc are composed by all tokens", t => {
	const result = bashParser("echo 42", { insertLOC: true });
	// console.log(JSON.stringify(result, null, 4));
	utils.checkResults(t, result.commands[0], {
		type: "Command",
		name: {
			type: "Word",
			text: "echo",
			loc: mkloc(1, 1, 1, 4, 0, 3)
		},
		loc: mkloc(1, 1, 1, 7, 0, 6),
		suffix: [
			{
				type: "Word",
				text: "42",
				loc: mkloc(1, 6, 1, 7, 5, 6)
			}
		]
	});
});

test("loc works with multiple newlines", t => {
	const result = bashParser("\n\n\necho 42", { insertLOC: true });
	utils.checkResults(t, result.commands[0], {
		type: "Command",
		name: {
			type: "Word",
			text: "echo",
			loc: mkloc(4, 1, 4, 4, 3, 6)
		},
		loc: mkloc(4, 1, 4, 7, 3, 9),
		suffix: [
			{
				type: "Word",
				text: "42",
				loc: mkloc(4, 6, 4, 7, 8, 9)
			}
		]
	});
});

test("loc with LINEBREAK_IN statement", t => {
	const cmd = `for x
	in ; do
	echo $x;
done
`;

	const result = bashParser(cmd, { insertLOC: true });
	// utils.logResults(result)
	const expected = {
		type: "For",
		name: {
			text: "x",
			type: "Name",
			loc: {
				start: {
					col: 5,
					row: 1,
					char: 4
				},
				end: {
					col: 5,
					row: 1,
					char: 4
				}
			}
		},
		do: {
			type: "CompoundList",
			commands: [
				{
					type: "Command",
					name: {
						text: "echo",
						type: "Word",
						loc: {
							start: {
								col: 2,
								row: 3,
								char: 16
							},
							end: {
								col: 5,
								row: 3,
								char: 19
							}
						}
					},
					loc: {
						start: {
							col: 2,
							row: 3,
							char: 16
						},
						end: {
							col: 8,
							row: 3,
							char: 22
						}
					},
					suffix: [
						{
							text: "$x",
							expansion: [
								{
									loc: {
										start: 0,
										end: 1
									},
									parameter: "x",
									type: "ParameterExpansion"
								}
							],
							type: "Word",
							loc: {
								start: {
									col: 7,
									row: 3,
									char: 21
								},
								end: {
									col: 8,
									row: 3,
									char: 22
								}
							}
						}
					]
				}
			],
			loc: {
				start: {
					col: 7,
					row: 2,
					char: 12
				},
				end: {
					col: 4,
					row: 4,
					char: 28
				}
			}
		},
		loc: {
			start: {
				col: 1,
				row: 1,
				char: 0
			},
			end: {
				col: 4,
				row: 4,
				char: 28
			}
		}
	};

	utils.checkResults(t, result.commands[0], expected);
});

test("loc in multi line commands", t => {
	const result = bashParser("echo;\nls;\n", { insertLOC: true });
	// utils.logResults(result);
	utils.checkResults(t, result, {
		loc: mkloc(1, 1, 2, 2, 0, 7),
		type: "Script",
		commands: [
			{
				type: "Command",
				name: {
					type: "Word",
					text: "echo",
					loc: mkloc(1, 1, 1, 4, 0, 3)
				},
				loc: mkloc(1, 1, 1, 4, 0, 3)
			},
			{
				type: "Command",
				name: {
					type: "Word",
					text: "ls",
					loc: mkloc(2, 1, 2, 2, 6, 7)
				},
				loc: mkloc(2, 1, 2, 2, 6, 7)
			}
		]
	});
});
<|endoftext|>


<commit_before>/*global describe:true it:true */
'use strict';

var app = require('../app').app
var request = require('supertest')

describe('The router', function() {
  describe('index page',  function() {
    it('should return HTTP 200 OK', function(done) {
      request(app)
        .get('/')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(200, done)
    })

    it("should contain the current app's URL in the  tag", function(done) {
      request(app)
        .get('/')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(200, //, done)
    })
  })

  describe('404 page',  function() {
    it('should return HTTP 404 Not Found', function(done) {
      request(app)
        .get('/404')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(404, done)
    })

    it('should contain the URL not found in the page', function(done) {
      request(app)
        .get('/404')
        .set('Accept', 'text/html')
        .expect(404, /
\/404<\/div>/, done)
    })
  })
})
<commit_msg>Fix unescaped character<commit_after>/*global describe:true it:true */
'use strict';

var app = require('../app').app
var request = require('supertest')

describe('The router', function() {
  describe('index page',  function() {
    it('should return HTTP 200 OK', function(done) {
      request(app)
        .get('/')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(200, done)
    })

    it("should contain the current app's URL in the  tag", function(done) {
      request(app)
        .get('/')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(200, //, done)
    })
  })

  describe('404 page',  function() {
    it('should return HTTP 404 Not Found', function(done) {
      request(app)
        .get('/404')
        .set('Accept', 'text/html')
        .expect('Content-Type', 'text/html; charset=utf-8')
        .expect(404, done)
    })

    it('should contain the URL not found in the page', function(done) {
      request(app)
        .get('/404')
        .set('Accept', 'text/html')
        .expect(404, /
\/404<\/div>/, done)
    })
  })
})
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { Router } from 'routes';
import { Autobind } from 'es-decorators';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { toggleModal } from 'redactions/modal';

// Components
import Field from 'components/form/Field';
import Input from 'components/form/Input';
import Button from 'components/ui/Button';
import Spinner from 'components/ui/Spinner';

// Services
import WidgetService from 'services/WidgetService';

// utils
import { getChartConfig } from 'utils/widgets/WidgetHelper';

const FORM_ELEMENTS = {
  elements: {
  },
  validate() {
    const elements = this.elements;
    Object.keys(elements).forEach((k) => {
      elements[k].validate();
    });
  },
  isValid() {
    const elements = this.elements;
    const valid = Object.keys(elements)
      .map(k => elements[k].isValid())
      .filter(v => v !== null)
      .every(element => element);

    return valid;
  }
};

class SaveWidgetModal extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      submitting: false,
      loading: false,
      saved: false,
      error: false,
      widget: {}
    };

    this.widgetService = new WidgetService(null, {
      apiURL: process.env.WRI_API_URL
    });
  }

  @Autobind
  handleCancel() {
    this.props.toggleModal(false);
  }

  handleGoToMyRW() {
    Router.pushRoute('myrw', { tab: 'widgets', subtab: 'my-widgets' });
  }

  @Autobind
  onSubmit(event) {
    event.preventDefault();

    this.setState({
      loading: true
    });
    const { widgetEditor, tableName, dataset } = this.props;
    const { limit, value, category, color, size, orderBy, aggregateFunction } = widgetEditor;

    const widgetConfig = { widgetConfig: Object.assign(
      {},
      { paramsConfig: {
        limit,
        value,
        category,
        color,
        size,
        orderBy,
        aggregateFunction
      }
      },
      getChartConfig(widgetEditor, tableName, dataset)
    ) };
    const widgetObj = Object.assign({}, this.state.widget, widgetConfig);

    this.widgetService.saveUserWidget(widgetObj, this.props.dataset, this.props.user.token)
      .then((response) => {
        if (response.errors) {
          this.setState({
            saved: false,
            loading: false,
            error: true,
            errorMessage: response.errors[0].detail
          });
        } else {
          this.setState({
            saved: true,
            loading: false,
            error: false
          });
        }
      }).catch((err) => {
        this.setState({
          saved: false,
          error: true
        });
      });
  }

  @Autobind
  handleChange(value) {
    const newWidgetObj = Object.assign({}, this.state.widget, value);
    this.setState({ widget: newWidgetObj });
  }

  render() {
    const { submitting, loading, saved, error, errorMessage } = this.state;

    return (

        {!saved &&

Save widget

        }
        {saved &&

Widget saved!

        }
        <Spinner
          isLoading={loading}
          className="-light -relative"
        />
        {error &&

Error

          {errorMessage}

        }
        {!saved &&
          <form className="form-container" onSubmit={this.onSubmit}>
            <fieldset className="c-field-container">
              <Field
                ref={(c) => { if (c) FORM_ELEMENTS.elements.title = c; }}
                onChange={value => this.handleChange({ name: value })}
                validations={['required']}
                properties={{
                  title: 'title',
                  label: 'Title',
                  type: 'text',
                  required: true,
                  placeholder: 'Widget title'
                }}
              >
                {Input}
              </Field>
              <Field
                ref={(c) => { if (c) FORM_ELEMENTS.elements.description = c; }}
                onChange={value => this.handleChange({ description: value })}
                properties={{
                  title: 'description',
                  label: 'Description',
                  type: 'text',
                  placeholder: 'Widget description'
                }}
              >
                {Input}
              </Field>
            </fieldset>

              <Button
                properties={{
                  type: 'submit',
                  disabled: submitting,
                  className: '-secondary'
                }}
              >
                  Save
                </Button>
              <Button
                properties={{
                  disabled: submitting,
                  className: '-primary'
                }}
                onClick={this.handleCancel}
              >
                  Cancel
                </Button>

          </form>
        }
        {saved &&

            <Button
              properties={{
                className: '-primary'
              }}
              onClick={this.handleCancel}
            >
                OK
              </Button>
            <Button
              properties={{
                className: '-secondary'
              }}
              onClick={this.handleGoToMyRW}
            >
                Check my widgets
              </Button>

        }

    );
  }
}

SaveWidgetModal.propTypes = {
  dataset: PropTypes.string.isRequired,
  tableName: PropTypes.string.isRequired,
  // Store
  user: PropTypes.object.isRequired,
  widgetEditor: PropTypes.object.isRequired,
  toggleModal: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  user: state.user,
  widgetEditor: state.widgetEditor
});

const mapDispatchToProps = dispatch => ({
  toggleModal: (open) => { dispatch(toggleModal(open)); }
});

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(SaveWidgetModal);
<commit_msg>add missing chartType variable when saving widgets<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { Router } from 'routes';
import { Autobind } from 'es-decorators';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { toggleModal } from 'redactions/modal';

// Components
import Field from 'components/form/Field';
import Input from 'components/form/Input';
import Button from 'components/ui/Button';
import Spinner from 'components/ui/Spinner';

// Services
import WidgetService from 'services/WidgetService';

// utils
import { getChartConfig } from 'utils/widgets/WidgetHelper';

const FORM_ELEMENTS = {
  elements: {
  },
  validate() {
    const elements = this.elements;
    Object.keys(elements).forEach((k) => {
      elements[k].validate();
    });
  },
  isValid() {
    const elements = this.elements;
    const valid = Object.keys(elements)
      .map(k => elements[k].isValid())
      .filter(v => v !== null)
      .every(element => element);

    return valid;
  }
};

class SaveWidgetModal extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      submitting: false,
      loading: false,
      saved: false,
      error: false,
      widget: {}
    };

    this.widgetService = new WidgetService(null, {
      apiURL: process.env.WRI_API_URL
    });
  }

  @Autobind
  handleCancel() {
    this.props.toggleModal(false);
  }

  handleGoToMyRW() {
    Router.pushRoute('myrw', { tab: 'widgets', subtab: 'my-widgets' });
  }

  @Autobind
  onSubmit(event) {
    event.preventDefault();

    this.setState({
      loading: true
    });
    const { widgetEditor, tableName, dataset } = this.props;
    const { limit, value, category, color, size, orderBy, aggregateFunction, chartType } = widgetEditor;

    const widgetConfig = { widgetConfig: Object.assign(
      {},
      { paramsConfig: {
        limit,
        value,
        category,
        color,
        size,
        orderBy,
        aggregateFunction,
        chartType
      }
      },
      getChartConfig(widgetEditor, tableName, dataset)
    ) };
    const widgetObj = Object.assign({}, this.state.widget, widgetConfig);

    this.widgetService.saveUserWidget(widgetObj, this.props.dataset, this.props.user.token)
      .then((response) => {
        if (response.errors) {
          this.setState({
            saved: false,
            loading: false,
            error: true,
            errorMessage: response.errors[0].detail
          });
        } else {
          this.setState({
            saved: true,
            loading: false,
            error: false
          });
        }
      }).catch((err) => {
        this.setState({
          saved: false,
          error: true
        });
      });
  }

  @Autobind
  handleChange(value) {
    const newWidgetObj = Object.assign({}, this.state.widget, value);
    this.setState({ widget: newWidgetObj });
  }

  render() {
    const { submitting, loading, saved, error, errorMessage } = this.state;

    return (

        {!saved &&

Save widget

        }
        {saved &&

Widget saved!

        }
        <Spinner
          isLoading={loading}
          className="-light -relative"
        />
        {error &&

Error

          {errorMessage}

        }
        {!saved &&
          <form className="form-container" onSubmit={this.onSubmit}>
            <fieldset className="c-field-container">
              <Field
                ref={(c) => { if (c) FORM_ELEMENTS.elements.title = c; }}
                onChange={value => this.handleChange({ name: value })}
                validations={['required']}
                properties={{
                  title: 'title',
                  label: 'Title',
                  type: 'text',
                  required: true,
                  placeholder: 'Widget title'
                }}
              >
                {Input}
              </Field>
              <Field
                ref={(c) => { if (c) FORM_ELEMENTS.elements.description = c; }}
                onChange={value => this.handleChange({ description: value })}
                properties={{
                  title: 'description',
                  label: 'Description',
                  type: 'text',
                  placeholder: 'Widget description'
                }}
              >
                {Input}
              </Field>
            </fieldset>

              <Button
                properties={{
                  type: 'submit',
                  disabled: submitting,
                  className: '-secondary'
                }}
              >
                  Save
                </Button>
              <Button
                properties={{
                  disabled: submitting,
                  className: '-primary'
                }}
                onClick={this.handleCancel}
              >
                  Cancel
                </Button>

          </form>
        }
        {saved &&

            <Button
              properties={{
                className: '-primary'
              }}
              onClick={this.handleCancel}
            >
                OK
              </Button>
            <Button
              properties={{
                className: '-secondary'
              }}
              onClick={this.handleGoToMyRW}
            >
                Check my widgets
              </Button>

        }

    );
  }
}

SaveWidgetModal.propTypes = {
  dataset: PropTypes.string.isRequired,
  tableName: PropTypes.string.isRequired,
  // Store
  user: PropTypes.object.isRequired,
  widgetEditor: PropTypes.object.isRequired,
  toggleModal: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  user: state.user,
  widgetEditor: state.widgetEditor
});

const mapDispatchToProps = dispatch => ({
  toggleModal: (open) => { dispatch(toggleModal(open)); }
});

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(SaveWidgetModal);
<|endoftext|>


<commit_before>define({
    fr: {
        'Allowed values:'             : 'Valeurs autorisées :',
        'Compare all with predecessor': 'Tout comparer avec ...',
        'compare changes to:'         : 'comparer les changements à :',
        'compared to'                 : 'comparer à',
        'Default value:'              : 'Valeur par défaut :',
        'Description'                 : 'Description',
        'Field'                       : 'Champ',
        'General'                     : 'Général',
        'Generated with'              : 'Généré avec',
        'Name'                        : 'Nom',
        'No response values.'         : 'Aucune valeur de réponse.',
        'optional'                    : 'optionel',
        'Parameter'                   : 'Paramètre',
        'Permission:'                 : 'Permission :',
        'Response'                    : 'Réponse',
        'Send'                        : 'Envoyer',
        'Send a Sample Request'       : 'Envoyer une requête représentative',
        'show up to version:'         : 'Montrer à partir de la version :',
        'Size range:'                 : 'Ordre de grandeur :',
        'Type'                        : 'Type',
        'url'                         : 'url'
    }
});<commit_msg>Spelling mistake in the french translation file<commit_after>define({
    fr: {
        'Allowed values:'             : 'Valeurs autorisées :',
        'Compare all with predecessor': 'Tout comparer avec ...',
        'compare changes to:'         : 'comparer les changements à :',
        'compared to'                 : 'comparer à',
        'Default value:'              : 'Valeur par défaut :',
        'Description'                 : 'Description',
        'Field'                       : 'Champ',
        'General'                     : 'Général',
        'Generated with'              : 'Généré avec',
        'Name'                        : 'Nom',
        'No response values.'         : 'Aucune valeur de réponse.',
        'optional'                    : 'optionnel',
        'Parameter'                   : 'Paramètre',
        'Permission:'                 : 'Permission :',
        'Response'                    : 'Réponse',
        'Send'                        : 'Envoyer',
        'Send a Sample Request'       : 'Envoyer une requête représentative',
        'show up to version:'         : 'Montrer à partir de la version :',
        'Size range:'                 : 'Ordre de grandeur :',
        'Type'                        : 'Type',
        'url'                         : 'url'
    }
});
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var async = require('async');
var mongoose = require('mongoose');

var models_path = __dirname + '/../models';
fs.readdirSync(models_path).forEach(function (file) {
    require(models_path + '/' + file);
});

var TestData = {
    build: function(done) {
        console.log('Inserting test data...');
        async.series([
            function(cb) {
                mongoose.model('CraReporters').create({'activity_year': '2013',
                 'respondent_id': '0000000001', 'agency_code': '1', 'respondent_name': 'foo'
                 }, function(err, item) {
                    cb();
                });
            }
        ], function() {
              console.log('..done inserting test data');
              done();
           }
        );
    }
};

module.exports = TestData;
<commit_msg>missed some updates<commit_after>'use strict';

var fs = require('fs');
var async = require('async');
var mongoose = require('mongoose');

var models_path = __dirname + '/../models';
fs.readdirSync(models_path).forEach(function (file) {
    require(models_path + '/' + file);
});

var TestData = {
    build: function(done) {
        console.log('Inserting test data...');
        async.series([
            function(cb) {
                mongoose.model('CraReporters').create({'activity_year': '2013',
                 'respondent_id': '0000000001', 'agency_code': '1', 'respondent_name': 'foo'
                 }, function(err, item) {
                     cb();
                });
            },
            function(cb) {
                mongoose.model('Panel').create({'activity_year': '2013', 'data':
                 [
                     { 'respondent_id': '0000000001', 'other_lender_code': '0', 'parent_name': 'foo'},
                     { 'respondent_id': '0000000002', 'other_lender_code': '0', 'parent_name': ''},
                     { 'respondent_id': '0000000003', 'other_lender_code': '1', 'parent_name': 'foo'},
                     { 'respondent_id': '0000000004', 'other_lender_code': '1', 'parent_name': ''}
                 ] }, function(err, item) {
                    cb();
                });
            }
        ], function() {
              console.log('..done inserting test data');
              done();
           }
        );
    }
};

module.exports = TestData;
<|endoftext|>


<commit_before>'use strict';

var expect             = require('chai').expect;
var sinon              = require('sinon');
var ModelBase          = require('../mocks/model');
var UserBase           = require('../mocks/user');
var Rule               = require('../../lib/rule');
var Can                = require('../../lib/can');
var resolver           = require('../../lib/resolver');
var AuthorizationError = require('../../lib/resolver');

describe('Can', function () {

  var can;
  beforeEach(function () {
    can = new Can(UserBase);
  });

  describe('constructor', function () {

    it('stores the source model', function () {
      expect(can).to.have.property('_user', UserBase);
    });

    it('generates convenience #do methods for Can.methods', function () {
      sinon.stub(Can.prototype, 'do');
      can = new Can(UserBase);
      expect(can).to.respondTo('write');
      expect(can).to.respondTo('read');
      can.write(ModelBase);
      expect(can.do).to.have.been.calledWith('write', ModelBase);
      expect(can.do).to.have.been.calledOn(can);
      Can.prototype.do.restore();
    });

  });

  describe('Can#create', function () {

    it('creates an new Can instance', function () {
      expect(Can.create(true))
        .to.be.an.instanceOf(Can)
        .and.to.have.property('_user', true);
    });

  });

  describe('#do', function () {

    beforeEach(function () {
      sinon.stub(resolver, 'resolve');
    });

    afterEach(function () {
      resolver.resolve.restore();
    });

    it('passes the user, method, and target to the rule resolver', function () {
      resolver.resolve.returns([]);
      can.do('write', ModelBase).catch(function () {});
      expect(resolver.resolve).to.have.been.calledWith(UserBase, 'write', ModelBase);
    });

    it('throws if there are no matching rules', function () {
      resolver.resolve.returns([]);
      return expect(can.do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError, /No authorization rules/);
    });

    it('runs each rule', function () {
      var rule = new Rule(true);
      sinon.spy(rule, 'run');
      resolver.resolve.returns([rule]);
      return new Can(UserBase)
        .do('write', ModelBase)
        .finally(function () {
          expect(rule.run).to.have.been.calledWith(UserBase, ModelBase);
        });
    });

    it('resolves if any rule resolves', function () {
      resolver.resolve.returns([new Rule(true), new Rule(false)]);
      return new Can(UserBase).do('write', ModelBase);
    });

    it('rejects if only a single rule rejects', function () {
      resolver.resolve.returns([new Rule(false)]);
      expect(new Can(UserBase).do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError);
    });

    it('wraps multiple errors into a single one', function () {
      resolver.resolve.returns([new Rule(false), new Rule(false)]);
      return expect(new Can(UserBase).do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError, 'Multiple authorization rules failed.');
    });

    it('appends multiple errors to the error object', function () {
      resolver.resolve.returns([new Rule(false), new Rule(false)]);
      return new Can(UserBase).do('write', ModelBase)
        .catch(function (err) {
          expect(err).to.have.property('errors').with.length(2);
        });
    });

  });

});<commit_msg>Fix missing `return` on promise expectation<commit_after>'use strict';

var expect             = require('chai').expect;
var sinon              = require('sinon');
var ModelBase          = require('../mocks/model');
var UserBase           = require('../mocks/user');
var Rule               = require('../../lib/rule');
var Can                = require('../../lib/can');
var resolver           = require('../../lib/resolver');
var AuthorizationError = require('../../lib/resolver');

describe('Can', function () {

  var can;
  beforeEach(function () {
    can = new Can(UserBase);
  });

  describe('constructor', function () {

    it('stores the source model', function () {
      expect(can).to.have.property('_user', UserBase);
    });

    it('generates convenience #do methods for Can.methods', function () {
      sinon.stub(Can.prototype, 'do');
      can = new Can(UserBase);
      expect(can).to.respondTo('write');
      expect(can).to.respondTo('read');
      can.write(ModelBase);
      expect(can.do).to.have.been.calledWith('write', ModelBase);
      expect(can.do).to.have.been.calledOn(can);
      Can.prototype.do.restore();
    });

  });

  describe('Can#create', function () {

    it('creates an new Can instance', function () {
      expect(Can.create(true))
        .to.be.an.instanceOf(Can)
        .and.to.have.property('_user', true);
    });

  });

  describe('#do', function () {

    beforeEach(function () {
      sinon.stub(resolver, 'resolve');
    });

    afterEach(function () {
      resolver.resolve.restore();
    });

    it('passes the user, method, and target to the rule resolver', function () {
      resolver.resolve.returns([]);
      can.do('write', ModelBase).catch(function () {});
      expect(resolver.resolve).to.have.been.calledWith(UserBase, 'write', ModelBase);
    });

    it('throws if there are no matching rules', function () {
      resolver.resolve.returns([]);
      return expect(can.do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError, /No authorization rules/);
    });

    it('runs each rule', function () {
      var rule = new Rule(true);
      sinon.spy(rule, 'run');
      resolver.resolve.returns([rule]);
      return new Can(UserBase)
        .do('write', ModelBase)
        .finally(function () {
          expect(rule.run).to.have.been.calledWith(UserBase, ModelBase);
        });
    });

    it('resolves if any rule resolves', function () {
      resolver.resolve.returns([new Rule(true), new Rule(false)]);
      return new Can(UserBase).do('write', ModelBase);
    });

    it('rejects if only a single rule rejects', function () {
      resolver.resolve.returns([new Rule(false)]);
      return expect(new Can(UserBase).do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError);
    });

    it('wraps multiple errors into a single one', function () {
      resolver.resolve.returns([new Rule(false), new Rule(false)]);
      return expect(new Can(UserBase).do('write', ModelBase))
        .to.be.rejectedWith(AuthorizationError, 'Multiple authorization rules failed.');
    });

    it('appends multiple errors to the error object', function () {
      resolver.resolve.returns([new Rule(false), new Rule(false)]);
      return new Can(UserBase).do('write', ModelBase)
        .catch(function (err) {
          expect(err).to.have.property('errors').with.length(2);
        });
    });

  });

});<|endoftext|>