<commit_before>/* jshint node:true */
/**
 * MIT licensed, see LICENSE file
 * Copyright (c) Venkateswara VP <reflexdemon@github>
 */

(function() {
    'use strict';
    var gulp = require('gulp'),
        testingUtil = require('./testing_util'),
        util = require('../util'),
        _ = require('lodash'),
        mockGulpDest = require('mock-gulp-dest')(gulp);

    var assert = require('assertthat');

    require('../slushfile');
    describe('slush-angular-gulp', function() {
        before(function() {
            process.chdir(__dirname);
        });
        describe('default generator', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    name: 'module'
                });
            });
            it('should put all project files in current working directory', function(done) {
                gulp.start('default').once('stop', function() {
                    // mockGulpDest.cwd().should.equal(__dirname);
                    // mockGulpDest.basePath().should.equal(__dirname);

                    assert.that(mockGulpDest.cwd()).is.equalTo(__dirname);
                    assert.that(mockGulpDest.basePath()).is.equalTo(__dirname);
                    done();
                });
            });
            it('should add dot files to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains([
                        '.bowerrc',
                        '.csslintrc',
                        '.editorconfig',
                        '.gitignore',
                        '.jshintrc'
                    ]);
                    done();
                });
            });
            it('should add bower.json and package.json to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains([
                        'package.json',
                        'bower.json'
                    ]);
                    done();
                });
            });
            it('should add a gulpfile to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('gulpfile.js');
                    done();
                });
            });
            it('should add a karma config file to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('karma.conf.js');
                    done();
                });
            });
            it('should add a readme file to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('README.md');
                    done();
                });
            });
            it('should add an index.html to the app folder', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/index.html');
                    done();
                });
            });
            it('should add a JavaScript app module definition file by default', function(done) {
                testingUtil.mockPrompt({
                    name: 'module'
                });
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/app.js');
                    done();
                });
            });
            it('should create a gitkeep file in the app assets dir', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/assets/.gitkeep');
                    done();
                });
            });
            describe('Todo example', function() {
                it('should not add any todo example files by default', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module'
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestNotContains({
                            'src/app/components/todo': [
                                'todo.js',
                                'todo.html',
                                'todo.css',
                                'todo-route.js',
                                'todo-controller.spec.js',
                                'todo-controller.js'
                            ]
                        });
                        done();
                    });
                });
                describe('When Todo example is included', function() {
                    beforeEach(function() {
                        testingUtil.mockPrompt({
                            name: 'module',
                            example: ['todo']
                        });
                    });
                    it('should add a module specific template', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains('src/app/components/todo/todo.html');
                            done();
                        });
                    });
                    it('should add a module definition file for the Todo module', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains('src/app/components/todo/todo.js');
                            done();
                        });
                    });
                    it('should add a Todo controller with a corresponding test file', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains([
                                'src/app/components/todo/todo-controller.js',
                                'src/app/components/todo/todo-controller.spec.js'
                            ]);
                            done();
                        });
                    });
                });
            });
            describe('CSS files', function() {
                it('should add less stylesheets by default', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.less',
                            'src/app/styles/_base.less',
                            'src/app/components/todo/todo.less'
                        ]);
                        done();
                    });
                });
                it('should add LESS stylesheets when LESS is chosen', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        csstype: 'less',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.less',
                            'src/app/styles/_base.less',
                            'src/app/components/todo/todo.less'
                        ]);
                        done();
                    });
                });
                it('should add Sass stylesheets when Sass is chosen', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        csstype: 'sass',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.scss',
                            'src/app/styles/_base.scss',
                            'src/app/components/todo/todo.scss'
                        ]);
                        done();
                    });
                });
            });
        });
        ///////////// Constants ////////////
        describe('constant generator', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myconstant'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the constant file in the correct directory', function(done) {
                gulp.start('constant').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct constant filename', function(done) {
                gulp.start('constant').once('stop', function() {
                    mockGulpDest.assertDestContains('myconstant-constant.js')
                    done();
                });
            });

        });
        ///////////// Controllers ////////////
        describe('controller generator with test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mycontroller',
                    test : true
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the controller file in the correct directory', function(done) {
                gulp.start('controller').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct controller filename', function(done) {
                gulp.start('controller').once('stop', function() {
                    mockGulpDest.assertDestContains('mycontroller-controller.js');
                    mockGulpDest.assertDestContains('mycontroller-controller.spec.js');
                    done();
                });
            });

        }); // With test controller
        describe('controller generator without test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mycontroller',
                    test : false
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the controller file in the correct directory', function(done) {
                gulp.start('controller').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct controller filename', function(done) {
                gulp.start('controller').once('stop', function() {
                    mockGulpDest.assertDestContains('mycontroller-controller.js');
                    done();
                });
            });

        }); // With out test controller
        describe('decorator generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mydecorator'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the decorator file in the correct directory', function(done) {
                gulp.start('decorator').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct decorator filename', function(done) {
                gulp.start('decorator').once('stop', function() {
                    mockGulpDest.assertDestContains('mydecorator-decorator.js');
                    done();
                });
            });

        }); // decorator test
        describe('directive generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mydirective'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the directive file in the correct directory', function(done) {
                gulp.start('directive').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct directive filename', function(done) {
                gulp.start('directive').once('stop', function() {
                    mockGulpDest.assertDestContains('mydirective-directive.js');
                    done();
                });
            });

        }); // directive test
        describe('factory generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myfactory'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the factory file in the correct directory', function(done) {
                gulp.start('factory').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct factory filename', function(done) {
                gulp.start('factory').once('stop', function() {
                    mockGulpDest.assertDestContains('myfactory-factory.js');
                    done();
                });
            });

        }); // factory test
        describe('filter generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myfilter'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the filter file in the correct directory', function(done) {
                gulp.start('filter').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct filter filename', function(done) {
                gulp.start('filter').once('stop', function() {
                    mockGulpDest.assertDestContains('myfilter-filter.js');
                    done();
                });
            });

        }); // filter test
    });

})();
<commit_msg>Unit Testing for Module added<commit_after>/* jshint node:true */
/**
 * MIT licensed, see LICENSE file
 * Copyright (c) Venkateswara VP <reflexdemon@github>
 */

(function() {
    'use strict';
    var gulp = require('gulp'),
        testingUtil = require('./testing_util'),
        util = require('../util'),
        _ = require('lodash'),
        mockGulpDest = require('mock-gulp-dest')(gulp);

    var assert = require('assertthat');

    require('../slushfile');
    describe('slush-angular-gulp', function() {
        before(function() {
            process.chdir(__dirname);
        });
        describe('default generator', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    name: 'module'
                });
            });
            it('should put all project files in current working directory', function(done) {
                gulp.start('default').once('stop', function() {
                    // mockGulpDest.cwd().should.equal(__dirname);
                    // mockGulpDest.basePath().should.equal(__dirname);

                    assert.that(mockGulpDest.cwd()).is.equalTo(__dirname);
                    assert.that(mockGulpDest.basePath()).is.equalTo(__dirname);
                    done();
                });
            });
            it('should add dot files to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains([
                        '.bowerrc',
                        '.csslintrc',
                        '.editorconfig',
                        '.gitignore',
                        '.jshintrc'
                    ]);
                    done();
                });
            });
            it('should add bower.json and package.json to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains([
                        'package.json',
                        'bower.json'
                    ]);
                    done();
                });
            });
            it('should add a gulpfile to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('gulpfile.js');
                    done();
                });
            });
            it('should add a karma config file to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('karma.conf.js');
                    done();
                });
            });
            it('should add a readme file to project root', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('README.md');
                    done();
                });
            });
            it('should add an index.html to the app folder', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/index.html');
                    done();
                });
            });
            it('should add a JavaScript app module definition file by default', function(done) {
                testingUtil.mockPrompt({
                    name: 'module'
                });
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/app.js');
                    done();
                });
            });
            it('should create a gitkeep file in the app assets dir', function(done) {
                gulp.start('default').once('stop', function() {
                    mockGulpDest.assertDestContains('src/app/assets/.gitkeep');
                    done();
                });
            });
            describe('Todo example', function() {
                it('should not add any todo example files by default', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module'
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestNotContains({
                            'src/app/components/todo': [
                                'todo.js',
                                'todo.html',
                                'todo.css',
                                'todo-route.js',
                                'todo-controller.spec.js',
                                'todo-controller.js'
                            ]
                        });
                        done();
                    });
                });
                describe('When Todo example is included', function() {
                    beforeEach(function() {
                        testingUtil.mockPrompt({
                            name: 'module',
                            example: ['todo']
                        });
                    });
                    it('should add a module specific template', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains('src/app/components/todo/todo.html');
                            done();
                        });
                    });
                    it('should add a module definition file for the Todo module', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains('src/app/components/todo/todo.js');
                            done();
                        });
                    });
                    it('should add a Todo controller with a corresponding test file', function(done) {
                        gulp.start('default').once('stop', function() {
                            mockGulpDest.assertDestContains([
                                'src/app/components/todo/todo-controller.js',
                                'src/app/components/todo/todo-controller.spec.js'
                            ]);
                            done();
                        });
                    });
                });
            });
            describe('CSS files', function() {
                it('should add less stylesheets by default', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.less',
                            'src/app/styles/_base.less',
                            'src/app/components/todo/todo.less'
                        ]);
                        done();
                    });
                });
                it('should add LESS stylesheets when LESS is chosen', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        csstype: 'less',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.less',
                            'src/app/styles/_base.less',
                            'src/app/components/todo/todo.less'
                        ]);
                        done();
                    });
                });
                it('should add Sass stylesheets when Sass is chosen', function(done) {
                    testingUtil.mockPrompt({
                        name: 'module',
                        csstype: 'sass',
                        example: ['todo']
                    });
                    gulp.start('default').once('stop', function() {
                        mockGulpDest.assertDestContains([
                            'src/app/app.scss',
                            'src/app/styles/_base.scss',
                            'src/app/components/todo/todo.scss'
                        ]);
                        done();
                    });
                });
            });
        });
        ///////////// Constants ////////////
        describe('constant generator', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myconstant'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the constant file in the correct directory', function(done) {
                gulp.start('constant').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct constant filename', function(done) {
                gulp.start('constant').once('stop', function() {
                    mockGulpDest.assertDestContains('myconstant-constant.js')
                    done();
                });
            });

        });
        ///////////// Controllers ////////////
        describe('controller generator with test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mycontroller',
                    test : true
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the controller file in the correct directory', function(done) {
                gulp.start('controller').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct controller filename', function(done) {
                gulp.start('controller').once('stop', function() {
                    mockGulpDest.assertDestContains('mycontroller-controller.js');
                    mockGulpDest.assertDestContains('mycontroller-controller.spec.js');
                    done();
                });
            });

        }); // With test controller
        describe('controller generator without test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mycontroller',
                    test : false
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the controller file in the correct directory', function(done) {
                gulp.start('controller').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct controller filename', function(done) {
                gulp.start('controller').once('stop', function() {
                    mockGulpDest.assertDestContains('mycontroller-controller.js');
                    done();
                });
            });

        }); // With out test controller
        describe('decorator generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mydecorator'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the decorator file in the correct directory', function(done) {
                gulp.start('decorator').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct decorator filename', function(done) {
                gulp.start('decorator').once('stop', function() {
                    mockGulpDest.assertDestContains('mydecorator-decorator.js');
                    done();
                });
            });

        }); // decorator test
        describe('directive generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'mydirective'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the directive file in the correct directory', function(done) {
                gulp.start('directive').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct directive filename', function(done) {
                gulp.start('directive').once('stop', function() {
                    mockGulpDest.assertDestContains('mydirective-directive.js');
                    done();
                });
            });

        }); // directive test
        describe('factory generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myfactory'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the factory file in the correct directory', function(done) {
                gulp.start('factory').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct factory filename', function(done) {
                gulp.start('factory').once('stop', function() {
                    mockGulpDest.assertDestContains('myfactory-factory.js');
                    done();
                });
            });

        }); // factory test
        describe('filter generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'module1',
                    fileName: 'myfilter'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the filter file in the correct directory', function(done) {
                gulp.start('filter').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/module1');
                    done();
                });
            });
            it('should put the correct filter filename', function(done) {
                gulp.start('filter').once('stop', function() {
                    mockGulpDest.assertDestContains('myfilter-filter.js');
                    done();
                });
            });

        }); // filter test
        describe('module - config generator test', function() {
            beforeEach(function() {
                testingUtil.mockPrompt({
                    module: 'mymodule',
                    config: 'config'
                });
                util.setRuntimeMode('TEST');
            });
            it('should put the module file in the correct directory', function(done) {
                gulp.start('module').once('stop', function() {
                    assert.that(mockGulpDest.basePath()).is.endingWith('src/app/components/mymodule');
                    done();
                });
            });
            it('should put the correct module filename', function(done) {
                gulp.start('module').once('stop', function() {
                    mockGulpDest.assertDestContains('mymodule-config.js');
                    done();
                });
            });

        }); // module test
    });

})();
<|endoftext|>


