<commit_before>ScriptLoader.load(
    'GridManager'
);
var FILE_COOKIE_NAME = 'NRGNFRPID';

Grid.implement({
    _popImage:function (path, tmplElement) {
        var popUpImg = new Element('img', {'src':'resizer/w298-h224/' + path, 'width':60, 'height':45, 'styles':{
            border:'1px solid gray',
            'border-radius':'10px',
            'z-index':100
        }, 'events':{
            'click':function (e) {
                this.destroy()
            },
            'mouseleave':function (e) {
                this.destroy();
            }
        }}).inject(document.body).position({'relativeTo':tmplElement, 'position':'center'}).set('morph', {duration:'short', transition:'linear'});
        var p = popUpImg.getPosition();
        popUpImg.morph({width:298, height:224, left:p.x - 112, top:p.y - 149});
    },

    iterateFields:function (record, fieldName, row) {
// Пропускаем невидимые поля.
        if (!this.metadata[fieldName].visible ||
            this.metadata[fieldName].type == 'hidden') return;
        var cell = new Element('td').injectInside(row);
        if (fieldName == 'upl_path') {
            cell.setStyles({ 'text-align':'center', 'vertical-align':'middle' });

            var image = new Element('img', {src:'about:blank'});
            var tmt, dimensions = {'width':40, 'height':40};
            var container = new Element('div', {'class':'thumb_container'}).inject(cell);

            switch (record['upl_internal_type']) {
                case 'folder':
                    image.setProperty('src', 'images/icons/icon_folder.gif');
                    break;
                case 'repo':
                    image.setProperty('src', 'images/icons/icon_repository.gif');
                    break;
                case 'folderup':
                    image.setProperty('src', 'images/icons/icon_folder_up.gif');
                    break;
                case 'video':
                case 'image':
                    dimensions = {'width':60, 'height':45};
                    image.setProperty('src', 'resizer/w60-h45/' + record[fieldName]).addEvents({
                        'error':function () {
                            image.setProperty('src', 'images/icons/icon_error_image.gif');
                            container.removeEvents('mouseenter').removeEvent('mouseleave');
                        }
                    }).setStyles({'border-radius':'5px', 'border':'1px solid transparent'});
                    container.addEvents({
                        'mouseenter':function (e) {
                            var el = $(e.target);
                            if (el.get('tag') != 'img') {
                                el = el.getElement('img');
                            }
                            el.setStyle('border', '1px solid gray');
                            tmt = this._popImage.delay(700, this, [record[fieldName], el])
                        }.bind(this),
                        'mouseleave':function (e) {
                            var el = $(e.target);
                            if (el.get('tag') != 'img') {
                                el = el.getElement('img');
                            }
                            el.setStyle('border', '1px solid transparent');
                            if (tmt) {
                                clearTimeout(tmt);
                            }
                        }
                    });

                    if (record['upl_internal_type'] == 'video') {
                        container.grab(new Element('div', {'class':'video_file'}));
                    }
                    break;
                default:
                    dimensions = {'width':39, 'height':48};
                    image.setProperty('src', 'images/icons/icon_undefined.gif');
                    break;
            }
            image.setProperties(dimensions).inject(container);
        }
        else if (fieldName == 'upl_properties') {
            cell.addClass('properties');
            var propsTable = new Element('tbody');
            cell.grab(new Element('table').grab(propsTable));

            if (!record['upl_internal_type'].test('folder|repo')) {
                if (record['upl_mime_type'])
                    new Element('tr').inject(propsTable).adopt([
                        new Element('td', {'html':this.metadata['upl_mime_type'].title + ' :'}),
                        new Element('td', {'html':record['upl_mime_type']})
                    ]
                    );
                switch (record['upl_internal_type']) {
                    case 'video':
                        if (record['upl_duration'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_duration'].title + ' :'}),
                                new Element('td', {'html':record['upl_duration']})
                            ]
                            );
                        break;
                    case 'image':
                        if (record['upl_width'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_width'].title + ' :'}),
                                new Element('td', {'html':record['upl_width']})
                            ]
                            );
                        if (record['upl_height'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_height'].title + ' :'}),
                                new Element('td', {'html':record['upl_height']})
                            ]
                            );
                        break;
                    default :
                        break;
                }
                new Element('tr').inject(propsTable).adopt([
                    new Element('td', {'html':this.metadata['upl_publication_date'].title + ' :'}),
                    new Element('td', {'html':record['upl_publication_date']})
                ]
                );
            }
        }
        else {
            var fieldValue = '';
            if (record[fieldName]) {
                var fieldValue = record[fieldName].clean();
            }
            if (fieldValue != '') cell.set('html', fieldValue);
            //if (fieldValue != '') cell.appendText(fieldValue);
            else cell.set('html', ' ');
        }
    }
});
var FileRepository = new Class({
    Extends:GridManager,
    initialize:function (element) {
        this.parent(element);
        this.currentPID = false;
    },
    onDoubleClick:function () {
        this.open();
    },
    onSelect:function () {
        var r = this.grid.getSelectedRecord(), control;
        this.toolbar.enableControls();
        var openBtn = this.toolbar.getControlById('open');
        switch (r.upl_internal_type) {
            case 'folder':
                if (openBtn)openBtn.enable();
                break;
            case 'folderup':
                this.toolbar.disableControls();
                if (openBtn)openBtn.enable();
                this.toolbar.getControlById('addDir').enable();
                this.toolbar.getControlById('add').enable()
                break;
            case 'repo':
                this.toolbar.disableControls();
                if (openBtn)openBtn.enable();
                break;
            default:
                //this.toolbar.getControlById('open').disable();
                break;
        }
    },
    processServerResponse:function (result) {

        if (!this.initialized) {
            this.grid.setMetadata(result.meta);
            this.initialized = true;
        }
        if (!result.data) {
            result.data = [];
        }
        if (this.currentPID)
            Cookie.write(FILE_COOKIE_NAME, this.currentPID, {path:new URI(Energine.base).get('directory'), duration:1});
        /*if (this.currentPID) {
         result.data.unshift({'upl_id':0, 'upl_internal_type':'folderup', 'upl_path':'', 'upl_pid':'', 'upl_title':'...'});
         }*/
        this.grid.setData(result.data);

        if (result.pager)
            this.pageList.build(result.pager.count, result.pager.current, result.pager.records);

        if (!this.grid.isEmpty()) {
            this.toolbar.enableControls();
            this.pageList.enable();
        }

        var controlsEnabledByDefault = ['add'];
        for (var i = 0, l = controlsEnabledByDefault.length; i < l; i++) {
            if (control = this.toolbar.getControlById(controlsEnabledByDefault[i])) control.enable();
        }

        this.grid.build();
        this.overlay.hide();
    },
    open:function () {
        var r = this.grid.getSelectedRecord();
        switch (r.upl_internal_type) {
            case 'repo':
            case 'folder':
                this.currentPID = r.upl_id;
                this.filter.remove();
                this.loadPage(1);
                break;
            case 'folderup':
                this.currentPID = r.upl_id;
                this.loadPage(1);
                break;
            default:
                ModalBox.setReturnValue(r);
                ModalBox.close();
                break;
        }
    },
    add:function () {
        var pid = this.grid.getSelectedRecord().upl_pid;
        if (pid) {
            pid += '/';
        }
        ModalBox.open({
            url:this.singlePath + pid + 'add/',
            onClose:this._processAfterCloseAction.bind(this)
        });
    },
    addDir:function () {
        var pid = this.grid.getSelectedRecord().upl_pid;
        if (pid) {
            pid += '/';
        }
        ModalBox.open({
            url:this.singlePath + pid + 'add-dir/',
            //onClose:this._processAfterCloseAction.bind(this)
            onClose:function (response) {
                if (response && response.result) {
                    this.currentPID = response.data;
                    this._processAfterCloseAction(response);
                }

            }.bind(this)
        });
    },
    uploadZip:function (data) {
        this.request(this.singlePath + 'upload-zip', 'PID=' + this.grid.getSelectedRecord().upl_pid + '&data=' + encodeURIComponent(data.result), function (response) {
            console.log(response)
        });
        //this.singlePath + 'upload-zip',
    },
    loadPage:function (pageNum) {
        this.pageList.disable();
        this.toolbar.disableControls();
        this.overlay.show();
        this.grid.clear();
        var level = '', cookiePID;

        if (this.currentPID === 0) {
            level = '';
        }
        else if (this.currentPID) {
            level = this.currentPID + '/';
        }
        else if (cookiePID = Cookie.read(FILE_COOKIE_NAME)) {
            this.currentPID = cookiePID;
            level = this.currentPID + '/';
        }

        var postBody = '', url = this.singlePath + level + 'get-data/' + 'page-' + pageNum + '/';
        //if (this.langId) postBody += 'languageID=' + this.langId + '&';
        postBody += this.filter.getValue();
        /*if (this.grid.sort.order) {
         url = this.singlePath + 'get-data/' + this.grid.sort.field + '-' +
         this.grid.sort.order + '/page-' + pageNum
         }*/
        this.request(url,
            postBody,
            this.processServerResponse.bind(this),
            null,
            this.processServerError.bind(this)
        );
    }
});
<commit_msg>В репозитории добавлена возможность скачать файл<commit_after>ScriptLoader.load(
    'GridManager'
);
var FILE_COOKIE_NAME = 'NRGNFRPID';

