<commit_before>import React from 'react';

import ObserveModel from '../decorators/observe-model';
import {BranchPropType} from '../prop-types';
import BranchView from '../views/branch-view';
import BranchMenuView from '../views/branch-menu-view';
import PushPullView from '../views/push-pull-view';
import PushPullMenuView from '../views/push-pull-menu-view';
import ChangedFilesCountView from '../views/changed-files-count-view';
import Tooltip from '../views/tooltip';
import Commands, {Command} from '../views/commands';
import yubikiri from 'yubikiri';
import {autobind} from 'core-decorators';

@ObserveModel({
  getModel: props => props.repository,
  fetchData: repository => {
    return yubikiri({
      currentBranch: repository.getCurrentBranch(),
      branches: repository.getBranches(),
      changedFilesCount: repository.getStatusesForChangedFiles().then(statuses => {
        const {stagedFiles, unstagedFiles, mergeConflictFiles} = statuses;
        const changedFiles = new Set();

        for (const filePath in unstagedFiles) {
          changedFiles.add(filePath);
        }
        for (const filePath in stagedFiles) {
          changedFiles.add(filePath);
        }
        for (const filePath in mergeConflictFiles) {
          changedFiles.add(filePath);
        }

        return changedFiles.size;
      }),
      remoteName: async query => repository.getRemoteForBranch(await query.branchName),
      aheadCount: async query => repository.getAheadCount(await query.branchName),
      behindCount: async query => repository.getBehindCount(await query.branchName),
      pullDisabled: async query => (await query.changedFilesCount) > 0,
    });
  },
})
export default class StatusBarTileController extends React.Component {
  static propTypes = {
    workspace: React.PropTypes.object.isRequired,
    notificationManager: React.PropTypes.object.isRequired,
    commandRegistry: React.PropTypes.object.isRequired,
    tooltips: React.PropTypes.object.isRequired,
    repository: React.PropTypes.object,
    currentBranch: BranchPropType,
    branches: React.PropTypes.arrayOf(React.PropTypes.string),
    remoteName: React.PropTypes.string,
    aheadCount: React.PropTypes.number,
    behindCount: React.PropTypes.number,
    changedFilesCount: React.PropTypes.number,
    pullDisabled: React.PropTypes.bool,
    toggleGitPanel: React.PropTypes.func,
  }

  static defaultProps = {
    toggleGitPanel: () => {},
  }

  constructor(props, context) {
    super(props, context);

    this.state = {
      inProgress: false,
      pushInProgress: false,
      fetchInProgress: false,
    };
  }

  render() {
    const repoProps = {
      currentBranch: this.props.currentBranch || {name: '', isDetached: false},
      branches: this.props.branches,
      remoteName: this.props.remoteName,
      aheadCount: this.props.aheadCount,
      behindCount: this.props.behindCount,
      pullDisabled: this.props.pullDisabled,
      changedFilesCount: this.props.changedFilesCount,
    };

    return (

        <Commands registry={this.props.commandRegistry} target="atom-workspace">
          <Command command="github:fetch" callback={this.fetch} />
          <Command command="github:pull" callback={this.pull} />
          <Command
            command="github:push"
            callback={() => this.push({force: false, setUpstream: !this.props.remoteName})}
          />
          <Command
            command="github:force-push"
            callback={() => this.push({force: true, setUpstream: !this.props.remoteName})}
          />
        </Commands>
        <BranchView
          ref={e => { this.branchView = e; }}
          workspace={this.props.workspace}
          checkout={this.checkout}
          {...repoProps}
        />
        <Tooltip
          manager={this.props.tooltips}
          target={() => this.branchView}
          trigger="click"
          className="github-StatusBarTileController-tooltipMenu">
          <BranchMenuView
            workspace={this.props.workspace}
            notificationManager={this.props.notificationManager}
            commandRegistry={this.props.commandRegistry}
            checkout={this.checkout}
            {...repoProps}
          />
        </Tooltip>
        <PushPullView
          ref={e => { this.pushPullView = e; }}
          pushInProgress={this.state.pushInProgress}
          fetchInProgress={this.state.fetchInProgress}
          {...repoProps}
        />
        <Tooltip
          manager={this.props.tooltips}
          target={() => this.pushPullView}
          trigger="click"
          className="github-StatusBarTileController-tooltipMenu">
          <PushPullMenuView
            workspace={this.props.workspace}
            notificationManager={this.props.notificationManager}
            inProgress={this.state.inProgress}
            push={this.push}
            pull={this.pull}
            fetch={this.fetch}
            {...repoProps}
          />
        </Tooltip>
        <ChangedFilesCountView
          didClick={this.props.toggleGitPanel}
          {...repoProps}
        />

          ⏰

    );
  }

  @autobind
  handleOpenGitTimingsView(e) {
    e.preventDefault();
    this.props.workspace.open('atom-github://debug/timings');
  }

  setInProgressWhile(block, {push, pull, fetch} = {push: false, pull: false, fetch: false}) {
    return new Promise((resolve, reject) => {
      if (this.state.inProgress) {
        resolve();
        return;
      }

      this.setState({inProgress: true, pushInProgress: push, fetchInProgress: pull || fetch}, async () => {
        try {
          await block();
        } catch (e) {
          reject(e);
        } finally {
          this.setState({inProgress: false, pushInProgress: false, fetchInProgress: false}, resolve);
        }
      });
    });
  }

  @autobind
  checkout(branchName, options) {
    return this.setInProgressWhile(() => this.props.repository.checkout(branchName, options));
  }

  @autobind
  async push(options) {
    await this.setInProgressWhile(() => {
      return this.props.repository.push(this.props.currentBranch.name, options);
    }, {push: true});
  }

  @autobind
  async pull() {
    if (this.props.pullDisabled) {
      return;
    }

    await this.setInProgressWhile(() => this.props.repository.pull(this.props.currentBranch.name), {pull: true});
  }

  @autobind
  async fetch() {
    await this.setInProgressWhile(() => this.props.repository.fetch(this.props.currentBranch.name), {fetch: true});
  }
}
<commit_msg>`query.branchName` isn't a thing<commit_after>import React from 'react';

import ObserveModel from '../decorators/observe-model';
import {BranchPropType} from '../prop-types';
import BranchView from '../views/branch-view';
import BranchMenuView from '../views/branch-menu-view';
import PushPullView from '../views/push-pull-view';
import PushPullMenuView from '../views/push-pull-menu-view';
import ChangedFilesCountView from '../views/changed-files-count-view';
import Tooltip from '../views/tooltip';
import Commands, {Command} from '../views/commands';
import yubikiri from 'yubikiri';
import {autobind} from 'core-decorators';

@ObserveModel({
  getModel: props => props.repository,
  fetchData: repository => {
    return yubikiri({
      currentBranch: repository.getCurrentBranch(),
      branches: repository.getBranches(),
      changedFilesCount: repository.getStatusesForChangedFiles().then(statuses => {
        const {stagedFiles, unstagedFiles, mergeConflictFiles} = statuses;
        const changedFiles = new Set();

        for (const filePath in unstagedFiles) {
          changedFiles.add(filePath);
        }
        for (const filePath in stagedFiles) {
          changedFiles.add(filePath);
        }
        for (const filePath in mergeConflictFiles) {
          changedFiles.add(filePath);
        }

        return changedFiles.size;
      }),
      remoteName: async query => repository.getRemoteForBranch((await query.currentBranch).name),
      aheadCount: async query => repository.getAheadCount((await query.currentBranch).name),
      behindCount: async query => repository.getBehindCount((await query.currentBranch).name),
      pullDisabled: async query => (await query.changedFilesCount) > 0,
    });
  },
})
export default class StatusBarTileController extends React.Component {
  static propTypes = {
    workspace: React.PropTypes.object.isRequired,
    notificationManager: React.PropTypes.object.isRequired,
    commandRegistry: React.PropTypes.object.isRequired,
    tooltips: React.PropTypes.object.isRequired,
    repository: React.PropTypes.object,
    currentBranch: BranchPropType,
    branches: React.PropTypes.arrayOf(React.PropTypes.string),
    remoteName: React.PropTypes.string,
    aheadCount: React.PropTypes.number,
    behindCount: React.PropTypes.number,
    changedFilesCount: React.PropTypes.number,
    pullDisabled: React.PropTypes.bool,
    toggleGitPanel: React.PropTypes.func,
  }

  static defaultProps = {
    toggleGitPanel: () => {},
  }

  constructor(props, context) {
    super(props, context);

    this.state = {
      inProgress: false,
      pushInProgress: false,
      fetchInProgress: false,
    };
  }

  render() {
    const repoProps = {
      currentBranch: this.props.currentBranch || {name: '', isDetached: false},
      branches: this.props.branches,
      remoteName: this.props.remoteName,
      aheadCount: this.props.aheadCount,
      behindCount: this.props.behindCount,
      pullDisabled: this.props.pullDisabled,
      changedFilesCount: this.props.changedFilesCount,
    };

    return (

        <Commands registry={this.props.commandRegistry} target="atom-workspace">
          <Command command="github:fetch" callback={this.fetch} />
          <Command command="github:pull" callback={this.pull} />
          <Command
            command="github:push"
            callback={() => this.push({force: false, setUpstream: !this.props.remoteName})}
          />
          <Command
            command="github:force-push"
            callback={() => this.push({force: true, setUpstream: !this.props.remoteName})}
          />
        </Commands>
        <BranchView
          ref={e => { this.branchView = e; }}
          workspace={this.props.workspace}
          checkout={this.checkout}
          {...repoProps}
        />
        <Tooltip
          manager={this.props.tooltips}
          target={() => this.branchView}
          trigger="click"
          className="github-StatusBarTileController-tooltipMenu">
          <BranchMenuView
            workspace={this.props.workspace}
            notificationManager={this.props.notificationManager}
            commandRegistry={this.props.commandRegistry}
            checkout={this.checkout}
            {...repoProps}
          />
        </Tooltip>
        <PushPullView
          ref={e => { this.pushPullView = e; }}
          pushInProgress={this.state.pushInProgress}
          fetchInProgress={this.state.fetchInProgress}
          {...repoProps}
        />
        <Tooltip
          manager={this.props.tooltips}
          target={() => this.pushPullView}
          trigger="click"
          className="github-StatusBarTileController-tooltipMenu">
          <PushPullMenuView
            workspace={this.props.workspace}
            notificationManager={this.props.notificationManager}
            inProgress={this.state.inProgress}
            push={this.push}
            pull={this.pull}
            fetch={this.fetch}
            {...repoProps}
          />
        </Tooltip>
        <ChangedFilesCountView
          didClick={this.props.toggleGitPanel}
          {...repoProps}
        />

          ⏰

    );
  }

