Skip to content

Instantly share code, notes, and snippets.

@trevorhreed
Last active January 14, 2022 21:15
Show Gist options
  • Save trevorhreed/a7637cef3defa8d698bb87e25e7577f3 to your computer and use it in GitHub Desktop.
Save trevorhreed/a7637cef3defa8d698bb87e25e7577f3 to your computer and use it in GitHub Desktop.
getFnParams: takes a function and returns the names of that function's parameters as an array
const fnParamsRe = /^(?:async)?\s*(?:(?:function\s+[a-zA-Z_][a-zA-Z0-9_]*|function|[a-zA-Z_][a-zA-Z0-9_]*)\s*(?:\(([^)]*)\))|(?:\(([^)]*)\)|([a-zA-Z_][a-zA-Z0-9_]*))\s*=>\s*{)/
const sepRe = /\s*,\s*/g
const getFnParams = fn => {
const source = fn.toString()
const match = fnParamsRe.exec(source) || []
const paramStr = match[1] || match[2] || match[3] || ''
return paramStr.split(sepRe).filter(Boolean)
}
(() => {
// function
function f1(param) { }
function f2(p1, p2) { }
async function f3(p1, p2) { }
// arrow
const a1 = param => { }
const a2 = (p1, p2) => { }
const a3 = async param => { }
const a4 = async (p1, p2) => { }
// member
const obj = {
m1(p1, p2) { },
async m2(p1, p2) { },
m3: function (p1, p2) { },
m4: async function (p1, p2) { },
m5: param => { },
m6: async param => { },
m7: (p1, p2) => { },
m8: async (p1, p2) => { },
}
const testFns = [
// function
f1, f2, f3, function (p1, p2) { },
// arrow
a1, a2, a3, a4, param => { }, (p1, p2) => { },
// member
obj.m1, obj.m2, obj.m3, obj.m4, obj.m5, obj.m6, obj.m7
]
const testParams = [
// function
['param'],
['p1', 'p2'],
['p1', 'p2'],
['p1', 'p2'],
// arrow
['param'],
['p1', 'p2'],
['param'],
['p1', 'p2'],
['param'],
['p1', 'p2'],
// member
['p1', 'p2'],
['p1', 'p2'],
['p1', 'p2'],
['p1', 'p2'],
['param'],
['param'],
['p1', 'p2'],
['p1', 'p2']
]
const arrsAreEqual = (a1, a2) => {
if (a1.length !== a2.length) return false
for (let i = 0, l = a1.length; i < l; i++) {
if (a1[i] !== a2[i]) return false
}
return true
}
let failCount = 0
for (let i = 0, l = testFns.length; i < l; i++) {
const testFn = testFns[i]
const expected = testParams[i]
const actual = getFnParams(testFn)
const passed = arrsAreEqual(expected, actual)
if (!passed) {
failCount++
console.log(` #${i.toString().padStart(8)}failed: ${testFn.toString()}`)
}
}
if (failCount) {
const rate = Math.round(failCount / testFns.length * 100)
const red = '\x1b[31m'
const reset = '\x1b[0m'
console.log(`${red}\n${failCount} failed tests (${rate}%).${reset}`)
} else {
console.log(`\nAll tests passed.`)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment