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

    var models = {};
    var collections = {};

    models.Release = Backbone.Model.extend({
        constructorName: 'Release',
        urlRoot: '/api/releases'
    });

    models.Releases = Backbone.Collection.extend({
        constructorName: 'Releases',
        model: models.Release,
        url: '/api/releases',
        comparator: function(release) {
            return release.id;
        }
    });

    models.Cluster = Backbone.Model.extend({
        constructorName: 'Cluster',
        urlRoot: '/api/clusters',
        defaults: function() {
            var defaults = {
                nodes: new models.Nodes(),
                tasks: new models.Tasks()
            };
            defaults.nodes.cluster = defaults.tasks.cluster = this;
            return defaults;
        },
        validate: function(attrs) {
            var errors = {};
            if (!$.trim(attrs.name) || $.trim(attrs.name).length == 0) {
                errors.name = 'Environment name cannot be empty';
            }
            if (!attrs.release) {
                errors.release = 'Please choose OpenStack release';
            }
            return _.isEmpty(errors) ? null : errors;
        },
        task: function(taskName, status) {
            return this.get('tasks') && this.get('tasks').find(function(task) {
                var result = false;
                if (task.get('name') == taskName) {
                    if (status) {
                        if (_.isArray(status)) {
                            result = _.contains(status, task.get('status'));
                        } else {
                            result = status == task.get('status');
                        }
                    } else {
                        result = true;
                    }
                }
                return result;
            });
        },
        hasChanges: function() {
            return this.get('nodes').hasChanges() || (this.get('changes').length && this.get('nodes').currentNodes().length);
        },
        needsRedeployment: function() {
            return this.get('nodes').where({pending_addition: false, status: 'error'}).length;
        },
        canChangeMode: function(newMode) {
            var nodes = this.get('nodes');
            return !(nodes.currentNodes().length || nodes.where({role: 'controller'}).length > 1 || (newMode && newMode == 'singlenode' && (nodes.length > 1 || (nodes.length == 1 && !nodes.where({role: 'controller'}).length))));
        },
        canAddNodes: function(role) {
            // forbid adding when tasks are running
            if (this.task('deploy', 'running') || this.task('verify_networks', 'running')) {
                return false;
            }
            // forbid add more than 1 controller in simple mode
            if (role == 'controller' && this.get('mode') != 'ha' && _.filter(this.get('nodes').nodesAfterDeployment(), function(node) {return node.get('role') == role;}).length >= 1) {
                return false;
            }
            return true;
        },
        canDeleteNodes: function(role) {
            // forbid deleting when tasks are running
            if (this.task('deploy', 'running') || this.task('verify_networks', 'running')) {
                return false;
            }
            // forbid deleting when there is nothing to delete
            if (!_.filter(this.get('nodes').nodesAfterDeployment(), function(node) {return node.get('role') == role;}).length) {
                return false;
            }
            return true;
        },
        availableModes: function() {
            return ['multinode', 'ha'];
        },
        availableRoles: function() {
            var roles = ['controller'];
            if (this.get('mode') != 'singlenode') {
                if (this.get('type') == 'both') {
                    roles.push('compute', 'cinder');
                } else {
                    roles.push(this.get('type'));
                }
            }
            return roles;
        },
        parse: function(response) {
            response.release = new models.Release(response.release);
            return response;
        },
        fetchRelated: function(related, options) {
            return this.get(related).fetch(_.extend({data: {cluster_id: this.id}}, options));
        }
    });

    models.Clusters = Backbone.Collection.extend({
        constructorName: 'Clusters',
        model: models.Cluster,
        url: '/api/clusters',
        comparator: function(cluster) {
            return cluster.id;
        }
    });

    models.Node = Backbone.Model.extend({
        constructorName: 'Node',
        urlRoot: '/api/nodes',
        volumeGroupsByRoles: function(role) {
            var volumeGroups =  {
                controller: ['os'],
                compute: ['os', 'vm'],
                cinder: ['os', 'cinder']
            };
            return volumeGroups[role];
        },
        resource: function(resourceName) {
            var resource = 0;
            try {
                if (resourceName == 'cores') {
                    resource = this.get('meta').cpu.total;
                } else if (resourceName == 'hdd') {
                    var hdd = 0;
                    _.each(this.get('meta').disks, function(disk) {
                        if (_.isNumber(disk.size)) {
                            hdd += disk.size;
                        }
                    });
                    resource = hdd;
                } else if (resourceName == 'ram') {
                    resource = this.get('meta').memory.total / Math.pow(1024, 3);
                }
            } catch (e) {}
            if (_.isNaN(resource)) {
                resource = 0;
            }
            return resource;
        }
    });

    models.Nodes = Backbone.Collection.extend({
        constructorName: 'Nodes',
        model: models.Node,
        url: '/api/nodes',
        comparator: function(node) {
            return node.id;
        },
        hasChanges: function() {
            return !!this.filter(function(node) {
                return node.get('pending_addition') || node.get('pending_deletion');
            }).length;
        },
        currentNodes: function() {
            return this.filter(function(node) {return !node.get('pending_addition');});
        },
        nodesAfterDeployment: function() {
            return this.filter(function(node) {return node.get('pending_addition') || !node.get('pending_deletion');});
        },
        resources: function(resourceName) {
            var resources = this.map(function(node) {return node.resource(resourceName);});
            return _.reduce(resources, function(sum, n) {return sum + n;}, 0);
        }
    });

    models.Task = Backbone.Model.extend({
        constructorName: 'Task',
        urlRoot: '/api/tasks'
    });

    models.Tasks = Backbone.Collection.extend({
        constructorName: 'Tasks',
        model: models.Task,
        url: '/api/tasks',
        toJSON: function(options) {
            return this.pluck('id');
        },
        comparator: function(task) {
            return task.id;
        }
    });

    models.Notification = Backbone.Model.extend({
        constructorName: 'Notification',
        urlRoot: '/api/notifications'
    });

    models.Notifications = Backbone.Collection.extend({
        constructorName: 'Notifications',
        model: models.Notification,
        url: '/api/notifications',
        comparator: function(notification) {
            return notification.id;
        }
    });

    models.Settings = Backbone.Model.extend({
        constructorName: 'Settings',
        urlRoot: '/api/clusters/',
        isNew: function() {
            return false;
        }
    });

    models.Disk = Backbone.Model.extend({
        constructorName: 'Disk',
        urlRoot: '/api/nodes/',
        validate: function(attrs, options) {
            var errors = {};
            var volume = _.find(attrs.volumes, {vg: options.group});
            if (_.isNaN(volume.size) || volume.size < 0) {
                errors[volume.vg] = 'Invalid size';
            } else if (volume.size > options.unallocated) {
                errors[volume.vg] = 'Maximal size is ' + options.unallocated + ' GB';
            } else if (volume.size < options.min) {
                errors[volume.vg] = 'Minimal size is ' + options.min + ' GB';
            }
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Disks = Backbone.Collection.extend({
        constructorName: 'Disks',
        model: models.Disk,
        url: '/api/nodes/',
        comparator: function(disk) {
            return disk.id;
        }
    });

    models.Interface = Backbone.Model.extend({
        constructorName: 'Interface',
        parse: function(response) {
            response.assigned_networks = new models.InterfaceNetworks(response.assigned_networks);
            return response;
        },
        toJSON: function(options) {
            return _.extend(this.constructor.__super__.toJSON.call(this, options), {assigned_networks: this.get('assigned_networks').toJSON()});
        }
    });

    models.Interfaces = Backbone.Collection.extend({
        constructorName: 'Interfaces',
        model: models.Interface,
        comparator: function(ifc) {
            return ifc.get('name');
        }
    });

    models.InterfaceNetwork = Backbone.Model.extend({
        constructorName: 'InterfaceNetwork'
    });

    models.InterfaceNetworks = Backbone.Collection.extend({
        constructorName: 'InterfaceNetworks',
        model: models.InterfaceNetwork
    });

    models.NodeInterfaceConfiguration = Backbone.Model.extend({
        constructorName: 'NodeInterfaceConfiguration',
        parse: function(response) {
            response.interfaces = new models.Interfaces(response.interfaces);
            return response;
        }
    });

    models.NodeInterfaceConfigurations = Backbone.Collection.extend({
        url: '/api/nodes/interfaces',
        constructorName: 'NodeInterfaceConfigurations',
        model: models.NodeInterfaceConfiguration
    });

    models.Network = Backbone.Model.extend({
        constructorName: 'Network',
        getAttributes: function() {
            var attributes = {
                'floating': ['ip_ranges', 'vlan_start'],
                'public': ['ip_ranges', 'vlan_start', 'netmask', 'gateway'],
                'management': ['cidr', 'vlan_start'],
                'storage': ['cidr', 'vlan_start'],
                'fixed': ['cidr', 'amount', 'network_size', 'vlan_start']
            };
            return attributes[this.get('name')] || ['vlan_start'];
        },
        validateIP: function(value) {
            var ipRegexp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
            return _.isString(value) && !value.match(ipRegexp);
        },
        validate: function(attrs) {
            var errors = {};
            var match;
            _.each(this.getAttributes(), _.bind(function(attribute) {
                if (attribute == 'ip_ranges') {
                    _.each(attrs.ip_ranges, _.bind(function(range, index) {
                        if (_.first(range) || _.last(range)) {
                            var rangeErrors = {index: index};
                            if (_.first(range) && this.validateIP(_.first(range))) {
                                rangeErrors.start = 'Invalid IP';
                            }
                            if (_.last(range) && this.validateIP(_.last(range))) {
                                rangeErrors.end = 'Invalid IP';
                            }
                            if (rangeErrors.start || rangeErrors.end) {
                                errors.ip_ranges = _.compact(_.union([rangeErrors], errors.ip_ranges));
                            }
                        }
                    }, this));
                } else if (attribute == 'cidr') {
                    var cidrRegexp = /^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2]\d|3[0-2])$/;
                    if (_.isString(attrs.cidr)) {
                        match = attrs.cidr.match(cidrRegexp);
                        if (match) {
                            var prefix = parseInt(match[1], 10);
                            if (prefix < 2) {
                                errors.cidr = 'Network is too large';
                            }
                            if (prefix > 30) {
                                errors.cidr = 'Network is too small';
                            }
                        } else {
                            errors.cidr = 'Invalid CIDR';
                        }
                    } else {
                        errors.cidr = 'Invalid CIDR';
                    }
                } else if (attribute == 'vlan_start') {
                    if (_.isString(attrs.vlan_start)) {
                        match = attrs.vlan_start.match(/^[0-9]+$/);
                        if (match) {
                            attrs.vlan_start = parseInt(match[0], 10);
                        } else {
                            errors.vlan_start = 'Invalid VLAN ID';
                        }
                    }
                    if (_.isNaN(attrs.vlan_start) || !_.isNumber(attrs.vlan_start) || attrs.vlan_start < 1 || attrs.vlan_start > 4094) {
                        errors.vlan_start = 'Invalid VLAN ID';
                    }
                } else if (attribute == 'netmask' && this.validateIP(attrs.netmask)) {
                    errors.netmask = 'Invalid netmask';
                } else if (attribute == 'gateway' && this.validateIP(attrs.gateway)) {
                    errors.gateway = 'Invalid gateway';
                } else if (attribute == 'amount') {
                    if (_.isString(attrs.amount)) {
                        match = attrs.amount.match(/^[0-9]+$/);
                        if (match) {
                            attrs.amount = parseInt(match[0], 10);
                        } else {
                            errors.amount = 'Invalid amount of networks';
                        }
                    }
                    if (!attrs.amount || (attrs.amount && (!_.isNumber(attrs.amount) || attrs.amount < 1))) {
                        errors.amount = 'Invalid amount of networks';
                    }
                    if (attrs.amount && attrs.amount > 4095 - attrs.vlan_start) {
                        errors.amount = 'Number of networks needs more VLAN IDs than available. Check VLAN ID Range field.';
                    }
                }
            }, this));
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Networks = Backbone.Collection.extend({
        constructorName: 'Networks',
        model: models.Network,
        comparator: function(network) {
            return network.id && network.get('name') != 'public';
        }
    });

    models.NetworkConfiguration = Backbone.Model.extend({
        constructorName: 'NetworkConfiguration',
        urlRoot: '/api/clusters',
        parse: function(response) {
            response.networks = new models.Networks(response.networks);
            return response;
        },
        toJSON: function() {
            return {
                net_manager: this.get('net_manager'),
                networks: this.get('networks').toJSON()
            };
        },
        isNew: function() {
            return false;
        }
    });

    models.LogSource = Backbone.Model.extend({
        constructorName: 'LogSource',
        urlRoot: '/api/logs/sources'
    });

    models.LogSources = Backbone.Collection.extend({
        constructorName: 'LogSources',
        model: models.LogSource,
        url: '/api/logs/sources'
    });

    return models;
});
<commit_msg>Add validation for empy range<commit_after>define(function() {
    'use strict';

    var models = {};
    var collections = {};

    models.Release = Backbone.Model.extend({
        constructorName: 'Release',
        urlRoot: '/api/releases'
    });

    models.Releases = Backbone.Collection.extend({
        constructorName: 'Releases',
        model: models.Release,
        url: '/api/releases',
        comparator: function(release) {
            return release.id;
        }
    });

    models.Cluster = Backbone.Model.extend({
        constructorName: 'Cluster',
        urlRoot: '/api/clusters',
        defaults: function() {
            var defaults = {
                nodes: new models.Nodes(),
                tasks: new models.Tasks()
            };
            defaults.nodes.cluster = defaults.tasks.cluster = this;
            return defaults;
        },
        validate: function(attrs) {
            var errors = {};
            if (!$.trim(attrs.name) || $.trim(attrs.name).length == 0) {
                errors.name = 'Environment name cannot be empty';
            }
            if (!attrs.release) {
                errors.release = 'Please choose OpenStack release';
            }
            return _.isEmpty(errors) ? null : errors;
        },
        task: function(taskName, status) {
            return this.get('tasks') && this.get('tasks').find(function(task) {
                var result = false;
                if (task.get('name') == taskName) {
                    if (status) {
                        if (_.isArray(status)) {
                            result = _.contains(status, task.get('status'));
                        } else {
                            result = status == task.get('status');
                        }
                    } else {
                        result = true;
                    }
                }
                return result;
            });
        },
        hasChanges: function() {
            return this.get('nodes').hasChanges() || (this.get('changes').length && this.get('nodes').currentNodes().length);
        },
        needsRedeployment: function() {
            return this.get('nodes').where({pending_addition: false, status: 'error'}).length;
        },
        canChangeMode: function(newMode) {
            var nodes = this.get('nodes');
            return !(nodes.currentNodes().length || nodes.where({role: 'controller'}).length > 1 || (newMode && newMode == 'singlenode' && (nodes.length > 1 || (nodes.length == 1 && !nodes.where({role: 'controller'}).length))));
        },
        canAddNodes: function(role) {
            // forbid adding when tasks are running
            if (this.task('deploy', 'running') || this.task('verify_networks', 'running')) {
                return false;
            }
            // forbid add more than 1 controller in simple mode
            if (role == 'controller' && this.get('mode') != 'ha' && _.filter(this.get('nodes').nodesAfterDeployment(), function(node) {return node.get('role') == role;}).length >= 1) {
                return false;
            }
            return true;
        },
        canDeleteNodes: function(role) {
            // forbid deleting when tasks are running
            if (this.task('deploy', 'running') || this.task('verify_networks', 'running')) {
                return false;
            }
            // forbid deleting when there is nothing to delete
            if (!_.filter(this.get('nodes').nodesAfterDeployment(), function(node) {return node.get('role') == role;}).length) {
                return false;
            }
            return true;
        },
        availableModes: function() {
            return ['multinode', 'ha'];
        },
        availableRoles: function() {
            var roles = ['controller'];
            if (this.get('mode') != 'singlenode') {
                if (this.get('type') == 'both') {
                    roles.push('compute', 'cinder');
                } else {
                    roles.push(this.get('type'));
                }
            }
            return roles;
        },
        parse: function(response) {
            response.release = new models.Release(response.release);
            return response;
        },
        fetchRelated: function(related, options) {
            return this.get(related).fetch(_.extend({data: {cluster_id: this.id}}, options));
        }
    });

    models.Clusters = Backbone.Collection.extend({
        constructorName: 'Clusters',
        model: models.Cluster,
        url: '/api/clusters',
        comparator: function(cluster) {
            return cluster.id;
        }
    });

    models.Node = Backbone.Model.extend({
        constructorName: 'Node',
        urlRoot: '/api/nodes',
        volumeGroupsByRoles: function(role) {
            var volumeGroups =  {
                controller: ['os'],
                compute: ['os', 'vm'],
                cinder: ['os', 'cinder']
            };
            return volumeGroups[role];
        },
        resource: function(resourceName) {
            var resource = 0;
            try {
                if (resourceName == 'cores') {
                    resource = this.get('meta').cpu.total;
                } else if (resourceName == 'hdd') {
                    var hdd = 0;
                    _.each(this.get('meta').disks, function(disk) {
                        if (_.isNumber(disk.size)) {
                            hdd += disk.size;
                        }
                    });
                    resource = hdd;
                } else if (resourceName == 'ram') {
                    resource = this.get('meta').memory.total / Math.pow(1024, 3);
                }
            } catch (e) {}
            if (_.isNaN(resource)) {
                resource = 0;
            }
            return resource;
        }
    });

    models.Nodes = Backbone.Collection.extend({
        constructorName: 'Nodes',
        model: models.Node,
        url: '/api/nodes',
        comparator: function(node) {
            return node.id;
        },
        hasChanges: function() {
            return !!this.filter(function(node) {
                return node.get('pending_addition') || node.get('pending_deletion');
            }).length;
        },
        currentNodes: function() {
            return this.filter(function(node) {return !node.get('pending_addition');});
        },
        nodesAfterDeployment: function() {
            return this.filter(function(node) {return node.get('pending_addition') || !node.get('pending_deletion');});
        },
        resources: function(resourceName) {
            var resources = this.map(function(node) {return node.resource(resourceName);});
            return _.reduce(resources, function(sum, n) {return sum + n;}, 0);
        }
    });

    models.Task = Backbone.Model.extend({
        constructorName: 'Task',
        urlRoot: '/api/tasks'
    });

    models.Tasks = Backbone.Collection.extend({
        constructorName: 'Tasks',
        model: models.Task,
        url: '/api/tasks',
        toJSON: function(options) {
            return this.pluck('id');
        },
        comparator: function(task) {
            return task.id;
        }
    });

    models.Notification = Backbone.Model.extend({
        constructorName: 'Notification',
        urlRoot: '/api/notifications'
    });

    models.Notifications = Backbone.Collection.extend({
        constructorName: 'Notifications',
        model: models.Notification,
        url: '/api/notifications',
        comparator: function(notification) {
            return notification.id;
        }
    });

    models.Settings = Backbone.Model.extend({
        constructorName: 'Settings',
        urlRoot: '/api/clusters/',
        isNew: function() {
            return false;
        }
    });

    models.Disk = Backbone.Model.extend({
        constructorName: 'Disk',
        urlRoot: '/api/nodes/',
        validate: function(attrs, options) {
            var errors = {};
            var volume = _.find(attrs.volumes, {vg: options.group});
            if (_.isNaN(volume.size) || volume.size < 0) {
                errors[volume.vg] = 'Invalid size';
            } else if (volume.size > options.unallocated) {
                errors[volume.vg] = 'Maximal size is ' + options.unallocated + ' GB';
            } else if (volume.size < options.min) {
                errors[volume.vg] = 'Minimal size is ' + options.min + ' GB';
            }
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Disks = Backbone.Collection.extend({
        constructorName: 'Disks',
        model: models.Disk,
        url: '/api/nodes/',
        comparator: function(disk) {
            return disk.id;
        }
    });

    models.Interface = Backbone.Model.extend({
        constructorName: 'Interface',
        parse: function(response) {
            response.assigned_networks = new models.InterfaceNetworks(response.assigned_networks);
            return response;
        },
        toJSON: function(options) {
            return _.extend(this.constructor.__super__.toJSON.call(this, options), {assigned_networks: this.get('assigned_networks').toJSON()});
        }
    });

    models.Interfaces = Backbone.Collection.extend({
        constructorName: 'Interfaces',
        model: models.Interface,
        comparator: function(ifc) {
            return ifc.get('name');
        }
    });

    models.InterfaceNetwork = Backbone.Model.extend({
        constructorName: 'InterfaceNetwork'
    });

    models.InterfaceNetworks = Backbone.Collection.extend({
        constructorName: 'InterfaceNetworks',
        model: models.InterfaceNetwork
    });

    models.NodeInterfaceConfiguration = Backbone.Model.extend({
        constructorName: 'NodeInterfaceConfiguration',
        parse: function(response) {
            response.interfaces = new models.Interfaces(response.interfaces);
            return response;
        }
    });

    models.NodeInterfaceConfigurations = Backbone.Collection.extend({
        url: '/api/nodes/interfaces',
        constructorName: 'NodeInterfaceConfigurations',
        model: models.NodeInterfaceConfiguration
    });

    models.Network = Backbone.Model.extend({
        constructorName: 'Network',
        getAttributes: function() {
            var attributes = {
                'floating': ['ip_ranges', 'vlan_start'],
                'public': ['ip_ranges', 'vlan_start', 'netmask', 'gateway'],
                'management': ['cidr', 'vlan_start'],
                'storage': ['cidr', 'vlan_start'],
                'fixed': ['cidr', 'amount', 'network_size', 'vlan_start']
            };
            return attributes[this.get('name')] || ['vlan_start'];
        },
        validateIP: function(value) {
            var ipRegexp = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
            return _.isString(value) && !value.match(ipRegexp);
        },
        validate: function(attrs) {
            var errors = {};
            var match;
            _.each(this.getAttributes(), _.bind(function(attribute) {
                if (attribute == 'ip_ranges') {
                    _.each(attrs.ip_ranges, _.bind(function(range, index) {
                        if (_.first(range) || _.last(range)) {
                            var rangeErrors = {index: index};
                            if (_.first(range) && this.validateIP(_.first(range))) {
                                rangeErrors.start = 'Invalid IP';
                            }
                            if (_.last(range) && this.validateIP(_.last(range))) {
                                rangeErrors.end = 'Invalid IP';
                            }
                            if (_.first(range) == '') {
                                rangeErrors.start = 'Empty range';
                            }
                            if (_.last(range) == '') {
                                rangeErrors.end = 'Empty range';
                            }
                            if (rangeErrors.start || rangeErrors.end) {
                                errors.ip_ranges = _.compact(_.union([rangeErrors], errors.ip_ranges));
                            }
                        }
                    }, this));
                } else if (attribute == 'cidr') {
                    var cidrRegexp = /^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2]\d|3[0-2])$/;
                    if (_.isString(attrs.cidr)) {
                        match = attrs.cidr.match(cidrRegexp);
                        if (match) {
                            var prefix = parseInt(match[1], 10);
                            if (prefix < 2) {
                                errors.cidr = 'Network is too large';
                            }
                            if (prefix > 30) {
                                errors.cidr = 'Network is too small';
                            }
                        } else {
                            errors.cidr = 'Invalid CIDR';
                        }
                    } else {
                        errors.cidr = 'Invalid CIDR';
                    }
                } else if (attribute == 'vlan_start') {
                    if (_.isString(attrs.vlan_start)) {
                        match = attrs.vlan_start.match(/^[0-9]+$/);
                        if (match) {
                            attrs.vlan_start = parseInt(match[0], 10);
                        } else {
                            errors.vlan_start = 'Invalid VLAN ID';
                        }
                    }
                    if (_.isNaN(attrs.vlan_start) || !_.isNumber(attrs.vlan_start) || attrs.vlan_start < 1 || attrs.vlan_start > 4094) {
                        errors.vlan_start = 'Invalid VLAN ID';
                    }
                } else if (attribute == 'netmask' && this.validateIP(attrs.netmask)) {
                    errors.netmask = 'Invalid netmask';
                } else if (attribute == 'gateway' && this.validateIP(attrs.gateway)) {
                    errors.gateway = 'Invalid gateway';
                } else if (attribute == 'amount') {
                    if (_.isString(attrs.amount)) {
                        match = attrs.amount.match(/^[0-9]+$/);
                        if (match) {
                            attrs.amount = parseInt(match[0], 10);
                        } else {
                            errors.amount = 'Invalid amount of networks';
                        }
                    }
                    if (!attrs.amount || (attrs.amount && (!_.isNumber(attrs.amount) || attrs.amount < 1))) {
                        errors.amount = 'Invalid amount of networks';
                    }
                    if (attrs.amount && attrs.amount > 4095 - attrs.vlan_start) {
                        errors.amount = 'Number of networks needs more VLAN IDs than available. Check VLAN ID Range field.';
                    }
                }
            }, this));
            return _.isEmpty(errors) ? null : errors;
        }
    });

    models.Networks = Backbone.Collection.extend({
        constructorName: 'Networks',
        model: models.Network,
        comparator: function(network) {
            return network.id && network.get('name') != 'public';
        }
    });

    models.NetworkConfiguration = Backbone.Model.extend({
        constructorName: 'NetworkConfiguration',
        urlRoot: '/api/clusters',
        parse: function(response) {
            response.networks = new models.Networks(response.networks);
            return response;
        },
        toJSON: function() {
            return {
                net_manager: this.get('net_manager'),
                networks: this.get('networks').toJSON()
            };
        },
        isNew: function() {
            return false;
        }
    });

    models.LogSource = Backbone.Model.extend({
        constructorName: 'LogSource',
        urlRoot: '/api/logs/sources'
    });

    models.LogSources = Backbone.Collection.extend({
        constructorName: 'LogSources',
        model: models.LogSource,
        url: '/api/logs/sources'
    });

    return models;
});
<|endoftext|>


<commit_before>var Color = require('../lib/Color');

console.log(Color.fromHex('#FF0000'));<commit_msg>Updated test for fromHex<commit_after>var Color = require('../lib/Color');

console.log(Color.fromHex('#FF0000').a == 1);<|endoftext|>


<commit_before>/* globals require casper Jupyter */
var system = require('system');

var root = casper,
  _img = 0,
  node_modules = system.env.NBPRESENT_TEST_MODULES || "../../../node_modules",
  vendor = root.vendor = root.vendor ? root.vendor : (root.vendor = {}),
  _ = vendor._ = require(node_modules + "/lodash"),
  _shotDir = "_unnamed";

function nextId(){
  return ("000" + (_img++)).slice(-4);
}

function slug(text){
  return text.replace(/[^a-z0-9]/g, "_");
}

root.screenshot = function(message){
  return this.captureSelector([
      "screenshots/",
       _shotDir,
       "/",
       nextId(),
       "_",
       slug(message),
       ".png"
    ].join(""),
    "body"
  );
};

root.screenshot.init = function(ns){
  _shotDir = ns;
  _img = 0;
  return root;
};

root.canSeeAndClick = function(message, visible, click){
  var things = message;

  if(arguments.length !== 1){
    things = [[message, visible, click]];
  }

  var that = this;

  things.map(function(thing){
    var message = thing[0],
      visible = thing[1],
      click = thing[2];

    that = that
      .waitUntilVisible(visible)
      .then(function(){
        this.test.assertExists(click || visible, "I can see and click " + message);
        this.screenshot(message);
        this.click(click || visible);
      });
  });

  return that;
}

root.hasMeta = function(path, tests){
  var meta;

  this.thenEvaluate(function () {
    require(['base/js/events'], function(events) {
      Jupyter._save_success = Jupyter._save_failed = false;
      events.on('notebook_saved.Notebook', function () {
        Jupyter._save_success = true;
      });
      events.on('notebook_save_failed.Notebook',
        function (event, error) {
          Jupyter._save_failed = "save failed with " + error;
      });
      Jupyter.notebook.save_notebook();
    });
});

this.waitFor(function () {
  return this.evaluate(function(){
    return Jupyter._save_failed || Jupyter._save_success;
  });
});

return this
  .then(function(){
    meta = this.evaluate(function(){
      return Jupyter.notebook.metadata;
    });
  })
  .then(function(){
    _.map(tests, function(test, message){
      var results = test(_.get(meta, path));
      this.test.assertEquals(results[0], results[1],
        "I remember " + message + " in " + path);
    }, this);
  });
};

root.dragRelease = function(message, selector, opts){
  var it, x, y, x1, y1;
  return this.then(function(){
    it = this.getElementBounds(selector);
    x = it.left + it.width / 2;
    y = it.top + it.height / 2;
    x1 = x + (opts.right || -opts.left || 0);
    y1 = y + (opts.down || -opts.up || 0);
  })
  .then(function(){
    this.mouse.down(x, y);
  })
  .then(function(){
    this.screenshot("click " + message);
    this.mouse.move(x1, y1);
  })
  .then(function(){
    this.screenshot("drag " + message);
    this.mouse.up(x1, y1);
  })
  .then(function(){
    this.screenshot("release " + message);
  });
};

root.baseline_notebook = function(){
  // the actual test

  this.append_cell();
  this.set_cell_text(1, [
    'from IPython.display import Markdown',
    'Markdown("# Hello World!")'
  ].join("\n"));
  this.execute_cell_then(1);

  this.append_cell();
  this.set_cell_text(2, [
    'from ipywidgets import FloatSlider',
    'x = FloatSlider()',
    'x'
  ].join("\n"));
  this.execute_cell_then(2);
}

root.saveNbpresent = function (){
  return this.thenEvaluate(function(){
    window.nbpresent.mode.metadata(true);
  });
}
<commit_msg>using simpler utils from nb_anacondacloud<commit_after>;(function(){
  "use strict";

  var system = require('system');

  var root = casper,
    _img = 0,
    _shotDir = "unnamed";

  function nextId(){
    return ("000" + (_img++)).slice(-4);
  }

  function slug(text){
    return text.replace(/[^a-z0-9]/g, "_");
  }

  root.screenshot = function(message){
    this.captureSelector([
        "screenshots/",
         _shotDir,
         "/",
         nextId(),
         "_",
         slug(message),
         ".png",
      ].join(""),
      "body"
    );
  };

  root.screenshot.init = function(ns){
    _shotDir = ns;
    _img = 0;
  };

  root.canSeeAndClick = function(message, visible, click){
    return this
      .waitUntilVisible(visible)
      .then(function(){
        this.test.assertExists(click || visible, "I can see and click " + message);
        this.screenshot(message);
        this.click(click || visible);
      });
  }

  root.dragRelease = function(message, selector, opts){
    var it, x, y, x1, y1;
    return this.then(function(){
      it = this.getElementBounds(selector);
      x = it.left + it.width / 2;
      y = it.top + it.height / 2;
      x1 = x + (opts.right || -opts.left || 0);
      y1 = y + (opts.down || -opts.up || 0);
    })
    .then(function(){
      this.mouse.down(x, y);
    })
    .then(function(){
      this.screenshot("click " + message);
      this.mouse.move(x1, y1);
    })
    .then(function(){
      this.screenshot("drag " + message);
      this.mouse.up(x1, y1);
    })
    .then(function(){
      this.screenshot("release " + message);
    });
  };

  root.baseline_notebook = function(){
    // the actual test
    this.set_cell_text(0, [
      'from IPython.display import Markdown',
      'Markdown("# Hello World!")'
    ].join("\n"));
    this.execute_cell_then(0);

    this.append_cell();
  };

  root.runCell = function(idx, lines){
    // the actual test
    this.set_cell_text(idx, lines.join("\n"));
    this.execute_cell_then(idx);
  }

}).call(this);
<|endoftext|>


<commit_before>var tape = require('tape')
var pull = require('pull-stream')
var pushable = require('pull-pushable')
var mux = require('../')

module.exports = function(serializer, buffers) {

  var b = buffers
  ? function (b) {
    return (
        Buffer.isBuffer(b)
      ? {type: 'Buffer', data: [].slice.call(b) }
      : b
    )
  }
  : function (b) { return b }

  var client = {
    hello  : 'async',
    goodbye: 'async',
    stuff  : 'source',
    bstuff : 'source',
    things : 'sink',
    suchstreamwow: 'duplex'
  }

  tape('async', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      hello: function (a, cb) {
        cb(null, 'hello, '+a)
      },
      goodbye: function(b, cb) {
        cb(null, b)
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    A.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')

      var buf = new Buffer([0, 1, 2, 3, 4])
      A.goodbye(buf, function (err, buf2) {
        if (err) throw err
        console.log(b(buf2), b(buf))
        t.deepEqual(b(buf2), b(buf))
        t.end()
      })
    })

  })

  tape('source', function (t) {

    var expected = [
          new Buffer([0, 1]),
          new Buffer([2, 3]),
          new Buffer([4, 5])
        ]

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      stuff: function (b) {
        return pull.values([1, 2, 3, 4, 5].map(function (a) {
          return a * b
        }))
      },
      bstuff: function() {
        return pull.values(expected)
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    pull(A.stuff(5), pull.collect(function (err, ary) {
      if(err) throw err
      console.log(ary)
      t.deepEqual(ary, [5, 10, 15, 20, 25])

      pull(A.bstuff(), pull.collect(function(err, ary) {
        if (err) throw err
        console.log(ary.map(b), expected.map(b))
        t.deepEqual(ary.map(b), expected.map(b))
        t.end()
      }))
    }))

  })

  tape('sync', function (t) {
    var client = {
      syncOk : 'sync',
      syncErr: 'sync'
    }

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      syncOk: function (a) {
        return {okay: a}
      },
      syncErr: function(b) {
        throw new Error('test error:'+b)
      }
    })

    var s = A.createStream()
    pull(s, B.createStream(), s)

    A.syncOk(true, function (err, value) {
      t.deepEqual(value, {okay: true})
      A.syncErr('blah', function (err) {
        t.equal(err.message, 'test error:blah')
        t.end()

      })
    })

  })

  tape('sink', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      things: function (someParam) {
        return pull.collect(function(err, values) {
          if (err) throw err
          t.equal(someParam, 5)
          t.deepEqual(values, [1, 2, 3, 4, 5])
          t.end()
        })
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)
    pull(pull.values([1,2,3,4,5]), A.things(5))
  })

  tape('duplex', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      suchstreamwow: function (someParam) {
        // did the param come through?
        t.equal(someParam, 5)

        // normally, we'd use pull.values and pull.collect
        // however, pull.values sends 'end' onto the stream, which closes the muxrpc stream immediately
        // ...and we need the stream to stay open for the drain to collect
        var nextValue = 0
        var p = pushable()
        for (var i=0; i < 5; i++)
          p.push(i)
        return {
          source: p,
          sink: pull.drain(function(value) {
            console.log('************', nextValue, value)
            t.equal(nextValue, value)
            nextValue++
            if (nextValue == 5)
              t.end()
          })
        }
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log.bind(console, 'IN')), B.createStream(), pull.through(console.log.bind(console,'OUT')), s)
    var dup = A.suchstreamwow(5)
    pull(dup, dup)
  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      t.ok(err)
      t.end()
    })

    s.sink(function (abort, cb) { cb(true) })
  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      console.log('CB!')
      t.ok(err)
      t.end()
    })

    s.source(true, function () {})
  })

  tape('buffer calls before stream is created', function (t) {
    var A = mux(client, null) ()
    var B = mux(null, client) ({
      hello: function (a, cb) {
        cb(null, 'hello, '+a)
      },
    })

    A.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')
      t.end()
    })

    var s = A.createStream()
    pull(s, B.createStream(), s)

  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      t.ok(err)

      var B = mux(null, client) ({
        hello: function (a, cb) {
          cb(null, 'hello, '+a)
        },
      })

      var s = A.createStream()

      pull(s, B.createStream(), s)

      A.hello('world', function (err, value) {
        t.notOk(err)
        t.equal(value, 'hello, world')
        t.end()
      })
    })

    s.sink(function (abort, cb) { cb(true) })
  })

  tape('recover error written to outer stream', function (t) {

    var A = mux(client, null) ()
    var err = new Error('testing errors')
    var s = A.createStream(function (_err) {
      t.equal(_err, err)
      t.end()
    })

    pull(pull.error(err), s.sink)

  })

  tape('recover error when outer stream aborted', function (t) {

    var A = mux(client, null) ()
    var err = new Error('testing errors')
    var s = A.createStream(function (_err) {
      t.equal(_err, err)
      t.end()
    })

    s.source(err, function () {})
  })

  tape('cb when stream is ended', function (t) {

    var A = mux(client, null) ()
    var s = A.createStream(function (_err) {
      t.equal(_err, null)
      t.end()
    })

    pull(pull.empty(), s.sink)

  })

  tape('cb when stream is aborted', function (t) {

    var A = mux(client, null) ()
    var s = A.createStream(function (_err) {
      t.equal(_err, null)
      t.end()
    })

    s.source(true, function () {})
  })

  var client2 = {
    salutations: {
      hello: 'async',
      goodbye: 'async'
    }
  }

  tape('nested methods', function (t) {
    var A = mux(client2, null, serializer) ()
    var B = mux(null, client2, serializer) ({
      salutations: {
        hello: function (a, cb) {
          cb(null, 'hello, '+a)
        },
        goodbye: function(b, cb) {
          cb(null, b)
        }
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    A.salutations.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')

      var buf = new Buffer([0, 1, 2, 3, 4])
      A.salutations.goodbye(buf, function (err, buf2) {
        if (err) throw err
        t.deepEqual( b(buf2), b(buf))
        t.end()
      })
    })

  })

  tape('sink', function (t) {
    var A = mux(client, null, serializer)()
    var B = mux(null, client, serializer)({
      things: function (len) {
        return pull.collect(function (err, ary) {
          t.equal(ary.length, len)
        })
      }
    })

    var s = A.createStream(); pull(s, B.createStream(), s)

    pull(pull.values([1,2,3]), A.things(3, function (err) {
      if(err) throw err
      t.end()
    }))
  })

  tape('sink - abort', function (t) {
    var err = new Error('test abort error')

    var A = mux(client, null, serializer)()
    var B = mux(null, client, serializer)({
      things: function (len) {
        return function (read) {
          read(err, function () {})
        }
      }
    })

    var s = A.createStream(); pull(s, B.createStream(), s)

    pull(pull.values([1,2,3]), A.things(3, function (_err) {
      t.ok(_err)
      t.equal(_err.message, err.message)
      t.end()
    }))

  })

}

//see ./jsonb.js for tests with serialization.
if(!module.parent)
  module.exports(function (e) { return e });
<commit_msg>handle the different way of JSONing buffers<commit_after>var tape = require('tape')
var pull = require('pull-stream')
var pushable = require('pull-pushable')
var mux = require('../')

module.exports = function(serializer, buffers) {

  var b = buffers
  ? function (b) {
    return (
        Buffer.isBuffer(b)
        //reserialize, to take into the account
        //changes Buffer#toJSON between 0.10 and 0.12
      ? JSON.parse(JSON.stringify(b))
      : b
    )
  }
  : function (b) { return b }

  var client = {
    hello  : 'async',
    goodbye: 'async',
    stuff  : 'source',
    bstuff : 'source',
    things : 'sink',
    suchstreamwow: 'duplex'
  }

  tape('async', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      hello: function (a, cb) {
        cb(null, 'hello, '+a)
      },
      goodbye: function(b, cb) {
        cb(null, b)
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    A.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')

      var buf = new Buffer([0, 1, 2, 3, 4])
      A.goodbye(buf, function (err, buf2) {
        if (err) throw err
        console.log(b(buf2), b(buf))
        t.deepEqual(b(buf2), b(buf))
        t.end()
      })
    })

  })

  tape('source', function (t) {

    var expected = [
          new Buffer([0, 1]),
          new Buffer([2, 3]),
          new Buffer([4, 5])
        ]

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      stuff: function (b) {
        return pull.values([1, 2, 3, 4, 5].map(function (a) {
          return a * b
        }))
      },
      bstuff: function() {
        return pull.values(expected)
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    pull(A.stuff(5), pull.collect(function (err, ary) {
      if(err) throw err
      console.log(ary)
      t.deepEqual(ary, [5, 10, 15, 20, 25])

      pull(A.bstuff(), pull.collect(function(err, ary) {
        if (err) throw err
        console.log(ary.map(b), expected.map(b))
        t.deepEqual(ary.map(b), expected.map(b))
        t.end()
      }))
    }))

  })

  tape('sync', function (t) {
    var client = {
      syncOk : 'sync',
      syncErr: 'sync'
    }

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      syncOk: function (a) {
        return {okay: a}
      },
      syncErr: function(b) {
        throw new Error('test error:'+b)
      }
    })

    var s = A.createStream()
    pull(s, B.createStream(), s)

    A.syncOk(true, function (err, value) {
      t.deepEqual(value, {okay: true})
      A.syncErr('blah', function (err) {
        t.equal(err.message, 'test error:blah')
        t.end()

      })
    })

  })

  tape('sink', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      things: function (someParam) {
        return pull.collect(function(err, values) {
          if (err) throw err
          t.equal(someParam, 5)
          t.deepEqual(values, [1, 2, 3, 4, 5])
          t.end()
        })
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)
    pull(pull.values([1,2,3,4,5]), A.things(5))
  })

  tape('duplex', function (t) {

    var A = mux(client, null, serializer) ()
    var B = mux(null, client, serializer) ({
      suchstreamwow: function (someParam) {
        // did the param come through?
        t.equal(someParam, 5)

        // normally, we'd use pull.values and pull.collect
        // however, pull.values sends 'end' onto the stream, which closes the muxrpc stream immediately
        // ...and we need the stream to stay open for the drain to collect
        var nextValue = 0
        var p = pushable()
        for (var i=0; i < 5; i++)
          p.push(i)
        return {
          source: p,
          sink: pull.drain(function(value) {
            console.log('************', nextValue, value)
            t.equal(nextValue, value)
            nextValue++
            if (nextValue == 5)
              t.end()
          })
        }
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log.bind(console, 'IN')), B.createStream(), pull.through(console.log.bind(console,'OUT')), s)
    var dup = A.suchstreamwow(5)
    pull(dup, dup)
  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      t.ok(err)
      t.end()
    })

    s.sink(function (abort, cb) { cb(true) })
  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      console.log('CB!')
      t.ok(err)
      t.end()
    })

    s.source(true, function () {})
  })

  tape('buffer calls before stream is created', function (t) {
    var A = mux(client, null) ()
    var B = mux(null, client) ({
      hello: function (a, cb) {
        cb(null, 'hello, '+a)
      },
    })

    A.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')
      t.end()
    })

    var s = A.createStream()
    pull(s, B.createStream(), s)

  })

  tape('async - error', function (t) {
    var A = mux(client, null) ()

    var s = A.createStream()

    A.hello('world', function (err, value) {
      t.ok(err)

      var B = mux(null, client) ({
        hello: function (a, cb) {
          cb(null, 'hello, '+a)
        },
      })

      var s = A.createStream()

      pull(s, B.createStream(), s)

      A.hello('world', function (err, value) {
        t.notOk(err)
        t.equal(value, 'hello, world')
        t.end()
      })
    })

    s.sink(function (abort, cb) { cb(true) })
  })

  tape('recover error written to outer stream', function (t) {

    var A = mux(client, null) ()
    var err = new Error('testing errors')
    var s = A.createStream(function (_err) {
      t.equal(_err, err)
      t.end()
    })

    pull(pull.error(err), s.sink)

  })

  tape('recover error when outer stream aborted', function (t) {

    var A = mux(client, null) ()
    var err = new Error('testing errors')
    var s = A.createStream(function (_err) {
      t.equal(_err, err)
      t.end()
    })

    s.source(err, function () {})
  })

  tape('cb when stream is ended', function (t) {

    var A = mux(client, null) ()
    var s = A.createStream(function (_err) {
      t.equal(_err, null)
      t.end()
    })

    pull(pull.empty(), s.sink)

  })

  tape('cb when stream is aborted', function (t) {

    var A = mux(client, null) ()
    var s = A.createStream(function (_err) {
      t.equal(_err, null)
      t.end()
    })

    s.source(true, function () {})
  })

  var client2 = {
    salutations: {
      hello: 'async',
      goodbye: 'async'
    }
  }

  tape('nested methods', function (t) {
    var A = mux(client2, null, serializer) ()
    var B = mux(null, client2, serializer) ({
      salutations: {
        hello: function (a, cb) {
          cb(null, 'hello, '+a)
        },
        goodbye: function(b, cb) {
          cb(null, b)
        }
      }
    })

    var s = A.createStream()
    pull(s, pull.through(console.log), B.createStream(), pull.through(console.log), s)

    A.salutations.hello('world', function (err, value) {
      if(err) throw err
      console.log(value)
      t.equal(value, 'hello, world')

      var buf = new Buffer([0, 1, 2, 3, 4])
      A.salutations.goodbye(buf, function (err, buf2) {
        if (err) throw err
        t.deepEqual( b(buf2), b(buf))
        t.end()
      })
    })

  })

  tape('sink', function (t) {
    var A = mux(client, null, serializer)()
    var B = mux(null, client, serializer)({
      things: function (len) {
        return pull.collect(function (err, ary) {
          t.equal(ary.length, len)
        })
      }
    })

    var s = A.createStream(); pull(s, B.createStream(), s)

    pull(pull.values([1,2,3]), A.things(3, function (err) {
      if(err) throw err
      t.end()
    }))
  })

  tape('sink - abort', function (t) {
    var err = new Error('test abort error')

    var A = mux(client, null, serializer)()
    var B = mux(null, client, serializer)({
      things: function (len) {
        return function (read) {
          read(err, function () {})
        }
      }
    })

    var s = A.createStream(); pull(s, B.createStream(), s)

    pull(pull.values([1,2,3]), A.things(3, function (_err) {
      t.ok(_err)
      t.equal(_err.message, err.message)
      t.end()
    }))

  })

}