<commit_before>/**
 * <TextareaAutosize />
 */

import React from 'react';
import calculateNodeHeight from './calculateNodeHeight';

const emptyFunction = function() {};

export default class TextareaAutosize extends React.Component {

  static propTypes = {
    /**
     * Current textarea value.
     */
    value: React.PropTypes.string,

    /**
     * Callback on value change.
     */
    onChange: React.PropTypes.func,

    /**
     * Callback on height changes.
     */
    onHeightChange: React.PropTypes.func,

    /**
     * Try to cache DOM measurements performed by component so that we don't
     * touch DOM when it's not needed.
     *
     * This optimization doesn't work if we dynamically style <textarea />
     * component.
     */
    useCacheForDOMMeasurements: React.PropTypes.bool,

    /**
     * Minimal numbder of rows to show.
     */
    rows: React.PropTypes.number,

    /**
     * Alias for `rows`.
     */
    minRows: React.PropTypes.number,

    /**
     * Maximum number of rows to show.
     */
    maxRows: React.PropTypes.number
  }

  static defaultProps = {
    onChange: emptyFunction,
    onHeightChange: emptyFunction,
    useCacheForDOMMeasurements: false
  }

  constructor(props) {
    super(props);
    this.state = {
      height: null,
      minHeight: -Infinity,
      maxHeight: Infinity
    };
    this._onNextFrameActionId = null;
    this._rootDOMNode = null;
    this._onChange = this._onChange.bind(this);
    this._resizeComponent = this._resizeComponent.bind(this);
    this._onRootDOMNode = this._onRootDOMNode.bind(this);
  }

  render() {
    let {valueLink, ...props} = this.props;
    props = {...props};
    if (typeof valueLink === 'object') {
      props.value = this.props.valueLink.value;
    }
    props.style = {
      ...props.style,
      height: this.state.height
    };
    let maxHeight = Math.max(
      props.style.maxHeight ? props.style.maxHeight : Infinity,
      this.state.maxHeight);
    if (maxHeight < this.state.height) {
      props.style.overflow = 'hidden';
    }
    return (
      <textarea
        {...props}
        onChange={this._onChange}
        ref={this._onRootDOMNode}
        />
    );
  }

  componentDidMount() {
    this._resizeComponent();
    window.addEventListener('resize', this._resizeComponent);
  }

  componentWillReceiveProps() {
    // Re-render with the new content then recalculate the height as required.
    this._clearNextFrame();
    this._onNextFrameActionId = onNextFrame(this._resizeComponent);
  }

  componentDidUpdate(prevProps, prevState) {
    // Invoke callback when old height does not equal to new one.
    if (this.state.height !== prevState.height) {
      this.props.onHeightChange(this.state.height);
    }
  }

  componentWillUnmount() {
    // Remove any scheduled events to prevent manipulating the node after it's
    // been unmounted.
    this._clearNextFrame();
    window.removeEventListener('resize', this._resizeComponent);
  }

  _clearNextFrame() {
    if (this._onNextFrameActionId) {
      clearNextFrameAction(this._onNextFrameActionId);
    }
  }

  _onRootDOMNode(node) {
    this._rootDOMNode = node;
  }

  _onChange(e) {
    this._resizeComponent();
    let {valueLink, onChange} = this.props;
    if (valueLink) {
      valueLink.requestChange(e.target.value);
    } else {
      onChange(e);
    }
  }

  _resizeComponent() {
    let {useCacheForDOMMeasurements} = this.props;
    this.setState(calculateNodeHeight(
      this._rootDOMNode,
      useCacheForDOMMeasurements,
      this.props.rows || this.props.minRows,
      this.props.maxRows));
  }

  /**
   * Read the current value of <textarea /> from DOM.
   */
  get value(): string {
    return this._rootDOMNode.value;
  }

  /**
   * Set the current value of <textarea /> DOM node.
   */
  set value(val) {
    this._rootDOMNode.value = val;
  }

  /**
   * Read the current selectionStart of <textarea /> from DOM.
   */
  get selectionStart(): number {
    return this._rootDOMNode.selectionStart;
  }

  /**
   * Set the current selectionStart of <textarea /> DOM node.
   */
  set selectionStart(selectionStart: number) {
    this._rootDOMNode.selectionStart = selectionStart;
  }

  /**
   * Read the current selectionEnd of <textarea /> from DOM.
   */
  get selectionEnd(): number {
    return this._rootDOMNode.selectionEnd;
  }

  /**
   * Set the current selectionEnd of <textarea /> DOM node.
   */
  set selectionEnd(selectionEnd: number) {
    this._rootDOMNode.selectionEnd = selectionEnd;
  }

  /**
   * Put focus on a <textarea /> DOM element.
   */
  focus() {
    this._rootDOMNode.focus();
  }

  /**
   * Shifts focus away from a <textarea /> DOM element.
   */
  blur() {
    this._rootDOMNode.blur();
  }

}

function onNextFrame(cb) {
  if (window.requestAnimationFrame) {
    return window.requestAnimationFrame(cb);
  }
  return window.setTimeout(cb, 1);
}

function clearNextFrameAction(nextFrameId) {
  if (window.cancelAnimationFrame) {
    window.cancelAnimationFrame(nextFrameId);
  } else {
    window.clearTimeout(nextFrameId);
  }
}
<commit_msg>fix: fixes #70<commit_after>/**
 * <TextareaAutosize />
 */

import React from 'react';
import calculateNodeHeight from './calculateNodeHeight';

const emptyFunction = function() {};

export default class TextareaAutosize extends React.Component {

  static propTypes = {
    /**
     * Current textarea value.
     */
    value: React.PropTypes.string,

    /**
     * Callback on value change.
     */
    onChange: React.PropTypes.func,

    /**
     * Callback on height changes.
     */
    onHeightChange: React.PropTypes.func,

    /**
     * Try to cache DOM measurements performed by component so that we don't
     * touch DOM when it's not needed.
     *
     * This optimization doesn't work if we dynamically style <textarea />
     * component.
     */
    useCacheForDOMMeasurements: React.PropTypes.bool,

    /**
     * Minimal numbder of rows to show.
     */
    rows: React.PropTypes.number,

    /**
     * Alias for `rows`.
     */
    minRows: React.PropTypes.number,

    /**
     * Maximum number of rows to show.
     */
    maxRows: React.PropTypes.number
  }

  static defaultProps = {
    onChange: emptyFunction,
    onHeightChange: emptyFunction,
    useCacheForDOMMeasurements: false
  }

  constructor(props) {
    super(props);
    this.state = {
      height: null,
      minHeight: -Infinity,
      maxHeight: Infinity
    };
    this._onNextFrameActionId = null;
    this._rootDOMNode = null;
    this._onChange = this._onChange.bind(this);
    this._resizeComponent = this._resizeComponent.bind(this);
    this._onRootDOMNode = this._onRootDOMNode.bind(this);
  }

  render() {
    let {valueLink, ...props} = this.props;
    props = {...props};
    if (typeof valueLink === 'object') {
      props.value = this.props.valueLink.value;
    }
    props.style = {
      ...props.style,
      height: this.state.height || 0,
    };
    let maxHeight = Math.max(
      props.style.maxHeight ? props.style.maxHeight : Infinity,
      this.state.maxHeight);
    if (maxHeight < this.state.height) {
      props.style.overflow = 'hidden';
    }
    return (
      <textarea
        {...props}
        onChange={this._onChange}
        ref={this._onRootDOMNode}
        />
    );
  }

  componentDidMount() {
    this._resizeComponent();
    window.addEventListener('resize', this._resizeComponent);
  }

  componentWillReceiveProps() {
    // Re-render with the new content then recalculate the height as required.
    this._clearNextFrame();
    this._onNextFrameActionId = onNextFrame(this._resizeComponent);
  }

