<commit_before>var fs = require('fs')
var os = require('os')
var path = require('path')
var test = require('tape')
var spawn = require('tape-spawn')
var helpers = require('./helpers')

var tmp = os.tmpdir()
var dat = path.resolve(__dirname + '/../cli.js')
var dat1 = path.join(tmp, 'dat-cli-1')

test('cli: dat -v (version)', function (t) {
  var st = spawn(t, dat + ' -v')
  var pkg = require('../package.json')
  st.stdout.match(pkg.version + '\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat --version (version)', function (t) {
  var st = spawn(t, dat + ' --version')
  var pkg = require('../package.json')
  st.stdout.match(pkg.version + '\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat (usage)', function (t) {
  var st = spawn(t, dat)
  st.stderr.match(fs.readFileSync(path.join('usage', 'root.txt')).toString() + '\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

test('cli: dat init -h (init usage)', function (t) {
  var st = spawn(t, dat + ' init -h')
  st.stderr.match(fs.readFileSync(path.join('usage', 'init.txt')).toString() + '\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

test('cli: invalid command', function (t) {
  var st = spawn(t, dat + ' pizza')
  st.stderr.match('dat: pizza is not a valid command\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

var cleanup = helpers.onedat(dat1)

// sanity: make sure cwd isn't in a repo
test('cli: dat status (cwd)', function (t) {
  var st = spawn(t, dat + ' status')
  st.stderr.match(/This is not a dat repository/)
  st.stdout.empty()
  st.end()
})

test('cli: dat -p (path)', function (t) {
  var st = spawn(t, dat + ' status -p ' + dat1)
  st.stderr.match(/This dat is empty/)
  st.stdout.empty()
  st.end()
})

test('cli: dat --path (path)', function (t) {
  var st = spawn(t, dat + ' status --path=' + dat1)
  st.stderr.match(/This dat is empty/)
  st.stdout.empty()
  st.end()
})

test('cli: dat status --json', function (t) {
  var st = spawn(t, dat + ' status --json --path=' + dat1)
  st.stdout.match('{"error":true,"message":"This dat is empty"}\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat status --json --verbose', function (t) {
  var st = spawn(t, dat + ' status --json --verbose --path=' + dat1)
  st.stdout.match(new RegExp('"error":true,"message":"This dat is empty","stack":"Error:'))
  st.stderr.empty()
  st.end()
})

test('cli: dat status --verbose', function (t) {
  var st = spawn(t, dat + ' status --verbose --path=' + dat1)
  st.stderr.match(/This dat is empty\nError/)
  st.stdout.empty()
  st.end()
})

test('cli: cleanup', function (t) {
  cleanup()
  t.end()
})
<commit_msg>tests shouldn't depend on local directory -- create a tmp dir for status tests<commit_after>var fs = require('fs')
var os = require('os')
var path = require('path')
var test = require('tape')
var spawn = require('tape-spawn')
var helpers = require('./helpers')

var tmp = os.tmpdir()
var dat = path.resolve(__dirname + '/../cli.js')
var dat1 = path.join(tmp, 'dat-cli-1')

test('cli: dat -v (version)', function (t) {
  var st = spawn(t, dat + ' -v')
  var pkg = require('../package.json')
  st.stdout.match(pkg.version + '\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat --version (version)', function (t) {
  var st = spawn(t, dat + ' --version')
  var pkg = require('../package.json')
  st.stdout.match(pkg.version + '\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat (usage)', function (t) {
  var st = spawn(t, dat)
  st.stderr.match(fs.readFileSync(path.join('usage', 'root.txt')).toString() + '\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

test('cli: dat init -h (init usage)', function (t) {
  var st = spawn(t, dat + ' init -h')
  st.stderr.match(fs.readFileSync(path.join('usage', 'init.txt')).toString() + '\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

test('cli: invalid command', function (t) {
  var st = spawn(t, dat + ' pizza')
  st.stderr.match('dat: pizza is not a valid command\n', 'usage matched')
  st.stdout.empty()
  st.end()
})

var cleanup = helpers.onedat(dat1)

var tmp = os.tmpdir()

// sanity: make sure cwd isn't in a repo
test('cli: dat status (cwd)', function (t) {
  var st = spawn(t, dat + ' status', {cwd: tmp})
  st.stderr.match(/This is not a dat repository/)
  st.stdout.empty()
  st.end()
})

test('cli: dat -p (path)', function (t) {
  var st = spawn(t, dat + ' status -p ' + dat1, {cwd: tmp})
  st.stderr.match(/This dat is empty/)
  st.stdout.empty()
  st.end()
})

test('cli: dat --path (path)', function (t) {
  var st = spawn(t, dat + ' status --path=' + dat1, {cwd: tmp})
  st.stderr.match(/This dat is empty/)
  st.stdout.empty()
  st.end()
})

test('cli: dat status --json', function (t) {
  var st = spawn(t, dat + ' status --json --path=' + dat1, {cwd: tmp})
  st.stdout.match('{"error":true,"message":"This dat is empty"}\n')
  st.stderr.empty()
  st.end()
})

test('cli: dat status --json --verbose', function (t) {
  var st = spawn(t, dat + ' status --json --verbose --path=' + dat1, {cwd: tmp})
  st.stdout.match(new RegExp('"error":true,"message":"This dat is empty","stack":"Error:'))
  st.stderr.empty()
  st.end()
})

test('cli: dat status --verbose', function (t) {
  var st = spawn(t, dat + ' status --verbose --path=' + dat1)
  st.stderr.match(/This dat is empty\nError/)
  st.stdout.empty()
  st.end()
})

test('cli: cleanup', function (t) {
  cleanup()
  t.end()
})
<|endoftext|>


<commit_before>var buster = require("buster-core");
var br = require("buster-resources");
var bCapServBayeuxServer = require("./buster-capture-server-bayeux-server");
var httpServerRequestListenerProxy = require("./http-server-request-listener-proxy");
var bCapServSession = require("./session");
var bCapServSessionQueue = require("./session-queue");
var bCapServSlave = require("./slave");
var URL = require("url");
var when = require("when");
var faye = require("faye");

var NOOP = function(){};

exports.create = function () {
    var httpServer;
    var headerHeight;
    var headerResourceSet;
    var bayeuxServer;
    var logger = {"error":NOOP,"warn":NOOP,"log":NOOP,"info":NOOP,"debug":NOOP};
    var resourcesMiddleware = br.resourceMiddleware.create("");
    var resourceCache = br.resourceSetCache.create();
    var sessionQueue = bCapServSessionQueue.create();

    var captureServer = {
        messagingContextPath: "/messaging",
        capturePath: "/capture",

        get logger() {
            return logger;
        },

        set logger(newLogger) {
            logger = newLogger;
            bayeuxServer.setLogger(newLogger);
        },

        header: function (height, resourceSet) {
            headerHeight = height;
            headerResourceSet = resourceSet;
            sessionQueue.slaves.forEach(function (slave) {
                slave.header(headerHeight, headerResourceSet);
            });
        },

        createSession: function (data) {
            var deferred = when.defer();
            createSession(data).then(function (session) {
                deferred.resolve(session.serialize());
            }, function (err) {
                deferred.reject(err);
            });
            return deferred.promise;
        },

        endSession: function (id) {
            var session = sessionQueue.sessions.filter(function (sess) {
                return sess.id == id;
            })[0];

            if (session) {
                sessionQueue.dequeue(session);
            }
        },

        currentSession: function () {
            var s = sessionQueue.currentSession()
            return s && s.serialize();
        },

        get bayeux() {
            return bayeuxServer.getClient();
        },

        attach: function (_httpServer) {
            httpServer = _httpServer;
            bayeuxServer.attach(httpServer);
            httpServerRequestListenerProxy.attach(httpServer, respond);
        },

        oncapture: function (req, res, slave) {
            res.writeHead(302, {"Location": slave.url});
            res.end();
        },

        sessions: function () {
            return sessionQueue.sessions.map(function (s) { return s.serialize(); });
        },

        slaves: function () {
            return sessionQueue.slaves.map(function (s) { return s.serialize(); });
        }
    };

    function respond(req, res) {
        var url = URL.parse(req.url);

        if (req.method == "GET" && url.pathname == captureServer.capturePath) {
            captureSlave(req, res);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/sessions") {
            listSessionsFromRequest(res);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/sessions/current") {
            showCurrentSession(res);
            return true;
        }

        if (req.method == "POST" && url.pathname == "/sessions") {
            logger.debug("Creating session via HTTP");
            createSessionFromRequest(req, res);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/resources") {
            listKnownResources(res);
            return true;
        }

        if (resourcesMiddleware.respond(req, res)) return true;

        if (sessionQueue.sessions.some(function(session) {
            return session.respond(req, res, url.pathname);
        })) return true;

        if (sessionQueue.slaves.some(function(slave) {
            return slave.respond(req, res, url.pathname);
        })) return true;

        if (/^\/slaves\/[^\/]+\/browser$/.test(url.pathname)) {
            captureSlave(req, res);
            return true;
        }
    }

    function listKnownResources(res) {
        res.writeHead(200);
        res.write(JSON.stringify(resourceCache.resourceVersions()));
        res.end();
    }

    function listSessionsFromRequest(res) {
        res.writeHead(200, {"Content-Type": "application/json"});
        res.write(JSON.stringify(captureServer.sessions()));
        res.end();
    }

    function showCurrentSession(res) {
        var currentSession = sessionQueue.currentSession();

        if (currentSession) {
            res.writeHead(200, {"Content-Type": "application/json"});
            res.write(JSON.stringify(currentSession.serialize()));
        } else {
            res.writeHead(404);
        }

        res.end();
    }

    function createSessionFromRequest(req, res) {
        var requestBody = "";
        req.setEncoding("utf8");
        req.on("data", function (chunk) { requestBody += chunk; });
        req.on("end", function () {
            createSessionWithRequestBody(requestBody, req, res);
        });
    }

    function createSessionWithRequestBody(requestBody, req, res) {
        try {
            var data = JSON.parse(requestBody);
        } catch(e) {
            return failWithMessage(res, "Invalid JSON");
        }

        createSession(data).then(function (session) {
            var statusCode = session === sessionQueue.currentSession() ? 201 : 202;
            var serializedSession = session.serialize();
            res.writeHead(statusCode, {"Location": serializedSession.rootPath});
            res.write(JSON.stringify(serializedSession));
            res.end();
        }, function (err) {
            res.writeHead(403);
            res.write(err.toString());
            res.end();
        });
    }

    function createSession(data) {
        var serializedSessionPromise = when.defer();

        bCapServSession.create(data, httpServer).then(function (session) {
            var state = sessionQueue.enqueue(session);
            switch (state) {
            case bCapServSessionQueue.ENQUEUE_STARTED:
            case bCapServSessionQueue.ENQUEUE_QUEUED:
                captureServer.bayeux.publish("/session/create", {
                    session: session.serialize()
                });
                serializedSessionPromise.resolve(session);
                break;
            case bCapServSessionQueue.ENQUEUE_FAILED:
                serializedSessionPromise.reject("No slaves captured, session not created");
                break;
            }
        }, function (err) {
            serializedSessionPromise.reject(err);
        });

        return serializedSessionPromise;
    }

    function failWithMessage(res, message) {
        res.writeHead(400);
        res.write(message + "\n");
        res.end();
    }

    function captureSlave(req, res) {
        var slave = bCapServSlave.create(captureServer, bayeuxServer, resourcesMiddleware, sessionQueue, req.headers["user-agent"], logger);
        slave.header(headerHeight, headerResourceSet);
        slave.on("ready", function () {
            captureServer.oncapture(req, res, slave);
            sessionQueue.addSlave(slave);
            captureServer.bayeux.publish("/capture", slave.serialize());
        });
    }

    bayeuxServer = bCapServBayeuxServer.create(logger, captureServer.messagingContextPath);

    sessionQueue.prepare = function (e) {
        var deferred = when.defer();
        resourceCache.inflate(e.session.resourceSet).then(function (rs) {
            resourcesMiddleware.mount(e.session.resourcesPath, rs);
            deferred.resolve();
        }, function (err) {
            deferred.reject(err);
        });
        return deferred.promise;
    };

    sessionQueue.on("loaded", function (e) {
        captureServer.bayeux.publish("/session/start", {
            session: e.session.serialize(),
            slaves: e.slaves.map(function (slave) {
                return {userAgent: slave.userAgent, id: slave.id};
            })
        });
    });

    sessionQueue.on("unloaded", function (e) {
        resourcesMiddleware.unmount(e.session.resourcesPath);
        captureServer.bayeux.publish("/session/end", {session: e.session.serialize()});
    });

    return captureServer;
};

exports.createSessionMessenger = function (messagingUrl, session) {
    var bayeux = new faye.Client(messagingUrl);
    var contextPath = session.bayeuxContextPath;

    return {
        publish: function (path, data) {
            return bayeux.publish(contextPath + path, data);
        },

        subscribe: function (path, cb) {
            return bayeux.subscribe(contextPath + path, cb);
        },

        disconnect: function () {
            return bayeux.disconnect();
        }
    };
}<commit_msg>Renaming method to make it obvious that it's not session specific.<commit_after>var buster = require("buster-core");
var br = require("buster-resources");
var bCapServBayeuxServer = require("./buster-capture-server-bayeux-server");
var httpServerRequestListenerProxy = require("./http-server-request-listener-proxy");
var bCapServSession = require("./session");
var bCapServSessionQueue = require("./session-queue");
var bCapServSlave = require("./slave");
var URL = require("url");
var when = require("when");
var faye = require("faye");

var NOOP = function(){};

exports.create = function () {
    var httpServer;
    var headerHeight;
    var headerResourceSet;
    var bayeuxServer;
    var logger = {"error":NOOP,"warn":NOOP,"log":NOOP,"info":NOOP,"debug":NOOP};
    var resourcesMiddleware = br.resourceMiddleware.create("");
    var resourceCache = br.resourceSetCache.create();
    var sessionQueue = bCapServSessionQueue.create();

    var captureServer = {
        messagingContextPath: "/messaging",
        capturePath: "/capture",

        get logger() {
            return logger;
        },

        set logger(newLogger) {
            logger = newLogger;
            bayeuxServer.setLogger(newLogger);
        },

        header: function (height, resourceSet) {
            headerHeight = height;
            headerResourceSet = resourceSet;
            sessionQueue.slaves.forEach(function (slave) {
                slave.header(headerHeight, headerResourceSet);
            });
        },

        createSession: function (data) {
            var deferred = when.defer();
            createSession(data).then(function (session) {
                deferred.resolve(session.serialize());
            }, function (err) {
                deferred.reject(err);
            });
            return deferred.promise;
        },

        endSession: function (id) {
            var session = sessionQueue.sessions.filter(function (sess) {
                return sess.id == id;
            })[0];

            if (session) {
                sessionQueue.dequeue(session);
            }
        },

        currentSession: function () {
            var s = sessionQueue.currentSession()
            return s && s.serialize();
        },

        get bayeux() {
            return bayeuxServer.getClient();
        },

        attach: function (_httpServer) {
            httpServer = _httpServer;
            bayeuxServer.attach(httpServer);
            httpServerRequestListenerProxy.attach(httpServer, respond);
        },

        oncapture: function (req, res, slave) {
            res.writeHead(302, {"Location": slave.url});
            res.end();
        },

        sessions: function () {
            return sessionQueue.sessions.map(function (s) { return s.serialize(); });
        },

        slaves: function () {
            return sessionQueue.slaves.map(function (s) { return s.serialize(); });
        }
    };

    function respond(req, res) {
        var url = URL.parse(req.url);

        if (req.method == "GET" && url.pathname == captureServer.capturePath) {
            captureSlave(req, res);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/sessions") {
            listSessionsFromRequest(res);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/sessions/current") {
            showCurrentSession(res);
            return true;
        }

        if (req.method == "POST" && url.pathname == "/sessions") {
            logger.debug("Creating session via HTTP");
            respondWithFullBody(req, res, createSessionWithRequestBody);
            return true;
        }

        if (req.method == "GET" && url.pathname == "/resources") {
            listKnownResources(res);
            return true;
        }

        if (resourcesMiddleware.respond(req, res)) return true;

        if (sessionQueue.sessions.some(function(session) {
            return session.respond(req, res, url.pathname);
        })) return true;

        if (sessionQueue.slaves.some(function(slave) {
            return slave.respond(req, res, url.pathname);
        })) return true;

        if (/^\/slaves\/[^\/]+\/browser$/.test(url.pathname)) {
            captureSlave(req, res);
            return true;
        }
    }

    function listKnownResources(res) {
        res.writeHead(200);
        res.write(JSON.stringify(resourceCache.resourceVersions()));
        res.end();
    }

    function listSessionsFromRequest(res) {
        res.writeHead(200, {"Content-Type": "application/json"});
        res.write(JSON.stringify(captureServer.sessions()));
        res.end();
    }

    function showCurrentSession(res) {
        var currentSession = sessionQueue.currentSession();

        if (currentSession) {
            res.writeHead(200, {"Content-Type": "application/json"});
            res.write(JSON.stringify(currentSession.serialize()));
        } else {
            res.writeHead(404);
        }

        res.end();
    }

    // Calls CB when the entire request body has been received.
    function respondWithFullBody(req, res, cb) {
        var requestBody = "";
        req.setEncoding("utf8");
        req.on("data", function (chunk) { requestBody += chunk; });
        req.on("end", function () { cb(requestBody, req, res); });
    }

    function createSessionWithRequestBody(requestBody, req, res) {
        try {
            var data = JSON.parse(requestBody);
        } catch(e) {
            return failWithMessage(res, "Invalid JSON");
        }

        createSession(data).then(function (session) {
            var statusCode = session === sessionQueue.currentSession() ? 201 : 202;
            var serializedSession = session.serialize();
            res.writeHead(statusCode, {"Location": serializedSession.rootPath});
            res.write(JSON.stringify(serializedSession));
            res.end();
        }, function (err) {
            res.writeHead(403);
            res.write(err.toString());
            res.end();
        });
    }

    function createSession(data) {
        var serializedSessionPromise = when.defer();

        bCapServSession.create(data, httpServer).then(function (session) {
            var state = sessionQueue.enqueue(session);
            switch (state) {
            case bCapServSessionQueue.ENQUEUE_STARTED:
            case bCapServSessionQueue.ENQUEUE_QUEUED:
                captureServer.bayeux.publish("/session/create", {
                    session: session.serialize()
                });
                serializedSessionPromise.resolve(session);
                break;
            case bCapServSessionQueue.ENQUEUE_FAILED:
                serializedSessionPromise.reject("No slaves captured, session not created");
                break;
            }
        }, function (err) {
            serializedSessionPromise.reject(err);
        });

        return serializedSessionPromise;
    }

    function failWithMessage(res, message) {
        res.writeHead(400);
        res.write(message + "\n");
        res.end();
    }

    function captureSlave(req, res) {
        var slave = bCapServSlave.create(captureServer, bayeuxServer, resourcesMiddleware, sessionQueue, req.headers["user-agent"], logger);
        slave.header(headerHeight, headerResourceSet);
        slave.on("ready", function () {
            captureServer.oncapture(req, res, slave);
            sessionQueue.addSlave(slave);
            captureServer.bayeux.publish("/capture", slave.serialize());
        });
    }

    bayeuxServer = bCapServBayeuxServer.create(logger, captureServer.messagingContextPath);

    sessionQueue.prepare = function (e) {
        var deferred = when.defer();
        resourceCache.inflate(e.session.resourceSet).then(function (rs) {
            resourcesMiddleware.mount(e.session.resourcesPath, rs);
            deferred.resolve();
        }, function (err) {
            deferred.reject(err);
        });
        return deferred.promise;
    };

    sessionQueue.on("loaded", function (e) {
        captureServer.bayeux.publish("/session/start", {
            session: e.session.serialize(),
            slaves: e.slaves.map(function (slave) {
                return {userAgent: slave.userAgent, id: slave.id};
            })
        });
    });

    sessionQueue.on("unloaded", function (e) {
        resourcesMiddleware.unmount(e.session.resourcesPath);
        captureServer.bayeux.publish("/session/end", {session: e.session.serialize()});
    });

    return captureServer;
};

exports.createSessionMessenger = function (messagingUrl, session) {
    var bayeux = new faye.Client(messagingUrl);
    var contextPath = session.bayeuxContextPath;

    return {
        publish: function (path, data) {
            return bayeux.publish(contextPath + path, data);
        },

        subscribe: function (path, cb) {
            return bayeux.subscribe(contextPath + path, cb);
        },

        disconnect: function () {
            return bayeux.disconnect();
        }
    };
}<|endoftext|>


<commit_before>#!/usr/bin/env node

var fs = require('fs'),
    program = require('commander'),
    async = require('async'),
    child = require('child_process'),
    cwd = process.cwd(),
    pids = [],
    returnVal = 0;

program.command('test')
    .description('Run unit and functional tests')
    .option('-u, --unit', 'Run unit tests')
    .option('-f, --func', 'Run functional tests')
    .option('-b, --no-build', 'Don\'t build the apps')
    .option('-d, --no-deploy', 'Don\'t deploy the apps')
    .option('-s, --no-selenium', 'Don\'t run arrow_selenium')
    .option('-a, --no-arrow', 'Don\'t run arrow_server')
    .action(test);

program.command('build')
    .description('Build all HTML5 apps')
    .action(build);

program.command('deploy')
    .description('Deploy all apps')
    .action(deploy);

program.parse(process.argv);

function test (cmd) {
    var series = [];
    // Default to all tests
    if (!cmd.unit && !cmd.func) {
        cmd.unit = true;
        cmd.func = true;
    }
    if (cmd.unit) {
        if (cmd.arrow) {
            series.push(startArrowServer);
        }
        series.push(runUnitTests);
    }
    if (cmd.func) {
        if (cmd.build) {
            series.push(function (callback) {
                build(cmd, callback);
            });
        }
        if (cmd.selenium) {
            series.push(startArrowSelenium);
        }
        if (cmd.deploy) {
            series.push(function (callback) {
                deploy(cmd, callback);
            });
        }
        series.push(runFuncTests);
    }
    async.series(series, finalize);
}

function startArrowServer (callback) {
    console.log("---Starting Arrow Server---");
    var p = runCommand(cwd, "arrow_server");
    pids.push(p.pid);
    setTimeout(function () {
        callback(null);
    }, 5000);
}

function runUnitTests (callback) {
    console.log('---Running Unit Tests---');
    var arrowReportDir = cwd + '/arrowreport/unit/';
    runCommand(cwd, "mkdir", [cwd + '/arrowreport/'], function () {
        runCommand(cwd, "mkdir", [arrowReportDir], function () {
            var cmd = runCommand(
                cwd + '/unit',
                "arrow",
                ["\"**/*_descriptor.json\"", "--browser=phantomjs", "--report=true", "--reportFolder=" + arrowReportDir],
                function (code) {
                    callback(code);
                }
            );
            cmd.stdout.on('data', function (data) {
                process.stdout.write(data);
            });
        });
    });
}

function build (cmd, callback) {
    console.log('---Building Apps---');
    runCommand(
        cwd + '/func/applications/frameworkapp/common',
        "mojito",
        ['build', 'html5app', cwd + '/func/applications/frameworkapp/flatfile'],
        callback
    );
}

function deploy (cmd, callback) {
    console.log('---Deploying Apps---');
    var appSeries = [],
        appsConfig = JSON.parse(fs.readFileSync(cwd + '/func/applications/apps.json', 'utf8')),
        apps = appsConfig.applications;

    for (var i=0; i<apps.length; i++) {
        (function () {
            var app = apps[i],
                port = app.port ? parseInt(app.port) : null,
                type = app.type || 'mojito';

            if ('mojito' === type) {
                if (app.tests) {
                    var mytests = app.tests;
                    for(var j=0; j<mytests.length; j++) {
                        (function () {
                            var test = mytests[j],
                                port = test.port ? parseInt(test.port) : null;
                            appSeries.push(function (callback) {
                                runMojitoApp(cwd + '/func/applications', app.path, port, test.param, callback);
                            });
                        })();
                    }
                } else if (app.enabled === "true" && app.path && port) {
                    appSeries.push(function (callback) {
                        runMojitoApp(cwd + '/func/applications', app.path, port, app.param, callback);
                    });
                }
            } else if ('static' === type) {
                appSeries.push(function (callback) {
                    runStaticApp(cwd + '/func/applications', app.path, port, app.param, callback);
                });
            }
        })();
    }
    async.series(appSeries, callback);
}

function startArrowSelenium (callback) {
    console.log("---Starting Arrow Selenium---");
    var p = runCommand(cwd+"/func/applications/frameworkapp/common", "arrow_selenium", ["--open=firefox"]);
    setTimeout(function () {
        pids.push(p.pid);
        callback(null);
    }, 10000);
}

function runFuncTests (callback) {
    console.log('---Running Functional Tests---');
    var arrowReportDir = cwd + '/arrowreport/func/';
    runCommand(cwd, "mkdir", [arrowReportDir], function () {
        var cmd = runCommand(
            cwd + '/func/',
            "arrow",
            ["\"**/*_descriptor.json\"", "--browser=firefox", "--reuseSession", "--report=true", "--reportFolder=" + arrowReportDir],
            function (code) {
                callback(code);
            }
        );
        cmd.stdout.on('data', function (data) {
            process.stdout.write(data);
        });
    });
}

function finalize (err, results) {
    for(var i=0; i < pids.length; i++) {
        console.log('Shutting down pid ' + pids[i]);
        process.kill(pids[i]);
    }
    if (err) {
        console.log(err);
        console.log('FAILED');
        process.exit(1);
        return;
    }
    console.log('Completed');
    process.exit(0);

}

function runCommand (path, command, argv, callback) {
    callback = callback || function () {};
    process.chdir(path);
    var cmd = child.spawn(command, argv, {
        cwd: path,
        env: process.env
    });

    cmd.stdout.on('data', function (data) {
        // Don't care generally. But, specific commands may want a listener for this.
    });

    cmd.stderr.on('data', function (data) {
        process.stdout.write(data);
    });

    cmd.on('exit', function (code) {
        cmd.stdin.end();
        if (0 !== code) {
            callback('exit: child process exited with code ' + code);
        }
        callback(code);
    });

    cmd.on('uncaughtException', function (err) {
        process.stderr.write('uncaught exception: ' + err+'\n');
        callback(1);
    });

    return cmd;
}

function runMojitoApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting ' + path + ' at port ' + port + ' with params ' + (params || 'empty'));
    var p = runCommand(basePath + '/' + path, "mojito", ["start", port, "--context", params], function () {});
    pids.push(p.pid);
    // Give each app a second to start
    setTimeout(function () { callback(null) }, 1000);
}

function runStaticApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting static server for ' + path + ' at port ' + port);
    var p = runCommand(basePath + '/' + path, "node", [cwd + "/base/staticServer.js", port], function () {});
    pids.push(p.pid);
    // Give each app a second to start
    setTimeout(function () { callback(null) }, 1000);
}<commit_msg>Fixed some issues with run.js<commit_after>#!/usr/bin/env node

var fs = require('fs'),
    program = require('commander'),
    async = require('async'),
    child = require('child_process'),
    cwd = __dirname,
    pids = [],
    returnVal = 0;

program.command('test')
    .description('Run unit and functional tests')
    .option('-u, --unit', 'Run unit tests')
    .option('-f, --func', 'Run functional tests')
    .option('-b, --no-build', 'Don\'t build the apps')
    .option('-d, --no-deploy', 'Don\'t deploy the apps')
    .option('-s, --no-selenium', 'Don\'t run arrow_selenium')
    .option('-a, --no-arrow', 'Don\'t run arrow_server')
    .action(test);

program.command('build')
    .description('Build all HTML5 apps')
    .action(build);

program.command('deploy')
    .description('Deploy all apps')
    .action(deploy);

program.parse(process.argv);

function test (cmd) {
    var series = [];
    // Default to all tests
    if (!cmd.unit && !cmd.func) {
        cmd.unit = true;
        cmd.func = true;
    }
    if (cmd.unit) {
        if (cmd.arrow) {
            series.push(startArrowServer);
        }
        series.push(runUnitTests);
    }
    if (cmd.func) {
        if (cmd.build) {
            series.push(function (callback) {
                build(cmd, callback);
            });
        }
        if (cmd.selenium) {
            series.push(startArrowSelenium);
        }
        if (cmd.deploy) {
            series.push(function (callback) {
                deploy(cmd, callback);
            });
        }
        series.push(runFuncTests);
    }
    async.series(series, finalize);
}

function startArrowServer (callback) {
    var timeout,
        listener = function (data) {
            process.stdout.write(data);
        };
    console.log("---Starting Arrow Server---");
    var p = runCommand(cwd, "arrow_server", [], function () {
        // If this command returns called, then it failed to launch
        if (timeout) {
            clearTimeout(timeout);
        }
        console.log('arrow_server failed to start. If it is already running' +
            ' use \'-a\' to skip startup of arrow_server.');
        pids.pop();
        callback(1); // Trigger failure
    });
    p.stdout.on('data', listener);
    pids.push(p.pid);
    timeout = setTimeout(function () {
        p.stdout.removeListener('data', listener); // Stop printing output from arrow_server
        callback(null);
    }, 5000);
}

function runUnitTests (callback) {
    console.log('---Running Unit Tests---');
    var arrowReportDir = cwd + '/arrowreport/unit/';
    runCommand(cwd, "mkdir", [cwd + '/arrowreport/'], function () {
        runCommand(cwd, "mkdir", [arrowReportDir], function () {
            var cmd = runCommand(
                cwd + '/unit',
                "arrow",
                [cwd + "/unit/**/test_descriptor.json", "--browser=phantomjs", "--report=true", "--reportFolder=" + arrowReportDir],
                function (code) {
                    callback(code);
                }
            );
            cmd.stdout.on('data', function (data) {
                process.stdout.write(data);
            });
        });
    });
}

function build (cmd, callback) {
    console.log('---Building Apps---');
    runCommand(
        cwd + '/func/applications/frameworkapp/common',
        "mojito",
        ['build', 'html5app', cwd + '/func/applications/frameworkapp/flatfile'],
        callback
    );
}

function deploy (cmd, callback) {
    console.log('---Deploying Apps---');
    var appSeries = [],
        appsConfig = JSON.parse(fs.readFileSync(cwd + '/func/applications/apps.json', 'utf8')),
        apps = appsConfig.applications;

    for (var i=0; i<apps.length; i++) {
        (function () {
            var app = apps[i],
                port = app.port ? parseInt(app.port) : null,
                type = app.type || 'mojito';

            if ('mojito' === type) {
                if (app.tests) {
                    var mytests = app.tests;
                    for(var j=0; j<mytests.length; j++) {
                        (function () {
                            var test = mytests[j],
                                port = test.port ? parseInt(test.port) : null;
                            appSeries.push(function (callback) {
                                runMojitoApp(cwd + '/func/applications', app.path, port, test.param, callback);
                            });
                        })();
                    }
                } else if (app.enabled === "true" && app.path && port) {
                    appSeries.push(function (callback) {
                        runMojitoApp(cwd + '/func/applications', app.path, port, app.param, callback);
                    });
                }
            } else if ('static' === type) {
                appSeries.push(function (callback) {
                    runStaticApp(cwd + '/func/applications', app.path, port, app.param, callback);
                });
            }
        })();
    }
    async.series(appSeries, callback);
}

function startArrowSelenium (callback) {
    console.log("---Starting Arrow Selenium---");
    var p = runCommand(cwd+"/func/applications/frameworkapp/common", "arrow_selenium", ["--open=firefox"]);
    setTimeout(function () {
        pids.push(p.pid);
        callback(null);
    }, 10000);
}

function runFuncTests (callback) {
    console.log('---Running Functional Tests---');
    var arrowReportDir = cwd + '/arrowreport/func/';
    runCommand(cwd, "mkdir", [arrowReportDir], function () {
        var cmd = runCommand(
            cwd + '/func/',
            "arrow",
            [cwd + "/func/**/test_descriptor.json", "--browser=firefox", "--reuseSession", "--report=true", "--reportFolder=" + arrowReportDir],
            function (code) {
                callback(code);
            }
        );
        cmd.stdout.on('data', function (data) {
            process.stdout.write(data);
        });
    });
}

function finalize (err, results) {
    for(var i=0; i < pids.length; i++) {
        console.log('Shutting down pid ' + pids[i]);
        process.kill(pids[i]);
    }
    if (err) {
        console.log(err);
        console.log('FAILED');
        process.exit(1);
        return;
    }
    console.log('Completed');
    process.exit(0);

}

function runCommand (path, command, argv, callback) {
    callback = callback || function () {};
    console.log(path);
    process.chdir(path);
    var cmd = child.spawn(command, argv, {
        cwd: path,
        env: process.env
    });

    cmd.stdout.on('data', function (data) {
        // Don't care generally. But, specific commands may want a listener for this.
    });

    cmd.stderr.on('data', function (data) {
        process.stdout.write(data);
    });

    cmd.on('exit', function (code) {
        cmd.stdin.end();
        if (0 !== code) {
            callback('exit: child process exited with code ' + code);
        }
        callback(code);
    });

    cmd.on('uncaughtException', function (err) {
        process.stderr.write('uncaught exception: ' + err+'\n');
        callback(1);
    });

    return cmd;
}

function runMojitoApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting ' + path + ' at port ' + port + ' with params ' + (params || 'empty'));
    var p = runCommand(basePath + '/' + path, "mojito", ["start", port, "--context", params], function () {});
    pids.push(p.pid);
    // Give each app a second to start
    setTimeout(function () { callback(null) }, 1000);
}

function runStaticApp (basePath, path, port, params, callback) {
    params = params || '';
    console.log('Starting static server for ' + path + ' at port ' + port);
    var p = runCommand(basePath + '/' + path, "node", [cwd + "/base/staticServer.js", port], function () {});
    pids.push(p.pid);
    // Give each app a second to start
    setTimeout(function () { callback(null) }, 1000);
}<|endoftext|>


<commit_before>define(function(require, exports, module) {
    //requirements
    var Block = require('../block');

    describe('Метод set', function() {

        it('Устанавливает значение через deepextend', function(){

            var block = new Block({
                a: {
                    b: 'b'
                }
            });

            block.set({
                a: {
                    c: 'c'
                }
            });

            expect(block.get('a.b')).toBe('b');
            expect(block.get('a.c')).toBe('c');

        });

        it('Устанавливает значение по указанному пути', function(){

            var block = new Block({
                a: {
                    b: 'b'
                }
            });

            block.set('a.c.d', 'c');

            expect(block.get('a.b')).toBe('b');
            expect(block.get('a.c.d')).toBe('c');

        });

        it('Вызывает событие set', function(){

            var block = new Block(),
                handler = jasmine.createSpy('handler');

            block.on('set', handler);

            block.set('a.c', {d: 'd'});

            expect(handler).toHaveBeenCalledWith({a: {c: {d: 'd'}}});

        });

    });

});<commit_msg>fail again<commit_after>define(function(require, exports, module) {
    //requirements
    var Block = require('../block');

    describe('Метод set', function() {

        it('Устанавливает значение через deepextend', function(){

            var block = new Block({
                a: {
                    b: 'b'
                }
            });

            block.set({
                a: {
                    c: 'cc'
                }
            });

            expect(block.get('a.b')).toBe('b');
            expect(block.get('a.c')).toBe('c');

        });

        it('Устанавливает значение по указанному пути', function(){

            var block = new Block({
                a: {
                    b: 'b'
                }
            });

            block.set('a.c.d', 'c');

            expect(block.get('a.b')).toBe('b');
            expect(block.get('a.c.d')).toBe('c');

        });

        it('Вызывает событие set', function(){

            var block = new Block(),
                handler = jasmine.createSpy('handler');

            block.on('set', handler);

            block.set('a.c', {d: 'd'});

            expect(handler).toHaveBeenCalledWith({a: {c: {d: 'd'}}});

        });

    });

});<|endoftext|>


<commit_before>module.exports = class Router {
  constructor() {
    this._newContent = null;
    this._newContentPromise = Promise.resolve();
    this._viewElement = document.querySelector('section.view-content');
    this._isAnimatingOut = false;
    this._isAnimatingIn = false;
    this._spinnerTimeout = 0;
    this._currentPath = window.location.pathname;

    this._boostrapNavigation();
    this._onChanged();
  }

  _queueSpinner() {
    this._spinnerTimeout = setTimeout(() => {
      document.body.classList.add('view-pending');
    }, 500);
  }

  _hideSpinner() {
    document.body.classList.remove('view-pending');
    clearTimeout(this._spinnerTimeout);
  }

  _onChanged() {
    console.log(`Router::_onChanged(${window.location.pathname})`);
    if (this._currentPath === window.location.pathname) {
      console.log('Bumping request');
      return Promise.resolve();
    }

    this._currentPath = window.location.pathname;

    this._newContentPromise = this._loadAsyncView();

    if (this._isAnimatingOut) {
      console.log(' Either animating out or loading still - sorry');
      return Promise.resolve();
    }

    this._isAnimatingOut = true;
    return this._animateOut().then(() => {
      console.log('Router::_animateOut complete');
      this._isAnimatingOut = false;
      return this._newContentPromise;
    }).then(() => {
      console.log(`Async View Resolved With ${this._newContent.getAttribute('id')}`);
      this._viewElement.innerHTML = this._newContent.innerHTML;
      this._animatingIn = true;
      return this._animateIn();
    }).then(() => {
      console.log('Router::_animateIn complete');
      this._animatingIn = false;
    }).catch(error => {
      console.warn(error);
    });
  }

  _loadAsyncView() {
    console.log(`Router::_loadAsyncView(${this._currentPath})`);

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      xhr.onload = evt => {
        this._newContent = evt.target.response.querySelector('*');
        console.log(this._newContent);
        resolve();
      };

      xhr.onerror = reject;

      xhr.responseType = 'document';
      console.log(`XHR open ${this._currentPath}${this._currentPath.endsWith('/') ? '' : '/'}`);
      xhr.open('GET', `${this._currentPath}${this._currentPath.endsWith('/') ? '' : '/'}`);
      xhr.send();
    });
  }

  _animateIn() {
    console.log('Router::_animateIn()');
    this._hideSpinner();

    return new Promise((resolve, reject) => {
      const onTransitionEnd = () => {
        this._viewElement.removeEventListener('transitionend', onTransitionEnd);
        resolve();
      };

      this._viewElement.classList.add('visible');
      this._viewElement.addEventListener('transitionend', onTransitionEnd);
    });
  }

  _animateOut() {
    console.log(`Router::_animateOut()`);
    if (document.body.classList.contains('view-pending')) {
      console.log('Already pending - not going to anim out');
      return Promise.resolve();
    }
    this._queueSpinner();

    return new Promise((resolve, reject) => {
      const onTransitionEnd = () => {
        this._viewElement.removeEventListener('transitionend', onTransitionEnd);
        resolve();
      };

      this._viewElement.classList.remove('visible');
      this._viewElement.addEventListener('transitionend', onTransitionEnd);

    });
  }

  go(url) {
    window.history.pushState(null, null, url);
    return this._onChanged();
  }

  _boostrapNavigation() {
    window.addEventListener('popstate', this._onChanged.bind(this));
    Array.prototype.forEach.call(document.querySelectorAll('.header .header-content nav li'), link => {
      console.log('Attaching listener');

      // Plain old li click listener
      link.addEventListener('click', evt => {
        this.go(evt.target.firstChild.href);
      });

      /**
       * If the user clicks a link inside a list item
       * that link will be the `.target` of the event
       * passed into the onClick function - however we
       * always want to call onClick with the list item
       * as the event target so we can get its firstChild's
       * href
       */
      link.firstChild.addEventListener('click', evt => {
        evt.preventDefault();
        evt.stopPropagation(); // prevents us from triggering li click again on bubble stage
        link.click();
      });
    });
  }
}
<commit_msg>Partial<commit_after>module.exports = class Router {
  constructor() {
    this._newContent = null;
    this._newContentPromise = Promise.resolve();
    this._viewElement = document.querySelector('section.view-content');
    this._isAnimatingOut = false;
    this._isAnimatingIn = false;
    this._spinnerTimeout = 0;
    this._currentPath = window.location.pathname;

    this._boostrapNavigation();
    this._onChanged();
  }

  _queueSpinner() {
    this._spinnerTimeout = setTimeout(() => {
      document.body.classList.add('view-pending');
    }, 500);
  }

  _hideSpinner() {
    document.body.classList.remove('view-pending');
    clearTimeout(this._spinnerTimeout);
  }

  _onChanged() {
    console.log(`Router::_onChanged(${window.location.pathname})`);
    if (this._currentPath === window.location.pathname) {
      console.log('Bumping request');
      return Promise.resolve();
    }

    this._currentPath = window.location.pathname;

    this._newContentPromise = this._loadAsyncView();

    if (this._isAnimatingOut) {
      console.log(' Either animating out or loading still - sorry');
      return Promise.resolve();
    }

    this._isAnimatingOut = true;
    return this._animateOut().then(() => {
      console.log('Router::_animateOut complete');
      this._isAnimatingOut = false;
      return this._newContentPromise;
    }).then(() => {
      console.log(`Async View Resolved With ${this._newContent.getAttribute('id')}`);
      this._viewElement.innerHTML = this._newContent.innerHTML;
      this._animatingIn = true;
      return this._animateIn();
    }).then(() => {
      console.log('Router::_animateIn complete');
      this._animatingIn = false;
    }).catch(error => {
      console.warn(error);
    });
  }

  _loadAsyncView() {
    console.log(`Router::_loadAsyncView(${this._currentPath})`);

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      xhr.onload = evt => {
        this._newContent = evt.target.response.querySelector('div[view]');
        console.log(this._newContent);
        resolve();
      };

      xhr.onerror = reject;

      xhr.responseType = 'document';
      console.log(`XHR open ${this._currentPath}${this._currentPath.endsWith('/') ? '' : '/'}?partial`);
      xhr.open('GET', `${this._currentPath}${this._currentPath.endsWith('/') ? '' : '/'}?partial`);
      xhr.send();
    });
  }

  _animateIn() {
    console.log('Router::_animateIn()');
    this._hideSpinner();

    return new Promise((resolve, reject) => {
      const onTransitionEnd = () => {
        this._viewElement.removeEventListener('transitionend', onTransitionEnd);
        resolve();
      };

      this._viewElement.classList.add('visible');
      this._viewElement.addEventListener('transitionend', onTransitionEnd);
    });
  }

  _animateOut() {
    console.log(`Router::_animateOut()`);
    if (document.body.classList.contains('view-pending')) {
      console.log('Already pending - not going to anim out');
      return Promise.resolve();
    }
    this._queueSpinner();

    return new Promise((resolve, reject) => {
      const onTransitionEnd = () => {
        this._viewElement.removeEventListener('transitionend', onTransitionEnd);
        resolve();
      };

      this._viewElement.classList.remove('visible');
      this._viewElement.addEventListener('transitionend', onTransitionEnd);

    });
  }

  go(url) {
    window.history.pushState(null, null, url);
    return this._onChanged();
  }

  _boostrapNavigation() {
    window.addEventListener('popstate', this._onChanged.bind(this));
    Array.prototype.forEach.call(document.querySelectorAll('.header .header-content nav li'), link => {
      console.log('Attaching listener');

      // Plain old li click listener
      link.addEventListener('click', evt => {
        this.go(evt.target.firstChild.href);
      });

      /**
       * If the user clicks a link inside a list item
       * that link will be the `.target` of the event
       * passed into the onClick function - however we
       * always want to call onClick with the list item
       * as the event target so we can get its firstChild's
       * href
       */
      link.firstChild.addEventListener('click', evt => {
        evt.preventDefault();
        evt.stopPropagation(); // prevents us from triggering li click again on bubble stage
        link.click();
      });
    });
  }
}
<|endoftext|>


<commit_before>var log = require('logule').init(module, 'temp');
var HumixSense = require('node-humix-sense')

var child = require('child_process');
var proc;

var config = {
    "moduleName":"dht22",
    "commands" : [],
    "events" : ["temp","humid"],
    "debug": true
}

var humix = new HumixSense(config);

var humixSensor;

humix.on('connection', function(humixSensorModule){
    humixSensor = humixSensorModule;

    console.log('Communication with humix-sense is now ready. hsm:'+humixSensor);
});

function getSensorData(){

    proc = child.exec("sudo ./controls/humix-sense-temp/loldht 7", function(err,data){

        if(err){

            log.error("Error:"+err.toString());
        }

        var str = data.toString(), lines = str.split(/(\r?\n)/g);
        for (var i=0; i<lines.length; i++) {

            if(lines[i].indexOf("Humidity") != -1){

                log.info('Parsed Data: '+ lines[i]);

                var s = lines[i];
                var hindex = s.indexOf('=');
                var pindex = s.indexOf('%');
                var humid_str = s.substring(hindex+1,pindex).trim();
                log.info("humid:"+humid_str);

                s = s.substring(pindex);

                hindex = s.indexOf('=');
                pindex = s.indexOf('*');

                var temp_str = s.substring(hindex+1,pindex).trim();
                log.info("temp:"+temp_str);

                var temp_data = {

                           "temp" : parseInt(temp_str)
                };

                var humid_data = {
                        "humid" : parseInt(humid_str)
                };

                log.info("Temperature:"+JSON.stringify(temp_data));
                log.info("Humidity:"+JSON.stringify(humid_data));
                humixSensor.event('temp',JSON.stringify(temp_data));
                humixSensor.event('humid',JSON.stringify(humid_data));

            }
        }
    });

}

setInterval(function(){
    getSensorData();

},5000);
<commit_msg>change exec path<commit_after>var log = require('logule').init(module, 'temp');
var HumixSense = require('node-humix-sense')

var child = require('child_process');
var proc;

var config = {
    "moduleName":"dht22",
    "commands" : [],
    "events" : ["temp","humid"],
    "debug": true
}

var humix = new HumixSense(config);

var humixSensor;

humix.on('connection', function(humixSensorModule){
    humixSensor = humixSensorModule;

    console.log('Communication with humix-sense is now ready. hsm:'+humixSensor);
});

function getSensorData(){

    proc = child.exec("sudo ./loldht 7", function(err,data){

        if(err){

            log.error("Error:"+err.toString());
        }

        var str = data.toString(), lines = str.split(/(\r?\n)/g);
        for (var i=0; i<lines.length; i++) {

            if(lines[i].indexOf("Humidity") != -1){

                log.info('Parsed Data: '+ lines[i]);

                var s = lines[i];
                var hindex = s.indexOf('=');
                var pindex = s.indexOf('%');
                var humid_str = s.substring(hindex+1,pindex).trim();
                log.info("humid:"+humid_str);

                s = s.substring(pindex);

                hindex = s.indexOf('=');
                pindex = s.indexOf('*');

                var temp_str = s.substring(hindex+1,pindex).trim();
                log.info("temp:"+temp_str);

                var temp_data = {

                           "temp" : parseInt(temp_str)
                };

                var humid_data = {
                        "humid" : parseInt(humid_str)
                };

                log.info("Temperature:"+JSON.stringify(temp_data));
                log.info("Humidity:"+JSON.stringify(humid_data));
                humixSensor.event('temp',JSON.stringify(temp_data));
                humixSensor.event('humid',JSON.stringify(humid_data));

            }
        }
    });

}

setInterval(function(){
    getSensorData();

},5000);
<|endoftext|>


<commit_before>var audio = require('./audio');
var inherits = require('util').inherits;
var Readable = require('stream').Readable;
var debug = require('debug')('osxaudio:input');

var MAX_BUFFERS = 16;

var input = null;

function Input(opts) {
  if (!(this instanceof Input)) {
    return new Input(opts);
  }
  Readable.call(this, opts);

  if (!opts) opts = {};

  this._audioBuffers = [];

  if (!input) {
    input = new audio.input();
  }

  input.on('message', this._audioCallback.bind(this));

  if (!input.isOpen()) {
    debug('opening input');
    input.openInput();
  }

  debug("instantiated.");

  return this;
}
inherits(Input, Readable);

Input.prototype._audioCallback = function(size, message) {
  if (this._audioBuffers.push(message) > MAX_BUFFERS) {
    debug('exceeded MAX_BUFFERS, shifting older buffers');
    this._audioBuffers.splice(0, this._audioBuffers.length - MAX_BUFFERS);
  }
  this.read(0);
};

Input.prototype._read = function(n) {
  debug("_read()");
  var chunk = this._audioBuffers.pop();
  if (typeof chunk !== 'undefined') {
    debug("_read() pushing data");
    this.push(chunk);
  }
  else {
    if (input.isOpen()) {
      debug("_read() pushing blank string");
      this.push('');
    }
    else {
      debug("_read() input is closed. push null");
      this.push(null);
    }
  }
};

Input.prototype.openInput = function() {
  if(!input) {
    input = new audio.input();
  }

  if (!input.isOpen()) {
    input.openInput();
  }
};

Input.prototype.closeInput = function() {
  if (input.isOpen()) {
    debug("closeInput() input was open, shutting down");
    input.closeInput();
  }
};

module.exports = Input;
<commit_msg>refactors input stream<commit_after>var audio = require('./audio');
var inherits = require('util').inherits;
var Readable = require('stream').Readable;
var debug = require('debug')('osxaudio:input');

var MAX_BUFFERS = 16;

var input = null;
var readers = [];

function Input(opts) {
  if (!(this instanceof Input)) {
    return new Input(opts);
  }
  Readable.call(this, opts);

  if (!opts) opts = {};

  this._audioBuffers = [];
  this.reading = false;

  debug("instantiated.");

  return this;
}
inherits(Input, Readable);

Input.prototype._audioCallback = function(size, message) {
  if(this.reading) {
    this.push(message);
    this.read(0);
  }
};

Input.prototype._read = function(n) {
  if (!this.reading) {
    debug('_read() opening input');
    this.openInput();
  }
};

Input.prototype.openInput = function() {
  if(!input) {
    input = new audio.input();
  }

  if (!input.isOpen()) {
    input.openInput();
  }

  input.on('message', this._audioCallback.bind(this));

  // add ourselves to the readers index
  readers.push(this);
  this.reading = true;
};

Input.prototype.closeInput = function() {
  // remove ourself from the readers index
  var index = readers.indexOf(this);
  if (index > -1) {
    readers.splice(index, 1);
  }

  // if we were the last reader, kill the input
  if (readers.length === 0 && input.isOpen()) {
    debug("closeInput() last reader closed, shutting down");
    input.closeInput();
  }

  input.removeListener('message', this._audioCallback.bind(this));

  // close the stream
  this.push(null);
  this.reading = false;
};

module.exports = Input;
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(fix): 2017-6-14 09:35:00<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>var ReactiveModel = require("./index");
var assert = require("assert");

function increment(x){
  return x + 1;
}

function add(a, b){
  return a + b;
}

describe("ReactiveModel", function (){

  it("Should add a public property and get its value.", function (){
    var model = ReactiveModel();
    model.addPublicProperty("x", 5);
    assert.equal(model.x(), 5);
  });

  it("Should add a public property and set its value.", function (){
    var model = ReactiveModel();
    model.addPublicProperty("x", 5);
    model.x(10);
    assert.equal(model.x(), 10);
  });

  it("Should support chaining when setting multiple properties.", function (){
    var model = ReactiveModel();
    model.addPublicProperty("x", 5);
    model.addPublicProperty("y", 6);

    model
      .x(10)
      .y(20);

    assert.equal(model.x(), 10);
    assert.equal(model.y(), 20);
  });

  it("Should chain addPublicProperty.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
    assert.equal(model.x(), 5);
  });

  it("Should get state.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10)
      .x(10)
      .y(20);

    ReactiveModel.digest();

    var state = model.state();
    assert.equal(Object.keys(state).length, 2);
    assert.equal(state.x, 10);
    assert.equal(state.y, 20);
  });

  it("Should get state and omit default values.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10);

    ReactiveModel.digest();

    var state = model.state();
    assert.equal(Object.keys(state).length, 0);
  });

  it("Should set state.", function (){

    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10);

    model.state({
      x: 20,
      y: 50
    });

    assert.equal(model.x(), 20);
    assert.equal(model.y(), 50);

  });

  it("Should chain setState.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10)
      .state({ x: 20, y: 50 });
    assert.equal(model.x(), 20);
    assert.equal(model.y(), 50);
  });

  it("Should set state with default values for omitted properties.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10)
      .x(20)
      .y(50);

    assert.equal(model.x(), 20);
    assert.equal(model.y(), 50);

    model.state({});

    assert.equal(model.x(), 5);
    assert.equal(model.y(), 10);
  });

  it("Should set state with default values and new values.", function (){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10)
      .x(20)
      .y(50);

    assert.equal(model.x(), 20);
    assert.equal(model.y(), 50);

    model.state({ x: 30 });

    assert.equal(model.x(), 30);
    assert.equal(model.y(), 10);
  });

  it("Should listen for changes in state, getting default empty state.", function (done){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10);

    model.state.on(function (newState){
      assert.equal(Object.keys(newState).length, 0);
      done();
    });
  });

  it("Should listen for changes in state, getting state after one change.", function (done){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10);

    model.state.on(function (newState){
      assert.equal(Object.keys(newState).length, 1);
      assert.equal(newState.x, 15);
      done();
    });

    model.x(15);
  });

  it("Should listen for changes in state, getting state after two changes.", function (done){
    var model = ReactiveModel()
      .addPublicProperty("x", 5)
      .addPublicProperty("y", 10);

    model.state.on(function (newState){
      assert.equal(Object.keys(newState).length, 2);
      assert.equal(newState.x, 15);
      assert.equal(newState.y, 45);
      done();
    });

    model.x(15).y(45);
  });

  it("Should throw an error when attempting to add a public property after state has been accessed.", function (){
    var model = ReactiveModel();
    model.addPublicProperty("x", 5);
    model.state();
    assert.throws(model.addPublicProperty, Error);
  });

  it("Should throw an error when attempting to add a public property after state has been set.", function (){
    var model = ReactiveModel();
    model.addPublicProperty("x", 5);
    model.state({ x: 20});
    assert.throws(model.addPublicProperty, Error);
  });

  it("Should react.", function (){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a){
        return a + 1;
      }, "a"]
    });

    ReactiveModel.digest();

    assert.equal(model.b(), 6);
  });

  it("Should react and use newly set value.", function (){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a){
        return a + 1;
      }, "a"]
    });

    model.a(10);

    ReactiveModel.digest();

    assert.equal(model.b(), 11);
  });

  it("Should react with two public input properties.", function (){
    var model = ReactiveModel()
      .addPublicProperty("firstName", "Jane")
      .addPublicProperty("lastName", "Smith");

    model({
      fullName: [function (firstName, lastName){
        return firstName + " " + lastName;
      }, "firstName, lastName"]
    });

    ReactiveModel.digest();

    assert.equal(model.fullName(), "Jane Smith");

  });

  it("should propagate two hops in a single digest", function (){

    var model = ReactiveModel()
      .addPublicProperty("a", 0);

    model({
      b: [increment, "a"],
      c: [increment, "b"]
    });

    model.a(1);
    ReactiveModel.digest();

    assert.equal(model.a(), 1);
    assert.equal(model.b(), 2);
    assert.equal(model.c(), 3);
  });

  it("Should evaluate tricky case.", function (){

    var model = ReactiveModel()
      .addPublicProperty("a", 1)
      .addPublicProperty("c", 2);

    // a - b
    //       \
    //        e
    //       /
    // c - d

    model({
      b: [increment, "a"],
      d: [increment, "c"],
      e: [add, "b, d"]
    });

    ReactiveModel.digest();

    assert.equal(model.e(), (1 + 1) + (2 + 1));
  });

  it("Should auto-digest.", function (done){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a){
        return a + 1;
      }, "a"]
    });

    setTimeout(function(){
      assert.equal(model.b(), 6);
      model.a(10);
      assert.equal(model.b(), 6);
      setTimeout(function(){
        assert.equal(model.b(), 11);
        done();
      });
    });
  });

  it("should work with booleans", function (){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a){
        return !a;
      }, "a"]
    });

    model.a(false);
    ReactiveModel.digest();
    assert.equal(model.b(), true);

    model.a(true);
    ReactiveModel.digest();
    assert.equal(model.b(), false);
  });

  it("Should work with asynchronous case.", function (testDone){
    var model = new ReactiveModel()
      .addPublicProperty("a", 5);

    model({

      // Similarly to mocha, if an extra "done" argument is on the function,
      // it is treated as an asynchronous function. The "done" callback should
      // be invoked asynchronously with the new value for the output property.
      b: [function (a, done){
        setTimeout(function (){
          done(a + 1);
        }, 20);
      }, "a"],
      c: [function (b){
        assert.equal(b, 2);
        testDone();
      }, "b"]
    });

    model.a(1);
  });

  it("Should work with asynchronous case that is not actually asynchronous.", function (testDone){
    var model = new ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a, done){

        // The "done" callback is being invoked synchronously.
        // This kind of code should not be written, but just in case people do it by accident,
        // the library is set up to have the expected behavior.
        done(a + 1);

      }, "a"],
      c: [function (b){
        assert.equal(b, 2);
        testDone();
      }, "b"]
    });

    model.a(1);
  });
  // TODO should throw an error if done() is called more than once.

  it("Should remove synchronous reactive function on destroy.", function (){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a){
        return a + 1;
      }, "a"]
    });

    model.a(10);
    ReactiveModel.digest();
    assert.equal(model.b(), 11);

    model.destroy();
    model.a(20);
    ReactiveModel.digest();
    assert.equal(model.b(), 11);

  });

  it("Should remove asynchronous reactive function on destroy.", function (done){
    var model = ReactiveModel()
      .addPublicProperty("a", 5);

    model({
      b: [function (a, done){
        setTimeout(function(){
          done(a + 1);
        }, 5);
      }, "a"]
    });

    model.a(10);
    ReactiveModel.digest();
    setTimeout(function(){
      assert.equal(model.b(), 11);
      model.destroy();
      model.a(20);

      setTimeout(function(){
        assert.equal(model.b(), 11);
        done();
      }, 10);

      assert.equal(model.b(), 11);
    }, 10);

  });
  // TODO more aggressive destroy - remove properties from graph & remove their listeners
  // TODO dependencies that are not defined as public properties or outputs.
  // TODO bind
  //
  // TODO move TODOs to GitHub Issues
});
<commit_msg>Add sections to tests<commit_after>var ReactiveModel = require("./index");
var assert = require("assert");