Grid.implement({
    _popImage:function (path, tmplElement) {
        var popUpImg = new Element('img', {'src':'resizer/w298-h224/' + path, 'width':60, 'height':45, 'styles':{
            border:'1px solid gray',
            'border-radius':'10px',
            'z-index':1
        }, 'events':{
            'click':function (e) {
                this.destroy()
            },
            'mouseleave':function (e) {
                this.destroy();
            }
        }}).inject(document.body).position({'relativeTo':tmplElement, 'position':'center'}).set('morph', {duration:'short', transition:'linear'});
        var p = popUpImg.getPosition();
        popUpImg.morph({width:298, height:224, left:p.x, top:p.y});
    },

    iterateFields:function (record, fieldName, row) {
// Пропускаем невидимые поля.
        if (!this.metadata[fieldName].visible ||
            this.metadata[fieldName].type == 'hidden') return;
        var cell = new Element('td').injectInside(row);
        if (fieldName == 'upl_path') {
            cell.setStyles({ 'text-align':'center', 'vertical-align':'middle' });

            var image = new Element('img', {src:'about:blank'});
            var tmt, dimensions = {'width':40, 'height':40};
            var container = new Element('div', {'class':'thumb_container'}).inject(cell);

            switch (record['upl_internal_type']) {
                case 'folder':
                    image.setProperty('src', 'images/icons/icon_folder.gif');
                    break;
                case 'repo':
                    image.setProperty('src', 'images/icons/icon_repository.gif');
                    break;
                case 'folderup':
                    image.setProperty('src', 'images/icons/icon_folder_up.gif');
                    break;
                case 'video':
                case 'image':
                    dimensions = {'width':60, 'height':45};
                    image.setProperty('src', 'resizer/w60-h45/' + record[fieldName]).addEvents({
                        'error':function () {
                            image.setProperty('src', 'images/icons/icon_error_image.gif');
                            container.removeEvents('mouseenter').removeEvent('mouseleave');
                        }
                    }).setStyles({'border-radius':'5px', 'border':'1px solid transparent'});
                    container.addEvents({
                        'mouseenter':function (e) {
                            var el = $(e.target);
                            if (el.get('tag') != 'img') {
                                el = el.getElement('img');
                            }
                            el.setStyle('border', '1px solid gray');
                            tmt = this._popImage.delay(700, this, [record[fieldName], el])
                        }.bind(this),
                        'mouseleave':function (e) {
                            var el = $(e.target);
                            if (el.get('tag') != 'img') {
                                el = el.getElement('img');
                            }
                            el.setStyle('border', '1px solid transparent');
                            if (tmt) {
                                clearTimeout(tmt);
                            }
                        }
                    });

                    if (record['upl_internal_type'] == 'video') {
                        container.grab(new Element('div', {'class':'video_file'}));
                    }
                    break;
                default:
                    dimensions = {'width':39, 'height':48};
                    image.setProperty('src', 'images/icons/icon_undefined.gif');
                    break;
            }
            image.setProperties(dimensions).inject(container);
        }
        else if (fieldName == 'upl_properties') {
            cell.addClass('properties');
            var propsTable = new Element('tbody');
            cell.grab(new Element('table').grab(propsTable));

            if (!record['upl_internal_type'].test('folder|repo')) {
                /*new Element('tr').inject(propsTable).adopt([
                 new Element('td', {'colspan': 2, 'html':''+ record['upl_path'] + ''}),
                 ]
                 );*/
                if (record['upl_mime_type'])
                    new Element('tr').inject(propsTable).adopt([
                        new Element('td', {'html':this.metadata['upl_mime_type'].title + ' :'}),
                        new Element('td', {'html':record['upl_mime_type']})
                    ]
                    );
                switch (record['upl_internal_type']) {
                    case 'video':
                        if (record['upl_duration'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_duration'].title + ' :'}),
                                new Element('td', {'html':record['upl_duration']})
                            ]
                            );
                        break;
                    case 'image':
                        if (record['upl_width'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_width'].title + ' :'}),
                                new Element('td', {'html':record['upl_width']})
                            ]
                            );
                        if (record['upl_height'])
                            new Element('tr').inject(propsTable).adopt([
                                new Element('td', {'html':this.metadata['upl_height'].title + ' :'}),
                                new Element('td', {'html':record['upl_height']})
                            ]
                            );
                        break;
                    default :
                        break;
                }
                new Element('tr').inject(propsTable).adopt([
                    new Element('td', {'html':this.metadata['upl_publication_date'].title + ' :'}),
                    new Element('td', {'html':record['upl_publication_date']})
                ]
                );
            }
        }
        else if (fieldName == 'upl_title') {
            var fieldValue = '';
            if (record[fieldName]) {
                var fieldValue = record[fieldName].clean();
            }
            if (fieldValue != '') cell.set('html', '' + fieldValue + '');
            else cell.set('html', ' ');
        }
    }
});
var FileRepository = new Class({
    Extends:GridManager,
    initialize:function (element) {
        this.parent(element);
        this.currentPID = false;
    },
    onDoubleClick:function () {
        this.open();
    },
    onSelect:function () {
        var r = this.grid.getSelectedRecord(), control;
        this.toolbar.enableControls();
        var openBtn = this.toolbar.getControlById('open');
        switch (r.upl_internal_type) {
            case 'folder':
                if (openBtn)openBtn.enable();
                break;
            case 'folderup':
                this.toolbar.disableControls();
                if (openBtn)openBtn.enable();
                this.toolbar.getControlById('addDir').enable();
                this.toolbar.getControlById('add').enable()
                break;
            case 'repo':
                this.toolbar.disableControls();
                if (openBtn)openBtn.enable();
                break;
            default:
                //this.toolbar.getControlById('open').disable();
                break;
        }
    },
    processServerResponse:function (result) {

        if (!this.initialized) {
            this.grid.setMetadata(result.meta);
            this.initialized = true;
        }
        if (!result.data) {
            result.data = [];
        }
        if (this.currentPID)
            Cookie.write(FILE_COOKIE_NAME, this.currentPID, {path:new URI(Energine.base).get('directory'), duration:1});
        /*if (this.currentPID) {
         result.data.unshift({'upl_id':0, 'upl_internal_type':'folderup', 'upl_path':'', 'upl_pid':'', 'upl_title':'...'});
         }*/
        this.grid.setData(result.data);

        if (result.pager)
            this.pageList.build(result.pager.count, result.pager.current, result.pager.records);

        if (!this.grid.isEmpty()) {
            this.toolbar.enableControls();
            this.pageList.enable();
        }

        var controlsEnabledByDefault = ['add'];
        for (var i = 0, l = controlsEnabledByDefault.length; i < l; i++) {
            if (control = this.toolbar.getControlById(controlsEnabledByDefault[i])) control.enable();
        }

        this.grid.build();
        this.overlay.hide();
    },
    open:function () {
        var r = this.grid.getSelectedRecord();
        switch (r.upl_internal_type) {
            case 'repo':
            case 'folder':
                this.currentPID = r.upl_id;
                this.filter.remove();
                this.loadPage(1);
                break;
            case 'folderup':
                this.currentPID = r.upl_id;
                this.loadPage(1);
                break;
            default:
                ModalBox.setReturnValue(r);
                ModalBox.close();
                break;
        }
    },
    add:function () {
        var pid = this.grid.getSelectedRecord().upl_pid;
        if (pid) {
            pid += '/';
        }
        ModalBox.open({
            url:this.singlePath + pid + 'add/',
            onClose:this._processAfterCloseAction.bind(this)
        });
    },
    addDir:function () {
        var pid = this.grid.getSelectedRecord().upl_pid;
        if (pid) {
            pid += '/';
        }
        ModalBox.open({
            url:this.singlePath + pid + 'add-dir/',
            //onClose:this._processAfterCloseAction.bind(this)
            onClose:function (response) {
                if (response && response.result) {
                    this.currentPID = response.data;
                    this._processAfterCloseAction(response);
                }

            }.bind(this)
        });
    },
    uploadZip:function (data) {
        this.request(this.singlePath + 'upload-zip', 'PID=' + this.grid.getSelectedRecord().upl_pid + '&data=' + encodeURIComponent(data.result), function (response) {
            console.log(response)
        });
        //this.singlePath + 'upload-zip',
    },
    loadPage:function (pageNum) {
        this.pageList.disable();
        this.toolbar.disableControls();
        this.overlay.show();
        this.grid.clear();
        var level = '', cookiePID;

        if (this.currentPID === 0) {
            level = '';
        }
        else if (this.currentPID) {
            level = this.currentPID + '/';
        }
        else if (cookiePID = Cookie.read(FILE_COOKIE_NAME)) {
            this.currentPID = cookiePID;
            level = this.currentPID + '/';
        }

        var postBody = '', url = this.singlePath + level + 'get-data/' + 'page-' + pageNum + '/';
        //if (this.langId) postBody += 'languageID=' + this.langId + '&';
        postBody += this.filter.getValue();
        /*if (this.grid.sort.order) {
         url = this.singlePath + 'get-data/' + this.grid.sort.field + '-' +
         this.grid.sort.order + '/page-' + pageNum
         }*/
        this.request(url,
            postBody,
            this.processServerResponse.bind(this),
            null,
            this.processServerError.bind(this)
        );
    }
});
<|endoftext|>


<commit_before>var redis = require('node-redis'),
    fs = require('fs'),
    path = require('path'),
    EventEmitter = require("events").EventEmitter,
    uuid = require('node-uuid');

var Thoonk = function() {
    EventEmitter.call(this);

    this.redis = redis.createClient();
    this.lredis = redis.createClient();
    this.ready = false;

    this.lredis.on('message', function(channel, msg) {
        msg = msg.toString();
        this.emit(channel, channel, msg);
    }.bind(this));

    this.lredis.on('subscribe', function(channel) {
        this.emit('subscribed.' + channel);
    }.bind(this));

    this.scripts = {};
    this.shas = {};

    this.instance = uuid();

    this.subscriptions = {};

    this.objects = {};
};

Thoonk.prototype = EventEmitter.prototype;
Thoonk.prototype.constructor = Thoonk;

(function() {
    //continue extending Thoonk

    this.quit = function() {
        this.redis.quit();
        this.lredis.quit();
    };

    this.registerType = function(objname, theobject, callback) {
        this.objects[objname] = function(name) {
            return new theobject(name, this);
        }.bind(this);
        var dir = theobject.prototype.scriptdir;
        this.scripts[theobject.prototype.objtype] = {};
        this.shas[theobject.prototype.objtype] = {}
        var curdir = fs.readdirSync(dir);
        curdir.forEach(function(filename, fidx, curdir) {
            if(path.extname(filename) == '.lua') {
                var verbname = path.basename(filename).slice(0,-4);
                this.scripts[theobject.prototype.objtype][verbname] = fs.readFileSync(dir + '/' + filename).toString();
                var last = (fidx + 1 == curdir.length);
                this.redis.sendCommand('SCRIPT', ['LOAD', this.scripts[theobject.prototype.objtype][verbname]], function(err, reply) {
                    if(err) { console.log(verbname, err); }
                    this.shas[theobject.prototype.objtype][verbname] = reply.toString();
                    if(last) {
                        if(callback) {
                            callback(false);
                        }
                        this.emit('loaded.' + objname);
                    }
                }.bind(this));
            }
        }.bind(this));
    };

    this.create = function() {
    };

    this._runscript = function(objtype, scriptname, feedname, args, callback) {
        args = [this.shas[objtype][scriptname], '0', feedname].concat(args);
        this.redis.sendCommand('EVALSHA', args, callback);
    };

    this.feed = function(name, config) {
        return new Feed(name);
    };

}).call(Thoonk.prototype);