//see ./jsonb.js for tests with serialization.
if(!module.parent)
  module.exports(function (e) { return e });
<|endoftext|>


<commit_before>var bncode = require('bncode')
var createTorrent = require('../')
var crypto = require('crypto')
var parseTorrent = require('parse-torrent')
var test = require('tape')

function sha1 (buf) {
  return crypto.createHash('sha1').update(buf).digest('hex')
}

test('create single file torrent', function (t) {
  t.plan(12)

  var leavesPath = __dirname + '/content/Leaves of Grass by Walt Whitman.epub'

  var startTime = Date.now()
  createTorrent(leavesPath, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'Leaves of Grass by Walt Whitman.epub')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.equals(parsedTorrent.files[0].path, 'Leaves of Grass by Walt Whitman.epub')
    t.equals(parsedTorrent.files[0].length, 362017)

    t.equal(parsedTorrent.length, 362017)
    t.equal(parsedTorrent.pieceLength, 16384)

    t.deepEquals(parsedTorrent.pieces, [
      '1f9c3f59beec079715ec53324bde8569e4a0b4eb',
      'ec42307d4ce5557b5d3964c5ef55d354cf4a6ecc',
      '7bf1bcaf79d11fa5e0be06593c8faafc0c2ba2cf',
      '76d71c5b01526b23007f9e9929beafc5151e6511',
      '0931a1b44c21bf1e68b9138f90495e690dbc55f5',
      '72e4c2944cbacf26e6b3ae8a7229d88aafa05f61',
      'eaae6abf3f07cb6db9677cc6aded4dd3985e4586',
      '27567fa7639f065f71b18954304aca6366729e0b',
      '4773d77ae80caa96a524804dfe4b9bd3deaef999',
      'c9dd51027467519d5eb2561ae2cc01467de5f643',
      '0a60bcba24797692efa8770d23df0a830d91cb35',
      'b3407a88baa0590dc8c9aa6a120f274367dcd867',
      'e88e8338c572a06e3c801b29f519df532b3e76f6',
      '70cf6aee53107f3d39378483f69cf80fa568b1ea',
      'c53b506159e988d8bc16922d125d77d803d652c3',
      'ca3070c16eed9172ab506d20e522ea3f1ab674b3',
      'f923d76fe8f44ff32e372c3b376564c6fb5f0dbe',
      '52164f03629fd1322636babb2c014b7dae582da4',
      '1363965261e6ce12b43701f0a8c9ed1520a70eba',
      '004400a267765f6d3dd5c7beb5bd3c75f3df2a54',
      '560a61801147fa4ec7cf568e703acb04e5610a4d',
      '56dcc242d03293e9446cf5e457d8eb3d9588fd90',
      'c698de9b0dad92980906c026d8c1408fa08fe4ec'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), 'd2474e86c95b19b8bcfdb92bc12c9d44667cfa36')
  })
})

