<commit_before>var tape = require("tape");
var jsdom = require("./jsdom");
var d3 = require("d3-selection");
var d3_graphviz = require("../");

tape("Check our understanding of how Graphviz draws nodes.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(endTest);

    function endTest() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.key == 'a'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');

        graphviz
            .drawNode(0, -36, 54, 36, 'c', 'ellipse');

        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing an edge');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing an edge');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing an edge');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing an edge');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing an edge');
        graphviz
            .insertCurrentNode('c');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn edge');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn edge');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn edge');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn edge');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn edge');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.key == 'c'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node with an URL attribute in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b [URL="dummy"];}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'c', 'ellipse', {URL: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('c');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.parent.parent.key == 'c'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node with an tooltip attribute in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b [tooltip="dummy"];}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial nodes');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'd', 'ellipse', {tooltip: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('d');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.parent.parent.key == 'd'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("insertCurrentNode() inserts the currently drawn node into the joined data structure so that it can be animated when the graph is re-rendered", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'e', 'ellipse', {URL: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('e');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
         test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        graphviz
            .dot('digraph {a -> b; e}')
            .render(endTest);
    }

    function endTest() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after re-rendering with the inserted node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after re-rendering with the inserted node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after re-rendering with the inserted node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after re-rendering with the inserted node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after re-rendering with the inserted node');
        test.end();
    }

});
<commit_msg>Added test of abortDrawingNode<commit_after>var tape = require("tape");
var jsdom = require("./jsdom");
var d3 = require("d3-selection");
var d3_graphviz = require("../");

tape("Check our understanding of how Graphviz draws nodes.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(endTest);

    function endTest() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.key == 'a'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');

        graphviz
            .drawNode(0, -36, 54, 36, 'c', 'ellipse');

        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing an edge');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing an edge');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing an edge');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing an edge');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing an edge');
        graphviz
            .insertCurrentNode('c');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn edge');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn edge');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn edge');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn edge');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn edge');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.key == 'c'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node with an URL attribute in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b [URL="dummy"];}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'c', 'ellipse', {URL: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('c');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.parent.parent.key == 'c'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("drawNode() draws a node with an tooltip attribute in the same way as Graphviz does", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b [tooltip="dummy"];}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial nodes');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'd', 'ellipse', {tooltip: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('d');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        nodeShape = d3.selectAll('.node').selectAll('ellipse').filter(function(d) {
            return d.parent.parent.parent.key == 'd'
        });

        test.equal(nodeShape.attr("cx"), '27', 'cx of ellipse node');
        test.equal(nodeShape.attr("cy"), '-18', 'cy of ellipse node');
        test.equal(nodeShape.attr("rx"), '27', 'rx of ellipse node');
        test.equal(nodeShape.attr("ry"), '18', 'ry of ellipse node');

        test.end();
    }

});

tape("insertCurrentNode() inserts the currently drawn node into the joined data structure so that it can be animated when the graph is re-rendered", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'e', 'ellipse', {URL: "dummy2"});
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');
        graphviz
            .insertCurrentNode('e');
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after inserting the currently drawn node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after inserting the currently drawn node');
         test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after inserting the currently drawn node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after inserting the currently drawn node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after inserting the currently drawn node');

        graphviz
            .dot('digraph {a -> b; e}')
            .render(endTest);
    }

    function endTest() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after re-rendering with the inserted node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after re-rendering with the inserted node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after re-rendering with the inserted node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after re-rendering with the inserted node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after re-rendering with the inserted node');
        test.end();
    }

});

tape("abortDrawingNode() removes the node currently being drawn", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var graphviz = d3_graphviz.graphviz("#graph");

    var num_nodes = 2;
    var num_edges = 1;

    graphviz
        .zoom(false)
        .logEvents(true)
        .dot('digraph {graph [rankdir="LR"]; a -> b;}')
        .render(drawNode);

    function drawNode() {
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of initial nodes');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of initial edges');
        test.equal(d3.selectAll('polygon').size(), num_edges + 1, 'Number of initial polygons');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of initial ellipses');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of initial paths');
        graphviz
            .drawNode(0, -36, 54, 36, 'e');
        num_nodes += 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after drawing a node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after drawing a node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after drawing a node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after drawing a node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after drawing a node');

        graphviz
            .abortDrawingNode();
        num_nodes -= 1;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after aborting drawing of the current node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after aborting drawing of the current node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons aborting drawing of the current node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses aborting drawing of the current node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after aborting drawing of the current node');

        graphviz
            .dot('digraph {a -> b; b -> a}')
            .render(endTest);
    }

    function endTest() {
        num_nodes = 2;
        num_edges = 2;
        test.equal(d3.selectAll('.node').size(), num_nodes, 'Number of nodes after re-rendering with the inserted node');
        test.equal(d3.selectAll('.edge').size(), num_edges, 'Number of edges after re-rendering with the inserted node');
        test.equal(d3.selectAll('polygon').size(), 1 + num_edges, 'Number of polygons after re-rendering with the inserted node');
        test.equal(d3.selectAll('ellipse').size(), num_nodes, 'Number of ellipses after re-rendering with the inserted node');
        test.equal(d3.selectAll('path').size(), num_edges, 'Number of paths after re-rendering with the inserted node');
        test.end();
    }

});
<|endoftext|>


<commit_before>const path = require('path');
const capitalize = require('lodash/capitalize');
const { expect } = require('../setup');
const cli = require('../lib/cli');
const {
	DEVICE_ID,
	DEVICE_NAME,
	DEVICE_PLATFORM_NAME,
	PATH_TMP_DIR,
	PATH_PROJ_STROBY_INO
} = require('../lib/env');

