<commit_before>/**
 * @file ScrollTable component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment, createRef} from 'react';
import PropTypes from 'prop-types';

// Components
import BaseTable from '../_BaseTable';
import ScrollableTable from '../_ScrollableTable';
import DynamicRenderTableProvider from '../_DynamicRenderTableProvider';

// Statics
import Theme from '../Theme';
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import {findDOMNode} from 'react-dom';
import classNames from 'classnames';
import Util from '../_vendors/Util';
import ScrollBar from '../_vendors/ScrollBar';

class ScrollTable extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static Fixed = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.headScroller = createRef();
        this.bodyScroller = createRef();
        this.footScroller = createRef();

        this.lastScrollerEl = {};

    }

    componentDidMount() {

        this.updateEl();

        const {onInit} = this.props;
        onInit && onInit();

    }

    componentDidUpdate() {
        this.updateEl();
    }

    updateFragmentEl = fragment => {

        const {onGetScrollerEl} = this.props,
            instance = this?.[`${fragment}Scroller`]?.current,
            el = instance && findDOMNode(instance);

        if (!onGetScrollerEl || !el || this.lastScrollerEl[fragment] == el) {
            return;
        }

        onGetScrollerEl(fragment, el);
        this.lastScrollerEl[fragment] = el;

    };

    updateEl = () => {

        const {isHeadFixed, isFootFixed} = this.props;

        this.updateFragmentEl(TableFragment.BODY);
        isHeadFixed && this.updateFragmentEl(TableFragment.HEAD);
        isFootFixed && this.updateFragmentEl(TableFragment.FOOT);

    };

    hasVerticalScroll = () => {

        const scrollEl = this.lastScrollerEl[TableFragment.BODY];

        if (!scrollEl) {
            return false;
        }

        return scrollEl.scrollHeight > scrollEl.clientHeight;

    };

    handleColumnsSpan = (...restArgs) => {
        const {fixed, onRequestColumnsSpan} = this.props;
        return onRequestColumnsSpan && onRequestColumnsSpan(fixed, ...restArgs);
    };

    render() {

        const {

            horizontalScrollStyle, verticalScrollStyle, fixed, columns, headColumns, bodyColumns,
            isHeadHidden, isFootHidden, isLayoutFixed, isHeadFixed, isFootFixed, data, scroll,
            useDynamicRender, dynamicRenderIndex, scrollHeight, rowHeight, scrollBuffer, defaultColumnWidth,
            onScroll, onWheel, onColumnMeasure,

            // not passing down these props
            onInit, onGetScrollerEl,

            ...restProps

        } = this.props;

        if (!columns && !headColumns && !bodyColumns) {
            return null;
        }

        const hasVerticalScroll = this.hasVerticalScroll(),
            hasHead = !isHeadHidden && isHeadFixed,
            hasFoot = !isFootHidden && isFootFixed,
            scrollableTableStyle = ScrollBar.getHideHorizontalScrollBarStyle();

        return (
            <Fragment>

                {
                    hasHead ?
                        <ScrollableTable ref={this.headScroller}
                                         className="scroll-table-head"
                                         style={scrollableTableStyle}
                                         fragment={TableFragment.HEAD}
                                         scroll={scroll}
                                         useDynamicRender={useDynamicRender}
                                         scrollHeight={scrollHeight}
                                         rowHeight={rowHeight}
                                         scrollBuffer={scrollBuffer}
                                         onScroll={onScroll}>
                            {
                                scrollEl =>
                                    <BaseTable {...restProps}
                                               fixed={fixed}
                                               fragment={TableFragment.HEAD}
                                               columns={columns}
                                               headColumns={headColumns}
                                               bodyColumns={bodyColumns}
                                               isHeadFixed={isHeadFixed}
                                               isFootFixed={isFootFixed}
                                               data={data}
                                               scrollEl={scrollEl}
                                               useDynamicRender={useDynamicRender}
                                               scrollHeight={scrollHeight}
                                               rowHeight={rowHeight}
                                               scrollBuffer={scrollBuffer}
                                               hasVerticalScroll={hasVerticalScroll}
                                               isBodyHidden={true}
                                               isFootHidden={true}
                                               isLayoutFixed={isLayoutFixed}
                                               defaultColumnWidth={defaultColumnWidth}
                                               useColumnsWidth={true}
                                               onRequestColumnsSpan={this.handleColumnsSpan}/>
                            }
                        </ScrollableTable>
                        :
                        null
                }

                <ScrollableTable ref={this.bodyScroller}
                                 className={classNames('scroll-table-body', {
                                     'has-head': hasHead,
                                     'has-foot': hasFoot
                                 })}
                                 style={verticalScrollStyle}
                                 scroll={scroll}
                                 useDynamicRender={useDynamicRender}
                                 scrollHeight={scrollHeight}
                                 rowHeight={rowHeight}
                                 scrollBuffer={scrollBuffer}
                                 onScroll={onScroll}
                                 onWheel={onWheel}>
                    {
                        scrollEl =>
                            <DynamicRenderTableProvider data={data}
                                                        useDynamicRender={useDynamicRender}
                                                        rowHeight={rowHeight}>
                                <BaseTable {...restProps}
                                           style={{
                                               width: horizontalScrollStyle?.width,
                                               minWidth: horizontalScrollStyle?.width ? '100%' : null,
                                               transform: useDynamicRender && dynamicRenderIndex ?
                                                   `translateY(${dynamicRenderIndex.startWithBuffer * rowHeight}px)`
                                                   :
                                                   null
                                           }}
                                           fixed={fixed}
                                           fragment={TableFragment.BODY}
                                           columns={columns}
                                           headColumns={headColumns}
                                           bodyColumns={bodyColumns}
                                           isHeadFixed={isHeadFixed}
                                           isFootFixed={isFootFixed}
                                           isLayoutFixed={isLayoutFixed}
                                           isHeadHidden={isHeadHidden || isHeadFixed}
                                           isFootHidden={isFootHidden || isFootFixed}
                                           data={data}
                                           scrollEl={scrollEl}
                                           useDynamicRender={useDynamicRender}
                                           scrollHeight={scrollHeight}
                                           rowHeight={rowHeight}
                                           scrollBuffer={scrollBuffer}
                                           defaultColumnWidth={defaultColumnWidth}
                                           onRequestColumnsSpan={this.handleColumnsSpan}
                                           onColumnMeasure={onColumnMeasure}/>
                            </DynamicRenderTableProvider>
                    }
                </ScrollableTable>

                {
                    hasFoot ?
                        <ScrollableTable ref={this.footScroller}
                                         className="scroll-table-foot"
                                         style={scrollableTableStyle}
                                         fragment={TableFragment.FOOT}
                                         scroll={scroll}
                                         useDynamicRender={useDynamicRender}
                                         scrollHeight={scrollHeight}
                                         rowHeight={rowHeight}
                                         scrollBuffer={scrollBuffer}
                                         onScroll={onScroll}>
                            {
                                scrollEl =>
                                    <BaseTable {...restProps}
                                               fixed={fixed}
                                               fragment={TableFragment.FOOT}
                                               columns={columns}
                                               headColumns={headColumns}
                                               bodyColumns={bodyColumns}
                                               isHeadFixed={isHeadFixed}
                                               isFootFixed={isFootFixed}
                                               ignoreColumnSpan={true}
                                               data={data}
                                               scrollEl={scrollEl}
                                               useDynamicRender={useDynamicRender}
                                               scrollHeight={scrollHeight}
                                               rowHeight={rowHeight}
                                               scrollBuffer={scrollBuffer}
                                               hasVerticalScroll={hasVerticalScroll}
                                               isHeadHidden={true}
                                               isBodyHidden={true}
                                               isLayoutFixed={isLayoutFixed}
                                               defaultColumnWidth={defaultColumnWidth}
                                               useColumnsWidth={true}
                                               onRequestColumnsSpan={this.handleColumnsSpan}/>
                            }
                        </ScrollableTable>
                        :
                        null
                }

            </Fragment>
        );

    }
}

ScrollTable.propTypes = {

    horizontalScrollStyle: PropTypes.object,
    verticalScrollStyle: PropTypes.object,

    fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

    /**
     * The theme of the table select radio or checkbox.
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.func]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * The title in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headTitle: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * The title in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyTitle: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * The title in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footTitle: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true, this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),

        /**
         * whether the column can be resized
         */
        resizable: PropTypes.bool

    })),
    headColumns: PropTypes.array,
    bodyColumns: PropTypes.array,
    columnKeyField: PropTypes.string,
    columnsWidth: PropTypes.object,
    data: PropTypes.array,
    dynamicRenderData: PropTypes.array,
    value: PropTypes.array,
    idField: PropTypes.string,
    expandRows: PropTypes.array,

    /**
     * scroll
     */
    scroll: PropTypes.shape({
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    }),

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    isClickSorting: PropTypes.bool,

    /**
     * fixed
     */
    isLayoutFixed: PropTypes.bool,
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * has renderer
     */
    hasHeadRenderer: PropTypes.bool,
    hasBodyRenderer: PropTypes.bool,
    hasFootRenderer: PropTypes.bool,

    /**
     * fixed column
     */
    hasFixedLeftColumn: PropTypes.bool,
    hasFixedRightColumn: PropTypes.bool,

    /**
     * Dynamic Render
     */
    useDynamicRender: PropTypes.bool,
    dynamicRenderIndex: PropTypes.object,
    scrollHeight: PropTypes.number,
    rowHeight: PropTypes.number,
    scrollBuffer: PropTypes.number,

    /**
     * column resizable
     */
    defaultColumnWidth: PropTypes.number,
    minColumnWidth: PropTypes.number,
    maxColumnWidth: PropTypes.number,
    resizingColumn: PropTypes.object,

    /**
     * callback
     */
    onInit: PropTypes.func,
    onGetScrollerEl: PropTypes.func,
    onExpandChange: PropTypes.func,
    onScroll: PropTypes.func,
    onWheel: PropTypes.func,
    onSortChange: PropTypes.func,
    onRequestColumnsSpan: PropTypes.func,
    onColumnsWidthChange: PropTypes.func,
    onColumnResizeStart: PropTypes.func,
    onColumnResizeEnd: PropTypes.func,
    onColumnMeasure: PropTypes.func

};

ScrollTable.defaultProps = {

    columnKeyField: 'key',
    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,
    idField: 'id',
    expandRows: [],

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    isClickSorting: true,

    /**
     * fixed
     */
    isLayoutFixed: true,
    isHeadFixed: false,
    isFootFixed: false,

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * has renderer
     */
    hasHeadRenderer: true,
    hasBodyRenderer: true,
    hasFootRenderer: true,

    /**
     * fixed column
     */
    hasFixedLeftColumn: false,
    hasFixedRightColumn: false,

    /**
     * Dynamic Render
     */
    useDynamicRender: false,
    scrollHeight: 500,
    rowHeight: 50,
    scrollBuffer: 8,

    /**
     * column resizable
     */
    defaultColumnWidth: 100,
    minColumnWidth: 64,
    maxColumnWidth: Infinity

};

export default ScrollTable;
<commit_msg>update ScrollTable<commit_after>/**
 * @file ScrollTable component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component, Fragment, createRef} from 'react';
import PropTypes from 'prop-types';

// Components
import BaseTable from '../_BaseTable';
import ScrollableTable from '../_ScrollableTable';
import DynamicRenderTableProvider from '../_DynamicRenderTableProvider';

// Statics
import Theme from '../Theme';
import TableFragment from '../_statics/TableFragment';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import {findDOMNode} from 'react-dom';
import classNames from 'classnames';
import Util from '../_vendors/Util';
import ScrollBar from '../_vendors/ScrollBar';

class ScrollTable extends Component {

    static Fragment = TableFragment;
    static Align = HorizontalAlign;
    static Fixed = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.headScroller = createRef();
        this.bodyScroller = createRef();
        this.footScroller = createRef();

        this.lastScrollerEl = {};

    }

    componentDidMount() {
        this.updateEl();
        this.props.onInit?.();
    }

    componentDidUpdate() {
        this.updateEl();
    }

    updateFragmentEl = fragment => {

        const {onGetScrollerEl} = this.props,
            instance = this?.[`${fragment}Scroller`]?.current,
            el = instance && findDOMNode(instance);

        if (!onGetScrollerEl || !el || this.lastScrollerEl[fragment] == el) {
            return;
        }

        onGetScrollerEl(fragment, el);
        this.lastScrollerEl[fragment] = el;

    };

    updateEl = () => {

        const {isHeadFixed, isFootFixed} = this.props;

        this.updateFragmentEl(TableFragment.BODY);
        isHeadFixed && this.updateFragmentEl(TableFragment.HEAD);
        isFootFixed && this.updateFragmentEl(TableFragment.FOOT);

    };

    hasVerticalScroll = () => {

        const scrollEl = this.lastScrollerEl[TableFragment.BODY];

        if (!scrollEl) {
            return false;
        }

        return scrollEl.scrollHeight > scrollEl.clientHeight;

    };

    handleColumnsSpan = (...restArgs) => {
        const {fixed} = this.props;
        return this.props.onRequestColumnsSpan?.(fixed, ...restArgs);
    };

    render() {

        const {

            horizontalScrollStyle, verticalScrollStyle, fixed, columns, headColumns, bodyColumns,
            isHeadHidden, isFootHidden, isLayoutFixed, isHeadFixed, isFootFixed, data, scroll,
            useDynamicRender, dynamicRenderIndex, scrollHeight, rowHeight, scrollBuffer, defaultColumnWidth,
            onScroll, onWheel, onColumnMeasure,

            // not passing down these props
            onInit, onGetScrollerEl,

            ...restProps

        } = this.props;

        if (!columns && !headColumns && !bodyColumns) {
            return null;
        }

        const hasVerticalScroll = this.hasVerticalScroll(),
            hasHead = !isHeadHidden && isHeadFixed,
            hasFoot = !isFootHidden && isFootFixed,
            scrollableTableStyle = ScrollBar.getHideHorizontalScrollBarStyle();

        return (
            <Fragment>

                {
                    hasHead ?
                        <ScrollableTable ref={this.headScroller}
                                         className="scroll-table-head"
                                         style={scrollableTableStyle}
                                         fragment={TableFragment.HEAD}
                                         scroll={scroll}
                                         useDynamicRender={useDynamicRender}
                                         scrollHeight={scrollHeight}
                                         rowHeight={rowHeight}
                                         scrollBuffer={scrollBuffer}
                                         onScroll={onScroll}>
                            {
                                scrollEl =>
                                    <BaseTable {...restProps}
                                               fixed={fixed}
                                               fragment={TableFragment.HEAD}
                                               columns={columns}
                                               headColumns={headColumns}
                                               bodyColumns={bodyColumns}
                                               isHeadFixed={isHeadFixed}
                                               isFootFixed={isFootFixed}
                                               data={data}
                                               scrollEl={scrollEl}
                                               useDynamicRender={useDynamicRender}
                                               scrollHeight={scrollHeight}
                                               rowHeight={rowHeight}
                                               scrollBuffer={scrollBuffer}
                                               hasVerticalScroll={hasVerticalScroll}
                                               isBodyHidden={true}
                                               isFootHidden={true}
                                               isLayoutFixed={isLayoutFixed}
                                               defaultColumnWidth={defaultColumnWidth}
                                               useColumnsWidth={true}
                                               onRequestColumnsSpan={this.handleColumnsSpan}/>
                            }
                        </ScrollableTable>
                        :
                        null
                }

                <ScrollableTable ref={this.bodyScroller}
                                 className={classNames('scroll-table-body', {
                                     'has-head': hasHead,
                                     'has-foot': hasFoot
                                 })}
                                 style={verticalScrollStyle}
                                 scroll={scroll}
                                 useDynamicRender={useDynamicRender}
                                 scrollHeight={scrollHeight}
                                 rowHeight={rowHeight}
                                 scrollBuffer={scrollBuffer}
                                 onScroll={onScroll}
                                 onWheel={onWheel}>
                    {
                        scrollEl =>
                            <DynamicRenderTableProvider data={data}
                                                        useDynamicRender={useDynamicRender}
                                                        rowHeight={rowHeight}>
                                <BaseTable {...restProps}
                                           style={{
                                               width: horizontalScrollStyle?.width,
                                               minWidth: horizontalScrollStyle?.width ? '100%' : null,
                                               transform: useDynamicRender && dynamicRenderIndex ?
                                                   `translateY(${dynamicRenderIndex.startWithBuffer * rowHeight}px)`
                                                   :
                                                   null
                                           }}
                                           fixed={fixed}
                                           fragment={TableFragment.BODY}
                                           columns={columns}
                                           headColumns={headColumns}
                                           bodyColumns={bodyColumns}
                                           isHeadFixed={isHeadFixed}
                                           isFootFixed={isFootFixed}
                                           isLayoutFixed={isLayoutFixed}
                                           isHeadHidden={isHeadHidden || isHeadFixed}
                                           isFootHidden={isFootHidden || isFootFixed}
                                           data={data}
                                           scrollEl={scrollEl}
                                           useDynamicRender={useDynamicRender}
                                           scrollHeight={scrollHeight}
                                           rowHeight={rowHeight}
                                           scrollBuffer={scrollBuffer}
                                           defaultColumnWidth={defaultColumnWidth}
                                           onRequestColumnsSpan={this.handleColumnsSpan}
                                           onColumnMeasure={onColumnMeasure}/>
                            </DynamicRenderTableProvider>
                    }
                </ScrollableTable>

                {
                    hasFoot ?
                        <ScrollableTable ref={this.footScroller}
                                         className="scroll-table-foot"
                                         style={scrollableTableStyle}
                                         fragment={TableFragment.FOOT}
                                         scroll={scroll}
                                         useDynamicRender={useDynamicRender}
                                         scrollHeight={scrollHeight}
                                         rowHeight={rowHeight}
                                         scrollBuffer={scrollBuffer}
                                         onScroll={onScroll}>
                            {
                                scrollEl =>
                                    <BaseTable {...restProps}
                                               fixed={fixed}
                                               fragment={TableFragment.FOOT}
                                               columns={columns}
                                               headColumns={headColumns}
                                               bodyColumns={bodyColumns}
                                               isHeadFixed={isHeadFixed}
                                               isFootFixed={isFootFixed}
                                               ignoreColumnSpan={true}
                                               data={data}
                                               scrollEl={scrollEl}
                                               useDynamicRender={useDynamicRender}
                                               scrollHeight={scrollHeight}
                                               rowHeight={rowHeight}
                                               scrollBuffer={scrollBuffer}
                                               hasVerticalScroll={hasVerticalScroll}
                                               isHeadHidden={true}
                                               isBodyHidden={true}
                                               isLayoutFixed={isLayoutFixed}
                                               defaultColumnWidth={defaultColumnWidth}
                                               useColumnsWidth={true}
                                               onRequestColumnsSpan={this.handleColumnsSpan}/>
                            }
                        </ScrollableTable>
                        :
                        null
                }

            </Fragment>
        );

    }
}

ScrollTable.propTypes = {

    horizontalScrollStyle: PropTypes.object,
    verticalScrollStyle: PropTypes.object,

    fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

    /**
     * The theme of the table select radio or checkbox.
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * unique keyof column.
         */
        key: PropTypes.string,

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.func]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * The title in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headTitle: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * The title in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyTitle: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * The title in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footTitle: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true, this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),

        /**
         * whether the column can be resized
         */
        resizable: PropTypes.bool

    })),
    headColumns: PropTypes.array,
    bodyColumns: PropTypes.array,
    columnKeyField: PropTypes.string,
    columnsWidth: PropTypes.object,
    data: PropTypes.array,
    dynamicRenderData: PropTypes.array,
    value: PropTypes.array,
    idField: PropTypes.string,
    expandRows: PropTypes.array,

    /**
     * scroll
     */
    scroll: PropTypes.shape({
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    }),

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    isClickSorting: PropTypes.bool,

    /**
     * fixed
     */
    isLayoutFixed: PropTypes.bool,
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * has renderer
     */
    hasHeadRenderer: PropTypes.bool,
    hasBodyRenderer: PropTypes.bool,
    hasFootRenderer: PropTypes.bool,

    /**
     * fixed column
     */
    hasFixedLeftColumn: PropTypes.bool,
    hasFixedRightColumn: PropTypes.bool,

    /**
     * Dynamic Render
     */
    useDynamicRender: PropTypes.bool,
    dynamicRenderIndex: PropTypes.object,
    scrollHeight: PropTypes.number,
    rowHeight: PropTypes.number,
    scrollBuffer: PropTypes.number,

    /**
     * column resizable
     */
    defaultColumnWidth: PropTypes.number,
    minColumnWidth: PropTypes.number,
    maxColumnWidth: PropTypes.number,
    resizingColumn: PropTypes.object,

    /**
     * callback
     */
    onInit: PropTypes.func,
    onGetScrollerEl: PropTypes.func,
    onExpandChange: PropTypes.func,
    onScroll: PropTypes.func,
    onWheel: PropTypes.func,
    onSortChange: PropTypes.func,
    onRequestColumnsSpan: PropTypes.func,
    onColumnsWidthChange: PropTypes.func,
    onColumnResizeStart: PropTypes.func,
    onColumnResizeEnd: PropTypes.func,
    onColumnMeasure: PropTypes.func

};

ScrollTable.defaultProps = {

    columnKeyField: 'key',
    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,
    idField: 'id',
    expandRows: [],

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    isClickSorting: true,

    /**
     * fixed
     */
    isLayoutFixed: true,
    isHeadFixed: false,
    isFootFixed: false,

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * has renderer
     */
    hasHeadRenderer: true,
    hasBodyRenderer: true,
    hasFootRenderer: true,

    /**
     * fixed column
     */
    hasFixedLeftColumn: false,
    hasFixedRightColumn: false,

    /**
     * Dynamic Render
     */
    useDynamicRender: false,
    scrollHeight: 500,
    rowHeight: 50,
    scrollBuffer: 8,

    /**
     * column resizable
     */
    defaultColumnWidth: 100,
    minColumnWidth: 64,
    maxColumnWidth: Infinity

};

export default ScrollTable;
<|endoftext|>


<commit_before>'use strict'

const { expect } = require('chai')
const Joi = require('joi')
const { Range } = require('semver')
const t = (module.exports = require('../tester').createServiceTester())

function expectSemverRange(value) {
  expect(() => new Range(value)).not.to.throw()
}

t.create('gets the node version of passport')
  .get('/passport.json')
  .expectBadge({ label: 'node', message: Joi.string() })
  .afterJSON(json => {
    expectSemverRange(json.value)
  })

t.create('gets the node version of @stdlib/stdlib')
  .get('/@stdlib/stdlib.json')
  .expectBadge({ label: 'node', message: Joi.string() })
  .afterJSON(json => {
    expectSemverRange(json.value)
  })

t.create("gets the tagged release's node version version of ionic")
  .get('/ionic/next.json')
  .expectBadge({ label: 'node@next', message: Joi.string() })
  .afterJSON(json => {
    expectSemverRange(json.value)
  })

t.create('gets the node version of passport from a custom registry')
  .get('/passport.json?registry_uri=https://registry.npmjs.com')
  .expectBadge({ label: 'node', message: Joi.string() })
  .afterJSON(json => {
    expectSemverRange(json.value)
  })

t.create("gets the tagged release's node version of @cycle/core")
  .get('/@cycle/core/canary.json')
  .expectBadge({ label: 'node@canary', message: Joi.string() })
  .afterJSON(json => {
    expectSemverRange(json.value)
  })

t.create('invalid package name')
  .get('/frodo-is-not-a-package.json')
  .expectBadge({ label: 'node', message: 'package not found' })
<commit_msg>[Node] tests improvements (#3288)<commit_after>'use strict'

const { expect } = require('chai')
const { Range } = require('semver')
const t = (module.exports = require('../tester').createServiceTester())

function expectSemverRange(message) {
  expect(() => new Range(message)).not.to.throw()
}

t.create('gets the node version of passport')
  .get('/passport.json')
  .expectBadge({ label: 'node' })
  .afterJSON(json => {
    expectSemverRange(json.message)
  })

t.create('gets the node version of @stdlib/stdlib')
  .get('/@stdlib/stdlib.json')
  .expectBadge({ label: 'node' })
  .afterJSON(json => {
    expectSemverRange(json.message)
  })

t.create("gets the tagged release's node version version of ionic")
  .get('/ionic/next.json')
  .expectBadge({ label: 'node@next' })
  .afterJSON(json => {
    expectSemverRange(json.message)
  })

t.create('gets the node version of passport from a custom registry')
  .get('/passport.json?registry_uri=https://registry.npmjs.com')
  .expectBadge({ label: 'node' })
  .afterJSON(json => {
    expectSemverRange(json.message)
  })

t.create("gets the tagged release's node version of @cycle/core")
  .get('/@cycle/core/canary.json')
  .expectBadge({ label: 'node@canary' })
  .afterJSON(json => {
    expectSemverRange(json.message)
  })

t.create('invalid package name')
  .get('/frodo-is-not-a-package.json')
  .expectBadge({ label: 'node', message: 'package not found' })
<|endoftext|>


<commit_before>import axios from 'axios';
import Vuex from 'vuex';

import {createLocalVue} from '../helper';
import {statusOptions} from '../../vuex/store/model_builder';
import stud_schedule, { postProcess } from '../../vuex/store/schedule/student';
import {expectAction} from '../helper';

import mockCoursesJaverage2013Spring from
  '../mock_data/stud_schedule/javerage2013Spring.json';
import mockCoursesJeos2013Spring from
  '../mock_data/stud_schedule/jeos2013Spring.json';
import mockCoursesJeos2013SummerB from
  '../mock_data/stud_schedule/jeos2013SummerB.json';

const localVue = createLocalVue(Vuex);

jest.mock('axios');

describe('Stud Course model', () => {
  let store;

  beforeEach(() => {
    store = new Vuex.Store({
      modules: {
        'stud_schedule': stud_schedule,
      },
    });
  });

  it('Check status changes on fetch - success', () => {
    axios.get.mockResolvedValue(
      {data: mockCoursesJaverage2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
      {type: 'setStatus', payload: statusOptions[1]},
      {type: 'setValue', payload: mockCoursesJaverage2013Spring},
      {type: 'setStatus', payload: statusOptions[0]},
    ]);
  });

  it('Check status changes on fetch - failure', () => {
    axios.get.mockResolvedValue(Promise.reject({response: {status: 404}}));
    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };
    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setStatus', payload: statusOptions[2]},
      ]);
  });

  it ('Check postProcess - javerage 2013 spring', () => {
    axios.get.mockResolvedValue(
        {data: mockCoursesJaverage2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setValue', payload: mockCoursesJaverage2013Spring},
        {type: 'setStatus', payload: statusOptions[0]},
      ]);
  });

  it ('Check postProcess - jeos 2013 spring', () => {
    axios.get.mockResolvedValue(
      {data: mockCoursesJeos2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setValue', payload: mockCoursesJeos2013Spring},
        {type: 'setStatus', payload: statusOptions[0]},
      ]);
  });

  it ('Check postProcess - javerage 2013 spring', () => {
    let mockData = {
      '2013,spring': mockCoursesJaverage2013Spring,
    };

    let proccessedData = postProcess(mockData);

    console.log(proccessedData);
  });
});
<commit_msg>Removed broken/incomplete test<commit_after>import axios from 'axios';
import Vuex from 'vuex';

import {createLocalVue} from '../helper';
import {statusOptions} from '../../vuex/store/model_builder';
import stud_schedule, { postProcess } from '../../vuex/store/schedule/student';
import {expectAction} from '../helper';

import mockCoursesJaverage2013Spring from
  '../mock_data/stud_schedule/javerage2013Spring.json';
import mockCoursesJeos2013Spring from
  '../mock_data/stud_schedule/jeos2013Spring.json';
import mockCoursesJeos2013SummerB from
  '../mock_data/stud_schedule/jeos2013SummerB.json';

const localVue = createLocalVue(Vuex);

jest.mock('axios');

describe('Stud Course model', () => {
  let store;

  beforeEach(() => {
    store = new Vuex.Store({
      modules: {
        'stud_schedule': stud_schedule,
      },
    });
  });

  it('Check status changes on fetch - success', () => {
    axios.get.mockResolvedValue(
      {data: mockCoursesJaverage2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
      {type: 'setStatus', payload: statusOptions[1]},
      {type: 'setValue', payload: mockCoursesJaverage2013Spring},
      {type: 'setStatus', payload: statusOptions[0]},
    ]);
  });

  it('Check status changes on fetch - failure', () => {
    axios.get.mockResolvedValue(Promise.reject({response: {status: 404}}));
    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };
    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setStatus', payload: statusOptions[2]},
      ]);
  });

  it ('Check postProcess - javerage 2013 spring', () => {
    axios.get.mockResolvedValue(
        {data: mockCoursesJaverage2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setValue', payload: mockCoursesJaverage2013Spring},
        {type: 'setStatus', payload: statusOptions[0]},
      ]);
  });

  it ('Check postProcess - jeos 2013 spring', () => {
    axios.get.mockResolvedValue(
      {data: mockCoursesJeos2013Spring, status: 200}
    );

    const getters = {
      isReadyTagged: () => false,
      isFetchingTagged: () => false,
    };

    return expectAction(
      stud_schedule.actions.fetch, null, stud_schedule.state, getters, [
        {type: 'setStatus', payload: statusOptions[1]},
        {type: 'setValue', payload: mockCoursesJeos2013Spring},
        {type: 'setStatus', payload: statusOptions[0]},
      ]);
  });
});
<|endoftext|>


<commit_before>describe('auth/authentication_provider', () => {
  let Ravel, ravelApp, provider;
  beforeEach(() => {
    Ravel = require('../../lib/ravel');
    ravelApp = new Ravel();
    ravelApp.set('log level', ravelApp.log.NONE);
    ravelApp.set('keygrip keys', ['abc']);
    class TestProvider extends Ravel.AuthenticationProvider {
      get name () {
        return 'test';
      }
    }
    provider = new TestProvider(ravelApp);
  });

  describe('constructor', () => {
    it('should allow clients to implement an authentication provider which has a name and several methods', () => {
      class GoogleOAuth2 extends Ravel.AuthenticationProvider {
        get name () {
          return 'google-oauth2';
        }
      }
      provider = new GoogleOAuth2(ravelApp);
      ravelApp.emit('pre listen');
      expect(provider.name).toBe('google-oauth2');
      expect(typeof provider.init).toBe('function');
      expect(typeof provider.handlesClient).toBe('function');
      expect(typeof provider.credentialToProfile).toBe('function');
      expect(typeof provider.log).toBe('object');
      expect(typeof provider.ravelInstance).toBe('object');
      expect(typeof provider.ApplicationError).toBe('function');
    });

    it('should require clients to supply a name for the provider', () => {
      expect(() => {
        new Ravel.AuthenticationProvider(ravelApp); // eslint-disable-line no-new
      }).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#init()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', () => {
      expect(() => provider.init()).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#handlesClient()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', () => {
      expect(() => provider.handlesClient()).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#credentialToProfile()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', async () => {
      await expect(provider.credentialToProfile()).rejects.toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('ravelApp.authorizationProviders', () => {
    it('should return an empty Array if no AuthorizationProviders are registered', () => {
      ravelApp = new Ravel();
      expect(typeof ravelApp.authenticationProviders).toBe('function');
      expect(Array.isArray(ravelApp.authenticationProviders())).toBe(true);
      expect(ravelApp.authenticationProviders().length).toBe(0);
    });

    it('should return an Array of registered AuthorizationProviders', () => {
      class GoogleOAuth2 extends Ravel.AuthenticationProvider {
        get name () {
          return 'google-oauth2';
        }
      }
      provider = new GoogleOAuth2(ravelApp);
      expect(typeof ravelApp.authenticationProviders).toBe('function');
      expect(Array.isArray(ravelApp.authenticationProviders())).toBe(true);
      expect(ravelApp.authenticationProviders().length).toBe(2);
      expect(ravelApp.authenticationProviders()[1]).toBe(provider);
    });

    it('should require clients to supply a name for the provider', () => {
      expect(() => {
        new Ravel.AuthenticationProvider(ravelApp); // eslint-disable-line no-new
      }).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });
});
<commit_msg>Fixing log message<commit_after>describe('auth/authentication_provider', () => {
  let Ravel, ravelApp, provider;
  beforeEach(() => {
    Ravel = require('../../lib/ravel');
    ravelApp = new Ravel();
    ravelApp.log.setLevel(ravelApp.log.NONE); // because we won't init
    class TestProvider extends Ravel.AuthenticationProvider {
      get name () {
        return 'test';
      }
    }
    provider = new TestProvider(ravelApp);
  });

  describe('constructor', () => {
    it('should allow clients to implement an authentication provider which has a name and several methods', async () => {
      class GoogleOAuth2 extends Ravel.AuthenticationProvider {
        get name () {
          return 'google-oauth2';
        }
      }
      provider = new GoogleOAuth2(ravelApp);
      ravelApp.emit('pre listen');
      expect(provider.name).toBe('google-oauth2');
      expect(typeof provider.init).toBe('function');
      expect(typeof provider.handlesClient).toBe('function');
      expect(typeof provider.credentialToProfile).toBe('function');
      expect(typeof provider.log).toBe('object');
      expect(typeof provider.ravelInstance).toBe('object');
      expect(typeof provider.ApplicationError).toBe('function');
    });

    it('should require clients to supply a name for the provider', () => {
      expect(() => {
        new Ravel.AuthenticationProvider(ravelApp); // eslint-disable-line no-new
      }).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#init()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', () => {
      expect(() => provider.init()).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#handlesClient()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', () => {
      expect(() => provider.handlesClient()).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('#credentialToProfile()', () => {
    it('should throw ravelApp.ApplicationError.NotImplemented, since this is a template', async () => {
      await expect(provider.credentialToProfile()).rejects.toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });

  describe('ravelApp.authorizationProviders', () => {
    it('should return an empty Array if no AuthorizationProviders are registered', () => {
      ravelApp = new Ravel();
      expect(typeof ravelApp.authenticationProviders).toBe('function');
      expect(Array.isArray(ravelApp.authenticationProviders())).toBe(true);
      expect(ravelApp.authenticationProviders().length).toBe(0);
    });

    it('should return an Array of registered AuthorizationProviders', async () => {
      class GoogleOAuth2 extends Ravel.AuthenticationProvider {
        get name () {
          return 'google-oauth2';
        }
      }
      provider = new GoogleOAuth2(ravelApp);
      expect(typeof ravelApp.authenticationProviders).toBe('function');
      expect(Array.isArray(ravelApp.authenticationProviders())).toBe(true);
      expect(ravelApp.authenticationProviders().length).toBe(2);
      expect(ravelApp.authenticationProviders()[1]).toBe(provider);
    });

    it('should require clients to supply a name for the provider', () => {
      expect(() => {
        new Ravel.AuthenticationProvider(ravelApp); // eslint-disable-line no-new
      }).toThrow(ravelApp.ApplicationError.NotImplemented);
    });
  });
});
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    fs = require('fs-extra'),
    glob = require('glob'),
    exec = require('child_process').exec,
    uuid = require('node-uuid')

var watcher = gulp.watch('Temp/UnityTempFile-*', ['compile'])

var directoryName = __dirname.split("/").reverse()[0]

// default config
var config = {
    version: "0.0.0",
    organisation: "Organisation",
    module: "MyFirstModule",
    packageType: "UnityExtension",
    unityversions: ["4.6", "5.0"],
    defines: {
        "4.6": [
            "UNITY_4_6"
        ],
        "5.0": [
            "UNITY_5_0"
        ],
        "all": [
            "DEBUG"
        ]
    }
}

fs.readJson('./module-config.json', function (err, json) {
    if (err) return console.error(err)
    config = json
})

gulp.task('default', function () {
    if (fs.exists('build/')) {
        fs.unlink('build/')
    }
    watcher.on('change', function (event) {
        if (event.type == "added")
            config.unityversions.forEach(function (unityversion) {
                fs.copySync(event.path, event.path.replace("UnityTempFile-", unityversion + "_UnityTempFile-"))
            })
    })
});

function removeDefine(unityversion) {
    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'}).replace(/^-define:.*$[\s\S]/mg, '');
        fs.writeFileSync(file, data)
    })
}

function removeModuleReference(unityversion) {
    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'}).replace(/^-r:'.*[Data\\|Contents\/]UnityExtensions\/[^Unity\/].*'$[\s\S]/mg, "")
        fs.writeFileSync(file, data)
    })
}

function replaceOut(unityversion, path) {

    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'});
        pattern = /^\-out:'Temp\/(.*)\.dll'$/m
        editor_pattern = /-Editor/
        firstpass_pattern = /-firstpass$/
        if (pattern.test(data)) {
            match = data.match(pattern);
            out = path

            from = match[1]
            to = directoryName

            if (editor_pattern.test(from))
                to += from.match(editor_pattern)

            if (firstpass_pattern.test(from)) {
                to += from.match(firstpass_pattern)
                out += "Standard Assets/"
            }

            if (editor_pattern.test(from))
                out += "Editor/"

            exec('mkdir -p \'' + out + '\'')

            dll = out + to + ".dll"

            console.log('compiling ' + dll)
            fs.writeFileSync(file, data.replace(pattern, "-out:'" + dll + "'"))
        }
    })
}

function appendDefine(unityversion) {

    defines = []

    if (config.hasOwnProperty('defines')) {
        if (config.defines.hasOwnProperty(unityversion)) {
            defines = defines.concat(config.defines[unityversion])
        }

        if (config.defines.hasOwnProperty('all')) {
            defines = defines.concat(config.defines['all'])
        }
    }
    getTempFiles(unityversion).forEach(function (file) {
        data = fs.readFileSync(file, {encoding: 'utf8'});

        defines.forEach(function (define) {
            data += '-define:' + define + '\n'
        })
        fs.writeFileSync(file, data)
    })
}

gulp.task('compile', function () {
    config.unityversions.forEach(function (unityversion) {

        path = 'build/' + config.organisation + '/' + config.module + '/' + unityversion + '/'

        removeDefine(unityversion)
        removeModuleReference(unityversion)
        replaceOut(unityversion, path)

        appendDefine(unityversion)

        getTempFiles(unityversion).forEach(function (file) {
            exec("mcs " + jointLine(file))
            fs.unlink(file)
        })

        ivy = template_ivy

        ivy = ivy.replace("#VERSION#", config.version)
            .replace("#ORGANISATION#", config.organisation)
            .replace("#MODULE#", config.module)
            .replace("#PACKAGETYPE#", config.packageType)
            .replace("#UNITYVERSION#", unityversion)

        artifactNames = glob.GlobSync(path + "/**/*.dll").found
        artifacts = []
        for (var i = 0; i < artifactNames.length; i++) {
            artifactName = artifactNames[i].split(unityversion)[1].substring(1).replace(/\.dll$/, '')
            artifact = template_artifact
            artifact = artifact.replace("#NAME#", artifactName)
                .replace("#GUID#", guid())
            sleep(0.1)
            artifacts.push(artifact)

        }

        ivy = ivy.replace("#ARTIFACTS#", artifacts.join('\n') + '\n')
        ivy_path = path + "ivy.xml"
        fs.exists(ivy_path) ? fs.writeFileSync(ivy_path, ivy) : fs.outputFileSync(ivy_path, ivy)
    })
});

function jointLine(file) {
    var data = fs.readFileSync(file, {encoding: 'utf8'});
    return data.replace(/$[\s\S]/mg, ' ');
}

function getTempFiles(unityversion) {
    return glob.GlobSync("Temp/" + unityversion + "_UnityTempFile-*").found
}
function guid() {
    return uuid.v1().replace(/-/g, '')
}

function sleep(second) {
    var e = new Date().getTime() + (second * 1000);
    while (new Date().getTime() <= e) {
    }
}

var template_ivy = '<?xml version="1.0" encoding="utf-8"?>\n'
template_ivy += '<ivy-module version="2.0">\n'
template_ivy += '  <info version="#VERSION#" organisation="#ORGANISATION#" module="#MODULE#" e:packageType="#PACKAGETYPE#" e:unityVersion="#UNITYVERSION#" xmlns:e="http://ant.apache.org/ivy/extra" />\n'
template_ivy += '  <publications xmlns:e="http://ant.apache.org/ivy/extra">\n'
template_ivy += '#ARTIFACTS#'
template_ivy += '  </publications>\n'
template_ivy += '</ivy-module>\n'

var template_artifact = '    <artifact name="#NAME#" type="dll" ext="dll" e:guid="#GUID#" />'<commit_msg>mcs に-sdk:2パラメータ追加<commit_after>var gulp = require('gulp'),
    fs = require('fs-extra'),
    glob = require('glob'),
    exec = require('child_process').exec,
    uuid = require('node-uuid')

var watcher = gulp.watch('Temp/UnityTempFile-*', ['compile'])

var directoryName = __dirname.split("/").reverse()[0]

// default config
var config = {
    version: "0.0.0",
    organisation: "Organisation",
    module: "MyFirstModule",
    packageType: "UnityExtension",
    unityversions: ["4.6", "5.0"],
    defines: {
        "4.6": [
            "UNITY_4_6"
        ],
        "5.0": [
            "UNITY_5_0"
        ],
        "all": [
            "DEBUG"
        ]
    }
}

fs.readJson('./module-config.json', function (err, json) {
    if (err) return console.error(err)
    config = json
})

gulp.task('default', function () {
    if (fs.exists('build/')) {
        fs.unlink('build/')
    }
    watcher.on('change', function (event) {
        if (event.type == "added")
            config.unityversions.forEach(function (unityversion) {
                fs.copySync(event.path, event.path.replace("UnityTempFile-", unityversion + "_UnityTempFile-"))
            })
    })
});

function removeDefine(unityversion) {
    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'}).replace(/^-define:.*$[\s\S]/mg, '');
        fs.writeFileSync(file, data)
    })
}

function removeModuleReference(unityversion) {
    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'}).replace(/^-r:'.*[Data\\|Contents\/]UnityExtensions\/[^Unity\/].*'$[\s\S]/mg, "")
        fs.writeFileSync(file, data)
    })
}

function replaceOut(unityversion, path) {

    getTempFiles(unityversion).forEach(function (file) {
        var data = fs.readFileSync(file, {encoding: 'utf8'});
        pattern = /^\-out:'Temp\/(.*)\.dll'$/m
        editor_pattern = /-Editor/
        firstpass_pattern = /-firstpass$/
        if (pattern.test(data)) {
            match = data.match(pattern);
            out = path

            from = match[1]
            to = directoryName

            if (editor_pattern.test(from))
                to += from.match(editor_pattern)

            if (firstpass_pattern.test(from)) {
                to += from.match(firstpass_pattern)
                out += "Standard Assets/"
            }

            if (editor_pattern.test(from))
                out += "Editor/"

            exec('mkdir -p \'' + out + '\'')

            dll = out + to + ".dll"

            console.log('compiling ' + dll)
            fs.writeFileSync(file, data.replace(pattern, "-out:'" + dll + "'"))
        }
    })
}

function appendDefine(unityversion) {

    defines = []

    if (config.hasOwnProperty('defines')) {
        if (config.defines.hasOwnProperty(unityversion)) {
            defines = defines.concat(config.defines[unityversion])
        }

        if (config.defines.hasOwnProperty('all')) {
            defines = defines.concat(config.defines['all'])
        }
    }
    getTempFiles(unityversion).forEach(function (file) {
        data = fs.readFileSync(file, {encoding: 'utf8'});

        defines.forEach(function (define) {
            data += '-define:' + define + '\n'
        })
        fs.writeFileSync(file, data)
    })
}

gulp.task('compile', function () {
    config.unityversions.forEach(function (unityversion) {

        path = 'build/' + config.organisation + '/' + config.module + '/' + unityversion + '/'

        removeDefine(unityversion)
        removeModuleReference(unityversion)
        replaceOut(unityversion, path)

        appendDefine(unityversion)

        getTempFiles(unityversion).forEach(function (file) {
            exec("mcs -sdk:2 " + jointLine(file))
            fs.unlink(file)
        })

        ivy = template_ivy

        ivy = ivy.replace("#VERSION#", config.version)
            .replace("#ORGANISATION#", config.organisation)
            .replace("#MODULE#", config.module)
            .replace("#PACKAGETYPE#", config.packageType)
            .replace("#UNITYVERSION#", unityversion)

        artifactNames = glob.GlobSync(path + "/**/*.dll").found
        artifacts = []
        for (var i = 0; i < artifactNames.length; i++) {
            artifactName = artifactNames[i].split(unityversion)[1].substring(1).replace(/\.dll$/, '')
            artifact = template_artifact
            artifact = artifact.replace("#NAME#", artifactName)
                .replace("#GUID#", guid())
            sleep(0.1)
            artifacts.push(artifact)

        }

        ivy = ivy.replace("#ARTIFACTS#", artifacts.join('\n') + '\n')
        ivy_path = path + "ivy.xml"
        fs.exists(ivy_path) ? fs.writeFileSync(ivy_path, ivy) : fs.outputFileSync(ivy_path, ivy)
    })
});

function jointLine(file) {
    var data = fs.readFileSync(file, {encoding: 'utf8'});
    return data.replace(/$[\s\S]/mg, ' ');
}

function getTempFiles(unityversion) {
    return glob.GlobSync("Temp/" + unityversion + "_UnityTempFile-*").found
}
function guid() {
    return uuid.v1().replace(/-/g, '')
}

function sleep(second) {
    var e = new Date().getTime() + (second * 1000);
    while (new Date().getTime() <= e) {
    }
}

var template_ivy = '<?xml version="1.0" encoding="utf-8"?>\n'
template_ivy += '<ivy-module version="2.0">\n'
template_ivy += '  <info version="#VERSION#" organisation="#ORGANISATION#" module="#MODULE#" e:packageType="#PACKAGETYPE#" e:unityVersion="#UNITYVERSION#" xmlns:e="http://ant.apache.org/ivy/extra" />\n'
template_ivy += '  <publications xmlns:e="http://ant.apache.org/ivy/extra">\n'
template_ivy += '#ARTIFACTS#'
template_ivy += '  </publications>\n'
template_ivy += '</ivy-module>\n'

var template_artifact = '    <artifact name="#NAME#" type="dll" ext="dll" e:guid="#GUID#" />'<|endoftext|>


<commit_before>/**
 * The level test driver.
 * Tests collections are specified in .js files in the solutions directory.
 * To extract the xml for a test from a workspace, run the following code in
 * your console:
 * Blockly.Xml.domToText(Blockly.Xml.blockSpaceToDom(Blockly.mainBlockSpace));
 */

// todo - should we also have tests around which blocks to show as part of the
// feedback when a user gets the puzzle wrong?

var path = require('path');
var assert = require('chai').assert;
var $ = require('jquery');
require('jquery-ui');

var testUtils = require('./util/testUtils');
testUtils.setupLocales();

var wrappedEventListener = require('./util/wrappedEventListener');
var testCollectionUtils = require('./util/testCollectionUtils');

// One day this might be the sort of thing we share with initApp.js
function loadSource(src) {
  var deferred = new $.Deferred();
  document.body.appendChild($('<script>', { src: src }).on('load', function () {
    deferred.resolve();
  })[0]);
  return deferred;
}

describe('Level tests', function() {
  var studioApp;
  var originalRender;

  before(function(done) {
    this.timeout(15000);

    window.jQuery = $;
    window.$ = $;

    // Load a bunch of droplet sources. We could potentially gate this on level.editCode,
    // but that doesn't get us a lot since everything is run in a single session now.
    loadSource('http://localhost:8001/apps/lib/jsinterpreter/acorn_interpreter.js')
    .then(function () { return loadSource('http://localhost:8001/apps/lib/requirejs/full/require.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/ace.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/mode-javascript.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/ext-language_tools.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/droplet/droplet-full.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/tooltipster/jquery.tooltipster.js'); })
    .then(function () {
      assert(window.requirejs);
      done();
    });
  });

  beforeEach(function () {
    testUtils.setupBlocklyFrame();
    studioApp = testUtils.getStudioAppSingleton();

    wrappedEventListener.attach();

    // For some reason, svg rendering is taking a long time in phantomjs. None
    // of these tests depend on that rendering actually happening.
    originalRender = Blockly.BlockSvg.prototype.render;
    Blockly.BlockSvg.prototype.render = function () {
      this.block_.rendered = true;
    };

    if (window.Studio) {
      var Projectile = require('@cdo/apps/studio/projectile');
      Projectile.__resetIds();
    }
  });

  testCollectionUtils.getCollections().forEach(runTestCollection);

  afterEach(function () {
    var studioApp = require('@cdo/apps/StudioApp').singleton;
    if (studioApp.editor && studioApp.editor.aceEditor &&
        studioApp.editor.aceEditor.session &&
        studioApp.editor.aceEditor.session.$mode &&
        studioApp.editor.aceEditor.session.$mode.cleanup) {
      studioApp.editor.aceEditor.session.$mode.cleanup();
    }
    wrappedEventListener.detach();
    Blockly.BlockSvg.prototype.render = originalRender;

    // Clean up some state that is meant to be per level. This is an issue
    // because we're using the same window for all tests.
    if (window.Maze) {
      window.Maze.bee = null;
      window.Maze.wordSearch = null;
    }
    if (window.Studio) {
      window.Studio.customLogic = null;
      window.Studio.interpreter = null;
    }
  });
});

// Loads a test collection at path and runs all the tests specified in it.
function runTestCollection (item) {
  var runLevelTest = require('./util/runLevelTest');
  // Append back the .js so that we can distinguish 2_1.js from 2_10.js when grepping
  var path = item.path + '.js';
  var testCollection = item.data;

  var app = testCollection.app;

  describe(path, function () {
    testCollection.tests.forEach(function (testData, index) {
      testUtils.setupLocale(app);
      var dataItem = require('./util/data')(app);

      // todo - maybe change the name of expected to make it clear what type of
      // test is being run, since we're using the same JSON files for these
      // and our getMissingRequiredBlocks tests (and likely also other things
      // in the future)
      if (testData.expected) {
        it(testData.description, function (done) {
          // can specify a test specific timeout in json file.
          if (testData.timeout !== undefined) {
            this.timeout(testData.timeout);
          }

          if (testUtils.debugMode()) {
            // No timeout if we have a debugger attached
            this.timeout(0);
          }
          runLevelTest(testCollection, testData, dataItem, done);
        });
      }
    });
  });
}
<commit_msg>fix mochaTest failures<commit_after>/**
 * The level test driver.
 * Tests collections are specified in .js files in the solutions directory.
 * To extract the xml for a test from a workspace, run the following code in
 * your console:
 * Blockly.Xml.domToText(Blockly.Xml.blockSpaceToDom(Blockly.mainBlockSpace));
 */

// todo - should we also have tests around which blocks to show as part of the
// feedback when a user gets the puzzle wrong?

var path = require('path');
var assert = require('chai').assert;
var $ = require('jquery');
require('jquery-ui');

var testUtils = require('./util/testUtils');
testUtils.setupLocales();

var wrappedEventListener = require('./util/wrappedEventListener');
var testCollectionUtils = require('./util/testCollectionUtils');

// One day this might be the sort of thing we share with initApp.js
function loadSource(src) {
  var deferred = new $.Deferred();
  document.body.appendChild($('<script>', { src: src }).on('load', function () {
    deferred.resolve();
  })[0]);
  return deferred;
}

describe('Level tests', function() {
  var studioApp;
  var originalRender;

  before(function(done) {
    this.timeout(15000);

    window.jQuery = $;
    window.$ = $;

    // Load a bunch of droplet sources. We could potentially gate this on level.editCode,
    // but that doesn't get us a lot since everything is run in a single session now.
    loadSource('http://localhost:8001/apps/lib/jsinterpreter/acorn_interpreter.js')
    .then(function () { return loadSource('http://localhost:8001/apps/lib/requirejs/full/require.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/ace.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/mode-javascript.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/ace/src-noconflict/ext-language_tools.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/droplet/droplet-full.js'); })
    .then(function () { return loadSource('http://localhost:8001/apps/lib/tooltipster/jquery.tooltipster.js'); })
    .then(function () {
      assert(window.requirejs);
      done();
    });
  });

  beforeEach(function () {
    testUtils.setupBlocklyFrame();
    studioApp = testUtils.getStudioAppSingleton();

    wrappedEventListener.attach();

    // For some reason, svg rendering is taking a long time in phantomjs. None
    // of these tests depend on that rendering actually happening.
    originalRender = Blockly.BlockSvg.prototype.render;
    Blockly.BlockSvg.prototype.render = function () {
      this.block_.rendered = true;
    };

    if (window.Studio) {
      var Projectile = require('@cdo/apps/studio/projectile');
      Projectile.__resetIds();
      Studio.JSInterpreter = undefined;
    }
  });

  testCollectionUtils.getCollections().forEach(runTestCollection);

  afterEach(function () {
    var studioApp = require('@cdo/apps/StudioApp').singleton;
    if (studioApp.editor && studioApp.editor.aceEditor &&
        studioApp.editor.aceEditor.session &&
        studioApp.editor.aceEditor.session.$mode &&
        studioApp.editor.aceEditor.session.$mode.cleanup) {
      studioApp.editor.aceEditor.session.$mode.cleanup();
    }
    wrappedEventListener.detach();
    Blockly.BlockSvg.prototype.render = originalRender;

    // Clean up some state that is meant to be per level. This is an issue
    // because we're using the same window for all tests.
    if (window.Maze) {
      window.Maze.bee = null;
      window.Maze.wordSearch = null;
    }
    if (window.Studio) {
      window.Studio.customLogic = null;
      window.Studio.interpreter = null;
    }
  });
});

// Loads a test collection at path and runs all the tests specified in it.
function runTestCollection (item) {
  var runLevelTest = require('./util/runLevelTest');
  // Append back the .js so that we can distinguish 2_1.js from 2_10.js when grepping
  var path = item.path + '.js';
  var testCollection = item.data;

  var app = testCollection.app;

  describe(path, function () {
    testCollection.tests.forEach(function (testData, index) {
      testUtils.setupLocale(app);
      var dataItem = require('./util/data')(app);

      // todo - maybe change the name of expected to make it clear what type of
      // test is being run, since we're using the same JSON files for these
      // and our getMissingRequiredBlocks tests (and likely also other things
      // in the future)
      if (testData.expected) {
        it(testData.description, function (done) {
          // can specify a test specific timeout in json file.
          if (testData.timeout !== undefined) {
            this.timeout(testData.timeout);
          }

          if (testUtils.debugMode()) {
            // No timeout if we have a debugger attached
            this.timeout(0);
          }
          runLevelTest(testCollection, testData, dataItem, done);
        });
      }
    });
  });
}
<|endoftext|>


<commit_before>"use strict";

var debug = require('debug')('waigo-startup-routes'),
  queryString = require('query-string');

var waigo = global.waigo,
  _ = waigo._;

/**
 * Build URL to given route.
 * @param  {App} app         The app.
 * @param  {String} routeName   Name of route.
 * @param  {Object} [urlParams]   URL params for route.
 * @param  {Object} [queryParams] URL query params.
 * @param {Object} [options] Options.
 * @param {Boolean} [options.absolute] If `true` then return absolute URL including site base URL.
 * @return {String}             Route URL
 */
var routeUrl = function(app, routeName, urlParams, queryParams, options) {
  options = _.extend({
    absolute: false
  }, options);

  debug('Generate URL for route ' + routeName);

  var route = app.routes.byName[routeName];

  if (!route) {
    throw new Error('No route named: ' + routeName);
  }

  var str = options.absolute ? app.config.baseURL : '';

  str += route.url;

  // TODO: integrate params
  if (!_.isEmpty(queryParams)) {
    str += '?' + queryString.stringify(queryParams);
  }

  return str;
};

/**
 * Setup route mappings.
 *
 * This sets up a `koa-trie-router` and maps routes to it using the
 * [route mapper](../routeMapper.js.html).
 *
 * @param {Object} app The application.
 */
module.exports = function*(app) {
  debug('Setting up routes');

  require('koa-trie-router')(app);

  var routeFiles = waigo.getFilesInFolder('routes');

  app.routes = {};

  _.each(routeFiles, function(routeFile) {
    debug('Loading ' + routeFile);

    _.extend(app.routes, waigo.load(routeFile));
  });

  waigo.load('support/routeMapper').map(app, app.routes);

  app.use(app.router);

  // helper to build a URL based on a route
  app.routeUrl = app.locals.routeUrl = _.bind(routeUrl, null, app);
};

<commit_msg>use merge() instead of extend() for when collecting route definitions from source files<commit_after>"use strict";

var debug = require('debug')('waigo-startup-routes'),
  queryString = require('query-string');

var waigo = global.waigo,
  _ = waigo._;

/**
 * Build URL to given route.
 * @param  {App} app         The app.
 * @param  {String} routeName   Name of route.
 * @param  {Object} [urlParams]   URL params for route.
 * @param  {Object} [queryParams] URL query params.
 * @param {Object} [options] Options.
 * @param {Boolean} [options.absolute] If `true` then return absolute URL including site base URL.
 * @return {String}             Route URL
 */
var routeUrl = function(app, routeName, urlParams, queryParams, options) {
  options = _.extend({
    absolute: false
  }, options);

  debug('Generate URL for route ' + routeName);

  var route = app.routes.byName[routeName];

  if (!route) {
    throw new Error('No route named: ' + routeName);
  }

  var str = options.absolute ? app.config.baseURL : '';

  str += route.url;

  // TODO: integrate params
  if (!_.isEmpty(queryParams)) {
    str += '?' + queryString.stringify(queryParams);
  }

  return str;
};

/**
 * Setup route mappings.
 *
 * This sets up a `koa-trie-router` and maps routes to it using the
 * [route mapper](../routeMapper.js.html).
 *
 * @param {Object} app The application.
 */
module.exports = function*(app) {
  debug('Setting up routes');

  require('koa-trie-router')(app);

  var routeFiles = waigo.getFilesInFolder('routes');

  app.routes = {};

  _.each(routeFiles, function(routeFile) {
    debug('Loading ' + routeFile);

    _.merge(app.routes, waigo.load(routeFile));
  });

  waigo.load('support/routeMapper').map(app, app.routes);

  app.use(app.router);

  // helper to build a URL based on a route
  app.routeUrl = app.locals.routeUrl = _.bind(routeUrl, null, app);
};

<|endoftext|>


<commit_before>/**
 * A bot that welcomes new guild members when they join
 */

// Import the discord.js module
const Discord = require('discord.js');

// Create an instance of a Discord client
const client = new Discord.Client();

/**
 * The ready event is vital, it means that only _after_ this will your bot start reacting to information
 * received from Discord
 */
client.on('ready', () => {
  console.log('I am ready!');
});

// Create an event listener for new guild members
client.on('guildMemberAdd', member => {
  // Send the message to a designated channel on a server:
  const channel = member.guild.channels.find('name', 'member-log');
  // Do nothing if the channel wasn't found on this server
  if (!channel) return;
  // Send the message, mentioning the member
  channel.send(`Welcome to the server, ${member}`);
});

// Log our bot in using the token from https://discordapp.com/developers/applications/me
client.login('your token here');
<commit_msg>docs: using deprecated version of find<commit_after>/**
 * A bot that welcomes new guild members when they join
 */

// Import the discord.js module
const Discord = require('discord.js');

// Create an instance of a Discord client
const client = new Discord.Client();

/**
 * The ready event is vital, it means that only _after_ this will your bot start reacting to information
 * received from Discord
 */
client.on('ready', () => {
  console.log('I am ready!');
});

// Create an event listener for new guild members
client.on('guildMemberAdd', member => {
  // Send the message to a designated channel on a server:
  const channel = member.guild.channels.find(ch => ch.name === 'member-log');
  // Do nothing if the channel wasn't found on this server
  if (!channel) return;
  // Send the message, mentioning the member
  channel.send(`Welcome to the server, ${member}`);
});

// Log our bot in using the token from https://discordapp.com/developers/applications/me
client.login('your token here');
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp')

.directive("myHasError", function() {
    return {
	restrict: 'A',
	transclude: true,
	template: function(element, attrs) {
	    // cleanup element:
	    element.removeAttr('my-has-error');

	    var name = attrs.myHasError;
	    return "

";
        }
    };
})

.directive("myErrorMsgs", function() {
    return {
	restrict: 'A',
	transclude: true,
	template: function(element, attrs) {
	    // cleanup element:
	    element.removeAttr('my-error-msgs');

	    var name = attrs.myErrorMsgs;
	    var error_msgs = '
' +
		'

' +
		'
';
	    var error_msgs2 = '
' +
		'

' +
		'
';
	    return "

" + error_msgs + error_msgs2 + "
";
        }
    };
})

.directive("myBootstrapFormGroup", function() {
    return {
	restrict: 'A',
        transclude: true,
	template: function(element, attrs) {
	    var name = attrs.myBootstrapFormGroup;
	    // cleanup element:
	    element.removeAttr('my-bootstrap-form-group');
	    element.removeAttr('label');
	    element.removeAttr('multi');
	    element.addClass("form-group");
	    var mayHasErrorAttr = name && !attrs.multi ? "my-has-error='" + name + "'" : '';
	    var error_msgs = name && !attrs.multi ? "my-error-msgs='" + name + "'" : '';
	    var label = attrs.label ? '' + attrs.label + '' : '';
	    var subClass = (attrs.label ? '' : 'col-md-offset-3') + ' ' + (attrs.multi ? '' : 'col-md-9');
	    var sub = '

';
	    return "
" + label + sub + "
";
        }
    };
})

.directive("formControl", function() {
    return {
	restrict: 'A',
	require: 'ngModel', // controller to be passed into directive linking function
	link: function (scope, elem, attr, ctrl) {
	    elem.addClass("form-control");
	    elem.attr('id', attr.name);
        }
    };
});
<commit_msg>fix myBootstrapFormGroup for multi with no label (the col-xx-offset must be handled in first multi)<commit_after>'use strict';

angular.module('myApp')

.directive("myHasError", function() {
    return {
	restrict: 'A',
	transclude: true,
	template: function(element, attrs) {
	    // cleanup element:
	    element.removeAttr('my-has-error');

	    var name = attrs.myHasError;
	    return "

";
        }
    };
})

.directive("myErrorMsgs", function() {
    return {
	restrict: 'A',
	transclude: true,
	template: function(element, attrs) {
	    // cleanup element:
	    element.removeAttr('my-error-msgs');

	    var name = attrs.myErrorMsgs;
	    var error_msgs = '
' +
		'

' +
		'
';
	    var error_msgs2 = '
' +
		'

' +
		'
';
	    return "

" + error_msgs + error_msgs2 + "
";
        }
    };
})

.directive("myBootstrapFormGroup", function() {
    return {
	restrict: 'A',
        transclude: true,
	template: function(element, attrs) {
	    var name = attrs.myBootstrapFormGroup;
	    // cleanup element:
	    element.removeAttr('my-bootstrap-form-group');
	    element.removeAttr('label');
	    element.removeAttr('multi');
	    element.addClass("form-group");
	    var mayHasErrorAttr = name && !attrs.multi ? "my-has-error='" + name + "'" : '';
	    var error_msgs = name && !attrs.multi ? "my-error-msgs='" + name + "'" : '';
	    var label = attrs.label ? '' + attrs.label + '' : '';
	    var subClass = (attrs.label || attrs.multi ? '' : 'col-md-offset-3') + ' ' + (attrs.multi ? '' : 'col-md-9');
	    var sub = '

';
	    return "
" + label + sub + "
";
        }
    };
})

.directive("formControl", function() {
    return {
	restrict: 'A',
	require: 'ngModel', // controller to be passed into directive linking function
	link: function (scope, elem, attr, ctrl) {
	    elem.addClass("form-control");
	    elem.attr('id', attr.name);
        }
    };
});
<|endoftext|>