test('create multi file torrent', function (t) {
  t.plan(16)

  var numbersPath = __dirname + '/content/numbers'

  var startTime = Date.now()
  createTorrent(numbersPath, {
    pieceLength: 32768, // force piece length to 32KB so info-hash will
                        // match what transmission generataed, since we use
                        // a different algo for picking piece length

    private: false      // also force `private: false` to match transmission

  }, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'numbers')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.deepEquals(parsedTorrent.files[0].path, 'numbers/1.txt')
    t.deepEquals(parsedTorrent.files[0].length, 1)

    t.deepEquals(parsedTorrent.files[1].path, 'numbers/2.txt')
    t.deepEquals(parsedTorrent.files[1].length, 2)

    t.deepEquals(parsedTorrent.files[2].path, 'numbers/3.txt')
    t.deepEquals(parsedTorrent.files[2].length, 3)

    t.equal(parsedTorrent.length, 6)
    t.equal(parsedTorrent.pieceLength, 32768)

    t.deepEquals(parsedTorrent.pieces, [
      '1f74648e50a6a6708ec54ab327a163d5536b7ced'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), '80562f38656b385ea78959010e51a2cc9db41ea0')

  })
})

test('create multi file torrent with nested directories', function (t) {
  t.plan(22)

  var numbersPath = __dirname + '/content/lots-of-numbers'

  var startTime = Date.now()
  createTorrent(numbersPath, {
    pieceLength: 32768, // force piece length to 32KB so info-hash will
                        // match what transmission generataed, since we use
                        // a different algo for picking piece length

    private: false      // also force `private: false` to match transmission

  }, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'lots-of-numbers')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.deepEquals(parsedTorrent.files[0].path, 'lots-of-numbers/big numbers/10.txt')
    t.deepEquals(parsedTorrent.files[0].length, 2)

    t.deepEquals(parsedTorrent.files[1].path, 'lots-of-numbers/big numbers/11.txt')
    t.deepEquals(parsedTorrent.files[1].length, 2)

    t.deepEquals(parsedTorrent.files[2].path, 'lots-of-numbers/big numbers/12.txt')
    t.deepEquals(parsedTorrent.files[2].length, 2)

    t.deepEquals(parsedTorrent.files[3].path, 'lots-of-numbers/small numbers/1.txt')
    t.deepEquals(parsedTorrent.files[3].length, 1)

    t.deepEquals(parsedTorrent.files[4].path, 'lots-of-numbers/small numbers/2.txt')
    t.deepEquals(parsedTorrent.files[4].length, 2)

    t.deepEquals(parsedTorrent.files[5].path, 'lots-of-numbers/small numbers/3.txt')
    t.deepEquals(parsedTorrent.files[5].length, 3)

    t.equal(parsedTorrent.length, 12)
    t.equal(parsedTorrent.pieceLength, 32768)

    t.deepEquals(parsedTorrent.pieces, [
      '47972f2befaee58b6f3860cd39bd56cb33a488f0'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), '427887e9c03e123f9c8458b1947090edf1c75baa')

  })
})
<commit_msg>whitespace<commit_after>var bncode = require('bncode')
var createTorrent = require('../')
var crypto = require('crypto')
var parseTorrent = require('parse-torrent')
var test = require('tape')