var ThoonkBaseObject = function(name, thoonk) {
    EventEmitter.call(this);
    this.thoonk = thoonk;
    this.redis = this.thoonk.redis;
    this.name = name;
    //TODO: create feed if it doesn't exist
};

ThoonkBaseObject.prototype = EventEmitter.prototype;
ThoonkBaseObject.constructor = ThoonkBaseObject;

(function() {

    this._build_event = function(eventtype) {
        return 'event.' + this.objtype + '.' + eventtype + ':' + this.name
    };

    this.handle_event = function(channel, msg) {
        //override this function in your object
    };

    this.init_subscribe = function(functions) {
        if(!this.thoonk.subscriptions.hasOwnProperty(this.name)) {
            this.thoonk.once('subscribed.' + this._build_event(this.subscribables[this.subscribables.length - 1]), function() {
                this.emit('subscribe_ready');
            }.bind(this));
            this.thoonk.subscriptions[this.name] = this.subscribables;
            for(var subscribable in this.subscribables) {
                this.thoonk.lredis.subscribe(this._build_event(this.subscribables[subscribable]));
            }
        }
        if(!this.subinitted) {
            for(var subscribable in this.subscribables) {
                this.thoonk.on(this._build_event(this.subscribables[subscribable]), this.handle_event.bind(this));
            }
            this.subinitted = true;
        }
    };

    this.runscript = function(scriptname, args, callback) {
        this.thoonk._runscript(this.objtype, scriptname, this.name, args, function(err, results) {
            if(err) {
                console.log(scriptname, err);
            } else {
                var newr = [];
                for(var i in results) {
                    if(results[i] != null && typeof results[i] === "object" && results[i].constructor == Buffer) {
                        newr.push(results[i].toString())
                    } else {
                        newr.push(results[i]);
                    }
                }
                callback.apply(this, newr);
            };
        }.bind(this));
    };

}).call(ThoonkBaseObject.prototype);

exports.Thoonk = Thoonk;
exports.ThoonkBaseObject = ThoonkBaseObject;
<commit_msg>deal with non-lua files in the scripts directory<commit_after>var redis = require('node-redis'),
    fs = require('fs'),
    path = require('path'),
    EventEmitter = require("events").EventEmitter,
    uuid = require('node-uuid');

var Thoonk = function() {
    EventEmitter.call(this);

    this.redis = redis.createClient();
    this.lredis = redis.createClient();
    this.ready = false;

    this.lredis.on('message', function(channel, msg) {
        msg = msg.toString();
        this.emit(channel, channel, msg);
    }.bind(this));

    this.lredis.on('subscribe', function(channel) {
        this.emit('subscribed.' + channel);
    }.bind(this));

    this.scripts = {};
    this.shas = {};

    this.instance = uuid();

    this.subscriptions = {};

    this.objects = {};
};

Thoonk.prototype = EventEmitter.prototype;
Thoonk.prototype.constructor = Thoonk;

(function() {
    //continue extending Thoonk

    this.quit = function() {
        this.redis.quit();
        this.lredis.quit();
    };

    this.registerType = function(objname, theobject, callback) {
        this.objects[objname] = function(name) {
            return new theobject(name, this);
        }.bind(this);
        var dir = theobject.prototype.scriptdir;
        this.scripts[theobject.prototype.objtype] = {};
        this.shas[theobject.prototype.objtype] = {}
        var curdir = fs.readdirSync(dir);
        curdir = curdir.filter(function(fname) { return fname.substr(-4) == '.lua'; });
        curdir.forEach(function(filename, fidx, curdir) {
            var last = (fidx + 1 == curdir.length);
            if(path.extname(filename) == '.lua') {
                var verbname = path.basename(filename).slice(0,-4);
                this.scripts[theobject.prototype.objtype][verbname] = fs.readFileSync(dir + '/' + filename).toString();
                this.redis.sendCommand('SCRIPT', ['LOAD', this.scripts[theobject.prototype.objtype][verbname]], function(err, reply) {
                    if(err) { console.log(verbname, err); }
                    this.shas[theobject.prototype.objtype][verbname] = reply.toString();
                    if(last) {
                        if(callback) {
                            callback(false);
                        }
                        this.emit('loaded.' + objname);
                    }
                }.bind(this));
            }
        }.bind(this));
    };

    this.create = function() {
    };

    this._runscript = function(objtype, scriptname, feedname, args, callback) {
        args = [this.shas[objtype][scriptname], '0', feedname].concat(args);
        this.redis.sendCommand('EVALSHA', args, callback);
    };

    this.feed = function(name, config) {
        return new Feed(name);
    };

}).call(Thoonk.prototype);

var ThoonkBaseObject = function(name, thoonk) {
    EventEmitter.call(this);
    this.thoonk = thoonk;
    this.redis = this.thoonk.redis;
    this.name = name;
    //TODO: create feed if it doesn't exist
};

ThoonkBaseObject.prototype = EventEmitter.prototype;
ThoonkBaseObject.constructor = ThoonkBaseObject;

(function() {

    this._build_event = function(eventtype) {
        return 'event.' + this.objtype + '.' + eventtype + ':' + this.name
    };

    this.handle_event = function(channel, msg) {
        //override this function in your object
    };

    this.init_subscribe = function(functions) {
        if(!this.thoonk.subscriptions.hasOwnProperty(this.name)) {
            this.thoonk.once('subscribed.' + this._build_event(this.subscribables[this.subscribables.length - 1]), function() {
                this.emit('subscribe_ready');
            }.bind(this));
            this.thoonk.subscriptions[this.name] = this.subscribables;
            for(var subscribable in this.subscribables) {
                this.thoonk.lredis.subscribe(this._build_event(this.subscribables[subscribable]));
            }
        }
        if(!this.subinitted) {
            for(var subscribable in this.subscribables) {
                this.thoonk.on(this._build_event(this.subscribables[subscribable]), this.handle_event.bind(this));
            }
            this.subinitted = true;
        }
    };

    this.runscript = function(scriptname, args, callback) {
        this.thoonk._runscript(this.objtype, scriptname, this.name, args, function(err, results) {
            if(err) {
                console.log(scriptname, err);
            } else {
                var newr = [];
                for(var i in results) {
                    if(results[i] != null && typeof results[i] === "object" && results[i].constructor == Buffer) {
                        newr.push(results[i].toString())
                    } else {
                        newr.push(results[i]);
                    }
                }
                callback.apply(this, newr);
            };
        }.bind(this));
    };

}).call(ThoonkBaseObject.prototype);

exports.Thoonk = Thoonk;
exports.ThoonkBaseObject = ThoonkBaseObject;
<|endoftext|>


<commit_before>const Bot = require('../Bot');

class SmartBot extends Bot {

  constructor(logger, name, game) {
    super(logger, name, game);

    this._cards = {};
    this._gameStatus = null;
    this._handCardKnown = null;
  }

  static getType() {
    return 'smart';
  }

  ['roundStart']() {
    this._cards = {};
    this._gameStatus = null;
  }

  ['gameStatus'](event) {
    this._gameStatus = event;

    this._gameStatus.players.forEach((player) => {
      this._addPlayerCardBase(player.name);

      this._cards[player.name].tableCards = player.tableCards.slice(0);
    });
  }

  ['cardReveal'](event) {
    this._addPlayerCardBase(event.player);
    this._cards[event.player].handCards.push(event.card);

    this.logger.info(
      `${this.getName()} remembers that ${event.player} has ${event.card}`
    );
  }

  ['cardShow'](event) {
    if (event.player !== this.getName()) return;

    const knownCard = this._cards[this.getName()].handCards[0];
    this.logger.info(
      `${this.getName()} knows that ${event.target}`,
      `knows its hand card ${knownCard}`
    );
    this._handCardKnown = knownCard;
  }

  ['cardPlay'](event) {
    const { player, card } = event;
    this._addPlayerCardBase(player);

    const index = this._cards[player].handCards.indexOf(card);

    if (index > -1) {
      const handCards = this._cards[player].handCards;
      this._cards[player].handCards = handCards.splice(index, 1);

      this.logger.info(
        `${this.getName()} knows that ${player}`,
        `does not have ${card} anymore`
      );
    }
  }

  ['privateStatus'](event) {
    this._cards[this.getName()].handCards = event.cardsInHand.map(c => c.name);
    // Filter irrelevant input
    if (!event.isCurrentPlayer) return;

    const cardToPlay = this._getPreferredCard(event.cardsInHand);
    const cardName = cardToPlay.name;
    const cardTarget = this._getPreferredTarget(cardToPlay);
    const cardChoice = this._getPreferredChoice(cardToPlay, cardTarget);

    this.getGame().playCardAsPlayer(
      this.getName(),
      cardName,
      cardTarget,
      cardChoice
    );
  }

  _addPlayerCardBase(player) {
    if (this._cards[player]) return;

    this._cards[player] = {
      handCards: [],
      tableCards: [],
    };
  }

  _getPreferredCard(cardsInHand) {
    const canPlayCards = cardsInHand.slice(0).filter(c => c.canPlay);

    // If someone knows our card and we can play it, play it away
    if (this._handCardKnown) {
      const canPlayKnownCard = canPlayCards.find(
        c => c.name === this._handCardKnown
      );

      if (canPlayKnownCard) {
        this.logger.info(
          `${this.getName()} knows that someone else knows its hand`,
          'card and chooses to play the known card'
        );

        this._handCardKnown = null;
        return canPlayKnownCard;
      }
    }

    // Otherwise play the smallest value card
    canPlayCards.sort((c1, c2) => (
      this.CARD_VALUES[c1.name] - this.CARD_VALUES[c2.name]
    ));

    return canPlayCards[0];
  }

  _getPreferredTarget(cardToPlay) {
    let validTargets = cardToPlay.validTargetPlayers;

    if (cardToPlay.name === 'Guard') {
      const target = Object.keys(this._cards)
        .filter(playerName => validTargets.indexOf(playerName) !== -1)
        .find((playerName) => {
          const playerCards = this._cards[playerName];
          return playerCards.length > 0 && playerCards[0] !== 'Guard';
        });

      if (target) {
        this.logger.info(
          `${this.getName()} knows the hand card of ${target}`,
          `and targets ${target} with a Guard`
        );
        return target;
      }
    }

    // Prioritize other targets
    if (validTargets.length === 1) {
      validTargets = validTargets.filter(target => target !== this.getName());
    }

    if (cardToPlay.validTargetPlayers.length > 0) {
      return validTargets[
        Math.floor(Math.random() * validTargets.length)
      ];
    }

    return null;
  }

