<commit_before>function whatToTestSpidermonkeyTrunk(code)
{
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("Math.fround") == -1         // bug 995673
       && code.indexOf("valueOf") == -1             // bug 995673
       && code.indexOf("ArrayBuffer") == -1         // bug 995679
       && code.indexOf("neuter") == -1              // bug 995679
       && code.indexOf("filterPar") == -1           // bug 996895
       && code.indexOf("defineProperty") == -1      // bug 998059
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla24(code)
{
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (24 branch)
       && code.indexOf("RegExp") == -1              // bug 945512 (24 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<commit_msg>Add bug 998262.<commit_after>function whatToTestSpidermonkeyTrunk(code)
{
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("Math.fround") == -1         // bug 995673
       && code.indexOf("valueOf") == -1             // bug 995673
       && code.indexOf("ArrayBuffer") == -1         // bug 995679
       && code.indexOf("neuter") == -1              // bug 995679
       && code.indexOf("filterPar") == -1           // bug 996895
       && code.indexOf("defineProperty") == -1      // bug 998059
       && code.indexOf("buildPar") == -1            // bug 998262
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla24(code)
{
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (24 branch)
       && code.indexOf("RegExp") == -1              // bug 945512 (24 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<|endoftext|>


<commit_before>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("timeout") == -1             // time runs and crawls
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("dumpHeapComplete") == -1    // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("load") == -1                // load()ed regression test might output dates, etc
       && code.indexOf("drainAllocationsLog") == -1 // drainAllocationsLog returns an object with a timestamp, see bug 1066313
       && code.indexOf("getBacktrace") == -1        // getBacktrace returns memory addresses which differs depending on flags
       && code.indexOf("inJit") == -1               // may become true after several iterations, or return a string with --no-baseline
       && code.indexOf("inIon") == -1               // may become true after several iterations, or return a string with --no-ion
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("length") == -1              // bug 1027846
       && code.indexOf("preventExtensions") == -1   // bug 1085299
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla31(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (31 branch)
       && code.indexOf("length") == -1              // bug 998059 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 998262 (31 branch)
       && code.indexOf("with") == -1                // bug 998580 (31 branch)
       && code.indexOf("use asm") == -1             // bug 999790 (31 branch)
       && code.indexOf("Math.round") == -1          // bug 1000606 (31 branch)
       && code.indexOf("Math.fround") == -1         // bug 1000606 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1000605 (31 branch)
       && code.indexOf("Math.asinh") == -1          // bug 1007213 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1008818 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1015656 (31 branch)
       && code.indexOf("arguments") == -1           // bug 1024444 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1025587 (31 branch)
       && code.indexOf("length") == -1              // bug 1027846 (31 branch)
       && code.indexOf("enumerable") == -1          // bug 1054545 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 1066496 (31 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<commit_msg>Add bug 1153153.<commit_after>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("timeout") == -1             // time runs and crawls
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("dumpHeapComplete") == -1    // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("load") == -1                // load()ed regression test might output dates, etc
       && code.indexOf("drainAllocationsLog") == -1 // drainAllocationsLog returns an object with a timestamp, see bug 1066313
       && code.indexOf("getBacktrace") == -1        // getBacktrace returns memory addresses which differs depending on flags
       && code.indexOf("inJit") == -1               // may become true after several iterations, or return a string with --no-baseline
       && code.indexOf("inIon") == -1               // may become true after several iterations, or return a string with --no-ion
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("length") == -1              // bug 1027846
       && code.indexOf("preventExtensions") == -1   // bug 1085299
       && code.indexOf("use strict") == -1          // bug 1153153
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla31(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (31 branch)
       && code.indexOf("length") == -1              // bug 998059 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 998262 (31 branch)
       && code.indexOf("with") == -1                // bug 998580 (31 branch)
       && code.indexOf("use asm") == -1             // bug 999790 (31 branch)
       && code.indexOf("Math.round") == -1          // bug 1000606 (31 branch)
       && code.indexOf("Math.fround") == -1         // bug 1000606 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1000605 (31 branch)
       && code.indexOf("Math.asinh") == -1          // bug 1007213 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1008818 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1015656 (31 branch)
       && code.indexOf("arguments") == -1           // bug 1024444 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1025587 (31 branch)
       && code.indexOf("length") == -1              // bug 1027846 (31 branch)
       && code.indexOf("enumerable") == -1          // bug 1054545 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 1066496 (31 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<|endoftext|>


<commit_before>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("/*NODIFF*/") == -1                // Ignore diff testing on these labels
       && code.indexOf("Date") == -1                      // time marches on
       && code.indexOf("backtrace") == -1                 // shows memory addresses
       && code.indexOf("drainAllocationsLog") == -1       // drainAllocationsLog returns an object with a timestamp, see bug 1066313
       && code.indexOf("dumpObject") == -1                // shows heap addresses
       && code.indexOf("dumpHeap") == -1                  // shows heap addresses
       && code.indexOf("dumpStringRepresentation") == -1  // shows memory addresses
       && code.indexOf("evalInWorker") == -1              // causes diffs in --no-threads vs --ion-offthread-compile=off
       && code.indexOf("getBacktrace") == -1              // getBacktrace returns memory addresses which differs depending on flags
       && code.indexOf("getLcovInfo") == -1
       && code.indexOf("load") == -1                      // load()ed regression test might output dates, etc
       && code.indexOf("offThreadCompileScript") == -1    // causes diffs in --no-threads vs --ion-offthread-compile=off
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("oomAtAllocation") == -1
       && code.indexOf("printProfilerEvents") == -1       // causes diffs in --ion-eager vs --baseline-eager
       && code.indexOf("validategc") == -1
       && code.indexOf("inIon") == -1                     // may become true after several iterations, or return a string with --no-ion
       && code.indexOf("inJit") == -1                     // may become true after several iterations, or return a string with --no-baseline
       && code.indexOf("random") == -1
       && code.indexOf("timeout") == -1                   // time runs and crawls
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1                 // see bug 743425
       && code.indexOf("disassemble") == -1             // see bug 1237403 (related to asm.js)
       && code.indexOf(".script") == -1                 // see bug 1237464
       && code.indexOf(".parameterNames") == -1         // see bug 1237464
       && code.indexOf(".environment") == -1            // see bug 1237464
       && code.indexOf(".onNewGlobalObject") == -1      // see bug 1238246
       && code.indexOf("Object.seal") == -1             // bug 937922
       && code.indexOf("length") == -1                  // bug 1027846
       && code.indexOf("preventExtensions") == -1       // bug 1085299
       && code.indexOf("Math.round") == -1              // bug 1236114
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/))  // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla31(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (31 branch)
       && code.indexOf("length") == -1              // bug 998059 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 998262 (31 branch)
       && code.indexOf("with") == -1                // bug 998580 (31 branch)
       && code.indexOf("use asm") == -1             // bug 999790 (31 branch)
       && code.indexOf("Math.round") == -1          // bug 1000606 (31 branch)
       && code.indexOf("Math.fround") == -1         // bug 1000606 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1000605 (31 branch)
       && code.indexOf("Math.asinh") == -1          // bug 1007213 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1008818 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1015656 (31 branch)
       && code.indexOf("arguments") == -1           // bug 1024444 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1025587 (31 branch)
       && code.indexOf("length") == -1              // bug 1027846 (31 branch)
       && code.indexOf("enumerable") == -1          // bug 1054545 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 1066496 (31 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA31)
  whatToTest = whatToTestSpidermonkeyMozilla31;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<commit_msg>Add bug 1244502.<commit_after>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("/*NODIFF*/") == -1                // Ignore diff testing on these labels
       && code.indexOf("Date") == -1                      // time marches on
       && code.indexOf("backtrace") == -1                 // shows memory addresses
       && code.indexOf("drainAllocationsLog") == -1       // drainAllocationsLog returns an object with a timestamp, see bug 1066313
       && code.indexOf("dumpObject") == -1                // shows heap addresses
       && code.indexOf("dumpHeap") == -1                  // shows heap addresses
       && code.indexOf("dumpStringRepresentation") == -1  // shows memory addresses
       && code.indexOf("evalInWorker") == -1              // causes diffs in --no-threads vs --ion-offthread-compile=off
       && code.indexOf("getBacktrace") == -1              // getBacktrace returns memory addresses which differs depending on flags
       && code.indexOf("getLcovInfo") == -1
       && code.indexOf("load") == -1                      // load()ed regression test might output dates, etc
       && code.indexOf("offThreadCompileScript") == -1    // causes diffs in --no-threads vs --ion-offthread-compile=off
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("oomAtAllocation") == -1
       && code.indexOf("printProfilerEvents") == -1       // causes diffs in --ion-eager vs --baseline-eager
       && code.indexOf("validategc") == -1
       && code.indexOf("inIon") == -1                     // may become true after several iterations, or return a string with --no-ion
       && code.indexOf("inJit") == -1                     // may become true after several iterations, or return a string with --no-baseline
       && code.indexOf("random") == -1
       && code.indexOf("timeout") == -1                   // time runs and crawls
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1                 // see bug 743425
       && code.indexOf("disassemble") == -1             // see bug 1237403 (related to asm.js)
       && code.indexOf(".script") == -1                 // see bug 1237464
       && code.indexOf(".parameterNames") == -1         // see bug 1237464
       && code.indexOf(".environment") == -1            // see bug 1237464
       && code.indexOf(".onNewGlobalObject") == -1      // see bug 1238246
       && code.indexOf("Object.seal") == -1             // bug 937922
       && code.indexOf("length") == -1                  // bug 1027846
       && code.indexOf("preventExtensions") == -1       // bug 1085299
       && code.indexOf("Math.round") == -1              // bug 1236114
       && code.indexOf("localeCompare") == -1           // bug 1244502
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/))  // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla31(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (31 branch)
       && code.indexOf("length") == -1              // bug 998059 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 998262 (31 branch)
       && code.indexOf("with") == -1                // bug 998580 (31 branch)
       && code.indexOf("use asm") == -1             // bug 999790 (31 branch)
       && code.indexOf("Math.round") == -1          // bug 1000606 (31 branch)
       && code.indexOf("Math.fround") == -1         // bug 1000606 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1000605 (31 branch)
       && code.indexOf("Math.asinh") == -1          // bug 1007213 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1008818 (31 branch)
       && code.indexOf("Math.ceil") == -1           // bug 1015656 (31 branch)
       && code.indexOf("arguments") == -1           // bug 1024444 (31 branch)
       && code.indexOf("use strict") == -1          // bug 1025587 (31 branch)
       && code.indexOf("length") == -1              // bug 1027846 (31 branch)
       && code.indexOf("enumerable") == -1          // bug 1054545 (31 branch)
       && code.indexOf("buildPar") == -1            // bug 1066496 (31 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA31)
  whatToTest = whatToTestSpidermonkeyMozilla31;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<|endoftext|>


<commit_before>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("Math.round") == -1          // bug 1000606
       && code.indexOf("Math.fround") == -1         // bug 1000606
       && code.indexOf("Math.log2") == -1           // bug 1000606
       && code.indexOf("Math.asinh") == -1          // bug 1007213
       && code.indexOf("length") == -1              // bug 1027846
       && code.indexOf("__proto__") == -1           // bug 1033873
       && code.indexOf("exec") == -1                // bug 1033946
       && code.indexOf("RegExp") == -1              // bug 1033946
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla24(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (24 branch)
       && code.indexOf("RegExp") == -1              // bug 945512 (24 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<commit_msg>Add bug 1034280.<commit_after>function whatToTestSpidermonkeyTrunk(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
       && code.indexOf("reducePar") == -1           // only deterministic for associative elemental-reducers
       && code.indexOf("scanPar") == -1             // only deterministic for associative elemental-reducers
       && code.indexOf("scatterPar") == -1          // only deterministic for associative conflict-resolvers
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("/*NODIFF*/") == -1          // Ignore diff testing on these labels
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922
       && code.indexOf("Math.round") == -1          // bug 1000606
       && code.indexOf("Math.fround") == -1         // bug 1000606
       && code.indexOf("Math.log2") == -1           // bug 1000606
       && code.indexOf("Math.asinh") == -1          // bug 1007213
       && code.indexOf("length") == -1              // bug 1027846
       && code.indexOf("__proto__") == -1           // bug 1033873
       && code.indexOf("exec") == -1                // bug 1033946
       && code.indexOf("RegExp") == -1              // bug 1033946
       && code.indexOf("filterPar") == -1           // bug 1034280
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestSpidermonkeyMozilla24(code)
{
  /* jshint laxcomma: true */
  // regexps can't match across lines, so replace whitespace with spaces.
  var codeL = code.replace(/\s/g, " ");

  return {

    allowParse: true,

    allowExec: unlikelyToHang(code)
      && (jsshell || code.indexOf("nogeckoex") == -1)
    ,

    allowIter: true,

    // Ideally we'd detect whether the shell was compiled with --enable-more-deterministic
    expectConsistentOutput: true
       && (gcIsQuiet || code.indexOf("gc") == -1)
       && code.indexOf("Date") == -1                // time marches on
       && code.indexOf("random") == -1
       && code.indexOf("dumpObject") == -1          // shows heap addresses
       && code.indexOf("oomAfterAllocations") == -1
    ,

    expectConsistentOutputAcrossIter: true
       && code.indexOf("options") == -1             // options() is per-cx, and the js shell doesn't create a new cx for each sandbox/compartment
    ,

    expectConsistentOutputAcrossJITs: true
       && code.indexOf("'strict") == -1             // see bug 743425
       && code.indexOf("Object.seal") == -1         // bug 937922 (24 branch)
       && code.indexOf("RegExp") == -1              // bug 945512 (24 branch)
       && !( codeL.match(/\/.*[\u0000\u0080-\uffff]/)) // doesn't stay valid utf-8 after going through python (?)

  };
}

function whatToTestJavaScriptCore(code)
{
  return {

    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: false, // JavaScriptCore does not support |yield| and |Iterator|
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false

  };
}

function whatToTestGeneric(code)
{
  return {
    allowParse: true,
    allowExec: unlikelyToHang(code),
    allowIter: (typeof Iterator == "function"),
    expectConsistentOutput: false,
    expectConsistentOutputAcrossIter: false,
    expectConsistentOutputAcrossJITs: false
  };
}

var whatToTest;
if (engine == ENGINE_SPIDERMONKEY_TRUNK)
  whatToTest = whatToTestSpidermonkeyTrunk;
else if (engine == ENGINE_SPIDERMONKEY_MOZILLA24)
  whatToTest = whatToTestSpidermonkeyMozilla24;
else if (engine == ENGINE_JAVASCRIPTCORE)
  whatToTest = whatToTestJavaScriptCore;
else
  whatToTest = whatToTestGeneric;

function unlikelyToHang(code)
{
  var codeL = code.replace(/\s/g, " ");

  // Things that are likely to hang in all JavaScript engines
  return true
    && code.indexOf("infloop") == -1
    && !( codeL.match( /const.*for/ )) // can be an infinite loop: function() { const x = 1; for each(x in ({a1:1})) dumpln(3); }
    && !( codeL.match( /for.*const/ )) // can be an infinite loop: for each(x in ...); const x;
    && !( codeL.match( /for.*in.*uneval/ )) // can be slow to loop through the huge string uneval(this), for example
    && !( codeL.match( /for.*for.*for/ )) // nested for loops (including for..in, array comprehensions, etc) can take a while
    && !( codeL.match( /for.*for.*gc/ ))
    ;
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import Scroll, {scroller} from 'react-scroll';
import canada from './Canada.jpg'

class Image extends React.Component {
    constructor(props) {
      super(props);
      this.state = { width: 0, height: 0, file: '',imagePreviewUrl: '', w:'', h: '600', url: 'https://mr.goose.ml/api', promiseValue: ''};
      this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
      this.scrollToTop = this.scrollToTop.bind(this);
    }

    //general scaling
    scrollToTop() {
        Scroll.animateScroll.scrollToTop();
    }

    componentDidMount() {
        this.updateWindowDimensions();
        window.addEventListener('resize', this.updateWindowDimensions);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.updateWindowDimensions);
    }

    updateWindowDimensions() {
        this.setState({ width: window.innerWidth, height: window.innerHeight });
    }

    //Handles submission, to be done.
    _handleSubmit(e) {
      var formData = new FormData();
      e.preventDefault();//Prevent going off application.
      console.log('uploading ', this.state.file);

      const file = this.state.file;
      formData.append("file", file);
      fetch(this.state.url, {
        method: 'POST',
        body: formData
      }).then(function(response) {
        console.log(response);
        const temp = response.json().then(function(result){
        this.state.promiseValue = result;
	});
        this.props.returnValue(this.state.promiseValue);
        console.log(temp);

        return response;
      })
    }

    //Handles loading of files.
    _handleImageChange(e) {
      e.preventDefault();//Prevent going off application.

      let reader = new FileReader();
      let file = e.target.files[0];

      reader.onloadend = () => {
        this.setState({
          file: file,
          imagePreviewUrl: reader.result,
        });

        console.log('uploading ', this.state.file);
      }

      reader.readAsDataURL(file)
    }

    render() {
        const style = {
            marginLeft: this.state.width * 0.05 + 'px',
            width: this.state.width * 0.5,
            display: this.props.ifShow
        }

        let {imagePreviewUrl} = this.state;
        let $imagePreview = null;
        if (imagePreviewUrl) {
            $imagePreview = ();
        } else {
            $imagePreview = ();
        }

        return (

                <form onSubmit={(e)=>this._handleSubmit(e)}>

                        Click to Choose an Image
                        <input className="fileInput"
                        type="file"
                        onChange={(e)=>this._handleImageChange(e)} />

                        {$imagePreview}

                    <button className="submitButton"
                        type="submit"
                        onClick={(e)=>this._handleSubmit(e)}>Rate my image, Mr.Goose!
                    </button>
                </form>

        )
    }
  }

export default Image;
<commit_msg>attempt to fix non declare error<commit_after>import React, {Component} from 'react';
import Scroll, {scroller} from 'react-scroll';
import canada from './Canada.jpg'

class Image extends React.Component {
    constructor(props) {
      super(props);
      this.state = { width: 0, height: 0, file: '',imagePreviewUrl: '', w:'', h: '600', url: 'https://mr.goose.ml/api', promiseValue: ''};
      this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
      this.scrollToTop = this.scrollToTop.bind(this);
      this._handleSubmit = this._handleSubmit.bind(this);
    }

    //general scaling
    scrollToTop() {
        Scroll.animateScroll.scrollToTop();
    }

    componentDidMount() {
        this.updateWindowDimensions();
        window.addEventListener('resize', this.updateWindowDimensions);
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.updateWindowDimensions);
    }

    updateWindowDimensions() {
        this.setState({ width: window.innerWidth, height: window.innerHeight });
    }

    //Handles submission, to be done.
    _handleSubmit(e) {
      var formData = new FormData();
      e.preventDefault();//Prevent going off application.
      console.log('uploading ', this.state.file);

      const file = this.state.file;
      formData.append("file", file);
      fetch(this.state.url, {
        method: 'POST',
        body: formData
      }).then(function(response) {
        console.log(response);
        const temp = response.json().then(function(result){
        this.state.promiseValue = result;
	});
        this.props.returnValue(this.state.promiseValue);
        console.log(temp);

        return response;
      })
    }

    //Handles loading of files.
    _handleImageChange(e) {
      e.preventDefault();//Prevent going off application.

      let reader = new FileReader();
      let file = e.target.files[0];

      reader.onloadend = () => {
        this.setState({
          file: file,
          imagePreviewUrl: reader.result,
        });

        console.log('uploading ', this.state.file);
      }

      reader.readAsDataURL(file)
    }

    render() {
        const style = {
            marginLeft: this.state.width * 0.05 + 'px',
            width: this.state.width * 0.5,
            display: this.props.ifShow
        }

        let {imagePreviewUrl} = this.state;
        let $imagePreview = null;
        if (imagePreviewUrl) {
            $imagePreview = ();
        } else {
            $imagePreview = ();
        }

        return (

                <form onSubmit={(e)=>this._handleSubmit(e)}>

                        Click to Choose an Image
                        <input className="fileInput"
                        type="file"
                        onChange={(e)=>this._handleImageChange(e)} />

                        {$imagePreview}

                    <button className="submitButton"
                        type="submit"
                        onClick={(e)=>this._handleSubmit(e)}>Rate my image, Mr.Goose!
                    </button>
                </form>

        )
    }
  }

export default Image;
<|endoftext|>


<commit_before>var cookie = require('cookie');
var colName = 'sessions';
var expire_time = 168; // one week 7*24

var publicSession = {

    set: function (data, callback) {

        if (data.constructor.name !== 'Object') {
            return callback(new Error('Data must be an object.'))
        }

        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                self[key] = data[key];
            }
        }
        callback();
    },
    end: function (all, callback) {
        if (typeof all === 'function') {
            callback = all;
        }
        callback();
    },
    renew: function (callback) {
        callback();
    }
};

