<commit_before>var margin = {top:50,left:50};
var nodes = [], linksArray = [],nodeIds = [], links = [],uniqueLinks=[], nodesObject = new Object;

var minBandX = 200, minBandY = 200;
var xLevel = 0, yLevel = 0;

var y = [];
var drawPath = d3.line().curve(d3.curveCardinal );

var strokeWidth = d3.scaleLinear().range([3,50]);

d3.json("assets/data3.json", function(error, data) {

    var jsonData = data.paths;

    Object.keys(jsonData).forEach(function(key){
        var path = jsonData[key];

        var link = [];
        path.forEach(function(p){
            if(p.pageid != undefined){
                p.id = p.pageid;
                if(!nodeIds.includes(p.pageid)){
                    nodeIds.push(p.pageid);
                    var tmp = new Object;
                    tmp.id = p.pageid;
                    tmp.highlight = p.highlight;
                    tmp.label = p.label;
                    tmp.type = p.type;
                    tmp.cnt = 1;
                    nodes.push(tmp);
                }else{
                    nodes.forEach(function(n){
                        if(n.id==p.pageid){
                            n.cnt = n.cnt + 1;
                        }
                    })
                }
                link.push(p.pageid);
            }else if(p.decisionid != undefined){
                p.id = p.decisionid;
                if(!nodeIds.includes(p.decisionid)){
                    nodeIds.push(p.decisionid);
                    var tmp = new Object;
                    tmp.id = p.decisionid;
                    tmp.highlight = p.highlight;
                    tmp.label = p.label;
                    tmp.cnt = 1;
                    nodes.push(tmp);
                }else{
                   nodes.forEach(function(n){
                        if(n.id==p.decisionid){
                            n.cnt = n.cnt + 1;
                        }
                    })
                }
                link.push(p.decisionid);
            }else if(p.type == "exit"){
                link.push("exit_"+p.endstatus);
                p.id = "exit_"+p.endstatus;
            }
        })

        linksArray.push(link);
        if(!isArrayInArray(uniqueLinks,link)){
            uniqueLinks.push(link);
        }
    })

    var newPaths = Object.values(jsonData).sort(function(a,b){return b.length - a.length});

    var allIds = [];
    xLevel = d3.max(uniqueLinks.map(function(ul){return ul.length;}));

    uniqueLinks.forEach(function(ul){
        var i=0;
        linksArray.forEach(function(l){
            if(ul.equals(l)){
                i++;
            }
        })
        var tmp = new Object;
        tmp.weight = i;
        tmp.path = ul;
        links.push(tmp);
    })

    for(var i=0;i<xLevel;i++){
        nodesObject[i] = [];
    }

    newPaths.forEach(function(p){
        p.forEach(function(l,i){
            if(!allIds.includes(l.id)){
                allIds.push(l.id);
                if(nodesObject[i].map(function(n){return n.id}).includes(l.id)){
                    nodesObject[i].forEach(function(a){
                        if(a.id==l.id){
                            a.cnt = a.cnt + 1;
                        }
                    })
                }else{
                    l.cnt = 1;
                    nodesObject[i].push(l);
                }
            }else{
                if(nodesObject[i].map(function(n){return n.id}).includes(l.id)){
                    nodesObject[i].forEach(function(a){
                        if(a.id==l.id){
                            a.cnt = a.cnt + 1;
                        }
                    })
                }
            }
        })
    })

    var uniqueLinkArray = [];
    uniqueLinks.forEach(function(ul){
        ul.forEach(function(u,i){
            if(ul[i+1] == undefined){
            }else{
                var tmp = new Object;
                tmp['from'] = u;
                var toIds = uniqueLinkArray.filter(function(d){return d.from == u}).map(function(d){return d.to});
                tmp['to'] = ul[i+1];
                if(!toIds.includes(tmp['to'])){
                    uniqueLinkArray.push(tmp);
                }
            }
        })
    })
    var strokeMax = d3.max(nodes.map(function(n){return n.cnt}));

    var width = Object.keys(nodesObject).length * minBandX + margin.left * 2;

    var yMax = d3.max(Object.values(nodesObject).map(function(d){return d.length}));

    var height = yMax * minBandY + margin.top * 2;

    var svg = d3.select("#main_content").append('svg').attr("width",width).attr("height",height).append("g").attr("transform","translate("+margin.top+","+margin.left+")");
    var x = d3.scaleBand()
        .range([0, width])
        .paddingInner(0.1);

    for(var i=0;i<xLevel;i++){
        y[i] = d3.scaleBand().range([0,height]).paddingInner(0.1);
    }

    x.domain(Object.keys(nodesObject));

    Object.keys(nodesObject).forEach(function(d,i){
        var yDomain = [];
        for(var j=0;j<nodesObject[d].length;j++){
            yDomain.push(j);
        }
        y[i].domain(yDomain);
    })

    strokeWidth.domain([0,strokeMax]);

    var g_links = svg.append("g").attr('class',"g_links");
    g_links.selectAll('.link').data(uniqueLinkArray).enter().append('path').attr('class','link').attr("d",function(d){
            var pathData = [];
            var key = findKey(nodesObject,d.from);
            var tmp1 = [x(key[0]), y[key[0]](key[1]) + y[key[0]].bandwidth()/2];
            pathData.push(tmp1);

            key = findKey(nodesObject,d.to);
            var tmp3 = [x(key[0]),y[key[0]](key[1]) + y[key[0]].bandwidth()/2];

            var tmp2 = [];
            tmp2[0] = (tmp3[0] - tmp1[0])/2 + tmp1[0];

            if(tmp3[1] > tmp1[1]){
                tmp2[1] = tmp1[1] - (tmp1[1] - tmp3[1])/2 + 30;
            }else if(tmp3[1] < tmp1[1]){
                tmp2[1] = tmp1[1] + (tmp3[1] - tmp1[1])/2 - 30;
            }else{
                tmp2[1] = tmp1[1] + (tmp3[1] - tmp1[1])/2;
            }
            pathData.push(tmp2);
            pathData.push(tmp3);

            return drawPath(pathData);
        })
        .attr('stroke-width',function(d){
            var key = findKey(nodesObject,d.to);
            var tmp = nodesObject[key[0]][key[1]].cnt;
            return strokeWidth(tmp);
        });

    var g_node = svg.selectAll('.node_g').data(Object.values(nodesObject)).enter().append('g').attr('class',(d,i)=>'node_g g_'+i).attr('transform',function(d,i){return "translate("+x(i)+",0)"});
    g_node.selectAll('.node')
    .data(function(d,i){return d;}).enter()
    .append('circle').attr('class',function(d){return "node node_"+ d.id + " " + d.type})
    .attr('cx',function(d){return 0;})
    .attr('cy',function(d,i){
        var index = d3.select(this.parentNode).attr('class');
        index = parseInt(index.substr(9));
        return y[index](i) + y[index].bandwidth()/2;
    })
    .attr('r',30).attr('fill','red')
    .on("mousemove",function(d){
        div.transition()
            .duration(200)
            .style("opacity", .9);
        div .html(function(){
            if(d.label==undefined){
                return "Exit:"  + d.endstatus;
            }
            return d.label;
        })
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY - 28) + "px");
    }).on("mouseout",function(){
        div.transition()
        .duration(500)
        .style("opacity", 0);
    });

    g_node.selectAll("text").data(function(d){return d;}).enter().append("text").attr("x",function(d){return x(d.id)})
    .attr("y",function(d,i){
        var index = d3.select(this.parentNode).attr('class');
        index = parseInt(index.substr(9));
        return y[index](i) + y[index].bandwidth()/2;
    }).attr("text-anchor","middle").text(function(d){return d.cnt});

});

var div = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