  _getPreferredChoice(cardToPlay, cardTarget) {
    if (cardTarget && cardToPlay.name !== 'Guard') return null;

    // If we know the handcard, return that (if it is not Guard)
    const targetCards = this._cards[cardTarget];
    if (
        targetCards &&
        targetCards.handCards.length > 0 &&
        targetCards.handCards[0] !== 'Guard'
      ) {
      return targetCards.handCards[0];
    }

    // Otherwise count what is left and random
    const remainingCards = this.GUARD_TARGET_CARDS.slice(0);

    let knownCards = this._gameStatus.removedCards;

    Object.values(this._cards).forEach((playerCards) => {
      knownCards = knownCards.concat(
        playerCards.handCards, playerCards.tableCards
      );
    });

    knownCards.forEach((card) => {
      const index = remainingCards.indexOf(card);
      if (index > -1) {
        remainingCards.splice(index, 1);
      }
    });

    this.logger.info(
      `${this.getName()} knows that only certains cards remain hidden`,
      remainingCards
    );

    return remainingCards[Math.floor(Math.random() * remainingCards.length)];
  }
}

module.exports = SmartBot;
<commit_msg>Small bugfix<commit_after>const Bot = require('../Bot');

class SmartBot extends Bot {

  constructor(logger, name, game) {
    super(logger, name, game);

    this._cards = {};
    this._gameStatus = null;
    this._handCardKnown = null;
  }

  static getType() {
    return 'smart';
  }

  ['roundStart']() {
    this._cards = {};
    this._gameStatus = null;
  }

  ['gameStatus'](event) {
    this._gameStatus = event;

    this._gameStatus.players.forEach((player) => {
      this._addPlayerCardBase(player.name);

      this._cards[player.name].tableCards = player.tableCards.slice(0);
    });
  }

  ['cardReveal'](event) {
    this._addPlayerCardBase(event.player);
    this._cards[event.player].handCards.push(event.card);

    this.logger.info(
      `${this.getName()} remembers that ${event.player} has ${event.card}`
    );
  }

  ['cardShow'](event) {
    if (event.player !== this.getName()) return;

    const knownCard = this._cards[this.getName()].handCards[0];
    this.logger.info(
      `${this.getName()} knows that ${event.target}`,
      `knows its hand card ${knownCard}`
    );
    this._handCardKnown = knownCard;
  }

  ['cardPlay'](event) {
    const { player, card } = event;
    this._addPlayerCardBase(player);

    const index = this._cards[player].handCards.indexOf(card);

    if (index > -1) {
      const handCards = this._cards[player].handCards;
      this._cards[player].handCards = handCards.splice(index, 1);

      this.logger.info(
        `${this.getName()} knows that ${player}`,
        `does not have ${card} anymore`
      );
    }
  }

  ['privateStatus'](event) {
    this._cards[this.getName()].handCards = event.cardsInHand.map(c => c.name);
    // Filter irrelevant input
    if (!event.isCurrentPlayer) return;

    const cardToPlay = this._getPreferredCard(event.cardsInHand);
    const cardName = cardToPlay.name;
    const cardTarget = this._getPreferredTarget(cardToPlay);
    const cardChoice = this._getPreferredChoice(cardToPlay, cardTarget);

    this.getGame().playCardAsPlayer(
      this.getName(),
      cardName,
      cardTarget,
      cardChoice
    );
  }

  _addPlayerCardBase(player) {
    if (this._cards[player]) return;

    this._cards[player] = {
      handCards: [],
      tableCards: [],
    };
  }

  _getPreferredCard(cardsInHand) {
    const canPlayCards = cardsInHand.slice(0).filter(c => c.canPlay);

    // If someone knows our card and we can play it, play it away
    if (this._handCardKnown) {
      const canPlayKnownCard = canPlayCards.find(
        c => c.name === this._handCardKnown
      );

      if (canPlayKnownCard) {
        this.logger.info(
          `${this.getName()} knows that someone else knows its hand`,
          'card and chooses to play the known card'
        );

        this._handCardKnown = null;
        return canPlayKnownCard;
      }
    }

    // Otherwise play the smallest value card
    canPlayCards.sort((c1, c2) => (
      this.CARD_VALUES[c1.name] - this.CARD_VALUES[c2.name]
    ));

    return canPlayCards[0];
  }

  _getPreferredTarget(cardToPlay) {
    let validTargets = cardToPlay.validTargetPlayers;

    if (cardToPlay.name === 'Guard') {
      const target = Object.keys(this._cards)
        .filter(playerName => validTargets.indexOf(playerName) !== -1)
        .find((playerName) => {
          const playerCards = this._cards[playerName];
          return playerCards.length > 0 && playerCards[0] !== 'Guard';
        });

      if (target) {
        this.logger.info(
          `${this.getName()} knows the hand card of ${target}`,
          `and targets ${target} with a Guard`
        );
        return target;
      }
    }

    // Prioritize other targets
    if (validTargets.length !== 1) {
      validTargets = validTargets.filter(target => target !== this.getName());
    }

    if (cardToPlay.validTargetPlayers.length > 0) {
      return validTargets[
        Math.floor(Math.random() * validTargets.length)
      ];
    }

    return null;
  }

  _getPreferredChoice(cardToPlay, cardTarget) {
    if (cardTarget && cardToPlay.name !== 'Guard') return null;

    // If we know the handcard, return that (if it is not Guard)
    const targetCards = this._cards[cardTarget];
    if (
        targetCards &&
        targetCards.handCards.length > 0 &&
        targetCards.handCards[0] !== 'Guard'
      ) {
      return targetCards.handCards[0];
    }

    // Otherwise count what is left and random
    const remainingCards = this.GUARD_TARGET_CARDS.slice(0);

    let knownCards = this._gameStatus.removedCards;

    Object.values(this._cards).forEach((playerCards) => {
      knownCards = knownCards.concat(
        playerCards.handCards, playerCards.tableCards
      );
    });

    knownCards.forEach((card) => {
      const index = remainingCards.indexOf(card);
      if (index > -1) {
        remainingCards.splice(index, 1);
      }
    });

    this.logger.info(
      `${this.getName()} knows that only certains cards remain hidden`,
      remainingCards
    );

    return remainingCards[Math.floor(Math.random() * remainingCards.length)];
  }
}

module.exports = SmartBot;
<|endoftext|>