// session class
var Session = {

    set: function(data, callback) {

        if (data.constructor.name !== 'Object') {
            return callback(new Error('Data must be an object.'))
        }

        var self = this;

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            db.collection(colName).update({_sid: self._sid}, {$set: data}, function (err) {

                if (err) {
                    return callback(err);
                }

                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        self[key] = data[key];
                    }
                }

                callback();
            });
        });
    },

    end: function (endAll, callback) {

        if (typeof endAll === 'function') {
            callback = endAll;
            endAll = null;
        }

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            db.collection(colName).remove(
                endAll ? {_uid: this._uid} : {_sid: this._sid},
                callback
            );
        });

    },

    renew: function (callback) {

        var self = this;

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            var newSid = M.util.uid(23);

            db.collection(colName).update({_sid: self._sid}, {$set: {_sid: newSid}}, function (err) {

                if (err) {
                    return callback(err);
                }

                self._sid = newSid;

                callback();
            });
        });
    }
};

//------------------------------------------------------------------------------------------

function getSession (sessionId, now, expire, callback) {

    M.mongo.connect(M.config.mongoDB.name, function(err, db) {

        if (err) {
            return callback(err);
        }

        db.collection(colName).findAndModify(
            {_sid: sessionId, _exp: {$gt: now}},
            [],
            {$set: {_exp: expire}},
            {fields: {_id: 0}},
            callback
        );
    });
};