  @autobind
  handleOpenGitTimingsView(e) {
    e.preventDefault();
    this.props.workspace.open('atom-github://debug/timings');
  }

  setInProgressWhile(block, {push, pull, fetch} = {push: false, pull: false, fetch: false}) {
    return new Promise((resolve, reject) => {
      if (this.state.inProgress) {
        resolve();
        return;
      }

      this.setState({inProgress: true, pushInProgress: push, fetchInProgress: pull || fetch}, async () => {
        try {
          await block();
        } catch (e) {
          reject(e);
        } finally {
          this.setState({inProgress: false, pushInProgress: false, fetchInProgress: false}, resolve);
        }
      });
    });
  }

  @autobind
  checkout(branchName, options) {
    return this.setInProgressWhile(() => this.props.repository.checkout(branchName, options));
  }

  @autobind
  async push(options) {
    await this.setInProgressWhile(() => {
      return this.props.repository.push(this.props.currentBranch.name, options);
    }, {push: true});
  }

  @autobind
  async pull() {
    if (this.props.pullDisabled) {
      return;
    }

    await this.setInProgressWhile(() => this.props.repository.pull(this.props.currentBranch.name), {pull: true});
  }

  @autobind
  async fetch() {
    await this.setInProgressWhile(() => this.props.repository.fetch(this.props.currentBranch.name), {fetch: true});
  }
}
<|endoftext|>


<commit_before>var fuse = require('./')

fuse.mount('./mnt', {
  readdir: function (path, cb) {
    if (path === '/') return cb(0, ['test'])
    cb(0)
  },
  getattr: function (path, cb) {
    console.log('getattr(%s)', path)
    if (path === '/') {
      cb(0, {
        mtime: new Date(),
        atime: new Date(),
        ctime: new Date(),
        size: 100,
        mode: 16877,
        uid: process.getuid(),
        gid: process.getgid()
      })
      return
    }

    if (path === '/test') {
      cb(0, {
        mtime: new Date(),
        atime: new Date(),
        ctime: new Date(),
        size: 12,
        mode: 33188,
        uid: process.getuid(),
        gid: process.getgid()
      })
      return
    }

    cb(fuse.ENOENT)
  },
  open: function (path, flags, cb) {
    console.log('open(%s, %d)', path, flags)
    cb(0, 42) // 42 is an fd
  },
  read: function (path, fd, buf, len, pos, cb) {
    console.log('read(%s, %d, %d, %d)', path, fd, len, pos)
    var str = 'hello world\n'.slice(pos)
    if (!str) return cb(0)
    buf.write(str)
    return cb(str.length)
  }
})
<commit_msg>update example<commit_after>var fuse = require('./')

fuse.mount('./mnt', {
  readdir: function (path, cb) {
    if (path === '/') return cb(0, ['test'])
    cb(0)
  },
  getattr: function (path, cb) {
    console.log('getattr(%s)', path)
    if (path === '/') {
      cb(0, {
        mtime: new Date(),
        atime: new Date(),
        ctime: new Date(),
        size: 100,
        mode: 16877,
        uid: process.getuid(),
        gid: process.getgid()
      })
      return
    }

    if (path === '/test') {
      cb(0, {
        mtime: new Date(),
        atime: new Date(),
        ctime: new Date(),
        size: 12,
        mode: 33188,
        uid: process.getuid(),
        gid: process.getgid()
      })
      return
    }

    cb(fuse.ENOENT)
  },
  open: function (path, flags, cb) {
    console.log('open(%s, %d)', path, flags)
    cb(0, 42) // 42 is an fd
  },
  read: function (path, fd, buf, len, pos, cb) {
    console.log('read(%s, %d, %d, %d)', path, fd, len, pos)
    var str = 'hello world\n'.slice(pos)
    if (!str) return cb(0)
    buf.write(str)
    return cb(str.length)
  }
})

process.on('SIGINT', function () {
  fuse.unmount('./mnt', function () {
    process.exit()
  })
})
<|endoftext|>


<commit_before>import React from 'react'
import styled from 'styled-components'
import Link from 'gatsby-link'
import { Page, Row, Column } from 'hedron'

const BlogPostPreview = ({ title, date, author, image, excerpt, path }) => (
  <Container>
    <PostCard sm={11} md={8} lg={6} fluid>
      <PostLink to={path}>
        <PostTitle>{title}</PostTitle>
        <PostExcerpt>{excerpt}</PostExcerpt>
        <BlogAuthor>
          {author} on {date}
        </BlogAuthor>
      </PostLink>
    </PostCard>
  </Container>
)

export default BlogPostPreview

const Container = styled(Row)`
  @media (min-width: 770px) {
    margin-bottom: 20px;
  }
  justify-content: center;
`

const PostCard = styled(Column)`
  padding: 0.5rem 1.15rem;

  @media (min-width: 770px) {
    padding: 3.5rem 3.15rem;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: rgba(25, 17, 34, 0.05) 0px 3px 10px;
    transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1);

    &:hover {
      box-shadow: rgba(25, 17, 34, 0.1) 0px 10px 42px;
      transform: translateY(-4px);
    }

    &:active {
      box-shadow: rgba(25, 17, 34, 0.1) 0px 10px 42px;
      transform: translateY(-4px);
    }
  }
`

const PostLink = styled(Link)`
  text-decoration: none;
  color: inherit;
`

const PostTitle = styled.h1`
  font-family: ${props => props.theme.headingFont};
  font-size: 1.5rem;
  line-height: 2.5rem;
`

const PostExcerpt = styled.p`
  font-family: ${props => props.theme.headingFont};
  font-size: 1rem;
  margin: 0;
  padding-bottom: 0.5rem;
`

const BlogAuthor = styled.p`
  font-family: ${props => props.theme.headingFont};
  color: ${props => props.theme.secondaryBodyFontColor};
  font-size: 1rem;
`
<commit_msg>Animate responsive transition<commit_after>import React from 'react'
import styled from 'styled-components'
import Link from 'gatsby-link'
import { Page, Row, Column } from 'hedron'

const BlogPostPreview = ({ title, date, author, image, excerpt, path }) => (
  <Container>
    <PostCard sm={11} md={8} lg={6} fluid>
      <PostLink to={path}>
        <PostTitle>{title}</PostTitle>
        <PostExcerpt>{excerpt}</PostExcerpt>
        <BlogAuthor>
          {author} on {date}
        </BlogAuthor>
      </PostLink>
    </PostCard>
  </Container>
)

export default BlogPostPreview

const Container = styled(Row)`
  @media (min-width: 770px) {
    margin-bottom: 20px;
  }
  justify-content: center;
`

const PostCard = styled(Column)`
  padding: 0.5rem 1.15rem;
  transition: padding 500ms ease;

  @media (min-width: 770px) {
    padding: 3.5rem 3.15rem;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: rgba(25, 17, 34, 0.05) 0px 3px 10px;
    transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1);

    &:hover {
      box-shadow: rgba(25, 17, 34, 0.1) 0px 10px 42px;
      transform: translateY(-4px);
    }

    &:active {
      box-shadow: rgba(25, 17, 34, 0.1) 0px 10px 42px;
      transform: translateY(-4px);
    }
  }
`

const PostLink = styled(Link)`
  text-decoration: none;
  color: inherit;
`

const PostTitle = styled.h1`
  font-family: ${props => props.theme.headingFont};
  font-size: 1.5rem;
  line-height: 2.5rem;
`

const PostExcerpt = styled.p`
  font-family: ${props => props.theme.headingFont};
  font-size: 1rem;
  margin: 0;
  padding-bottom: 0.5rem;
`

const BlogAuthor = styled.p`
  font-family: ${props => props.theme.headingFont};
  color: ${props => props.theme.secondaryBodyFontColor};
  font-size: 1rem;
`
<|endoftext|>


<commit_before>const fs    = require('fs')
const os    = require('os')
const path  = require('path')

const defaultPaths = {
    darwin: [
        '/Applications/Adobe After Effects CC',
        '/Applications/Adobe After Effects CC 2015',
        '/Applications/Adobe After Effects CC 2016',
        '/Applications/Adobe After Effects CC 2017',
        '/Applications/Adobe After Effects CC 2018',
        '/Applications/Adobe After Effects CC 2019',
        '/Applications/Adobe After Effects 2020',
        '/Applications/Adobe After Effects 2021', // will this be even a thing? :D
        '/Applications/Adobe After Effects CC 2021', // will this be even a thing? :D
    ],
    win32: [
        'C:\\Program Files\\Adobe\\After Effects CC',
        'C:\\Program Files\\Adobe\\After Effects CC\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2015\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2016\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2017\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2018\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2019\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2020\\Support Files',

        'C:\\Program Files\\Adobe\\Adobe After Effects CC',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2015\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2016\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2017\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2018\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2019\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2020\\Support Files',
    ],
}

/**
 * Attemnt to find a aebinary path automatically
 * (using a table of predefined paths)
 * @param  {Object} settings
 * @return {String|null}
 */
module.exports = settings => {
    const platform = os.platform()

    if (!defaultPaths.hasOwnProperty(platform)) {
        return null;
    }

    const binary  = 'aerender' + (platform === 'win32' ? '.exe' : '' )
    const results = defaultPaths[platform]
        .map(folderPath => path.join(folderPath, binary))
        .filter(binaryPath => fs.existsSync(binaryPath))

    // return first matched result
    return results.length ? results[0] : null;
}
<commit_msg>added porbable windows cases<commit_after>const fs    = require('fs')
const os    = require('os')
const path  = require('path')

const defaultPaths = {
    darwin: [
        '/Applications/Adobe After Effects CC',
        '/Applications/Adobe After Effects CC 2015',
        '/Applications/Adobe After Effects CC 2016',
        '/Applications/Adobe After Effects CC 2017',
        '/Applications/Adobe After Effects CC 2018',
        '/Applications/Adobe After Effects CC 2019',
        '/Applications/Adobe After Effects 2020',
        '/Applications/Adobe After Effects 2021',
        '/Applications/Adobe After Effects CC 2021',
    ],
    win32: [
        'C:\\Program Files\\Adobe\\After Effects CC',
        'C:\\Program Files\\Adobe\\After Effects CC\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2015\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2016\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2017\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2018\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2019\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects CC 2020\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects 2020\\Support Files',
        'C:\\Program Files\\Adobe\\After Effects 2021\\Support Files',

        'C:\\Program Files\\Adobe\\Adobe After Effects CC',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2015\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2016\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2017\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2018\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2019\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects CC 2020\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects 2020\\Support Files',
        'C:\\Program Files\\Adobe\\Adobe After Effects 2021\\Support Files',
    ],
}

/**
 * Attemnt to find a aebinary path automatically
 * (using a table of predefined paths)
 * @param  {Object} settings
 * @return {String|null}
 */
