<commit_before>/*
| -------------------------------------------------------------------
|  GEXF Parser Tests
| -------------------------------------------------------------------
|
|
| Author : PLIQUE Guillaume (Yomguithereal)
| Version : 1.0
*/

(function() {

  // Helpers
  //---------

  Object.prototype.testBasics = function(basics) {

    // Root information
    strictEqual(this.version, basics.version, 'Version is retrieved.');
    strictEqual(this.mode, basics.mode, 'Mode is retrieved.');
    strictEqual(
      this.defaultEdgeType,
      basics.defaultEdgeType,
      'DefaultEdgeType is retrieved.'
    );

    // Meta
    deepEqual(
      this.meta,
      basics.meta,
      'Meta information is retrieved.'
    );

    // Node Model
    deepEqual(
      this.model.node,
      basics.model,
      'Node model correctly retrieved.'
    );

    // Edge Model
    deepEqual(
      this.model.edge,
      basics.edgeModel,
      'Edge model correctly retrieved.'
    );

    // Nodes
    strictEqual(this.nodes.length, basics.nodes_nb, 'All nodes retrieved.');
    deepEqual(
      this.nodes[basics.node_test.id],
      basics.node_test.node,
      'Node test passed.'
    );

    // Edges
    strictEqual(this.edges.length, basics.edges_nb, 'All edges retrieved.');
    deepEqual(
      this.edges[basics.edge_test.id],
      basics.edge_test.edge,
      'Edge test passed.'
    );
  };

  // Tests
  //-------
  var tests = [
    {
      title: 'Minimal Graph',
      gexf: 'minimal',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gexf.net',
          description: 'A hello world! file',
          lastmodifieddate: '2009-03-20'
        },
        model: [],
        edgeModel: [],
        nodes_nb: 2,
        node_test: {
          id: 0,
          node: {
            id: '0',
            label: 'Hello',
            attributes: {}
          }
        },
        edges_nb: 1,
        edge_test: {
          id: 0,
          edge: {
            id: '0',
            label: '',
            attributes: {},
            source: '0',
            target: '1',
            type: 'directed',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Basic Graph',
      gexf: 'yeast',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [],
        edgeModel: [],
        nodes_nb: 2361,
        node_test: {
          id: 502,
          node: {
            attributes: {},
            id: '5443',
            label: 'YDR283C'
          }
        },
        edges_nb: 7182,
        edge_test: {
          id: 1300,
          edge: {
            id: '14488',
            label: '',
            attributes: {},
            source: '5096',
            target: '6882',
            type: 'undirected',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Data Graph',
      gexf: 'data',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gephi.org',
          description: 'A Web network',
          lastmodifieddate: '2009-03-20'
        },
        model: [
          {id: '0', title: 'url', type: 'string'},
          {id: '1', title: 'indegree', type: 'float'},
          {id: '2', title: 'frog', type: 'boolean', defaultValue: 'true'}
        ],
        edgeModel: [],
        nodes_nb: 4,
        node_test: {
          id: 1,
          node: {
            id: '1',
            label: 'Webatlas',
            attributes: {
              frog: true,
              indegree: 2,
              url: 'http://webatlas.fr'
            }
          }
        },
        edges_nb: 5,
        edge_test: {
          id: 3,
          edge: {
            id: '3',
            label: '',
            attributes: {},
            source: '2',
            target: '1',
            type: 'directed',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Viz Graph',
      gexf: 'arctic',
      basics: {
        version: '1.0',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [
          {id: '0', title: 'nodedef', type: 'string'},
          {id: '1', title: 'label', type: 'string'},
          {id: '2', title: 'occurrences', type: 'integer'}
        ],
        edgeModel: [],
        nodes_nb: 1715,
        node_test: {
          id: 1100,
          node: {
            id: '1102',
            label: 'Interglacial Period',
            attributes: {
              label: 'Interglacial Period',
              nodedef: 'n1102',
              occurrences: 3
            },
            viz: {
              color: 'rgb(153,255,255)',
              position: {
                x: -31.175037,
                y: 179.857,
                z: 0
              },
              size: 3.6317973
            }
          }
        },
        edges_nb: 6676,
        edge_test: {
          id: 305,
          edge: {
            id: '305',
            label: '',
            attributes: {},
            source: '263',
            target: '113',
            type: 'undirected',
            weight: 1,
            viz: {}
          }
        }
      }
    },
    {
      title: 'Celegans Graph',
      gexf: 'celegans',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [],
        edgeModel: [],
        nodes_nb: 306,
        node_test: {
          id: 203,
          node: {
            id: '281',
            label: '282',
            attributes: {}
          }
        },
        edges_nb: 2345,
        edge_test: {
          id: 1602,
          edge: {
            id: '285',
            label: '',
            attributes: {},
            source: '38',
            target: '302',
            type: 'undirected',
            weight: 2
          }
        }
      }
    },
    {
      title: 'Les Misérables Graph',
      gexf: 'les_miserables',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'ofNodesAndEdges.com',
          title: 'Les Misérables, the characters coappearance weighted graph',
          lastmodifieddate: '2010-05-29+01:27'
        },
        model: [
          {id: 'authority', title: 'Authority', type: 'float'},
          {id: 'hub', title: 'Hub', type: 'float'}
        ],
        edgeModel: [],
        nodes_nb: 77,
        node_test: {
          id: 5,
          node: {
            id: '5.0',
            label: 'Geborand',
            attributes: {
              authority: 0.0034188034,
              hub: 0.0034188034
            },
            viz: {
              color: 'rgb(179,0,0)',
              position: {
                x: 318.6509,
                y: 85.41602,
                z: 0
              },
              size: 15
            }
          }
        },
        edges_nb: 254,
        edge_test: {
          id: 200,
          edge: {
            id: '198',
            label: '',
            attributes: {},
            source: '66.0',
            target: '62.0',
            type: 'directed',
            weight: 2,
            viz: {}
          }
        }
      }
    },
    {
      title: 'Edge Viz Graph',
      gexf: 'edge_viz',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Yomguithereal',
          title: 'An edge viz test graph',
          lastmodifieddate: '2010-05-29+01:27'
        },
        model: [
          {id: 'authority', title: 'Authority', type: 'float'},
          {id: 'hub', title: 'Hub', type: 'float'}
        ],
        edgeModel: [],
        nodes_nb: 2,
        node_test: {
          id: 0,
          node: {
            id: '0.0',
            label: 'Myriel',
            attributes: {
              authority: 0.01880342,
              hub: 0.01880342
            },
            viz: {
              color: 'rgb(216,72,45)',
              position: {
                x: 268.72385,
                y: 91.18155,
                z: 0
              },
              size: 22.714287
            }
          }
        },
        edges_nb: 1,
        edge_test: {
          id: 0,
          edge: {
            id: '0',
            label: '',
            attributes: {},
            source: '1.0',
            target: '0.0',
            type: 'directed',
            weight: 1,
            viz: {
              color: 'rgba(179,0,0,0.5)',
              thickness: 2,
              shape: 'dotted'
            }
          }
        }
      }
    },
    {
      title: 'Edge Data Graph',
      gexf: 'edge_data',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gephi.org',
          description: 'A Web network',
          lastmodifieddate: '2009-03-20'
        },
        model: [
          {id: '0', title: 'url', type: 'string'},
          {id: '1', title: 'indegree', type: 'float'},
          {id: '2', title: 'frog', type: 'boolean', defaultValue: 'true'}
        ],
        edgeModel: [
          {id: 'predicate', title: 'Predicate', type: 'string', defaultValue: 'likes'},
          {id: 'confidence', title: 'Confidence', type: 'float'}
        ],
        nodes_nb: 4,
        node_test: {
          id: 1,
          node: {
            id: '1',
            label: 'Webatlas',
            attributes: {
              frog: true,
              indegree: 2,
              url: 'http://webatlas.fr'
            },
            viz: {}
          }
        },
        edges_nb: 5,
        edge_test: {
          id: 3,
          edge: {
            id: '3',
            label: '',
            attributes: {
              predicate: 'likes',
              confidence: 0.88
            },
            source: '2',
            target: '1',
            type: 'directed',
            weight: 1,
            viz: {}
          }
        }
      }
    }
  ];

  // Running actual tests
  module('Parser');
  tests.map(function(t) {

    asyncTest(t.title, function() {
      GexfParser.fetch(
        'resources/' + t.gexf + '.gexf',
        function(graph) {
          start();
          // graph.title = t.title;
          graph.testBasics(t.basics);
        }
      );
    });
  });

  module('API');
  asyncTest('GexfParser.fetch', function() {
    var g2,
        g1 = GexfParser.fetch('resources/minimal.gexf');

    GexfParser.fetch('resources/minimal.gexf', function(graph) {
      g2 = graph;
      start();
      deepEqual(g1, g2, 'GexfParser.fetch works the same in both sync and async modes.');
    });
  });
  test('GexfParser.parse', function() {
    var xhr = (function() {
      if (window.XMLHttpRequest)
        return new XMLHttpRequest();

      var names,
          i;

      if (window.ActiveXObject) {
        names = [
          'Msxml2.XMLHTTP.6.0',
          'Msxml2.XMLHTTP.3.0',
          'Msxml2.XMLHTTP',
          'Microsoft.XMLHTTP'
        ];

        for (i in names)
          try {
            return new ActiveXObject(names[i]);
          } catch (e) {}
      }

      return null;
    })();

    if (!xhr)
      throw 'XMLHttpRequest not supported, cannot load the file.';

    if (xhr.overrideMimeType)
      xhr.overrideMimeType('text/xml');
    xhr.open('GET', 'resources/minimal.gexf', false);
    xhr.send();

    var gexf = xhr.responseXML,
        graph = GexfParser.parse(gexf);

    graph.testBasics(tests[0].basics);
  });
})();
<commit_msg>Fixing edge data test<commit_after>/*
| -------------------------------------------------------------------
|  GEXF Parser Tests
| -------------------------------------------------------------------
|
|
| Author : PLIQUE Guillaume (Yomguithereal)
| Version : 1.0
*/