<commit_before>define(function() {

// Allow subprojects to test against their own fixtures
var oldStart = window.start,
	qunitModule = QUnit.module,
	qunitTest = QUnit.test,
	// Store the old counts so that we only assert on tests that have actually leaked,
	// instead of asserting every time a test has leaked sometime in the past
	oldCacheLength = 0,
	oldFragmentsLength = 0,
	oldActive = 0,

	expectedDataKeys = {},

	splice = [].splice,
	reset,
	ajaxSettings = jQuery.ajaxSettings;

/**
 * QUnit configuration
 */

// Max time for stop() and asyncTest() until it aborts test
// and start()'s the next test.
QUnit.config.testTimeout = 20 * 1000; // 20 seconds

// Enforce an "expect" argument or expect() call in all test bodies.
QUnit.config.requireExpects = true;

/**
 * QUnit hooks
 */

// Sandbox start for great justice
window.start = function() {
	oldStart();
};

function keys(o) {
	var ret, key;
	if ( Object.keys ) {
		ret = Object.keys( o );
	} else {
		ret = [];
		for ( key in o ) {
			ret.push( key );
		}
	}
	ret.sort();
	return ret;
}

/**
 * @param {jQuery|HTMLElement|Object|Array} elems Target (or array of targets) for jQuery.data.
 * @param {string} key
 */
QUnit.expectJqData = function( elems, key ) {
	var i, elem, expando;

	// As of jQuery 2.0, there will be no "cache"-data is
	// stored and managed completely below the API surface
	if ( jQuery.cache ) {
		QUnit.current_testEnvironment.checkJqData = true;

		if ( elems.jquery && elems.toArray ) {
			elems = elems.toArray();
		}
		if ( !supportjQuery.isArray( elems ) ) {
			elems = [ elems ];
		}

		for ( i = 0; i < elems.length; i++ ) {
			elem = elems[i];

			// jQuery.data only stores data for nodes in jQuery.cache,
			// for other data targets the data is stored in the object itself,
			// in that case we can't test that target for memory leaks.
			// But we don't have to since in that case the data will/must will
			// be available as long as the object is not garbage collected by
			// the js engine, and when it is, the data will be removed with it.
			if ( !elem.nodeType ) {
				// Fixes false positives for dataTests(window), dataTests({}).
				continue;
			}

			expando = elem[ jQuery.expando ];

			if ( expando === undefined ) {
				// In this case the element exists fine, but
				// jQuery.data (or internal data) was never (in)directly
				// called.
				// Since this method was called it means some data was
				// expected to be found, but since there is nothing, fail early
				// (instead of in teardown).
				notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." );
			} else {
				if ( expectedDataKeys[expando] ) {
					expectedDataKeys[expando].push( key );
				} else {
					expectedDataKeys[expando] = [ key ];
				}
			}
		}
	}

};
QUnit.config.urlConfig.push({
	id: "jqdata",
	label: "Always check jQuery.data",
	tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it"
});

/**
 * Ensures that tests have cleaned up properly after themselves. Should be passed as the
 * teardown function on all modules' lifecycle object.
 */
window.moduleTeardown = function() {
	var i,
		expectedKeys, actualKeys,
		fragmentsLength = 0,
		cacheLength = 0;

	// Only look for jQuery data problems if this test actually
	// provided some information to compare against.
	if ( QUnit.urlParams.jqdata || this.checkJqData ) {
		for ( i in jQuery.cache ) {
			expectedKeys = expectedDataKeys[i];
			actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i];
			if ( !QUnit.equiv( expectedKeys, actualKeys ) ) {
				deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" );
			}
			delete jQuery.cache[i];
			delete expectedDataKeys[i];
		}
		// In case it was removed from cache before (or never there in the first place)
		for ( i in expectedDataKeys ) {
			deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" );
			delete expectedDataKeys[i];
		}
	}

	// Reset data register
	expectedDataKeys = {};

	// Check for (and clean up, if possible) incomplete animations/requests/etc.
	if ( jQuery.timers && jQuery.timers.length !== 0 ) {
		equal( jQuery.timers.length, 0, "No timers are still running" );
		splice.call( jQuery.timers, 0, jQuery.timers.length );
		jQuery.fx.stop();
	}
	if ( jQuery.active !== undefined && jQuery.active !== oldActive ) {
		equal( jQuery.active, oldActive, "No AJAX requests are still active" );
		if ( ajaxTest.abort ) {
			ajaxTest.abort("active requests");
		}
		oldActive = jQuery.active;
	}

	reset();

	for ( i in jQuery.cache ) {
		++cacheLength;
	}

	jQuery.fragments = {};

	for ( i in jQuery.fragments ) {
		++fragmentsLength;
	}

	// Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
	// if we unconditionally assert any of these, the test will fail with too many assertions :|
	if ( cacheLength !== oldCacheLength ) {
		equal( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
		oldCacheLength = cacheLength;
	}
	if ( fragmentsLength !== oldFragmentsLength ) {
		equal( fragmentsLength, oldFragmentsLength, "No unit tests leak memory in jQuery.fragments" );
		oldFragmentsLength = fragmentsLength;
	}
};

QUnit.done(function() {
	// Remove our own fixtures outside #qunit-fixture
	supportjQuery("#qunit ~ *").remove();
});

// jQuery-specific post-test cleanup
reset = function() {

	// Ensure jQuery events and data on the fixture are properly removed
	jQuery("#qunit-fixture").empty();
	// ...even if the jQuery under test has a broken .empty()
	supportjQuery("#qunit-fixture").empty();

	// Reset internal jQuery state
	jQuery.event.global = {};
	if ( ajaxSettings ) {
		jQuery.ajaxSettings = jQuery.extend( true, {}, ajaxSettings );
	} else {
		delete jQuery.ajaxSettings;
	}

	// Cleanup globals
	Globals.cleanup();

	jQuery("#qunit-fixture")[0].innerHTML = QUnit.config.fixture;
};

QUnit.testDone(reset);

// Register globals for cleanup and the cleanup code itself
// Explanation at http://perfectionkills.com/understanding-delete/#ie_bugs
window.Globals = (function() {
	var globals = {};
	return {
		register: function( name ) {
			globals[ name ] = true;
			supportjQuery.globalEval( "var " + name + " = undefined;" );
		},
		cleanup: function() {
			var name,
				current = globals;
			globals = {};
			for ( name in current ) {
				supportjQuery.globalEval( "try { " +
					"delete " + ( supportjQuery.support.deleteExpando ? "window['" + name + "']" : name ) +
				"; } catch( x ) {}" );
			}
		}
	};
})();

/**
 * Test a subproject with its own fixture
 * @param {String} label Project name
 * @param {String} url Test folder location
 * @param {RegExp} risTests To filter script sources
 */
function testSubproject( label, subProjectURL, risTests, complete ) {
	var sub, fixture, fixtureHTML,
		fixtureReplaced = false;

	// Don't let subproject tests jump the gun
	QUnit.config.reorder = false;

	// Create module
	module( label );

	// Duckpunch QUnit
	// TODO restore parent fixture on teardown to support reordering
	module = QUnit.module = function( name ) {
		var args = arguments;

		// Remember subproject-scoped module name
		sub = name;

		// Override
		args[0] = label;
		return qunitModule.apply( this, args );
	};
	test = function( name ) {
		var args = arguments,
			i = args.length - 1;

		// Prepend subproject-scoped module name to test name
		args[0] = sub + ": " + name;

		// Find test function and wrap to require subproject fixture
		for ( ; i >= 0; i-- ) {
			if ( supportjQuery.isFunction( args[i] ) ) {
				args[i] = requireFixture( args[i] );
				break;
			}
		}

		return qunitTest.apply( this, args );
	};

	// Load tests and fixture from subproject
	// Test order matters, so we must be synchronous and throw an error on load failure
	supportjQuery.ajax( subProjectURL, {
		async: false,
		dataType: "html",
		error: function( jqXHR, status ) {
			throw new Error( "Could not load: " + subProjectURL + " (" + status + ")" );
		},
		success: function( data, status, jqXHR ) {
			var sources = [],
				page = supportjQuery.parseHTML(
				// replace html/head with dummy elements so they are represented in the DOM
				( data || "" ).replace( /<\/?((!DOCTYPE|html|head)\b.*?)>/gi, "[$1]" ),
				document,
				true
			);

			if ( !page || !page.length ) {
				this.error( jqXHR, "no data" );
			}
			page = supportjQuery( page );

			// Include subproject tests
			page.filter("script[src]").add( page.find("script[src]") ).map(function() {
				var src = supportjQuery( this ).attr("src");
				if ( risTests.test( src ) ) {
					sources.push( src );
				}
			});

			// Ensure load order
			(function loadDep() {
				var dep = sources.shift();
				if ( dep ) {
					require( [ subProjectURL + dep ], loadDep );
				} else if ( complete ) {
					complete();
				}
			})();

			// Get the fixture, including content outside of #qunit-fixture
			fixture = page.find("[id='qunit-fixture']");
			fixtureHTML = fixture.html();
			fixture.empty();
			while ( fixture.length && !fixture.prevAll("[id='qunit']").length ) {
				fixture = fixture.parent();
			}
			fixture = fixture.add( fixture.nextAll() );
		}
	});

	function requireFixture( fn ) {
		return function() {
			if ( !fixtureReplaced ) {
				// Make sure that we retrieved a fixture for the subproject
				if ( !fixture.length ) {
					ok( false, "Found subproject fixture" );
					return;
				}

				// Update helper function behavior
				baseURL = subProjectURL;

				// Replace the current fixture, including content outside of #qunit-fixture
				var oldFixture = supportjQuery("#qunit-fixture");
				while ( oldFixture.length && !oldFixture.prevAll("[id='qunit']").length ) {
					oldFixture = oldFixture.parent();
				}
				oldFixture.nextAll().remove();
				oldFixture.replaceWith( fixture );

				// WARNING: UNDOCUMENTED INTERFACE
				QUnit.config.fixture = fixtureHTML;
				reset();
				if ( supportjQuery("#qunit-fixture").html() !== fixtureHTML ) {
					ok( false, "Copied subproject fixture" );
					return;
				}

				fixtureReplaced = true;
			}
			fn.apply( this, arguments );
		};
	}
}

return testSubproject;

});
<commit_msg>Tests: Remove one of the checks for memory leak<commit_after>define(function() {

// Allow subprojects to test against their own fixtures
var oldStart = window.start,
	qunitModule = QUnit.module,
	qunitTest = QUnit.test,
	// Store the old counts so that we only assert on tests that have actually leaked,
	// instead of asserting every time a test has leaked sometime in the past
	oldCacheLength = 0,
	oldActive = 0,

	expectedDataKeys = {},

	splice = [].splice,
	reset,
	ajaxSettings = jQuery.ajaxSettings;

/**
 * QUnit configuration
 */

// Max time for stop() and asyncTest() until it aborts test
// and start()'s the next test.
QUnit.config.testTimeout = 20 * 1000; // 20 seconds

// Enforce an "expect" argument or expect() call in all test bodies.
QUnit.config.requireExpects = true;

/**
 * QUnit hooks
 */

// Sandbox start for great justice
window.start = function() {
	oldStart();
};

function keys(o) {
	var ret, key;
	if ( Object.keys ) {
		ret = Object.keys( o );
	} else {
		ret = [];
		for ( key in o ) {
			ret.push( key );
		}
	}
	ret.sort();
	return ret;
}

/**
 * @param {jQuery|HTMLElement|Object|Array} elems Target (or array of targets) for jQuery.data.
 * @param {string} key
 */
QUnit.expectJqData = function( elems, key ) {
	var i, elem, expando;

	// As of jQuery 2.0, there will be no "cache"-data is
	// stored and managed completely below the API surface
	if ( jQuery.cache ) {
		QUnit.current_testEnvironment.checkJqData = true;

		if ( elems.jquery && elems.toArray ) {
			elems = elems.toArray();
		}
		if ( !supportjQuery.isArray( elems ) ) {
			elems = [ elems ];
		}

		for ( i = 0; i < elems.length; i++ ) {
			elem = elems[i];

			// jQuery.data only stores data for nodes in jQuery.cache,
			// for other data targets the data is stored in the object itself,
			// in that case we can't test that target for memory leaks.
			// But we don't have to since in that case the data will/must will
			// be available as long as the object is not garbage collected by
			// the js engine, and when it is, the data will be removed with it.
			if ( !elem.nodeType ) {
				// Fixes false positives for dataTests(window), dataTests({}).
				continue;
			}

			expando = elem[ jQuery.expando ];

			if ( expando === undefined ) {
				// In this case the element exists fine, but
				// jQuery.data (or internal data) was never (in)directly
				// called.
				// Since this method was called it means some data was
				// expected to be found, but since there is nothing, fail early
				// (instead of in teardown).
				notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." );
			} else {
				if ( expectedDataKeys[expando] ) {
					expectedDataKeys[expando].push( key );
				} else {
					expectedDataKeys[expando] = [ key ];
				}
			}
		}
	}

};
QUnit.config.urlConfig.push({
	id: "jqdata",
	label: "Always check jQuery.data",
	tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it"
});

/**
 * Ensures that tests have cleaned up properly after themselves. Should be passed as the
 * teardown function on all modules' lifecycle object.
 */
window.moduleTeardown = function() {
	var i,
		expectedKeys, actualKeys,
		cacheLength = 0;

	// Only look for jQuery data problems if this test actually
	// provided some information to compare against.
	if ( QUnit.urlParams.jqdata || this.checkJqData ) {
		for ( i in jQuery.cache ) {
			expectedKeys = expectedDataKeys[i];
			actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i];
			if ( !QUnit.equiv( expectedKeys, actualKeys ) ) {
				deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" );
			}
			delete jQuery.cache[i];
			delete expectedDataKeys[i];
		}
		// In case it was removed from cache before (or never there in the first place)
		for ( i in expectedDataKeys ) {
			deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" );
			delete expectedDataKeys[i];
		}
	}

	// Reset data register
	expectedDataKeys = {};

	// Check for (and clean up, if possible) incomplete animations/requests/etc.
	if ( jQuery.timers && jQuery.timers.length !== 0 ) {
		equal( jQuery.timers.length, 0, "No timers are still running" );
		splice.call( jQuery.timers, 0, jQuery.timers.length );
		jQuery.fx.stop();
	}
	if ( jQuery.active !== undefined && jQuery.active !== oldActive ) {
		equal( jQuery.active, oldActive, "No AJAX requests are still active" );
		if ( ajaxTest.abort ) {
			ajaxTest.abort("active requests");
		}
		oldActive = jQuery.active;
	}

	reset();

	for ( i in jQuery.cache ) {
		++cacheLength;
	}

	// Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
	// if we unconditionally assert any of these, the test will fail with too many assertions :|
	if ( cacheLength !== oldCacheLength ) {
		equal( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
		oldCacheLength = cacheLength;
	}
};

QUnit.done(function() {
	// Remove our own fixtures outside #qunit-fixture
	supportjQuery("#qunit ~ *").remove();
});

// jQuery-specific post-test cleanup
reset = function() {

	// Ensure jQuery events and data on the fixture are properly removed
	jQuery("#qunit-fixture").empty();
	// ...even if the jQuery under test has a broken .empty()
	supportjQuery("#qunit-fixture").empty();

	// Reset internal jQuery state
	jQuery.event.global = {};
	if ( ajaxSettings ) {
		jQuery.ajaxSettings = jQuery.extend( true, {}, ajaxSettings );
	} else {
		delete jQuery.ajaxSettings;
	}

	// Cleanup globals
	Globals.cleanup();

	jQuery("#qunit-fixture")[0].innerHTML = QUnit.config.fixture;
};

QUnit.testDone(reset);

// Register globals for cleanup and the cleanup code itself
// Explanation at http://perfectionkills.com/understanding-delete/#ie_bugs
window.Globals = (function() {
	var globals = {};
	return {
		register: function( name ) {
			globals[ name ] = true;
			supportjQuery.globalEval( "var " + name + " = undefined;" );
		},
		cleanup: function() {
			var name,
				current = globals;
			globals = {};
			for ( name in current ) {
				supportjQuery.globalEval( "try { " +
					"delete " + ( supportjQuery.support.deleteExpando ? "window['" + name + "']" : name ) +
				"; } catch( x ) {}" );
			}
		}
	};
})();

/**
 * Test a subproject with its own fixture
 * @param {String} label Project name
 * @param {String} url Test folder location
 * @param {RegExp} risTests To filter script sources
 */
function testSubproject( label, subProjectURL, risTests, complete ) {
	var sub, fixture, fixtureHTML,
		fixtureReplaced = false;

	// Don't let subproject tests jump the gun
	QUnit.config.reorder = false;

	// Create module
	module( label );

	// Duckpunch QUnit
	// TODO restore parent fixture on teardown to support reordering
	module = QUnit.module = function( name ) {
		var args = arguments;

		// Remember subproject-scoped module name
		sub = name;

		// Override
		args[0] = label;
		return qunitModule.apply( this, args );
	};
	test = function( name ) {
		var args = arguments,
			i = args.length - 1;

		// Prepend subproject-scoped module name to test name
		args[0] = sub + ": " + name;

		// Find test function and wrap to require subproject fixture
		for ( ; i >= 0; i-- ) {
			if ( supportjQuery.isFunction( args[i] ) ) {
				args[i] = requireFixture( args[i] );
				break;
			}
		}

		return qunitTest.apply( this, args );
	};

	// Load tests and fixture from subproject
	// Test order matters, so we must be synchronous and throw an error on load failure
	supportjQuery.ajax( subProjectURL, {
		async: false,
		dataType: "html",
		error: function( jqXHR, status ) {
			throw new Error( "Could not load: " + subProjectURL + " (" + status + ")" );
		},
		success: function( data, status, jqXHR ) {
			var sources = [],
				page = supportjQuery.parseHTML(
				// replace html/head with dummy elements so they are represented in the DOM
				( data || "" ).replace( /<\/?((!DOCTYPE|html|head)\b.*?)>/gi, "[$1]" ),
				document,
				true
			);

			if ( !page || !page.length ) {
				this.error( jqXHR, "no data" );
			}
			page = supportjQuery( page );

			// Include subproject tests
			page.filter("script[src]").add( page.find("script[src]") ).map(function() {
				var src = supportjQuery( this ).attr("src");
				if ( risTests.test( src ) ) {
					sources.push( src );
				}
			});

			// Ensure load order
			(function loadDep() {
				var dep = sources.shift();
				if ( dep ) {
					require( [ subProjectURL + dep ], loadDep );
				} else if ( complete ) {
					complete();
				}
			})();

			// Get the fixture, including content outside of #qunit-fixture
			fixture = page.find("[id='qunit-fixture']");
			fixtureHTML = fixture.html();
			fixture.empty();
			while ( fixture.length && !fixture.prevAll("[id='qunit']").length ) {
				fixture = fixture.parent();
			}
			fixture = fixture.add( fixture.nextAll() );
		}
	});

	function requireFixture( fn ) {
		return function() {
			if ( !fixtureReplaced ) {
				// Make sure that we retrieved a fixture for the subproject
				if ( !fixture.length ) {
					ok( false, "Found subproject fixture" );
					return;
				}

				// Update helper function behavior
				baseURL = subProjectURL;

				// Replace the current fixture, including content outside of #qunit-fixture
				var oldFixture = supportjQuery("#qunit-fixture");
				while ( oldFixture.length && !oldFixture.prevAll("[id='qunit']").length ) {
					oldFixture = oldFixture.parent();
				}
				oldFixture.nextAll().remove();
				oldFixture.replaceWith( fixture );

				// WARNING: UNDOCUMENTED INTERFACE
				QUnit.config.fixture = fixtureHTML;
				reset();
				if ( supportjQuery("#qunit-fixture").html() !== fixtureHTML ) {
					ok( false, "Copied subproject fixture" );
					return;
				}

				fixtureReplaced = true;
			}
			fn.apply( this, arguments );
		};
	}
}

return testSubproject;

});
<|endoftext|>