function sha1 (buf) {
  return crypto.createHash('sha1').update(buf).digest('hex')
}

test('create single file torrent', function (t) {
  t.plan(12)

  var leavesPath = __dirname + '/content/Leaves of Grass by Walt Whitman.epub'

  var startTime = Date.now()
  createTorrent(leavesPath, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'Leaves of Grass by Walt Whitman.epub')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.equals(parsedTorrent.files[0].path, 'Leaves of Grass by Walt Whitman.epub')
    t.equals(parsedTorrent.files[0].length, 362017)

    t.equal(parsedTorrent.length, 362017)
    t.equal(parsedTorrent.pieceLength, 16384)

    t.deepEquals(parsedTorrent.pieces, [
      '1f9c3f59beec079715ec53324bde8569e4a0b4eb',
      'ec42307d4ce5557b5d3964c5ef55d354cf4a6ecc',
      '7bf1bcaf79d11fa5e0be06593c8faafc0c2ba2cf',
      '76d71c5b01526b23007f9e9929beafc5151e6511',
      '0931a1b44c21bf1e68b9138f90495e690dbc55f5',
      '72e4c2944cbacf26e6b3ae8a7229d88aafa05f61',
      'eaae6abf3f07cb6db9677cc6aded4dd3985e4586',
      '27567fa7639f065f71b18954304aca6366729e0b',
      '4773d77ae80caa96a524804dfe4b9bd3deaef999',
      'c9dd51027467519d5eb2561ae2cc01467de5f643',
      '0a60bcba24797692efa8770d23df0a830d91cb35',
      'b3407a88baa0590dc8c9aa6a120f274367dcd867',
      'e88e8338c572a06e3c801b29f519df532b3e76f6',
      '70cf6aee53107f3d39378483f69cf80fa568b1ea',
      'c53b506159e988d8bc16922d125d77d803d652c3',
      'ca3070c16eed9172ab506d20e522ea3f1ab674b3',
      'f923d76fe8f44ff32e372c3b376564c6fb5f0dbe',
      '52164f03629fd1322636babb2c014b7dae582da4',
      '1363965261e6ce12b43701f0a8c9ed1520a70eba',
      '004400a267765f6d3dd5c7beb5bd3c75f3df2a54',
      '560a61801147fa4ec7cf568e703acb04e5610a4d',
      '56dcc242d03293e9446cf5e457d8eb3d9588fd90',
      'c698de9b0dad92980906c026d8c1408fa08fe4ec'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), 'd2474e86c95b19b8bcfdb92bc12c9d44667cfa36')
  })
})