module.exports = settings => {
    const platform = os.platform()

    if (!defaultPaths.hasOwnProperty(platform)) {
        return null;
    }

    const binary  = 'aerender' + (platform === 'win32' ? '.exe' : '' )
    const results = defaultPaths[platform]
        .map(folderPath => path.join(folderPath, binary))
        .filter(binaryPath => fs.existsSync(binaryPath))

    // return first matched result
    return results.length ? results[0] : null;
}
<|endoftext|>


<commit_before>describe("Calendar", function() {
  beforeEach(function() {
    this.describedClass = Calendar;
    this.builderFactory = new Calendar.DayBuilder.Factory;
    this.payments = [{ id: 1 }]
    this.buildJsonCalendar = function() {
      return {
        firstDate: 1325372400000,
        lastDate:  1327964400000,
        payments: this.payments
      };
    };

    this.buildSubject = function() {
      return this.subject = new this.describedClass (
        this.buildJsonCalendar(),
        this.builderFactory
      );
    };
  });

  describe('#firsDate', function() {
    it('converts firstDate to Date', function(){
      this.buildSubject();

      expect(this.subject.firstDate).toEqual(new Date(2012, 0, 1));
    });
  });

  describe('#lastDate', function() {
    it('converts lastDate to Date', function(){
      this.buildSubject();

      expect(this.subject.lastDate).toEqual(new Date(2012, 0, 31));
    });
  });

  describe('#payments', function(){
    it ('returns the given payments unwrapped', function() {
      this.buildSubject();

      expect(this.subject.payments).toEqual(this.payments);
    });
  });
});
<commit_msg>Add spec over calendar rows<commit_after>describe("Calendar", function() {
  beforeEach(function() {
    this.describedClass = Calendar;
    this.builderFactory = new Calendar.DayBuilder.Factory;
    this.payments = [{ id: 1 }];
    this.buildJsonCalendar = function() {
      return {
        firstDate: 1325372400000,
        lastDate:  1327964400000,
        payments: this.payments
      };
    };

    this.buildSubject = function() {
      return this.subject = new this.describedClass (
        this.buildJsonCalendar(),
        this.builderFactory
      );
    };
  });

  describe('#firsDate', function() {
    it('converts firstDate to Date', function(){
      this.buildSubject();

      expect(this.subject.firstDate).toEqual(new Date(2012, 0, 1));
    });
  });

  describe('#lastDate', function() {
    it('converts lastDate to Date', function(){
      this.buildSubject();

      expect(this.subject.lastDate).toEqual(new Date(2012, 0, 31));
    });
  });

  describe('#payments', function(){
    it ('returns the given payments unwrapped', function() {
      this.buildSubject();

      expect(this.subject.payments).toEqual(this.payments);
    });
  });

  describe('#rows', function() {
    describe('when the menth is the beggining of the month is the beginning of the week', function() {
      describe('the first date', function() {
        it('has 5 weeks', function() {
          this.buildSubject();

          expect(this.subject.rows.length).toEqual(5);
        });

        it('is the beggining of the month', function() {
          this.buildSubject();

          expect(this.subject.rows[0][0]).toEqual({ day: 1 });
        });
      });

      describe('the last date', function() {
        it('is the end of the week after the end of the month', function() {
          this.buildSubject();

          expect(this.subject.rows[4][6]).toEqual({ day: 4 });
        });
      });
    });

    describe('when the beggining of the month is in the middle of the week', function(){
      beforeEach(function() {
        this.buildJsonCalendar = function() {
          return {
            firstDate: 1328054400000,
            lastDate:  1330473600000,
            payments: this.payments
          };
        };
      });

      describe('the first date', function() {
        it('has 5 weeks', function() {
          this.buildSubject();

          expect(this.subject.rows.length).toEqual(5);
        });

        it('is within the last month', function() {
          console.info(this.buildJsonCalendar().lastDate);
          this.buildSubject();

          expect(this.subject.rows[0][0]).toEqual({ day: 29 });
        });
      });
      describe('the last date', function() {
        it('is the end of the week after the end of the month', function() {
          this.buildSubject();

          expect(this.subject.rows[4][6]).toEqual({ day: 3 });
        });
      });
    });

    describe('when the end of the month matches the end of the week', function(){
      beforeEach(function() {
        this.buildJsonCalendar = function() {
          return {
            firstDate: 1330560000000,
            lastDate:  1333152000000,
            payments: this.payments
          };
        };
      });

      describe('the first date', function() {
        it('has 5 weeks', function() {
          this.buildSubject();

          expect(this.subject.rows.length).toEqual(5);
        });

        it('is within the last month', function() {
          console.info(this.buildJsonCalendar().lastDate);
          this.buildSubject();

          expect(this.subject.rows[0][0]).toEqual({ day: 26 });
        });
      });

      describe('the last date', function() {
        it('is the end of the month', function() {
          this.buildSubject();

          expect(this.subject.rows[4][6]).toEqual({ day: 31 });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { connect } from "react-redux";

import { setValue, clearValues } from "@appbaseio/reactivecore/lib/actions";
import types from "@appbaseio/reactivecore/lib/utils/types";
import { getClassName } from "@appbaseio/reactivecore/lib/utils/helper";
import Button, { filters } from "../../styles/Button";

class SelectedFilters extends Component {
	remove = (component) => {
		this.props.setValue(component, null);
	};

	renderValue = (value, isArray) => {
		if (isArray && value.length) {
			const arrayToRender = value.map(item => this.renderValue(item));
			return arrayToRender.join(", ");
		} else if (value && typeof value === "object") {
			// TODO: support for NestedList
			if (value.label || value.key) {
				return value.label || value.key;
			}
			return null;
		}
		return value;
	}

	render() {
		const { selectedValues } = this.props;
		let hasValues = false;

		return (<div style={this.props.style} className={`${filters} ${this.props.className || ""}`}>
			{
				Object.keys(selectedValues)
					.filter(id => this.props.components.includes(id) && selectedValues[id].showFilter)
					.map((component, index) => {
						const { label, value } = selectedValues[component];
						const isArray = Array.isArray(value);

						if (label && (isArray && value.length) || (!isArray && value)) {
							hasValues = true;
							return (<Button
								className={getClassName(this.props.innerClass, "button") || null}
								key={`${component}-${index}`}
								onClick={() => this.remove(component)}
							>
								{selectedValues[component].label}: {this.renderValue(value, isArray)}
								✕
							</Button>);
						}
						return null;
					})
			}
			{
				hasValues
					? <Button className={getClassName(this.props.innerClass, "button") || null} onClick={this.props.clearValues}>Clear all filters</Button>
					: null
			}

)
	}
}

SelectedFilters.propTypes = {
	selectedValues: types.selectedValues,
	setValue: types.func,
	clearValues: types.func,
	components: types.components,
	style: types.style,
	className: types.string,
	innerClass: types.style
};

SelectedFilters.defaultProps = {
	style: {},
	className: null
}

const mapStateToProps = state => ({
	selectedValues: state.selectedValues,
	components: state.components
});

const mapDispatchtoProps = dispatch => ({
	setValue: (component, value) => dispatch(setValue(component, value)),
	clearValues: () => (dispatch(clearValues()))
});

export default connect(mapStateToProps, mapDispatchtoProps)(SelectedFilters);
<commit_msg>:sparkles: Adds SelectedFilters clear all props closes #122<commit_after>import React, { Component } from "react";
import { connect } from "react-redux";

import { setValue, clearValues } from "@appbaseio/reactivecore/lib/actions";
import types from "@appbaseio/reactivecore/lib/utils/types";
import { getClassName } from "@appbaseio/reactivecore/lib/utils/helper";
import Button, { filters } from "../../styles/Button";

class SelectedFilters extends Component {
	remove = (component) => {
		this.props.setValue(component, null);
	};

	renderValue = (value, isArray) => {
		if (isArray && value.length) {
			const arrayToRender = value.map(item => this.renderValue(item));
			return arrayToRender.join(", ");
		} else if (value && typeof value === "object") {
			// TODO: support for NestedList
			if (value.label || value.key) {
				return value.label || value.key;
			}
			return null;
		}
		return value;
	}

	render() {
		const { selectedValues } = this.props;
		let hasValues = false;

		return (<div style={this.props.style} className={`${filters} ${this.props.className || ""}`}>
			{
				Object.keys(selectedValues)
					.filter(id => this.props.components.includes(id) && selectedValues[id].showFilter)
					.map((component, index) => {
						const { label, value } = selectedValues[component];
						const isArray = Array.isArray(value);

						if (label && (isArray && value.length) || (!isArray && value)) {
							hasValues = true;
							return (<Button
								className={getClassName(this.props.innerClass, "button") || null}
								key={`${component}-${index}`}
								onClick={() => this.remove(component)}
							>
								{selectedValues[component].label}: {this.renderValue(value, isArray)}
								✕
							</Button>);
						}
						return null;
					})
			}
			{
				this.props.showClearAll && hasValues
					? <Button
						className={getClassName(this.props.innerClass, "button") || null}
						onClick={this.props.clearValues}
					>
						{this.props.clearAllLabel}
					</Button>
					: null
			}

)
	}
}

SelectedFilters.propTypes = {
	selectedValues: types.selectedValues,
	setValue: types.func,
	clearValues: types.func,
	components: types.components,
	style: types.style,
	className: types.string,
	innerClass: types.style,
	showClearAll: types.bool,
	clearAllLabel: types.title
};

SelectedFilters.defaultProps = {
	style: {},
	className: null,
	showClearAll: true,
	clearAllLabel: "Clear All"
}

const mapStateToProps = state => ({
	selectedValues: state.selectedValues,
	components: state.components
});

const mapDispatchtoProps = dispatch => ({
	setValue: (component, value) => dispatch(setValue(component, value)),
	clearValues: () => (dispatch(clearValues()))
});

export default connect(mapStateToProps, mapDispatchtoProps)(SelectedFilters);
<|endoftext|>


<commit_before>const React = require('react');
const _isEqual = require('lodash/isEqual');
const _merge = require('lodash/merge');
const _omit = require('lodash/omit');
const _functions = require('lodash/functions');

const StyleConstants = require('../constants/Style');

const Bar = React.createClass({
  propTypes: {
    animateOnHover: React.PropTypes.bool,
    animationDuration: React.PropTypes.number,
    height: React.PropTypes.number,
    hovering: React.PropTypes.bool,
    onClick: React.PropTypes.func,
    onMouseOut: React.PropTypes.func,
    onMouseOver: React.PropTypes.func,
    radius: React.PropTypes.number,
    value: React.PropTypes.number,
    width: React.PropTypes.number,
    x: React.PropTypes.number,
    y: React.PropTypes.number
  },

  componentDidMount () {
    if (this.props.animationDuration) {
      const transform = this._getTransformWithScale(0);

      d3.select(this.bar)
        .attr('transform', transform)
      .transition()
        .duration(this.props.animationDuration)
        .attr('transform', 'scale(1)');
    }
  },

  shouldComponentUpdate (nextProps) {
    return !_isEqual(_omit(nextProps, _functions(nextProps)), _omit(this.props, _functions(this.props)));
  },

  componentDidUpdate () {
    if (this.props.hovering && this.props.animateOnHover) {
      const transform = this._getTransformWithScale(0.9);

      d3.select(this.bar)
        .transition()
          .duration(100)
          .attr('transform', transform)
        .transition()
          .duration(100)
          .attr('transform', 'scale(1)');
    }
  },

  _getTransformWithScale (factor) {
    const centerX = 0;
    const centerY = (this.props.value > 0) ? this.props.y + this.props.height : this.props.y;
    const sx = -centerX * (factor - 1);
    const sy = -centerY * (factor - 1);

    return `translate(${sx},${sy}) scale(1, ${factor})`;
  },

  _drawPath ({ x, y, width, height, value, radius }) {
    if (value > 0) {
      return 'M' + x + ',' + y +
         'h' + (width - radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + radius +
         'v' + (height - radius) +
         'h' + (-width) +
         'v' + (-height + radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + -radius +
         'Z';
    } else {
      return 'M' + x + ',' + y +
         'h' + width +
         'v' + (height - radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + radius +
         'h' + (radius * 2 - width) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + -radius +
         'v' + (radius - height) +
         'Z';
    }
  },

  render () {
    return (
      <path
        d={this._drawPath({
          x: this.props.x,
          y: this.props.y,
          width: this.props.width,
          height: this.props.height,
          value: this.props.value,
          radius: this.props.radius
        })}
        onClick={this.props.onClick}
        onMouseOut={this.props.onMouseOut}
        onMouseOver={this.props.onMouseOver}
        ref={ref => {
          this.bar = ref;
        }}
        style={this.props.style}
      />
    );
  }
});

const BarChart = React.createClass({
  propTypes: {
    animateOnHover: React.PropTypes.bool,
    barRadius: React.PropTypes.number,
    data: React.PropTypes.array.isRequired,
    height: React.PropTypes.number,
    initialSelectedData: React.PropTypes.object,
    margin: React.PropTypes.shape({
      top: React.PropTypes.number,
      right: React.PropTypes.number,
      bottom: React.PropTypes.number,
      left: React.PropTypes.number
    }),
    onClick: React.PropTypes.func,
    onHover: React.PropTypes.func,
    showTooltips: React.PropTypes.bool,
    style: React.PropTypes.object,
    threshold: React.PropTypes.number,
    thresholdStyles: React.PropTypes.object,
    tooltipFormat: React.PropTypes.func,
    width: React.PropTypes.number,
    xAxis: React.PropTypes.element,
    yAxis: React.PropTypes.element
  },

  getDefaultProps () {
    return {
      animateOnHover: false,
      barRadius: 3,
      height: 300,
      margin: {
        top: 20,
        right: 20,
        bottom: 40,
        left: 20
      },
      onClick: () => {},
      onHover: () => {},
      style: {},
      tooltipFormat: (val) => val,
      width: 500,
      showTooltips: true
    };
  },

  getInitialState () {
    return {
      hoveringObj: {},
      clickedData: this.props.initialSelectedData || {}
    };
  },

  shouldComponentUpdate (nextProps, nextState) {
    return !_isEqual(nextProps, this.props) || !_isEqual(nextState, this.state);
  },

  componentDidUpdate () {
    let transform;

    if (Object.keys(this.state.hoveringObj).length) {
      const x = this._getTooltipX();
      const y = this._getTooltipY();

      transform = `translate(${x}, ${y})`;
    } else {
      transform = 'translate(-1000, -1000)';
    }

    d3.select(this.tooltip)
      .attr('transform', transform);
  },

  _handleMouseOver (x, y, width, height, data) {
    this.setState({
      hoveringObj: {
        x,
        y,
        width,
        height,
        value: data.value,
        label: data.label
      }
    });

    this.props.onHover(data);
  },

  _handleMouseOut () {
    this.setState({
      hoveringObj: {}
    });
  },

  _handleOnClick (data) {
    this.setState({
      clickedData: data
    });

    this.props.onClick(data);
  },

  _getTooltipX () {
    if (Object.keys(this.state.hoveringObj).length) {
      const margin = this.props.margin;
      const bb = this.tooltip.getBBox();
      const hoveringObj = this.state.hoveringObj;

      // Center the tooltip on the X Axis of the bar width
      const hoverCX = hoveringObj.width / 2 + hoveringObj.x + margin.left;
      const tooltipCX = bb.width / 2;

      return hoverCX - tooltipCX;
    }
    return -1000;
  },

  _getTooltipY () {
    if (Object.keys(this.state.hoveringObj).length) {
      const margin = this.props.margin;

      if (this.state.hoveringObj.value < 0) {
        return this.state.hoveringObj.y + margin.top + this.state.hoveringObj.height + this.tooltip.getBBox().height;
      }
      return this.state.hoveringObj.y + margin.top - this.tooltip.getBBox().height / 2;
    }
    return -1000;
  },

  render () {
    const styles = _merge({}, this.styles(), this.props.style);
    const { height, margin, width } = this.props;
    const widthMargin = width - margin.left - margin.right;
    const heightMargin = height - margin.top - margin.bottom;

    let hasNegative = false;
    let hasPositive = false;

    const data = this.props.data.map(d => {
      if (!hasNegative && d.value < 0) {
        hasNegative = true;
      } else if (!hasPositive && d.value > 0) {
        hasPositive = true;
      }
      return d.value;
    });
    let yDomain;

    if (hasNegative && hasPositive) {
      yDomain = [Math.min.apply(null, data), Math.max.apply(null, data)];
    } else if (hasNegative && !hasPositive) {
      yDomain = [Math.min.apply(null, data), 0];
    } else {
      yDomain = [0, Math.max.apply(null, data)];
    }

    const xDomain = this.props.data.map(d => {
      return d.label;
    });

    const yFunc = d3.scale.linear()
      .domain(yDomain)
      .range([heightMargin, 0]);

    const xFunc = d3.scale.ordinal()
      .domain(xDomain)
      .rangeRoundBands([0, widthMargin], 0.2);

    return (

        <svg
          height={height + margin.top + margin.bottom}
          preserveAspectRatio='xMinYMin meet'
          width={width + margin.left + margin.right}
          xmlns={'http://www.w3.org/2000/svg'}
        >
          <g transform={`translate(${margin.left},${margin.top})`}>
            {this.props.data.map(d => {
              if (d.value === 0) {
                return null;
              }

              const positive = (d.value > 0);
              const x = xFunc(d.label);
              const y = positive ? yFunc(d.value) : yFunc(0);
              const w = xFunc.rangeBand();
              const h = hasNegative ? Math.abs(yFunc(d.value) - yFunc(0)) : heightMargin - yFunc(d.value);
              const key = d.label + d.value;
              const clicked = this.state.clickedData.value === d.value && this.state.clickedData.label === d.label;
              const hovering = this.state.hoveringObj.value === d.value && this.state.hoveringObj.label === d.label;
              const baseStyle = d.color ? Object.assign({}, styles.bar, { fill: d.color }) : styles.bar;
              let style;

              if (clicked) {
                style = Object.assign({}, baseStyle, positive ? styles.positiveBarClicked : styles.negativeBarClicked);
              } else if (hovering) {
                style = Object.assign({}, baseStyle, positive ? styles.positiveBarHover : styles.negativeBarHover);
              } else {
                style = baseStyle;
              }

              return (
                <Bar
                  animateOnHover={this.props.animateOnHover}
                  animationDuration={700}
                  clicked={clicked}
                  height={h}
                  hovering={hovering}
                  key={key}
                  onClick={this._handleOnClick.bind(null, d)}
                  onMouseOut={this._handleMouseOut}
                  onMouseOver={this._handleMouseOver.bind(null, x, y, w, h, d)}
                  radius={this.props.barRadius}
                  style={style}
                  value={d.value}
                  width={w}
                  x={x}
                  y={y}
                />
              );
            })}
          </g>
          {this.props.yAxis ? this.props.yAxis : null}
          {this.props.xAxis ? this.props.xAxis : null}
          {this.props.threshold ? (
            <g transform={`translate(${margin.left},${margin.top})`}>
              <line
                style={styles.threshold}
                x1={0}
                x2={width - margin.left - margin.right}
                y1={yFunc(this.props.threshold)}
                y2={yFunc(this.props.threshold)}
              />
            </g>
          ) : null }
          <g
            ref={(ref) => {
              this.tooltip = ref;
            }}
            style={styles.tooltipContainer}
          >
            <text style={styles.tooltipText}>
              {this.props.tooltipFormat(this.state.hoveringObj.value)}
            </text>
          </g>
        </svg>

    );
  },

  styles () {
    return {
      bar: {
        fill: StyleConstants.Colors.FOG
      },
      positiveBarHover: {
        fill: StyleConstants.Colors.PRIMARY
      },
      negativeBarHover: {
        fill: StyleConstants.Colors.PRIMARY
      },
      positiveBarClicked: {
        fill: StyleConstants.Colors.PRIMARY
      },
      negativeBarClicked: {
        fill: StyleConstants.Colors.PRIMARY
      },
      tooltipContainer: {

      },
      tooltipText: {
        fontSize: StyleConstants.FontSizes.MEDIUM,
        fontFamily: StyleConstants.Fonts.SEMIBOLD,
        color: StyleConstants.Colors.CHARCOAL,
        textAlign: 'center',
        whiteSpace: 'nowrap'
      },
      threshold: {
        stroke: StyleConstants.Colors.ASH,
        strokeDasharray: '4,4',
        strokeWidth: 1
      }
    };
  }
});

module.exports = BarChart;
<commit_msg>remove thresholdStyles<commit_after>const React = require('react');
const _isEqual = require('lodash/isEqual');
const _merge = require('lodash/merge');
const _omit = require('lodash/omit');
const _functions = require('lodash/functions');

const StyleConstants = require('../constants/Style');

const Bar = React.createClass({
  propTypes: {
    animateOnHover: React.PropTypes.bool,
    animationDuration: React.PropTypes.number,
    height: React.PropTypes.number,
    hovering: React.PropTypes.bool,
    onClick: React.PropTypes.func,
    onMouseOut: React.PropTypes.func,
    onMouseOver: React.PropTypes.func,
    radius: React.PropTypes.number,
    value: React.PropTypes.number,
    width: React.PropTypes.number,
    x: React.PropTypes.number,
    y: React.PropTypes.number
  },

  componentDidMount () {
    if (this.props.animationDuration) {
      const transform = this._getTransformWithScale(0);

      d3.select(this.bar)
        .attr('transform', transform)
      .transition()
        .duration(this.props.animationDuration)
        .attr('transform', 'scale(1)');
    }
  },

  shouldComponentUpdate (nextProps) {
    return !_isEqual(_omit(nextProps, _functions(nextProps)), _omit(this.props, _functions(this.props)));
  },

  componentDidUpdate () {
    if (this.props.hovering && this.props.animateOnHover) {
      const transform = this._getTransformWithScale(0.9);

      d3.select(this.bar)
        .transition()
          .duration(100)
          .attr('transform', transform)
        .transition()
          .duration(100)
          .attr('transform', 'scale(1)');
    }
  },

  _getTransformWithScale (factor) {
    const centerX = 0;
    const centerY = (this.props.value > 0) ? this.props.y + this.props.height : this.props.y;
    const sx = -centerX * (factor - 1);
    const sy = -centerY * (factor - 1);

    return `translate(${sx},${sy}) scale(1, ${factor})`;
  },

  _drawPath ({ x, y, width, height, value, radius }) {
    if (value > 0) {
      return 'M' + x + ',' + y +
         'h' + (width - radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + radius +
         'v' + (height - radius) +
         'h' + (-width) +
         'v' + (-height + radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + radius + ',' + -radius +
         'Z';
    } else {
      return 'M' + x + ',' + y +
         'h' + width +
         'v' + (height - radius) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + radius +
         'h' + (radius * 2 - width) +
         'a' + radius + ',' + radius + ' 0 0 1 ' + -radius + ',' + -radius +
         'v' + (radius - height) +
         'Z';
    }
  },

  render () {
    return (
      <path
        d={this._drawPath({
          x: this.props.x,
          y: this.props.y,
          width: this.props.width,
          height: this.props.height,
          value: this.props.value,
          radius: this.props.radius
        })}
        onClick={this.props.onClick}
        onMouseOut={this.props.onMouseOut}
        onMouseOver={this.props.onMouseOver}
        ref={ref => {
          this.bar = ref;
        }}
        style={this.props.style}
      />
    );
  }
});

const BarChart = React.createClass({
  propTypes: {
    animateOnHover: React.PropTypes.bool,
    barRadius: React.PropTypes.number,
    data: React.PropTypes.array.isRequired,
    height: React.PropTypes.number,
    initialSelectedData: React.PropTypes.object,
    margin: React.PropTypes.shape({
      top: React.PropTypes.number,
      right: React.PropTypes.number,
      bottom: React.PropTypes.number,
      left: React.PropTypes.number
    }),
    onClick: React.PropTypes.func,
    onHover: React.PropTypes.func,
    showTooltips: React.PropTypes.bool,
    style: React.PropTypes.object,
    threshold: React.PropTypes.number,
    tooltipFormat: React.PropTypes.func,
    width: React.PropTypes.number,
    xAxis: React.PropTypes.element,
    yAxis: React.PropTypes.element
  },

  getDefaultProps () {
    return {
      animateOnHover: false,
      barRadius: 3,
      height: 300,
      margin: {
        top: 20,
        right: 20,
        bottom: 40,
        left: 20
      },
      onClick: () => {},
      onHover: () => {},
      style: {},
      tooltipFormat: (val) => val,
      width: 500,
      showTooltips: true
    };
  },

  getInitialState () {
    return {
      hoveringObj: {},
      clickedData: this.props.initialSelectedData || {}
    };
  },

  shouldComponentUpdate (nextProps, nextState) {
    return !_isEqual(nextProps, this.props) || !_isEqual(nextState, this.state);
  },

  componentDidUpdate () {
    let transform;

    if (Object.keys(this.state.hoveringObj).length) {
      const x = this._getTooltipX();
      const y = this._getTooltipY();

      transform = `translate(${x}, ${y})`;
    } else {
      transform = 'translate(-1000, -1000)';
    }

    d3.select(this.tooltip)
      .attr('transform', transform);
  },

  _handleMouseOver (x, y, width, height, data) {
    this.setState({
      hoveringObj: {
        x,
        y,
        width,
        height,
        value: data.value,
        label: data.label
      }
    });

    this.props.onHover(data);
  },

  _handleMouseOut () {
    this.setState({
      hoveringObj: {}
    });
  },

  _handleOnClick (data) {
    this.setState({
      clickedData: data
    });

    this.props.onClick(data);
  },

  _getTooltipX () {
    if (Object.keys(this.state.hoveringObj).length) {
      const margin = this.props.margin;
      const bb = this.tooltip.getBBox();
      const hoveringObj = this.state.hoveringObj;

      // Center the tooltip on the X Axis of the bar width
      const hoverCX = hoveringObj.width / 2 + hoveringObj.x + margin.left;
      const tooltipCX = bb.width / 2;

      return hoverCX - tooltipCX;
    }
    return -1000;
  },

  _getTooltipY () {
    if (Object.keys(this.state.hoveringObj).length) {
      const margin = this.props.margin;

      if (this.state.hoveringObj.value < 0) {
        return this.state.hoveringObj.y + margin.top + this.state.hoveringObj.height + this.tooltip.getBBox().height;
      }
      return this.state.hoveringObj.y + margin.top - this.tooltip.getBBox().height / 2;
    }
    return -1000;
  },

  render () {
    const styles = _merge({}, this.styles(), this.props.style);
    const { height, margin, width } = this.props;
    const widthMargin = width - margin.left - margin.right;
    const heightMargin = height - margin.top - margin.bottom;

    let hasNegative = false;
    let hasPositive = false;

    const data = this.props.data.map(d => {
      if (!hasNegative && d.value < 0) {
        hasNegative = true;
      } else if (!hasPositive && d.value > 0) {
        hasPositive = true;
      }
      return d.value;
    });
    let yDomain;

    if (hasNegative && hasPositive) {
      yDomain = [Math.min.apply(null, data), Math.max.apply(null, data)];
    } else if (hasNegative && !hasPositive) {
      yDomain = [Math.min.apply(null, data), 0];
    } else {
      yDomain = [0, Math.max.apply(null, data)];
    }

    const xDomain = this.props.data.map(d => {
      return d.label;
    });

    const yFunc = d3.scale.linear()
      .domain(yDomain)
      .range([heightMargin, 0]);

    const xFunc = d3.scale.ordinal()
      .domain(xDomain)
      .rangeRoundBands([0, widthMargin], 0.2);

    return (

        <svg
          height={height + margin.top + margin.bottom}
          preserveAspectRatio='xMinYMin meet'
          width={width + margin.left + margin.right}
          xmlns={'http://www.w3.org/2000/svg'}
        >
          <g transform={`translate(${margin.left},${margin.top})`}>
            {this.props.data.map(d => {
              if (d.value === 0) {
                return null;
              }

              const positive = (d.value > 0);
              const x = xFunc(d.label);
              const y = positive ? yFunc(d.value) : yFunc(0);
              const w = xFunc.rangeBand();
              const h = hasNegative ? Math.abs(yFunc(d.value) - yFunc(0)) : heightMargin - yFunc(d.value);
              const key = d.label + d.value;
              const clicked = this.state.clickedData.value === d.value && this.state.clickedData.label === d.label;
              const hovering = this.state.hoveringObj.value === d.value && this.state.hoveringObj.label === d.label;
              const baseStyle = d.color ? Object.assign({}, styles.bar, { fill: d.color }) : styles.bar;
              let style;

              if (clicked) {
                style = Object.assign({}, baseStyle, positive ? styles.positiveBarClicked : styles.negativeBarClicked);
              } else if (hovering) {
                style = Object.assign({}, baseStyle, positive ? styles.positiveBarHover : styles.negativeBarHover);
              } else {
                style = baseStyle;
              }

              return (
                <Bar
                  animateOnHover={this.props.animateOnHover}
                  animationDuration={700}
                  clicked={clicked}
                  height={h}
                  hovering={hovering}
                  key={key}
                  onClick={this._handleOnClick.bind(null, d)}
                  onMouseOut={this._handleMouseOut}
                  onMouseOver={this._handleMouseOver.bind(null, x, y, w, h, d)}
                  radius={this.props.barRadius}
                  style={style}
                  value={d.value}
                  width={w}
                  x={x}
                  y={y}
                />
              );
            })}
          </g>
          {this.props.yAxis ? this.props.yAxis : null}
          {this.props.xAxis ? this.props.xAxis : null}
          {this.props.threshold ? (
            <g transform={`translate(${margin.left},${margin.top})`}>
              <line
                style={styles.threshold}
                x1={0}
                x2={width - margin.left - margin.right}
                y1={yFunc(this.props.threshold)}
                y2={yFunc(this.props.threshold)}
              />
            </g>
          ) : null }
          <g
            ref={(ref) => {
              this.tooltip = ref;
            }}
            style={styles.tooltipContainer}
          >
            <text style={styles.tooltipText}>
              {this.props.tooltipFormat(this.state.hoveringObj.value)}
            </text>
          </g>
        </svg>

    );
  },

  styles () {
    return {
      bar: {
        fill: StyleConstants.Colors.FOG
      },
      positiveBarHover: {
        fill: StyleConstants.Colors.PRIMARY
      },
      negativeBarHover: {
        fill: StyleConstants.Colors.PRIMARY
      },
      positiveBarClicked: {
        fill: StyleConstants.Colors.PRIMARY
      },
      negativeBarClicked: {
        fill: StyleConstants.Colors.PRIMARY
      },
      tooltipContainer: {

      },
      tooltipText: {
        fontSize: StyleConstants.FontSizes.MEDIUM,
        fontFamily: StyleConstants.Fonts.SEMIBOLD,
        color: StyleConstants.Colors.CHARCOAL,
        textAlign: 'center',
        whiteSpace: 'nowrap'
      },
      threshold: {
        stroke: StyleConstants.Colors.ASH,
        strokeDasharray: '4,4',
        strokeWidth: 1
      }
    };
  }
});

module.exports = BarChart;
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Util = require('../util');

var CAMEL_TO_UNDERSCORE = {
  video: 'video',
  image: 'image',
  preview: 'preview',
  loop: 'loop',
  volume: 'volume',
  muted: 'muted',
  isStereo: 'is_stereo',
  defaultYaw: 'default_yaw',
  isYawOnly: 'is_yaw_only',
  isDebug: 'is_debug',
  isVROff: 'is_vr_off',
  isAutopanOff: 'is_autopan_off',
  hideFullscreenButton: 'hide_fullscreen_button'
};

/**
 * Contains all information about a given scene.
 */
function SceneInfo(opt_params) {
  var params = opt_params || {};
  params.player = {
    loop: opt_params.loop,
    volume: opt_params.volume,
    muted: opt_params.muted
  };

  this.image = params.image;
  this.preview = params.preview;
  this.video = params.video;
  this.defaultYaw = THREE.Math.degToRad(params.defaultYaw || 0);

  this.isStereo = Util.parseBoolean(params.isStereo);
  this.isYawOnly = Util.parseBoolean(params.isYawOnly);
  this.isDebug = Util.parseBoolean(params.isDebug);
  this.isVROff = Util.parseBoolean(params.isVROff);
  this.isAutopanOff = Util.parseBoolean(params.isAutopanOff);
  this.loop = Util.parseBoolean(params.player.loop);
  this.volume = parseFloat(
      params.player.volume ? params.player.volume : '1');
  this.muted = Util.parseBoolean(params.player.muted);
  this.hideFullscreenButton = Util.parseBoolean(params.hideFullscreenButton);
}

SceneInfo.loadFromGetParams = function() {
  var params = {};
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    params[camelCase] = Util.getQueryParameter(underscore)
                        || ((window.WebVRConfig && window.WebVRConfig.PLAYER) ? window.WebVRConfig.PLAYER[underscore] : "");
  }
  var scene = new SceneInfo(params);
  if (!scene.isValid()) {
    console.warn('Invalid scene: %s', scene.errorMessage);
  }
  return scene;
};

SceneInfo.loadFromAPIParams = function(underscoreParams) {
  var params = {};
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    if (underscoreParams[underscore]) {
      params[camelCase] = underscoreParams[underscore];
    }
  }
  var scene = new SceneInfo(params);
  if (!scene.isValid()) {
    console.warn('Invalid scene: %s', scene.errorMessage);
  }
  return scene;
};

SceneInfo.prototype.isValid = function() {
  // Either it's an image or a video.
  if (!this.image && !this.video) {
    this.errorMessage = 'Either image or video URL must be specified.';
    return false;
  }
  if (this.image && this.video) {
    this.errorMessage = 'Both image and video URL can\'t be specified.';
    return false;
  }
  if (this.image && !this.isValidImage_(this.image)) {
    this.errorMessage = 'Invalid image URL: ' + this.image;
    return false;
  }
  this.errorMessage = null;
  return true;
};

/**
 * Generates a URL to reflect this scene.
 */
SceneInfo.prototype.getCurrentUrl = function() {
  var url = location.protocol + '//' + location.host + location.pathname + '?';
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    var value = this[camelCase];
    if (value !== undefined) {
      url += underscore + '=' + value + '&';
    }
  }
  // Chop off the trailing ampersand.
  return url.substring(0, url.length - 1);
};

SceneInfo.prototype.isValidImage_ = function(imageUrl) {
  return true;
};

module.exports = SceneInfo;
<commit_msg>Removes the image && video check to enable the IE11 fallback<commit_after>/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var Util = require('../util');

var CAMEL_TO_UNDERSCORE = {
  video: 'video',
  image: 'image',
  preview: 'preview',
  loop: 'loop',
  volume: 'volume',
  muted: 'muted',
  isStereo: 'is_stereo',
  defaultYaw: 'default_yaw',
  isYawOnly: 'is_yaw_only',
  isDebug: 'is_debug',
  isVROff: 'is_vr_off',
  isAutopanOff: 'is_autopan_off',
  hideFullscreenButton: 'hide_fullscreen_button'
};

/**
 * Contains all information about a given scene.
 */
function SceneInfo(opt_params) {
  var params = opt_params || {};
  params.player = {
    loop: opt_params.loop,
    volume: opt_params.volume,
    muted: opt_params.muted
  };

  this.image = params.image;
  this.preview = params.preview;
  this.video = params.video;
  this.defaultYaw = THREE.Math.degToRad(params.defaultYaw || 0);

  this.isStereo = Util.parseBoolean(params.isStereo);
  this.isYawOnly = Util.parseBoolean(params.isYawOnly);
  this.isDebug = Util.parseBoolean(params.isDebug);
  this.isVROff = Util.parseBoolean(params.isVROff);
  this.isAutopanOff = Util.parseBoolean(params.isAutopanOff);
  this.loop = Util.parseBoolean(params.player.loop);
  this.volume = parseFloat(
      params.player.volume ? params.player.volume : '1');
  this.muted = Util.parseBoolean(params.player.muted);
  this.hideFullscreenButton = Util.parseBoolean(params.hideFullscreenButton);
}

SceneInfo.loadFromGetParams = function() {
  var params = {};
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    params[camelCase] = Util.getQueryParameter(underscore)
                        || ((window.WebVRConfig && window.WebVRConfig.PLAYER) ? window.WebVRConfig.PLAYER[underscore] : "");
  }
  var scene = new SceneInfo(params);
  if (!scene.isValid()) {
    console.warn('Invalid scene: %s', scene.errorMessage);
  }
  return scene;
};

SceneInfo.loadFromAPIParams = function(underscoreParams) {
  var params = {};
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    if (underscoreParams[underscore]) {
      params[camelCase] = underscoreParams[underscore];
    }
  }
  var scene = new SceneInfo(params);
  if (!scene.isValid()) {
    console.warn('Invalid scene: %s', scene.errorMessage);
  }
  return scene;
};

SceneInfo.prototype.isValid = function() {
  // Either it's an image or a video.
  if (!this.image && !this.video) {
    this.errorMessage = 'Either image or video URL must be specified.';
    return false;
  }
  if (this.image && !this.isValidImage_(this.image)) {
    this.errorMessage = 'Invalid image URL: ' + this.image;
    return false;
  }
  this.errorMessage = null;
  return true;
};

/**
 * Generates a URL to reflect this scene.
 */
SceneInfo.prototype.getCurrentUrl = function() {
  var url = location.protocol + '//' + location.host + location.pathname + '?';
  for (var camelCase in CAMEL_TO_UNDERSCORE) {
    var underscore = CAMEL_TO_UNDERSCORE[camelCase];
    var value = this[camelCase];
    if (value !== undefined) {
      url += underscore + '=' + value + '&';
    }
  }
  // Chop off the trailing ampersand.
  return url.substring(0, url.length - 1);
};

SceneInfo.prototype.isValidImage_ = function(imageUrl) {
  return true;
};

module.exports = SceneInfo;
<|endoftext|>


<commit_before>//= require openseadragon

(function($) {
  var __osd_counter = 0;
  function generateOsdId() {
    __osd_counter++;

    return "Openseadragon" + __osd_counter;
  }

  function initOpenSeadragon() {
    $('picture[data-openseadragon]').each(function() {
      var $picture = $(this);

      if (typeof $picture.attr('id') === "undefined") {
        $picture.attr('id', generateOsdId());
      }

      var collectionOptions = $picture.data('openseadragon');

      var sources = $picture.find('source[media="openseadragon"]');

      var tilesources = $.map(sources, function(e) {
        if ($(e).data('openseadragon')) {
          return $(e).data('openseadragon');
        } else {
          return $(e).attr('src');
        }
      });

      $picture.css("display", "block");
      $picture.css("height", "500px");

      OpenSeadragon(
        $.extend({ id: $picture.attr('id') }, collectionOptions, { tileSources: tilesources })
      );
    });
  };

  window.onload = initOpenSeadragon;
  document.addEventListener("page:load", initOpenSeadragon);
})(jQuery);
<commit_msg>Store OpenSeadragon.Viewer instantiation object handle<commit_after>//= require openseadragon

(function($) {
  var __osd_counter = 0;
  function generateOsdId() {
    __osd_counter++;

    return "Openseadragon" + __osd_counter;
  }

  function initOpenSeadragon() {
    $('picture[data-openseadragon]').each(function() {
      var $picture = $(this);

      if (typeof $picture.attr('id') === "undefined") {
        $picture.attr('id', generateOsdId());
      }

      var collectionOptions = $picture.data('openseadragon');

      var sources = $picture.find('source[media="openseadragon"]');

      var tilesources = $.map(sources, function(e) {
        if ($(e).data('openseadragon')) {
          return $(e).data('openseadragon');
        } else {
          return $(e).attr('src');
        }
      });

      $picture.css("display", "block");
      $picture.css("height", "500px");

      $picture.data('osdViewer', OpenSeadragon(
        $.extend({ id: $picture.attr('id') }, collectionOptions, { tileSources: tilesources })
      ));
    });
  };

  window.onload = initOpenSeadragon;
  document.addEventListener("page:load", initOpenSeadragon);
})(jQuery);<|endoftext|>


<commit_before>(function () {
  'use strict';

  host.global.helpers = {
    /**
     * Returns a POJO with the default JsonSchemaLib configuration
     *
     * @returns {object}
     */
    getDefaultConfig: function getDefaultConfig () {
      return {
        Promise: jsonSchemaLib.config.Promise,
        http: {
          headers: {},
          maxRedirects: 5,
          timeout: 5000,
          withCredentials: false,
        }
      };
    },

    /**
     * Returns an array of POJOs that matches the default JsonSchemaLib plugins
     *
     * @returns {object[]}
     */
    getDefaultPlugins: function getDefaultPlugins () {
      return host.node
        ? [
          { name: 'NodeUrlPlugin', priority: 20 },
          { name: 'FileSystemPlugin', priority: 10 },
          { name: 'HttpPlugin', priority: 5 },
          { name: 'BufferDecoderPlugin', priority: 10 },
          { name: 'ArrayDecoderPlugin', priority: 5 },
          { name: 'JsonPlugin', priority: 20 },
        ]
        : [
          { name: 'BrowserUrlPlugin', priority: 20 },
          { name: 'XMLHttpRequestPlugin', priority: 5 },
          { name: 'TextDecoderPlugin', priority: 10 },
          { name: 'ArrayDecoderPlugin', priority: 5 },
          { name: 'JsonPlugin', priority: 20 },
        ];
    },
  };

}());
<commit_msg>added a parameter to return plugins sorted vs. unsorted<commit_after>(function () {
  'use strict';

  host.global.helpers = {
    /**
     * Returns a POJO with the default JsonSchemaLib configuration
     *
     * @returns {object}
     */
    getDefaultConfig: function getDefaultConfig () {
      return {
        Promise: jsonSchemaLib.config.Promise,
        http: {
          headers: {},
          maxRedirects: 5,
          timeout: 5000,
          withCredentials: false,
        }
      };
    },

    /**
     * Returns an array of POJOs that matches the default JsonSchemaLib plugins
     *
     * @param {boolean} sorted
     * @returns {object[]}
     */
    getDefaultPlugins: function getDefaultPlugins (sorted) {
      if (host.node) {
        if (sorted) {
          return [
            { name: 'NodeUrlPlugin', priority: 20 },
            { name: 'JsonPlugin', priority: 20 },
            { name: 'FileSystemPlugin', priority: 10 },
            { name: 'BufferDecoderPlugin', priority: 10 },
            { name: 'HttpPlugin', priority: 5 },
            { name: 'ArrayDecoderPlugin', priority: 5 },
          ];
        }
        else {
          return [
            { name: 'NodeUrlPlugin', priority: 20 },
            { name: 'FileSystemPlugin', priority: 10 },
            { name: 'HttpPlugin', priority: 5 },
            { name: 'BufferDecoderPlugin', priority: 10 },
            { name: 'ArrayDecoderPlugin', priority: 5 },
            { name: 'JsonPlugin', priority: 20 },
          ];
        }
      }
      else {
        if (sorted) {
          return [
            { name: 'BrowserUrlPlugin', priority: 20 },
            { name: 'JsonPlugin', priority: 20 },
            { name: 'TextDecoderPlugin', priority: 10 },
            { name: 'XMLHttpRequestPlugin', priority: 5 },
            { name: 'ArrayDecoderPlugin', priority: 5 },
          ];
        }
        else {
          return [
            { name: 'BrowserUrlPlugin', priority: 20 },
            { name: 'XMLHttpRequestPlugin', priority: 5 },
            { name: 'TextDecoderPlugin', priority: 10 },
            { name: 'ArrayDecoderPlugin', priority: 5 },
            { name: 'JsonPlugin', priority: 20 },
          ];
        }
      }
    },
  };

}());
<|endoftext|>


<commit_before>'use strict';

// VARIABLES //

var valid;
var test;

// MAIN //

// Create our test cases:
valid = [];

test = {
	'code': [
		'/**',
		'* Squares a number.',
		'* ',
		'* @param {number} x - input number',
		'* @returns {number} x squared',
		'*',
		'* @example',
		'* var y = square( 2.0 );',
		'* // returns 4.0',
		'*/',
		'function square( x ) {',
		'  return x*x;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Returns a pseudo-random number on `[0,1]`.',
		'* ',
		'* @returns {number} uniform random number',
		'*',
		'* @example',
		'* var y = rand();',
		'* // e.g., returns 0.5363925252089496',
		'*/',
		'function rand() {',
		'  return Math.random();',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Returns the number of minutes in a month.',
		'*',
		'* @param {(string|Date|integer)} [month] - month',
		'* @param {integer} [year] - year',
		'* @throws {TypeError} first argument must be either a string, integer, or `Date` object',
		'* @throws {Error} must provide a recognized month',
		'* @throws {RangeError} an integer month argument must be on the interval `[1,12]`',
		'* @throws {TypeError} second argument must be an integer',
		'* @returns {integer} minutes in a month',
		'*',
		'* @example',
		'* var num = minutesInMonth();',
		'* // returns <number>',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2 );',
		'* // returns <number>',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2, 2016 );',
		'* // returns 41760',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2, 2017 );',
		'* // returns 40320',
		'*/',
		'function minutesInMonth( month, year ) {',
		'	var mins;',
		'	var mon;',
		'	var yr;',
		'	var d;',
		'	if ( arguments.length === 0 ) {',
		'		// Note: cannot cache as application may cross over into a new year:',
		'		d = new Date();',
		'		mon = d.getMonth() + 1; // zero-based',
		'		yr = d.getFullYear();',
		'	} else if ( arguments.length === 1 ) {',
		'		if ( isDateObject( month ) ) {',
		'			d = month;',
		'			mon = d.getMonth() + 1; // zero-based',
		'			yr = d.getFullYear();',
		'		} else if ( isString( month ) || isInteger( month ) ) {',
		'			// Note: cannot cache as application may cross over into a new year:',
		'			yr = ( new Date() ).getFullYear();',
		'			mon = month;',
		'		} else {',
		'			throw new TypeError( \'invalid input argument. First argument must be either a string, integer, or `Date` object. Value: `\'+month+\'`.\' );',
		'		}',
		'	} else {',
		'		if ( !isString( month ) && !isInteger( month ) ) {',
		'			throw new TypeError( \'invalid input argument. First argument must be either a string or integer. Value: `\'+month+\'`.\' );',
		'		}',
		'		if ( !isInteger( year ) ) {',
		'			throw new TypeError( \'invalid input argument. Second argument must be an integer. Value: `\'+year+\'`.\' );',
		'		}',
		'		mon = month;',
		'		yr = year;',
		'	}',
		'	if ( isInteger( mon ) && (mon < 1 || mon > 12) ) {',
		'		throw new RangeError( \'invalid input argument. An integer month value must be on the interval `[1,12]`. Value: `\'+mon+\'`.\' );',
		'	}',
		'	mon = lowercase( mon.toString() );',
		'	mins = MINUTES_IN_MONTH[ mon ];',
		'	if ( mins === void 0 ) {',
		'		throw new Error( \'invalid input argument. Must provide a recognized month. Value: `\'+mon+\'`.\' );',
		'	}',
		'	// Check if February during a leap year...',
		'	if ( mins === 40320 && isLeapYear( yr ) ) {',
		'		mins += MINUTES_IN_DAY;',
		'	}',
		'	return mins;',
		'} // end FUNCTION minutesInMonth()'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Removes a UTF-8 byte order mark (BOM) from the beginning of a string.',
		'*',
		'* ## Notes',
		'*',
		'* -   A UTF-8 byte order mark ([BOM][1]) is the byte sequence `0xEF,0xBB,0xBF`.',
		'* -   To convert a UTF-8 encoded `Buffer` to a `string`, the `Buffer` must be converted to \'[UTF-16][2]. The BOM thus gets converted to the single 16-bit code point `\'\ufeff\'` \'(UTF-16 BOM).',
		'*',
		'* [1]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8',
		'* [2]: http://es5.github.io/#x4.3.16',
		'*',
		'*',
		'* @param {string} str - input string',
		'* @throws {TypeError} must provide a string primitive',
		'* @returns {string} string with BOM removed',
		'*',
		'* @example',
		'* var str = removeUTF8BOM( \'\ufeffbeep\' );',
		'* // returns \'beep\'',
		'*/',
		'function removeUTF8BOM( str ) {',
		'	if ( !isString( str ) ) {',
		'		throw new TypeError( \'invalid input argument. Must provide a string primitive. Value: `\' + str + \'`.\' );',
		'	}',
		'	if ( str.charCodeAt( 0 ) === BOM ) {',
		'		return str.slice( 1 );',
		'	}',
		'	return str;',
		'} // end FUNCTION removeUTF8BOM()'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* @name arcsine',
		'* @memberof random',
		'* @readonly',
		'* @type {Function}',
		'* @see {@link module:@stdlib/random/base/arcsine}',
		'*/',
		'setReadOnly( random, \'arcsine\', require( \'@stdlib/random/base/arcsine\' ) );'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* > A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* > Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* > A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* > Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* >   A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* >   Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* >        A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* >        Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

// EXPORTS //

module.exports = valid;
<commit_msg>Remove duplicates<commit_after>'use strict';

// VARIABLES //

var valid;
var test;

// MAIN //

// Create our test cases:
valid = [];

test = {
	'code': [
		'/**',
		'* Squares a number.',
		'* ',
		'* @param {number} x - input number',
		'* @returns {number} x squared',
		'*',
		'* @example',
		'* var y = square( 2.0 );',
		'* // returns 4.0',
		'*/',
		'function square( x ) {',
		'  return x*x;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Returns a pseudo-random number on `[0,1]`.',
		'* ',
		'* @returns {number} uniform random number',
		'*',
		'* @example',
		'* var y = rand();',
		'* // e.g., returns 0.5363925252089496',
		'*/',
		'function rand() {',
		'  return Math.random();',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Returns the number of minutes in a month.',
		'*',
		'* @param {(string|Date|integer)} [month] - month',
		'* @param {integer} [year] - year',
		'* @throws {TypeError} first argument must be either a string, integer, or `Date` object',
		'* @throws {Error} must provide a recognized month',
		'* @throws {RangeError} an integer month argument must be on the interval `[1,12]`',
		'* @throws {TypeError} second argument must be an integer',
		'* @returns {integer} minutes in a month',
		'*',
		'* @example',
		'* var num = minutesInMonth();',
		'* // returns <number>',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2 );',
		'* // returns <number>',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2, 2016 );',
		'* // returns 41760',
		'*',
		'* @example',
		'* var num = minutesInMonth( 2, 2017 );',
		'* // returns 40320',
		'*/',
		'function minutesInMonth( month, year ) {',
		'	var mins;',
		'	var mon;',
		'	var yr;',
		'	var d;',
		'	if ( arguments.length === 0 ) {',
		'		// Note: cannot cache as application may cross over into a new year:',
		'		d = new Date();',
		'		mon = d.getMonth() + 1; // zero-based',
		'		yr = d.getFullYear();',
		'	} else if ( arguments.length === 1 ) {',
		'		if ( isDateObject( month ) ) {',
		'			d = month;',
		'			mon = d.getMonth() + 1; // zero-based',
		'			yr = d.getFullYear();',
		'		} else if ( isString( month ) || isInteger( month ) ) {',
		'			// Note: cannot cache as application may cross over into a new year:',
		'			yr = ( new Date() ).getFullYear();',
		'			mon = month;',
		'		} else {',
		'			throw new TypeError( \'invalid input argument. First argument must be either a string, integer, or `Date` object. Value: `\'+month+\'`.\' );',
		'		}',
		'	} else {',
		'		if ( !isString( month ) && !isInteger( month ) ) {',
		'			throw new TypeError( \'invalid input argument. First argument must be either a string or integer. Value: `\'+month+\'`.\' );',
		'		}',
		'		if ( !isInteger( year ) ) {',
		'			throw new TypeError( \'invalid input argument. Second argument must be an integer. Value: `\'+year+\'`.\' );',
		'		}',
		'		mon = month;',
		'		yr = year;',
		'	}',
		'	if ( isInteger( mon ) && (mon < 1 || mon > 12) ) {',
		'		throw new RangeError( \'invalid input argument. An integer month value must be on the interval `[1,12]`. Value: `\'+mon+\'`.\' );',
		'	}',
		'	mon = lowercase( mon.toString() );',
		'	mins = MINUTES_IN_MONTH[ mon ];',
		'	if ( mins === void 0 ) {',
		'		throw new Error( \'invalid input argument. Must provide a recognized month. Value: `\'+mon+\'`.\' );',
		'	}',
		'	// Check if February during a leap year...',
		'	if ( mins === 40320 && isLeapYear( yr ) ) {',
		'		mins += MINUTES_IN_DAY;',
		'	}',
		'	return mins;',
		'} // end FUNCTION minutesInMonth()'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Removes a UTF-8 byte order mark (BOM) from the beginning of a string.',
		'*',
		'* ## Notes',
		'*',
		'* -   A UTF-8 byte order mark ([BOM][1]) is the byte sequence `0xEF,0xBB,0xBF`.',
		'* -   To convert a UTF-8 encoded `Buffer` to a `string`, the `Buffer` must be converted to \'[UTF-16][2]. The BOM thus gets converted to the single 16-bit code point `\'\ufeff\'` \'(UTF-16 BOM).',
		'*',
		'* [1]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8',
		'* [2]: http://es5.github.io/#x4.3.16',
		'*',
		'*',
		'* @param {string} str - input string',
		'* @throws {TypeError} must provide a string primitive',
		'* @returns {string} string with BOM removed',
		'*',
		'* @example',
		'* var str = removeUTF8BOM( \'\ufeffbeep\' );',
		'* // returns \'beep\'',
		'*/',
		'function removeUTF8BOM( str ) {',
		'	if ( !isString( str ) ) {',
		'		throw new TypeError( \'invalid input argument. Must provide a string primitive. Value: `\' + str + \'`.\' );',
		'	}',
		'	if ( str.charCodeAt( 0 ) === BOM ) {',
		'		return str.slice( 1 );',
		'	}',
		'	return str;',
		'} // end FUNCTION removeUTF8BOM()'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* @name arcsine',
		'* @memberof random',
		'* @readonly',
		'* @type {Function}',
		'* @see {@link module:@stdlib/random/base/arcsine}',
		'*/',
		'setReadOnly( random, \'arcsine\', require( \'@stdlib/random/base/arcsine\' ) );'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* > A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* > Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

test = {
	'code': [
		'/**',
		'* Beep boop.',
		'*',
		'* >   A blockquote.',
		'*',
		'* ## Heading',
		'*',
		'* >   Another blockquote',
		'*',
		'* Some code...',
		'*',
		'* ```javascript',
		'* var f = foo();',
		'* ```',
		'*',
		'* Some LaTeX...',
		'*',
		'* ```tex',
		'* \\frac{1}{2}',
		'* ```',
		'*',
		'* ## Notes',
		'*',
		'* -   First.',
		'* -   Second.',
		'* -   Third.',
		'*',
		'* ## References',
		'*',
		'* -   Jane Doe. Science. 2017.',
		'*',
		'* | x | y |',
		'* | 1 | 2 |',
		'* | 2 | 1 |',
		'*',
		'*',
		'* @param {string} str - input value',
		'* @returns {string} output value',
		'*',
		'* @example',
		'* var out = beep( "boop" );',
		'* // returns "beepboop"',
		'*/',
		'function beep( str ) {',
		'\treturn "beep" + str;',
		'}'
	].join( '\n' )
};
valid.push( test );

// EXPORTS //

module.exports = valid;
<|endoftext|>


<commit_before>const command = {
  command: "test",
  description: "Run JavaScript and Solidity tests",
  builder: {
    "show-events": {
      describe: "Show all test logs",
      type: "boolean",
      default: false
    }
  },
  help: {
    usage:
      "truffle test [<test_file>] [--compile-all] [--network <name>] [--verbose-rpc] [--show-events]",
    options: [
      {
        option: "<test_file>",
        description:
          "Name of the test file to be run. Can include path information if the file " +
          "does not exist in the\n                    current directory."
      },
      {
        option: "--compile-all",
        description:
          "Compile all contracts instead of intelligently choosing which contracts need " +
          "to be compiled."
      },
      {
        option: "--network <name>",
        description:
          "Specify the network to use, using artifacts specific to that network. Network " +
          "name must exist\n                    in the configuration."
      },
      {
        option: "--verbose-rpc",
        description:
          "Log communication between Truffle and the Ethereum client."
      },
      {
        option: "--show-events",
        description: "Log all contract events."
      }
    ]
  },
  run: function(options, done) {
    const OS = require("os");
    const dir = require("node-dir");
    const temp = require("temp").track();
    const Config = require("truffle-config");
    const Artifactor = require("truffle-artifactor");
    const Develop = require("../develop");
    const Test = require("../test");
    const fs = require("fs");
    const { promisify } = require("util");
    const promisifiedCopy = promisify(require("../copy"));
    const Environment = require("../environment");

    var config = Config.detect(options);

    // if "development" exists, default to using that for testing
    if (!config.network && config.networks.development) {
      config.network = "development";
    }

    if (!config.network) {
      config.network = "test";
    } else {
      Environment.detect(config).catch(done);
    }

    var ipcDisconnect;

    let files = [];

    if (options.file) {
      files = [options.file];
    } else if (options._.length > 0) {
      Array.prototype.push.apply(files, options._);
    }

    try {
      if (files.length === 0) {
        files = dir.files(config.test_directory, { sync: true });
      }
    } catch (error) {
      return done(error);
    }

    files = files.filter(function(file) {
      return file.match(config.test_file_extension_regexp) != null;
    });

    temp.mkdir("test-", function(err, temporaryDirectory) {
      if (err) return done(err);

      function runCallback() {
        var args = arguments;
        // Ensure directory cleanup.
        done.apply(null, args);
        if (ipcDisconnect) {
          ipcDisconnect();
        }
      }

      function run() {
        // Set a new artifactor; don't rely on the one created by Environments.
        // TODO: Make the test artifactor configurable.
        config.artifactor = new Artifactor(temporaryDirectory);

        Test.run(
          config.with({
            test_files: files,
            contracts_build_directory: temporaryDirectory
          }),
          runCallback
        );
      }

      const environmentCallback = function(err) {
        if (err) return done(err);
        // Copy all the built files over to a temporary directory, because we
        // don't want to save any tests artifacts. Only do this if the build directory
        // exists.
        try {
          fs.statSync(config.contracts_build_directory);
        } catch (_error) {
          return run();
        }

        promisifiedCopy(config.contracts_build_directory, temporaryDirectory)
          .then(() => {
            config.logger.log(
              "Using network '" + config.network + "'." + OS.EOL
            );

            run();
          })
          .catch(done);
      };

      if (config.networks[config.network]) {
        Environment.detect(config)
          .then(() => environmentCallback())
          .catch(environmentCallback);
      } else {
        const ipcOptions = { network: "test" };

        const ganacheOptions = {
          host: "127.0.0.1",
          port: 7545,
          network_id: 4447,
          mnemonic:
            "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat",
          gasLimit: config.gas,
          noVMErrorsOnRPCResponse: true
        };
        Develop.connectOrStart(
          ipcOptions,
          ganacheOptions,
          (started, disconnect) => {
            ipcDisconnect = disconnect;
            Environment.develop(config, ganacheOptions)
              .then(() => environmentCallback())
              .catch(environmentCallback);
          }
        );
      }
    });
  }
};

module.exports = command;
<commit_msg>Use synchronous version of temp.mkdir method to remove another callback<commit_after>const command = {
  command: "test",
  description: "Run JavaScript and Solidity tests",
  builder: {
    "show-events": {
      describe: "Show all test logs",
      type: "boolean",
      default: false
    }
  },
  help: {
    usage:
      "truffle test [<test_file>] [--compile-all] [--network <name>] [--verbose-rpc] [--show-events]",
    options: [
      {
        option: "<test_file>",
        description:
          "Name of the test file to be run. Can include path information if the file " +
          "does not exist in the\n                    current directory."
      },
      {
        option: "--compile-all",
        description:
          "Compile all contracts instead of intelligently choosing which contracts need " +
          "to be compiled."
      },
      {
        option: "--network <name>",
        description:
          "Specify the network to use, using artifacts specific to that network. Network " +
          "name must exist\n                    in the configuration."
      },
      {
        option: "--verbose-rpc",
        description:
          "Log communication between Truffle and the Ethereum client."
      },
      {
        option: "--show-events",
        description: "Log all contract events."
      }
    ]
  },
  run: function(options, done) {
    const OS = require("os");
    const dir = require("node-dir");
    const temp = require("temp").track();
    const Config = require("truffle-config");
    const Artifactor = require("truffle-artifactor");
    const Develop = require("../develop");
    const Test = require("../test");
    const fs = require("fs");
    const { promisify } = require("util");
    const promisifiedCopy = promisify(require("../copy"));
    const Environment = require("../environment");

    var config = Config.detect(options);

    // if "development" exists, default to using that for testing
    if (!config.network && config.networks.development) {
      config.network = "development";
    }

    if (!config.network) {
      config.network = "test";
    } else {
      Environment.detect(config).catch(done);
    }

    var ipcDisconnect;

    let files = [];

    if (options.file) {
      files = [options.file];
    } else if (options._.length > 0) {
      Array.prototype.push.apply(files, options._);
    }

    try {
      if (files.length === 0) {
        files = dir.files(config.test_directory, { sync: true });
      }
    } catch (error) {
      return done(error);
    }

    files = files.filter(function(file) {
      return file.match(config.test_file_extension_regexp) != null;
    });

    let temporaryDirectory;
    try {
      temporaryDirectory = temp.mkdirSync("test-");
    } catch (error) {
      return done(error);
    }

    function runCallback() {
      var args = arguments;
      // Ensure directory cleanup.
      done.apply(null, args);
      if (ipcDisconnect) {
        ipcDisconnect();
      }
    }

    function run() {
      // Set a new artifactor; don't rely on the one created by Environments.
      // TODO: Make the test artifactor configurable.
      config.artifactor = new Artifactor(temporaryDirectory);

      Test.run(
        config.with({
          test_files: files,
          contracts_build_directory: temporaryDirectory
        }),
        runCallback
      );
    }

    const environmentCallback = function(err) {
      if (err) return done(err);
      // Copy all the built files over to a temporary directory, because we
      // don't want to save any tests artifacts. Only do this if the build directory
      // exists.
      try {
        fs.statSync(config.contracts_build_directory);
      } catch (_error) {
        return run();
      }

      promisifiedCopy(config.contracts_build_directory, temporaryDirectory)
        .then(() => {
          config.logger.log("Using network '" + config.network + "'." + OS.EOL);

          run();
        })
        .catch(done);
    };

    if (config.networks[config.network]) {
      Environment.detect(config)
        .then(() => environmentCallback())
        .catch(environmentCallback);
    } else {
      const ipcOptions = { network: "test" };

      const ganacheOptions = {
        host: "127.0.0.1",
        port: 7545,
        network_id: 4447,
        mnemonic:
          "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat",
        gasLimit: config.gas,
        noVMErrorsOnRPCResponse: true
      };
      Develop.connectOrStart(
        ipcOptions,
        ganacheOptions,
        (started, disconnect) => {
          ipcDisconnect = disconnect;
          Environment.develop(config, ganacheOptions)
            .then(() => environmentCallback())
            .catch(environmentCallback);
        }
      );
    }
  }
};

module.exports = command;
<|endoftext|>