<commit_before>/* This file has been generated by ox-ui-module generator.
 * Please only apply minor changes (better no changes at all) to this file
 * if you want to be able to run the generator again without much trouble.
 *
 * If you really have to change this file for whatever reason, try to contact
 * the core team and describe your use-case. May be, your changes can be
 * integrated into the templates to be of use for everybody.
 */
'use strict';

module.exports = function (grunt) {
    var path = require('path');
    var coreDir = grunt.option('coreDir') || grunt.config('local.coreDir') || '';

    // coreDir needs to be relative to the current working directory, because less doesn't like absolute paths
    // for @import statements (see http://stackoverflow.com/questions/10715214/lessc-with-an-absolute-path-in-importing)
    coreDir = path.relative(process.cwd(), coreDir);

    //TODO: get rid of coreDir dependency for less files
    //if no coreDir is specified, compile everything for 'default' theme, this can be used
    //with local versions of core definitions.less, mixins.less and style.less.
    //Just place those files in lib/appsuite/apps/themes/
    var coreThemes = (coreDir ?
        grunt.file.expand({cwd: path.join(coreDir, 'apps/themes/')}, '*/definitions.less') : []
    ).map(function (file) {
        return file.replace(/\/definitions.less$/, '');
    });
    var localThemes = grunt.file.expand({cwd: 'apps/themes/'}, '*/definitions.less').map(function (file) {
        return file.replace(/\/definitions.less$/, '');
    });

    function optionsFor(themeName) {
        return {
            compress: !grunt.config('local.debug'),
            cleancss: !grunt.config('local.debug'),
            ieCompat: false,
            syncImport: true,
            strictMath: false,
            strictUnits: false,
            relativeUrls: false,
            paths: [
                'bower_components/bootstrap/less',
                'bower_components/font-awesome/less',
                'lib/appsuite/apps/themes',
                path.join(coreDir, 'apps/themes'),
                'apps/themes',
            ],
            imports: {
                reference: [
                    'variables.less',
                    'mixins.less'
                ],
                less: [
                    'definitions.less',
                    themeName + '/definitions.less'
                ]
            }
        };
    }

    localThemes.forEach(function (themeName) {
        var theme = {};

        theme[themeName] = {
            options: optionsFor(themeName),
            files: [
                {
                    src: [
                        'bower_components/bootstrap/less/bootstrap.less',
                        'bower_components/bootstrap-datepicker/less/datepicker3.less',
                        'bower_components/font-awesome/less/font-awesome.less',
                        path.join(coreDir, 'apps/themes/style.less')
                    ],
                    expand: true,
                    rename: function (dest) { return dest; },
                    dest: 'build/apps/themes/' + themeName + '/common.css',
                    nonull: true
                },
                {
                    src: [
                        'apps/themes/' + themeName + '/style.less'
                    ],
                    expand: true,
                    rename: function (dest) { return dest; },
                    filter: function () {
                        //only generate this file if there is a style.less for this theme
                        return grunt.file.exists('apps/themes/' + themeName + '/style.less');
                    },
                    dest: 'build/apps/themes/' + themeName + '/style.css'
                },
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: path.join(coreDir, 'apps/'),
                    dest: 'build/apps/themes/' + themeName + '/'
                },
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: 'apps/',
                    dest: 'build/apps/themes/' + themeName + '/'
                }
            ]
        };
        grunt.config.extend('less', theme);
    });

    coreThemes.forEach(function (themeName) {
        var theme = {};
        theme['core_theme/' + themeName + '+local_less'] = {
            options: optionsFor(themeName),
            files: [
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: 'apps/',
                    dest: 'build/apps/themes/' + themeName + '/'
                }
            ]
        };
        grunt.config.extend('less', theme);
    });

    //init empty less config, if no themes detected, this will prevent grunt-newer
    //from failing
    grunt.config.extend('less', {});

    grunt.loadNpmTasks('assemble-less');
};
<commit_msg>make coreDir variable mandatory for building themes<commit_after>/* This file has been generated by ox-ui-module generator.
 * Please only apply minor changes (better no changes at all) to this file
 * if you want to be able to run the generator again without much trouble.
 *
 * If you really have to change this file for whatever reason, try to contact
 * the core team and describe your use-case. May be, your changes can be
 * integrated into the templates to be of use for everybody.
 */
'use strict';