test('create multi file torrent', function (t) {
  t.plan(16)

  var numbersPath = __dirname + '/content/numbers'

  var startTime = Date.now()
  createTorrent(numbersPath, {
    pieceLength: 32768, // force piece length to 32KB so info-hash will
                        // match what transmission generataed, since we use
                        // a different algo for picking piece length

    private: false      // also force `private: false` to match transmission

  }, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'numbers')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.deepEquals(parsedTorrent.files[0].path, 'numbers/1.txt')
    t.deepEquals(parsedTorrent.files[0].length, 1)

    t.deepEquals(parsedTorrent.files[1].path, 'numbers/2.txt')
    t.deepEquals(parsedTorrent.files[1].length, 2)

    t.deepEquals(parsedTorrent.files[2].path, 'numbers/3.txt')
    t.deepEquals(parsedTorrent.files[2].length, 3)

    t.equal(parsedTorrent.length, 6)
    t.equal(parsedTorrent.pieceLength, 32768)

    t.deepEquals(parsedTorrent.pieces, [
      '1f74648e50a6a6708ec54ab327a163d5536b7ced'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), '80562f38656b385ea78959010e51a2cc9db41ea0')
  })
})

test('create multi file torrent with nested directories', function (t) {
  t.plan(22)

  var numbersPath = __dirname + '/content/lots-of-numbers'

  var startTime = Date.now()
  createTorrent(numbersPath, {
    pieceLength: 32768, // force piece length to 32KB so info-hash will
                        // match what transmission generataed, since we use
                        // a different algo for picking piece length

    private: false      // also force `private: false` to match transmission

  }, function (err, torrent) {
    t.error(err)

    var parsedTorrent = parseTorrent(torrent)

    t.equals(parsedTorrent.name, 'lots-of-numbers')

    t.notOk(parsedTorrent.private)

    var createdTime = parsedTorrent.created / 1000
    t.ok(createdTime >= startTime, 'created time is after start time')
    t.ok(createdTime <= Date.now(), 'created time is before now')

    t.deepEquals(parsedTorrent.announceList, [
      ['udp://tracker.publicbt.com:80/announce'],
      ['udp://tracker.openbittorrent.com:80/announce']
    ])

    t.deepEquals(parsedTorrent.files[0].path, 'lots-of-numbers/big numbers/10.txt')
    t.deepEquals(parsedTorrent.files[0].length, 2)

    t.deepEquals(parsedTorrent.files[1].path, 'lots-of-numbers/big numbers/11.txt')
    t.deepEquals(parsedTorrent.files[1].length, 2)

    t.deepEquals(parsedTorrent.files[2].path, 'lots-of-numbers/big numbers/12.txt')
    t.deepEquals(parsedTorrent.files[2].length, 2)

    t.deepEquals(parsedTorrent.files[3].path, 'lots-of-numbers/small numbers/1.txt')
    t.deepEquals(parsedTorrent.files[3].length, 1)

    t.deepEquals(parsedTorrent.files[4].path, 'lots-of-numbers/small numbers/2.txt')
    t.deepEquals(parsedTorrent.files[4].length, 2)

    t.deepEquals(parsedTorrent.files[5].path, 'lots-of-numbers/small numbers/3.txt')
    t.deepEquals(parsedTorrent.files[5].length, 3)

    t.equal(parsedTorrent.length, 12)
    t.equal(parsedTorrent.pieceLength, 32768)

    t.deepEquals(parsedTorrent.pieces, [
      '47972f2befaee58b6f3860cd39bd56cb33a488f0'
    ])

    t.equals(sha1(parsedTorrent.infoBuffer), '427887e9c03e123f9c8458b1947090edf1c75baa')
  })
})
<|endoftext|>


<commit_before>var assert = require('assert'),
    sys = require('sys'),
    redis = require('../index');

module.exports = {
  'should load locally': function() {
      var redisClient = redis.createClient();

      assert.isNotNull(redisClient);
      assert.eql(redisClient.port, 6379);
      assert.eql(redisClient.host, "127.0.0.1");
      assert.isNotNull(redis.redis);

      redisClient.quit();
  },

  'should load when in heroku': function() {
      var currentREDISTOGO_URL = process.env.REDISTOGO_URL;
      process.env.REDISTOGO_URL = "redis://user:password@chubb.redistogo.com:9332/";

      var redisClient = redis.createClient();
      redisClient.on('error', function (err) {
          assert.includes(err.toString(), 'invalid password');
          redisClient.quit();
          process.exit(0); // this is not great, but I have not found any other way to stop the test suite...
      });

      assert.isNotNull(redisClient);
      assert.eql(redisClient.port, 9332);
      assert.eql(redisClient.host, "chubb.redistogo.com");
      assert.eql(redisClient.auth_pass, "password");
      assert.isNotNull(redis.redis);

      redisClient.quit();

      process.env.REDISTOGO_URL = currentREDISTOGO_URL;
  }
};
<commit_msg>taking away sys require<commit_after>var assert = require('assert'),
    redis = require('../index');

module.exports = {
  'should load locally': function() {
      var redisClient = redis.createClient();

      assert.isNotNull(redisClient);
      assert.eql(redisClient.port, 6379);
      assert.eql(redisClient.host, "127.0.0.1");
      assert.isNotNull(redis.redis);

      redisClient.quit();
  },

  'should load when in heroku': function() {
      var currentREDISTOGO_URL = process.env.REDISTOGO_URL;
      process.env.REDISTOGO_URL = "redis://user:password@chubb.redistogo.com:9332/";

      var redisClient = redis.createClient();
      redisClient.on('error', function (err) {
          assert.includes(err.toString(), 'invalid password');
          redisClient.quit();
          process.exit(0); // this is not great, but I have not found any other way to stop the test suite...
      });

      assert.isNotNull(redisClient);
      assert.eql(redisClient.port, 9332);
      assert.eql(redisClient.host, "chubb.redistogo.com");
      assert.eql(redisClient.auth_pass, "password");
      assert.isNotNull(redis.redis);

      redisClient.quit();

      process.env.REDISTOGO_URL = currentREDISTOGO_URL;
  }
};
<|endoftext|>


<commit_before>var test = require('tape');
var factor = require('../');
var mdeps = require('module-deps');
var through = require('through');
var path = require('path');
var fs = require('fs');
var pack = require('browser-pack');
var concat = require('concat-stream');
var vm = require('vm');