(function() {

  // Helpers
  //---------

  Object.prototype.testBasics = function(basics) {

    // Root information
    strictEqual(this.version, basics.version, 'Version is retrieved.');
    strictEqual(this.mode, basics.mode, 'Mode is retrieved.');
    strictEqual(
      this.defaultEdgeType,
      basics.defaultEdgeType,
      'DefaultEdgeType is retrieved.'
    );

    // Meta
    deepEqual(
      this.meta,
      basics.meta,
      'Meta information is retrieved.'
    );

    // Node Model
    deepEqual(
      this.model.node,
      basics.model,
      'Node model correctly retrieved.'
    );

    // Edge Model
    deepEqual(
      this.model.edge,
      basics.edgeModel,
      'Edge model correctly retrieved.'
    );

    // Nodes
    strictEqual(this.nodes.length, basics.nodes_nb, 'All nodes retrieved.');
    deepEqual(
      this.nodes[basics.node_test.id],
      basics.node_test.node,
      'Node test passed.'
    );

    // Edges
    strictEqual(this.edges.length, basics.edges_nb, 'All edges retrieved.');
    deepEqual(
      this.edges[basics.edge_test.id],
      basics.edge_test.edge,
      'Edge test passed.'
    );
  };

  // Tests
  //-------
  var tests = [
    {
      title: 'Minimal Graph',
      gexf: 'minimal',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gexf.net',
          description: 'A hello world! file',
          lastmodifieddate: '2009-03-20'
        },
        model: [],
        edgeModel: [],
        nodes_nb: 2,
        node_test: {
          id: 0,
          node: {
            id: '0',
            label: 'Hello',
            attributes: {}
          }
        },
        edges_nb: 1,
        edge_test: {
          id: 0,
          edge: {
            id: '0',
            label: '',
            attributes: {},
            source: '0',
            target: '1',
            type: 'directed',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Basic Graph',
      gexf: 'yeast',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [],
        edgeModel: [],
        nodes_nb: 2361,
        node_test: {
          id: 502,
          node: {
            attributes: {},
            id: '5443',
            label: 'YDR283C'
          }
        },
        edges_nb: 7182,
        edge_test: {
          id: 1300,
          edge: {
            id: '14488',
            label: '',
            attributes: {},
            source: '5096',
            target: '6882',
            type: 'undirected',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Data Graph',
      gexf: 'data',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gephi.org',
          description: 'A Web network',
          lastmodifieddate: '2009-03-20'
        },
        model: [
          {id: '0', title: 'url', type: 'string'},
          {id: '1', title: 'indegree', type: 'float'},
          {id: '2', title: 'frog', type: 'boolean', defaultValue: 'true'}
        ],
        edgeModel: [],
        nodes_nb: 4,
        node_test: {
          id: 1,
          node: {
            id: '1',
            label: 'Webatlas',
            attributes: {
              frog: true,
              indegree: 2,
              url: 'http://webatlas.fr'
            }
          }
        },
        edges_nb: 5,
        edge_test: {
          id: 3,
          edge: {
            id: '3',
            label: '',
            attributes: {},
            source: '2',
            target: '1',
            type: 'directed',
            weight: 1
          }
        }
      }
    },
    {
      title: 'Viz Graph',
      gexf: 'arctic',
      basics: {
        version: '1.0',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [
          {id: '0', title: 'nodedef', type: 'string'},
          {id: '1', title: 'label', type: 'string'},
          {id: '2', title: 'occurrences', type: 'integer'}
        ],
        edgeModel: [],
        nodes_nb: 1715,
        node_test: {
          id: 1100,
          node: {
            id: '1102',
            label: 'Interglacial Period',
            attributes: {
              label: 'Interglacial Period',
              nodedef: 'n1102',
              occurrences: 3
            },
            viz: {
              color: 'rgb(153,255,255)',
              position: {
                x: -31.175037,
                y: 179.857,
                z: 0
              },
              size: 3.6317973
            }
          }
        },
        edges_nb: 6676,
        edge_test: {
          id: 305,
          edge: {
            id: '305',
            label: '',
            attributes: {},
            source: '263',
            target: '113',
            type: 'undirected',
            weight: 1,
            viz: {}
          }
        }
      }
    },
    {
      title: 'Celegans Graph',
      gexf: 'celegans',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'undirected',
        meta: {},
        model: [],
        edgeModel: [],
        nodes_nb: 306,
        node_test: {
          id: 203,
          node: {
            id: '281',
            label: '282',
            attributes: {}
          }
        },
        edges_nb: 2345,
        edge_test: {
          id: 1602,
          edge: {
            id: '285',
            label: '',
            attributes: {},
            source: '38',
            target: '302',
            type: 'undirected',
            weight: 2
          }
        }
      }
    },
    {
      title: 'Les Misérables Graph',
      gexf: 'les_miserables',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'ofNodesAndEdges.com',
          title: 'Les Misérables, the characters coappearance weighted graph',
          lastmodifieddate: '2010-05-29+01:27'
        },
        model: [
          {id: 'authority', title: 'Authority', type: 'float'},
          {id: 'hub', title: 'Hub', type: 'float'}
        ],
        edgeModel: [],
        nodes_nb: 77,
        node_test: {
          id: 5,
          node: {
            id: '5.0',
            label: 'Geborand',
            attributes: {
              authority: 0.0034188034,
              hub: 0.0034188034
            },
            viz: {
              color: 'rgb(179,0,0)',
              position: {
                x: 318.6509,
                y: 85.41602,
                z: 0
              },
              size: 15
            }
          }
        },
        edges_nb: 254,
        edge_test: {
          id: 200,
          edge: {
            id: '198',
            label: '',
            attributes: {},
            source: '66.0',
            target: '62.0',
            type: 'directed',
            weight: 2,
            viz: {}
          }
        }
      }
    },
    {
      title: 'Edge Viz Graph',
      gexf: 'edge_viz',
      basics: {
        version: '1.1',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Yomguithereal',
          title: 'An edge viz test graph',
          lastmodifieddate: '2010-05-29+01:27'
        },
        model: [
          {id: 'authority', title: 'Authority', type: 'float'},
          {id: 'hub', title: 'Hub', type: 'float'}
        ],
        edgeModel: [],
        nodes_nb: 2,
        node_test: {
          id: 0,
          node: {
            id: '0.0',
            label: 'Myriel',
            attributes: {
              authority: 0.01880342,
              hub: 0.01880342
            },
            viz: {
              color: 'rgb(216,72,45)',
              position: {
                x: 268.72385,
                y: 91.18155,
                z: 0
              },
              size: 22.714287
            }
          }
        },
        edges_nb: 1,
        edge_test: {
          id: 0,
          edge: {
            id: '0',
            label: '',
            attributes: {},
            source: '1.0',
            target: '0.0',
            type: 'directed',
            weight: 1,
            viz: {
              color: 'rgba(179,0,0,0.5)',
              thickness: 2,
              shape: 'dotted'
            }
          }
        }
      }
    },
    {
      title: 'Edge Data Graph',
      gexf: 'edge_data',
      basics: {
        version: '1.2',
        mode: 'static',
        defaultEdgeType: 'directed',
        meta: {
          creator: 'Gephi.org',
          description: 'A Web network',
          lastmodifieddate: '2009-03-20'
        },
        model: [
          {id: '0', title: 'url', type: 'string'},
          {id: '1', title: 'indegree', type: 'float'},
          {id: '2', title: 'frog', type: 'boolean', defaultValue: 'true'}
        ],
        edgeModel: [
          {id: 'predicate', title: 'Predicate', type: 'string', defaultValue: 'likes'},
          {id: 'confidence', title: 'Confidence', type: 'float'}
        ],
        nodes_nb: 4,
        node_test: {
          id: 1,
          node: {
            id: '1',
            label: 'Webatlas',
            attributes: {
              frog: true,
              indegree: 2,
              url: 'http://webatlas.fr'
            }
          }
        },
        edges_nb: 5,
        edge_test: {
          id: 3,
          edge: {
            id: '3',
            label: '',
            attributes: {
              predicate: 'likes',
              confidence: 0.88
            },
            source: '2',
            target: '1',
            type: 'directed',
            weight: 1
          }
        }
      }
    }
  ];

  // Running actual tests
  module('Parser');
  tests.map(function(t) {

    asyncTest(t.title, function() {
      GexfParser.fetch(
        'resources/' + t.gexf + '.gexf',
        function(graph) {
          start();
          // graph.title = t.title;
          graph.testBasics(t.basics);
        }
      );
    });
  });

  module('API');
  asyncTest('GexfParser.fetch', function() {
    var g2,
        g1 = GexfParser.fetch('resources/minimal.gexf');

    GexfParser.fetch('resources/minimal.gexf', function(graph) {
      g2 = graph;
      start();
      deepEqual(g1, g2, 'GexfParser.fetch works the same in both sync and async modes.');
    });
  });
  test('GexfParser.parse', function() {
    var xhr = (function() {
      if (window.XMLHttpRequest)
        return new XMLHttpRequest();

      var names,
          i;

      if (window.ActiveXObject) {
        names = [
          'Msxml2.XMLHTTP.6.0',
          'Msxml2.XMLHTTP.3.0',
          'Msxml2.XMLHTTP',
          'Microsoft.XMLHTTP'
        ];

        for (i in names)
          try {
            return new ActiveXObject(names[i]);
          } catch (e) {}
      }

      return null;
    })();

    if (!xhr)
      throw 'XMLHttpRequest not supported, cannot load the file.';

    if (xhr.overrideMimeType)
      xhr.overrideMimeType('text/xml');
    xhr.open('GET', 'resources/minimal.gexf', false);
    xhr.send();

    var gexf = xhr.responseXML,
        graph = GexfParser.parse(gexf);

    graph.testBasics(tests[0].basics);
  });
})();
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
/* eslint-env node */
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);