  componentDidUpdate(prevProps, prevState) {
    // Invoke callback when old height does not equal to new one.
    if (this.state.height !== prevState.height) {
      this.props.onHeightChange(this.state.height);
    }
  }

  componentWillUnmount() {
    // Remove any scheduled events to prevent manipulating the node after it's
    // been unmounted.
    this._clearNextFrame();
    window.removeEventListener('resize', this._resizeComponent);
  }

  _clearNextFrame() {
    if (this._onNextFrameActionId) {
      clearNextFrameAction(this._onNextFrameActionId);
    }
  }

  _onRootDOMNode(node) {
    this._rootDOMNode = node;
  }

  _onChange(e) {
    this._resizeComponent();
    let {valueLink, onChange} = this.props;
    if (valueLink) {
      valueLink.requestChange(e.target.value);
    } else {
      onChange(e);
    }
  }

  _resizeComponent() {
    let {useCacheForDOMMeasurements} = this.props;
    this.setState(calculateNodeHeight(
      this._rootDOMNode,
      useCacheForDOMMeasurements,
      this.props.rows || this.props.minRows,
      this.props.maxRows));
  }

  /**
   * Read the current value of <textarea /> from DOM.
   */
  get value(): string {
    return this._rootDOMNode.value;
  }

  /**
   * Set the current value of <textarea /> DOM node.
   */
  set value(val) {
    this._rootDOMNode.value = val;
  }

  /**
   * Read the current selectionStart of <textarea /> from DOM.
   */
  get selectionStart(): number {
    return this._rootDOMNode.selectionStart;
  }

  /**
   * Set the current selectionStart of <textarea /> DOM node.
   */
  set selectionStart(selectionStart: number) {
    this._rootDOMNode.selectionStart = selectionStart;
  }

  /**
   * Read the current selectionEnd of <textarea /> from DOM.
   */
  get selectionEnd(): number {
    return this._rootDOMNode.selectionEnd;
  }

  /**
   * Set the current selectionEnd of <textarea /> DOM node.
   */
  set selectionEnd(selectionEnd: number) {
    this._rootDOMNode.selectionEnd = selectionEnd;
  }

  /**
   * Put focus on a <textarea /> DOM element.
   */
  focus() {
    this._rootDOMNode.focus();
  }

  /**
   * Shifts focus away from a <textarea /> DOM element.
   */
  blur() {
    this._rootDOMNode.blur();
  }

}

function onNextFrame(cb) {
  if (window.requestAnimationFrame) {
    return window.requestAnimationFrame(cb);
  }
  return window.setTimeout(cb, 1);
}

