Skip to content

Instantly share code, notes, and snippets.

@Ramblurr
Created April 15, 2025 11:08
Show Gist options
  • Save Ramblurr/27e196c4a170c761410b77f7eeee621b to your computer and use it in GitHub Desktop.
Save Ramblurr/27e196c4a170c761410b77f7eeee621b to your computer and use it in GitHub Desktop.
const pattern = /\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;)\{]*)\s*\)\s*\(\s*\)/g;
const showPassed = false;
const test = (input, expected) => {
const actual = input.match(pattern) || [];
const passed = JSON.stringify(actual) === JSON.stringify(expected);
if(showPassed || !passed) {
console.log(passed ? 'PASSED' : 'FAILED');
console.log(`Input:${input}`);
console.log(`Expected: ${JSON.stringify(expected)}`);
console.log(`Actual: ${JSON.stringify(actual)}`);
console.log('-'.repeat(50));
}
return passed;
};
const testCases = [
{
input: `(()=>{})()`,
expected:[`(()=>{})()`]
},
{
input: `( ( )=>{})()`,
expected:[`( ( )=>{})()`]
},
{
input: `(function() {})()`,
expected:[`(function() {})()`]
},
{
input: `(function( ) { })( )`,
expected:[`(function( ) { })( )`]
},
{
input: `const x = 5; (function() { return 10; })(); const y = 20;`,
expected: [`(function() { return 10; })()`]
},
{
input: `let a = 1; (() => { console.log('arrow'); })(); let b = 2;`,
expected: [`(() => { console.log('arrow'); })()`]
},
{
// multiple but non-nested IIFEs in one string
input: `
(function() { return 'first'; })();
(() => { return 'second'; })();`,
expected: [
`(function() { return 'first'; })()`,
`(() => { return 'second'; })()`
]
},
{
input: `(() => 'simple return')();`,
expected: [`(() => 'simple return')()`]
},
{
input: `(() => { if (foo) { return 1; } else { return ({a,b,c}); }})();`,
expected: [`(() => { if (foo) { return 1; } else { return ({a,b,c}); }})()`]
},
{ input: `(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`,
expected: [`(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`]
},
{ input: `$my-signal = "bar"; (() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`,
expected: [`(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`]
},
{ input: `$my-signal = "bar" && ( (() => { const foo1 = $my-signal; return foo1.toUpperCase(); })())`,
expected: [`(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`]
},
{ input: `$my-signal = "bar" && ()=>{} && (() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`,
expected: [`(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`]
},
{ input: `$my-signal = "bar" && ( (()=>{})() && ((function () {})()) || (() => { const foo1 = $my-signal; return foo1.toUpperCase(); })())`,
expected: [`(()=>{})()`, `(function () {})()`, `(() => { const foo1 = $my-signal; return foo1.toUpperCase(); })()`]
},
// -- These should not parse
{
input: `function regular() { return 'just a func'; }`,
expected: []
},
{
input: `(()=>{})`,
expected:[]
},
{
input: `(()=>{})(`,
expected:[]
},
{
input: `( ) => { }`,
expected:[]
},
{
input: `function() {}`,
expected:[]
},
{
input: `(function() {})`,
expected:[]
},
{
input: `(async function(){})()`, // technically a valid iife, but i dont want to support async
expected:[]
},
{
input: `((a,b)=>{})(1,2)`,
expected: []
},
{
//no args
input: `
((x, y) => {
return x + y;
})(5, 10);`,
expected: []
},
{
input: `
(function(outer) {
console.log('Outer param: ' + outer);
((inner) => {
console.log('Inner param: ' + inner);
})('nested value');
})('outer value');`,
expected: []
}
];
const run = () => {
let passedCount = 0;
let totalTests = testCases.length;
testCases.forEach(t => {
passedCount += test(t.input, t.expected) ? 1 : 0;
});
console.log()
console.log(`${passedCount}/${totalTests} passed`);
if(passedCount !== totalTests) process.exit(1);
};
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment