<commit_before>( // Module boilerplate to support node.js and AMD.
  (typeof module !== "undefined" && function (m) { module.exports = m(require('events')); }) ||
  (typeof define === "function" && function (m) { define(["events"], m); })
)(function (events) {
"use strict";
var EventEmitter = events.EventEmitter;

var exports = {};

// Only define Node-style usage using sync I/O if in node.
if (typeof module === "object") (function () {
    var dirname = require('path').dirname;
    var resolve = require('path').resolve;
    var existsSync = require('fs').existsSync || require('path').existsSync;
    var realpathSync = require('fs').realpathSync;
    var exists = require('fs').exists || require('path').exists;
    var realpath = require('fs').realpath;
    var packagePathCache = {};

    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    // This is assumed to be used at startup and uses sync I/O as well as can
    // throw exceptions.  It loads and parses a config file.
    function loadConfig(configPath, callback) {
      var config = require(configPath);
      var base = dirname(configPath);

      return resolveConfig(config, base, callback);
    }

    function resolveConfig(config, base, callback) {
        if (!callback)
            return resolveConfigSync(config, base);
        else
            resolveConfigAsync(config, base, callback);
    }

    function resolveConfigSync(config, base) {
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }
            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                var defaults = resolveModuleSync(base, plugin.packagePath);
                Object.keys(defaults).forEach(function (key) {
                    if (!plugin.hasOwnProperty(key)) {
                        plugin[key] = defaults[key];
                    }
                });
                plugin.packagePath = defaults.packagePath;
                plugin.setup = require(plugin.packagePath);
            }
        });
        return config;
    }

    function resolveConfigAsync(config, base, callback) {
        function resolveNext(i) {
            if (i >= config.length) {
                return callback(null, config);
            }

            var plugin = config[i];

            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[i] = { packagePath: plugin };
            }
            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                resolveModule(base, plugin.packagePath, function(err, defaults) {
                    if (err) return callback(err);

                    Object.keys(defaults).forEach(function (key) {
                        if (!plugin.hasOwnProperty(key)) {
                            plugin[key] = defaults[key];
                        }
                    });
                    plugin.packagePath = defaults.packagePath;
                    try {
                        plugin.setup = require(plugin.packagePath);
                    } catch(e) {
                        return callback(e);
                    }

                    return resolveNext(++i);
                });
                return;
            }

            return resolveNext(++i);
        }

        resolveNext(0);
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModuleSync(base, modulePath) {
        var packagePath;
        try {
            packagePath = resolvePackageSync(base, modulePath + "/package.json");
        }
        catch (err) {
            if (err.code !== "ENOENT") throw err;
        }
        var metadata = packagePath && require(packagePath).plugin || {};
        if (packagePath) {
            modulePath = dirname(packagePath);
        } else {
            modulePath = resolvePackageSync(base, modulePath);
        }
        var module = require(modulePath);
        metadata.provides = metadata.provides || module.provides || [];
        metadata.consumes = metadata.consumes || module.consumes || [];
        metadata.packagePath = modulePath;
        return metadata;
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModule(base, modulePath, callback) {
        resolvePackage(base, modulePath + "/package.json", function(err, packagePath) {
            if (err && err.code !== "ENOENT") return callback(err);
            var metadata = {};
            try {
                metadata = packagePath && require(packagePath).plugin || {};
            } catch(e) {
                return callback(e);
            }

            (function(next) {
                if (packagePath) {
                    next(null, dirname(packagePath));
                } else {
                    resolvePackage(base, modulePath, next);
                }
            })(function(err, modulePath) {
                if (err) return callback(err);

                var module;
                try {
                    module = require(modulePath);
                } catch(e) {
                    return callback(e);
                }
                metadata.provides = metadata.provides || module.provides || [];
                metadata.consumes = metadata.consumes || module.consumes || [];
                metadata.packagePath = modulePath;
                callback(null, metadata);
            });
        });
    }

    // Node style package resolving so that plugins' package.json can be found relative to the config file
    // It's not the full node require system algorithm, but it's the 99% case
    // This throws, make sure to wrap in try..catch
    function resolvePackageSync(base, packagePath) {
        var originalBase = base;
        if (!(base in packagePathCache)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (packagePath in cache) {
            return cache[packagePath];
        }
        var newPath;
        if (packagePath[0] === "." || packagePath[0] === "/") {
            newPath = resolve(base, packagePath);
            if (existsSync(newPath)) {
                newPath = realpathSync(newPath);
                cache[packagePath] = newPath;
                return newPath;
            }
        }
        else {
            while (base) {
                newPath = resolve(base, "node_modules", packagePath);
                if (existsSync(newPath)) {
                    newPath = realpathSync(newPath);
                    cache[packagePath] = newPath;
                    return newPath;
                }
                base = resolve(base, '..');
            }
        }
        var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
        err.code = "ENOENT";
        throw err;
    }

    function resolvePackage(base, packagePath, callback) {
        var originalBase = base;
        if (!packagePathCache.hasOwnProperty(base)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (cache.hasOwnProperty(packagePath)) {
            return callback(null, cache[packagePath]);
        }
        if (packagePath[0] === "." || packagePath[0] === "/") {
            var newPath = resolve(base, packagePath);
            exists(newPath, function(exists) {
                if (exists) {
                    realpath(newPath, function(err, newPath) {
                        if (err) return callback(err);

                        cache[packagePath] = newPath;
                        return callback(null, newPath);
                    });
                } else {
                    var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
                    err.code = "ENOENT";
                    return callback(err);
                }
            });
        }
        else {
            tryNext(base);
        }

        function tryNext(base) {
            if (!base) {
                var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
                err.code = "ENOENT";
                return callback(err);
            }

            var newPath = resolve(base, "node_modules", packagePath);
            exists(newPath, function(exists) {
                if (exists) {
                    realpath(newPath, function(err, newPath) {
                        if (err) return callback(err);

                        cache[packagePath] = newPath;
                        return callback(null, newPath);
                    });
                } else {
                    tryNext(resolve(base, '..'));
                }
            });
        }
    }

}());

// Otherwise use amd to load modules.
else (function () {
    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    function loadConfig(path, callback) {
        require([path], function (config) {
            resolveConfig(config, callback);
        });
    }

    function resolveConfig(config, callback) {
        var paths = [], pluginIndexes = {};
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }
            // The plugin is a package over the network.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                paths.push(plugin.packagePath);
                pluginIndexes[plugin.packagePath] = index;
            }
        });
        // Mass-Load path-based plugins using amd's require
        require(paths, function () {
            var args = arguments;
            paths.forEach(function (name, i) {
                var module = args[i];
                var plugin = config[pluginIndexes[name]];
                plugin.setup = module;
                plugin.provides = module.provides || [];
                plugin.consumes = module.consumes || [];
            });
            callback(null, config);
        });
    }
}());

exports.createApp = createApp;
exports.Architect = Architect;

// Check a plugin config list for bad dependencies and throw on error
function checkConfig(config) {

    // Check for the required fields in each plugin.
    config.forEach(function (plugin) {
        if (plugin.checked) { return; }
        if (!plugin.hasOwnProperty("setup")) {
            throw new Error("Plugin is missing the setup function " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("provides")) {
            throw new Error("Plugin is missing the provides array " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("consumes")) {
            throw new Error("Plugin is missing the consumes array " + JSON.stringify(plugin));
        }
    });

    return checkCycles(config);
}

function checkCycles(config) {
    var plugins = [];
    config.forEach(function(pluginConfig, index) {
        plugins.push({
            packagePath: pluginConfig.packagePath,
            provides: pluginConfig.provides.concat(),
            consumes: pluginConfig.consumes.concat(),
            i: index
        });
    });

    var resolved = {
        hub: true
    };
    var changed = true;
    var sorted = [];

    while(plugins.length && changed) {
        changed = false;

        plugins.concat().forEach(function(plugin) {
            var consumes = plugin.consumes.concat();

            var resolvedAll = true;
            for (var i=0; i<consumes.length; i++) {
                var service = consumes[i];
                if (!resolved[service]) {
                    resolvedAll = false;
                } else {
                    plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                }
            }

            if (!resolvedAll)
                return;

            plugins.splice(plugins.indexOf(plugin), 1);
            plugin.provides.forEach(function(service) {
                resolved[service] = true;
            });
            sorted.push(config[plugin.i]);
            changed = true;
        });
    }

    if (plugins.length) {
        plugins.forEach(function(plugin) {
            delete plugin.config;
        });

        console.error("Could not resolve dependencies of these plugins:", plugins);
        console.error("Resovled services:", resolved);
        throw new Error("Could not resolve dependencies");
    }

    return sorted;
}

function Architect(config) {
    var app = this;
    app.config = config;
    var services = app.services = {
        hub: {
            on: function (name, callback) {
                app.on(name, callback);
            }
        }
    };

    // Check the config
    try {
        var sortedPlugins = checkConfig(config);
    } catch (err) {
        return app.emit("error", err);
    }

    var destructors = [];

    function startPlugins() {
        var plugin = sortedPlugins.shift();
        if (!plugin)
            return app.emit("ready", app);

        var imports = {};
        if (plugin.consumes) {
            plugin.consumes.forEach(function (name) {
                imports[name] = services[name];
            });
        }

        plugin.setup(plugin, imports, function (err, provided) {
            if (err) { return app.emit("error", err); }
            plugin.provides.forEach(function (name) {
                if (!provided.hasOwnProperty(name)) {
                    var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin));
                    return app.emit("error", err);
                }
                services[name] = provided[name];

                provided[name].name = name;

                app.emit("service", name, services[name]);
            });
            if (provided && provided.hasOwnProperty("onDestroy"))
                destructors.push(provided.onDestroy);

            app.emit("plugin", plugin);
            startPlugins();
        });
    }

    // Give createApp some time to subscribe to our "ready" event
    (typeof process === "object" ? process.nextTick : setTimeout)(startPlugins);

    this.destroy = function() {
        destructors.forEach(function(destroy) {
            destroy();
        });

        destructors = [];
    };
}
Architect.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Architect}});