describe('Safari shim', () => {
  const shim = require('../../src/js/safari/safari_shim');
  let window;

  beforeEach(() => {
    window = {
      RTCPeerConnection: function() {}
    };
  });

  describe('shimStreamsAPI', () => {
    beforeEach(() => {
      window.RTCPeerConnection.prototype.addTrack = () => {};
      shim.shimLocalStreamsAPI(window);
      shim.shimRemoteStreamsAPI(window);
    });

    it('shimStreamsAPI existence', () => {
      const prototype = window.RTCPeerConnection.prototype;
      expect(prototype.addTrack.length).to.equal(2);
      expect(prototype.addStream.length).to.equal(1);
      expect(prototype.removeStream.length).to.equal(1);
      expect(prototype.getLocalStreams.length).to.equal(0);
      expect(prototype.getStreamById.length).to.equal(1);
      expect(prototype.getRemoteStreams.length).to.equal(0);
    });
    it('local streams API', () => {
      const pc = new window.RTCPeerConnection();
      pc.getSenders = () => {
        return [];
      };
      var stream = {id: 'id1', getTracks: () => {
        return [];
      }};
      expect(pc.getStreamById(stream.id)).to.equal(null);
      expect(pc.getLocalStreams().length).to.equal(0);
      expect(pc.getRemoteStreams().length).to.equal(0);

      pc.addStream(stream);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams()[0]).to.equal(stream);
      expect(pc.getRemoteStreams().length).to.equal(0);

      var stream2 = {id: 'id2', getTracks: stream.getTracks};
      pc.removeStream(stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams()[0]).to.equal(stream);

      pc.addTrack({}, stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getStreamById(stream2.id)).to.equal(stream2);
      expect(pc.getLocalStreams().length).to.equal(2);
      expect(pc.getLocalStreams()[0]).to.equal(stream);
      expect(pc.getLocalStreams()[1]).to.equal(stream2);

      pc.removeStream(stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams().length).to.equal(1);
      expect(pc.getLocalStreams()[0]).to.equal(stream);

      pc.removeStream(stream);
      expect(pc.getStreamById(stream.id)).to.equal(null);
      expect(pc.getLocalStreams().length).to.equal(0);
    });
  });

  describe('shimCallbacksAPI', () => {
    it('shimCallbacksAPI existence', () => {
      shim.shimCallbacksAPI(window);
      const prototype = window.RTCPeerConnection.prototype;
      expect(prototype.createOffer.length).to.equal(2);
      expect(prototype.createAnswer.length).to.equal(2);
      expect(prototype.setLocalDescription.length).to.equal(3);
      expect(prototype.setRemoteDescription.length).to.equal(3);
      expect(prototype.addIceCandidate.length).to.equal(3);
    });
  });

  ['createOffer', 'createAnswer'].forEach((method) => {
    describe('legacy ' + method + ' shim', () => {
      describe('options passing with', () => {
        let stub;
        beforeEach(() => {
          stub = sinon.stub();
          window.RTCPeerConnection.prototype[method] = stub;
          shim.shimCallbacksAPI(window);
        });

        it('no arguments', () => {
          const pc = new window.RTCPeerConnection();
          pc[method]();
          expect(stub).to.have.been.calledWith(undefined);
        });

        it('two callbacks', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null);
          expect(stub).to.have.been.calledWith(undefined);
        });

        it('a non-function first argument', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](1);
          expect(stub).to.have.been.calledWith(1);
        });

        it('two callbacks and options', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null, 1);
          expect(stub).to.have.been.calledWith(1);
        });

        it('two callbacks and two additional arguments', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null, 1, 2);
          expect(stub).to.have.been.calledWith(1);
        });
      });
    });
  });
});
<commit_msg>Using sinon.stub<commit_after>/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
/* eslint-env node */
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);

describe('Safari shim', () => {
  const shim = require('../../src/js/safari/safari_shim');
  let window;

  beforeEach(() => {
    window = {
      RTCPeerConnection: function() {}
    };
  });

  describe('shimStreamsAPI', () => {
    beforeEach(() => {
      window.RTCPeerConnection.prototype.addTrack = sinon.stub();
      shim.shimLocalStreamsAPI(window);
      shim.shimRemoteStreamsAPI(window);
    });

    it('shimStreamsAPI existence', () => {
      const prototype = window.RTCPeerConnection.prototype;
      expect(prototype.addTrack.length).to.equal(2);
      expect(prototype.addStream.length).to.equal(1);
      expect(prototype.removeStream.length).to.equal(1);
      expect(prototype.getLocalStreams.length).to.equal(0);
      expect(prototype.getStreamById.length).to.equal(1);
      expect(prototype.getRemoteStreams.length).to.equal(0);
    });
    it('local streams API', () => {
      const pc = new window.RTCPeerConnection();
      pc.getSenders = () => {
        return [];
      };
      var stream = {id: 'id1', getTracks: () => {
        return [];
      }};
      expect(pc.getStreamById(stream.id)).to.equal(null);
      expect(pc.getLocalStreams().length).to.equal(0);
      expect(pc.getRemoteStreams().length).to.equal(0);

      pc.addStream(stream);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams()[0]).to.equal(stream);
      expect(pc.getRemoteStreams().length).to.equal(0);

      var stream2 = {id: 'id2', getTracks: stream.getTracks};
      pc.removeStream(stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams()[0]).to.equal(stream);

      pc.addTrack({}, stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getStreamById(stream2.id)).to.equal(stream2);
      expect(pc.getLocalStreams().length).to.equal(2);
      expect(pc.getLocalStreams()[0]).to.equal(stream);
      expect(pc.getLocalStreams()[1]).to.equal(stream2);

      pc.removeStream(stream2);
      expect(pc.getStreamById(stream.id)).to.equal(stream);
      expect(pc.getLocalStreams().length).to.equal(1);
      expect(pc.getLocalStreams()[0]).to.equal(stream);

      pc.removeStream(stream);
      expect(pc.getStreamById(stream.id)).to.equal(null);
      expect(pc.getLocalStreams().length).to.equal(0);
    });
  });

  describe('shimCallbacksAPI', () => {
    it('shimCallbacksAPI existence', () => {
      shim.shimCallbacksAPI(window);
      const prototype = window.RTCPeerConnection.prototype;
      expect(prototype.createOffer.length).to.equal(2);
      expect(prototype.createAnswer.length).to.equal(2);
      expect(prototype.setLocalDescription.length).to.equal(3);
      expect(prototype.setRemoteDescription.length).to.equal(3);
      expect(prototype.addIceCandidate.length).to.equal(3);
    });
  });

  ['createOffer', 'createAnswer'].forEach((method) => {
    describe('legacy ' + method + ' shim', () => {
      describe('options passing with', () => {
        let stub;
        beforeEach(() => {
          stub = sinon.stub();
          window.RTCPeerConnection.prototype[method] = stub;
          shim.shimCallbacksAPI(window);
        });

        it('no arguments', () => {
          const pc = new window.RTCPeerConnection();
          pc[method]();
          expect(stub).to.have.been.calledWith(undefined);
        });

        it('two callbacks', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null);
          expect(stub).to.have.been.calledWith(undefined);
        });

        it('a non-function first argument', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](1);
          expect(stub).to.have.been.calledWith(1);
        });

        it('two callbacks and options', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null, 1);
          expect(stub).to.have.been.calledWith(1);
        });

        it('two callbacks and two additional arguments', () => {
          const pc = new window.RTCPeerConnection();
          pc[method](null, null, 1, 2);
          expect(stub).to.have.been.calledWith(1);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>//var Crawler = require('../../lib/crawler').Crawler;
//var _ = require('underscore');
//
//QUnit.module('links');
//
//var DEBUG = true;
//var MOCKPORT = 30045;
//
//
//test('links resolve to absolute urls', function() {
//    expect(2);
//    stop();
//
//    var c = new Crawler({
//        debug: DEBUG,
//        timeout: 500,
//        retryTimeout: 1000,
//        retries: 1,
//        onDrain: function() {
//            start();
//        }
//    });
//
//    c.queue([{
//        uri: 'http://127.0.0.1:' + MOCKPORT + '/mockfiles/links1.html',
//        callback: function(error, result, $) {
//
//            var links = _.map($('a'), function(a) {
//                return a.href;
//            });
//
//            //Both links should be resolve to absolute URLs
//            equal(links[0],'http://127.0.0.1:30045/mockfiles/links2.html');
//            equal(links[1],'http://127.0.0.1:30045/mockfiles/links2.html');
//        }
//    }]);
//});
//
//test("relative links resolve to absolute urls after redirect", function() {
//    expect( 1 );
//
//    stop();
//
//    var c = new Crawler({
//        "debug":DEBUG,
//        "timeout":500,
//        "retryTimeout":1000,
//        "retries":1,
//        "onDrain":function() {
//            start();
//        }
//    });
//
//    c.queue([{
//        "uri":"http://127.0.0.1:"+MOCKPORT+"/redirect/links2.html",
//        "callback":function(error,result,$) {
//
//            var links = _.map($("a"),function(a) {
//                return a.href;
//            });
//
//            // relative link should be resolve to correct absolute URL
//            equal(links[0],"http://127.0.0.1:"+MOCKPORT+"/mockfiles/links1.html");
//        }
//    }]);
//});<commit_msg>Write mocha chai test for links<commit_after>var Crawler = require('../../lib/crawler').Crawler;
var expect = require('chai').expect;
var _ = require('underscore');
var httpbinHost = 'httpbin.org';
var c;

describe("Links", function() {
    beforeEach(function() {
        c = new Crawler({
            forceUTF8: true
        });
    });
    it('should resolved links to absolute urls', function(done) {
        c.queue([{
            uri : 'http://'+httpbinHost+'/links/3/0',
            callback: function(error, result, $) {

                var links = _.map($('a'), function(a) {
                    return a.href;
                });
                //Both links should be resolve to absolute URLs
                expect(links[0]).to.equal('http://'+httpbinHost+'/links/3/1');
                expect(links[1]).to.equal('http://'+httpbinHost+'/links/3/2');
                expect(error).to.be.null;
                done();
            }
        }]);
    });
    it('should resolved links to absolute urls after redirect', function(done) {
        c.queue([{
            uri : 'http://'+httpbinHost+'/redirect-to?url=http://example.com/',
            callback: function(error, result, $) {

                expect(result.uri).to.equal('http://example.com/');
                expect(error).to.be.null;
                done();
            }
        }]);
    });
});<|endoftext|>


<commit_before>'use strict';

module.exports = {
	allTopCharts: require(__dirname + '/allTopCharts.test.js'),
	categoryTopcharts: require(__dirname + '/categoryTopcharts.test.js'),
	hotTrends: require(__dirname + '/hotTrends.test.js'),
	hotTrendsDetail: require(__dirname + '/hotTrendsDetail.test.js'),
	top30in30: require(__dirname + '/top30in30.test.js'),
	topRelated: require(__dirname + '/topRelated.test.js'),
};<commit_msg>fixing typo in categoryTopCharts<commit_after>'use strict';

module.exports = {
	allTopCharts: require(__dirname + '/allTopCharts.test.js'),
	categoryTopcharts: require(__dirname + '/categoryTopCharts.test.js'),
	hotTrends: require(__dirname + '/hotTrends.test.js'),
	hotTrendsDetail: require(__dirname + '/hotTrendsDetail.test.js'),
	top30in30: require(__dirname + '/top30in30.test.js'),
	topRelated: require(__dirname + '/topRelated.test.js'),
};<|endoftext|>


<commit_before>var assert = require('assert');
var bn = require('bn.js');
var bcoin = require('../');

describe('Wallet', function() {
  it('should generate new key and address', function() {
    var w = bcoin.wallet();
    var addr = w.getAddress();
    assert(addr);
    assert(bcoin.wallet.validateAddress(addr));
  });

  it('should validate existing address', function() {
    assert(bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
  });

  it('should fail to validate invalid address', function() {
    assert(!bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
  });

  it('should sign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        address: w.getAddress()
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    w.sign(tx);
    assert(tx.verify());
  });

  it('should multisign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        minSignatures: 1,
        address: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    var maxSize = tx.maxSize();
    w.sign(tx);
    assert(tx.render().length <= maxSize);
    assert(tx.verify());
  });

  it('should have TX pool and be serializable', function() {
    var w = bcoin.wallet();
    var f = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
    w.sign(t1);
    var t2 = bcoin.tx().input(t1, 0)
                       .out(w, 24000)
                       .out(w, 24000);
    w.sign(t2);
    var t3 = bcoin.tx().input(t1, 1)
                       .input(t2, 0)
                       .out(w, 23000);
    w.sign(t3);
    var t4 = bcoin.tx().input(t2, 1)
                       .input(t3, 0)
                       .out(w, 11000)
                       .out(w, 11000);
    w.sign(t4);
    var f1 = bcoin.tx().input(t4, 1)
                       .out(f, 10000);
    w.sign(f1);
    var fake = bcoin.tx().input(t1, 1)
                         .out(w, 500);

    // Just for debugging
    t1.hint = 't1';
    t2.hint = 't2';
    t3.hint = 't3';
    t4.hint = 't4';
    f1.hint = 'f1';
    fake.hint = 'fake';

    // Fake TX should temporarly change output
    w.addTX(fake);

    w.addTX(t4);
    assert.equal(w.balance().toString(10), '22500');
    w.addTX(t1);
    assert.equal(w.balance().toString(10), '73000');
    w.addTX(t2);
    assert.equal(w.balance().toString(10), '47000');
    w.addTX(t3);
    assert.equal(w.balance().toString(10), '22000');
    w.addTX(f1);
    assert.equal(w.balance().toString(10), '11000');
    assert(w.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));

    var w2 = bcoin.wallet.fromJSON(w.toJSON());
    assert.equal(w2.balance().toString(10), '11000');
    assert(w2.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));
  });

  it('should fill tx with inputs', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);

    // Fake TX should temporarly change output
    w1.addTX(t1);

    // Create new transaction
    var t2 = bcoin.tx().out(w2, 5460);
    w1.fill(t2, function(err) {
      assert(!err);
      assert(t2.verify());

      assert.equal(t2.funds('in').toString(10), 16380);
      assert.equal(t2.funds('out').toString(10), 6380);

      // Create new transaction
      var t3 = bcoin.tx().out(w2, 15000);
      w1.fill(t3, function(err) {
        assert(err);
        assert.equal(err.minBalance.toString(10), 25000);

        cb();
      });
    });
  });
});
<commit_msg>test: add test for signing multiple inputs with different keys.<commit_after>var assert = require('assert');
var bn = require('bn.js');
var bcoin = require('../');

