<commit_before>var r = require('./../../../drivers/javascript2/build/rethinkdb.js');

var JSPORT = process.argv[2]
var CPPPORT = process.argv[3]

// -- utilities --

Object.prototype.toString = function() {
    var s = '{'
    for (k in this) {
        if (!this.hasOwnProperty(k)) continue;
        s += k;
        s += ':'
        s += this[k].toString();
        s += ', ';
    }
    s += '}';
    return s;
};

function printTestFailure(name, src, message) {
    console.log("\nTEST FAILURE: "+name+"\nTEST BODY: "+src+"\n"+message+"\n");
}

function eq_test(one, two) {
    if (one instanceof Function) {
        return one(two);
    } else if (two instanceof Function) {
        return two(one);
    } else if (one instanceof Array) {

        if (!(two instanceof Array)) return false;

        if (one.length != two.length) return false;

        // Recurse on each element of array
        for (var i = 0; i < one.length; i++) {
            if (!eq_test(one[i], two[i])) return false;
        }

        return true;

    } else if (one instanceof Object) {

        if (!(two instanceof Object)) return false;

        // TODO: eq_test({},{foo:4}) will return true
        // Recurse on each property of object
        for (var key in one) {
            if (one.hasOwnProperty(key)) {
                if (!eq_test(one[key], two[key])) return false;
            }
        }
        return true;

    } else {

        // Primitive comparison
        return (typeof one === typeof two) && (one === two)
    }
}

// -- Curried output test functions --

// Equality comparison
function eq(exp) {
    var fun = function(val) {
        if (!eq_test(val, exp)) {
            return false;
        } else {
            return true;
        }
    };
    fun.toString = function() {
        return exp.toString();
    };
    return fun;
}

// Tests are stored in list until they can be sequentially evaluated
var tests = []

// Any variables defined by the tests are stored here
var defines = {}