function startSession (session, callback) {

	M.mongo.connect(M.config.mongoDB.name, function(err, db) {

        if (err) {
            return callback(err)
        };

        db.collection(colName).insert(session, {safe: true},  callback);
	});
};

function expire(hoursPlus) {
	return Math.round(new Date().getTime() / 3600000) + (hoursPlus || 0); //86400000 = 1day, 3600000 = 1hour
}

function sessionConstructor (session) {

    var clonedSession = Session.clone();

    for (var key in session) {
        if (session.hasOwnProperty(key)) {
            clonedSession[key] = session[key];
        }
    }

    return clonedSession;
}

function getPublicSession (link, localeFromCookie) {

    link.session = publicSession.clone();
    link.session._rid = M.config.app.publicRole;

    if (localeFromCookie) {
        link.session._loc = localeFromCookie;
    } else {
        link.session._loc = M.config.app.locale || "*";
        link.res.headers['set-cookie'] = M.config.session.locale + '=' + link.session._loc + '; path=/';
    }
}

//------------------------------------------------------------------------------------------

// TODO check in query params for an sid
// TODO check if locale is in url query params
function get (link, callback) {

    var cooky = {};

    if (link.req.headers.cookie) {

        // parse cookie
        cooky = cookie.parse(link.req.headers.cookie);

        // get session and overwrite default session
        if (cooky[M.config.session.id]) {

            return getSession(cooky.sid, expire(), expire(expire_time), function(err, session) {

                if (!err && session) {
                    link.session = sessionConstructor(session);
                } else {
                    // TODO maybe redirect user to a login page if session is not valid anymore
                    getPublicSession(link, cooky[M.config.session.locale]);
                }

                callback(link);
            });
        }
    }

    getPublicSession(link, cooky[M.config.session.locale]);

    callback(link);
};