// Warn if overriding existing method
if(Array.prototype.equals)
    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    for (var i = 0, l=this.length; i < l; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].equals(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

function isArrayInArray(arr, item){
  var item_as_string = JSON.stringify(item);

  var contains = arr.some(function(ele){
    return JSON.stringify(ele) === item_as_string;
  });
  return contains;
}

function findKey(obj, value)
{
    var key = [];

    for (var prop in obj)
    {
        if (obj.hasOwnProperty(prop))
        {
            var ids = obj[prop].map(function(d){return d.id});
            if(ids.includes(value)){
                key[0] = prop;
                key[1] = ids.indexOf(value);
            }
        }
    }

    return key;
};<commit_msg>drag/drop zoom func added<commit_after>var margin = {top:50,left:50};
var nodes = [], linksArray = [],nodeIds = [], links = [],uniqueLinks=[], nodesObject = new Object;

var minBandX = 200, minBandY = 200;
var xLevel = 0, yLevel = 0;

var y = [];
var drawPath = d3.line().curve(d3.curveCardinal );

var strokeWidth = d3.scaleLinear().range([3,50]);

d3.json("assets/data3.json", function(error, data) {

    var jsonData = data.paths;

    Object.keys(jsonData).forEach(function(key){
        var path = jsonData[key];

        var link = [];
        path.forEach(function(p){
            if(p.pageid != undefined){
                p.id = p.pageid;
                if(!nodeIds.includes(p.pageid)){
                    nodeIds.push(p.pageid);
                    var tmp = new Object;
                    tmp.id = p.pageid;
                    tmp.highlight = p.highlight;
                    tmp.label = p.label;
                    tmp.type = p.type;
                    tmp.cnt = 1;
                    nodes.push(tmp);
                }else{
                    nodes.forEach(function(n){
                        if(n.id==p.pageid){
                            n.cnt = n.cnt + 1;
                        }
                    })
                }
                link.push(p.pageid);
            }else if(p.decisionid != undefined){
                p.id = p.decisionid;
                if(!nodeIds.includes(p.decisionid)){
                    nodeIds.push(p.decisionid);
                    var tmp = new Object;
                    tmp.id = p.decisionid;
                    tmp.highlight = p.highlight;
                    tmp.label = p.label;
                    tmp.cnt = 1;
                    nodes.push(tmp);
                }else{
                   nodes.forEach(function(n){
                        if(n.id==p.decisionid){
                            n.cnt = n.cnt + 1;
                        }
                    })
                }
                link.push(p.decisionid);
            }else if(p.type == "exit"){
                link.push("exit_"+p.endstatus);
                p.id = "exit_"+p.endstatus;
            }
        })

        linksArray.push(link);
        if(!isArrayInArray(uniqueLinks,link)){
            uniqueLinks.push(link);
        }
    })

    var newPaths = Object.values(jsonData).sort(function(a,b){return b.length - a.length});

    var allIds = [];
    xLevel = d3.max(uniqueLinks.map(function(ul){return ul.length;}));

    uniqueLinks.forEach(function(ul){
        var i=0;
        linksArray.forEach(function(l){
            if(ul.equals(l)){
                i++;
            }
        })
        var tmp = new Object;
        tmp.weight = i;
        tmp.path = ul;
        links.push(tmp);
    })

    for(var i=0;i<xLevel;i++){
        nodesObject[i] = [];
    }

    newPaths.forEach(function(p){
        p.forEach(function(l,i){
            if(!allIds.includes(l.id)){
                allIds.push(l.id);
                if(nodesObject[i].map(function(n){return n.id}).includes(l.id)){
                    nodesObject[i].forEach(function(a){
                        if(a.id==l.id){
                            a.cnt = a.cnt + 1;
                        }
                    })
                }else{
                    l.cnt = 1;
                    nodesObject[i].push(l);
                }
            }else{
                if(nodesObject[i].map(function(n){return n.id}).includes(l.id)){
                    nodesObject[i].forEach(function(a){
                        if(a.id==l.id){
                            a.cnt = a.cnt + 1;
                        }
                    })
                }
            }
        })
    })

    var uniqueLinkArray = [];
    uniqueLinks.forEach(function(ul){
        ul.forEach(function(u,i){
            if(ul[i+1] == undefined){
            }else{
                var tmp = new Object;
                tmp['from'] = u;
                var toIds = uniqueLinkArray.filter(function(d){return d.from == u}).map(function(d){return d.to});
                tmp['to'] = ul[i+1];
                if(!toIds.includes(tmp['to'])){
                    uniqueLinkArray.push(tmp);
                }
            }
        })
    })
    var strokeMax = d3.max(nodes.map(function(n){return n.cnt}));

    var width = Object.keys(nodesObject).length * minBandX + margin.left * 2;

    var yMax = d3.max(Object.values(nodesObject).map(function(d){return d.length}));

    var height = yMax * minBandY + margin.top * 2;

    var svg = d3.select("#main_content").append('svg').attr("width",width).attr("height",height)
     .call(d3.zoom().on("zoom", function () {
    svg.attr("transform", d3.event.transform)
 }))
     .append("g")
    .attr("transform","translate("+margin.top+","+margin.left+")")

    var x = d3.scaleBand()
        .range([0, width])
        .paddingInner(0.1);

    for(var i=0;i<xLevel;i++){
        y[i] = d3.scaleBand().range([0,height]).paddingInner(0.1);
    }

    x.domain(Object.keys(nodesObject));

    Object.keys(nodesObject).forEach(function(d,i){
        var yDomain = [];
        for(var j=0;j<nodesObject[d].length;j++){
            yDomain.push(j);
        }
        y[i].domain(yDomain);
    })

    strokeWidth.domain([0,strokeMax]);

    var g_links = svg.append("g").attr('class',"g_links");
    g_links.selectAll('.link').data(uniqueLinkArray).enter().append('path').attr('class','link').attr("d",function(d){
            var pathData = [];
            var key = findKey(nodesObject,d.from);
            var tmp1 = [x(key[0]), y[key[0]](key[1]) + y[key[0]].bandwidth()/2];
            pathData.push(tmp1);

            key = findKey(nodesObject,d.to);
            var tmp3 = [x(key[0]),y[key[0]](key[1]) + y[key[0]].bandwidth()/2];

            var tmp2 = [];
            tmp2[0] = (tmp3[0] - tmp1[0])/2 + tmp1[0];

            if(tmp3[1] > tmp1[1]){
                tmp2[1] = tmp1[1] - (tmp1[1] - tmp3[1])/2 + 30;
            }else if(tmp3[1] < tmp1[1]){
                tmp2[1] = tmp1[1] + (tmp3[1] - tmp1[1])/2 - 30;
            }else{
                tmp2[1] = tmp1[1] + (tmp3[1] - tmp1[1])/2;
            }
            pathData.push(tmp2);
            pathData.push(tmp3);

            return drawPath(pathData);
        })
        .attr('stroke-width',function(d){
            var key = findKey(nodesObject,d.to);
            var tmp = nodesObject[key[0]][key[1]].cnt;
            return strokeWidth(tmp);
        });

    var g_node = svg.selectAll('.node_g').data(Object.values(nodesObject)).enter().append('g').attr('class',(d,i)=>'node_g g_'+i).attr('transform',function(d,i){return "translate("+x(i)+",0)"});
    g_node.selectAll('.node')
    .data(function(d,i){return d;}).enter()
    .append('circle').attr('class',function(d){return "node node_"+ d.id + " " + d.type})
    .attr('cx',function(d){return 0;})
    .attr('cy',function(d,i){
        var index = d3.select(this.parentNode).attr('class');
        index = parseInt(index.substr(9));
        return y[index](i) + y[index].bandwidth()/2;
    })
    .attr('r',30).attr('fill','red')
    .on("mousemove",function(d){
        div.transition()
            .duration(200)
            .style("opacity", .9);
        div .html(function(){
            if(d.label==undefined){
                return "Exit:"  + d.endstatus;
            }
            return d.label;
        })
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY - 28) + "px");
    }).on("mouseout",function(){
        div.transition()
        .duration(500)
        .style("opacity", 0);
    });

    g_node.selectAll("text").data(function(d){return d;}).enter().append("text").attr("x",function(d){return x(d.id)})
    .attr("y",function(d,i){
        var index = d3.select(this.parentNode).attr('class');
        index = parseInt(index.substr(9));
        return y[index](i) + y[index].bandwidth()/2;
    }).attr("text-anchor","middle").text(function(d){return d.cnt});

});

var div = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