function clearNextFrameAction(nextFrameId) {
  if (window.cancelAnimationFrame) {
    window.cancelAnimationFrame(nextFrameId);
  } else {
    window.clearTimeout(nextFrameId);
  }
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var jade = require('jade'),
    render = jade.render,
    nodes = jade.nodes;

jade.filters.conditionals = function(block, compiler){
    block.nodes.forEach(function(node, i){
        switch (node.name) {
            case 'if':
                block.nodes[i] = new nodes.Code('if (' + node.block.nodes[0].lines[0] + ')');
                block.nodes[i].block = node.block;
                break;
            case 'else':
                block.nodes[i] = new nodes.Code('else');
                block.nodes[i].block = node.block;
                break;
        }
    });
    compiler.visit(block);
    return '';
};

module.exports = {
    'test filter interpolation': function(assert){
        assert.equal(
            '',
            render(':javascript\n  | var name = "#{userName}";', { locals: { userName: 'tj' }}));
        assert.equal(
            '',
            render(':javascript\n  | var name = #{userName};', { locals: { userName: "'tj'" }}));
        assert.equal(
            '',
            render(':javascript\n  | var name = "\\#{userName}";', { locals: { userName: 'tj' }}));
    },

    'test :cdata filter': function(assert){
        assert.equal('<![CDATA[\nfoo\n]]>', render(':cdata\n  | foo'));
        assert.equal('<![CDATA[\nfoo\nbar\n]]>', render(':cdata\n  | foo\n  | bar'));
        assert.equal('<![CDATA[\nfoo\nbar\n]]>
something else
', render(':cdata\n  | foo\n  | bar\np something else'));
    },

    'test :javascript filter': function(assert){
        assert.equal(
            '',
            render(':javascript\n  | alert(\'foo\')'));
    },

    'test :markdown filter': function(assert){
        assert.equal(
            '
foo
\n\n

bar

baz

',
            render(':markdown\n  | #foo\n  | - bar\n  | - baz'))
    },

    'test :sass filter': function(assert){
        assert.equal(
            '',
            render(':sass\n  | body\n  |   :color #cc0000'));
        assert.equal(
            '',
            render(':sass\n  | body\n  |   :font-family \'Lucida Grande\''));
    },

    'test :less filter': function(assert){
        assert.equal(
            '',
            render(':less\n  | .class { width: 10px * 2 }'));
    },

    'test parse tree': function(assert){
        var str = [
            ':conditionals',
            '  if false',
            '    | oh noes',
            '  else',
            '    p amazing!'
        ].join('\n');

        var html = [
            '
amazing!
'
        ].join('');

        assert.equal(html, render(str));
    }
};<commit_msg>Better filter parse tree test<commit_after>
/**
 * Module dependencies.
 */

var jade = require('jade'),
    Compiler = jade.Compiler,
    render = jade.render,
    nodes = jade.nodes;

jade.filters.conditionals = function(block, compiler){
    return new Visitor(block).compile();
};

function Visitor(node) {
    this.node = node;
}

Visitor.prototype.__proto__ = Compiler.prototype;

Visitor.prototype.visit = function(node){
    if (node.name != 'else') this.line(node);
    this.visitNode(node);
};

Visitor.prototype.visitTag = function(node){
    switch (node.name) {
        case 'if':
            var condition = node.block.nodes[0].lines[0],
                block = node.block;
            block.nodes.shift();
            node = new nodes.Code('if (' + condition + ')', false);
            node.block = block;
            this.visit(node);
            break;
        case 'else':
            var block = node.block;
            node = new nodes.Code('else', false);
            node.block = block;
            node.instrumentLineNumber = false;
            this.visit(node);
            break;
        default:
            Compiler.prototype.visitTag.call(this, node);
    }
};

module.exports = {
    'test filter interpolation': function(assert){
        assert.equal(
            '',
            render(':javascript\n  | var name = "#{userName}";', { locals: { userName: 'tj' }}));
        assert.equal(
            '',
            render(':javascript\n  | var name = #{userName};', { locals: { userName: "'tj'" }}));
        assert.equal(
            '',
            render(':javascript\n  | var name = "\\#{userName}";', { locals: { userName: 'tj' }}));
    },

    'test :cdata filter': function(assert){
        assert.equal('<![CDATA[\nfoo\n]]>', render(':cdata\n  | foo'));
        assert.equal('<![CDATA[\nfoo\nbar\n]]>', render(':cdata\n  | foo\n  | bar'));
        assert.equal('<![CDATA[\nfoo\nbar\n]]>
something else
', render(':cdata\n  | foo\n  | bar\np something else'));
    },

    'test :javascript filter': function(assert){
        assert.equal(
            '',
            render(':javascript\n  | alert(\'foo\')'));
    },

    'test :markdown filter': function(assert){
        assert.equal(
            '
foo
\n\n

bar

baz

',
            render(':markdown\n  | #foo\n  | - bar\n  | - baz'))
    },

    'test :sass filter': function(assert){
        assert.equal(
            '',
            render(':sass\n  | body\n  |   :color #cc0000'));
        assert.equal(
            '',
            render(':sass\n  | body\n  |   :font-family \'Lucida Grande\''));
    },

    'test :less filter': function(assert){
        assert.equal(
            '',
            render(':less\n  | .class { width: 10px * 2 }'));
    },

    'test parse tree': function(assert){
        var str = [
            ':conditionals',
            '  if false',
            '    | oh noes',
            '  else',
            '    if null == false',
            '      p doh',
            '    else',
            '      p amazing!'
        ].join('\n');

        var html = [
            '
amazing!
'
        ].join('');

        assert.equal(html, render(str));
    }
};<|endoftext|>


<commit_before>var test = require('tape')
var hyperlog = require('hyperlog')
var memdb = require('memdb')
var path = require('path')
var fdstore = require('fd-chunk-store')
var osmdb = require('osm-p2p-db')
var http = require('http')
var url = require('url')
var concat = require('concat-stream')
var waterfall = require('run-waterfall')

var through = require('through2')
var Duplex = require('readable-stream/duplex')
var tmpdir = require('os').tmpdir()
var createGetMap = require('../api/get_map')
var createServer = require('./lib/test_server.js')

function getMap (osm, bbox, done) {
  var getMap = createGetMap(osm)
  getMap(bbox, {order: 'type'}, done)
}

function createOsm () {
  var storefile = path.join(tmpdir, 'osm-store-' + Math.random())
  return osmdb({
    log: hyperlog(memdb(), { valueEncoding: 'json' }),
    db: memdb(),
    store: fdstore(4096, storefile)
  })
}

test('do not include points from an excluded way fork', function (t) {
  t.plan(4)

  // Has the base way
  var osmBase = createOsm()

  // Has a fork of the base way
  var osmForkA = createOsm()

  // Has a different fork of the base way
  var osmForkB = createOsm()

  var nodes = [
    {
      type: 'node',
      lon: 0,
      lat: -1
    },
    {
      type: 'node',
      lon: 0,
      lat: 0
    },
    {
      type: 'node',
      lon: 0,
      lat: 1
    },
  ]

  var wayId
  var wayVersionId
  var changesetId
  var keyIds
  var forkARefs
  var forkAWayVersionId
  var forkBRefs
  var forkBWayVersionId
  var osmServer

  // Run the test steps
  waterfall([
    step1,
    step2,
    step3,
    step4,
    step5,
    step6,
    step7,
    step8,
    step9
  ], function (err) {
    t.error(err)
  })

  // 1. Create base way
  function step1 (done) {
    createChangeset(osmBase, function (cs) {
      changesetId = cs
      createNodes(osmBase, nodes, cs, function (keys) {
        keyIds = keys
        createWay(osmBase, keys, cs, function (way, wayVersion) {
          wayId = way
          wayVersionId = wayVersion
          done()
        })
      })
    })
  }

  // 2. Replicate base osm to fork A osm
  function step2 (done) {
    sync(osmBase.log, osmForkA.log, done)
  }

  // 3. Write modifications to fork A
  function step3 (done) {
    var node = {
      type: 'node',
      lon: 10,
      lat: 10
    }
    createChangeset(osmForkA, function (cs) {
      createNodes(osmForkA, [node], cs, function (keys) {
        var refs = keyIds.concat(keys)
        forkARefs = refs
        updateWay(osmForkA, wayId, wayVersionId, refs, cs, function (way) {
          forkAWayVersionId = way.key
          done()
        })
      })
    })
  }

  // 4. Replicate base osm to fork B osm
  function step4 (done) {
    sync(osmBase.log, osmForkB.log, done)
  }

  // 5. Write modifications to fork B
  function step5 (done) {
    var node = {
      type: 'node',
      lon: -10,
      lat: -10
    }
    createChangeset(osmForkB, function (cs) {
      createNodes(osmForkB, [node], cs, function (keys) {
        var refs = keyIds.concat(keys)
        forkBRefs = refs
        updateWay(osmForkB, wayId, wayVersionId, refs, cs, function (way) {
          forkBWayVersionId = way.key
          done()
        })
      })
    })
  }

  // 6. Replicate fork A and fork B
  function step6 (done) {
    sync(osmForkA.log, osmForkB.log, done)
  }

  // 7. Create an osm-p2p-server instance from fork A
  function step7 (done) {
    createServer(function (d) {
      osmServer = d
      done()
    })
  }

  // 8. Replicate fork A and the server
  function step8 (done) {
    sync(osmServer.osm.log, osmForkA.log, function (err) {
      osmServer.osm.ready(done)
    })
  }

  // 9. Run an http query on the server to see which way & points are returned
  function step9 (done) {
    var opts = {
      hostname: 'localhost',
      port: url.parse(osmServer.base).port,
      path: '/api/0.6/map?bbox=-90,-90,90,90',
      headers: {
        'Accept': 'application/json'
      }
    }
    http.get(opts, function (res) {
      res.pipe(concat(function (json) {
        var data = JSON.parse(json)
        var nodeIds = data.elements
          .filter(function (elm) { return elm.type === 'node' })
          .map(function (elm) { return elm.id })
        var ways = data.elements.filter(function (elm) { return elm.type === 'way' })

        t.equal(ways.length, 1)

        // Ensure the way present matches one of the two possible forks and its nodes
        if (ways[0].version === forkAWayVersionId) {
          t.equal(ways[0].version, forkAWayVersionId)
          t.deepEqual(nodeIds.sort(), forkARefs.sort())
        } else if (ways[0].version == forkBWayVersionId) {
          t.equal(ways[0].version, forkBWayVersionId)
          t.deepEqual(nodeIds.sort(), forkBRefs.sort())
        } else {
          t.error('unexpected way version id')
        }

        osmServer.server.cleanup(done)
      }))
    })
  }
})

function eqtype (t) {
  return function (node) { return node.type === t }
}

// creates a list of nodes
function createNodes (osm, nodes, changesetId, done) {
  var keys = []
  ;(function next () {
    var node = nodes.shift()
    if (!node) return done(keys)
    node.changeset = changesetId
    osm.create(node, function (err, key) {
      keys.push(key)
      next()
    })
  })()
}

// creates a changeset with a way and nodes
function createWay (osm, nodeIds, changesetId, done) {
  osm.create({
    type: 'way',
    refs: nodeIds,
    changeset: changesetId
  }, function (err, key, node) {
    done(key, node.key)
  })
}

// updates a changeset with a way and nodes
function updateWay (osm, way, parentId, refs, changesetId, done) {
  osm.put(way, {
    type: 'way',
    refs: refs,
    changeset: changesetId
  },
  { links: [parentId] },
  function (err, way) {
    done(way)
  })
}

// create a new changeset
function createChangeset (osm, done) {
  osm.create({
    type: 'changeset'
  }, function (err, key, node) {
    done(key, node.key)
  })
}

function sync (log1, log2, done) {
  var r1 = log1.replicate()
  r1.on('end', onEnd)
  r1.on('error', onEnd)

  var r2 = log2.replicate()
  r2.on('end', onEnd)
  r2.on('error', onEnd)

  r1.pipe(r2).pipe(r1)

  var pending = 2
  function onEnd (err) {
    if (err) {
      return done(err)
    }
    if (--pending === 0) {
      return done()
    }
  }
}
<commit_msg>Clean up and error handling.<commit_after>var test = require('tape')
var hyperlog = require('hyperlog')
var memdb = require('memdb')
var path = require('path')
var fdstore = require('fd-chunk-store')
var osmdb = require('osm-p2p-db')
var http = require('http')
var url = require('url')
var concat = require('concat-stream')
var waterfall = require('run-waterfall')

var tmpdir = require('os').tmpdir()
var createServer = require('./lib/test_server.js')

function createOsm () {
  var storefile = path.join(tmpdir, 'osm-store-' + Math.random())
  return osmdb({
    log: hyperlog(memdb(), { valueEncoding: 'json' }),
    db: memdb(),
    store: fdstore(4096, storefile)
  })
}

test('do not include points from an excluded way fork', function (t) {
  t.plan(10)

  // Has the base way
  var osmBase = createOsm()

  // Has a fork of the base way
  var osmForkA = createOsm()

  // Has a different fork of the base way
  var osmForkB = createOsm()

  var nodes = [
    {
      type: 'node',
      lon: 0,
      lat: -1
    },
    {
      type: 'node',
      lon: 0,
      lat: 0
    },
    {
      type: 'node',
      lon: 0,
      lat: 1
    }
  ]

  var wayId
  var wayVersionId
  var keyIds
  var forkARefs
  var forkAWayVersionId
  var forkBRefs
  var forkBWayVersionId
  var osmServer

  // Run the test steps
  waterfall([
    step1,
    step2,
    step3,
    step4,
    step5,
    step6,
    step7,
    step8,
    step9
  ], function (err) {
    t.error(err)
  })

  // 1. Create base way
  function step1 (done) {
    createChangeset(osmBase, function (err, cs) {
      t.error(err)
      createNodes(osmBase, nodes, cs, function (keys) {
        keyIds = keys
        createWay(osmBase, keys, cs, function (err, way, wayVersion) {
          t.error(err)
          wayId = way
          wayVersionId = wayVersion
          done()
        })
      })
    })
  }

  // 2. Replicate base osm to fork A osm
  function step2 (done) {
    sync(osmBase.log, osmForkA.log, done)
  }

  // 3. Write modifications to fork A
  function step3 (done) {
    var node = {
      type: 'node',
      lon: 10,
      lat: 10
    }
    createChangeset(osmForkA, function (err, cs) {
      t.error(err)
      createNodes(osmForkA, [node], cs, function (keys) {
        var refs = keyIds.concat(keys)
        forkARefs = refs
        updateWay(osmForkA, wayId, wayVersionId, refs, cs, function (err, way) {
          t.error(err)
          forkAWayVersionId = way.key
          done()
        })
      })
    })
  }

  // 4. Replicate base osm to fork B osm
  function step4 (done) {
    sync(osmBase.log, osmForkB.log, done)
  }

  // 5. Write modifications to fork B
  function step5 (done) {
    var node = {
      type: 'node',
      lon: -10,
      lat: -10
    }
    createChangeset(osmForkB, function (err, cs) {
      t.error(err)
      createNodes(osmForkB, [node], cs, function (keys) {
        var refs = keyIds.concat(keys)
        forkBRefs = refs
        updateWay(osmForkB, wayId, wayVersionId, refs, cs, function (err, way) {
          forkBWayVersionId = way.key
          done(err)
        })
      })
    })
  }

  // 6. Replicate fork A and fork B
  function step6 (done) {
    sync(osmForkA.log, osmForkB.log, done)
  }

  // 7. Create an osm-p2p-server instance from fork A
  function step7 (done) {
    createServer(function (d) {
      osmServer = d
      done()
    })
  }

  // 8. Replicate fork A and the server
  function step8 (done) {
    sync(osmServer.osm.log, osmForkA.log, function (err) {
      t.error(err)
      osmServer.osm.ready(done)
    })
  }

  // 9. Run an http query on the server to see which way & points are returned
  function step9 (done) {
    var opts = {
      hostname: 'localhost',
      port: url.parse(osmServer.base).port,
      path: '/api/0.6/map?bbox=-90,-90,90,90',
      headers: {
        'Accept': 'application/json'
      }
    }
    http.get(opts, function (res) {
      res.pipe(concat(function (json) {
        var data = JSON.parse(json)
        var nodeIds = data.elements
          .filter(function (elm) { return elm.type === 'node' })
          .map(function (elm) { return elm.id })
        var ways = data.elements.filter(function (elm) { return elm.type === 'way' })

        t.equal(ways.length, 1)

        // Ensure the way present matches one of the two possible forks and its nodes
        if (ways[0].version === forkAWayVersionId) {
          t.equal(ways[0].version, forkAWayVersionId)
          t.deepEqual(nodeIds.sort(), forkARefs.sort())
        } else if (ways[0].version === forkBWayVersionId) {
          t.equal(ways[0].version, forkBWayVersionId)
          t.deepEqual(nodeIds.sort(), forkBRefs.sort())
        } else {
          t.error('unexpected way version id')
        }

        osmServer.server.cleanup(done)
      }))
    })
  }
})

// creates a list of nodes
function createNodes (osm, nodes, changesetId, done) {
  var keys = []
  ;(function next () {
    var node = nodes.shift()
    if (!node) return done(keys)
    node.changeset = changesetId
    osm.create(node, function (err, key) {
      if (err) return done(err)
      keys.push(key)
      next()
    })
  })()
}

// creates a changeset with a way and nodes
function createWay (osm, nodeIds, changesetId, done) {
  osm.create({
    type: 'way',
    refs: nodeIds,
    changeset: changesetId
  }, function (err, key, node) {
    done(err, key, node.key)
  })
}

// updates a changeset with a way and nodes
function updateWay (osm, way, parentId, refs, changesetId, done) {
  osm.put(way, {
    type: 'way',
    refs: refs,
    changeset: changesetId
  },
  { links: [parentId] },
  function (err, way) {
    done(err, way)
  })
}

// create a new changeset
function createChangeset (osm, done) {
  osm.create({
    type: 'changeset'
  }, function (err, key, node) {
    done(err, key, node.key)
  })
}

function sync (log1, log2, done) {
  var r1 = log1.replicate()
  r1.on('end', onEnd)
  r1.on('error', onEnd)

  var r2 = log2.replicate()
  r2.on('end', onEnd)
  r2.on('error', onEnd)

  r1.pipe(r2).pipe(r1)

  var pending = 2
  function onEnd (err) {
    if (err) {
      return done(err)
    }
    if (--pending === 0) {
      return done()
    }
  }
}
<|endoftext|>


<commit_before>// POST /db/{db}/groups
// Groups / Create a group
//
// Alpha @ 0.1.37
//
// `202 Accepted`,
// [Delayed](/docs/#/concept/delayed.md).
// sometimes [Idempotent](/docs/#/concept/idempotent.md).
//
// Creates a new group. Initially empty.
//
// ### Request format
//     { "id" : <customid> | null,
//       "label" : <label> | null }
//  - `id` is an optional [custom identifier](/docs/#/types/custom-id.js).
//  - `label` is an optional [human-readable name](/docs/#/types/label.js).
//
// ### Response format
//     { "id" : <id>,
//       "at" : <clock> }

TODO("The response has valid return code and content type.", function(next) {

    var example = { "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);
    var response = Test.query("POST",["db/",db,"/groups"],example,auth).response();

    [
	Assert.areEqual(202, response.map('status')),
	Assert.isTrue(response.map('responseJSON'), "Response type is JSON")
    ].then(next);

});

//
// The behaviour of the request depends on whether an identifier was provided:
// **force-id** mode or **generate-id** mode.
//
// # Force-id mode
//
// RunOrg will attempt to create a group with that identifier, and do nothing if
// the group already exists ([idempotent](/docs/#/concept/idempotent.md)
// request).
//
// ### Example request
//     POST /db/0SNQc00211H/groups
//     Content-Type: application/json
//
//     { "id": "board",
//       "label": "Board members" }
//
// ### Example request
//     202 Accepted
//     Content-Type: application/json
//
//     { "id" : "board",
//       "at" : [[2,218]] }

TODO("Group with forced id appears.", function(next) {

    var id = "board";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    Test.query("POST",["db/",db,"/groups"],example,auth).response().then(function(){

	var get = Test.query("GET",["db/",db,"/groups/",id,"/info"],auth).result();

	[
	    Assert.areEqual({"id":id,"label":"Board members",count:0}, get)
	].then(next);

    });

});

TODO("New group with forced id created after deletion.", function(next) {

    var id = "board";
    var example = { "id" : id, "label" : "Broad members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    Test.query("POST",["db/",db,"/groups"],example,auth).response().then(function(){

	Test.query("DELETE",["db/",db,"/groups/",id],auth).response().then(function(){

	    example.label = "Board members";

	    Test.query("POST",["db/",db,"/groups"],example,auth).response().then(function(){

		var get = Test.query("GET",["db/",db,"/groups/",id,"/info"],auth).result();

		[
		    Assert.areEqual({"id":id,"label":"Board members",count:0}, get)
		].then(next);
	    });
	});
    });
});

// # Generate-id mode
//
// RunOrg will create brand new group, with a brand new identifier. Running the
// request twice will create two groups.
//
// ### Example request
//     POST /db/0SNQc00211H/groups
//     Content-Type: application/json
//
//     { "label": "Members imported on Nov 1, 2013" }
//
// ### Example request
//     202 Accepted
//     Content-Type: application/json
//
//     { "id" : "0SNQe0032JZ",
//       "at" : [[2,219]] }

TODO("Multiple creations create multiple groups.", function(next) {

    var example = { "label" : "Sample group" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    var id1 = Test.query("POST",["db/",db,"/groups"],example,auth).result("id");
    var id2 = Test.query("POST",["db/",db,"/groups"],example,auth).result("id");

    var get1 = Test.query("GET",["db/",db,"/groups/",id1,"/info"],auth).result();
    var get2 = Test.query("GET",["db/",db,"/groups/",id2,"/info"],auth).result();

    [
	Assert.notEqual(id1, id2),
	Assert.areEqual({"id":id1,"label":"Sample group",count:0}, get1),
	Assert.areEqual({"id":id2,"label":"Sample group",count:0}, get2)
    ].then(next);

});

// # Errors
//
// ## Returns `400 Bad Request`
// - ... if the provided identifier is not a valid [custom
//   identifier](/docs/#/types/custom-id.js)

TODO("Returns 400 when custom id is invalid.", function(next) {

    var ex1 = { "id": "a-b", "label" : "Invalid character" };
    var ex2 = { "id": "0123456789a", "label" : "Too long" };

    var db = Query.mkdb();
    var auth = Query.auth(db);
    var r1 = Test.query("POST",["db/",db,"/groups"],ex1,auth).response();
    var r2 = Test.query("POST",["db/",db,"/groups"],ex2,auth).response();

    [
	Assert.areEqual(400, r1.map('status')),
	Assert.areEqual(400, r2.map('status'))
    ].then(next);

});

// ## Returns `404 Not Found`
// - ... if database `{db}` does not exist

TODO("Returns 404 when database does not exist.", function(next) {
    var response = Test.query("POST",["db/01234567890/groups"],{},"00000000000").response();
    Assert.areEqual(404, response.map('status')).then(next);
});

// ## Returns `400 Conflict`
// - ... if a group already exists with the provided identifier.

TODO("Returns 409 when the group exists.", function(next) {

    var id = "board";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    Test.query("POST",["db/",db,"/groups"],example,auth).response().then(function(){
	var response = Test.query("POST",["db/",db,"/groups"],example,auth).response();
	Assert.areEqual(409, response.map('status')).then(next);
    });
});

TODO("Returns 409 when re-creating the admin group.", function(next) {

    var id = "admin";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    var response = Test.query("POST",["db/",db,"/groups"],example,auth.tok).response();
    Assert.areEqual(409, response.map('status')).then(next);
});

// ## Returns `401 Unauthorized`
// - ... if the provided token does not match the `as` contact.

TODO("Returns 401 when token is not valid.", function(next) {
    var db = Query.mkdb();
    Test.query("POST",["db/",db,"/groups"],{},{tok:"0123456789a",id:"0123456789a"})
	.error(401).then(next);
});

// # Access restrictions
//
// Currently, anyone can create a group with a token for the corresponding database.
// This is subject to change in future versions.
<commit_msg>Update tests for POST /groups<commit_after>// POST /db/{db}/groups
// Groups / Create a group
//
// Alpha @ 0.1.37
//
// `202 Accepted`,
// [Delayed](/docs/#/concept/delayed.md).
// sometimes [Idempotent](/docs/#/concept/idempotent.md).
//
// Creates a new group. Initially empty.
//
// ### Request format
//     { "id" : <customid> | null,
//       "label" : <label> | null }
//  - `id` is an optional [custom identifier](/docs/#/types/custom-id.js).
//  - `label` is an optional [human-readable name](/docs/#/types/label.js).
//
// ### Response format
//     { "id" : <id>,
//       "at" : <clock> }

var example = { "label" : "Board members" };

TEST("The response has valid return code and content type.", function(Query) {

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return Query.post(["db/",db,"/groups"],example,auth)
	.assertStatus(202).assertIsJson();

});

//
// The behaviour of the request depends on whether an identifier was provided:
// **force-id** mode or **generate-id** mode.
//
// # Force-id mode
//
// RunOrg will attempt to create a group with that identifier, and do nothing if
// the group already exists ([idempotent](/docs/#/concept/idempotent.md)
// request).
//
// ### Example request
//     POST /db/0SNQc00211H/groups
//     Content-Type: application/json
//
//     { "id": "board",
//       "label": "Board members" }
//
// ### Example request
//     202 Accepted
//     Content-Type: application/json
//
//     { "id" : "board",
//       "at" : [[2,218]] }

TEST("Group with forced id appears.", function(Query) {

    var id = "board";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return Query.post(["db/",db,"/groups"],example,auth).then(function() {
	var get = Query.get(["db/",db,"/groups/",id,"/info"],auth).then(function(d) { return d; });
	return Assert.areEqual({"id":id,"label":"Board members",count:0}, get);
    });

});

TEST("New group with forced id created after deletion.", function(Query) {

    var id = "board";
    var example = { "id" : id, "label" : "Broad members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return Query.post(["db/",db,"/groups"],example,auth).then(function() {

	return Query.del(["db/",db,"/groups/",id],auth).then(function(){

	    example.label = "Board members";

	    return Query.post(["db/",db,"/groups"],example,auth).then(function(){
		var get = Query.get(["db/",db,"/groups/",id,"/info"],auth).then(function(d) { return d; });
		return Assert.areEqual({"id":id,"label":"Board members",count:0}, get);
	    });
	});
    });
});

// # Generate-id mode
//
// RunOrg will create brand new group, with a brand new identifier. Running the
// request twice will create two groups.
//
// ### Example request
//     POST /db/0SNQc00211H/groups
//     Content-Type: application/json
//
//     { "label": "Members imported on Nov 1, 2013" }
//
// ### Example request
//     202 Accepted
//     Content-Type: application/json
//
//     { "id" : "0SNQe0032JZ",
//       "at" : [[2,219]] }

TEST("Multiple creations create multiple groups.", function(Query) {

    var example = { "label" : "Sample group" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    var id1 = Query.post(["db/",db,"/groups"],example,auth).id();
    var id2 = Query.post(["db/",db,"/groups"],example,auth).id();

    var get1 = Query.get(["db/",db,"/groups/",id1,"/info"],auth).then(function(d) { return d; });
    var get2 = Query.get(["db/",db,"/groups/",id2,"/info"],auth).then(function(d) { return d; });

    return $.when(
	Assert.notEqual(id1, id2),
	Assert.areEqual({"id":id1,"label":"Sample group",count:0}, get1),
	Assert.areEqual({"id":id2,"label":"Sample group",count:0}, get2)
    );

});

// # Errors
//
// ## Returns `400 Bad Request`
// - ... if the provided identifier is not a valid [custom
//   identifier](/docs/#/types/custom-id.js)

TEST("Returns 400 when custom id is invalid.", function(Query) {

    var ex1 = { "id": "a-b", "label" : "Invalid character" };
    var ex2 = { "id": "0123456789a", "label" : "Too long" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return $.when(
	Query.post(["db/",db,"/groups"],ex1,auth).assertStatus(400),
	Query.post(["db/",db,"/groups"],ex2,auth).assertStatus(400)
    );

});

// ## Returns `404 Not Found`
// - ... if database `{db}` does not exist

TEST("Returns 404 when database does not exist.", function(Query) {
    return Query.post(["db/01234567890/groups"],example).assertStatus(404);
});

// ## Returns `400 Conflict`
// - ... if a group already exists with the provided identifier.

TEST("Returns 409 when the group exists.", function(Query) {

    var id = "board";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return Query.post(["db/",db,"/groups"],example,auth).then(function() {
	return Query.post(["db/",db,"/groups"],example,auth).assertStatus(409);
    });
});

TEST("Returns 409 when re-creating the admin group.", function(Query) {

    var id = "admin";
    var example = { "id" : id, "label" : "Board members" };

    var db = Query.mkdb();
    var auth = Query.auth(db);

    return Query.post(["db/",db,"/groups"],example,auth).assertStatus(409);

});

// ## Returns `401 Unauthorized`
// - ... if the provided token does not match the `as` contact.

TEST("Returns 401 when token is not valid.", function(Query) {
    var db = Query.mkdb();
    return Query.post(["db/",db,"/groups"],{},{tok:"0123456789a",id:"0123456789a"})
	.assertStatus(401);
});

// # Access restrictions
//
// Currently, anyone can create a group with a token for the corresponding database.
// This is subject to change in future versions.
<|endoftext|>


<commit_before>import {firstImplementer} from '../lib/helpers';

class A {
  one() { return 'a-one'; }
  two() { return 'a-two'; }
}

class B {
  two() { return 'b-two'; }
  three() { return 'b-three'; }
}

describe('firstImplementer', function() {
  const a = new A();
  const b = new B();

  it('fails horribly', function() {
    assert.isTrue(false, 'NOTICE ME TRAVIS SENPAI');
  });

  it('calls methods from the first target that has the method', function() {
    const target = firstImplementer(a, b);
    assert.equal(target.one, a.one);
    assert.equal(target.two, a.two);
    assert.equal(target.three, b.three);
  });

  it('reports a combined prototype', function() {
    const target = firstImplementer(a, b);
    const proto = Object.getPrototypeOf(target);
    const obj = Object.create(proto);
    assert.equal(obj.one(), 'a-one');
    assert.equal(obj.two(), 'a-two');
    assert.equal(obj.three(), 'b-three');
  });

  it('sets properties that exist on an implementer on that implementer, and ones that do not on the target', function() {
    const target = firstImplementer(a, b);
    target.one = () => 'new-one';
    assert.equal(a.one(), 'new-one');
    target.three = () => 'new-three';
    assert.notOk(a.three);
    assert.equal(b.three(), 'new-three');
    target.four = () => 'four! ah ah ah';
    assert.notOk(a.four);
    assert.notOk(b.four);
    assert.equal(target.four(), 'four! ah ah ah');
  });

  it('correctly reports getOwnPropertyDescriptor', function() {
    const target = firstImplementer(a, b);
    const descOne = Object.getOwnPropertyDescriptor(target, 'one');
    assert.equal(descOne.value, a.one);
    const descThree = Object.getOwnPropertyDescriptor(target, 'three');
    assert.equal(descThree.value, b.three);
    const descTarget = Object.getOwnPropertyDescriptor(target, '__implementations');
    assert.deepEqual(descTarget.value, [a, b]);
  });

  it('provides an accessor for all implementers', function() {
    const target = firstImplementer(a, b);
    assert.deepEqual(target.getImplementers(), [a, b]);
  });
});
<commit_msg>Revert "Deliberately failing test"<commit_after>import {firstImplementer} from '../lib/helpers';

class A {
  one() { return 'a-one'; }
  two() { return 'a-two'; }
}

class B {
  two() { return 'b-two'; }
  three() { return 'b-three'; }
}

describe('firstImplementer', function() {
  const a = new A();
  const b = new B();

  it('calls methods from the first target that has the method', function() {
    const target = firstImplementer(a, b);
    assert.equal(target.one, a.one);
    assert.equal(target.two, a.two);
    assert.equal(target.three, b.three);
  });

  it('reports a combined prototype', function() {
    const target = firstImplementer(a, b);
    const proto = Object.getPrototypeOf(target);
    const obj = Object.create(proto);
    assert.equal(obj.one(), 'a-one');
    assert.equal(obj.two(), 'a-two');
    assert.equal(obj.three(), 'b-three');
  });

  it('sets properties that exist on an implementer on that implementer, and ones that do not on the target', function() {
    const target = firstImplementer(a, b);
    target.one = () => 'new-one';
    assert.equal(a.one(), 'new-one');
    target.three = () => 'new-three';
    assert.notOk(a.three);
    assert.equal(b.three(), 'new-three');
    target.four = () => 'four! ah ah ah';
    assert.notOk(a.four);
    assert.notOk(b.four);
    assert.equal(target.four(), 'four! ah ah ah');
  });

  it('correctly reports getOwnPropertyDescriptor', function() {
    const target = firstImplementer(a, b);
    const descOne = Object.getOwnPropertyDescriptor(target, 'one');
    assert.equal(descOne.value, a.one);
    const descThree = Object.getOwnPropertyDescriptor(target, 'three');
    assert.equal(descThree.value, b.three);
    const descTarget = Object.getOwnPropertyDescriptor(target, '__implementations');
    assert.deepEqual(descTarget.value, [a, b]);
  });

  it('provides an accessor for all implementers', function() {
    const target = firstImplementer(a, b);
    assert.deepEqual(target.getImplementers(), [a, b]);
  });
});
<|endoftext|>


<commit_before>/*eslint strict: [2, "function"]*/ // IIFE form
(function () {
    "use strict";
    /*global console: true*/

    /**
     * Simulate console object to generate exceptions when the output is not expected.
     */

    var memberList = ["log", "warn", "error"],
        consoleMethods = {},
        expected = [];

    /**
     * Generates the log, warn & error methods substituted on console
     *
     * @param {String} name "log", "warn" and "error"
     * @return {Function} Wrapper securing console method
     */
    function genMember (name) {
        function _process (text) {
            var
                expectedName,
                expectedText,
                expectedOutput,
                matchingText;
            if (0 !== expected.length) {
                expectedName = expected.shift();
                expectedText = expected.shift();
                expectedOutput = expected.shift();
            }
            if (expectedText instanceof RegExp) {
                expectedText.lastIndex = 0;
                matchingText = null !== expectedText.exec(text);
            } else {
                matchingText = expectedText === text;
            }
            if (expectedName !== name || !matchingText) {
                var error = new Error("Unexpected use of console." + name);
                error.text = text;
                throw error;
            }
            if (expectedOutput) {
                consoleMethods[name].apply(console, arguments);
            }
        }
        return function (text) {
            if (!text || -1 < text.indexOf("\x1B")) {
                // Escape sequence used, must be a mocha output
                consoleMethods[name].apply(console, arguments);
                return;
            }
            _process.apply(null, arguments);
        };
    }

    if (undefined === consoleMethods.log) {
        memberList.forEach(function (member) {
            consoleMethods[member] = console[member];
            console[member] = genMember(member);
        });
    }

    /**
     * Way to prevent failure of console usage
     *
     * @param {String} method method that will be called (log, warn or error)
     * @param {String} text expected text
     * @param {Boolean} [outputs=false] outputs Outputs the text
     */
    console.expects = function (method, text, outputs) {
        expected.push(method, text, outputs === true);
    };

    /**
     * Restore console methods
     */
    console.restore = function () {
        if (undefined !== consoleMethods.log) {
            memberList.forEach(function (member) {
                console[member] = consoleMethods[member];
            });
            consoleMethods = {};
        }
    };

}());
<commit_msg>!yoda style (#280)<commit_after>/*eslint strict: [2, "function"]*/ // IIFE form
(function () {
    "use strict";
    /*global console: true*/

    /**
     * Simulate console object to generate exceptions when the output is not expected.
     */

    var memberList = ["log", "warn", "error"],
        consoleMethods = {},
        expected = [];

    /**
     * Generates the log, warn & error methods substituted on console
     *
     * @param {String} name "log", "warn" and "error"
     * @return {Function} Wrapper securing console method
     */
    function genMember (name) {
        function _process (text) {
            var
                expectedName,
                expectedText,
                expectedOutput,
                matchingText;
            if (expected.length !== 0) {
                expectedName = expected.shift();
                expectedText = expected.shift();
                expectedOutput = expected.shift();
            }
            if (expectedText instanceof RegExp) {
                expectedText.lastIndex = 0;
                matchingText = expectedText.exec(text) !== null;
            } else {
                matchingText = expectedText === text;
            }
            if (expectedName !== name || !matchingText) {
                var error = new Error("Unexpected use of console." + name);
                error.text = text;
                throw error;
            }
            if (expectedOutput) {
                consoleMethods[name].apply(console, arguments);
            }
        }
        return function (text) {
            if (!text || text.indexOf("\x1B") > -1) {
                // Escape sequence used, must be a mocha output
                consoleMethods[name].apply(console, arguments);
                return;
            }
            _process.apply(null, arguments);
        };
    }

    if (undefined === consoleMethods.log) {
        memberList.forEach(function (member) {
            consoleMethods[member] = console[member];
            console[member] = genMember(member);
        });
    }

    /**
     * Way to prevent failure of console usage
     *
     * @param {String} method method that will be called (log, warn or error)
     * @param {String} text expected text
     * @param {Boolean} [outputs=false] outputs Outputs the text
     */
    console.expects = function (method, text, outputs) {
        expected.push(method, text, outputs === true);
    };

    /**
     * Restore console methods
     */
    console.restore = function () {
        if (undefined !== consoleMethods.log) {
            memberList.forEach(function (member) {
                console[member] = consoleMethods[member];
            });
            consoleMethods = {};
        }
    };

}());
<|endoftext|>


<commit_before>var iUI,iDialog;
var ball = {},arrow = {};
var AnimionTimer = true;
var obstacles = [];
var squares = {};
var scoreBox,score = 0;

//页面初始化
function pageInit(){
	layaInit();
}
pageInit();

//laya场景初始化
function layaInit(){
	Laya.MiniAdpter.init();
	Laya.init(750, 1206,Laya.WebGL);
	Laya.stage.scaleMode = "noborder";
	Laya.stage.alignH = "center";
	Laya.stage.alignV = "center";
	Laya.loader.load("res/atlas/main.atlas",laya.utils.Handler.create(this, loadComplate), null);
}

//资源加载完毕
function loadComplate(){
	UIinit();
	eventInit();
	Laya.stage.addChild(iUI);
	ArrowRotating();
	ballSpeedCount();
}//end func

//事件初始化
function eventInit(){
	iUI.BtnLeft.on("mousedown",this,rotateArrow,["left"]);
	iUI.BtnRight.on("mousedown",this,rotateArrow,["right"]);
	iDialog.againBtn.on("mousedown",this,resetGame);
}

//ui初始化
function UIinit(){
	iUI = new gameUI();
	iDialog = new GameEndUI();
	console.log(iDialog);
	console.log(iUI)
	ball.ui = iUI.ball;
	ball.quality = 10;					//球的质量
	// ball.ui.x = 360;
	ball.Xspeed = 0;					//球水平方向的速度
	ball.Yspeed = 0;					//球垂直方向的速度
	ball.Xforce = 0;					//球水平方向的受力状况
	ball.Yforce = 0;					//球垂直方向的受力状况
	arrow.ui = iUI.arrow;
	arrow.elasticity = 30;				//控制物的弹力系数  建议值 20 - 60  60时无动能损失
	arrow.speed = 0;
	arrow.rotationLimit = 25;
	// arrow.ui.rotation = -30;
	scoreBox = iUI.score;
	initObstacles();
}//end func

//初始化障碍物
function initObstacles(){
	for (var i = 0; i < iUI.Obstacles._childs.length; i++) {
		var item = {};
		item.ui = iUI.Obstacles._childs[i];
		item.elasticity = 40;
		item.score = 30;
		obstacles.push(item);
	}

	addSquares();
}//end func

//加入方块
function addSquares(){
	for (var i = 0; i < iUI.squares._childs.length; i++) {
		var item = {};
		item.ui = iUI.squares._childs[i];
		if(item.ui.name == "red"){
			item.elasticity = 40;
			item.score = 40;
			item.hitTimes = 1;
		}
		else if(item.ui.name == "green"){
			item.elasticity = 45;
			item.score = 50;
			item.hitTimes = 2;
		}
		else if(item.ui.name == "purple"){
			item.elasticity = 50;
			item.score = 60;
			item.hitTimes = 3;
		}
		item.id = "ball"+i;
		item.ui.visible = true;
		squares["ball"+i] = item;
	}
}//end func

//重置游戏
function resetGame(){
	score = 0;
	renderScore();
	ball.ui.x = 210;
	ball.ui.y = 800;
	ball.Xspeed = 0;
	ball.Yspeed = 0;
	AnimionTimer = true;
	ballSpeedCount();
	iDialog.close();
	addSquares();
}//end func

//旋转控制物
function rotateArrow(dir){
	if(arrow.speed == 1 || arrow.speed == -1 || arrow.speed == 0){
		if(dir == "left") arrow.speed = -3;
		else arrow.speed = 3;
	}
}//end func

//控制物的旋转
function ArrowRotating(){
	if(arrow.ui.rotation > arrow.rotationLimit){
		arrow.speed = -1;
	}
	else if(arrow.ui.rotation < -arrow.rotationLimit){
		arrow.speed = 1;
	}

	if(arrow.ui.rotation == 0 && (arrow.speed == 1 || arrow.speed == -1)){
		arrow.speed = 0;
	}
	else{
		arrow.ui.rotation += arrow.speed;
	}
	requestAnimationFrame(function(){
		ArrowRotating();
	});
}//end func

//渲染分数
function renderScore(){
	scoreBox.text = "得分："+score;
	iDialog.FinalScore.text = "得分："+score;
}//end func

//球速度的计算
function ballSpeedCount(){
	HorizontalSpeedBall();
	VerticalSpeedBall();
	ballAllHitTest();
	requestAnimationFrame(function(){
		if(AnimionTimer) ballSpeedCount();
	});
}//end func

//水平速度计算
function HorizontalSpeedBall(){
	var Force = ball.Xforce;
	ball.Xspeed = imath.FloatPointAdd(ball.Xspeed, imath.Acceleration(Force,0.0167));
	ball.ui.x += ball.Xspeed
	ball.Xforce = 0;
}//end func

//垂直速度计算
function VerticalSpeedBall(){
	var Force = imath.FloatPointAdd(ball.Yforce, imath.gravity);
	ball.Yspeed = imath.FloatPointAdd(ball.Yspeed, imath.Acceleration(Force,0.0167));
	ball.ui.y += ball.Yspeed
	ball.Yforce = 0;
}//end func

//球的越界检测
function ballOutTest(){
	var bool = false;
	if(ball.ui.x > 776 || ball.ui.x < -26 || ball.ui.y > 1235 || ball.ui.y < -26) bool = true;
	return bool;
}//end func

//球的全部碰撞检测计算
function ballAllHitTest(){
	var OutTest = ballOutTest();
	if(!OutTest){
		ballThingHitTest(arrow,true);
		for (var i = 0; i < obstacles.length; i++) {
			ballThingHitTest(obstacles[i],false);
		}
		for (var i in squares) {
			if(squares[i] != null) ballThingHitTest(squares[i],false);
		}
	}
	else{
		AnimionTimer = false;
		iDialog.show();
	}
}//end func

//球与物体的碰撞检测
function ballThingHitTest(thing,extForce){
	var res = imath.ballHitTest(thing.ui, ball.ui);
	if(res.hit) {
		AnimionTimer = false;
		CountForce(thing,res,extForce);
		ball.Yspeed = 0;
		ball.Xspeed = 0;
		addScore(thing);
		reduceHitTimes(thing);

		requestAnimationFrame(function(){
			AnimionTimer = true;
			ballSpeedCount();
		});
	}
}//end func

//增加分数
function addScore(thing){
	if(thing.hasOwnProperty("score")){
		score += thing.score;
		renderScore();
	}
}//end func

//减少碰撞次数
function reduceHitTimes(thing){
	if(thing.hasOwnProperty("hitTimes")){
		thing.hitTimes--;
		if(thing.hitTimes == 0){
			thing.ui.visible = false;
			squares[thing.id] = null;
		}
	}
}//end func

//计算力
function CountForce(ele,res,ext){
	var counterforce = Counterforce(ele, res);
	var extForce = {x:0,y:0}; //外力

	if(ext) extForce = CounterExtForce(res);
	ball.Xforce = counterforce.Xforce + extForce.x;
	ball.Yforce = counterforce.Yforce + extForce.y;
}//end func

//计算外力
function CounterExtForce(res){
	var force = {
		x:0,
		y:0
	};

	if(arrow.speed > 2 || arrow.speed < -2){
		var deg = imath.convertAngle(arrow.ui.rotation);
		var iforce = arrow.speed * 5000 * (ball.ui.x - arrow.ui.x) / (arrow.ui.width / 2);	//力

		if(res.surface == 0){
			iforce = iforce < 0 ? iforce : 0;
			iforce -= 1500;
			force.x = -iforce * Math.sin(deg);
			force.y = iforce * Math.cos(deg);
		}
		else if(res.surface == 2){
			iforce = -iforce;
			iforce = iforce > 0 ? iforce : 0;
			iforce += 1500;
			force.x = -iforce * Math.sin(deg);
			force.y = iforce * Math.cos(deg);
		}
	}
	// console.log(force)
	return force;
}//end func

//反作用力
function Counterforce(ele, res){
	var force = {
		Xforce:0,
		Yforce:0
	};

	var rotateDir = ele.ui.rotation > 0 ? 1 : -1;								//旋转方向
	var rotation = Math.abs(ele.ui.rotation); 									//不带方向的旋转角度
	var deg = imath.convertAngle(rotation);										//不带方向的旋转弧度
	var sinDeg = Math.sin(deg);													//正弦
	var cosDeg = Math.cos(deg);													//余弦
	var XdirF = ball.Xspeed * ball.quality * ele.elasticity;					//X方向所产生的反作用力
	var YdirF = ball.Yspeed * ball.quality * ele.elasticity - imath.gravity;	//Y方向所产生的反作用力
	var XdpsF = {																//X方向的实际反作用力（坐标系为物体旋转后的坐标系）
		force: 0,																//力
		xdir: 0,																//x方向
		ydir: 0,																//y方向
	};
	var YdpsF = {																//Y方向的实际反作用力（坐标系为物体旋转后的坐标系）
		force: 0,
		xdir: 0,
		ydir: 0
	};

	if(rotateDir == 1 && (res.surface == 0 || res.surface == 2)){
		XdpsF.force = XdirF * sinDeg;
		XdpsF.xdir = -1 * sinDeg;
		XdpsF.ydir = 1 * cosDeg;
		YdpsF.force = YdirF * cosDeg;
		YdpsF.xdir = 1 * sinDeg;
		YdpsF.ydir = -1 * cosDeg;
	}
	else if(rotateDir == 1 && (res.surface == 1 || res.surface == 3)){
		XdpsF.force = XdirF * cosDeg;
		XdpsF.xdir = 1 * cosDeg;
		XdpsF.ydir = 1 * sinDeg;
		YdpsF.force = YdirF * sinDeg;
		YdpsF.xdir = -1 * cosDeg;
		YdpsF.ydir = -1 * sinDeg;
	}
	else if(rotateDir == -1 && (res.surface == 0 || res.surface == 2)){
		XdpsF.force = XdirF * sinDeg;
		XdpsF.xdir = -1 * sinDeg;
		XdpsF.ydir = -1 * cosDeg;
		YdpsF.force = YdirF * cosDeg;
		YdpsF.xdir = -1 * sinDeg;
		YdpsF.ydir = -1 * cosDeg;
	}
	else if(rotateDir == -1 && (res.surface == 1 || res.surface == 3)){
		XdpsF.force = XdirF * cosDeg;
		XdpsF.xdir = -1 * cosDeg;
		XdpsF.ydir = 1 * sinDeg;
		YdpsF.force = YdirF * sinDeg;
		YdpsF.xdir = 1 * cosDeg;
		YdpsF.ydir = -1 * sinDeg;
	}

	force.Xforce = imath.FloatPointAdd(XdpsF.xdir * XdpsF.force, YdpsF.xdir * YdpsF.force);
	force.Yforce = imath.FloatPointAdd(XdpsF.ydir * XdpsF.force,  YdpsF.ydir * YdpsF.force);

	return force;
}//end func
<commit_msg>修改计算方法<commit_after>var iUI,iDialog;
var ball = {},arrow = {};
var AnimionTimer = true;
var obstacles = [];
var squares = {};
var scoreBox,score = 0;

//页面初始化
function pageInit(){
	layaInit();
}
pageInit();

//laya场景初始化
function layaInit(){
	Laya.MiniAdpter.init();
	Laya.init(750, 1206,Laya.WebGL);
	Laya.stage.scaleMode = "noborder";
	Laya.stage.alignH = "center";
	Laya.stage.alignV = "center";
	Laya.loader.load("res/atlas/main.atlas",laya.utils.Handler.create(this, loadComplate), null);
}

//资源加载完毕
function loadComplate(){
	UIinit();
	eventInit();
	Laya.stage.addChild(iUI);
	ArrowRotating();
	ballSpeedCount();
}//end func

//事件初始化
function eventInit(){
	iUI.BtnLeft.on("mousedown",this,rotateArrow,["left"]);
	iUI.BtnRight.on("mousedown",this,rotateArrow,["right"]);
	iDialog.againBtn.on("mousedown",this,resetGame);
}

//ui初始化
function UIinit(){
	iUI = new gameUI();
	iDialog = new GameEndUI();
	console.log(iDialog);
	console.log(iUI)
	ball.ui = iUI.ball;
	ball.quality = 10;					//球的质量
	// ball.ui.x = 360;
	ball.Xspeed = 0;					//球水平方向的速度
	ball.Yspeed = 0;					//球垂直方向的速度
	ball.Xforce = 0;					//球水平方向的受力状况
	ball.Yforce = 0;					//球垂直方向的受力状况
	arrow.ui = iUI.arrow;
	arrow.elasticity = 0.5;				//控制物的弹力系数  建议值 0 - 1  1时无动能损失
	arrow.speed = 0;
	arrow.rotationLimit = 25;
	// arrow.ui.rotation = -30;
	scoreBox = iUI.score;
	initObstacles();
}//end func

//初始化障碍物
function initObstacles(){
	for (var i = 0; i < iUI.Obstacles._childs.length; i++) {
		var item = {};
		item.ui = iUI.Obstacles._childs[i];
		item.elasticity = 0.7;
		item.score = 30;
		obstacles.push(item);
	}

	addSquares();
}//end func

//加入方块
function addSquares(){
	for (var i = 0; i < iUI.squares._childs.length; i++) {
		var item = {};
		item.ui = iUI.squares._childs[i];
		if(item.ui.name == "red"){
			item.elasticity = 0.7;
			item.score = 40;
			item.hitTimes = 1;
		}
		else if(item.ui.name == "green"){
			item.elasticity = 0.8;
			item.score = 50;
			item.hitTimes = 2;
		}
		else if(item.ui.name == "purple"){
			item.elasticity = 0.9;
			item.score = 60;
			item.hitTimes = 3;
		}
		item.id = "ball"+i;
		item.ui.visible = true;
		squares["ball"+i] = item;
	}
}//end func

//重置游戏
function resetGame(){
	score = 0;
	renderScore();
	ball.ui.x = 210;
	ball.ui.y = 800;
	ball.Xspeed = 0;
	ball.Yspeed = 0;
	AnimionTimer = true;
	ballSpeedCount();
	iDialog.close();
	addSquares();
}//end func

//旋转控制物
function rotateArrow(dir){
	if(arrow.speed == 1 || arrow.speed == -1 || arrow.speed == 0){
		if(dir == "left") arrow.speed = -3;
		else arrow.speed = 3;
	}
}//end func

//控制物的旋转
function ArrowRotating(){
	if(arrow.ui.rotation > arrow.rotationLimit){
		arrow.speed = -1;
	}
	else if(arrow.ui.rotation < -arrow.rotationLimit){
		arrow.speed = 1;
	}

	if(arrow.ui.rotation == 0 && (arrow.speed == 1 || arrow.speed == -1)){
		arrow.speed = 0;
	}
	else{
		arrow.ui.rotation += arrow.speed;
	}
	requestAnimationFrame(function(){
		ArrowRotating();
	});
}//end func

//渲染分数
function renderScore(){
	scoreBox.text = "得分："+score;
	iDialog.FinalScore.text = "得分："+score;
}//end func

//球速度的计算
function ballSpeedCount(){
	HorizontalSpeedBall();
	VerticalSpeedBall();
	ballAllHitTest();
	requestAnimationFrame(function(){
		if(AnimionTimer) ballSpeedCount();
	});
}//end func

//水平速度计算
function HorizontalSpeedBall(){
	var Force = ball.Xforce;
	ball.Xspeed = imath.FloatPointAdd(ball.Xspeed, imath.Acceleration(Force,0.0167));
	ball.ui.x += ball.Xspeed
	ball.Xforce = 0;
}//end func

//垂直速度计算
function VerticalSpeedBall(){
	var Force = imath.FloatPointAdd(ball.Yforce, imath.gravity);
	ball.Yspeed = imath.FloatPointAdd(ball.Yspeed, imath.Acceleration(Force,0.0167));
	ball.ui.y += ball.Yspeed
	ball.Yforce = 0;
}//end func

//球的越界检测
function ballOutTest(){
	var bool = false;
	if(ball.ui.x > 776 || ball.ui.x < -26 || ball.ui.y > 1235 || ball.ui.y < -26) bool = true;
	return bool;
}//end func

//球的全部碰撞检测计算
function ballAllHitTest(){
	var OutTest = ballOutTest();
	if(!OutTest){
		ballThingHitTest(arrow,true);
		for (var i = 0; i < obstacles.length; i++) {
			ballThingHitTest(obstacles[i],false);
		}
		for (var i in squares) {
			if(squares[i] != null) ballThingHitTest(squares[i],false);
		}
	}
	else{
		AnimionTimer = false;
		iDialog.show();
	}
}//end func

//球与物体的碰撞检测
function ballThingHitTest(thing,extForce){
	var res = imath.ballHitTest(thing.ui, ball.ui);
	if(res.hit) {
		AnimionTimer = false;
		CountForce(thing,res,extForce);
		ball.Yspeed = 0;
		ball.Xspeed = 0;
		addScore(thing);
		reduceHitTimes(thing);

		requestAnimationFrame(function(){
			AnimionTimer = true;
			ballSpeedCount();
		});
	}
}//end func

//增加分数
function addScore(thing){
	if(thing.hasOwnProperty("score")){
		score += thing.score;
		renderScore();
	}
}//end func

//减少碰撞次数
function reduceHitTimes(thing){
	if(thing.hasOwnProperty("hitTimes")){
		thing.hitTimes--;
		if(thing.hitTimes == 0){
			thing.ui.visible = false;
			squares[thing.id] = null;
		}
	}
}//end func

//计算力
function CountForce(ele,res,ext){
	var counterforce = Counterforce(ele, res);
	var extForce = {x:0,y:0}; //外力

	if(ext) extForce = CounterExtForce(res);
	ball.Xforce = counterforce.Xforce + extForce.x;
	ball.Yforce = counterforce.Yforce + extForce.y;
}//end func

//计算外力
function CounterExtForce(res){
	var force = {
		x:0,
		y:0
	};

	if(arrow.speed > 2 || arrow.speed < -2){
		var deg = imath.convertAngle(arrow.ui.rotation);
		var iforce = arrow.speed * 5000 * (ball.ui.x - arrow.ui.x) / (arrow.ui.width / 2);	//力

		if(res.surface == 0){
			iforce = iforce < 0 ? iforce : 0;
			iforce -= 1500;
			force.x = -iforce * Math.sin(deg);
			force.y = iforce * Math.cos(deg);
		}
		else if(res.surface == 2){
			iforce = -iforce;
			iforce = iforce > 0 ? iforce : 0;
			iforce += 1500;
			force.x = -iforce * Math.sin(deg);
			force.y = iforce * Math.cos(deg);
		}
	}
	// console.log(force)
	return force;
}//end func

//反作用力
function Counterforce(ele, res){
	var force = {
		Xforce:0,
		Yforce:0
	};

	var rotateDir = ele.ui.rotation > 0 ? 1 : -1;											//旋转方向
	var rotation = Math.abs(ele.ui.rotation); 												//不带方向的旋转角度
	var deg = imath.convertAngle(rotation);													//不带方向的旋转弧度
	var sinDeg = Math.sin(deg);																//正弦
	var cosDeg = Math.cos(deg);																//余弦
	var XdirF = ball.Xspeed * ball.quality * ele.elasticity / 0.0167;						//X方向所产生的反作用力
	var YdirF = ball.Yspeed * ball.quality * ele.elasticity / 0.0167 - imath.gravity;		//Y方向所产生的反作用力
	var XdpsF = {																			//X方向的实际反作用力（坐标系为物体旋转后的坐标系）
		force: 0,																			//力
		xdir: 0,																			//x方向
		ydir: 0,																			//y方向
	};
	var YdpsF = {																			//Y方向的实际反作用力（坐标系为物体旋转后的坐标系）
		force: 0,
		xdir: 0,
		ydir: 0
	};

	if(rotateDir == 1 && (res.surface == 0 || res.surface == 2)){
		XdpsF.force = XdirF * sinDeg;
		XdpsF.xdir = -1 * sinDeg;
		XdpsF.ydir = 1 * cosDeg;
		YdpsF.force = YdirF * cosDeg;
		YdpsF.xdir = 1 * sinDeg;
		YdpsF.ydir = -1 * cosDeg;
	}
	else if(rotateDir == 1 && (res.surface == 1 || res.surface == 3)){
		XdpsF.force = XdirF * cosDeg;
		XdpsF.xdir = 1 * cosDeg;
		XdpsF.ydir = 1 * sinDeg;
		YdpsF.force = YdirF * sinDeg;
		YdpsF.xdir = -1 * cosDeg;
		YdpsF.ydir = -1 * sinDeg;
	}
	else if(rotateDir == -1 && (res.surface == 0 || res.surface == 2)){
		XdpsF.force = XdirF * sinDeg;
		XdpsF.xdir = -1 * sinDeg;
		XdpsF.ydir = -1 * cosDeg;
		YdpsF.force = YdirF * cosDeg;
		YdpsF.xdir = -1 * sinDeg;
		YdpsF.ydir = -1 * cosDeg;
	}
	else if(rotateDir == -1 && (res.surface == 1 || res.surface == 3)){
		XdpsF.force = XdirF * cosDeg;
		XdpsF.xdir = -1 * cosDeg;
		XdpsF.ydir = 1 * sinDeg;
		YdpsF.force = YdirF * sinDeg;
		YdpsF.xdir = 1 * cosDeg;
		YdpsF.ydir = -1 * sinDeg;
	}

	force.Xforce = imath.FloatPointAdd(XdpsF.xdir * XdpsF.force, YdpsF.xdir * YdpsF.force);
	force.Yforce = imath.FloatPointAdd(XdpsF.ydir * XdpsF.force,  YdpsF.ydir * YdpsF.force);

	return force;
}//end func
<|endoftext|>