<commit_before>/*!
 *
 * Bancha Scaffolding Library
 * Copyright 2011-2014 codeQ e.U.
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Bancha.scaffold.Util tests
 *
 * @package       Bancha.scaffold.tests
 * @copyright     Copyright 2011-2014 codeQ e.U.
 * @link          http://scaffold.bancha.io
 * @since         Bancha Scaffold v 0.5.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 * @author        Roland Schuetz <mail@rolandschuetz.at>
 * @version       Bancha Scaffold v PRECOMPILER_ADD_BANCHA_SCAFFOLD_RELEASE_VERSION
 *
 * For more information go to http://scaffold.bancha.io
 */

describe("Bancha.scaffold.Util tests",function() {
    var util = Bancha.scaffold.Util;

    it("should pass all Bancha.scaffold.Util.toFirstUpper tests", function() {
        expect('User').toEqual(util.toFirstUpper('user'));
        expect('UserName').toEqual(util.toFirstUpper('userName'));
    });

    it("should pass all Bancha.scaffold.Util.humanize tests", function() {

        // first upper case
        expect('User').toEqual(util.humanize('user'));

        // ids
        expect('User').toEqual(util.humanize('user_id'));

        // underscores
        expect('User name').toEqual(util.humanize('user_name'));
        expect('Name with many spaces').toEqual(util.humanize('name_with_many_spaces'));

        // camel case
        expect('User name').toEqual(util.humanize('userName'));
        expect('Name with many spaces').toEqual(util.humanize('nameWithManySpaces'));

        // shouldn't change normal text
        expect('John Smith').toEqual(util.humanize('John Smith'));
        expect('This is a normal text with spaces, Upper case words and all UPPER CASE words!'
               ).toEqual(util.humanize('This is a normal text with spaces, Upper case words '+
               'and all UPPER CASE words!'));
    });

    it("should humanize class names", function() {
        // Standard namespaced and not namespaced
        expect('User').toEqual(util.humanizeClassName('Bancha.model.User'));
        expect('User').toEqual(util.humanizeClassName('Bancha.User'));
        expect('User').toEqual(util.humanizeClassName('User'));

        // check humanizing part
        expect('Awesome class').toEqual(util.humanizeClassName('Bancha.model.AwesomeClass'));
    });

    it("should replace button placeholder from an button config", function() {

        expect().toEqual(util.replaceButtonPlaceHolders()); //undefined
        expect([]).toEqual(util.replaceButtonPlaceHolders([])); //empty

        var config = {
            createButtonConfig: {
                myCreate: true
            },
            resetButtonConfig: {
                myReset: true
            },
            saveButtonConfig: {
                mySave: true
            },
            onCreate: function(a) {},
            onReset: function(b) {},
            onSave: function(c) {}
        };
        var scope =  {
            scoped:true
        };

        // test create button
        var expected = ['->',{
            myCreate: true,
            scope: scope,
            handler: config.onCreate
        }];
        expect(util.replaceButtonPlaceHolders(['->','create'], config, scope)).toEqual(expected);

        // test reset button
        expected.push({
            myReset: true,
            scope: scope,
            handler: config.onReset
        });
        expect(util.replaceButtonPlaceHolders(['->','create','reset'], config, scope)).toEqual(expected);

        // test save button
        expected.push({
            mySave: true,
            scope: scope,
            handler: config.onSave
        });
        expect(util.replaceButtonPlaceHolders(['->','create','reset','save'], config, scope)).toEqual(expected);

        // test with only the save button
        expected = [expected[3]];
        expect(expected).toEqual(util.replaceButtonPlaceHolders(['save'], config, scope));

        // test support for custom configs
        expected.push({
            myCustom: 'button-config'
        });
        expect(util.replaceButtonPlaceHolders(['save', {myCustom: 'button-config'}], config, scope)).toEqual(expected);
    });

    it("should inject buttons scopes for #replaceButtonPlaceHolders", function() {
        var input = [{
            myButton: true,
            scope: 'scaffold-scope-me'
        }];
        var scope =  {
            scoped:true
        };
        var expected = [{
            myButton: true,
            scope: {
                scoped:true
            }
        }];
        expect(util.replaceButtonPlaceHolders(input, {}, scope)).toEqual(expected);
    });

    it("should return a boolean when calling isModel, given a model or model name", function() {
        // return null if model doesn't exist
        expect(util.isModel(null)).toBeFalsy();
        expect(util.isModel('RANDOM_NONSENSE')).toBeFalsy();

        // return the class is a model is given
        Ext.define('Bancha.model.UtilSpecTestModel1', {
            extend: 'Ext.data.Model'
        });
        expect(util.isModel('Bancha.model.UtilSpecTestModel1')).toBeTruthy();
        expect(util.isModel(Bancha.model.UtilSpecTestModel1)).toBeTruthy();

        // return null if a class, but not a model
        Ext.define('Bancha.model.UtilSpecTestClass1', {
        });
        expect(util.isModel('Bancha.model.UtilSpecTestClass1')).toBeFalsy();
        expect(util.isModel(Bancha.model.UtilSpecTestClass1)).toBeFalsy();
    });

    it("should return a model given when calling getModel, given a model or model name", function() {
        // return null if model doesn't exist
        expect(util.getModel.bind(util, null)).toThrow();
        expect(util.getModel.bind(util, 'RANDOM_NONSENSE')).toThrow();

        // return the class is a model is given
        Ext.define('Bancha.model.UtilSpecTestModel2', {
            extend: 'Ext.data.Model'
        });
        expect(util.getModel('Bancha.model.UtilSpecTestModel2')).toEqual(Bancha.model.UtilSpecTestModel2);
        expect(util.getModel(Bancha.model.UtilSpecTestModel2)).toEqual(Bancha.model.UtilSpecTestModel2);

        // return null if a class, but not a model
        Ext.define('Bancha.model.UtilSpecTestClass2', {
        });
        expect(util.getModel.bind(util, 'Bancha.model.UtilSpecTestClass2')).toThrow();
        expect(util.getModel.bind(util, Bancha.model.UtilSpecTestClass2)).toThrow();
    });

});
<commit_msg>Fixed execution on phantomJS<commit_after>/*!
 *
 * Bancha Scaffolding Library
 * Copyright 2011-2014 codeQ e.U.
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Bancha.scaffold.Util tests
 *
 * @package       Bancha.scaffold.tests
 * @copyright     Copyright 2011-2014 codeQ e.U.
 * @link          http://scaffold.bancha.io
 * @since         Bancha Scaffold v 0.5.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 * @author        Roland Schuetz <mail@rolandschuetz.at>
 * @version       Bancha Scaffold v PRECOMPILER_ADD_BANCHA_SCAFFOLD_RELEASE_VERSION
 *
 * For more information go to http://scaffold.bancha.io
 */

describe("Bancha.scaffold.Util tests",function() {
    var util = Bancha.scaffold.Util;

    it("should pass all Bancha.scaffold.Util.toFirstUpper tests", function() {
        expect('User').toEqual(util.toFirstUpper('user'));
        expect('UserName').toEqual(util.toFirstUpper('userName'));
    });

    it("should pass all Bancha.scaffold.Util.humanize tests", function() {

        // first upper case
        expect('User').toEqual(util.humanize('user'));

        // ids
        expect('User').toEqual(util.humanize('user_id'));

        // underscores
        expect('User name').toEqual(util.humanize('user_name'));
        expect('Name with many spaces').toEqual(util.humanize('name_with_many_spaces'));

        // camel case
        expect('User name').toEqual(util.humanize('userName'));
        expect('Name with many spaces').toEqual(util.humanize('nameWithManySpaces'));

        // shouldn't change normal text
        expect('John Smith').toEqual(util.humanize('John Smith'));
        expect('This is a normal text with spaces, Upper case words and all UPPER CASE words!'
               ).toEqual(util.humanize('This is a normal text with spaces, Upper case words '+
               'and all UPPER CASE words!'));
    });

    it("should humanize class names", function() {
        // Standard namespaced and not namespaced
        expect('User').toEqual(util.humanizeClassName('Bancha.model.User'));
        expect('User').toEqual(util.humanizeClassName('Bancha.User'));
        expect('User').toEqual(util.humanizeClassName('User'));

        // check humanizing part
        expect('Awesome class').toEqual(util.humanizeClassName('Bancha.model.AwesomeClass'));
    });

    it("should replace button placeholder from an button config", function() {

        expect().toEqual(util.replaceButtonPlaceHolders()); //undefined
        expect([]).toEqual(util.replaceButtonPlaceHolders([])); //empty

        var config = {
            createButtonConfig: {
                myCreate: true
            },
            resetButtonConfig: {
                myReset: true
            },
            saveButtonConfig: {
                mySave: true
            },
            onCreate: function(a) {},
            onReset: function(b) {},
            onSave: function(c) {}
        };
        var scope =  {
            scoped:true
        };

        // test create button
        var expected = ['->',{
            myCreate: true,
            scope: scope,
            handler: config.onCreate
        }];
        expect(util.replaceButtonPlaceHolders(['->','create'], config, scope)).toEqual(expected);

        // test reset button
        expected.push({
            myReset: true,
            scope: scope,
            handler: config.onReset
        });
        expect(util.replaceButtonPlaceHolders(['->','create','reset'], config, scope)).toEqual(expected);

        // test save button
        expected.push({
            mySave: true,
            scope: scope,
            handler: config.onSave
        });
        expect(util.replaceButtonPlaceHolders(['->','create','reset','save'], config, scope)).toEqual(expected);

        // test with only the save button
        expected = [expected[3]];
        expect(expected).toEqual(util.replaceButtonPlaceHolders(['save'], config, scope));

        // test support for custom configs
        expected.push({
            myCustom: 'button-config'
        });
        expect(util.replaceButtonPlaceHolders(['save', {myCustom: 'button-config'}], config, scope)).toEqual(expected);
    });

    it("should inject buttons scopes for #replaceButtonPlaceHolders", function() {
        var input = [{
            myButton: true,
            scope: 'scaffold-scope-me'
        }];
        var scope =  {
            scoped:true
        };
        var expected = [{
            myButton: true,
            scope: {
                scoped:true
            }
        }];
        expect(util.replaceButtonPlaceHolders(input, {}, scope)).toEqual(expected);
    });

    it("should return a boolean when calling isModel, given a model or model name", function() {
        // return null if model doesn't exist
        expect(util.isModel(null)).toBeFalsy();
        expect(util.isModel('RANDOM_NONSENSE')).toBeFalsy();

        // return the class is a model is given
        Ext.define('Bancha.model.UtilSpecTestModel1', {
            extend: 'Ext.data.Model'
        });
        expect(util.isModel('Bancha.model.UtilSpecTestModel1')).toBeTruthy();
        expect(util.isModel(Bancha.model.UtilSpecTestModel1)).toBeTruthy();

        // return null if a class, but not a model
        Ext.define('Bancha.model.UtilSpecTestClass1', {
        });
        expect(util.isModel('Bancha.model.UtilSpecTestClass1')).toBeFalsy();
        expect(util.isModel(Bancha.model.UtilSpecTestClass1)).toBeFalsy();
    });

    it("should return a model given when calling getModel, given a model or model name", function() {
        // return null if model doesn't exist
        expect(Ext.Function.bind(util.getModel, util, [null])).toThrow();
        expect(Ext.Function.bind(util.getModel, util, ['RANDOM_NONSENSE'])).toThrow();

        // return the class is a model is given
        Ext.define('Bancha.model.UtilSpecTestModel2', {
            extend: 'Ext.data.Model'
        });
        expect(util.getModel('Bancha.model.UtilSpecTestModel2')).toEqual(Bancha.model.UtilSpecTestModel2);
        expect(util.getModel(Bancha.model.UtilSpecTestModel2)).toEqual(Bancha.model.UtilSpecTestModel2);

        // return null if a class, but not a model
        Ext.define('Bancha.model.UtilSpecTestClass2', {
        });
        expect(Ext.Function.bind(util.getModel, util, ['Bancha.model.UtilSpecTestClass2'])).toThrow();
        expect(Ext.Function.bind(util.getModel, util, [Bancha.model.UtilSpecTestClass2])).toThrow();
    });

});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import graphql from 'graphql';
import Helmet from 'react-helmet';
import styled from 'styled-components';
import EditBtn from '../components/EditBtn';
import Tags from '../components/Tags';
import { getStructuredData } from '../structuredData';
import CleanTime from '../components/Time';
import Comments from '../components/Comments';
import Posts from '../components/Posts';
import AnchorJS from 'anchor-js';

