<commit_before>// Block colors
var block_color_io=20;
var block_color_timer = 60;
var block_color_leds = 87;

Blockly.Lua['pin_mode'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var mode = block.getFieldValue('MODE');
    var code = "gpio.mode(" + pin + ", " + mode + ")\n";
    return code;
};

Blockly.Blocks['pin_mode'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["input", "gpio.INPUT"], ["output", "gpio.OUTPUT"]]), "MODE");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_io);
        this.setTooltip('Set the mode - input/output for a pin.');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['pin_write'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var level = Blockly.Lua.valueToCode(block, 'level',
       Blockly.Lua.ORDER_ATOMIC) || 'False';
    var code = "gpio.write(" + pin + ", " + level + " and 1 or 0)\n";
    return code;
};

Blockly.Blocks['pin_write'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendValueInput("level")
            .setCheck("Boolean")
            .appendField("write");
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_io);
        this.setTooltip('Write to a pin');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['pin_read'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var code = "gpio.read(" + pin + ")";
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['pin_read'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendDummyInput()
            .appendField("read");
        this.setInputsInline(true);
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip('');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['analog_read'] = function (block) {
    // Analog pin is fixed on the esp.
    var code = "adc.read(0)";
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['analog_read'] = {
    init: function () {
        this.appendDummyInput()
            .appendField('Read analog');
        this.setOutput(true);
        this.setColour(block_color_io);
    }
};

Blockly.Lua['tmr_alarm'] = function (block) {
    // Repeat string
    var timer = Blockly.Lua.valueToCode(block, 'timer',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    var interval = Blockly.Lua.valueToCode(block, 'interval',
        Blockly.Lua.ORDER_ATOMIC) || 100;
    var repeat = block.getFieldValue('REPEAT');
    var branch = Blockly.Lua.statementToCode(block, 'DO') || '';
    var code = 'tmr.alarm(' + timer + ',' + interval + ', ' + repeat + ', function() \n' + branch + '\nend )\n';
    return code;
};

Blockly.Blocks['tmr_alarm'] = {
    init: function() {
        this.appendValueInput("timer")
            .setCheck("Number")
            .appendField("timer");
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["every", "1"], ["after", "0"]]), "REPEAT");
        this.appendValueInput("interval")
            .setCheck("Number");
        this.appendStatementInput("DO")
            .appendField("millis do");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_timer);
        this.setTooltip('');
    }
};