describe('Wallet', function() {
  it('should generate new key and address', function() {
    var w = bcoin.wallet();
    var addr = w.getAddress();
    assert(addr);
    assert(bcoin.wallet.validateAddress(addr));
  });

  it('should validate existing address', function() {
    assert(bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
  });

  it('should fail to validate invalid address', function() {
    assert(!bcoin.wallet.validateAddress('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
  });

  it('should sign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        address: w.getAddress()
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    w.sign(tx);
    assert(tx.verify());
  });

  it('should multisign/verify TX', function() {
    var w = bcoin.wallet();

    // Input transcation
    var src = bcoin.tx({
      outputs: [{
        value: 5460 * 2,
        minSignatures: 1,
        address: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
      }, {
        value: 5460 * 2,
        address: w.getAddress() + 'x'
      }]
    });
    assert(w.ownOutput(src));
    assert.equal(w.ownOutput(src).reduce(function(acc, out) {
      return acc.iadd(out.value);
    }, new bn(0)).toString(10), 5460 * 2);

    var tx = bcoin.tx()
      .input(src, 0)
      .out(w.getAddress(), 5460);

    var maxSize = tx.maxSize();
    w.sign(tx);
    assert(tx.render().length <= maxSize);
    assert(tx.verify());
  });

  it('should have TX pool and be serializable', function() {
    var w = bcoin.wallet();
    var f = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
    w.sign(t1);
    var t2 = bcoin.tx().input(t1, 0)
                       .out(w, 24000)
                       .out(w, 24000);
    w.sign(t2);
    var t3 = bcoin.tx().input(t1, 1)
                       .input(t2, 0)
                       .out(w, 23000);
    w.sign(t3);
    var t4 = bcoin.tx().input(t2, 1)
                       .input(t3, 0)
                       .out(w, 11000)
                       .out(w, 11000);
    w.sign(t4);
    var f1 = bcoin.tx().input(t4, 1)
                       .out(f, 10000);
    w.sign(f1);
    var fake = bcoin.tx().input(t1, 1)
                         .out(w, 500);

    // Just for debugging
    t1.hint = 't1';
    t2.hint = 't2';
    t3.hint = 't3';
    t4.hint = 't4';
    f1.hint = 'f1';
    fake.hint = 'fake';

    // Fake TX should temporarly change output
    w.addTX(fake);

    w.addTX(t4);
    assert.equal(w.balance().toString(10), '22500');
    w.addTX(t1);
    assert.equal(w.balance().toString(10), '73000');
    w.addTX(t2);
    assert.equal(w.balance().toString(10), '47000');
    w.addTX(t3);
    assert.equal(w.balance().toString(10), '22000');
    w.addTX(f1);
    assert.equal(w.balance().toString(10), '11000');
    assert(w.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));

    var w2 = bcoin.wallet.fromJSON(w.toJSON());
    assert.equal(w2.balance().toString(10), '11000');
    assert(w2.all().some(function(tx) {
      return tx.hash('hex') === f1.hash('hex');
    }));
  });

  it('should fill tx with inputs', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);

    // Fake TX should temporarly change output
    w1.addTX(t1);

    // Create new transaction
    var t2 = bcoin.tx().out(w2, 5460);
    w1.fill(t2, function(err) {
      assert(!err);
      assert(t2.verify());

      assert.equal(t2.funds('in').toString(10), 16380);
      assert.equal(t2.funds('out').toString(10), 6380);

      // Create new transaction
      var t3 = bcoin.tx().out(w2, 15000);
      w1.fill(t3, function(err) {
        assert(err);
        assert.equal(err.minBalance.toString(10), 25000);

        cb();
      });
    });
  });

  it('should sign multiple inputs using different keys', function(cb) {
    var w1 = bcoin.wallet();
    var w2 = bcoin.wallet();
    var to = bcoin.wallet();

    // Coinbase
    var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);
    // Fake TX should temporarly change output
    w1.addTX(t1);
    // Coinbase
    var t2 = bcoin.tx().out(w2, 5460).out(w2, 5460).out(w2, 5460).out(w2, 5460);
    // Fake TX should temporarly change output
    w2.addTX(t2);

    // Create our tx with an output
    var tx = bcoin.tx();
    tx.out(to, 5460);

    var cost = tx.funds('out');
    var total = cost.add(new bn(w1.fee));

    var unspent1 = w1.unspent();
    var unspent2 = w2.unspent();

    // Add dummy output (for `left`) to calculate maximum TX size
    tx.out(w1, new bn(0));

    // Add our unspent inputs to sign
    tx.input(unspent1[0]);
    tx.input(unspent1[1]);
    tx.input(unspent2[0]);

    var left = tx.funds('in').sub(total);
    if (left.cmpn(w1.dust) < 0) {
      tx.outputs[tx.outputs.length - 2].value.iadd(left);
      left = new bn(0);
    }
    if (left.cmpn(0) === 0)
      tx.outputs.pop();
    else
      tx.outputs[tx.outputs.length - 1].value = left;

    // Sign transaction
    assert.equal(w1.sign(tx), 2);
    assert.equal(w2.sign(tx), 1);

    // Verify
    assert.equal(tx.verify(), true);

    // Sign transaction using `inputs` and `off` params.
    tx.inputs.length = 0;
    tx.input(unspent1[1]);
    tx.input(unspent1[2]);
    tx.input(unspent2[1]);
    assert.equal(w1.sign(tx, 'all', tx.inputs.slice(), 0), 2);
    assert.equal(w2.sign(tx, 'all', tx.inputs.slice(2), 2), 1);

    // Verify
    assert.equal(tx.verify(), true);

    cb();
  });
});
<|endoftext|>