const Time = styled(CleanTime)`
  text-align: center;
  font-size: ${props => props.theme.blog.post.header.time.fontSize};
  font-weight: bold;
  color: ${props => props.theme.blog.post.header.time.color};
  width: 100%;
  display: block;
`;

const Post = styled.article`
  margin: ${props => props.theme.blog.post.margin};
  padding: ${props => props.theme.blog.post.padding};
`;

const H1 = styled.h1`
  padding-bottom: 0;
  text-align: center;
  font-size: ${props => props.theme.blog.post.header.fontSize};
`;

const Content = styled.section`
  margin: 0 0 ${({ theme }) => theme.scale(6)} 0;

  code {
    color: ${props => props.theme.blog.post.content.code.color};
    font-size: ${props => props.theme.blog.post.content.code.fontSize};
    margin: ${props => props.theme.blog.post.content.code.margin};
    padding: ${props => props.theme.blog.post.content.code.padding};
    background-color: ${props => props.theme.blog.post.content.code.backgroundColor};
    border-radius: ${props => props.theme.blog.post.content.code.borderRadius};
  }

  .gatsby-highlight{
    margin:${props => props.theme.blog.post.content.highlight.margin};
    padding:${props => props.theme.blog.post.content.highlight.padding};
    background-color: ${props => props.theme.blog.post.content.highlight.backgroundColor};
    display: flex;
    border-radius: ${props => props.theme.blog.post.content.highlight.borderRadius};
    overflow: auto;

    code {
      color: ${props => props.theme.blog.post.content.highlight.code.color};
    }
  }

  a{
    color: ${props => props.theme.blog.post.content.a.color};
  }

  h1{
    margin:${props => props.theme.blog.post.content.h1.margin};
    padding:${props => props.theme.blog.post.content.h1.padding};
    font-size:${props => props.theme.blog.post.content.h1.fontSize};
  }

  h2{
    margin:${props => props.theme.blog.post.content.h2.margin};
    padding:${props => props.theme.blog.post.content.h2.padding};
    font-size:${props => props.theme.blog.post.content.h2.fontSize};
  }

  h3{
    margin:${props => props.theme.blog.post.content.h3.margin};
    padding:${props => props.theme.blog.post.content.h3.padding};
    font-size:${props => props.theme.blog.post.content.h3.fontSize};
  }

  h4{
    margin:${props => props.theme.blog.post.content.h4.margin};
    padding:${props => props.theme.blog.post.content.h4.padding};
    font-size:${props => props.theme.blog.post.content.h4.fontSize};
  }

  h5{
    margin:${props => props.theme.blog.post.content.h5.margin};
    padding:${props => props.theme.blog.post.content.h5.padding};
    font-size:${props => props.theme.blog.post.content.h5.fontSize};
  }

  h6{
    margin:${props => props.theme.blog.post.content.h6.margin};
    padding:${props => props.theme.blog.post.content.h6.padding};
    font-size:${props => props.theme.blog.post.content.h6.fontSize};
  }

  p{
    margin:${props => props.theme.blog.post.content.p.margin};
    padding:${props => props.theme.blog.post.content.p.padding};
    font-size: ${props => props.theme.p.fontSize};
    line-height: ${props => props.theme.p.lineHeight};
  }

  & > p:first-of-type::first-letter {
      font-size: ${props => props.theme.p.firstLetter.fontSize};
      color: ${props => props.theme.p.firstLetter.color};
      float: left;
      line-height: ${props => props.theme.p.firstLetter.lineHeight};
      padding: ${props => props.theme.p.firstLetter.padding};
      margin: ${props => props.theme.p.firstLetter.margin};
  }

  strong{
    font-weight: bold;
  }

  ul, ol {
    margin:${props => props.theme.blog.post.content.ul.margin};
    padding:${props => props.theme.blog.post.content.ul.padding};
    font-size:${props => props.theme.blog.post.content.ul.fontSize};
  }

  ul {
    list-style: disc;
  }

  ol {
    list-style: decimal;
  }

  li {
    padding-top: 1rem;
  }

  blockquote {
    font-style: italic;
    margin: 0;
    padding: ${({ theme }) => theme.scale(3)};
    position: relative;
    text-align: center;
    color: ${({ theme }) => theme.colors.white};
  }

  blockquote:before {
    line-height: 1.45;
    display: block;
    content: "\\201C";
    position: absolute;
    top: -${({ theme }) => theme.scale(-4)};
    left: -${({ theme }) => theme.scale(1)};
    font-size: ${({ theme }) => theme.scale(10)};
    color: ${({ theme }) => theme.colors.white};
  }

  blockquote:after {
    display: block;
    content: "\\201D";
    position: absolute;
    bottom: -${({ theme }) => theme.scale(6)};
    right: ${({ theme }) => theme.scale(1)};
    font-size: ${({ theme }) => theme.scale(10)};
    color: ${({ theme }) => theme.colors.white};
  }

  blockquote cite {
    color: ${({ theme }) => theme.colors.blue};
    font-size: ${({ theme }) => theme.scale(-1)};
    display: block;
  }

  blockquote cite:before {
    content: "\\2014 \\2009";
  }

  img {
    max-width: 100%;
  }
`;

const Iframe = styled.iframe`
  width: 100%;
  max-width: 40rem;
  height: 20rem;
  margin: auto;
  display: block;
`;

const getYoutube = (markdownRemark) => {
  const youtubeId = markdownRemark.frontmatter.youtubeId;
  return youtubeId
    ? (

    )
    : null;
};

class BlogPostRoute extends React.PureComponent {

  componentDidMount(){
    const anchors = new AnchorJS();
    anchors.add('h1, h2');
  }