// start new Session
// TODO set expire date in cookie header
// and make expire time configurable
function start (link, rid, uid, locale, data, callback) {

    if (typeof data === "function") {
        callback = data;
    }

    if (typeof rid !== 'number' || typeof uid !== 'number' || !locale) {
        return callback(new Error('Invalid arguments.'));
    }

    var session = data.constructor.name === 'Object' ? data : {};
    session._rid = rid,
    session._uid = uid,
    session._loc = locale,
    session._sid = M.util.uid(23),
    session._exp = expire(expire_time)

    startSession(session, function (err) {

		if (err) {
            return callback(err);
        }

        var clonedSession = Session.clone();

        for (var key in session) {
            if (session.hasOwnProperty(key)) {
                clonedSession[key] = session[key];
            }
        }

        link.res.headers['set-cookie'] = [
            M.config.session.id + '=' + session._sid + '; path=/',
            M.config.session.locale + '=' + locale + '; path=/'
        ];

		callback(null, sessionConstructor(session));
	});
};

exports.get = get;
exports.start = start;
exports.public = publicSession;
<commit_msg>added semicolions at end of line, bug<commit_after>var cookie = require('cookie');
var colName = 'sessions';
var expire_time = 168; // one week 7*24

var publicSession = {

    set: function (data, callback) {

        if (data.constructor.name !== 'Object') {
            return callback(new Error('Data must be an object.'))
        }

        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                self[key] = data[key];
            }
        }
        callback();
    },
    end: function (all, callback) {
        if (typeof all === 'function') {
            callback = all;
        }
        callback();
    },
    renew: function (callback) {
        callback();
    }
};

