<commit_before>describe('instantiation', function () {

    it('should create a new Notify instance', function () {
        var notification = new Notify('foo');
        expect(notification instanceof window.Notify).toBeTruthy();
    });

    it('should throw an exception if has no title', function () {
        expect(function () {
            var notification = new Notify();
        }).toThrow();
    });
});

describe('permission', function () {

    it('should check if permission is needed', function () {
        expect(Notify.needsPermission()).toBeTruthy();
    });

    it('should request permission from the user', function () {
        spyOn(window.Notification, 'requestPermission');
        Notify.requestPermission();
        expect(window.Notification.requestPermission).toHaveBeenCalled();
    });
});

describe('callbacks', function () {

    var callback;

    beforeEach(function() {
        callback = jasmine.createSpy();
    });

    it('should fire show callback', function () {
        var notification = new Notify('foo', {
            notifyShow: callback
        });
        notification.onShowNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire close callback', function () {
        var notification = new Notify('foo', {
            notifyClose: callback
        });
        notification.show();
        notification.onCloseNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire click callback', function () {
        var notification = new Notify('foo', {
            notifyClick: callback
        });
        notification.onClickNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire error callback', function () {
        var notification = new Notify('foo', {
            notifyError: callback
        });
        notification.show();
        notification.onErrorNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire permission granted callback', function () {
        Notify.requestPermission(callback, null);
        expect(callback).toHaveBeenCalled();
    });

    it('should fire permission denied callback', function () {
        Notify.requestPermission(null, callback);
        expect(callback).toHaveBeenCalled();
    });

    it('should destroy a notification once closed', function () {
        var notification = new Notify('foo', {
            notifyClose: callback
        });
        spyOn(notification, 'destroy');
        notification.onCloseNotification();
        expect(notification.destroy).toHaveBeenCalled();

    });
});

<commit_msg>Remove tests for PermissionGrantedCallback and PermissionDeniedCallback for now.<commit_after>describe('instantiation', function () {

    it('should create a new Notify instance', function () {
        var notification = new Notify('foo');
        expect(notification instanceof window.Notify).toBeTruthy();
    });

    it('should throw an exception if has no title', function () {
        expect(function () {
            var notification = new Notify();
        }).toThrow();
    });
});

describe('permission', function () {

    it('should check if permission is needed', function () {
        expect(Notify.needsPermission()).toBeTruthy();
    });

    it('should request permission from the user', function () {
        spyOn(window.Notification, 'requestPermission');
        Notify.requestPermission();
        expect(window.Notification.requestPermission).toHaveBeenCalled();
    });
});

describe('callbacks', function () {

    var callback;

    beforeEach(function() {
        callback = jasmine.createSpy();
    });

    it('should fire show callback', function () {
        var notification = new Notify('foo', {
            notifyShow: callback
        });
        notification.onShowNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire close callback', function () {
        var notification = new Notify('foo', {
            notifyClose: callback
        });
        notification.show();
        notification.onCloseNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire click callback', function () {
        var notification = new Notify('foo', {
            notifyClick: callback
        });
        notification.onClickNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should fire error callback', function () {
        var notification = new Notify('foo', {
            notifyError: callback
        });
        notification.show();
        notification.onErrorNotification();
        expect(callback).toHaveBeenCalled();
    });

    it('should destroy a notification once closed', function () {
        var notification = new Notify('foo', {
            notifyClose: callback
        });
        spyOn(notification, 'destroy');
        notification.onCloseNotification();
        expect(notification.destroy).toHaveBeenCalled();

    });
});

<|endoftext|>


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

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Tf from '../_Tf';

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';

import Util from '../_vendors/Util';
import TableCalculation from '../_vendors/TableCalculation';

class Tfoot extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    handleClick = e => {
        const {data, disabled, onFootClick} = this.props;
        !disabled && onFootClick && onFootClick(data, e);
    };

    render() {

        const {
                className, columns, data, disabled, baseColIndex,
                onCellClick
            } = this.props,
            columnsWithSpan = TableCalculation.getColumnsWithSpan(TableFragment.FOOT, columns);

        return (

                    {
                        columnsWithSpan && columnsWithSpan.map(({column, span}, colIndex) =>
                            <Tf key={colIndex}
                                className={column.footClassName}
                                style={column.footStyle}
                                colIndex={baseColIndex + colIndex}
                                data={data}
                                renderer={column.footRenderer}
                                align={column.footAlign}
                                span={span}
                                disabled={disabled}
                                onCellClick={onCellClick}/>
                        )
                    }

        );

    }
}

Tfoot.propTypes = {

    className: PropTypes.string,

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

        /**
         * width of column
         */
        width: PropTypes.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

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

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

        /**
         * The render content in header.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        headRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

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

        /**
         * column span of table header
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

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

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

        /**
         * The render content in table.
         * (1) data key，example： 'id'
         * (2) data key tamplate，example：'${id} - ${name}'
         * (3) callback，example：function (rowData, rowIndex, colIndex) {return rowData.id;}
         */
        bodyRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

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

        /**
         * column span of table body
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

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

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

        /**
         * The render content in footer.
         * (1) string，example： 'id'
         * (2) callback，example：function (colIndex) {return colIndex;}
         */
        footRenderer: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

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

        /**
         * column span of table foot
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

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

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

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

    })).isRequired,

    data: PropTypes.array,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,

    onFootClick: PropTypes.func,
    onCellClick: PropTypes.func

};

Tfoot.defaultProps = {
    disabled: false,
    baseColIndex: 0
};

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

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import Tf from '../_Tf';

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';

import Util from '../_vendors/Util';
import TableCalculation from '../_vendors/TableCalculation';

class Tfoot extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    handleClick = e => {
        const {data, disabled, onFootClick} = this.props;
        !disabled && onFootClick && onFootClick(data, e);
    };

    render() {

        const {className, columns, data, disabled, baseColIndex, onCellClick} = this.props,
            columnsWithSpan = TableCalculation.getColumnsWithSpan(TableFragment.FOOT, columns);

        return (

                    {
                        columnsWithSpan && columnsWithSpan.map(({column, span}, colIndex) =>
                            <Tf key={colIndex}
                                className={column.footClassName}
                                style={column.footStyle}
                                colIndex={baseColIndex + colIndex}
                                data={data}
                                renderer={column.footRenderer}
                                align={column.footAlign || column.align}
                                span={span}
                                disabled={disabled}
                                onCellClick={onCellClick}/>
                        )
                    }

        );

    }
}

Tfoot.propTypes = {

    className: PropTypes.string,

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

        /**
         * fixed position of column ( true / 'left' / 'right' )
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column
         */
        width: PropTypes.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

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

        /**
         * 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,

        /**
         * column span of table header
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, 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) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, 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,

        /**
         * column span of table foot
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

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

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

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

    })).isRequired,

    data: PropTypes.array,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,

    onFootClick: PropTypes.func,
    onCellClick: PropTypes.func

};

Tfoot.defaultProps = {
    disabled: false,
    baseColIndex: 0
};

export default Tfoot;
<|endoftext|>


<commit_before>/* global describe, it */

import 'should';
import SystemFonts from '../src/main';
import _ from 'lodash';
import path from 'path';

const customFontFolder = path.join('test', 'test-folder');

describe('SystemFonts', () => {

    it('should be a Function', () => {
        SystemFonts.should.be.a.Function();
    });

    describe('getFontsExtended method', () => {

        const systemFonts = new SystemFonts();

        it('should return a Promise', () => {
            systemFonts.getFontsExtended().should.be.a.Promise();
        });

        describe('the Promise', () => {

            it('should be fulfilled with an array of objects', done => {
                systemFonts.getFontsExtended().then(
                    res => {
                        const isArray = Array.isArray(res);
                        if (isArray && res.length > 0) {
                            const containsObjects = res.reduce((bool, d) => {
                                if (!_.isPlainObject(d)) return false;
                                return bool;
                            }, true);
                            if (containsObjects) {
                                done();
                            }
                        }
                    },
                    err => console.error(err)
                );
            });

        });

    });

    describe('getFontsExtendedSync method', () => {

        const systemFonts = new SystemFonts();

        it('should return an array of objects', () => {
            const fontList = systemFonts.getFontsExtendedSync();
            const isArray = Array.isArray(fontList);
            if (isArray && fontList.length > 0) {
                const containsObjects = fontList.reduce((bool, d) => {
                    if (!_.isPlainObject(d)) return false;
                    return bool;
                }, true);
                containsObjects.should.be.True();
            } else {
                throw new Error('Did not find font files!');
            }
        });

    });

    describe('getFonts method', () => {

        const systemFonts = new SystemFonts();

        it('should return a Promise', () => {
            systemFonts.getFonts().should.be.a.Promise();
        });

        describe('the Promise', () => {

            it('should be fulfilled with an array of strings', done => {
                systemFonts.getFonts().then(
                    res => {
                        const isArray = Array.isArray(res);
                        if (isArray && res.length > 0) {
                            const containsStrings = res.reduce((bool, d) => {
                                if (typeof d !== 'string') return false;
                                return bool;
                            }, true);
                            if (containsStrings) {
                                done();
                            }
                        }
                    },
                    err => console.error(err)
                );
            });

        });

    });

    describe('getFontsSync method', () => {

        const systemFonts = new SystemFonts();

        it('should return an array of strings', () => {
            const fontList = systemFonts.getFontsSync();
            const isArray = Array.isArray(fontList);
            let containsStrings;
            if (isArray && fontList.length > 0) {
                containsStrings = fontList.reduce((bool, d) => {
                    if (typeof d !== 'string') return false;
                    return bool;
                }, true);
            }
            containsStrings.should.be.True();
        });

    });

    describe('synchronous methods', () => {

        describe('if ignoreSystemFonts set to false', () => {
            it('system fonts should be included', () => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: false,
                    customDirs: [customFontFolder]
                }); {
                    const fontList = systemFonts.getFontsSync();
                    fontList.length.should.be.greaterThan(1);
                } {
                    const fontList = systemFonts.getFontsExtendedSync();
                    fontList.length.should.be.greaterThan(1);
                }
            });
        });

        describe('if ignoreSystemFonts set to true', () => {
            it('only fonts from custom fonts folders should be included', () => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: true,
                    customDirs: [customFontFolder]
                }); {
                    const fontList = systemFonts.getFontsSync();
                    fontList.length.should.equal(1);
                } {
                    const fontList = systemFonts.getFontsExtendedSync();
                    fontList.length.should.equal(1);
                }
            });
        });

    });

    describe('asynchronous methods', () => {

        describe('if ignoreSystemFonts set to false', () => {
            it('system fonts should be included', done => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: false,
                    customDirs: [customFontFolder]
                });
                Promise
                    .all([
                        systemFonts.getFonts(),
                        systemFonts.getFontsExtended()
                    ])
                    .then(([res0, res1]) => {
                        if (res0.length > 1 && res1.length > 1) {
                            done();
                        } else {
                            done(new Error(`Resolved with a quantities of ${res0.length} and ${res1.length}`));
                        }
                    })
                    .catch(err => done(err));
            });
        });

        describe('if ignoreSystemFonts set to true', () => {
            it('only fonts from custom fonts folders should be included', done => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: true,
                    customDirs: [customFontFolder]
                });
                Promise
                    .all([
                        systemFonts.getFonts(),
                        systemFonts.getFontsExtended()
                    ])
                    .then(([res0, res1]) => {
                        if (res0.length === 1 && res1.length === 1) {
                            done();
                        } else {
                            done(new Error(`Resolved with a quantities of ${res0.length} and ${res1.length}`));
                        }
                    })
                    .catch(err => done(err));
            });
        });

    });

});<commit_msg>Updated tests<commit_after>/* global describe, it */

import 'should';
import SystemFonts from '../src/main';
import _ from 'lodash';
import path from 'path';

const customFontFolder = path.join('test', 'test-folder');

describe('SystemFonts', () => {

    it('should be a Function', () => {
        SystemFonts.should.be.a.Function();
    });

    describe('getFontsExtended method', () => {

        const systemFonts = new SystemFonts();

        it('should return a Promise', () => {
            systemFonts.getFontsExtended().should.be.a.Promise();
        });

        describe('the Promise', () => {

            it('should be fulfilled with an array of objects', done => {
                systemFonts.getFontsExtended().then(
                    res => {
                        const isArray = Array.isArray(res);
                        if (isArray && res.length > 0) {
                            const containsObjects = res.reduce((bool, d) => {
                                if (!_.isPlainObject(d)) return false;
                                return bool;
                            }, true);
                            if (containsObjects) {
                                done();
                            }
                        }
                    },
                    err => console.error(err)
                );
            });

        });

    });

    describe('getFontsExtendedSync method', () => {

        const systemFonts = new SystemFonts();

        it('should return an array of objects', () => {
            const fontList = systemFonts.getFontsExtendedSync();
            const isArray = Array.isArray(fontList);
            if (isArray && fontList.length > 0) {
                const containsObjects = fontList.reduce((bool, d) => {
                    if (!_.isPlainObject(d)) return false;
                    return bool;
                }, true);
                containsObjects.should.be.True();
            } else {
                throw new Error('Did not find font files!');
            }
        });

    });

    describe('getFonts method', () => {

        const systemFonts = new SystemFonts();

        it('should return a Promise', () => {
            systemFonts.getFonts().should.be.a.Promise();
        });

        describe('the Promise', () => {

            it('should be fulfilled with an array of strings', done => {
                systemFonts.getFonts().then(
                    res => {
                        const isArray = Array.isArray(res);
                        if (isArray && res.length > 0) {
                            const containsStrings = res.reduce((bool, d) => {
                                if (typeof d !== 'string') return false;
                                return bool;
                            }, true);
                            if (containsStrings) {
                                done();
                            }
                        }
                    },
                    err => console.error(err)
                );
            });

        });

    });

    describe('getFontsSync method', () => {

        const systemFonts = new SystemFonts();

        it('should return an array of strings', () => {
            const fontList = systemFonts.getFontsSync();
            const isArray = Array.isArray(fontList);
            let containsStrings;
            if (isArray && fontList.length > 0) {
                containsStrings = fontList.reduce((bool, d) => {
                    if (typeof d !== 'string') return false;
                    return bool;
                }, true);
            }
            containsStrings.should.be.True();
        });

    });

    describe('synchronous methods', () => {

        describe('if ignoreSystemFonts set to false', () => {
            it('system fonts should be included', () => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: false,
                    customDirs: [customFontFolder]
                }); {
                    const fontList = systemFonts.getFontsSync();
                    fontList.length.should.be.greaterThan(1);
                } {
                    const fontList = systemFonts.getFontsExtendedSync();
                    fontList.length.should.be.greaterThan(1);
                }
            });
        });

        describe('if ignoreSystemFonts set to true', () => {
            it('only fonts from custom fonts folders should be included', () => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: true,
                    customDirs: [customFontFolder]
                }); {
                    const fontList = systemFonts.getFontsSync();
                    fontList.length.should.equal(1);
                } {
                    const fontList = systemFonts.getFontsExtendedSync();
                    fontList.length.should.equal(1);
                }
            });
        });

    });

    describe('asynchronous methods', () => {

        describe('if ignoreSystemFonts set to false', () => {
            it('system fonts should be included', done => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: false,
                    customDirs: [customFontFolder]
                });
                Promise
                    .all([
                        systemFonts.getFonts(),
                        systemFonts.getFontsExtended()
                    ])
                    .then(([res0, res1]) => {
                        if (res0.length > 1 && res1.length > 1) {
                            done();
                        } else {
                            done(new Error(`Resolved with a quantities of ${res0.length} and ${res1.length}`));
                        }
                    })
                    .catch(err => done(err));
            });
        });

        describe('if ignoreSystemFonts set to true', () => {
            it('only fonts from custom fonts folders should be included', done => {
                const systemFonts = new SystemFonts({
                    ignoreSystemFonts: true,
                    customDirs: [customFontFolder]
                });
                Promise
                    .all([
                        systemFonts.getFonts(),
                        systemFonts.getFontsExtended()
                    ])
                    .then(([res0, res1]) => {
                        if (res0.length === 1 && res1.length === 1) {
                            done();
                        } else {
                            done(new Error(`Resolved with a quantities of ${res0.length} and ${res1.length}`));
                        }
                    })
                    .catch(err => done(err));
            });
        });

    });

    describe('getFontFilesSync method', () => {
        it('should return all TTF and OTF font files', () => {
            const systemFonts = new SystemFonts();
            const files = systemFonts.getFontFilesSync();
            files.length.should.be.greaterThan(0);
            files.should.be.an.Array();
            files.every(f => typeof f === 'string').should.be.True();
        });
    });

    describe('getAllFontFilesSync method', () => {
        it('should return all TTF, OTF, TTC, and DFONT files', () => {
            const systemFonts = new SystemFonts();
            const files = systemFonts.getAllFontFilesSync();
            files.length.should.be.greaterThan(0);
            files.should.be.an.Array();
            files.every(f => typeof f === 'string').should.be.True();
        });
    });

});<|endoftext|>


<commit_before>var assert = require("assert");
var ThaliAclDb = require('../.');

//Initialize the ACL db
var   db = new ThaliAclDb('acl', { db: require('memdown') });

describe ("Initialize ACL", function(){
    it("Create Thali ACL db", function(done){
        var   db = new ThaliAclDb('acl', { db: require('memdown') });
        done();
    });
});

describe("Add roles", function(){
  it("Add admin role", function(done) {
      db.addRole('admin')
          .then(function () {
              assert(true);
              done();
          })
          .catch(function () {
              assert(false);
              done();
          });
  });
  it("Add guest role", function(done){
  db.addRole('guest')
      .then(function() {
          assert(true);
          done();
      })
      .catch(function () {
          assert(false);
          done();
      });
  });
});

describe("Remove roles", function(){
    it("Remove admin role", function(done) {
        db.removeRole('admin')
            .then(function () {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });
    it("Remove guest role", function(done){
        db.removeRole('guest')
            .then(function() {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });

    //TODO: Should this test fail, since there is no more guest role?
    it("Remove guest role", function(done){
        db.removeRole('guest')
            .then(function() {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });
});
<commit_msg>Added more mocha tests<commit_after>var assert = require("assert");
var ThaliAclDb = require('../.');

//Initialize the ACL db
var   db = new ThaliAclDb('acl', { db: require('memdown') });

describe ("Initialize ACL", function(){
    it("Create Thali ACL db", function(done){
        var   db = new ThaliAclDb('acl', { db: require('memdown') });
        done();
    });
});

describe("Add roles", function(){
    it("Add admin role", function(done) {
      db.addRole('admin')
          .then(function () {
              assert(true);
              done();
          })
          .catch(function () {
              assert(false);
              done();
          });
    });
    it("Add guest role", function(done){
    db.addRole('guest')
      .then(function() {
          assert(true);
          done();
      })
      .catch(function () {
          assert(false);
          done();
      });
    });
});

describe("Remove roles", function(){
    it("Remove admin role", function(done) {
        db.removeRole('admin')
            .then(function () {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });

    it("Remove guest role", function(done){
        db.removeRole('guest')
            .then(function() {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });
});

describe("Remove non-existing/invalid roles", function(){
    it("Remove manager role should fail", function(done) {
        db.removeRole('manager')
            .then(function () {
                assert(false)
                done();
             })
            .catch(function (err) {
                done(err);
            });
    });

    //TODO: Are we allowed to remove same roles multiple times?
    it("Remove guest role (which is already removed) should fail", function(done){
        db.removeRole('guest')
            .then(function() {
                console.log("guest role removed");
                assert(false);
                done();
            })
            .catch(function (err) {
                done(err);
            });
        done();
    });
});

describe("Add user to roles", function(){
    it("Add user thali to admin role", function(done) {
        db.addRole('admin')
            .then(function () {
                return db.addUserToRole("thali","admin");
            })
            .then(function () {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });
    it("Add user sam to guest role", function(done){
        db.addRole('guest')
            .then(function() {
                return db.addUserToRole("sam","guest");
            })
            .then(function () {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });
});

describe("Add user to invalid role", function(){
    it("User sally should not add to manager(non-existing) role", function(done) {
        db.addRole('admin')
            .then(function () {
                return db.addUserToRole("sally","manager");
            })
            .then(function () {
                assert(false);
                done();
            })
            .catch(function (err) {
                done(err);
            });
    });
});

describe("Remove user from role", function() {
    it("Remove user thali from admin role", function (done) {
        db.addRole('admin')
            .then(function () {
                return db.addUserToRole("thali", "admin");
            })
            .then(function () {
                return db.removeUserFromRole("thali","admin");
            })
            .then(function () {
                assert(true);
                done();
            })
            .catch(function () {
                assert(false);
                done();
            });
    });

    it("Remove invalid user(James) from admin role should fail", function (done) {
        db.addRole('admin')
            .then(function () {
                return db.removeUserFromRole("James","admin");
            })
            .then(function () {
                assert(false);
                done();
            })
            .catch(function (err) {
                done(err);
            });
    });
});

describe("Get role by user", function() {
    it("Role of user thali should be 'admin'", function (done) {
        db.addRole('admin')
            .then(function () {
                return db.addUserToRole("thali", "admin");
            })
            .then(function () {
                return db.getRolesByUser("thali");
            })
            .then(function (roles) {
                assert.equal(roles,'admin');
                done();
            })
            .catch(function (err) {
                done(err);
            });
    });
    //TODO: Review please
    it("Role of user sam shouldn't be be 'admin'", function (done) {
        db.addRole('guest')
            .then(function () {
                return db.addUserToRole("sam", "guest");
            })
            .then(function () {
                return db.getRolesByUser("sam");
            })
            .then(function (roles) {
                if(roles !== 'admin') {
                    assert(true);
                }
                else{
                    assert(false);
                }
                done();
            })
            .catch(function (err) {
                done(err);
            });
    });
});

describe("Get users by role", function() {
    it("Admin role should have one user - thali", function (done) {
        db.addRole('admin')
            .then(function () {
                return db.addUserToRole("thali", "admin");
            })
            .then(function () {
                return db.getUsersByRole("admin");
            })
            .then(function (users) {
                assert.equal(users,'thali');
                done();
            })
            .catch(function (err) {
                done(err);
            });
    });

});

<|endoftext|>


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

  describe('numberFormat', function() {
    describe('formatMoney', function() {
      it('should return a string', function() {
        expect(numberFormat.formatMoney(1)).to.be.a('string');
      });

      it('should default to 2 decimal places', function() {
        expect(numberFormat.formatMoney(1.123).substr(3).length).to.equal(2);
      });

      it('should round result if 0 passed for decimal_places', function() {
        var rounded_up = numberFormat.formatMoney(1.5, 0);
        var rounded_down = numberFormat.formatMoney(1.49, 0);

        expect(rounded_up).to.equal('$2');
        expect(rounded_down).to.equal('$1');
      });

      it('should default to "$" currency symbol', function() {
        expect(numberFormat.formatMoney(1)[0]).to.equal('$');
      });

      it('should default to "," thousands separator', function() {
        expect(numberFormat.formatMoney(1000)[2]).to.equal(',');
      });

      it('should default to "." decimal separator', function() {
        expect(numberFormat.formatMoney(1)[2]).to.equal('.');
      });

      it('should group numbers by thousands', function() {
        var formatted = numberFormat.formatMoney(1000000000);

        expect(formatted[2]).to.equal(',');
        expect(formatted[6]).to.equal(',');
        expect(formatted[10]).to.equal(',');
        expect(formatted.match(/,/g).length).to.equal(3);
      });

      it('should proccess alternate currency formats', function() {
        var costa_rico = numberFormat.formatMoney(1000000, undefined, '₡', '.', ',');
        var ukraine = numberFormat.formatMoney(1000000, undefined, '₴', ' ', ',');
        var switzerland = numberFormat.formatMoney(1000000, undefined, 'Fr. ', "'", '.');

        expect(costa_rico).to.equal('₡1.000.000,00');
        expect(ukraine).to.equal('₴1 000 000,00');
        expect(switzerland).to.equal("Fr. 1'000'000.00");
      });
    });

    describe('unformatMoney', function() {
      it('should return a number', function() {
        expect(numberFormat.unformatMoney('1')).to.be.a('number');
      });

      it('should return the numeric representation of a string', function() {
        expect(numberFormat.unformatMoney('1')).to.equal(1);
        expect(numberFormat.unformatMoney('100 goats')).to.equal(100);
        expect(numberFormat.unformatMoney('1,000,000')).to.equal(1000000);
        expect(numberFormat.unformatMoney('-1,000.985')).to.equal(-1000.985);
        expect(numberFormat.unformatMoney('$1,000,000.00')).to.equal(1000000);
        expect(numberFormat.unformatMoney('-$2,000.15: OVERDRAWN')).to.equal(-2000.15);
      });

      it('should only use leading minus or hyphen-minus to determine negativity', function() {
        expect(numberFormat.unformatMoney('−1'), 'leading minus')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('  −1'), 'leading minus + spaces')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('1−'), 'trailing minus')
          .to.equal(1);
        expect(numberFormat.unformatMoney('10−1'), 'inner minus')
          .to.equal(101);
        expect(numberFormat.unformatMoney('-1'), 'leading hyphen-minus')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('  -1'), 'leading hyphen-minus + spaces')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('1-'), 'trailing hyphen-minus')
          .to.equal(1);
        expect(numberFormat.unformatMoney('10-1'), 'inner hyphen-minus')
          .to.equal(101);
      });

      it('should remove non-numeric characters except decimal, while respecting leading minus as negative indicator', function() {
        var unformat = numberFormat.unformatMoney;

        expect(unformat('1!2@3#4$5%6a7`89₴01'), 'string includes non-numbers')
          .to.equal(12345678901);
        expect(unformat('1!2@3#4$5%6a7`.89₴01'), 'non-numbers and a decimal')
          .to.equal(1234567.8901);
        expect(unformat('-1!2@3#4$5%6a7`89₴01'), 'non-numbers and a leading minus')
          .to.equal(-12345678901);
        expect(unformat('-1!2@3#4$5%6a7`.89₴01'), 'non-numbers, decimal, and leading minus')
          .to.equal(-1234567.8901);
        expect(unformat('1!2@3#4$5%6a7`8-9₴01'), 'non-numbers plus internal minus')
          .to.equal(12345678901);
        expect(unformat('1!2@3#4$5%6a7`.8-9₴01'), 'non-numbers, decimal, and internal minus')
          .to.equal(1234567.8901);
        expect(unformat('-1!2@3#4$5%6a7`8-9₴01'), 'non-numbers, leading minus, and internal minus')
          .to.equal(-12345678901);
        expect(unformat('-1!2@3#4$5%6a7`.8-9₴01'), 'non-numbers, decimal, leading minus, and internal minus')
          .to.equal(-1234567.8901);
      });

      it('should remove any passed currency_symbol option before processing', function() {
        expect(numberFormat.unformatMoney("Fr. 1'000'000.00", {
          currency_symbol: 'Fr. '
        })).to.equal(1000000);
      });

      it('should respect alternate thousands_separator option when passed', function() {
        expect(numberFormat.unformatMoney('₡1.000.000', {
          thousands_separator: '.'
        })).to.equal(1000000);
      });

      it('should respect alternate decimal_separator option when passed', function() {
        expect(numberFormat.unformatMoney('₴1 000 000,99', {
          decimal_separator: ','
        })).to.equal(1000000.99);
      });
    });
  });
})(chai.expect);<commit_msg>Failing tests for the refactor of formatMoney to take an options hash as second argument.<commit_after>(function(expect) {
  'use strict';

  describe('numberFormat', function() {
    describe('formatMoney', function() {
      it('should return a string', function() {
        expect(numberFormat.formatMoney(1)).to.be.a('string');
      });

      it('should default to 2 decimal places', function() {
        expect(numberFormat.formatMoney(1.123).substr(3).length).to.equal(2);
      });

      it('should round result if 0 passed for decimal_places option', function() {
        var rounded_up = numberFormat.formatMoney(1.5, { decimal_places: 0 });
        var rounded_down = numberFormat.formatMoney(1.49, { decimal_places: 0 });

        expect(rounded_up).to.equal('$2');
        expect(rounded_down).to.equal('$1');
      });

      it('should default to "$" currency symbol', function() {
        expect(numberFormat.formatMoney(1)[0]).to.equal('$');
      });

      it('should default to "," thousands separator', function() {
        expect(numberFormat.formatMoney(1000)[2]).to.equal(',');
      });

      it('should default to "." decimal separator', function() {
        expect(numberFormat.formatMoney(1)[2]).to.equal('.');
      });

      it('should group numbers by thousands', function() {
        var formatted = numberFormat.formatMoney(1000000000);

        expect(formatted[2]).to.equal(',');
        expect(formatted[6]).to.equal(',');
        expect(formatted[10]).to.equal(',');
        expect(formatted.match(/,/g).length).to.equal(3);
      });

      it('should proccess alternate currency formats', function() {
        var costa_rico = numberFormat.formatMoney(1000000, {
          currency_symbol: '₡',
          thousands_separator: '.',
          decimal_separator: ','
        });
        var ukraine = numberFormat.formatMoney(1000000, {
          currency_symbol: '₴',
          thousands_separator: ' ',
          decimal_separator: ','
        });
        var switzerland = numberFormat.formatMoney(1000000, {
          currency_symbol: 'Fr. ',
          thousands_separator: "'"
        });

        expect(costa_rico).to.equal('₡1.000.000,00');
        expect(ukraine).to.equal('₴1 000 000,00');
        expect(switzerland).to.equal("Fr. 1'000'000.00");
      });
    });

    describe('unformatMoney', function() {
      it('should return a number', function() {
        expect(numberFormat.unformatMoney('1')).to.be.a('number');
      });

      it('should return the numeric representation of a string', function() {
        expect(numberFormat.unformatMoney('1')).to.equal(1);
        expect(numberFormat.unformatMoney('100 goats')).to.equal(100);
        expect(numberFormat.unformatMoney('1,000,000')).to.equal(1000000);
        expect(numberFormat.unformatMoney('-1,000.985')).to.equal(-1000.985);
        expect(numberFormat.unformatMoney('$1,000,000.00')).to.equal(1000000);
        expect(numberFormat.unformatMoney('-$2,000.15: OVERDRAWN')).to.equal(-2000.15);
      });

      it('should only use leading minus or hyphen-minus to determine negativity', function() {
        expect(numberFormat.unformatMoney('−1'), 'leading minus')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('  −1'), 'leading minus + spaces')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('1−'), 'trailing minus')
          .to.equal(1);
        expect(numberFormat.unformatMoney('10−1'), 'inner minus')
          .to.equal(101);
        expect(numberFormat.unformatMoney('-1'), 'leading hyphen-minus')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('  -1'), 'leading hyphen-minus + spaces')
          .to.equal(-1);
        expect(numberFormat.unformatMoney('1-'), 'trailing hyphen-minus')
          .to.equal(1);
        expect(numberFormat.unformatMoney('10-1'), 'inner hyphen-minus')
          .to.equal(101);
      });

      it('should remove non-numeric characters except decimal, while respecting leading minus as negative indicator', function() {
        var unformat = numberFormat.unformatMoney;

        expect(unformat('1!2@3#4$5%6a7`89₴01'), 'string includes non-numbers')
          .to.equal(12345678901);
        expect(unformat('1!2@3#4$5%6a7`.89₴01'), 'non-numbers and a decimal')
          .to.equal(1234567.8901);
        expect(unformat('-1!2@3#4$5%6a7`89₴01'), 'non-numbers and a leading minus')
          .to.equal(-12345678901);
        expect(unformat('-1!2@3#4$5%6a7`.89₴01'), 'non-numbers, decimal, and leading minus')
          .to.equal(-1234567.8901);
        expect(unformat('1!2@3#4$5%6a7`8-9₴01'), 'non-numbers plus internal minus')
          .to.equal(12345678901);
        expect(unformat('1!2@3#4$5%6a7`.8-9₴01'), 'non-numbers, decimal, and internal minus')
          .to.equal(1234567.8901);
        expect(unformat('-1!2@3#4$5%6a7`8-9₴01'), 'non-numbers, leading minus, and internal minus')
          .to.equal(-12345678901);
        expect(unformat('-1!2@3#4$5%6a7`.8-9₴01'), 'non-numbers, decimal, leading minus, and internal minus')
          .to.equal(-1234567.8901);
      });

      it('should remove any passed currency_symbol option before processing', function() {
        expect(numberFormat.unformatMoney("Fr. 1'000'000.00", {
          currency_symbol: 'Fr. '
        })).to.equal(1000000);
      });

      it('should respect alternate thousands_separator option when passed', function() {
        expect(numberFormat.unformatMoney('₡1.000.000', {
          thousands_separator: '.'
        })).to.equal(1000000);
      });

      it('should respect alternate decimal_separator option when passed', function() {
        expect(numberFormat.unformatMoney('₴1 000 000,99', {
          decimal_separator: ','
        })).to.equal(1000000.99);
      });
    });
  });
})(chai.expect);<|endoftext|>


<commit_before>import * as I from '../dist/infestines.cjs'
import * as R from 'ramda'

function show(x) {
  switch (typeof x) {
    case 'string':
    case 'object':
      return JSON.stringify(x)
    default:
      return `${x}`
  }
}

const showExpr = expr => (R.is(Function, expr) ? expr.toString() : expr)
const runExpr = expr =>
  R.is(Function, expr) ? expr() : eval(`() => ${expr}`)()

const testEq = (expr, expect) =>
  it(`${showExpr(expr)} => ${show(expect)}`, () => {
    const actual = runExpr(expr)
    if (!I.acyclicEqualsU(actual, expect))
      throw new Error(`Expected: ${show(expect)}, actual: ${show(actual)}`)
  })

const expectFail = expr =>
  it(`${expr} => failure`, () => {
    try {
      const actual = eval(`() => ${expr}`)()
      throw new Error(`Expected: failure, actual: ${show(actual)}`)
    } catch (_e) {
      return
    }
  })

function forAll(fn, x, n, cb) {
  function rec(n, x) {
    if (0 === n) cb(x)
    for (let i = 0; i < n; ++i) rec(i, fn(i, n, x))
  }
  rec(n, x)
}

function forAllFns(n, cb) {
  const args = R.map(i => `x${i}`, R.range(0, n))
  forAll((i, m, body) => `(${args.slice(i, m)}) => ${body}`, `[${args}]`, n, cb)
}

function forAllApplys(fn, n, cb) {
  const vals = R.range(0, n)
  forAll((i, m, lhs) => `${lhs}(${vals.slice(n - m, n - i)})`, `(${fn})`, n, cb)
}

describe('currying', () => {
  for (let n = 2; n <= 4; ++n) {
    forAllFns(n, fn =>
      forAllApplys(`I.curryN(${n}, ${fn})`, n, expr => {
        testEq(expr, R.range(0, n))
      })
    )
  }

  testEq(`I.curry(x => x+1)(1)`, 2)
  testEq(`I.curry((x,y) => x+y)(1)(2)`, 3)
  testEq(`I.curry((x,y,z) => x+y+z)(1)(2,3)`, 6)
  testEq(`I.curry((a, b, c, d) => a+b+c+d).length`, 4)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1).length`, 3)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1,2).length`, 2)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1)(2, 3).length`, 1)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1,2,3,4)`, 10)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1,2,3)(4)`, 10)
  testEq(`I.curry((a, b, c, d) => a+b+c+d)(1)(2,3,4)`, 10)

  expectFail(`I.curry(() => {})`)
  expectFail(`I.curry((a,b,c,d,e) => {})`)
})

describe('curry', () => {
  testEq(
    () => {
      // eslint-disable-next-line prefer-arrow-callback
      const foobar = I.curry(function foobar(x, y) {
        return x + y
      })
      return [foobar.name, foobar(1).name]
    },
    ['foobar', 'foobar']
  )
})

describe('arity', () => {
  testEq(`I.arityN(0, x => 101)()`, 101)
  testEq(`I.arityN(1, (x, y) => 42)()`, 42)
})

describe('id', () => {
  testEq(`I.id.length`, 1)
  testEq(`I.id("anything")`, 'anything')
})

describe('pipe and compose', () => {
  testEq('I.pipe2U(R.inc, R.negate)(1)', -2)
  testEq('I.compose2U(R.inc, R.negate)(1)', 0)
  testEq('I.pipe2U((a, b) => a + b, x => x + 1)(1,2)', 4)
  testEq('I.pipe2U((a, b) => a + b, x => x + 1).length', 2)
  testEq('I.compose2U(x => x + 1, (a, b) => a + b)(1,2)', 4)
  testEq('I.compose2U(x => x + 1, (a, b) => a + b).length', 2)
})

describe('seq', () => {
  testEq('I.seq(11)', 11)
  testEq('I.seq(11, x => x + 1)', 12)
})

describe('seqPartial', () => {
  testEq('I.seqPartial(11)', 11)
  testEq('I.seqPartial(11, x => x+2)', 13)
  testEq('I.seqPartial(11, _ => undefined, x => x.wouldFail)', undefined)
})

describe('array0', () => {
  testEq('I.array0', [])
})

describe('object0', () => {
  testEq('I.object0', {})
})

describe('isObject', () => {
  testEq('I.isObject(null)', false)
  testEq('I.isObject({})', true)
  testEq('I.isObject([])', false)
  testEq('I.isObject({constructor: "haha"})', true)
  testEq('I.isObject({constructor: Array})', true)
})

describe('isArray', () => {
  testEq('I.isArray(null)', false)
  testEq('I.isArray({})', false)
  testEq('I.isArray([])', true)
  testEq('I.isArray({constructor: Array})', false)
})

describe('isNumber', () => {
  testEq('I.isNumber(null)', false)
  testEq('I.isNumber({})', false)
  testEq('I.isNumber(101)', true)
})

describe('isString', () => {
  testEq('I.isString(null)', false)
  testEq('I.isString({})', false)
  testEq('I.isString("42")', true)
})

export class Foo {
  constructor(v) {
    this.v = v
  }
  equals(other) {
    return this.v === other.v
  }
}

describe('identicalU', () => {
  testEq('I.identicalU(null, null)', true)
  testEq('I.identicalU(-0, +0)', false)
  testEq('I.identicalU(NaN, NaN)', true)
  testEq('I.identicalU({}, {})', false)
})

describe('acyclicEqualsU', () => {
  testEq('I.acyclicEqualsU(null, {})', false)
  testEq('I.acyclicEqualsU({a:1}, {a:1, b:2})', false)
  testEq('I.acyclicEqualsU([1,2], [1])', false)
  testEq('I.acyclicEqualsU([1,2], [1,3])', false)
  testEq('I.acyclicEqualsU({a: 1, b: [true]}, {b: [true], a: 1})', true)
  testEq('I.acyclicEqualsU({a: 1, b: [true]}, {b: [true]})', false)
  testEq('I.acyclicEqualsU([], {})', false)
  testEq('I.acyclicEqualsU(new Foo(1), new Foo(1))', true)
  testEq('I.acyclicEqualsU(new Foo(2), new Foo(1))', false)
})

function XYZ(x, y, z) {
  this.x = x
  this.y = y
  this.z = z
}
XYZ.prototype.sum = function() {
  return this.x + this.y + this.z
}

describe('keys', () => {
  testEq('I.keys({})', [])
  testEq('I.keys({x: 1, y: 2})', ['x', 'y'])
  testEq('I.keys(new XYZ(3,1,4))', ['x', 'y', 'z'])
})

describe('values', () => {
  testEq('I.values({})', [])
  testEq('I.values({x: 1, y: 2})', [1, 2])
  testEq('I.values(new XYZ(3,1,4))', [3, 1, 4])
})

describe('unzipObjIntoU', () => {
  testEq(
    '{const ks=[],vs=[]; I.unzipObjIntoU({x:1,y:2}, ks, vs); return [ks, vs]}',
    [['x', 'y'], [1, 2]]
  )
  testEq('{const kvs=[]; I.unzipObjIntoU({x:1,y:2}, kvs, kvs); return kvs}', [
    'x',
    1,
    'y',
    2
  ])
})

describe('assocPartialU', () => {
  testEq('I.assocPartialU("x", 1, null)', {x: 1})
  testEq('I.assocPartialU("x", 1, undefined)', {x: 1})
  testEq('I.assocPartialU("x", 2, {x: 1})', {x: 2})
  testEq('I.assocPartialU("x", 2, {z: 1})', {z: 1, x: 2})
  testEq('I.assocPartialU("x", -1, new XYZ(3,1,4))', {x: -1, y: 1, z: 4})
})

describe('dissocPartialU', () => {
  testEq('I.dissocPartialU("x", null)', undefined)
  testEq('I.dissocPartialU("x", undefined)', undefined)
  testEq('I.dissocPartialU("x", {})', undefined)
  testEq('I.dissocPartialU("x", {x: 1})', undefined)
  testEq('I.dissocPartialU("x", {x: 1, y: 2})', {y: 2})
  testEq('I.dissocPartialU("y", new XYZ(3,1,4))', {x: 3, z: 4})
})

describe('isDefined', () => {
  testEq('I.isDefined(undefined)', false)
  testEq('I.isDefined(0/0)', true)
  testEq('I.isDefined(null)', true)
  testEq('I.isDefined("anything except undefined")', true)
})

describe('always', () => {
  testEq('I.always.length', 1)
  testEq('I.always(2).length', 1)
  testEq('I.always(1)(0)', 1)
})

describe('applyU', () => {
  testEq('I.applyU(x => x + 1, 2)', 3)
})

describe('sndU', () => {
  testEq('I.sndU("a", "b")', 'b')
})

describe('hasU', () => {
  testEq('I.hasU("constructor", {})', false)
  testEq('I.hasU("length", [])', true)
  testEq('I.hasU("x", {x: 0})', true)
  testEq('I.hasU("y", {x: 0})', false)
})

describe('inherit', () => {
  testEq(
    `{
        function Base(foo) {
          this._foo = foo
        }
        I.inherit(Base, Object, {
          Foo() {return this.Bar() + this._foo}
        }, {
          bar: 11
        })
        function Derived(foo) {
          Base.call(this, foo)
        }
        I.inherit(Derived, Base, {
          Bar() {return 10 + Base.bar}
        })
        return new Derived(5).Foo()
      }`,
    26
  )
})

if (process.env.NODE_ENV !== 'production')
  describe('function names', () => {
    for (const k in I) {
      if (I.isFunction(I[k])) {
        testEq(`I.${k}.name`, k.replace(/U$/, ''))
      }
    }
  })
<commit_msg>Little less stringy<commit_after>import * as I from '../dist/infestines.cjs'
import * as R from 'ramda'

function show(x) {
  switch (typeof x) {
    case 'string':
    case 'object':
      return JSON.stringify(x)
    default:
      return `${x}`
  }
}

const showExpr = expr =>
  R.is(Function, expr)
    ? expr
        .toString()
        .replace(/\s+/g, ' ')
        .replace(/^\s*function\s*\(\s*\)\s*{\s*(return\s*)?/, '')
        .replace(/\s*;?\s*}\s*$/, '')
        .replace(/function\s*(\([a-zA-Z]*\))\s*/g, '$1 => ')
        .replace(/{\s*return\s*([^{;]+)\s*;\s*}/g, '$1')
    : expr
const runExpr = expr =>
  R.is(Function, expr) ? expr() : eval(`() => ${expr}`)()

const testEq = (expr, expect) =>
  it(`${showExpr(expr)} => ${show(expect)}`, () => {
    const actual = runExpr(expr)
    if (!I.acyclicEqualsU(actual, expect))
      throw new Error(`Expected: ${show(expect)}, actual: ${show(actual)}`)
  })

const expectFail = expr =>
  it(`${showExpr(expr)} => failure`, () => {
    try {
      const actual = runExpr(expr)
      throw new Error(`Expected: failure, actual: ${show(actual)}`)
    } catch (_e) {
      return
    }
  })

function forAll(fn, x, n, cb) {
  function rec(n, x) {
    if (0 === n) cb(x)
    for (let i = 0; i < n; ++i) rec(i, fn(i, n, x))
  }
  rec(n, x)
}

function forAllFns(n, cb) {
  const args = R.map(i => `x${i}`, R.range(0, n))
  forAll((i, m, body) => `(${args.slice(i, m)}) => ${body}`, `[${args}]`, n, cb)
}

function forAllApplys(fn, n, cb) {
  const vals = R.range(0, n)
  forAll((i, m, lhs) => `${lhs}(${vals.slice(n - m, n - i)})`, `(${fn})`, n, cb)
}

describe('currying', () => {
  for (let n = 2; n <= 4; ++n) {
    forAllFns(n, fn =>
      forAllApplys(`I.curryN(${n}, ${fn})`, n, expr => {
        testEq(expr, R.range(0, n))
      })
    )
  }

  testEq(() => I.curry(x => x + 1)(1), 2)
  testEq(() => I.curry((x, y) => x + y)(1)(2), 3)
  testEq(() => I.curry((x, y, z) => x + y + z)(1)(2, 3), 6)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d).length, 4)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1).length, 3)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1, 2).length, 2)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1)(2, 3).length, 1)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1, 2, 3, 4), 10)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1, 2, 3)(4), 10)
  testEq(() => I.curry((a, b, c, d) => a + b + c + d)(1)(2, 3, 4), 10)

  expectFail(() => I.curry(() => {}))
  expectFail(() => I.curry((_a, _b, _c, _d, _e) => {}))
})

describe('curry', () => {
  testEq(
    () => {
      const foobar = I.curry(function foobar(x, y) {
        return x + y
      })
      return [foobar.name, foobar(1).name]
    },
    ['foobar', 'foobar']
  )
})

describe('arity', () => {
  testEq(() => I.arityN(0, _x => 101)(), 101)
  testEq(() => I.arityN(1, (_x, _y) => 42)(), 42)
})

describe('id', () => {
  testEq(() => I.id.length, 1)
  testEq(() => I.id('anything'), 'anything')
})

describe('pipe and compose', () => {
  testEq(() => I.pipe2U(R.inc, R.negate)(1), -2)
  testEq(() => I.compose2U(R.inc, R.negate)(1), 0)
  testEq(() => I.pipe2U((a, b) => a + b, x => x + 1)(1, 2), 4)
  testEq(() => I.pipe2U((a, b) => a + b, x => x + 1).length, 2)
  testEq(() => I.compose2U(x => x + 1, (a, b) => a + b)(1, 2), 4)
  testEq(() => I.compose2U(x => x + 1, (a, b) => a + b).length, 2)
})

describe('seq', () => {
  testEq(() => I.seq(11), 11)
  testEq(() => I.seq(11, x => x + 1), 12)
})

describe('seqPartial', () => {
  testEq(() => I.seqPartial(11), 11)
  testEq(() => I.seqPartial(11, x => x + 2), 13)
  testEq(() => I.seqPartial(11, _ => undefined, x => x.wouldFail), undefined)
})

describe('array0', () => {
  testEq(() => I.array0, [])
})

describe('object0', () => {
  testEq(() => I.object0, {})
})

describe('isObject', () => {
  testEq(() => I.isObject(null), false)
  testEq(() => I.isObject({}), true)
  testEq(() => I.isObject([]), false)
  testEq(() => I.isObject({constructor: 'haha'}), true)
  testEq(() => I.isObject({constructor: Array}), true)
})

describe('isArray', () => {
  testEq(() => I.isArray(null), false)
  testEq(() => I.isArray({}), false)
  testEq(() => I.isArray([]), true)
  testEq(() => I.isArray({constructor: Array}), false)
})

describe('isNumber', () => {
  testEq(() => I.isNumber(null), false)
  testEq(() => I.isNumber({}), false)
  testEq(() => I.isNumber(101), true)
})

describe('isString', () => {
  testEq(() => I.isString(null), false)
  testEq(() => I.isString({}), false)
  testEq(() => I.isString('42'), true)
})

export class Foo {
  constructor(v) {
    this.v = v
  }
  equals(other) {
    return this.v === other.v
  }
}

describe('identicalU', () => {
  testEq(() => I.identicalU(null, null), true)
  testEq(() => I.identicalU(-0, +0), false)
  testEq(() => I.identicalU(NaN, NaN), true)
  testEq(() => I.identicalU({}, {}), false)
})

describe('acyclicEqualsU', () => {
  testEq(() => I.acyclicEqualsU(null, {}), false)
  testEq(() => I.acyclicEqualsU({a: 1}, {a: 1, b: 2}), false)
  testEq(() => I.acyclicEqualsU([1, 2], [1]), false)
  testEq(() => I.acyclicEqualsU([1, 2], [1, 3]), false)
  testEq(() => I.acyclicEqualsU({a: 1, b: [true]}, {b: [true], a: 1}), true)
  testEq(() => I.acyclicEqualsU({a: 1, b: [true]}, {b: [true]}), false)
  testEq(() => I.acyclicEqualsU([], {}), false)
  testEq(() => I.acyclicEqualsU(new Foo(1), new Foo(1)), true)
  testEq(() => I.acyclicEqualsU(new Foo(2), new Foo(1)), false)
})

function XYZ(x, y, z) {
  this.x = x
  this.y = y
  this.z = z
}
XYZ.prototype.sum = function() {
  return this.x + this.y + this.z
}

describe('keys', () => {
  testEq(() => I.keys({}), [])
  testEq(() => I.keys({x: 1, y: 2}), ['x', 'y'])
  testEq(() => I.keys(new XYZ(3, 1, 4)), ['x', 'y', 'z'])
})

describe('values', () => {
  testEq(() => I.values({}), [])
  testEq(() => I.values({x: 1, y: 2}), [1, 2])
  testEq(() => I.values(new XYZ(3, 1, 4)), [3, 1, 4])
})

describe('unzipObjIntoU', () => {
  testEq(
    () => {
      const ks = [],
        vs = []
      I.unzipObjIntoU({x: 1, y: 2}, ks, vs)
      return [ks, vs]
    },
    [['x', 'y'], [1, 2]]
  )
  testEq(
    () => {
      const kvs = []
      I.unzipObjIntoU({x: 1, y: 2}, kvs, kvs)
      return kvs
    },
    ['x', 1, 'y', 2]
  )
})

describe('assocPartialU', () => {
  testEq(() => I.assocPartialU('x', 1, null), {x: 1})
  testEq(() => I.assocPartialU('x', 1, undefined), {x: 1})
  testEq(() => I.assocPartialU('x', 2, {x: 1}), {x: 2})
  testEq(() => I.assocPartialU('x', 2, {z: 1}), {z: 1, x: 2})
  testEq(() => I.assocPartialU('x', -1, new XYZ(3, 1, 4)), {x: -1, y: 1, z: 4})
})

describe('dissocPartialU', () => {
  testEq(() => I.dissocPartialU('x', null), undefined)
  testEq(() => I.dissocPartialU('x', undefined), undefined)
  testEq(() => I.dissocPartialU('x', {}), undefined)
  testEq(() => I.dissocPartialU('x', {x: 1}), undefined)
  testEq(() => I.dissocPartialU('x', {x: 1, y: 2}), {y: 2})
  testEq(() => I.dissocPartialU('y', new XYZ(3, 1, 4)), {x: 3, z: 4})
})

describe('isDefined', () => {
  testEq(() => I.isDefined(undefined), false)
  testEq(() => I.isDefined(0 / 0), true)
  testEq(() => I.isDefined(null), true)
  testEq(() => I.isDefined('anything except undefined'), true)
})

describe('always', () => {
  testEq(() => I.always.length, 1)
  testEq(() => I.always(2).length, 1)
  testEq(() => I.always(1)(0), 1)
})

describe('applyU', () => {
  testEq(() => I.applyU(x => x + 1, 2), 3)
})

describe('sndU', () => {
  testEq(() => I.sndU('a', 'b'), 'b')
})

describe('hasU', () => {
  testEq(() => I.hasU('constructor', {}), false)
  testEq(() => I.hasU('length', []), true)
  testEq(() => I.hasU('x', {x: 0}), true)
  testEq(() => I.hasU('y', {x: 0}), false)
})

describe('inherit', () => {
  testEq(() => {
    function Base(foo) {
      this._foo = foo
    }
    I.inherit(
      Base,
      Object,
      {
        Foo() {
          return this.Bar() + this._foo
        }
      },
      {
        bar: 11
      }
    )
    function Derived(foo) {
      Base.call(this, foo)
    }
    I.inherit(Derived, Base, {
      Bar() {
        return 10 + Base.bar
      }
    })
    return new Derived(5).Foo()
  }, 26)
})

if (process.env.NODE_ENV !== 'production')
  describe('function names', () => {
    for (const k in I) {
      if (I.isFunction(I[k])) {
        testEq(() => I[k].name, k.replace(/U$/, ''))
      }
    }
  })
<|endoftext|>


<commit_before>import ReactiveElement from "../core/ReactiveElement.js";
import * as templating from "../core/template.js";
import * as calendar from "./calendar.js";
import CalendarElementMixin from "./CalendarElementMixin.js";
import {
  defaultState,
  ids,
  render,
  setState,
  state,
  template,
} from "./internal.js";

const Base = CalendarElementMixin(ReactiveElement);

/**
 * Header showing a localized month name and the year
 *
 * [A default representation of the month and year in browser's default locale](/demos/calendarMonthYearHeader.html)
 *
 * Given a reference `date` property, this component will show a calendar
 * representation of that month and year.
 *
 * All of the Elix calendar components attempt to provide full
 * [international calendar support](CalendarMonth#international-support)
 * to the extent currently possible in the user's web browser.
 *
 * [CalendarMonth](CalendarMonth) instantiates `CalendarMonthYearHeader` to show
 * the name of the current month and the year as a header for the calendar
 * month.
 *
 * @inherits ReactiveElement
 * @mixes CalendarElementMixin
 */
class CalendarMonthYearHeader extends Base {
  get [defaultState]() {
    return Object.assign(super[defaultState], {
      date: calendar.today(),
      monthFormat: "long",
      yearFormat: "numeric",
    });
  }

  /**
   * The format used to render the month name.
   *
   * The allowable formats are the same as the `month` formats in
   * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
   *
   * @type {('numeric'|'2-digit'|'long'|'short'|'narrow')}
   * @default 'long'
   */
  get monthFormat() {
    return this[state].monthFormat;
  }
  set monthFormat(monthFormat) {
    this[setState]({ monthFormat });
  }

  [render](/** @type {ChangedFlags} */ changed) {
    super[render](changed);
    if (
      changed.date ||
      changed.locale ||
      changed.monthFormat ||
      changed.yearFormat
    ) {
      const { date, locale, monthFormat, yearFormat } = this[state];
      /** @type {PlainObject} */ const formatOptions = {};
      if (monthFormat) {
        formatOptions.month = monthFormat;
      }
      if (yearFormat) {
        formatOptions.year = yearFormat;
      }
      const formatter = calendar.dateTimeFormat(locale, formatOptions);
      this[ids].formatted.textContent = formatter.format(date);
    }
  }

  get [template]() {
    return templating.html`

    `;
  }

  /**
   * The format used to render the year.
   *
   * The allowable formats are the same as the `year` formats in
   * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
   *
   * @type {('numeric'|'2-digit')}
   * @default 'numeric'
   */
  get yearFormat() {
    return this[state].yearFormat;
  }
  set yearFormat(yearFormat) {
    this[setState]({ yearFormat });
  }
}

export default CalendarMonthYearHeader;
<commit_msg>Fix import.<commit_after>import { templateFrom } from "../core/htmlLiterals.js";
import ReactiveElement from "../core/ReactiveElement.js";
import * as calendar from "./calendar.js";
import CalendarElementMixin from "./CalendarElementMixin.js";
import {
  defaultState,
  ids,
  render,
  setState,
  state,
  template,
} from "./internal.js";

const Base = CalendarElementMixin(ReactiveElement);

/**
 * Header showing a localized month name and the year
 *
 * [A default representation of the month and year in browser's default locale](/demos/calendarMonthYearHeader.html)
 *
 * Given a reference `date` property, this component will show a calendar
 * representation of that month and year.
 *
 * All of the Elix calendar components attempt to provide full
 * [international calendar support](CalendarMonth#international-support)
 * to the extent currently possible in the user's web browser.
 *
 * [CalendarMonth](CalendarMonth) instantiates `CalendarMonthYearHeader` to show
 * the name of the current month and the year as a header for the calendar
 * month.
 *
 * @inherits ReactiveElement
 * @mixes CalendarElementMixin
 */
class CalendarMonthYearHeader extends Base {
  get [defaultState]() {
    return Object.assign(super[defaultState], {
      date: calendar.today(),
      monthFormat: "long",
      yearFormat: "numeric",
    });
  }

  /**
   * The format used to render the month name.
   *
   * The allowable formats are the same as the `month` formats in
   * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
   *
   * @type {('numeric'|'2-digit'|'long'|'short'|'narrow')}
   * @default 'long'
   */
  get monthFormat() {
    return this[state].monthFormat;
  }
  set monthFormat(monthFormat) {
    this[setState]({ monthFormat });
  }

  [render](/** @type {ChangedFlags} */ changed) {
    super[render](changed);
    if (
      changed.date ||
      changed.locale ||
      changed.monthFormat ||
      changed.yearFormat
    ) {
      const { date, locale, monthFormat, yearFormat } = this[state];
      /** @type {PlainObject} */ const formatOptions = {};
      if (monthFormat) {
        formatOptions.month = monthFormat;
      }
      if (yearFormat) {
        formatOptions.year = yearFormat;
      }
      const formatter = calendar.dateTimeFormat(locale, formatOptions);
      this[ids].formatted.textContent = formatter.format(date);
    }
  }

  get [template]() {
    return templateFrom.html`

    `;
  }

  /**
   * The format used to render the year.
   *
   * The allowable formats are the same as the `year` formats in
   * [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat).
   *
   * @type {('numeric'|'2-digit')}
   * @default 'numeric'
   */
  get yearFormat() {
    return this[state].yearFormat;
  }
  set yearFormat(yearFormat) {
    this[setState]({ yearFormat });
  }
}

export default CalendarMonthYearHeader;
<|endoftext|>


<commit_before>(function(){
    angular.module('angularytics', []).provider('Angularytics', function() {

        var eventHandlersNames = ['Google'];
        this.setEventHandlers = function(handlers) {
            if (angular.isString(handlers)) {
                handlers = [handlers];
            }
            eventHandlersNames = [];
            angular.forEach(handlers, function(handler) {
                eventHandlersNames.push(capitalizeHandler(handler))
            });
        }

        var capitalizeHandler = function(handler) {
            return handler.charAt(0).toUpperCase() + handler.substring(1);
        }

        var pageChangeEvent = '$locationChangeSuccess';
        this.setPageChangeEvent = function(newPageChangeEvent) {
          pageChangeEvent = newPageChangeEvent;
        }

        this.$get = function($injector, $rootScope, $location) {

            // Helper methods
            var eventHandlers = [];

            angular.forEach(eventHandlersNames, function(handler) {
                eventHandlers.push($injector.get('Angularytics' + handler + 'Handler'));
            });

            var forEachHandlerDo = function(action) {
                angular.forEach(eventHandlers, function(handler) {
                    action(handler);
                });
            }

            // Event listeing
            $rootScope.$on(pageChangeEvent, function() {
                forEachHandlerDo(function(handler) {
                    var url = $location.path();
                    if (url) {
                        handler.trackPageView(url);
                    }
                })
            });

            var service = {};
            // Just dummy function so that it's instantiated on app creation
            service.init = function() {

            }

            service.trackEvent = function(category, action, opt_label, opt_value, opt_noninteraction) {
                forEachHandlerDo(function(handler) {
                    if (category && action) {
                        handler.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
                    }
                });
            }

            return service;

        };

    });
})();
<commit_msg>add trackPageView(url)<commit_after>(function(){
    angular.module('angularytics', []).provider('Angularytics', function() {

        var eventHandlersNames = ['Google'];
        this.setEventHandlers = function(handlers) {
            if (angular.isString(handlers)) {
                handlers = [handlers];
            }
            eventHandlersNames = [];
            angular.forEach(handlers, function(handler) {
                eventHandlersNames.push(capitalizeHandler(handler))
            });
        }

        var capitalizeHandler = function(handler) {
            return handler.charAt(0).toUpperCase() + handler.substring(1);
        }

        var pageChangeEvent = '$locationChangeSuccess';
        this.setPageChangeEvent = function(newPageChangeEvent) {
          pageChangeEvent = newPageChangeEvent;
        }

        this.$get = function($injector, $rootScope, $location) {

            // Helper methods
            var eventHandlers = [];

            angular.forEach(eventHandlersNames, function(handler) {
                eventHandlers.push($injector.get('Angularytics' + handler + 'Handler'));
            });

            var forEachHandlerDo = function(action) {
                angular.forEach(eventHandlers, function(handler) {
                    action(handler);
                });
            }

            // Event listeing
            $rootScope.$on(pageChangeEvent, function() {
                forEachHandlerDo(function(handler) {
                    var url = $location.path();
                    if (url) {
                        handler.trackPageView(url);
                    }
                })
            });

            var service = {};
            // Just dummy function so that it's instantiated on app creation
            service.init = function() {

            }

            service.trackEvent = function(category, action, opt_label, opt_value, opt_noninteraction) {
                forEachHandlerDo(function(handler) {
                    if (category && action) {
                        handler.trackEvent(category, action, opt_label, opt_value, opt_noninteraction);
                    }
                });
            }

            service.trackPageView = function(url) {
                forEachHandlerDo(function(handler) {
                    if (url) {
                        handler.trackPageView(url);
                    }
                });
            }

            return service;

        };

    });
})();
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var os = require( 'os' );
var path = require('path');
var assert = require( 'assert' );
var fs = require( 'fs-extra' );
var uuid = require( 'node-uuid' );
var helpers = require( '../testutil/helpers.js' );
var gs = require('..' );

function defineTests( transport ) {

	describe( transport.name + ' checkout', function() {
		this.timeout( 30 * 60 * 1000 ); // 30 minutes

		helpers.promiseIt('CreateRepo', async function( tempDir ) {
			let result = await helpers.createRepo( tempDir, transport );
			assert.equal( transport.isRepoFolder( result.dir ), true, 'Repository directory created correctly' );
		} );

		helpers.promiseIt('Checkout', async function( tempDir ) {
			let result = await helpers.createRepo( tempDir, transport );
			let checkoutDir = path.join( tempDir, uuid.v4() );
			await transport.checkout( result.url, null, checkoutDir );
			assert.equal( transport.isWorkingCopy( checkoutDir ), true, 'Repository checkout out correctly' );
		} );
	} );
}

defineTests( gs.svn );
if ( os.platform() !== 'win32' ) {
	defineTests( gs.git );
}

<commit_msg>added template tests<commit_after>/*jslint node: true */
'use strict';

var os = require( 'os' );
var path = require('path');
var assert = require( 'assert' );
var fs = require( 'fs-extra' );
var uuid = require( 'node-uuid' );
var helpers = require( '../testutil/helpers.js' );
var gs = require('..' );

function defineTests( transport ) {

	describe( transport.name + ' tests', function() {
		this.timeout( 30 * 60 * 1000 ); // 30 minutes

		helpers.promiseIt('createRepo', async function( tempDir ) {
			let result = await helpers.createRepo( tempDir, transport );
			assert.equal( transport.isRepoFolder( result.dir ), true, 'Repository directory created correctly' );
		} );

		helpers.promiseIt('checkout', async function( tempDir ) {
			let result = await helpers.createRepo( tempDir, transport );
			let checkoutDir = path.join( tempDir, uuid.v4() );
			await transport.checkout( result.url, null, checkoutDir );
			assert.equal( transport.isWorkingCopy( checkoutDir ), true, 'Repository checkout out correctly' );
		} );

		helpers.promiseIt('isWorkingCopyClean', async function( tempDir ) {

		} );

		helpers.promiseIt('update', async function( tempDir ) {

		} );

		helpers.promiseIt('exists', async function( tempDir ) {

		} );

		helpers.promiseIt('cat', async function( tempDir ) {

		} );

		helpers.promiseIt('unCat', async function( tempDir ) {

		} );

		helpers.promiseIt('getWorkingCopyInfo', async function( tempDir ) {

		} );

		helpers.promiseIt('getUrlHeadRevision', async function( tempDir ) {

		} );

		helpers.promiseIt('getWorkingCopyRevision', async function( tempDir ) {

		} );

		helpers.promiseIt('listTags', async function( tempDir ) {

		} );

		helpers.promiseIt('exportDir', async function( tempDir ) {

		} );

		helpers.promiseIt('createBranch', async function( tempDir ) {

		} );

		helpers.promiseIt('createTag', async function( tempDir ) {

		} );
	} );
}

defineTests( gs.svn );
if ( os.platform() !== 'win32' ) {
	defineTests( gs.git );
}

<|endoftext|>