Architect.prototype.getService = function(name) {
    if (!this.services[name]) {
        throw new Error("Service '" + name + "' not found in architect app!");
    }
    return this.services[name];
};

// Returns an event emitter that represents the app.  It can emit events.
// event: ("service" name, service) emitted when a service is ready to be consumed.
// event: ("plugin", plugin) emitted when a plugin registers.
// event: ("ready", app) emitted when all plugins are ready.
// event: ("error", err) emitted when something goes wrong.
// app.services - a hash of all the services in this app
// app.config - the plugin config that was passed in.
function createApp(config, callback) {
    var app;
    try {
        app = new Architect(config);
    } catch(err) {
        if (!callback) throw err;
        return callback(err, app);
    }
    if (callback) {
        app.on("error", done);
        app.on("ready", onReady);
    }
    return app;

    function onReady(app) {
        done();
    }

    function done(err) {
        if (err) {
            app.destroy();
        }
        app.removeListener("error", done);
        app.removeListener("ready", onReady);
        callback(err, app);
    }

}

return exports;

});
<commit_msg>added name and imports to plugin<commit_after>( // Module boilerplate to support node.js and AMD.
  (typeof module !== "undefined" && function (m) { module.exports = m(require('events')); }) ||
  (typeof define === "function" && function (m) { define(["events"], m); })
)(function (events) {
"use strict";
var EventEmitter = events.EventEmitter;

var exports = {};

// Only define Node-style usage using sync I/O if in node.
if (typeof module === "object") (function () {
    var dirname = require('path').dirname;
    var resolve = require('path').resolve;
    var existsSync = require('fs').existsSync || require('path').existsSync;
    var realpathSync = require('fs').realpathSync;
    var exists = require('fs').exists || require('path').exists;
    var realpath = require('fs').realpath;
    var packagePathCache = {};

    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    // This is assumed to be used at startup and uses sync I/O as well as can
    // throw exceptions.  It loads and parses a config file.
    function loadConfig(configPath, callback) {
      var config = require(configPath);
      var base = dirname(configPath);

      return resolveConfig(config, base, callback);
    }

    function resolveConfig(config, base, callback) {
        if (!callback)
            return resolveConfigSync(config, base);
        else
            resolveConfigAsync(config, base, callback);
    }

    function resolveConfigSync(config, base) {
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }
            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                var defaults = resolveModuleSync(base, plugin.packagePath);
                Object.keys(defaults).forEach(function (key) {
                    if (!plugin.hasOwnProperty(key)) {
                        plugin[key] = defaults[key];
                    }
                });
                plugin.packagePath = defaults.packagePath;
                plugin.setup = require(plugin.packagePath);
            }
        });
        return config;
    }

    function resolveConfigAsync(config, base, callback) {
        function resolveNext(i) {
            if (i >= config.length) {
                return callback(null, config);
            }

            var plugin = config[i];

            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[i] = { packagePath: plugin };
            }
            // The plugin is a package on the disk.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                resolveModule(base, plugin.packagePath, function(err, defaults) {
                    if (err) return callback(err);

                    Object.keys(defaults).forEach(function (key) {
                        if (!plugin.hasOwnProperty(key)) {
                            plugin[key] = defaults[key];
                        }
                    });
                    plugin.packagePath = defaults.packagePath;
                    try {
                        plugin.setup = require(plugin.packagePath);
                    } catch(e) {
                        return callback(e);
                    }

                    return resolveNext(++i);
                });
                return;
            }

            return resolveNext(++i);
        }

        resolveNext(0);
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModuleSync(base, modulePath) {
        var packagePath;
        try {
            packagePath = resolvePackageSync(base, modulePath + "/package.json");
        }
        catch (err) {
            if (err.code !== "ENOENT") throw err;
        }
        var metadata = packagePath && require(packagePath).plugin || {};
        if (packagePath) {
            modulePath = dirname(packagePath);
        } else {
            modulePath = resolvePackageSync(base, modulePath);
        }
        var module = require(modulePath);
        metadata.provides = metadata.provides || module.provides || [];
        metadata.consumes = metadata.consumes || module.consumes || [];
        metadata.packagePath = modulePath;
        return metadata;
    }

    // Loads a module, getting metadata from either it's package.json or export
    // object.
    function resolveModule(base, modulePath, callback) {
        resolvePackage(base, modulePath + "/package.json", function(err, packagePath) {
            if (err && err.code !== "ENOENT") return callback(err);
            var metadata = {};
            try {
                metadata = packagePath && require(packagePath).plugin || {};
            } catch(e) {
                return callback(e);
            }

            (function(next) {
                if (packagePath) {
                    next(null, dirname(packagePath));
                } else {
                    resolvePackage(base, modulePath, next);
                }
            })(function(err, modulePath) {
                if (err) return callback(err);

                var module;
                try {
                    module = require(modulePath);
                } catch(e) {
                    return callback(e);
                }
                metadata.provides = metadata.provides || module.provides || [];
                metadata.consumes = metadata.consumes || module.consumes || [];
                metadata.packagePath = modulePath;
                callback(null, metadata);
            });
        });
    }

    // Node style package resolving so that plugins' package.json can be found relative to the config file
    // It's not the full node require system algorithm, but it's the 99% case
    // This throws, make sure to wrap in try..catch
    function resolvePackageSync(base, packagePath) {
        var originalBase = base;
        if (!(base in packagePathCache)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (packagePath in cache) {
            return cache[packagePath];
        }
        var newPath;
        if (packagePath[0] === "." || packagePath[0] === "/") {
            newPath = resolve(base, packagePath);
            if (existsSync(newPath)) {
                newPath = realpathSync(newPath);
                cache[packagePath] = newPath;
                return newPath;
            }
        }
        else {
            while (base) {
                newPath = resolve(base, "node_modules", packagePath);
                if (existsSync(newPath)) {
                    newPath = realpathSync(newPath);
                    cache[packagePath] = newPath;
                    return newPath;
                }
                base = resolve(base, '..');
            }
        }
        var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
        err.code = "ENOENT";
        throw err;
    }

    function resolvePackage(base, packagePath, callback) {
        var originalBase = base;
        if (!packagePathCache.hasOwnProperty(base)) {
            packagePathCache[base] = {};
        }
        var cache = packagePathCache[base];
        if (cache.hasOwnProperty(packagePath)) {
            return callback(null, cache[packagePath]);
        }
        if (packagePath[0] === "." || packagePath[0] === "/") {
            var newPath = resolve(base, packagePath);
            exists(newPath, function(exists) {
                if (exists) {
                    realpath(newPath, function(err, newPath) {
                        if (err) return callback(err);

                        cache[packagePath] = newPath;
                        return callback(null, newPath);
                    });
                } else {
                    var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
                    err.code = "ENOENT";
                    return callback(err);
                }
            });
        }
        else {
            tryNext(base);
        }

        function tryNext(base) {
            if (!base) {
                var err = new Error("Can't find '" + packagePath + "' relative to '" + originalBase + "'");
                err.code = "ENOENT";
                return callback(err);
            }

            var newPath = resolve(base, "node_modules", packagePath);
            exists(newPath, function(exists) {
                if (exists) {
                    realpath(newPath, function(err, newPath) {
                        if (err) return callback(err);

                        cache[packagePath] = newPath;
                        return callback(null, newPath);
                    });
                } else {
                    tryNext(resolve(base, '..'));
                }
            });
        }
    }

}());

// Otherwise use amd to load modules.
else (function () {
    exports.loadConfig = loadConfig;
    exports.resolveConfig = resolveConfig;

    function loadConfig(path, callback) {
        require([path], function (config) {
            resolveConfig(config, callback);
        });
    }

    function resolveConfig(config, callback) {
        var paths = [], pluginIndexes = {};
        config.forEach(function (plugin, index) {
            // Shortcut where string is used for plugin without any options.
            if (typeof plugin === "string") {
                plugin = config[index] = { packagePath: plugin };
            }
            // The plugin is a package over the network.  We need to load it.
            if (plugin.hasOwnProperty("packagePath") && !plugin.hasOwnProperty("setup")) {
                paths.push(plugin.packagePath);
                pluginIndexes[plugin.packagePath] = index;
            }
        });
        // Mass-Load path-based plugins using amd's require
        require(paths, function () {
            var args = arguments;
            paths.forEach(function (name, i) {
                var module = args[i];
                var plugin = config[pluginIndexes[name]];
                plugin.setup = module;
                plugin.provides = module.provides || [];
                plugin.consumes = module.consumes || [];
            });
            callback(null, config);
        });
    }
}());

exports.createApp = createApp;
exports.Architect = Architect;