// session class
var Session = {

    set: function(data, callback) {

        if (data.constructor.name !== 'Object') {
            return callback(new Error('Data must be an object.'))
        }

        var self = this;

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            db.collection(colName).update({_sid: self._sid}, {$set: data}, function (err) {

                if (err) {
                    return callback(err);
                }

                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        self[key] = data[key];
                    }
                }

                callback();
            });
        });
    },

    end: function (endAll, callback) {

        if (typeof endAll === 'function') {
            callback = endAll;
            endAll = null;
        }

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            db.collection(colName).remove(
                endAll ? {_uid: this._uid} : {_sid: this._sid},
                callback
            );
        });

    },

    renew: function (callback) {

        var self = this;

        M.mongo.connect(M.config.mongoDB.name, function (err, db) {

            if (err) {
                return callback(err);
            }

            var newSid = M.util.uid(23);

            db.collection(colName).update({_sid: self._sid}, {$set: {_sid: newSid}}, function (err) {

                if (err) {
                    return callback(err);
                }

                self._sid = newSid;

                callback();
            });
        });
    }
};

//------------------------------------------------------------------------------------------

function getSession (sessionId, now, expire, callback) {

    M.mongo.connect(M.config.mongoDB.name, function(err, db) {

        if (err) {
            return callback(err);
        }

        db.collection(colName).findAndModify(
            {_sid: sessionId, _exp: {$gt: now}},
            [],
            {$set: {_exp: expire}},
            {fields: {_id: 0}},
            callback
        );
    });
};

function startSession (session, callback) {

	M.mongo.connect(M.config.mongoDB.name, function(err, db) {

        if (err) {
            return callback(err)
        };

        db.collection(colName).insert(session, {safe: true},  callback);
	});
};

function expire(hoursPlus) {
	return Math.round(new Date().getTime() / 3600000) + (hoursPlus || 0); //86400000 = 1day, 3600000 = 1hour
}

function sessionConstructor (session) {

    var clonedSession = Session.clone();

    for (var key in session) {
        if (session.hasOwnProperty(key)) {
            clonedSession[key] = session[key];
        }
    }

    return clonedSession;
}

function getPublicSession (link, localeFromCookie) {

    link.session = publicSession.clone();
    link.session._rid = M.config.app.publicRole;

    if (localeFromCookie) {
        link.session._loc = localeFromCookie;
    } else {
        link.session._loc = M.config.app.locale || "*";
        link.res.headers['set-cookie'] = M.config.session.locale + '=' + link.session._loc + '; path=/';
    }
}

//------------------------------------------------------------------------------------------

// TODO check in query params for an sid
// TODO check if locale is in url query params
function get (link, callback) {

    var cooky = {};

    if (link.req.headers.cookie) {

        // parse cookie
        cooky = cookie.parse(link.req.headers.cookie);

        // get session and overwrite default session
        if (cooky[M.config.session.id]) {

            return getSession(cooky.sid, expire(), expire(expire_time), function(err, session) {

                if (!err && session) {
                    link.session = sessionConstructor(session);
                } else {
                    // TODO maybe redirect user to a login page if session is not valid anymore
                    getPublicSession(link, cooky[M.config.session.locale]);
                }

                callback(link);
            });
        }
    }

    getPublicSession(link, cooky[M.config.session.locale]);

    callback(link);
};

// start new Session
// TODO set expire date in cookie header
// and make expire time configurable
function start (link, rid, uid, locale, data, callback) {

    if (typeof data === "function") {
        callback = data;
    }

    if (typeof rid !== 'number' || typeof uid !== 'number' || !locale) {
        return callback(new Error('Invalid arguments.'));
    }

    var session = data.constructor.name === 'Object' ? data : {};
    session._rid = rid;
    session._uid = uid;
    session._loc = locale;
    session._sid = M.util.uid(23);
    session._exp = expire(expire_time);

    startSession(session, function (err) {

		if (err) {
            return callback(err);
        }

        var clonedSession = Session.clone();

        for (var key in session) {
            if (session.hasOwnProperty(key)) {
                clonedSession[key] = session[key];
            }
        }

        link.res.headers['set-cookie'] = [
            M.config.session.id + '=' + session._sid + '; path=/',
            M.config.session.locale + '=' + locale + '; path=/'
        ];

		callback(null, sessionConstructor(session));
	});
};

exports.get = get;
exports.start = start;
exports.public = publicSession;
<|endoftext|>


<commit_before>var ChromeDriver = require('./chrome-driver')
var DevNull = require('dev-null')
var fs = require('fs')
var path = require('path')
var WebDriver = require('webdriverio')

function Application (options) {
  options = options || {}
  this.host = options.host || '127.0.0.1'
  this.port = parseInt(options.port, 10) || 9515
  this.quitTimeout = parseInt(options.quitTimeout, 10) || 1000
  this.startTimeout = parseInt(options.startTimeout, 10) || 5000
  this.waitTimeout = parseInt(options.waitTimeout, 10) || 5000
  this.connectionRetryCount = parseInt(options.connectionRetryCount, 10) || 10
  this.connectionRetryTimeout = parseInt(options.connectionRetryTimeout, 10) || 30000
  this.nodePath = options.nodePath || process.execPath

  this.path = options.path
  this.args = options.args || []
  this.env = options.env || {}
  this.workingDirectory = options.cwd || process.cwd()
}

