const methods = require('./methods.json')

module.exports = (tape, executeFunctions) => (opt1, opt2, cb) => {
  cb = cb || opt2 || opt1 // `opt1` and/or `opt2` could be missing

  tape(opt1, opt2, t => {
    methods.forEach(name => attachMethod(t, name, executeFunctions))
    cb(t) // hand t over to the actual test
  })
}

function attachMethod (t, name, executeFunctions) {
  var tryToExecute = noop => noop
  if (executeFunctions) tryToExecute = (t, arg) => (typeof arg === 'function') ? arg(t) : arg

  String.prototype[name] = function (arg1, arg2) { // eslint-disable-line
    var arity = arguments.length
    if (arity === 2) {
      arg2 = tryToExecute(t, arg2)
      t[name](arg1, arg2, this)
      return
    }
    if (arity === 1) {
      arg1 = tryToExecute(t, arg1)
      t[name](arg1, this)
      return
    }
    t[name](this)
  }
}

@@ -238,19 +238,16 @@
 hMethod(
-t, 
 name, ex
@@ -260,16 +260,19 @@
 unctions
+, t
 ))%0A    c
@@ -341,19 +341,16 @@
 Method (
-t, 
 name, ex
@@ -363,16 +363,19 @@
 unctions
+, t
 ) %7B%0A  va
@@ -539,23 +539,23 @@
 ion (arg
-1
+0
 , arg
-2
+1
 ) %7B // e
@@ -638,17 +638,17 @@
      arg
-2
+1
  = tryTo
@@ -659,23 +659,23 @@
 ute(
-t, arg2
+arg1, t
 )%0A      
 t%5Bna
@@ -662,32 +662,39 @@
 (arg1, t)%0A      
+return 
 t%5Bname%5D(arg1, ar
@@ -692,23 +692,23 @@
 (arg
-1
+0
 , arg
-2
+1
 , this)%0A
     
@@ -699,37 +699,24 @@
 arg1, this)%0A
-      return%0A
     %7D%0A    if
@@ -733,33 +733,33 @@
 = 1) %7B%0A      arg
-1
+0
  = tryToExecute(
@@ -762,23 +762,23 @@
 ute(
-t, arg1
+arg0, t
 )%0A      
 t%5Bna
@@ -769,24 +769,31 @@
 0, t)%0A      
+return 
 t%5Bname%5D(arg1
@@ -791,17 +791,17 @@
 ame%5D(arg
-1
+0
 , this)%0A
@@ -798,24 +798,28 @@
 g0, this)%0A  
+  %7D%0A
     return%0A 
@@ -816,26 +816,16 @@
   return
-%0A    %7D%0A   
  t%5Bname%5D

return func result; don't eat arguments