<commit_before>describe("Game is created", function() {

    beforeEach(function() {
	  this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});
    });

    it("sets x", function(){
	expect(50).toEqual(this.gameFactory.x);
    });

    it("sets y", function(){
	expect(80).toEqual(this.gameFactory.y);
    });

    it("sets box lengths", function(){
	expect({biggest_side: 400, middle_side: 270, smallest_side:140}).toEqual(this.gameFactory.box_lengths);
    });

    it("sets side length", function(){
	expect(400).toEqual(this.gameFactory.sideLength);
    });

    it("starts in phase one at game start", function(){
	expect(true).toEqual(this.gameFactory.in_phase_1());
    });

    it("does not start in phase 2 at game start", function(){
	expect(false).toEqual(this.gameFactory.in_phase_2());
    });

    it("does not start in phase 3 at game start", function(){
	expect(false).toEqual(this.gameFactory.in_phase_3());
    });

    it("creates 18 game pieces", function(){
	expect(18).toEqual(this.gameFactory.gamePieceArray.length);
    });

    it("creates 24 game spaces", function(){
	expect(24).toEqual(this.gameFactory.gameSpaceArray.length);
    });

    it("creates a stage", function() {

       //this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

       var ExpectedStage = new Kinetic.Stage({
        container: 'container',
        width: 500,
        height: 600
    });

        var ActualStage = this.gameFactory.stageContainer;
        expect(ActualStage.attrs).toEqual(ExpectedStage.attrs);
    });

    it("creates a game board", function() {

	//var gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

        var Expected_game_board = new Kinetic.Group({
            x: 50,
            y: 80
        });
        var Actual_game_board = this.gameFactory.game_board;
        //Kinetic objects are a bit complex, if you just grab attrs, it contains the attributes we actually set, such as x and y here
        expect(Actual_game_board.attrs).toEqual(Expected_game_board.attrs);
    });

    it("sets only one piece to movable", function(){

	var countDraggable = 0;

	for(var i = 0; i < this.gameFactory.gamePieceArray.length; i++){
	    if(this.gameFactory.gamePieceArray[i].circle.draggable()){
	       countDraggable++;
	    }
	}

	expect(1).toEqual(countDraggable);
    });

    it("sets the first white piece to movable", function(){
	expect(true).toEqual(this.gameFactory.gamePieceArray[17].circle.draggable());
    });

    it("creates 3 boxes and draws them on the game board", function() {
        expect(true).toEqual(true);
    });

    it("adds game board to game board layer", function() {
        expect(true).toEqual(true);
    });

    it("creates 9 red and 9 white game pieces and adds to game board layer", function() {
        expect(true).toEqual(true);
    });

    it("adds game board layer to the stage", function() {
        expect(true).toEqual(true);
    });
});

describe("Game piece is created", function() {

    beforeEach(function() {

	this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

	this.gamePiece = new GamePiece(      450,
					      30,
					      'red',
					      false,
					      this.gameFactory.gameBoardLayer,
					      this.gameFactory.gameSpaceArray,
					      0, this.gameFactory
				      );
    });

    it("creates a circle", function(){
	var Expected_circle = new Kinetic.Circle({
				      x: 450,
                                      y: 30,
                                      radius: 20,
                                      fill: 'red',
                                      stroke: 'black',
                                      strokeWidth: 2,
                                      draggable: false});

	expect(this.gamePiece.circle.attrs).toEqual(Expected_circle.attrs);
    });

    it("test the setDraggable function", function() {

	this.gamePiece.setDraggable(true);

        expect(true).toEqual(this.gamePiece.circle.draggable());
    });

    it("test the set_next function", function() {

	this.gamePiece.set_next(true);

        expect(true).toEqual(this.gamePiece.circle.next);
    });

    it("test the setInMill function", function() {

	this.gamePiece.setInMill();

        expect(false).toEqual(this.gamePiece.removable);
    });

    it("test the setSpace function", function() {

	this.gamePiece.setSpace(5);

        expect(5).toEqual(this.gamePiece.space);
    });

    it("test the moved function", function() {

        expect(0).toEqual(this.gamePiece.moved());
    });

    it("test the on_board function", function() {

        expect(false).toEqual(this.gamePiece.on_board());
    });

});

describe("Transitions from 1 to 2", function() {

    beforeEach(function() {

	this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

	for (var i = 0; i < this.gameFactory.gamePieceArray.length; i++){

	  for(var j = 0; j < this.gameFactory.gameSpaceArray.length; j++){

	      if(!this.gameFactory.gameSpaceArray[j].occupied){
		  this.gameFactory.gamePieceArray[i].circle.x(this.gameFactory.gameSpaceArray[j].circle.getAbsolutePosition().x);
		  this.gameFactory.gamePieceArray[i].circle.y(this.gameFactory.gameSpaceArray[j].circle.getAbsolutePosition().y);
		  this.gameFactory.gamePieceArray[i].circle.draggable(true);
		  this.gameFactory.gameSpaceArray[j].occupied = true;
		  this.gameFactory.gamePieceArray[i].circle.on_board = true;
		  this.gameFactory.gameBoardLayer.draw();
		  break;
	      }

	  }

	}

    });

    it("test not in phase 1", function() {

         expect(false).toEqual(this.gameFactory.in_phase_1());
    });

    it("test in phase 2", function() {

        expect(true).toEqual(this.gameFactory.in_phase_2());
    });

    it("test not in phase 3", function() {

         expect(false).toEqual(this.gameFactory.in_phase_3());
    });

});
<commit_msg>Added decremantar tests from other spec<commit_after>describe("Game is created", function() {

    beforeEach(function() {
	  this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});
    });

    it("sets x", function(){
	expect(50).toEqual(this.gameFactory.x);
    });

    it("sets y", function(){
	expect(80).toEqual(this.gameFactory.y);
    });

    it("sets box lengths", function(){
	expect({biggest_side: 400, middle_side: 270, smallest_side:140}).toEqual(this.gameFactory.box_lengths);
    });

    it("sets side length", function(){
	expect(400).toEqual(this.gameFactory.sideLength);
    });

    it("starts in phase one at game start", function(){
	expect(true).toEqual(this.gameFactory.in_phase_1());
    });

    it("does not start in phase 2 at game start", function(){
	expect(false).toEqual(this.gameFactory.in_phase_2());
    });

    it("does not start in phase 3 at game start", function(){
	expect(false).toEqual(this.gameFactory.in_phase_3());
    });

    it("creates 18 game pieces", function(){
	expect(18).toEqual(this.gameFactory.gamePieceArray.length);
    });

    it("creates 24 game spaces", function(){
	expect(24).toEqual(this.gameFactory.gameSpaceArray.length);
    });

    it("creates a stage", function() {

       //this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

       var ExpectedStage = new Kinetic.Stage({
        container: 'container',
        width: 500,
        height: 600
    });

        var ActualStage = this.gameFactory.stageContainer;
        expect(ActualStage.attrs).toEqual(ExpectedStage.attrs);
    });

    it("creates a game board", function() {

	//var gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

        var Expected_game_board = new Kinetic.Group({
            x: 50,
            y: 80
        });
        var Actual_game_board = this.gameFactory.game_board;
        //Kinetic objects are a bit complex, if you just grab attrs, it contains the attributes we actually set, such as x and y here
        expect(Actual_game_board.attrs).toEqual(Expected_game_board.attrs);
    });

    it("sets only one piece to movable", function(){

	var countDraggable = 0;

	for(var i = 0; i < this.gameFactory.gamePieceArray.length; i++){
	    if(this.gameFactory.gamePieceArray[i].circle.draggable()){
	       countDraggable++;
	    }
	}

	expect(1).toEqual(countDraggable);
    });

    it("sets the first white piece to movable", function(){
	expect(true).toEqual(this.gameFactory.gamePieceArray[17].circle.draggable());
    });

    it("creates 3 boxes and draws them on the game board", function() {
        expect(true).toEqual(true);
    });

    it("adds game board to game board layer", function() {
        expect(true).toEqual(true);
    });

    it("creates 9 red and 9 white game pieces and adds to game board layer", function() {
        expect(true).toEqual(true);
    });

    it("adds game board layer to the stage", function() {
        expect(true).toEqual(true);
    });
});

describe("Game piece is created", function() {

    beforeEach(function() {

	this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

	this.gamePiece = new GamePiece(      450,
					      30,
					      'red',
					      false,
					      this.gameFactory.gameBoardLayer,
					      this.gameFactory.gameSpaceArray,
					      0, this.gameFactory
				      );
    });

    it("creates a circle", function(){
	var Expected_circle = new Kinetic.Circle({
				      x: 450,
                                      y: 30,
                                      radius: 20,
                                      fill: 'red',
                                      stroke: 'black',
                                      strokeWidth: 2,
                                      draggable: false});

	expect(this.gamePiece.circle.attrs).toEqual(Expected_circle.attrs);
    });

    it("test the setDraggable function", function() {

	this.gamePiece.setDraggable(true);

        expect(true).toEqual(this.gamePiece.circle.draggable());
    });

    it("test the set_next function", function() {

	this.gamePiece.set_next(true);

        expect(true).toEqual(this.gamePiece.circle.next);
    });

    it("test the setInMill function", function() {

	this.gamePiece.setInMill();

        expect(false).toEqual(this.gamePiece.removable);
    });

    it("test the setSpace function", function() {

	this.gamePiece.setSpace(5);

        expect(5).toEqual(this.gamePiece.space);
    });

    it("test the moved function", function() {

        expect(0).toEqual(this.gamePiece.moved());
    });

    it("test the on_board function", function() {

        expect(false).toEqual(this.gamePiece.on_board());
    });

});

