How to use @redux-saga/is - 10 common examples

To help you get started, we’ve selected a few @redux-saga/is examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github redux-saga / redux-saga / packages / core / __tests__ / interpreter / base.js View on Github external
test('saga iteration', () => {
  let actual = []
  const middleware = sagaMiddleware()
  createStore(() => ({}), {}, applyMiddleware(middleware))

  function* genFn() {
    actual.push(yield 1)
    actual.push(yield 2)
    return 3
  }

  const task = middleware.run(genFn) // saga should return a promise of the iterator result

  expect(is.promise(task.toPromise())).toBe(true)
  return task.toPromise().then(res => {
    // saga's iterator should return false from isRunning()
    expect(task.isRunning()).toBe(false) // saga returned promise should resolve with the iterator return value

    expect(res).toBe(3) // saga should collect yielded values from the iterator

    expect(actual).toEqual([1, 2])
  })
})
test('saga error handling', () => {
github jfairbank / redux-saga-test-plan / src / expectSaga / index.js View on Github external
if (providedValue !== value) {
          return providedValue;
        }

        // Because we manually consume the `call`, we need to manually store
        // the effect, so assertions on the `call` work.
        processEffect({
          effectId: nextSagaId(),
          effect: value,
        });

        const { context, fn, args } = effect;
        const result = fn.apply(context, args);

        if (is.iterator(result)) {
          return call(defaultSagaWrapper, result, refineYieldedValue);
        }

        return result;
      }

      // Ensure we wrap yielded iterators (i.e. `yield someInnerSaga()`) for
      // providers to work.
      case is.iterator(value):
        return useProvidedValue(defaultSagaWrapper(value, refineYieldedValue));

      default:
        return useProvidedValue(value);
    }
  }
github redux-saga / redux-saga / packages / core / __tests__ / middleware.js View on Github external
actual = args
  }

  const middleware = sagaMiddleware()

  try {
    middleware.run(function*() {})
  } catch (e) {
    // middleware.run must throw an Error when executed before the middleware is connected to a Store
    expect(e instanceof Error).toBe(true)
  }

  createStore(() => {}, applyMiddleware(middleware))
  const task = middleware.run(saga, 'argument') // middleware.run must return a Task Object

  expect(is.task(task)).toBe(true)
  const expected = ['argument'] // middleware must run the Saga and provides it with the given arguments

  expect(actual).toEqual(expected)
})
github redux-saga / redux-saga / packages / core / src / internal / matcher.js View on Github external
export default function matcher(pattern) {
  // prettier-ignore
  const matcherCreator = (
      pattern === '*'            ? wildcard
    : is.string(pattern)         ? string
    : is.array(pattern)          ? array
    : is.stringableFunc(pattern) ? string
    : is.func(pattern)           ? predicate
    : is.symbol(pattern)         ? symbol
    : null
  )

  if (matcherCreator === null) {
    throw new Error(`invalid pattern: ${pattern}`)
  }

  return matcherCreator(pattern)
}
github redux-saga / redux-saga / packages / core / src / internal / proc.js View on Github external
- By cancelling the parent task manually
          - By joining a Cancelled task
        **/
        mainTask.status = CANCELLED
        /**
          Cancels the current effect; this will propagate the cancellation down to any called tasks
        **/
        next.cancel()
        /**
          If this Generator has a `return` method then invokes it
          This will jump to the finally block
        **/
        result = is.func(iterator.return) ? iterator.return(TASK_CANCEL) : { done: true, value: TASK_CANCEL }
      } else if (shouldTerminate(arg)) {
        // We get TERMINATE flag, i.e. by taking from a channel that ended using `take` (and not `takem` used to trap End of channels)
        result = is.func(iterator.return) ? iterator.return() : { done: true }
      } else {
        result = iterator.next(arg)
      }

      if (!result.done) {
        digestEffect(result.value, parentEffectId, next)
      } else {
        /**
          This Generator has ended, terminate the main task and notify the fork queue
        **/
        if (mainTask.status !== CANCELLED) {
          mainTask.status = DONE
        }
        mainTask.cont(result.value)
      }
    } catch (error) {
github redux-saga / redux-saga / packages / core / src / internal / effectRunnerMap.js View on Github external
function runCancelEffect(env, taskOrTasks, cb, { task }) {
  if (taskOrTasks === SELF_CANCELLATION) {
    cancelSingleTask(task)
  } else if (is.array(taskOrTasks)) {
    taskOrTasks.forEach(cancelSingleTask)
  } else {
    cancelSingleTask(taskOrTasks)
  }
  cb()
  // cancel effects are non cancellables
}
github redux-saga / redux-saga / packages / core / src / internal / matcher.js View on Github external
export default function matcher(pattern) {
  // prettier-ignore
  const matcherCreator = (
      pattern === '*'            ? wildcard
    : is.string(pattern)         ? string
    : is.array(pattern)          ? array
    : is.stringableFunc(pattern) ? string
    : is.func(pattern)           ? predicate
    : is.symbol(pattern)         ? symbol
    : null
  )

  if (matcherCreator === null) {
    throw new Error(`invalid pattern: ${pattern}`)
  }

  return matcherCreator(pattern)
}
github redux-saga / redux-saga / packages / core / src / internal / effectRunnerMap.js View on Github external
function createTaskIterator({ context, fn, args }) {
  // catch synchronous failures; see #152 and #441
  try {
    const result = fn.apply(context, args)

    // i.e. a generator function returns an iterator
    if (is.iterator(result)) {
      return result
    }

    let resolved = false

    const next = arg => {
      if (!resolved) {
        resolved = true
        // Only promises returned from fork will be interpreted. See #1573
        return { value: result, done: !is.promise(result) }
      } else {
        return { value: arg, done: true }
      }
    }

    return makeIterator(next)
github redux-saga / redux-saga / packages / core / src / internal / proc.js View on Github external
it allows this generator to propagate cancellation downward.

      ATTENTION! effect runners must setup the cancel logic by setting cb.cancel = [cancelMethod]
      And the setup must occur before calling the callback

      This is a sort of inversion of control: called async functions are responsible
      of completing the flow by calling the provided continuation; while caller functions
      are responsible for aborting the current flow by calling the attached cancel function

      Library users can attach their own cancellation logic to promises by defining a
      promise[CANCEL] method in their returned promises
      ATTENTION! calling cancel must have no effect on an already completed or cancelled effect
    **/
    if (is.promise(effect)) {
      resolvePromise(effect, currCb)
    } else if (is.iterator(effect)) {
      // resolve iterator
      proc(env, effect, task.context, effectId, meta, /* isRoot */ false, currCb)
    } else if (effect && effect[IO]) {
      const effectRunner = effectRunnerMap[effect.type]
      effectRunner(env, effect.payload, currCb, executingContext)
    } else {
      // anything else returned as is
      currCb(effect)
    }
  }
github redux-saga / redux-saga / packages / core / src / internal / effectRunnerMap.js View on Github external
function runCallEffect(env, { context, fn, args }, cb, { task }) {
  // catch synchronous failures; see #152
  try {
    const result = fn.apply(context, args)

    if (is.promise(result)) {
      resolvePromise(result, cb)
      return
    }

    if (is.iterator(result)) {
      // resolve iterator
      proc(env, result, task.context, currentEffectId, getMetaInfo(fn), /* isRoot */ false, cb)
      return
    }

    cb(result)
  } catch (error) {
    cb(error, true)
  }
}