<commit_before>var hasNativeGetSelection = "getSelection" in window;
var hasNativeDomRange = "createRange" in document;

function createRangySelection(win) {
    return rangy.getSelection(win);
}

function createNativeSelection(win) {
    return win.getSelection();
}

function createRangyRange(doc) {
    return new rangy.DomRange(doc);
}

function createNativeDomRange(doc) {
    return doc.createRange();
}

function createWrappedNativeDomRange(doc) {
    return rangy.createRange(doc);
}

function testExceptionCode(t, func, code) {
    try {
        func();
        t.fail("No error thrown");
    } catch (ex) {
        t.assertEquals(ex.code, code);
    }
}

function getOtherDocument() {
    var iframe = document.getElementById("selectors");
    return iframe.contentDocument || iframe.contentWindow.document;
}

function testSelectionAndRangeCreators(wins, winName, selectionCreator, selectionCreatorName, rangeCreator, rangeCreatorName) {
    xn.test.suite(selectionCreatorName + " in " + winName + " window with range creator " + rangeCreatorName, function(s) {
        var win, doc;
        var DomRange = rangy.DomRange;
        var DOMException = rangy.dom.DOMException;
        var RangeException = DomRange.RangeException;

        s.setUp = function(t) {
            win = wins[0];
            doc = win.document;
            var div = doc.createElement("div");
            var plainText = div.appendChild(doc.createTextNode("plain"));
            var b = div.appendChild(doc.createElement("b"));
            var boldText = b.appendChild(doc.createTextNode("bold"));
            var i = b.appendChild(doc.createElement("i"));
            var boldAndItalicText = i.appendChild(doc.createTextNode("bold and italic"));
            doc.body.appendChild(div);
            var div2 = doc.createElement("div");
            var div2Text = div2.appendChild(doc.createTextNode("Second div"));
            doc.body.appendChild(div2);

            t.nodes = {
                div: div,
                plainText: plainText,
                b: b,
                boldText: boldText,
                i: i,
                boldAndItalicText: boldAndItalicText,
                div2: div2,
                div2Text: div2Text
            };
        };

        s.tearDown = function(t) {
            doc.body.removeChild(t.nodes.div);
            doc.body.removeChild(t.nodes.div2);
            t.nodes = null;
        };

        s.test("removeAllRanges test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("addRange test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.plainText);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertEquivalent(sel.focusNode, t.nodes.plainText);
            t.assertEquals(sel.focusOffset, t.nodes.plainText.length);
            t.assertEquivalent(sel.isCollapsed, false);
        });

        s.test("removeRange test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.removeRange(range);
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("removeRange instance test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            range.selectNodeContents(t.nodes.b);
            sel.removeRange(range);
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("getRangeAt test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
        });

        s.test("Multiple ranges test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            var r2 = rangeCreator(doc);
            r2.selectNodeContents(t.nodes.boldText);
            sel.addRange(r2);

            if (sel.rangeCount == 2) {
                t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
                t.assert(DomRange.util.rangesEqual(r2, sel.getRangeAt(1)));
            } else if (sel.rangeCount == 1) {
                t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
            }
        });

        s.test("Collapse same document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.collapse(t.nodes.plainText, 1);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.plainText);
            t.assertEquals(sel.anchorOffset, 1);
            t.assertEquivalent(sel.focusNode, t.nodes.plainText);
            t.assertEquals(sel.focusOffset, 1);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("Collapse other document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.collapse(t.nodes.b, 1);
            var otherDoc = getOtherDocument();
            testExceptionCode(t, function() {
                sel.collapse(otherDoc.body, 0);
            }, DOMException.prototype.WRONG_DOCUMENT_ERR);
        });

        s.test("collapseToStart test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.boldText, 1);
            range.setEnd(t.nodes.boldText, 2);
            sel.addRange(range);
            sel.collapseToStart();
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.boldText);
            t.assertEquals(sel.anchorOffset, 1);
            t.assertEquivalent(sel.focusNode, t.nodes.boldText);
            t.assertEquals(sel.focusOffset, 1);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("collapseToEnd test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.boldText, 1);
            range.setEnd(t.nodes.boldText, 2);
            sel.addRange(range);
            sel.collapseToEnd();
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.boldText);
            t.assertEquals(sel.anchorOffset, 2);
            t.assertEquivalent(sel.focusNode, t.nodes.boldText);
            t.assertEquals(sel.focusOffset, 2);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("selectAllChildren same document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.plainText, 1);
            range.setEnd(t.nodes.plainText, 2);
            sel.addRange(range);
            sel.selectAllChildren(doc.body);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, doc.body);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertEquivalent(sel.focusNode, doc.body);
            t.assertEquals(sel.focusOffset, doc.body.childNodes.length);
            t.assertEquivalent(sel.isCollapsed, false);
        });
    }, false);
}

var iframeWin = [];

/*
function testRangeCreator(rangeCreator, rangeCratorName) {
    testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", rangeCreator, rangeCratorName);

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators([window], "main", createNativeSelection, "native selection", rangeCreator, rangeCratorName);
    }

    testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", rangeCreator, rangeCratorName);

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators(iframeWin, "iframe", createNativeSelection, "native selection", rangeCreator, rangeCratorName);
    }
}
*/

testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createRangyRange, "Rangy Range");
testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createRangyRange, "Rangy Range");

testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createWrappedNativeDomRange, "Wrapped native Range");
testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createWrappedNativeDomRange, "Wrapped native Range");

if (hasNativeDomRange) {
    testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createNativeDomRange, "native Range");
    testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createNativeDomRange, "native Range");

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators([window], "main", createNativeSelection, "native selection", createNativeDomRange, "native Range");
        testSelectionAndRangeCreators(iframeWin, "iframe", createNativeSelection, "native selection", createNativeDomRange, "native Range");
    }
}

/*
testRangeCreator(createRangyRange, "Rangy Range");
testRangeCreator(createWrappedNativeDomRange, "Wrapped native Range");

if (hasNativeDomRange) {
    testRangeCreator(createNativeDomRange, "native Range");
}
*/

xn.addEventListener(window, "load", function() {
    // Do it in an iframe
    var iframe = document.body.appendChild(document.createElement("iframe"));
    var win = iframe.contentWindow;
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    doc.open();
    doc.write("<title>Rangy Selection Test</title>Content");
    doc.close();
    iframeWin[0] = win;
});
<commit_msg>Added test for toString according to HTML 5 draft<commit_after>var hasNativeGetSelection = "getSelection" in window;
var hasNativeDomRange = "createRange" in document;

function createRangySelection(win) {
    return rangy.getSelection(win);
}

function createNativeSelection(win) {
    return win.getSelection();
}

function createRangyRange(doc) {
    return new rangy.DomRange(doc);
}

function createNativeDomRange(doc) {
    return doc.createRange();
}

function createWrappedNativeDomRange(doc) {
    return rangy.createRange(doc);
}

function testExceptionCode(t, func, code) {
    try {
        func();
        t.fail("No error thrown");
    } catch (ex) {
        t.assertEquals(ex.code, code);
    }
}

function getOtherDocument() {
    var iframe = document.getElementById("selectors");
    return iframe.contentDocument || iframe.contentWindow.document;
}