Application.prototype.start = function () {
  var self = this
  return self.exists()
    .then(function () { return self.startChromeDriver() })
    .then(function () { return self.createClient() })
    .then(function () { require('./api').initialize(self) })
    .then(function () { self.running = true })
}

Application.prototype.stop = function () {
  var self = this

  if (!self.isRunning()) return Promise.reject(Error('Application not running'))

  return new Promise(function (resolve, reject) {
    self.client.windowByIndex(0).quitApplication().then(function () {
      setTimeout(function () {
        self.client.end().then(function () {
          self.chromeDriver.stop()
          self.running = false
          resolve()
        }, reject)
      }, self.quitTimeout)
    }, reject)
  })
}

Application.prototype.isRunning = function () {
  return this.running
}

Application.prototype.exists = function () {
  var self = this
  return new Promise(function (resolve, reject) {
    fs.stat(self.path, function (error, stat) {
      if (error) return reject(error)
      if (stat.isFile()) return resolve()
      reject(Error('Application path specified is not a file: ' + self.path))
    })
  })
}

Application.prototype.startChromeDriver = function () {
  this.chromeDriver = new ChromeDriver(this.host, this.port, this.nodePath, this.startTimeout, this.workingDirectory)
  return this.chromeDriver.start()
}

Application.prototype.createClient = function () {
  var self = this
  return new Promise(function (resolve, reject) {
    var args = []
    args.push('spectron-path=' + self.path)
    self.args.forEach(function (arg, index) {
      args.push('spectron-arg' + index + '=' + arg)
    })

    for (var name in self.env) {
      args.push('spectron-env-' + name + '=' + self.env[name])
    }

    var launcherPath = null
    if (process.platform === 'win32') {
      launcherPath = path.join(__dirname, '..', 'bin', 'launcher.exe')
    } else {
      launcherPath = path.join(__dirname, 'launcher.js')
    }

    if (process.env.APPVEYOR) {
      args.push('no-sandbox')
    }

    var options = {
      host: self.host,
      port: self.port,
      waitforTimeout: self.waitTimeout,
      connectionRetryCount: self.connectionRetryCount,
      connectionRetryTimeout: self.connectionRetryTimeout,
      desiredCapabilities: {
        browserName: 'electron',
        chromeOptions: {
          binary: launcherPath,
          args: args
        }
      },
      logOutput: DevNull()
    }

    self.client = WebDriver.remote(options)
    self.addCommands()
    self.initializeClient(resolve, reject)
  })
}

Application.prototype.initializeClient = function (resolve, reject) {
  var maxTries = 10
  var tries = 0
  var self = this
  var init = function () {
    tries++
    self.client.init().then(resolve, function (error) {
      if (tries >= maxTries) {
        error.message = 'Client initialization failed after ' + tries + ' attempts: '
        error.message += error.type + ' ' + error.message
        reject(error)
      } else {
        global.setTimeout(init, 250)
      }
    })
  }
  init()
}

Application.prototype.addCommands = function () {
  // TODO Remove in favor of get/setBounds API
  this.client.addCommand('getWindowDimensions', function () {
    return this.getWindowBounds()
  })
  this.client.addCommand('setWindowDimensions', function (x, y, width, height) {
    return this.setWindowBounds({x: x, y: y, width: width, height: height})
  })

  this.client.addCommand('getWindowWidth', function () {
    return this.getWindowBounds().then(function (bounds) {
      return bounds.width
    })
  })

  this.client.addCommand('getWindowHeight', function () {
    return this.getWindowBounds().then(function (bounds) {
      return bounds.height
    })
  })

  this.client.addCommand('setWindowBounds', function (bounds) {
    return this.execute(function (bounds) {
      require('electron').remote.getCurrentWindow().setBounds(bounds)
    }, bounds)
  })

  this.client.addCommand('waitUntilTextExists', function (selector, text, timeout) {
    return this.waitUntil(function () {
      return this.isExisting(selector).getText(selector).then(function (selectorText) {
        return selectorText.indexOf(text) !== -1
      })
    }, timeout).then(function () { }, function (error) {
      error.message = 'waitUntilTextExists ' + error.message
      return error
    })
  })

  this.client.addCommand('quitApplication', function () {
    return this.execute(function () {
      require('electron').remote.app.quit()
    })
  })

  this.client.addCommand('getAppPath', function (pathName) {
    return this.execute(function (pathName) {
      return require('electron').remote.app.getPath(pathName)
    }, pathName).then(getResponseValue)
  })

  this.client.addCommand('waitUntilWindowLoaded', function (timeout) {
    return this.waitUntil(function () {
      return this.isWindowLoading().then(function (loading) {
        return !loading
      })
    }, timeout).then(function () { }, function (error) {
      error.message = 'waitUntilWindowLoaded ' + error.message
      return error
    })
  })

  this.client.addCommand('getWindowCount', function () {
    return this.windowHandles().then(getResponseValue).then(function (handles) {
      return handles.length
    })
  })

  this.client.addCommand('windowByIndex', function (index) {
    return this.windowHandles().then(getResponseValue).then(function (handles) {
      return this.window(handles[index])
    })
  })

  this.client.addCommand('getSelectedText', function () {
    return this.execute(function () {
      return window.getSelection().toString()
    }).then(getResponseValue)
  })

  this.client.addCommand('getMainProcessGlobal', function (globalName) {
    return this.execute(function (globalName) {
      return require('electron').remote.getGlobal(globalName)
    }, globalName).then(getResponseValue)
  })

  this.client.addCommand('getArgv', function () {
    return this.execute(function () {
      return require('electron').remote.getGlobal('process').argv
    }).then(getResponseValue)
  })

  this.client.addCommand('getCwd', function () {
    return this.execute(function () {
      return require('electron').remote.getGlobal('process').cwd()
    }).then(getResponseValue)
  })

  this.client.addCommand('getClipboardText', function () {
    return this.execute(function () {
      return require('electron').clipboard.readText()
    }).then(getResponseValue)
  })

  this.client.addCommand('setClipboardText', function (text) {
    return this.execute(function (text) {
      return require('electron').clipboard.writeText(text)
    }, text).then(getResponseValue)
  })

  this.client.addCommand('setDocumentEdited', function (edited) {
    return this.execute(function (edited) {
      return require('electron').remote.getCurrentWindow().setDocumentEdited(edited)
    }, edited).then(getResponseValue)
  })

  this.client.addCommand('setRepresentedFilename', function (filename) {
    return this.execute(function (filename) {
      return require('electron').remote.getCurrentWindow().setRepresentedFilename(filename)
    }, filename).then(getResponseValue)
  })

  this.client.addCommand('getRenderProcessLogs', function () {
    return this.log('browser').then(getResponseValue)
  })

  var self = this
  this.client.addCommand('getMainProcessLogs', function () {
    var logs = self.chromeDriver.getLogs()
    self.chromeDriver.clearLogs()
    return logs
  })

  this.client.addCommand('isWindowLoading', function () {
    return this.execute(function () {
      return require('electron').remote.getCurrentWindow().webContents.isLoading()
    }).then(getResponseValue)
  })

  this.addCurrentWindowGetter('getBounds', 'getWindowBounds')
  this.addCurrentWindowGetter('isDevToolsOpened', 'isWindowDevToolsOpened')
  this.addCurrentWindowGetter('isFocused', 'isWindowFocused')
  this.addCurrentWindowGetter('isFullScreen', 'isWindowFullScreen')
  this.addCurrentWindowGetter('isMaximized', 'isWindowMaximized')
  this.addCurrentWindowGetter('isMinimized', 'isWindowMinimized')
  this.addCurrentWindowGetter('isVisible', 'isWindowVisible')

  this.addCurrentWindowGetter('hide', 'hideWindow')
  this.addCurrentWindowGetter('maximize', 'maximizeWindow')
  this.addCurrentWindowGetter('minimize', 'minimizeWindow')
  this.addCurrentWindowGetter('show', 'showWindow')

  this.addCurrentWindowGetter('selectAll', 'selectAll')
  this.addCurrentWindowGetter('paste', 'paste')

  this.addCurrentWindowGetter('isDocumentEdited', 'isDocumentEdited')
  this.addCurrentWindowGetter('getRepresentedFilename', 'getRepresentedFilename')
}