describe("Transitions from 1 to 2", function() {

    beforeEach(function() {

	this.gameFactory = new GameBoard(50, 80, {biggest_side: 400, middle_side: 270, smallest_side:140});

	for (var i = 0; i < this.gameFactory.gamePieceArray.length; i++){

	  for(var j = 0; j < this.gameFactory.gameSpaceArray.length; j++){

	      if(!this.gameFactory.gameSpaceArray[j].occupied){
		  this.gameFactory.gamePieceArray[i].circle.x(this.gameFactory.gameSpaceArray[j].circle.getAbsolutePosition().x);
		  this.gameFactory.gamePieceArray[i].circle.y(this.gameFactory.gameSpaceArray[j].circle.getAbsolutePosition().y);
		  this.gameFactory.gamePieceArray[i].circle.draggable(true);
		  this.gameFactory.gameSpaceArray[j].occupied = true;
		  this.gameFactory.gamePieceArray[i].circle.on_board = true;
		  this.gameFactory.gameBoardLayer.draw();
		  break;
	      }

	  }

	}

    });

    it("test not in phase 1", function() {

         expect(false).toEqual(this.gameFactory.in_phase_1());
    });

    it("test in phase 2", function() {

        expect(true).toEqual(this.gameFactory.in_phase_2());
    });

    it("test not in phase 3", function() {

         expect(false).toEqual(this.gameFactory.in_phase_3());
    });

});

describe("Decremantar", function() {
    it("Keeps track of how many pieces are on the board", function() {
        decremantar = new Decremantar();
        decremantar.decrement("white");
        decremantar.decrement("red");
        decremantar.decrement("white");
        decremantar.decrement("red");
        expect(decremantar.red).toEqual(7);
        expect(decremantar.white).toEqual(7);
    });

    it("returns true if the number of pieces for a player is less than three.", function() {
        decremantar = new Decremantar();
        for(i = 0; i < 6; i++) {
            decremantar.decrement("white");
            decremantar.decrement("red");
        }
        expect(decremantar.hasThreeOrLess("red")).toEqual(true);
        expect(decremantar.hasThreeOrLess("white")).toEqual(true);
    });
});
<|endoftext|>


<commit_before>import _ from 'lodash';

import * as awsApis from './aws-api';
import { awsActionTypes, configActions } from './actions';
import {
  AWS_ACCESS_KEY_ID,
  AWS_CONTROLLER_SUBNET_IDS,
  AWS_CONTROLLER_SUBNETS,
  AWS_REGION,
  AWS_SECRET_ACCESS_KEY,
  AWS_SESSION_TOKEN,
  AWS_WORKER_SUBNET_IDS,
  AWS_WORKER_SUBNETS,
  PLATFORM_TYPE,
  STS_ENABLED,
} from './cluster-config';
import { BARE_METAL_TF } from './platforms';
import { TectonicGA } from './tectonic-ga';

const { batchSetIn } = configActions;

const createAction = (name, fn, shouldReject = false) => (body, creds, isNow) => (dispatch, getState) => {
  const { clusterConfig } = getState();

  creds = Object.assign({
    AccessKeyID: clusterConfig[AWS_ACCESS_KEY_ID],
    SecretAccessKey: clusterConfig[AWS_SECRET_ACCESS_KEY],
    SessionToken: clusterConfig[STS_ENABLED] && clusterConfig[AWS_SESSION_TOKEN] || '',
    Region: clusterConfig[AWS_REGION],
  }, creds);

  const obj = {
    inFly: true,
  };

  // Don't unset values and errors if we can track causality
  if (!isNow) {
    obj.value = [];
    obj.error = null;
  }

  dispatch({
    type: awsActionTypes.SET,
    payload: {[name]: obj},
  });

  let platform;
  if (clusterConfig[PLATFORM_TYPE] === BARE_METAL_TF) {
    platform = 'metal';
  }
  return fn(body, creds, platform)
    .then(value => {
      if (isNow && !isNow()) {
        return;
      }
      dispatch({
        type: awsActionTypes.SET,
        payload: {
          [name]: {
            inFly: false,
            value: value,
            error: null,
          },
        },
      });
      return value;
    })
    .catch(error => {
      if (isNow && !isNow()) {
        console.log(`not now. returning ${error}`);
        return;
      }

      console.error(error.stack || error);

      dispatch({
        type: awsActionTypes.SET,
        payload: {
          [name]: {
            inFly: false,
            value: [],
            error: error,
          },
        },
      });
      if (!shouldReject) {
        return error;
      }

      let message = error.message || error;
      if (message === 'Failed to fetch') {
        message += ` ${name}`;
      }
      TectonicGA.sendEvent('Async Error', 'user input', message, 'aws-tf');
      return Promise.reject(message);
    });
};

export const getVpcs = createAction('availableVpcs', awsApis.getVpcs);
export const getVpcSubnets = createAction('availableVpcSubnets', awsApis.getVpcSubnets);
export const getSsh = createAction('availableSsh', awsApis.getSsh, true);
export const getIamRoles = createAction('availableIamRoles', awsApis.getIamRoles);
export const getRegions = createAction('availableRegions', awsApis.getRegions, true);
export const getZones = createAction('availableR53Zones', awsApis.getZones, true);
export const getDomainInfo = createAction('domainInfo', awsApis.getDomainInfo);
export const validateSubnets = createAction('validateSubnets', awsApis.validateSubnets);
export const TFDestroy = createAction('destroy', awsApis.TFDestroy, true);

const getDefaultSubnets_ = createAction('subnets', awsApis.getDefaultSubnets);

export const getDefaultSubnets = (body, creds, isNow) => (dispatch, getState) =>
  getDefaultSubnets_({vpcCIDR: '10.0.0.0/16'}, creds)(dispatch, getState)
    .then(subnets => {
      if (isNow && !isNow()) {
        return;
      }
      const batches = [];
      _.each(subnets.public, ({availabilityZone, instanceCIDR, id}) => {
        batches.push([`${AWS_CONTROLLER_SUBNETS}.${availabilityZone}`, instanceCIDR]);
        // TODO: (ggreer) stop resetting this? (ditto for worker subnet ids)
        batches.push([`${AWS_CONTROLLER_SUBNET_IDS}.${availabilityZone}`, id]);
      });
      _.each(subnets.private, ({availabilityZone, instanceCIDR, id}) => {
        batches.push([`${AWS_WORKER_SUBNETS}.${availabilityZone}`, instanceCIDR]);
        batches.push([`${AWS_WORKER_SUBNET_IDS}.${availabilityZone}`, id]);
      });
      batchSetIn(dispatch, batches);
    });
<commit_msg>frontend: Don't reset AWS VPC subnet IDs<commit_after>import _ from 'lodash';

import * as awsApis from './aws-api';
import { awsActionTypes, configActions } from './actions';
import {
  AWS_ACCESS_KEY_ID,
  AWS_CONTROLLER_SUBNET_IDS,
  AWS_CONTROLLER_SUBNETS,
  AWS_REGION,
  AWS_SECRET_ACCESS_KEY,
  AWS_SESSION_TOKEN,
  AWS_WORKER_SUBNET_IDS,
  AWS_WORKER_SUBNETS,
  PLATFORM_TYPE,
  STS_ENABLED,
} from './cluster-config';
import { BARE_METAL_TF } from './platforms';
import { TectonicGA } from './tectonic-ga';

const { batchSetIn } = configActions;

const createAction = (name, fn, shouldReject = false) => (body, creds, isNow) => (dispatch, getState) => {
  const { clusterConfig } = getState();

  creds = Object.assign({
    AccessKeyID: clusterConfig[AWS_ACCESS_KEY_ID],
    SecretAccessKey: clusterConfig[AWS_SECRET_ACCESS_KEY],
    SessionToken: clusterConfig[STS_ENABLED] && clusterConfig[AWS_SESSION_TOKEN] || '',
    Region: clusterConfig[AWS_REGION],
  }, creds);

  const obj = {
    inFly: true,
  };

  // Don't unset values and errors if we can track causality
  if (!isNow) {
    obj.value = [];
    obj.error = null;
  }

  dispatch({
    type: awsActionTypes.SET,
    payload: {[name]: obj},
  });

  let platform;
  if (clusterConfig[PLATFORM_TYPE] === BARE_METAL_TF) {
    platform = 'metal';
  }
  return fn(body, creds, platform)
    .then(value => {
      if (isNow && !isNow()) {
        return;
      }
      dispatch({
        type: awsActionTypes.SET,
        payload: {
          [name]: {
            inFly: false,
            value: value,
            error: null,
          },
        },
      });
      return value;
    })
    .catch(error => {
      if (isNow && !isNow()) {
        console.log(`not now. returning ${error}`);
        return;
      }

      console.error(error.stack || error);

      dispatch({
        type: awsActionTypes.SET,
        payload: {
          [name]: {
            inFly: false,
            value: [],
            error: error,
          },
        },
      });
      if (!shouldReject) {
        return error;
      }

      let message = error.message || error;
      if (message === 'Failed to fetch') {
        message += ` ${name}`;
      }
      TectonicGA.sendEvent('Async Error', 'user input', message, 'aws-tf');
      return Promise.reject(message);
    });
};

export const getVpcs = createAction('availableVpcs', awsApis.getVpcs);
export const getVpcSubnets = createAction('availableVpcSubnets', awsApis.getVpcSubnets);
export const getSsh = createAction('availableSsh', awsApis.getSsh, true);
export const getIamRoles = createAction('availableIamRoles', awsApis.getIamRoles);
export const getRegions = createAction('availableRegions', awsApis.getRegions, true);
export const getZones = createAction('availableR53Zones', awsApis.getZones, true);
export const getDomainInfo = createAction('domainInfo', awsApis.getDomainInfo);
export const validateSubnets = createAction('validateSubnets', awsApis.validateSubnets);
export const TFDestroy = createAction('destroy', awsApis.TFDestroy, true);