// Warn if overriding existing method
if(Array.prototype.equals)
    console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    for (var i = 0, l=this.length; i < l; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].equals(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

function isArrayInArray(arr, item){
  var item_as_string = JSON.stringify(item);

  var contains = arr.some(function(ele){
    return JSON.stringify(ele) === item_as_string;
  });
  return contains;
}

function findKey(obj, value)
{
    var key = [];

    for (var prop in obj)
    {
        if (obj.hasOwnProperty(prop))
        {
            var ids = obj[prop].map(function(d){return d.id});
            if(ids.includes(value)){
                key[0] = prop;
                key[1] = ids.indexOf(value);
            }
        }
    }

    return key;
};<|endoftext|>


<commit_before>var path = require("path");
var createPic = ((cb) => {
    try {
        console.log('owo');
        let gd = require('node-gd');
        let f = '../fonts/RegencieLight.ttf';
        let c = {
            black: 0x000000, white: 0xffffff, red: 0xff0000, green: 0x00ff00,
            blue: 0x0000ff, gray: 0xc6c6c6, dgray: 0x555555, lgray: 0xdcdcdc
        };
        console.log('OwO');
        console.log(path.join(__dirname, './assets/template.png'));
        let t = gd.createFromPng(path.join(__dirname, './assets/template.png'));
        console.log('hide');
        let a = gd.createFromJpeg(path.join(__dirname, './assets/hide.jpg'));
        console.log('uwu!');
        a.copyResampled(t, 21, 22, 0, 0, 76, 76, a.width, a.height).destroy();
// Name
        t.stringFT(c.dgray, f, 14, 0, 122, 33, '[Hidekazu]');
// EXP
        let cexp = 1000;
        let tnexp = 1695;
        let exp = Math.floor(cexp / tnexp * 159) + 126;
        t.filledRectangle(126, 43, exp, 55, c.gray);
        t.stringFT(c.dgray, f, 8, 0, 189, 54, `${cexp}/${tnexp}`);

// Level
        let lv = '10'
        t.stringFT(c.dgray, f, 14, 0, 130, 80, `LEVEL`);
        t.stringFT(c.dgray, f, 14, 0, 155 - (lv.length * lv.length), 100, `${lv}`);

// Rank
        let rn = '1';
        t.stringFT(c.dgray, f, 14, 0, 230, 80, `RANK`);
        t.stringFT(c.dgray, f, 14, 0, 252 - (rn.length * rn.length), 100, `${rn}`);
        console.log('saved file');
        t.savePng('../temp/output.png', 0, function (err) {
            console.log('cb called!');
            if (err) return cb(err);
            cb(null, '../temp/output.png');
        });
        t.destroy()
    } catch (e) {
        console.log(e);
    }
});
module.exports = createPic;
<commit_msg>asdadad<commit_after>var path = require("path");
var createPic = ((cb) => {
    try {
        console.log('owo');
        let gd = require('node-gd');
        let f = path.join(__dirname, '../fonts/RegencieLight.ttf')
        console.log(path.join(__dirname, '../fonts/RegencieLight.ttf'));
        let c = {
            black: 0x000000, white: 0xffffff, red: 0xff0000, green: 0x00ff00,
            blue: 0x0000ff, gray: 0xc6c6c6, dgray: 0x555555, lgray: 0xdcdcdc
        };
        console.log('OwO');
        console.log(path.join(__dirname, './assets/template.png'));
        let t = gd.createFromPng(path.join(__dirname, './assets/template.png'));
        console.log('hide');
        let a = gd.createFromJpeg(path.join(__dirname, './assets/hide.jpg'));
        console.log('uwu!');
        a.copyResampled(t, 21, 22, 0, 0, 76, 76, a.width, a.height).destroy();
// Name
        t.stringFT(c.dgray, f, 14, 0, 122, 33, '[Hidekazu]');
// EXP
        let cexp = 1000;
        let tnexp = 1695;
        let exp = Math.floor(cexp / tnexp * 159) + 126;
        t.filledRectangle(126, 43, exp, 55, c.gray);
        t.stringFT(c.dgray, f, 8, 0, 189, 54, `${cexp}/${tnexp}`);

// Level
        let lv = '10'
        t.stringFT(c.dgray, f, 14, 0, 130, 80, `LEVEL`);
        t.stringFT(c.dgray, f, 14, 0, 155 - (lv.length * lv.length), 100, `${lv}`);

// Rank
        let rn = '1';
        t.stringFT(c.dgray, f, 14, 0, 230, 80, `RANK`);
        t.stringFT(c.dgray, f, 14, 0, 252 - (rn.length * rn.length), 100, `${rn}`);
        console.log('saved file');
        t.savePng('../temp/output.png', 0, function (err) {
            console.log('cb called!');
            if (err) return cb(err);
            cb(null, '../temp/output.png');
        });
        t.destroy()
    } catch (e) {
        console.log(e);
    }
});
module.exports = createPic;
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2015-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

'use strict';

describe('Collection API', function() {
  let nodes;
  let Collection;
  let recast;
  let NodePath;
  let types;
  let b;

  beforeEach(function() {
    jest.resetModuleRegistry();

    Collection = require('../Collection');
    recast = require('recast');

    NodePath = recast.types.NodePath;
    types = recast.types.namedTypes;
    b = recast.types.builders;

    nodes = [b.identifier('foo'), b.identifier('bar')];
  });

  describe('Instantiation', function() {

    it('should create a collection from an array of nodes', function() {
      expect(Collection.fromNodes(nodes).getTypes()).toContain('Identifier');
    });

    it('should create a collection from an array of paths', function() {
      const paths = [
        new NodePath(b.identifier('foo')),
        new NodePath(b.identifier('bar')),
      ];
      expect(Collection.fromPaths(paths).getTypes()).toContain('Identifier');
    });

    it('accepts an empty array as input', function() {
      const values = [];
      expect(() => Collection.fromPaths(values)).not.toThrow();
      expect(() => Collection.fromNodes(values)).not.toThrow();
    });

    it('throws if it is passed an array of mixed values', function() {
      const values = [
        new NodePath(b.identifier('foo')),
        b.identifier('bar'),
      ];
      expect(() => Collection.fromPaths(values)).toThrow();
      expect(() => Collection.fromNodes(values)).toThrow();
    });

    it('returns a collection of the closest common type', function() {
      let nodes = [
        b.identifier('foo'),
        b.sequenceExpression([]),
      ];
      expect(Collection.fromNodes(nodes).getTypes())
        .toContain('Expression');

      nodes = [
        b.identifier('foo'),
        b.blockStatement([]),
      ];
      expect(Collection.fromNodes(nodes).getTypes())
        .toContain('Node');
    });
  });

  describe('Method extensions', function() {
    it('handles method extensions for types', function() {
      const Collection = require('../Collection');
      const getNames = jest.fn(function() {
        expect(this.nodes()).toEqual(nodes);
      });
      Collection.registerMethods({getNames: getNames}, types.Identifier);

      const collection = Collection.fromNodes(nodes);

      expect(collection.getNames).toBeDefined();
      collection.getNames();
      expect(getNames).toBeCalled();
    });

    it('throws if a method is called for the wrong node type', function() {
      const Collection = require('../Collection');
      const getNames = jest.genMockFunction();
      Collection.registerMethods({getNames: getNames}, types.Identifier);

      const collection = Collection.fromNodes([
        b.blockStatement([])
      ]);

      expect(() => collection.getNames()).toThrow();
    });

    it('ads "global" methods to all types', function() {
      const Collection = require('../Collection');
      const getNames = jest.genMockFunction();
      Collection.registerMethods({getNames: getNames});

      expect(Collection.fromNodes([b.blockStatement([])])).toBeDefined();
      expect(Collection.fromNodes(nodes)).toBeDefined();
      expect(Collection.fromNodes([])).toBeDefined();
    });

    it('handles type inheritance chains', function() {
      const Collection = require('../Collection');
      const nodeMethod = function() {};
      const identifierMethod = function() {};
      Collection.registerMethods({nodeMethod: nodeMethod}, types.Node);
      Collection.registerMethods(
        {identifierMethod: identifierMethod},
        types.Identifier
      );

      const collection = Collection.fromNodes([b.identifier('foo')]);

      expect(() => collection.identifierMethod()).not.toThrow();
      expect(() => collection.nodeMethod()).not.toThrow();
    });

    it('handles type inheritance with multiple parents', function() {
      Collection.registerMethods(
        {expressionMethod: function() {}},
        types.Expression
      );
      const collection = Collection.fromNodes([
        b.functionExpression(null, [], b.blockStatement([]))
      ]);
      expect(() => collection.expressionMethod()).not.toThrow();
    });

    it('allows multiple registrations for non-conflicting types', function () {
      Collection.registerMethods(
        {foo: function () {}},
        types.FunctionExpression
      );

      Collection.registerMethods(
        {foo: function () {}},
        types.BinaryExpression
      );

      const collection = Collection.fromNodes([
        b.functionExpression(null, [], b.blockStatement([])),
        b.functionExpression(null, [], b.blockStatement([])),
        b.binaryExpression('+', b.identifier('a'), b.identifier('b'))
      ]);

      function typeFilter(type) {
        return function (path) {
          return type.check(path.value);
        };
      }

      // allowed if collection contents match one of the registered types.
      collection.filter(typeFilter(types.BinaryExpression)).foo();
      collection.filter(typeFilter(types.FunctionExpression)).foo();

      // not allowed if there is mixed types (even though all types match one function or the other).
      expect(function () {
        collection.foo();
      }).toThrow();
    });

    describe('hasConflictingRegistration', function () {
      function register(methodName, type) {
        const methods = {};
        methods[methodName] = function () {};
        if (!types[type]) {
          throw new Error(type + ' is not a valid type');
        }
        Collection.registerMethods(methods, types[type]);
      }

      it('true if supertype is registered', function () {
        register('supertypeIsRegistered', 'Expression');
        expect(Collection.hasConflictingRegistration('supertypeIsRegistered', 'FunctionExpression')).toBe(true);
      });

      it('true if subtype is registered', function () {
        register('subtypeIsRegistered', 'FunctionExpression');
        expect(Collection.hasConflictingRegistration('subtypeIsRegistered', 'Expression')).toBe(true);
      });

      it('false if only a sibling type is registered', function () {
        register('siblingIsRegistered', 'FunctionExpression');
        expect(Collection.hasConflictingRegistration('siblingIsRegistered', 'BinaryExpression')).toBe(false);
      });
    });
  });

  describe('Processing functions', function() {
    describe('filter', function() {
      it('lets you filter with custom logic', function() {
        const filter = jest.fn(function(path) {
          return path.value.name === 'foo';
        });
        const fooVariables = Collection.fromNodes(nodes).filter(filter);

        expect(filter.mock.calls.length).toBe(2);
        expect(fooVariables.length).toBe(1);
      });

    });

    describe('forEach', function() {
      it('lets you iterate over each element of an collection', function() {
        const each = jest.genMockFunction();
        Collection.fromNodes(nodes).forEach(each);

        expect(each.mock.calls.length).toBe(2);
        expect(each.mock.calls[0][0].value).toBe(nodes[0]);
        expect(each.mock.calls[1][0].value).toBe(nodes[1]);
      });

      it('returns the collection itself', function() {
        const fVariables = Collection.fromNodes(nodes);
        const result = fVariables.forEach(function(){});

        expect(result).toBe(fVariables);
      });
    });

    describe('map', function() {
      it('returns a new collection with mapped values', function() {
        const root = Collection.fromNodes(nodes);
        const mapped = root.map((_, i) => new NodePath(nodes[+!i]));

        expect(root).not.toBe(mapped);
        expect(mapped.length).toBe(2);
        expect(mapped.nodes()[0]).toBe(nodes[1]);
        expect(mapped.nodes()[1]).toBe(nodes[0]);
      });

      it('dedupes elements', function() {
        const path = new NodePath(nodes[0]);
        const root = Collection.fromNodes(nodes);
        const mapped = root.map(() => path);

        expect(root).not.toBe(mapped);
        expect(mapped.length).toBe(1);
        expect(mapped.paths()[0]).toBe(path);
      });
    });

    describe('at', function() {
      it('should work with positive indecies', function() {
        const root = Collection.fromNodes(nodes);
        expect(root.at(0).nodes()[0]).toEqual(nodes[0]);
        expect(root.at(1).nodes()[0]).toEqual(nodes[1]);
      });

      it('should work with negative indecies', function() {
        const root = Collection.fromNodes(nodes);
        expect(root.at(-1).nodes()[0]).toEqual(nodes[nodes.length - 1]);
        expect(root.at(-2).nodes()[0]).toEqual(nodes[nodes.length - 2]);
      });
    });

    describe('get', function() {
      it('should throw descriptive error when no paths are present', function() {
        const root = Collection.fromNodes([]);
        expect(() => root.get()).toThrowError(/cannot call "get" on a collection with no paths/);
      });
    });
  });
});
<commit_msg>Fix typo in Collection test<commit_after>/*
 *  Copyright (c) 2015-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

'use strict';

describe('Collection API', function() {
  let nodes;
  let Collection;
  let recast;
  let NodePath;
  let types;
  let b;

  beforeEach(function() {
    jest.resetModuleRegistry();

    Collection = require('../Collection');
    recast = require('recast');

    NodePath = recast.types.NodePath;
    types = recast.types.namedTypes;
    b = recast.types.builders;

    nodes = [b.identifier('foo'), b.identifier('bar')];
  });

  describe('Instantiation', function() {

    it('should create a collection from an array of nodes', function() {
      expect(Collection.fromNodes(nodes).getTypes()).toContain('Identifier');
    });

    it('should create a collection from an array of paths', function() {
      const paths = [
        new NodePath(b.identifier('foo')),
        new NodePath(b.identifier('bar')),
      ];
      expect(Collection.fromPaths(paths).getTypes()).toContain('Identifier');
    });

    it('accepts an empty array as input', function() {
      const values = [];
      expect(() => Collection.fromPaths(values)).not.toThrow();
      expect(() => Collection.fromNodes(values)).not.toThrow();
    });

    it('throws if it is passed an array of mixed values', function() {
      const values = [
        new NodePath(b.identifier('foo')),
        b.identifier('bar'),
      ];
      expect(() => Collection.fromPaths(values)).toThrow();
      expect(() => Collection.fromNodes(values)).toThrow();
    });

    it('returns a collection of the closest common type', function() {
      let nodes = [
        b.identifier('foo'),
        b.sequenceExpression([]),
      ];
      expect(Collection.fromNodes(nodes).getTypes())
        .toContain('Expression');

      nodes = [
        b.identifier('foo'),
        b.blockStatement([]),
      ];
      expect(Collection.fromNodes(nodes).getTypes())
        .toContain('Node');
    });
  });

  describe('Method extensions', function() {
    it('handles method extensions for types', function() {
      const Collection = require('../Collection');
      const getNames = jest.fn(function() {
        expect(this.nodes()).toEqual(nodes);
      });
      Collection.registerMethods({getNames: getNames}, types.Identifier);

      const collection = Collection.fromNodes(nodes);

      expect(collection.getNames).toBeDefined();
      collection.getNames();
      expect(getNames).toBeCalled();
    });

    it('throws if a method is called for the wrong node type', function() {
      const Collection = require('../Collection');
      const getNames = jest.genMockFunction();
      Collection.registerMethods({getNames: getNames}, types.Identifier);

      const collection = Collection.fromNodes([
        b.blockStatement([])
      ]);

      expect(() => collection.getNames()).toThrow();
    });

    it('adds "global" methods to all types', function() {
      const Collection = require('../Collection');
      const getNames = jest.genMockFunction();
      Collection.registerMethods({getNames: getNames});

      expect(Collection.fromNodes([b.blockStatement([])])).toBeDefined();
      expect(Collection.fromNodes(nodes)).toBeDefined();
      expect(Collection.fromNodes([])).toBeDefined();
    });

    it('handles type inheritance chains', function() {
      const Collection = require('../Collection');
      const nodeMethod = function() {};
      const identifierMethod = function() {};
      Collection.registerMethods({nodeMethod: nodeMethod}, types.Node);
      Collection.registerMethods(
        {identifierMethod: identifierMethod},
        types.Identifier
      );

      const collection = Collection.fromNodes([b.identifier('foo')]);

      expect(() => collection.identifierMethod()).not.toThrow();
      expect(() => collection.nodeMethod()).not.toThrow();
    });

    it('handles type inheritance with multiple parents', function() {
      Collection.registerMethods(
        {expressionMethod: function() {}},
        types.Expression
      );
      const collection = Collection.fromNodes([
        b.functionExpression(null, [], b.blockStatement([]))
      ]);
      expect(() => collection.expressionMethod()).not.toThrow();
    });

    it('allows multiple registrations for non-conflicting types', function () {
      Collection.registerMethods(
        {foo: function () {}},
        types.FunctionExpression
      );

      Collection.registerMethods(
        {foo: function () {}},
        types.BinaryExpression
      );

      const collection = Collection.fromNodes([
        b.functionExpression(null, [], b.blockStatement([])),
        b.functionExpression(null, [], b.blockStatement([])),
        b.binaryExpression('+', b.identifier('a'), b.identifier('b'))
      ]);

      function typeFilter(type) {
        return function (path) {
          return type.check(path.value);
        };
      }

      // allowed if collection contents match one of the registered types.
      collection.filter(typeFilter(types.BinaryExpression)).foo();
      collection.filter(typeFilter(types.FunctionExpression)).foo();

      // not allowed if there is mixed types (even though all types match one function or the other).
      expect(function () {
        collection.foo();
      }).toThrow();
    });

    describe('hasConflictingRegistration', function () {
      function register(methodName, type) {
        const methods = {};
        methods[methodName] = function () {};
        if (!types[type]) {
          throw new Error(type + ' is not a valid type');
        }
        Collection.registerMethods(methods, types[type]);
      }

      it('true if supertype is registered', function () {
        register('supertypeIsRegistered', 'Expression');
        expect(Collection.hasConflictingRegistration('supertypeIsRegistered', 'FunctionExpression')).toBe(true);
      });

      it('true if subtype is registered', function () {
        register('subtypeIsRegistered', 'FunctionExpression');
        expect(Collection.hasConflictingRegistration('subtypeIsRegistered', 'Expression')).toBe(true);
      });

      it('false if only a sibling type is registered', function () {
        register('siblingIsRegistered', 'FunctionExpression');
        expect(Collection.hasConflictingRegistration('siblingIsRegistered', 'BinaryExpression')).toBe(false);
      });
    });
  });

  describe('Processing functions', function() {
    describe('filter', function() {
      it('lets you filter with custom logic', function() {
        const filter = jest.fn(function(path) {
          return path.value.name === 'foo';
        });
        const fooVariables = Collection.fromNodes(nodes).filter(filter);

        expect(filter.mock.calls.length).toBe(2);
        expect(fooVariables.length).toBe(1);
      });

    });

    describe('forEach', function() {
      it('lets you iterate over each element of an collection', function() {
        const each = jest.genMockFunction();
        Collection.fromNodes(nodes).forEach(each);

        expect(each.mock.calls.length).toBe(2);
        expect(each.mock.calls[0][0].value).toBe(nodes[0]);
        expect(each.mock.calls[1][0].value).toBe(nodes[1]);
      });

      it('returns the collection itself', function() {
        const fVariables = Collection.fromNodes(nodes);
        const result = fVariables.forEach(function(){});

        expect(result).toBe(fVariables);
      });
    });

    describe('map', function() {
      it('returns a new collection with mapped values', function() {
        const root = Collection.fromNodes(nodes);
        const mapped = root.map((_, i) => new NodePath(nodes[+!i]));

        expect(root).not.toBe(mapped);
        expect(mapped.length).toBe(2);
        expect(mapped.nodes()[0]).toBe(nodes[1]);
        expect(mapped.nodes()[1]).toBe(nodes[0]);
      });

      it('dedupes elements', function() {
        const path = new NodePath(nodes[0]);
        const root = Collection.fromNodes(nodes);
        const mapped = root.map(() => path);

        expect(root).not.toBe(mapped);
        expect(mapped.length).toBe(1);
        expect(mapped.paths()[0]).toBe(path);
      });
    });

    describe('at', function() {
      it('should work with positive indecies', function() {
        const root = Collection.fromNodes(nodes);
        expect(root.at(0).nodes()[0]).toEqual(nodes[0]);
        expect(root.at(1).nodes()[0]).toEqual(nodes[1]);
      });

      it('should work with negative indecies', function() {
        const root = Collection.fromNodes(nodes);
        expect(root.at(-1).nodes()[0]).toEqual(nodes[nodes.length - 1]);
        expect(root.at(-2).nodes()[0]).toEqual(nodes[nodes.length - 2]);
      });
    });

    describe('get', function() {
      it('should throw descriptive error when no paths are present', function() {
        const root = Collection.fromNodes([]);
        expect(() => root.get()).toThrowError(/cannot call "get" on a collection with no paths/);
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict'

const resolve = require('path').resolve
const expect = require('chai').expect

const Node = require('node-html-light').Node
const Injector = require(resolve('lib/injector'))

describe('Injector', () => {

    let injector = null
    let injectedHtmlString = '

'

    beforeEach(() => {
        injector = new Injector(/index[-0-9a-z]*.html/, Node.fromString(injectedHtmlString))
    })

    describe('.matches', () => {
        it('index.html', () => {
            const matches = injector.matches('index.html')
            expect(matches).to.be.true
        })

        it('index-abc.html', () => {
            const matches = injector.matches('index-abc.html')
            expect(matches).to.be.true
        })

        it('index-a2b3c.html', () => {
            const matches = injector.matches('index-a2b3c.html')
            expect(matches).to.be.true
        })

        it('does no match', () => {
            const matches = injector.matches('file.html')
            expect(matches).to.be.false
        })
    })
    describe('.inject', () => {
        let html = null
        beforeEach(() => {
            html = `

            `
        })
        it('adds the livereload script', () => {
            const htmlWithLiveReload = injector.inject(html).toString('utf-8')
            expect(htmlWithLiveReload.indexOf('

')).to.be.greaterThan(-1)
        })
    })
})<commit_msg>test(injector.js): test error if target is not converted to string<commit_after>'use strict'

const resolve = require('path').resolve
const expect = require('chai').expect

const Node = require('node-html-light').Node
const Injector = require(resolve('lib/injector'))

describe('Injector', () => {

    let injector = null
    let injectedHtmlString = '

'

    beforeEach(() => {
        injector = new Injector(/index[-0-9a-z]*.html/, Node.fromString(injectedHtmlString))
    })

    describe('.matches regex ', () => {
        beforeEach(() => {
            injector = new Injector(/index[-0-9a-z]*.html/, Node.fromString(injectedHtmlString))
        })
        it('index.html', () => {
            const matches = injector.matches('index.html')
            expect(matches).to.be.true
        })

        it('index-abc.html', () => {
            const matches = injector.matches('index-abc.html')
            expect(matches).to.be.true
        })

        it('index-a2b3c.html', () => {
            const matches = injector.matches('index-a2b3c.html')
            expect(matches).to.be.true
        })

        it('does no match', () => {
            const matches = injector.matches('file.html')
            expect(matches).to.be.false
        })
    })
    describe('.matches string', () => {
        beforeEach(() => {
            injector = new Injector('index[-0-9a-z]*.html', Node.fromString(injectedHtmlString))
        })
        it('index.html', () => {
            const matches = injector.matches('index.html')
            expect(matches).to.be.true
        })

        it('index-abc.html', () => {
            const matches = injector.matches('index-abc.html')
            expect(matches).to.be.true
        })
        it('index-a2b3c.html', () => {
            const matches = injector.matches('index-a2b3c.html')
            expect(matches).to.be.true
        })

        it('does no match', () => {
            const matches = injector.matches('file.html')
            expect(matches).to.be.false
        })
    })
    describe('.inject', () => {
        let html = null
        beforeEach(() => {
            html = `

            `
        })
        it('adds the livereload script', () => {
            const htmlWithLiveReload = injector.inject(html).toString('utf-8')
            expect(htmlWithLiveReload.indexOf('

')).to.be.greaterThan(-1)
        })
    })
})<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: MenuView.js                                                          \\
// Module: View                                                               \\
// Requires: Core, Foundation, DOM, View.js, AbstractMenu.js                  \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var MenuView = NS.Class({

    Extends: NS.View,

    Mixin: NS.AbstractMenu,

    init: function ( options ) {
        MenuView.parent.init.call( this, options );
        var items = this.get( 'items' ),
            shortcuts = this._shortcuts = {},
            keyBindings = this._keyBindings =
                Object.create( this._keyBindings );

        items.forEach( function ( item ) {
            var shortcut = item.shortcut;
            if ( shortcut ) {
                shortcuts[ shortcut ] = item;
                keyBindings[ shortcut ] = 'onShortcut';
            }
        });
    },

    className: 'MenuView',

    showFilter: false,

    didCreateLayer: function ( layer ) {
        MenuView.parent.didCreateLayer.call( this, layer );
        layer.addEventListener( 'mouseover', this, false );
        layer.addEventListener( 'mouseout', this, false );
    },

    willDestroyLayer: function ( layer ) {
        layer.removeEventListener( 'mouseout', this, false );
        layer.removeEventListener( 'mouseover', this, false );
        MenuView.parent.willDestroyLayer.call( this, layer );
    },

    didAppendLayerToDocument: function () {
        MenuView.parent.didAppendLayerToDocument.call( this );
        if ( this.get( 'showFilter' ) ) {
            this.focusItem( this.get( 'items' )[0] );
            this._input.focus();
        }
        return this;
    },

    didRemoveLayerFromDocument: function () {
        this.focusItem( null );
        return MenuView.parent.didRemoveLayerFromDocument.call( this );
    },

    _render: function ( layer ) {
        var Element = NS.Element,
            el = Element.create;

        Element.appendChildren( layer, [
            this.get( 'showFilter' ) ? el( 'div', [
                this._input = el( 'input', {
                    type: 'text'
                })
            ]) : null,
            el( 'ul', this.get( 'items' ).map( function ( item, index ) {
                var li = item.li = el( 'li', {
                    className: item.className,
                    style: item.style
                }, [
                    el( 'span', {
                        className: 'label' +
                            ( item.shortcut ? ' hasShortcut' : '' ),
                        text: item.label
                    }),
                    item.shortcut ? el( 'span.shortcut', {
                        text: item.shortcut
                    }) : null
                ]);
                li._index = index;
                return li;
            }) )
        ]);
    },

    // --- AbstractMenu support ---

    filterItem: function ( item, pattern ) {
        var Element = NS.Element,
            addClass = Element.addClass,
            removeClass = Element.removeClass;
        if ( pattern.test( item.label ) ) {
            if ( item.isHidden ) {
                removeClass( item.li, 'hidden' );
                item.isHidden = false;
            }
        } else {
            if ( !item.isHidden ) {
                addClass( item.li, 'hidden' );
                item.isHidden = true;
            }
        }
    },
    isItemHidden: function ( item ) {
        return item.isHidden;
    },
    didBlurItem: function ( item ) {
        NS.Element.removeClass( item.li, 'focussed' );
    },
    didFocusItem: function ( item ) {
        NS.Element.addClass( item.li, 'focussed' );
    },
    didSelectItem: function ( item ) {
        item.onSelect();
        this.hideInNextEventLoop();
    },
    getItemFromElement: function ( el ) {
        var layer = this.get( 'layer' );
        while ( el.nodeName !== 'LI' &&
            ( el = el.parentNode ) && el !== layer ) {/* Empty */}
        return ( el && el !== layer ) ? this.get( 'items' )[ el._index ] : null;
    },

    hide: function () {
        var parent = this.get( 'parentView' );
        if ( parent ) { parent.hide(); }
    },

    // --- End AbstractMenu support ---

    _keyBindings: {
        esc: 'onEscape',
        enter: 'selectFocussed',
        up: 'focusPrevious',
        down: 'focusNext'
    },

    onEscape: function ( event ) {
        var input = this._input;
        if ( input && input.value ) {
            // Firefox refuses to erase the value if you do it in the same event
            // loop; it puts it back in just before keyup. Bizarre.
            NS.RunLoop.invokeInNextEventLoop( function () {
                input.value = '';
                input.focus();
                this._syncFilterValue();
            }, this );
        }
        else {
            this.hideInNextEventLoop();
        }
        if ( event ) { event.preventDefault(); }
    },

    onShortcut: function ( event, key ) {
        event.preventDefault();
        this.didSelectItem( this._shortcuts[ key ] );
    },

    _syncFilterValue: function () {
        if ( this._input ) {
            this.set( 'filterValue', this._input.value );
        }
    }.on( 'input' )
});

NS.MenuView = MenuView;

}( this.O ) );
<commit_msg>Make MenuView more accessible.<commit_after>// -------------------------------------------------------------------------- \\
// File: MenuView.js                                                          \\
// Module: View                                                               \\
// Requires: Core, Foundation, DOM, View.js, AbstractMenu.js                  \\
// Author: Neil Jenkins                                                       \\
// License: © 2010–2012 Opera Software ASA. All rights reserved.              \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var MenuView = NS.Class({

    Extends: NS.View,

    Mixin: NS.AbstractMenu,

    init: function ( options ) {
        MenuView.parent.init.call( this, options );
        var items = this.get( 'items' ),
            shortcuts = this._shortcuts = {},
            keyBindings = this._keyBindings =
                Object.create( this._keyBindings );

        items.forEach( function ( item ) {
            var shortcut = item.shortcut;
            if ( shortcut ) {
                shortcuts[ shortcut ] = item;
                keyBindings[ shortcut ] = 'onShortcut';
            }
        });
    },

    className: 'MenuView',

    showFilter: false,

    didCreateLayer: function ( layer ) {
        MenuView.parent.didCreateLayer.call( this, layer );
        layer.addEventListener( 'mouseover', this, false );
        layer.addEventListener( 'mouseout', this, false );
    },

    willDestroyLayer: function ( layer ) {
        layer.removeEventListener( 'mouseout', this, false );
        layer.removeEventListener( 'mouseover', this, false );
        MenuView.parent.willDestroyLayer.call( this, layer );
    },

    didAppendLayerToDocument: function () {
        MenuView.parent.didAppendLayerToDocument.call( this );
        if ( this.get( 'showFilter' ) ) {
            this.focusItem( this.get( 'items' )[0] );
            this._input.focus();
        }
        return this;
    },

    didRemoveLayerFromDocument: function () {
        this.focusItem( null );
        return MenuView.parent.didRemoveLayerFromDocument.call( this );
    },

    _render: function ( layer ) {
        var Element = NS.Element,
            el = Element.create;

        Element.appendChildren( layer, [
            this.get( 'showFilter' ) ? el( 'div', [
                this._input = el( 'input', {
                    type: 'text'
                })
            ]) : null,
            el( 'ul', this.get( 'items' ).map( function ( item, index ) {
                var li = item.li = el( 'li', {
                    className: item.className,
                    style: item.style
                }, [
                    el( 'button', {
                        className: 'label' +
                            ( item.shortcut ? ' hasShortcut' : '' ),
                        text: item.label
                    }),
                    item.shortcut ? el( 'span.shortcut', {
                        text: item.shortcut
                    }) : null
                ]);
                li._index = index;
                return li;
            }) )
        ]);
    },

    // --- AbstractMenu support ---

    filterItem: function ( item, pattern ) {
        var Element = NS.Element,
            addClass = Element.addClass,
            removeClass = Element.removeClass;
        if ( pattern.test( item.label ) ) {
            if ( item.isHidden ) {
                removeClass( item.li, 'hidden' );
                item.isHidden = false;
            }
        } else {
            if ( !item.isHidden ) {
                addClass( item.li, 'hidden' );
                item.isHidden = true;
            }
        }
    },
    isItemHidden: function ( item ) {
        return item.isHidden;
    },
    didBlurItem: function ( item ) {
        NS.Element.removeClass( item.li, 'focussed' );
    },
    didFocusItem: function ( item ) {
        NS.Element.addClass( item.li, 'focussed' );
    },
    didSelectItem: function ( item ) {
        item.onSelect();
        this.hideInNextEventLoop();
    },
    getItemFromElement: function ( el ) {
        var layer = this.get( 'layer' );
        while ( el.nodeName !== 'LI' &&
            ( el = el.parentNode ) && el !== layer ) {/* Empty */}
        return ( el && el !== layer ) ? this.get( 'items' )[ el._index ] : null;
    },

    hide: function () {
        var parent = this.get( 'parentView' );
        if ( parent ) { parent.hide(); }
    },

    // --- End AbstractMenu support ---

    _keyBindings: {
        esc: 'onEscape',
        enter: 'selectFocussed',
        up: 'focusPrevious',
        down: 'focusNext'
    },

    onEscape: function ( event ) {
        var input = this._input;
        if ( input && input.value ) {
            // Firefox refuses to erase the value if you do it in the same event
            // loop; it puts it back in just before keyup. Bizarre.
            NS.RunLoop.invokeInNextEventLoop( function () {
                input.value = '';
                input.focus();
                this._syncFilterValue();
            }, this );
        }
        else {
            this.hideInNextEventLoop();
        }
        if ( event ) { event.preventDefault(); }
    },

    onShortcut: function ( event, key ) {
        event.preventDefault();
        this.didSelectItem( this._shortcuts[ key ] );
    },

    _syncFilterValue: function () {
        if ( this._input ) {
            this.set( 'filterValue', this._input.value );
        }
    }.on( 'input' )
});

NS.MenuView = MenuView;

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


<commit_before>describe('EventBus', function () {

   var eventbus;
   var testListener;
   var event;

   beforeEach(function () {

      eventbus = moduleSystem.getPart('event-bus');

      testListener = {
         onTestChanged: jasmine.createSpy('onTestChanged'),
         onEvent: jasmine.createSpy('onEvent')
      };

      event = {
         name: 'TestChanged',
         testProperty: 'testValue'
      };
   });

   afterEach(function () {
      eventbus.reset();
   });

   describe('when one listener is registered', function () {

      beforeEach(function () {

         eventbus.add(testListener);
      });

      it('should call onEventName from registered Modules, when a Event is published', function () {

         eventbus.publish(event);

         expect(testListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
            testProperty: 'testValue'
         }));
      });

      it('should call callback function with listener object as thisArg', function () {

         var thisArg;
         testListener.onTestChanged.and.callFake(function () {
            thisArg = this;
         });

         eventbus.publish(event);

         expect(thisArg).toBe(testListener);
      });

      it('should throw if a module with the same name is already registered', function () {

         expect(function () {
            eventbus.add(testListener);
         }).toThrow();
      });

      it('should send event every to onEvent', function () {

         eventbus.publish(event);

         expect(testListener.onEvent).toHaveBeenCalledWith(event);
      });

      it('should send event without name to onEvent', function () {

         var eventWithoutName = {
            testProperty: 'testValue'
         };

         eventbus.publish(eventWithoutName);

         expect(testListener.onEvent).toHaveBeenCalledWith(eventWithoutName);
      });

      it('should do nothing when published event is undefined', function () {

         expect(function () {
            eventbus.publish();
         }).toThrowError('Published event cannot be undefined');
      });

      describe('when second listener is registered', function () {

         var secondTestListener;

         beforeEach(function () {

            secondTestListener = {
               onTestChanged: jasmine.createSpy('onTestChanged')
            };

            eventbus.add(secondTestListener, true);
         });

         it('should call every registered listener', function () {

            eventbus.publish(event);

            expect(testListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
               testProperty: 'testValue'
            }));
            expect(secondTestListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
               testProperty: 'testValue'
               git
            }));

         });
      });
   });
});<commit_msg>added to travis build<commit_after>describe('EventBus', function () {

   var eventbus;
   var testListener;
   var event;

   beforeEach(function () {

      eventbus = moduleSystem.getPart('event-bus');

      testListener = {
         onTestChanged: jasmine.createSpy('onTestChanged'),
         onEvent: jasmine.createSpy('onEvent')
      };

      event = {
         name: 'TestChanged',
         testProperty: 'testValue'
      };
   });

   afterEach(function () {
      eventbus.reset();
   });

   describe('when one listener is registered', function () {

      beforeEach(function () {

         eventbus.add(testListener);
      });

      it('should call onEventName from registered Modules, when a Event is published', function () {

         eventbus.publish(event);

         expect(testListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
            testProperty: 'testValue'
         }));
      });

      it('should call callback function with listener object as thisArg', function () {

         var thisArg;
         testListener.onTestChanged.and.callFake(function () {
            thisArg = this;
         });

         eventbus.publish(event);

         expect(thisArg).toBe(testListener);
      });

      it('should throw if a module with the same name is already registered', function () {

         expect(function () {
            eventbus.add(testListener);
         }).toThrow();
      });

      it('should send event every to onEvent', function () {

         eventbus.publish(event);

         expect(testListener.onEvent).toHaveBeenCalledWith(event);
      });

      it('should send event without name to onEvent', function () {

         var eventWithoutName = {
            testProperty: 'testValue'
         };

         eventbus.publish(eventWithoutName);

         expect(testListener.onEvent).toHaveBeenCalledWith(eventWithoutName);
      });

      it('should do nothing when published event is undefined', function () {

         expect(function () {
            eventbus.publish();
         }).toThrowError('Published event cannot be undefined');
      });

      describe('when second listener is registered', function () {

         var secondTestListener;

         beforeEach(function () {

            secondTestListener = {
               onTestChanged: jasmine.createSpy('onTestChanged')
            };

            eventbus.add(secondTestListener, true);
         });

         it('should call every registered listener', function () {

            eventbus.publish(event);

            expect(testListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
               testProperty: 'testValue'
            }));
            expect(secondTestListener.onTestChanged).toHaveBeenCalledWith(jasmine.objectContaining({
               testProperty: 'testValue'
            }));
         });
      });
   });
});<|endoftext|>


<commit_before>/*
 Tests
 */

import _ from "lodash"
_.extend(global, require('./shared'))

import {logger} from "../src/utils"

import Client from '../src/client'

// Logging Levels
logger.getLogger("predicthq.client").setLevel('DEBUG')

let test_account_id = process.env.TEST_ACCOUNT_ID
let test_user_password_access_token = process.env.TEST_USER_PASSWORD_ACCESS_TOKEN
let test_client_credentials_access_token = process.env.TEST_CLIENT_CREDENTIALS_ACCESS_TOKEN

describe('Events', () => {

    it('Search', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        c.events.search()
            .then((results)=> {

                // default limit 10 records
                expect(results.toArray().length).toEqual(10)

                // Check for known field
                let keys = _.keys(results.toArray()[0])
                expect(keys).toContain('id')

                // Check iterator
                let events = []
                for (let event of results) {
                    events.push(event)
                }

                expect(events.length).toEqual(10)

                done()

            }).catch(done)

    }),

    it('Search - with filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // singapore
        c.events.search({
            q: 'Macklemore', rank_level: [4, 5], 'place.scope': ['1880251'],
            'start.gte': '2016-09-20', 'start.lt': '2016-09-21', 'start.tz': 'Asia/Singapore'
        })
            .then((results)=> {

                // Expect one record
                expect(results.toArray().length).toEqual(1)

                done()

            }).catch(done)

    }),

    it('Search - scope filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // singapore
        c.events.search({
            q: 'Green Bay', label: ['american-football'], rank_level: [4, 5], 'place.scope': ['5244267', '4887398'],
            'start.gte': '2016-12-10', 'start.lt': '2016-12-20', 'category':'sports', 'sort': 'start'
        })
            .then((results)=> {

                // Expect two record
                expect(results.toArray().length).toEqual(2)

                // Green Bay Packers vs Seattle Seahawks - NFL (11th Dec)
                expect(results.toArray()[0]['id']).toEqual('HyWiCstzPezY83Tvt8')

                // Chicago Bears vs Green Bay Packers - NFL (18th Dec)
                expect(results.toArray()[1]['id']).toEqual('ZLFqzNXgmfKW477iE2')

                done()

            }).catch(done)

    }),

    it('Search - with within filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // boston
        c.events.search({
            'within': '1km@42.35996,-71.06009',
            'rank_level': [4,5],
            'start.gte': '2016-03-08', 'start.lt': '2016-03-09',
        })
            .then((results)=> {

                // Expect one record
                expect(results.toArray().length).toEqual(1)

                expect(results.toArray()[0]['id']).toEqual('d5jeNGOP0qmd')
                expect(results.toArray()[0]['title']).toEqual('The Who')

                done()

            }).catch(done)

    }),

    it('Search - Delta (updated and state filter)', (done) => {

            let c = new Client({access_token: test_client_credentials_access_token})

            c.events.search({
                'updated.gte': '2017-05-01',
                'updated.lte': '2017-05-02',
                'label': ['performing-arts'],
                'country': 'US',
                'sort': ['start'],
                'state': ['deleted']
            })
                .then((results)=> {

                    // Expect some results
                    expect(results.toArray().length).toEqual(10)

                    expect(results.toArray()[0]['id']).toEqual('geABVyeWJm8n')

                    done()

                }).catch(done)

    }),

    it('Search - count only', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        c.events.count({'rank_level': [5], 'category': 'sports'})
            .then((results)=> {

                expect(_.keys(results.toDict())).toEqual([ 'count', 'top_rank', 'rank_levels', 'categories', 'labels' ])

                expect(results.toDict()['count']).toBeGreaterThan(10000)

                done()

            }).catch(done)

    }),

    it('Search using account', (done) => {

        let c = new Client({access_token: test_user_password_access_token})

        c.events.for_account(test_account_id).search()
            .then((results)=> {

                // default limit 10 records
                expect(results.toArray().length).toEqual(10)

                done()

            }).catch(done)

    }),

    it('Calendar', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        let options = {
            'active.gte': '2016-01-01',
            'active.lte': '2016-01-03',
            'country': 'CA',
            'top_events.limit': 1,
            'top_events.sort': ['rank']
        }

        c.events.calendar(options)
            .then((results)=> {

                let days = _.keyBy(results.toArray(), 'date')
                expect(_.keys(days)).toEqual(['2016-01-01', '2016-01-02', '2016-01-03'])

                done()

            }).catch(done)

    })

    it('Calendar using Account', (done) => {

        let c = new Client({access_token: test_user_password_access_token})

        let options = {
            'active.gte': '2016-01-01',
            'active.lte': '2016-01-03',
            'country': 'CA',
            'top_events.limit': 1,
            'top_events.sort': ['rank']
        }

        c.events.for_account(test_account_id).calendar(options)
            .then((results)=> {

                let days = _.keyBy(results.toArray(), 'date')
                expect(_.keys(days)).toEqual(['2016-01-01', '2016-01-02', '2016-01-03'])

                done()

            }).catch(done)

    })

})
<commit_msg>Fix count endpoint test<commit_after>/*
 Tests
 */

import _ from "lodash"
_.extend(global, require('./shared'))

import {logger} from "../src/utils"

import Client from '../src/client'

// Logging Levels
logger.getLogger("predicthq.client").setLevel('DEBUG')

let test_account_id = process.env.TEST_ACCOUNT_ID
let test_user_password_access_token = process.env.TEST_USER_PASSWORD_ACCESS_TOKEN
let test_client_credentials_access_token = process.env.TEST_CLIENT_CREDENTIALS_ACCESS_TOKEN

describe('Events', () => {

    it('Search', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        c.events.search()
            .then((results)=> {

                // default limit 10 records
                expect(results.toArray().length).toEqual(10)

                // Check for known field
                let keys = _.keys(results.toArray()[0])
                expect(keys).toContain('id')

                // Check iterator
                let events = []
                for (let event of results) {
                    events.push(event)
                }

                expect(events.length).toEqual(10)

                done()

            }).catch(done)

    }),

    it('Search - with filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // singapore
        c.events.search({
            q: 'Macklemore', rank_level: [4, 5], 'place.scope': ['1880251'],
            'start.gte': '2016-09-20', 'start.lt': '2016-09-21', 'start.tz': 'Asia/Singapore'
        })
            .then((results)=> {

                // Expect one record
                expect(results.toArray().length).toEqual(1)

                done()

            }).catch(done)

    }),

    it('Search - scope filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // singapore
        c.events.search({
            q: 'Green Bay', label: ['american-football'], rank_level: [4, 5], 'place.scope': ['5244267', '4887398'],
            'start.gte': '2016-12-10', 'start.lt': '2016-12-20', 'category':'sports', 'sort': 'start'
        })
            .then((results)=> {

                // Expect two record
                expect(results.toArray().length).toEqual(2)

                // Green Bay Packers vs Seattle Seahawks - NFL (11th Dec)
                expect(results.toArray()[0]['id']).toEqual('HyWiCstzPezY83Tvt8')

                // Chicago Bears vs Green Bay Packers - NFL (18th Dec)
                expect(results.toArray()[1]['id']).toEqual('ZLFqzNXgmfKW477iE2')

                done()

            }).catch(done)

    }),

    it('Search - with within filter', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        // boston
        c.events.search({
            'within': '1km@42.35996,-71.06009',
            'rank_level': [4,5],
            'start.gte': '2016-03-08', 'start.lt': '2016-03-09',
        })
            .then((results)=> {

                // Expect one record
                expect(results.toArray().length).toEqual(1)

                expect(results.toArray()[0]['id']).toEqual('d5jeNGOP0qmd')
                expect(results.toArray()[0]['title']).toEqual('The Who')

                done()

            }).catch(done)

    }),

    it('Search - Delta (updated and state filter)', (done) => {

            let c = new Client({access_token: test_client_credentials_access_token})

            c.events.search({
                'updated.gte': '2017-05-01',
                'updated.lte': '2017-05-02',
                'label': ['performing-arts'],
                'country': 'US',
                'sort': ['start'],
                'state': ['deleted']
            })
                .then((results)=> {

                    // Expect some results
                    expect(results.toArray().length).toEqual(10)

                    expect(results.toArray()[0]['id']).toEqual('geABVyeWJm8n')

                    done()

                }).catch(done)

    }),

    it('Search - count only', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        c.events.count({'rank_level': [5], 'category': 'sports'})
            .then((results)=> {

                expect(_.keys(results.toDict())).toEqual([ 'count', 'top_rank', 'top_local_rank', 'rank_levels', 'local_rank_levels', 'categories', 'labels' ])

                expect(results.toDict()['count']).toBeGreaterThan(10000)

                done()

            }).catch(done)

    }),

    it('Search using account', (done) => {

        let c = new Client({access_token: test_user_password_access_token})

        c.events.for_account(test_account_id).search()
            .then((results)=> {

                // default limit 10 records
                expect(results.toArray().length).toEqual(10)

                done()

            }).catch(done)

    }),

    it('Calendar', (done) => {

        let c = new Client({access_token: test_client_credentials_access_token})

        let options = {
            'active.gte': '2016-01-01',
            'active.lte': '2016-01-03',
            'country': 'CA',
            'top_events.limit': 1,
            'top_events.sort': ['rank']
        }

        c.events.calendar(options)
            .then((results)=> {

                let days = _.keyBy(results.toArray(), 'date')
                expect(_.keys(days)).toEqual(['2016-01-01', '2016-01-02', '2016-01-03'])

                done()

            }).catch(done)

    })

    it('Calendar using Account', (done) => {

        let c = new Client({access_token: test_user_password_access_token})

        let options = {
            'active.gte': '2016-01-01',
            'active.lte': '2016-01-03',
            'country': 'CA',
            'top_events.limit': 1,
            'top_events.sort': ['rank']
        }

        c.events.for_account(test_account_id).calendar(options)
            .then((results)=> {

                let days = _.keyBy(results.toArray(), 'date')
                expect(_.keys(days)).toEqual(['2016-01-01', '2016-01-02', '2016-01-03'])

                done()

            }).catch(done)

    })

})
<|endoftext|>


<commit_before>import crypto from "crypto";
import path from "path";
import isEot from "is-eot";
import isSvg from "is-svg";
import isTtf from "is-ttf";
import isWoff from "is-woff";
import isWoff2 from "is-woff2";
import standalone from "../standalone";

const fixturesGlob = "src/__tests__/fixtures";