<commit_before>window.onload = function () {

  'use strict';

  var Cropper = window.Cropper;
  var URL = window.URL || window.webkitURL;
  var container = document.querySelector('.img-container');
  var image = container.getElementsByTagName('img').item(0);
  var download = document.getElementById('download');
  var actions = document.getElementById('actions');
  var dataX = document.getElementById('dataX');
  var dataY = document.getElementById('dataY');
  var dataHeight = document.getElementById('dataHeight');
  var dataWidth = document.getElementById('dataWidth');
  var dataRotate = document.getElementById('dataRotate');
  var dataScaleX = document.getElementById('dataScaleX');
  var dataScaleY = document.getElementById('dataScaleY');
  var options = {
    aspectRatio: 16 / 9,
    preview: '.img-preview',
    ready: function (e) {
      console.log(e.type);
    },
    cropstart: function (e) {
      console.log(e.type, e.detail.action);
    },
    cropmove: function (e) {
      console.log(e.type, e.detail.action);
    },
    cropend: function (e) {
      console.log(e.type, e.detail.action);
    },
    crop: function (e) {
      var data = e.detail;

      console.log(e.type);
      dataX.value = Math.round(data.x);
      dataY.value = Math.round(data.y);
      dataHeight.value = Math.round(data.height);
      dataWidth.value = Math.round(data.width);
      dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
      dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
      dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
    },
    zoom: function (e) {
      console.log(e.type, e.detail.ratio);
    }
  };
  var cropper = new Cropper(image, options);
  var originalImageURL = image.src;
  var uploadedImageType = 'image/jpeg';
  var uploadedImageURL;

  // Tooltip
  $('[data-toggle="tooltip"]').tooltip();

  // Buttons
  if (!document.createElement('canvas').getContext) {
    $('button[data-method="getCroppedCanvas"]').prop('disabled', true);
  }

  if (typeof document.createElement('cropper').style.transition === 'undefined') {
    $('button[data-method="rotate"]').prop('disabled', true);
    $('button[data-method="scale"]').prop('disabled', true);
  }

  // Download
  if (typeof download.download === 'undefined') {
    download.className += ' disabled';
  }

  // Options
  actions.querySelector('.docs-toggles').onchange = function (event) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    var cropBoxData;
    var canvasData;
    var isCheckbox;
    var isRadio;

    if (!cropper) {
      return;
    }

    if (target.tagName.toLowerCase() === 'label') {
      target = target.querySelector('input');
    }

    isCheckbox = target.type === 'checkbox';
    isRadio = target.type === 'radio';

    if (isCheckbox || isRadio) {
      if (isCheckbox) {
        options[target.name] = target.checked;
        cropBoxData = cropper.getCropBoxData();
        canvasData = cropper.getCanvasData();

        options.ready = function () {
          console.log('ready');
          cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
        };
      } else {
        options[target.name] = target.value;
        options.ready = function () {
          console.log('ready');
        };
      }

      // Restart
      cropper.destroy();
      cropper = new Cropper(image, options);
    }
  };

  // Methods
  actions.querySelector('.docs-buttons').onclick = function (event) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    var cropped;
    var result;
    var input;
    var data;

    if (!cropper) {
      return;
    }

    while (target !== this) {
      if (target.getAttribute('data-method')) {
        break;
      }

      target = target.parentNode;
    }

    if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
      return;
    }

    data = {
      method: target.getAttribute('data-method'),
      target: target.getAttribute('data-target'),
      option: target.getAttribute('data-option') || undefined,
      secondOption: target.getAttribute('data-second-option') || undefined
    };

    cropped = cropper.cropped;

    if (data.method) {
      if (typeof data.target !== 'undefined') {
        input = document.querySelector(data.target);

        if (!target.hasAttribute('data-option') && data.target && input) {
          try {
            data.option = JSON.parse(input.value);
          } catch (e) {
            console.log(e.message);
          }
        }
      }

      switch (data.method) {
        case 'rotate':
          if (cropped && options.viewMode > 0) {
            cropper.clear();
          }

          break;

        case 'getCroppedCanvas':
          try {
            data.option = JSON.parse(data.option);
          } catch (e) {
            console.log(e.message);
          }

          if (uploadedImageType === 'image/jpeg') {
            if (!data.option) {
              data.option = {};
            }

            data.option.fillColor = '#fff';
          }

          break;
      }

      result = cropper[data.method](data.option, data.secondOption);

      switch (data.method) {
        case 'rotate':
          if (cropped && options.viewMode > 0) {
            cropper.crop();
          }

          break;

        case 'scaleX':
        case 'scaleY':
          target.setAttribute('data-option', -data.option);
          break;

        case 'getCroppedCanvas':
          if (result) {
            // Bootstrap's Modal
            $('#getCroppedCanvasModal').modal().find('.modal-body').html(result);

            if (!download.disabled) {
              download.href = result.toDataURL(uploadedImageType);
            }
          }

          break;

        case 'destroy':
          cropper = null;

          if (uploadedImageURL) {
            URL.revokeObjectURL(uploadedImageURL);
            uploadedImageURL = '';
            image.src = originalImageURL;
          }

          break;
      }

      if (typeof result === 'object' && result !== cropper && input) {
        try {
          input.value = JSON.stringify(result);
        } catch (e) {
          console.log(e.message);
        }
      }
    }
  };

  document.body.onkeydown = function (event) {
    var e = event || window.event;

    if (!cropper || this.scrollTop > 300) {
      return;
    }

    switch (e.keyCode) {
      case 37:
        e.preventDefault();
        cropper.move(-1, 0);
        break;

      case 38:
        e.preventDefault();
        cropper.move(0, -1);
        break;

      case 39:
        e.preventDefault();
        cropper.move(1, 0);
        break;

      case 40:
        e.preventDefault();
        cropper.move(0, 1);
        break;
    }
  };

  // Import image
  var inputImage = document.getElementById('inputImage');

  if (URL) {
    inputImage.onchange = function () {
      var files = this.files;
      var file;

      if (cropper && files && files.length) {
        file = files[0];

        if (/^image\/\w+/.test(file.type)) {
          uploadedImageType = file.type;

          if (uploadedImageURL) {
            URL.revokeObjectURL(uploadedImageURL);
          }

          image.src = uploadedImageURL = URL.createObjectURL(file);
          cropper.destroy();
          cropper = new Cropper(image, options);
          inputImage.value = null;
        } else {
          window.alert('Please choose an image file.');
        }
      }
    };
  } else {
    inputImage.disabled = true;
    inputImage.parentNode.className += ' disabled';
  }
};
<commit_msg>docs: keep the same image name when download<commit_after>window.onload = function () {

  'use strict';

  var Cropper = window.Cropper;
  var URL = window.URL || window.webkitURL;
  var container = document.querySelector('.img-container');
  var image = container.getElementsByTagName('img').item(0);
  var download = document.getElementById('download');
  var actions = document.getElementById('actions');
  var dataX = document.getElementById('dataX');
  var dataY = document.getElementById('dataY');
  var dataHeight = document.getElementById('dataHeight');
  var dataWidth = document.getElementById('dataWidth');
  var dataRotate = document.getElementById('dataRotate');
  var dataScaleX = document.getElementById('dataScaleX');
  var dataScaleY = document.getElementById('dataScaleY');
  var options = {
    aspectRatio: 16 / 9,
    preview: '.img-preview',
    ready: function (e) {
      console.log(e.type);
    },
    cropstart: function (e) {
      console.log(e.type, e.detail.action);
    },
    cropmove: function (e) {
      console.log(e.type, e.detail.action);
    },
    cropend: function (e) {
      console.log(e.type, e.detail.action);
    },
    crop: function (e) {
      var data = e.detail;

      console.log(e.type);
      dataX.value = Math.round(data.x);
      dataY.value = Math.round(data.y);
      dataHeight.value = Math.round(data.height);
      dataWidth.value = Math.round(data.width);
      dataRotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
      dataScaleX.value = typeof data.scaleX !== 'undefined' ? data.scaleX : '';
      dataScaleY.value = typeof data.scaleY !== 'undefined' ? data.scaleY : '';
    },
    zoom: function (e) {
      console.log(e.type, e.detail.ratio);
    }
  };
  var cropper = new Cropper(image, options);
  var originalImageURL = image.src;
  var uploadedImageType = 'image/jpeg';
  var uploadedImageName = 'cropped.jpg';
  var uploadedImageURL;

  // Tooltip
  $('[data-toggle="tooltip"]').tooltip();

  // Buttons
  if (!document.createElement('canvas').getContext) {
    $('button[data-method="getCroppedCanvas"]').prop('disabled', true);
  }

  if (typeof document.createElement('cropper').style.transition === 'undefined') {
    $('button[data-method="rotate"]').prop('disabled', true);
    $('button[data-method="scale"]').prop('disabled', true);
  }

  // Download
  if (typeof download.download === 'undefined') {
    download.className += ' disabled';
  }

  // Options
  actions.querySelector('.docs-toggles').onchange = function (event) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    var cropBoxData;
    var canvasData;
    var isCheckbox;
    var isRadio;

    if (!cropper) {
      return;
    }

    if (target.tagName.toLowerCase() === 'label') {
      target = target.querySelector('input');
    }

    isCheckbox = target.type === 'checkbox';
    isRadio = target.type === 'radio';

    if (isCheckbox || isRadio) {
      if (isCheckbox) {
        options[target.name] = target.checked;
        cropBoxData = cropper.getCropBoxData();
        canvasData = cropper.getCanvasData();

        options.ready = function () {
          console.log('ready');
          cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
        };
      } else {
        options[target.name] = target.value;
        options.ready = function () {
          console.log('ready');
        };
      }

      // Restart
      cropper.destroy();
      cropper = new Cropper(image, options);
    }
  };

  // Methods
  actions.querySelector('.docs-buttons').onclick = function (event) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    var cropped;
    var result;
    var input;
    var data;

    if (!cropper) {
      return;
    }

    while (target !== this) {
      if (target.getAttribute('data-method')) {
        break;
      }

      target = target.parentNode;
    }

    if (target === this || target.disabled || target.className.indexOf('disabled') > -1) {
      return;
    }

    data = {
      method: target.getAttribute('data-method'),
      target: target.getAttribute('data-target'),
      option: target.getAttribute('data-option') || undefined,
      secondOption: target.getAttribute('data-second-option') || undefined
    };

    cropped = cropper.cropped;

    if (data.method) {
      if (typeof data.target !== 'undefined') {
        input = document.querySelector(data.target);

        if (!target.hasAttribute('data-option') && data.target && input) {
          try {
            data.option = JSON.parse(input.value);
          } catch (e) {
            console.log(e.message);
          }
        }
      }

      switch (data.method) {
        case 'rotate':
          if (cropped && options.viewMode > 0) {
            cropper.clear();
          }

          break;

        case 'getCroppedCanvas':
          try {
            data.option = JSON.parse(data.option);
          } catch (e) {
            console.log(e.message);
          }

          if (uploadedImageType === 'image/jpeg') {
            if (!data.option) {
              data.option = {};
            }

            data.option.fillColor = '#fff';
          }

          break;
      }

      result = cropper[data.method](data.option, data.secondOption);

      switch (data.method) {
        case 'rotate':
          if (cropped && options.viewMode > 0) {
            cropper.crop();
          }

          break;

        case 'scaleX':
        case 'scaleY':
          target.setAttribute('data-option', -data.option);
          break;

        case 'getCroppedCanvas':
          if (result) {
            // Bootstrap's Modal
            $('#getCroppedCanvasModal').modal().find('.modal-body').html(result);

            if (!download.disabled) {
              download.download = uploadedImageName;
              download.href = result.toDataURL(uploadedImageType);
            }
          }

          break;

        case 'destroy':
          cropper = null;

          if (uploadedImageURL) {
            URL.revokeObjectURL(uploadedImageURL);
            uploadedImageURL = '';
            image.src = originalImageURL;
          }

          break;
      }

      if (typeof result === 'object' && result !== cropper && input) {
        try {
          input.value = JSON.stringify(result);
        } catch (e) {
          console.log(e.message);
        }
      }
    }
  };

  document.body.onkeydown = function (event) {
    var e = event || window.event;

    if (!cropper || this.scrollTop > 300) {
      return;
    }

    switch (e.keyCode) {
      case 37:
        e.preventDefault();
        cropper.move(-1, 0);
        break;

      case 38:
        e.preventDefault();
        cropper.move(0, -1);
        break;

      case 39:
        e.preventDefault();
        cropper.move(1, 0);
        break;

      case 40:
        e.preventDefault();
        cropper.move(0, 1);
        break;
    }
  };

  // Import image
  var inputImage = document.getElementById('inputImage');

  if (URL) {
    inputImage.onchange = function () {
      var files = this.files;
      var file;

      if (cropper && files && files.length) {
        file = files[0];

        if (/^image\/\w+/.test(file.type)) {
          uploadedImageType = file.type;
          uploadedImageName = file.name;

          if (uploadedImageURL) {
            URL.revokeObjectURL(uploadedImageURL);
          }

          image.src = uploadedImageURL = URL.createObjectURL(file);
          cropper.destroy();
          cropper = new Cropper(image, options);
          inputImage.value = null;
        } else {
          window.alert('Please choose an image file.');
        }
      }
    };
  } else {
    inputImage.disabled = true;
    inputImage.parentNode.className += ' disabled';
  }
};
<|endoftext|>