  render(){
    const { markdownRemark } = this.props.data;
    const { langKey } = this.props.pathContext;
    const youtube = getYoutube(markdownRemark);
    const structuredData = getStructuredData(markdownRemark);
    const url = `https://angeloocana.com${markdownRemark.fields.slug}`;

    const tags = (
      <Tags tags={markdownRemark.fields.tagSlugs} />
    );

    return (
      <Post>
        <Helmet
          title={`${markdownRemark.frontmatter.title}`}
          meta={[{ name: 'description', content: markdownRemark.excerpt }]}
        />


<commit_before>exports.up = function(knex, Promise) {
  return knex.schema.createTable('teams', function(table) {
    table.increments('id').primary().index();
    table.string('name').notNullable().index();
    table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
    table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
  })
  .then(() => {
    return knex.schema.createTable('action_types', function(table) {
      table.bigIncrements('id').primary().index();
      table.string('code').notNullable().unique().index();
      table.string('name').notNullable();
      table.integer('value').unsigned().notNullable();
      table.integer('cooldown').unsigned().notNullable(); // ms

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('users', function(table) {
      table.bigIncrements('id').primary().index();
      table.string('uuid').notNullable().unique().index();
      table.string('name').notNullable();
      table.integer('team_id').unsigned().notNullable().index();
      table.foreign('team_id')
        .references('id')
        .inTable('teams')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('actions', function(table) {
      table.bigIncrements('id').primary().index();

      table.integer('user_id').unsigned().index();
      table.foreign('user_id')
        .references('id')
        .inTable('users')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.integer('team_id').unsigned().notNullable();
      table.foreign('team_id')
        .references('id')
        .inTable('teams')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.specificType('location', 'point').index('actions_index_location', 'GIST');
      table.integer('action_type_id').unsigned().notNullable();
      table.foreign('action_type_id')
        .references('id')
        .inTable('action_types')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.string('image_path');
      table.string('text', 151);

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('feed_items', function(table) {
      table.bigIncrements('id').primary().index();

      // Null for 'system' user
      table.integer('user_id').unsigned().index();
      table.foreign('user_id')
        .references('id')
        .inTable('users')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.specificType('location', 'point').index('feed_items_index_location', 'GIST');

      table.string('image_path');
      table.string('text', 151)
      // TODO: Should have IN constraint ('TEXT', 'IMAGE', 'CHECK_IN')
      table.string('type', 10);

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('actions')
  .then(() => {
    return knex.schema.dropTable('action_types');
  })
  .then(() => {
    return knex.schema.dropTable('users');
  })
  .then(() => {
    return knex.schema.dropTable('teams');
  })
  .then(() => {
    return knex.schema.dropTable('feed');
  });
};
<commit_msg>Added aggregated column to actions table<commit_after>exports.up = function(knex, Promise) {
  return knex.schema.createTable('teams', function(table) {
    table.increments('id').primary().index();
    table.string('name').notNullable().index();
    table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
    table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
  })
  .then(() => {
    return knex.schema.createTable('action_types', function(table) {
      table.bigIncrements('id').primary().index();
      table.string('code').notNullable().unique().index();
      table.string('name').notNullable();
      table.integer('value').unsigned().notNullable();
      table.integer('cooldown').unsigned().notNullable(); // ms

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('users', function(table) {
      table.bigIncrements('id').primary().index();
      table.string('uuid').notNullable().unique().index();
      table.string('name').notNullable();
      table.integer('team_id').unsigned().notNullable().index();
      table.foreign('team_id')
        .references('id')
        .inTable('teams')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('actions', function(table) {
      table.bigIncrements('id').primary().index();

      table.integer('user_id').unsigned().index();
      table.foreign('user_id')
        .references('id')
        .inTable('users')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.integer('team_id').unsigned().notNullable();
      table.foreign('team_id')
        .references('id')
        .inTable('teams')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.specificType('location', 'point').index('actions_index_location', 'GIST');
      table.integer('action_type_id').unsigned().notNullable();
      table.foreign('action_type_id')
        .references('id')
        .inTable('action_types')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.string('image_path');
      table.string('text', 151);
      // Has action been aggregated to feed
      table.boolean('aggregated').notNullable().defaultTo(false);

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  })
  .then(() => {
    return knex.schema.createTable('feed_items', function(table) {
      table.bigIncrements('id').primary().index();

      // Null for 'system' user
      table.integer('user_id').unsigned().index();
      table.foreign('user_id')
        .references('id')
        .inTable('users')
        .onDelete('RESTRICT')
        .onUpdate('CASCADE');

      table.specificType('location', 'point').index('feed_items_index_location', 'GIST');

      table.string('image_path');
      table.string('text', 151)
      // TODO: Should have IN constraint ('TEXT', 'IMAGE', 'CHECK_IN')
      table.string('type', 10);

      table.timestamp('created_at').index().notNullable().defaultTo(knex.fn.now());
      table.timestamp('updated_at').index().notNullable().defaultTo(knex.fn.now());
    });
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('actions')
  .then(() => {
    return knex.schema.dropTable('action_types');
  })
  .then(() => {
    return knex.schema.dropTable('users');
  })
  .then(() => {
    return knex.schema.dropTable('teams');
  })
  .then(() => {
    return knex.schema.dropTable('feed');
  });
};
<|endoftext|>


<commit_before>/* @flow */

import React from 'react';
import {
    TouchableHighlight,
    TouchableWithoutFeedback,
    View
} from 'react-native';

import AbstractContainer from '../AbstractContainer';

/**
 * Represents a container of React Native/mobile {@link Component} children.
 *
 * @extends AbstractContainer
 */
export default class Container extends AbstractContainer {
    /**
     * {@code Container} component's property types.
     *
     * @static
     */
    static propTypes = AbstractContainer.propTypes;

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        // eslint-disable-next-line prefer-const
        let { onClick, style, touchFeedback, visible, ...props } = this.props;

        // onClick & touchFeedback
        (typeof touchFeedback === 'undefined') && (touchFeedback = onClick);

        // visible

        // The following property is responsible to hide/show this Container by
        // setting its size to 0. This will make the component not visible, but
        // it won't be destroyed, all its state is preserved. This is
        // intentional.
        // TODO: replace with display: 'none', supported in RN >= 0.43.
        const hidden = visible === false;  // true / undefined

        if (hidden) {
            style = {
                ...style,
                height: 0,
                width: 0
            };
        }

        // eslint-disable-next-line object-property-newline
        let component = super._render(View, { ...props, style });

        if (!hidden && (touchFeedback || onClick)) {
            const parentType
                = touchFeedback ? TouchableHighlight : TouchableWithoutFeedback;
            const parentProps = {};

            onClick && (parentProps.onPress = onClick);

            component = React.createElement(parentType, parentProps, component);
        }

        return component;
    }
}
<commit_msg>[RN] Simplify hiding Container components<commit_after>/* @flow */

import React from 'react';
import {
    TouchableHighlight,
    TouchableWithoutFeedback,
    View
} from 'react-native';

import AbstractContainer from '../AbstractContainer';

/**
 * Represents a container of React Native/mobile {@link Component} children.
 *
 * @extends AbstractContainer
 */
export default class Container extends AbstractContainer {
    /**
     * {@code Container} component's property types.
     *
     * @static
     */
    static propTypes = AbstractContainer.propTypes;

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        const {
            onClick,
            touchFeedback = onClick,
            visible = true,
            ...props
        } = this.props;

        // visible
        if (!visible) {
            // Intentionally hide this Container without destroying it.
            // TODO Replace with display: 'none' supported in RN >= 0.43.
            props.style = {
                ...props.style,
                height: 0,
                width: 0
            };
        }

        let element = super._render(View, props);

        // onClick & touchFeedback
        if (visible && (onClick || touchFeedback)) {
            element = React.createElement(
                touchFeedback ? TouchableHighlight : TouchableWithoutFeedback,
                { onPress: onClick },
                element
            );
        }

        return element;
    }
}
<|endoftext|>


<commit_before>import React from "react"

const displayName = "HomePageHeader"

function Header() {
  return

Moeen Farooq Basra

Master in Information Technology

Fullstack Developer at
        Awok.com

{`{ PHP, JavaScript, Python, MySQL, MongoDB }`}

}
Header.displayName = displayName

export default Header
<commit_msg>update profile pic path<commit_after>import React from "react"

const displayName = "HomePageHeader"

function Header() {
  return

Moeen Farooq Basra

Master in Information Technology

Fullstack Developer at
        Awok.com

{`{ PHP, JavaScript, Python, MySQL, MongoDB }`}

}
Header.displayName = displayName

export default Header
<|endoftext|>


<commit_before>//-*- x-counterpart: ../../../../../../source/lib/app/addons/ac/assets.common.js; -*-
/*
 * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, nomen:true, node:true*/
/*global YUI*/

YUI().use('mojito-assets-addon', 'test', function(Y, NAME) {

    var suite = new Y.Test.Suite(NAME + ' tests @@'),
        cases = {},
        A = Y.Assert,
        AA = Y.ArrayAssert;

    cases = {
        name: 'basics',

        setUp: function() {
            var init = {
                    instance: {
                        type: 'foo',
                        config: {
                            assets: {}
                        }
                    }
                };

            addon = new Y.mojito.addons.ac.assets(init);
            YUI.namespace('_mojito._cache.compiled');
        },

        tearDown: function() {
            addon = null;
        },

        'test one top css with type and location': function() {
            var css, result;

            css = '';
            addon.addAsset('css', 'top', css);
            result = addon.getAssets('top');

            A.isObject(result.top, 'missing top block');
            A.isObject(result.top.css, 'missing top.css block');
            A.isArray(result.top.css, 'top.css should be an array');
            A.areSame(1, result.top.css.length, 'bad top.css array length');
            A.areSame(css, result.top.css[0], 'bad css value');
        },

        'test inlined css is deduped': function() {
            var othertest = 'test one top css with type and location',
                css = '';

            this[othertest]();

            A.areSame(1, addon.getAssets('top').top.css.length);
            addon.addAsset('css', 'top', css);
            A.areSame(1, addon.getAssets('top').top.css.length);
        },

//         'test inlined css get wrapped in style tags': function() {
//             var css = '.foo { color:red; }',
//                 expected = '',
//                 tmp;
//
//             YUI.namespace('_mojito._cache.compiled.css.inline');
//             tmp = YUI._mojito._cache.compiled.css.inline[id]
//
//             addon.addAsset('css', 'top', css);
//             A.areSame(expected, addon.getAssets('top').top.css[0]);
//         },

        'test image preloading (for lcov, really)': function() {
            var imgs = [
                'http://yahoo.com',
                'http://yahoo.com'
            ];
            addon.preLoadImages(imgs);
        },

        'test one bottom css with type and location': function() {
            var css = '';

            addon.addAsset('css', 'bottom', css);

            var res = addon.getAssets('bottom');

            A.isObject(res.bottom, 'missing bottom block');
            A.isUndefined(res.top, 'bottom.css should not exist');
            A.isObject(res.bottom.css, 'missing bottom.css block');
            A.isArray(res.bottom.css, 'bottom.css should be an array');
            A.areSame(1, res.bottom.css.length, 'bad bottom.css array length');
            A.areSame(css, res.bottom.css[0], 'bad css value');

        },

        'test two css with type and location': function() {
            var css1 = '';
            var css2 = '';

            addon.addAsset('css', 'top', css1);
            addon.addAsset('css', 'top', css2);

            var res = addon.getAssets('top');

            A.areSame(2, res.top.css.length, 'bad css.top array length');
            A.areSame(css1, res.top.css[0], 'bad css value');
            A.areSame(css2, res.top.css[1], 'bad css value');

        },

        'test two css with type and location, one top, one bottom': function() {
            var css1 = '';
            var css2 = '';

            addon.addAsset('css', 'top', css1);
            addon.addAsset('css', 'bottom', css2);

            var t = addon.getAssets('top');
            var b = addon.getAssets('bottom');

            A.areSame(1, t.top.css.length, 'bad css.top array length');
            A.areSame(1, t.top.css.length, 'bad css.bottom array length');
            A.areSame(css1, t.top.css[0], 'bad top css value');
            A.areSame(css2, b.bottom.css[0], 'bad bottom css value');

        },

        'test addCss() with location override': function() {
            var css = 'css';

            addon.addCss(css, 'bottom');

            var btm = addon.getAssets('bottom');

            A.areSame(1, btm.bottom.css.length, 'bad bottom array length');
            A.areSame(css, btm.bottom.css[0], 'bad css');
        },

        'test addCss() with no location provides default "top"': function() {
            var css = 'css';

            addon.addCss(css);

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(b.bottom, 'bottom should not be defined');
            A.areSame(1, t.top.css.length, 'bad top array length');
            A.areSame(css, t.top.css[0], 'badd css');
        },

        'test addBlob() with location override': function() {

            var blob = '
<span>This is escaped markup</span>
';

            addon.addBlob(blob, 'bottom');

            var btm = addon.getAssets('bottom');

            A.areSame(1, btm.bottom.blob.length, 'bad bottom array length');
            A.areSame(blob, btm.bottom.blob[0], 'bad blob');
        },

        'test addBlob() with no location provides default "bottom"': function() {

            var blob = '
<span>This is escaped markup</span>
';

            addon.addBlob(blob)

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(t.top, 'top should not be defined');
            A.areSame(1, b.bottom.blob.length, 'bad bottom array length');
            A.areSame(blob, b.bottom.blob[0], 'bad blob');
        },

        'test addJs() with location override': function() {
            var js = 'js';

            addon.addJs(js, 'top');

            var t = addon.getAssets('top');

            A.areSame(1, t.top.js.length, 'bad bottom array length');
            A.areSame(js, t.top.js[0], 'bad js');
        },

        'test addJs() with no location provides default "bottom"': function() {
            var js = 'js';

            addon.addJs(js);

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(t.top, 'top should not be defined');
            A.areSame(1, b.bottom.js.length, 'bad bottom array length');
            A.areSame(js, b.bottom.js[0], 'bad js');
        },

        'test addCss() and addJs()': function() {
            var js1 = 'js1', js2 = 'js2',
                css1 = 'css1', css2 = 'css2';

            addon.addJs(js1);
            addon.addCss(css1);
            addon.addJs(js2);
            addon.addCss(css2);

            var t = addon.getAssets('top');
            var b = addon.getAssets('bottom');

            A.isUndefined(b.bottom.css, 'should not have bottom css');
            AA.itemsAreEqual([js1, js2], b.bottom.js, 'bad js values');
            A.isUndefined(t.top.js, 'should not have top js');
            AA.itemsAreEqual([css1, css2], t.top.css, 'bad css values');
        },

        'test assets mix properly': function() {

            addon.addJs('jsf1', 'top');
            addon.addJs('jsf2', 'top');

            addon.addCss('cssf1');      // css defaults to top
            addon.addJs('jsf3');        // js defaults to bottom

            var to = {
                    top: {
                        js: ['jst1','jst2'],
                        css: ['csst1','csst2','csst3']
                    },
                    bottom: {
                        js: ['jsb1']
                    }
                };

            var expected = {
                    top: {
                        js: ['jst1','jst2','jsf1','jsf2'],
                        css: ['csst1','csst2','csst3','cssf1']
                    },
                    bottom: {
                        js: ['jsb1', 'jsf3']
                    }
                };

            addon.mergeMetaInto({assets: to});

            AA.itemsAreEqual(expected.top.js, to.top.js);
            AA.itemsAreEqual(expected.top.css, to.top.css);
            AA.itemsAreEqual(expected.bottom.js, to.bottom.js);
            A.isUndefined(to.bottom.css, 'bad bottom.css');
        },

        'test assets unique properly': function() {

            // New values which should be added to the 'to' target.
            addon.addJs('jsf1', 'top');
            addon.addJs('jsf2', 'top');

            addon.addCss('cssf1');      // css defaults to top
            addon.addJs('jsf3');        // js defaults to bottom

            // Duplicates of values in 'to', should be eliminated, not added.
            addon.addJs('jsb1');
            addon.addCss('csst1');

            var to = {
                top: {
                    js: ['jst1','jst2'],
                    css: ['csst1','csst2','csst3']
                },
                bottom: {
                    js: ['jsb1']
                }
            };

            var expected = {
                top: {
                    js: ['jst1','jst2','jsf1','jsf2'],
                    css: ['csst1','csst2','csst3','cssf1']
                },
                bottom: {
                    js: ['jsb1', 'jsf3']
                }
            };

            addon.mergeMetaInto({assets: to});

            AA.itemsAreEqual(expected.top.js, to.top.js);
            AA.itemsAreEqual(expected.top.css, to.top.css);
            AA.itemsAreEqual(expected.bottom.js, to.bottom.js);
            A.isUndefined(to.bottom.css, 'bad bottom.css');
        },

        'addAsset() should return undefined if no content': function() {
            A.isUndefined(addon.addAsset()); // for coverage, func always void
        },

        'addAsset() should normalize relative uris from assetsRoot config': function() {
            var init = {
                    instance: {
                        assetsRoot: '/abc/def',
                        config: {}
                    }
                },
                addon = new Y.mojito.addons.ac.assets(init),
                expected = init.instance.assetsRoot + '/foo.js';

            addon.addAsset('js', 'top', './foo.js');

            A.areSame(expected, addon.getAssets().top.js[0]);
        },

        'addAsset() should dedupe': function() {
            var othertest = 'addAsset() should normalize relative uris from assetsRoot config';
            this[othertest]();

            addon.addAsset('js', 'top', './foo');// add again
            addon.addAsset('js', 'top', './foo');// add again

            A.areEqual(1, addon.getAssets().top.js.length);
        },

        'test asset initialization via constructor': function() {
            var init = {
                    instance: {
                        config: {}
                    }
                },
                addon,
                actual,
                expected;

            init.instance.config.assets = {
                top: {
                    js: ['jst1','jst2'],
                    css: ['csst1','csst2','csst3']
                },
                bottom: {
                    js: ['jsb1']
                }
            };

            expected = Y.merge(init.instance.config.assets); // copy

            addon = new Y.mojito.addons.ac.assets(init);
            actual = addon.getAssets();

            AA.itemsAreEqual(expected.top.js, actual.top.js);

            expected.foo = 9; // prove we made a copy
            A.areNotSame(expected.foo, actual.foo);

        },

        'test inline css': function() {
            YUI._mojito._cache.compiled.css = {
                'inline': {
                    'my-path': 'file-contents'
                }
            };
            addon.context = { runtime: 'client' };
            addon.mojitType = 'fruit';
            addon.addAsset('css', 'top', 'my-path');

            var results = addon.getAssets();
            A.isNotUndefined(results);
            var expected = { top: { blob: [ '\n' ] } };

            A.areEqual(Y.JSON.stringify(expected), Y.JSON.stringify(results));
        }
    };

    suite.add(new Y.Test.Case(cases));
    Y.Test.Runner.add(suite);

});
<commit_msg>clean up test suite name<commit_after>//-*- x-counterpart: ../../../../../../source/lib/app/addons/ac/assets.common.js; -*-
/*
 * Copyright (c) 2011-2012, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint anon:true, sloppy:true, nomen:true, node:true*/
/*global YUI*/

YUI().use('mojito-assets-addon', 'test', function(Y, NAME) {

    var suite = new Y.Test.Suite('mojito-assets-addon tests'),
        cases = {},
        A = Y.Assert,
        AA = Y.ArrayAssert;

    cases = {
        name: 'basics',

        setUp: function() {
            var init = {
                    instance: {
                        type: 'foo',
                        config: {
                            assets: {}
                        }
                    }
                };

            addon = new Y.mojito.addons.ac.assets(init);
            YUI.namespace('_mojito._cache.compiled');
        },

        tearDown: function() {
            addon = null;
        },

        'test one top css with type and location': function() {
            var css, result;

            css = '';
            addon.addAsset('css', 'top', css);
            result = addon.getAssets('top');

            A.isObject(result.top, 'missing top block');
            A.isObject(result.top.css, 'missing top.css block');
            A.isArray(result.top.css, 'top.css should be an array');
            A.areSame(1, result.top.css.length, 'bad top.css array length');
            A.areSame(css, result.top.css[0], 'bad css value');
        },

        'test inlined css is deduped': function() {
            var othertest = 'test one top css with type and location',
                css = '';

            this[othertest]();

            A.areSame(1, addon.getAssets('top').top.css.length);
            addon.addAsset('css', 'top', css);
            A.areSame(1, addon.getAssets('top').top.css.length);
        },

//         'test inlined css get wrapped in style tags': function() {
//             var css = '.foo { color:red; }',
//                 expected = '',
//                 tmp;
//
//             YUI.namespace('_mojito._cache.compiled.css.inline');
//             tmp = YUI._mojito._cache.compiled.css.inline[id]
//
//             addon.addAsset('css', 'top', css);
//             A.areSame(expected, addon.getAssets('top').top.css[0]);
//         },

        'test image preloading (for lcov, really)': function() {
            var imgs = [
                'http://yahoo.com',
                'http://yahoo.com'
            ];
            addon.preLoadImages(imgs);
        },

        'test one bottom css with type and location': function() {
            var css = '';

            addon.addAsset('css', 'bottom', css);

            var res = addon.getAssets('bottom');

            A.isObject(res.bottom, 'missing bottom block');
            A.isUndefined(res.top, 'bottom.css should not exist');
            A.isObject(res.bottom.css, 'missing bottom.css block');
            A.isArray(res.bottom.css, 'bottom.css should be an array');
            A.areSame(1, res.bottom.css.length, 'bad bottom.css array length');
            A.areSame(css, res.bottom.css[0], 'bad css value');

        },

        'test two css with type and location': function() {
            var css1 = '';
            var css2 = '';

            addon.addAsset('css', 'top', css1);
            addon.addAsset('css', 'top', css2);

            var res = addon.getAssets('top');

            A.areSame(2, res.top.css.length, 'bad css.top array length');
            A.areSame(css1, res.top.css[0], 'bad css value');
            A.areSame(css2, res.top.css[1], 'bad css value');

        },

        'test two css with type and location, one top, one bottom': function() {
            var css1 = '';
            var css2 = '';

            addon.addAsset('css', 'top', css1);
            addon.addAsset('css', 'bottom', css2);

            var t = addon.getAssets('top');
            var b = addon.getAssets('bottom');

            A.areSame(1, t.top.css.length, 'bad css.top array length');
            A.areSame(1, t.top.css.length, 'bad css.bottom array length');
            A.areSame(css1, t.top.css[0], 'bad top css value');
            A.areSame(css2, b.bottom.css[0], 'bad bottom css value');

        },

        'test addCss() with location override': function() {
            var css = 'css';

            addon.addCss(css, 'bottom');

            var btm = addon.getAssets('bottom');

            A.areSame(1, btm.bottom.css.length, 'bad bottom array length');
            A.areSame(css, btm.bottom.css[0], 'bad css');
        },

        'test addCss() with no location provides default "top"': function() {
            var css = 'css';

            addon.addCss(css);

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(b.bottom, 'bottom should not be defined');
            A.areSame(1, t.top.css.length, 'bad top array length');
            A.areSame(css, t.top.css[0], 'badd css');
        },

        'test addBlob() with location override': function() {

            var blob = '
<span>This is escaped markup</span>
';

            addon.addBlob(blob, 'bottom');

            var btm = addon.getAssets('bottom');

            A.areSame(1, btm.bottom.blob.length, 'bad bottom array length');
            A.areSame(blob, btm.bottom.blob[0], 'bad blob');
        },

        'test addBlob() with no location provides default "bottom"': function() {

            var blob = '
<span>This is escaped markup</span>
';

            addon.addBlob(blob)

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(t.top, 'top should not be defined');
            A.areSame(1, b.bottom.blob.length, 'bad bottom array length');
            A.areSame(blob, b.bottom.blob[0], 'bad blob');
        },

        'test addJs() with location override': function() {
            var js = 'js';

            addon.addJs(js, 'top');

            var t = addon.getAssets('top');

            A.areSame(1, t.top.js.length, 'bad bottom array length');
            A.areSame(js, t.top.js[0], 'bad js');
        },

        'test addJs() with no location provides default "bottom"': function() {
            var js = 'js';

            addon.addJs(js);

            var b = addon.getAssets('bottom');
            var t = addon.getAssets('top');

            A.isUndefined(t.top, 'top should not be defined');
            A.areSame(1, b.bottom.js.length, 'bad bottom array length');
            A.areSame(js, b.bottom.js[0], 'bad js');
        },

        'test addCss() and addJs()': function() {
            var js1 = 'js1', js2 = 'js2',
                css1 = 'css1', css2 = 'css2';

            addon.addJs(js1);
            addon.addCss(css1);
            addon.addJs(js2);
            addon.addCss(css2);

            var t = addon.getAssets('top');
            var b = addon.getAssets('bottom');

            A.isUndefined(b.bottom.css, 'should not have bottom css');
            AA.itemsAreEqual([js1, js2], b.bottom.js, 'bad js values');
            A.isUndefined(t.top.js, 'should not have top js');
            AA.itemsAreEqual([css1, css2], t.top.css, 'bad css values');
        },

        'test assets mix properly': function() {

            addon.addJs('jsf1', 'top');
            addon.addJs('jsf2', 'top');

            addon.addCss('cssf1');      // css defaults to top
            addon.addJs('jsf3');        // js defaults to bottom

            var to = {
                    top: {
                        js: ['jst1','jst2'],
                        css: ['csst1','csst2','csst3']
                    },
                    bottom: {
                        js: ['jsb1']
                    }
                };

            var expected = {
                    top: {
                        js: ['jst1','jst2','jsf1','jsf2'],
                        css: ['csst1','csst2','csst3','cssf1']
                    },
                    bottom: {
                        js: ['jsb1', 'jsf3']
                    }
                };

            addon.mergeMetaInto({assets: to});

            AA.itemsAreEqual(expected.top.js, to.top.js);
            AA.itemsAreEqual(expected.top.css, to.top.css);
            AA.itemsAreEqual(expected.bottom.js, to.bottom.js);
            A.isUndefined(to.bottom.css, 'bad bottom.css');
        },

        'test assets unique properly': function() {

            // New values which should be added to the 'to' target.
            addon.addJs('jsf1', 'top');
            addon.addJs('jsf2', 'top');

            addon.addCss('cssf1');      // css defaults to top
            addon.addJs('jsf3');        // js defaults to bottom

            // Duplicates of values in 'to', should be eliminated, not added.
            addon.addJs('jsb1');
            addon.addCss('csst1');

            var to = {
                top: {
                    js: ['jst1','jst2'],
                    css: ['csst1','csst2','csst3']
                },
                bottom: {
                    js: ['jsb1']
                }
            };

            var expected = {
                top: {
                    js: ['jst1','jst2','jsf1','jsf2'],
                    css: ['csst1','csst2','csst3','cssf1']
                },
                bottom: {
                    js: ['jsb1', 'jsf3']
                }
            };

            addon.mergeMetaInto({assets: to});

            AA.itemsAreEqual(expected.top.js, to.top.js);
            AA.itemsAreEqual(expected.top.css, to.top.css);
            AA.itemsAreEqual(expected.bottom.js, to.bottom.js);
            A.isUndefined(to.bottom.css, 'bad bottom.css');
        },

        'addAsset() should return undefined if no content': function() {
            A.isUndefined(addon.addAsset()); // for coverage, func always void
        },

        'addAsset() should normalize relative uris from assetsRoot config': function() {
            var init = {
                    instance: {
                        assetsRoot: '/abc/def',
                        config: {}
                    }
                },
                addon = new Y.mojito.addons.ac.assets(init),
                expected = init.instance.assetsRoot + '/foo.js';

            addon.addAsset('js', 'top', './foo.js');

            A.areSame(expected, addon.getAssets().top.js[0]);
        },

        'addAsset() should dedupe': function() {
            var othertest = 'addAsset() should normalize relative uris from assetsRoot config';
            this[othertest]();

            addon.addAsset('js', 'top', './foo');// add again
            addon.addAsset('js', 'top', './foo');// add again

            A.areEqual(1, addon.getAssets().top.js.length);
        },

        'test asset initialization via constructor': function() {
            var init = {
                    instance: {
                        config: {}
                    }
                },
                addon,
                actual,
                expected;

            init.instance.config.assets = {
                top: {
                    js: ['jst1','jst2'],
                    css: ['csst1','csst2','csst3']
                },
                bottom: {
                    js: ['jsb1']
                }
            };

            expected = Y.merge(init.instance.config.assets); // copy

            addon = new Y.mojito.addons.ac.assets(init);
            actual = addon.getAssets();

            AA.itemsAreEqual(expected.top.js, actual.top.js);

            expected.foo = 9; // prove we made a copy
            A.areNotSame(expected.foo, actual.foo);

        },

        'test inline css': function() {
            YUI._mojito._cache.compiled.css = {
                'inline': {
                    'my-path': 'file-contents'
                }
            };
            addon.context = { runtime: 'client' };
            addon.mojitType = 'fruit';
            addon.addAsset('css', 'top', 'my-path');

            var results = addon.getAssets();
            A.isNotUndefined(results);
            var expected = { top: { blob: [ '\n' ] } };

            A.areEqual(Y.JSON.stringify(expected), Y.JSON.stringify(results));
        }
    };

    suite.add(new Y.Test.Case(cases));
    Y.Test.Runner.add(suite);

});
<|endoftext|>


<commit_before>angular.module("routes", []).service('routes', ['$interpolate', function($interpolate) {
    var routes = {
        helpTextSearch: '/help/text-search/',
        contactUs: '/contact',
        submitQuery: '/export/submit-query',
        resultsPage: '/export/results',
        rnaView: '/rna/{{ upi }}',
        rnaViewWithTaxid: '/rna/{{upi}}/{{ taxid }}',
        apiPublicationsView: '/api/v1/rna/{{ upi }}/publications/{{ taxid }}',
        apiRnaView: '/api/v1/rna/{{ upi }}',
        apiGenomeLocationsView: '/api/v1/rna/{{ upi }}/genome-locations/{{ taxid }}',
        apiRfamHitsView: '/api/v1/rna/{{ upi }}/rfam-hits/{{ taxid }}',
        apiProteinTargetsView: '/api/v1/rna/{{ upi }}/protein-targets/{{ taxid }}',
        apiLncrnaTargetsView: '/api/v1/rna/{{ upi }}/lncrna-targets/{{ taxid }}',
        apiSequenceFeaturesView: '/api/v1/rna/{{ upi }}/sequence-features/{{ taxid }}',
        lineageView: '/rna/{{ upi }}/lineage',
        expertDbsApi: '/api/v1/expert-dbs/{{ expertDbName }}',
        expertDbStatsApi: '/api/v1/expert-db-stats/{{ expertDbName }}',
        textSearch: 'search',
        expertDbLogo: '/static/img/expert-db-logos/{{ expertDbName }}.png',
        apiSecondaryStructuresView: '/api/v1/rna/{{ upi }}/2d/{{ taxid }}',
        sequenceSearchSubmitJob: '/sequence-search/submit-job',
        sequenceSearchJobStatus: '/sequence-search/job-status/{{ jobId }}',
        sequenceSearchResults: '/sequence-search/job-results/{{ jobId }}',
        sequenceSearchInfernalJobStatus: '/sequence-search/infernal-job-status/{{ jobId }}',
        sequenceSearchInfernalResults: '/sequence-search/infernal-results/{{ jobId }}',
        apiEnsemblComparaView: '/api/v1/rna/{{ upi }}/ensembl-compara/{{ taxid }}',
        genomesApi: '/api/v1/genomes/{{ ensemblAssembly }}',
        proxy: '/api/internal/proxy?url={{ url }}',
        ebiSearch:
            '{{ ebiBaseUrl }}' +
            '?query={{ query }}' +
            '&format=json' +
            '&hlfields={{ hlfields }}' +
            '&facetcount={{ facetcount }}' +
            '&facetfields={{ facetfields }}' +
            '&facetdepth=10' +
            '&size={{ pagesize }}' +
            '&start={{ start }}' +
            '&sort={{ sort }}' +
            '&hlpretag=' +
            '&hlposttag='
        ,
        ebiMd5Lookup:
            '{{ ebiBaseUrl }}' +
            '?query={{ md5 }}' +
            '&fields=description' +
            '&format=json' +
            '&sort=boost:descending'
        ,
        ebiAutocomplete: 'http://www.ebi.ac.uk/ebisearch/ws/rest/RNAcentral/autocomplete?term={{ query }}&format=json',
        apiGoTermsView: '/api/v1/rna/{{ upi }}/go-annotations/{{ taxid }}',
        quickGoSummaryPage: 'https://www.ebi.ac.uk/QuickGO/term/{{ term_id }}',
        quickGoChart: 'https://www.ebi.ac.uk/QuickGO/services/ontology/{{ ontology }}/terms/{{ term_ids }}/chart?base64=true',
    };

    // apply $interpolate to each route template expression
    return Object.keys(routes)
          .map(function(key) { var output = {}; output[key] = $interpolate(routes[key]); return output })
          .reduce(function(result, keyValue ) { return _.extend(result, keyValue) } );
}]);
<commit_msg>Increase facetdepth<commit_after>angular.module("routes", []).service('routes', ['$interpolate', function($interpolate) {
    var routes = {
        helpTextSearch: '/help/text-search/',
        contactUs: '/contact',
        submitQuery: '/export/submit-query',
        resultsPage: '/export/results',
        rnaView: '/rna/{{ upi }}',
        rnaViewWithTaxid: '/rna/{{upi}}/{{ taxid }}',
        apiPublicationsView: '/api/v1/rna/{{ upi }}/publications/{{ taxid }}',
        apiRnaView: '/api/v1/rna/{{ upi }}',
        apiGenomeLocationsView: '/api/v1/rna/{{ upi }}/genome-locations/{{ taxid }}',
        apiRfamHitsView: '/api/v1/rna/{{ upi }}/rfam-hits/{{ taxid }}',
        apiProteinTargetsView: '/api/v1/rna/{{ upi }}/protein-targets/{{ taxid }}',
        apiLncrnaTargetsView: '/api/v1/rna/{{ upi }}/lncrna-targets/{{ taxid }}',
        apiSequenceFeaturesView: '/api/v1/rna/{{ upi }}/sequence-features/{{ taxid }}',
        lineageView: '/rna/{{ upi }}/lineage',
        expertDbsApi: '/api/v1/expert-dbs/{{ expertDbName }}',
        expertDbStatsApi: '/api/v1/expert-db-stats/{{ expertDbName }}',
        textSearch: 'search',
        expertDbLogo: '/static/img/expert-db-logos/{{ expertDbName }}.png',
        apiSecondaryStructuresView: '/api/v1/rna/{{ upi }}/2d/{{ taxid }}',
        sequenceSearchSubmitJob: '/sequence-search/submit-job',
        sequenceSearchJobStatus: '/sequence-search/job-status/{{ jobId }}',
        sequenceSearchResults: '/sequence-search/job-results/{{ jobId }}',
        sequenceSearchInfernalJobStatus: '/sequence-search/infernal-job-status/{{ jobId }}',
        sequenceSearchInfernalResults: '/sequence-search/infernal-results/{{ jobId }}',
        apiEnsemblComparaView: '/api/v1/rna/{{ upi }}/ensembl-compara/{{ taxid }}',
        genomesApi: '/api/v1/genomes/{{ ensemblAssembly }}',
        proxy: '/api/internal/proxy?url={{ url }}',
        ebiSearch:
            '{{ ebiBaseUrl }}' +
            '?query={{ query }}' +
            '&format=json' +
            '&hlfields={{ hlfields }}' +
            '&facetcount={{ facetcount }}' +
            '&facetfields={{ facetfields }}' +
            '&facetdepth=15' +
            '&size={{ pagesize }}' +
            '&start={{ start }}' +
            '&sort={{ sort }}' +
            '&hlpretag=' +
            '&hlposttag='
        ,
        ebiMd5Lookup:
            '{{ ebiBaseUrl }}' +
            '?query={{ md5 }}' +
            '&fields=description' +
            '&format=json' +
            '&sort=boost:descending'
        ,
        ebiAutocomplete: 'http://www.ebi.ac.uk/ebisearch/ws/rest/RNAcentral/autocomplete?term={{ query }}&format=json',
        apiGoTermsView: '/api/v1/rna/{{ upi }}/go-annotations/{{ taxid }}',
        quickGoSummaryPage: 'https://www.ebi.ac.uk/QuickGO/term/{{ term_id }}',
        quickGoChart: 'https://www.ebi.ac.uk/QuickGO/services/ontology/{{ ontology }}/terms/{{ term_ids }}/chart?base64=true',
    };

    // apply $interpolate to each route template expression
    return Object.keys(routes)
          .map(function(key) { var output = {}; output[key] = $interpolate(routes[key]); return output })
          .reduce(function(result, keyValue ) { return _.extend(result, keyValue) } );
}]);
<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import Socket from 'socket.io-client';
import Reflux from 'reflux';

const socket = Socket.connect();

const actions = Reflux.createActions(
  ['textfieldUpdated']
);

let timer = null;

const dummyData = [{
  label: 'Title',
  data: [
    {
      text: 'Test Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Hest Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Fest Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Gæst Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    }
  ]
},
  {
    label: 'Author',
    data: [
      {
        text: 'Test Hest',
        img: 'http://dummyimage.com/50x50/000/fff'
      },
      {
        text: 'Hest Hest',
        img: ''
      },
      {
        text: 'Fest Hest',
        img: ''
      },
      {
        text: 'Gæst Hest',
        img: ''
      }
    ]
  }];

const store = Reflux.createStore({
  listenables: [actions],

  _store: {
    data: []
  },

  init() {
    socket.on('getPopSuggestionsResponse', this.serviceResponse);
  },

  serviceResponse(data) {
    let _data = null;
    if (data.error) {
      console.error('PopSuggest responded with an error: ', data);
      _data = [];
    }
    else {
      _data = dummyData;
    }

    this._store.data = _data;
    this.trigger(this._store);
  },

  onTextfieldUpdated(value) {
    console.log('onTextfieldUpdated');
    socket.emit('getPopSuggestionsRequest', value);
  },

  getInitialState() {
    return this._store;
  }
});

var SearchField = React.createClass({
  mixins: [Reflux.connect(store)],

  render() {
    const AutoComplete = this.props.autocomplete;
    const text = this.state.text || '';
    const data = this.state.data || [];
    const autoCompleteVisible = (data.length >= 1 && text.length >= 1);

    return (

        <input type='text' placeholder='Søg og du skal finde' value={text} onChange={this._handleOnChange} onKeyUp={this._handleOnKeyUp} className={'search-input'}/>
        <AutoComplete data={data} visible={autoCompleteVisible}/>

    );
  },

  _handleOnChange(e) {
    const txt = e.target.value;
    this.setState({text: txt});
  },

  _handleOnKeyUp() {
    clearTimeout(timer);

    timer = setTimeout(() => {
      actions.textfieldUpdated(this.state.text);
    }, 250);
  },

  propTypes: {
    autocomplete: React.PropTypes.func.isRequired
  }
});

export default SearchField;
<commit_msg>fixed linting errors<commit_after>'use strict';
import React from 'react';
import Socket from 'socket.io-client';
import Reflux from 'reflux';

const socket = Socket.connect();

const actions = Reflux.createActions(
  ['textfieldUpdated']
);

let timer = null;

const dummyData = [{
  label: 'Title',
  data: [
    {
      text: 'Test Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Hest Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Fest Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    },
    {
      text: 'Gæst Hest',
      img: 'http://dummyimage.com/50x50/000/fff'
    }
  ]
},
  {
    label: 'Author',
    data: [
      {
        text: 'Test Hest',
        img: 'http://dummyimage.com/50x50/000/fff'
      },
      {
        text: 'Hest Hest',
        img: ''
      },
      {
        text: 'Fest Hest',
        img: ''
      },
      {
        text: 'Gæst Hest',
        img: ''
      }
    ]
  }];

const store = Reflux.createStore({
  listenables: [actions],

  _store: {
    data: []
  },

  init() {
    socket.on('getPopSuggestionsResponse', this.serviceResponse);
  },

  serviceResponse(data) {
    let _data = null;
    if (data.error) {
      console.error('PopSuggest responded with an error: ', data); // eslint-disable-line
      _data = [];
    }
    else {  // eslint-disable-line
      _data = dummyData;
    }

    this._store.data = _data;
    this.trigger(this._store);
  },

  onTextfieldUpdated(value) {
    socket.emit('getPopSuggestionsRequest', value);
  },

  getInitialState() {
    return this._store;
  }
});

var SearchField = React.createClass({
  mixins: [Reflux.connect(store)],

  render() {
    const AutoComplete = this.props.autocomplete;
    const text = this.state.text || '';
    const data = this.state.data || [];
    const autoCompleteVisible = (data.length >= 1 && text.length >= 1);

    return (

        <input type='text' placeholder='Søg og du skal finde' value={text} onChange={this._handleOnChange} onKeyUp={this._handleOnKeyUp} className={'search-input'}/>
        <AutoComplete data={data} visible={autoCompleteVisible}/>

    );
  },

  _handleOnChange(e) {
    const txt = e.target.value;
    this.setState({text: txt});
  },

  _handleOnKeyUp() {
    clearTimeout(timer);

    timer = setTimeout(() => {
      actions.textfieldUpdated(this.state.text);
    }, 250);
  },

  propTypes: {
    autocomplete: React.PropTypes.func.isRequired
  }
});

export default SearchField;
<|endoftext|>


<commit_before>import React from 'react';
import metadataProvider from '../../lib/metadataProvider.js';
import MetaFormGroup from '../groupComponents/MetaFormGroup.js';
import GlyphButton from '../GlyphButton.js';
import Glyphicon from 'react-bootstrap/lib/Glyphicon.js';
import DropdownButton from 'react-bootstrap/lib/DropdownButton.js';
import MenuItem from 'react-bootstrap/lib/MenuItem.js';
import Dropdown from 'react-bootstrap/lib/Dropdown.js';
import arrayHelper from'../../lib/helpers/arrayHelper.js';
import Modal from 'react-bootstrap/lib/Modal.js';
import Button from 'react-bootstrap/lib/Button.js';
import MetaForm from '../../MetaForm.js';
import Table from 'react-bootstrap/lib/Table.js';
import functionHelper from '../../lib/helpers/functionHelper.js';
import _ from 'underscore';

const MetaFormModal = React.createClass({

    propTypes: {
        schema: React.PropTypes.object.isRequired,
        componentFactory: React.PropTypes.object.isRequired,
        model: React.PropTypes.object.isRequired,
        entityType: React.PropTypes.string.isRequired,
        layoutName: React.PropTypes.string.isRequired,
        onSave: React.PropTypes.function,
        onCancel: React.PropTypes.function
    },

    handleSave: function (model) {
        if (this.props.onSave) {
            this.props.onSave(model);
        }
    },

    handleCancel: function () {
        if (this.props.onCancel) {
            this.props.onCancel();
        }
    },

    getDefaultProps: function () {
        return {
            show: false
        }
    },

    render: function () {
        return <Modal show={this.props.show} bsSize="large">
            <Modal.Header>
                <Modal.Title>Modal heading</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <MetaForm
                    schema={this.props.schema}
                    ref="mf"
                    entityName={this.props.entityType}
                    layoutName={this.props.layoutName}
                    componentFactory={this.props.componentFactory}
                    model={this.props.model}
                    onSave={this.handleSave}
                    onCancel={this.handleCancel}
                    />
            </Modal.Body>
        </Modal>
    }
});

const ArrayGridRow = React.createClass({

    propTypes: {
        index: React.PropTypes.number.isRequired,
        onAction: React.PropTypes.func
    },

    handleAction: function (e, eventKey) {
        if (this.props.onAction) {
            this.props.onAction(this.props.index, eventKey)
        }
    },

    render: function () {
        return

                {this.props.children}

                <Dropdown pullRight onSelect={this.handleAction}>
                    <Dropdown.Toggle noCaret>
                        <Glyphicon glyph="cog"/>
                    </Dropdown.Toggle>
                    <Dropdown.Menu >
                        <MenuItem eventKey="edit"><Glyphicon glyph="pencil"/>
                            Edit
                        </MenuItem>
                        <MenuItem eventKey="remove"><Glyphicon glyph="remove" className="text-danger"/>Remove
                        </MenuItem>
                        <MenuItem divider/>
                        <MenuItem eventKey="moveUp"><Glyphicon glyph="chevron-up"/>
                            Move up
                        </MenuItem>
                        <MenuItem eventKey="moveDown"><Glyphicon glyph="chevron-down"/>Move down
                        </MenuItem>
                        <MenuItem divider/>
                        <MenuItem eventKey="moveFirst"><Glyphicon glyph="chevron-up"/>Move first
                        </MenuItem>
                        <MenuItem eventKey="moveLast"><Glyphicon glyph="chevron-down"/>Move last
                        </MenuItem>
                    </Dropdown.Menu>
                </Dropdown>

;
    }
});

const ArrayGrid = React.createClass({

    handleItemAction: function (index, eventKey) {
        if (this.props.onItemAction) {
            this.props.onItemAction(index, eventKey);
        }
    },

    render: function () {

        let rows = this.props.items.map((item, index) => {
            return <ArrayGridRow index={index} onAction={this.handleItemAction}>
                {item.text}
            </ArrayGridRow>;
        });

        return

            {rows}

;
    }
});

const ArrayGridContainer = React.createClass({

    propTypes: {
        name: React.PropTypes.string.isRequired,
        componentFactory: React.PropTypes.object.isRequired,
        entityType: React.PropTypes.string.isRequired,
        layoutName: React.PropTypes.string,
        _itemDisplayName: React
    },

    getInitialState: () => {
        return {
            editingItemIndex: null
        }
    },

    handleAdd: function () {
        let newState = _.extend({}, this.state);
        newState.editingItemIndex = -1;
        this.setState(newState);
    },

    handleSaveItem: function (model) {
        if (this.props.onChange) {
            let value = this.props.value;

            if(!this.state.editingItemIndex === null || this.state.editingItemIndex === undefined) {
                // I'm not sure if an exception should be thrown here. It should probably be. However, there could
                // be a situation that could change it. Needs further analysis.
                return;
            }
            else if(this.state.editingItemIndex == -1) {
                value.push(model);
            }
            else {
                value[this.state.editingItemIndex] = model;
            }

            this.props.onChange({id: this.props.id, value: value});
            this.handleModalClose();
        }
    },

    handleModalClose: function () {
        let newState = _.extend({}, this.state);
        newState.editingItemIndex = null;
        this.setState(newState);
    },

    handleItemAction: function (index, eventKey) {
        let value = this.props.value;

        if (eventKey == "edit") {
            let newState = _.extend({}, this.state);
            newState.editingItemIndex = index;
            this.setState(newState);
            return;
        }

        switch (eventKey) {
            case "remove":
                value.splice(index, 1);
                break;
            case 'moveUp':
                arrayHelper.move(value, index, index - 1);
                break;
            case 'moveDown':
                arrayHelper.move(value, index, index + 1);
                break;
            case 'moveFirst':
                arrayHelper.move(value, index, 0);
                break;
            case 'moveLast':
                arrayHelper.move(value, index, value.length - 1);
                break;
        }
        if (this.props.onChange) {
            this.props.onChange({id: this.props.id, value: value});
        }
    },

    render: function () {

        var header = this.props.displayName ?

                {this.props.displayName}

            : null;

        let items;
        if (this.props._itemDisplayName) {
            let itemDisplayNameFunction = functionHelper.getFunction(this.props._itemDisplayName);
            items = this.props.value.map(i => {
                return {
                    text: itemDisplayNameFunction(i)
                };
            });
        }
        else {
            items = this.props.value.map(i => {
                return {
                    text: i.toString()
                };
            });
        }

        let showModal = this.state.editingItemIndex != null && this.state.editingItemIndex != undefined;
        let modalModel;
        if (this.state.editingItemIndex == -1) {
            modalModel = {}
        }
        else if (this.state.editingItemIndex >= 0) {
            modalModel = this.props.value[this.state.editingItemIndex];
        }
        else {
            modalModel = null;
        }

        return (

                {header}

                    <ArrayGrid items={items} onItemAction={this.handleItemAction}/>

                        <GlyphButton glyph="plus" text={this.props.addText ? this.props.addText : "Add" }
                                     onClick={this.handleAdd} />

                <MetaFormModal
                    show={showModal}
                    schema={this.props.schema}
                    componentFactory={this.props.componentFactory}
                    model={modalModel}
                    entityType={this.props.entityType}
                    layoutName={this.props.layoutName}
                    onSave={this.handleSaveItem}
                    onCancel={this.handleModalClose}
                    />

        );
    }
});

export default ArrayGridContainer;<commit_msg>Fine tuning the ArrayGridContainer styles<commit_after>import React from 'react';
import metadataProvider from '../../lib/metadataProvider.js';
import MetaFormGroup from '../groupComponents/MetaFormGroup.js';
import GlyphButton from '../GlyphButton.js';
import Glyphicon from 'react-bootstrap/lib/Glyphicon.js';
import DropdownButton from 'react-bootstrap/lib/DropdownButton.js';
import MenuItem from 'react-bootstrap/lib/MenuItem.js';
import Dropdown from 'react-bootstrap/lib/Dropdown.js';
import arrayHelper from'../../lib/helpers/arrayHelper.js';
import Modal from 'react-bootstrap/lib/Modal.js';
import Button from 'react-bootstrap/lib/Button.js';
import MetaForm from '../../MetaForm.js';
import Table from 'react-bootstrap/lib/Table.js';
import FormGroup from './FormGroup.js';
import functionHelper from '../../lib/helpers/functionHelper.js';
import _ from 'underscore';

const MetaFormModal = React.createClass({

    propTypes: {
        schema: React.PropTypes.object.isRequired,
        componentFactory: React.PropTypes.object.isRequired,
        model: React.PropTypes.object.isRequired,
        entityType: React.PropTypes.string.isRequired,
        layoutName: React.PropTypes.string.isRequired,
        onSave: React.PropTypes.function,
        onCancel: React.PropTypes.function
    },

    handleSave: function (model) {
        if (this.props.onSave) {
            this.props.onSave(model);
        }
    },

    handleCancel: function () {
        if (this.props.onCancel) {
            this.props.onCancel();
        }
    },

    getDefaultProps: function () {
        return {
            show: false
        }
    },

    render: function () {
        return <Modal show={this.props.show} bsSize="large">
            <Modal.Header>
                <Modal.Title>Modal heading</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <MetaForm
                    schema={this.props.schema}
                    ref="mf"
                    entityName={this.props.entityType}
                    layoutName={this.props.layoutName}
                    componentFactory={this.props.componentFactory}
                    model={this.props.model}
                    onSave={this.handleSave}
                    onCancel={this.handleCancel}
                    />
            </Modal.Body>
        </Modal>
    }
});

const ArrayGridRow = React.createClass({

    propTypes: {
        index: React.PropTypes.number.isRequired,
        onAction: React.PropTypes.func
    },

    handleAction: function (e, eventKey) {
        if (this.props.onAction) {
            this.props.onAction(this.props.index, eventKey)
        }
    },

    render: function () {
        return

                {this.props.children}

                <Dropdown pullRight onSelect={this.handleAction}>
                    <Dropdown.Toggle noCaret>
                        <Glyphicon glyph="cog"/>
                    </Dropdown.Toggle>
                    <Dropdown.Menu >
                        <MenuItem eventKey="edit"><Glyphicon glyph="pencil"/>
                            Edit
                        </MenuItem>
                        <MenuItem eventKey="remove"><Glyphicon glyph="remove" className="text-danger"/>Remove
                        </MenuItem>
                        <MenuItem divider/>
                        <MenuItem eventKey="moveUp"><Glyphicon glyph="chevron-up"/>
                            Move up
                        </MenuItem>
                        <MenuItem eventKey="moveDown"><Glyphicon glyph="chevron-down"/>Move down
                        </MenuItem>
                        <MenuItem divider/>
                        <MenuItem eventKey="moveFirst"><Glyphicon glyph="chevron-up"/>Move first
                        </MenuItem>
                        <MenuItem eventKey="moveLast"><Glyphicon glyph="chevron-down"/>Move last
                        </MenuItem>
                    </Dropdown.Menu>
                </Dropdown>

;
    }
});

const ArrayGrid = React.createClass({

    handleItemAction: function (index, eventKey) {
        if (this.props.onItemAction) {
            this.props.onItemAction(index, eventKey);
        }
    },

    render: function () {

        let rows = this.props.items.map((item, index) => {
            return <ArrayGridRow index={index} onAction={this.handleItemAction}>
                {item.text}
            </ArrayGridRow>;
        });

        return

            {rows}

;
    }
});

const ArrayGridContainer = React.createClass({

    propTypes: {
        name: React.PropTypes.string.isRequired,
        componentFactory: React.PropTypes.object.isRequired,
        entityType: React.PropTypes.string.isRequired,
        layoutName: React.PropTypes.string,
        _itemDisplayName: React
    },

    getInitialState: () => {
        return {
            editingItemIndex: null
        }
    },

    handleAdd: function () {
        let newState = _.extend({}, this.state);
        newState.editingItemIndex = -1;
        this.setState(newState);
    },

    handleSaveItem: function (model) {
        if (this.props.onChange) {
            let value = this.props.value;

            if(!this.state.editingItemIndex === null || this.state.editingItemIndex === undefined) {
                // I'm not sure if an exception should be thrown here. It should probably be. However, there could
                // be a situation that could change it. Needs further analysis.
                return;
            }
            else if(this.state.editingItemIndex == -1) {
                value.push(model);
            }
            else {
                value[this.state.editingItemIndex] = model;
            }

            this.props.onChange({id: this.props.id, value: value});
            this.handleModalClose();
        }
    },

    handleModalClose: function () {
        let newState = _.extend({}, this.state);
        newState.editingItemIndex = null;
        this.setState(newState);
    },

    handleItemAction: function (index, eventKey) {
        let value = this.props.value;

        if (eventKey == "edit") {
            let newState = _.extend({}, this.state);
            newState.editingItemIndex = index;
            this.setState(newState);
            return;
        }

        switch (eventKey) {
            case "remove":
                value.splice(index, 1);
                break;
            case 'moveUp':
                arrayHelper.move(value, index, index - 1);
                break;
            case 'moveDown':
                arrayHelper.move(value, index, index + 1);
                break;
            case 'moveFirst':
                arrayHelper.move(value, index, 0);
                break;
            case 'moveLast':
                arrayHelper.move(value, index, value.length - 1);
                break;
        }
        if (this.props.onChange) {
            this.props.onChange({id: this.props.id, value: value});
        }
    },

    render: function () {

        let items;
        if (this.props._itemDisplayName) {
            let itemDisplayNameFunction = functionHelper.getFunction(this.props._itemDisplayName);
            items = this.props.value.map(i => {
                return {
                    text: itemDisplayNameFunction(i)
                };
            });
        }
        else {
            items = this.props.value.map(i => {
                return {
                    text: i.toString()
                };
            });
        }

        let showModal = this.state.editingItemIndex != null && this.state.editingItemIndex != undefined;
        let modalModel;
        if (this.state.editingItemIndex == -1) {
            modalModel = {}
        }
        else if (this.state.editingItemIndex >= 0) {
            modalModel = this.props.value[this.state.editingItemIndex];
        }
        else {
            modalModel = null;
        }

        return (

                <FormGroup displayName={this.props.displayName}>
                    <ArrayGrid items={items} onItemAction={this.handleItemAction}/>
                </FormGroup>

                        <GlyphButton glyph="plus" text={this.props.addText ? this.props.addText : "Add" }
                                     onClick={this.handleAdd} />

                <MetaFormModal
                    show={showModal}
                    schema={this.props.schema}
                    componentFactory={this.props.componentFactory}
                    model={modalModel}
                    entityType={this.props.entityType}
                    layoutName={this.props.layoutName}
                    onSave={this.handleSaveItem}
                    onCancel={this.handleModalClose}
                    />

        );
    }
});

export default ArrayGridContainer;<|endoftext|>


<commit_before>import React from 'react';
import { render } from '@testing-library/react';
import i18n from './i18n';
import { withTranslation } from '../src/withTranslation';

jest.unmock('../src/withTranslation');

describe('withTranslation', () => {
  class TestComponent extends React.Component {
    render() {
      const { t, i18n: instance } = this.props;
      expect(typeof t).toBe('function');
      expect(instance).toBe(i18n);

      return
{t('key1')}
;
    }
  }

  it('should export wrapped component', () => {
    const HocElement = withTranslation()(TestComponent);
    expect(HocElement.WrappedComponent).toBe(TestComponent);
  });

  it('should render correct content', () => {
    const HocElement = withTranslation()(TestComponent);
    const { container } = render(<HocElement />);
    expect(container.firstChild).toMatchInlineSnapshot(`

          test

    `);
  });

  it('should has ref', () => {
    const HocElement = withTranslation('translation', { withRef: true })(TestComponent);
    const hocRef = React.createRef();
    render(<HocElement ref={hocRef} />);
    expect(hocRef.current).not.toBeNull();
  });
});
<commit_msg>Updated snapshot in withTranslation<commit_after>import React from 'react';
import { render } from '@testing-library/react';
import i18n from './i18n';
import { withTranslation } from '../src/withTranslation';

jest.unmock('../src/withTranslation');

describe('withTranslation', () => {
  class TestComponent extends React.Component {
    render() {
      const { t, i18n: instance } = this.props;
      expect(typeof t).toBe('function');
      expect(instance).toBe(i18n);

      return
{t('key1')}
;
    }
  }

  it('should export wrapped component', () => {
    const HocElement = withTranslation()(TestComponent);
    expect(HocElement.WrappedComponent).toBe(TestComponent);
  });

  it('should render correct content', () => {
    const HocElement = withTranslation()(TestComponent);
    const { container } = render(<HocElement />);
    expect(container.firstChild).toMatchInlineSnapshot(`

        test

    `);
  });

  it('should has ref', () => {
    const HocElement = withTranslation('translation', { withRef: true })(TestComponent);
    const hocRef = React.createRef();
    render(<HocElement ref={hocRef} />);
    expect(hocRef.current).not.toBeNull();
  });
});
<|endoftext|>


<commit_before>// This takes a serial-port factory and mocks the shit out of it in complete isolation per require of this file

"use strict";
var rewire = require('rewire');
process.platform = 'darwin';
var serialPort = rewire('../serialport');

var mockSerialportPoller = function (hardware) {
  var Poller = function (path, cb) {
    this.port = hardware.ports[path];
    if (!this.port) {
      throw new Error(path + " does not exist - please call hardware.createPort(path) first");
    }
    this.port.poller = this;
    this.polling = null;
    this.cb = cb;
  };
  Poller.prototype.start = function () {
    this.polling = true;
  };
  Poller.prototype.close = function () {
    this.polling = false;
  };
  Poller.prototype.detectRead = function () {
    this.cb();
  };
  return Poller;
};

var Hardware = function () {
  this.ports = {};
  this.mockBinding = {
    list: this.list.bind(this),
    open: this.open.bind(this),
    write: this.write.bind(this),
    close: this.close.bind(this),
    flush: this.flush.bind(this),
    SerialportPoller: mockSerialportPoller(this)
  };
};

Hardware.prototype.reset = function () {
  this.ports = {};
};

Hardware.prototype.createPort = function (path) {
  this.ports[path] = {
    data: new Buffer(0),
    lastWrite: null,
    open: false,
    poller: null,
    info: {
      comName: path,
      manufacturer: '',
      serialNumber: '',
      pnpId: '',
      locationId: '',
      vendorId: '',
      productId: ''
    }
  };
};

Hardware.prototype.emitData = function (path, data) {
  var port = this.ports[path];
  if(!port) {
    throw new Error(path + " does not exist - please call hardware.createPort(path) first");
  }
  port.data = Buffer.concat([port.data, data]);
  port.poller && port.poller.detectRead();
};

Hardware.prototype.disconnect = function (path) {
  var port = this.ports[path];
  if (!port) {
    throw new Error(path + " does not exist - please call hardware.createPort(path) first");
  }
  port.openOpt.disconnectedCallback();
};

Hardware.prototype.list = function (cb) {
  var ports = this.ports;
  var info = Object.keys(ports).map(function (path) {
    return ports[path].info;
  });
  cb && cb(info);
};

Hardware.prototype.open = function (path, opt, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.open = true;
  port.openOpt = opt;
  cb && cb(null, path); // using path as the fd for convience
};

Hardware.prototype.write = function (path, buffer, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.lastWrite = new Buffer(buffer); //copy
  cb && cb(null, buffer.length);
};

Hardware.prototype.close = function (path, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.open = false;
  cb && cb(null);
};

Hardware.prototype.flush = function (path, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  cb && cb(null, undefined);
};

var hardware = new Hardware();
serialPort.hardware = hardware;
serialPort.SerialPortBinding = hardware.mockBinding;

serialPort.__set__('fs', {
  read: function (path, buffer, offset, length, position, cb) {
    var port = hardware.ports[path];
    if (!port) {
      return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
    }
    if (port.data.length === 0) {
      return cb(null, 0, buffer);
    }
    if ((offset + length) > buffer.length) {
      throw new Error("Length extends beyond buffer");
    }
    var read = port.data.slice(0, length);
    port.data = port.data.slice(length);
    read.copy(buffer, offset);
    cb(null, read.length, buffer);
  }
});

module.exports = serialPort;
<commit_msg>don't modify process.platform in tests as it's going to be read only<commit_after>// This takes a serial-port factory and mocks the shit out of it in complete isolation per require of this file

"use strict";
var rewire = require('rewire');
var serialPort = rewire('../serialport');

var mockSerialportPoller = function (hardware) {
  var Poller = function (path, cb) {
    this.port = hardware.ports[path];
    if (!this.port) {
      throw new Error(path + " does not exist - please call hardware.createPort(path) first");
    }
    this.port.poller = this;
    this.polling = null;
    this.cb = cb;
  };
  Poller.prototype.start = function () {
    this.polling = true;
  };
  Poller.prototype.close = function () {
    this.polling = false;
  };
  Poller.prototype.detectRead = function () {
    this.cb();
  };
  return Poller;
};

var Hardware = function () {
  this.ports = {};
  this.mockBinding = {
    list: this.list.bind(this),
    open: this.open.bind(this),
    write: this.write.bind(this),
    close: this.close.bind(this),
    flush: this.flush.bind(this),
    SerialportPoller: mockSerialportPoller(this)
  };
};

Hardware.prototype.reset = function () {
  this.ports = {};
};

Hardware.prototype.createPort = function (path) {
  this.ports[path] = {
    data: new Buffer(0),
    lastWrite: null,
    open: false,
    poller: null,
    info: {
      comName: path,
      manufacturer: '',
      serialNumber: '',
      pnpId: '',
      locationId: '',
      vendorId: '',
      productId: ''
    }
  };
};

Hardware.prototype.emitData = function (path, data) {
  var port = this.ports[path];
  if(!port) {
    throw new Error(path + " does not exist - please call hardware.createPort(path) first");
  }
  port.data = Buffer.concat([port.data, data]);
  port.poller && port.poller.detectRead();
};

Hardware.prototype.disconnect = function (path) {
  var port = this.ports[path];
  if (!port) {
    throw new Error(path + " does not exist - please call hardware.createPort(path) first");
  }
  port.openOpt.disconnectedCallback();
};

Hardware.prototype.list = function (cb) {
  var ports = this.ports;
  var info = Object.keys(ports).map(function (path) {
    return ports[path].info;
  });
  cb && cb(info);
};

Hardware.prototype.open = function (path, opt, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.open = true;
  port.openOpt = opt;
  cb && cb(null, path); // using path as the fd for convience
};

Hardware.prototype.write = function (path, buffer, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.lastWrite = new Buffer(buffer); //copy
  cb && cb(null, buffer.length);
};

Hardware.prototype.close = function (path, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  port.open = false;
  cb && cb(null);
};

Hardware.prototype.flush = function (path, cb) {
  var port = this.ports[path];
  if (!port) {
    return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
  }
  cb && cb(null, undefined);
};

var hardware = new Hardware();
serialPort.hardware = hardware;
serialPort.SerialPortBinding = hardware.mockBinding;

serialPort.__set__('fs', {
  read: function (path, buffer, offset, length, position, cb) {
    var port = hardware.ports[path];
    if (!port) {
      return cb(new Error(path + " does not exist - please call hardware.createPort(path) first"));
    }
    if (port.data.length === 0) {
      return cb(null, 0, buffer);
    }
    if ((offset + length) > buffer.length) {
      throw new Error("Length extends beyond buffer");
    }
    var read = port.data.slice(0, length);
    port.data = port.data.slice(length);
    read.copy(buffer, offset);
    cb(null, read.length, buffer);
  }
});

serialPort.__set__('process', {
  platform: 'darwin',
  nextTick: process.nextTick
});

module.exports = serialPort;
<|endoftext|>


<commit_before>// https://trade.1234567.com.cn/Investment/change?BusinSerialNo=e338a06930d249df9159af485954866e

module.exports = function(){
	console.log("tiantian_xiugai");
	$(function(){
		setTimeout(function(){
			if($("#ctl00_body_amount").length>0){
				if($("#zdxe").length>0){
					// 新增定投的地方
					$("#ctl00_body_rbPeriodTime_1").click();
					// $("#ctl00_body_rpPeriodTime_ctl01_ddList").click();
					var rnd = _.random(1, 5);
					$("#ctl00_body_rpPeriodTime_ctl01_ddList").val(rnd);
					var rndtext = $("#ctl00_body_rpPeriodTime_ctl01_ddList").find("option[value='"+rnd+"']").text();
					$("#ctl00_body_hfWorkWeek").val(rndtext);
					//这个才是真正起到数据作用的
					$("#ctl00_body_hfPeriodday").val(rnd);
					// $("#ctl00_body_rpPeriodTime_ctl01_ddList").find("option[value='"+rnd+"']").attr("selected",true);
					// console.log('av: ', $("#ctl00_body_rpPeriodTime_ctl01_ddList").val());
					var rndAm = _.random(11, 233);
					// $("#ctl00_body_amount").val($("#zdxe").text().trim().jia(11));
					$("#ctl00_body_amount").val($("#zdxe").text().trim().jia(rndAm));
				}else{
					// 更改

				}
			};

			if($("#ctl00_body_txtPaypwd").length>0){
				C.storage.get('ttpw', function(items){
					// if(items['ttpw']){
						$("#ctl00_body_txtPaypwd").val(items['ttpw']);
					// }else{
					// 	$("#ctl00_body_btnSp2, #ctl00_body_btnSp3").click(function(){
					// 		C.storage.set({ttpw: $("#ctl00_body_txtPaypwd").val()});
					// 	});
					// }
				});
			};

			if($("#ctl00_body_btnSp1").length>0){
				$("html,body").animate({scrollTop:$("#ctl00_body_btnSp1").offset().top-450});
			}else if($("#ctl00_body_btnSp2").length>0){
				$("html,body").animate({scrollTop:$("#ctl00_body_btnSp2").offset().top-450});
			}else if($(".tarr").length>0){
				$("html,body").animate({scrollTop:$(".tarr").offset().top-450});
			}

		}, 500);

	});

}()<commit_msg>fix randomprice<commit_after>// https://trade.1234567.com.cn/Investment/change?BusinSerialNo=e338a06930d249df9159af485954866e

module.exports = function(){
	console.log("tiantian_xiugai");
	$(function(){
		setTimeout(function(){
			if($("#ctl00_body_amount").length>0){
				if($("#zdxe").length>0){
					// 新增定投的地方
					$("#ctl00_body_rbPeriodTime_1").click();
					// $("#ctl00_body_rpPeriodTime_ctl01_ddList").click();
					var rnd = _.random(1, 5);
					$("#ctl00_body_rpPeriodTime_ctl01_ddList").val(rnd);
					var rndtext = $("#ctl00_body_rpPeriodTime_ctl01_ddList").find("option[value='"+rnd+"']").text();
					$("#ctl00_body_hfWorkWeek").val(rndtext);
					//这个才是真正起到数据作用的
					$("#ctl00_body_hfPeriodday").val(rnd);
					// $("#ctl00_body_rpPeriodTime_ctl01_ddList").find("option[value='"+rnd+"']").attr("selected",true);
					// console.log('av: ', $("#ctl00_body_rpPeriodTime_ctl01_ddList").val());
					var rndAm = _.random(111, 666);
					// $("#ctl00_body_amount").val($("#zdxe").text().trim().jia(11));
					$("#ctl00_body_amount").val($("#zdxe").text().trim().jia(rndAm));
				}else{
					// 更改

				}
			};

			if($("#ctl00_body_txtPaypwd").length>0){
				C.storage.get('ttpw', function(items){
					// if(items['ttpw']){
						$("#ctl00_body_txtPaypwd").val(items['ttpw']);
					// }else{
					// 	$("#ctl00_body_btnSp2, #ctl00_body_btnSp3").click(function(){
					// 		C.storage.set({ttpw: $("#ctl00_body_txtPaypwd").val()});
					// 	});
					// }
				});
			};

			if($("#ctl00_body_btnSp1").length>0){
				$("html,body").animate({scrollTop:$("#ctl00_body_btnSp1").offset().top-450});
			}else if($("#ctl00_body_btnSp2").length>0){
				$("html,body").animate({scrollTop:$("#ctl00_body_btnSp2").offset().top-450});
			}else if($(".tarr").length>0){
				$("html,body").animate({scrollTop:$(".tarr").offset().top-450});
			}

		}, 500);

	});

}()<|endoftext|>