const getDefaultSubnets_ = createAction('subnets', awsApis.getDefaultSubnets);

export const getDefaultSubnets = (body, creds, isNow) => (dispatch, getState) =>
  getDefaultSubnets_({vpcCIDR: '10.0.0.0/16'}, creds)(dispatch, getState)
    .then(subnets => {
      if (isNow && !isNow()) {
        return;
      }
      const batches = [];
      _.each(subnets.public, ({availabilityZone, instanceCIDR}) => {
        batches.push([`${AWS_CONTROLLER_SUBNETS}.${availabilityZone}`, instanceCIDR]);
      });
      _.each(subnets.private, ({availabilityZone, instanceCIDR}) => {
        batches.push([`${AWS_WORKER_SUBNETS}.${availabilityZone}`, instanceCIDR]);
      });
      batchSetIn(dispatch, batches);
    });
<|endoftext|>


<commit_before>describe("ember-oauth2", function() {

  window.App = Ember.Application.create({
    NAME: 'test-app'
  });

  var authorizeUri;
  var callbackUri;
  beforeEach(function() {
    var authBaseUri = 'https://foobar.dev/oauth/authorize';
    var redirectUri = 'https://qux.dev/oauth/callback';
    var clientId = '12345';
    var scope = 'public';
    var state = '6789';
    Ember.OAuth2.config = {
      test_auth: {
        clientId: clientId,
        authBaseUri: authBaseUri,
        redirectUri: redirectUri,
        scope: scope,
        state: state
      }
    };
    App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
    authorizeUri = authBaseUri;
    authorizeUri += '?response_type=token'
                 + '&redirect_uri=' + encodeURIComponent(redirectUri)
                 + '&client_id=' + encodeURIComponent(clientId)
                 + '&state=' + encodeURIComponent(state)
                 + '&scope=' + encodeURIComponent(scope);

    callbackUri = redirectUri;
    callbackUri += '#access_token=' + ('12345abc')
                + '&token_type=' + 'Bearer'
                + '&expires_in=' + '3600';
  });

  afterEach(function() {
    authorizeUri = null;
  });

  describe("Create Namespaces and configure object", function() {
    it("should create a OAuth2 object", function() {
      expect(Ember.OAuth2).toBeDefined();
    });

    it("should create a configuration object for Ember.OAuth2", function() {
      expect(Ember.OAuth2.config).toBeDefined();
    });
  });

  describe("Errors when configuration is incomplete", function() {
    it("should require a clientId", function() {
      Ember.OAuth2.config.test_auth.clientId = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No client id given."));
    });

    it("should require a authorization base uri", function() {
      Ember.OAuth2.config.test_auth.authBaseUri = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No auth base uri given."));
    });

    it("should require a callback uri", function() {
      Ember.OAuth2.config.test_auth.redirectUri = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No redirect uri given."));
    });
  });

  describe("Generate OAuth2 providers url", function() {
    it("should create the url with the options", function() {
      expect(App.oauth.authUri()).toEqual(authorizeUri)
    });
  });

  describe("Parse the access token from the callback url", function() {
    it("should define a parseCallback function", function() {
      expect(Ember.OAuth2.parseCallback).toBeDefined();
    });

    it("should return the params from the callback url", function() {
      expect(Ember.OAuth2.parseCallback(callbackUri)).toEqual({ access_token : '12345abc', token_type : 'Bearer', expires_in : '3600' })
    });
  });

});
<commit_msg>add methods that need to be implemented by the OAuth2 application<commit_after>describe("ember-oauth2", function() {

  window.App = Ember.Application.create({
    NAME: 'test-app'
  });

  var authorizeUri;
  var callbackUri;
  beforeEach(function() {
    var authBaseUri = 'https://foobar.dev/oauth/authorize';
    var redirectUri = 'https://qux.dev/oauth/callback';
    var clientId = '12345';
    var scope = 'public';
    var state = '6789';
    Ember.OAuth2.config = {
      test_auth: {
        clientId: clientId,
        authBaseUri: authBaseUri,
        redirectUri: redirectUri,
        scope: scope,
        state: state
      }
    };
    App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
    authorizeUri = authBaseUri;
    authorizeUri += '?response_type=token'
                 + '&redirect_uri=' + encodeURIComponent(redirectUri)
                 + '&client_id=' + encodeURIComponent(clientId)
                 + '&state=' + encodeURIComponent(state)
                 + '&scope=' + encodeURIComponent(scope);

    callbackUri = redirectUri;
    callbackUri += '#access_token=' + ('12345abc')
                + '&token_type=' + 'Bearer'
                + '&expires_in=' + '3600';
  });

  afterEach(function() {
    authorizeUri = null;
  });

  describe("Create Namespaces and configure object", function() {
    it("should create a OAuth2 object", function() {
      expect(Ember.OAuth2).toBeDefined();
    });

    it("should create a configuration object for Ember.OAuth2", function() {
      expect(Ember.OAuth2.config).toBeDefined();
    });
  });

  describe("Errors when configuration is incomplete", function() {
    it("should require a clientId", function() {
      Ember.OAuth2.config.test_auth.clientId = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No client id given."));
    });

    it("should require a authorization base uri", function() {
      Ember.OAuth2.config.test_auth.authBaseUri = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No auth base uri given."));
    });

    it("should require a callback uri", function() {
      Ember.OAuth2.config.test_auth.redirectUri = null;
      App.oauth = Ember.OAuth2.create(Ember.OAuth2.config.test_auth);
      expect(function() {App.oauth.auth()}).toThrow(new Error("No redirect uri given."));
    });
  });

  describe("Generate OAuth2 providers url", function() {
    it("should create the url with the options", function() {
      expect(App.oauth.authUri()).toEqual(authorizeUri)
    });
  });

  describe("Parse the access token from the callback url", function() {
    it("should define a parseCallback function", function() {
      expect(Ember.OAuth2.parseCallback).toBeDefined();
    });

    it("should return the params from the callback url", function() {
      expect(Ember.OAuth2.parseCallback(callbackUri)).toEqual({ access_token : '12345abc', token_type : 'Bearer', expires_in : '3600' })
    });
  });

  describe("These methods need to be implemented by the OAuth2 application", function() {
    it("should define the onSuccess callback", function() {
      expect(App.oauth.onSuccess).toBeDefined();
    });

    it("should define the onError callback", function() {
      expect(App.oauth.onError).toBeDefined();
    });
  });
});
<|endoftext|>


<commit_before>var Rpd = Rpd, Kefir = Kefir;

var RpdMatchers = RpdMatchers;

if ((typeof Rpd === 'undefined')
 && (typeof Kefir === 'undefined')
 && (typeof RpdMatchers === 'undefined')
 && (typeof require !== 'undefined')) {
    Kefir = require('../vendor/kefir.min.js');
    Rpd = require('../src/rpd.js');
    RpdMatchers = require('./matchers.js');
}

Rpd.channeltype('spec/any', { });