<commit_before>var assert    = require('assert');
var EasyMySQL = require('../lib/easy_mysql');
var easy_pool = require('../lib/easy_pool');
var common    = require('./common');
var settings  = common.settings;
var clone     = common.clone;
var check_err = common.check_err;
var setup_db  = common.setup_db;

describe('EasyMySQL', function () {
    var easy_mysql;

    beforeEach(function (done) {
        setup_db(function (err, result) {
            check_err(err);
            easy_mysql = EasyMySQL.connect(settings);
            done();
        });
    });

    describe("execute", function () {
        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql", function (done) {
                    var sql = "insert into widgets(name) values (?)";

                    easy_mysql.execute(sql, ['foo'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(result);
                        var sql = "select * from widgets";
                        easy_mysql.execute(sql, function (err, results) {
                            assert.equal(results[0].name, 'foo');
                            done();
                        });
                    });
                });
            });

            describe("without params", function () {
                it("passes query to mysql", function (done) {
                    var sql = "insert into widgets(name) values ('bob')";

                    easy_mysql.execute(sql, function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(result);
                        var sql = "select * from widgets";
                        easy_mysql.execute(sql, function (err, results) {
                            assert.equal(results[0].name, 'bob');
                            done();
                        });
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets where id = ?";
                easy_mysql.execute(sql, [1], function (err, result) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(result, null);
                    done();
                });
            });
        });
    });

    describe("get_one", function () {
        beforeEach(function (done) {
            var sql = "insert into widgets(name) values ('bob'), ('jim')";
            easy_mysql.execute(sql, function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql, returns single object", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_one(sql, ['bob'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.equal(result.name, 'bob');
                        done();
                    });
                });
            });

            describe("without params", function (done) {
                it("passes query to mysql, returns single object", function (done) {
                    var sql = "select name from widgets order by name desc limit 1";
                    easy_mysql.get_one(sql, function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.equal(result.name, 'jim');
                        done();
                    });
                });
            });

            describe("when no results found", function () {
                it("returns null", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_one(sql, ['not real'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.strictEqual(result, null);
                        done();
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets";
                easy_mysql.get_one(sql, function (err, result) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(result, null);
                    done();
                });
            });
        });
    });

    describe("get_all", function () {
        beforeEach(function (done) {
            var sql = "insert into widgets(name) values ('bob'), ('jim')";
            easy_mysql.execute(sql, function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql, returns results array", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_all(sql, ['bob'], function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results[0].name, 'bob');
                        done();
                    });
                });
            });

            describe("without params", function () {
                it("passes query to mysql, returns results array", function (done) {
                    var sql = "select name from widgets order by name desc";
                    easy_mysql.getAll(sql, function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results.length, 2);
                        assert.equal(results[0].name, 'jim');
                        done();
                    });
                });
            });

            describe("when no results found", function () {
                it("returns empty array", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_all(sql, ['not real'], function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results.length, 0);
                        done();
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets";
                easy_mysql.get_all(sql, function (err, results) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(results, null);
                    done();
                });
            });
        });
    });

    describe("connecting with pools", function () {
        beforeEach(function (done) {
            setup_db(function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("EasyMysql.connect_with_pool", function () {
            it("lets us execute queries", function (done) {
                var pool = easy_pool.fetch(settings);
                var easy = EasyMySQL.connect_with_pool(pool);
                var sql  = "insert into widgets(name) values (?)";

                easy_mysql.execute(sql, ['foo'], function (err, result) {
                    check_err(err);
                    assert.strictEqual(err, null);
                    assert.ok(result);
                    var sql = "select * from widgets";
                    easy_mysql.execute(sql, function (err, results) {
                        assert.equal(results[0].name, 'foo');
                        done();
                    });
                });
            });
        });

        describe("EasyMysql.connect_with_easy_pool", function () {
            it("lets us execute queries", function (done) {
                var easy_pool_settings = clone(settings);
                var easy = EasyMySQL.connect_with_easy_pool(easy_pool_settings);
                var sql  = "insert into widgets(name) values (?)";

                easy_mysql.execute(sql, ['foo'], function (err, result) {
                    check_err(err);
                    assert.strictEqual(err, null);
                    assert.ok(result);
                    var sql = "select * from widgets";
                    easy_mysql.execute(sql, function (err, results) {
                        assert.equal(results[0].name, 'foo');
                        done();
                    });
                });
            });
        });
    });
});
<commit_msg>fixing error made when renaming vars<commit_after>var assert    = require('assert');
var EasyMySQL = require('../lib/easy_mysql');
var easy_pool = require('../lib/easy_pool');
var common    = require('./common');
var settings  = common.settings;
var clone     = common.clone;
var check_err = common.check_err;
var setup_db  = common.setup_db;

describe('EasyMySQL', function () {
    var easy_mysql;

    beforeEach(function (done) {
        setup_db(function (err, result) {
            check_err(err);
            easy_mysql = EasyMySQL.connect(settings);
            done();
        });
    });

    describe("execute", function () {
        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql", function (done) {
                    var sql = "insert into widgets(name) values (?)";

                    easy_mysql.execute(sql, ['foo'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(result);
                        var sql = "select * from widgets";
                        easy_mysql.execute(sql, function (err, results) {
                            assert.equal(results[0].name, 'foo');
                            done();
                        });
                    });
                });
            });

            describe("without params", function () {
                it("passes query to mysql", function (done) {
                    var sql = "insert into widgets(name) values ('bob')";

                    easy_mysql.execute(sql, function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(result);
                        var sql = "select * from widgets";
                        easy_mysql.execute(sql, function (err, results) {
                            assert.equal(results[0].name, 'bob');
                            done();
                        });
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets where id = ?";
                easy_mysql.execute(sql, [1], function (err, result) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(result, null);
                    done();
                });
            });
        });
    });

    describe("get_one", function () {
        beforeEach(function (done) {
            var sql = "insert into widgets(name) values ('bob'), ('jim')";
            easy_mysql.execute(sql, function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql, returns single object", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_one(sql, ['bob'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.equal(result.name, 'bob');
                        done();
                    });
                });
            });

            describe("without params", function (done) {
                it("passes query to mysql, returns single object", function (done) {
                    var sql = "select name from widgets order by name desc limit 1";
                    easy_mysql.get_one(sql, function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.equal(result.name, 'jim');
                        done();
                    });
                });
            });

            describe("when no results found", function () {
                it("returns null", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_one(sql, ['not real'], function (err, result) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.strictEqual(result, null);
                        done();
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets";
                easy_mysql.get_one(sql, function (err, result) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(result, null);
                    done();
                });
            });
        });
    });

    describe("get_all", function () {
        beforeEach(function (done) {
            var sql = "insert into widgets(name) values ('bob'), ('jim')";
            easy_mysql.execute(sql, function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("valid queries", function () {
            describe("with params", function () {
                it("passes query and params to mysql, returns results array", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_all(sql, ['bob'], function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results[0].name, 'bob');
                        done();
                    });
                });
            });

            describe("without params", function () {
                it("passes query to mysql, returns results array", function (done) {
                    var sql = "select name from widgets order by name desc";
                    easy_mysql.getAll(sql, function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results.length, 2);
                        assert.equal(results[0].name, 'jim');
                        done();
                    });
                });
            });

            describe("when no results found", function () {
                it("returns empty array", function (done) {
                    var sql = "select * from widgets where name = ?";
                    easy_mysql.get_all(sql, ['not real'], function (err, results) {
                        check_err(err);
                        assert.strictEqual(err, null);
                        assert.ok(Array.isArray(results));
                        assert.equal(results.length, 0);
                        done();
                    });
                });
            });
        });

        describe("with invalid query", function () {
            it("calls done with error", function (done) {
                var sql = "BOGUSselect * from widgets";
                easy_mysql.get_all(sql, function (err, results) {
                    assert.ok(err instanceof Error);
                    assert.strictEqual(results, null);
                    done();
                });
            });
        });
    });

    describe("connecting with pools", function () {
        beforeEach(function (done) {
            setup_db(function (err, result) {
                check_err(err);
                done();
            });
        });

        describe("EasyMysql.connect_with_pool", function () {
            it("lets us execute queries", function (done) {
                var pool = easy_pool.fetch(settings);
                easy_mysql = EasyMySQL.connect_with_pool(pool);
                var sql  = "insert into widgets(name) values (?)";

                easy_mysql.execute(sql, ['foo'], function (err, result) {
                    check_err(err);
                    assert.strictEqual(err, null);
                    assert.ok(result);
                    var sql = "select * from widgets";
                    easy_mysql.execute(sql, function (err, results) {
                        assert.equal(results[0].name, 'foo');
                        done();
                    });
                });
            });
        });

        describe("EasyMysql.connect_with_easy_pool", function () {
            it("lets us execute queries", function (done) {
                var easy_pool_settings = clone(settings);
                easy_mysql = EasyMySQL.connect_with_easy_pool(easy_pool_settings);
                var sql  = "insert into widgets(name) values (?)";

                easy_mysql.execute(sql, ['foo'], function (err, result) {
                    check_err(err);
                    assert.strictEqual(err, null);
                    assert.ok(result);
                    var sql = "select * from widgets";
                    easy_mysql.execute(sql, function (err, results) {
                        assert.equal(results[0].name, 'foo');
                        done();
                    });
                });
            });
        });
    });
});
<|endoftext|>


