{"version":3,"file":"testUtils.umd.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","teardown","undefined","result","Promise","resolve","flush","toFlush","previousRequestAnimationFrame","requestAnimationFrame","rerender","fc","err","finish","e"],"mappings":"2NAMO,SAASA,WACfC,UAAQC,EAA2BD,UAAQE,kBAC3CF,UAAQE,kBAAoB,SAAAC,UAAOH,UAAQI,EAAqBD,GACzD,kBAAMH,UAAQI,GAAsBJ,UAAQI,KAGpD,IAAMC,EAAa,SAAAC,UAAkB,MAATA,GAAsC,mBAAdA,EAAMC,MAGtDC,EAAW,EAwFR,SAASC,IACXT,UAAQI,IAEXJ,UAAQI,WACDJ,UAAQI,QAG+B,IAApCJ,UAAQC,GAClBD,UAAQE,kBAAoBF,UAAQC,SAC7BD,UAAQC,GAEfD,UAAQE,uBAAoBQ,0BAxFvB,SAAaP,QACbK,EAAW,EAAG,KAObG,EAASR,WACXE,EAAWM,GACPA,EAAOJ,KAAK,aAChBC,OAGFA,EACKI,QAAQC,eAOZC,EAAOC,EAJLC,EAAgChB,UAAQiB,sBACxCC,EAAWnB,IAMjBC,UAAQiB,sBAAwB,SAAAE,UAAOL,EAAQK,OAuB3CC,EACAT,EAtBEU,EAAS,mBAEbH,IACOJ,GACNC,EAAUD,EACVA,EAAQ,KAERC,IACAG,IAEDT,IACC,MAAOa,GACHF,IACJA,EAAME,GAIRtB,UAAQiB,sBAAwBD,IAC9BR,OAOFG,EAASR,IACR,MAAOmB,GACRF,EAAME,KAGHjB,EAAWM,UACPA,EAAOJ,KAAKc,EAAQ,SAAAD,SAC1BC,IACMD,OAORC,IACID,QACGA,SAEAR,QAAQC"}