<commit_before>Utils = {
  loadTemplates: function() {
    var templates = {};
    $('*[type="text/x-js-template"]').map(function() {
      var name = $(this).attr('name');
      var source = $(this).html().replace('>', '>');
      if(name.split('/')[1][0] == '_') { Handlebars.registerPartial(name.replace('/', ''), source) }
      templates[name] = Handlebars.compile(source);
    });
    return templates;
  },
  queryString: function(params) {
    if(!params) return '';
    var query = _.compact(_.map(params, function(value, key) { return value ? key + '=' + value : null }));
    return query.length > 0 ? '?' + query.join('&') : '';
  },
  duration: function(started, finished) {
    started  = new Date(started);
    finished = finished ? new Date(finished) : new Date();
    return started ? Math.round((finished - started) / 1000) : 0;
  },
  activateTab: function(element, tab) {
    $('.tabs li', element).removeClass('active');
    $('#tab_' + tab.toLowerCase(), element).addClass('active');
  },
  animated: function(element) {
    return !!element.queue()[0];
  },
  flash: function(element) {
    if(!element.length == 0 && !Utils.animated(element)) {
      Utils._flash(element);
    }
  },
  _flash: function(element) {
    element.effect('highlight', {}, 1000, function () {
      Utils._flash(element)
    });
  },
  unflash: function(element) {
    if(!element.length == 0) {
      element.stop().css({ 'background-color': '', 'background-image': '' });
    }
  },
  filterLog: function(string) {
    string = Utils.stripPaths(string);
    string = Utils.escapeHtml(string);
    string = Utils.foldLog(string);
    string = Deansi.parse(string);
    string = Utils.numberLines(string);
    return string;
  },
  stripPaths: function(string) {
    return string.replace(/\/tmp\/travis\/builds(\/[^\/\n]+){2}\//g, '');
  },
  escapeHtml: function(string) {
    return Handlebars.Utils.escapeExpression(string);
  },
  escapeRuby: function(string) {
    return string.replace(/#<(\w+.*?)>/, '#<$1>');
  },
  numberLines: function(string) {
    var newstring = "";
    var counter = 0;
    _.each(string.split('\n'), function (line) {
      counter++;
      newstring += "
" + counter+ "" + line + "
"
    })
    return newstring;
  },
  foldLog: function(string) {
    string = Utils.unfoldLog(string);
    var folds = {
      // 'clone': /(^|<\/div>)(\$ git clone.*\r?\n(?:(Initialized|remote:|Receiving|Resolving).*?\r?\n)*)/m,
      // 'clean':   /(^|<\\/div>)(\\$ git clean.*\\r?\\n(?:Removing .*\\r?\\n)+\\r?\\n*)/gm,
      // 'fetch':   /(^|<\\/div>)(\\$ git fetch.*\\r?\\nFrom .*\\n.*)\\r?\\n/gm,
      'bundle':  /(^|<\/div>)(\$ bundle install.*\r?\n*(?:(Fetching|Updating|Using|Installing|remote:|Receiving|Resolving|Unpacking).+\r?\n*)*)/gm,
      'migrate': /(^|<\/div>)(\$ rake db:migrate[\s\S]*(?:^== +\w+: migrated \(.*\) =+\r?\n))\r?\n?/gm,
      'exec':    /(^|<\/div>)(\/home\/([^\/]+)\/.rvm\/rubies\/\S*?\/(ruby|rbx|jruby) .*?)\r?\n/gm
    };
    _.each(folds, function(fold, type) {
      string = string.replace(fold, function() { return arguments[1] + '
\n' + arguments[2].trim() + '
\n'; });
    });
    return string;
  },
  unfoldLog: function(string) {
    return string.replace(/
([\s\S]*?)<\/div>/mg, '$1\n');
  },
  updateTimes: function(element) {
    $('.timeago', element).timeago();
    $('.duration', element).readableTime();

    if(!Utils._updateTimesInterval) {
      Utils._updateTimesInterval = setInterval(function() { Utils.updateTimes() }, 3000);
    }
  },
  readableTime: function(duration) {
    var days    = Math.floor(duration / 86400)
    var hours   = Math.floor(duration % 86400 / 3600);
    var minutes = Math.floor(duration % 3600 / 60);
    var seconds = duration % 60;

    if(days > 0) {
      return 'more than 24 hrs';
    } else {
      var result = [];
      if(hours   > 0) { result.push(hours + ' hrs'); }
      if(minutes > 0) { result.push(minutes + ' min'); }
      if(seconds > 0) { result.push(seconds + ' sec'); }
      return result.length > 0 ? result.join(' ') : '-';
    }
  },
  updateGithubStats: function(repository, element) {
    if(!window.__TESTING__) {
      $.getJSON('http://github.com/api/v2/json/repos/show/' + repository.get('slug') + '?callback=?', function(data) {
        var url = 'http://github.com/' + repository.get('slug');
        element.find('.watchers').attr('href', url + '/watchers').text(data.repository.watchers);
        element.find('.forks').attr('href', url + '/network').text(data.repository.forks);
        element.find('.github-admin').attr('href', url + '/admin/hooks#travis_minibucket');
      });
    }
  }
}

Utils.PathHelpers = {
  repositoryPath: function(owner, name, line_number) {
    if (line_number) {
      // #!/:owner/:name/L:line_number
      return "#!/" + owner + "/" + name + "/L" + line_number
    } else {
      // #!/:owner/:name
      return path = "#!/" + owner + "/" + name
    }
  },
  repositoryBuildPath: function(owner, name, build_id, line_number) {
    if (line_number) {
      //#!/:owner/:name/builds/:id/L:line_number
      return "#!/" + owner + "/" + name + "/builds/" + build_id +"/L" + line_number
    } else {
      //#!/:owner/:name/builds
      return "#!/" + owner + "/" + name + "/builds/" + build_id
    }
  }
}

function trace() {
  try {
    i.dont.exist; // force an exception
  } catch(e) {
    var lines = e.stack.split('\n').slice(2);
    var stack = _.map(lines, function(line) { return line.replace(/^\s*at/, ''); });
    console.log('trace -------------------------------');
    _.each(stack, function(line) { console.log(line); });
  }
}

window._console = console;
/*
 * In order to use old (default) behavior of console, please use __DEBUG__ in URL hash, or __DEBUG__ global variable
 *   when hash is not accessible
 */
var console = {
  log: function() {
    if (/__DEBUG__/.exec(window.location.hash) || window.__DEBUG__) {
      if (!_.isEmpty(window.__DEBUG_FILTER__)) {
        if (_.include(arguments[0], window.__DEBUG_FILTER__)) {
          window._console.log(arguments)
        }
      }
      else {
        window._console.log(arguments)
      }
    }
  }
}
<commit_msg>move debug log condition one level up<commit_after>Utils = {
  loadTemplates: function() {
    var templates = {};
    $('*[type="text/x-js-template"]').map(function() {
      var name = $(this).attr('name');
      var source = $(this).html().replace('>', '>');
      if(name.split('/')[1][0] == '_') { Handlebars.registerPartial(name.replace('/', ''), source) }
      templates[name] = Handlebars.compile(source);
    });
    return templates;
  },
  queryString: function(params) {
    if(!params) return '';
    var query = _.compact(_.map(params, function(value, key) { return value ? key + '=' + value : null }));
    return query.length > 0 ? '?' + query.join('&') : '';
  },
  duration: function(started, finished) {
    started  = new Date(started);
    finished = finished ? new Date(finished) : new Date();
    return started ? Math.round((finished - started) / 1000) : 0;
  },
  activateTab: function(element, tab) {
    $('.tabs li', element).removeClass('active');
    $('#tab_' + tab.toLowerCase(), element).addClass('active');
  },
  animated: function(element) {
    return !!element.queue()[0];
  },
  flash: function(element) {
    if(!element.length == 0 && !Utils.animated(element)) {
      Utils._flash(element);
    }
  },
  _flash: function(element) {
    element.effect('highlight', {}, 1000, function () {
      Utils._flash(element)
    });
  },
  unflash: function(element) {
    if(!element.length == 0) {
      element.stop().css({ 'background-color': '', 'background-image': '' });
    }
  },
  filterLog: function(string) {
    string = Utils.stripPaths(string);
    string = Utils.escapeHtml(string);
    string = Utils.foldLog(string);
    string = Deansi.parse(string);
    string = Utils.numberLines(string);
    return string;
  },
  stripPaths: function(string) {
    return string.replace(/\/tmp\/travis\/builds(\/[^\/\n]+){2}\//g, '');
  },
  escapeHtml: function(string) {
    return Handlebars.Utils.escapeExpression(string);
  },
  escapeRuby: function(string) {
    return string.replace(/#<(\w+.*?)>/, '#<$1>');
  },
  numberLines: function(string) {
    var newstring = "";
    var counter = 0;
    _.each(string.split('\n'), function (line) {
      counter++;
      newstring += "
" + counter+ "" + line + "
"
    })
    return newstring;
  },
  foldLog: function(string) {
    string = Utils.unfoldLog(string);
    var folds = {
      // 'clone': /(^|<\/div>)(\$ git clone.*\r?\n(?:(Initialized|remote:|Receiving|Resolving).*?\r?\n)*)/m,
      // 'clean':   /(^|<\\/div>)(\\$ git clean.*\\r?\\n(?:Removing .*\\r?\\n)+\\r?\\n*)/gm,
      // 'fetch':   /(^|<\\/div>)(\\$ git fetch.*\\r?\\nFrom .*\\n.*)\\r?\\n/gm,
      'bundle':  /(^|<\/div>)(\$ bundle install.*\r?\n*(?:(Fetching|Updating|Using|Installing|remote:|Receiving|Resolving|Unpacking).+\r?\n*)*)/gm,
      'migrate': /(^|<\/div>)(\$ rake db:migrate[\s\S]*(?:^== +\w+: migrated \(.*\) =+\r?\n))\r?\n?/gm,
      'exec':    /(^|<\/div>)(\/home\/([^\/]+)\/.rvm\/rubies\/\S*?\/(ruby|rbx|jruby) .*?)\r?\n/gm
    };
    _.each(folds, function(fold, type) {
      string = string.replace(fold, function() { return arguments[1] + '
\n' + arguments[2].trim() + '
\n'; });
    });
    return string;
  },
  unfoldLog: function(string) {
    return string.replace(/
([\s\S]*?)<\/div>/mg, '$1\n');
  },
  updateTimes: function(element) {
    $('.timeago', element).timeago();
    $('.duration', element).readableTime();

    if(!Utils._updateTimesInterval) {
      Utils._updateTimesInterval = setInterval(function() { Utils.updateTimes() }, 3000);
    }
  },
  readableTime: function(duration) {
    var days    = Math.floor(duration / 86400)
    var hours   = Math.floor(duration % 86400 / 3600);
    var minutes = Math.floor(duration % 3600 / 60);
    var seconds = duration % 60;

    if(days > 0) {
      return 'more than 24 hrs';
    } else {
      var result = [];
      if(hours   > 0) { result.push(hours + ' hrs'); }
      if(minutes > 0) { result.push(minutes + ' min'); }
      if(seconds > 0) { result.push(seconds + ' sec'); }
      return result.length > 0 ? result.join(' ') : '-';
    }
  },
  updateGithubStats: function(repository, element) {
    if(!window.__TESTING__) {
      $.getJSON('http://github.com/api/v2/json/repos/show/' + repository.get('slug') + '?callback=?', function(data) {
        var url = 'http://github.com/' + repository.get('slug');
        element.find('.watchers').attr('href', url + '/watchers').text(data.repository.watchers);
        element.find('.forks').attr('href', url + '/network').text(data.repository.forks);
        element.find('.github-admin').attr('href', url + '/admin/hooks#travis_minibucket');
      });
    }
  }
}

Utils.PathHelpers = {
  repositoryPath: function(owner, name, line_number) {
    if (line_number) {
      // #!/:owner/:name/L:line_number
      return "#!/" + owner + "/" + name + "/L" + line_number
    } else {
      // #!/:owner/:name
      return path = "#!/" + owner + "/" + name
    }
  },
  repositoryBuildPath: function(owner, name, build_id, line_number) {
    if (line_number) {
      //#!/:owner/:name/builds/:id/L:line_number
      return "#!/" + owner + "/" + name + "/builds/" + build_id +"/L" + line_number
    } else {
      //#!/:owner/:name/builds
      return "#!/" + owner + "/" + name + "/builds/" + build_id
    }
  }
}

function trace() {
  try {
    i.dont.exist; // force an exception
  } catch(e) {
    var lines = e.stack.split('\n').slice(2);
    var stack = _.map(lines, function(line) { return line.replace(/^\s*at/, ''); });
    console.log('trace -------------------------------');
    _.each(stack, function(line) { console.log(line); });
  }
}

window._console = console;
/*
 * In order to use old (default) behavior of console, please use __DEBUG__ in URL hash, or __DEBUG__ global variable
 *   when hash is not accessible
 */
var console = {
  log: function() {
    if (/__DEBUG__/.exec(window.location.hash) || window.__DEBUG__) {
      if (!_.isEmpty(window.__DEBUG_FILTER__)) {
        if (_.include(arguments[0], window.__DEBUG_FILTER__)) {
          window._console.log(arguments)
        }
      }
    }
    else {
      window._console.log(arguments)
    }
  }
}
<|endoftext|>


<commit_before>test("do while", function() {
    do {
        assert(true);
        return;
    } while(false);
    assert(false, "did not execute");
});

test("do while and continue", function() {
    var flag = false;
    do {
        if(flag) {
            assert(false, "loop executed again after continue in do..while(false)");
        }
        flag = true;
        continue;
    } while(false);
    assert(true);
});

test("with", function() {
    var b = 0;
    var x = { a: 1 };
    with(x) {
        assert_equal("number", typeof a);
        assert_equal(1, a);
        var y = 2;
        b = 3;
        a = 4;
    }
    assert_equal(4, x.a);
    assert_equal(2, y);
    assert_equal("undefined", typeof x.b);
    assert_equal(3, b);
});

test("default in switch", function() {
    switch(1) {
        case 1: assert(true); break;
        default: assert(false); break;
    }

    switch(2) {
        case 1: assert(false); break;
        default: assert(true); break;
    }

    switch(1) {
        default: assert(false); break;
        case 1: assert(true); break;
    }

    switch(2) {
        default: assert(true); break;
        case 1: assert(false); break;
    }
});

test("combo-assignment-arithmetic on member", function() {
    var x = { a: 1 };
    assert_equal(3, x.a += 2);
    assert_equal(3, x.a);
});

test("combo-assignment-arithmetic on index", function() {
    var x = { a: 1 };
    assert_equal(3, x["a"] += 2);
    assert_equal(3, x["a"]);
});

test("assignment non-lval throws", function() {
    try {
        eval("hi() = 123");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("combo-assignment-arithmetic on non-lval throws", function() {
    try {
        eval("hi() += 123");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("post-increment", function() {
    var i = 0;
    var a = [1];
    var o = { x: 2 };
    assert_equal(0, i++);
    assert_equal(1, a[0]++);
    assert_equal(2, o.x++);
    assert_equal(1, i);
    assert_equal(2, a[0]);
    assert_equal(3, o.x);
});

test("pre-increment", function() {
    var i = 0;
    var a = [1];
    var o = { x: 2 };
    assert_equal(1, ++i);
    assert_equal(2, ++a[0]);
    assert_equal(3, ++o.x);
    assert_equal(1, i);
    assert_equal(2, a[0]);
    assert_equal(3, o.x);
});

test("post/pre increment on non-lval throws", function() {
    try {
        eval("hi()++;");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
    try {
        eval("++hi();");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("calling", function() {
    var x = { a: function() { return this; } };
    assert_equal(x, x["a"]());
    assert_equal(x, x.a());
    assert_equal(123, Number(x.a.call(123)));
    function closure() {
        var fn = x.a;
        assert_equal(this, fn());
    }
    closure();
});

test("delete", function() {
    window.x = 123;
    var y = { a:1, b:2, c:3 };
    var z = [1,2,3,4];

    assert_equal("number", typeof x);
    delete x;
    assert_equal("undefined", typeof x);

    assert_equal("number", typeof y.b);
    delete y.b;
    assert_equal("undefined", typeof y.b);

    assert_equal("number", typeof y.c);
    with(y) delete c;
    assert_equal("undefined", typeof y.c);

    assert("1,2,3,4" == z);
    delete z[2];
    assert("1,2,,4" == z);

    var fncalled = false;
    function fn() { fncalled = true; }
    assert_equal(true, delete fn());
    assert_equal("function", typeof fn);
    assert_equal("undefined", typeof fn());
    assert_equal(true, fncalled);

    function Fn() { }
    Fn.prototype.hi = 123;
    assert_equal(true, delete Fn.prototype);
    assert_equal(123, Fn.prototype.hi);
});

test("break label", function() {
    br: while(true) {
        while(true) {
            break br;
            assert(false, "did not break");
        }
        assert(false, "did not escape second loop");
    }
    assert(true);
});

test("can't continue to non existant label", function() {
    try {
        eval('while(false) continue foo;');
    } catch(e) {
        assert(e instanceof SyntaxError);
        assert(/foo/.test(e.toString()));
    }
});

test("labelled continue while", function() {
    var x = false;
    a:while(true) {
        if(x) {
            assert(true);
            return;
        }
        while(true) {
            x = true;
            continue a;
            assert(false, "did not continue");
        }
    }
});

test("labelled continue do-while", function() {
    a:do {
        do {
            continue a;
            assert(false);
        } while(false);
        assert(false);
    } while(false);
    assert(true);
});

test("labelled continue for-loop", function() {
    var x = false;
    function init() {
        if(x) {
            assert(false, "reran initializer");
        }
        x = true;
    }
    var i = 0;
    a: for(init(); i < 10; i++) {
        assert(true);
        do {
            continue a;
            assert(false);
        } while(false);
        assert(false);
    }
    assert(true);
});

test("labelled continue for-in", function() {
    var a = 0, c = [1, 2, 3, 4, 5];
    l: for(var x in c) {
        if(c.hasOwnProperty(x)) {
            do {
                a += c[x];
                continue l;
                assert(false);
            } while(false);
            assert(false);
        }
    }
    assert_equal(15, a);
});

test("floating point is used for large numbers but not for small numbers", function() {
    assert_equal(99999999999999999999999999999999999999, 99999999999999999999999999999999999999 + 1);
    assert(999999 !== 999999 + 1);
});

test("redeclaring a variable", function() {
    assert_equal(123, (function(a) {
       var a;
       return a;
    })(123));
});<commit_msg>add test for labels belonging to non-loop statements<commit_after>test("do while", function() {
    do {
        assert(true);
        return;
    } while(false);
    assert(false, "did not execute");
});

test("do while and continue", function() {
    var flag = false;
    do {
        if(flag) {
            assert(false, "loop executed again after continue in do..while(false)");
        }
        flag = true;
        continue;
    } while(false);
    assert(true);
});

test("with", function() {
    var b = 0;
    var x = { a: 1 };
    with(x) {
        assert_equal("number", typeof a);
        assert_equal(1, a);
        var y = 2;
        b = 3;
        a = 4;
    }
    assert_equal(4, x.a);
    assert_equal(2, y);
    assert_equal("undefined", typeof x.b);
    assert_equal(3, b);
});

test("default in switch", function() {
    switch(1) {
        case 1: assert(true); break;
        default: assert(false); break;
    }

    switch(2) {
        case 1: assert(false); break;
        default: assert(true); break;
    }

    switch(1) {
        default: assert(false); break;
        case 1: assert(true); break;
    }

    switch(2) {
        default: assert(true); break;
        case 1: assert(false); break;
    }
});

test("combo-assignment-arithmetic on member", function() {
    var x = { a: 1 };
    assert_equal(3, x.a += 2);
    assert_equal(3, x.a);
});

test("combo-assignment-arithmetic on index", function() {
    var x = { a: 1 };
    assert_equal(3, x["a"] += 2);
    assert_equal(3, x["a"]);
});

test("assignment non-lval throws", function() {
    try {
        eval("hi() = 123");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("combo-assignment-arithmetic on non-lval throws", function() {
    try {
        eval("hi() += 123");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("post-increment", function() {
    var i = 0;
    var a = [1];
    var o = { x: 2 };
    assert_equal(0, i++);
    assert_equal(1, a[0]++);
    assert_equal(2, o.x++);
    assert_equal(1, i);
    assert_equal(2, a[0]);
    assert_equal(3, o.x);
});

test("pre-increment", function() {
    var i = 0;
    var a = [1];
    var o = { x: 2 };
    assert_equal(1, ++i);
    assert_equal(2, ++a[0]);
    assert_equal(3, ++o.x);
    assert_equal(1, i);
    assert_equal(2, a[0]);
    assert_equal(3, o.x);
});

test("post/pre increment on non-lval throws", function() {
    try {
        eval("hi()++;");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
    try {
        eval("++hi();");
        assert(false, "didn't throw");
    } catch(e) {
        assert(e instanceof SyntaxError);
    }
});

test("calling", function() {
    var x = { a: function() { return this; } };
    assert_equal(x, x["a"]());
    assert_equal(x, x.a());
    assert_equal(123, Number(x.a.call(123)));
    function closure() {
        var fn = x.a;
        assert_equal(this, fn());
    }
    closure();
});

test("delete", function() {
    window.x = 123;
    var y = { a:1, b:2, c:3 };
    var z = [1,2,3,4];

    assert_equal("number", typeof x);
    delete x;
    assert_equal("undefined", typeof x);

    assert_equal("number", typeof y.b);
    delete y.b;
    assert_equal("undefined", typeof y.b);

    assert_equal("number", typeof y.c);
    with(y) delete c;
    assert_equal("undefined", typeof y.c);

    assert("1,2,3,4" == z);
    delete z[2];
    assert("1,2,,4" == z);

    var fncalled = false;
    function fn() { fncalled = true; }
    assert_equal(true, delete fn());
    assert_equal("function", typeof fn);
    assert_equal("undefined", typeof fn());
    assert_equal(true, fncalled);

    function Fn() { }
    Fn.prototype.hi = 123;
    assert_equal(true, delete Fn.prototype);
    assert_equal(123, Fn.prototype.hi);
});

test("break label", function() {
    br: while(true) {
        while(true) {
            break br;
            assert(false, "did not break");
        }
        assert(false, "did not escape second loop");
    }
    assert(true);
});

test("can't continue to non existant label", function() {
    try {
        eval('while(false) continue foo;');
    } catch(e) {
        assert(e instanceof SyntaxError);
        assert(/foo/.test(e.toString()));
    }
});

test("labelled continue while", function() {
    var x = false;
    a:while(true) {
        if(x) {
            assert(true);
            return;
        }
        while(true) {
            x = true;
            continue a;
            assert(false, "did not continue");
        }
    }
});

test("labelled continue do-while", function() {
    a:do {
        do {
            continue a;
            assert(false);
        } while(false);
        assert(false);
    } while(false);
    assert(true);
});

test("labelled continue for-loop", function() {
    var x = false;
    function init() {
        if(x) {
            assert(false, "reran initializer");
        }
        x = true;
    }
    var i = 0;
    a: for(init(); i < 10; i++) {
        assert(true);
        do {
            continue a;
            assert(false);
        } while(false);
        assert(false);
    }
    assert(true);
});

test("labelled continue for-in", function() {
    var a = 0, c = [1, 2, 3, 4, 5];
    l: for(var x in c) {
        if(c.hasOwnProperty(x)) {
            do {
                a += c[x];
                continue l;
                assert(false);
            } while(false);
            assert(false);
        }
    }
    assert_equal(15, a);
});

test("labelled block", function() {
    eval("a: { };");
    assert(true);
});

test("floating point is used for large numbers but not for small numbers", function() {
    assert_equal(99999999999999999999999999999999999999, 99999999999999999999999999999999999999 + 1);
    assert(999999 !== 999999 + 1);
});

test("redeclaring a variable", function() {
    assert_equal(123, (function(a) {
       var a;
       return a;
    })(123));
});<|endoftext|>


<commit_before>'use strict';

var Bacon         = require('baconjs').Bacon;
var Game          = require('./game');
var GameComponent = require('./game_component');
var React         = require('react');
var _             = require('lodash');

function dispatch(fn) {
  fn();
}

function state(newState, fn) {
  return [newState, [new Bacon.Next(function() { return fn; })]];
}

function GameController(options) {
  var countryStream = new Bacon.Bus();

  countryStream
    .withStateMachine(null, this.stateTransform.bind(this))
    .onValue(dispatch);

  this.game = new Game(options.width, options.height);

  this.gameComponent = React.renderComponent(
    GameComponent({game: this.game, stream: countryStream}),
    options.el
  );
}

// The state transformation function for the country stream.
GameController.prototype.stateTransform = function(previousCountry, event) {
  if (event.hasValue()) {
    var fn, nextCountry = event.value();

    if (previousCountry && _.contains(previousCountry.neighbours, nextCountry)) {
      // The user selected one of the nearby countries.
      fn = this.attackOrMove.bind(this, previousCountry, nextCountry);
      return state(undefined, fn);
    } else if (previousCountry === nextCountry) {
      // The user selected the previously selected country.
      fn = this.deselectCountry.bind(this, nextCountry);
      return state(undefined, fn);
    } else {
      // The user selected a new country.
      fn = this.selectCountry.bind(this, nextCountry);
      return state(nextCountry, fn);
    }
  } else {
    return [previousCountry, [event]];
  }
};

GameController.prototype.selectCountry = function(country) {
  console.log('select', country);
  this.gameComponent.selectCountry(country);
};

GameController.prototype.deselectCountry = function(country) {
  console.log('deselect', country);
  this.gameComponent.deselectCountry();
};

GameController.prototype.attackOrMove = function(source, target) {
  console.log('attackOrMove', source, target);
  // TODO: Figure out if we're moving or attacking.
  this.game.world.move(source, target);
  this.gameComponent.deselectCountry();
};

GameController.prototype.constructor = GameController;

module.exports = GameController;
<commit_msg>Clear selection before applying operation.<commit_after>'use strict';

var Bacon         = require('baconjs').Bacon;
var Game          = require('./game');
var GameComponent = require('./game_component');
var React         = require('react');
var _             = require('lodash');

function dispatch(fn) {
  fn();
}

function state(newState, fn) {
  return [newState, [new Bacon.Next(function() { return fn; })]];
}

function GameController(options) {
  var countryStream = new Bacon.Bus();

  countryStream
    .withStateMachine(null, this.stateTransform.bind(this))
    .onValue(dispatch);

  this.game = new Game(options.width, options.height);

  this.gameComponent = React.renderComponent(
    GameComponent({game: this.game, stream: countryStream}),
    options.el
  );
}

// The state transformation function for the country stream.
GameController.prototype.stateTransform = function(previousCountry, event) {
  if (event.hasValue()) {
    var fn, nextCountry = event.value();

    if (previousCountry && _.contains(previousCountry.neighbours, nextCountry)) {
      // The user selected one of the nearby countries.
      fn = this.attackOrMove.bind(this, previousCountry, nextCountry);
      return state(undefined, fn);
    } else if (previousCountry === nextCountry) {
      // The user selected the previously selected country.
      fn = this.deselectCountry.bind(this, nextCountry);
      return state(undefined, fn);
    } else {
      // The user selected a new country.
      fn = this.selectCountry.bind(this, nextCountry);
      return state(nextCountry, fn);
    }
  } else {
    return [previousCountry, [event]];
  }
};

GameController.prototype.selectCountry = function(country) {
  console.log('select', country);
  this.gameComponent.selectCountry(country);
};

GameController.prototype.deselectCountry = function(country) {
  console.log('deselect', country);
  this.gameComponent.deselectCountry();
};

GameController.prototype.attackOrMove = function(source, target) {
  console.log('attackOrMove', source, target);
  this.gameComponent.deselectCountry();
  // TODO: Figure out if we're moving or attacking.
  this.game.world.move(source, target);
};

GameController.prototype.constructor = GameController;

module.exports = GameController;
<|endoftext|>


<commit_before>// There's no reason that this file is in JavaScript instead of CoffeeScript.
// We should convert it and update the brunch config.

// If we wanted to be more robust, we could use this: https://github.com/padolsey/operative/blob/master/src/operative.js
if(typeof window !== 'undefined' || !self.importScripts)
  throw "Attempt to load worker_world into main window instead of web worker.";

// assign global window so that Brunch's require (in world.js) can go into it
self.window = self;
self.workerID = "Worker";

self.logLimit = 200;
self.logsLogged = 0;
var console = {
  log: function() {
    if(self.logsLogged++ == self.logLimit)
      self.postMessage({type: 'console-log', args: ["Log limit " + self.logLimit + " reached; shutting up."], id: self.workerID});
    else if(self.logsLogged < self.logLimit) {
      args = [].slice.call(arguments);
      for(var i = 0; i < args.length; ++i) {
        if(args[i] && args[i].constructor) {
          if(args[i].constructor.className === "Thang" || args[i].isComponent)
            args[i] = args[i].toString();
        }
      }
      try {
        self.postMessage({type: 'console-log', args: args, id: self.workerID});
      }
      catch(error) {
        self.postMessage({type: 'console-log', args: ["Could not post log: " + args, error.toString(), error.stack, error.stackTrace], id: self.workerID});
      }
    }
  }};  // so that we don't crash when debugging statements happen
console.error = console.info = console.log;
self.console = console;

importScripts('/javascripts/world.js');

// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
Object.defineProperty(self, "XMLHttpRequest", {
  get: function() { throw new Error("Access to XMLHttpRequest is forbidden."); },
  configurable: false
});

self.transferableSupported = function transferableSupported() {
  // Not in IE, even in IE 11
  try {
    var ab = new ArrayBuffer(1);
    worker.postMessage(ab, [ab]);
    return ab.byteLength == 0;
  } catch(error) {
    return false;
  }
  return false;
}

var World = self.require('lib/world/world');
var GoalManager = self.require('lib/world/GoalManager');

self.runWorld = function runWorld(args) {
  self.postedErrors = {};
  self.t0 = new Date();
  self.firstWorld = args.firstWorld;
  self.postedErrors = false;
  self.logsLogged = 0;

  try {
    self.world = new World(args.worldName, args.userCodeMap);
    if(args.level)
      self.world.loadFromLevel(args.level, true);
    self.goalManager = new GoalManager(self.world);
    self.goalManager.setGoals(args.goals);
    self.goalManager.setCode(args.userCodeMap);
    self.goalManager.worldGenerationWillBegin();
    self.world.setGoalManager(self.goalManager);
  }
  catch (error) {
    self.onWorldError(error);
    return;
  }
  Math.random = self.world.rand.randf;  // so user code is predictable
  self.world.loadFrames(self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress);
};

self.onWorldLoaded = function onWorldLoaded() {
  self.goalManager.worldGenerationEnded();
  var t1 = new Date();
  var diff = t1 - self.t0;
  var transferableSupported = self.transferableSupported();
  try {
    var serialized = self.world.serialize();
  }
  catch(error) {
    console.log("World serialization error:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  var t2 = new Date();
  //console.log("About to transfer", serialized.serializedWorld.trackedPropertiesPerThangValues, serialized.transferableObjects);
  try {
    if(transferableSupported)
      self.postMessage({type: 'new-world', serialized: serialized.serializedWorld, goalStates: self.goalManager.getGoalStates()}, serialized.transferableObjects);
    else
      self.postMessage({type: 'new-world', serialized: serialized.serializedWorld, goalStates: self.goalManager.getGoalStates()});
  }
  catch(error) {
    console.log("World delivery error:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  var t3 = new Date();
  console.log("And it was so: (" + (diff / self.world.totalFrames).toFixed(3) + "ms per frame,", self.world.totalFrames, "frames)\nSimulation   :", diff + "ms \nSerialization:", (t2 - t1) + "ms\nDelivery     :", (t3 - t2) + "ms");
  self.world = null;
};

self.onWorldError = function onWorldError(error) {
  if(error instanceof Aether.problems.UserCodeProblem) {
    if(!self.postedErrors[error.key]) {
      var problem = error.serialize();
      self.postMessage({type: 'user-code-problem', problem: problem});
      self.postedErrors[error.key] = problem;
    }
  }
  else {
    console.log("Non-UserCodeError:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  /*  We don't actually have the recoverable property any more; hmm
  if(!self.firstWorld && !error.recoverable) {
    self.abort();
    return false;
  }
  */
  return true;
};

self.onWorldLoadProgress = function onWorldLoadProgress(progress) {
  self.postMessage({type: 'world-load-progress-changed', progress: progress});
};

self.abort = function abort() {
  if(self.world && self.world.name) {
    console.log("About to abort:", self.world.name, typeof self.world.abort);
    if(typeof self.world !== "undefined")
      self.world.abort();
    self.world = null;
  }
  self.postMessage({type: 'abort'});
};

self.reportIn = function reportIn() {
  self.postMessage({type: 'reportIn'});
}

self.addEventListener('message', function(event) {
  self[event.data.func](event.data.args);
});

self.postMessage({type: 'worker-initialized'});
<commit_msg>Added Function.Prototype.bind shim to world worker to enable running on headless browsers<commit_after>// There's no reason that this file is in JavaScript instead of CoffeeScript.
// We should convert it and update the brunch config.

// If we wanted to be more robust, we could use this: https://github.com/padolsey/operative/blob/master/src/operative.js
if(typeof window !== 'undefined' || !self.importScripts)
  throw "Attempt to load worker_world into main window instead of web worker.";

// Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// This is here for running simuations in enviroments lacking function.bind (PhantomJS mostly)
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind (Shim) - target is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

// assign global window so that Brunch's require (in world.js) can go into it
self.window = self;
self.workerID = "Worker";

self.logLimit = 200;
self.logsLogged = 0;
var console = {
  log: function() {
    if(self.logsLogged++ == self.logLimit)
      self.postMessage({type: 'console-log', args: ["Log limit " + self.logLimit + " reached; shutting up."], id: self.workerID});
    else if(self.logsLogged < self.logLimit) {
      args = [].slice.call(arguments);
      for(var i = 0; i < args.length; ++i) {
        if(args[i] && args[i].constructor) {
          if(args[i].constructor.className === "Thang" || args[i].isComponent)
            args[i] = args[i].toString();
        }
      }
      try {
        self.postMessage({type: 'console-log', args: args, id: self.workerID});
      }
      catch(error) {
        self.postMessage({type: 'console-log', args: ["Could not post log: " + args, error.toString(), error.stack, error.stackTrace], id: self.workerID});
      }
    }
  }};  // so that we don't crash when debugging statements happen
console.error = console.info = console.log;
self.console = console;

importScripts('/javascripts/world.js');

// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
Object.defineProperty(self, "XMLHttpRequest", {
  get: function() { throw new Error("Access to XMLHttpRequest is forbidden."); },
  configurable: false
});

self.transferableSupported = function transferableSupported() {
  // Not in IE, even in IE 11
  try {
    var ab = new ArrayBuffer(1);
    worker.postMessage(ab, [ab]);
    return ab.byteLength == 0;
  } catch(error) {
    return false;
  }
  return false;
}

var World = self.require('lib/world/world');
var GoalManager = self.require('lib/world/GoalManager');

self.runWorld = function runWorld(args) {
  self.postedErrors = {};
  self.t0 = new Date();
  self.firstWorld = args.firstWorld;
  self.postedErrors = false;
  self.logsLogged = 0;

  try {
    self.world = new World(args.worldName, args.userCodeMap);
    if(args.level)
      self.world.loadFromLevel(args.level, true);
    self.goalManager = new GoalManager(self.world);
    self.goalManager.setGoals(args.goals);
    self.goalManager.setCode(args.userCodeMap);
    self.goalManager.worldGenerationWillBegin();
    self.world.setGoalManager(self.goalManager);
  }
  catch (error) {
    self.onWorldError(error);
    return;
  }
  Math.random = self.world.rand.randf;  // so user code is predictable
  self.world.loadFrames(self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress);
};

self.onWorldLoaded = function onWorldLoaded() {
  self.goalManager.worldGenerationEnded();
  var t1 = new Date();
  var diff = t1 - self.t0;
  var transferableSupported = self.transferableSupported();
  try {
    var serialized = self.world.serialize();
  }
  catch(error) {
    console.log("World serialization error:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  var t2 = new Date();
  //console.log("About to transfer", serialized.serializedWorld.trackedPropertiesPerThangValues, serialized.transferableObjects);
  try {
    if(transferableSupported)
      self.postMessage({type: 'new-world', serialized: serialized.serializedWorld, goalStates: self.goalManager.getGoalStates()}, serialized.transferableObjects);
    else
      self.postMessage({type: 'new-world', serialized: serialized.serializedWorld, goalStates: self.goalManager.getGoalStates()});
  }
  catch(error) {
    console.log("World delivery error:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  var t3 = new Date();
  console.log("And it was so: (" + (diff / self.world.totalFrames).toFixed(3) + "ms per frame,", self.world.totalFrames, "frames)\nSimulation   :", diff + "ms \nSerialization:", (t2 - t1) + "ms\nDelivery     :", (t3 - t2) + "ms");
  self.world = null;
};

self.onWorldError = function onWorldError(error) {
  if(error instanceof Aether.problems.UserCodeProblem) {
    if(!self.postedErrors[error.key]) {
      var problem = error.serialize();
      self.postMessage({type: 'user-code-problem', problem: problem});
      self.postedErrors[error.key] = problem;
    }
  }
  else {
    console.log("Non-UserCodeError:", error.toString() + "\n" + error.stack || error.stackTrace);
  }
  /*  We don't actually have the recoverable property any more; hmm
  if(!self.firstWorld && !error.recoverable) {
    self.abort();
    return false;
  }
  */
  return true;
};

self.onWorldLoadProgress = function onWorldLoadProgress(progress) {
  self.postMessage({type: 'world-load-progress-changed', progress: progress});
};

self.abort = function abort() {
  if(self.world && self.world.name) {
    console.log("About to abort:", self.world.name, typeof self.world.abort);
    if(typeof self.world !== "undefined")
      self.world.abort();
    self.world = null;
  }
  self.postMessage({type: 'abort'});
};

self.reportIn = function reportIn() {
  self.postMessage({type: 'reportIn'});
}

self.addEventListener('message', function(event) {
  self[event.data.func](event.data.args);
});

self.postMessage({type: 'worker-initialized'});
<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import c from 'classnames';
import moment from 'moment';
import { Link } from 'react-router';

import { formatThousands } from '../utils/format';

var LocationCard = React.createClass({
  displayName: 'LocationCard',

  propTypes: {
    compact: React.PropTypes.bool,
    name: React.PropTypes.string,
    city: React.PropTypes.string,
    countryData: React.PropTypes.object,
    sourceData: React.PropTypes.object,
    totalMeasurements: React.PropTypes.number,
    parametersList: React.PropTypes.array,
    lastUpdate: React.PropTypes.string,
    collectionStart: React.PropTypes.string
  },

  renderParameters: function () {
    return this.props.parametersList.map(o => o.name).join(', ');
  },

  render: function () {
    let updated = moment(this.props.lastUpdate).fromNow();
    let started = moment(this.props.collectionStart).format('YYYY/MM/DD');

    return (

Updated {updated}

<Link to={`/location/${this.props.name}`} title={`View ${this.props.name} page`}>{this.props.name}</Link> in {this.props.city}, {this.props.countryData.name}

Collection Start: {started}

Measurements: {formatThousands(this.props.totalMeasurements)}

Values: {this.renderParameters()}

Source: <a href={this.props.sourceData.url} title={`View source for  ${this.props.name}`}>{this.props.sourceData.name}

<a href='#' className='button-card-download' title={`Download data for ${this.props.name}`}>Download

<Link to={`/location/${this.props.name}`} className='button-card-view' title={`View ${this.props.name} page`}>View More</Link>

    );
  }
});

module.exports = LocationCard;
<commit_msg>Fix problem with missing source<commit_after>'use strict';
import React from 'react';
import c from 'classnames';
import moment from 'moment';
import { Link } from 'react-router';

import { formatThousands } from '../utils/format';

var LocationCard = React.createClass({
  displayName: 'LocationCard',

  propTypes: {
    compact: React.PropTypes.bool,
    name: React.PropTypes.string,
    city: React.PropTypes.string,
    countryData: React.PropTypes.object,
    sourceData: React.PropTypes.object,
    totalMeasurements: React.PropTypes.number,
    parametersList: React.PropTypes.array,
    lastUpdate: React.PropTypes.string,
    collectionStart: React.PropTypes.string
  },

  renderParameters: function () {
    return this.props.parametersList.map(o => o.name).join(', ');
  },

  render: function () {
    let updated = moment(this.props.lastUpdate).fromNow();
    let started = moment(this.props.collectionStart).format('YYYY/MM/DD');

    return (

Updated {updated}

<Link to={`/location/${this.props.name}`} title={`View ${this.props.name} page`}>{this.props.name}</Link> in {this.props.city}, {this.props.countryData.name}

Collection Start: {started}

Measurements: {formatThousands(this.props.totalMeasurements)}

Values: {this.renderParameters()}

              {this.props.sourceData
              ?
Source: <a href={this.props.sourceData.url} title={`View source for  ${this.props.name}`}>{this.props.sourceData.name}

              : null}

<a href='#' className='button-card-download' title={`Download data for ${this.props.name}`}>Download

<Link to={`/location/${this.props.name}`} className='button-card-view' title={`View ${this.props.name} page`}>View More</Link>

    );
  }
});

module.exports = LocationCard;
<|endoftext|>


<commit_before>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (module, io, should) {

  var parser = io.parser;

  module.exports = {

    'decoding error packet': function () {
      parser.decodePacket('7:::').should().eql({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: ''
      });
    },

    'decoding error packet with reason': function () {
      parser.decodePacket('7:::0').should().eql({
          type: 'error'
        , reason: 'transport not supported'
        , advice: ''
        , endpoint: ''
      });
    },

    'decoding error packet with reason and advice': function () {
      parser.decodePacket('7:::2+0').should().eql({
          type: 'error'
        , reason: 'unauthorized'
        , advice: 'reconnect'
        , endpoint: ''
      });
    },

    'decoding error packet with endpoint': function () {
      parser.decodePacket('7::/woot').should().eql({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: '/woot'
      });
    },

    'decoding ack packet': function () {
      parser.decodePacket('6:::140').should().eql({
          type: 'ack'
        , ackId: '140'
        , endpoint: ''
        , args: []
      });
    },

    'decoding ack packet with args': function () {
      parser.decodePacket('6:::12+["woot","wa"]').should().eql({
          type: 'ack'
        , ackId: '12'
        , endpoint: ''
        , args: ['woot', 'wa']
      });
    },

    'decoding ack packet with bad json': function () {
      var thrown = false;

      try {
        parser.decodePacket('6:::1+{"++]').should().eql({
            type: 'ack'
          , ackId: '1'
          , endpoint: ''
          , args: []
        });
      } catch (e) {
        thrown = true;
      }

      thrown.should().be_false;
    },

    'decoding json packet': function () {
      parser.decodePacket('4:::"2"').should().eql({
          type: 'json'
        , endpoint: ''
        , data: '2'
      });
    },

    'decoding json packet with message id and ack data': function () {
      parser.decodePacket('4:1+::{"a":"b"}').should().eql({
          type: 'json'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , data: { a: 'b' }
      });
    },

    'decoding an event packet': function () {
      parser.decodePacket('5:::{"name":"woot"}').should().eql({
          type: 'event'
        , name: 'woot'
        , endpoint: ''
        , args: []
      });
    },

    'decoding an event packet with message id and ack': function () {
      parser.decodePacket('5:1+::{"name":"tobi"}').should().eql({
          type: 'event'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , name: 'tobi'
        , args: []
      });
    },

    'decoding an event packet with data': function () {
      parser.decodePacket('5:::{"name":"edwald","args":[{"a": "b"},2,"3"]}')
      .should().eql({
          type: 'event'
        , name: 'edwald'
        , endpoint: ''
        , args: [{a: 'b'}, 2, '3']
      });
    },

    'decoding a message packet': function () {
      parser.decodePacket('3:::woot').should().eql({
          type: 'message'
        , endpoint: ''
        , data: 'woot'
      });
    },

    'decoding a message packet with id and endpoint': function () {
      parser.decodePacket('3:5:/tobi').should().eql({
          type: 'message'
        , id: 5
        , ack: true
        , endpoint: '/tobi'
        , data: ''
      });
    },

    'decoding a heartbeat packet': function () {
      parser.decodePacket('2:::').should().eql({
          type: 'heartbeat'
        , endpoint: ''
      });
    },

    'decoding a connection packet': function () {
      parser.decodePacket('1::/tobi').should().eql({
          type: 'connect'
        , endpoint: '/tobi'
        , qs: ''
      });
    },

    'decoding a connection packet with query string': function () {
      parser.decodePacket('1::/test:?test=1').should().eql({
          type: 'connect'
        , endpoint: '/test'
        , qs: '?test=1'
      });
    },

    'decoding a disconnection packet': function () {
      parser.decodePacket('0::/woot').should().eql({
          type: 'disconnect'
        , endpoint: '/woot'
      });
    },

    'encoding error packet': function () {
      parser.encodePacket({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: ''
      }).should().eql('7::');
    },

    'encoding error packet with reason': function () {
      parser.encodePacket({
          type: 'error'
        , reason: 'transport not supported'
        , advice: ''
        , endpoint: ''
      }).should().eql('7:::0');
    },

    'encoding error packet with reason and advice': function () {
      parser.encodePacket({
          type: 'error'
        , reason: 'unauthorized'
        , advice: 'reconnect'
        , endpoint: ''
      }).should().eql('7:::2+0');
    },

    'encoding error packet with endpoint': function () {
      parser.encodePacket({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: '/woot'
      }).should().eql('7::/woot');
    },

    'encoding ack packet': function () {
      parser.encodePacket({
          type: 'ack'
        , ackId: '140'
        , endpoint: ''
        , args: []
      }).should().eql('6:::140');
    },

    'encoding ack packet with args': function () {
      parser.encodePacket({
          type: 'ack'
        , ackId: '12'
        , endpoint: ''
        , args: ['woot', 'wa']
      }).should().eql('6:::12+["woot","wa"]');
    },

    'encoding json packet': function () {
      parser.encodePacket({
          type: 'json'
        , endpoint: ''
        , data: '2'
      }).should().eql('4:::"2"');
    },

    'encoding json packet with message id and ack data': function () {
      parser.encodePacket({
          type: 'json'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , data: { a: 'b' }
      }).should().eql('4:1+::{"a":"b"}');
    },

    'encoding an event packet': function () {
      parser.encodePacket({
          type: 'event'
        , name: 'woot'
        , endpoint: ''
        , args: []
      }).should().eql('5:::{"name":"woot"}');
    },

    'encoding an event packet with message id and ack': function () {
      parser.encodePacket({
          type: 'event'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , name: 'tobi'
        , args: []
      }).should().eql('5:1+::{"name":"tobi"}');
    },

    'encoding an event packet with data': function () {
      parser.encodePacket({
          type: 'event'
        , name: 'edwald'
        , endpoint: ''
        , args: [{a: 'b'}, 2, '3']
      }).should().eql('5:::{"name":"edwald","args":[{"a":"b"},2,"3"]}');
    },

    'encoding a message packet': function () {
      parser.encodePacket({
          type: 'message'
        , endpoint: ''
        , data: 'woot'
      }).should().eql('3:::woot');
    },

    'encoding a message packet with id and endpoint': function () {
      parser.encodePacket({
          type: 'message'
        , id: 5
        , ack: true
        , endpoint: '/tobi'
        , data: ''
      }).should().eql('3:5:/tobi');
    },

    'encoding a heartbeat packet': function () {
      parser.encodePacket({
          type: 'heartbeat'
        , endpoint: ''
      }).should().eql('2::');
    },

    'encoding a connection packet': function () {
      parser.encodePacket({
          type: 'connect'
        , endpoint: '/tobi'
        , qs: ''
      }).should().eql('1::/tobi');
    },

    'encoding a connection packet with query string': function () {
      parser.encodePacket({
          type: 'connect'
        , endpoint: '/test'
        , qs: '?test=1'
      }).should().eql('1::/test:?test=1');
    },

    'encoding a disconnection packet': function () {
      parser.encodePacket({
          type: 'disconnect'
        , endpoint: '/woot'
      }).should().eql('0::/woot');
    },

    'test decoding a payload': function () {
      parser.decodePayload('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d'
        + '\ufffd3\ufffd0::').should().eql([
          { type: 'message', data: '5', endpoint: '' }
        , { type: 'message', data: '53d', endpoint: '' }
        , { type: 'disconnect', endpoint: '' }
      ]);
    },

    'test encoding a payload': function () {
      parser.encodePayload([
          parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
        , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
      ]).should().eql('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d')
    }

  };

})(
    'undefined' == typeof module ? module = {} : module
  , 'undefined' == typeof io ? require('socket.io-client') : io
  , 'undefined' == typeof should ? require('should') : should
);
<commit_msg>Added parser test for newline.<commit_after>
/*!
 * socket.io-node
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (module, io, should) {

  var parser = io.parser;

  module.exports = {

    'decoding error packet': function () {
      parser.decodePacket('7:::').should().eql({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: ''
      });
    },

    'decoding error packet with reason': function () {
      parser.decodePacket('7:::0').should().eql({
          type: 'error'
        , reason: 'transport not supported'
        , advice: ''
        , endpoint: ''
      });
    },

    'decoding error packet with reason and advice': function () {
      parser.decodePacket('7:::2+0').should().eql({
          type: 'error'
        , reason: 'unauthorized'
        , advice: 'reconnect'
        , endpoint: ''
      });
    },

    'decoding error packet with endpoint': function () {
      parser.decodePacket('7::/woot').should().eql({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: '/woot'
      });
    },

    'decoding ack packet': function () {
      parser.decodePacket('6:::140').should().eql({
          type: 'ack'
        , ackId: '140'
        , endpoint: ''
        , args: []
      });
    },

    'decoding ack packet with args': function () {
      parser.decodePacket('6:::12+["woot","wa"]').should().eql({
          type: 'ack'
        , ackId: '12'
        , endpoint: ''
        , args: ['woot', 'wa']
      });
    },

    'decoding ack packet with bad json': function () {
      var thrown = false;

      try {
        parser.decodePacket('6:::1+{"++]').should().eql({
            type: 'ack'
          , ackId: '1'
          , endpoint: ''
          , args: []
        });
      } catch (e) {
        thrown = true;
      }

      thrown.should().be_false;
    },

    'decoding json packet': function () {
      parser.decodePacket('4:::"2"').should().eql({
          type: 'json'
        , endpoint: ''
        , data: '2'
      });
    },

    'decoding json packet with message id and ack data': function () {
      parser.decodePacket('4:1+::{"a":"b"}').should().eql({
          type: 'json'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , data: { a: 'b' }
      });
    },

    'decoding an event packet': function () {
      parser.decodePacket('5:::{"name":"woot"}').should().eql({
          type: 'event'
        , name: 'woot'
        , endpoint: ''
        , args: []
      });
    },

    'decoding an event packet with message id and ack': function () {
      parser.decodePacket('5:1+::{"name":"tobi"}').should().eql({
          type: 'event'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , name: 'tobi'
        , args: []
      });
    },

    'decoding an event packet with data': function () {
      parser.decodePacket('5:::{"name":"edwald","args":[{"a": "b"},2,"3"]}')
      .should().eql({
          type: 'event'
        , name: 'edwald'
        , endpoint: ''
        , args: [{a: 'b'}, 2, '3']
      });
    },

    'decoding a message packet': function () {
      parser.decodePacket('3:::woot').should().eql({
          type: 'message'
        , endpoint: ''
        , data: 'woot'
      });
    },

    'decoding a message packet with id and endpoint': function () {
      parser.decodePacket('3:5:/tobi').should().eql({
          type: 'message'
        , id: 5
        , ack: true
        , endpoint: '/tobi'
        , data: ''
      });
    },

    'decoding a heartbeat packet': function () {
      parser.decodePacket('2:::').should().eql({
          type: 'heartbeat'
        , endpoint: ''
      });
    },

    'decoding a connection packet': function () {
      parser.decodePacket('1::/tobi').should().eql({
          type: 'connect'
        , endpoint: '/tobi'
        , qs: ''
      });
    },

    'decoding a connection packet with query string': function () {
      parser.decodePacket('1::/test:?test=1').should().eql({
          type: 'connect'
        , endpoint: '/test'
        , qs: '?test=1'
      });
    },

    'decoding a disconnection packet': function () {
      parser.decodePacket('0::/woot').should().eql({
          type: 'disconnect'
        , endpoint: '/woot'
      });
    },

    'encoding error packet': function () {
      parser.encodePacket({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: ''
      }).should().eql('7::');
    },

    'encoding error packet with reason': function () {
      parser.encodePacket({
          type: 'error'
        , reason: 'transport not supported'
        , advice: ''
        , endpoint: ''
      }).should().eql('7:::0');
    },

    'encoding error packet with reason and advice': function () {
      parser.encodePacket({
          type: 'error'
        , reason: 'unauthorized'
        , advice: 'reconnect'
        , endpoint: ''
      }).should().eql('7:::2+0');
    },

    'encoding error packet with endpoint': function () {
      parser.encodePacket({
          type: 'error'
        , reason: ''
        , advice: ''
        , endpoint: '/woot'
      }).should().eql('7::/woot');
    },

    'encoding ack packet': function () {
      parser.encodePacket({
          type: 'ack'
        , ackId: '140'
        , endpoint: ''
        , args: []
      }).should().eql('6:::140');
    },

    'encoding ack packet with args': function () {
      parser.encodePacket({
          type: 'ack'
        , ackId: '12'
        , endpoint: ''
        , args: ['woot', 'wa']
      }).should().eql('6:::12+["woot","wa"]');
    },

    'encoding json packet': function () {
      parser.encodePacket({
          type: 'json'
        , endpoint: ''
        , data: '2'
      }).should().eql('4:::"2"');
    },

    'encoding json packet with message id and ack data': function () {
      parser.encodePacket({
          type: 'json'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , data: { a: 'b' }
      }).should().eql('4:1+::{"a":"b"}');
    },

    'encoding an event packet': function () {
      parser.encodePacket({
          type: 'event'
        , name: 'woot'
        , endpoint: ''
        , args: []
      }).should().eql('5:::{"name":"woot"}');
    },

    'encoding an event packet with message id and ack': function () {
      parser.encodePacket({
          type: 'event'
        , id: 1
        , ack: 'data'
        , endpoint: ''
        , name: 'tobi'
        , args: []
      }).should().eql('5:1+::{"name":"tobi"}');
    },

    'encoding an event packet with data': function () {
      parser.encodePacket({
          type: 'event'
        , name: 'edwald'
        , endpoint: ''
        , args: [{a: 'b'}, 2, '3']
      }).should().eql('5:::{"name":"edwald","args":[{"a":"b"},2,"3"]}');
    },

    'encoding a message packet': function () {
      parser.encodePacket({
          type: 'message'
        , endpoint: ''
        , data: 'woot'
      }).should().eql('3:::woot');
    },

    'encoding a message packet with id and endpoint': function () {
      parser.encodePacket({
          type: 'message'
        , id: 5
        , ack: true
        , endpoint: '/tobi'
        , data: ''
      }).should().eql('3:5:/tobi');
    },

    'encoding a heartbeat packet': function () {
      parser.encodePacket({
          type: 'heartbeat'
        , endpoint: ''
      }).should().eql('2::');
    },

    'encoding a connection packet': function () {
      parser.encodePacket({
          type: 'connect'
        , endpoint: '/tobi'
        , qs: ''
      }).should().eql('1::/tobi');
    },

    'encoding a connection packet with query string': function () {
      parser.encodePacket({
          type: 'connect'
        , endpoint: '/test'
        , qs: '?test=1'
      }).should().eql('1::/test:?test=1');
    },

    'encoding a disconnection packet': function () {
      parser.encodePacket({
          type: 'disconnect'
        , endpoint: '/woot'
      }).should().eql('0::/woot');
    },

    'test decoding a payload': function () {
      parser.decodePayload('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d'
        + '\ufffd3\ufffd0::').should().eql([
          { type: 'message', data: '5', endpoint: '' }
        , { type: 'message', data: '53d', endpoint: '' }
        , { type: 'disconnect', endpoint: '' }
      ]);
    },

    'test encoding a payload': function () {
      parser.encodePayload([
          parser.encodePacket({ type: 'message', data: '5', endpoint: '' })
        , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' })
      ]).should().eql('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d')
    },

    'test decoding newline': function () {
      parser.decodePacket('3:::\n').should().eql({
          type: 'message'
        , endpoint: ''
        , data: '\n'
      });
    }

  };

})(
    'undefined' == typeof module ? module = {} : module
  , 'undefined' == typeof io ? require('socket.io-client') : io
  , 'undefined' == typeof should ? require('should') : should
);
<|endoftext|>


<commit_before>var assert = require('assert')
var fs = require('fs')
var path = require('path')
var rcedit = require('..')
var rcinfo = require('rcinfo')
var temp = require('temp').track()

var beforeEach = global.beforeEach
var describe = global.describe
var it = global.it

describe('rcedit(exePath, options, callback)', function () {
  this.timeout(60000)

  var exePath = null
  var tempPath = null

  beforeEach(function () {
    tempPath = temp.mkdirSync('node-rcedit-')
    exePath = path.join(tempPath, 'electron.exe')
    var fixturesExePath = path.join(__dirname, 'fixtures', 'electron.exe')
    fs.writeFileSync(exePath, fs.readFileSync(fixturesExePath))
  })

  it('updates the information in the executable', function (done) {
    var options = {
      'version-string': {
        CompanyName: 'Umbrella',
        FileDescription: 'Vanhouten',
        LegalCopyright: 'Maritime',
        ProductName: 'Millhouse'
      },
      'file-version': '3.4.5.6',
      'product-version': '4.5.6.7',
      icon: path.join(__dirname, 'fixtures', 'app.ico')
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.CompanyName, 'Umbrella')
        assert.equal(info.FileDescription, 'Vanhouten')
        assert.equal(info.LegalCopyright, 'Maritime')
        assert.equal(info.ProductName, 'Millhouse')
        assert.equal(info.FileVersion, '3.4.5.6')
        assert.equal(info.ProductVersion, '4.5.6.7')

        done()
      })
    })
  })

  it('supports non-ASCII characters in the .exe path', function (done) {
    var unicodePath = path.join(path.dirname(exePath), 'äeiöü.exe')
    fs.renameSync(exePath, unicodePath)

    var options = {
      'version-string': {
        FileDescription: 'foo',
        ProductName: 'bar'
      },
      'file-version': '8.0.8'
    }

    rcedit(unicodePath, options, function (error) {
      if (error != null) return done(error)
      done()
    })
  })

  it('supports a product version of 1', function (done) {
    var options = {
      'product-version': '1'
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.ProductVersion, '1.0.0.0')

        done()
      })
    })
  })

  it('supports a product version of 1.0', function (done) {
    var options = {
      'product-version': '1.0'
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.ProductVersion, '1.0.0.0')

        done()
      })
    })
  })

  it('reports an error when the .exe path does not exist', function (done) {
    rcedit(path.join(tempPath, 'does-not-exist.exe'), {'file-version': '3.4.5.6'}, function (error) {
      assert.ok(error instanceof Error)
      assert.notEqual(error.message.indexOf('rcedit.exe failed with exit code 1.'), -1)
      assert.notEqual(error.message.indexOf('Fatal error: Unable to load file'), -1)

      done()
    })
  })
})
<commit_msg>Add test for missing icon path<commit_after>var assert = require('assert')
var fs = require('fs')
var path = require('path')
var rcedit = require('..')
var rcinfo = require('rcinfo')
var temp = require('temp').track()

var beforeEach = global.beforeEach
var describe = global.describe
var it = global.it

describe('rcedit(exePath, options, callback)', function () {
  this.timeout(60000)

  var exePath = null
  var tempPath = null

  beforeEach(function () {
    tempPath = temp.mkdirSync('node-rcedit-')
    exePath = path.join(tempPath, 'electron.exe')
    var fixturesExePath = path.join(__dirname, 'fixtures', 'electron.exe')
    fs.writeFileSync(exePath, fs.readFileSync(fixturesExePath))
  })

  it('updates the information in the executable', function (done) {
    var options = {
      'version-string': {
        CompanyName: 'Umbrella',
        FileDescription: 'Vanhouten',
        LegalCopyright: 'Maritime',
        ProductName: 'Millhouse'
      },
      'file-version': '3.4.5.6',
      'product-version': '4.5.6.7',
      icon: path.join(__dirname, 'fixtures', 'app.ico')
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.CompanyName, 'Umbrella')
        assert.equal(info.FileDescription, 'Vanhouten')
        assert.equal(info.LegalCopyright, 'Maritime')
        assert.equal(info.ProductName, 'Millhouse')
        assert.equal(info.FileVersion, '3.4.5.6')
        assert.equal(info.ProductVersion, '4.5.6.7')

        done()
      })
    })
  })

  it('supports non-ASCII characters in the .exe path', function (done) {
    var unicodePath = path.join(path.dirname(exePath), 'äeiöü.exe')
    fs.renameSync(exePath, unicodePath)

    var options = {
      'version-string': {
        FileDescription: 'foo',
        ProductName: 'bar'
      },
      'file-version': '8.0.8'
    }

    rcedit(unicodePath, options, function (error) {
      if (error != null) return done(error)
      done()
    })
  })

  it('supports a product version of 1', function (done) {
    var options = {
      'product-version': '1'
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.ProductVersion, '1.0.0.0')

        done()
      })
    })
  })

  it('supports a product version of 1.0', function (done) {
    var options = {
      'product-version': '1.0'
    }

    rcedit(exePath, options, function (error) {
      if (error != null) return done(error)

      rcinfo(exePath, function (error, info) {
        if (error != null) return done(error)

        assert.equal(info.ProductVersion, '1.0.0.0')

        done()
      })
    })
  })

  it('reports an error when the .exe path does not exist', function (done) {
    rcedit(path.join(tempPath, 'does-not-exist.exe'), {'file-version': '3.4.5.6'}, function (error) {
      assert.ok(error instanceof Error)
      assert.notEqual(error.message.indexOf('rcedit.exe failed with exit code 1.'), -1)
      assert.notEqual(error.message.indexOf('Fatal error: Unable to load file'), -1)

      done()
    })
  })

  it('reports an error when the icon path does not exist', function (done) {
    rcedit(exePath, {icon: path.join(tempPath, 'does-not-exist.ico')}, function (error) {
      assert.ok(error instanceof Error)
      assert.notEqual(error.message.indexOf('Fatal error: Unable to set icon'), -1)

      done()
    })
  })
})
<|endoftext|>


<commit_before>var expect = require('chai').expect,
  nock = require('nock'),
  Scraper = require('../lib/scraper');

describe('Scraper', function() {
  var scraper;

  beforeEach(function() {
    scraper = new Scraper();
  });

  describe('#get()', function() {
    it('returns a valid url', function(done) {
      nock('http://www.example.com')
        .get('/foobar')
        .reply(200, '
Hello, World!
');

      scraper.get('http://www.example.com/foobar').then(function($) {
        expect($('h1').text()).to.equal('Hello, World!');
        expect($.body).to.equal('
Hello, World!
');
        expect($.response.statusCode).to.equal(200);
      }).done(done, done);
    });

    it('errors on invalid url', function(done) {
      scraper.get('http://localhost:65000').then(done, function() {
        done();
      });
    });

    it('uses headers from previous response', function(done) {
      nock('http://www.example.com')
        .get('/')
        .reply(200, 'Hello, World!', {
          'Set-Cookie': 'foo=bar;'
        });
      nock('http://www.example.com')
        .matchHeader('Cookie', 'foo=bar')
        .get('/foobar')
        .times(2)
        .reply(200, 'Hello, World!');

      scraper.get('http://www.example.com/').then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).done(function() {
        done();
      }, done);
    });

    it('uses same user-agent for each request', function(done) {
      nock('http://www.example.com')
        .matchHeader('User-Agent', scraper.userAgent)
        .get('/foobar')
        .times(2)
        .reply(200, 'Ok');

      scraper.get('http://www.example.com/foobar').then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).done(function() {
        done();
      }, done);
    });
  });

  describe('#post()', function() {
    it('uses provided form values', function(done) {
      nock('http://www.example.com')
        .post('/foobar', {
          foo: 'bar'
        })
        .reply(200, 'Hello, World!');

      scraper.post('http://www.example.com/foobar', { foo: 'bar' }).done(function() {
        done();
      }, done);
    });
  });
})<commit_msg>Adds test for subsequent cookie responses<commit_after>var expect = require('chai').expect,
  nock = require('nock'),
  Scraper = require('../lib/scraper');

describe('Scraper', function() {
  var scraper;

  beforeEach(function() {
    scraper = new Scraper();
  });

  describe('#get()', function() {
    it('returns a valid url', function(done) {
      nock('http://www.example.com')
        .get('/foobar')
        .reply(200, '
Hello, World!
');

      scraper.get('http://www.example.com/foobar').then(function($) {
        expect($('h1').text()).to.equal('Hello, World!');
        expect($.body).to.equal('
Hello, World!
');
        expect($.response.statusCode).to.equal(200);
      }).done(done, done);
    });

    it('errors on invalid url', function(done) {
      scraper.get('http://localhost:65000').then(done, function() {
        done();
      });
    });

    it('uses headers from previous response', function(done) {
      nock('http://www.example.com')
        .get('/')
        .reply(200, 'Hello, World!', {
          'Set-Cookie': 'foo=bar;'
        });
      nock('http://www.example.com')
        .matchHeader('Cookie', 'foo=bar')
        .get('/foobar')
        .times(2)
        .reply(200, 'Hello, World!');

      scraper.get('http://www.example.com/').then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).done(function() {
        done();
      }, done);
    });

    it('adds new headers', function(done) {
      nock('http://www.example.com')
        .get('/')
        .reply(200, 'Hello, World!', {
          'Set-Cookie': 'foo=bar;'
        });
      nock('http://www.example.com')
        .matchHeader('Cookie', 'foo=bar')
        .get('/foobar')
        .reply(200, 'Hello, World!', {
          'Set-Cookie': 'hello=world; foo=test'
        });
      nock('http://www.example.com')
        .matchHeader('Cookie', 'foo=test; hello=world')
        .get('/hello')
        .reply(200, 'Hello, World!');

      scraper.get('http://www.example.com/').then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).then(function() {
        return scraper.get('http://www.example.com/hello');
      }).done(function() {
        done();
      }, done);
    })

    it('uses same user-agent for each request', function(done) {
      nock('http://www.example.com')
        .matchHeader('User-Agent', scraper.userAgent)
        .get('/foobar')
        .times(2)
        .reply(200, 'Ok');

      scraper.get('http://www.example.com/foobar').then(function() {
        return scraper.get('http://www.example.com/foobar');
      }).done(function() {
        done();
      }, done);
    });
  });

  describe('#post()', function() {
    it('uses provided form values', function(done) {
      nock('http://www.example.com')
        .post('/foobar', {
          foo: 'bar'
        })
        .reply(200, 'Hello, World!');

      scraper.post('http://www.example.com/foobar', { foo: 'bar' }).done(function() {
        done();
      }, done);
    });
  });
})<|endoftext|>