<commit_before>import { appContext } from './appContext'


let recursiveDepth = 0

/*
Add to appContext for func and clean it up at the end

Arguments are: ([context,] func)

Context is optional, so you can just pass: (func)

Note: this can't be called wrapping a 'describe' function. It only works on 'it'.
 */
const clearAppContext = () => {
  Object.keys(appContext).forEach((key) => {
    delete appContext[key]
  })
}

export default (...contextAndFunc) =>
  async () => {
    if (recursiveDepth === 0) {
      const existingKeys = Object.keys(appContext)
      if (existingKeys.length) {
        clearAppContext()
        throw new Error(
          `appContext appears to have objects leftover from a previous test: ${existingKeys}\n` +
          'Did you forget to use mockAppContext() around code that modified the context?'
        )
      }
    }
    const [contextObjOrFunc, func] = (contextAndFunc.length <= 1) ?
      [{}, ...contextAndFunc] :
      contextAndFunc
    const originalAppContext = { ...appContext }
    recursiveDepth += 1
    try {
      const context = (typeof contextObjOrFunc === 'function') ? contextObjOrFunc() : contextObjOrFunc
      if (context) {
        Object.assign(appContext, context)
      }
      return await func(appContext)
    } finally {
      recursiveDepth -= 1
      clearAppContext()
      Object.assign(appContext, originalAppContext)
    }
  }<commit_msg>contextFunc passed to mockAppContext can be async<commit_after>import { appContext } from './appContext'


let recursiveDepth = 0

/*
Add to appContext for func and clean it up at the end

Arguments are: ([context,] func)

Context is optional, so you can just pass: (func)

Note: this can't be called wrapping a 'describe' function. It only works on 'it'.
 */
const clearAppContext = () => {
  Object.keys(appContext).forEach((key) => {
    delete appContext[key]
  })
}

// @params: (contextGeneratingFunc | contextObj)?, testFunc
// Most commonly generate the context using a function. It can either return the context object
// directly or use initModules internally.
export default (...contextAndFunc) =>
  async () => {
    if (recursiveDepth === 0) {
      const existingKeys = Object.keys(appContext)
      if (existingKeys.length) {
        clearAppContext()
        throw new Error(
          `appContext appears to have objects leftover from a previous test: ${existingKeys}\n` +
          'Did you forget to use mockAppContext() around code that modified the context?'
        )
      }
    }
    const [contextObjOrFunc, testFunc] = (contextAndFunc.length <= 1) ?
      [{}, ...contextAndFunc] :
      contextAndFunc
    const originalAppContext = { ...appContext }
    recursiveDepth += 1
    try {
      const context = (typeof contextObjOrFunc === 'function') ? await contextObjOrFunc() : contextObjOrFunc
      if (context) {
        Object.assign(appContext, context)
      }
      return await testFunc(appContext)
    } finally {
      recursiveDepth -= 1
      clearAppContext()
      Object.assign(appContext, originalAppContext)
    }
  }

{'fraction_non_alphanumeric': 0.10904947916666667, 'fraction_numerical': 0.0032552083333333335, 'mean_word_length': 2.9346991037131884, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1267618', 'n_tokens_mistral': 881, 'n_tokens_neox': 851, 'n_words': 277}