test('more complicated dependencies', function (t) {
    t.plan(5);
    var files = [ 'x.js', 'y.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [ read('z.js'), read('a.js') ],
        'x.js': [
            read('x.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            })
        ],
        'y.js': [
            read('y.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './a.js': norm('a.js') }
            })
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        'x.js': pack({ raw: true }),
        'y.js': pack({ raw: true })
    };

    var pending = 3;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['x.js'].pipe(concat(function (src) {
        sources['x.js'] = src;
        done();
    }));
    packs['y.js'].pipe(concat(function (src) {
        sources['y.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srcx = 'require=' + sources.common
            + ';require=' + sources['x.js']
        ;
        function logx (msg) { t.equal(msg, 55500) }
        vm.runInNewContext(srcx, { console: { log: logx } });

        var srcy = 'require=' + sources.common
            + ';require=' + sources['y.js']
        ;
        function logy (msg) { t.equal(msg, 333) }
        vm.runInNewContext(srcy, { console: { log: logy } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true });
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('same module included twice', function (t) {
    //t.plan(5);
    t.plan(3);

    var files = [ 't.js' ].map(function (file) {
        return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [],
        't.js': [
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true })
    };

    var pending = 2;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logx (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logx } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true });
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('threshold function reorganizes bundles', function (t) {
    t.plan(5);
    var files = [ 'y.js', 't.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [
            read('z.js')
        ],
        't.js': [
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ],
        'y.js': [
            read('y.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './a.js': norm('a.js') }
            }),
            read('a.js')
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true }),
        'y.js': pack({ raw: true })
    };

    var pending = 3;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));
    packs['y.js'].pipe(concat(function (src) {
        sources['y.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logt (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logt } });

        var srcy = 'require=' + sources.common
            + ';require=' + sources['y.js']
        ;
        function logy (msg) { t.equal(msg, 333) }
        vm.runInNewContext(srcy, { console: { log: logy } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true, threshold: function(row, groups) {
        if (/.*a\.js$/.test(row.id)) {
            return false;
        };
        if (/.*[z]\.js$/.test(row.id)) {
            return true;
        };
        return this._defaultThreshold(row, groups);
    }});
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('if dependent is in common, so is dependee', function (t) {
    t.plan(3);
    var files = [ 't.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ],
        't.js': [
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            })
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true }),
    };

    var pending = 2;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logt (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logt } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true, threshold: function(row, groups) {
        if (/.*[w]\.js$/.test(row.id)) {
            return true;
        };
        return this._defaultThreshold(row, groups);
    }});
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

function rowsOf (cb) {
    var rows = [];
    return through(write, end);

    function write (row) { rows.push(row) }
    function end () { cb(rows) }
}

function read (name, ref) {
    if (!ref) ref = {};
    var file = norm(name);
    ref.id = file;
    ref.source = fs.readFileSync(file, 'utf8');
    if (!ref.deps) ref.deps = {};
    return ref;
}

function norm (file) {
    return path.normalize(__dirname + '/files/' + file);
}
<commit_msg>less fragile files test orderings<commit_after>var test = require('tape');
var factor = require('../');
var mdeps = require('module-deps');
var through = require('through');
var path = require('path');
var fs = require('fs');
var pack = require('browser-pack');
var concat = require('concat-stream');
var vm = require('vm');

test('more complicated dependencies', function (t) {
    t.plan(5);
    var files = [ 'x.js', 'y.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [ read('z.js'), read('a.js') ],
        'x.js': [
            read('x.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            })
        ],
        'y.js': [
            read('y.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './a.js': norm('a.js') }
            })
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        'x.js': pack({ raw: true }),
        'y.js': pack({ raw: true })
    };

    var pending = 3;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['x.js'].pipe(concat(function (src) {
        sources['x.js'] = src;
        done();
    }));
    packs['y.js'].pipe(concat(function (src) {
        sources['y.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srcx = 'require=' + sources.common
            + ';require=' + sources['x.js']
        ;
        function logx (msg) { t.equal(msg, 55500) }
        vm.runInNewContext(srcx, { console: { log: logx } });

        var srcy = 'require=' + sources.common
            + ';require=' + sources['y.js']
        ;
        function logy (msg) { t.equal(msg, 333) }
        vm.runInNewContext(srcy, { console: { log: logy } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true });
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('same module included twice', function (t) {
    //t.plan(5);
    t.plan(3);

    var files = [ 't.js' ].map(function (file) {
        return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [],
        't.js': sortRows([
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ])
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true })
    };

    var pending = 2;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logx (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logx } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true });
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('threshold function reorganizes bundles', function (t) {
    t.plan(5);
    var files = [ 'y.js', 't.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [
            read('z.js')
        ],
        't.js': sortRows([
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            }),
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ]),
        'y.js': sortRows([
            read('y.js', {
                entry: true,
                deps: { './z.js': norm('z.js'), './a.js': norm('a.js') }
            }),
            read('a.js')
        ])
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true }),
        'y.js': pack({ raw: true })
    };

    var pending = 3;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));
    packs['y.js'].pipe(concat(function (src) {
        sources['y.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logt (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logt } });

        var srcy = 'require=' + sources.common
            + ';require=' + sources['y.js']
        ;
        function logy (msg) { t.equal(msg, 333) }
        vm.runInNewContext(srcy, { console: { log: logy } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true, threshold: function(row, groups) {
        if (/.*a\.js$/.test(row.id)) {
            return false;
        };
        if (/.*[z]\.js$/.test(row.id)) {
            return true;
        };
        return this._defaultThreshold(row, groups);
    }});
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

test('if dependent is in common, so is dependee', function (t) {
    t.plan(3);
    var files = [ 't.js' ].map(function (file) {
      return path.join(__dirname, 'files', file);
    });

    var expected = {
        common: [
            read('w.js', {
                deps: { './a.js': norm('a.js') }
            }),
            read('a.js')
        ],
        't.js': [
            read('t.js', {
                entry: true,
                deps: { './a.js': norm('a.js'), './w.js': norm('w.js') }
            })
        ]
    };

    var packs = {
        common: pack({ raw: true }),
        't.js': pack({ raw: true }),
    };

    var pending = 2;

    var sources = {};
    packs.common.pipe(concat(function (src) {
        sources.common = src;
        done();
    }));
    packs['t.js'].pipe(concat(function (src) {
        sources['t.js'] = src;
        done();
    }));

    function done () {
        if (--pending !== 0) return;
        var srct = 'require=' + sources.common
            + ';require=' + sources['t.js']
        ;
        function logt (msg) { t.equal(msg, 300) }
        vm.runInNewContext(srct, { console: { log: logt } });
    }

    var rows = [];
    var fr = factor(files, { objectMode: true, raw: true, threshold: function(row, groups) {
        if (/.*[w]\.js$/.test(row.id)) {
            return true;
        };
        return this._defaultThreshold(row, groups);
    }});
    fr.on('stream', function (bundle) {
        var name = path.basename(bundle.file);
        bundle.pipe(rowsOf(function (rows) {
            t.deepEqual(rows, expected[name]);
        }));
        bundle.pipe(packs[name]);
    });
    mdeps(files).pipe(fr)
    fr.pipe(rowsOf(function (rows) {
        t.deepEqual(rows, expected.common);
    }));
    fr.pipe(packs.common);
});

function rowsOf (cb) {
    var rows = [];
    return through(write, end);

    function write (row) { rows.push(row) }
    function end () { cb(sortRows(rows)) }
}

function sortRows (rows) {
    return rows.sort(function (a, b) {
        return a.id < b.id ? 1 : -1;
    });
}

function read (name, ref) {
    if (!ref) ref = {};
    var file = norm(name);
    ref.id = file;
    ref.source = fs.readFileSync(file, 'utf8');
    if (!ref.deps) ref.deps = {};
    return ref;
}

function norm (file) {
    return path.normalize(__dirname + '/files/' + file);
}
<|endoftext|>


<commit_before>const express = require('express');
const http = require('http');

const request = require('supertest');
const cheerio = require('cheerio');

const should = require('should');

describe('front-list', function () {
	const app = express();
	let globalReq = null;
	app.use('/', (req, res, next) => {
		globalReq = req;
		next();
	});
	app.use('/', require('../router/front'));

	it('default pagecode', (done) => {
		request(app).get('/').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(1);
			globalReq.tags.should.length(0);
			done();
		});
	});

	it('pagecode', (done) => {
		request(app).get('/4').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(4);
			globalReq.tags.should.length(0);
			done();
		});
	});

	it('no pagecode taglist', (done) => {
		request(app).get('/tag/vec, apple,     original, javascript').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.tags.should
				.containEql('vec')
				.containEql('apple')
				.containEql('original')
				.containEql('javascript')

			done();
		});
	})
	it('has pagecode taglist', (done) => {
		request(app).get('/8/tag/vec, apple, original, java script').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(8);
			globalReq.tags.should
				.containEql('vec')
				.containEql('apple')
				.containEql('original')
				.containEql('java script')

			done();
		});
	})
});

describe('front-article', () => {
	const app = express();
	let globalReq = null;
	app.use('/', (req, res, next) => {
		globalReq = req;
		next();
	});
	app.use('/', require('../router/front'));

	it('article nofound', done => {
		request(app).get('/article/ahghiajgoija89396hnsg89h98h').end(function (err, res) {
			res.status.should.equal(404);
			done();
		});
	})
});
<commit_msg>front test<commit_after>const express = require('express');
const http = require('http');
const libArticle = require('../lib/article');

const request = require('supertest');
const cheerio = require('cheerio');

const should = require('should');

describe('front-list', function () {
	const app = express();
	let globalReq = null;
	app.use('/', (req, res, next) => {
		globalReq = req;
		next();
	});
	app.use('/', require('../app'));

	it('default pagecode', (done) => {
		request(app).get('/').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(1);
			globalReq.tags.should.length(0);
			done();
		});
	});

	it('pagecode', (done) => {
		request(app).get('/4').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(4);
			globalReq.tags.should.length(0);
			done();
		});
	});

	it('no pagecode taglist', (done) => {
		request(app).get('/tag/vec, apple,     original, javascript').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.tags.should
				.containEql('vec')
				.containEql('apple')
				.containEql('original')
				.containEql('javascript')

			done();
		});
	})

	it('has pagecode taglist', (done) => {
		request(app).get('/8/tag/vec, apple, original, java script').end(function (err, res) {
			res.status.should.equal(200);
			globalReq.pagecode.should.equal(8);
			globalReq.tags.should
				.containEql('vec')
				.containEql('apple')
				.containEql('original')
				.containEql('java script')

			done();
		});
	})

	it('has tag taglist', done => {
		libArticle.insert({
			title: 'testing',
			content: '# title',
			contentType: 'markdown',
			tags: ['Programming'],
		}).then(result => {
			request(app).get('/tag/Programming').expect(200, (err, res) => {
				if (err) { throw err }
				res.text.should.containEql(result.title)
				done()
			})
		}).catch(err => {
			throw err;
		})
	})
});

describe('front-article', () => {
	const app = express();
	let globalReq = null;
	app.use('/', (req, res, next) => {
		globalReq = req;
		next();
	});
	app.use('/', require('../app'));

	it('article nofound', done => {
		request(app).get('/article/ahghiajgoija89396hnsg89h98h').end(function (err, res) {
			res.status.should.equal(404);
			done();
		});
	})

});
<|endoftext|>


<commit_before>'use strict'

require('./get')
require('./is')
require('./path')
require('./uuid')
require('./descriptors')
require('./flatten')
require('./unflatten')
require('./hash')
require('./keyHash')
require('./define')
require('./require')
require('./include.js')
<commit_msg>added strip<commit_after>'use strict'

require('./get')
require('./is')
require('./path')
require('./uuid')
require('./descriptors')
require('./flatten')
require('./unflatten')
require('./hash')
require('./keyHash')
require('./define')
require('./require')
require('./include.js')
require('./strip.js')
<|endoftext|>