function increment(x){
  return x + 1;
}

function add(a, b){
  return a + b;
}

describe("ReactiveModel", function (){

  describe("Adding public properties", function (){

    it("Should add a public property and get its value.", function (){
      var model = ReactiveModel();
      model.addPublicProperty("x", 5);
      assert.equal(model.x(), 5);
    });

    it("Should add a public property and set its value.", function (){
      var model = ReactiveModel();
      model.addPublicProperty("x", 5);
      model.x(10);
      assert.equal(model.x(), 10);
    });

    it("Should support chaining when setting multiple properties.", function (){
      var model = ReactiveModel();
      model.addPublicProperty("x", 5);
      model.addPublicProperty("y", 6);

      model
        .x(10)
        .y(20);

      assert.equal(model.x(), 10);
      assert.equal(model.y(), 20);
    });

    it("Should chain addPublicProperty.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
      assert.equal(model.x(), 5);
    });
  });

  describe("Accessing state", function (){

    it("Should get state.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10)
        .x(10)
        .y(20);

      ReactiveModel.digest();

      var state = model.state();
      assert.equal(Object.keys(state).length, 2);
      assert.equal(state.x, 10);
      assert.equal(state.y, 20);
    });

    it("Should get state and omit default values.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10);

      ReactiveModel.digest();

      var state = model.state();
      assert.equal(Object.keys(state).length, 0);
    });

    it("Should set state.", function (){

      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10);

      model.state({
        x: 20,
        y: 50
      });

      assert.equal(model.x(), 20);
      assert.equal(model.y(), 50);

    });

    it("Should chain setState.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10)
        .state({ x: 20, y: 50 });
      assert.equal(model.x(), 20);
      assert.equal(model.y(), 50);
    });

    it("Should set state with default values for omitted properties.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10)
        .x(20)
        .y(50);

      assert.equal(model.x(), 20);
      assert.equal(model.y(), 50);

      model.state({});

      assert.equal(model.x(), 5);
      assert.equal(model.y(), 10);
    });

    it("Should set state with default values and new values.", function (){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10)
        .x(20)
        .y(50);

      assert.equal(model.x(), 20);
      assert.equal(model.y(), 50);

      model.state({ x: 30 });

      assert.equal(model.x(), 30);
      assert.equal(model.y(), 10);
    });

    it("Should listen for changes in state, getting default empty state.", function (done){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10);

      model.state.on(function (newState){
        assert.equal(Object.keys(newState).length, 0);
        done();
      });
    });

    it("Should listen for changes in state, getting state after one change.", function (done){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10);

      model.state.on(function (newState){
        assert.equal(Object.keys(newState).length, 1);
        assert.equal(newState.x, 15);
        done();
      });

      model.x(15);
    });

    it("Should listen for changes in state, getting state after two changes.", function (done){
      var model = ReactiveModel()
        .addPublicProperty("x", 5)
        .addPublicProperty("y", 10);

      model.state.on(function (newState){
        assert.equal(Object.keys(newState).length, 2);
        assert.equal(newState.x, 15);
        assert.equal(newState.y, 45);
        done();
      });

      model.x(15).y(45);
    });

    it("Should throw an error when attempting to add a public property after state has been accessed.", function (){
      var model = ReactiveModel();
      model.addPublicProperty("x", 5);
      model.state();
      assert.throws(model.addPublicProperty, Error);
    });

    it("Should throw an error when attempting to add a public property after state has been set.", function (){
      var model = ReactiveModel();
      model.addPublicProperty("x", 5);
      model.state({ x: 20});
      assert.throws(model.addPublicProperty, Error);
    });
  });

  describe("Reactive functions", function (){

    it("Should react.", function (){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a){
          return a + 1;
        }, "a"]
      });

      ReactiveModel.digest();

      assert.equal(model.b(), 6);
    });

    it("Should react and use newly set value.", function (){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a){
          return a + 1;
        }, "a"]
      });

      model.a(10);

      ReactiveModel.digest();

      assert.equal(model.b(), 11);
    });

    it("Should react with two public input properties.", function (){
      var model = ReactiveModel()
        .addPublicProperty("firstName", "Jane")
        .addPublicProperty("lastName", "Smith");

      model({
        fullName: [function (firstName, lastName){
          return firstName + " " + lastName;
        }, "firstName, lastName"]
      });

      ReactiveModel.digest();

      assert.equal(model.fullName(), "Jane Smith");

    });

    it("should propagate two hops in a single digest", function (){

      var model = ReactiveModel()
        .addPublicProperty("a", 0);

      model({
        b: [increment, "a"],
        c: [increment, "b"]
      });

      model.a(1);
      ReactiveModel.digest();

      assert.equal(model.a(), 1);
      assert.equal(model.b(), 2);
      assert.equal(model.c(), 3);
    });

    it("Should evaluate tricky case.", function (){

      var model = ReactiveModel()
        .addPublicProperty("a", 1)
        .addPublicProperty("c", 2);

      // a - b
      //       \
      //        e
      //       /
      // c - d

      model({
        b: [increment, "a"],
        d: [increment, "c"],
        e: [add, "b, d"]
      });

      ReactiveModel.digest();

      assert.equal(model.e(), (1 + 1) + (2 + 1));
    });

    it("Should auto-digest.", function (done){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a){
          return a + 1;
        }, "a"]
      });

      setTimeout(function(){
        assert.equal(model.b(), 6);
        model.a(10);
        assert.equal(model.b(), 6);
        setTimeout(function(){
          assert.equal(model.b(), 11);
          done();
        });
      });
    });

    it("should work with booleans", function (){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a){
          return !a;
        }, "a"]
      });

      model.a(false);
      ReactiveModel.digest();
      assert.equal(model.b(), true);

      model.a(true);
      ReactiveModel.digest();
      assert.equal(model.b(), false);
    });

    it("Should work with asynchronous case.", function (testDone){
      var model = new ReactiveModel()
        .addPublicProperty("a", 5);

      model({

        // Similarly to mocha, if an extra "done" argument is on the function,
        // it is treated as an asynchronous function. The "done" callback should
        // be invoked asynchronously with the new value for the output property.
        b: [function (a, done){
          setTimeout(function (){
            done(a + 1);
          }, 20);
        }, "a"],
        c: [function (b){
          assert.equal(b, 2);
          testDone();
        }, "b"]
      });

      model.a(1);
    });

    it("Should work with asynchronous case that is not actually asynchronous.", function (testDone){
      var model = new ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a, done){

          // The "done" callback is being invoked synchronously.
          // This kind of code should not be written, but just in case people do it by accident,
          // the library is set up to have the expected behavior.
          done(a + 1);

        }, "a"],
        c: [function (b){
          assert.equal(b, 2);
          testDone();
        }, "b"]
      });

      model.a(1);
    });
    // TODO should throw an error if done() is called more than once.

    it("Should remove synchronous reactive function on destroy.", function (){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a){
          return a + 1;
        }, "a"]
      });

      model.a(10);
      ReactiveModel.digest();
      assert.equal(model.b(), 11);

      model.destroy();
      model.a(20);
      ReactiveModel.digest();
      assert.equal(model.b(), 11);

    });

    it("Should remove asynchronous reactive function on destroy.", function (done){
      var model = ReactiveModel()
        .addPublicProperty("a", 5);

      model({
        b: [function (a, done){
          setTimeout(function(){
            done(a + 1);
          }, 5);
        }, "a"]
      });

      model.a(10);
      ReactiveModel.digest();
      setTimeout(function(){
        assert.equal(model.b(), 11);
        model.destroy();
        model.a(20);

        setTimeout(function(){
          assert.equal(model.b(), 11);
          done();
        }, 10);

        assert.equal(model.b(), 11);
      }, 10);

    });
  });
    // TODO more aggressive destroy - remove properties from graph & remove their listeners
    // TODO dependencies that are not defined as public properties or outputs.
    // TODO bind
    //
    // TODO move TODOs to GitHub Issues
});
<|endoftext|>