// Check a plugin config list for bad dependencies and throw on error
function checkConfig(config) {

    // Check for the required fields in each plugin.
    config.forEach(function (plugin) {
        if (plugin.checked) { return; }
        if (!plugin.hasOwnProperty("setup")) {
            throw new Error("Plugin is missing the setup function " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("provides")) {
            throw new Error("Plugin is missing the provides array " + JSON.stringify(plugin));
        }
        if (!plugin.hasOwnProperty("consumes")) {
            throw new Error("Plugin is missing the consumes array " + JSON.stringify(plugin));
        }
    });

    return checkCycles(config);
}

function checkCycles(config) {
    var plugins = [];
    config.forEach(function(pluginConfig, index) {
        plugins.push({
            packagePath: pluginConfig.packagePath,
            provides: pluginConfig.provides.concat(),
            consumes: pluginConfig.consumes.concat(),
            i: index
        });
    });

    var resolved = {
        hub: true
    };
    var changed = true;
    var sorted = [];

    while(plugins.length && changed) {
        changed = false;

        plugins.concat().forEach(function(plugin) {
            var consumes = plugin.consumes.concat();

            var resolvedAll = true;
            for (var i=0; i<consumes.length; i++) {
                var service = consumes[i];
                if (!resolved[service]) {
                    resolvedAll = false;
                } else {
                    plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                }
            }

            if (!resolvedAll)
                return;

            plugins.splice(plugins.indexOf(plugin), 1);
            plugin.provides.forEach(function(service) {
                resolved[service] = true;
            });
            sorted.push(config[plugin.i]);
            changed = true;
        });
    }

    if (plugins.length) {
        plugins.forEach(function(plugin) {
            delete plugin.config;
        });

        console.error("Could not resolve dependencies of these plugins:", plugins);
        console.error("Resovled services:", resolved);
        throw new Error("Could not resolve dependencies");
    }

    return sorted;
}

function Architect(config) {
    var app = this;
    app.config = config;
    var services = app.services = {
        hub: {
            on: function (name, callback) {
                app.on(name, callback);
            }
        }
    };

    // Check the config
    try {
        var sortedPlugins = checkConfig(config);
    } catch (err) {
        return app.emit("error", err);
    }

    var destructors = [];

    function startPlugins() {
        var plugin = sortedPlugins.shift();
        if (!plugin)
            return app.emit("ready", app);

        var imports = {};
        if (plugin.consumes) {
            plugin.consumes.forEach(function (name) {
                imports[name] = services[name];
            });
        }

        plugin.setup(plugin, imports, function (err, provided) {
            if (err) { return app.emit("error", err); }
            plugin.provides.forEach(function (name) {
                if (!provided.hasOwnProperty(name)) {
                    var err = new Error("Plugin failed to provide " + name + " service. " + JSON.stringify(plugin));
                    return app.emit("error", err);
                }
                services[name] = provided[name];
                provided[name].name = name;
                app.emit("service", name, services[name]);
            });
            if (provided && provided.hasOwnProperty("onDestroy"))
                destructors.push(provided.onDestroy);

            app.emit("plugin", plugin);
            startPlugins();
        });
    }

    // Give createApp some time to subscribe to our "ready" event
    (typeof process === "object" ? process.nextTick : setTimeout)(startPlugins);

    this.destroy = function() {
        destructors.forEach(function(destroy) {
            destroy();
        });

        destructors = [];
    };
}
Architect.prototype = Object.create(EventEmitter.prototype, {constructor:{value:Architect}});

Architect.prototype.getService = function(name) {
    if (!this.services[name]) {
        throw new Error("Service '" + name + "' not found in architect app!");
    }
    return this.services[name];
};

// Returns an event emitter that represents the app.  It can emit events.
// event: ("service" name, service) emitted when a service is ready to be consumed.
// event: ("plugin", plugin) emitted when a plugin registers.
// event: ("ready", app) emitted when all plugins are ready.
// event: ("error", err) emitted when something goes wrong.
// app.services - a hash of all the services in this app
// app.config - the plugin config that was passed in.
function createApp(config, callback) {
    var app;
    try {
        app = new Architect(config);
    } catch(err) {
        if (!callback) throw err;
        return callback(err, app);
    }
    if (callback) {
        app.on("error", done);
        app.on("ready", onReady);
    }
    return app;

    function onReady(app) {
        done();
    }

    function done(err) {
        if (err) {
            app.destroy();
        }
        app.removeListener("error", done);
        app.removeListener("ready", onReady);
        callback(err, app);
    }

}

return exports;

});
<|endoftext|>


<commit_before>var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
	if (TEST_REGEXP.test(file)) {
		// Normalize paths to RequireJS module names.
		// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
		// then do not normalize the paths
		var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
		allTestFiles.push(normalizedTestModule);
	}
});

require.config({
	// Karma serves files under /base, which is the basePath from your config file
	baseUrl: '/base',

	paths: {
		// 'jquery': './libs/jquery',
		'timer': './src/timer.jquery',
		'fixtures': './test/fixtures'
	},

	// dynamically load all test files
	deps: allTestFiles,

	// we have to kickoff jasmine, as it is asynchronous
	callback: window.__karma__.start
});
<commit_msg>removed commented line<commit_after>var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function(file) {
	if (TEST_REGEXP.test(file)) {
		// Normalize paths to RequireJS module names.
		// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
		// then do not normalize the paths
		var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
		allTestFiles.push(normalizedTestModule);
	}
});

require.config({
	// Karma serves files under /base, which is the basePath from your config file
	baseUrl: '/base',

	paths: {
		'timer': './src/timer.jquery',
		'fixtures': './test/fixtures'
	},

	// dynamically load all test files
	deps: allTestFiles,

	// we have to kickoff jasmine, as it is asynchronous
	callback: window.__karma__.start
});
<|endoftext|>


<commit_before>const { types } = require("mobx-state-tree");
const process = require("immer").default;
const util = require("util");

const global = "g";
const dot = ".";
const array = "[";
const object = "{";
const mutate = "@";
const identity = "#";

const add = "+";
const minus = "-";
const times = "*";
const divide = "/";
const mod = "%";

const ifOp = "?";
const switchOp = "s";
const forOp = "f";

const lessThan = "<";
const greaterThan = ">";
const lessThanOrEqual = "v";
const greaterThanOrEqual = "^";

const equal = "=";
const strictEqual = "e";
const notEqual = "!";
const notStrictEqual = "n";

const importOp = "m";
const newOp = "w";
const typeofOp = "t";
const instanceOfOp = "i";
const classOp = "c";
const thisOp = "h";

const opFuncs = {
  [global]: typeof window !== "undefined" ? window : global,
  [dot](obj, key) {
    try {
      return obj[key];
    } catch (ex) {
      return ex;
    }
  },
  [add](...nums) {
    let sum;
    for (let i = 0; i < nums.length; i++) {
      if (i === 0) {
        sum = nums[i];
      } else {
        sum += nums[i];
      }
    }
    return sum;
  },
  [minus](...nums) {
    let sum;
    for (let i = 0; i < nums.length; i++) {
      if (i === 0) {
        sum = nums[i];
      } else {
        sum -= nums[i];
      }
    }
    return sum;
  },
  [array](...items) {
    return items;
  },
  [object](...kvs) {
    const obj = {};
    for (let i = 0; i < kvs.length; i = i + 2) {
      obj[kvs[i]] = kvs[i + 1];
    }
    return obj;
  },
  [ifOp](condition, trueVal, falseVal) {
    return condition ? trueVal : falseVal;
  },
  [switchOp](switcher, ...casePairs) {
    // console.log(switcher, ...casePairs, "SWIT");
    const { length } = casePairs;
    for (let i = 0; i < length; i += 2) {
      if (switcher === casePairs[i]) {
        return casePairs[i + 1];
      }
    }
    if (length % 2) {
      return casePairs[length - 1];
    }
  },
  [lessThan](a, b) {
    return a < b;
  },
  [identity](x) {
    return function() {
      return x;
    };
  }
};

const ops = [
  global,
  dot,
  array,
  object,
  add,
  minus,
  times,
  divide,
  mod,
  ifOp,
  switchOp,
  forOp,
  importOp,
  newOp,
  typeofOp,
  instanceOfOp,
  classOp,
  thisOp,
  lessThan,
  greaterThan,
  lessThanOrEqual,
  greaterThanOrEqual,
  equal,
  strictEqual,
  notEqual,
  notStrictEqual,
  mutate,
  identity
];

const Pkg = types.model("Pkg", {
  id: types.identifier(types.string),
  path: types.string,
  resolved: types.optional(types.boolean, false)
});

const Val = types
  .model("Val", {
    val: types.union(types.number, types.string, types.boolean, types.null)
  })
  .views(self => ({
    get out() {
      return self.val;
    }
  }));

const Op = types
  .model("Op", {
    op: types.enumeration(ops)
  })
  .views(self => ({
    get out() {
      const opFunc = opFuncs[self.op];
      if (!opFunc) {
        throw new Error(self.op + " op not yet implemented!");
      }
      return opFunc;
    }
  }));

const Arg = types.model("Arg", {
  arg: types.refinement(types.number, n => n >= 0 && !(n % 1))
});
// .views(self => ({}));

const Use = types.model("Use", {
  use: types.string
});
// .views(self => ({
//   out(repo) {
//     return;
//   }
// }));

const PkgUse = types.model("Use", {
  pkg: types.reference(Pkg)
});
// .views(self => ({
//   get out() {
//     return;
//   }
// }));

const Word = types.union(Val, Op, Arg, types.late(() => Fn), Use, PkgUse);

const Line = types.refinement(types.array(Word), l => l.length);

const Call = types
  .model("Call", {
    id: types.identifier(types.string),
    line: Line
  })
  .views(self => ({
    out(repo) {
      return parseCallLine(repo, self.line);
    }
  }));

const Declaration = types.union(types.late(() => Call), types.late(() => Def));

const Fn = types
  .model("Fn", {
    fn: types.reference(Declaration)
  })
  .views(self => ({
    out(repo) {
      return self.fn.out(repo);
    }
  }));