describe('registering', function() {

// -----------------------------------------------------------------------------
// ===============================- renderer -==================================
// -----------------------------------------------------------------------------

describe('renderer', function() {
});

// -----------------------------------------------------------------------------
// =================================- node -====================================
// -----------------------------------------------------------------------------

function withNewModel(fn) {
    var updateSpy = jasmine.createSpy('update');
    var renderer = Rpd.renderer('foo', function(user_conf) {
        return updateSpy;
    });

    var model = Rpd.Model.start().renderWith('foo').attachTo({});

    fn(model, updateSpy);
}

describe('node type', function() {

    beforeEach(function() {
        jasmine.addMatchers({
            toHaveBeenOrderlyCalledWith: RpdMatchers.toHaveBeenOrderlyCalledWith,
            toHaveBeenCalledOnce: RpdMatchers.toHaveBeenCalledOnce,
            toHaveBeenCalledTwice: RpdMatchers.toHaveBeenCalledTwice,
            toHaveBeenCalledTimes: RpdMatchers.toHaveBeenCalledTimes
        });
    });

    it('could be registered with an empty object', function() {
        expect(function() {
            Rpd.nodetype('spec/foo', {});
        }).not.toThrow();
    });

    it('redefining the type re-writes previous type');

    it('passes the specified name to every created instance');

    it('creates specified inlets for the node instance', function() {
        Rpd.nodetype('spec/foo', {
            inlets: {
                'a': { type: 'spec/any' },
                'b': { type: 'spec/any' }
            }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'inlet/add',
                      inlet: jasmine.objectContaining({
                          name: 'a',
                          type: 'spec/any'
                      }) })
            );

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'inlet/add',
                      inlet: jasmine.objectContaining({
                          name: 'b',
                          type: 'spec/any'
                      }) })
            );

        });
    });

    it('creates specified outlets for the node instance', function() {

        Rpd.nodetype('spec/foo', {
            outlets: {
                'a': { type: 'spec/any' },
                'b': { type: 'spec/any' }
            }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'outlet/add',
                      outlet: jasmine.objectContaining({
                          name: 'a',
                          type: 'spec/any'
                      }) })
            );

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'outlet/add',
                      outlet: jasmine.objectContaining({
                          name: 'b',
                          type: 'spec/any'
                      }) })
            );

        });
    });

    it('informs it is ready when all inlets and outlets are ready', function() {

        Rpd.nodetype('spec/foo', {
            inlets:  { 'a': { type: 'spec/any' },
                       'b': { type: 'spec/any' } },
            outlets: { 'c': { type: 'spec/any' },
                       'd': { type: 'spec/any' } }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenOrderlyCalledWith([
                [ jasmine.anything(), jasmine.objectContaining({ type: 'inlet/add' }) ],
                [ jasmine.anything(), jasmine.objectContaining({ type: 'outlet/add' }) ],
                [ jasmine.anything(), jasmine.objectContaining({ type: 'node/ready' }) ]
            ]);

        });
    });

    it('informs it is ready only once', function() {

        Rpd.nodetype('spec/foo', {
            inlets:  { 'a': { type: 'spec/any' } },
            outlets: { 'b': { type: 'spec/any' } }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            updateSpy.calls.reset();

            node.addInlet('spec/any', 'foo');

            expect(updateSpy).not.toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining({ type: 'node/ready' }));

        });
    });

    describe('processing function', function() {

        var processSpy;

        beforeEach(function() { processSpy = jasmine.createSpy('process'); });

        it('is not called when inlets have no default values', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('is still not called when inlets have no default values and there is an outlet', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('is called once when single inlet has some default value', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any', default: 10 },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).toHaveBeenCalledWith({ 'a': 10 }, jasmine.anything());
                expect(processSpy).toHaveBeenCalledOnce();
            });

        });

        it('is called once when several inlets have default value (since node is ready)', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any', default: 10 },
                          'b': { type: 'spec/any', default: 5  } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                // this tests are required due to the fact processing function receives the same object
                // modified through time, so if these checks are preformed after the calls, they do fail
                // see: https://github.com/shamansir/rpd/issues/89
                // and: https://github.com/jasmine/jasmine/issues/872
                var ensureExecuted = handleNextCalls(processSpy, [
                    function() { expect(processSpy).toHaveBeenCalledWith({ 'a': 10 }, jasmine.anything()); },
                    function() { expect(processSpy).toHaveBeenCalledWith({ 'a': 10, 'b': 5 }, jasmine.anything()); }
                ]);

                var node = new Rpd.Node('spec/foo');

                ensureExecuted();

                //console.log(updateSpy.calls.allArgs());

                //expect(processSpy).toHaveBeenCalledWith({ 'a': 10, 'b': 5 }, jasmine.anything());
                //expect(processSpy).toHaveBeenCalledOnce();

            });

        });

        it('is not affected with number of outlets', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any', default: 10 },
                          'b': { type: 'spec/any', default: 5  } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).toHaveBeenCalledTwice();
            });

        });

        it('gets values from inlets even when there\'s no outlets', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                node.inlets['a'].receive(2);
                expect(processSpy).toHaveBeenCalledWith({ a: 2 }, jasmine.anything());
                node.inlets['b'].receive('abc');
                expect(processSpy).toHaveBeenCalledWith({ a: 2, b: 'abc' }, jasmine.anything());

            });

        });

        it('sets outlets to their default values', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any' },
                          'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any', default: 17 } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                var outlet = node.outlets['c'];
                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 17
                    })
                );
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('passes previous values with a call');

        it('does not reacts if updated channel was cold, but keeps its value for next update');

        it('passes values to corresponding outlets based on default inlets values', function() {

            processSpy.and.callFake(function(inlets) {
                return { 'c': (inlets.a || 0) * (inlets.b || 1) };
            });

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any', default: 7 },
                           'b': { type: 'spec/any', default: 2 } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                var outlet = node.outlets['c'];

                expect(processSpy).toHaveBeenCalled();

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 7 // 7 * 1
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 14 // 2 * 7
                    })
                );

            });

        });

        it('passes single values to corresponding outlets', function() {

            processSpy.and.callFake(function(inlets) {
                return { 'c': (inlets.a || 0) * (inlets.b || 1) };
            });

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                node.inlets['a'].receive(7);
                node.inlets['b'].receive(2);
                node.inlets['b'].receive(6);

                var outlet = node.outlets['c'];

                expect(processSpy).toHaveBeenCalled();

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 7 // 7 * 1
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 14 // 2 * 7
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 12 // 2 * 6
                    })
                );

            });

        });

        it('passes streamed values to corresponding outlets');

        it('updates the outlet value even when processing function was executed before this outlet was created');

        it('switches off previous stream when new one was plugged to outlet');

        //it('if no outlet was updated, does not calls the')

        // it('still receives updates from hidden channels');

    });

});

// -----------------------------------------------------------------------------
// ===============================- channel -===================================
// -----------------------------------------------------------------------------

describe('channel type', function() {

});

// -----------------------------------------------------------------------------
// =================================- link -====================================
// -----------------------------------------------------------------------------

describe('link type', function() {

});

// -----------------------------------------------------------------------------
// ============================- node renderer -================================
// -----------------------------------------------------------------------------

describe('node renderer', function() {

});

// -----------------------------------------------------------------------------
// ==========================- channel renderer -===============================
// -----------------------------------------------------------------------------

describe('channel renderer', function() {

});

});

function handleNextCalls(spy, handlers) {
    var timesCalled = 0;

    spy.and.callFake(function() {
        //expect(spy.calls.count()).toBeGreaterThan(0);
        //console.log(timesCalled);
        //console.log(spy.calls.argsFor(timesCalled));
        expect(handlers[timesCalled]).toBeTruthy('No handler for a call #' + timesCalled);
        handlers[timesCalled](spy);
        timesCalled++;
    });

    return function() {
        expect(spy).toHaveBeenCalledTimes(handlers.length);
    }
}
<commit_msg>remove comments (tests still fail!)<commit_after>var Rpd = Rpd, Kefir = Kefir;

var RpdMatchers = RpdMatchers;

if ((typeof Rpd === 'undefined')
 && (typeof Kefir === 'undefined')
 && (typeof RpdMatchers === 'undefined')
 && (typeof require !== 'undefined')) {
    Kefir = require('../vendor/kefir.min.js');
    Rpd = require('../src/rpd.js');
    RpdMatchers = require('./matchers.js');
}

Rpd.channeltype('spec/any', { });

describe('registering', function() {

// -----------------------------------------------------------------------------
// ===============================- renderer -==================================
// -----------------------------------------------------------------------------

describe('renderer', function() {
});

// -----------------------------------------------------------------------------
// =================================- node -====================================
// -----------------------------------------------------------------------------

function withNewModel(fn) {
    var updateSpy = jasmine.createSpy('update');
    var renderer = Rpd.renderer('foo', function(user_conf) {
        return updateSpy;
    });

    var model = Rpd.Model.start().renderWith('foo').attachTo({});

    fn(model, updateSpy);
}

describe('node type', function() {

    beforeEach(function() {
        jasmine.addMatchers({
            toHaveBeenOrderlyCalledWith: RpdMatchers.toHaveBeenOrderlyCalledWith,
            toHaveBeenCalledOnce: RpdMatchers.toHaveBeenCalledOnce,
            toHaveBeenCalledTwice: RpdMatchers.toHaveBeenCalledTwice,
            toHaveBeenCalledTimes: RpdMatchers.toHaveBeenCalledTimes
        });
    });

    it('could be registered with an empty object', function() {
        expect(function() {
            Rpd.nodetype('spec/foo', {});
        }).not.toThrow();
    });

    it('redefining the type re-writes previous type');

    it('passes the specified name to every created instance');

    it('creates specified inlets for the node instance', function() {
        Rpd.nodetype('spec/foo', {
            inlets: {
                'a': { type: 'spec/any' },
                'b': { type: 'spec/any' }
            }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'inlet/add',
                      inlet: jasmine.objectContaining({
                          name: 'a',
                          type: 'spec/any'
                      }) })
            );

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'inlet/add',
                      inlet: jasmine.objectContaining({
                          name: 'b',
                          type: 'spec/any'
                      }) })
            );

        });
    });

    it('creates specified outlets for the node instance', function() {

        Rpd.nodetype('spec/foo', {
            outlets: {
                'a': { type: 'spec/any' },
                'b': { type: 'spec/any' }
            }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'outlet/add',
                      outlet: jasmine.objectContaining({
                          name: 'a',
                          type: 'spec/any'
                      }) })
            );

            expect(updateSpy).toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining(
                    { type: 'outlet/add',
                      outlet: jasmine.objectContaining({
                          name: 'b',
                          type: 'spec/any'
                      }) })
            );

        });
    });

    it('informs it is ready when all inlets and outlets are ready', function() {

        Rpd.nodetype('spec/foo', {
            inlets:  { 'a': { type: 'spec/any' },
                       'b': { type: 'spec/any' } },
            outlets: { 'c': { type: 'spec/any' },
                       'd': { type: 'spec/any' } }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            expect(updateSpy).toHaveBeenOrderlyCalledWith([
                [ jasmine.anything(), jasmine.objectContaining({ type: 'inlet/add' }) ],
                [ jasmine.anything(), jasmine.objectContaining({ type: 'outlet/add' }) ],
                [ jasmine.anything(), jasmine.objectContaining({ type: 'node/ready' }) ]
            ]);

        });
    });

    it('informs it is ready only once', function() {

        Rpd.nodetype('spec/foo', {
            inlets:  { 'a': { type: 'spec/any' } },
            outlets: { 'b': { type: 'spec/any' } }
        });

        withNewModel(function(model, updateSpy) {

            var node = new Rpd.Node('spec/foo');

            updateSpy.calls.reset();

            node.addInlet('spec/any', 'foo');

            expect(updateSpy).not.toHaveBeenCalledWith(
                jasmine.anything(),
                jasmine.objectContaining({ type: 'node/ready' }));

        });
    });

    describe('processing function', function() {

        var processSpy;

        beforeEach(function() { processSpy = jasmine.createSpy('process'); });

        it('is not called when inlets have no default values', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('is still not called when inlets have no default values and there is an outlet', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('is called once when single inlet has some default value', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any', default: 10 },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).toHaveBeenCalledWith({ 'a': 10 }, jasmine.anything());
                expect(processSpy).toHaveBeenCalledOnce();
            });

        });

        it('is called once when several inlets have default value (since node is ready)', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any', default: 10 },
                          'b': { type: 'spec/any', default: 5  } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                // this tests are required due to the fact processing function receives the same object
                // modified through time, so if these checks are preformed after the calls, they do fail
                // see: https://github.com/shamansir/rpd/issues/89
                // and: https://github.com/jasmine/jasmine/issues/872
                var ensureExecuted = handleNextCalls(processSpy, [
                    function() { expect(processSpy).toHaveBeenCalledWith({ 'a': 10 }, jasmine.anything()); },
                    function() { expect(processSpy).toHaveBeenCalledWith({ 'a': 10, 'b': 5 }, jasmine.anything()); }
                ]);

                var node = new Rpd.Node('spec/foo');

                ensureExecuted();

                //console.log(updateSpy.calls.allArgs());

                //expect(processSpy).toHaveBeenCalledWith({ 'a': 10, 'b': 5 }, jasmine.anything());
                //expect(processSpy).toHaveBeenCalledOnce();

            });

        });

        it('is not affected with number of outlets', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any', default: 10 },
                          'b': { type: 'spec/any', default: 5  } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                expect(processSpy).toHaveBeenCalledTwice();
            });

        });

        it('gets values from inlets even when there\'s no outlets', function() {

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                node.inlets['a'].receive(2);
                expect(processSpy).toHaveBeenCalledWith({ a: 2 }, jasmine.anything());
                node.inlets['b'].receive('abc');
                expect(processSpy).toHaveBeenCalledWith({ a: 2, b: 'abc' }, jasmine.anything());

            });

        });

        it('sets outlets to their default values', function() {

            Rpd.nodetype('spec/foo', {
                inlets: { 'a': { type: 'spec/any' },
                          'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any', default: 17 } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {
                var node = new Rpd.Node('spec/foo');
                var outlet = node.outlets['c'];
                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 17
                    })
                );
                expect(processSpy).not.toHaveBeenCalled();
            });

        });

        it('passes previous values with a call');

        it('does not reacts if updated channel was cold, but keeps its value for next update');

        it('passes values to corresponding outlets based on default inlets values', function() {

            processSpy.and.callFake(function(inlets) {
                return { 'c': (inlets.a || 0) * (inlets.b || 1) };
            });

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any', default: 7 },
                           'b': { type: 'spec/any', default: 2 } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                var outlet = node.outlets['c'];

                expect(processSpy).toHaveBeenCalled();

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 7 // 7 * 1
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 14 // 2 * 7
                    })
                );

            });

        });

        it('passes single values to corresponding outlets', function() {

            processSpy.and.callFake(function(inlets) {
                return { 'c': (inlets.a || 0) * (inlets.b || 1) };
            });

            Rpd.nodetype('spec/foo', {
                inlets:  { 'a': { type: 'spec/any' },
                           'b': { type: 'spec/any' } },
                outlets: { 'c': { type: 'spec/any' } },
                process: processSpy
            });

            withNewModel(function(model, updateSpy) {

                var node = new Rpd.Node('spec/foo');

                node.inlets['a'].receive(7);
                node.inlets['b'].receive(2);
                node.inlets['b'].receive(6);

                var outlet = node.outlets['c'];

                expect(processSpy).toHaveBeenCalled();

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 7 // 7 * 1
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 14 // 2 * 7
                    })
                );

                expect(updateSpy).toHaveBeenCalledWith(
                    jasmine.anything(),
                    jasmine.objectContaining({
                        type: 'outlet/update',
                        outlet: outlet,
                        value: 12 // 2 * 6
                    })
                );

            });

        });

        it('passes streamed values to corresponding outlets');

        it('updates the outlet value even when processing function was executed before this outlet was created');

        it('switches off previous stream when new one was plugged to outlet');

        //it('if no outlet was updated, does not calls the')

        // it('still receives updates from hidden channels');

    });

});

// -----------------------------------------------------------------------------
// ===============================- channel -===================================
// -----------------------------------------------------------------------------

describe('channel type', function() {

});

// -----------------------------------------------------------------------------
// =================================- link -====================================
// -----------------------------------------------------------------------------

describe('link type', function() {

});

// -----------------------------------------------------------------------------
// ============================- node renderer -================================
// -----------------------------------------------------------------------------

describe('node renderer', function() {

});

// -----------------------------------------------------------------------------
// ==========================- channel renderer -===============================
// -----------------------------------------------------------------------------

describe('channel renderer', function() {

});

});

function handleNextCalls(spy, handlers) {
    var timesCalled = 0;

    spy.and.callFake(function() {
        expect(handlers[timesCalled]).toBeTruthy('No handler for a call #' + timesCalled);
        handlers[timesCalled](spy);
        timesCalled++;
    });

    return function() {
        expect(spy).toHaveBeenCalledTimes(handlers.length);
    }
}
<|endoftext|>


<commit_before>describe("fdom.resources", function() {
  var resources;

  beforeEach(function() {
    resources = new Resource();
    fdom.debug = new fdom.port.Debug();
  });

  it("should resolve URLs", function(done) {
    var promise = resources.get("http://localhost/folder/manifest.json",
                                 "file.js");
    var callback = function(response) {
      expect(response).toEqual('http://localhost/folder/file.js');
      done();
    };
    promise.then(callback);
  });

  it("should cache resolved URLs", function(done) {
    spyOn(resources, 'resolve').and.callThrough();
    var deferred = resources.get("http://localhost/folder/manifest.json",
                                 "file.js");
    setTimeout(function() {
      deferred = resources.get("http://localhost/folder/manifest.json",
                               "file.js");
      expect(resources.resolve.calls.count()).toEqual(1);
      done();
    }, 0);
  });

  it("should fetch URLs", function(done) {
    var promise;
    promise = resources.getContents('manifest://{"name":"test"}');
    promise.then(function(response) {
      expect(JSON.parse(response).name).toEqual("test");
      done();
    });
  });

  it("should warn on degenerate URLs", function(done) {
    var promise = resources.getContents();
    var spy = jasmine.createSpy('r');
    promise.then(function() {}, spy);
    setTimeout(function() {
      expect(spy).toHaveBeenCalled();

      promise = resources.resolve('test');
      promise.then(function() {}, spy);

      setTimeout(function() {
        expect(spy.calls.count()).toEqual(2);
        done();
      }, 0);
    }, 0);
  });

  it("should handle custom resolvers", function(done) {
    var resolver = function(manifest, url, resolve) {
      if (manifest.indexOf('test') === 0) {
        resolve('resolved://' + url);
        return true;
      } else {
        return false;
      }
    };
    resources.addResolver(resolver);

    var promise = resources.get('test://manifest', 'myurl');
    var r1, r2;
    promise.then(function(url) {r1 = url;});

    promise = resources.get('otherprot://manifest', 'myurl');
    promise.then(function(url) {r2 = url;});

    setTimeout(function() {
      expect(r1).toEqual('resolved://myurl');
      expect(r2).toEqual(undefined);
      done();
    }, 0);
  });

  it("should handle custom retrievers", function(done) {
    var retriever = function(url, resolve) {
      expect(url).toContain("test://");
      resolve('Custom content!');
    };
    resources.addRetriever('test', retriever);

    var r1, r2;
    var promise = resources.getContents('test://url');
    promise.then(function(data) {r1 = data;});

    promise = resources.getContents('unknown://url');
    promise.then(function() {r2 = 'success';}, function() {r2 = 'failed';});

    setTimeout(function() {
      expect(r1).toEqual('Custom content!');
      expect(r2).toEqual('failed');
      done();
    }, 0);
  });

  it("should not allow replacing retrievers", function() {
    var retriever = function(url, deferred) {
      expect(url).toContain("test://");
      deferred.resolve('Custom content!');
    };
    spyOn(fdom.debug, 'warn');
    resources.addRetriever('http', retriever);
    expect(fdom.debug.warn).toHaveBeenCalled();
  });
});

describe('fdom.resources.httpResolver', function() {
  var r, f, spy, resources;

  beforeEach(function() {
    resources = new Resource();
    r = spy = jasmine.createSpy('resolvedURL');
    f = function() {};
  });

  it("should resolve relative URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', 'test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.example.com/path/test.html');
  });

  it("should resolve path absolute URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', '/test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.example.com/test.html');
  });

  it("should resolve absolute URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', 'http://www.other.com/test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.other.com/test.html');
  });

  it("should not resolve URLs without manifest", function() {
    resources.httpResolver(undefined, 'test.html', r, f);
    expect(spy).not.toHaveBeenCalled();
  });
});
<commit_msg>removing some setTimeouts in resource.spec.js<commit_after>describe("fdom.resources", function() {
  var resources;

  beforeEach(function() {
    resources = new Resource();
    fdom.debug = new fdom.port.Debug();
  });

  it("should resolve URLs", function(done) {
    var promise = resources.get("http://localhost/folder/manifest.json",
                                 "file.js");
    var callback = function(response) {
      expect(response).toEqual('http://localhost/folder/file.js');
      done();
    };
    promise.then(callback);
  });

  it("should cache resolved URLs", function(done) {
    spyOn(resources, 'resolve').and.callThrough();
    var deferred = resources.get("http://localhost/folder/manifest.json",
                                 "file.js");
    setTimeout(function() {
      deferred = resources.get("http://localhost/folder/manifest.json",
                               "file.js");
      expect(resources.resolve.calls.count()).toEqual(1);
      done();
    }, 0);
  });

  it("should fetch URLs", function(done) {
    var promise;
    promise = resources.getContents('manifest://{"name":"test"}');
    promise.then(function(response) {
      expect(JSON.parse(response).name).toEqual("test");
      done();
    });
  });

  it("should warn on degenerate URLs", function(done) {
    var promise = resources.getContents();
    var spy = jasmine.createSpy('r');
    promise.then(function() {}, function() {
      resources.resolve('test').then(function(){}, function() {
        done();
      });
    });
  });

  it("should handle custom resolvers", function(done) {
    var resolver = function(manifest, url, resolve) {
      if (manifest.indexOf('test') === 0) {
        resolve('resolved://' + url);
        return true;
      } else {
        return false;
      }
    };
    resources.addResolver(resolver);

    var promise = resources.get('test://manifest', 'myurl');
    var r1, r2;
    promise.then(function(url) {r1 = url;});

    promise = resources.get('otherprot://manifest', 'myurl');
    promise.then(function(url) {r2 = url;});

    setTimeout(function() {
      expect(r1).toEqual('resolved://myurl');
      expect(r2).toEqual(undefined);
      done();
    }, 0);
  });

  it("should handle custom retrievers", function(done) {
    var retriever = function(url, resolve) {
      expect(url).toContain("test://");
      resolve('Custom content!');
    };
    resources.addRetriever('test', retriever);

    var r1, r2;
    var promise = resources.getContents('test://url');
    promise.then(function(data) {r1 = data;});

    promise = resources.getContents('unknown://url');
    promise.then(function() {r2 = 'success';}, function() {r2 = 'failed';});

    setTimeout(function() {
      expect(r1).toEqual('Custom content!');
      expect(r2).toEqual('failed');
      done();
    }, 0);
  });

  it("should not allow replacing retrievers", function() {
    var retriever = function(url, deferred) {
      expect(url).toContain("test://");
      deferred.resolve('Custom content!');
    };
    spyOn(fdom.debug, 'warn');
    resources.addRetriever('http', retriever);
    expect(fdom.debug.warn).toHaveBeenCalled();
  });
});

describe('fdom.resources.httpResolver', function() {
  var r, f, spy, resources;

  beforeEach(function() {
    resources = new Resource();
    r = spy = jasmine.createSpy('resolvedURL');
    f = function() {};
  });

  it("should resolve relative URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', 'test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.example.com/path/test.html');
  });

  it("should resolve path absolute URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', '/test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.example.com/test.html');
  });

  it("should resolve absolute URLs", function() {
    resources.httpResolver('http://www.example.com/path/manifest.json', 'http://www.other.com/test.html', r, f);
    expect(spy).toHaveBeenCalledWith('http://www.other.com/test.html');
  });

  it("should not resolve URLs without manifest", function() {
    resources.httpResolver(undefined, 'test.html', r, f);
    expect(spy).not.toHaveBeenCalled();
  });
});
<|endoftext|>


<commit_before>/**
 * Created by (c) Sebastian Kaim, 2016
 *
 * This file is licensed under the MIT License.
 */
"use strict";

(function ($) {

    // returns whether values are less than (maxDev * 100)% away
    var isNearby = function (one, two, maxDev) {
        return Math.abs(1 - Math.abs(one / two)) < maxDev;
    };

    // dot helper class
    // x,y are assumend to already be relative to align unless el is not undefined
    var dot = function (_x, _y, _text, _align, el) {
        this.x = _x;
        this.y = _y;
        this.text = _text; // dot text
        this.align = _align; // {x, y} to which these coords are relative to
        this.radius = 24; // hover event radius

        if(el != undefined)
        {
            this.x = (this.x * this.align.x) / el.width;
            this.y = (this.y * this.align.y) / el.height;
        }

        this.render = function (context) {
            context.beginPath();
            var rx = (this.x * el.width) / this.align.x;
            var ry = (this.y * el.height) / this.align.y;
            context.arc(rx, ry, 4, 0, Math.PI * 2, true);
            context.fill();
        };

        // returns whether (x,y) match this point when relative to el or, if
        // el == undefined, they're matching
        this.isMe = function (x, y, el) {
            if(el != undefined)
            {
                x = (x * this.align.x) / el.width;
                y = (y * this.align.y) / el.height;
            }
            return isNearby(x, this.x, 0.01) && isNearby(y, this.y, 0.01);
        };
    };

    // register the plugin
    $.fn.dotHover = function (dots, options) {

        // settings
        var settings = $.extend({
            // defaults

            // this should be a valid image url which will be used as background
            img: "karte.png",

            // whether to allow the user to place dots on click
            setmode: false,

            // a callback for when an event is created
            setcallback: function (dot) {},

            // default text for an unitialized dot
            defaulttext: "Example Text",

            // Reference width/height to which all coords are relative to.
            // Usually, there's no reason to change this, but if you have
            // old coords which are aligned differently you may want to
            // override this. The default values are pretty high for better
            // precision.
            align: {
                x: 100000, // width
                y: 100000 // height
            }

        }, options );

        // initialize dots
        settings.dots = [];
        $.each(dots, function (i, el) {
            settings.dots.push(new dot(el.x, el.y, el.text));
        });

        //
        // create tooltip canvas
        //
        var tooltip = $('<div/>')
            .appendTo('body')
            .addClass('hoverDotTooltip')
            .css({
                backgroundColor: 'white',
                border: '1px solid blue',
                position: 'absolute',
                padding: '5px',
                marginLeft: '-50px'
            })
            .hide();

        var contexts = [];

        var showHideTooltip = function (show) {
            if(show)
            {
                tooltip.show();
                tooltip.get(0).style.marginLeft = ((-tooltip.width() / 2) + 3) + "px";
            }
            else
            {
                tooltip.hide();
            }
        };

        //
        // handle tooltip positioning on mouse move
        //
        var mouseMoveEvent = function(event, img, offsetX, offsetY) {
            var mouseX = parseInt(event.clientX - offsetX + $(window).scrollLeft());
            var mouseY = parseInt(event.clientY - offsetY + $(window).scrollTop());

            var hit = false;
            for (var i = 0; i < settings.dots.length; i++) {
                var dot = settings.dots[i];
                var dx = mouseX - dot.x;
                var dy = mouseY - dot.y;

                if (dx * dx + dy * dy < dot.radius) {
                    tooltip.get(0).style.top = ((dot.y - 40) + offsetY) + "px"; // -40 to "center" the canvas
                    tooltip.get(0).style.left = (dot.x + offsetX) + "px";

                    tooltip.html(dot.text);
                    hit = true;
                }
            }

            showHideTooltip(hit);
        };

        // re-renders all dots
        var render = function () {
            $.each(contexts, function (i, data) {
                $.each(settings.dots, function (j, dot) {
                    dot.render(data.ctx);
                });
            });
        };

        //
        // places a new dot
        //
        var placedot = function (event, element) {
            var ndot = new dot(event.clientX - element.offsetLeft,
                event.clientY - element.offsetTop + $(window).scrollTop(),
                settings.defaulttext,
                settings.align,
                element);

            settings.dots.push(ndot);
            render();
            settings.setcallback(ndot);
        };

        //
        // removes a dot
        //
        this.removeDot = function(x, y)
        {
            settings.dots = settings.dots.filter(function(el, index) {
                return dot.x != x && dot.y != y;
            });
        };

        // init mouse move on each element
        this.each(function(i, el) {
            el.style= 'background: url(' + settings.img + ');' +
            'background-repeat: no-repeat; ' +
            'background-size: contain;' +
            'width: ' + settings.width + '; ';
            //'height: ' + settings.height + '; '

            contexts.push( { el: el, ctx: el.getContext('2d') });

            $(el).mousemove (function (event) {
                mouseMoveEvent(event, el, el.offsetLeft, el.offsetTop);
            });

            if(settings.setmode) $(el).click(function (e) {
                placedot(e, el);
            });
        });

        // render initial dots
        render();

        return this;
    };

})(jQuery);
<commit_msg>Fixed hovering! Yay!<commit_after>/**
 * Created by (c) Sebastian Kaim, 2016
 *
 * This file is licensed under the MIT License.
 */
"use strict";

(function ($) {

    // returns whether values are less than (maxDev * 100)% away
    var isNearby = function (one, two, maxDev) {
        return Math.abs(1 - Math.abs(one / two)) < maxDev;
    };

    // dot helper class
    // x,y are assumend to already be relative to align unless el is not undefined
    var dot = function (_x, _y, _text, _align, el) {
        this.x = _x;
        this.y = _y;
        this.text = _text; // dot text
        this.align = _align; // {x, y} to which these coords are relative to
        this.radius = 24; // hover event radius

        if(el != undefined)
        {
            this.x = (this.x * this.align.x) / $(el).width();
            this.y = (this.y * this.align.y) / $(el).height();
        }

        this.relativeX = function (el) {
            return (this.x * $(el).width()) / this.align.x;
        };

        this.relativeY = function (el) {
            return (this.y * $(el).height()) / this.align.y;
        };

        this.render = function (context, el) {
            context.beginPath();
            context.arc(this.relativeX(el), this.relativeY(el), 4, 0, Math.PI * 2, true);
            context.fill();
        };

        // returns whether (x,y) match this point when relative to el or, if
        // el == undefined, they're matching (== diffrence less than maxDeviration)
        this.isMe = function (x, y, el, maxDeviration) {
            maxDeviration = maxDeviration || 0.01;
            if(el != undefined)
            {
                x = (x * this.align.x) / $(el).width();
                y = (y * this.align.y) / $(el).height();
            }
            return isNearby(x, this.x, maxDeviration) && isNearby(y, this.y, maxDeviration);
        };
    };

    // register the plugin
    $.fn.dotHover = function (dots, options) {

        // settings
        var settings = $.extend({
            // defaults

            // this should be a valid image url which will be used as background
            img: "karte.png",

            // whether to allow the user to place dots on click
            setmode: false,

            // a callback for when an event is created
            setcallback: function (dot) {},

            // default text for an unitialized dot
            defaulttext: "Example Text",

            // Reference width/height to which all coords are relative to.
            // Usually, there's no reason to change this, but if you have
            // old coords which are aligned differently you may want to
            // override this. The default values are pretty high for better
            // precision.
            align: {
                x: 100000, // width
                y: 100000 // height
            }

        }, options );

        // initialize dots
        settings.dots = [];
        $.each(dots, function (i, el) {
            settings.dots.push(new dot(el.x, el.y, el.text, settings.align));
        });

        //
        // create tooltip canvas
        //
        var tooltip = $('<div/>')
            .appendTo('body')
            .addClass('hoverDotTooltip')
            .css({
                backgroundColor: 'white',
                border: '1px solid blue',
                position: 'absolute',
                padding: '5px',
                marginLeft: '-50px'
            })
            .hide();

        var contexts = [];

        var showHideTooltip = function (show) {
            if(show)
            {
                tooltip.show();
                tooltip.get(0).style.marginLeft = ((-tooltip.width() / 2) + 3) + "px";
            }
            else
            {
                tooltip.hide();
            }
        };

        //
        // handle tooltip positioning on mouse move
        //
        var mouseMoveEvent = function(event, img, offsetX, offsetY) {
            var mouseX = parseInt(event.clientX - offsetX + $(window).scrollLeft());
            var mouseY = parseInt(event.clientY - offsetY + $(window).scrollTop());

            var hit = false;
            for (var i = 0; i < settings.dots.length; i++) {
                var dot = settings.dots[i];
                var dx = mouseX - dot.relativeX(img);
                var dy = mouseY - dot.relativeY(img);

                if (dx * dx + dy * dy < dot.radius) {
                    tooltip.get(0).style.top = ((dot.relativeY(img) - 40) + offsetY) + "px"; // -40 to "center" the canvas
                    tooltip.get(0).style.left = (dot.relativeX(img) + offsetX) + "px";

                    tooltip.html(dot.text);
                    hit = true;
                }
            }

            showHideTooltip(hit);
        };

        // re-renders all dots
        var render = function () {
            $.each(contexts, function (i, data) {
                $.each(settings.dots, function (j, dot) {
                    dot.render(data.ctx, data.el);
                });
            });
        };

        //
        // places a new dot
        //
        var placedot = function (event, element) {
            var ndot = new dot(event.clientX - element.offsetLeft,
                event.clientY - element.offsetTop + $(window).scrollTop(),
                settings.defaulttext,
                settings.align,
                element);

            settings.dots.push(ndot);
            render();
            settings.setcallback(ndot);
        };

        //
        // removes a dot
        //
        this.removeDot = function(x, y)
        {
            settings.dots = settings.dots.filter(function(el, index) {
                return dot.x != x && dot.y != y;
            });
        };

        // init mouse move on each element
        this.each(function(i, el) {
            el.style= 'background: url(' + settings.img + ');' +
            'background-repeat: no-repeat; ' +
            'background-size: contain;' +
            'width: ' + settings.width + '; ';
            //'height: ' + settings.height + '; '

            contexts.push( { el: el, ctx: el.getContext('2d') });

            $(el).mousemove (function (event) {
                mouseMoveEvent(event, el, el.offsetLeft, el.offsetTop);
            });

            if(settings.setmode) $(el).click(function (e) {
                placedot(e, el);
            });

            $(el).resize(render);
        });

        // render initial dots
        render();

        return this;
    };

})(jQuery);
<|endoftext|>


<commit_before><commit_msg>uglify the recent changes<commit_after><|endoftext|>


<commit_before>/**
 * Created by julia on 01.11.2016.
 */
global.Promise = require('bluebird');
const Eris = require("eris");
let StatsD = require('hot-shots');
let dogstatsd = new StatsD();
const EventEmitter = require('eventemitter3');
const guildModel = require('./DB/guild');
const config = require('./config/main.json');
let winston = require('winston');
let raven = require('raven');
let mongoose = require('mongoose');
let url = config.beta ? 'mongodb://localhost/discordbot-beta' : 'mongodb://localhost/discordbot';
let Connector = require('./structures/connector');
let ModuleManager = require('./modules/moduleManager');
mongoose.Promise = Promise;
mongoose.connect(url, (err) => {
    if (err) return winston.error('Failed to connect to the database!');
});
let stat = config.beta ? 'rem-beta' : 'rem-live';
let blocked = require('blocked');
let version = require('./package.json').version;
let Raven = new raven.Client();
if (!config.no_error_tracking) {
    Raven.config(config.sentry_token, {
        captureUnhandledRejections: true,
        release: version,
        environment: config.environment
    }).install(() => {
        winston.error('Oh no I died!');
        process.exit(1);
    });
}
/**
 * The base shard class
 * @extends EventEmitter
 */
class Shard extends EventEmitter {
    /**
     * The constructor
     * @constructor
     * @param SHARD_ID The shardid of the bot
     * @param SHARD_COUNT the max shardcount
     * @param hub the clusterhub instance used to send data back and forth
     */
    constructor(SHARD_ID, SHARD_COUNT, hub) {
        super();
        this.id = SHARD_ID;
        this.count = SHARD_COUNT;
        this.bot = null;
        this.ready = false;
        this.CON = new Connector();
        this.MSG = null;
        this.HUB = hub;
        this.MOD = new ModuleManager();
        this.GM = null;
        this.UM = null;
        this.interval = null;
        this.init();
    }

    /**
     * Setup a listener if the eventloop blocks,
     * then call the initClient method
     */
    init() {
        blocked((ms) => {
            console.log('Shard:' + this.id + ' BLOCKED FOR %sms', ms | 0);
        });
        this.initClient();
    }

    /**
     * Initiates the Client and Eris
     * In this function Rem sets up listeners for common events, configures eris and starts the lib
     */
    initClient() {
        let options = {
            autoreconnect: true,
            compress: true,
            messageLimit: 200,
            disableEveryone: true,
            getAllUsers: true,
            firstShardID: parseInt(this.id),
            lastShardID: parseInt(this.id),
            maxShards: parseInt(this.count),
            disableEvents: ['typingStart', 'typingStop', 'guildMemberSpeaking', 'messageUpdate']
        };
        winston.info(options);
        let bot = new Eris(config.token, options);
        this.bot = bot;
        global.rem = bot;
        bot.on('ready', () => {
            bot.editStatus(`online`, {name: `!w.help for commands`});
            this.clientReady()
        });
        bot.on('messageCreate', (msg) => {
            dogstatsd.increment(`${stat}.messages`);
            msg.CON = this.CON;
            this.message(msg)
        });
        bot.on('guildCreate', (Guild) => {
            this.guildCreate(Guild)
        });
        bot.on('guildDelete', (Guild) => {
            this.guildDelete(Guild);
        });
        bot.on('voiceChannelJoin', (m, n) => {
            this.voiceUpdate(m, n, false);
        });
        bot.on('voiceChannelLeave', (m, o) => {
            this.voiceUpdate(m, o, true);
        });
        bot.on('guildMemberAdd', (g, m) => {
            this.guildMemberAdd(g, m)
        });
        bot.on('guildMemberRemove', (g, m) => {
            this.guildMemberRemove(g, m)
        });
        // bot.on('debug', this.debug);
        // bot.on('warn', this.warn);
        bot.on('error', this.error);
        process.on('SIGINT', () => {
            this.shutdown()
        });
        bot.connect();
    }

    /**
     * Here comes the really interesting stuff.
     * 1. Rem starts the init function of the Module Loader, which loads all mods inside /managed
     * 2. Once the modloader is done, rem gets the needed mods and sets them as instancevariables
     * 3. Then some event listeners are setup, which are later used for cache-syncing
     * 4. Rem logs that the commands are ready.
     * 5. Now, Rem sends an initial data update to the main process to update the guild/user counts if necessary.
     * 6. A Interval gets created to update data every 5 mins
     */
    clientReady() {
        this.MOD.init(this.HUB, Raven).then(() => {
            this.ready = true;
            this.MSG = this.MOD.getMod('mm');
            this.GM = this.MOD.getMod('gm');
            this.UM = this.MOD.getMod('um');
            this.UM.on('_cache_update', (data) => {
                this.emitCacheUpdate(data);
            });
            this.GM.on('_cache_update', (data) => {
                this.emitCacheUpdate(data);
            });
            this.HUB.on('_cache_update', (data) => {
                this.updateLocalCache(data);
            });
            this.HUB.on('request_data_master', (evId) => {
                this.HUB.emitRemote(`resolve_data_master_${evId}`, {
                    sid: this.id,
                    users: this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b),
                    guilds: this.bot.guilds.size,
                    channels: this.bot.guilds.map(g => g.channels.size).reduce((a, b) => a + b)
                });
            });
            winston.info('commands are ready!');
            this.sendStats();
            this.createInterval();
        });
        // this.LANG = new LanguageManager();
        // this.VOICE = new VoiceManager();
        // this.MSG = new MsgManager(this.LANG, this.VOICE);
        // this.MSG.on('ready', (cmds) => {
        //     this.ready = true;
        //     this.HUB.emit('_guild_update', this.id, this.bot.guilds.size);
        //     this.HUB.emit('_user_update', this.id, this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b));
        //     winston.info('commands are ready!');
        //     this.sendStats();
        //     this.createInterval();
        //     // console.log(cmds);
        // });
    }

    message(msg) {
        if (this.ready && !msg.author.bot) {
            this.CON.invokeAllCollectors(msg);
            this.MSG.check(msg);
        }
    }

    guildCreate(Guild) {
        this.sendStats();
        guildModel.findOne({id: Guild.id}, (err, guild) => {
            if (err) {
                Raven.captureError(err);
                return winston.error(err);
            }
            if (guild) {

            } else {
                let guild = new guildModel({
                    id: Guild.id,
                    nsfwChannels: [],
                    cmdChannels: [],
                    lastVoiceChannel: "",
                    levelEnabled: true,
                    pmNotifications: true,
                    chNotifications: false,
                    prefix: "!w.",
                    lng: "en"
                });
                guild.save((err) => {
                    if (err) return winston.error(err);
                });
            }
        });
    }

    guildDelete(Guild) {
        this.sendStats();
    }

    guildMemberAdd(member) {

    }

    guildMemberRemove(member) {

    }

    voiceUpdate(member, channel, leave) {
        // if (!leave) {
        //     console.log('user joined voice!');
        // } else {
        //     console.log('user left voice!');
        // }
    }

    debug(info) {
        console.debug(info);
    }

    warn(info) {
        winston.warn(info);
    }

    error(err) {
        winston.error(err);
    }

    shutdown() {
        clearInterval(this.interval);
        mongoose.connection.close();
        try {
            this.bot.disconnect();
        } catch (e) {
            console.log(e);
        }
        setTimeout(() => {
            process.exit(0);
        }, 200);
    }

    createInterval() {
        this.interval = setInterval(() => {
            this.sendStats();
        }, 1000 * 500);
    }

    sendStats() {
        this.HUB.emit('_guild_update', this.id, this.bot.guilds.size);
        this.HUB.emit('_user_update', this.id, this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b));
    }

    updateLocalCache({type, data}) {
        switch (type) {
            case 'user':
                this.MOD.getMod('um').updateCache(data);
                return;
            case 'guild':
                this.MOD.getMod('gm').updateCache(data);
                return;
            default:
                return;
        }
    }

    emitCacheUpdate({type, data}) {
        this.HUB.emitRemote('_cache_update', {shard: this.id, type, data});
    }

}
module.exports = Shard;
<commit_msg>hotfix.<commit_after>/**
 * Created by julia on 01.11.2016.
 */
