{"version":3,"file":"testUtils.module.js","sources":["../src/index.js"],"sourcesContent":["import { options } from 'preact';\r\n\r\n/**\r\n * Setup a rerender function that will drain the queue of pending renders\r\n * @returns {() => void}\r\n */\r\nexport function setupRerender() {\r\n\toptions.__test__previousDebounce = options.debounceRendering;\r\n\toptions.debounceRendering = cb => (options.__test__drainQueue = cb);\r\n\treturn () => options.__test__drainQueue && options.__test__drainQueue();\r\n}\r\n\r\nconst isThenable = value => value != null && typeof value.then == 'function';\r\n\r\n/** Depth of nested calls to `act`. */\r\nlet actDepth = 0;\r\n\r\n/**\r\n * Run a test function, and flush all effects and rerenders after invoking it.\r\n *\r\n * Returns a Promise which resolves \"immediately\" if the callback is\r\n * synchronous or when the callback's result resolves if it is asynchronous.\r\n *\r\n * @param {() => void|Promise} cb The function under test. This may be sync or async.\r\n * @return {Promise}\r\n */\r\nexport function act(cb) {\r\n\tif (++actDepth > 1) {\r\n\t\t// If calls to `act` are nested, a flush happens only when the\r\n\t\t// outermost call returns. In the inner call, we just execute the\r\n\t\t// callback and return since the infrastructure for flushing has already\r\n\t\t// been set up.\r\n\t\t//\r\n\t\t// If an exception occurs, the outermost `act` will handle cleanup.\r\n\t\tconst result = cb();\r\n\t\tif (isThenable(result)) {\r\n\t\t\treturn result.then(() => {\r\n\t\t\t\t--actDepth;\r\n\t\t\t});\r\n\t\t}\r\n\t\t--actDepth;\r\n\t\treturn Promise.resolve();\r\n\t}\r\n\r\n\tconst previousRequestAnimationFrame = options.requestAnimationFrame;\r\n\tconst rerender = setupRerender();\r\n\r\n\t/** @type {() => void} */\r\n\tlet flush, toFlush;\r\n\r\n\t// Override requestAnimationFrame so we can flush pending hooks.\r\n\toptions.requestAnimationFrame = fc => (flush = fc);\r\n\r\n\tconst finish = () => {\r\n\t\ttry {\r\n\t\t\trerender();\r\n\t\t\twhile (flush) {\r\n\t\t\t\ttoFlush = flush;\r\n\t\t\t\tflush = null;\r\n\r\n\t\t\t\ttoFlush();\r\n\t\t\t\trerender();\r\n\t\t\t}\r\n\t\t\tteardown();\r\n\t\t} catch (e) {\r\n\t\t\tif (!err) {\r\n\t\t\t\terr = e;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\toptions.requestAnimationFrame = previousRequestAnimationFrame;\r\n\t\t--actDepth;\r\n\t};\r\n\r\n\tlet err;\r\n\tlet result;\r\n\r\n\ttry {\r\n\t\tresult = cb();\r\n\t} catch (e) {\r\n\t\terr = e;\r\n\t}\r\n\r\n\tif (isThenable(result)) {\r\n\t\treturn result.then(finish, err => {\r\n\t\t\tfinish();\r\n\t\t\tthrow err;\r\n\t\t});\r\n\t}\r\n\r\n\t// nb. If the callback is synchronous, effects must be flushed before\r\n\t// `act` returns, so that the caller does not have to await the result,\r\n\t// even though React recommends this.\r\n\tfinish();\r\n\tif (err) {\r\n\t\tthrow err;\r\n\t}\r\n\treturn Promise.resolve();\r\n}\r\n\r\n/**\r\n * Teardown test environment and reset preact's internal state\r\n */\r\nexport function teardown() {\r\n\tif (options.__test__drainQueue) {\r\n\t\t// Flush any pending updates leftover by test\r\n\t\toptions.__test__drainQueue();\r\n\t\tdelete options.__test__drainQueue;\r\n\t}\r\n\r\n\tif (typeof options.__test__previousDebounce != 'undefined') {\r\n\t\toptions.debounceRendering = options.__test__previousDebounce;\r\n\t\tdelete options.__test__previousDebounce;\r\n\t} else {\r\n\t\toptions.debounceRendering = undefined;\r\n\t}\r\n}\r\n"],"names":["setupRerender","options","__test__previousDebounce","debounceRendering","cb","__test__drainQueue","isThenable","value","then","actDepth","act","result","Promise","resolve","flush","toFlush","previousRequestAnimationFrame","requestAnimationFrame","rerender","fc","err","finish","teardown","e","undefined"],"mappings":"iCAMA,SAAgBA,WACfC,EAAQC,EAA2BD,EAAQE,kBAC3CF,EAAQE,kBAAoB,SAAAC,UAAOH,EAAQI,EAAqBD,GACzD,kBAAMH,EAAQI,GAAsBJ,EAAQI,KAGpD,IAAMC,EAAa,SAAAC,UAAkB,MAATA,GAAsC,mBAAdA,EAAMC,MAGtDC,EAAW,EAWR,SAASC,EAAIN,QACbK,EAAW,EAAG,KAObE,EAASP,WACXE,EAAWK,GACPA,EAAOH,KAAK,aAChBC,OAGFA,EACKG,QAAQC,eAOZC,EAAOC,EAJLC,EAAgCf,EAAQgB,sBACxCC,EAAWlB,IAMjBC,EAAQgB,sBAAwB,SAAAE,UAAOL,EAAQK,OAuB3CC,EACAT,EAtBEU,EAAS,mBAEbH,IACOJ,GACNC,EAAUD,EACVA,EAAQ,KAERC,IACAG,IAEDI,IACC,MAAOC,GACHH,IACJA,EAAMG,GAIRtB,EAAQgB,sBAAwBD,IAC9BP,OAOFE,EAASP,IACR,MAAOmB,GACRH,EAAMG,KAGHjB,EAAWK,UACPA,EAAOH,KAAKa,EAAQ,SAAAD,SAC1BC,IACMD,OAORC,IACID,QACGA,SAEAR,QAAQC,UAMhB,SAAgBS,IACXrB,EAAQI,IAEXJ,EAAQI,WACDJ,EAAQI,QAG+B,IAApCJ,EAAQC,GAClBD,EAAQE,kBAAoBF,EAAQC,SAC7BD,EAAQC,GAEfD,EAAQE,uBAAoBqB"}