<commit_before>
var enigmajs = require('..');

// Creating the components of the machine

var eintrittswalzen = [];
eintrittswalzen.push( new enigmajs.Eintrittswalze('ABCDEFGHIJKLMNOPQRSTUVWXYZ') );

var rotoren = [];
rotoren.push( new enigmajs.Rotor('EKMFLGDQVZNTOWYHXUSPAIBRCJ', 'Q',  'I') );
rotoren.push( new enigmajs.Rotor('AJDKSIRUXBLHWTMCQGZNPYFVOE', 'E',  'II') );
rotoren.push( new enigmajs.Rotor('BDFHJLCPRTXVZNYEIWGAKMUSQO', 'V',  'III') );
rotoren.push( new enigmajs.Rotor('ESOVPZJAYQUIRHXLNFTGKDCMWB', 'J',  'IV') );
rotoren.push( new enigmajs.Rotor('VZBRGITYUPSDNHLXAWMJQOFECK', 'Z',  'V') );
// rotoren.push( new enigmajs.Rotor('JPGVOUMFYQBENHZRDKASXLICTW', 'ZM', 'VI') );
// rotoren.push( new enigmajs.Rotor('NZJHGRCXMYSWBOUFAIVLPEKQDT', 'ZM', 'VII') );
// rotoren.push( new enigmajs.Rotor('FKQHTLXOCBJSPDZRAMEWNIUYGV', 'ZM', 'VIII') );

var umkehrwalzen = [];
umkehrwalzen.push( new enigmajs.Umkehrwalze('EJMZALYXVBWFCRQUONTSPIKHGD') );
umkehrwalzen.push( new enigmajs.Umkehrwalze('YRUHQSLDPXNGOKMIEBFZCWVJAT') );
umkehrwalzen.push( new enigmajs.Umkehrwalze('FVPJIAOYEDRZXWGCTKUQSBNMHL') );

var steckerbrett = new enigmajs.Steckerbrett('');

var enigma;

var array = rotoren;
var permutations = [];

for (var i = 0; i < array.length; i++) {
  for (var j = 0; j < array.length; j++) {
    for (var k = 0; k < array.length; k++) {
      if ( i !== j && i !== k && j !== k )
        permutations.push([array[i], array[j], array[k]]);
    }
  }
}

describe('Enigma', function(){

  describe('#getPositions()', function() {

    it('should have position `AAA` after 16901 calls of #rotate()', function() {

      for (var i = 0; i < eintrittswalzen.length; i++) {
        var eintrittswalze = eintrittswalzen[i];

        for (var j = 0; j < umkehrwalzen.length; j++) {
          var ukw = umkehrwalzen[j];

          for (var k = 0; k < permutations.length; k++) {

            enigma = null;
            enigma = new enigmajs.Enigma(permutations[k], ukw, steckerbrett, eintrittswalze);

            enigma.setPositions('AAA');
            enigma.setRingSettings('AAA');

            for (var l = 1; l < (26*25*26+1); l++) {
              enigma.rotate();
            }

            this.timeout(10000);
            enigma.getPositions().should.equal('AAA');

          }
        }
      }

    });
  });
});
<commit_msg>Update enigma-rotation.js<commit_after>
var enigmajs = require('..');

// Creating the components of the machine

var eintrittswalzen = [];
eintrittswalzen.push( new enigmajs.Eintrittswalze('ABCDEFGHIJKLMNOPQRSTUVWXYZ') );

var rotoren = [];
rotoren.push( new enigmajs.Rotor('EKMFLGDQVZNTOWYHXUSPAIBRCJ', 'Q',  'I') );
rotoren.push( new enigmajs.Rotor('AJDKSIRUXBLHWTMCQGZNPYFVOE', 'E',  'II') );
rotoren.push( new enigmajs.Rotor('BDFHJLCPRTXVZNYEIWGAKMUSQO', 'V',  'III') );
rotoren.push( new enigmajs.Rotor('ESOVPZJAYQUIRHXLNFTGKDCMWB', 'J',  'IV') );
rotoren.push( new enigmajs.Rotor('VZBRGITYUPSDNHLXAWMJQOFECK', 'Z',  'V') );
// rotoren.push( new enigmajs.Rotor('JPGVOUMFYQBENHZRDKASXLICTW', 'ZM', 'VI') );
// rotoren.push( new enigmajs.Rotor('NZJHGRCXMYSWBOUFAIVLPEKQDT', 'ZM', 'VII') );
// rotoren.push( new enigmajs.Rotor('FKQHTLXOCBJSPDZRAMEWNIUYGV', 'ZM', 'VIII') );

var umkehrwalzen = [];
umkehrwalzen.push( new enigmajs.Umkehrwalze('EJMZALYXVBWFCRQUONTSPIKHGD') );
umkehrwalzen.push( new enigmajs.Umkehrwalze('YRUHQSLDPXNGOKMIEBFZCWVJAT') );
umkehrwalzen.push( new enigmajs.Umkehrwalze('FVPJIAOYEDRZXWGCTKUQSBNMHL') );

var steckerbrett = new enigmajs.Steckerbrett('');

var enigma;

var permutations = [];

for (var i = 0; i < rotoren.length; i++) {
  for (var j = 0; j < rotoren.length; j++) {
    for (var k = 0; k < rotoren.length; k++) {
      if ( i !== j && i !== k && j !== k )
        permutations.push([rotoren[i], rotoren[j], rotoren[k]]);
    }
  }
}