describe('Cloud Commands [@device]', () => {
	const strobyBinPath = path.join(PATH_TMP_DIR, 'photon-stroby.bin');
	const help = [
		'Access Particle cloud functionality',
		'Usage: particle cloud <command>',
		'Help:  particle help cloud <command>',
		'',
		'Commands:',
		'  claim    Register a device with your user account with the cloud',
		'  list     Display a list of your devices, as well as their variables and functions',
		'  remove   Release a device from your account so that another user may claim it',
		'  name     Give a device a name!',
		'  flash    Pass a binary, source file, or source directory to a device!',
		'  compile  Compile a source file, or directory using the cloud compiler',
		'  nyan     Make your device shout rainbows',
		'  login    Login to the cloud and store an access token locally',
		'  logout   Log out of your session and clear your saved access token',
		'',
		'Global Options:',
		'  -v, --verbose  Increases how much logging to display  [count]',
		'  -q, --quiet    Decreases how much logging to display  [count]'
	];

	before(async () => {
		await cli.setTestProfileAndLogin();
		await cli.flashBlankFirmwareOTAForTest();
	});

	after(async () => {
		await cli.claimTestDevice();
		await cli.revertDeviceName();
		await cli.logout();
		await cli.setDefaultProfile();
	});

	it('Shows `help` content', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['help', 'cloud']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run without arguments', async () => {
		const { stdout, stderr, exitCode } = await cli.run('cloud');

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run with `--help` flag', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['cloud', '--help']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Lists devices', async () => {
		const args = ['cloud', 'list'];
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(args);

		expect(stdout).to.include(`${DEVICE_NAME} [${DEVICE_ID}] (${platform})`);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Compiles firmware', async () => {
		const args = ['cloud', 'compile', 'photon', PATH_PROJ_STROBY_INO, '--saveTo', strobyBinPath];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			'Compiling code for photon',
			'',
			'Including:',
			`    ${PATH_PROJ_STROBY_INO}`,
			'attempting to compile firmware ',
			'', // TODO (mirande): should be 'downloading binary from: /v1/binaries/5d38f108bc91fb000130a3f9' but the hash changes on each run
			`saving to: ${strobyBinPath}`,
			'Memory use: ',
			'   text\t   data\t    bss\t    dec\t    hex\tfilename',
			'   7436\t    116\t   1444\t   8996\t   2324\t/workspace/target/workspace.elf',
			'',
			'Compile succeeded.',
			`Saved firmware to: ${strobyBinPath}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Flashes firmware', async () => {
		const args = ['cloud', 'flash', DEVICE_NAME, PATH_PROJ_STROBY_INO];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			'Including:',
			`    ${PATH_PROJ_STROBY_INO}`,
			`attempting to flash firmware to your device ${DEVICE_NAME}`,
			'Flash device OK:  Update started'
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);

		await cli.waitForVariable('name', 'stroby');
	});

	it('Removes device', async () => {
		const args = ['cloud', 'remove', DEVICE_NAME, '--yes'];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`releasing device ${DEVICE_NAME}`,
			'Okay!'
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Claims device', async () => {
		const args = ['cloud', 'claim', DEVICE_ID];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`Claiming device ${DEVICE_ID}`,
			`Successfully claimed device ${DEVICE_ID}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Names a device', async () => {
		const name = `${DEVICE_NAME}-updated`;
		const args = ['cloud', 'name', DEVICE_ID, name];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`Renaming device ${DEVICE_ID}`,
			`Successfully renamed device ${DEVICE_ID} to: ${name}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});
});

<commit_msg>add end-to-end tests to verify `--followSymlinks` handling in `cloud` commands<commit_after>const path = require('path');
const capitalize = require('lodash/capitalize');
const { expect } = require('../setup');
const cli = require('../lib/cli');
const {
	DEVICE_ID,
	DEVICE_NAME,
	DEVICE_PLATFORM_NAME,
	PATH_TMP_DIR,
	PATH_PROJ_STROBY_INO
} = require('../lib/env');

describe('Cloud Commands [@device]', () => {
	const strobyBinPath = path.join(PATH_TMP_DIR, 'photon-stroby.bin');
	const help = [
		'Access Particle cloud functionality',
		'Usage: particle cloud <command>',
		'Help:  particle help cloud <command>',
		'',
		'Commands:',
		'  claim    Register a device with your user account with the cloud',
		'  list     Display a list of your devices, as well as their variables and functions',
		'  remove   Release a device from your account so that another user may claim it',
		'  name     Give a device a name!',
		'  flash    Pass a binary, source file, or source directory to a device!',
		'  compile  Compile a source file, or directory using the cloud compiler',
		'  nyan     Make your device shout rainbows',
		'  login    Login to the cloud and store an access token locally',
		'  logout   Log out of your session and clear your saved access token',
		'',
		'Global Options:',
		'  -v, --verbose  Increases how much logging to display  [count]',
		'  -q, --quiet    Decreases how much logging to display  [count]'
	];

	before(async () => {
		await cli.setTestProfileAndLogin();
		await cli.flashBlankFirmwareOTAForTest();
	});

	after(async () => {
		await cli.claimTestDevice();
		await cli.revertDeviceName();
		await cli.logout();
		await cli.setDefaultProfile();
	});

	it('Shows `help` content', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['help', 'cloud']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run without arguments', async () => {
		const { stdout, stderr, exitCode } = await cli.run('cloud');

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Shows `help` content when run with `--help` flag', async () => {
		const { stdout, stderr, exitCode } = await cli.run(['cloud', '--help']);

		expect(stdout).to.equal('');
		expect(stderr.split('\n')).to.include.members(help);
		expect(exitCode).to.equal(0);
	});

	it('Lists devices', async () => {
		const args = ['cloud', 'list'];
		const platform = capitalize(DEVICE_PLATFORM_NAME);
		const { stdout, stderr, exitCode } = await cli.run(args);

		expect(stdout).to.include(`${DEVICE_NAME} [${DEVICE_ID}] (${platform})`);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Compiles firmware', async () => {
		const args = ['cloud', 'compile', 'photon', PATH_PROJ_STROBY_INO, '--saveTo', strobyBinPath];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			'Compiling code for photon',
			'',
			'Including:',
			`    ${PATH_PROJ_STROBY_INO}`,
			'attempting to compile firmware ',
			'', // TODO (mirande): should be 'downloading binary from: /v1/binaries/5d38f108bc91fb000130a3f9' but the hash changes on each run
			`saving to: ${strobyBinPath}`,
			'Memory use: ',
			'   text\t   data\t    bss\t    dec\t    hex\tfilename',
			'   7436\t    116\t   1444\t   8996\t   2324\t/workspace/target/workspace.elf',
			'',
			'Compile succeeded.',
			`Saved firmware to: ${strobyBinPath}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Compiles a project with symlinks to parent/other file locations', async () => {
		const name = 'symlinks';
		const platform = 'photon';
		const cwd = path.join(PATH_FIXTURES_PROJECTS_DIR, 'symlink', 'main-project');
		const destination = path.join(PATH_TMP_DIR, `${name}-${platform}.bin`);
		const args = ['cloud', 'compile', platform, '--saveTo', destination, '--followSymlinks'];
		const { stdout, stderr, exitCode } = await cli.run(args, { cwd });
		const log = [
			`Compiling code for ${platform}`,
			'Including:',
			'    shared/sub_dir/helper.h',
			'    app.ino',
			'    shared/sub_dir/helper.cpp',
			'    project.properties',
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Flashes firmware', async () => {
		const args = ['cloud', 'flash', DEVICE_NAME, PATH_PROJ_STROBY_INO];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			'Including:',
			`    ${PATH_PROJ_STROBY_INO}`,
			`attempting to flash firmware to your device ${DEVICE_NAME}`,
			'Flash device OK:  Update started'
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);

		await cli.waitForVariable('name', 'stroby');
	});

	it('Flashes a project with symlinks to parent/other file locations', async () => {
		const cwd = path.join(PATH_FIXTURES_PROJECTS_DIR, 'symlink', 'main-project');
		const args = ['cloud', 'flash', DEVICE_NAME, '--followSymlinks'];
		const { stdout, stderr, exitCode } = await cli.run(args, { cwd });
		const log = [
			'Including:',
			'    shared/sub_dir/helper.h',
			'    app.ino',
			'    shared/sub_dir/helper.cpp',
			'    project.properties',
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Removes device', async () => {
		const args = ['cloud', 'remove', DEVICE_NAME, '--yes'];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`releasing device ${DEVICE_NAME}`,
			'Okay!'
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Claims device', async () => {
		const args = ['cloud', 'claim', DEVICE_ID];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`Claiming device ${DEVICE_ID}`,
			`Successfully claimed device ${DEVICE_ID}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});

	it('Names a device', async () => {
		const name = `${DEVICE_NAME}-updated`;
		const args = ['cloud', 'name', DEVICE_ID, name];
		const { stdout, stderr, exitCode } = await cli.run(args);
		const log = [
			`Renaming device ${DEVICE_ID}`,
			`Successfully renamed device ${DEVICE_ID} to: ${name}`
		];

		expect(stdout.split('\n')).to.include.members(log);
		expect(stderr).to.equal('');
		expect(exitCode).to.equal(0);
	});
});

<|endoftext|>


<commit_before>/**
 *
 * @file
 *
 * @see demo.js
 * practical use case
 *
 */

exports.Succss = Succss;

Succss.setFileName = function(captureState) {
  return captureState.name + '--' + captureState.viewport.name + '-viewport.png';
};

SuccssCount = {
  planned:0,
  remaining:0,
  failures:0,
};

function Succss(options) {

  var self = this;

  if (!self.casper) {
    throw "[SucCSS] Succss.casper instance missing.";
  }
  var casperInstance = self.casper;

  if (!self.webpages) {
    throw "[SucCSS] Succss.webpages instance missing.";
  }
  var data = self.webpages;
  var options = options || {};
  // After capture callback.
  var acallback = self.callback;

  var pages = Object.keys(data);

  var capturesFound = false;
  var captureFilters = false;

  var viewportsData = self.viewports || {
    'default': {
      'width':1366,
      'height':768
    }
  };
  var viewports = Object.keys(viewportsData);

  if(!self.setFileName) self.setFileName = Succss.setFileName;
  var setFileName = Succss.prototype.setFileName;

  if (options.pages != undefined) {
    pages = options.pages.split(',');
    console.log ('Warning! --pages option found, captures will only run for: ' + options.pages);
    for (var p in pages) {
      if(data[pages[p]] == undefined) {
        throw "[SucCSS] The page configuration " + pages[p] + '" was not found.';
      }
    }
  }

  if (options.captures != undefined) {
    captureFilters = options.captures.split(',');
    console.log ('Warning! --captures option found, captures will only run for: ' + options.captures);
  }
  if (options.viewports != undefined) {
    viewports = options.viewports.split(',');
    console.log ('Warning! --viewports option found, captures will only run with: ' + options.viewports + ' viewport.');
    for (var v in viewports) {
      if(viewportsData[viewports[v]] == undefined) {
        throw "[SucCSS] The viewport " + viewports[v] + " was not found.";
      }
    }
  }

  for (var v in viewportsData) {
    viewportsData[v].name = v;
    // @TODO check viewports correctness.
  }

  for (var p in pages) {

    var page = pages[p];
    data[page].name = page;

    if (data[page].url == undefined) {
      throw "[SucCSS] Each configuration page requires an url, see ./regrecss/demo.js";
    }
    if (data[page].url.indexOf('http') != 0) {
      data[page].url = 'http://' + data[page].url;
    }

    if (!data[page].directory) data[page].directory = './screenshots';

    if (data[page].captures == undefined || !Object.keys(data[page].captures).length) {
      data[page].captures = {
        'body':''
      }
    }

    var captures = data[page].captures;
    data[page].captureKeys = Array();

    for (var c in captures) {

      if (captureFilters == false || captureFilters.indexOf(c) != -1) {

        data[page].captureKeys.push(c);
        if (!captureFilters || captureFilters.indexOf(c) != -1) {
          capturesFound = true;
        }

        if (data[page].captures[c] instanceof Object) {
          data[page].captures[c] = {
            selector:captures[c].selector || c,
            before:captures[c].before || false
          };
        }
        else {
          data[page].captures[c] = {
            selector:captures[c] || c
          }
        }
        data[page].captures[c].name = c;
        data[page].captures[c].after = acallback;
      }
    }
  }

  if (!capturesFound) {
    throw "[SucCSS] No captures selector " + viewports[v] + " found. Check your Succss.webpages configuration.";
  }

  var createCaptureState = function(pageName, captureIndex, viewportName, action) {
    // Available in setFileName:
    captureState = data[pageName].captures[captureIndex];
    captureState.page = data[pageName];
    captureState.viewport = viewportsData[viewportName];
    captureState.options = options;
    // Available in after capture callback:
    captureState.file = self.setFileName(captureState);
    captureState.filePath = captureState.page.directory + '/' + captureState.file;
    captureState.action = action || 'add';
    return captureState;
  }

  self.add = function() {

    casperInstance.start('about:blank', function() {

      casperInstance.each(pages, function(casperInstance, p) {

        if (options.rmtree == true && fs.isDirectory(data[p].directory)) {
          console.log('\nWarning! ' + data[p].directory + " directory tree erased.");
          fs.removeTree(data[p].directory);
        }

        console.log('\nFound "' + p + '" page configuration.');

        SuccssCount.planned += data[p].captureKeys.length*viewports.length;
        SuccssCount.remaining = SuccssCount.planned;

        casperInstance.each(data[p].captureKeys, function(casperInstance, c) {

          casperInstance.each(viewports, function(casperInstance, v) {

            casperInstance.thenOpen(data[p].url, function(){

              SuccssCount.remaining--;

              var capture = createCaptureState(p, c, v);

              console.log('\nCapturing "' + capture.page.name + '" ' + capture.name + ' screenshot with ' + v + ' viewport:');
              console.log('\nSelector is: "' + capture.selector);
              console.log('> Opening ' + capture.page.url);

              casperInstance.viewport(capture.viewport.width, capture.viewport.height);

              if (casperInstance.currentHTTPStatus != 200) {
                switch (casperInstance.currentHTTPStatus) {
                  case null:
                    throw "[SucCSS] Can't access " + capture.page.url + ". Check the website url and your internet connexion.";
                    break;
                  default:
                    throw "[SucCSS] Response code for " + capture.page.url + " was " + casperInstance.currentHTTPStatus;
                }
              }

              console.log('> ... Saving ' + capture.name + ' screenshot under ' + capture.filePath);
              self.takeScreenshot(casperInstance, capture);

            });
          });
        });
      });
    }).run();
  }

  self.check = function() {

    casperInstance.start('about:blank', function() {

//      casperInstance.each(pages, function(casperInstance, k) {
//
//        casperInstance.each(data[k].sections, function(casperInstance, c) {
//
//          var section = data[k][c];
//
//          casperInstance.each(Object.keys(section.selectors), function(casperInstance, sel) {
//
//            casperInstance.each(Object.keys(data[k].viewports), function(casperInstance, v) {
//
//              var dir = section.screenDir + '/' + section.selectors[sel].name + '--' + v + '-viewport';
//              var checkDest = section.screenDir + '/tmp/' + section.selectors[sel].name + '--' + v + '-viewport';
//
//              casperInstance.thenOpen(section.targetPath, function(){
//
//                casperInstance.viewport(data[k].viewportsData[v].width, data[k].viewportsData[v].height);
//
//                if (casperInstance.currentHTTPStatus != 200) {
//                  throw "[SucCSS] Can't access " + section.targetPath + ". Check the website url and your internet connexion.";
//                }
//
//                Succss.takeScreenshot(casperInstance, checkDest, sel, section.selectors[sel].callback, afterCapture);
//
//                var imgLoadCount = 0;
//                imgBase = new Image();
//                imgBase.src = fs.absolute(dir);
//                imgCheck = new Image();
//                imgCheck.src = fs.absolute(checkDest);
//
//                imgBase.onload = imgCheck.onload = function() {
//                  imgLoadCount++;
//                  if (imgLoadCount == 2) {
//                    imgDiff = imagediff.diff(imgBase, imgCheck);
//                    console.log(imagediff.equal(imgBase, imgCheck));
//                    var canvas = imagediff.createCanvas();
//                    canvas.width = imgBase.width * 3;
//                    canvas.height = imgBase.height;
//                    var ctx = canvas.getContext('2d');
//                    ctx.putImageData(imgDiff, 0, 0);
//                    ctx.drawImage(imgBase, imgBase.width, 0);
//                    ctx.drawImage(imgCheck, imgBase.width*2, 0);
//                    var imgDiff = canvas.toDataURL("image/png").split(",")[1];
//                    var imgDiffPath = section.screenDir + '/imagediff' +
//                    fs.write("file.png",atob(imgDiff),'wb');
//                  }
//                }
//
//              });
//            });
//          });
//        });
//      });
    }).run();
  }

  self.takeScreenshot = function(casper, captureState) {

    // Before capture:
    casper.then(function() {
      casper.waitForSelector(captureState.selector, function() {
        if (captureState.before) {
          var siblings = {};
          var pageCaptures = data[captureState.page.name].captures;
          for (var c in pageCaptures) {
            if (c != captureState.name && pageCaptures[c].before) {
              siblings[c] = pageCaptures[c].before.bind(casper, siblings);
            }
          }
          captureState.before.call(casper, siblings);
        }
      });
    });

    var imgOptions = {
      format: 'png',
      quality: 80
    };

    casper.then(function() {

      casper.captureSelector(captureState.filePath, captureState.selector, imgOptions);

      // After capture:
      if (captureState.after != undefined) {
        try {
          captureState.after.call(self, captureState, SuccssCount);
        }
        catch (err) {
          casper.test.error(err);
          SuccssCount.failures++;
        }
      }
      if (SuccssCount.remaining == 0 && SuccssCount.failures) {
        casper.test.error('Your tests failed with ' + SuccssCount.failures + ' errors.');
      }
    });
  }

  self.diff = function(img1, img2) {

  }

  return self;

}<commit_msg>Replacing the old setFileName static and prototype method with a proper function<commit_after>/**
 *
 * @file
 *
 * @see demo.js
 * practical use case
 *
 */

exports.Succss = Succss;

SuccssCount = {
  planned:0,
  remaining:0,
  failures:0,
};

function Succss(options) {

  var self = this;

  if (!self.casper) {
    throw "[SucCSS] Succss.casper instance missing.";
  }
  var casperInstance = self.casper;

  if (!self.webpages) {
    throw "[SucCSS] Succss.webpages instance missing.";
  }
  var data = self.webpages;
  var options = options || {};
  // After capture callback.
  var acallback = self.callback;

  var pages = Object.keys(data);

  var capturesFound = false;
  var captureFilters = false;

  var viewportsData = self.viewports || {
    'default': {
      'width':1366,
      'height':768
    }
  };
  var viewports = Object.keys(viewportsData);

  if(!self.setFileName) self.setFileName = function(captureState) {
    return captureState.name + '--' + captureState.viewport.name + '-viewport.png';
  };

  if (options.pages != undefined) {
    pages = options.pages.split(',');
    console.log ('Warning! --pages option found, captures will only run for: ' + options.pages);
    for (var p in pages) {
      if(data[pages[p]] == undefined) {
        throw "[SucCSS] The page configuration " + pages[p] + '" was not found.';
      }
    }
  }

  if (options.captures != undefined) {
    captureFilters = options.captures.split(',');
    console.log ('Warning! --captures option found, captures will only run for: ' + options.captures);
  }
  if (options.viewports != undefined) {
    viewports = options.viewports.split(',');
    console.log ('Warning! --viewports option found, captures will only run with: ' + options.viewports + ' viewport.');
    for (var v in viewports) {
      if(viewportsData[viewports[v]] == undefined) {
        throw "[SucCSS] The viewport " + viewports[v] + " was not found.";
      }
    }
  }

  for (var v in viewportsData) {
    viewportsData[v].name = v;
    // @TODO check viewports correctness.
  }

  for (var p in pages) {

    var page = pages[p];
    data[page].name = page;

    if (data[page].url == undefined) {
      throw "[SucCSS] Each configuration page requires an url, see ./regrecss/demo.js";
    }
    if (data[page].url.indexOf('http') != 0) {
      data[page].url = 'http://' + data[page].url;
    }

    if (!data[page].directory) data[page].directory = './screenshots';

    if (data[page].captures == undefined || !Object.keys(data[page].captures).length) {
      data[page].captures = {
        'body':''
      }
    }

    var captures = data[page].captures;
    data[page].captureKeys = Array();

    for (var c in captures) {

      if (captureFilters == false || captureFilters.indexOf(c) != -1) {

        data[page].captureKeys.push(c);
        if (!captureFilters || captureFilters.indexOf(c) != -1) {
          capturesFound = true;
        }

        if (data[page].captures[c] instanceof Object) {
          data[page].captures[c] = {
            selector:captures[c].selector || c,
            before:captures[c].before || false
          };
        }
        else {
          data[page].captures[c] = {
            selector:captures[c] || c
          }
        }
        data[page].captures[c].name = c;
        data[page].captures[c].after = acallback;
      }
    }
  }

  if (!capturesFound) {
    throw "[SucCSS] No captures selector " + viewports[v] + " found. Check your Succss.webpages configuration.";
  }

  var createCaptureState = function(pageName, captureIndex, viewportName, action) {
    // Available in setFileName:
    captureState = data[pageName].captures[captureIndex];
    captureState.page = data[pageName];
    captureState.viewport = viewportsData[viewportName];
    captureState.options = options;
    // Available in after capture callback:
    captureState.file = self.setFileName(captureState);
    captureState.filePath = captureState.page.directory + '/' + captureState.file;
    captureState.action = action || 'add';
    return captureState;
  }

  self.add = function() {

    casperInstance.start('about:blank', function() {

      casperInstance.each(pages, function(casperInstance, p) {

        if (options.rmtree == true && fs.isDirectory(data[p].directory)) {
          console.log('\nWarning! ' + data[p].directory + " directory tree erased.");
          fs.removeTree(data[p].directory);
        }

        console.log('\nFound "' + p + '" page configuration.');

        SuccssCount.planned += data[p].captureKeys.length*viewports.length;
        SuccssCount.remaining = SuccssCount.planned;

        casperInstance.each(data[p].captureKeys, function(casperInstance, c) {

          casperInstance.each(viewports, function(casperInstance, v) {

            casperInstance.thenOpen(data[p].url, function(){

              SuccssCount.remaining--;

              var capture = createCaptureState(p, c, v);

              console.log('\nCapturing "' + capture.page.name + '" ' + capture.name + ' screenshot with ' + v + ' viewport:');
              console.log('\nSelector is: "' + capture.selector);
              console.log('> Opening ' + capture.page.url);

              casperInstance.viewport(capture.viewport.width, capture.viewport.height);

              if (casperInstance.currentHTTPStatus != 200) {
                switch (casperInstance.currentHTTPStatus) {
                  case null:
                    throw "[SucCSS] Can't access " + capture.page.url + ". Check the website url and your internet connexion.";
                    break;
                  default:
                    throw "[SucCSS] Response code for " + capture.page.url + " was " + casperInstance.currentHTTPStatus;
                }
              }

              console.log('> ... Saving ' + capture.name + ' screenshot under ' + capture.filePath);
              self.takeScreenshot(casperInstance, capture);

            });
          });
        });
      });
    }).run();
  }

  self.check = function() {

    casperInstance.start('about:blank', function() {

//      casperInstance.each(pages, function(casperInstance, k) {
//
//        casperInstance.each(data[k].sections, function(casperInstance, c) {
//
//          var section = data[k][c];
//
//          casperInstance.each(Object.keys(section.selectors), function(casperInstance, sel) {
//
//            casperInstance.each(Object.keys(data[k].viewports), function(casperInstance, v) {
//
//              var dir = section.screenDir + '/' + section.selectors[sel].name + '--' + v + '-viewport';
//              var checkDest = section.screenDir + '/tmp/' + section.selectors[sel].name + '--' + v + '-viewport';
//
//              casperInstance.thenOpen(section.targetPath, function(){
//
//                casperInstance.viewport(data[k].viewportsData[v].width, data[k].viewportsData[v].height);
//
//                if (casperInstance.currentHTTPStatus != 200) {
//                  throw "[SucCSS] Can't access " + section.targetPath + ". Check the website url and your internet connexion.";
//                }
//
//                Succss.takeScreenshot(casperInstance, checkDest, sel, section.selectors[sel].callback, afterCapture);
//
//                var imgLoadCount = 0;
//                imgBase = new Image();
//                imgBase.src = fs.absolute(dir);
//                imgCheck = new Image();
//                imgCheck.src = fs.absolute(checkDest);
//
//                imgBase.onload = imgCheck.onload = function() {
//                  imgLoadCount++;
//                  if (imgLoadCount == 2) {
//                    imgDiff = imagediff.diff(imgBase, imgCheck);
//                    console.log(imagediff.equal(imgBase, imgCheck));
//                    var canvas = imagediff.createCanvas();
//                    canvas.width = imgBase.width * 3;
//                    canvas.height = imgBase.height;
//                    var ctx = canvas.getContext('2d');
//                    ctx.putImageData(imgDiff, 0, 0);
//                    ctx.drawImage(imgBase, imgBase.width, 0);
//                    ctx.drawImage(imgCheck, imgBase.width*2, 0);
//                    var imgDiff = canvas.toDataURL("image/png").split(",")[1];
//                    var imgDiffPath = section.screenDir + '/imagediff' +
//                    fs.write("file.png",atob(imgDiff),'wb');
//                  }
//                }
//
//              });
//            });
//          });
//        });
//      });
    }).run();
  }

  self.takeScreenshot = function(casper, captureState) {

    // Before capture:
    casper.then(function() {
      casper.waitForSelector(captureState.selector, function() {
        if (captureState.before) {
          var siblings = {};
          var pageCaptures = data[captureState.page.name].captures;
          for (var c in pageCaptures) {
            if (c != captureState.name && pageCaptures[c].before) {
              siblings[c] = pageCaptures[c].before.bind(casper, siblings);
            }
          }
          captureState.before.call(casper, siblings);
        }
      });
    });

    var imgOptions = {
      format: 'png',
      quality: 80
    };

    casper.then(function() {

      casper.captureSelector(captureState.filePath, captureState.selector, imgOptions);

      // After capture:
      if (captureState.after != undefined) {
        try {
          captureState.after.call(self, captureState, SuccssCount);
        }
        catch (err) {
          casper.test.error(err);
          SuccssCount.failures++;
        }
      }
      if (SuccssCount.remaining == 0 && SuccssCount.failures) {
        casper.test.error('Your tests failed with ' + SuccssCount.failures + ' errors.');
      }
    });
  }

  self.diff = function(img1, img2) {

  }

  return self;

}<|endoftext|>


<commit_before>var http = require("http"),
    os = require("os"),
    path = require("path"),
    store = require("level-store"),
    url = require("url");

function generateId() {
  return [Date.now(), Math.round(Math.random() * 100000)].join("-");
};

var Suckit = module.exports = function Suckit(options) {
  http.Server.call(this);

  this.sessionId = generateId();
  this.dataPath = options.dataPath || os.tmpdir();
  this.buckets = {};

  this.on("request", this.onRequest.bind(this));
};
Suckit.prototype = Object.create(http.Server.prototype);

Suckit.prototype.getBucket = function getBucket(name) {
  if (!this.buckets[name]) {
    this.emit("log", "info", "opening bucket", {session: this.sessionId, name: name});

    this.buckets[name] = store(path.join(this.dataPath, name));
  }

  return this.buckets[name];
};

Suckit.prototype.onRequest = function onRequest(req, res) {
  var requestId = generateId();

  this.emit("log", "info", "request", {session: this.sessionId, request: requestId, method: req.method, url: req.url});

  if (req.method !== "GET" && req.method !== "PUT" && req.method !== "POST") {
    res.writeHead(406);
    return res.end();
  }

  var uri = url.parse(req.url, true);

  var bits = uri.pathname.replace(/^\//, "").split("/");

  var bucketName = bits.shift(),
      fileName = bits.shift();

  if (!bucketName) {
    res.writeHead(406);
    return res.end();
  }

  var bucket = this.getBucket(bucketName);

  if (req.method === "GET" && bucketName && fileName) {
    this.emit("log", "info", "getting entry", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});

    return bucket.exists(fileName, function(err, exists) {
      if (err) {
        this.emit("log", "error", "error checking if file exists", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, err: err.message});
        res.writeHead(500);
        return res.end();
      }

      if (!exists) {
        this.emit("log", "warn", "file doesn't exist", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
        res.writeHead(404);
        return res.end();
      }

      this.emit("log", "info", "beginning to serve file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, live: !!uri.query.live});

      var file = bucket.createReadStream(fileName, {live: !!uri.query.live});
      file.on("end", function() {
        this.emit("log", "info", "finished serving file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
      }.bind(this));

      res.writeHead(200, {"content-type": "application/octet-stream"});
      file.pipe(res);
    }.bind(this));
  }

  if (req.method === "POST" && bucketName && !fileName) {
    fileName = generateId();

    this.emit("log", "info", "generated file name", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
  }

  if ((req.method === "POST" || req.method === "PUT") && bucketName && fileName) {
    var append = req.method === "POST";

    this.emit("log", "info", "asked to write to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append});

    return bucket.exists(fileName, function(err, exists) {
      if (err) {
        this.emit("log", "error", "error checking if file exists", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, err: err.message});
        res.writeHead(500);
        return res.end();
      }

      var newFile = !exists;

      this.emit("log", "info", "beginning to write to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append, newFile: newFile});

      var file = bucket.createWriteStream(fileName, {append: append});

      req.pipe(file);

      req.on("end", function() {
        this.emit("log", "info", "finished writing to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append, newFile: newFile});
        res.writeHead(newFile ? 201 : 200, {location: ["", bucketName, fileName].join("/")});
        res.end();
      }.bind(this));
    }.bind(this));
  }

  this.emit("log", "warn", "unrecognised request", {session: this.sessionId, request: requestId, method: req.method, bucket: bucketName, file: fileName});

  res.writeHead(406);
  res.end();
};

Suckit.createServer = function createServer(options) {
  return new Suckit(options);
};
<commit_msg>remove timeout on http server for large, large posts etc<commit_after>var http = require("http"),
    os = require("os"),
    path = require("path"),
    store = require("level-store"),
    url = require("url");

function generateId() {
  return [Date.now(), Math.round(Math.random() * 100000)].join("-");
};

var Suckit = module.exports = function Suckit(options) {
  http.Server.call(this);

  this.sessionId = generateId();
  this.dataPath = options.dataPath || os.tmpdir();
  this.buckets = {};

  this.timeout = 0;

  this.on("request", this.onRequest.bind(this));
};
Suckit.prototype = Object.create(http.Server.prototype);

Suckit.prototype.getBucket = function getBucket(name) {
  if (!this.buckets[name]) {
    this.emit("log", "info", "opening bucket", {session: this.sessionId, name: name});

    this.buckets[name] = store(path.join(this.dataPath, name));
  }

  return this.buckets[name];
};

Suckit.prototype.onRequest = function onRequest(req, res) {
  var requestId = generateId();

  this.emit("log", "info", "request", {session: this.sessionId, request: requestId, method: req.method, url: req.url});

  if (req.method !== "GET" && req.method !== "PUT" && req.method !== "POST") {
    res.writeHead(406);
    return res.end();
  }

  var uri = url.parse(req.url, true);

  var bits = uri.pathname.replace(/^\//, "").split("/");

  var bucketName = bits.shift(),
      fileName = bits.shift();

  if (!bucketName) {
    res.writeHead(406);
    return res.end();
  }

  var bucket = this.getBucket(bucketName);

  if (req.method === "GET" && bucketName && fileName) {
    this.emit("log", "info", "getting entry", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});

    return bucket.exists(fileName, function(err, exists) {
      if (err) {
        this.emit("log", "error", "error checking if file exists", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, err: err.message});
        res.writeHead(500);
        return res.end();
      }

      if (!exists) {
        this.emit("log", "warn", "file doesn't exist", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
        res.writeHead(404);
        return res.end();
      }

      this.emit("log", "info", "beginning to serve file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, live: !!uri.query.live});

      var file = bucket.createReadStream(fileName, {live: !!uri.query.live});
      file.on("end", function() {
        this.emit("log", "info", "finished serving file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
      }.bind(this));

      res.writeHead(200, {"content-type": "application/octet-stream"});
      file.pipe(res);
    }.bind(this));
  }

  if (req.method === "POST" && bucketName && !fileName) {
    fileName = generateId();

    this.emit("log", "info", "generated file name", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName});
  }

  if ((req.method === "POST" || req.method === "PUT") && bucketName && fileName) {
    var append = req.method === "POST";

    this.emit("log", "info", "asked to write to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append});

    return bucket.exists(fileName, function(err, exists) {
      if (err) {
        this.emit("log", "error", "error checking if file exists", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, err: err.message});
        res.writeHead(500);
        return res.end();
      }

      var newFile = !exists;

      this.emit("log", "info", "beginning to write to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append, newFile: newFile});

      var file = bucket.createWriteStream(fileName, {append: append});

      req.pipe(file);

      req.on("end", function() {
        this.emit("log", "info", "finished writing to file", {session: this.sessionId, request: requestId, bucket: bucketName, file: fileName, append: append, newFile: newFile});
        res.writeHead(newFile ? 201 : 200, {location: ["", bucketName, fileName].join("/")});
        res.end();
      }.bind(this));
    }.bind(this));
  }

  this.emit("log", "warn", "unrecognised request", {session: this.sessionId, request: requestId, method: req.method, bucket: bucketName, file: fileName});

  res.writeHead(406);
  res.end();
};

Suckit.createServer = function createServer(options) {
  return new Suckit(options);
};
<|endoftext|>


<commit_before>// ==UserScript==
// @name Bibliotik.me / WM Integrator
// @namespace https://karamanolev.com
// @version 0.2.1
// @description Integration between WM and Bibliotik.me
// @match http://bibliotik.me/*
// @match https://bibliotik.me/*
// @grant GM_xmlhttpRequest
// @updateURL {{ root }}/userscript/bibliotik.user.js
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
// @require {{ root }}/static/js/jquery.noty.packaged.min.js
// ==/UserScript==

var torrentsInfoUrl = '{{ root }}/books/bibliotik/json/torrents_info';
var addTorrentUrl = '{{ root }}/books/bibliotik/json/add/';
var downloadUrl = '{{ root }}/download/zip/bibliotik/';

$.noty.defaults.timeout = 5000;
var loadingImg = '<img class="loading-img" src="data:image/gif;base64,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" width="12" height="12" valign="middle" />';
function formatResponseError(response) {
    if (response.statusText) {
        return response.statusText;
    }
    return "Unknown network error.";
}

function submitIds(rows, callback) {
    setTimeout(function () {
        var ids = [];
        for (var i in rows) ids.push(rows[i].whatId);
        var idsString = 'ids=' + encodeURIComponent(ids.join(','));
        GM_xmlhttpRequest({
            method: "GET",
            url: torrentsInfoUrl + '?' + idsString,
            onload: function (response) {
                callback($.parseJSON(response.responseText));
            },
            onerror: function (response) {
                debugger;
                noty({
                    text: 'Error loading WM data: ' + formatResponseError(response),
                    type: 'error'
                });
            }
        });
    }, 0);
}

function stealBibliotikSessionId(callback) {
    var extensionId = "opapngdimmnncheoehlpdnceakheghcn";
    var timeoutID = setTimeout(function () {
        noty({
            text: 'Please make sure the extension is installed and working.',
            type: 'error'
        });
    }, 1500);
    chrome.runtime.sendMessage(extensionId, "stealBibliotikId", function (response) {
        clearTimeout(timeoutID);
        if (response == null) {
            noty({
                text: 'The extension could not find the session ID. Make sure you are logged in Bibliotik.',
                type: 'error'
            });
        }
        callback(response);
    });
}

function addTorrent(torrentId, callback) {
    stealBibliotikSessionId(function (sessionId) {
        var params = encodeURIComponent(torrentId) + '?';
        params += 'bibliotik_id=' + encodeURIComponent(sessionId);
        GM_xmlhttpRequest({
            method: "GET",
            url: addTorrentUrl + params,
            onload: function (response) {
                callback($.parseJSON(response.responseText));
            },
            onerror: function (response) {
                callback({
                    success: false,
                    error: formatResponseError(response)
                });
            }
        });
    });
}

function getId(link) {
    var regexps = [
        /torrents\/(\d+)\/download/
    ];
    var result = null;
    $.each(regexps, function (i, r) {
        var m = link.match(r);
        if (m !== null) {
            result = m[1];
        }
    });
    return result;
}

var torrentRows = [];

function downloadTorrent(row) {
    row.actions.html(loadingImg);
    row.isAdding = true;
    addTorrent(row.whatId, function (addResult) {
        var htmlTitle;
        row.isAdding = false;
        if (addResult.success) {
            htmlTitle = $('').text(addResult.title).prop('outerHTML');
            noty({
                text: 'Torrent ' + htmlTitle + ' added successfully!',
                type: 'success'
            });
            row.actions.text('OK');
        } else if (addResult.error_code == 'already_added') {
            htmlTitle = $('').text(addResult.title).prop('outerHTML');
            noty({
                text: 'Torrent ' + htmlTitle + ' already added!',
                type: 'warning'
            });
            row.actions.text('ERR');
        } else {
            noty({
                text: 'Error adding ' + resp.id + ': ' + addResult.error,
                type: 'error'
            });
            row.actions.text('ERR');
        }
    });
}

function processResult(result) {
    $.each(result, function (i, resp) {
        var row = torrentRows[i];
        var link;

        if (row.isAdding) {
            return;
        }

        row.actions.empty();
        if (resp.status == 'downloaded') {
            // Download
            link = $('↓DL');
            row.actions.append(link);
        } else if (resp.status == 'downloading') {
            row.actions.text(Math.floor(resp.progress * 100) + '%');
        } else if (resp.status == 'missing') {
            // Add to WM

            link = $('GET');
            link.click(function (e) {
                e.preventDefault();
                if (confirm('Are you sure you want to download ' + resp.id + '?')) {
                    downloadTorrent(row);
                }
            });
            row.actions.append(' ');
            row.actions.append(link);
        } else {
            row.actions.text(result[i].status);
        }
    });
}

function processRow() {
    var $this = $(this);
    var link = $this.find('a[title="Download"]');
    if (!link.length) return;
    var actions = link.parent();
    actions.css('width', 50);
    var torrentId = getId(link.attr('href'));
    var customActions = $('');
    actions.append(customActions);

    customActions.append(loadingImg);

    torrentRows.push({
        row: $this,
        whatId: torrentId,
        actions: customActions
    });
}

if (window.location.href.replace('https', 'http').indexOf('https://bibliotik.me/uploads') == 0) {
    $('div#body > div.table_div > form > table > tbody > tr').each(processRow);
} else if (window.location.href.replace('https', 'http').indexOf('https://bibliotik.me/collections') == 0) {
    $('div#body div.table_div table > tbody > tr[id]').each(processRow);
} else {
    $('tr.torrent').each(processRow);
    $('p#details_links').each(processRow);
    setTimeout(function () {
        $('p#details_links').css('width', 110);
    }, 10);
}

if (torrentRows.length) {
    function refreshStatuses() {
        submitIds(torrentRows, processResult);
    }

    refreshStatuses();
    if (torrentRows.length < 256) {
        setInterval(refreshStatuses, 10000);
    }
}

unsafeWindow.wmGetAllTorrents = function () {
    $.each(torrentRows, function (i, row) {
        if (row.downloadLink) {
            downloadTorrent(row);
        }
    });
};
<commit_msg>Correcting an undefined variable<commit_after>// ==UserScript==
// @name Bibliotik.me / WM Integrator
// @namespace https://karamanolev.com
// @version 0.2.2
// @description Integration between WM and Bibliotik.me
// @match http://bibliotik.me/*
// @match https://bibliotik.me/*
// @grant GM_xmlhttpRequest
// @updateURL {{ root }}/userscript/bibliotik.user.js
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
// @require {{ root }}/static/js/jquery.noty.packaged.min.js
// ==/UserScript==

var torrentsInfoUrl = '{{ root }}/books/bibliotik/json/torrents_info';
var addTorrentUrl = '{{ root }}/books/bibliotik/json/add/';
var downloadUrl = '{{ root }}/download/zip/bibliotik/';

$.noty.defaults.timeout = 5000;
var loadingImg = '<img class="loading-img" src="data:image/gif;base64,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" width="12" height="12" valign="middle" />';
function formatResponseError(response) {
    if (response.statusText) {
        return response.statusText;
    }
    return "Unknown network error.";
}

function submitIds(rows, callback) {
    setTimeout(function () {
        var ids = [];
        for (var i in rows) ids.push(rows[i].whatId);
        var idsString = 'ids=' + encodeURIComponent(ids.join(','));
        GM_xmlhttpRequest({
            method: "GET",
            url: torrentsInfoUrl + '?' + idsString,
            onload: function (response) {
                callback($.parseJSON(response.responseText));
            },
            onerror: function (response) {
                debugger;
                noty({
                    text: 'Error loading WM data: ' + formatResponseError(response),
                    type: 'error'
                });
            }
        });
    }, 0);
}

function stealBibliotikSessionId(callback) {
    var extensionId = "opapngdimmnncheoehlpdnceakheghcn";
    var timeoutID = setTimeout(function () {
        noty({
            text: 'Please make sure the extension is installed and working.',
            type: 'error'
        });
    }, 1500);
    chrome.runtime.sendMessage(extensionId, "stealBibliotikId", function (response) {
        clearTimeout(timeoutID);
        if (response == null) {
            noty({
                text: 'The extension could not find the session ID. Make sure you are logged in Bibliotik.',
                type: 'error'
            });
        }
        callback(response);
    });
}

function addTorrent(torrentId, callback) {
    stealBibliotikSessionId(function (sessionId) {
        var params = encodeURIComponent(torrentId) + '?';
        params += 'bibliotik_id=' + encodeURIComponent(sessionId);
        GM_xmlhttpRequest({
            method: "GET",
            url: addTorrentUrl + params,
            onload: function (response) {
                callback($.parseJSON(response.responseText));
            },
            onerror: function (response) {
                callback({
                    success: false,
                    error: formatResponseError(response)
                });
            }
        });
    });
}

function getId(link) {
    var regexps = [
        /torrents\/(\d+)\/download/
    ];
    var result = null;
    $.each(regexps, function (i, r) {
        var m = link.match(r);
        if (m !== null) {
            result = m[1];
        }
    });
    return result;
}

var torrentRows = [];

function downloadTorrent(row) {
    row.actions.html(loadingImg);
    row.isAdding = true;
    addTorrent(row.whatId, function (addResult) {
        var htmlTitle;
        row.isAdding = false;
        if (addResult.success) {
            htmlTitle = $('').text(addResult.title).prop('outerHTML');
            noty({
                text: 'Torrent ' + htmlTitle + ' added successfully!',
                type: 'success'
            });
            row.actions.text('OK');
        } else if (addResult.error_code == 'already_added') {
            htmlTitle = $('').text(addResult.title).prop('outerHTML');
            noty({
                text: 'Torrent ' + htmlTitle + ' already added!',
                type: 'warning'
            });
            row.actions.text('ERR');
        } else {
            noty({
                text: 'Error adding ' + row.whatId + ': ' + addResult.error,
                type: 'error'
            });
            row.actions.text('ERR');
        }
    });
}

function processResult(result) {
    $.each(result, function (i, resp) {
        var row = torrentRows[i];
        var link;

        if (row.isAdding) {
            return;
        }

        row.actions.empty();
        if (resp.status == 'downloaded') {
            // Download
            link = $('↓DL');
            row.actions.append(link);
        } else if (resp.status == 'downloading') {
            row.actions.text(Math.floor(resp.progress * 100) + '%');
        } else if (resp.status == 'missing') {
            // Add to WM

            link = $('GET');
            link.click(function (e) {
                e.preventDefault();
                if (confirm('Are you sure you want to download ' + resp.id + '?')) {
                    downloadTorrent(row);
                }
            });
            row.actions.append(' ');
            row.actions.append(link);
        } else {
            row.actions.text(result[i].status);
        }
    });
}

function processRow() {
    var $this = $(this);
    var link = $this.find('a[title="Download"]');
    if (!link.length) return;
    var actions = link.parent();
    actions.css('width', 50);
    var torrentId = getId(link.attr('href'));
    var customActions = $('');
    actions.append(customActions);

    customActions.append(loadingImg);

    torrentRows.push({
        row: $this,
        whatId: torrentId,
        actions: customActions
    });
}

if (window.location.href.replace('https', 'http').indexOf('https://bibliotik.me/uploads') == 0) {
    $('div#body > div.table_div > form > table > tbody > tr').each(processRow);
} else if (window.location.href.replace('https', 'http').indexOf('https://bibliotik.me/collections') == 0) {
    $('div#body div.table_div table > tbody > tr[id]').each(processRow);
} else {
    $('tr.torrent').each(processRow);
    $('p#details_links').each(processRow);
    setTimeout(function () {
        $('p#details_links').css('width', 110);
    }, 10);
}

if (torrentRows.length) {
    function refreshStatuses() {
        submitIds(torrentRows, processResult);
    }

    refreshStatuses();
    if (torrentRows.length < 256) {
        setInterval(refreshStatuses, 10000);
    }
}

unsafeWindow.wmGetAllTorrents = function () {
    $.each(torrentRows, function (i, row) {
        if (row.downloadLink) {
            downloadTorrent(row);
        }
    });
};
<|endoftext|>


<commit_before>import registerListeners from './register-listeners';

export default ({ request, files, instance, progress }) =>
  new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    instance(xhr);

    registerListeners({ xhr, resolve, progress });

    xhr.open(request.method || 'POST', request.url);
    xhr.withCredentials = request.withCredentials || false;

    if (request.headers) {
      Object.keys(request.headers).forEach(header =>
        xhr.setRequestHeader(header, request.headers[header]));
    }
    //send just the file if no fields or filename is set
    if (!request.fileName && !request.fields) return xhr.send(files[0]);

    var formData = new FormData();
    Array.from(files).forEach(file =>
      formData.append(request.fileName || 'file', file));

    if (request.fields) {
      Object.keys(request.fields).forEach(field =>
        formData.append(field, request.fields[field]));
    }

    xhr.send(formData);
  });
<commit_msg>Append fields before files in FormData of request<commit_after>import registerListeners from './register-listeners';

export default ({ request, files, instance, progress }) =>
  new Promise(resolve => {
    const xhr = new XMLHttpRequest();
    instance(xhr);

    registerListeners({ xhr, resolve, progress });

    xhr.open(request.method || 'POST', request.url);
    xhr.withCredentials = request.withCredentials || false;

    if (request.headers) {
      Object.keys(request.headers).forEach(header =>
        xhr.setRequestHeader(header, request.headers[header]));
    }
    //send just the file if no fields or filename is set
    if (!request.fileName && !request.fields) return xhr.send(files[0]);

    var formData = new FormData();

    //append fields first, fixes https://github.com/expressjs/multer/issues/322
    if (request.fields) {
      Object.keys(request.fields).forEach(field =>
        formData.append(field, request.fields[field]));
    }

    Array.from(files).forEach(file =>
      formData.append(request.fileName || 'file', file));

    xhr.send(formData);
  });
<|endoftext|>


<commit_before>import test from 'ava';
import findPatterns from '../source/find-patterns';

test('when calling find-patterns', t => {
	const actual = findPatterns();
	t.ok(typeof actual.then === 'function', 'it should return a promise');
});

test('when calling with no arguments', t => {
	const actual = findPatterns();
	t.throws(actual, TypeError, 'it should throw a TypeError');
});
<commit_msg>test(find-patterns): merge test cases<commit_after>import test from 'ava';
import findPatterns from '../source/find-patterns';

test('when calling find-patterns with no arguments', t => {
	const actual = findPatterns();
	t.throws(actual, TypeError, 'it should throw a TypeError');
});
<|endoftext|>


<commit_before>var R = require('..');
var eq = require('./shared/eq');

describe('findLastIndex', function() {
  var obj1 = {x: 100};
  var obj2 = {x: 200};
  var a = [11, 10, 9, 'cow', obj1, 8, 7, 100, 200, 300, obj2, 4, 3, 2, 1, 0];
  var even = function(x) { return x % 2 === 0; };
  var gt100 = function(x) { return x > 100; };
  var isStr = function(x) { return typeof x === 'string'; };
  var xGt100 = function(o) { return o && o.x > 100; };
  var intoArray = R.into([]);

  it('returns the index of the last element that satisfies the predicate', function() {
    eq(R.findLastIndex(even, a), 15);
    eq(R.findLastIndex(gt100, a), 9);
    eq(R.findLastIndex(isStr, a), 3);
    eq(R.findLastIndex(xGt100, a), 10);
  });

  it('returns -1 when no element satisfies the predicate', function() {
    eq(R.findLastIndex(even, ['zing']), -1);
  });

  it('returns the index of the last element into an array that satisfies the predicate', function() {
    eq(intoArray(R.findLastIndex(even), a), [15]);
    eq(intoArray(R.findLastIndex(gt100), a), [9]);
    eq(intoArray(R.findLastIndex(isStr), a), [3]);
    eq(intoArray(R.findLastIndex(xGt100), a), [10]);
  });

  it('returns -1 into an array when no element satisfies the predicate', function() {
    eq(intoArray(R.findLastIndex(even), ['zing']), [-1]);
  });

  it('works when the first element matches', function() {
    eq(R.findLastIndex(even, [2, 3, 5]), 0);
  });

  it('does not go into an infinite loop on an empty array', function() {
    eq(R.findLastIndex(even, []), -1);
  });

  it('is curried', function() {
    eq(typeof R.findLastIndex(even), 'function');
    eq(R.findLastIndex(even)(a), 15);
  });

});
<commit_msg>Add transfomer and transducer tests for findLastIndex<commit_after>var R = require('..');
var eq = require('./shared/eq');
var listXf = require('./helpers/listXf');

describe('findLastIndex', function() {
  var obj1 = {x: 100};
  var obj2 = {x: 200};
  var a = [11, 10, 9, 'cow', obj1, 8, 7, 100, 200, 300, obj2, 4, 3, 2, 1, 0];
  var even = function(x) { return x % 2 === 0; };
  var gt100 = function(x) { return x > 100; };
  var isStr = function(x) { return typeof x === 'string'; };
  var xGt100 = function(o) { return o && o.x > 100; };
  var intoArray = R.into([]);

  it('returns the index of the last element that satisfies the predicate', function() {
    eq(R.findLastIndex(even, a), 15);
    eq(R.findLastIndex(gt100, a), 9);
    eq(R.findLastIndex(isStr, a), 3);
    eq(R.findLastIndex(xGt100, a), 10);
  });

  it('returns -1 when no element satisfies the predicate', function() {
    eq(R.findLastIndex(even, ['zing']), -1);
  });

  it('returns the index of the last element into an array that satisfies the predicate', function() {
    eq(intoArray(R.findLastIndex(even), a), [15]);
    eq(intoArray(R.findLastIndex(gt100), a), [9]);
    eq(intoArray(R.findLastIndex(isStr), a), [3]);
    eq(intoArray(R.findLastIndex(xGt100), a), [10]);
  });

  it('returns -1 into an array when no element satisfies the predicate', function() {
    eq(intoArray(R.findLastIndex(even), ['zing']), [-1]);
  });

  it('works when the first element matches', function() {
    eq(R.findLastIndex(even, [2, 3, 5]), 0);
  });

  it('does not go into an infinite loop on an empty array', function() {
    eq(R.findLastIndex(even, []), -1);
  });

  it('is curried', function() {
    eq(typeof R.findLastIndex(even), 'function');
    eq(R.findLastIndex(even)(a), 15);
  });

  it('can act as a transducer', function() {
    var numbers = [0,5,0,5];
    var idx = 3;
    var val = 5;

    var xf = R.compose(R.identity, R.findLastIndex(R.equals(val)));

    eq(R.into([], xf, numbers), [idx]);
  });

  it('dispatches to transformer objects', function() {
    eq(R.findLastIndex(R.identity, listXf), {
      f: R.identity,
      idx: -1,
      lastIdx: -1,
      xf: listXf
    });
  });

});
<|endoftext|>


<commit_before>var baseUrl = "http://marihachi.php.xdomain.jp/crystal-resonance";
$(function() {
	// ログイン処理
	$('#login-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/login", {
			type: 'post',
			data: $('#login-form').serialize(),
			dataType: 'json',
		}).done(function() {
			location.reload();
		}).fail(function() {
			$('#log-message').text("ログインに失敗しました");
		});
	});

	// ログアウト処理
	$('#logout-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/logout", {
			type: 'get',
			dataType: 'json',
		}).done(function() {
			location.reload();
		}).fail(function() {
			$('#log-message').text("ログアウトに失敗しました");
		});
	});

	$('#signup-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/create", {
			type: 'post',
			data: $(this).serialize(),
			dataType: 'json',
		}).done(function() {
			location.href = "../";
		}).fail(function() {
			$('#log-message').text("サインアップに失敗しました");
		});
	});
});<commit_msg>Fix destination at create account<commit_after>var baseUrl = "http://marihachi.php.xdomain.jp/crystal-resonance";
$(function() {
	// ログイン処理
	$('#login-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/login", {
			type: 'post',
			data: $('#login-form').serialize(),
			dataType: 'json',
		}).done(function() {
			location.reload();
		}).fail(function() {
			$('#log-message').text("ログインに失敗しました");
		});
	});

	// ログアウト処理
	$('#logout-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/logout", {
			type: 'get',
			dataType: 'json',
		}).done(function() {
			location.reload();
		}).fail(function() {
			$('#log-message').text("ログアウトに失敗しました");
		});
	});

	$('#signup-form').submit(function(e) {
		e.preventDefault();
		$.ajax(baseUrl + "/api/account/create", {
			type: 'post',
			data: $(this).serialize(),
			dataType: 'json',
		}).done(function() {
			location.href = baseUrl;
		}).fail(function() {
			$('#log-message').text("サインアップに失敗しました");
		});
	});
});<|endoftext|>


<commit_before>describe('flatten array', function () {
  it('should flatten an array', function () {
    var tmpArray = [],
        arr = [1, 2, [1, 2, [3, 4, 5, [1]]], 2, [2]],
        expected = [1, 1, 1, 2, 2, 2, 2, 3, 4, 5];

   function go(arra) {
      var self = arguments.callee;

      arra.forEach(function (item) {
        if(typeof item === 'object') {
          self(item);
        } else {
          tmpArray.push(item);
         }
      });

      return tmpArray;
    }
    arr =  go(arr).sort();

    expect(arr).toEqual(expected);
  });
});

<commit_msg>Renamed<commit_after>describe('flatten array', function () {
  it('should flatten an array', function () {
    var tmpArray = [],
        arr = [1, 2, [1, 2, [3, 4, 5, [1]]], 2, [2]],
        expected = [1, 1, 1, 2, 2, 2, 2, 3, 4, 5];

   function flatten(arr) {
      var self = arguments.callee;

      arr.forEach(function (item) {
        if(typeof item === 'object') {
          self(item);
        } else {
          tmpArray.push(item);
         }
      });

      return tmpArray;
    }
    arr =  flatten(arr).sort();

    expect(arr).toEqual(expected);
  });
});

<|endoftext|>