const parseCallLine = (repo, line) => {
  const func = (...params) => {
    // TODO: hoist unchanging (non-param) slots
    const tokens = line.map(word => {
      if ("val" in word || "op" in word) {
        return word.out;
      }
      if ("arg" in word) {
        return params[word.arg];
      }
      if ("fn" in word) {
        return word.fn.out(repo);
      }
      throw new Error("No match found for code, brah! " + word);
    });

    const [head, ...args] = tokens;
    return typeof head === "function" ? head(...args) : head;
  };
  if (!line.some(word => "arg" in word)) {
    return func();
  }
  return func;
};

const Def = types
  .model("Def", {
    id: types.identifier(types.string),
    lines: types.maybe(types.map(Line)),
    ret: Line
  })
  // .preProcessSnapshot(snapshot =>
  //   process(snapshot, draft => {
  //     const { i, l, r } = draft;
  //     if (i) {
  //       draft.id = i;
  //     }
  //     if (l) {
  //       draft.lines = l;
  //     }
  //     if (r) {
  //       draft.ret = r;
  //     }
  //   })
  // )
  .views(self => ({
    out(repo) {
      const { lines } = self;
      return (...params) => {
        const parseLine = line => {
          const tokens = line.map(word => {
            if ("val" in word || "op" in word) {
              return word.out;
            }
            if ("arg" in word) {
              return params[word.arg];
            }
            if ("use" in word) {
              if (!lines) {
                throw new Error("No lines brah!");
              }
              const innerLine = lines.get(word.use);
              if (!innerLine) {
                throw new Error("nononononono line");
              }
              if (!innerLine.some(ilWord => "use" in ilWord)) {
                return parseCallLine(repo, innerLine)(...params);
              }
              return parseLine(innerLine)(...params);
            }
            if ("fn" in word) {
              return word.fn.out(repo);
            }
            throw new Error("No match found!");
          });
          const [head, ...args] = tokens;
          return typeof head === "function" ? head(...args) : head;
        };
        return parseLine(self.ret);
      };
    }
  }));

const Repo = types
  .model("Repo", {
    decs: types.map(Declaration)
  })
  .views(self => ({
    out(id) {
      return self.decs.get(id).out(self);
    }
  }));

const test = {
  decs: {
    a: { id: "a", ret: [{ arg: 0 }] },
    b: { id: "b", ret: [{ op: add }, { arg: 0 }, { val: 1 }] },
    b1: { id: "b1", ret: [{ op: minus }, { arg: 0 }, { val: 1 }] },
    ba: { id: "ba", line: [{ op: add }, { val: 1 }, { val: 2 }] },
    c: {
      id: "c",
      line: [
        { op: switchOp },
        { arg: 0 },
        { val: "INCREMENT" },
        { fn: "a" },
        { val: "DECREMENT" },
        { fn: "b1" },
        { fn: "a" }
      ]
    },
    d: { id: "d", line: [{ op: dot }, { arg: 0 }, { val: "type" }] },
    e: {
      id: "e",
      lines: { a: [{ fn: "d" }, { arg: 0 }] },
      ret: [{ fn: "c" }, { use: "a" }]
    }
  }
};
const pTest = {
  a: { r: [0] },
  b: { r: ["+", 0, [1]] },
  b1: { r: ["-", 0, [1]] },
  ba: { l: ["+", [1], [2]] },
  c: {
    l: [
      "s",
      0,
      ["INCREMENT"],
      { f: "a" },
      ["DECREMENT"],
      { f: "b1" },
      { f: "a" }
    ]
  },
  d: { l: [".", 0, ["type"]] },
  e: { r: [{ f: "c" }, { u: "a" }], l: { a: [{ f: "d" }, 0] } }
};

const packWord = full => {
  if ("val" in full) {
    return [full.val];
  }
  if ("op" in full) {
    return full.op;
  }
  if ("fn" in full) {
    return { f: full.fn };
  }
  if ("arg" in full) {
    return full.arg;
  }
  if ("use" in full) {
    return { u: full.use };
  }
  throw new Error(`Could not pack word. Has no match: ${full}`);
};

const packDeclaration = full => {
  const packed = { i: full.id };
  if (full.line) {
    packed.l = full.line.map(packWord);
  } else {
    packed.r = full.ret.map(packWord);
    if (full.lines) {
      packed.l = {};
      for (const id in full.lines) {
        packed.l[id] = full.lines[id].map(packWord);
      }
    }
  }
  return packed;
};

const packDecSet = full => {
  const packed = {};
  for (const id in full) {
    const packedDec = packDeclaration(full[id]);
    const { i, ...rest } = packedDec;
    packed[id] = rest;
    // packed.push(packedDec);
  }
  return packed;
};

const unpackWord = packed => {
  if (Array.isArray(packed)) {
    return { val: packed[0] };
  }
  if (typeof packed === "string") {
    return { op: packed };
  }
  if (typeof packed === "number") {
    return { arg: packed };
  }
  if ("f" in packed) {
    return { fn: packed.f };
  }
  if ("u" in packed) {
    return { use: packed.u };
  }
  throw new Error(`Could not unpack word. Has no match: ${packed}`);
};

const unpackDeclaration = packed => {
  const full = {};
  if (packed.r) {
    full.ret = packed.r.map(unpackWord);
    if (packed.l) {
      full.lines = {};
      for (const id in packed.l) {
        full.lines[id] = packed.l[id].map(unpackWord);
      }
    }
  } else {
    full.line = packed.l.map(unpackWord);
  }
  return full;
};

const unpackDecSet = packed => {
  const full = {};
  for (const id in packed) {
    const packedDec = packed[id];
    const fullDec = unpackDeclaration(packedDec);
    fullDec.id = id;
    full[id] = fullDec;
  }
  return full;
};

const packTest = packDecSet(test.decs);
const unpackTest = unpackDecSet(packTest);
console.log(util.inspect(packTest, { depth: null }));
// console.log(util.inspect(unpackTest, { depth: null }));
const before = JSON.stringify(test.decs).length;
const after = JSON.stringify(packTest).length;
const unpacked = JSON.stringify(unpackTest).length;
console.log(before, after, unpacked, after / before * 100);

const store = Repo.create({ decs: unpackTest });
const a = store.out("a");
const b = store.out("b");
console.log(a(1), 1);
console.log(store.out("ba"));

const c = store.out("d");
console.log(c({ type: "INCREMENT" }), "INCREMENT");

const e = store.out("e");
console.log(e({ type: "DECREMENT" })(5));
<commit_msg> chore: cleanup, repo context boilerplate<commit_after>const { types } = require("mobx-state-tree");
const util = require("util");

const global = "g";
const dot = ".";
const array = "[";
const object = "{";
const mutate = "@";
const identity = "#";

const add = "+";
const minus = "-";
const times = "*";
const divide = "/";
const mod = "%";

const ifOp = "?";
const switchOp = "s";
const forOp = "f";

const lessThan = "<";
const greaterThan = ">";
const lessThanOrEqual = "v";
const greaterThanOrEqual = "^";

const equal = "=";
const strictEqual = "e";
const notEqual = "!";
const notStrictEqual = "n";

const importOp = "m";
const newOp = "w";
const typeofOp = "t";
const instanceOfOp = "i";
const classOp = "c";
const thisOp = "h";

const opFuncs = {
  [global]: typeof window !== "undefined" ? window : global,
  [dot](obj, key) {
    try {
      return obj[key];
    } catch (ex) {
      return ex;
    }
  },
  [add](...nums) {
    let sum;
    for (let i = 0; i < nums.length; i++) {
      if (i === 0) {
        sum = nums[i];
      } else {
        sum += nums[i];
      }
    }
    return sum;
  },
  [minus](...nums) {
    let sum;
    for (let i = 0; i < nums.length; i++) {
      if (i === 0) {
        sum = nums[i];
      } else {
        sum -= nums[i];
      }
    }
    return sum;
  },
  [array](...items) {
    return items;
  },
  [object](...kvs) {
    const obj = {};
    for (let i = 0; i < kvs.length; i = i + 2) {
      obj[kvs[i]] = kvs[i + 1];
    }
    return obj;
  },
  [ifOp](condition, trueVal, falseVal) {
    return condition ? trueVal : falseVal;
  },
  [switchOp](switcher, ...casePairs) {
    // console.log(switcher, ...casePairs, "SWIT");
    const { length } = casePairs;
    for (let i = 0; i < length; i += 2) {
      if (switcher === casePairs[i]) {
        return casePairs[i + 1];
      }
    }
    if (length % 2) {
      return casePairs[length - 1];
    }
  },
  [lessThan](a, b) {
    return a < b;
  },
  [identity](x) {
    return function() {
      return x;
    };
  }
};

const ops = [
  global,
  dot,
  array,
  object,
  add,
  minus,
  times,
  divide,
  mod,
  ifOp,
  switchOp,
  forOp,
  importOp,
  newOp,
  typeofOp,
  instanceOfOp,
  classOp,
  thisOp,
  lessThan,
  greaterThan,
  lessThanOrEqual,
  greaterThanOrEqual,
  equal,
  strictEqual,
  notEqual,
  notStrictEqual,
  mutate,
  identity
];

const Pkg = types.model("Pkg", {
  id: types.identifier(types.string),
  path: types.string,
  resolved: types.optional(types.boolean, false)
});

const Val = types
  .model("Val", {
    val: types.union(types.number, types.string, types.boolean, types.null)
  })
  .views(self => ({
    get out() {
      return self.val;
    }
  }));

const Op = types
  .model("Op", {
    op: types.enumeration(ops)
  })
  .views(self => ({
    get out() {
      const opFunc = opFuncs[self.op];
      if (!opFunc) {
        throw new Error(self.op + " op not yet implemented!");
      }
      return opFunc;
    }
  }));