module.exports = function (grunt) {
    var path = require('path');
    var coreDir = grunt.option('coreDir') || grunt.config('local.coreDir') || '';

    // coreDir needs to be relative to the current working directory, because less doesn't like absolute paths
    // for @import statements (see http://stackoverflow.com/questions/10715214/lessc-with-an-absolute-path-in-importing)
    coreDir = path.relative(process.cwd(), coreDir);

    //TODO: get rid of coreDir dependency for less files
    //if no coreDir is specified, compile everything for 'default' theme, this can be used
    //with local versions of core definitions.less, mixins.less and style.less.
    //Just place those files in lib/appsuite/apps/themes/
    var coreThemes = (coreDir ?
        grunt.file.expand({cwd: path.join(coreDir, 'apps/themes/')}, '*/definitions.less') : []
    ).map(function (file) {
        return file.replace(/\/definitions.less$/, '');
    });
    var localThemes = grunt.file.expand({cwd: 'apps/themes/'}, '*/definitions.less').map(function (file) {
        return file.replace(/\/definitions.less$/, '');
    });

    function optionsFor(themeName) {
        return {
            compress: !grunt.config('local.debug'),
            cleancss: !grunt.config('local.debug'),
            ieCompat: false,
            syncImport: true,
            strictMath: false,
            strictUnits: false,
            relativeUrls: false,
            paths: [
                'bower_components/bootstrap/less',
                'bower_components/font-awesome/less',
                'lib/appsuite/apps/themes',
                path.join(coreDir, 'apps/themes'),
                'apps/themes',
            ],
            imports: {
                reference: [
                    'variables.less',
                    'mixins.less'
                ],
                less: [
                    'definitions.less',
                    themeName + '/definitions.less'
                ]
            }
        };
    }

    localThemes.forEach(function (themeName) {
        var theme = {};

        theme[themeName] = {
            options: optionsFor(themeName),
            files: [
                {
                    src: [
                        'bower_components/bootstrap/less/bootstrap.less',
                        'bower_components/bootstrap-datepicker/less/datepicker3.less',
                        'bower_components/font-awesome/less/font-awesome.less',
                        path.join(coreDir, 'apps/themes/style.less')
                    ],
                    expand: true,
                    rename: function (dest) { return dest; },
                    filter: function () {
                        if (!coreDir) {
                            grunt.log.warn('Building local themes without a --coreDir option is not supported, at the moment');
                        }
                        return coreDir;
                    },
                    dest: 'build/apps/themes/' + themeName + '/common.css',
                    nonull: true
                },
                {
                    src: [
                        'apps/themes/' + themeName + '/style.less'
                    ],
                    expand: true,
                    rename: function (dest) { return dest; },
                    filter: function () {
                        //only generate this file if there is a style.less for this theme
                        return coreDir && grunt.file.exists('apps/themes/' + themeName + '/style.less');
                    },
                    dest: 'build/apps/themes/' + themeName + '/style.css'
                },
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: path.join(coreDir, 'apps/'),
                    filter: function () {
                        return coreDir;
                    },
                    dest: 'build/apps/themes/' + themeName + '/'
                },
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: 'apps/',
                    filter: function () {
                        return coreDir;
                    },
                    dest: 'build/apps/themes/' + themeName + '/'
                }
            ]
        };
        grunt.config.extend('less', theme);
    });

    coreThemes.forEach(function (themeName) {
        var theme = {};
        theme['core_theme/' + themeName + '+local_less'] = {
            options: optionsFor(themeName),
            files: [
                {
                    src: ['**/*.less', '!themes/**/*.less', '!themes/*.less'],
                    expand: true,
                    ext: '.css',
                    cwd: 'apps/',
                    dest: 'build/apps/themes/' + themeName + '/'
                }
            ]
        };
        grunt.config.extend('less', theme);
    });

    //init empty less config, if no themes detected, this will prevent grunt-newer
    //from failing
    grunt.config.extend('less', {});

    grunt.loadNpmTasks('assemble-less');
};
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Petka Antonov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
(function( global, $ ) {

    function escapeForQuote( str ) {
        return (str + "").replace( /(\\|")/g, "\\$1" );
    }

    var invalidTypes = {
        "button": 0,
        "file": 0,
        "hidden": 0,
        "image": 0,
        "reset": 0,
        "submit": 0
    };

    var returnNull = function() {
        return null;
    };

    if( !global.localStorage ) {
        global.localStorage = {
            getItem: returnNull,
            setItem: returnNull,
            removeItem: returnNull,
            clear: returnNull
        };
    }

    function FieldState( form ) {
        this.element = $(form);
        this.identifier = (this.element.prop("id") + "");
    }

    FieldState.prototype = {

        restore: function() {
            var items = global.localStorage.getItem( this.identifier ),
                storedValue, storedValueType, $elems;

            if( !items ) {
                return;
            }

            try {
                items = $.parseJSON( items );
            }
            catch( error ) {
                return;
            }

            for( var key in items ) {
                storedValue = items[key];
                storedValueType = $.type( storedValue );

                $elems = $( '[name="' + escapeForQuote(key)  + '"]', this.element );

                if( storedValueType === "array" ) { //Multiple elements with same name or single element with multiple values

                    if( $elems.length === 1 ) { // A single element with multiple values
                        $elems.val( storedValue );
                    }
                    else {
                        $elems.each( $.proxy( function(index, elem){
                            var value = this[index];

                            if( typeof value === "boolean" ) {  //Radio/Checkbox
                                elem.checked = value;
                            }
                            else {
                                $( elem ).val( value )
                            }
                        }, storedValue ) );
                    }
                }
                else if( storedValueType === "boolean" ) { //Radio/Checkbox
                    $elems.prop("checked", storedValue);
                }
                else {
                    $elems.val( items[key] );
                }
                $elems.trigger("fieldstate:restored");
            }

        },

        clear: function() {
            global.localStorage.removeItem( this.identifier );
        },

        save: function() {
            if( !global.JSON || !global.JSON.stringify ) {
                return;
            }

            var obj = {};
            $( '[name][data-fieldstate!="false"]', this.element ).each( function(){
                var name = this.name, value, type = this.type && this.type.toLowerCase() || "";

                if( invalidTypes[type] === 0 ) {
                    return;
                }

                if( name && $(this).is("input,select,textarea") ) {

                    value = type === "radio" || type === "checkbox" ? !!this.checked : $(this).val();

                    if( name in obj ) { //Multiple elements with same name
                        if( $.type( obj[name] ) !== "array" ) {
                            obj[name] = [obj[name]];
                        }
                        obj[name].push( value );
                    }
                    else {
                        obj[name] = value;
                    }
                }
            });

            global.localStorage.setItem( this.identifier, global.JSON.stringify( obj ) );
        },

        constructor: FieldState
    };

    $.fn.fieldstate = function( option ) {

        return this.filter( "form" ).each( function() {

            var $this = $(this),
                instance = $this.data( "FieldState-instance" );

            if( !instance ) {
                $this.data( "FieldState-instance", ( instance = new FieldState( this ) ) );
                if( !option ) {
                    option = $this.data( "fieldstate" );
                }
            }

            if( typeof option === "string" && option in instance ) {
                instance[option]();
            }

        });

    };

    $.fn.fieldstate.Constructor = FieldState;
    $( function() {
        $( "form[data-fieldstate]" ).fieldstate().on( {
            submit: function() {
                $(this).fieldstate("save");
            },

            reset: function() {
                $(this).fieldstate("clear");
            },

            change: function() {
                $(this).fieldstate("save");
            }
        });

        $( window ).on( "beforeunload", function(){
            $( "form[data-fieldstate]" ).fieldstate("save");
        });
    });

})( this, this.jQuery );<commit_msg>use sesssion storage instead of local<commit_after>/*
Copyright (c) 2012 Petka Antonov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
(function( global, $ ) {

    function escapeForQuote( str ) {
        return (str + "").replace( /(\\|")/g, "\\$1" );
    }

    var invalidTypes = {
        "button": 0,
        "file": 0,
        "hidden": 0,
        "image": 0,
        "reset": 0,
        "submit": 0
    };

    var returnNull = function() {
        return null;
    };

    if( !global.sessionStorage ) {
        global.sessionStorage = {
            getItem: returnNull,
            setItem: returnNull,
            removeItem: returnNull,
            clear: returnNull
        };
    }

    function FieldState( form ) {
        this.element = $(form);
        this.identifier = (this.element.prop("id") + "");
    }

    FieldState.prototype = {

        restore: function() {
            var items = global.sessionStorage.getItem( this.identifier ),
                storedValue, storedValueType, $elems;

            if( !items ) {
                return;
            }

            try {
                items = $.parseJSON( items );
            }
            catch( error ) {
                return;
            }

            for( var key in items ) {
                storedValue = items[key];
                storedValueType = $.type( storedValue );

                $elems = $( '[name="' + escapeForQuote(key)  + '"]', this.element );

                if( storedValueType === "array" ) { //Multiple elements with same name or single element with multiple values

                    if( $elems.length === 1 ) { // A single element with multiple values
                        $elems.val( storedValue );
                    }
                    else {
                        $elems.each( $.proxy( function(index, elem){
                            var value = this[index];

                            if( typeof value === "boolean" ) {  //Radio/Checkbox
                                elem.checked = value;
                            }
                            else {
                                $( elem ).val( value )
                            }
                        }, storedValue ) );
                    }
                }
                else if( storedValueType === "boolean" ) { //Radio/Checkbox
                    $elems.prop("checked", storedValue);
                }
                else {
                    $elems.val( items[key] );
                }
                $elems.trigger("fieldstate:restored");
            }

        },

        clear: function() {
            global.sessionStorage.removeItem( this.identifier );
        },

        save: function() {
            if( !global.JSON || !global.JSON.stringify ) {
                return;
            }

            var obj = {};
            $( '[name][data-fieldstate!="false"]', this.element ).each( function(){
                var name = this.name, value, type = this.type && this.type.toLowerCase() || "";

                if( invalidTypes[type] === 0 ) {
                    return;
                }

                if( name && $(this).is("input,select,textarea") ) {

                    value = type === "radio" || type === "checkbox" ? !!this.checked : $(this).val();

                    if( name in obj ) { //Multiple elements with same name
                        if( $.type( obj[name] ) !== "array" ) {
                            obj[name] = [obj[name]];
                        }
                        obj[name].push( value );
                    }
                    else {
                        obj[name] = value;
                    }
                }
            });

            global.sessionStorage.setItem( this.identifier, global.JSON.stringify( obj ) );
        },

        constructor: FieldState
    };

    $.fn.fieldstate = function( option ) {

        return this.filter( "form" ).each( function() {

            var $this = $(this),
                instance = $this.data( "FieldState-instance" );

            if( !instance ) {
                $this.data( "FieldState-instance", ( instance = new FieldState( this ) ) );
                if( !option ) {
                    option = $this.data( "fieldstate" );
                }
            }

            if( typeof option === "string" && option in instance ) {
                instance[option]();
            }

        });

    };

    $.fn.fieldstate.Constructor = FieldState;
    $( function() {
        $( "form[data-fieldstate]" ).fieldstate().on( {
            submit: function() {
                $(this).fieldstate("save");
            },

            reset: function() {
                $(this).fieldstate("clear");
            },

            change: function() {
                $(this).fieldstate("save");
            }
        });

        $( window ).on( "beforeunload", function(){
            $( "form[data-fieldstate]" ).fieldstate("save");
        });
    });

})( this, this.jQuery );<|endoftext|>


<commit_before>// Page.js - файл содержит все необходимые функции для работы модуля Page
var yupe;
if (!yupe)
    yupe = {};
else if (typeof yupe != 'object')
    throw new Error('yupe name exists, but is not object!');

if (!yupe.modules)
    yupe.modules = {};
else if (typeof yupe.modules != 'object')
    throw new Error('yupe.modules name exists, but is not object!');

if (yupe.modules.page)
    throw new Error('yupe.modules.page already exists!');
else
    yupe.modules.page = {
        translit: function(text) {
            alert(text);
            return text;
        }
    }<commit_msg>удален каталог /protected/modules/page/web/<commit_after><|endoftext|>


<commit_before>define(['lib/local_storage'], function(storage) {
    return {

        storageKey: 'recently-viewed-products',
        numProducts: 4,

        addProductIntoLocalStorage: function(product) {

            if (typeof product == 'undefined') {
                return;
            }

            var recentlyViewedProducts = storage.get(this.storageKey) || [];

            recentlyViewedProducts = this.removeProductFromListBySku(recentlyViewedProducts, product['sku']);
            recentlyViewedProducts.unshift(product);

            if (recentlyViewedProducts.length > this.numProducts + 1) {
                recentlyViewedProducts.shift();
            }

            storage.set(this.storageKey, recentlyViewedProducts);
        },

        getRecentlyViewedProductsHtml: function(currentProduct) {

            var products = storage.get(this.storageKey);

            if (null === products || !products.hasOwnProperty('length') || !products.length) {
                return '';
            }

            var productList = document.createElement('UL');
            productList.className = 'product-grid';

            for (var i = 0; i < products.length && i < this.numProducts; i++) {
                if (currentProduct.hasOwnProperty('sku') && products[i]['sku'] == currentProduct['sku']) {
                    continue;
                }

                productList.innerHTML += products[i]['html'];
            }

            // TODO: Add "last" class to last element of the list.

            return productList.innerHTML;
        },

        removeProductFromListBySku: function(list, sku) {

            var newList = [];

            for (var i = 0; i < list.length; i++) {
                if (list[i]['sku'] != sku) {
                    newList.push(list[i]);
                }
            }

            return newList
        }
    }
});
<commit_msg>Issue #402: Fix recently viewed products outer HTML<commit_after>define(['lib/local_storage'], function(storage) {
    return {

        storageKey: 'recently-viewed-products',
        numProducts: 4,

        addProductIntoLocalStorage: function(product) {

            if (typeof product == 'undefined') {
                return;
            }

            var recentlyViewedProducts = storage.get(this.storageKey) || [];

            recentlyViewedProducts = this.removeProductFromListBySku(recentlyViewedProducts, product['sku']);
            recentlyViewedProducts.unshift(product);

            if (recentlyViewedProducts.length > this.numProducts + 1) {
                recentlyViewedProducts.shift();
            }

            storage.set(this.storageKey, recentlyViewedProducts);
        },

        getRecentlyViewedProductsHtml: function(currentProduct) {

            var products = storage.get(this.storageKey);

            if (null === products || !products.hasOwnProperty('length') || !products.length) {
                return '';
            }

            var productList = document.createElement('UL');
            productList.className = 'product-grid';

            for (var i = 0; i < products.length && i < this.numProducts; i++) {
                if (currentProduct.hasOwnProperty('sku') && products[i]['sku'] == currentProduct['sku']) {
                    continue;
                }

                productList.innerHTML += products[i]['html'];
            }

            // TODO: Add "last" class to last element of the list.

            var temporaryContainer = document.createElement('DIV');
            temporaryContainer.appendChild(productList);

            return temporaryContainer.innerHTML;
        },

        removeProductFromListBySku: function(list, sku) {

            var newList = [];

            for (var i = 0; i < list.length; i++) {
                if (list[i]['sku'] != sku) {
                    newList.push(list[i]);
                }
            }

            return newList
        }
    }
});
<|endoftext|>


<commit_before>import assert from 'assert';
import reset from './reset';
import {
  objectToTime,
  cleanOrderedTimestamps,
  counterInc,
  counter,
} from '../src/RollingAttributesHelper';

describe('DDBehavioralAttributesHelper', () => {
  // describe('#cleanOrderedTimestamps', () => {
  //   it('should work with empty array', () => {
  //     const data = [];
  //     cleanOrderedTimestamps(data, 123);
  //     assert.deepEqual(data, []);
  //   });

  //   it('should not drop topical data', () => {
  //     const data = [[11, 9], [5, 7], [4, 2], [3, 1]];
  //     cleanOrderedTimestamps(data, 1);
  //     assert.deepEqual(data, [[11, 9], [5, 7], [4, 2], [3, 1]]);
  //   });

  //   it('should drop outdated data', () => {
  //     const data1 = [[11, 9], [5, 7], [4, 2], [3, 1]];
  //     const data2 = [[11, 9], [5, 7], [4, 2], [3, 1]];
  //     cleanOrderedTimestamps(data1, 4);
  //     cleanOrderedTimestamps(data2, 12);
  //     assert.deepEqual(data1, [[11, 9], [5, 7]]);
  //     assert.deepEqual(data2, []);
  //   });
  // });

  describe('#objectToTime', () => {
    it('should work with string arguments', () => {
      assert.equal(objectToTime('1day'), 86400);
      assert.equal(objectToTime('1week'), 7 * 86400);
      assert.equal(objectToTime('1month'), 30 * 86400);
      assert.equal(objectToTime('whatever'), 86400);
    });

    it('should work with object arguments', () => {
      assert.equal(objectToTime({ days: 2 }), 2 * 86400);
      assert.equal(objectToTime({ weeks: 3 }), 21 * 86400);
      assert.equal(objectToTime({ monthes: 2 }), 60 * 86400);
      assert.equal(objectToTime({ hours: 5 }), 5 * 3600);
      assert.equal(objectToTime({ minutes: 17 }), 17 * 60);
    });
  });

  describe('#counterInc', () => {
    it('should increment counter on empty data', () => {
      let paramsStorage = counterInc('foo', '1day', '1month', {});
      paramsStorage = counterInc('foo', '1day', '1month', { foo: paramsStorage });

      const firstKey = Object.keys(paramsStorage.data)[0];

      assert.ok(firstKey);
      assert.equal(paramsStorage.data[firstKey], 2);
    });

    // it('should increment counter on non empty data', () => {
    //   const previosEventsCount = 7;
    //   let paramsStorage = {
    //     foo: {
    //       ttl: 2592000000,
    //       data: { [new Date().getTime() - 86400001]: previosEventsCount },
    //     },
    //   };

    //   paramsStorage = counterInc('foo', '1day', '1month', paramsStorage);

    //   assert.equal(paramsStorage.data.length, 2);
    //   assert.equal(paramsStorage.data[0][1], 1);
    //   assert.equal(paramsStorage.data[1][1], previosEventsCount);
    // });
  });

  describe('#counter', () => {
    it('should eval counter correct', () => {
      const previosEventsCount = 33;
      let paramsStorage = {
        foo: {
          ttl: 2592000,
          data: { [new Date().getTime() - 86401]: previosEventsCount },
        },
      };

      paramsStorage = counterInc('foo', '1day', '1month', paramsStorage);
      paramsStorage = counterInc('foo', '1day', '1month', { foo: paramsStorage });

      assert.equal(counter('foo', { foo: paramsStorage }), 35);
    });
  });
});
<commit_msg>make tests work<commit_after>import assert from 'assert';
import {
  objectToTime,
  cleanData,
  counterInc,
  counter,
} from '../src/RollingAttributesHelper';

function getData(currentTime) {
  const ct = parseInt(currentTime / 1000, 10);
  return {
    [ct - 10]: 9,
    [ct - 8]: 7,
    [ct - 5]: 2,
    [ct - 3]: 1,
  };
}

describe('RollingAttributesHelper', () => {
  describe('#cleanData', () => {
    it('should work with empty dict', () => {
      const paramStorage = {
        ttl: 2592000,
        data: {},
        granularity: 86400,
      };

      const { data } = cleanData(paramStorage);
      assert.deepEqual(data, {});
    });

    it('should not drop topical data', () => {
      const currentTime = Date.now();
      const paramStorage = {
        ttl: 2592000,
        data: getData(currentTime),
        granularity: 86400,
      };

      const { data } = cleanData(paramStorage, currentTime);
      assert.deepEqual(data, getData(currentTime));
    });

    it('should drop outdated data', () => {
      const currentTime = Date.now();
      const ttl = 2592000;
      const paramStorage = {
        ttl,
        data: getData(currentTime),
        granularity: 86400,
      };
      const currentTimeShort = parseInt(currentTime / 1000, 10);

      // clear half of data
      const { data: data1 } = cleanData(paramStorage, currentTime + (ttl - 8) * 1000);
      // clear all data
      const { data: data2 } = cleanData(paramStorage, currentTime + (ttl - 3) * 1000);

      assert.deepEqual(data1, { [currentTimeShort - 5]: 2, [currentTimeShort - 3]: 1 });
      assert.deepEqual(data2, {});
    });
  });

  describe('#objectToTime', () => {
    it('should work with string arguments', () => {
      assert.equal(objectToTime('1day'), 86400);
      assert.equal(objectToTime('1week'), 7 * 86400);
      assert.equal(objectToTime('1month'), 30 * 86400);
      assert.equal(objectToTime('whatever'), 86400);
    });

    it('should work with object arguments', () => {
      assert.equal(objectToTime({ days: 2 }), 2 * 86400);
      assert.equal(objectToTime({ weeks: 3 }), 21 * 86400);
      assert.equal(objectToTime({ monthes: 2 }), 60 * 86400);
      assert.equal(objectToTime({ hours: 5 }), 5 * 3600);
      assert.equal(objectToTime({ minutes: 17 }), 17 * 60);
    });
  });

  describe('#counterInc', () => {
    it('should increment counter on empty data', () => {
      let paramsStorage = counterInc('foo', '1day', '1month', {});
      paramsStorage = counterInc('foo', '1day', '1month', { foo: paramsStorage });

      const firstKey = Object.keys(paramsStorage.data)[0];

      assert.ok(firstKey);
      assert.equal(paramsStorage.data[firstKey], 2);
    });

    it('should increment counter on non empty data', () => {
      const previosEventsCount = 7;
      const timestamp = new Date().getTime() - 86400001;
      let paramsStorage = {
        foo: {
          ttl: 2592000,
          data: { [timestamp]: previosEventsCount },
        },
      };

      paramsStorage = counterInc('foo', '1day', '1month', paramsStorage);
      const otherTimestamp = Object.keys(paramsStorage.data).filter(k => k !== timestamp)[0];

      assert.equal(Object.keys(paramsStorage.data).length, 2);
      assert.equal(paramsStorage.data[timestamp], previosEventsCount);
      assert.equal(paramsStorage.data[otherTimestamp], 1);
    });
  });

  describe('#counter', () => {
    it('should eval counter correct', () => {
      const previosEventsCount = 33;
      let paramsStorage = {
        foo: {
          ttl: 2592000,
          data: { [new Date().getTime() - 86401]: previosEventsCount },
          granularity: 86400,
        },
      };

      paramsStorage = counterInc('foo', '1day', '1month', paramsStorage);
      paramsStorage = counterInc('foo', '1day', '1month', { foo: paramsStorage });

      assert.equal(counter('foo', { foo: paramsStorage }), 35);
    });
  });
});
<|endoftext|>


<commit_before>describe('color-contrast', function () {
	'use strict';

	var fixture = document.getElementById('fixture');

	var checkContext = {
		_relatedNodes: [],
		_data: null,
		data: function (d) {
			this._data = d;
		},
		relatedNodes: function (rn) {
			this._relatedNodes = rn;
		}
	};

	afterEach(function () {
		fixture.innerHTML = '';
		checkContext._relatedNodes = [];
		checkContext._data = null;
	});

	it('should return store the proper values in data', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		var white = new axe.commons.color.Color(255, 255, 255, 1);
		var black = new axe.commons.color.Color(0, 0, 0, 1);
		assert.equal(checkContext._data.bgColor, white.toHexString());
		assert.equal(checkContext._data.fgColor, black.toHexString());
		assert.equal(checkContext._data.contrastRatio, '21.00');
		assert.equal(checkContext._data.fontWeight, 'bold');
		assert.closeTo(parseFloat(checkContext._data.fontSize), 14, 0.5);
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of bold tag', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of font weight', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of font size', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return false when there is not sufficient contrast because of font size', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isFalse(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, [target]);
	});

	it('should return true when there is sufficient contrast with explicit transparency', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast with implicit transparency', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return false when there is not sufficient contrast', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isFalse(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, [target]);
	});

	describe('matches', function () {

		it('should not match when there is no text', function () {
			fixture.innerHTML = '
' +
				'
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match when there is text', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match when there is text that is out of the container', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match when there is text that is out of the container with overflow hidden', function () {
			fixture.innerHTML = '
' +
				'text
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match when there is text that is in the scroll reach of container', function () {
			fixture.innerHTML = '
' +
				'text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should match when there is text that is only partially out of the container', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should match <input type="text">', function () {
			fixture.innerHTML = '<input type="text">';
			var target = fixture.querySelector('input');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="hidden">', function () {
			fixture.innerHTML = '<input type="hidden">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="checkbox">', function () {
			fixture.innerHTML = '<input type="checkbox">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="radio">', function () {
			fixture.innerHTML = '<input type="radio">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="color">', function () {
			fixture.innerHTML = '<input type="color">';
			var target = fixture.querySelector('input');
			// Some browsers will fallback to type=text for unknown input types (looking at you IE)
			if (target.type === 'color') {
				assert.isFalse(checks['color-contrast'].matches(target));
			}
		});

		it('should not match <input type="range">', function () {
			fixture.innerHTML = '<input type="range">';
			var target = fixture.querySelector('input');
			// Some browsers will fallback to type=text for unknown input types (looking at you IE)
			if (target.type === 'range') {
				assert.isFalse(checks['color-contrast'].matches(target));
			}
		});

		it('should match <select> with options', function () {
			fixture.innerHTML = '<select><option>Hello</option></select>';
			var target = fixture.querySelector('select');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <select> with no options', function () {
			fixture.innerHTML = '<select></select>';
			var target = fixture.querySelector('select');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match <textarea>', function () {
			fixture.innerHTML = '<textarea></textarea>';
			var target = fixture.querySelector('textarea');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <option>', function () {
			fixture.innerHTML = '<select><option>hi</option></select>';
			var target = fixture.querySelector('option');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match inputs that are disabled', function () {
			fixture.innerHTML = '<input type="text" disabled>';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));

		});

		it('should not match <textarea disabled>', function () {
			fixture.innerHTML = '<textarea disabled></textarea>';
			var target = fixture.querySelector('textarea');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <select> with options', function () {
			fixture.innerHTML = '<select disabled><option>Hello</option></select>';
			var target = fixture.querySelector('select');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match <button>', function () {
			fixture.innerHTML = '<button>hi</button>';
			var target = fixture.querySelector('button');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <button disabled>', function () {
			fixture.innerHTML = '<button disabled>hi</button>';
			var target = fixture.querySelector('button');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type=image>', function () {
			fixture.innerHTML = '<input type="image">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - explicit label', function () {
			fixture.innerHTML = 'Test<input type="text" id="t1" disabled>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (input)', function () {
			fixture.innerHTML = 'Test<input type="text" disabled>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (textarea)', function () {
			fixture.innerHTML = 'Test<textarea disabled>Hi</textarea>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (select)', function () {
			fixture.innerHTML = 'Test<select disabled><option>Test</option></select>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - aria-labelledby', function () {
			fixture.innerHTML = '
Test
<input type="text" aria-labelledby="bob t1 fred" disabled>';
			var target = fixture.querySelector('div');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should ignore position:fixed elements', function () {
			fixture.innerHTML = '

header

stuff This is some text

';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});
	});

});
<commit_msg>Should be tested against `evaluate()`<commit_after>describe('color-contrast', function () {
	'use strict';

	var fixture = document.getElementById('fixture');

	var checkContext = {
		_relatedNodes: [],
		_data: null,
		data: function (d) {
			this._data = d;
		},
		relatedNodes: function (rn) {
			this._relatedNodes = rn;
		}
	};

	afterEach(function () {
		fixture.innerHTML = '';
		checkContext._relatedNodes = [];
		checkContext._data = null;
	});

	it('should return store the proper values in data', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		var white = new axe.commons.color.Color(255, 255, 255, 1);
		var black = new axe.commons.color.Color(0, 0, 0, 1);
		assert.equal(checkContext._data.bgColor, white.toHexString());
		assert.equal(checkContext._data.fgColor, black.toHexString());
		assert.equal(checkContext._data.contrastRatio, '21.00');
		assert.equal(checkContext._data.fontWeight, 'bold');
		assert.closeTo(parseFloat(checkContext._data.fontSize), 14, 0.5);
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of bold tag', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of font weight', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast because of font size', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return false when there is not sufficient contrast because of font size', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isFalse(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, [target]);
	});

	it('should return true when there is sufficient contrast with explicit transparency', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast with implicit transparency', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');

		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return true when there is sufficient contrast', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, []);
	});

	it('should return false when there is not sufficient contrast', function () {
		fixture.innerHTML = '
' +
			'My text
';
		var target = fixture.querySelector('#target');
		assert.isFalse(checks['color-contrast'].evaluate.call(checkContext, target));
		assert.deepEqual(checkContext._relatedNodes, [target]);
	});

	describe('matches', function () {

		it('should not match when there is no text', function () {
			fixture.innerHTML = '
' +
				'
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match when there is text', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match when there is text that is out of the container', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match when there is text that is out of the container with overflow hidden', function () {
			fixture.innerHTML = '
' +
				'text
';
			var target = fixture.querySelector('#target');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match when there is text that is in the scroll reach of container', function () {
			fixture.innerHTML = '
' +
				'text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should match when there is text that is only partially out of the container', function () {
			fixture.innerHTML = '
' +
				'My text
';
			var target = fixture.querySelector('#target');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should match <input type="text">', function () {
			fixture.innerHTML = '<input type="text">';
			var target = fixture.querySelector('input');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="hidden">', function () {
			fixture.innerHTML = '<input type="hidden">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="checkbox">', function () {
			fixture.innerHTML = '<input type="checkbox">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="radio">', function () {
			fixture.innerHTML = '<input type="radio">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type="color">', function () {
			fixture.innerHTML = '<input type="color">';
			var target = fixture.querySelector('input');
			// Some browsers will fallback to type=text for unknown input types (looking at you IE)
			if (target.type === 'color') {
				assert.isFalse(checks['color-contrast'].matches(target));
			}
		});

		it('should not match <input type="range">', function () {
			fixture.innerHTML = '<input type="range">';
			var target = fixture.querySelector('input');
			// Some browsers will fallback to type=text for unknown input types (looking at you IE)
			if (target.type === 'range') {
				assert.isFalse(checks['color-contrast'].matches(target));
			}
		});

		it('should match <select> with options', function () {
			fixture.innerHTML = '<select><option>Hello</option></select>';
			var target = fixture.querySelector('select');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <select> with no options', function () {
			fixture.innerHTML = '<select></select>';
			var target = fixture.querySelector('select');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match <textarea>', function () {
			fixture.innerHTML = '<textarea></textarea>';
			var target = fixture.querySelector('textarea');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <option>', function () {
			fixture.innerHTML = '<select><option>hi</option></select>';
			var target = fixture.querySelector('option');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match inputs that are disabled', function () {
			fixture.innerHTML = '<input type="text" disabled>';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));

		});

		it('should not match <textarea disabled>', function () {
			fixture.innerHTML = '<textarea disabled></textarea>';
			var target = fixture.querySelector('textarea');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <select> with options', function () {
			fixture.innerHTML = '<select disabled><option>Hello</option></select>';
			var target = fixture.querySelector('select');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should match <button>', function () {
			fixture.innerHTML = '<button>hi</button>';
			var target = fixture.querySelector('button');
			assert.isTrue(checks['color-contrast'].matches(target));
		});

		it('should not match <button disabled>', function () {
			fixture.innerHTML = '<button disabled>hi</button>';
			var target = fixture.querySelector('button');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match <input type=image>', function () {
			fixture.innerHTML = '<input type="image">';
			var target = fixture.querySelector('input');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - explicit label', function () {
			fixture.innerHTML = 'Test<input type="text" id="t1" disabled>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (input)', function () {
			fixture.innerHTML = 'Test<input type="text" disabled>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (textarea)', function () {
			fixture.innerHTML = 'Test<textarea disabled>Hi</textarea>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - implicit label (select)', function () {
			fixture.innerHTML = 'Test<select disabled><option>Test</option></select>';
			var target = fixture.querySelector('label');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should not match a disabled input\'s label - aria-labelledby', function () {
			fixture.innerHTML = '
Test
<input type="text" aria-labelledby="bob t1 fred" disabled>';
			var target = fixture.querySelector('div');
			assert.isFalse(checks['color-contrast'].matches(target));
		});

		it('should ignore position:fixed elements above the target', function () {
			fixture.innerHTML = '

header

stuff This is some text

';
			assert.isTrue(checks['color-contrast'].evaluate.call(checkContext, target));
			assert.deepEqual(checkContext._relatedNodes, []);
		});
	});

});
<|endoftext|>


<commit_before><commit_msg>Add basic test for geojsonLayerController<commit_after>'use strict';

require('mocha-given')
var chai       = require('chai')
var expect     = chai.expect
var context    = describe
var catchError = require('catch-error')
var sinon      = require('sinon')
var sinonChai  = require('sinon-chai')
chai.use(sinonChai)

var gjLayerControllerFactory = require('../lib/geojsonLayerController')

class Map {}
class KeyController {}
var dataServiceFactory = () => {
  return {}
}
var popupPresenterFactory = () => {
  return {}
}
var stylePresenterFactory = () => {
  return {}
}
var filterFactory = () => {
  return {}
}

describe('geojsonLayerController', () => {
  describe('creating a geojsonLayerController', () => {
    var config, gjLayerController

    Given('some config', () => {
      config = {
        map: new Map(),
        keyController: new KeyController(),
        dataServiceFactory: dataServiceFactory,
        popupPresenterFactory: popupPresenterFactory,
        stylePresenterFactory: stylePresenterFactory,
        filterFactory: filterFactory
      }
    })
    When('the module is called with config', () => {
      gjLayerController = gjLayerControllerFactory(config)
    })
    Then('the module should be an object', () => {
      expect(gjLayerController).to.be.an('object')
    })
  })
})
<|endoftext|>


<commit_before>
var venueBlacklist = {
  547302:  "Ale Pupi",
  1379610: "Amica-ravintola Valtatie 30",
  1782433: "As Oy Sorsapuisto",
  951950:  "Keskustori",
  3324214: "Nalkala",
  125270:  "Näsin sauna",
  865959:  "Stefan's Steakhouse",
  1293012: "Tampere",
  2566357: "TKL bussi 28",
};

var beerBlacklist = {
  39534:  "Karhu A",
  39540:  "Karhu III",
  36800:  "Lapin Kulta Premium III",
  925902: "Long Drink Grapefruit",
};

angular.module('afteri', []).controller('afteriCtrl', ['$scope', '$http', function($scope, $http) {

  $http.get('/data/thepub.json').then(function (response) {

    var checkins = response.data.response.checkins.items;
    var filteredCheckins = _.reject(checkins, function(item) {
      return venueBlacklist[item.venue.venue_id] || beerBlacklist[item.beer.bid];
    });

    var topSuggestions = _(filteredCheckins)
      .uniq('venue.venue_id')
      .sortBy('beer.beer_abv')
      .reverse()
      .take(3)
      .value();

    $scope.suggestions = topSuggestions;
    $scope.checkins = checkins;

  });

}]);
<commit_msg>Stop prioritizing high-ABV beers<commit_after>
var venueBlacklist = {
  547302:  "Ale Pupi",
  1379610: "Amica-ravintola Valtatie 30",
  1782433: "As Oy Sorsapuisto",
  951950:  "Keskustori",
  3324214: "Nalkala",
  125270:  "Näsin sauna",
  865959:  "Stefan's Steakhouse",
  1293012: "Tampere",
  2566357: "TKL bussi 28",
};

var beerBlacklist = {
  39534:  "Karhu A",
  39540:  "Karhu III",
  36800:  "Lapin Kulta Premium III",
  925902: "Long Drink Grapefruit",
};

angular.module('afteri', []).controller('afteriCtrl', ['$scope', '$http', function($scope, $http) {

  $http.get('/data/thepub.json').then(function (response) {

    var checkins = response.data.response.checkins.items;
    var filteredCheckins = _.reject(checkins, function(item) {
      return venueBlacklist[item.venue.venue_id] || beerBlacklist[item.beer.bid];
    });

    var topSuggestions = _(filteredCheckins)
      .uniq('venue.venue_id')
      .take(3)
      .sortBy('beer.beer_abv')
      .reverse()
      .value();

    $scope.suggestions = topSuggestions;
    $scope.checkins = checkins;

  });

}]);
<|endoftext|>


<commit_before>
var venueBlacklist = {
  1379610: "Amica-ravintola Valtatie 30",
  1782433: "As Oy Sorsapuisto",
  865959:  "Stefan's Steakhouse",
};

var beerBlacklist = {
  39534: "Karhu A",
  39540: "Karhu III",
  36800: "Lapin Kulta Premium III",
};

angular.module('afteri', []).controller('afteriCtrl', ['$scope', '$http', function($scope, $http) {

  $http.get('data/thepub.json').then(function (response) {
    var checkins = _.reject(response.data.response.checkins.items, function(item) {
      return venueBlacklist[item.venue.venue_id] || beerBlacklist[item.beer.bid];
    });

    var topSuggestions = _(checkins)
      .uniq('venue.venue_id')
      .sortBy('beer.beer_abv')
      .reverse()
      .take(3)
      .value();

    $scope.suggestions = topSuggestions;
    $scope.checkins = checkins;

  });

}]);
<commit_msg>Update blacklists<commit_after>
var venueBlacklist = {
  547302:  "Ale Pupi",
  1379610: "Amica-ravintola Valtatie 30",
  1782433: "As Oy Sorsapuisto",
  951950:  "Keskustori",
  125270:  "Näsin sauna",
  865959:  "Stefan's Steakhouse",
  1293012: "Tampere",
  2566357: "TKL bussi 28",
};

var beerBlacklist = {
  39534:  "Karhu A",
  39540:  "Karhu III",
  36800:  "Lapin Kulta Premium III",
  925902: "Long Drink Grapefruit",
};

angular.module('afteri', []).controller('afteriCtrl', ['$scope', '$http', function($scope, $http) {

  $http.get('data/thepub.json').then(function (response) {
    var checkins = _.reject(response.data.response.checkins.items, function(item) {
      return venueBlacklist[item.venue.venue_id] || beerBlacklist[item.beer.bid];
    });

    var topSuggestions = _(checkins)
      .uniq('venue.venue_id')
      .sortBy('beer.beer_abv')
      .reverse()
      .take(3)
      .value();

    $scope.suggestions = topSuggestions;
    $scope.checkins = checkins;

  });

}]);
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Mar 03 2016 19:57:50 GMT-0600 (CST)
var Set = require('collections/set');
module.exports = function (config) {
  // Set up default files to test against
  var karmaTest = 'karma-test.js';
  var successTest = 'success-test.js';
  var phantomJsTest = 'phantomjs-test.js';
  var eofCommentTest = 'eof-comment-test.js';
  var failureTest = 'failure-test.js';
  var sourceMapTest = 'source-map-test.js';
  var uncaughtExceptionTest = 'uncaught-exception-test.js';
  // TODO: Restore `*-test.js` (DEV: This will intentionally fail lint)
  var testFiles = ['*-test.js'];
  var testFiles = ['node-script-src-test.js'];
  var excludeFiles = new Set([failureTest, karmaTest, phantomJsTest, sourceMapTest, uncaughtExceptionTest]);

  // If we are testing uncaught exceptions, then update our tests
  if (process.env.TEST_TYPE === 'UNCAUGHT_EXCEPTION') {
    testFiles = [uncaughtExceptionTest];
    excludeFiles.delete(uncaughtExceptionTest);
  } else if (process.env.TEST_TYPE === 'EOF_COMMENT') {
    testFiles = [eofCommentTest];
    excludeFiles.delete(eofCommentTest);
  } else if (process.env.TEST_TYPE === 'FAILURE') {
    testFiles = [failureTest];
    excludeFiles.delete(failureTest);
  } else if (process.env.TEST_TYPE === 'KARMA') {
    testFiles = [karmaTest];
    excludeFiles.delete(karmaTest);
  } else if (process.env.TEST_TYPE === 'PHANTOMJS') {
    testFiles = [successTest, phantomJsTest];
    excludeFiles = new Set();
  } else if (process.env.TEST_TYPE === 'SOURCE_MAP') {
    testFiles = [sourceMapTest];
    excludeFiles.delete(sourceMapTest);
  } else if (process.env.TEST_TYPE) {
    throw new Error('Unrecognized test type "' + process.env.TEST_TYPE + '"');
  }

  // Define our config
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: testFiles,

    // list of files to exclude
    exclude: excludeFiles.toArray(),

    browserNoActivityTimeout: 2000,
    client: {
      useIframe: false
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '*-test.js': ['electron']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Electron'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    // Load in our module as a plugin
    // https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/examples/simple/karma.conf.js
    plugins: [
        require('../../'),
        'karma-mocha',
        'karma-phantomjs-launcher'
    ]
  });
};
<commit_msg>Updated our test expectations<commit_after>// Karma configuration
// Generated on Thu Mar 03 2016 19:57:50 GMT-0600 (CST)
var Set = require('collections/set');
module.exports = function (config) {
  // Set up default files to test against
  var karmaTest = 'karma-test.js';
  var successTest = 'success-test.js';
  var phantomJsTest = 'phantomjs-test.js';
  var eofCommentTest = 'eof-comment-test.js';
  var failureTest = 'failure-test.js';
  var sourceMapTest = 'source-map-test.js';
  var uncaughtExceptionTest = 'uncaught-exception-test.js';
  // TODO: Restore `*-test.js` (DEV: This will intentionally fail lint)
  var testFiles = ['*-test.js'];
  var testFiles = ['node-generic-test.js', 'node-require-test.js'];
  var excludeFiles = new Set([failureTest, karmaTest, phantomJsTest, sourceMapTest, uncaughtExceptionTest]);

  // If we are testing uncaught exceptions, then update our tests
  if (process.env.TEST_TYPE === 'UNCAUGHT_EXCEPTION') {
    testFiles = [uncaughtExceptionTest];
    excludeFiles.delete(uncaughtExceptionTest);
  } else if (process.env.TEST_TYPE === 'EOF_COMMENT') {
    testFiles = [eofCommentTest];
    excludeFiles.delete(eofCommentTest);
  } else if (process.env.TEST_TYPE === 'FAILURE') {
    testFiles = [failureTest];
    excludeFiles.delete(failureTest);
  } else if (process.env.TEST_TYPE === 'KARMA') {
    testFiles = [karmaTest];
    excludeFiles.delete(karmaTest);
  } else if (process.env.TEST_TYPE === 'PHANTOMJS') {
    testFiles = [successTest, phantomJsTest];
    excludeFiles = new Set();
  } else if (process.env.TEST_TYPE === 'SOURCE_MAP') {
    testFiles = [sourceMapTest];
    excludeFiles.delete(sourceMapTest);
  } else if (process.env.TEST_TYPE) {
    throw new Error('Unrecognized test type "' + process.env.TEST_TYPE + '"');
  }

  // Define our config
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: testFiles,

    // list of files to exclude
    exclude: excludeFiles.toArray(),

    browserNoActivityTimeout: 2000,
    client: {
      useIframe: false
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '*-test.js': ['electron']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Electron'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    // Load in our module as a plugin
    // https://github.com/karma-runner/karma-chrome-launcher/blob/v0.2.2/examples/simple/karma.conf.js
    plugins: [
        require('../../'),
        'karma-mocha',
        'karma-phantomjs-launcher'
    ]
  });
};
<|endoftext|>


<commit_before>// All Models & Collections Used in the Tests
// (sort of mimics a simple multi-site blogging engine)
module.exports = function(Bookshelf) {

  var _ = require('lodash');

  function _parsed (attributes) {
    var parsed = {};
    Object.keys(attributes).forEach(function (name) {
      parsed[name + "_parsed"] = attributes[name];
    });
    return parsed;
  }

  function _format (attributes) {
    var formatted = {};
    Object.keys(attributes).forEach(function (name) {
      formatted[name.replace('_parsed', '')] = attributes[name];
    });
    return formatted;
  }

  var Info = Bookshelf.Model.extend({
    tableName: 'info'
  });

  var SiteMeta = Bookshelf.Model.extend({
    tableName: 'sitesmeta',
    site: function() {
      return this.belongsTo(Site);
    },
    info: function() {
      return this.hasOne(Info);
    }
  });

  var Uuid = Bookshelf.Model.extend({
    idAttribute: 'uuid',
    tableName: 'uuid_test'
  });

  var Site = Bookshelf.Model.extend({
    tableName: 'sites',
    defaults: {
      name: 'Your Cool Site'
    },
    authors: function() {
      return this.hasMany(Author);
    },
    photos: function() {
      return this.morphMany(Photo, 'imageable');
    },
    thumbnails: function() {
      return this.morphMany(Thumbnail, 'imageable', ["ImageableType", "ImageableId"]);
    },
    blogs: function() {
      return this.hasMany(Blog);
    },
    meta: function() {
      return this.hasOne(SiteMeta);
    },
    info: function() {
      return this.hasOne(Info).through(SiteMeta, 'meta_id');
    },
    admins: function() {
      return this.belongsToMany(Admin).withPivot('item');
    }
  });

  // A SiteParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var SiteParsed = Site.extend({
    parse: _parsed,
    format: _format,
    photos: function() {
      return this.morphMany(PhotoParsed, 'imageable');
    }
  });

  var Admin = Bookshelf.Model.extend({
    tableName: 'admins',
    hasTimestamps: true
  });

  // Author of a blog post.
  var Author = Bookshelf.Model.extend({
    tableName: 'authors',
    site: function() {
      return this.belongsTo(Site);
    },
    photo: function() {
      return this.morphOne(Photo, 'imageable');
    },
    thumbnail: function() {
      return this.morphOne(Thumbnail, 'imageable', ["ImageableType", "ImageableId"]);
    },
    posts: function() {
      return this.belongsToMany(Post);
    },
    ownPosts: function() {
      return this.hasMany(Post, 'owner_id');
    },
    blogs: function() {
      return this.belongsToMany(Blog).through(Post, 'owner_id');
    }
  });

  // A AuthorParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var AuthorParsed = Author.extend({
    parse: _parsed,
    format: _format,
    photos: function() {
      return this.morphMany(PhotoParsed, 'imageable');
    }
  });

  // A blog for a site.
  var Blog = Bookshelf.Model.extend({
    tableName: 'blogs',
    defaults: {
      title: ''
    },
    site: function() {
      return this.belongsTo(Site);
    },
    posts: function() {
      return this.hasMany(Post);
    },
    parsedPosts: function () {
      return this.hasMany(PostParsed);
    },
    validate: function(attrs) {
      if (!attrs.title) return 'A title is required.';
    },
    comments: function() {
      return this.hasMany(Comment).through(Post);
    }
  });

  // An individual post on a blog.
  var Post = Bookshelf.Model.extend({
    tableName: 'posts',
    defaults: {
      author: '',
      title: '',
      body: '',
      published: false
    },
    hasTimestamps: true,
    blog: function() {
      return this.belongsTo(Blog);
    },
    authors: function() {
      return this.belongsToMany(Author);
    },
    tags: function() {
      return this.belongsToMany(Tag);
    },
    comments: function() {
      return this.hasMany(Comment);
    }
  });

  // A PostParsed appends "_parsed" to each field name on fetch
  var PostParsed = Post.extend({
    parse: _parsed
  });

  var Posts = Bookshelf.Collection.extend({
    model: Post
  });

  var Comment = Bookshelf.Model.extend({
    tableName: 'comments',
    defaults: {
      email: '',
      post: ''
    },
    posts: function() {
      return this.belongsTo(Post);
    },
    blog: function() {
      return this.belongsTo(Blog).through(Post);
    }
  });

  var Tag = Bookshelf.Model.extend({
    tableName: 'tags',
    posts: function() {
      return this.belongsToMany(Post);
    }
  });

  var User = Bookshelf.Model.extend({
    tableName: 'users',
    idAttribute: 'uid',
    roles: function() {
      return this.belongsToMany(Role, 'users_roles', 'uid', 'rid');
    }
  });

  var Role = Bookshelf.Model.extend({
    tableName: 'roles',
    idAttribute: 'rid',
    users: function(){
      return this.belongsToMany(User, 'users_roles', 'rid', 'uid');
    }
  });

  var Photo = Bookshelf.Model.extend({
    tableName: 'photos',
    imageable: function() {
      return this.morphTo('imageable', Site, Author);
    },
    imageableParsed: function() {
      return this.morphTo('imageable', SiteParsed, AuthorParsed);
    }
  });

  var Thumbnail = Bookshelf.Model.extend({
    tableName: 'thumbnails',
    imageable: function() {
      return this.morphTo('imageable', ["ImageableType", "ImageableId"], Site, Author);
    }
  });

  // A PhotoParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var PhotoParsed = Photo.extend({
    parse: _parsed,
    format: _format
  });

  var Photos = Bookshelf.Collection.extend({
    model: Photo
  });

  var Settings = Bookshelf.Model.extend({ tableName: 'Settings' });

  var Customer = Bookshelf.Model.extend({
    tableName: 'Customer',
    settings: function () {
      return this.hasOne(Settings);
    }
  });

  var Hostname = Bookshelf.Model.extend({
    tableName: 'hostnames',
    idAttribute: 'hostname',
    instance: function() {
      return this.belongsTo(Instance);
    }
  });

  var Instance = Bookshelf.Model.extend({
    tableName: 'instances',
    hostnames: function() {
      return this.hasMany(Hostname);
    }
  });

  var ParsedModel = Bookshelf.Model.extend({
    format: function (attrs) {
      return _.transform(attrs, function (result, val, key) {
        result[_.snakeCase(key)] = val;
      });
    },
    parse: function (attrs) {
      return _.transform(attrs, function (result, val, key) {
        result[_.camelCase(key)] = val;
      });
    }
  });

  // Has columns: id, user_id, token
  var UserTokenParsed = ParsedModel.extend({
    tableName: 'tokens',
    user: function () {
      return this.belongsTo(UserParsed);
    }
  });

  // Has columns: id, email, first_name, last_name
  var UserParsed = ParsedModel.extend({
    tableName: 'parsed_users',
  });

  /**
   * Issue #578 - lifecycle events on pivot model for belongsToMany().through()
   *
   * Here we bootstrap some models involved in a .belongsToMany().through()
   * relationship. The models are overridden with actual relationship methods
   * e.g. `lefts: function () { return this.belongsToMany(LeftModel).through(JoinModel) }`
   * within the tests to ensure the appropriate lifecycle events are being
   * triggered.
   */

  var LeftModel = Bookshelf.Model.extend({
    tableName: 'lefts'
  });

  var RightModel = Bookshelf.Model.extend({
    tableName: 'rights'
  });

  var JoinModel = Bookshelf.Model.extend({
    tableName: 'lefts_rights',
    defaults: { parsedName: '' },
    format: function (attrs) {
      return _.reduce(attrs, function(memo, val, key) {
        memo[_.snakeCase(key)] = val;
        return memo;
      }, {});
    },
    parse: function (attrs) {
      return _.reduce(attrs, function(memo, val, key) {
        memo[_.camelCase(key)] = val;
        return memo;
      }, {});
    },
    lefts: function() {
      return this.belongsTo(LeftModel);
    },
    rights: function() {
      return this.belongsTo(RightModel);
    }
  });

  return {
    Models: {
      Site: Site,
      SiteParsed: SiteParsed,
      SiteMeta: SiteMeta,
      Admin: Admin,
      Author: Author,
      AuthorParsed: AuthorParsed,
      Blog: Blog,
      Post: Post,
      PostParsed: PostParsed,
      Comment: Comment,
      Tag: Tag,
      User: User,
      UserParsed: UserParsed,
      UserTokenParsed: UserTokenParsed,
      Role: Role,
      Photo: Photo,
      PhotoParsed: PhotoParsed,
      Thumbnail: Thumbnail,
      Info: Info,
      Customer: Customer,
      Settings: Settings,
      Instance: Instance,
      Hostname: Hostname,
      Uuid: Uuid,
      LeftModel: LeftModel,
      RightModel: RightModel,
      JoinModel: JoinModel
    }
  };

};
<commit_msg>Update integration test models.<commit_after>// All Models & Collections Used in the Tests
// (sort of mimics a simple multi-site blogging engine)
module.exports = function(Bookshelf) {

  var _ = require('lodash');

  function _parsed (attributes) {
    var parsed = {};
    Object.keys(attributes).forEach(function (name) {
      parsed[name + "_parsed"] = attributes[name];
    });
    return parsed;
  }

  function _format (attributes) {
    var formatted = {};
    Object.keys(attributes).forEach(function (name) {
      formatted[name.replace('_parsed', '')] = attributes[name];
    });
    return formatted;
  }

  var Info = Bookshelf.Model.extend({
    tableName: 'info'
  });

  var SiteMeta = Bookshelf.Model.extend({
    tableName: 'sitesmeta',
    site: function() {
      return this.belongsTo(Site);
    },
    info: function() {
      return this.hasOne(Info);
    }
  });

  var Uuid = Bookshelf.Model.extend({
    idAttribute: 'uuid',
    tableName: 'uuid_test'
  });

  var Site = Bookshelf.Model.extend({
    tableName: 'sites',
    defaults: {
      name: 'Your Cool Site'
    },
    authors: function() {
      return this.hasMany(Author);
    },
    photos: function() {
      return this.morphMany(Photo, 'imageable');
    },
    thumbnails: function() {
      return this.morphMany(Thumbnail, 'imageable', ["ImageableType", "ImageableId"]);
    },
    blogs: function() {
      return this.hasMany(Blog);
    },
    meta: function() {
      return this.hasOne(SiteMeta);
    },
    info: function() {
      return this.hasOne(Info).through(SiteMeta, 'meta_id');
    },
    admins: function() {
      return this.belongsToMany(Admin).withPivot('item');
    }
  });

  // A SiteParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var SiteParsed = Site.extend({
    parse: _parsed,
    format: _format,
    photos: function() {
      return this.morphMany(PhotoParsed, 'imageable');
    }
  });

  var Admin = Bookshelf.Model.extend({
    tableName: 'admins',
    hasTimestamps: true
  });

  // Author of a blog post.
  var Author = Bookshelf.Model.extend({
    tableName: 'authors',
    site: function() {
      return this.belongsTo(Site);
    },
    photo: function() {
      return this.morphOne(Photo, 'imageable');
    },
    thumbnail: function() {
      return this.morphOne(Thumbnail, 'imageable', ["ImageableType", "ImageableId"]);
    },
    posts: function() {
      return this.belongsToMany(Post);
    },
    ownPosts: function() {
      return this.hasMany(Post, 'owner_id');
    },
    blogs: function() {
      return this.belongsToMany(Blog).through(Post, 'owner_id');
    }
  });

  // A AuthorParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var AuthorParsed = Author.extend({
    parse: _parsed,
    format: _format,
    photos: function() {
      return this.morphMany(PhotoParsed, 'imageable');
    }
  });

  // A blog for a site.
  var Blog = Bookshelf.Model.extend({
    tableName: 'blogs',
    defaults: {
      title: ''
    },
    site: function() {
      return this.belongsTo(Site);
    },
    posts: function() {
      return this.hasMany(Post);
    },
    parsedPosts: function () {
      return this.hasMany(PostParsed);
    },
    validate: function(attrs) {
      if (!attrs.title) return 'A title is required.';
    },
    comments: function() {
      return this.hasMany(Comment).through(Post);
    }
  });

  // An individual post on a blog.
  var Post = Bookshelf.Model.extend({
    tableName: 'posts',
    defaults: {
      name: '',
      content: ''
    },
    hasTimestamps: false,
    blog: function() {
      return this.belongsTo(Blog);
    },
    authors: function() {
      return this.belongsToMany(Author);
    },
    tags: function() {
      return this.belongsToMany(Tag);
    },
    comments: function() {
      return this.hasMany(Comment);
    }
  });

  // A PostParsed appends "_parsed" to each field name on fetch
  var PostParsed = Post.extend({
    parse: _parsed
  });

  var Posts = Bookshelf.Collection.extend({
    model: Post
  });

  var Comment = Bookshelf.Model.extend({
    tableName: 'comments',
    defaults: {
      email: '',
      comment: ''
    },
    posts: function() {
      return this.belongsTo(Post);
    },
    blog: function() {
      return this.belongsTo(Blog).through(Post);
    }
  });

  var Tag = Bookshelf.Model.extend({
    tableName: 'tags',
    posts: function() {
      return this.belongsToMany(Post);
    }
  });

  var User = Bookshelf.Model.extend({
    tableName: 'users',
    idAttribute: 'uid',
    roles: function() {
      return this.belongsToMany(Role, 'users_roles', 'uid', 'rid');
    }
  });

  var Role = Bookshelf.Model.extend({
    tableName: 'roles',
    idAttribute: 'rid',
    users: function(){
      return this.belongsToMany(User, 'users_roles', 'rid', 'uid');
    }
  });

  var Photo = Bookshelf.Model.extend({
    tableName: 'photos',
    imageable: function() {
      return this.morphTo('imageable', Site, Author);
    },
    imageableParsed: function() {
      return this.morphTo('imageable', SiteParsed, AuthorParsed);
    }
  });

  var Thumbnail = Bookshelf.Model.extend({
    tableName: 'thumbnails',
    imageable: function() {
      return this.morphTo('imageable', ["ImageableType", "ImageableId"], Site, Author);
    }
  });

  // A PhotoParsed appends "_parsed" to each field name on fetch
  // and removes "_parsed" when formatted
  var PhotoParsed = Photo.extend({
    parse: _parsed,
    format: _format
  });

  var Photos = Bookshelf.Collection.extend({
    model: Photo
  });

  var Settings = Bookshelf.Model.extend({ tableName: 'Settings' });

  var Customer = Bookshelf.Model.extend({
    tableName: 'Customer',
    settings: function () {
      return this.hasOne(Settings);
    }
  });

  var Hostname = Bookshelf.Model.extend({
    tableName: 'hostnames',
    idAttribute: 'hostname',
    instance: function() {
      return this.belongsTo(Instance);
    }
  });

  var Instance = Bookshelf.Model.extend({
    tableName: 'instances',
    hostnames: function() {
      return this.hasMany(Hostname);
    }
  });

  var ParsedModel = Bookshelf.Model.extend({
    format: function (attrs) {
      return _.transform(attrs, function (result, val, key) {
        result[_.snakeCase(key)] = val;
      });
    },
    parse: function (attrs) {
      return _.transform(attrs, function (result, val, key) {
        result[_.camelCase(key)] = val;
      });
    }
  });

  // Has columns: id, user_id, token
  var UserTokenParsed = ParsedModel.extend({
    tableName: 'tokens',
    user: function () {
      return this.belongsTo(UserParsed);
    }
  });

  // Has columns: id, email, first_name, last_name
  var UserParsed = ParsedModel.extend({
    tableName: 'parsed_users',
  });

  /**
   * Issue #578 - lifecycle events on pivot model for belongsToMany().through()
   *
   * Here we bootstrap some models involved in a .belongsToMany().through()
   * relationship. The models are overridden with actual relationship methods
   * e.g. `lefts: function () { return this.belongsToMany(LeftModel).through(JoinModel) }`
   * within the tests to ensure the appropriate lifecycle events are being
   * triggered.
   */

  var LeftModel = Bookshelf.Model.extend({
    tableName: 'lefts'
  });

  var RightModel = Bookshelf.Model.extend({
    tableName: 'rights'
  });

  var JoinModel = Bookshelf.Model.extend({
    tableName: 'lefts_rights',
    defaults: { parsedName: '' },
    format: function (attrs) {
      return _.reduce(attrs, function(memo, val, key) {
        memo[_.snakeCase(key)] = val;
        return memo;
      }, {});
    },
    parse: function (attrs) {
      return _.reduce(attrs, function(memo, val, key) {
        memo[_.camelCase(key)] = val;
        return memo;
      }, {});
    },
    lefts: function() {
      return this.belongsTo(LeftModel);
    },
    rights: function() {
      return this.belongsTo(RightModel);
    }
  });

  return {
    Models: {
      Site: Site,
      SiteParsed: SiteParsed,
      SiteMeta: SiteMeta,
      Admin: Admin,
      Author: Author,
      AuthorParsed: AuthorParsed,
      Blog: Blog,
      Post: Post,
      PostParsed: PostParsed,
      Comment: Comment,
      Tag: Tag,
      User: User,
      UserParsed: UserParsed,
      UserTokenParsed: UserTokenParsed,
      Role: Role,
      Photo: Photo,
      PhotoParsed: PhotoParsed,
      Thumbnail: Thumbnail,
      Info: Info,
      Customer: Customer,
      Settings: Settings,
      Instance: Instance,
      Hostname: Hostname,
      Uuid: Uuid,
      LeftModel: LeftModel,
      RightModel: RightModel,
      JoinModel: JoinModel
    }
  };

};
<|endoftext|>


<commit_before>import test from 'ava'
import fs from 'fs-extra'
import Promise from 'bluebird'
const remove = Promise.promisify(fs.remove)
const tmpdir = require('os').tmpdir()

import { gatsby } from '../support'

test('calling gatsby new succesfully creates new site from default starter', async t => {
  await remove(`${tmpdir}/gatsby-default-starter`)
  const noArgs = await gatsby(['new', `${tmpdir}/tmp/gatsby-default-starter`])
  console.log(noArgs)
  t.is(noArgs.code, 0)
})
<commit_msg>Remove console.log<commit_after>import test from 'ava'
import fs from 'fs-extra'
import Promise from 'bluebird'
const remove = Promise.promisify(fs.remove)
const tmpdir = require('os').tmpdir()

import { gatsby } from '../support'

test('calling gatsby new succesfully creates new site from default starter', async t => {
  await remove(`${tmpdir}/gatsby-default-starter`)
  const noArgs = await gatsby(['new', `${tmpdir}/tmp/gatsby-default-starter`])
  t.is(noArgs.code, 0)
})
<|endoftext|>


<commit_before>

(function($, moment){

	$('#listado-mesas').live('pageshow',function(event, ui){

		/**
        pintar celdas para marcar
        **/
		var $ancla = null,
			$anterior = null;

		$('#listado-mesas').delegate('td.libre', 'mousedown', function(e) {
			if ( $ancla === null ) {
				$ancla = $anterior = $(this);
				$(this).addClass('ancla-mark');
			}
        });

		$('#listado-mesas').delegate('td.libre', 'mouseover', function(e) {
			if ( $ancla && $anterior ) {
				if ( $anterior.next()[0] == $(this)[0] ) {
					$(this).addClass('future-mark');
					$anterior = $(this);
				}
				if ( $anterior.prev()[0] == $(this)[0] ) {
					$anterior.removeClass('future-mark');
					$anterior = $(this);
				}
			}
        });

        $('body').bind( 'mouseup', function(e) {
        	if ( $ancla ) {
        		$ancla.removeClass('ancla-mark');
				$ancla.parent().find('.future-mark').removeClass('future-mark');
				$ancla = $anterior = null;
        	}
        });

        /**
        Popsible ancla ON HOVER
        **/
        $('#listado-mesas').delegate('td.libre', 'mouseover', function(e) {
			if ( $ancla === null ) {
				$(this).addClass('posible-ancla-mark');
			}
        });

		$('#listado-mesas').delegate('td.libre', 'mouseout', function(e) {
			if ( $ancla === null ) {
				$(this).removeClass('posible-ancla-mark');
			}
        });

        /**
        Creacion de mesa nueva con chekin - checkout
        **/
		var dayCin, dayCout, mozo;
		$('#listado-mesas').delegate('td.libre', 'mousedown', function(e) {
			dayCin = $(this).data('day');
			if (!dayCin) {
				// si no hay dia es porque me pare sobre una reserva, entonces tomo su fecha checkout
				dayCin = $(this).data('checkout');
			}
			mozo =  $(this).parents('.mozo-row').data('mozo-id');
        });

        $('#listado-mesas').delegate('td.libre', 'mouseup', function(e) {
			dayCout = moment( $(this).data('day') ).add(1, 'day').format('YYYY-MM-DD');
			if (!dayCout) {
				// si no hay dia es porque me pare sobre una reserva, entonces tomo su fecha checkout
				dayCout = $(this).data('checkin');
			}
			var mozo2 =  $(this).parents('.mozo-row').data('mozo-id');
			if ( dayCin && dayCout && mozo2 == mozo && dayCout != dayCin )  {
				var miniMesa = {
					mozo_id: mozo,
					numero: 1,
					checkin: dayCin,
					checkout: dayCout
				}
				var mesa = Risto.Adition.adicionar.crearNuevaMesa( miniMesa );
                Risto.Adition.EventHandler.mesaSeleccionada( {"mesa": mesa} );
                Risto.Adition.adicionar.setCurrentMesa( mesa );
                $.mobile.changePage('#mesa-view');
			}
            dayCin = dayCout = mozo = null;
        });

    });

    $('#listado-mesas').live('pagebeforehide',function(event, ui){
         $('#listado-mesas').undelegate('td.mozo-col', 'mousedown');
         $('#listado-mesas').undelegate('td.mozo-col', 'mouseup');
    });

	var CalendarGrid = function() {
        this.cantDayShown	= ko.observable(35);
        this.months         = ko.observableArray( [] );
        this.days           = ko.observableArray( [] );

        // agrego atributos generales
        Risto.modelizar(this);

        return this.initialize();
	}

	CalendarGrid.prototype =  {

		initialize: function () {
			var from  = moment().toDate(),
				to    = moment().add( this.cantDayShown(), 'days' ).toDate();

			this.setFromToDate(from, to);
		},

		setFromToDate: function ( from, to) {

			var days = [],
				months = {};

			moment().range( from , to ).by('days', function(moment) {
			  	days.push( moment );

			  	// armar meses array
			  	monthKey = "__" + moment.month();
			  	if ( months.hasOwnProperty(monthKey) ) {
			  		months[monthKey].cant++;
			  	} else {
			  		months[monthKey] = {
			  			cant: 1,
			  			name: moment.format("MMMM")
			  		}
			  	}
			});

			// armar array (convertir de object a array)
		  	var aMonths = [];
		  	for (var i in months) {
		  		aMonths.push( months[i] );
		  	}

			this.days(days);
			this.months(aMonths);

		},

		backDay: function () {
			var first = Risto.Adition.adicionar.calendarGrid.days()[0].subtract(1, 'day');
			var last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-2];

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		prevDay: function () {
			var first = Risto.Adition.adicionar.calendarGrid.days()[1],
				last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-1].add(1, 'day');

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		backWeek: function () {
			var weekCantDays = 15;
			var first = Risto.Adition.adicionar.calendarGrid.days()[0].subtract(weekCantDays, 'day');
			var last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-weekCantDays-1];

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		prevWeek: function () {
			var weekCantDays = 15;
			var first = Risto.Adition.adicionar.calendarGrid.days()[weekCantDays-1],
				last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-1].add(weekCantDays, 'day');

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},
	}

	Risto.CalendarGrid = CalendarGrid;

})(jQuery, moment);<commit_msg>bind mejorado para la grilla<commit_after>

(function($, moment){

	$('#listado-mesas').live('pageshow',function(event, ui){

		/**
        pintar celdas para marcar
        **/
		var $ancla = null,
			$anterior = null;

		function agregarAncla ( $el ) {
			if ( $ancla === null ) {
				$ancla = $anterior = $el;
				$el.addClass('ancla-mark');
			}
		}

		function mostrarSiguienteAncla ( $el ) {
			if ( $ancla && $anterior ) {
				if ( $anterior.next()[0] == $el[0] ) {
					$el.addClass('future-mark');
					$anterior = $el;
				}
				if ( $anterior.prev()[0] == $el[0] ) {
					$anterior.removeClass('future-mark');
					$anterior = $el;
				}
			}
		}

		function cortarAncla( $el ) {
			if ( $ancla ) {
        		$ancla.removeClass('ancla-mark');
				$ancla.parent().find('.future-mark').removeClass('future-mark');
				$ancla = $anterior = null;
        	}
		}

		function mostrarPosibleAncla( $el ) {
			if ( $ancla === null ) {
				$el.addClass('posible-ancla-mark');
			}
		}

		function ocultarPosibleAncla( $el ) {
			if ( $ancla === null ) {
				$el.removeClass('posible-ancla-mark');
			}
		}

		/**
        Creacion de mesa nueva con chekin - checkout
        **/
		var dayCin, dayCout, mozo;

		function iniciarCheckin( $el ) {
			dayCin = $el.data('day');
			if (!dayCin) {
				// si no hay dia es porque me pare sobre una reserva, entonces tomo su fecha checkout
				dayCin = $el.data('checkout');
			}
			mozo =  $el.parents('.mozo-row').data('mozo-id');
		}

		function iniciarCheckout( $el ) {
			dayCout = moment( $el.data('day') ).add(1, 'day').format('YYYY-MM-DD');
			if (!dayCout) {
				// si no hay dia es porque me pare sobre una reserva, entonces tomo su fecha checkout
				dayCout = $el.data('checkin');
			}
			var mozo2 =  $el.parents('.mozo-row').data('mozo-id');
			if ( dayCin && dayCout && mozo2 == mozo && dayCout != dayCin )  {
				var miniMesa = {
					mozo_id: mozo,
					numero: 1,
					checkin: dayCin,
					checkout: dayCout
				}
				var mesa = Risto.Adition.adicionar.crearNuevaMesa( miniMesa );
                Risto.Adition.EventHandler.mesaSeleccionada( {"mesa": mesa} );
                Risto.Adition.adicionar.setCurrentMesa( mesa );
                $.mobile.changePage('#mesa-view');
			}
            dayCin = dayCout = mozo = null;
		}

		$(this).delegate('td.libre', 'mousedown', function(e) {
			agregarAncla( $(this) );
			iniciarCheckin( $(this) );
        });

		$(this).delegate('.mozo-mesas td.libre', 'mouseenter', function(e) {
			mostrarPosibleAncla( $(this) );
			mostrarSiguienteAncla( $(this) );
        });

        $('body').bind( 'mouseup', function(e) {
        	cortarAncla( $(this) );
        });

		$(this).delegate('.mozo-mesas td.libre', 'mouseleave', function(e) {
			ocultarPosibleAncla( $(this) );
        });

        $(this).delegate('.mozo-mesas td.libre', 'mouseup', function(e) {
			iniciarCheckout( $(this) );
        });

    });

    $('#listado-mesas').live('pagebeforehide',function(event, ui){
         $(this).undelegate('td.libre', 'mousedown');
         $(this).undelegate('.mozo-mesas td.libre', 'mouseenter');
         $('body').unbind( 'mouseup');
         $(this).undelegate('.mozo-mesas td.libre', 'mouseleave');
         $(this).undelegate('.mozo-mesas td.libre', 'mouseup');
    });

	var CalendarGrid = function() {
        this.cantDayShown	= ko.observable(35);
        this.months         = ko.observableArray( [] );
        this.days           = ko.observableArray( [] );

        // agrego atributos generales
        Risto.modelizar(this);

        return this.initialize();
	}

	CalendarGrid.prototype =  {

		initialize: function () {
			var from  = moment().toDate(),
				to    = moment().add( this.cantDayShown(), 'days' ).toDate();

			this.setFromToDate(from, to);
		},

		setFromToDate: function ( from, to) {

			var days = [],
				months = {};

			moment().range( from , to ).by('days', function(moment) {
			  	days.push( moment );

			  	// armar meses array
			  	monthKey = "__" + moment.month();
			  	if ( months.hasOwnProperty(monthKey) ) {
			  		months[monthKey].cant++;
			  	} else {
			  		months[monthKey] = {
			  			cant: 1,
			  			name: moment.format("MMMM")
			  		}
			  	}
			});

			// armar array (convertir de object a array)
		  	var aMonths = [];
		  	for (var i in months) {
		  		aMonths.push( months[i] );
		  	}

			this.days(days);
			this.months(aMonths);

		},

		backDay: function () {
			var first = Risto.Adition.adicionar.calendarGrid.days()[0].subtract(1, 'day');
			var last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-2];

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		prevDay: function () {
			var first = Risto.Adition.adicionar.calendarGrid.days()[1],
				last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-1].add(1, 'day');

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		backWeek: function () {
			var weekCantDays = 15;
			var first = Risto.Adition.adicionar.calendarGrid.days()[0].subtract(weekCantDays, 'day');
			var last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-weekCantDays-1];

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},

		prevWeek: function () {
			var weekCantDays = 15;
			var first = Risto.Adition.adicionar.calendarGrid.days()[weekCantDays-1],
				last = Risto.Adition.adicionar.calendarGrid.days()[Risto.Adition.adicionar.calendarGrid.days().length-1].add(weekCantDays, 'day');

			Risto.Adition.adicionar.calendarGrid.setFromToDate(first, last);
		},
	}

	Risto.CalendarGrid = CalendarGrid;

})(jQuery, moment);<|endoftext|>