function testSelectionAndRangeCreators(wins, winName, selectionCreator, selectionCreatorName, rangeCreator, rangeCreatorName) {
    xn.test.suite(selectionCreatorName + " in " + winName + " window with range creator " + rangeCreatorName, function(s) {
        var win, doc;
        var DomRange = rangy.DomRange;
        var DOMException = rangy.dom.DOMException;
        var RangeException = DomRange.RangeException;

        s.setUp = function(t) {
            win = wins[0];
            doc = win.document;
            var div = doc.createElement("div");
            var plainText = div.appendChild(doc.createTextNode("plain"));
            var b = div.appendChild(doc.createElement("b"));
            var boldText = b.appendChild(doc.createTextNode("bold"));
            var i = b.appendChild(doc.createElement("i"));
            var boldAndItalicText = i.appendChild(doc.createTextNode("bold and italic"));
            doc.body.appendChild(div);
            var div2 = doc.createElement("div");
            var div2Text = div2.appendChild(doc.createTextNode("Second div"));
            doc.body.appendChild(div2);

            t.nodes = {
                div: div,
                plainText: plainText,
                b: b,
                boldText: boldText,
                i: i,
                boldAndItalicText: boldAndItalicText,
                div2: div2,
                div2Text: div2Text
            };
        };

        s.tearDown = function(t) {
            doc.body.removeChild(t.nodes.div);
            doc.body.removeChild(t.nodes.div2);
            t.nodes = null;
        };

        s.test("removeAllRanges test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("addRange test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.plainText);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertEquivalent(sel.focusNode, t.nodes.plainText);
            t.assertEquals(sel.focusOffset, t.nodes.plainText.length);
            t.assertEquivalent(sel.isCollapsed, false);
        });

        s.test("removeRange test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.removeRange(range);
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("removeRange instance test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            range.selectNodeContents(t.nodes.b);
            sel.removeRange(range);
            t.assertEquals(sel.rangeCount, 0);
            t.assertNull(sel.anchorNode);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertNull(sel.focusNode);
            t.assertEquals(sel.focusOffset, 0);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("getRangeAt test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
        });

        s.test("Multiple ranges test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            var r2 = rangeCreator(doc);
            r2.selectNodeContents(t.nodes.boldText);
            sel.addRange(r2);

            if (sel.rangeCount == 2) {
                t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
                t.assert(DomRange.util.rangesEqual(r2, sel.getRangeAt(1)));
            } else if (sel.rangeCount == 1) {
                t.assert(DomRange.util.rangesEqual(range, sel.getRangeAt(0)));
            }
        });

        s.test("Collapse same document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.collapse(t.nodes.plainText, 1);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.plainText);
            t.assertEquals(sel.anchorOffset, 1);
            t.assertEquivalent(sel.focusNode, t.nodes.plainText);
            t.assertEquals(sel.focusOffset, 1);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("Collapse other document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(t.nodes.plainText);
            sel.addRange(range);
            sel.collapse(t.nodes.b, 1);
            var otherDoc = getOtherDocument();
            testExceptionCode(t, function() {
                sel.collapse(otherDoc.body, 0);
            }, DOMException.prototype.WRONG_DOCUMENT_ERR);
        });

        s.test("collapseToStart test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.boldText, 1);
            range.setEnd(t.nodes.boldText, 2);
            sel.addRange(range);
            sel.collapseToStart();
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.boldText);
            t.assertEquals(sel.anchorOffset, 1);
            t.assertEquivalent(sel.focusNode, t.nodes.boldText);
            t.assertEquals(sel.focusOffset, 1);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("collapseToEnd test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.boldText, 1);
            range.setEnd(t.nodes.boldText, 2);
            sel.addRange(range);
            sel.collapseToEnd();
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, t.nodes.boldText);
            t.assertEquals(sel.anchorOffset, 2);
            t.assertEquivalent(sel.focusNode, t.nodes.boldText);
            t.assertEquals(sel.focusOffset, 2);
            t.assertEquivalent(sel.isCollapsed, true);
        });

        s.test("selectAllChildren same document test", function(t) {
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.setStart(t.nodes.plainText, 1);
            range.setEnd(t.nodes.plainText, 2);
            sel.addRange(range);
            sel.selectAllChildren(doc.body);
            t.assertEquals(sel.rangeCount, 1);
            t.assertEquivalent(sel.anchorNode, doc.body);
            t.assertEquals(sel.anchorOffset, 0);
            t.assertEquivalent(sel.focusNode, doc.body);
            t.assertEquals(sel.focusOffset, doc.body.childNodes.length);
            t.assertEquivalent(sel.isCollapsed, false);
        });

        s.test("HTML 5 toString test", function(t) {
            var div = doc.createElement("div");
            div.innerHTML = 'onetwo';
            doc.body.appendChild(div);
            var sel = selectionCreator(win);
            sel.removeAllRanges();
            var range = rangeCreator(doc);
            range.selectNodeContents(div);
            sel.addRange(range);
            var rangeText = range.toString();
            var selText = sel.toString();
            doc.body.removeChild(div);
            t.assertEquals(rangeText, "onevar x = 1;two");
            t.assertEquals(selText, "onevar x = 1;two");
        });

    }, false);
}

var iframeWin = [];

/*
function testRangeCreator(rangeCreator, rangeCratorName) {
    testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", rangeCreator, rangeCratorName);

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators([window], "main", createNativeSelection, "native selection", rangeCreator, rangeCratorName);
    }

    testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", rangeCreator, rangeCratorName);

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators(iframeWin, "iframe", createNativeSelection, "native selection", rangeCreator, rangeCratorName);
    }
}
*/

testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createRangyRange, "Rangy Range");
testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createRangyRange, "Rangy Range");

testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createWrappedNativeDomRange, "Wrapped native Range");
testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createWrappedNativeDomRange, "Wrapped native Range");

if (hasNativeDomRange) {
    testSelectionAndRangeCreators([window], "main", createRangySelection, "Rangy Selection", createNativeDomRange, "native Range");
    testSelectionAndRangeCreators(iframeWin, "iframe", createRangySelection, "Rangy Selection", createNativeDomRange, "native Range");

    if (hasNativeGetSelection) {
        testSelectionAndRangeCreators([window], "main", createNativeSelection, "native selection", createNativeDomRange, "native Range");
        testSelectionAndRangeCreators(iframeWin, "iframe", createNativeSelection, "native selection", createNativeDomRange, "native Range");
    }
}

/*
testRangeCreator(createRangyRange, "Rangy Range");
testRangeCreator(createWrappedNativeDomRange, "Wrapped native Range");

if (hasNativeDomRange) {
    testRangeCreator(createNativeDomRange, "native Range");
}
*/

xn.addEventListener(window, "load", function() {
    // Do it in an iframe
    var iframe = document.body.appendChild(document.createElement("iframe"));
    var win = iframe.contentWindow;
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    doc.open();
    doc.write("<title>Rangy Selection Test</title>Content");
    doc.close();
    iframeWin[0] = win;
});
<|endoftext|>


<commit_before>import React from 'react';

import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';

import Git from 'nodegit';

class gitFunctions {

  static createCommit(repoPath, oid, commitMsg) {
    let index;
    let repo;

    // repoName = "../"+repoName;

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
      .then(function(repoResult) {
        repo = repoResult;
        return Git.Reference.nameToId(repo, "HEAD");
      })
      .then(function(head) {
        return repo.getCommit(head);
      })
      .then(function(parent) {
        const currTimeInSecs = (new Date()).getTime()/1000;
        let author = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);
        let committer = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);

        return repo.createCommit("HEAD", author, committer, commitMsg, oid, [parent]);
      });
  }

  static getStatus(repoPath) {

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo);
  }

  static getIndex(repoPath) {

    let repo;
    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
    .then( (repoResult) => {
      repo = repoResult;
    })
    .then(function() {
      return repo.refreshIndex();
    });

  }
}

class CheckBoxWrapper extends React.Component {
    constructor(props) {
    super(props);
    this.state={
      checked: this.props.checked
    };
  }

  onEventCheck = (event, isInputChecked) => {
    event.stopPropagation();

    this.changeCheckedState(isInputChecked);
  }

  changeCheckedState = (isInputChecked) => {

    window.setTimeout( () => {
      this.setState({
        checked: isInputChecked? true : false
      });
    }, 0);

    // this.props.onChangeSelected(this.props.uniqueId, isInputChecked );
  }

  componentWillReceiveProps = (newprops) => {
  }

  render = () => {
    const styles={
      checkbox: {
        marginBottom: 3
      }
    };

    return(

        <Checkbox style={styles.checkbox} label={this.props.label}
        value={this.props.value} onCheck={this.onEventCheck} checked={this.state.checked} />

    )
  }
}

class ChangesList extends React.Component {
  constructor(props) {
    super(props);
    //contains refs to all the CheckBoxWrapper components
    this.checkboxRefs= [];
  }