describe("standalone", () => {
  it("should throw error if `files` not passed", async () => {
    try {
      await standalone();
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch("You must pass webfont a `files` glob");
    }
  });

  it("should throw error `files glob patterns specified did not match any files` if not found files", async () => {
    expect.assertions(1);

    try {
      await standalone({
        files: `${fixturesGlob}/not-found-svg-icons/**/*`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(
        "Files glob patterns specified did not match any files"
      );
    }
  });

  it("should generate all fonts", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
  });

  // Need search better way to test `fs` delay
  it("should generate all fonts and will be deterministic", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);

    const svgHash = crypto
      .createHash("md5")
      .update(result.svg)
      .digest("hex");
    const ttfHash = crypto
      .createHash("md5")
      .update(result.ttf)
      .digest("hex");
    const eotHash = crypto
      .createHash("md5")
      .update(result.eot)
      .digest("hex");
    const woffHash = crypto
      .createHash("md5")
      .update(result.woff)
      .digest("hex");
    const woff2Hash = crypto
      .createHash("md5")
      .update(result.woff2)
      .digest("hex");

    expect(svgHash).toBe("ead2b6f69fc603bf1cbd00bf9f8a8a33");
    expect(ttfHash).toBe("8ffaa42f84b0835c7c250ec16e8f5d78");
    expect(eotHash).toBe("cc86496a4fd871e31a79043a7ba96a07");
    expect(woffHash).toBe("e90fb075e22ab56621e1caf13c52ef17");
    expect(woff2Hash).toBe("c71b12c10bb6576528ef1a461c166e3a");
  });

  it("should generate only `svg`, `ttf` and `eot` fonts", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["svg", "ttf", "eot"]
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(result.woff).toBeUndefined();
    expect(result.woff2).toBeUndefined();
  });

  it("should generate only `woff2` font", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["woff2"]
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(result.woff).toBeUndefined();
    expect(isWoff2(result.woff2)).toBe(true);
  });

  it("should generate all fonts with build-in template", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css"
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate only `woff` and `woff2` fonts with build-in template", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["woff", "woff2"],
      template: "css"
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate all fonts with custom `template` with absolute path", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: path.join(fixturesGlob, "templates/template.css")
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate all fonts with custom `template` with relative path", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "src/__tests__/fixtures/templates/template.css"
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and export file path in result", async () => {
    const configFile = path.join(fixturesGlob, "configs/.webfontrc");
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.foo).toBe("bar");
  });

  it("should load config and respect `template` option with build-in template value", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-build-in-template"
    );

    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe("scss");
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and respect `template` option with external template value", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-external-template"
    );
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe(
      "src/__tests__/fixtures/templates/template.css"
    );
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and respect `formats` option", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-custom-formats"
    );
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(result.woff).toBeUndefined();
    expect(isWoff2(result.woff2)).toBe(true);
  });

  it("should generate the ordered output source in the same order of entry", async () => {
    expect.assertions(1);

    const templateOutput = `
    .webfont-envelope::before {
      content: "\\ea01";
    }
    .webfont-avatar::before {
      content: "\\ea02";
    }
  `;
    const result = await standalone({
      files: [
        `${fixturesGlob}/svg-icons/envelope.svg`,
        `${fixturesGlob}/svg-icons/avatar.svg`
      ],
      sort: false,
      template: path.join(fixturesGlob, "templates/template-ordered.css")
    });

    expect(templateOutput.replace(/(\s)/g, "")).toBe(
      result.template.replace(/(\s)/g, "")
    );
  });

  it("should throw error on bad svg images - `Unclosed root tag`", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar.svg`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unclosed root tag/);
    }
  });

  it("should throw error on bad svg images - `Unterminated command at index`", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-1.svg`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unterminated command at index/);
    }
  });

  it('should throw error on bad svg images - `Unexpected character "N"`', async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-2.svg`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unexpected character "N"/);
    }
  });

  it("should throw error on bad svg images - empty file", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-3.svg`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Empty file/);
    }
  });

  it("should throw error of config file not found", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.not-exist-webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/svg-icons/**/*`
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.code).toBe("ENOENT");
    }
  });

  it("should create css selectors with transform titles through function", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["eot"],
      glyphTransformFn: obj => {
        obj.name += "_transform";

        return obj;
      },
      template: "css"
    });

    expect(result.template).toMatchSnapshot();
  });

  it("should respect `template` options", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css",
      templateClassName: "foo",
      templateFontName: "bar",
      templateFontPath: "./foo-bar"
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe("css");
    expect(result.usedBuildInTemplate).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should export `glyphsData` in `result`", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css"
    });

    expect(Array.isArray(result.glyphsData)).toBe(true);
    expect(result.glyphsData.length > 0).toBe(true);
  });
});
<commit_msg>style: format standalone test code style<commit_after>import crypto from "crypto";
import path from "path";
import isEot from "is-eot";
import isSvg from "is-svg";
import isTtf from "is-ttf";
import isWoff from "is-woff";
import isWoff2 from "is-woff2";
import standalone from "../standalone";

const fixturesGlob = "src/__tests__/fixtures";

describe("standalone", () => {
  it("should throw error if `files` not passed", async () => {
    try {
      await standalone();
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch("You must pass webfont a `files` glob");
    }
  });

  it("should throw error `files glob patterns specified did not match any files` if not found files", async () => {
    expect.assertions(1);

    try {
      await standalone({
        files: `${fixturesGlob}/not-found-svg-icons/**/*`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(
        "Files glob patterns specified did not match any files"
      );
    }
  });

  it("should generate all fonts", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
  });

  // Need search better way to test `fs` delay
  it("should generate all fonts and will be deterministic", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);

    const svgHash = crypto.createHash("md5").update(result.svg).digest("hex");
    const ttfHash = crypto.createHash("md5").update(result.ttf).digest("hex");
    const eotHash = crypto.createHash("md5").update(result.eot).digest("hex");
    const woffHash = crypto.createHash("md5").update(result.woff).digest("hex");
    const woff2Hash = crypto
      .createHash("md5")
      .update(result.woff2)
      .digest("hex");

    expect(svgHash).toBe("ead2b6f69fc603bf1cbd00bf9f8a8a33");
    expect(ttfHash).toBe("8ffaa42f84b0835c7c250ec16e8f5d78");
    expect(eotHash).toBe("cc86496a4fd871e31a79043a7ba96a07");
    expect(woffHash).toBe("e90fb075e22ab56621e1caf13c52ef17");
    expect(woff2Hash).toBe("c71b12c10bb6576528ef1a461c166e3a");
  });

  it("should generate only `svg`, `ttf` and `eot` fonts", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["svg", "ttf", "eot"],
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(result.woff).toBeUndefined();
    expect(result.woff2).toBeUndefined();
  });

  it("should generate only `woff2` font", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["woff2"],
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(result.woff).toBeUndefined();
    expect(isWoff2(result.woff2)).toBe(true);
  });

  it("should generate all fonts with build-in template", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css",
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate only `woff` and `woff2` fonts with build-in template", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["woff", "woff2"],
      template: "css",
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate all fonts with custom `template` with absolute path", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: path.join(fixturesGlob, "templates/template.css"),
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should generate all fonts with custom `template` with relative path", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "src/__tests__/fixtures/templates/template.css",
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and export file path in result", async () => {
    const configFile = path.join(fixturesGlob, "configs/.webfontrc");
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.foo).toBe("bar");
  });

  it("should load config and respect `template` option with build-in template value", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-build-in-template"
    );

    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe("scss");
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and respect `template` option with external template value", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-external-template"
    );
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe(
      "src/__tests__/fixtures/templates/template.css"
    );
    expect(result.template).toMatchSnapshot();
  });

  it("should load config and respect `formats` option", async () => {
    const configFile = path.join(
      fixturesGlob,
      "configs/.webfontrc-with-custom-formats"
    );
    const result = await standalone({
      configFile,
      files: `${fixturesGlob}/svg-icons/**/*`,
    });

    expect(result.svg).toBeUndefined();
    expect(result.ttf).toBeUndefined();
    expect(result.eot).toBeUndefined();
    expect(result.woff).toBeUndefined();
    expect(isWoff2(result.woff2)).toBe(true);
  });

  it("should generate the ordered output source in the same order of entry", async () => {
    expect.assertions(1);

    const templateOutput = `
    .webfont-envelope::before {
      content: "\\ea01";
    }
    .webfont-avatar::before {
      content: "\\ea02";
    }
  `;
    const result = await standalone({
      files: [
        `${fixturesGlob}/svg-icons/envelope.svg`,
        `${fixturesGlob}/svg-icons/avatar.svg`,
      ],
      sort: false,
      template: path.join(fixturesGlob, "templates/template-ordered.css"),
    });

    expect(templateOutput.replace(/(\s)/g, "")).toBe(
      result.template.replace(/(\s)/g, "")
    );
  });

  it("should throw error on bad svg images - `Unclosed root tag`", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar.svg`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unclosed root tag/);
    }
  });

  it("should throw error on bad svg images - `Unterminated command at index`", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-1.svg`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unterminated command at index/);
    }
  });

  it('should throw error on bad svg images - `Unexpected character "N"`', async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-2.svg`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Unexpected character "N"/);
    }
  });

  it("should throw error on bad svg images - empty file", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/bad-svg-icons/avatar-3.svg`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.message).toMatch(/Empty file/);
    }
  });

  it("should throw error of config file not found", async () => {
    expect.assertions(1);

    const configFile = path.join(fixturesGlob, "configs/.not-exist-webfontrc");

    try {
      await standalone({
        configFile,
        files: `${fixturesGlob}/svg-icons/**/*`,
      });
    } catch (error) {
      // eslint-disable-next-line jest/no-conditional-expect
      expect(error.code).toBe("ENOENT");
    }
  });

  it("should create css selectors with transform titles through function", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      formats: ["eot"],
      glyphTransformFn: (obj) => {
        obj.name += "_transform";

        return obj;
      },
      template: "css",
    });

    expect(result.template).toMatchSnapshot();
  });

  it("should respect `template` options", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css",
      templateClassName: "foo",
      templateFontName: "bar",
      templateFontPath: "./foo-bar",
    });

    expect(isSvg(result.svg)).toBe(true);
    expect(isTtf(result.ttf)).toBe(true);
    expect(isEot(result.eot)).toBe(true);
    expect(isWoff(result.woff)).toBe(true);
    expect(isWoff2(result.woff2)).toBe(true);
    expect(result.config.template).toBe("css");
    expect(result.usedBuildInTemplate).toBe(true);
    expect(result.template).toMatchSnapshot();
  });

  it("should export `glyphsData` in `result`", async () => {
    const result = await standalone({
      files: `${fixturesGlob}/svg-icons/**/*`,
      template: "css",
    });

    expect(Array.isArray(result.glyphsData)).toBe(true);
    expect(result.glyphsData.length > 0).toBe(true);
  });
});
<|endoftext|>