<commit_before>var testHelper = require('../../support/test_helper');

var assert = require('../../support/assert');
var _             = require('underscore');
var redis         = require('redis');
var cartodbServer = require('../../../lib/cartodb/server');
var getLayerTypeFn = require('windshaft').model.MapConfig.prototype.getType;
var PortedServerOptions = require('./support/ported_server_options');
var LayergroupToken = require('../../../lib/cartodb/models/layergroup_token');

var BaseController = require('../../../lib/cartodb/controllers/base');

describe('multilayer interactivity and layers order', function() {

    var server = cartodbServer(PortedServerOptions);
    server.setMaxListeners(0);
    var redisClient = redis.createClient(PortedServerOptions.redis.port);

    var req2paramsFn;
    before(function() {
        req2paramsFn = BaseController.prototype.req2params;
        BaseController.prototype.req2params = PortedServerOptions.req2params;
    });

    after(function() {
        BaseController.prototype.req2params = req2paramsFn;
    });

    function layerType(layer) {
        return layer.type || 'undefined';
    }

    function testInteractivityLayersOrderScenario(testScenario) {
        it(testScenario.desc, function(done) {
            var layergroup =  {
                version: '1.3.0',
                layers: testScenario.layers
            };

            PortedServerOptions.afterLayergroupCreateCalls = 0;

            assert.response(server,
                {
                    url: '/database/windshaft_test/layergroup',
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    data: JSON.stringify(layergroup)
                },
                {
                    //status: 200, don't use status here to have a more meaningful error message
                    headers: {
                        'content-type': 'application/json; charset=utf-8'
                    }
                },
                function(response) {
                    assert.equal(
                        response.statusCode,
                        200,
                            'Expected status code 200, got ' + response.statusCode +
                            '\n\tResponse body: ' + response.body +
                            '\n\tLayer types: ' + layergroup.layers.map(layerType).join(', ')
                    );

//                    assert.equal(PortedServerOptions.afterLayergroupCreateCalls, 1);

                    var layergroupResponse = JSON.parse(response.body);
                    assert.ok(layergroupResponse);

                    var layergroupId = layergroupResponse.layergroupid;
                    assert.ok(layergroupId);
                    assert.equal(layergroupResponse.metadata.layers.length, layergroup.layers.length);

                    // check layers metadata at least match in number
                    var layersMetadata = layergroupResponse.metadata.layers;
                    assert.equal(layersMetadata.length, layergroup.layers.length);
                    for (var i = 0, len = layersMetadata.length; i < len; i++) {
                        assert.equal(
                            getLayerTypeFn(layersMetadata[i].type),
                            getLayerTypeFn(layergroup.layers[i].type)
                        );
                    }
                    // check torque metadata at least match in number
                    var torqueLayers = layergroup.layers.filter(function(layer) { return layer.type === 'torque'; });
                    if (torqueLayers.length) {
                        assert.equal(Object.keys(layergroupResponse.metadata.torque).length, torqueLayers.length);
                    }

                    var keysToDelete = {
                        'user:localhost:mapviews:global': 5
                    };
                    keysToDelete['map_cfg|' + LayergroupToken.parse(layergroupId).token] = 0;

                    testHelper.deleteRedisKeys(keysToDelete, done);
                }
            );
        });
    }

    var cartocssVersion = '2.3.0';
    var cartocss = '#layer { line-width:16; }';
    var sql = "select 1 as i, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom";
    var sqlWadus = "select 1 as wadus, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom";

    var httpLayer = {
        type: 'http',
        options: {
            urlTemplate: 'http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png',
            subdomains: ['a','b','c']
        }
    };

    var torqueLayer = {
        type: 'torque',
        options: {
            sql: "select 1 id, '1970-01-02'::date d, 'POINT(0 0)'::geometry the_geom_webmercator",
            cartocss: [
                "Map {",
                    "-torque-frame-count:2;",
                    "-torque-resolution:3;",
                    "-torque-time-attribute:d;",
                    "-torque-aggregation-function:'count(id)';",
                "}"
            ].join(' '),
            cartocss_version: '2.0.1'
        }
    };

    var mapnikLayer = {
        type: 'mapnik',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var mapnikInteractivityLayer = {
        type: 'mapnik',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var cartodbLayer = {
        type: 'cartodb',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var cartodbInteractivityLayer = {
        type: 'cartodb',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var cartodbWadusInteractivityLayer = {
        type: 'cartodb',
        options: {
            sql: sqlWadus,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'wadus',
            geom_column: 'the_geom'
        }
    };

    var noTypeLayer = {
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var noTypeInteractivityLayer = {
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var allLayers = [
        httpLayer,
        torqueLayer,
        mapnikLayer,
        mapnikInteractivityLayer,
        cartodbLayer,
        cartodbInteractivityLayer,
        cartodbWadusInteractivityLayer,
        noTypeLayer,
        noTypeInteractivityLayer
    ];

    var testScenarios = [
        {
            desc: 'one layer, no interactivity',
            layers: [cartodbLayer]
        },
        {
            desc: 'one layer with interactivity',
            layers: [cartodbInteractivityLayer]
        },
        {
            desc: 'two layers, interactivity mix',
            layers: [
                cartodbLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'two layers, different interactivity columns',
            layers: [
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'mix of no interactivity with interactivity',
            layers: [
                cartodbInteractivityLayer,
                cartodbLayer,
                cartodbWadusInteractivityLayer
            ]
        },
        {
            desc: 'interactivity layers + torque',
            layers: [
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'torque + interactivity layers',
            layers: [
                torqueLayer,
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'interactivity + torque + interactivity',
            layers: [
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + mix of [no] interactivity layers',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                cartodbLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + interactivity + torque + no interactivity + torque + interactivity',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbLayer,
                torqueLayer,
                cartodbWadusInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – two layers, interactivity mix',
            layers: [
                mapnikLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – mix of no interactivity with interactivity',
            layers: [
                cartodbInteractivityLayer,
                cartodbLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – interactivity layers + torque',
            layers: [
                mapnikInteractivityLayer,
                cartodbInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'mapnik type – http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                mapnikInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'no type – two layers, interactivity mix',
            layers: [
                noTypeLayer,
                noTypeInteractivityLayer
            ]
        },
        {
            desc: 'no type – mix of no interactivity with interactivity',
            layers: [
                noTypeInteractivityLayer,
                noTypeLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'no type – interactivity layers + torque',
            layers: [
                noTypeLayer,
                noTypeInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'no type – http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                noTypeInteractivityLayer,
                torqueLayer,
                noTypeInteractivityLayer
            ]
        }
    ];

    var chaosScenariosSize = 25;
    var chaosScenarios = [];
    for (var i = 0; i < chaosScenariosSize; i++) {
        // Underscore.js' sample method uses Fisher-Yates shuffle internally, see http://bost.ocks.org/mike/shuffle/
        var randomLayers = _.sample(allLayers, _.random(1, allLayers.length));
        chaosScenarios.push({
            desc: 'chaos scenario – layer types: ' + randomLayers.map(layerType).join(', '),
            layers: randomLayers
        });
    }

    testScenarios.forEach(testInteractivityLayersOrderScenario);
    chaosScenarios.forEach(testInteractivityLayersOrderScenario);

});

<commit_msg>style<commit_after>var testHelper = require('../../support/test_helper');

var assert = require('../../support/assert');
var _             = require('underscore');
var cartodbServer = require('../../../lib/cartodb/server');
var getLayerTypeFn = require('windshaft').model.MapConfig.prototype.getType;
var PortedServerOptions = require('./support/ported_server_options');
var LayergroupToken = require('../../../lib/cartodb/models/layergroup_token');

var BaseController = require('../../../lib/cartodb/controllers/base');

describe('multilayer interactivity and layers order', function() {

    var server = cartodbServer(PortedServerOptions);
    server.setMaxListeners(0);

    var req2paramsFn;
    before(function() {
        req2paramsFn = BaseController.prototype.req2params;
        BaseController.prototype.req2params = PortedServerOptions.req2params;
    });

    after(function() {
        BaseController.prototype.req2params = req2paramsFn;
    });

    function layerType(layer) {
        return layer.type || 'undefined';
    }

    function testInteractivityLayersOrderScenario(testScenario) {
        it(testScenario.desc, function(done) {
            var layergroup =  {
                version: '1.3.0',
                layers: testScenario.layers
            };

            PortedServerOptions.afterLayergroupCreateCalls = 0;

            assert.response(server,
                {
                    url: '/database/windshaft_test/layergroup',
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    data: JSON.stringify(layergroup)
                },
                {
                    //status: 200, don't use status here to have a more meaningful error message
                    headers: {
                        'content-type': 'application/json; charset=utf-8'
                    }
                },
                function(response) {
                    assert.equal(
                        response.statusCode,
                        200,
                            'Expected status code 200, got ' + response.statusCode +
                            '\n\tResponse body: ' + response.body +
                            '\n\tLayer types: ' + layergroup.layers.map(layerType).join(', ')
                    );

//                    assert.equal(PortedServerOptions.afterLayergroupCreateCalls, 1);

                    var layergroupResponse = JSON.parse(response.body);
                    assert.ok(layergroupResponse);

                    var layergroupId = layergroupResponse.layergroupid;
                    assert.ok(layergroupId);
                    assert.equal(layergroupResponse.metadata.layers.length, layergroup.layers.length);

                    // check layers metadata at least match in number
                    var layersMetadata = layergroupResponse.metadata.layers;
                    assert.equal(layersMetadata.length, layergroup.layers.length);
                    for (var i = 0, len = layersMetadata.length; i < len; i++) {
                        assert.equal(
                            getLayerTypeFn(layersMetadata[i].type),
                            getLayerTypeFn(layergroup.layers[i].type)
                        );
                    }
                    // check torque metadata at least match in number
                    var torqueLayers = layergroup.layers.filter(function(layer) { return layer.type === 'torque'; });
                    if (torqueLayers.length) {
                        assert.equal(Object.keys(layergroupResponse.metadata.torque).length, torqueLayers.length);
                    }

                    var keysToDelete = {
                        'user:localhost:mapviews:global': 5
                    };
                    keysToDelete['map_cfg|' + LayergroupToken.parse(layergroupId).token] = 0;

                    testHelper.deleteRedisKeys(keysToDelete, done);
                }
            );
        });
    }

    var cartocssVersion = '2.3.0';
    var cartocss = '#layer { line-width:16; }';
    var sql = "select 1 as i, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom";
    var sqlWadus = "select 1 as wadus, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom";

    var httpLayer = {
        type: 'http',
        options: {
            urlTemplate: 'http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png',
            subdomains: ['a','b','c']
        }
    };

    var torqueLayer = {
        type: 'torque',
        options: {
            sql: "select 1 id, '1970-01-02'::date d, 'POINT(0 0)'::geometry the_geom_webmercator",
            cartocss: [
                "Map {",
                    "-torque-frame-count:2;",
                    "-torque-resolution:3;",
                    "-torque-time-attribute:d;",
                    "-torque-aggregation-function:'count(id)';",
                "}"
            ].join(' '),
            cartocss_version: '2.0.1'
        }
    };

    var mapnikLayer = {
        type: 'mapnik',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var mapnikInteractivityLayer = {
        type: 'mapnik',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var cartodbLayer = {
        type: 'cartodb',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var cartodbInteractivityLayer = {
        type: 'cartodb',
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var cartodbWadusInteractivityLayer = {
        type: 'cartodb',
        options: {
            sql: sqlWadus,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'wadus',
            geom_column: 'the_geom'
        }
    };

    var noTypeLayer = {
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            geom_column: 'the_geom'
        }
    };

    var noTypeInteractivityLayer = {
        options: {
            sql: sql,
            cartocss_version: cartocssVersion,
            cartocss: cartocss,
            interactivity: 'i',
            geom_column: 'the_geom'
        }
    };

    var allLayers = [
        httpLayer,
        torqueLayer,
        mapnikLayer,
        mapnikInteractivityLayer,
        cartodbLayer,
        cartodbInteractivityLayer,
        cartodbWadusInteractivityLayer,
        noTypeLayer,
        noTypeInteractivityLayer
    ];

    var testScenarios = [
        {
            desc: 'one layer, no interactivity',
            layers: [cartodbLayer]
        },
        {
            desc: 'one layer with interactivity',
            layers: [cartodbInteractivityLayer]
        },
        {
            desc: 'two layers, interactivity mix',
            layers: [
                cartodbLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'two layers, different interactivity columns',
            layers: [
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'mix of no interactivity with interactivity',
            layers: [
                cartodbInteractivityLayer,
                cartodbLayer,
                cartodbWadusInteractivityLayer
            ]
        },
        {
            desc: 'interactivity layers + torque',
            layers: [
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'torque + interactivity layers',
            layers: [
                torqueLayer,
                cartodbWadusInteractivityLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'interactivity + torque + interactivity',
            layers: [
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + mix of [no] interactivity layers',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                cartodbLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'http + interactivity + torque + no interactivity + torque + interactivity',
            layers: [
                httpLayer,
                cartodbInteractivityLayer,
                torqueLayer,
                cartodbLayer,
                torqueLayer,
                cartodbWadusInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – two layers, interactivity mix',
            layers: [
                mapnikLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – mix of no interactivity with interactivity',
            layers: [
                cartodbInteractivityLayer,
                cartodbLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'mapnik type – interactivity layers + torque',
            layers: [
                mapnikInteractivityLayer,
                cartodbInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'mapnik type – http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                mapnikInteractivityLayer,
                torqueLayer,
                cartodbInteractivityLayer
            ]
        },
        {
            desc: 'no type – two layers, interactivity mix',
            layers: [
                noTypeLayer,
                noTypeInteractivityLayer
            ]
        },
        {
            desc: 'no type – mix of no interactivity with interactivity',
            layers: [
                noTypeInteractivityLayer,
                noTypeLayer,
                mapnikInteractivityLayer
            ]
        },
        {
            desc: 'no type – interactivity layers + torque',
            layers: [
                noTypeLayer,
                noTypeInteractivityLayer,
                torqueLayer
            ]
        },
        {
            desc: 'no type – http + interactivity + torque + interactivity',
            layers: [
                httpLayer,
                noTypeInteractivityLayer,
                torqueLayer,
                noTypeInteractivityLayer
            ]
        }
    ];

    var chaosScenariosSize = 25;
    var chaosScenarios = [];
    for (var i = 0; i < chaosScenariosSize; i++) {
        // Underscore.js' sample method uses Fisher-Yates shuffle internally, see http://bost.ocks.org/mike/shuffle/
        var randomLayers = _.sample(allLayers, _.random(1, allLayers.length));
        chaosScenarios.push({
            desc: 'chaos scenario – layer types: ' + randomLayers.map(layerType).join(', '),
            layers: randomLayers
        });
    }

    testScenarios.forEach(testInteractivityLayersOrderScenario);
    chaosScenarios.forEach(testInteractivityLayersOrderScenario);

});

<|endoftext|>