Application.prototype.addCurrentWindowGetter = function (methodName, commandName) {
  if (!commandName) commandName = methodName

  var currentWindowGetter = function (methodName) {
    return require('electron').remote.getCurrentWindow()[methodName]()
  }

  this.client.addCommand(commandName, function () {
    return this.execute(currentWindowGetter, methodName).then(getResponseValue)
  })
}

var getResponseValue = function (response) {
  return response.value
}

module.exports = Application
<commit_msg>Return initialize promise<commit_after>var api = require('./api')
var ChromeDriver = require('./chrome-driver')
var DevNull = require('dev-null')
var fs = require('fs')
var path = require('path')
var WebDriver = require('webdriverio')

function Application (options) {
  options = options || {}
  this.host = options.host || '127.0.0.1'
  this.port = parseInt(options.port, 10) || 9515
  this.quitTimeout = parseInt(options.quitTimeout, 10) || 1000
  this.startTimeout = parseInt(options.startTimeout, 10) || 5000
  this.waitTimeout = parseInt(options.waitTimeout, 10) || 5000
  this.connectionRetryCount = parseInt(options.connectionRetryCount, 10) || 10
  this.connectionRetryTimeout = parseInt(options.connectionRetryTimeout, 10) || 30000
  this.nodePath = options.nodePath || process.execPath

  this.path = options.path
  this.args = options.args || []
  this.env = options.env || {}
  this.workingDirectory = options.cwd || process.cwd()
}

Application.prototype.start = function () {
  var self = this
  return self.exists()
    .then(function () { return self.startChromeDriver() })
    .then(function () { return self.createClient() })
    .then(function () { return api.initialize(self) })
    .then(function () { self.running = true })
}

Application.prototype.stop = function () {
  var self = this

  if (!self.isRunning()) return Promise.reject(Error('Application not running'))

  return new Promise(function (resolve, reject) {
    self.client.windowByIndex(0).quitApplication().then(function () {
      setTimeout(function () {
        self.client.end().then(function () {
          self.chromeDriver.stop()
          self.running = false
          resolve()
        }, reject)
      }, self.quitTimeout)
    }, reject)
  })
}

Application.prototype.isRunning = function () {
  return this.running
}

Application.prototype.exists = function () {
  var self = this
  return new Promise(function (resolve, reject) {
    fs.stat(self.path, function (error, stat) {
      if (error) return reject(error)
      if (stat.isFile()) return resolve()
      reject(Error('Application path specified is not a file: ' + self.path))
    })
  })
}

Application.prototype.startChromeDriver = function () {
  this.chromeDriver = new ChromeDriver(this.host, this.port, this.nodePath, this.startTimeout, this.workingDirectory)
  return this.chromeDriver.start()
}

Application.prototype.createClient = function () {
  var self = this
  return new Promise(function (resolve, reject) {
    var args = []
    args.push('spectron-path=' + self.path)
    self.args.forEach(function (arg, index) {
      args.push('spectron-arg' + index + '=' + arg)
    })

    for (var name in self.env) {
      args.push('spectron-env-' + name + '=' + self.env[name])
    }

    var launcherPath = null
    if (process.platform === 'win32') {
      launcherPath = path.join(__dirname, '..', 'bin', 'launcher.exe')
    } else {
      launcherPath = path.join(__dirname, 'launcher.js')
    }

    if (process.env.APPVEYOR) {
      args.push('no-sandbox')
    }

    var options = {
      host: self.host,
      port: self.port,
      waitforTimeout: self.waitTimeout,
      connectionRetryCount: self.connectionRetryCount,
      connectionRetryTimeout: self.connectionRetryTimeout,
      desiredCapabilities: {
        browserName: 'electron',
        chromeOptions: {
          binary: launcherPath,
          args: args
        }
      },
      logOutput: DevNull()
    }

    self.client = WebDriver.remote(options)
    self.addCommands()
    self.initializeClient(resolve, reject)
  })
}