const Arg = types.model("Arg", {
  arg: types.refinement(types.number, n => n >= 0 && !(n % 1))
});
// .views(self => ({}));

const Use = types.model("Use", {
  use: types.string
});
// .views(self => ({
//   out(repo) {
//     return;
//   }
// }));

const PkgUse = types.model("Use", {
  pkg: types.reference(Pkg)
});
// .views(self => ({
//   get out() {
//     return;
//   }
// }));

const Word = types.union(Val, Op, Arg, types.late(() => Fn), Use, PkgUse);

const Line = types.refinement(types.array(Word), l => l.length);

const Call = types
  .model("Call", {
    id: types.identifier(types.string),
    line: Line
  })
  .views(self => ({
    out(repo) {
      return parseCallLine(repo, self.line);
    }
  }));

const Declaration = types.union(types.late(() => Call), types.late(() => Def));

const Fn = types
  .model("Fn", {
    fn: types.reference(Declaration)
  })
  .views(self => ({
    out(repo) {
      return self.fn.out(repo);
    }
  }));

const parseCallLine = (repo, line) => {
  const func = (...params) => {
    // TODO: hoist unchanging (non-param) slots
    const tokens = line.map(word => {
      if ("val" in word || "op" in word) {
        return word.out;
      }
      if ("arg" in word) {
        return params[word.arg];
      }
      if ("fn" in word) {
        return word.fn.out(repo);
      }
      throw new Error("No match found for code, brah! " + word);
    });

    const [head, ...args] = tokens;
    return typeof head === "function" ? head(...args) : head;
  };
  if (!line.some(word => "arg" in word)) {
    return func();
  }
  return func;
};

const Def = types
  .model("Def", {
    id: types.identifier(types.string),
    lines: types.maybe(types.map(Line)),
    ret: Line,
    repo: types.optional(types.reference(types.late(() => Repo)), 0)
  })
  .views(self => ({
    out(repo) {
      const { lines } = self;
      return (...params) => {
        const parseLine = line => {
          const tokens = line.map(word => {
            if ("val" in word || "op" in word) {
              return word.out;
            }
            if ("arg" in word) {
              return params[word.arg];
            }
            if ("use" in word) {
              if (!lines) {
                throw new Error("No lines brah!");
              }
              const innerLine = lines.get(word.use);
              if (!innerLine) {
                throw new Error("nononononono line");
              }
              if (!innerLine.some(ilWord => "use" in ilWord)) {
                return parseCallLine(repo, innerLine)(...params);
              }
              return parseLine(innerLine)(...params);
            }
            if ("fn" in word) {
              return word.fn.out(repo);
            }
            throw new Error("No match found!");
          });
          const [head, ...args] = tokens;
          return typeof head === "function" ? head(...args) : head;
        };
        return parseLine(self.ret);
      };
    }
  }));

const Repo = types
  .model("Repo", {
    _id: types.optional(types.identifier(types.number), 0),
    decs: types.map(Declaration)
  })
  .views(self => ({
    out(id) {
      return self.decs.get(id).out(self);
    }
  }));

const test = {
  decs: {
    a: { id: "a", ret: [{ arg: 0 }] },
    b: { id: "b", ret: [{ op: add }, { arg: 0 }, { val: 1 }] },
    b1: { id: "b1", ret: [{ op: minus }, { arg: 0 }, { val: 1 }] },
    ba: { id: "ba", line: [{ op: add }, { val: 1 }, { val: 2 }] },
    c: {
      id: "c",
      line: [
        { op: switchOp },
        { arg: 0 },
        { val: "INCREMENT" },
        { fn: "a" },
        { val: "DECREMENT" },
        { fn: "b1" },
        { fn: "a" }
      ]
    },
    d: { id: "d", line: [{ op: dot }, { arg: 0 }, { val: "type" }] },
    e: {
      id: "e",
      lines: { a: [{ fn: "d" }, { arg: 0 }] },
      ret: [{ fn: "c" }, { use: "a" }]
    }
  }
};
const pTest = {
  a: { r: [0] },
  b: { r: ["+", 0, [1]] },
  b1: { r: ["-", 0, [1]] },
  ba: { l: ["+", [1], [2]] },
  c: {
    l: ["s", 0, ["INCREMENT"], { f: "a" }, ["DECREMENT"], { f: "b1" }, { f: "a" }]
  },
  d: { l: [".", 0, ["type"]] },
  e: { r: [{ f: "c" }, { u: "a" }], l: { a: [{ f: "d" }, 0] } }
};

const packWord = full => {
  if ("val" in full) {
    return [full.val];
  }
  if ("op" in full) {
    return full.op;
  }
  if ("fn" in full) {
    return { f: full.fn };
  }
  if ("arg" in full) {
    return full.arg;
  }
  if ("use" in full) {
    return { u: full.use };
  }
  throw new Error(`Could not pack word. Has no match: ${full}`);
};

const packDeclaration = full => {
  const packed = { i: full.id };
  if (full.line) {
    packed.l = full.line.map(packWord);
  } else {
    packed.r = full.ret.map(packWord);
    if (full.lines) {
      packed.l = {};
      for (const id in full.lines) {
        packed.l[id] = full.lines[id].map(packWord);
      }
    }
  }
  return packed;
};

const packDecSet = full => {
  const packed = {};
  for (const id in full) {
    const packedDec = packDeclaration(full[id]);
    const { i, ...rest } = packedDec;
    packed[id] = rest;
    // packed.push(packedDec);
  }
  return packed;
};

const unpackWord = packed => {
  if (Array.isArray(packed)) {
    return { val: packed[0] };
  }
  if (typeof packed === "string") {
    return { op: packed };
  }
  if (typeof packed === "number") {
    return { arg: packed };
  }
  if ("f" in packed) {
    return { fn: packed.f };
  }
  if ("u" in packed) {
    return { use: packed.u };
  }
  throw new Error(`Could not unpack word. Has no match: ${packed}`);
};

const unpackDeclaration = packed => {
  const full = {};
  if (packed.r) {
    full.ret = packed.r.map(unpackWord);
    if (packed.l) {
      full.lines = {};
      for (const id in packed.l) {
        full.lines[id] = packed.l[id].map(unpackWord);
      }
    }
  } else {
    full.line = packed.l.map(unpackWord);
  }
  return full;
};

const unpackDecSet = packed => {
  const full = {};
  for (const id in packed) {
    const packedDec = packed[id];
    const fullDec = unpackDeclaration(packedDec);
    fullDec.id = id;
    full[id] = fullDec;
  }
  return full;
};

const packTest = packDecSet(test.decs);
const unpackTest = unpackDecSet(packTest);
console.log(util.inspect(packTest, { depth: null }));
// console.log(util.inspect(unpackTest, { depth: null }));
const before = JSON.stringify(test.decs).length;
const after = JSON.stringify(packTest).length;
const unpacked = JSON.stringify(unpackTest).length;
console.log(before, after, unpacked, after / before * 100);

const store = Repo.create({ decs: unpackTest });
const a = store.out("a");
const b = store.out("b");
console.log(a(1), 1);
console.log(store.out("ba"));

const c = store.out("d");
console.log(c({ type: "INCREMENT" }), "INCREMENT");

const e = store.out("e");
console.log(e({ type: "DECREMENT" })(5));
<|endoftext|>


<commit_before>'use strict';

/* eslint-disable func-names */
/* eslint-disable prefer-arrow-callback */

const fs = require('fs/promises')
const assert = require('assert');
const supertest = require('supertest');
const Xible = require('..');

const CONFIG_PATH = '~/.xible/config.json';
const xible = new Xible({
  configPath: CONFIG_PATH
});

describe('Node', function () {
  before(function () {
    this.timeout(10000);
    return xible.init();
  });

  after(function () {
    return xible.close();
  });

  describe('getStructure', function () {
    const dirPath = `${__dirname}/../nodes/test-node`;
    before(async function () {
      await fs.mkdir(dirPath);
    });

    after(async function () {
      await fs.rm(dirPath, { force: true, recursive: true });
    });

    it('empty dir should return null', async function () {
      assert.equal(await xible.Node.getStructure(dirPath), null);
    });

    it('non-structure.json should return null', async function () {
      await fs.writeFile(`${dirPath}/ignore.json`, '{}');
      assert.equal(await xible.Node.getStructure(dirPath), null);
    });

    it('faulty structure.json should throw', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ name: "test-node" }'); // note missing quotes around 'name' key
      assert.rejects(async () => xible.Node.getStructure(dirPath));
    });

    it('structure.json should return', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node" }');
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.name, 'test-node');
      assert.deepEqual(structure.node.routePaths, {});
    });

    it('faulty typdef.json should throw', async function () {
      await fs.writeFile(`${dirPath}/typedef.json`, '{ name: "test-node" }');
      assert.rejects(async () => xible.Node.getStructure(dirPath));
    });

    it('typedef.json should return', async function () {
      await fs.writeFile(`${dirPath}/typedef.json`, '{ "test-node": { "color": "gold" } }');
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.typedefs['test-node'].color, 'gold');
    });

    it('editor should return', async function () {
      await fs.mkdir(`${dirPath}/editor`);
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.editorContentPath, null);
      assert.equal(structure.node.editorContentIndexPath, null);
    });

    it('editor index should return', async function () {
      await fs.writeFile(`${dirPath}/editor/index.htm`, '<input />');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.editorContentIndexPath, null);
    });

    it('routes/global.js should return', async function () {
      await fs.mkdir(`${dirPath}/routes`);
      await fs.writeFile(`${dirPath}/routes/global.js`, 'process.exit(0);');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.routePaths.global, null);
      assert.equal(structure.node.routePaths.flow, null);
    });

    it('routes/flow.js should return', async function () {
      await fs.writeFile(`${dirPath}/routes/flow.js`, 'process.exit(0);');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.routePaths.global, null);
      assert.notEqual(structure.node.routePaths.flow, null);
    });

    it('vault[] should translate to dataStructure[].vault and vice versa', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "dataStructure": { "some": {}, "else": { "vault": true } }, "vault": ["some"] }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.dataStructure.some.vault, true);
      assert.equal(structure.node.vault.includes('else'), true);
    });

    it('dataStructure[].vault should translate to non-existing vault[]', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "dataStructure": { "some": {}, "else": { "vault": true } } }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.vault.includes('else'), true);
    });

    it('vault[] should ignore non-existing dataStructure[]', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "vault": ["some"] }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.dataStructure, null);
    });
  });
});
<commit_msg>linting<commit_after>'use strict';