describe('Enigma', function(){

  describe('#getPositions()', function() {

    it('should have position `AAA` after 16901 calls of #rotate()', function() {

      for (var i = 0; i < eintrittswalzen.length; i++) {
        var eintrittswalze = eintrittswalzen[i];

        for (var j = 0; j < umkehrwalzen.length; j++) {
          var ukw = umkehrwalzen[j];

          for (var k = 0; k < permutations.length; k++) {

            enigma = null;
            enigma = new enigmajs.Enigma(permutations[k], ukw, steckerbrett, eintrittswalze);

            enigma.setPositions('AAA');
            enigma.setRingSettings('AAA');

            for (var l = 1; l < (26*25*26+1); l++) {
              enigma.rotate();
            }

            this.timeout(10000);
            enigma.getPositions().should.equal('AAA');

          }
        }
      }

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


<commit_before>const {basename} = require('path');
const filename = basename(__filename);

const WebSocket = require('ws');
const {VertexServer, VertexSocket} = require('../');

describe(filename, () => {

  let wsServer, vServer;

  let wsServerSocket, wsSocket, vServerSocket, vSocket;

  before('start websocket server', done => {
    wsServer = new WebSocket.Server({ port: 8080 });
    wsServer.on('listening', done);
  });

  after('stop clients', () => {
    if (wsSocket) wsSocket.close();
    if (vSocket) vSocket.destroy();
  });

  after('stop websocket server', done => {
    wsServer.close(done);
  });

  before('start vertex server', done => {
    VertexServer.listen()
      .then(server => {
        vServer = server;
        done();
      })
      .catch(done);
  });

  after('stop vertex server', done => {
    if (!vServer) return done();
    vServer.close();
    done();
  });

  before('connect websocket client', done => {

    wsServer.on('connection', socket => {
      wsServerSocket = socket;
      done();
    });

    wsSocket = new WebSocket('ws://localhost:8080');

  });

  before('connect vertex client', done => {

    vServer.on('connection', socket => {
      vServerSocket = socket;
      // done();
    });

    VertexSocket.connect()
      .then(client => {
        vSocket = client;
        done();
      })
      .catch(done);

  });

  context('small frames', function () {

    // 10000 small frames - websocket:     3094ms
    // 10000 small frames - vertex socket: 1373ms

    this.timeout(10000);

    it('compare websocket', done => {

      let messages = [];
      let count = 10000;
      let startAt = Date.now();

      wsServerSocket.on('message', message => {
        JSON.stringify(JSON.parse(message)); // same load as vertex
        Date.now();
        wsServerSocket.send(message);
      });

      wsSocket.on('message', message => {
        JSON.parse(message);
        Date.now();
        messages.push(message);
        if (messages.length >= count) {

          console.log('%d small frames - websocket: %dms', count, Date.now() - startAt);

          return done();
        }
        wsSocket.send(message);
      });

      wsSocket.send(JSON.stringify({small: 'payload'}));

    });

    it('compare vertex socket', done => {

      let messages = [];
      let count = 10000;
      let startAt = Date.now();

      vServerSocket.on('data', data => {
        vServerSocket.write(data);
      })

      vSocket.on('data', data => {
        messages.push(data);
        if (messages.length >= count) {

          console.log('%d small frames - vertex socket: %dms', count, Date.now() - startAt);

          return done();
        }
        vSocket.write(data);
      })

      vSocket.write({small: 'payload'});

    });

  });

});
<commit_msg>compare websocket<commit_after>const {basename} = require('path');
const filename = basename(__filename);

const WebSocket = require('ws');
const {VertexServer, VertexSocket} = require('../');

describe(filename, () => {

  let wsServer, vServer;

  let wsServerSocket, wsSocket, vServerSocket, vSocket;

  before('start websocket server', done => {
    wsServer = new WebSocket.Server({ port: 8080 });
    wsServer.on('listening', done);
  });

  after('stop clients', () => {
    if (wsSocket) wsSocket.close();
    if (vSocket) vSocket.destroy();
  });

  after('stop websocket server', done => {
    wsServer.close(done);
  });

  before('start vertex server', done => {
    VertexServer.listen()
      .then(server => {
        vServer = server;
        done();
      })
      .catch(done);
  });

  after('stop vertex server', done => {
    if (!vServer) return done();
    vServer.close();
    done();
  });

  before('connect websocket client', done => {

    wsServer.on('connection', socket => {
      wsServerSocket = socket;
      done();
    });

    wsSocket = new WebSocket('ws://localhost:8080');

  });

  before('connect vertex client', done => {

    vServer.on('connection', socket => {
      vServerSocket = socket;
      // done();
    });

    VertexSocket.connect()
      .then(client => {
        vSocket = client;
        vSocket.write(); // prevent "Inactivity on connect" closing the socket
        done();
      })
      .catch(done);

  });

  context('small frames', function () {

    // 10000 small frames - websocket:     3094ms
    // 10000 small frames - vertex socket: 1373ms

    this.timeout(10000);

    it('compare websocket', done => {

      let messages = [];
      let count = 10000;
      let startAt = Date.now();

      wsServerSocket.on('message', message => {
        JSON.stringify(JSON.parse(message)); // same load as vertex
        Date.now();
        wsServerSocket.send(message);
      });

      wsSocket.on('message', message => {
        JSON.parse(message);
        Date.now();
        messages.push(message);
        if (messages.length >= count) {

          console.log('%d small frames - websocket: %dms', count, Date.now() - startAt);

          return done();
        }
        wsSocket.send(message);
      });

      wsSocket.send(JSON.stringify({small: 'payload'}));

    });

    it('compare vertex socket', done => {

      let messages = [];
      let count = 10000;
      let startAt = Date.now();

      vServerSocket.on('data', data => {
        vServerSocket.write(data);
      })

      vSocket.on('data', data => {
        messages.push(data);
        if (messages.length >= count) {

          console.log('%d small frames - vertex socket: %dms', count, Date.now() - startAt);

          return done();
        }
        vSocket.write(data);
      })

      vSocket.write({small: 'payload'});

    });

  });

});
<|endoftext|>


<commit_before>require('./pre');

const assert = require('chai').assert;
const expect = require('chai').expect;
const vulcanval = require('../../src/js/vulcanval');

var vv, map, converted, expected;

describe('Method cleanMap()', function () {

  it('Cleaning a plain map (with disabled and ignored fields)', function () {
    map = {
      a: 1,
      b: true,
      c: 'str1',
      d: 'str2',
      'fieldset.field1': 'a random value',
      weird: 'MSDG=9(#)=KMDF KKFD=AS=:X") =Z=#!"C_=":V#RO',
      rare: {
        trash: 'trash',
        _1: '12dsf2a48as8da5sdas',
        __private: ')/H=FSDM;S=D8C;5$%;C(W=#"%?":#$"¡#$O:!=()$UV;P")'
      }
    };
    expected = {
      b: true,
      d: 'str2',
      'fieldset.field1': 'a random value'
    };
    vv = vulcanval({
      fields: [{
        name: 'a',
        onlyUI: true
      }, {
        name: 'b'
      }, {
        name: 'c',
        disabled: true
      }, {
        name: 'd'
      }, {
        name: 'fieldset.field1'
      }]
    });
    converted = vv.cleanMap(true, map);
    assert.deepEqual(converted, expected);
  });

  it('Cleaning a nested map (with disabled and ignored fields)', function () {
    map = {
      set1: {
        field1: 'str1',
        field2: 'str2'
      },
      off: 'this is off',
      set2: {
        set3: {
          field3: true,
          field4: false,
          moreOff: 'Gsdfsd$(=dfsDFUUDFIKMVS#29838594JKIEJT(%#/(/"(&4?"¡")")))',
        },
        field5: 'str3'
      }
    };
    expected = {
      set1: {
        field2: 'str2'
      },
      set2: {
        set3: {
          field4: false
        },
        field5: 'str3'
      }
    };
    vv = vulcanval({
      fields: [
        { name: 'set1.field1', disabled: true },
        { name: 'set1.field2' },
        { name: 'set2.set3.field3', onlyUI: true },
        { name: 'set2.set3.field4' },
        { name: 'set2.field5' }
      ]
    });
    converted = vv.cleanMap(false, map);
    assert.deepEqual(converted, expected);
  });
});
<commit_msg>[test] cleanMap<commit_after>require('./pre');

const assert = require('chai').assert;
const expect = require('chai').expect;
const vulcanval = require('../../src/js/vulcanval');

describe('Method cleanMap()', function () {

  it('Cleaning a plain map (with disabled and ignored fields)', function () {
    const map = {
      a: 1,
      b: true,
      c: 'str1',
      d: 'str2',
      'fieldset.field1': 'a random value',
      weird: 'MSDG=9(#)=KMDF KKFD=AS=:X") =Z=#!"C_=":V#RO',
      rare: {
        trash: 'trash',
        _1: '12dsf2a48as8da5sdas',
        __private: ')/H=FSDM;S=D8C;5$%;C(W=#"%?":#$"¡#$O:!=()$UV;P")'
      }
    };
    const expected = {
      b: true,
      d: 'str2',
      'fieldset.field1': 'a random value'
    };
    const vv = vulcanval({
      fields: [{
        name: 'a',
        onlyUI: true
      }, {
        name: 'b'
      }, {
        name: 'c',
        disabled: true
      }, {
        name: 'd'
      }, {
        name: 'fieldset.field1'
      }]
    });
    const converted = vv.cleanMap(true, map);
    assert.deepEqual(converted, expected);
  });

  it('Cleaning a nested map (with disabled and ignored fields)', function () {
    const map = {
      set1: {
        field1: 'str1',
        field2: 'str2'
      },
      off: 'this is off',
      set2: {
        set3: {
          field3: true,
          field4: false,
          moreOff: 'Gsdfsd$(=dfsDFUUDFIKMVS#29838594JKIEJT(%#/(/"(&4?"¡")")))',
        },
        field5: 'str3'
      }
    };
    const expected = {
      set1: {
        field2: 'str2'
      },
      set2: {
        set3: {
          field4: false
        },
        field5: 'str3'
      }
    };
    const vv = vulcanval({
      fields: [
        { name: 'set1.field1', disabled: true },
        { name: 'set1.field2' },
        { name: 'set2.set3.field3', onlyUI: true },
        { name: 'set2.set3.field4' },
        { name: 'set2.field5' }
      ]
    });
    const converted = vv.cleanMap(false, map);
    assert.deepEqual(converted, expected);
  });

  it('Clean a map with undefined properties', function () {
    const map = {
      name: 'string',
      something: true,
      email: null,
      here: {},
    };
    const vv = vulcanval({
      fields: [{
        name: 'name',
        required: true,
      }, {
        name: 'surname',
        required: true,
      }, {
        name: 'email',
        required: true,
      }]
    });
    const actual = vv.cleanMap(true, map);
    const expected = {
      name: 'string',
      email: null,
    };
    expect(actual).to.eql(expected);
  });

  it('By default it cleans a plain map', function () {
    const map = {
      name: 'string',
      something: true,
      email: null,
      here: {},
    };
    const vv = vulcanval({
      fields: [{
        name: 'name',
        required: true,
      }, {
        name: 'surname',
        required: true,
      }, {
        name: 'email',
        required: true,
      }]
    });
    const actual = vv.cleanMap(map);
    const expected = {
      name: 'string',
      email: null,
    };
    expect(actual).to.eql(expected);
  });

});
<|endoftext|>