// Connect first to cpp server
r.connect({port:CPPPORT}, function(cpp_conn_err, cpp_conn) {

    // Now connect to js server
    //r.connect({port:JSPORT}, function(js_conn_err, js_conn) {

        // Pull a test off the queue and run it
        function runTest() {
            var testPair = tests.shift();
            if (testPair) {
                if (testPair instanceof Function) {
                    testPair();
                    runTest();
                    return;
                } else {

                    testName = testPair[2];

                    try {
                        var exp_fun = eval(testPair[1]);
                    } catch (err) {
                        // Oops, this shouldn't have happened
                        console.log(testName);
                        console.log(testPair[1]);
                        throw err;
                    }
                    if (!exp_fun)
                        exp_fun = function() { return true; };

                    if (!(exp_fun instanceof Function))
                        exp_fun = eq(exp_fun);

                    var src = testPair[0]
                    try {
                        with (defines) {
                            test = eval(src);
                        }
                    } catch(bld_err) {
                        if (exp_fun.isErr) {
                            if (!exp_fun(bld_err)) {
                                printTestFailure(testName, src,
                                    "Error eval'ing test src not equal to expected err:\n\tERROR: "+
                                        bld_err.toString()+"\n\tExpected: "+exp_fun.toString());
                            }
                        } else {
                            printTestFailure(testName, src, "Error eval'ing test src:\n\t"+bld_err.toString());
                        }

                        // continue to next test
                        runTest();
                        return;
                    }

                    // Run test first on cpp server
                    try {
                        test.run(cpp_conn, cpp_cont);
                    } catch(err) {
                        if (exp_fun.isErr) {
                            if (!exp_fun(err)) {
                                printTestFailure(testName, src,
                                    "Error running test not equal to expected err:\n\tERROR: "+
                                        err.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                            }
                        } else {
                            printTestFailure(testName, src, "Error running test:\n\t"+err.toString());
                        }

                        // Continue to next test
                        runTest();
                        return;
                    }

                    function cpp_cont(cpp_err, cpp_res) {

                        // Convert to array if it's a cursor
                        if (cpp_res instanceof Object && cpp_res.toArray) {
                            cpp_res.toArray(afterArray);
                        } else {
                            afterArray(null, cpp_res);
                        }

                        function afterArray(arr_err, cpp_res) {

                            // Now run test on js server
                            //test.run(js_conn, js_cont);

                            //function js_cont(js_err, js_res) {

                                /*
                                if (js_res instanceof Object && js_res.toArray) {
                                    js_res.toArray(afterArray2);
                                } else {
                                    afterArray2(null, js_res);
                                }
                                */
                                afterArray2(null, null);

                                // Again, convert to array
                                function afterArray2(arr_err, js_res) {

                                    if (cpp_err) {
                                        if (exp_fun.isErr) {
                                            if (!exp_fun(cpp_err)) {
                                                printTestFailure(testName, src,
                                                    "Error running test on CPP server not equal to expected err:"+
                                                    "\n\tERROR: "+cpp_err.toString()+
                                                    "\n\tEXPECTED "+exp_fun.toString());
                                            }
                                        } else {
                                            printTestFailure(testName, src,
                                                "Error running test on CPP server:"+
                                                "\n\tERROR: "+cpp_err.toString());
                                        }
                                    } else if (!exp_fun(cpp_res)) {
                                        printTestFailure(testName, src,
                                            "CPP result is not equal to expected result:"+
                                            "\n\tVALUE: "+cpp_res.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                                    }

                                    /*
                                    if (js_err) {
                                        if (exp_fun.isErr && !exp_fun(js_err)) {
                                            printTestFailure(testName, src,
                                                "Error running test on JS server not equal to expected err:"+
                                                "\n\tERROR: "+js_err.toString()+
                                                "\n\tEXPECTED "+exp_fun.toString());
                                        } else {
                                            printTestFailure(testName, src,
                                                "Error running test on JS server:"+
                                                "\n\tERROR: "+cpp_err.toString());
                                        }
                                    } else if (!exp_fun(js_res)) {
                                        printTestFailure(testName, src,
                                            "JS result is not equal to expected result:"+
                                            "\n\tVALUE: "+js_res.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                                    }
                                    */

                                    // Continue to next test. Tests are fully sequential
                                    // so you can rely on previous queries results in
                                    // subsequent tests.
                                    runTest();
                                    return;
                                }
                            //}
                        }
                    }
                }
            } else {
                // We've hit the end of our test list
                // closing the connection will allow the
                // event loop to quit naturally
                cpp_conn.close();
                //js_conn.close();
            }
        }

        // Start the recursion though all the tests
        runTest();
    //});
});

// Invoked by generated code to add test and expected result
// Really constructs list of tests to be sequentially evaluated
function test(testSrc, resSrc, name) {
    tests.push([testSrc, resSrc, name])
}

// Invoked by generated code to define variables to used within
// subsequent tests
function define(expr) {
    tests.push(function() {
        with (defines) {
            eval("defines."+expr);
        }
    });
}

// Invoked by generated code to support bag comparison on this expected value
function bag(list) {
    var bag = eval(list).sort();
    var fun = function(other) {
        other = other.sort();
        return eq_test(bag, other);
    };
    fun.toString = function() {
        return "bag("+list+")";
    };
    return fun;
}

// Invoked by generated code to demonstrate expected error output
function err(err_name, err_msg, err_frames) {
    var err_frames = null; // Don't test frames for now, at least not until the C++ is done with them
    var fun = function(other) {
        if (!(function() {
            if (!(other instanceof Error)) return false;
            if (err_name && !(other.name === err_name)) return false;

            // Strip out "offending object" from err message
            other.msg = other.msg.replace(/:\n([\r\n]|.)*/m, ".");

            if (err_msg && !(other.msg === err_msg)) return false;
            if (err_frames && !(eq_test(other.frames, err_frames))) return false;
            return true;
        })()) {
            return false;
        }
        return true;
    }
    fun.isErr = true;
    fun.toString = function() {
        return err_name+"(\""+err_msg+"\")";
    };
    return fun;
}

function arr(length, eq_fun) {
    var fun = function(thing) {
        if (!thing.length || thing.length === length) return false;
        return !eq_fun || eq_fun(thing);
    };
    fun.toString = function() {
        return "arr("+length+(eq_fun ? ", "+eq_fun.toString() : '')+")";
    };
    return fun;
}

function uuid() {
    var fun = function(thing) {
        console.log(thing);
        return thing.match && thing.match(/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/);
    };
    fun.toString = function() {
        return "uuid()";
    };
    return fun;
};

True = true;
False = false;
<commit_msg>fix uuid checking in JS test driver<commit_after>var r = require('./../../../drivers/javascript2/build/rethinkdb.js');

var JSPORT = process.argv[2]
var CPPPORT = process.argv[3]

// -- utilities --

Object.prototype.toString = function() {
    var s = '{'
    for (k in this) {
        if (!this.hasOwnProperty(k)) continue;
        s += k;
        s += ':'
        s += this[k].toString();
        s += ', ';
    }
    s += '}';
    return s;
};

function printTestFailure(name, src, message) {
    console.log("\nTEST FAILURE: "+name+"\nTEST BODY: "+src+"\n"+message+"\n");
}

function eq_test(one, two) {
    if (one instanceof Function) {
        return one(two);
    } else if (two instanceof Function) {
        return two(one);
    } else if (one instanceof Array) {

        if (!(two instanceof Array)) return false;

        if (one.length != two.length) return false;

        // Recurse on each element of array
        for (var i = 0; i < one.length; i++) {
            if (!eq_test(one[i], two[i])) return false;
        }

        return true;

    } else if (one instanceof Object) {

        if (!(two instanceof Object)) return false;

        // TODO: eq_test({},{foo:4}) will return true
        // Recurse on each property of object
        for (var key in one) {
            if (one.hasOwnProperty(key)) {
                if (!eq_test(one[key], two[key])) return false;
            }
        }
        return true;

    } else {

        // Primitive comparison
        return (typeof one === typeof two) && (one === two)
    }
}

// -- Curried output test functions --

// Equality comparison
function eq(exp) {
    var fun = function(val) {
        if (!eq_test(val, exp)) {
            return false;
        } else {
            return true;
        }
    };
    fun.toString = function() {
        return exp.toString();
    };
    return fun;
}

// Tests are stored in list until they can be sequentially evaluated
var tests = []

// Any variables defined by the tests are stored here
var defines = {}

// Connect first to cpp server
r.connect({port:CPPPORT}, function(cpp_conn_err, cpp_conn) {

    // Now connect to js server
    //r.connect({port:JSPORT}, function(js_conn_err, js_conn) {

        // Pull a test off the queue and run it
        function runTest() {
            var testPair = tests.shift();
            if (testPair) {
                if (testPair instanceof Function) {
                    testPair();
                    runTest();
                    return;
                } else {

                    testName = testPair[2];

                    try {
                        var exp_fun = eval(testPair[1]);
                    } catch (err) {
                        // Oops, this shouldn't have happened
                        console.log(testName);
                        console.log(testPair[1]);
                        throw err;
                    }
                    if (!exp_fun)
                        exp_fun = function() { return true; };

                    if (!(exp_fun instanceof Function))
                        exp_fun = eq(exp_fun);

                    var src = testPair[0]
                    try {
                        with (defines) {
                            test = eval(src);
                        }
                    } catch(bld_err) {
                        if (exp_fun.isErr) {
                            if (!exp_fun(bld_err)) {
                                printTestFailure(testName, src,
                                    "Error eval'ing test src not equal to expected err:\n\tERROR: "+
                                        bld_err.toString()+"\n\tExpected: "+exp_fun.toString());
                            }
                        } else {
                            printTestFailure(testName, src, "Error eval'ing test src:\n\t"+bld_err.toString());
                        }

                        // continue to next test
                        runTest();
                        return;
                    }

                    // Run test first on cpp server
                    try {
                        test.run(cpp_conn, cpp_cont);
                    } catch(err) {
                        if (exp_fun.isErr) {
                            if (!exp_fun(err)) {
                                printTestFailure(testName, src,
                                    "Error running test not equal to expected err:\n\tERROR: "+
                                        err.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                            }
                        } else {
                            printTestFailure(testName, src, "Error running test:\n\t"+err.toString());
                        }

                        // Continue to next test
                        runTest();
                        return;
                    }

                    function cpp_cont(cpp_err, cpp_res) {

                        // Convert to array if it's a cursor
                        if (cpp_res instanceof Object && cpp_res.toArray) {
                            cpp_res.toArray(afterArray);
                        } else {
                            afterArray(null, cpp_res);
                        }

                        function afterArray(arr_err, cpp_res) {

                            // Now run test on js server
                            //test.run(js_conn, js_cont);

                            //function js_cont(js_err, js_res) {

                                /*
                                if (js_res instanceof Object && js_res.toArray) {
                                    js_res.toArray(afterArray2);
                                } else {
                                    afterArray2(null, js_res);
                                }
                                */
                                afterArray2(null, null);

                                // Again, convert to array
                                function afterArray2(arr_err, js_res) {

                                    if (cpp_err) {
                                        if (exp_fun.isErr) {
                                            if (!exp_fun(cpp_err)) {
                                                printTestFailure(testName, src,
                                                    "Error running test on CPP server not equal to expected err:"+
                                                    "\n\tERROR: "+cpp_err.toString()+
                                                    "\n\tEXPECTED "+exp_fun.toString());
                                            }
                                        } else {
                                            printTestFailure(testName, src,
                                                "Error running test on CPP server:"+
                                                "\n\tERROR: "+cpp_err.toString());
                                        }
                                    } else if (!exp_fun(cpp_res)) {
                                        printTestFailure(testName, src,
                                            "CPP result is not equal to expected result:"+
                                            "\n\tVALUE: "+cpp_res.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                                    }

                                    /*
                                    if (js_err) {
                                        if (exp_fun.isErr && !exp_fun(js_err)) {
                                            printTestFailure(testName, src,
                                                "Error running test on JS server not equal to expected err:"+
                                                "\n\tERROR: "+js_err.toString()+
                                                "\n\tEXPECTED "+exp_fun.toString());
                                        } else {
                                            printTestFailure(testName, src,
                                                "Error running test on JS server:"+
                                                "\n\tERROR: "+cpp_err.toString());
                                        }
                                    } else if (!exp_fun(js_res)) {
                                        printTestFailure(testName, src,
                                            "JS result is not equal to expected result:"+
                                            "\n\tVALUE: "+js_res.toString()+"\n\tEXPECTED: "+exp_fun.toString());
                                    }
                                    */

                                    // Continue to next test. Tests are fully sequential
                                    // so you can rely on previous queries results in
                                    // subsequent tests.
                                    runTest();
                                    return;
                                }
                            //}
                        }
                    }
                }
            } else {
                // We've hit the end of our test list
                // closing the connection will allow the
                // event loop to quit naturally
                cpp_conn.close();
                //js_conn.close();
            }
        }

        // Start the recursion though all the tests
        runTest();
    //});
});

// Invoked by generated code to add test and expected result
// Really constructs list of tests to be sequentially evaluated
function test(testSrc, resSrc, name) {
    tests.push([testSrc, resSrc, name])
}

// Invoked by generated code to define variables to used within
// subsequent tests
function define(expr) {
    tests.push(function() {
        with (defines) {
            eval("defines."+expr);
        }
    });
}

// Invoked by generated code to support bag comparison on this expected value
function bag(list) {
    var bag = eval(list).sort();
    var fun = function(other) {
        other = other.sort();
        return eq_test(bag, other);
    };
    fun.toString = function() {
        return "bag("+list+")";
    };
    return fun;
}

// Invoked by generated code to demonstrate expected error output
function err(err_name, err_msg, err_frames) {
    var err_frames = null; // Don't test frames for now, at least not until the C++ is done with them
    var fun = function(other) {
        if (!(function() {
            if (!(other instanceof Error)) return false;
            if (err_name && !(other.name === err_name)) return false;

            // Strip out "offending object" from err message
            other.msg = other.msg.replace(/:\n([\r\n]|.)*/m, ".");

            if (err_msg && !(other.msg === err_msg)) return false;
            if (err_frames && !(eq_test(other.frames, err_frames))) return false;
            return true;
        })()) {
            return false;
        }
        return true;
    }
    fun.isErr = true;
    fun.toString = function() {
        return err_name+"(\""+err_msg+"\")";
    };
    return fun;
}

function arr(length, eq_fun) {
    var fun = function(thing) {
        if (!thing.length || thing.length !== length) return false;
        return !eq_fun || thing.every(eq_fun);
    };
    fun.toString = function() {
        return "arr("+length+(eq_fun ? ", "+eq_fun.toString() : '')+")";
    };
    return fun;
}

function uuid() {
    var fun = function(thing) {
        return thing.match && thing.match(/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/);
    };
    fun.toString = function() {
        return "uuid()";
    };
    return fun;
};

True = true;
False = false;
<|endoftext|>


<commit_before>(function () {

  function QuadraticDrawing () {
  }

  QuadraticDrawing.prototype = {

    height : null,
    width : null,
    rendered : false,

    render : function (node) {
      var
        canvas = document.createElement('canvas'),//bonzo.create('<canvas></canvas>')[0],
        offset = bonzo(node).offset();

      this.height = offset.height;
      this.width = offset.width;

      bonzo(canvas)
        .attr('height', offset.height)
        .attr('width', offset.width)
        .css({
          position : 'absolute',
          top : '0px',
          left : '0px'
        });

      node.appendChild(canvas);
      bonzo(node).css({
        position : 'relative'
      });

      if (typeof FlashCanvas !== 'undefined') FlashCanvas.initElement(canvas);
      this.context = canvas.getContext('2d');
      this.rendered = true;
    },

    draw : function (data, options, node) {

      if (!this.rendered) this.render(node);

      var
        context = this.context,
        height = this.height,
        width = this.width,
        half = Math.round(height / 2) - .5,
        min, max;

      options = options || { min : width / 2, max : width / 2};

      min = options.min + 0.5;
      max = options.max + 0.5;

      context.clearRect(0, 0, width, height);
      if (min || max) {
        context.save();
        context.strokeStyle = '#B6D9FF';
        context.fillOpacity = .5;
        context.fillStyle = 'rgba(182, 217, 255, .4)';
        context.beginPath();

        // Left
        if (min <= 1) {
          context.moveTo(0, height);
          context.lineTo(0, -0.5);
        } else {
          context.moveTo(min, height);
          context.quadraticCurveTo(min, half, Math.max(min - half, min / 2), half);
          context.lineTo(Math.min(half, min / 2), half);
          context.quadraticCurveTo(0, half, 0, -0.5);
        }

        // Top
        context.lineTo(width, -0.5);

        // Right
        if (max >= width - 1) {
          context.lineTo(max, height);
        } else {
          context.quadraticCurveTo(width, half, Math.max(width - half, width - (width - max) / 2), half);
          context.lineTo(Math.min(max + half, width - (width - max) / 2), half);
          context.quadraticCurveTo(max, half, max, height);
        }

        context.stroke();
        context.closePath();
        context.fill();
        context.restore();
      }
    },
    trigger : function (child, name, options) {
      if (name === 'zoom') {
        this.zoom(child, options);
      } else if (name === 'click') {
        this.click(child);
      }
    },
    zoom : function (child, options) {
      var
        x = options.x || {},
        min = x.min,
        max = x.max,
        api = child.api;

      child.draw(null, {
        min : min,
        max : max
      });
    },
    click : function (child) {
      child.draw(null, {
        min : child.width / 2,
        max : child.width / 2
      });
    }
  };
  envision.QuadraticDrawing = QuadraticDrawing;
})();
<commit_msg>Added configurable colors.<commit_after>(function () {

  function QuadraticDrawing (options) {
    this.options = options || {};
  }

  QuadraticDrawing.prototype = {

    height : null,
    width : null,
    rendered : false,

    render : function (node) {
      var
        canvas = document.createElement('canvas'),//bonzo.create('<canvas></canvas>')[0],
        offset = bonzo(node).offset();

      this.height = offset.height;
      this.width = offset.width;

      bonzo(canvas)
        .attr('height', offset.height)
        .attr('width', offset.width)
        .css({
          position : 'absolute',
          top : '0px',
          left : '0px'
        });

      node.appendChild(canvas);
      bonzo(node).css({
        position : 'relative'
      });

      if (typeof FlashCanvas !== 'undefined') FlashCanvas.initElement(canvas);
      this.context = canvas.getContext('2d');
      this.rendered = true;
    },

    draw : function (data, options, node) {

      if (!this.rendered) this.render(node);

      var
        context = this.context,
        height = this.height,
        width = this.width,
        half = Math.round(height / 2) - .5,
        min, max;

      options = options || { min : width / 2, max : width / 2};

      min = options.min + 0.5;
      max = options.max + 0.5;

      context.clearRect(0, 0, width, height);
      if (min || max) {
        context.save();
        context.strokeStyle = this.options.strokeStyle || '#B6D9FF';
        context.fillStyle = this.options.fillStyle || 'rgba(182, 217, 255, .4)';
        context.beginPath();

        // Left
        if (min <= 1) {
          context.moveTo(0, height);
          context.lineTo(0, -0.5);
        } else {
          context.moveTo(min, height);
          context.quadraticCurveTo(min, half, Math.max(min - half, min / 2), half);
          context.lineTo(Math.min(half, min / 2), half);
          context.quadraticCurveTo(0, half, 0, -0.5);
        }

        // Top
        context.lineTo(width, -0.5);

        // Right
        if (max >= width - 1) {
          context.lineTo(max, height);
        } else {
          context.quadraticCurveTo(width, half, Math.max(width - half, width - (width - max) / 2), half);
          context.lineTo(Math.min(max + half, width - (width - max) / 2), half);
          context.quadraticCurveTo(max, half, max, height);
        }

        context.stroke();
        context.closePath();
        context.fill();
        context.restore();
      }
    },
    trigger : function (child, name, options) {
      if (name === 'zoom') {
        this.zoom(child, options);
      } else if (name === 'click') {
        this.click(child);
      }
    },
    zoom : function (child, options) {
      var
        x = options.x || {},
        min = x.min,
        max = x.max,
        api = child.api;

      child.draw(null, {
        min : min,
        max : max
      });
    },
    click : function (child) {
      child.draw(null, {
        min : child.width / 2,
        max : child.width / 2
      });
    }
  };
  envision.QuadraticDrawing = QuadraticDrawing;
})();
<|endoftext|>


<commit_before>import Remote, {nullRemote} from '../../lib/models/remote';

describe('Remote', function() {
  it('detects and extracts information from GitHub repository URLs', function() {
    const urls = [
      ['git@github.com:atom/github.git', 'ssh'],
      ['https://github.com/atom/github.git', 'https'],
      ['https://git:pass@github.com/atom/github.git', 'https'],
      ['ssh+https://github.com/atom/github.git', 'ssh+https'],
      ['git://github.com/atom/github', 'git'],
      ['ssh://git@github.com:atom/github.git', 'ssh'],
    ];

    for (const [url, proto] of urls) {
      const remote = new Remote('origin', url);

      assert.isTrue(remote.isPresent());
      assert.strictEqual(remote.getName(), 'origin');
      assert.strictEqual(remote.getNameOr('else'), 'origin');
      assert.strictEqual(remote.getUrl(), url);
      assert.isTrue(remote.isGithubRepo());
      assert.strictEqual(remote.getDomain(), 'github.com');
      assert.strictEqual(remote.getProtocol(), proto);
      assert.strictEqual(remote.getOwner(), 'atom');
      assert.strictEqual(remote.getRepo(), 'github');
      assert.strictEqual(remote.getSlug(), 'atom/github');
    }
  });

  it('detects non-GitHub remotes', function() {
    const urls = [
      'git@gitlab.com:atom/github.git',
      'atom/github',
    ];

    for (const url of urls) {
      const remote = new Remote('origin', url);

      assert.isTrue(remote.isPresent());
      assert.strictEqual(remote.getName(), 'origin');
      assert.strictEqual(remote.getNameOr('else'), 'origin');
      assert.strictEqual(remote.getUrl(), url);
      assert.isFalse(remote.isGithubRepo());
      assert.isNull(remote.getDomain());
      assert.isNull(remote.getOwner());
      assert.isNull(remote.getRepo());
      assert.isNull(remote.getSlug());
    }
  });

  it('may be created without a URL', function() {
    const remote = new Remote('origin');

    assert.isTrue(remote.isPresent());
    assert.strictEqual(remote.getName(), 'origin');
    assert.strictEqual(remote.getNameOr('else'), 'origin');
    assert.isNull(remote.getUrl());
    assert.isFalse(remote.isGithubRepo());
    assert.isNull(remote.getDomain());
    assert.isNull(remote.getOwner());
    assert.isNull(remote.getRepo());
    assert.isNull(remote.getSlug());
  });

  it('has a corresponding null object', function() {
    assert.isFalse(nullRemote.isPresent());
    assert.strictEqual(nullRemote.getName(), '');
    assert.strictEqual(nullRemote.getUrl(), '');
    assert.isFalse(nullRemote.isGithubRepo());
    assert.isNull(nullRemote.getDomain());
    assert.isNull(nullRemote.getProtocol());
    assert.isNull(nullRemote.getOwner());
    assert.isNull(nullRemote.getRepo());
    assert.isNull(nullRemote.getSlug());
    assert.strictEqual(nullRemote.getNameOr('else'), 'else');
  });
});
<commit_msg>getUrl() is undefined, not null<commit_after>import Remote, {nullRemote} from '../../lib/models/remote';

describe('Remote', function() {
  it('detects and extracts information from GitHub repository URLs', function() {
    const urls = [
      ['git@github.com:atom/github.git', 'ssh'],
      ['https://github.com/atom/github.git', 'https'],
      ['https://git:pass@github.com/atom/github.git', 'https'],
      ['ssh+https://github.com/atom/github.git', 'ssh+https'],
      ['git://github.com/atom/github', 'git'],
      ['ssh://git@github.com:atom/github.git', 'ssh'],
    ];

    for (const [url, proto] of urls) {
      const remote = new Remote('origin', url);

      assert.isTrue(remote.isPresent());
      assert.strictEqual(remote.getName(), 'origin');
      assert.strictEqual(remote.getNameOr('else'), 'origin');
      assert.strictEqual(remote.getUrl(), url);
      assert.isTrue(remote.isGithubRepo());
      assert.strictEqual(remote.getDomain(), 'github.com');
      assert.strictEqual(remote.getProtocol(), proto);
      assert.strictEqual(remote.getOwner(), 'atom');
      assert.strictEqual(remote.getRepo(), 'github');
      assert.strictEqual(remote.getSlug(), 'atom/github');
    }
  });

  it('detects non-GitHub remotes', function() {
    const urls = [
      'git@gitlab.com:atom/github.git',
      'atom/github',
    ];

    for (const url of urls) {
      const remote = new Remote('origin', url);

      assert.isTrue(remote.isPresent());
      assert.strictEqual(remote.getName(), 'origin');
      assert.strictEqual(remote.getNameOr('else'), 'origin');
      assert.strictEqual(remote.getUrl(), url);
      assert.isFalse(remote.isGithubRepo());
      assert.isNull(remote.getDomain());
      assert.isNull(remote.getOwner());
      assert.isNull(remote.getRepo());
      assert.isNull(remote.getSlug());
    }
  });

  it('may be created without a URL', function() {
    const remote = new Remote('origin');

    assert.isTrue(remote.isPresent());
    assert.strictEqual(remote.getName(), 'origin');
    assert.strictEqual(remote.getNameOr('else'), 'origin');
    assert.isUndefined(remote.getUrl());
    assert.isFalse(remote.isGithubRepo());
    assert.isNull(remote.getDomain());
    assert.isNull(remote.getOwner());
    assert.isNull(remote.getRepo());
    assert.isNull(remote.getSlug());
  });

  it('has a corresponding null object', function() {
    assert.isFalse(nullRemote.isPresent());
    assert.strictEqual(nullRemote.getName(), '');
    assert.strictEqual(nullRemote.getUrl(), '');
    assert.isFalse(nullRemote.isGithubRepo());
    assert.isNull(nullRemote.getDomain());
    assert.isNull(nullRemote.getProtocol());
    assert.isNull(nullRemote.getOwner());
    assert.isNull(nullRemote.getRepo());
    assert.isNull(nullRemote.getSlug());
    assert.strictEqual(nullRemote.getNameOr('else'), 'else');
  });
});
<|endoftext|>


<commit_before>define(['jquery', 'underscore', 'backbone',
	'text!./app/views/templates/main.html',
	'text!./app/views/templates/item-listing.html',
	'text!./app/views/templates/item-listing-empty.html',
	'text!./app/views/templates/person-info.html',
	'text!./app/views/templates/loading.html',
	'text!./app/views/templates/delete-modal.html',
    'text!./app/views/templates/view-modal.html',
	'models', 'utils', 'facebook', 'view_common'
], function($, _, Backbone, mainTemplate, itemListingTemplate, itemListingEmptyTemplate, personInfoTemplate, defaultLoadingTemplate,
	deleteModalTemplate, viewModalTemplate, Models, Utils) {
	var Views = {};

	Views.GenericCollectionView = Backbone.View.extend({
		loadingTemplate: defaultLoadingTemplate,

		initialize: function() {
			this.listenTo(this.collection, 'add', this.collectionAdded);
			this.listenTo(this.collection, 'change', this.collectionChanged);
			this.listenTo(this.collection, 'remove', this.collectionRemoved);
			this.listenTo(this.collection, 'delete', this.itemDeleted);

			var that = this;
			this.listenTo(this.collection, 'fetched', function() {
				that._loaded = true;
				that.render();
			});

			this.childViews = [];
			this.render();
		},

		render: function() {
			var fragment = document.createDocumentFragment();

			if (!this._loaded) {
				$(this.loadingTemplate).appendTo(fragment);
			} else if (this.childViews.length > 0) {
				_(this.childViews).each(function(currentView) {
					fragment.appendChild(currentView.render().el);
				});
			} else {
				$(itemListingEmptyTemplate).appendTo(fragment);
			}

			this._appendFragmentToDocument(fragment);
			return this;
		},

		collectionAdded: function(item) {
			var that = this;
			item.set({
				userId: that.options.userId
			});
			this._addViewForModel(item);
			this.render();
		},

		collectionRemoved: function(item) {
			this.childViews = this.childViews.filter(function(view) {
				return view.model.id !== item.id;
			});
			this.render();
		},

		collectionChanged: function(item) {
			if (!item.changed.userId) {
				this.childViews = [];
				this._addAllModels();
			}
		},

		itemDeleted: function(item) {
			this.collection.remove(item);
		},

		_addViewForModel: function(item) {
			this.childViews.push(new this.subView({
				model: item
			}));
		},

		_addAllModels: function() {
			var that = this;
			this.collection.each(function(item) {
				item.set({
					userId: that.options.userId
				});
				that._addViewForModel(item);
			});
			this.render();
		}
	});

	Views.ItemView = Backbone.View.extend({
		template: _.template(itemListingTemplate),
		personInfoTemplate: _.template(personInfoTemplate),

		events: {
			"click button#btn-pledge": 'pledgeClicked',
			"click button#btn-unpledge": 'unpledgeClicked',
			"click button#btn-delete": 'deleteClicked',
			"click div.item-buyers": "buyersClicked",
            "click a.listing" : "listingClicked"
		},

		initialize: function() {
			this.listenTo(this.model, "change", this.render);
			this.id = "item-" + this.model.attributes.id;
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			return this;
		},

		pledgeClicked: function(e) {
            e.stopImmediatePropagation();

			var that = this;
			$.ajax({
				url: '/service/me/want',
				dataType: 'json',
				type: 'POST',
				data: {
					product_listing_id: this.model.attributes.id
				}
			}).success(function() {
				Utils.postUserTimeline(that.model.attributes.id);
			});
			this.model.fetch();
		},

		unpledgeClicked: function(e) {
            e.stopImmediatePropagation();

			$.ajax({
				url: '/service/me/dontWant',
				dataType: 'json',
				type: 'POST',
				data: {
					product_listing_id: this.model.attributes.id
				}
			});
			this.model.fetch();
		},

		buyersClicked: function(e) {
            e.stopImmediatePropagation();

			if (this._buyerListPopover) {
				//We only handle this once.
				return;
			}

			var buyerIds = this.model.attributes.buyers;
			buyerIds.push(this.model.attributes.owner);
			var buyerQueries = [];
			var buyerObjects = new Backbone.Collection([], {

			});
			_.each(buyerIds, function(currentId) {
				var requestUrl = Utils.getFacebookApiLink(currentId);
				var pictureUrl = requestUrl + '/picture';
				buyerQueries.push($.ajax({
					url: requestUrl,
					dataType: 'json',
					type: 'GET',
					success: function(response) {
						buyerObjects.add({
							name: response.name,
							link: response.link || '//www.facebook.com/' + response.id,
							picture: pictureUrl
						});
					}
				}));
			});

			var that = this;
			$.when.apply($, buyerQueries)
				.done(function() {
					function handlePopoverClick(e) {
						if (!that._buyerListPopover) {
							return;
						}

						var target = e.target || e.toElement;
						if (target === that._buyerListPopover[0]) {
							//We are going to ourself.
							that._buyerListPopover.popover('toggle');
						} else {
							dismissPopover();
						}
					}

					function dismissPopover() {
						if (that._buyerListPopover) {
							that._buyerListPopover.popover('hide');
						}
					}

					var buyerFragment = document.createElement('div');
					for (var i = 0; i < buyerObjects.length; ++i) {
						$(that.personInfoTemplate(buyerObjects.models[i].attributes)).
						appendTo(buyerFragment);
					}

					$('a', buyerFragment).tooltip();
					that._buyerListPopover = $('div.item-buyers span.item-buyers-list', that.$el);
					that._buyerListPopover.parents('div.item-listing').on('scroll', dismissPopover);
					$(document).on('click', handlePopoverClick);
					that._buyerListPopover.popover({
						selector: '#' + this.id,
						html: true,
						content: buyerFragment,
						container: that._buyerListPopover,
						toggle: 'trigger'
					});
					that._buyerListPopover.popover('show');
				});
		},

		deleteClicked: function(e) {
            e.stopImmediatePropagation();

			if (this.modal) {
				this.disposeModal();
			}

			this.modal = new Views.DeleteListingView({
				model: this.model,
				el: '#modal-container'
			});
			this.listenTo(this.modal, 'viewClosed', this.disposeModal);
		},

        listingClicked: function() {
			if (this.modal) {
				this.disposeModal();
			}

			this.modal = new Views.ViewItemModal({
				model: this.model,
				el: '#modal-container'
			});
			this.listenTo(this.modal, 'viewClosed', this.disposeModal);
        },

		disposeModal: function(isDeleted) {
			this.modal.undelegateEvents();

			if (isDeleted) {
				this.model.trigger("delete", this.model);
			}
		}
	});

	Views.DeleteListingView = Backbone.View.extend({
		template: _.template(deleteModalTemplate),

		initialize: function() {
			this.render();
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			$('#delete-warning-modal').modal('show');
		},

		events: {
			"click button.btn-danger": "deleteClicked",
			"click button.btn-success": "keepClicked"
		},

		deleteClicked: function() {
			var serviceUrl = '/service/listings/delete/' + this.model.attributes.id;

			var that = this;
			$.ajax({
				url: serviceUrl,
				dataType: 'json',
				type: 'GET',
				success: function() {
					that.dismissModal(true);
				},
				error: function() {
					alert("Oops. We couldn't delete the listing - try again later!");
				}
			});
		},

		keepClicked: function() {
			this.dismissModal(false);
		},

		dismissModal: function(isDeleted) {
			$('#delete-warning-modal').modal('hide');
			this.trigger("viewClosed", isDeleted);
		}
	});

	Views.ListingView = Views.GenericCollectionView.extend({
		_appendFragmentToDocument: function(fragment) {
			this.$('.item-listing').html(fragment);
		},
		subView: Views.ItemView
	});

	Views.ViewItemModal = Backbone.View.extend({
		template: _.template(viewModalTemplate),

		initialize: function() {
            this.listenTo(this.model, 'change', this.render);
            this.model.fetch();
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			$('#view-listing-modal').modal('show');
		},

		events: {
			"click button.btn-danger": "closeModal"
		},

		closeModal: function() {
			this.trigger("viewClosed");
		}
	});

	return Views;
});<commit_msg>Added Privacy policy template<commit_after>define(['jquery', 'underscore', 'backbone',
	'text!./app/views/templates/main.html',
	'text!./app/views/templates/item-listing.html',
	'text!./app/views/templates/item-listing-empty.html',
	'text!./app/views/templates/person-info.html',
	'text!./app/views/templates/loading.html',
	'text!./app/views/templates/delete-modal.html',
	'text!./app/views/templates/privacy-policy.html',
    'text!./app/views/templates/view-modal.html',
	'models', 'utils', 'facebook', 'view_common'
], function($, _, Backbone, mainTemplate, itemListingTemplate, itemListingEmptyTemplate, personInfoTemplate, defaultLoadingTemplate,
	deleteModalTemplate, viewModalTemplate, Models, Utils) {
	var Views = {};

	Views.GenericCollectionView = Backbone.View.extend({
		loadingTemplate: defaultLoadingTemplate,

		initialize: function() {
			this.listenTo(this.collection, 'add', this.collectionAdded);
			this.listenTo(this.collection, 'change', this.collectionChanged);
			this.listenTo(this.collection, 'remove', this.collectionRemoved);
			this.listenTo(this.collection, 'delete', this.itemDeleted);

			var that = this;
			this.listenTo(this.collection, 'fetched', function() {
				that._loaded = true;
				that.render();
			});

			this.childViews = [];
			this.render();
		},

		render: function() {
			var fragment = document.createDocumentFragment();

			if (!this._loaded) {
				$(this.loadingTemplate).appendTo(fragment);
			} else if (this.childViews.length > 0) {
				_(this.childViews).each(function(currentView) {
					fragment.appendChild(currentView.render().el);
				});
			} else {
				$(itemListingEmptyTemplate).appendTo(fragment);
			}

			this._appendFragmentToDocument(fragment);
			return this;
		},

		collectionAdded: function(item) {
			var that = this;
			item.set({
				userId: that.options.userId
			});
			this._addViewForModel(item);
			this.render();
		},

		collectionRemoved: function(item) {
			this.childViews = this.childViews.filter(function(view) {
				return view.model.id !== item.id;
			});
			this.render();
		},

		collectionChanged: function(item) {
			if (!item.changed.userId) {
				this.childViews = [];
				this._addAllModels();
			}
		},

		itemDeleted: function(item) {
			this.collection.remove(item);
		},

		_addViewForModel: function(item) {
			this.childViews.push(new this.subView({
				model: item
			}));
		},

		_addAllModels: function() {
			var that = this;
			this.collection.each(function(item) {
				item.set({
					userId: that.options.userId
				});
				that._addViewForModel(item);
			});
			this.render();
		}
	});

	Views.ItemView = Backbone.View.extend({
		template: _.template(itemListingTemplate),
		personInfoTemplate: _.template(personInfoTemplate),

		events: {
			"click button#btn-pledge": 'pledgeClicked',
			"click button#btn-unpledge": 'unpledgeClicked',
			"click button#btn-delete": 'deleteClicked',
			"click div.item-buyers": "buyersClicked",
            "click a.listing" : "listingClicked"
		},

		initialize: function() {
			this.listenTo(this.model, "change", this.render);
			this.id = "item-" + this.model.attributes.id;
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			return this;
		},

		pledgeClicked: function(e) {
            e.stopImmediatePropagation();

			var that = this;
			$.ajax({
				url: '/service/me/want',
				dataType: 'json',
				type: 'POST',
				data: {
					product_listing_id: this.model.attributes.id
				}
			}).success(function() {
				Utils.postUserTimeline(that.model.attributes.id);
			});
			this.model.fetch();
		},

		unpledgeClicked: function(e) {
            e.stopImmediatePropagation();

			$.ajax({
				url: '/service/me/dontWant',
				dataType: 'json',
				type: 'POST',
				data: {
					product_listing_id: this.model.attributes.id
				}
			});
			this.model.fetch();
		},

		buyersClicked: function(e) {
            e.stopImmediatePropagation();

			if (this._buyerListPopover) {
				//We only handle this once.
				return;
			}

			var buyerIds = this.model.attributes.buyers;
			buyerIds.push(this.model.attributes.owner);
			var buyerQueries = [];
			var buyerObjects = new Backbone.Collection([], {

			});
			_.each(buyerIds, function(currentId) {
				var requestUrl = Utils.getFacebookApiLink(currentId);
				var pictureUrl = requestUrl + '/picture';
				buyerQueries.push($.ajax({
					url: requestUrl,
					dataType: 'json',
					type: 'GET',
					success: function(response) {
						buyerObjects.add({
							name: response.name,
							link: response.link || '//www.facebook.com/' + response.id,
							picture: pictureUrl
						});
					}
				}));
			});

			var that = this;
			$.when.apply($, buyerQueries)
				.done(function() {
					function handlePopoverClick(e) {
						if (!that._buyerListPopover) {
							return;
						}

						var target = e.target || e.toElement;
						if (target === that._buyerListPopover[0]) {
							//We are going to ourself.
							that._buyerListPopover.popover('toggle');
						} else {
							dismissPopover();
						}
					}

					function dismissPopover() {
						if (that._buyerListPopover) {
							that._buyerListPopover.popover('hide');
						}
					}

					var buyerFragment = document.createElement('div');
					for (var i = 0; i < buyerObjects.length; ++i) {
						$(that.personInfoTemplate(buyerObjects.models[i].attributes)).
						appendTo(buyerFragment);
					}

					$('a', buyerFragment).tooltip();
					that._buyerListPopover = $('div.item-buyers span.item-buyers-list', that.$el);
					that._buyerListPopover.parents('div.item-listing').on('scroll', dismissPopover);
					$(document).on('click', handlePopoverClick);
					that._buyerListPopover.popover({
						selector: '#' + this.id,
						html: true,
						content: buyerFragment,
						container: that._buyerListPopover,
						toggle: 'trigger'
					});
					that._buyerListPopover.popover('show');
				});
		},

		deleteClicked: function(e) {
            e.stopImmediatePropagation();

			if (this.modal) {
				this.disposeModal();
			}

			this.modal = new Views.DeleteListingView({
				model: this.model,
				el: '#modal-container'
			});
			this.listenTo(this.modal, 'viewClosed', this.disposeModal);
		},

        listingClicked: function() {
			if (this.modal) {
				this.disposeModal();
			}

			this.modal = new Views.ViewItemModal({
				model: this.model,
				el: '#modal-container'
			});
			this.listenTo(this.modal, 'viewClosed', this.disposeModal);
        },

		disposeModal: function(isDeleted) {
			this.modal.undelegateEvents();

			if (isDeleted) {
				this.model.trigger("delete", this.model);
			}
		}
	});

	Views.DeleteListingView = Backbone.View.extend({
		template: _.template(deleteModalTemplate),

		initialize: function() {
			this.render();
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			$('#delete-warning-modal').modal('show');
		},

		events: {
			"click button.btn-danger": "deleteClicked",
			"click button.btn-success": "keepClicked"
		},

		deleteClicked: function() {
			var serviceUrl = '/service/listings/delete/' + this.model.attributes.id;

			var that = this;
			$.ajax({
				url: serviceUrl,
				dataType: 'json',
				type: 'GET',
				success: function() {
					that.dismissModal(true);
				},
				error: function() {
					alert("Oops. We couldn't delete the listing - try again later!");
				}
			});
		},

		keepClicked: function() {
			this.dismissModal(false);
		},

		dismissModal: function(isDeleted) {
			$('#delete-warning-modal').modal('hide');
			this.trigger("viewClosed", isDeleted);
		}
	});

	Views.ListingView = Views.GenericCollectionView.extend({
		_appendFragmentToDocument: function(fragment) {
			this.$('.item-listing').html(fragment);
		},
		subView: Views.ItemView
	});

	Views.ViewItemModal = Backbone.View.extend({
		template: _.template(viewModalTemplate),

		initialize: function() {
            this.listenTo(this.model, 'change', this.render);
            this.model.fetch();
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			$('#view-listing-modal').modal('show');
		},

		events: {
			"click button.btn-danger": "closeModal"
		},

		closeModal: function() {
			this.trigger("viewClosed");
		}
	});

	return Views;
});<|endoftext|>


<commit_before>function SubgraphEvent(renderObject) {
	// render object for this graph event
	this.renderObject = renderObject;

	var progress = function(alpha) {
		// range should match start to drawLines/drawCircles
	    var range = 0.1 - 0.01;
	    var percent = ((0.1 - alpha) / range) * 100;
	    return Math.floor(percent);
	};

        // circles stay stacked unless they change every tick
        this.renderObject.force.on("tick", function() {
                var alpha = renderObject.force.alpha();
                // use callback on bar to disable popup at 100%
                if (renderObject.canTick === true) {
                    $("#progress").progressBar(progress(alpha),
                                               {callback:progressCallback});
                }
                // start drawing lines when the graph is about to stay stable
                if (alpha<0.01 && renderObject.ready===false) {
                        $("#step2").hide();

			// draw nodes
			renderObject.drawCircles();
			// stop ticking immeidately as the complete graph was drawn
			renderObject.force.stop();

			// on click render the selected subgraph
			renderObject.circle.on('click', function(d, i) {
				// throw a new popup up
				resetPopup();

                                // make only the graph tick
                                renderObject.canTick = false;

                                // reenable the search and subgraph button
	                        $("#searchbar").show();
                                $("#dots").show();

				// erase and empty current render
				renderObject.empty();
				// call to server to obtain the selected graph info
				var ajaxUrl = 'data/search.php?subgraph='+d.subgraph_id;
				if (d.subgraph_id==1)
					ajaxUrl = 'data/search.php?user=vmworld&depth=2600';
				d3.json(ajaxUrl, function(data) {
					// switch the spinning bar for the loading bar
					switchBars();
					// data for new graph
					window.gr.data(data.nodes, data.links);
					window.gr.setCenterNode(0);
					// redraw selected graph with new graph events
					window.gr.draw();
				});
			});
			// mark render object as completely ready
			renderObject.ready = true;
		}

		// ticking the cirlces
		renderObject.circle
			.attr("cx", function(d) { return d.x; })
			.attr("cy", function(d) { return d.y; });
	});
}
<commit_msg>debugging subgraph<commit_after>function SubgraphEvent(renderObject) {
	// render object for this graph event
	this.renderObject = renderObject;

	var progress = function(alpha) {
		// range should match start to drawLines/drawCircles
	    var range = 0.1 - 0.01;
	    var percent = ((0.1 - alpha) / range) * 100;
	    return Math.floor(percent);
	};

        // circles stay stacked unless they change every tick
        this.renderObject.force.on("tick", function() {
                var alpha = renderObject.force.alpha();
                // use callback on bar to disable popup at 100%
                if (renderObject.canTick === true) {
                    $("#progress").progressBar(progress(alpha),
                                               {callback:progressCallback});
                }
                // start drawing lines when the graph is about to stay stable
                if (alpha<0.01 && renderObject.ready===false) {
                        $("#step2").hide();

			// draw nodes
			renderObject.drawCircles();
			// stop ticking immeidately as the complete graph was drawn
			renderObject.force.stop();

			// on click render the selected subgraph
			renderObject.circle.on('click', function(d, i) {
				// throw a new popup up
				resetPopup();

                                // make only the graph tick
                                renderObject.canTick = false;

                                // reenable the search and subgraph button
	                        $("#searchbar").show();
                                $("#dots").show();

				// erase and empty current render
				renderObject.empty();
				// call to server to obtain the selected graph info
				var ajaxUrl = 'data/search.php?subgraph='+d.subgraph_id;
				if (d.subgraph_id==1)
					ajaxUrl = 'data/search.php?user=vmworld&depth=100';
				d3.json(ajaxUrl, function(data) {
					// switch the spinning bar for the loading bar
					switchBars();
					// data for new graph
					window.gr.data(data.nodes, data.links);
					window.gr.setCenterNode(0);
					// redraw selected graph with new graph events
					window.gr.draw();
				});
			});
			// mark render object as completely ready
			renderObject.ready = true;
		}

		// ticking the cirlces
		renderObject.circle
			.attr("cx", function(d) { return d.x; })
			.attr("cy", function(d) { return d.y; });
	});
}
<|endoftext|>


<commit_before>"use strict";

const chai = require( "chai" );
const peg = require( "pegjs-dev" );
const sinon = require( "sinon" );

const expect = chai.expect;

describe( "PEG.js API", function () {

    describe( "generate", function () {

        it( "generates a parser", function () {

            const parser = peg.generate( "start = 'a'" );

            expect( parser ).to.be.an( "object" );
            expect( parser.parse( "a" ) ).to.equal( "a" );

        } );

        it( "throws an exception on syntax error", function () {

            expect( () => {

                peg.generate( "start = @" );

            } ).to.throw();

        } );

        it( "throws an exception on semantic error", function () {

            expect( () => {

                peg.generate( "start = undefined" );

            } ).to.throw();

        } );

        describe( "allowed start rules", function () {

            const grammar = `

                a = 'x'
                b = 'x'
                c = 'x'

            `;

            it( "throws an error on missing rule", function () {

                expect( () => {

                    peg.generate( grammar, { allowedStartRules: [ "missing" ] } );

                } ).to.throw();

            } );

            // The |allowedStartRules| option is implemented separately for each
            // optimization mode, so we need to test it in both.

            describe( "when optimizing for parsing speed", function () {

                describe( "when |allowedStartRules| is not set", function () {

                    it( "generated parser can start only from the first rule", function () {

                        const parser = peg.generate( grammar, { optimize: "speed" } );

                        expect( parser.parse( "x", { startRule: "a" } ) ).to.equal( "x" );
                        expect( () => {

                            parser.parse( "x", { startRule: "b" } );

                        } ).to.throw();
                        expect( () => {

                            parser.parse( "x", { startRule: "c" } );

                        } ).to.throw();

                    } );

                } );

                describe( "when |allowedStartRules| is set", function () {

                    it( "generated parser can start only from specified rules", function () {

                        const parser = peg.generate( grammar, {
                            optimize: "speed",
                            allowedStartRules: [ "b", "c" ]
                        } );

                        expect( () => {

                            parser.parse( "x", { startRule: "a" } );

                        } ).to.throw();
                        expect( parser.parse( "x", { startRule: "b" } ) ).to.equal( "x" );
                        expect( parser.parse( "x", { startRule: "c" } ) ).to.equal( "x" );

                    } );

                } );

            } );

            describe( "when optimizing for code size", function () {

                describe( "when |allowedStartRules| is not set", function () {

                    it( "generated parser can start only from the first rule", function () {

                        const parser = peg.generate( grammar, { optimize: "size" } );

                        expect( parser.parse( "x", { startRule: "a" } ) ).to.equal( "x" );
                        expect( () => {

                            parser.parse( "x", { startRule: "b" } );

                        } ).to.throw();
                        expect( () => {

                            parser.parse( "x", { startRule: "c" } );

                        } ).to.throw();

                    } );

                } );

                describe( "when |allowedStartRules| is set", function () {

                    it( "generated parser can start only from specified rules", function () {

                        const parser = peg.generate( grammar, {
                            optimize: "size",
                            allowedStartRules: [ "b", "c" ]
                        } );

                        expect( () => {

                            parser.parse( "x", { startRule: "a" } );

                        } ).to.throw();
                        expect( parser.parse( "x", { startRule: "b" } ) ).to.equal( "x" );
                        expect( parser.parse( "x", { startRule: "c" } ) ).to.equal( "x" );

                    } );

                } );

            } );

        } );

        describe( "intermediate results caching", function () {

            const grammar = `

                { var n = 0; }
                start = (a 'b') / (a 'c') { return n; }
                a = 'a' { n++; }

            `;

            describe( "when |cache| is not set", function () {

                it( "generated parser doesn't cache intermediate parse results", function () {

                    const parser = peg.generate( grammar );
                    expect( parser.parse( "ac" ) ).to.equal( 2 );

                } );

            } );

            describe( "when |cache| is set to |false|", function () {

                it( "generated parser doesn't cache intermediate parse results", function () {

                    const parser = peg.generate( grammar, { cache: false } );
                    expect( parser.parse( "ac" ) ).to.equal( 2 );

                } );

            } );

            describe( "when |cache| is set to |true|", function () {

                it( "generated parser caches intermediate parse results", function () {

                    const parser = peg.generate( grammar, { cache: true } );
                    expect( parser.parse( "ac" ) ).to.equal( 1 );

                } );

            } );

        } );

        describe( "tracing", function () {

            const grammar = "start = 'a'";

            describe( "when |trace| is not set", function () {

                it( "generated parser doesn't trace", function () {

                    const parser = peg.generate( grammar );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( false );

                } );

            } );

            describe( "when |trace| is set to |false|", function () {

                it( "generated parser doesn't trace", function () {

                    const parser = peg.generate( grammar, { trace: false } );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( false );

                } );

            } );

            describe( "when |trace| is set to |true|", function () {

                it( "generated parser traces", function () {

                    const parser = peg.generate( grammar, { trace: true } );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( true );

                } );

            } );

        } );

        // The |optimize| option isn't tested because there is no meaningful way to
        // write the tests without turning this into a performance test.

        describe( "output", function () {

            const grammar = "start = 'a'";

            describe( "when |output| is not set", function () {

                it( "returns generated parser object", function () {

                    const parser = peg.generate( grammar );

                    expect( parser ).to.be.an( "object" );
                    expect( parser.parse( "a" ) ).to.equal( "a" );

                } );

            } );

            describe( "when |output| is set to |\"parser\"|", function () {

                it( "returns generated parser object", function () {

                    const parser = peg.generate( grammar, { output: "parser" } );

                    expect( parser ).to.be.an( "object" );
                    expect( parser.parse( "a" ) ).to.equal( "a" );

                } );

            } );

            describe( "when |output| is set to |\"source\"|", function () {

                it( "returns generated parser source code", function () {

                    const source = peg.generate( grammar, { output: "source" } );

                    expect( source ).to.be.a( "string" );
                    expect( eval( source ).parse( "a" ) ).to.equal( "a" );

                } );

            } );

        } );

        // The |format|, |exportVars|, and |dependencies| options are not tested
        // becasue there is no meaningful way to thest their effects without turning
        // this into an integration test.

        // The |plugins| option is tested in plugin API tests.

        describe( "reserved words", function () {

            const RESERVED_WORDS = [
                "break",
                "case",
                "catch",
                "class",
                "const",
                "continue",
                "debugger",
                "default",
                "delete",
                "do",
                "else",
                "enum",
                "export",
                "extends",
                "false",
                "finally",
                "for",
                "function",
                "if",
                "import",
                "instanceof",
                "in",
                "new",
                "null",
                "return",
                "super",
                "switch",
                "this",
                "throw",
                "true",
                "try",
                "typeof",
                "var",
                "void",
                "while",
                "with"
            ];

            describe( "throws an exception on reserved JS words used as labels", function () {

                for ( const label of RESERVED_WORDS ) {

                    it( label, function () {

                        expect( () => {

                            peg.generate( [
                                "start = " + label + ":end",
                                "end = 'a'"
                            ].join( "\n" ), { output: "source" } );

                        } ).to.throw( peg.parser.SyntaxError );

                    } );

                }

            } );

            describe( "not throws an exception on reserved JS words used as rule name", function () {

                for ( const rule of RESERVED_WORDS ) {

                    it( rule, function () {

                        expect( () => {

                            peg.generate( [
                                "start = " + rule,
                                rule + " = 'a'"
                            ].join( "\n" ), { output: "source" } );

                        } ).to.not.throw( peg.parser.SyntaxError );

                    } );

                }

            } );

        } );

        it( "accepts custom options", function () {

            peg.generate( "start = 'a'", { foo: 42 } );

        } );

    } );

} );
<commit_msg>Use peg.util.reservedWords<commit_after>"use strict";

const chai = require( "chai" );
const peg = require( "pegjs-dev" );
const sinon = require( "sinon" );

const expect = chai.expect;

describe( "PEG.js API", function () {

    describe( "generate", function () {

        it( "generates a parser", function () {

            const parser = peg.generate( "start = 'a'" );

            expect( parser ).to.be.an( "object" );
            expect( parser.parse( "a" ) ).to.equal( "a" );

        } );

        it( "throws an exception on syntax error", function () {

            expect( () => {

                peg.generate( "start = @" );

            } ).to.throw();

        } );

        it( "throws an exception on semantic error", function () {

            expect( () => {

                peg.generate( "start = undefined" );

            } ).to.throw();

        } );

        describe( "allowed start rules", function () {

            const grammar = `

                a = 'x'
                b = 'x'
                c = 'x'

            `;

            it( "throws an error on missing rule", function () {

                expect( () => {

                    peg.generate( grammar, { allowedStartRules: [ "missing" ] } );

                } ).to.throw();

            } );

            // The |allowedStartRules| option is implemented separately for each
            // optimization mode, so we need to test it in both.

            describe( "when optimizing for parsing speed", function () {

                describe( "when |allowedStartRules| is not set", function () {

                    it( "generated parser can start only from the first rule", function () {

                        const parser = peg.generate( grammar, { optimize: "speed" } );

                        expect( parser.parse( "x", { startRule: "a" } ) ).to.equal( "x" );
                        expect( () => {

                            parser.parse( "x", { startRule: "b" } );

                        } ).to.throw();
                        expect( () => {

                            parser.parse( "x", { startRule: "c" } );

                        } ).to.throw();

                    } );

                } );

                describe( "when |allowedStartRules| is set", function () {

                    it( "generated parser can start only from specified rules", function () {

                        const parser = peg.generate( grammar, {
                            optimize: "speed",
                            allowedStartRules: [ "b", "c" ]
                        } );

                        expect( () => {

                            parser.parse( "x", { startRule: "a" } );

                        } ).to.throw();
                        expect( parser.parse( "x", { startRule: "b" } ) ).to.equal( "x" );
                        expect( parser.parse( "x", { startRule: "c" } ) ).to.equal( "x" );

                    } );

                } );

            } );

            describe( "when optimizing for code size", function () {

                describe( "when |allowedStartRules| is not set", function () {

                    it( "generated parser can start only from the first rule", function () {

                        const parser = peg.generate( grammar, { optimize: "size" } );

                        expect( parser.parse( "x", { startRule: "a" } ) ).to.equal( "x" );
                        expect( () => {

                            parser.parse( "x", { startRule: "b" } );

                        } ).to.throw();
                        expect( () => {

                            parser.parse( "x", { startRule: "c" } );

                        } ).to.throw();

                    } );

                } );

                describe( "when |allowedStartRules| is set", function () {

                    it( "generated parser can start only from specified rules", function () {

                        const parser = peg.generate( grammar, {
                            optimize: "size",
                            allowedStartRules: [ "b", "c" ]
                        } );

                        expect( () => {

                            parser.parse( "x", { startRule: "a" } );

                        } ).to.throw();
                        expect( parser.parse( "x", { startRule: "b" } ) ).to.equal( "x" );
                        expect( parser.parse( "x", { startRule: "c" } ) ).to.equal( "x" );

                    } );

                } );

            } );

        } );

        describe( "intermediate results caching", function () {

            const grammar = `

                { var n = 0; }
                start = (a 'b') / (a 'c') { return n; }
                a = 'a' { n++; }

            `;

            describe( "when |cache| is not set", function () {

                it( "generated parser doesn't cache intermediate parse results", function () {

                    const parser = peg.generate( grammar );
                    expect( parser.parse( "ac" ) ).to.equal( 2 );

                } );

            } );

            describe( "when |cache| is set to |false|", function () {

                it( "generated parser doesn't cache intermediate parse results", function () {

                    const parser = peg.generate( grammar, { cache: false } );
                    expect( parser.parse( "ac" ) ).to.equal( 2 );

                } );

            } );

            describe( "when |cache| is set to |true|", function () {

                it( "generated parser caches intermediate parse results", function () {

                    const parser = peg.generate( grammar, { cache: true } );
                    expect( parser.parse( "ac" ) ).to.equal( 1 );

                } );

            } );

        } );

        describe( "tracing", function () {

            const grammar = "start = 'a'";

            describe( "when |trace| is not set", function () {

                it( "generated parser doesn't trace", function () {

                    const parser = peg.generate( grammar );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( false );

                } );

            } );

            describe( "when |trace| is set to |false|", function () {

                it( "generated parser doesn't trace", function () {

                    const parser = peg.generate( grammar, { trace: false } );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( false );

                } );

            } );

            describe( "when |trace| is set to |true|", function () {

                it( "generated parser traces", function () {

                    const parser = peg.generate( grammar, { trace: true } );
                    const tracer = { trace: sinon.spy() };

                    parser.parse( "a", { tracer: tracer } );

                    expect( tracer.trace.called ).to.equal( true );

                } );

            } );

        } );

        // The |optimize| option isn't tested because there is no meaningful way to
        // write the tests without turning this into a performance test.

        describe( "output", function () {

            const grammar = "start = 'a'";

            describe( "when |output| is not set", function () {

                it( "returns generated parser object", function () {

                    const parser = peg.generate( grammar );

                    expect( parser ).to.be.an( "object" );
                    expect( parser.parse( "a" ) ).to.equal( "a" );

                } );

            } );

            describe( "when |output| is set to |\"parser\"|", function () {

                it( "returns generated parser object", function () {

                    const parser = peg.generate( grammar, { output: "parser" } );

                    expect( parser ).to.be.an( "object" );
                    expect( parser.parse( "a" ) ).to.equal( "a" );

                } );

            } );

            describe( "when |output| is set to |\"source\"|", function () {

                it( "returns generated parser source code", function () {

                    const source = peg.generate( grammar, { output: "source" } );

                    expect( source ).to.be.a( "string" );
                    expect( eval( source ).parse( "a" ) ).to.equal( "a" );

                } );

            } );

        } );

        // The |format|, |exportVars|, and |dependencies| options are not tested
        // becasue there is no meaningful way to thest their effects without turning
        // this into an integration test.

        // The |plugins| option is tested in plugin API tests.

        describe( "reserved words", function () {

            const RESERVED_WORDS = peg.util.reservedWords;

            describe( "throws an exception on reserved JS words used as labels", function () {

                for ( const label of RESERVED_WORDS ) {

                    it( label, function () {

                        expect( () => {

                            peg.generate( [
                                "start = " + label + ":end",
                                "end = 'a'"
                            ].join( "\n" ), { output: "source" } );

                        } ).to.throw( peg.parser.SyntaxError );

                    } );

                }

            } );

            describe( "not throws an exception on reserved JS words used as rule name", function () {

                for ( const rule of RESERVED_WORDS ) {

                    it( rule, function () {

                        expect( () => {

                            peg.generate( [
                                "start = " + rule,
                                rule + " = 'a'"
                            ].join( "\n" ), { output: "source" } );

                        } ).to.not.throw( peg.parser.SyntaxError );

                    } );

                }

            } );

        } );

        it( "accepts custom options", function () {

            peg.generate( "start = 'a'", { foo: 42 } );

        } );

    } );

} );
<|endoftext|>