/* eslint-disable func-names */
/* eslint-disable prefer-arrow-callback */

const fs = require('fs/promises');
const assert = require('assert');
const Xible = require('..');

const CONFIG_PATH = '~/.xible/config.json';
const xible = new Xible({
  configPath: CONFIG_PATH
});

describe('Node', function () {
  before(function () {
    this.timeout(10000);
    return xible.init();
  });

  after(function () {
    return xible.close();
  });

  describe('getStructure', function () {
    const dirPath = `${__dirname}/../nodes/test-node`;
    before(async function () {
      await fs.mkdir(dirPath);
    });

    after(async function () {
      await fs.rm(dirPath, { force: true, recursive: true });
    });

    it('empty dir should return null', async function () {
      assert.equal(await xible.Node.getStructure(dirPath), null);
    });

    it('non-structure.json should return null', async function () {
      await fs.writeFile(`${dirPath}/ignore.json`, '{}');
      assert.equal(await xible.Node.getStructure(dirPath), null);
    });

    it('faulty structure.json should throw', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ name: "test-node" }'); // note missing quotes around 'name' key
      assert.rejects(async () => xible.Node.getStructure(dirPath));
    });

    it('structure.json should return', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node" }');
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.name, 'test-node');
      assert.deepEqual(structure.node.routePaths, {});
    });

    it('faulty typdef.json should throw', async function () {
      await fs.writeFile(`${dirPath}/typedef.json`, '{ name: "test-node" }');
      assert.rejects(async () => xible.Node.getStructure(dirPath));
    });

    it('typedef.json should return', async function () {
      await fs.writeFile(`${dirPath}/typedef.json`, '{ "test-node": { "color": "gold" } }');
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.typedefs['test-node'].color, 'gold');
    });

    it('editor should return', async function () {
      await fs.mkdir(`${dirPath}/editor`);
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.editorContentPath, null);
      assert.equal(structure.node.editorContentIndexPath, null);
    });

    it('editor index should return', async function () {
      await fs.writeFile(`${dirPath}/editor/index.htm`, '<input />');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.editorContentIndexPath, null);
    });

    it('routes/global.js should return', async function () {
      await fs.mkdir(`${dirPath}/routes`);
      await fs.writeFile(`${dirPath}/routes/global.js`, 'process.exit(0);');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.routePaths.global, null);
      assert.equal(structure.node.routePaths.flow, null);
    });

    it('routes/flow.js should return', async function () {
      await fs.writeFile(`${dirPath}/routes/flow.js`, 'process.exit(0);');
      const structure = await xible.Node.getStructure(dirPath);
      assert.notEqual(structure.node.routePaths.global, null);
      assert.notEqual(structure.node.routePaths.flow, null);
    });

    it('vault[] should translate to dataStructure[].vault and vice versa', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "dataStructure": { "some": {}, "else": { "vault": true } }, "vault": ["some"] }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.dataStructure.some.vault, true);
      assert.equal(structure.node.vault.includes('else'), true);
    });

    it('dataStructure[].vault should translate to non-existing vault[]', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "dataStructure": { "some": {}, "else": { "vault": true } } }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.vault.includes('else'), true);
    });

    it('vault[] should ignore non-existing dataStructure[]', async function () {
      await fs.writeFile(`${dirPath}/structure.json`, '{ "name": "test-node", "vault": ["some"] }');
      delete require.cache[require.resolve(`${dirPath}/structure.json`)];
      const structure = await xible.Node.getStructure(dirPath);
      assert.equal(structure.node.dataStructure, null);
    });
  });
});
<|endoftext|>


<commit_before>var serverOverride = null;
// Set up the Alchemy client object
//var serverOverride = "10.20.0.161"; // David vm
//var serverOverride = "10.10.10.64"; // Admo-room
//Set this value to make the framework connect to another IP address

AdmoApp.WebSocket = new Alchemy({
    Server: serverOverride || "localhost",
    Port:1080,
    SocketType: Alchemy.prototype.SocketTypes.WebSocket,
    Action: "doesntmatter",
    DebugMode: false
});

AdmoApp.WebSocket.Connected = function(){
    console.log("connected");
    //Send a keep alive to the C# server every 4 seconds
    var alive = {type:'alive'};
    setInterval(function(){
      console.log("Sending alive ping");
      AlchemyServer.Send(alive);
    },4000);

    //The server isn't actually connected here. So we fake waiting a while.
    //This needs to be fixed some how.
    //TODO: Fix this is a hack
    setTimeout(function(){
      AlchemyServer.Send({type:'config'})
    },500);

};
AdmoApp.WebSocket.Disconnected = function(){
    console.log("disconnected");
};

AdmoApp.WebSocket.MessageReceived = function(event){
  //console.log(event);
   try{
        var eventData = JSON.parse(event.data);
        switch(eventData.type){
          case 'kinectState':
            AdmoApp.handleGesture(eventData.data);
            break;
          case 'swipeGesture':
            AdmoApp.handleSwipe(eventData.data);
            break;
          case 'config':
            AdmoApp.handleConfig(eventData.data);
            break;
          case 'reload':
            AdmoApp.reload(eventData.data);
            break;
          default:
            console.log("unable to proccess event from server");
            console.log(eventData);
            break;
        }

    }catch(exception){
        console.log("Unable to handle event data");
        console.log(exception);
        console.log(event);
    }
};
<commit_msg>added user outline to accepted websocket events<commit_after>var serverOverride = null;
// Set up the Alchemy client object
//var serverOverride = "10.20.0.161"; // David vm
//var serverOverride = "10.10.10.64"; // Admo-room
//Set this value to make the framework connect to another IP address

AdmoApp.WebSocket = new Alchemy({
    Server: serverOverride || "localhost",
    Port:1080,
    SocketType: Alchemy.prototype.SocketTypes.WebSocket,
    Action: "doesntmatter",
    DebugMode: false
});

AdmoApp.WebSocket.Connected = function(){
    console.log("connected");
    //Send a keep alive to the C# server every 4 seconds
    var alive = {type:'alive'};
    setInterval(function(){
      console.log("Sending alive ping");
      AlchemyServer.Send(alive);
    },4000);

    //The server isn't actually connected here. So we fake waiting a while.
    //This needs to be fixed some how.
    //TODO: Fix this is a hack
    setTimeout(function(){
      AlchemyServer.Send({type:'config'})
    },500);

};
AdmoApp.WebSocket.Disconnected = function(){
    console.log("disconnected");
};

AdmoApp.WebSocket.MessageReceived = function(event){
  //console.log(event);
   try{
        var eventData = JSON.parse(event.data);
        switch(eventData.type){
          case 'kinectState':
            AdmoApp.handleGesture(eventData.data);
            break;
          case 'swipeGesture':
            AdmoApp.handleSwipe(eventData.data);
            break;
          case 'userImage':
            AdmoApp.handleImageFrame(eventData.data);
            break;
          case 'config':
            AdmoApp.handleConfig(eventData.data);
            break;
          case 'reload':
            AdmoApp.reload(eventData.data);
            break;
          default:
            console.log("unable to proccess event from server");
            console.log(eventData);
            break;
        }

    }catch(exception){
        console.log("Unable to handle event data");
        console.log(exception);
        console.log(event);
    }
};
<|endoftext|>


<commit_before>var tape = require('tape');
var rodabase = require('../');
var memdown = require('memdown');
var jsondown = require('jsondown');
var _ = require('underscore');

var roda = rodabase('./test/data/crud.json', {
  // db: memdown
  db: jsondown
});
var n = 100;

roda.base.use('diff', function delay(ctx, next){
  console.log(ctx.result);
  setTimeout(next, 100);
});

tape('Put tx read lock', function(t){
  var api = roda('t1');

  t.plan(2);
  function run(i){
    var tx = roda.transaction();
    api.get('k', tx, function(err, val){

      api.put({
        _id: 'k',
        k: (val ? val.k : 0) + 1
      }, tx);

      tx.commit();
    });
  }
  for(var i = 0; i < n; i++)
    run(i);

  var tx = roda.transaction();

  api.get('k', tx, function(err, val){
    t.ok(val);
    t.equal(val.k, n, 'Tx incrememnt');
  });

  tx.commit();
});

tape('Put increment', function(t){
  t.plan(2);
  var api = roda('t2');
  var _id = '', _rev = '';
  var list = [];

  for(var i = 0; i < n; i++)
    api.put({ i: i }, function(err, val){
      list.push(val);
      if(val.i === n - 1){
        list = _.sortBy(list, 'i');
        t.deepEqual(_.sortBy(list, '_id'), list, '_id incremental');
        t.deepEqual(_.sortBy(list, '_rev'), list, '_rev incremental');
      }
    });
});

<commit_msg>ADD tx increment test case<commit_after>var tape = require('tape');
var rodabase = require('../');
var memdown = require('memdown');
var jsondown = require('jsondown');
var _ = require('underscore');