  toggleWrapperState = () => {
    this.checkboxRefs.forEach( (ref, index) => {
      if(ref !== null)
        ref.changeCheckedState(this.props.selectAll);
    })
  }

  render = () => {
    let renderStatus;
    if(this.props.statuses.length === 0) {
      renderStatus =
No Changes!

    }
    else {
      renderStatus = this.props.statuses.map((status, index) => {
                      return <CheckBoxWrapper key={index} uniqueId={index} label={status.label}
                      ref={(ref) => this.checkboxRefs[index] = ref}
                      onChangeSelected={this.props.onChangeSelected} checked={this.props.selectAll} value={status.value} />;
        });
    }
    return(

        {renderStatus}

    )
  }
}

class StatusTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      statuses: [],
      selectAll: true
    };
  }

  getStatus = (repo) => {
    let promise = gitFunctions.getStatus(repo);
    promise.then(function(repo) {
      repo.getStatus().then(function(status) {
        return status;
      })
      .done(function(statuses) {
        this.setState({
          statuses:statuses
        });
      }.bind(this));
    }.bind(this));
  }

  checkSelectAll = (event, isInputChecked) => {

    event.stopPropagation();

    window.setTimeout( () => {
      this.setState({
        selectAll: isInputChecked? true : false
      });

      //reaches into the changesList component, which
      //in turn reaches into individual CheckBoxWrapper components
      //and sets state accordingly
      this.changesList.toggleWrapperState(this.state.selectAll);
    }, 0);

  }

  componentWillReceiveProps = (newprops) => {
    // console.log('receive props',this.state.selectAll);
      this.getStatus(newprops.repo.path);
  }

  render = () => {
    let localStatus = [];
    if(this.state.statuses.length === 0)
    {
      localStatus = [];
    }
    else {

      const statusToText=function(status) {
        let words=[];
        let flag = 0;
        let int = 1;

        if (status.isNew()) { words.push(NEW); flag = 1;}
        if (status.isModified()) { words.push(MODIFIED); flag = 1;}
        if (status.isTypechange()) { words.push(TYPECHANGED); flag = 1;}
        if (status.isRenamed()) { words.push(RENAMED); flag = 1;}
        if (status.isIgnored()) { words.push(IGNORED); flag = 1; }
        if(flag == 0) { words.push(DELETED); }

        return words;
      };

      localStatus = this.state.statuses.map((file, index) => {

        let change=statusToText(file);
        let changes =[];
        changes.push({file.path()});
        changes.push(change);

        return ({
          label:changes,
          value: file.path()
        });

      });
    }

    const styles = {
      root:{
        border: '1px solid black'
      },
      ul:{
        listStyleType: 'none'
      }
    };
    return(

STATUS

        <Checkbox label='Select All:' ref={(ref) => this.selectAll = ref}  style={{width: 200}}
        onCheck={this.checkSelectAll} checked={this.state.selectAll} labelPosition='left' />
        <ChangesList ref={(ref) => this.changesList = ref} selectAll={this.state.selectAll}
        statuses={localStatus} />

    )
  }
}

class IndexTable extends React.Component {
  constructor(props) {
    super(props);
  }

  render = () => {
    return (

        {this.props.indexEntries.map( (entry, index) => {
          return
{entry}

;
        })}

    );
  }
}

class StagingArea extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      indexPaths: [],
      commitMsg: '',
    };
  }

  addToIndex = () => {

    let checkedChanges = [];
    //reaches into each checkboxWrapper to obtain checked value
    checkedChanges = this.statusTable.changesList.checkboxRefs.map( (ref, index) => {
      if(ref !== null)
        return ref.state.checked;
    });

    let indexPaths =[];

    this.statusTable.changesList.props.statuses.forEach( (status, index) => {

      //if corresponding checkbox has been checked only
      if(checkedChanges[index])
        indexPaths.push(status);
    });

    // console.log('index',indexPaths);

    window.setTimeout( () => {

      this.setState({
        indexPaths: indexPaths
      });
      // console.log(this.state.indexPaths);
    }, 0);
  }

  createCommit = () => {

    let index;
    let oid;

    let promise = gitFunctions.getIndex(this.props.repo.path);
    promise = promise.then((indexResult) => {
      index = indexResult;
    });

    let filePaths = this.state.indexPaths.map( (status) => {
      return status.value;
    });

    // console.log(filePaths);

    //takes in initial promise, uses it to chain a new promise to it, and returns the promise,
    //which is used in the next iteration
    promise = filePaths.reduce( (prevPromise, path, currentIndex) => {
                return prevPromise.then( () => {
                  return index.addByPath(path);
                });
              }, promise);

    promise.then(() => {
      return index.write();
    })
    .then(() => {
      console.log(index.entries());
    })
    .then(() => {
      return index.writeTree();
    })
    .then( (oidResult) => {
      oid = oidResult;
      console.log('index tree written!');
    })
    //until here, all entries were added to the index and an index tree was written
    //from here, the new commit is generated using the index tree
    .then( () => {
      let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid, this.state.commitMsg);
      innerPromise.done(function(commitId) {
        console.log('Commit Hash:'+commitId);
      });

    });
  }

  updateValue = (event) => {
    this.setState({
      commitMsg: event.target.value
    });
  }

  componentWillReceiveProps = (newprops) => {
    // console.log(newprops);
  }

  render = () => {
    const styles = {
      block: {
        maxWidth: 250,
      },
      checkbox: {
        marginBottom: 16,
      },
      main: {
        height:350,
        overflow: 'scroll',
        // backgroundColor: 'black'
      }
    };
    return (

        <RaisedButton label='Create Commit!' onMouseDown={this.createCommit} />
        <RaisedButton label='Add to Index!' onMouseDown={this.addToIndex} />
        <TextField
          hintText="Enter commit message..."
          multiLine={true}
          rows={2}
          rowsMax={2}
          value={this.state.commitMsg}
          onChange={this.updateValue}
        />
        <StatusTable {...this.props} ref={(ref) => this.statusTable = ref} />
        <IndexTable indexEntries={this.state.indexPaths.map( (status) => {return status.label})} />

    )
  }
}

export default StagingArea;
<commit_msg>Frontend: shows diffs of all unstaged changes<commit_after>import React from 'react';

import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import Checkbox from 'material-ui/Checkbox';
import FlatButton from 'material-ui/FlatButton';

import DiffPanel from './utils/DiffPanel';

import Git, { Diff } from 'nodegit';

class gitFunctions {

  static createCommit(repoPath, oid, commitMsg) {
    let index;
    let repo;

    // repoName = "../"+repoName;

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
      .then(function(repoResult) {
        repo = repoResult;
        return Git.Reference.nameToId(repo, "HEAD");
      })
      .then(function(head) {
        return repo.getCommit(head);
      })
      .then(function(parent) {
        const currTimeInSecs = (new Date()).getTime()/1000;
        let author = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);
        let committer = Git.Signature.create("Author name",
          "emailid@domain.com", currTimeInSecs , 0);

        return repo.createCommit("HEAD", author, committer, commitMsg, oid, [parent]);
      });
  }

  static getStatus(repoPath) {

    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo);
  }

  static getIndex(repoPath) {

    let repo;
    let pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
    .then( (repoResult) => {
      repo = repoResult;
    })
    .then(function() {
      return repo.refreshIndex();
    });

  }

  static getUnstagedChanges(repoPath) {

    const pathToRepo = require('path').resolve(repoPath);

    return Git.Repository.open(pathToRepo)
    .then( (repo) => {
      // console.log(repo);
      return Diff.indexToWorkdir(repo, null, {
      flags: Diff.OPTION.SHOW_UNTRACKED_CONTENT |
             Diff.OPTION.RECURSE_UNTRACKED_DIRS
      });
    });
  }
}

class CheckBoxWrapper extends React.Component {
    constructor(props) {
    super(props);
    this.state={
      checked: this.props.checked
    };
  }

  onEventCheck = (event, isInputChecked) => {
    event.stopPropagation();

    this.changeCheckedState(isInputChecked);
  }

  changeCheckedState = (isInputChecked) => {

    window.setTimeout( () => {
      this.setState({
        checked: isInputChecked? true : false
      });
    }, 0);

    // this.props.onChangeSelected(this.props.uniqueId, isInputChecked );
  }