Application.prototype.initializeClient = function (resolve, reject) {
  var maxTries = 10
  var tries = 0
  var self = this
  var init = function () {
    tries++
    self.client.init().then(resolve, function (error) {
      if (tries >= maxTries) {
        error.message = 'Client initialization failed after ' + tries + ' attempts: '
        error.message += error.type + ' ' + error.message
        reject(error)
      } else {
        global.setTimeout(init, 250)
      }
    })
  }
  init()
}

Application.prototype.addCommands = function () {
  // TODO Remove in favor of get/setBounds API
  this.client.addCommand('getWindowDimensions', function () {
    return this.getWindowBounds()
  })
  this.client.addCommand('setWindowDimensions', function (x, y, width, height) {
    return this.setWindowBounds({x: x, y: y, width: width, height: height})
  })

  this.client.addCommand('getWindowWidth', function () {
    return this.getWindowBounds().then(function (bounds) {
      return bounds.width
    })
  })

  this.client.addCommand('getWindowHeight', function () {
    return this.getWindowBounds().then(function (bounds) {
      return bounds.height
    })
  })

  this.client.addCommand('setWindowBounds', function (bounds) {
    return this.execute(function (bounds) {
      require('electron').remote.getCurrentWindow().setBounds(bounds)
    }, bounds)
  })

  this.client.addCommand('waitUntilTextExists', function (selector, text, timeout) {
    return this.waitUntil(function () {
      return this.isExisting(selector).getText(selector).then(function (selectorText) {
        return selectorText.indexOf(text) !== -1
      })
    }, timeout).then(function () { }, function (error) {
      error.message = 'waitUntilTextExists ' + error.message
      return error
    })
  })

  this.client.addCommand('quitApplication', function () {
    return this.execute(function () {
      require('electron').remote.app.quit()
    })
  })

  this.client.addCommand('getAppPath', function (pathName) {
    return this.execute(function (pathName) {
      return require('electron').remote.app.getPath(pathName)
    }, pathName).then(getResponseValue)
  })

  this.client.addCommand('waitUntilWindowLoaded', function (timeout) {
    return this.waitUntil(function () {
      return this.isWindowLoading().then(function (loading) {
        return !loading
      })
    }, timeout).then(function () { }, function (error) {
      error.message = 'waitUntilWindowLoaded ' + error.message
      return error
    })
  })

  this.client.addCommand('getWindowCount', function () {
    return this.windowHandles().then(getResponseValue).then(function (handles) {
      return handles.length
    })
  })

  this.client.addCommand('windowByIndex', function (index) {
    return this.windowHandles().then(getResponseValue).then(function (handles) {
      return this.window(handles[index])
    })
  })

  this.client.addCommand('getSelectedText', function () {
    return this.execute(function () {
      return window.getSelection().toString()
    }).then(getResponseValue)
  })

  this.client.addCommand('getMainProcessGlobal', function (globalName) {
    return this.execute(function (globalName) {
      return require('electron').remote.getGlobal(globalName)
    }, globalName).then(getResponseValue)
  })

  this.client.addCommand('getArgv', function () {
    return this.execute(function () {
      return require('electron').remote.getGlobal('process').argv
    }).then(getResponseValue)
  })

  this.client.addCommand('getCwd', function () {
    return this.execute(function () {
      return require('electron').remote.getGlobal('process').cwd()
    }).then(getResponseValue)
  })

  this.client.addCommand('getClipboardText', function () {
    return this.execute(function () {
      return require('electron').clipboard.readText()
    }).then(getResponseValue)
  })

  this.client.addCommand('setClipboardText', function (text) {
    return this.execute(function (text) {
      return require('electron').clipboard.writeText(text)
    }, text).then(getResponseValue)
  })

  this.client.addCommand('setDocumentEdited', function (edited) {
    return this.execute(function (edited) {
      return require('electron').remote.getCurrentWindow().setDocumentEdited(edited)
    }, edited).then(getResponseValue)
  })

  this.client.addCommand('setRepresentedFilename', function (filename) {
    return this.execute(function (filename) {
      return require('electron').remote.getCurrentWindow().setRepresentedFilename(filename)
    }, filename).then(getResponseValue)
  })

  this.client.addCommand('getRenderProcessLogs', function () {
    return this.log('browser').then(getResponseValue)
  })

  var self = this
  this.client.addCommand('getMainProcessLogs', function () {
    var logs = self.chromeDriver.getLogs()
    self.chromeDriver.clearLogs()
    return logs
  })

  this.client.addCommand('isWindowLoading', function () {
    return this.execute(function () {
      return require('electron').remote.getCurrentWindow().webContents.isLoading()
    }).then(getResponseValue)
  })

  this.addCurrentWindowGetter('getBounds', 'getWindowBounds')
  this.addCurrentWindowGetter('isDevToolsOpened', 'isWindowDevToolsOpened')
  this.addCurrentWindowGetter('isFocused', 'isWindowFocused')
  this.addCurrentWindowGetter('isFullScreen', 'isWindowFullScreen')
  this.addCurrentWindowGetter('isMaximized', 'isWindowMaximized')
  this.addCurrentWindowGetter('isMinimized', 'isWindowMinimized')
  this.addCurrentWindowGetter('isVisible', 'isWindowVisible')

  this.addCurrentWindowGetter('hide', 'hideWindow')
  this.addCurrentWindowGetter('maximize', 'maximizeWindow')
  this.addCurrentWindowGetter('minimize', 'minimizeWindow')
  this.addCurrentWindowGetter('show', 'showWindow')

  this.addCurrentWindowGetter('selectAll', 'selectAll')
  this.addCurrentWindowGetter('paste', 'paste')

  this.addCurrentWindowGetter('isDocumentEdited', 'isDocumentEdited')
  this.addCurrentWindowGetter('getRepresentedFilename', 'getRepresentedFilename')
}

Application.prototype.addCurrentWindowGetter = function (methodName, commandName) {
  if (!commandName) commandName = methodName

  var currentWindowGetter = function (methodName) {
    return require('electron').remote.getCurrentWindow()[methodName]()
  }

  this.client.addCommand(commandName, function () {
    return this.execute(currentWindowGetter, methodName).then(getResponseValue)
  })
}

var getResponseValue = function (response) {
  return response.value
}

module.exports = Application
<|endoftext|>