<commit_before>'use strict';

var test = require('ava');
var viewport = require('./');

test('return viewports', function (t) {
	t.plan(2);

	viewport(['iphone 4', 'iphone 5'], function (err, res) {
		t.assert(!err);
		t.assert(res.length === 5);
	});
});

test('return all viewports', function (t) {
	t.plan(2);

	viewport(function (err, res) {
		t.assert(!err);
		t.assert(res.length > 50);
	});
});
<commit_msg>Add CLI test<commit_after>'use strict';

var spawn = require('child_process').spawn;
var test = require('ava');
var viewport = require('./');

test('return viewports', function (t) {
	t.plan(2);

	viewport(['iphone 4', 'iphone 5'], function (err, res) {
		t.assert(!err);
		t.assert(res.length === 5);
	});
});

test('return all viewports', function (t) {
	t.plan(2);

	viewport(function (err, res) {
		t.assert(!err);
		t.assert(res.length > 50);
	});
});

test('return viewports using the CLI', function (t) {
	t.plan(2);

	var cp = spawn(__dirname + '/cli.js');

	cp.stdout.setEncoding('utf8');
	cp.stdout.on('data', function (data) {
		t.assert(data);
		t.assert(data.indexOf('iphone 4,ios,5.1.1,320x480,2010-06') !== -1);
	});

	cp.stdin.end('iphone4');
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-6-13 20:47:54<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(fix): 2017-7-6 08:09:55<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>
/**
 * juice
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

module.exports = exports = juice;

/**
 * Module dependencies.
 */

var utils = require('./utils')
  , Selector = require('./selector')
  , Property = require('./property')

/**
 * Package version
 */

exports.version = '0.0.6';

/**
 * Export Selector.
 */

exports.Selector = Selector;

/**
 * Export Property.
 */

exports.Property = Property;

/**
 * Export utils.
 */

exports.utils = require('./utils');

/**
 * Ignored pseudo-selectors.
 *
 */

exports.ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link'];

/**
 * Inlines the CSS specified by `css` into the `html`
 *
 * @param {String} html
 * @param {String} css
 * @api public
 */

var styleSelector = new Selector('<style attribute>', [1, 0, 0, 0])
  , importantSelector = new Selector('<!important>', [2, 0, 0, 0])

function juice (html, css, options) {
  var rules = utils.parseCSS(css)
    , document = utils.jsdom(html)
    , editedElements = []
    , options = options || {}

  rules.forEach(function (rule) {
    var sel = rule[0]
      , style = rule[1]
      , selector = new Selector(sel)

    if (selector.parsed().some(function (sel) {
      return sel.pseudos && sel.pseudos.some(function (pseudo) {
        return ~exports.ignoredPseudos.indexOf(pseudo.key);
      });
    })) return;

    utils.toArray(document.querySelectorAll(sel)).forEach(function (el) {
      if (!el.styleProps) {
        el.styleProps = {}

        // if the element has inline styles, fake selector with topmost specificity
        if (el.getAttribute('style')) {
          var cssText = '* { ' + el.getAttribute('style') + ' } '
          addProps(utils.parseCSS(cssText)[0][1], styleSelector);
        }

        // store reference to an element we need to compile style="" attr for
        editedElements.push(el);
      }

      // go through the properties
      function addProps (style, selector) {
        for (var i = 0, l = style.length; i < l; i++) {
          var name = style[i]
            , value = style[name]
            , sel = style._importants[name] ? importantSelector : selector
            , prop = new Property(name, value, sel)
            , existing = el.styleProps[name]

          if (existing) {
            var winner = existing.compare(prop)
              , loser = prop == winner ? existing : prop

            if (winner == prop) el.styleProps[name] = prop;
          } else {
            el.styleProps[name] = prop;
          }
        }
      }

      addProps(style, selector);
    });
  });

  // set `style` attributes
  editedElements.forEach(function (el) {
    var style = '';
    for (var i in el.styleProps)
      style += el.styleProps[i].toString();
    el.setAttribute('style', style);
  });

  var inner = document.innerHTML;

  // free the associated memory
  // with lazily created parentWindow
  document.parentWindow.close();

  return inner;
}
<commit_msg>DRY version number<commit_after>
/**
 * juice
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

module.exports = exports = juice;

/**
 * Module dependencies.
 */

var utils = require('./utils')
  , Selector = require('./selector')
  , Property = require('./property')
  , packageJson = require('../package')

/**
 * Package version
 */

exports.version = packageJson.version;

/**
 * Export Selector.
 */

exports.Selector = Selector;

/**
 * Export Property.
 */

exports.Property = Property;

/**
 * Export utils.
 */

exports.utils = require('./utils');

/**
 * Ignored pseudo-selectors.
 *
 */

exports.ignoredPseudos = ['hover', 'active', 'focus', 'visited', 'link'];

/**
 * Inlines the CSS specified by `css` into the `html`
 *
 * @param {String} html
 * @param {String} css
 * @api public
 */

var styleSelector = new Selector('<style attribute>', [1, 0, 0, 0])
  , importantSelector = new Selector('<!important>', [2, 0, 0, 0])

function juice (html, css, options) {
  var rules = utils.parseCSS(css)
    , document = utils.jsdom(html)
    , editedElements = []
    , options = options || {}

  rules.forEach(function (rule) {
    var sel = rule[0]
      , style = rule[1]
      , selector = new Selector(sel)

    if (selector.parsed().some(function (sel) {
      return sel.pseudos && sel.pseudos.some(function (pseudo) {
        return ~exports.ignoredPseudos.indexOf(pseudo.key);
      });
    })) return;

    utils.toArray(document.querySelectorAll(sel)).forEach(function (el) {
      if (!el.styleProps) {
        el.styleProps = {}

        // if the element has inline styles, fake selector with topmost specificity
        if (el.getAttribute('style')) {
          var cssText = '* { ' + el.getAttribute('style') + ' } '
          addProps(utils.parseCSS(cssText)[0][1], styleSelector);
        }

        // store reference to an element we need to compile style="" attr for
        editedElements.push(el);
      }

      // go through the properties
      function addProps (style, selector) {
        for (var i = 0, l = style.length; i < l; i++) {
          var name = style[i]
            , value = style[name]
            , sel = style._importants[name] ? importantSelector : selector
            , prop = new Property(name, value, sel)
            , existing = el.styleProps[name]

          if (existing) {
            var winner = existing.compare(prop)
              , loser = prop == winner ? existing : prop

            if (winner == prop) el.styleProps[name] = prop;
          } else {
            el.styleProps[name] = prop;
          }
        }
      }

      addProps(style, selector);
    });
  });

  // set `style` attributes
  editedElements.forEach(function (el) {
    var style = '';
    for (var i in el.styleProps)
      style += el.styleProps[i].toString();
    el.setAttribute('style', style);
  });

  var inner = document.innerHTML;

  // free the associated memory
  // with lazily created parentWindow
  document.parentWindow.close();

  return inner;
}
<|endoftext|>


<commit_before>'use strict';

var assert = require('assert'),
    gutil = require('gulp-util'),
    typograf = require('./');

it('should prepare text', function (cb) {
    var input = '   Hello world!!   ',
        output = 'Hello world!';

    var stream = typograf({lang: 'ru'});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});

it('should prepare text with disabled rule "common/punctuation/exclamation"', function (cb) {
    var input = '   Hello world!!   ',
        output = 'Hello world!';

    var stream = typograf({lang: 'ru', disable: ['common/punctuation/exclamation']});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});

it('should prepare text with enabled rule "ru/money/ruble"', function (cb) {
    var input = '   1 руб.   ',
        output = '1\u00A0₽';

    var stream = typograf({lang: 'ru', enable: ['ru/money/ruble']});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});
<commit_msg>Fix test<commit_after>'use strict';

var assert = require('assert'),
    gutil = require('gulp-util'),
    typograf = require('./');

it('should prepare text', function (cb) {
    var input = '   Hello world!!   ',
        output = 'Hello world!';

    var stream = typograf({lang: 'ru'});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});

it('should prepare text with disabled rule "common/punctuation/exclamation"', function (cb) {
    var input = '   Hello world!!   ',
        output = 'Hello world!!';

    var stream = typograf({lang: 'ru', disable: ['common/punctuation/exclamation']});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});

it('should prepare text with enabled rule "ru/money/ruble"', function (cb) {
    var input = '   1 руб.   ',
        output = '1\u00A0₽';

    var stream = typograf({lang: 'ru', enable: ['ru/money/ruble']});
    stream.on('data', function(data) {
        assert.equal(data.contents.toString(), output);
        cb();
    });

    stream.write(new gutil.File({
        contents: new Buffer(input)
    }));
});
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-17 08:50:27<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>var React = require('react/addons');
var PureRenderMixin = React.addons.PureRenderMixin;
var cx = require('classnames');

var KEY_CODES = {
  'return': 13,
  'bspace': 8,
  'delete': 46,
  'cmd':    91,
  'cmd2':   92
};
var PLACEHOLDER = 'Type caption for image';

var { string, bool } = React.PropTypes;

var FigCaption = React.createClass({
  mixins: [PureRenderMixin],

  propTypes: {
    text: string
  },

  getDefaultProps() {
    return {
      text: ''
    };
  },

  getInitialState() {
    return {
      empty: this.props.text.length === 0
    };
  },

  // focus on the text when we click in
  handleClick() {
    if (this.state.empty) {
      setTimeout(this._selectTextNode, 0);
    }
  },

  // set our selection at the beginning of the node
  _selectTextNode() {
    var textNode = React.findDOMNode(this.refs.caption);
    var selection = document.getSelection();
    var range = document.createRange();
    range.setStart(textNode.firstChild, 0);
    range.setEnd(textNode.firstChild, 0);
    selection.removeAllRanges();
    selection.addRange(range);
  },

  // clear out placeholder once typing starts
  handleKeyDown(e) {
    this._setNonEmptyWhenTyping(e);
    this._preventDeletionOutsideCaption(e);
  },

  _setNonEmptyWhenTyping(e) {
    if (e.keyCode > KEY_CODES.delete &&
        e.keyCode !== KEY_CODES.cmd &&
        e.keyCode !== KEY_CODES.cmd2) {
      this.setState({empty: false});
    }
  },

  _preventDeletionOutsideCaption(e) {
    // only allow deletion of actual caption text
    var sel = document.getSelection();
    var beg = sel.anchorOffset === 0 && sel.type === 'Caret';

    var noBspace = beg && e.keyCode === KEY_CODES.bspace;
    if (noBspace || e.keyCode === KEY_CODES.return) {
      e.preventDefault();
      e.stopPropagation();
    }
  },

  // show placeholder if content is empty
  handleKeyUp(e) {
    this._showPlaceholderWhenEmpty();
  },

  _showPlaceholderWhenEmpty() {
    var node = React.findDOMNode(this.refs.caption);
    if (node.textContent.trim() === "") {
      this.setState({empty: true}, this._selectTextNode);
    }
  },

  render() {
    var capClass = cx({
      'ic-Editor-FigCaption': true,
      'ic-Editor-FigCaption--empty': this.state.empty
    });

    attr = {
      'ref': "caption",
      'contentEditable': "true",
      'className': capClass,
      'onKeyDown': this.handleKeyDown,
      'onKeyUp': this.handleKeyUp,
      'onClick': this.handleClick,
      'data-caption': "true",
      'data-figureid': this.props.figureId
    };

    if (this.state.empty) {
      attr.children = (

          {PLACEHOLDER}

      );
    } else {
      attr.dangerouslySetInnerHTML = { __html: this.props.text };
    }
    return React.createElement('figcaption', attr);
  }
});

module.exports = FigCaption;
<commit_msg>don't allow selection of figure captions<commit_after>var React = require('react/addons');
var PureRenderMixin = React.addons.PureRenderMixin;
var cx = require('classnames');

var KEY_CODES = {
  'return': 13,
  'bspace': 8,
  'delete': 46,
  'cmd':    91,
  'cmd2':   92
};
var PLACEHOLDER = 'Type caption for image';

var { string, bool } = React.PropTypes;

var FigCaption = React.createClass({
  mixins: [PureRenderMixin],

  propTypes: {
    text: string
  },

  getDefaultProps() {
    return {
      text: ''
    };
  },

  getInitialState() {
    return {
      empty: this.props.text.length === 0
    };
  },

  // focus on the text when we click in
  handleClick(e) {
    if (this.state.empty) {
      setTimeout(this._selectTextNode, 0);
    }
  },

  // prevent selection of placeholder
  handleMouseDown(e) {
    if (this.state.empty) {
      e.preventDefault();
    }
  },

  // set our selection at the beginning of the node
  _selectTextNode() {
    var textNode = React.findDOMNode(this.refs.caption);
    var selection = document.getSelection();
    var range = document.createRange();
    range.setStart(textNode.firstChild, 0);
    range.setEnd(textNode.firstChild, 0);
    selection.removeAllRanges();
    selection.addRange(range);
  },

  // clear out placeholder once typing starts
  handleKeyDown(e) {
    this._setNonEmptyWhenTyping(e);
    this._preventDeletionOutsideCaption(e);
  },

  _setNonEmptyWhenTyping(e) {
    if (e.keyCode > KEY_CODES.delete &&
        e.keyCode !== KEY_CODES.cmd &&
        e.keyCode !== KEY_CODES.cmd2) {
      this.setState({empty: false});
    }
  },

  _preventDeletionOutsideCaption(e) {
    // only allow deletion of actual caption text
    var sel = document.getSelection();
    var beg = sel.anchorOffset === 0 && sel.type === 'Caret';

    var noBspace = beg && e.keyCode === KEY_CODES.bspace;
    if (noBspace || e.keyCode === KEY_CODES.return) {
      e.preventDefault();
      e.stopPropagation();
    }
  },

  // show placeholder if content is empty
  handleKeyUp(e) {
    this._showPlaceholderWhenEmpty();
  },

  _showPlaceholderWhenEmpty() {
    var node = React.findDOMNode(this.refs.caption);
    if (node.textContent.trim() === "") {
      this.setState({empty: true}, this._selectTextNode);
    }
  },

  render() {
    var capClass = cx({
      'ic-Editor-FigCaption': true,
      'ic-Editor-FigCaption--empty': this.state.empty
    });

    attr = {
      'ref': "caption",
      'contentEditable': "true",
      'className': capClass,
      'onKeyDown': this.handleKeyDown,
      'onKeyUp': this.handleKeyUp,
      'onMouseDown': this.handleMouseDown,
      'onClick': this.handleClick,
      'data-caption': "true",
      'data-figureid': this.props.figureId
    };

    if (this.state.empty) {
      attr.children = (

          {PLACEHOLDER}

      );
    } else {
      attr.dangerouslySetInnerHTML = { __html: this.props.text };
    }
    return React.createElement('figcaption', attr);
  }
});

module.exports = FigCaption;
<|endoftext|>