var roda = rodabase('./test/data/crud.json', {
  // db: memdown
  db: jsondown
});
var n = 100;

// roda.base.use('diff', function delay(ctx, next){
//   console.log(ctx.result);
//   setTimeout(next, 100);
// });

tape('Read lock', function(t){
  var api = roda('1');

  t.plan(2);
  function run(i){
    var tx = roda.transaction();
    api.get('k', tx, function(err, val){

      api.put({
        _id: 'k',
        k: (val ? val.k : 0) + 1
      }, tx);

      tx.commit();
    });
  }
  for(var i = 0; i < n; i++)
    run(i);

  var tx = roda.transaction();

  api.get('k', tx, function(err, val){
    t.ok(val);
    t.equal(val.k, n, 'Tx incrememnt');
  });

  tx.commit();
});

tape('Put increment', function(t){
  t.plan(2);
  var api = roda('2');

  for(var i = 0; i < n; i++)
    api.put({ i: i }, function(err, val){
      if(val.i === n - 1){
        api.read(function(err, list){
          list = _.sortBy(list, 'i');
          t.deepEqual(_.sortBy(list, '_id'), list, '_id incremental');
          t.deepEqual(_.sortBy(list, '_rev'), list, '_rev incremental');
        });
      }
    });
});

tape('Put tx increment', function(t){
  t.plan(4);
  var api = roda('3');
  var tx = roda.transaction();

  for(var i = 0; i < n; i++)
    api.put({ i: i }, tx);

  api.read(function(err, list){
    t.equal(list.length, 0, 'list empty before commit');
    tx.commit(function(){
      api.read(function(err, list){
        list = _.sortBy(list, 'i');
        t.equal(list.length, n, 'list filled after commit');
        t.deepEqual(_.sortBy(list, '_id'), list, '_id incremental');
        t.deepEqual(_.sortBy(list, '_rev'), list, '_rev incremental');
      });
    });
  });
});

<|endoftext|>


<commit_before>var should = require('should')
  , time = require('../')

describe('Date', function () {

  describe('constructor', function() {

    it('should parse strings relative to TZ', function() {

      var d = new time.Date('2012-1-12 02:00 PM', 'America/New_York')
      d.getTime().should.equal(1326394800000)
      d.getTimezone().should.equal('America/New_York')

      d = new time.Date('2012-1-12 02:00 PM', 'America/Los_Angeles')
      d.getTime().should.equal(1326405600000)
      d.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should interpret date parts relative to TZ', function() {

      var d = new time.Date(2012, 0, 12, 14, 'America/New_York')
      d.getTime().should.equal(1326394800000)
      d.getFullYear().should.equal(2012)
      d.getTimezone().should.equal('America/New_York')

      d = new time.Date(2012, 0, 12, 14, 'America/Los_Angeles')
      d.getTime().should.equal(1326405600000)
      d.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should accept milliseconds regardless of TZ', function() {

      var d1 = new time.Date(1352005200000, 'America/New_York')
      var d2 = new time.Date(1352005200000, 'America/Los_Angeles')

      d1.getTime().should.equal(d2.getTime())
      d1.getTimezone().should.equal('America/New_York')
      d2.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should parse strings around 2038', function() {

      //Before threshold
      var d = new time.Date('2037-12-31 11:59:59 PM', 'UTC')
      d.getTime().should.equal(2145916799000)
      //After threshold
      d = new time.Date('2038-01-01 00:00:00 AM', 'UTC')
      d.getTime().should.equal(2145916800000)

      //Before threshold
      d = new time.Date('2038-1-19 03:14:06 AM', 'UTC')
      d.getTime().should.equal(2147483646000)
      //After threshold
      d = new time.Date('2038-1-19 03:14:07 AM', 'UTC')
      d.getTime().should.equal(2147483647000)
    })
  })

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

    beforeEach(function () {
      time.tzset('UTC')
    })

    it('should clean up after itself', function () {
      var initial = process.env.TZ
        , d = new time.Date()
      d.setTimezone('America/Argentina/San_Juan')
      initial.should.equal(process.env.TZ)
    })

    it('should be chainable', function () {
      var initial = process.env.TZ
        , d = new time.Date().setTimezone('America/Argentina/San_Juan')
      d.getTimezone().should.equal('America/Argentina/San_Juan')
    })

    it('should change the "timezone offset"', function () {
      var d = new time.Date()
        , offset = d.getTimezoneOffset()
      d.setTimezone('US/Pacific')
      d.getTimezoneOffset().should.not.equal(offset)
    })

    it('should match the UTC values when set to "UTC"', function () {
      var d = new time.Date()
      d.setTimezone('UTC')
      d.getUTCDay().should.equal(d.getDay())
      d.getUTCDate().should.equal(d.getDate())
      d.getUTCFullYear().should.equal(d.getFullYear())
      d.getUTCHours().should.equal(d.getHours())
      d.getUTCMilliseconds().should.equal(d.getMilliseconds())
      d.getUTCMinutes().should.equal(d.getMinutes())
      d.getUTCMonth().should.equal(d.getMonth())
      d.getUTCSeconds().should.equal(d.getSeconds())
      d.getTimezoneOffset().should.equal(0)
    })

    it('should especially change the "hours" value', function () {
      var d = new time.Date()
        , hours = d.getHours()

      d.setTimezone('US/Pacific')
      d.getHours().should.not.equal(hours)
      hours = d.getHours()

      d.setTimezone('US/Eastern')
      d.getHours().should.not.equal(hours)
      hours = d.getHours()

      d.setTimezone('America/Argentina/San_Juan')
      d.getHours().should.not.equal(hours)
    })

    describe('relative', function () {

      it('should change the timezone', function () {
        var d = new time.Date()
        d.setTimezone('US/Pacific', true)
        d.getTimezone().should.not.equal(process.env.TZ)
      })

      it('should keep local values', function () {
        var d = new time.Date()
          , millis = d.getMilliseconds()
          , seconds = d.getSeconds()
          , minutes = d.getMinutes()
          , hours = d.getHours()
          , date = d.getDate()
          , month = d.getMonth()
          , year = d.getFullYear()
        d.setTimezone('US/Pacific', true)

        d.getMilliseconds().should.equal(millis)
        d.getSeconds().should.equal(seconds)
        d.getMinutes().should.equal(minutes)
        d.getHours().should.equal(hours)
        d.getDate().should.equal(date)
        d.getMonth().should.equal(month)
        d.getFullYear().should.equal(year)
      })

      it('should change the date\'s internal time value', function () {
        var d = new time.Date()
          , old = d.getTime()
        d.setTimezone('US/Pacific', true)
        d.getTime().should.not.equal(old)
      })

      it('should calculate correctly when UTC date is day after timezone date', function () {
        var forwards = {
            timezone: 'US/Pacific', hour: 22, minute: 47,
            year: 2013, month: 1, date: 31
        };
        var d = new time.Date(
          forwards.year, forwards.month - 1, forwards.date,
          forwards.hour, forwards.minute, 1, 1, forwards.timezone
        );
        d.toString().should.equal('Thu Jan 31 2013 22:47:01 GMT-0800 (PST)');
        d.setTimezone('UTC');
        d.toString().should.equal('Fri Feb 01 2013 06:47:01 GMT+0000 (UTC)');
      })

      it('should calculate correctly when UTC date is day before timezone date', function () {
        var d = new time.Date(2010, 0, 31, 19, 0, 0, 0, 'UTC');
        d.toString().should.equal('Sun Jan 31 2010 19:00:00 GMT+0000 (UTC)')

        var backwards = {
            timezone: 'Australia/Sydney', hour: 2, minute: 47,
            year: 2013, month: 2, date: 1
        };

        var d2 = new time.Date(
          backwards.year, backwards.month - 1, backwards.date,
          backwards.hour, backwards.minute, 1, 1, backwards.timezone
        );
        d2.toString().should.equal('Fri Feb 01 2013 02:47:01 GMT+1100 (EST)');
        d2.setTimezone('UTC');
        d2.toString().should.equal('Thu Jan 31 2013 15:47:01 GMT+0000 (UTC)');
      })

      it('should calculate correctly on edge of months', function() {
        var d = new time.Date("2013-02-01 01:02:03", 'US/Pacific');
        d.toString().should.equal('Fri Feb 01 2013 01:02:03 GMT-0800 (PST)');
        d.setTimezone('UTC');
        d.toString().should.equal('Fri Feb 01 2013 09:02:03 GMT+0000 (UTC)');
      })

    })

  })
})
<commit_msg>set* and setUTC* tests<commit_after>var should = require('should')
  , time = require('../')