Blockly.Lua['tmr_stop'] = function (block) {
    var timer = Blockly.Lua.valueToCode(block, 'timer',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    var code = 'tmr.stop(' + timer + ')\n';
    return code;
};

Blockly.Blocks['tmr_stop'] = {
    init: function () {
        this.appendValueInput("timer")
            .appendField("stop timer");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip('');
        this.setColour(block_color_timer);
    }
};

Blockly.Lua['text_rep'] = function (block) {
    // Repeat string
    var text = Blockly.Lua.valueToCode(block, 'TEXT',
        Blockly.Lua.ORDER_ATOMIC) || '\'\'';
    var count = Blockly.Lua.valueToCode(block, 'COUNT',
        Blockly.Lua.ORDER_ATOMIC) || '0';
    var code = 'string.rep(' + text + ', ' + count + ')';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['text_rep'] = {
    init: function () {
        this.appendValueInput("TEXT")
            .setCheck("String")
            .appendField("repeat text");
        this.appendValueInput("COUNT")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("times");
        this.setInputsInline(true);
        this.setOutput(true, "String");
        this.setColour(160);
        this.setTooltip('');
    }
};

Blockly.Lua['ws2812_writergb'] = function (block) {
    // Ws2812 write rgb list
    // Decode a list(table) of RGB not a string.
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var data = Blockly.Lua.valueToCode(block, 'data',
        Blockly.Lua.ORDER_ATOMIC) || '\'\'';
    var code = 'ws2812.writergb(' + pin + ", table.concat(" + data + ', \'\'))';
    return code;
};

Blockly.Blocks['ws2812_writergb'] ={
    init: function () {
        this.appendDummyInput()
            .appendField("ws2812 output");
        this.appendValueInput("data")
            .setCheck("Array")
            .appendField("colour list");
        this.appendDummyInput()
            .appendField("on ");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(false);
        this.setColour(block_color_leds);
        this.setTooltip('');
    }
};

Blockly.Lua['dht_temp'] = function(block) {
    // Read DHT temperature
    var pin = Blockly.Lua.valueToCode(block, 'pin',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    // To get one value, we have to construct in brackets, then deref.
    var code= '({dht.read(' + pin + ')})[2]';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['dht_temp'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("Read dht temperature on");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip("Read the temperature from a dht sensor");
    }
};

Blockly.Lua['dht_humidity'] = function(block) {
    // Read DHT temperature
    var pin = Blockly.Lua.valueToCode(block, 'pin',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    // To get one value, we have to construct in brackets, then deref.
    var code= '({dht.read(' + pin + ')})[3]';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['dht_humidity'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("Get dht humidity on");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip("Read the humidity from a dht sensor");
    }
};

/* Redefine colours for use with rgb devices like the ws2812. */
var repack_colour_=function(colour) {
    var r = parseInt(colour.substring(2, 3), 16);
    var g = parseInt(colour.substring(4, 5), 16);
    var b = parseInt(colour.substring(6, 7), 16);
    return r + "," + g + "," + b;
};

Blockly.Lua['colour_picker'] = function(block) {
  // Colour picker.
  var code = 'string.char(' + repack_colour_(block.getFieldValue('COLOUR')) + ')';
  return [code, Blockly.Lua.ORDER_ATOMIC];
};

Blockly.Lua['colour_random'] = function(block) {
  // Generate a random colour.
  var code = 'string.char(math.random(0, 2^5 - 1), math.random(0, 2^5 - 1), math.random(0, 2^5 - 1))';
  return [code, Blockly.Lua.ORDER_HIGH];
};

Blockly.Lua['colour_rgb'] = function(block) {
  // Compose a colour from RGB components.
  var r = Blockly.Lua.valueToCode(block, 'RED',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var g = Blockly.Lua.valueToCode(block, 'GREEN',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var b = Blockly.Lua.valueToCode(block, 'BLUE',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var code = 'string.char(' + r + ', ' + g + ', ' + b + ')';
  return [code, Blockly.Lua.ORDER_HIGH];
};

Blockly.Lua['colour_blend'] = function(block) {
  // Blend two colours together.
  var functionName = Blockly.Lua.provideFunction_(
      'colour_blend',
      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
          '(colour1, colour2, ratio)',
       '  local r1 = string.byte(colour1, 0)',
       '  local r2 = string.byte(colour2, 0)',
       '  local g1 = string.byte(colour1, 1)',
       '  local g2 = string.byte(colour2, 1)',
       '  local b1 = string.byte(colour1, 2)',
       '  local b2 = string.byte(colour2, 2)',
       '  local ratio = math.min(1, math.max(0, ratio))',
       '  local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)',
       '  local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)',
       '  local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)',
       '  return string.char(r, g, b)',
       'end']);
  var colour1 = Blockly.Lua.valueToCode(block, 'COLOUR1',
      Blockly.Lua.ORDER_NONE) || 'string.char(0, 0, 0)';
  var colour2 = Blockly.Lua.valueToCode(block, 'COLOUR2',
      Blockly.Lua.ORDER_NONE) || 'string.char(0, 0, 0)';
  var ratio = Blockly.Lua.valueToCode(block, 'RATIO',
      Blockly.Lua.ORDER_NONE) || 0;
  var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
  return [code, Blockly.Lua.ORDER_HIGH];
};

/* Fixes (to be pushed back into lua/lists.js - update_libs.sh needs to accomodate this properly) */
Blockly.Lua['lists_split'] = function(block) {
    var mode = block.getFieldValue('MODE');
    var input = Blockly.Lua.valueToCode(block, 'INPUT');
    if(mode == 'JOIN') {
        var code = "table.concat(" + input + ")";
        return [code, Blockly.Lua.ORDER_HIGH];
    } else {
        //
        throw "Woops - not yet implemented";
    }
};

Blockly.Blocks['lights_led_grid'] ={
    init: function () {
        this.appendDummyInput()
            .appendField("led grid:");
        var grid_width = 8; // TODO: Configurable
        var grid_height = 8;
        for(var row=0; row<grid_height; row++) {
            var line = this.appendDummyInput().appendField(row + " ");
            for(var column=0; column<grid_width; column++) {
                line = line.appendField(new Blockly.FieldColour('#660000'), 'd' + row + '_' + column );
            }
        }
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_leds);
        this.setTooltip('Make a grid of colours for lights.');
    }
};

Blockly.Lua['lights_led_grid'] = function(block) {};
<commit_msg>LED grid works!<commit_after>// Block colors
var block_color_io=20;
var block_color_timer = 60;
var block_color_leds = 87;

Blockly.Lua['pin_mode'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var mode = block.getFieldValue('MODE');
    var code = "gpio.mode(" + pin + ", " + mode + ")\n";
    return code;
};

Blockly.Blocks['pin_mode'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["input", "gpio.INPUT"], ["output", "gpio.OUTPUT"]]), "MODE");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_io);
        this.setTooltip('Set the mode - input/output for a pin.');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['pin_write'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var level = Blockly.Lua.valueToCode(block, 'level',
       Blockly.Lua.ORDER_ATOMIC) || 'False';
    var code = "gpio.write(" + pin + ", " + level + " and 1 or 0)\n";
    return code;
};

Blockly.Blocks['pin_write'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendValueInput("level")
            .setCheck("Boolean")
            .appendField("write");
        this.setInputsInline(true);
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_io);
        this.setTooltip('Write to a pin');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['pin_read'] = function (block) {
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var code = "gpio.read(" + pin + ")";
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['pin_read'] = {
    init: function () {
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.appendDummyInput()
            .appendField("read");
        this.setInputsInline(true);
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip('');
        this.setHelpUrl('http://www.example.com/');
    }
};

Blockly.Lua['analog_read'] = function (block) {
    // Analog pin is fixed on the esp.
    var code = "adc.read(0)";
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['analog_read'] = {
    init: function () {
        this.appendDummyInput()
            .appendField('Read analog');
        this.setOutput(true);
        this.setColour(block_color_io);
    }
};

Blockly.Lua['tmr_alarm'] = function (block) {
    // Repeat string
    var timer = Blockly.Lua.valueToCode(block, 'timer',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    var interval = Blockly.Lua.valueToCode(block, 'interval',
        Blockly.Lua.ORDER_ATOMIC) || 100;
    var repeat = block.getFieldValue('REPEAT');
    var branch = Blockly.Lua.statementToCode(block, 'DO') || '';
    var code = 'tmr.alarm(' + timer + ',' + interval + ', ' + repeat + ', function() \n' + branch + '\nend )\n';
    return code;
};

Blockly.Blocks['tmr_alarm'] = {
    init: function() {
        this.appendValueInput("timer")
            .setCheck("Number")
            .appendField("timer");
        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["every", "1"], ["after", "0"]]), "REPEAT");
        this.appendValueInput("interval")
            .setCheck("Number");
        this.appendStatementInput("DO")
            .appendField("millis do");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setColour(block_color_timer);
        this.setTooltip('');
    }
};

Blockly.Lua['tmr_stop'] = function (block) {
    var timer = Blockly.Lua.valueToCode(block, 'timer',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    var code = 'tmr.stop(' + timer + ')\n';
    return code;
};

Blockly.Blocks['tmr_stop'] = {
    init: function () {
        this.appendValueInput("timer")
            .appendField("stop timer");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setTooltip('');
        this.setColour(block_color_timer);
    }
};

Blockly.Lua['text_rep'] = function (block) {
    // Repeat string
    var text = Blockly.Lua.valueToCode(block, 'TEXT',
        Blockly.Lua.ORDER_ATOMIC) || '\'\'';
    var count = Blockly.Lua.valueToCode(block, 'COUNT',
        Blockly.Lua.ORDER_ATOMIC) || '0';
    var code = 'string.rep(' + text + ', ' + count + ')';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['text_rep'] = {
    init: function () {
        this.appendValueInput("TEXT")
            .setCheck("String")
            .appendField("repeat text");
        this.appendValueInput("COUNT")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("times");
        this.setInputsInline(true);
        this.setOutput(true, "String");
        this.setColour(160);
        this.setTooltip('');
    }
};

Blockly.Lua['ws2812_writergb'] = function (block) {
    // Ws2812 write rgb list
    // Decode a list(table) of RGB not a string.
    var pin = Blockly.Lua.valueToCode(block, 'pin',
       Blockly.Lua.ORDER_ATOMIC) || 0;
    var data = Blockly.Lua.valueToCode(block, 'data',
        Blockly.Lua.ORDER_ATOMIC) || '\'\'';
    var code = 'ws2812.writergb(' + pin + ", table.concat(" + data + ', \'\'))';
    return code;
};

Blockly.Blocks['ws2812_writergb'] ={
    init: function () {
        this.appendDummyInput()
            .appendField("ws2812 output");
        this.appendValueInput("data")
            .setCheck("Array")
            .appendField("colour list");
        this.appendDummyInput()
            .appendField("on ");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setPreviousStatement(true);
        this.setNextStatement(true);
        this.setInputsInline(false);
        this.setColour(block_color_leds);
        this.setTooltip('');
    }
};

Blockly.Lua['dht_temp'] = function(block) {
    // Read DHT temperature
    var pin = Blockly.Lua.valueToCode(block, 'pin',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    // To get one value, we have to construct in brackets, then deref.
    var code= '({dht.read(' + pin + ')})[2]';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['dht_temp'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("Read dht temperature on");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip("Read the temperature from a dht sensor");
    }
};

Blockly.Lua['dht_humidity'] = function(block) {
    // Read DHT temperature
    var pin = Blockly.Lua.valueToCode(block, 'pin',
        Blockly.Lua.ORDER_ATOMIC) || 0;
    // To get one value, we have to construct in brackets, then deref.
    var code= '({dht.read(' + pin + ')})[3]';
    return [code, Blockly.Lua.ORDER_FUNCTION_CALL];
};

Blockly.Blocks['dht_humidity'] = {
    init: function() {
        this.appendDummyInput()
            .appendField("Get dht humidity on");
        this.appendValueInput("pin")
            .setCheck("Number")
            .appendField("pin");
        this.setOutput(true);
        this.setColour(block_color_io);
        this.setTooltip("Read the humidity from a dht sensor");
    }
};

/* Redefine colours for use with rgb devices like the ws2812. */
var repack_colour_=function(colour) {
    var r = parseInt(colour.substring(2, 3), 16);
    var g = parseInt(colour.substring(4, 5), 16);
    var b = parseInt(colour.substring(6, 7), 16);
    return r + "," + g + "," + b;
};

Blockly.Lua['colour_picker'] = function(block) {
  // Colour picker.
  var code = 'string.char(' + repack_colour_(block.getFieldValue('COLOUR')) + ')';
  return [code, Blockly.Lua.ORDER_ATOMIC];
};

Blockly.Lua['colour_random'] = function(block) {
  // Generate a random colour.
  var code = 'string.char(math.random(0, 2^5 - 1), math.random(0, 2^5 - 1), math.random(0, 2^5 - 1))';
  return [code, Blockly.Lua.ORDER_HIGH];
};

Blockly.Lua['colour_rgb'] = function(block) {
  // Compose a colour from RGB components.
  var r = Blockly.Lua.valueToCode(block, 'RED',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var g = Blockly.Lua.valueToCode(block, 'GREEN',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var b = Blockly.Lua.valueToCode(block, 'BLUE',
                                     Blockly.Lua.ORDER_NONE) || 0;
  var code = 'string.char(' + r + ', ' + g + ', ' + b + ')';
  return [code, Blockly.Lua.ORDER_HIGH];
};

Blockly.Lua['colour_blend'] = function(block) {
  // Blend two colours together.
  var functionName = Blockly.Lua.provideFunction_(
      'colour_blend',
      ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ +
          '(colour1, colour2, ratio)',
       '  local r1 = string.byte(colour1, 0)',
       '  local r2 = string.byte(colour2, 0)',
       '  local g1 = string.byte(colour1, 1)',
       '  local g2 = string.byte(colour2, 1)',
       '  local b1 = string.byte(colour1, 2)',
       '  local b2 = string.byte(colour2, 2)',
       '  local ratio = math.min(1, math.max(0, ratio))',
       '  local r = math.floor(r1 * (1 - ratio) + r2 * ratio + .5)',
       '  local g = math.floor(g1 * (1 - ratio) + g2 * ratio + .5)',
       '  local b = math.floor(b1 * (1 - ratio) + b2 * ratio + .5)',
       '  return string.char(r, g, b)',
       'end']);
  var colour1 = Blockly.Lua.valueToCode(block, 'COLOUR1',
      Blockly.Lua.ORDER_NONE) || 'string.char(0, 0, 0)';
  var colour2 = Blockly.Lua.valueToCode(block, 'COLOUR2',
      Blockly.Lua.ORDER_NONE) || 'string.char(0, 0, 0)';
  var ratio = Blockly.Lua.valueToCode(block, 'RATIO',
      Blockly.Lua.ORDER_NONE) || 0;
  var code = functionName + '(' + colour1 + ', ' + colour2 + ', ' + ratio + ')';
  return [code, Blockly.Lua.ORDER_HIGH];
};

/* Fixes (to be pushed back into lua/lists.js - update_libs.sh needs to accomodate this properly) */
Blockly.Lua['lists_split'] = function(block) {
    var mode = block.getFieldValue('MODE');
    var input = Blockly.Lua.valueToCode(block, 'INPUT');
    if(mode == 'JOIN') {
        var code = "table.concat(" + input + ")";
        return [code, Blockly.Lua.ORDER_HIGH];
    } else {
        //
        throw "Woops - not yet implemented";
    }
};

Blockly.Blocks['lights_led_grid'] ={
    init: function () {
        this.appendDummyInput()
            .appendField("led grid:");
        var grid_width = 8; // TODO: Configurable
        var grid_height = 8;
        for(var row=0; row<grid_height; row++) {
            var line = this.appendDummyInput().appendField(row + " ");
            for(var column=0; column<grid_width; column++) {
                // TODO: Option, variables or colours.
                line = line.appendField(new Blockly.FieldColour('#660000'), 'd' + row + '_' + column );
            }
        }
        this.setOutput(true);
        this.setColour(block_color_leds);
        this.setTooltip('Make a grid of colours for lights.');
    }
};

Blockly.Lua['lights_led_grid'] = function(block) {
    var code = '{string.char(';
    var grid_width = 8; // TODO: Configurable
    var grid_height = 8;

    var next_comma = "\n  ";
    for(var row=0; row<grid_height; row++) {
        var prefix="d" + row + "_";
        for(var column=0; column<grid_width; column++) {
            code += next_comma + repack_colour_(block.getFieldValue(prefix + column));
            next_comma = ", ";
        }
        next_comma = ",\n  ";
    }
    code += ')}';
    return [code, Blockly.Lua.ORDER_ATOMIC]
};
<|endoftext|>


<commit_before>"use strict";
var assert = require('assert');

var Game = function() {

  var rolls = [];

  var isSpare = function(frameStart) {
    return 10 === rolls[frameStart] + rolls[frameStart + 1];
  };

  this.roll = function(pins) {
    rolls.push(pins);
  };

  this.score = function() {
    var score = 0;
    var frameStart = 0;
    for (var i=0;i<10;++i) {
      var frameScore = rolls[frameStart] + rolls[frameStart+1];
      if (rolls[frameStart] === 10) {
        score += rolls[frameStart + 1] + rolls[frameStart + 2] + 10;
         frameStart++;
      }
      else if (isSpare(frameStart)) {
        score += rolls[frameStart + 2] + 10;
        frameStart += 2;
      }
      else {
        score += rolls[frameStart] + rolls[frameStart+1];
        frameStart += 2;
      }
    }

    return score;
  };

  return this;
};

describe('bowling game', function() {
  describe('game', function() {

    var game;

    beforeEach(function() {
      game = new Game();
    });

    var rollMany = function(n, pins) {
      for (var i=0;i<n;++i) {
        game.roll(pins);
      }
    }

    it('is able to bowl a gutter game', function() {
      rollMany(20,0);

      assert.equal(0, game.score());
    });

    it('scores non strike pins', function() {
      game.roll(5);
      rollMany(19,0);

      assert.equal(5, game.score());
    });

    it('successfully scores a spare', function() {
      game.roll(3);
      game.roll(7);
      game.roll(2);

      rollMany(17,0);
      assert.equal(3 + 7 + 2 + 2, game.score());
    });

    it('successfully scores a strike', function() {
      game.roll(10);
      game.roll(5);
      game.roll(2);

      rollMany(17,0);
      assert.equal(10 + 5 + 2 + 5 + 2, game.score());
    });

    it('can roll the perfect game', function() {
      rollMany(12,10);
      assert.equal(300, game.score());
    });
  });
});<commit_msg>bowling game kata<commit_after><|endoftext|>


<commit_before>"use strict";
var assert = require('assert');

var Game = function() {

  var rolls = [];

  this.roll = function(pins) {
    rolls.push(pins);
  };

  this.score = function() {
    var score = 0;
    for (var i=0;i<rolls.length;++i) {
      score += rolls[i];
    }

    return score;
  };

  return this;
};

describe('bowling game', function() {
  describe('game', function() {

    var game;

    beforeEach(function() {
      game = new Game();
    });

    var rollMany = function(n, pins) {
      for (var i=0;i<n;++i) {
        game.roll(pins);
      }
    }

    it('is able to bowl a gutter game', function() {
      rollMany(20,0);

      assert.equal(0, game.score());
    });

    it('scores non strike pins', function() {
      game.roll(5);
      rollMany(19,0);

      assert.equal(5, game.score());
    });

    it.skip('successfully scores a spare', function() {
      game.roll(3);
      game.roll(7);
      game.roll(2);

      rollMany(17,0);
      assert.equal(3 + 7 + 2 + 2, game.score());
    });
  });
});<commit_msg>refactor to count to frames<commit_after>"use strict";
var assert = require('assert');

var Game = function() {

  var rolls = [];

  this.roll = function(pins) {
    rolls.push(pins);
  };

  this.score = function() {
    var score = 0;
    for (var i=0;i<10;++i) {
      score += (rolls[2*i] + rolls[2*i+1]);
    }

    return score;
  };

  return this;
};

describe('bowling game', function() {
  describe('game', function() {

    var game;

    beforeEach(function() {
      game = new Game();
    });

    var rollMany = function(n, pins) {
      for (var i=0;i<n;++i) {
        game.roll(pins);
      }
    }

    it('is able to bowl a gutter game', function() {
      rollMany(20,0);

      assert.equal(0, game.score());
    });

    it('scores non strike pins', function() {
      game.roll(5);
      rollMany(19,0);

      assert.equal(5, game.score());
    });

    it.skip('successfully scores a spare', function() {
      game.roll(3);
      game.roll(7);
      game.roll(2);

      rollMany(17,0);
      assert.equal(3 + 7 + 2 + 2, game.score());
    });
  });
});<|endoftext|>


<commit_before><commit_msg>check-links: do not check gh new issue links<commit_after><|endoftext|>


<commit_before>var fs = require('fs');
var aync = require('async');
var exec = require('child_process').exec;
var helpers = require('../helpers/helpers.js');
var builder = require('../helpers/dockerfileBuilder.js');
var spawnSeriesLib = require('../helpers/spawnSeries.js');
var dockerSpawnSeries = spawnSeriesLib.dockerSpawnSeries;
var configFile = "./.lifter/lifter.yml";

var exitInstructions = [];

// if boot2docker VM doesn't exist: init , else boot
var start_b2d = function() {
  exec('boot2docker info', function(err, stdout, stderr) {
    if (err) {
      if (/machine not exist/.test(stderr)) {
        console.log('boot2docker VM not installed, running boot2docker init');
        exec_b2d_init();
      }
    } else {
      boot_b2d();
    }
  });
};

// create boot2docker VM, then boot
var exec_b2d_init = function() {
  exec('boot2docker init', function(err, stdout, stderr) {
    if (err) console.log(stderr);
    console.log('boot2docker VM created!');
    boot_b2d();
  });
};

// If b2d is powered off, power it on
var boot_b2d = function() {
  exec('boot2docker status', function (err, stdout, stderr) {
    if (err) console.log(err);
    if (/running/.test(stdout)) {
      console.log('boot2docker is already running');
      finishInit();
    } else { //if (/poweroff/.test(stdout)) {
      console.log('boot2docker not running, powering on...');
      exec_b2d_Up();
    }
  });
}

var exec_b2d_Up = function() {
  var setEnvs = false;
  var exportCmds = [];
  exec('boot2docker up', function(err, stdout, stderr) {
    if (err) console.log("exec err: ", err);
    console.log('boot2docker VM powered on');
    finishInit();
  });
};

// check /etc/hosts for proper dockerhost IP
var checkHostsFileForDockerhost = function() {
  var hosts = fs.readFileSync('/etc/hosts');
  var hostsWritten = /dockerhost/.test(hosts);

  exec('boot2docker ip', function(err, stdout, stderr) {
    if (err) console.log(stderr);
    // grab ip out of stdout
    var ip = /\d*\.\d*\.\d*\.\d*/.exec(stdout)[0];
    var ipRegex = new RegExp(ip);
    // change line if ip not in hosts file

    createShellScript();
    builder.buildDockerfile();

    if (hostsWritten) {
      console.log('dockerhost found in /etc/hosts');
      if (!ipRegex.test(hosts)) {
        console.log('dockerhost IP incorrect... removing');
        // removeIPinHostsFile(ip);
        exitInstructions.push(
          'echo sed \'/dockerhost/d\' /etc/hosts | sudo tee /etc/hosts');
        exitInstructions.push(
          'echo ' + ip + ' dockerhost | sudo tee -a /etc/hosts');
      } else {
        console.log('dockerhost IP is correct');
      }
    } else {
      console.log('dockerhost not found in /etc/hosts... adding');
      exitInstructions.push(
          'echo ' + ip + ' dockerhost | sudo tee -a /etc/hosts');
      // addDockerhostToHostsFile(ip);
    }
    // console.log(exitInstructions);
    createLocalContainer();
  });

}

// create shell script to launch app
var createShellScript = function() {
  var settings = helpers.readYAML();

  var shellFileContent = '#!/bin/sh\n' +

                         // wait 10 seconds for containers to be configured
                         'sleep 10\n' +

                         'DB_PORT=' + settings.dbPort + "\n" +
                         'CURL_OUTPUT=$(curl dbLink:$DB_PORT)\n' +
                         // this success message is  specific to mongo, need to change
                         'SUCCESS="It looks like you are trying to access MongoDB over HTTP on the native driver port."\n' +
                         'LAUNCH_CMD="' + settings.launchCommand + '"\n' +

                         // checking if application and database container are linked
                         'until [[ $CURL_OUTPUT == $SUCCESS ]]\n' +
                         // if they are not, waits 20seconds and checks again
                         'do\n' +
                         'echo "Linking database container"\n' +
                         'sleep 20\n' +
                         'CURL_OUTPUT=$(curl dbLink:$DB_PORT)\n' +
                         // otherwise it runns the launch command
                         'done\n' +
                         'echo "Containers linked, running application launch command"\n' +
                         'cd prod\n' +
                         '$LAUNCH_CMD';

  fs.writeFile("./.lifter/app.sh", shellFileContent, function(err) {
    if (err) console.log(err);
    console.log("Launch script created: app.sh");
  });
}

var createLocalContainer = function() {
  var settings = helpers.readYAML();
  //docker build -t username_on_docker_hub/create_new_repo_name .
  var appContainerName = settings.appContainerName;
  var imageName = settings.username + '/' + settings.repoName;

  var dbContainerName = settings.dbContainerName;
  var dbImageName = settings.dbImageName;
  var dbLinkName = dbContainerName+'-link';

  var buildCmd = ['docker',
    ['build', '-t', imageName, '.']];
  var dbRunCmd = ['docker',
    ['run', '--restart=always',
     '--name', dbContainerName, dbImageName]];
  var appRunCmd = ['docker',
    ['run', '--restart=always',
     '--name', appContainerName,
     '--link', dbContainerName+':'+dbLinkName
     '-p', settings.portPrivate+':'+settings.portPublic,
     '-v', settings.launchPath+':/src:ro', imageName, 'sh', '/src/app.sh']];

  dockerSpawnSeries([
    buildCmd,
    mongoRunCmd,
    appRunCmd
  ], finishInit);
}

var printInstructions = function() {
  if (exitInstructions.length > 0) {
    console.log("Run these commands:")
    exitInstructions.forEach(function(str) {
      console.log("    " + str);
    });
  }
}

var finishInit = function () {
  aync.series([
    checkHostsFileForDockerhost,
    createShellScript,
    createLocalContainer
  ]);
  console.log('Local docker environment created!');
  printInstructions();
}

module.exports = {
  start_b2d: start_b2d
}
<commit_msg>change dbImageName to dbTag<commit_after>var fs = require('fs');
var aync = require('async');
var exec = require('child_process').exec;
var helpers = require('../helpers/helpers.js');
var builder = require('../helpers/dockerfileBuilder.js');
var spawnSeriesLib = require('../helpers/spawnSeries.js');
var dockerSpawnSeries = spawnSeriesLib.dockerSpawnSeries;
var configFile = "./.lifter/lifter.yml";

var exitInstructions = [];

// if boot2docker VM doesn't exist: init , else boot
var start_b2d = function() {
  exec('boot2docker info', function(err, stdout, stderr) {
    if (err) {
      if (/machine not exist/.test(stderr)) {
        console.log('boot2docker VM not installed, running boot2docker init');
        exec_b2d_init();
      }
    } else {
      boot_b2d();
    }
  });
};

// create boot2docker VM, then boot
var exec_b2d_init = function() {
  exec('boot2docker init', function(err, stdout, stderr) {
    if (err) console.log(stderr);
    console.log('boot2docker VM created!');
    boot_b2d();
  });
};

// If b2d is powered off, power it on
var boot_b2d = function() {
  exec('boot2docker status', function (err, stdout, stderr) {
    if (err) console.log(err);
    if (/running/.test(stdout)) {
      console.log('boot2docker is already running');
      finishInit();
    } else { //if (/poweroff/.test(stdout)) {
      console.log('boot2docker not running, powering on...');
      exec_b2d_Up();
    }
  });
}

var exec_b2d_Up = function() {
  var setEnvs = false;
  var exportCmds = [];
  exec('boot2docker up', function(err, stdout, stderr) {
    if (err) console.log("exec err: ", err);
    console.log('boot2docker VM powered on');
    finishInit();
  });
};

// check /etc/hosts for proper dockerhost IP
var checkHostsFileForDockerhost = function() {
  var hosts = fs.readFileSync('/etc/hosts');
  var hostsWritten = /dockerhost/.test(hosts);

  exec('boot2docker ip', function(err, stdout, stderr) {
    if (err) console.log(stderr);
    // grab ip out of stdout
    var ip = /\d*\.\d*\.\d*\.\d*/.exec(stdout)[0];
    var ipRegex = new RegExp(ip);
    // change line if ip not in hosts file

    createShellScript();
    builder.buildDockerfile();

    if (hostsWritten) {
      console.log('dockerhost found in /etc/hosts');
      if (!ipRegex.test(hosts)) {
        console.log('dockerhost IP incorrect... removing');
        // removeIPinHostsFile(ip);
        exitInstructions.push(
          'echo sed \'/dockerhost/d\' /etc/hosts | sudo tee /etc/hosts');
        exitInstructions.push(
          'echo ' + ip + ' dockerhost | sudo tee -a /etc/hosts');
      } else {
        console.log('dockerhost IP is correct');
      }
    } else {
      console.log('dockerhost not found in /etc/hosts... adding');
      exitInstructions.push(
          'echo ' + ip + ' dockerhost | sudo tee -a /etc/hosts');
      // addDockerhostToHostsFile(ip);
    }
    // console.log(exitInstructions);
    createLocalContainer();
  });

}

// create shell script to launch app
var createShellScript = function() {
  var settings = helpers.readYAML();

  var shellFileContent = '#!/bin/sh\n' +

                         // wait 10 seconds for containers to be configured
                         'sleep 10\n' +

                         'DB_PORT=' + settings.dbPort + "\n" +
                         'CURL_OUTPUT=$(curl dbLink:$DB_PORT)\n' +
                         // this success message is  specific to mongo, need to change
                         'SUCCESS="It looks like you are trying to access MongoDB over HTTP on the native driver port."\n' +
                         'LAUNCH_CMD="' + settings.launchCommand + '"\n' +

                         // checking if application and database container are linked
                         'until [[ $CURL_OUTPUT == $SUCCESS ]]\n' +
                         // if they are not, waits 20seconds and checks again
                         'do\n' +
                         'echo "Linking database container"\n' +
                         'sleep 20\n' +
                         'CURL_OUTPUT=$(curl dbLink:$DB_PORT)\n' +
                         // otherwise it runns the launch command
                         'done\n' +
                         'echo "Containers linked, running application launch command"\n' +
                         'cd prod\n' +
                         '$LAUNCH_CMD';

  fs.writeFile("./.lifter/app.sh", shellFileContent, function(err) {
    if (err) console.log(err);
    console.log("Launch script created: app.sh");
  });
}

var createLocalContainer = function() {
  var settings = helpers.readYAML();
  //docker build -t username_on_docker_hub/create_new_repo_name .
  var appContainerName = settings.appContainerName;
  var imageName = settings.username + '/' + settings.repoName;

  var dbContainerName = settings.dbContainerName;
  var dbImageName = settings.dbTag;
  var dbLinkName = dbContainerName+'-link';

  var buildCmd = ['docker',
    ['build', '-t', imageName, '.']];
  var dbRunCmd = ['docker',
    ['run', '--restart=always',
     '--name', dbContainerName, dbImageName]];
  var appRunCmd = ['docker',
    ['run', '--restart=always',
     '--name', appContainerName,
     '--link', dbContainerName+':'+dbLinkName
     '-p', settings.portPrivate+':'+settings.portPublic,
     '-v', settings.launchPath+':/src:ro', imageName, 'sh', '/src/app.sh']];

  dockerSpawnSeries([
    buildCmd,
    mongoRunCmd,
    appRunCmd
  ], finishInit);
}

var printInstructions = function() {
  if (exitInstructions.length > 0) {
    console.log("Run these commands:")
    exitInstructions.forEach(function(str) {
      console.log("    " + str);
    });
  }
}

var finishInit = function () {
  aync.series([
    checkHostsFileForDockerhost,
    createShellScript,
    createLocalContainer
  ]);
  console.log('Local docker environment created!');
  printInstructions();
}

module.exports = {
  start_b2d: start_b2d
}
<|endoftext|>


<commit_before>/**
 * Basic Authentication Module for AngularJs
 *
 * Copyright (C) Ian Kelly
 * License: MIT
 */

'use strict';

(function() {

	var angularBasicAuth = angular.module(
		'angularBasicAuth',
		[
			'LocalStorageModule',
			'base64'
		]);

	// Constants
	var MS_PER_MINUTE = 1000 * 60;

	/**
	* Difference between two dates in hours
	*
	* @param {Date} a First date
	* @param {Date} b Second date
	*/
	function dateDiffInMinutes(earlier, later) {
		return (later.getTime() - earlier.getTime()) / MS_PER_MINUTE;
	}

	/**
	 * Constants
	 */
	angularBasicAuth.constant('MODULE_VERSION', '0.0.0');

	/**
	 * Defaults
	 */
	angularBasicAuth.value('authDefaults', {
		authenticateUrl: '/api/authenticate',
		sessionMinutes: 180
	});

	/**
	* HTTP Interceptor to add Authorization headers to all requests if the
	* auth local storage property has been set
	*/
	angularBasicAuth.factory('authInterceptor',
		[
			'$q',
			'authService',
			function ($q, authService) {

				var authInterceptor = {

					/**
					* Request Interceptor
					*
					* Adds an authorization header, if and only if there
					* is one found in the local storage
					*/
					request: function(config) {
						var auth = authService.getAuth();
						if (auth) {
							config.headers.Authorization = auth;
						}
						return config;
					},

					/**
					* Error Interceptor
					*
					* Used to trap an authentication error
					*/
					responseError: function(rejection) {
						// this is a failure to authenticate
						// so inform the authenticaton service
						if (rejection.status === 401) {
							authService.handleAuthFailure();
						}

						return $q.reject(rejection);
					}
				};

				return authInterceptor;
			}
		]);

	/**
	* Service to handle user authentication
	*
	* This is a singleton service, so we will instantiate this once in an iife
	*/
	(function() {
		angularBasicAuth.factory('authService',
			[
				'$log',
				'localStorageService',
				'$base64',
				'$q',
				'$rootScope',
				'$interval',
				'authDefaults',
				function ($log, localStorage, $base64, $q, $rootScope, $interval, authDefaults) {

					$log.debug('authService constructed');

					var LS_USERNAME = 'username';
					var LS_AUTHENTICATION = 'auth';
					var LS_LASTACTIVITY = 'last-activity';

					/**
					* Logout and wipe the local storage
					*/
					function logout() {
						$log.debug('logout event');
						localStorage.remove(LS_AUTHENTICATION);
						localStorage.remove(LS_LASTACTIVITY);
						localStorage.remove(LS_USERNAME);
						$rootScope.$emit('logout');
					}

					/**
					* Set the user credentials
					*
					* @param {String} username Username
					* @param {String} password Unencryped password
					*/
					function setCredentials(username, password) {
						$log.debug('Setting credentials for user: ' + username);

						localStorage.set(LS_USERNAME, username);

						// set the value of the auth-header
						localStorage.set(LS_AUTHENTICATION,
							'Basic ' + $base64.encode(username + ':' + password));

						recordActivity();
					}

					/**
					* Record account activity
					*/
					function recordActivity() {
						localStorage.set(LS_LASTACTIVITY, (new Date()).toString());
					}

					/**
					* Is the login current
					*/
					function isCurrent() {
						// retrieve the last activity of the account
						var lastActivity = localStorage.get(LS_LASTACTIVITY) || '';

						if (lastActivity === '') {
							return false;
						}

						return (dateDiffInMinutes(new Date(lastActivity), new Date()) < authDefaults.sessionMinutes);
					}

					/**
					* Confirm the account is current
					*/
					function confirmCurrent() {
						if (!isCurrent()) {
							$log.debug('Authentication credentials missing or out of date');
							logout();
						}
					}

					/**
					* Returns the current authentication header
					*/
					function getAuth() {
						return localStorage.get(LS_AUTHENTICATION);
					}

					// we should work out whether we are current or not
					confirmCurrent();

					// set an inteval to do this regularly
					$interval(confirmCurrent, 60000);

					return {
						/**
						* Get any current authentication header
						*/
						getAuth: getAuth,

						/**
						* Handles logout
						*/
						logout: logout,

						/**
						* Record activity
						*/
						activity: recordActivity,

						/**
						* The current username
						*
						* @return {String} The current username
						*/
						username: function() {
							confirmCurrent();
							return localStorage.get(LS_USERNAME);
						},

						/**
						* Handle an authentication failure
						*/
						handleAuthFailure: function() {
							logout();
							$rootScope.$emit('authentication-failure');
						},

						/**
						* Handles login to the application
						*
						* @param  {String} username The username
						* @param  {String} password The password
						* @return {Object}          Promise for the transaction
						*/
						login: function(username, password) {
							$log.debug('login event');

							// record the credentials
							setCredentials(username, password);

							var deferred = $q.defer();

							/**
							* Process the response, and if there are any issues
							* the reject the promise
							*/
							function processResponse() {
								/* jshint validthis: true */
								if (this.status !== 200) {
									deferred.reject();
								} else {
									deferred.resolve();
								}
							}

							// don't use $http to avoid circular reference, so
							// directly use XMLHttpRequest and $q
							var promise = deferred.promise;
							var request = new XMLHttpRequest();
							request.onload = processResponse;
							request.open('GET', authDefaults.authenticateUrl);
							request.setRequestHeader('Accept', 'application/json');
							request.setRequestHeader('Authorization', getAuth());
							request.send(null);

							/**
							* Allow subscribers to the promise to add a
							* success function to the login event
							*/
							promise.success = function(fn) {
								promise.then(function() {
									fn();
								});
								return promise;
							};

							/**
							* Allow subscribers to the promise to add
							* an error function to the login event
							*/
							promise.error = function(fn) {
								promise.then(null, function() {
									fn();
								});
								return promise;
							};

							/**
							* Handle the promise being rejected or resolved
							*/
							promise.then(function () {
								// we've confirmed credentials match a user
								$log.debug('Successfully authenticated');
								$rootScope.$emit('login', username);
							}, function () {
								// some error in credential check
								$log.debug('Test authentication failed');
								logout();
								$rootScope.$emit('authentication-failed', username);
							});

							return promise;
						}
					};
				}
			]
		);
	})();

	// add the interceptor to the http service
	angularBasicAuth.config(['$httpProvider', function($httpProvider) {
		$httpProvider.interceptors.push('authInterceptor');
	}]);

})();
<commit_msg>Change how broadcast is done to ensure everything can subscribe to login/logout events<commit_after>/**
 * Basic Authentication Module for AngularJs
 *
 * Copyright (C) Ian Kelly
 * License: MIT
 */

'use strict';

(function() {

	var angularBasicAuth = angular.module(
		'angularBasicAuth',
		[
			'LocalStorageModule',
			'base64'
		]);

	// Constants
	var MS_PER_MINUTE = 1000 * 60;

	/**
	* Difference between two dates in hours
	*
	* @param {Date} a First date
	* @param {Date} b Second date
	*/
	function dateDiffInMinutes(earlier, later) {
		return (later.getTime() - earlier.getTime()) / MS_PER_MINUTE;
	}

	/**
	 * Constants
	 */
	angularBasicAuth.constant('MODULE_VERSION', '0.0.0');

	/**
	 * Defaults
	 */
	angularBasicAuth.value('authDefaults', {
		authenticateUrl: '/api/authenticate',
		sessionMinutes: 180
	});

	/**
	* HTTP Interceptor to add Authorization headers to all requests if the
	* auth local storage property has been set
	*/
	angularBasicAuth.factory('authInterceptor',
		[
			'$q',
			'authService',
			function ($q, authService) {

				var authInterceptor = {

					/**
					* Request Interceptor
					*
					* Adds an authorization header, if and only if there
					* is one found in the local storage
					*/
					request: function(config) {
						var auth = authService.getAuth();
						if (auth) {
							config.headers.Authorization = auth;
						}
						return config;
					},

					/**
					* Error Interceptor
					*
					* Used to trap an authentication error
					*/
					responseError: function(rejection) {
						// this is a failure to authenticate
						// so inform the authenticaton service
						if (rejection.status === 401) {
							authService.handleAuthFailure();
						}

						return $q.reject(rejection);
					}
				};

				return authInterceptor;
			}
		]);

	/**
	* Service to handle user authentication
	*
	* This is a singleton service, so we will instantiate this once in an iife
	*/
	(function() {
		angularBasicAuth.factory('authService',
			[
				'$log',
				'localStorageService',
				'$base64',
				'$q',
				'$rootScope',
				'$interval',
				'authDefaults',
				function ($log, localStorage, $base64, $q, $rootScope, $interval, authDefaults) {

					$log.debug('authService constructed');

					var LS_USERNAME = 'username';
					var LS_AUTHENTICATION = 'auth';
					var LS_LASTACTIVITY = 'last-activity';

					/**
					* Logout and wipe the local storage
					*/
					function logout() {
						$log.debug('logout event');
						localStorage.remove(LS_AUTHENTICATION);
						localStorage.remove(LS_LASTACTIVITY);
						localStorage.remove(LS_USERNAME);
						$rootScope.$emit('logout');
					}

					/**
					* Set the user credentials
					*
					* @param {String} username Username
					* @param {String} password Unencryped password
					*/
					function setCredentials(username, password) {
						$log.debug('Setting credentials for user: ' + username);

						localStorage.set(LS_USERNAME, username);

						// set the value of the auth-header
						localStorage.set(LS_AUTHENTICATION,
							'Basic ' + $base64.encode(username + ':' + password));

						recordActivity();
					}

					/**
					* Record account activity
					*/
					function recordActivity() {
						localStorage.set(LS_LASTACTIVITY, (new Date()).toString());
					}

					/**
					* Is the login current
					*/
					function isCurrent() {
						// retrieve the last activity of the account
						var lastActivity = localStorage.get(LS_LASTACTIVITY) || '';

						if (lastActivity === '') {
							return false;
						}

						return (dateDiffInMinutes(new Date(lastActivity), new Date()) < authDefaults.sessionMinutes);
					}

					/**
					* Confirm the account is current
					*/
					function confirmCurrent() {
						if (!isCurrent()) {
							$log.debug('Authentication credentials missing or out of date');
							logout();
						}
					}

					/**
					* Returns the current authentication header
					*/
					function getAuth() {
						return localStorage.get(LS_AUTHENTICATION);
					}

					// we should work out whether we are current or not
					confirmCurrent();

					// set an inteval to do this regularly
					$interval(confirmCurrent, 60000);

					return {
						/**
						* Get any current authentication header
						*/
						getAuth: getAuth,

						/**
						* Handles logout
						*/
						logout: logout,

						/**
						* Record activity
						*/
						activity: recordActivity,

						/**
						* The current username
						*
						* @return {String} The current username
						*/
						username: function() {
							confirmCurrent();
							return localStorage.get(LS_USERNAME);
						},

						/**
						* Handle an authentication failure
						*/
						handleAuthFailure: function() {
							logout();
							$rootScope.$emit('authentication-failure');
						},

						/**
						* Handles login to the application
						*
						* @param  {String} username The username
						* @param  {String} password The password
						* @return {Object}          Promise for the transaction
						*/
						login: function(username, password) {
							$log.debug('login event');

							// record the credentials
							setCredentials(username, password);

							var deferred = $q.defer();

							/**
							* Process the response, and if there are any issues
							* the reject the promise
							*/
							function processResponse() {
								/* jshint validthis: true */
								if (this.status !== 200) {
									deferred.reject();
								} else {
									deferred.resolve();
								}
							}

							// don't use $http to avoid circular reference, so
							// directly use XMLHttpRequest and $q
							var promise = deferred.promise;
							var request = new XMLHttpRequest();
							request.onload = processResponse;
							request.open('GET', authDefaults.authenticateUrl);
							request.setRequestHeader('Accept', 'application/json');
							request.setRequestHeader('Authorization', getAuth());
							request.send(null);

							/**
							* Allow subscribers to the promise to add a
							* success function to the login event
							*/
							promise.success = function(fn) {
								promise.then(function() {
									fn();
								});
								return promise;
							};

							/**
							* Allow subscribers to the promise to add
							* an error function to the login event
							*/
							promise.error = function(fn) {
								promise.then(null, function() {
									fn();
								});
								return promise;
							};

							/**
							* Handle the promise being rejected or resolved
							*/
							promise.then(function () {
								// we've confirmed credentials match a user
								$log.debug('Successfully authenticated');
								$rootScope.$broadcast('login', username);
							}, function () {
								// some error in credential check
								$log.debug('Test authentication failed');
								logout();
								$rootScope.$broadcast('authentication-failed', username);
							});

							return promise;
						}
					};
				}
			]
		);
	})();

	// add the interceptor to the http service
	angularBasicAuth.config(['$httpProvider', function($httpProvider) {
		$httpProvider.interceptors.push('authInterceptor');
	}]);

})();
<|endoftext|>


<commit_before>  angular.module('ngEqualizer', []).factory('EqualizerState', [
    '$window', function($window) {
      var equalize, items;
      items = {};
      $window = $($window);
      equalize = _.debounce(function() {
        var item, name, _fn;
        _fn = function(item, name) {
          var i, maxHeight, _i, _j, _k, _len, _len1, _len2;
          maxHeight = 0;
          for (_i = 0, _len = item.length; _i < _len; _i++) {
            i = item[_i];
            i.element.css({
              'minHeight': i.minHeight,
              'height': 'auto'
            });
          }
          for (_j = 0, _len1 = item.length; _j < _len1; _j++) {
            i = item[_j];
            console.log('a', i.element.outerHeight());
            maxHeight = Math.max(maxHeight, i.element.outerHeight());
            console.log('b', maxHeight);
          }
          if (maxHeight > 0) {
            for (_k = 0, _len2 = item.length; _k < _len2; _k++) {
              i = item[_k];
              i.element.css('minHeight', maxHeight);
            }
          }
        };
        for (name in items) {
          item = items[name];
          _fn(item, name);
        }
      }, 30);
      $window.on('resize', equalize);
      return {
        get: function(group) {
          return items[group] || [];
        },
        add: function(group, element) {
          if (!angular.isArray(items[group])) {
            items[group] = [];
          }
          items[group].push({
            height: element.css('height') || 'auto',
            minHeight: element.css('minHeight') || 0,
            element: element
          });
          equalize();
          return this;
        },
        remove: function(group, element) {
          var i, key, _ref;
          _ref = items[group];
          for (key in _ref) {
            i = _ref[key];
            if (i.element === element) {
              element.css({
                'minHeight': i.minHeight,
                'height': i.height
              });
              items[group].splice(key, 1);
              break;
            }
          }
          return this;
        },
        equalize: equalize
      };
    }
  ]).directive('equalizer', [
    'EqualizerState', function(EqualizerState) {
      return {
        restrict: 'A',
        link: function(scope, el, attr) {
          var group;
          group = scope.$eval(attr.equalizer);
          EqualizerState.add(group, el);
          el.on('$destroy', function() {
            EqualizerState.remove(group, el);
          });
          scope.$on('$destroy', function() {
            EqualizerState.remove(group, el);
          });
        }
      };
    }
  ]);
<commit_msg>Update angular-equalizer.js<commit_after>  angular.module('ngEqualizer', []).factory('EqualizerState', [
    '$window', function($window) {
      var equalize, items;
      items = {};
      $window = $($window);
      equalize = _.debounce(function() {
        var item, name, _fn;
        _fn = function(item, name) {
          var i, maxHeight, _i, _j, _k, _len, _len1, _len2;
          maxHeight = 0;
          for (_i = 0, _len = item.length; _i < _len; _i++) {
            i = item[_i];
            i.element.css({
              'minHeight': i.minHeight,
              'height': 'auto'
            });
          }
          for (_j = 0, _len1 = item.length; _j < _len1; _j++) {
            i = item[_j];
            maxHeight = Math.max(maxHeight, i.element.outerHeight());
          }
          if (maxHeight > 0) {
            for (_k = 0, _len2 = item.length; _k < _len2; _k++) {
              i = item[_k];
              i.element.css('minHeight', maxHeight);
            }
          }
        };
        for (name in items) {
          item = items[name];
          _fn(item, name);
        }
      }, 30);
      $window.on('resize', equalize);
      return {
        get: function(group) {
          return items[group] || [];
        },
        add: function(group, element) {
          if (!angular.isArray(items[group])) {
            items[group] = [];
          }
          items[group].push({
            height: element.css('height') || 'auto',
            minHeight: element.css('minHeight') || 0,
            element: element
          });
          equalize();
          return this;
        },
        remove: function(group, element) {
          var i, key, _ref;
          _ref = items[group];
          for (key in _ref) {
            i = _ref[key];
            if (i.element === element) {
              element.css({
                'minHeight': i.minHeight,
                'height': i.height
              });
              items[group].splice(key, 1);
              break;
            }
          }
          return this;
        },
        equalize: equalize
      };
    }
  ]).directive('equalizer', [
    'EqualizerState', function(EqualizerState) {
      return {
        restrict: 'A',
        link: function(scope, el, attr) {
          var group;
          group = scope.$eval(attr.equalizer);
          EqualizerState.add(group, el);
          el.on('$destroy', function() {
            EqualizerState.remove(group, el);
          });
          scope.$on('$destroy', function() {
            EqualizerState.remove(group, el);
          });
        }
      };
    }
  ]);
<|endoftext|>


<commit_before>import angular2now from './angular2-now';

describe("angular2-now", () => {
  const ngModuleName = 'test';

  it("should be available defined", () => {
    expect(angular2now).toBeDefined();
  });

  describe("SetModule()", () => {
    it("should create module", () => {
      angular2now.SetModule(ngModuleName, ['ui.router']);
      expect(angular.module(ngModuleName)).toBeDefined();
    });

    it("should have proper name", () => {
      expect(angular.module(ngModuleName).name).toBe(ngModuleName);
    });

    it("should contain ui.router", () => {
      expect(angular.module(ngModuleName).requires).toContain('ui.router');
    });

    it("should keep recently created module as current module", () => {
      expect(angular2now.options().currentModule()).toBe(ngModuleName);
    });

    it("should get module", () => {
      expect(angular2now.SetModule(ngModuleName)).toBe(angular.module(ngModuleName));
    });

    it("should overwrite module when using namespace and the same module name", () => {
      const nsModule = `ns:${ngModuleName}`
      angular2now.SetModule(nsModule, []);

      // module with ns:test as name should not be available
      expect(() => {
        angular.module(nsModule);
      }).toThrowError(/not available/);
      // test should now not contain ui.router
      expect(angular2now.SetModule(ngModuleName).requires).not.toContain('ui.router');
    });

    it("should update current module when new has been created", () => {
      const newModule = `${ngModuleName}New`
      angular2now.SetModule(newModule, []);
      expect(angular2now.options().currentModule()).toBe(newModule);
    });
  });

  describe("@Inject()", () => {
    // TODO add tests of null, undefined and empty array as Inject() argument
    it("should throw error on empty dependencies", () => {
      expect(() => {
        angular2now.Inject();
      }).toThrowError(Error, /dependencies/);
    });

    it("should pass dependencies as an array", () => {
      expect(() => {
        angular2now.Inject(['$http', '$q']);
      }).not.toThrowError(Error, /dependencies/);
    });

    it("should pass dependencies directly", () => {
      expect(() => {
        angular2now.Inject('$http', '$q');
      }).not.toThrowError(Error, /dependencies/);
    });

    it("should fail on missing target", () => {
      expect(() => {
        angular2now.Inject(['$http', '$q'])();
      }).toThrowError(TypeError, /class/);
    });

    describe("with target", () => {
      // Services
      const Injectables = {
        target: ['$log', '$q'],
        inject: ['$http', '$http', '$q', 'customService']
      };
      const concatedRaw = Injectables.inject.concat(Injectables.target);
      const concated = _.uniq(
        _.reject(concatedRaw, (inj) => inj[0] !== '$')
      );
      // target mock
      const TargetMock = {
        $inject: Injectables.target
      };
      // @Inject mock
      const InjectMock = angular2now.Inject(Injectables.inject);

      it("should return target", () => {
        expect(InjectMock(TargetMock)).toBe(TargetMock);
      });

      // TODO fix bug! There are duplicates if target contains injectables and there is the same injectable provided by @Inject()
      it("should concat injectables", () => {
        // check if all injectables have been added
        concated.forEach((inj) => {
          expect(TargetMock.$inject.indexOf(inj)).not.toBe(-1);
        });

      });

      it("should add namespace to injectables", () => {
        const namespaced = _.reject(concatedRaw, (inj) => inj[0] === '$');

        // check with namespace prefix
        namespaced.forEach((inj) => {
          expect(TargetMock.$inject.indexOf(`ns_${inj}`)).not.toBe(-1);
        });
      });

      // TODO wait for pbastowski response
      /*
      it("should prevent duplicates", () => {
        const uniqueConcated = _.uniq(concatedRaw);
        const uniqueTarget = _.uniq(TargetMock.$inject);
        const diff = _.difference(uniqueTarget, uniqueConcated);

        expect(diff.length).toBe(0);
      });*/
    });
  });

  describe("@View()", () => {
    it("should set templateUrl if argument is a string", () => {
      const target = {};
      const templateUrl = 'test.html';

      angular2now.View(templateUrl)(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should overwrite target's templateUrl if argument is a string", () => {
      const templateUrl = 'test.html';
      const target = {
        templateUrl: `old-${templateUrl}`
      };

      angular2now.View(templateUrl)(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should overwrite target's templateUrl if specified in options", () => {
      const templateUrl = 'test.html';
      const target = {
        templateUrl: `old-${templateUrl}`
      };

      angular2now.View({
        templateUrl
      })(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should set template", () => {
      const template = 'foobar';
      const target = {};

      angular2now.View({
        template
      })(target);

      expect(target.template).toBe(template);
    });

    it("should overwrite target's template", () => {
      const template = 'foobar';
      const target = {
        template: `old-${template}`
      };

      angular2now.View({
        template
      })(target);

      expect(target.template).toBe(template);
    });

    it("should set transclude", () => {
      const transclude = true;
      const target = {};

      angular2now.View({
        transclude
      })(target);

      expect(target.transclude).toBe(transclude);
    });

    it("should overwrite transclude", () => {
      const transclude = true;
      const target = {
        transclude: false
      };

      angular2now.View({
        transclude
      })(target);

      expect(target.transclude).toBe(transclude);
    });

    it("should transclude content directive if available", () => {
      const template = `
        <div>
          <content></content>
        </div>
      `;
      const target = {
        template
      };

      angular2now.View()(target);

      expect(target.template).toContain('ng-transclude');
    });

    it("should set directives", () => {
      const directives = ['directive'];
      const target = {};

      angular2now.View({
        directives
      })(target);

      expect(target.directives).toBe(directives);
    });

    it("should overwrite directives", () => {
      const directives = ['directive'];
      const target = {
        directives: _.map(directives, (d) => `old-${d}`)
      };

      angular2now.View({
        directives
      })(target);

      expect(target.directives).toBe(directives);
    });
  });

  describe("@Controller()", () => {
    const name = 'TestCtrl';
    const moduleMock = {
      controller: function() {}
    }
    let spy;
    let spyCtrl;

    function Target() {};

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyCtrl = spyOn(moduleMock, 'controller');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set name if argument is a string", () => {
        angular2now.Controller(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(`ns_${name}`, Target);
      });

      it("should set name if argument is an object with name property", () => {
        angular2now.Controller({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(`ns_${name}`, Target);
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set name if argument is a string", () => {
        angular2now.Controller(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(name, Target);
      });

      it("should set name if argument is an object with name property", () => {
        angular2now.Controller({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(name, Target);
      });
    });

    it("should return target", () => {
      const result = angular2now.Controller({
        name
      })(Target);

      expect(result).toBe(Target);
    });
  });

  describe("@Service()", () => {
    const name = 'TestService';
    const moduleMock = {
      service: function() {}
    }
    let spy;
    let spyService;

    function Target() {};

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyService = spyOn(moduleMock, 'service');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set service if argument is a string", () => {
        angular2now.Service(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(`ns_${name}`, Target);
      });

      it("should set service if argument is an object with name property", () => {
        angular2now.Service({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(`ns_${name}`, Target);
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set service if argument is a string", () => {
        angular2now.Service(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(name, Target);
      });

      it("should set service if argument is an object with name property", () => {
        angular2now.Service({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(name, Target);
      });
    });
  });

  describe("@Filter()", () => {
    const name = 'TestFilter';
    const moduleMock = {
      filter: function() {}
    }
    let spy;
    let spyFilter;
    const foo = 'bar';

    function Target() {
      return arguments;
    };
    Target.$inject = ['$http'];

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyFilter = spyOn(moduleMock, 'filter');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set filter if argument is a string", () => {
        angular2now.Filter(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(`ns_${name}`, jasmine.any(Function));
      });

      it("should set filter if argument is an object with name property", () => {
        angular2now.Filter({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(`ns_${name}`, jasmine.any(Function));
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set filter if argument is a string", () => {
        angular2now.Filter(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(name, jasmine.any(Function));
      });

      it("should set filter if argument is an object with name property", () => {
        angular2now.Filter({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(name, jasmine.any(Function));
      });
    });

    it("should pass target's arguments to filter function", () => {
      angular2now.SetModule(`:${ngModuleName}`);
      angular2now.Filter({
        name
      })(Target);

      // call filter function
      const args = spyFilter.calls.mostRecent().args[1]('foo', 'bar');

      // check arguments
      expect(args[0]).toBe('foo');
      expect(args[1]).toBe('bar');
    });

    it("should copy injectables to filter function", () => {
      angular2now.SetModule(`:${ngModuleName}`);
      angular2now.Filter({
        name
      })(Target);

      // call filter function
      const func = spyFilter.calls.mostRecent().args[1];

      expect(func.$inject).toEqual(Target.$inject);
    });

    it("should return the same target", () => {
      const result = angular2now.Filter({
        name
      })(Target);

      expect(result).toBe(Target);
    });
  });

  describe("@ScopeShared()", () => {
    it("should set scope as undefined", () => {
      const target = {};

      angular2now.ScopeShared(target);

      expect(target.scope).toBeUndefined();
    });

    it("should overwrite scope to undefined", () => {
      const target = {
        scope: true
      };

      angular2now.ScopeShared(target);

      expect(target.scope).toBeUndefined();
    });

    it("should return target", () => {
      const target = {
        scope: true
      };

      const result = angular2now.ScopeShared(target);

      expect(result).toBe(target);
    });
  });

  describe("@ScopeNew()", () => {
    it("should set scope as true", () => {
      const target = {};

      angular2now.ScopeNew(target);

      expect(target.scope).toBe(true);
    });

    it("should overwrite scope to true", () => {
      const target = {
        scope: undefined
      };

      angular2now.ScopeNew(target);

      expect(target.scope).toBe(true);
    });

    it("should return target", () => {
      const target = {};

      const result = angular2now.ScopeShared(target);

      expect(result).toBe(target);
    });
  });

  describe("@Directive", () => {
    it("should be an alias for @Component()", () => {
      expect(angular2now.Directive).toBe(angular2now.Component);
    });
  });

  describe("@Component()", () => {
    const moduleMock = {
      directive: () => {}
    };
    let target;
    let spyModule;
    let spyDirective;
    const nameCamel = 'testComponent';
    const nameClass = '.testComponent';
    const nameDashed = 'test-component';

    function getDDO(opt) {
      const ddo = spyDirective.calls.mostRecent().args[1]();

      return ddo[opt];
    }

    beforeEach(() => {
      target = {};
      spyModule = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyDirective = spyOn(moduleMock, 'directive');
    });

    describe("options.selector", () => {

      it("should set selector if argument is a string", () => {
        angular2now.Component(nameDashed)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should be able to unCamelCase selector", () => {
        angular2now.Component(nameCamel)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should handle class name as selector", () => {
        angular2now.Component(nameClass)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should call angular.directive with proper selector", () => {
        angular2now.Component(nameClass)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective).toHaveBeenCalled();
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });
    });

    describe("options.injectables", () => {
      const injectables = ['$http', '$q'];

      beforeEach(() => {
        target.name = nameCamel;
      });

      it("should set injectables", () => {
        angular2now.Component({
          injectables
        })(target);

        expect(target.$inject).toEqual(injectables);
        expect(target.$injectDefer).toEqual(target.$inject);
      });
    });

    describe("options.services", () => {
      const services = ['$http', '$q'];

      beforeEach(() => {
        target.name = nameCamel;
      });

      it("should set services", () => {
        angular2now.Component({
          services
        })(target);

        expect(target.$inject).toEqual(services);
        expect(target.$injectDefer).toEqual(target.$inject);
      });
    });

    describe("options.template", () => {
      it("should set template", () => {
        const template = 'foo';

        angular2now.Component({
          template
        })(target);

        expect(getDDO('template')).toBe(template);
      });
    });
  });
});
<commit_msg>test(Component): options.templateUrl<commit_after>import angular2now from './angular2-now';

describe("angular2-now", () => {
  const ngModuleName = 'test';

  it("should be available defined", () => {
    expect(angular2now).toBeDefined();
  });

  describe("SetModule()", () => {
    it("should create module", () => {
      angular2now.SetModule(ngModuleName, ['ui.router']);
      expect(angular.module(ngModuleName)).toBeDefined();
    });

    it("should have proper name", () => {
      expect(angular.module(ngModuleName).name).toBe(ngModuleName);
    });

    it("should contain ui.router", () => {
      expect(angular.module(ngModuleName).requires).toContain('ui.router');
    });

    it("should keep recently created module as current module", () => {
      expect(angular2now.options().currentModule()).toBe(ngModuleName);
    });

    it("should get module", () => {
      expect(angular2now.SetModule(ngModuleName)).toBe(angular.module(ngModuleName));
    });

    it("should overwrite module when using namespace and the same module name", () => {
      const nsModule = `ns:${ngModuleName}`
      angular2now.SetModule(nsModule, []);

      // module with ns:test as name should not be available
      expect(() => {
        angular.module(nsModule);
      }).toThrowError(/not available/);
      // test should now not contain ui.router
      expect(angular2now.SetModule(ngModuleName).requires).not.toContain('ui.router');
    });

    it("should update current module when new has been created", () => {
      const newModule = `${ngModuleName}New`
      angular2now.SetModule(newModule, []);
      expect(angular2now.options().currentModule()).toBe(newModule);
    });
  });

  describe("@Inject()", () => {
    // TODO add tests of null, undefined and empty array as Inject() argument
    it("should throw error on empty dependencies", () => {
      expect(() => {
        angular2now.Inject();
      }).toThrowError(Error, /dependencies/);
    });

    it("should pass dependencies as an array", () => {
      expect(() => {
        angular2now.Inject(['$http', '$q']);
      }).not.toThrowError(Error, /dependencies/);
    });

    it("should pass dependencies directly", () => {
      expect(() => {
        angular2now.Inject('$http', '$q');
      }).not.toThrowError(Error, /dependencies/);
    });

    it("should fail on missing target", () => {
      expect(() => {
        angular2now.Inject(['$http', '$q'])();
      }).toThrowError(TypeError, /class/);
    });

    describe("with target", () => {
      // Services
      const Injectables = {
        target: ['$log', '$q'],
        inject: ['$http', '$http', '$q', 'customService']
      };
      const concatedRaw = Injectables.inject.concat(Injectables.target);
      const concated = _.uniq(
        _.reject(concatedRaw, (inj) => inj[0] !== '$')
      );
      // target mock
      const TargetMock = {
        $inject: Injectables.target
      };
      // @Inject mock
      const InjectMock = angular2now.Inject(Injectables.inject);

      it("should return target", () => {
        expect(InjectMock(TargetMock)).toBe(TargetMock);
      });

      // TODO fix bug! There are duplicates if target contains injectables and there is the same injectable provided by @Inject()
      it("should concat injectables", () => {
        // check if all injectables have been added
        concated.forEach((inj) => {
          expect(TargetMock.$inject.indexOf(inj)).not.toBe(-1);
        });

      });

      it("should add namespace to injectables", () => {
        const namespaced = _.reject(concatedRaw, (inj) => inj[0] === '$');

        // check with namespace prefix
        namespaced.forEach((inj) => {
          expect(TargetMock.$inject.indexOf(`ns_${inj}`)).not.toBe(-1);
        });
      });

      // TODO wait for pbastowski response
      /*
      it("should prevent duplicates", () => {
        const uniqueConcated = _.uniq(concatedRaw);
        const uniqueTarget = _.uniq(TargetMock.$inject);
        const diff = _.difference(uniqueTarget, uniqueConcated);

        expect(diff.length).toBe(0);
      });*/
    });
  });

  describe("@View()", () => {
    it("should set templateUrl if argument is a string", () => {
      const target = {};
      const templateUrl = 'test.html';

      angular2now.View(templateUrl)(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should overwrite target's templateUrl if argument is a string", () => {
      const templateUrl = 'test.html';
      const target = {
        templateUrl: `old-${templateUrl}`
      };

      angular2now.View(templateUrl)(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should overwrite target's templateUrl if specified in options", () => {
      const templateUrl = 'test.html';
      const target = {
        templateUrl: `old-${templateUrl}`
      };

      angular2now.View({
        templateUrl
      })(target);

      expect(target.templateUrl).toBe(templateUrl);
    });

    it("should set template", () => {
      const template = 'foobar';
      const target = {};

      angular2now.View({
        template
      })(target);

      expect(target.template).toBe(template);
    });

    it("should overwrite target's template", () => {
      const template = 'foobar';
      const target = {
        template: `old-${template}`
      };

      angular2now.View({
        template
      })(target);

      expect(target.template).toBe(template);
    });

    it("should set transclude", () => {
      const transclude = true;
      const target = {};

      angular2now.View({
        transclude
      })(target);

      expect(target.transclude).toBe(transclude);
    });

    it("should overwrite transclude", () => {
      const transclude = true;
      const target = {
        transclude: false
      };

      angular2now.View({
        transclude
      })(target);

      expect(target.transclude).toBe(transclude);
    });

    it("should transclude content directive if available", () => {
      const template = `
        <div>
          <content></content>
        </div>
      `;
      const target = {
        template
      };

      angular2now.View()(target);

      expect(target.template).toContain('ng-transclude');
    });

    it("should set directives", () => {
      const directives = ['directive'];
      const target = {};

      angular2now.View({
        directives
      })(target);

      expect(target.directives).toBe(directives);
    });

    it("should overwrite directives", () => {
      const directives = ['directive'];
      const target = {
        directives: _.map(directives, (d) => `old-${d}`)
      };

      angular2now.View({
        directives
      })(target);

      expect(target.directives).toBe(directives);
    });
  });

  describe("@Controller()", () => {
    const name = 'TestCtrl';
    const moduleMock = {
      controller: function() {}
    }
    let spy;
    let spyCtrl;

    function Target() {};

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyCtrl = spyOn(moduleMock, 'controller');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set name if argument is a string", () => {
        angular2now.Controller(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(`ns_${name}`, Target);
      });

      it("should set name if argument is an object with name property", () => {
        angular2now.Controller({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(`ns_${name}`, Target);
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set name if argument is a string", () => {
        angular2now.Controller(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(name, Target);
      });

      it("should set name if argument is an object with name property", () => {
        angular2now.Controller({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyCtrl).toHaveBeenCalledWith(name, Target);
      });
    });

    it("should return target", () => {
      const result = angular2now.Controller({
        name
      })(Target);

      expect(result).toBe(Target);
    });
  });

  describe("@Service()", () => {
    const name = 'TestService';
    const moduleMock = {
      service: function() {}
    }
    let spy;
    let spyService;

    function Target() {};

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyService = spyOn(moduleMock, 'service');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set service if argument is a string", () => {
        angular2now.Service(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(`ns_${name}`, Target);
      });

      it("should set service if argument is an object with name property", () => {
        angular2now.Service({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(`ns_${name}`, Target);
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set service if argument is a string", () => {
        angular2now.Service(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(name, Target);
      });

      it("should set service if argument is an object with name property", () => {
        angular2now.Service({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyService).toHaveBeenCalledWith(name, Target);
      });
    });
  });

  describe("@Filter()", () => {
    const name = 'TestFilter';
    const moduleMock = {
      filter: function() {}
    }
    let spy;
    let spyFilter;
    const foo = 'bar';

    function Target() {
      return arguments;
    };
    Target.$inject = ['$http'];

    beforeEach(() => {
      // set spies
      spy = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyFilter = spyOn(moduleMock, 'filter');
    });

    describe("with namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`ns:${ngModuleName}`);
      });

      it("should set filter if argument is a string", () => {
        angular2now.Filter(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(`ns_${name}`, jasmine.any(Function));
      });

      it("should set filter if argument is an object with name property", () => {
        angular2now.Filter({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(`ns_${name}`, jasmine.any(Function));
      });
    });

    describe("without namespace", () => {
      beforeEach(() => {
        // set ngModuleName as currentModule
        angular2now.SetModule(`:${ngModuleName}`);
      });

      it("should set filter if argument is a string", () => {
        angular2now.Filter(name)(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(name, jasmine.any(Function));
      });

      it("should set filter if argument is an object with name property", () => {
        angular2now.Filter({
          name
        })(Target);

        expect(spy).toHaveBeenCalledWith(ngModuleName);
        expect(spyFilter).toHaveBeenCalledWith(name, jasmine.any(Function));
      });
    });

    it("should pass target's arguments to filter function", () => {
      angular2now.SetModule(`:${ngModuleName}`);
      angular2now.Filter({
        name
      })(Target);

      // call filter function
      const args = spyFilter.calls.mostRecent().args[1]('foo', 'bar');

      // check arguments
      expect(args[0]).toBe('foo');
      expect(args[1]).toBe('bar');
    });

    it("should copy injectables to filter function", () => {
      angular2now.SetModule(`:${ngModuleName}`);
      angular2now.Filter({
        name
      })(Target);

      // call filter function
      const func = spyFilter.calls.mostRecent().args[1];

      expect(func.$inject).toEqual(Target.$inject);
    });

    it("should return the same target", () => {
      const result = angular2now.Filter({
        name
      })(Target);

      expect(result).toBe(Target);
    });
  });

  describe("@ScopeShared()", () => {
    it("should set scope as undefined", () => {
      const target = {};

      angular2now.ScopeShared(target);

      expect(target.scope).toBeUndefined();
    });

    it("should overwrite scope to undefined", () => {
      const target = {
        scope: true
      };

      angular2now.ScopeShared(target);

      expect(target.scope).toBeUndefined();
    });

    it("should return target", () => {
      const target = {
        scope: true
      };

      const result = angular2now.ScopeShared(target);

      expect(result).toBe(target);
    });
  });

  describe("@ScopeNew()", () => {
    it("should set scope as true", () => {
      const target = {};

      angular2now.ScopeNew(target);

      expect(target.scope).toBe(true);
    });

    it("should overwrite scope to true", () => {
      const target = {
        scope: undefined
      };

      angular2now.ScopeNew(target);

      expect(target.scope).toBe(true);
    });

    it("should return target", () => {
      const target = {};

      const result = angular2now.ScopeShared(target);

      expect(result).toBe(target);
    });
  });

  describe("@Directive", () => {
    it("should be an alias for @Component()", () => {
      expect(angular2now.Directive).toBe(angular2now.Component);
    });
  });

  describe("@Component()", () => {
    const moduleMock = {
      directive: () => {}
    };
    let target;
    let spyModule;
    let spyDirective;
    const nameCamel = 'testComponent';
    const nameClass = '.testComponent';
    const nameDashed = 'test-component';

    function getDDO(opt) {
      const ddo = spyDirective.calls.mostRecent().args[1]();

      return ddo[opt];
    }

    beforeEach(() => {
      target = {};
      spyModule = spyOn(angular, 'module').and.returnValue(moduleMock);
      spyDirective = spyOn(moduleMock, 'directive');
    });

    describe("options.selector", () => {

      it("should set selector if argument is a string", () => {
        angular2now.Component(nameDashed)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should be able to unCamelCase selector", () => {
        angular2now.Component(nameCamel)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should handle class name as selector", () => {
        angular2now.Component(nameClass)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });

      it("should call angular.directive with proper selector", () => {
        angular2now.Component(nameClass)(target);
        expect(target.selector).toBe(nameDashed);
        expect(spyDirective).toHaveBeenCalled();
        expect(spyDirective.calls.mostRecent().args[0]).toBe(nameCamel);
      });
    });

    describe("options.injectables", () => {
      const injectables = ['$http', '$q'];

      beforeEach(() => {
        target.name = nameCamel;
      });

      it("should set injectables", () => {
        angular2now.Component({
          injectables
        })(target);

        expect(target.$inject).toEqual(injectables);
        expect(target.$injectDefer).toEqual(target.$inject);
      });
    });

    describe("options.services", () => {
      const services = ['$http', '$q'];

      beforeEach(() => {
        target.name = nameCamel;
      });

      it("should set services", () => {
        angular2now.Component({
          services
        })(target);

        expect(target.$inject).toEqual(services);
        expect(target.$injectDefer).toEqual(target.$inject);
      });
    });

    describe("options.template", () => {
      it("should set template", () => {
        const template = 'foo';

        angular2now.Component({
          template
        })(target);

        expect(getDDO('template')).toBe(template);
      });
    });

    describe("options.templateUrl", () => {
      it("should set templateUrl", () => {
        const templateUrl = 'foo.html';

        angular2now.Component({
          templateUrl
        })(target);

        expect(getDDO('templateUrl')).toBe(templateUrl);
      });
    });
  });
});
<|endoftext|>


<commit_before>/* eslint-env browser */
'use strict';

let Player = require('../model/Player');

module.exports = {
  init() {

  },

  preload() {

  },

  create() {
    // Add map
    let map = this.game.add.tilemap('map', 16, 16);
    map.addTilesetImage('tiles');
    //  This isn't totally accurate, but it'll do for now
    map.setCollisionBetween(54, 83);
    // Create layer
    this.layer = map.createLayer(0);
    this.layer.resizeWorld();
    // Add character
    this.player = new Player(this, 0, 0);

    // Follow character
    this.camera.follow(this.player);
    // Create cursor keys
    this.cursors = this.game.input.keyboard.createCursorKeys();

    this.setupObstacles();
  },

  update() {
    this.player.resetVelocity();
    this.game.physics.arcade.collide(this.player, this.layer);
    this.game.physics.arcade.collide(this.player, this.obstacleGroup);

    this.player.body.velocity.set(0);

    if (this.cursors.left.isDown) {
      this.player.walkLeft();
    } else if (this.cursors.right.isDown) {
      this.player.walkRight();
    } else if (this.cursors.up.isDown) {
      this.player.walkUp();
    } else if (this.cursors.down.isDown) {
      this.player.walkDown();
    } else {
      this.player.stop();
    }
  },

  render() {

  },

  setupObstacles() {
    this.obstacleGroup = this.add.group();

    this.input.onUp.add(this.handleMouseUp, this);
  },

  handleMouseUp(pointer) {
    this.addObstacle(pointer.clientX, pointer.clientY);
  },

  addObstacle(x, y) {
    const obstacle = this.makePhysicsSprite(x, y, 'obstacle');

    this.obstacleGroup.add(obstacle);

    obstacle.anchor.set(0.5);

    obstacle.body.moves = false;
  },

  makePhysicsSprite(x, y, asset) {
    const sprite = this.make.sprite(x, y, asset);

    this.physics.enable(sprite, Phaser.Physics.ARCADE);

    return sprite;
  },
};
<commit_msg>Remove velocity setter<commit_after>/* eslint-env browser */
'use strict';

let Player = require('../model/Player');

module.exports = {
  init() {

  },

  preload() {

  },

  create() {
    // Add map
    let map = this.game.add.tilemap('map', 16, 16);
    map.addTilesetImage('tiles');
    //  This isn't totally accurate, but it'll do for now
    map.setCollisionBetween(54, 83);
    // Create layer
    this.layer = map.createLayer(0);
    this.layer.resizeWorld();
    // Add character
    this.player = new Player(this, 0, 0);

    // Follow character
    this.camera.follow(this.player);
    // Create cursor keys
    this.cursors = this.game.input.keyboard.createCursorKeys();

    this.setupObstacles();
  },

  update() {
    this.player.resetVelocity();

    this.game.physics.arcade.collide(this.player, this.layer);
    this.game.physics.arcade.collide(this.player, this.obstacleGroup);

    if (this.cursors.left.isDown) {
      this.player.walkLeft();
    } else if (this.cursors.right.isDown) {
      this.player.walkRight();
    } else if (this.cursors.up.isDown) {
      this.player.walkUp();
    } else if (this.cursors.down.isDown) {
      this.player.walkDown();
    } else {
      this.player.stop();
    }
  },

  render() {

  },

  setupObstacles() {
    this.obstacleGroup = this.add.group();

    this.input.onUp.add(this.handleMouseUp, this);
  },

  handleMouseUp(pointer) {
    this.addObstacle(pointer.clientX, pointer.clientY);
  },

  addObstacle(x, y) {
    const obstacle = this.makePhysicsSprite(x, y, 'obstacle');

    this.obstacleGroup.add(obstacle);

    obstacle.anchor.set(0.5);

    obstacle.body.moves = false;
  },

  makePhysicsSprite(x, y, asset) {
    const sprite = this.make.sprite(x, y, asset);

    this.physics.enable(sprite, Phaser.Physics.ARCADE);

    return sprite;
  },
};
<|endoftext|>


<commit_before><commit_msg>Update load files to make jspec test work<commit_after><|endoftext|>