global.Promise = require('bluebird');
const Eris = require("eris");
let StatsD = require('hot-shots');
let dogstatsd = new StatsD();
const EventEmitter = require('eventemitter3');
const guildModel = require('./DB/guild');
const config = require('./config/main.json');
let winston = require('winston');
let raven = require('raven');
let mongoose = require('mongoose');
let url = config.beta ? 'mongodb://localhost/discordbot-beta' : 'mongodb://localhost/discordbot';
let Connector = require('./structures/connector');
let ModuleManager = require('./modules/moduleManager');
mongoose.Promise = Promise;
mongoose.connect(url, (err) => {
    if (err) return winston.error('Failed to connect to the database!');
});
let stat = config.beta ? 'rem-beta' : 'rem-live';
let blocked = require('blocked');
let version = require('./package.json').version;
let Raven = new raven.Client();
if (!config.no_error_tracking) {
    Raven.config(config.sentry_token, {
        release: version,
        environment: config.environment
    }).install(() => {
        winston.error('Oh no I died!');
        process.exit(1);
    });
}
/**
 * The base shard class
 * @extends EventEmitter
 */
class Shard extends EventEmitter {
    /**
     * The constructor
     * @constructor
     * @param SHARD_ID The shardid of the bot
     * @param SHARD_COUNT the max shardcount
     * @param hub the clusterhub instance used to send data back and forth
     */
    constructor(SHARD_ID, SHARD_COUNT, hub) {
        super();
        this.id = SHARD_ID;
        this.count = SHARD_COUNT;
        this.bot = null;
        this.ready = false;
        this.CON = new Connector();
        this.MSG = null;
        this.HUB = hub;
        this.MOD = new ModuleManager();
        this.GM = null;
        this.UM = null;
        this.interval = null;
        this.init();
    }

    /**
     * Setup a listener if the eventloop blocks,
     * then call the initClient method
     */
    init() {
        blocked((ms) => {
            console.log('Shard:' + this.id + ' BLOCKED FOR %sms', ms | 0);
        });
        this.initClient();
    }

    /**
     * Initiates the Client and Eris
     * In this function Rem sets up listeners for common events, configures eris and starts the lib
     */
    initClient() {
        let options = {
            autoreconnect: true,
            compress: true,
            messageLimit: 200,
            disableEveryone: true,
            getAllUsers: true,
            firstShardID: parseInt(this.id),
            lastShardID: parseInt(this.id),
            maxShards: parseInt(this.count),
            disableEvents: ['typingStart', 'typingStop', 'guildMemberSpeaking', 'messageUpdate']
        };
        winston.info(options);
        let bot = new Eris(config.token, options);
        this.bot = bot;
        global.rem = bot;
        bot.on('ready', () => {
            bot.editStatus(`online`, {name: `!w.help for commands`});
            this.clientReady()
        });
        bot.on('messageCreate', (msg) => {
            dogstatsd.increment(`${stat}.messages`);
            msg.CON = this.CON;
            this.message(msg)
        });
        bot.on('guildCreate', (Guild) => {
            this.guildCreate(Guild)
        });
        bot.on('guildDelete', (Guild) => {
            this.guildDelete(Guild);
        });
        bot.on('voiceChannelJoin', (m, n) => {
            this.voiceUpdate(m, n, false);
        });
        bot.on('voiceChannelLeave', (m, o) => {
            this.voiceUpdate(m, o, true);
        });
        bot.on('guildMemberAdd', (g, m) => {
            this.guildMemberAdd(g, m)
        });
        bot.on('guildMemberRemove', (g, m) => {
            this.guildMemberRemove(g, m)
        });
        // bot.on('debug', this.debug);
        // bot.on('warn', this.warn);
        bot.on('error', this.error);
        process.on('SIGINT', () => {
            this.shutdown()
        });
        bot.connect();
    }

    /**
     * Here comes the really interesting stuff.
     * 1. Rem starts the init function of the Module Loader, which loads all mods inside /managed
     * 2. Once the modloader is done, rem gets the needed mods and sets them as instancevariables
     * 3. Then some event listeners are setup, which are later used for cache-syncing
     * 4. Rem logs that the commands are ready.
     * 5. Now, Rem sends an initial data update to the main process to update the guild/user counts if necessary.
     * 6. A Interval gets created to update data every 5 mins
     */
    clientReady() {
        this.MOD.init(this.HUB, Raven).then(() => {
            this.ready = true;
            this.MSG = this.MOD.getMod('mm');
            this.GM = this.MOD.getMod('gm');
            this.UM = this.MOD.getMod('um');
            this.UM.on('_cache_update', (data) => {
                this.emitCacheUpdate(data);
            });
            this.GM.on('_cache_update', (data) => {
                this.emitCacheUpdate(data);
            });
            this.HUB.on('_cache_update', (data) => {
                this.updateLocalCache(data);
            });
            this.HUB.on('request_data_master', (evId) => {
                this.HUB.emitRemote(`resolve_data_master_${evId}`, {
                    sid: this.id,
                    users: this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b),
                    guilds: this.bot.guilds.size,
                    channels: this.bot.guilds.map(g => g.channels.size).reduce((a, b) => a + b)
                });
            });
            winston.info('commands are ready!');
            this.sendStats();
            this.createInterval();
        });
        // this.LANG = new LanguageManager();
        // this.VOICE = new VoiceManager();
        // this.MSG = new MsgManager(this.LANG, this.VOICE);
        // this.MSG.on('ready', (cmds) => {
        //     this.ready = true;
        //     this.HUB.emit('_guild_update', this.id, this.bot.guilds.size);
        //     this.HUB.emit('_user_update', this.id, this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b));
        //     winston.info('commands are ready!');
        //     this.sendStats();
        //     this.createInterval();
        //     // console.log(cmds);
        // });
    }

    message(msg) {
        if (this.ready && !msg.author.bot) {
            this.CON.invokeAllCollectors(msg);
            this.MSG.check(msg);
        }
    }

    guildCreate(Guild) {
        this.sendStats();
        guildModel.findOne({id: Guild.id}, (err, guild) => {
            if (err) {
                Raven.captureError(err);
                return winston.error(err);
            }
            if (guild) {

            } else {
                let guild = new guildModel({
                    id: Guild.id,
                    nsfwChannels: [],
                    cmdChannels: [],
                    lastVoiceChannel: "",
                    levelEnabled: true,
                    pmNotifications: true,
                    chNotifications: false,
                    prefix: "!w.",
                    lng: "en"
                });
                guild.save((err) => {
                    if (err) return winston.error(err);
                });
            }
        });
    }

    guildDelete(Guild) {
        this.sendStats();
    }

    guildMemberAdd(member) {

    }

    guildMemberRemove(member) {

    }

    voiceUpdate(member, channel, leave) {
        // if (!leave) {
        //     console.log('user joined voice!');
        // } else {
        //     console.log('user left voice!');
        // }
    }

    debug(info) {
        console.debug(info);
    }

    warn(info) {
        winston.warn(info);
    }

    error(err) {
        winston.error(err);
    }

    shutdown() {
        clearInterval(this.interval);
        mongoose.connection.close();
        try {
            this.bot.disconnect();
        } catch (e) {
            console.log(e);
        }
        setTimeout(() => {
            process.exit(0);
        }, 200);
    }

    createInterval() {
        this.interval = setInterval(() => {
            this.sendStats();
        }, 1000 * 500);
    }

    sendStats() {
        this.HUB.emit('_guild_update', this.id, this.bot.guilds.size);
        this.HUB.emit('_user_update', this.id, this.bot.guilds.map(g => g.memberCount).reduce((a, b) => a + b));
    }

    updateLocalCache({type, data}) {
        switch (type) {
            case 'user':
                this.MOD.getMod('um').updateCache(data);
                return;
            case 'guild':
                this.MOD.getMod('gm').updateCache(data);
                return;
            default:
                return;
        }
    }

    emitCacheUpdate({type, data}) {
        this.HUB.emitRemote('_cache_update', {shard: this.id, type, data});
    }

}
module.exports = Shard;
<|endoftext|>