  componentWillReceiveProps = (newprops) => {
  }

  render = () => {
    const styles={
      checkbox: {
        marginBottom: 3
      }
    };

    return(

        <Checkbox style={styles.checkbox} label={this.props.label}
        value={this.props.value} onCheck={this.onEventCheck} checked={this.state.checked} />

    )
  }
}

class ChangesList extends React.Component {
  constructor(props) {
    super(props);
    //contains refs to all the CheckBoxWrapper components
    this.checkboxRefs= [];
  }

  toggleWrapperState = () => {
    this.checkboxRefs.forEach( (ref, index) => {
      if(ref !== null)
        ref.changeCheckedState(this.props.selectAll);
    })
  }

  render = () => {
    let renderStatus;
    if(this.props.statuses.length === 0) {
      renderStatus =
No Changes!

    }
    else {
      renderStatus = this.props.statuses.map((status, index) => {
                      return <CheckBoxWrapper key={index} uniqueId={index} label={status.label}
                      ref={(ref) => this.checkboxRefs[index] = ref}
                      onChangeSelected={this.props.onChangeSelected} checked={this.props.selectAll} value={status.value} />;
        });
    }
    return(

        {renderStatus}

    )
  }
}

class StatusTable extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      statuses: [],
      selectAll: true
    };
  }

  getStatus = (repo) => {
    let promise = gitFunctions.getStatus(repo);
    promise.then(function(repo) {
      repo.getStatus().then(function(status) {
        return status;
      })
      .done(function(statuses) {
        this.setState({
          statuses:statuses
        });
      }.bind(this));
    }.bind(this));
  }

  checkSelectAll = (event, isInputChecked) => {

    event.stopPropagation();

    window.setTimeout( () => {
      this.setState({
        selectAll: isInputChecked? true : false
      });

      //reaches into the changesList component, which
      //in turn reaches into individual CheckBoxWrapper components
      //and sets state accordingly
      this.changesList.toggleWrapperState(this.state.selectAll);
    }, 0);

  }

  componentWillReceiveProps = (newprops) => {
    // console.log('receive props',this.state.selectAll);
      this.getStatus(newprops.repo.path);
  }

  render = () => {
    let localStatus = [];
    if(this.state.statuses.length === 0)
    {
      localStatus = [];
    }
    else {

      const statusToText=function(status) {
        let words=[];
        let flag = 0;
        let int = 1;

        if (status.isNew()) { words.push(NEW); flag = 1;}
        if (status.isModified()) { words.push(MODIFIED); flag = 1;}
        if (status.isTypechange()) { words.push(TYPECHANGED); flag = 1;}
        if (status.isRenamed()) { words.push(RENAMED); flag = 1;}
        if (status.isIgnored()) { words.push(IGNORED); flag = 1; }
        if(flag == 0) { words.push(DELETED); }

        return words;
      };

      localStatus = this.state.statuses.map((file, index) => {

        let change=statusToText(file);
        let changes =[];
        changes.push({file.path()});
        changes.push(change);

        return ({
          label:changes,
          value: file.path()
        });

      });
    }

    const styles = {
      root:{
        border: '1px solid black'
      },
      ul:{
        listStyleType: 'none'
      }
    };
    return(

STATUS

        <Checkbox label='Select All:' ref={(ref) => this.selectAll = ref}  style={{width: 200}}
        onCheck={this.checkSelectAll} checked={this.state.selectAll} labelPosition='left' />
        <ChangesList ref={(ref) => this.changesList = ref} selectAll={this.state.selectAll}
        statuses={localStatus} />

    )
  }
}

class IndexTable extends React.Component {
  constructor(props) {
    super(props);
  }

  render = () => {
    return (

        {this.props.indexEntries.map( (entry, index) => {
          return
{entry}

;
        })}

    );
  }
}

class StagingArea extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      indexPaths: [],
      commitMsg: '',
      diffs: [],
    };
  }

  addToIndex = () => {

    let checkedChanges = [];
    //reaches into each checkboxWrapper to obtain checked value
    checkedChanges = this.statusTable.changesList.checkboxRefs.map( (ref, index) => {
      if(ref !== null)
        return ref.state.checked;
    });

    let indexPaths =[];

    this.statusTable.changesList.props.statuses.forEach( (status, index) => {

      //if corresponding checkbox has been checked only
      if(checkedChanges[index])
        indexPaths.push(status);
    });

    // console.log('index',indexPaths);

    window.setTimeout( () => {

      this.setState({
        indexPaths: indexPaths
      });
      // console.log(this.state.indexPaths);
    }, 0);
  }

  createCommit = () => {

    let index;
    let oid;

    let promise = gitFunctions.getIndex(this.props.repo.path);
    promise = promise.then((indexResult) => {
      index = indexResult;
    });

    let filePaths = this.state.indexPaths.map( (status) => {
      return status.value;
    });

    // console.log(filePaths);

    //takes in initial promise, uses it to chain a new promise to it, and returns the promise,
    //which is used in the next iteration
    promise = filePaths.reduce( (prevPromise, path, currentIndex) => {
                return prevPromise.then( () => {
                  return index.addByPath(path);
                });
              }, promise);

    promise.then(() => {
      return index.write();
    })
    .then(() => {
      console.log(index.entries());
    })
    .then(() => {
      return index.writeTree();
    })
    .then( (oidResult) => {
      oid = oidResult;
      console.log('index tree written!');
    })
    //until here, all entries were added to the index and an index tree was written
    //from here, the new commit is generated using the index tree
    .then( () => {
      let innerPromise = gitFunctions.createCommit(this.props.repo.path, oid, this.state.commitMsg);
      innerPromise.done(function(commitId) {
        console.log('Commit Hash:'+commitId);
      });

    });
  }

  updateValue = (event) => {
    this.setState({
      commitMsg: event.target.value
    });
  }

  componentDidMount = () => {
    let diffArr = [];
    if(this.props.repo)
      gitFunctions.getUnstagedChanges(this.props.repo.path)
      .then( (diff) => {
        diff.patches().then((patches) => {
          patches.forEach((patch) => {
            // console.log(patch.lineStats());
            patch.hunks().then((hunks) => {
              hunks.forEach((hunk) => {
                hunk.lines().then((lines) => {
                  diffArr.push("diff", patch.oldFile().path(),
                    patch.newFile().path());
                    // console.log("diff", patch.oldFile().path(),
                    //   patch.newFile().path());
                  diffArr.push(hunk.header());
                  // console.log(hunk.header());
                  lines.forEach(function(line) {
                    // console.log(String.fromCharCode(line.origin()));
                    diffArr.push(String.fromCharCode(line.origin())+
                      line.content());
                    // console.log(String.fromCharCode(line.origin()) +
                    // line.content());
                  });
                })
                .done( () => {
                  // console.log(diffArr);
                  this.setState({
                    diffs: diffArr,
                    });
                });
              });
            });
          });
        });
      });
  }

  componentWillReceiveProps = (newprops) => {
    let diffArr = [];
    if(newprops.repo)
      gitFunctions.getUnstagedChanges(newprops.repo.path)
      .then( (diff) => {
        diff.patches().then((patches) => {
          patches.forEach((patch) => {
            // console.log(patch.lineStats());
            patch.hunks().then((hunks) => {
              hunks.forEach((hunk) => {
                hunk.lines().then((lines) => {
                  diffArr.push("diff", patch.oldFile().path(),
                    patch.newFile().path());
                    // console.log("diff", patch.oldFile().path(),
                    //   patch.newFile().path());
                  diffArr.push(hunk.header());
                  // console.log(hunk.header());
                  lines.forEach(function(line) {
                    // console.log(String.fromCharCode(line.origin()));
                    diffArr.push(String.fromCharCode(line.origin())+
                      line.content());
                    // console.log(String.fromCharCode(line.origin()) +
                    // line.content());
                  });
                })
                .done( () => {
                  // console.log(diffArr);
                  this.setState({
                    diffs: diffArr,
                    });
                });
              });
            });
          });
        });
      });
  }

  render = () => {
    const styles = {
      block: {
        maxWidth: 250,
      },
      checkbox: {
        marginBottom: 16,
      },
      main: {
        height:350,
        overflow: 'scroll',
        // backgroundColor: 'black'
      }
    };
    return (

        <RaisedButton label='Create Commit!' onMouseDown={this.createCommit} />
        <RaisedButton label='Add to Index!' onMouseDown={this.addToIndex} />
        <TextField
          hintText="Enter commit message..."
          multiLine={true}
          rows={2}
          rowsMax={2}
          value={this.state.commitMsg}
          onChange={this.updateValue}
        />
        <StatusTable {...this.props} ref={(ref) => this.statusTable = ref} />
        <IndexTable indexEntries={this.state.indexPaths.map( (status) => {return status.label})} />
        <DiffPanel diffs={this.state.diffs} />

    )
  }
}

export default StagingArea;
<|endoftext|>


<commit_before>// version 0.0.1
// 2012-10-10 Copyright (c) 2012, Christian Angermann
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
// ==UserScript==
// @name        TicketPrint
// @namespace   http://jira.com
// @description Gives the possibility to print out your story cards in a proper
// way
// @include     http://jira.*.*/jira/browse/*
// @include     https://jira.*.*/jira/browse/*
// @version     1
// ==/UserScript==
// bookmarklet wrapper
// javascript:void(function(){})();
///////////////////////////////////////////////////////////////////////////////
;String.prototype.truncate = function (maxlength) {

  'use strict';

  var length = this.length,
    suffix = '…',
    suffixLength = suffix.length,
    result = this
  ;
  if (length > maxlength) {
    result = this.substr(0, (maxlength - suffixLength)) + suffix;
  }
  return result;
};
/**
 * Will trim a string with whitespace and newlines like this:
 * '   foo
 *   bar  thut    '.trimWhitespace(); // output: 'foo bar thut'
 */
String.prototype.trimWhitespace = function () {
  return this.replace(/\s+/g, ' ').split(/\n/).join(' ');
};

///////////////////////////////////////////////////////////////////////////////

var xing = xing || {};
xing.jira = xing.jira || {};

xing.jira.Data = function ($) {

  'use strict';

  this.data = {};

  this.collectDataFromDom = function () {
    var $target = $('#greenhopper-agile-issue-web-panel dd');
    this.data = {
      number      : $('#key-val').text() || '',
      description : $('#description-val').html() || '',
      dueDate     : $('#due-date time').text() || '',
      members     : ['Björn', 'Christian', 'Jan', 'Johannes', 'Magith', 'Mark', 'Tanja'],
      type        : $('#type-val img').attr('alt') || '',
      reporter    : $('#reporter-val span').text() || '',
      created     : $('#create-date time').text() || '',
      title       : $('#summary-val a').text() || '',
      component   : $('#components-field').text() || '',
      target      : $target[0] ? $target.text().trimWhitespace() : ''
    };
  };

  // initialize
  this.collectDataFromDom();

};

xing.jira.Table = (function ($) {

  'use strict';

  function text(tag) {
    return 'text' in tag ? tag.text : '';
  }

  function options(tag, additionalClass) {
    additionalClass = ' ' + additionalClass || '';
    var options = tag['options'] || {},
      cssClass = 'cssClass' in options ? options.cssClass : '',
      attrs = '',
      option
    ;

    $.extend(options, {cssClass: cssClass + additionalClass});

    if (options.cssClass === ' ') {
      delete options.cssClass;
    }

    for (option in options) {
      var attr = option === 'cssClass' ? 'class' : option,
        value = options[option] || ''
      ;

      attr = attr.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
      attrs += ' ' + attr + '="' + value + '"';
    }
    return attrs;
  }

  var module = {

    row: function (index, rowData) {
      var result = '';
      $(rowData).each(function(index, cellData) {
        result += module.cell(cellData);
      })

      return '
' + result + '
';
    },

    cell: function (cellData) {
      var cell = cellData.cell,
        result = '',
        tag = cellData.head ? 'th' : 'td'
      ;

      result += module.cellTitle(cell);
      result += module.cellBody(cell);

      return '<' + tag + options(cell) + '>
' + result + '
</' + tag +'>';
    },

    cellBody: function (cell) {
      var result = '';

      if ('body' in cell) {
        var body = cell.body;

        result += '
' + text(body) + '
';
      }
      return result;
    },

    cellTitle: function (cell) {
      var result = '';

      if ('title' in cell) {
        var title = cell.title;
        result += '
' + text(title) + '
';
      }
      return result;
    },

    build: function (tableData) {
      var result = '';

      $(tableData).each(function (index, rowData) {
        result += module.row(index, rowData);
      });

      return '
' + result + '
';
    },

    getFormat: function (data) {
      return module.format = [
        [
          {
            head: true,
            cell: {
              options: {cssClass: 'gm-number gm-center gm-20'},
              body: {
                text: data.number,
                options: {cssClass: 'h1'}
              }
            }
          }, {
            head: true,
            cell: {
              options: {colspan: 4, cssClass: 'gm-title'},
              body: {
                text: data.title.truncate(74),
                options: {cssClass: 'h2 gm-hyphen'}
              }
            }
          }
        ], [
          {
            cell: {
              options: {rowspan: 1},
              title: {
                text: 'Due date'
              },
              body: {
                options: {cssClass: 'h4'},
                text: data.dueDate
              }
            }
          }, {
            cell: {
              options: {colspan: 4, cssClass: 'gm-pairing'},
              title: {
                text: 'Pairing',
                options: {cssClass: 'gm-snap-left h5'}
              },
              body: {
                text: data.members.join(' '),
                options: {cssClass: 'gm-snap-left h5'}
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Type'
              },
              body: {
                text: data.type
              }
            }
          }, {
            cell: {
              options: {rowspan: 4, colspan: 4, cssClass: 'gm-desc gm-hyphen'},
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Reporter'
              },
              body: {
                text: data.reporter
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Component'
              },
              body: {
                text: data.component
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Target'
              },
              body: {
                text: data.target
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Created'
              },
              body: {
                text: data.created
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-date-content'},
              title: {
                text: 'Start Progress'
              },
              body: {
                text: 'Day | Time'
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-date-content'},
              title: {
                text: 'End date'
              },
              body: {
                text: 'Day | Time'
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-qa'},
              title: {
                text: 'QA passed'
              },
              body: {
                text: ''
              }
            }
          }, {
            cell: {
              title: {
                text: 'Release'
              }
            }
          }
        ]
      ];
    }

  };

  return module;

}(jQuery));
///////////////////////////////////////////////////////////////////////////////
xing.jira.Application = (function ($) {

  'use strict'; // jslint

  function clickOutsidePopupHandler(event) {
    var $target = $(event.target),
      $container = $target.hasClass('gm-container') && $target || $target.parents('.gm-container')
    ;
    // remove popup is mouse clicked outside the popup
    if (!$container[0]) {
      hidePopup();
    }
  }

  function hidePopup(argument) {
    $('#gm-popup').remove();
    // jQuery 1.7+
    $(document).unbind('click', clickOutsidePopupHandler);
    // $(document).off('click', clickOutsidePopupHandler);
  }

  function addButton() {
    if ($('.gm-show-popup')[0]) return false;

    var $wrapper = $('

'),
      $button = $('Print Card'),
      $toolbars = $('.toolbar-group')
    ;

    $($toolbars[$toolbars.length - 1]).append($wrapper.append($button));

    $button.bind('click', function (event) {
    // jQuery 1.7+
    // $toolbars.on('click', '.gm-show-popup', function (event) {
      event.preventDefault();
      module.showPopup();
      // assign event listener after this click
      setTimeout(function () {
        $(document).click(clickOutsidePopupHandler);
        // jQuery 1.7+
        // $(document).on('click', clickOutsidePopupHandler);
      }, 1);
    });
  }

  var module = {

    addStyle: function(css) {
      var head,
        style = document.getElementById('gm-style')
      ;

      head = document.getElementsByTagName('head')[0];

      if (!style) {
        if (!head) {
          return;
        }
        style = document.createElement('style');
        style.setAttribute('id', 'gm-style');
        style.type = 'text/css';
        style.media = 'screen,print';
        head.appendChild(style);
      }
      style.innerHTML += css + '\n';
    },

    showPopup: function () {
      var data = new xing.jira.Data(jQuery).data,
        tableBuilder = xing.jira.Table,
        tableFormat = tableBuilder.getFormat(data)
      ;

      if ($('.gm-popup')[0]) return false;

      $('body').append(
        $('
'
         + '
'
         + '
Print preview
'
         + '
'
         + '
'
         +          tableBuilder.build(tableFormat)
         + '
'
         + '
'
         + '
'
         + '          <button class="gm-print aui-button">Print</button>'
         + '          Cancel'
         + '
'
         + '
'
         + '
'
         + '
'
         + '

'
         + '
'
        )
      );

      $('.gm-container')
        .delegate('.gm-print', 'click', function (event) {
        // jQuery 1.7+
        // .on('click', '.gm-print', function (event) {
          event.preventDefault();
          window.print();
        })
        .delegate('.gm-cancel', 'click', function (event) {
        // jQuery 1.7+
        // .on('click', '.gm-cancel', function (event) {
          event.preventDefault();
          hidePopup();
        })
      ;
    },

    init: function (css) {
      module.addStyle(css);
      addButton();

    },

  };

  return module;

}(jQuery));
<commit_msg>Drop license stuff from the script head<commit_after>// version 1.0.0
// ==UserScript==
// @name        TicketPrint
// @namespace   http://jira.com
// @description Gives the possibility to print out your story cards in a proper
// way
// @include     http://jira.*.*/jira/browse/*
// @include     https://jira.*.*/jira/browse/*
// @version     1
// ==/UserScript==
///////////////////////////////////////////////////////////////////////////////
;String.prototype.truncate = function (maxlength) {

  'use strict';

  var length = this.length,
    suffix = '…',
    suffixLength = suffix.length,
    result = this
  ;
  if (length > maxlength) {
    result = this.substr(0, (maxlength - suffixLength)) + suffix;
  }
  return result;
};
/**
 * Will trim a string with whitespace and newlines like this:
 * '   foo
 *   bar  thut    '.trimWhitespace(); // output: 'foo bar thut'
 */
String.prototype.trimWhitespace = function () {
  return this.replace(/\s+/g, ' ').split(/\n/).join(' ');
};

///////////////////////////////////////////////////////////////////////////////

var xing = xing || {};
xing.jira = xing.jira || {};

xing.jira.Data = function ($) {

  'use strict';

  this.data = {};

  this.collectDataFromDom = function () {
    var $target = $('#greenhopper-agile-issue-web-panel dd');
    this.data = {
      number      : $('#key-val').text() || '',
      description : $('#description-val').html() || '',
      dueDate     : $('#due-date time').text() || '',
      members     : ['Björn', 'Christian', 'Jan', 'Johannes', 'Magith', 'Mark', 'Tanja'],
      type        : $('#type-val img').attr('alt') || '',
      reporter    : $('#reporter-val span').text() || '',
      created     : $('#create-date time').text() || '',
      title       : $('#summary-val a').text() || '',
      component   : $('#components-field').text() || '',
      target      : $target[0] ? $target.text().trimWhitespace() : ''
    };
  };

  // initialize
  this.collectDataFromDom();

};

xing.jira.Table = (function ($) {

  'use strict';

  function text(tag) {
    return 'text' in tag ? tag.text : '';
  }

  function options(tag, additionalClass) {
    additionalClass = ' ' + additionalClass || '';
    var options = tag['options'] || {},
      cssClass = 'cssClass' in options ? options.cssClass : '',
      attrs = '',
      option
    ;

    $.extend(options, {cssClass: cssClass + additionalClass});

    if (options.cssClass === ' ') {
      delete options.cssClass;
    }

    for (option in options) {
      var attr = option === 'cssClass' ? 'class' : option,
        value = options[option] || ''
      ;

      attr = attr.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
      attrs += ' ' + attr + '="' + value + '"';
    }
    return attrs;
  }

  var module = {

    row: function (index, rowData) {
      var result = '';
      $(rowData).each(function(index, cellData) {
        result += module.cell(cellData);
      })

      return '
' + result + '
';
    },

    cell: function (cellData) {
      var cell = cellData.cell,
        result = '',
        tag = cellData.head ? 'th' : 'td'
      ;

      result += module.cellTitle(cell);
      result += module.cellBody(cell);

      return '<' + tag + options(cell) + '>
' + result + '
</' + tag +'>';
    },

    cellBody: function (cell) {
      var result = '';

      if ('body' in cell) {
        var body = cell.body;

        result += '
' + text(body) + '
';
      }
      return result;
    },

    cellTitle: function (cell) {
      var result = '';

      if ('title' in cell) {
        var title = cell.title;
        result += '
' + text(title) + '
';
      }
      return result;
    },

    build: function (tableData) {
      var result = '';

      $(tableData).each(function (index, rowData) {
        result += module.row(index, rowData);
      });

      return '
' + result + '
';
    },

    getFormat: function (data) {
      return module.format = [
        [
          {
            head: true,
            cell: {
              options: {cssClass: 'gm-number gm-center gm-20'},
              body: {
                text: data.number,
                options: {cssClass: 'h1'}
              }
            }
          }, {
            head: true,
            cell: {
              options: {colspan: 4, cssClass: 'gm-title'},
              body: {
                text: data.title.truncate(74),
                options: {cssClass: 'h2 gm-hyphen'}
              }
            }
          }
        ], [
          {
            cell: {
              options: {rowspan: 1},
              title: {
                text: 'Due date'
              },
              body: {
                options: {cssClass: 'h4'},
                text: data.dueDate
              }
            }
          }, {
            cell: {
              options: {colspan: 4, cssClass: 'gm-pairing'},
              title: {
                text: 'Pairing',
                options: {cssClass: 'gm-snap-left h5'}
              },
              body: {
                text: data.members.join(' '),
                options: {cssClass: 'gm-snap-left h5'}
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Type'
              },
              body: {
                text: data.type
              }
            }
          }, {
            cell: {
              options: {rowspan: 4, colspan: 4, cssClass: 'gm-desc gm-hyphen'},
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Reporter'
              },
              body: {
                text: data.reporter
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Component'
              },
              body: {
                text: data.component
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Target'
              },
              body: {
                text: data.target
              }
            }
          }
        ], [
          {
            cell: {
              title: {
                text: 'Created'
              },
              body: {
                text: data.created
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-date-content'},
              title: {
                text: 'Start Progress'
              },
              body: {
                text: 'Day | Time'
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-date-content'},
              title: {
                text: 'End date'
              },
              body: {
                text: 'Day | Time'
              }
            }
          }, {
            cell: {
              options: {cssClass: 'gm-qa'},
              title: {
                text: 'QA passed'
              },
              body: {
                text: ''
              }
            }
          }, {
            cell: {
              title: {
                text: 'Release'
              }
            }
          }
        ]
      ];
    }

  };

  return module;

}(jQuery));
///////////////////////////////////////////////////////////////////////////////
xing.jira.Application = (function ($) {

  'use strict'; // jslint

  function clickOutsidePopupHandler(event) {
    var $target = $(event.target),
      $container = $target.hasClass('gm-container') && $target || $target.parents('.gm-container')
    ;
    // remove popup is mouse clicked outside the popup
    if (!$container[0]) {
      hidePopup();
    }
  }

  function hidePopup(argument) {
    $('#gm-popup').remove();
    // jQuery 1.7+
    $(document).unbind('click', clickOutsidePopupHandler);
    // $(document).off('click', clickOutsidePopupHandler);
  }

  function addButton() {
    if ($('.gm-show-popup')[0]) return false;

    var $wrapper = $('

'),
      $button = $('Print Card'),
      $toolbars = $('.toolbar-group')
    ;

    $($toolbars[$toolbars.length - 1]).append($wrapper.append($button));

    $button.bind('click', function (event) {
    // jQuery 1.7+
    // $toolbars.on('click', '.gm-show-popup', function (event) {
      event.preventDefault();
      module.showPopup();
      // assign event listener after this click
      setTimeout(function () {
        $(document).click(clickOutsidePopupHandler);
        // jQuery 1.7+
        // $(document).on('click', clickOutsidePopupHandler);
      }, 1);
    });
  }

  var module = {

    addStyle: function(css) {
      var head,
        style = document.getElementById('gm-style')
      ;

      head = document.getElementsByTagName('head')[0];

      if (!style) {
        if (!head) {
          return;
        }
        style = document.createElement('style');
        style.setAttribute('id', 'gm-style');
        style.type = 'text/css';
        style.media = 'screen,print';
        head.appendChild(style);
      }
      style.innerHTML += css + '\n';
    },

    showPopup: function () {
      var data = new xing.jira.Data(jQuery).data,
        tableBuilder = xing.jira.Table,
        tableFormat = tableBuilder.getFormat(data)
      ;

      if ($('.gm-popup')[0]) return false;

      $('body').append(
        $('
'
         + '
'
         + '
Print preview
'
         + '
'
         + '
'
         +          tableBuilder.build(tableFormat)
         + '
'
         + '
'
         + '
'
         + '          <button class="gm-print aui-button">Print</button>'
         + '          Cancel'
         + '
'
         + '
'
         + '
'
         + '
'
         + '

'
         + '
'
        )
      );

      $('.gm-container')
        .delegate('.gm-print', 'click', function (event) {
        // jQuery 1.7+
        // .on('click', '.gm-print', function (event) {
          event.preventDefault();
          window.print();
        })
        .delegate('.gm-cancel', 'click', function (event) {
        // jQuery 1.7+
        // .on('click', '.gm-cancel', function (event) {
          event.preventDefault();
          hidePopup();
        })
      ;
    },

    init: function (css) {
      module.addStyle(css);
      addButton();

    },

  };

  return module;

}(jQuery));
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Torn City Gym and crime bot
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  Try to take over the world, for the lazy.
// @author       Jurriaan Den Toonder<jurriaan.toonder@liquidpineapple.net>
// @match        http://www.torn.com/*
// @require      http://code.jquery.com/jquery-2.2.2.min.js
// @run-at       document-end
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// ==/UserScript==
/* jshint -W097 */
'use strict';

$(document).ready(function(){
    console.log("Torn city bot loaded!");
    window.setInterval(init, 2000);
});

function init() {
    var action = GM_getValue('action', 'gym');
    var stats = checkStats();
    if (action === 'gym') {
        GM_setValue('action', 'gym');
        if (stats['energy'] >= 5) {
            console.log("Energy >= 5, doGym()");
            var gymStep = GM_getValue('gym_step', 1);
            doGym(gymStep);
        } else {
            GM_setValue('action', 'crime');
        }
    } else if (action === 'crime') {
        if (stats['nerve'] >= 4) {
            console.log("Nerve >= 4, doCrime()");
            var crimeStep = GM_getValue('crime_step', 1);
            console.log("CRIME STEP: " + crimeStep);
            doCrime(crimeStep);
        } else {
            GM_deleteValue('action');//Cannot do anything
        }
    } else {
        console.error("Invalid action, resetting bot and reloading");
        GM_deleteValue('action');
        window.location.href = '/index.php';
    }
}

function checkStats() {
    var Energy = document.getElementById('energy').children[1].dataset.current;
    var Nerve = document.getElementById('nerve').children[1].dataset.current;
    var Happy = document.getElementById('happy').children[1].dataset.current;
    var Life = document.getElementById('life').children[1].dataset.current;
    return {
        'energy': Energy,
        'nerve': Nerve,
        'happy': Happy,
        'life': Life
    };
}

function doGym(step) {
    if (step === 1) {
        console.log("doGym step 1");
        GM_setValue('gym_step', 2);
        if (window.location.pathname == '/gym.php'){
            doGym(2)
        } else {
            window.location.href = '/gym.php';
        }
    }
    if (step === 2) {
        console.log("doGym step 2");
        if (window.location.pathname != '/gym.php') {
            window.location.href = '/gym.php';
        }
        var Strength = document.getElementById('strengthTotal').innerText;
        var Defense = document.getElementById('defenceTotal').innerText;
        var Speed = document.getElementById('speedTotal').innerText;
        var Dexterity = document.getElementById('dexterityTotal').innerText;

        GM_setValue('gym_step', 1);

        if (Strength <= Defense) {
            document.getElementById('divStrength').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divStrength').getElementsByClassName('trainStat')[0].click();
        } else if (Defense <= Speed) {
            document.getElementById('divDefence').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divDefence').getElementsByClassName('trainStat')[0].click();
        } else if (Speed <= Dexterity) {
            document.getElementById('divSpeed').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divSpeed').getElementsByClassName('trainStat')[0].click();
        } else {
            document.getElementById('divDexterity').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divDexterity').getElementsByClassName('trainStat')[0].click();
        }

        window.setTimeout(function() {
            var stats = checkStats();
            if (stats['energy'] >= 5) {
                GM_setValue('gym_step', 1);
                doGym(1);
            } else {
                window.location.href = '/index.php';
            }
        }, 1500);
    }
}

function doCrime(step) {
    if (step === 1) {
        console.log("doCrime step 1");
        GM_setValue('crime_step', 2);
        window.location.href = '/crimes.php';
    }
    if (step === 2) {
        console.log("doCrime step 2");
        $('input[name=crime][value=shoplift]').click();
        GM_setValue('crime_step', 3);
    }
    if (step === 3) {
        $('input[name=crime][value=sweetshop]').click();
        GM_setValue('crime_step', 4);
    }
    if (step === 4) {
        $('input[name=crime][value=extrastrongmints]').click();
        GM_setValue('crime_step', 5);
    }
    if (step === 5) {
        GM_setValue('crime_step', 1);
        window.location.href = '/index.php';
    }
}<commit_msg>Updated namespace and updateURL<commit_after>// ==UserScript==
// @name         Torn City automatic Gym and Crime bot
// @namespace    http://liquidpineapple.net
// @version      0.5
// @description  Try to take over the world, for the lazy.
// @author       Jurriaan Den Toonder<jurriaan.toonder@liquidpineapple.net>
// @downloadURL  https://github.com/Fastjur/Torn-City-Bot/raw/master/src/TornCityBot.user.js
// @updateURL    https://github.com/Fastjur/Torn-City-Bot/raw/master/src/TornCityBot.user.js
// @match        http://www.torn.com/*
// @require      http://code.jquery.com/jquery-2.2.2.min.js
// @run-at       document-end
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// ==/UserScript==
'use strict';

$(document).ready(function(){
    console.log("Torn city bot loaded!");
    window.setInterval(init, 2000);
});

function init() {
    var action = GM_getValue('action', 'gym');
    var stats = checkStats();
    if (action === 'gym') {
        GM_setValue('action', 'gym');
        if (stats['energy'] >= 5) {
            console.log("Energy >= 5, doGym()");
            var gymStep = GM_getValue('gym_step', 1);
            doGym(gymStep);
        } else {
            GM_setValue('action', 'crime');
        }
    } else if (action === 'crime') {
        if (stats['nerve'] >= 4) {
            console.log("Nerve >= 4, doCrime()");
            var crimeStep = GM_getValue('crime_step', 1);
            console.log("CRIME STEP: " + crimeStep);
            doCrime(crimeStep);
        } else {
            GM_deleteValue('action');//Cannot do anything
        }
    } else {
        console.error("Invalid action, resetting bot and reloading");
        GM_deleteValue('action');
        window.location.href = '/index.php';
    }
}

function checkStats() {
    var Energy = document.getElementById('energy').children[1].dataset.current;
    var Nerve = document.getElementById('nerve').children[1].dataset.current;
    var Happy = document.getElementById('happy').children[1].dataset.current;
    var Life = document.getElementById('life').children[1].dataset.current;
    return {
        'energy': Energy,
        'nerve': Nerve,
        'happy': Happy,
        'life': Life
    };
}

function doGym(step) {
    if (step === 1) {
        console.log("doGym step 1");
        GM_setValue('gym_step', 2);
        if (window.location.pathname == '/gym.php'){
            doGym(2)
        } else {
            window.location.href = '/gym.php';
        }
    }
    if (step === 2) {
        console.log("doGym step 2");
        if (window.location.pathname != '/gym.php') {
            window.location.href = '/gym.php';
        }
        var Strength = document.getElementById('strengthTotal').innerText;
        var Defense = document.getElementById('defenceTotal').innerText;
        var Speed = document.getElementById('speedTotal').innerText;
        var Dexterity = document.getElementById('dexterityTotal').innerText;

        GM_setValue('gym_step', 1);

        if (Strength <= Defense) {
            document.getElementById('divStrength').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divStrength').getElementsByClassName('trainStat')[0].click();
        } else if (Defense <= Speed) {
            document.getElementById('divDefence').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divDefence').getElementsByClassName('trainStat')[0].click();
        } else if (Speed <= Dexterity) {
            document.getElementById('divSpeed').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divSpeed').getElementsByClassName('trainStat')[0].click();
        } else {
            document.getElementById('divDexterity').getElementsByClassName('numb')[0].value = 1;
            document.getElementById('divDexterity').getElementsByClassName('trainStat')[0].click();
        }

        window.setTimeout(function() {
            var stats = checkStats();
            if (stats['energy'] >= 5) {
                GM_setValue('gym_step', 1);
                doGym(1);
            } else {
                window.location.href = '/index.php';
            }
        }, 1500);
    }
}

function doCrime(step) {
    if (step === 1) {
        console.log("doCrime step 1");
        GM_setValue('crime_step', 2);
        window.location.href = '/crimes.php';
    }
    if (step === 2) {
        console.log("doCrime step 2");
        $('input[name=crime][value=shoplift]').click();
        GM_setValue('crime_step', 3);
    }
    if (step === 3) {
        $('input[name=crime][value=sweetshop]').click();
        GM_setValue('crime_step', 4);
    }
    if (step === 4) {
        $('input[name=crime][value=extrastrongmints]').click();
        GM_setValue('crime_step', 5);
    }
    if (step === 5) {
        GM_setValue('crime_step', 1);
        window.location.href = '/index.php';
    }
}<|endoftext|>


<commit_before>define('spec/preloader', ['lyria/preloader'], function(Preloader) {

  describe('lyria/preloader', function() {

    var preloader = new Preloader();

    it('is a function', function() {
      expect(Preloader).to.be.a('function');
    });

    describe('constructor', function() {
      it('lyria/game is instantiable', function() {
        expect(preloader).to.be.a('object');
        expect(preloader).to.be.an.instanceOf(Preloader);
      });

      it('Instance has default values', function() {
        expect(preloader.assets).to.be.empty;
        expect(preloader.maxAssets).to.equal(0);
        expect(preloader.assetsLoaded).to.equal(0);
        expect(preloader.steps).to.be.empty;
        expect(preloader.taskList).to.be.empty;
      });
    });

    it('Instance has property assets', function() {
      expect(preloader).to.have.property('assets');
      expect(preloader.assets).to.be.a('object');
    });

    it('Instance has property maxAssets', function() {
      expect(preloader).to.have.property('maxAssets');
      expect(preloader.maxAssets).to.be.a('number');
    });

    it('Instance has property assetsLoaded', function() {
      expect(preloader).to.have.property('assetsLoaded');
      expect(preloader.assetsLoaded).to.be.a('number');
    });

    it('Instance has property steps', function() {
      expect(preloader).to.have.property('steps');
      expect(preloader.steps).to.be.a('array');
    });

    it('Instance has property taskList', function() {
      expect(preloader).to.have.property('taskList');
      expect(preloader.taskList).to.be.a('array');
    });

    it('#start', function() {
      expect(Preloader.prototype.start).to.be.a('function');
      expect(preloader).to.have.property('start');
      expect(preloader.start).to.equal(Preloader.prototype.start);
    });

    describe('#task', function() {
      it('exists', function() {
        expect(Preloader.prototype.task).to.be.a('function');
        expect(preloader).to.have.property('start');
        expect(preloader.task).to.equal(Preloader.prototype.task);
      });

      it('running synchronous tasks', function() {
        var preloader = new Preloader();
        var steps = 0;

        preloader.task(function() { steps++; });
        preloader.task(function() { steps++; });
        preloader.task(function() { steps++; });

        preloader.start();

        expect(steps).to.be.a('number');
        expect(steps).to.equal(3);
      });
    });

    describe('#task.async', function() {
      it('exists', function() {
        expect(Preloader.prototype.task.async).to.be.a('function');
        expect(preloader).to.have.property('start');
        expect(preloader.task.async).to.equal(Preloader.prototype.task.async);
      });
    });

  });

});
<commit_msg>Added asynchronous preloader test<commit_after>define('spec/preloader', ['lyria/preloader'], function(Preloader) {

  describe('lyria/preloader', function() {

    var preloader = new Preloader();

    it('is a function', function() {
      expect(Preloader).to.be.a('function');
    });

    describe('constructor', function() {
      it('lyria/game is instantiable', function() {
        expect(preloader).to.be.a('object');
        expect(preloader).to.be.an.instanceOf(Preloader);
      });

      it('Instance has default values', function() {
        expect(preloader.assets).to.be.empty
        expect(preloader.maxAssets).to.equal(0);
        expect(preloader.assetsLoaded).to.equal(0);
        expect(preloader.steps).to.be.empty
        expect(preloader.taskList).to.be.empty
      });
    });

    it('Instance has property assets', function() {
      expect(preloader).to.have.property('assets');
      expect(preloader.assets).to.be.a('object');
    });

    it('Instance has property maxAssets', function() {
      expect(preloader).to.have.property('maxAssets');
      expect(preloader.maxAssets).to.be.a('number');
    });

    it('Instance has property assetsLoaded', function() {
      expect(preloader).to.have.property('assetsLoaded');
      expect(preloader.assetsLoaded).to.be.a('number');
    });

    it('Instance has property steps', function() {
      expect(preloader).to.have.property('steps');
      expect(preloader.steps).to.be.a('array');
    });

    it('Instance has property taskList', function() {
      expect(preloader).to.have.property('taskList');
      expect(preloader.taskList).to.be.a('array');
    });

    it('#start', function() {
      expect(Preloader.prototype.start).to.be.a('function');
      expect(preloader).to.have.property('start');
      expect(preloader.start).to.equal(Preloader.prototype.start);
    });

    describe('#task', function() {
      it('exists', function() {
        expect(Preloader.prototype.task).to.be.a('function');
        expect(preloader).to.have.property('start');
        expect(preloader.task).to.equal(Preloader.prototype.task);
      });

      it('running synchronous tasks', function() {
        var preloader = new Preloader();
        var steps = 0;

        preloader.task(function() {
          steps++;
        });
        preloader.task(function() {
          steps++;
        });
        preloader.task(function() {
          steps++;
        });

        preloader.start();

        expect(steps).to.be.a('number');
        expect(steps).to.equal(3);
      });
    });

    describe('#task.async', function() {
      it('exists', function() {
        expect(Preloader.prototype.task.async).to.be.a('function');
        expect(preloader).to.have.property('start');
        expect(preloader.task.async).to.equal(Preloader.prototype.task.async);
      });

      it('running asynchronous tasks', function(testDone) {
        var preloader = new Preloader();
        var steps = 0;

        var checkIfDone = function() {
          expect(steps).to.be.a('number');
          expect(steps).to.equal(3);
          testDone();
        };

        var stepFn = function() {
          steps++;
        };

        preloader.task.async(function(done) {
          setTimeout(function() {
            stepFn();
            checkIfDone();
            done();
          }, 200);
        });
        preloader.task.async(function(done) {
          setTimeout(function() {
            stepFn();
            checkIfDone();
            done();
          }, 300);
        });
        preloader.task.async(function(done) {
          setTimeout(function() {
            stepFn();
            checkIfDone();
            done();
          }, 400);
        });

        preloader.start();
      });
    });

  });

});
<|endoftext|>