describe('Date', function () {

  describe('constructor', function() {

    it('should parse strings relative to TZ', function() {

      var d = new time.Date('2012-1-12 02:00 PM', 'America/New_York')
      d.getTime().should.equal(1326394800000)
      d.getTimezone().should.equal('America/New_York')

      d = new time.Date('2012-1-12 02:00 PM', 'America/Los_Angeles')
      d.getTime().should.equal(1326405600000)
      d.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should interpret date parts relative to TZ', function() {

      var d = new time.Date(2012, 0, 12, 14, 'America/New_York')
      d.getTime().should.equal(1326394800000)
      d.getFullYear().should.equal(2012)
      d.getTimezone().should.equal('America/New_York')

      d = new time.Date(2012, 0, 12, 14, 'America/Los_Angeles')
      d.getTime().should.equal(1326405600000)
      d.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should accept milliseconds regardless of TZ', function() {

      var d1 = new time.Date(1352005200000, 'America/New_York')
      var d2 = new time.Date(1352005200000, 'America/Los_Angeles')

      d1.getTime().should.equal(d2.getTime())
      d1.getTimezone().should.equal('America/New_York')
      d2.getTimezone().should.equal('America/Los_Angeles')
    })

    it('should parse strings around 2038', function() {

      //Before threshold
      var d = new time.Date('2037-12-31 11:59:59 PM', 'UTC')
      d.getTime().should.equal(2145916799000)
      //After threshold
      d = new time.Date('2038-01-01 00:00:00 AM', 'UTC')
      d.getTime().should.equal(2145916800000)

      //Before threshold
      d = new time.Date('2038-1-19 03:14:06 AM', 'UTC')
      d.getTime().should.equal(2147483646000)
      //After threshold
      d = new time.Date('2038-1-19 03:14:07 AM', 'UTC')
      d.getTime().should.equal(2147483647000)
    })
  })

  it('should accept js1.3 extended set* arguments', function() {

    var d = new time.Date(2000, 1, 2, 3, 4, 5, 6, 'America/Chicago');
    d.setFullYear(2001, 2, 3);
    d.getTime().should.equal(983610245006);
    d.setFullYear(2002, 3);
    d.getTime().should.equal(1017824645006);
    d.setMonth(4, 5);
    d.getTime().should.equal(1020585845006);
    d.setHours(4, 5, 6, 7);
    d.getTime().should.equal(1020589506007);
    d.setHours(5, 6, 7);
    d.getTime().should.equal(1020593167007);
    d.setHours(6, 7);
    d.getTime().should.equal(1020596827007);
    d.setMinutes(8, 9, 10);
    d.getTime().should.equal(1020596889010);
    d.setMinutes(9, 10);
    d.getTime().should.equal(1020596950010);
    d.setSeconds(11, 12);
    d.getTime().should.equal(1020596951012);
  })

  it('should accept js1.3 extended setUTC* arguments', function() {

    var d = new time.Date(2000, 1, 2, 3, 4, 5, 6, 'America/Chicago');
    d.setUTCFullYear(2001, 2, 3);
    d.getTime().should.equal(983610245006);
    d.setUTCFullYear(2002, 3);
    d.getTime().should.equal(1017824645006);
    d.setUTCMonth(4, 5);
    d.getTime().should.equal(1020589445006);
    d.setUTCHours(4, 5, 6, 7);
    d.getTime().should.equal(1020571506007);
    d.setUTCHours(5, 6, 7);
    d.getTime().should.equal(1020575167007);
    d.setUTCHours(6, 7);
    d.getTime().should.equal(1020578827007);
    d.setUTCMinutes(8, 9, 10);
    d.getTime().should.equal(1020578889010);
    d.setUTCMinutes(9, 10);
    d.getTime().should.equal(1020578950010);
    d.setUTCSeconds(11, 12);
    d.getTime().should.equal(1020578951012);
  })

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

    beforeEach(function () {
      time.tzset('UTC')
    })

    it('should clean up after itself', function () {
      var initial = process.env.TZ
        , d = new time.Date()
      d.setTimezone('America/Argentina/San_Juan')
      initial.should.equal(process.env.TZ)
    })

    it('should be chainable', function () {
      var initial = process.env.TZ
        , d = new time.Date().setTimezone('America/Argentina/San_Juan')
      d.getTimezone().should.equal('America/Argentina/San_Juan')
    })

    it('should change the "timezone offset"', function () {
      var d = new time.Date()
        , offset = d.getTimezoneOffset()
      d.setTimezone('US/Pacific')
      d.getTimezoneOffset().should.not.equal(offset)
    })

    it('should match the UTC values when set to "UTC"', function () {
      var d = new time.Date()
      d.setTimezone('UTC')
      d.getUTCDay().should.equal(d.getDay())
      d.getUTCDate().should.equal(d.getDate())
      d.getUTCFullYear().should.equal(d.getFullYear())
      d.getUTCHours().should.equal(d.getHours())
      d.getUTCMilliseconds().should.equal(d.getMilliseconds())
      d.getUTCMinutes().should.equal(d.getMinutes())
      d.getUTCMonth().should.equal(d.getMonth())
      d.getUTCSeconds().should.equal(d.getSeconds())
      d.getTimezoneOffset().should.equal(0)
    })

    it('should especially change the "hours" value', function () {
      var d = new time.Date()
        , hours = d.getHours()

      d.setTimezone('US/Pacific')
      d.getHours().should.not.equal(hours)
      hours = d.getHours()

      d.setTimezone('US/Eastern')
      d.getHours().should.not.equal(hours)
      hours = d.getHours()

      d.setTimezone('America/Argentina/San_Juan')
      d.getHours().should.not.equal(hours)
    })

    describe('relative', function () {

      it('should change the timezone', function () {
        var d = new time.Date()
        d.setTimezone('US/Pacific', true)
        d.getTimezone().should.not.equal(process.env.TZ)
      })

      it('should keep local values', function () {
        var d = new time.Date()
          , millis = d.getMilliseconds()
          , seconds = d.getSeconds()
          , minutes = d.getMinutes()
          , hours = d.getHours()
          , date = d.getDate()
          , month = d.getMonth()
          , year = d.getFullYear()
        d.setTimezone('US/Pacific', true)

        d.getMilliseconds().should.equal(millis)
        d.getSeconds().should.equal(seconds)
        d.getMinutes().should.equal(minutes)
        d.getHours().should.equal(hours)
        d.getDate().should.equal(date)
        d.getMonth().should.equal(month)
        d.getFullYear().should.equal(year)
      })

      it('should change the date\'s internal time value', function () {
        var d = new time.Date()
          , old = d.getTime()
        d.setTimezone('US/Pacific', true)
        d.getTime().should.not.equal(old)
      })

      it('should calculate correctly when UTC date is day after timezone date', function () {
        var forwards = {
            timezone: 'US/Pacific', hour: 22, minute: 47,
            year: 2013, month: 1, date: 31
        };
        var d = new time.Date(
          forwards.year, forwards.month - 1, forwards.date,
          forwards.hour, forwards.minute, 1, 1, forwards.timezone
        );
        d.toString().should.equal('Thu Jan 31 2013 22:47:01 GMT-0800 (PST)');
        d.setTimezone('UTC');
        d.toString().should.equal('Fri Feb 01 2013 06:47:01 GMT+0000 (UTC)');
      })

      it('should calculate correctly when UTC date is day before timezone date', function () {
        var d = new time.Date(2010, 0, 31, 19, 0, 0, 0, 'UTC');
        d.toString().should.equal('Sun Jan 31 2010 19:00:00 GMT+0000 (UTC)')

        var backwards = {
            timezone: 'Australia/Sydney', hour: 2, minute: 47,
            year: 2013, month: 2, date: 1
        };

        var d2 = new time.Date(
          backwards.year, backwards.month - 1, backwards.date,
          backwards.hour, backwards.minute, 1, 1, backwards.timezone
        );
        d2.toString().should.equal('Fri Feb 01 2013 02:47:01 GMT+1100 (EST)');
        d2.setTimezone('UTC');
        d2.toString().should.equal('Thu Jan 31 2013 15:47:01 GMT+0000 (UTC)');
      })

      it('should calculate correctly on edge of months', function() {
        var d = new time.Date("2013-02-01 01:02:03", 'US/Pacific');
        d.toString().should.equal('Fri Feb 01 2013 01:02:03 GMT-0800 (PST)');
        d.setTimezone('UTC');
        d.toString().should.equal('Fri Feb 01 2013 09:02:03 GMT+0000 (UTC)');
      })

    })

  })
})
<|endoftext|>


<commit_before>var parser = require('../');
var test = require('tape');
var fs = require('fs');

var files = {
    main: __dirname + '/files/main.js',
    foo: __dirname + '/files/foo.js',
    bar: __dirname + '/files/bar.js'
};

var sources = Object.keys(files).reduce(function (acc, file) {
    acc[file] = fs.readFileSync(files[file], 'utf8');
    return acc;
}, {});

test('deps', function (t) {
    t.plan(1);
    var p = parser(files.main);
    var rows = [];

    p.on('data', function (row) { rows.push(row) });
    p.on('end', function () {
        t.same(rows.sort(cmp), [
            {
                id: files.main,
                source: sources.main,
                entry: true,
                deps: { './foo': files.foo }
            },
            {
                id: files.foo,
                source: sources.foo,
                deps: { './bar': files.bar }
            },
            {
                id: files.bar,
                source: sources.bar,
                deps: {}
            }
        ].sort(cmp));
    });
});

function cmp (a, b) { return a.id < b.id ? -1 : 1 }
<commit_msg>updated deps test<commit_after>var parser = require('../');
var test = require('tape');
var fs = require('fs');

var files = {
    main: __dirname + '/files/main.js',
    foo: __dirname + '/files/foo.js',
    bar: __dirname + '/files/bar.js'
};

var sources = Object.keys(files).reduce(function (acc, file) {
    acc[file] = fs.readFileSync(files[file], 'utf8');
    return acc;
}, {});

test('deps', function (t) {
    t.plan(1);
    var p = parser();
    p.end({ file: files.main, entry: true });

    var rows = [];
    p.on('data', function (row) { rows.push(row) });
    p.on('end', function () {
        t.same(rows.sort(cmp), [
            {
                id: files.main,
                source: sources.main,
                entry: true,
                deps: { './foo': files.foo }
            },
            {
                id: files.foo,
                source: sources.foo,
                deps: { './bar': files.bar }
            },
            {
                id: files.bar,
                source: sources.bar,
                deps: {}
            }
        ].sort(cmp));
    });
});

function cmp (a, b) { return a.id < b.id ? -1 : 1 }
<|endoftext|>