Skip to content

Conversation

doubledare704
Copy link

@doubledare704 doubledare704 commented Sep 14, 2025

feat(testing): add selective action stubbing support

  • Add support for include/exclude options in stubActions parameter
  • Allow stubbing only specific actions or excluding specific actions from stubbing
  • Maintain backward compatibility with boolean stubActions values
  • Add comprehensive tests for all selective stubbing scenarios
  • Update documentation with examples and usage patterns

Closes #2970

Summary by CodeRabbit

  • New Features
    • Introduced selective action stubbing in testing: configure stubbed actions via include/exclude. Boolean usage remains supported. Include takes precedence; empty include/exclude defaults to stubbing all.
  • Documentation
    • Added “Selective action stubbing” guide with examples and tips in English and Chinese testing docs.
  • Tests
    • Added comprehensive coverage for include/exclude scenarios, precedence, empty arrays, and edge cases.

feat(testing): add selective action stubbing support

- Add support for include/exclude options in stubActions parameter
- Allow stubbing only specific actions or excluding specific actions from stubbing
- Maintain backward compatibility with boolean stubActions values
- Add comprehensive tests for all selective stubbing scenarios
- Update documentation with examples and usage patterns
- Fix workspace naming conflict in online-playground package

Closes vuejs#2970
Copy link

netlify bot commented Sep 14, 2025

Deploy Preview for pinia-official canceled.

Name Link
🔨 Latest commit 0d9ca09
🔍 Latest deploy log https://app.netlify.com/projects/pinia-official/deploys/68c6f6d8604fa40008b062b9

Copy link

coderabbitai bot commented Sep 14, 2025

Walkthrough

Adds selective action stubbing to testing utilities by extending stubActions to accept include/exclude lists, updates tests and docs (EN and ZH) to cover behavior and usage, and renames the online playground package.

Changes

Cohort / File(s) Summary of Changes
Testing API: selective stubbing logic
packages/testing/src/testing.ts
Extends TestingOptions.stubActions from boolean to boolean or { include?: string[]; exclude?: string[] }. Implements per-action stubbing with include precedence, exclude fallback, and default-to-all when neither provided.
Tests for selective stubbing
packages/testing/src/testing.spec.ts
Adds useMultiActionStore and a test suite covering include/exclude, empty arrays, precedence, boolean modes, and non-existent action names.
Docs: EN
packages/docs/cookbook/testing.md
Adds “Selective action stubbing” section with examples, precedence note, default behavior, and tips for manual mocking. Section appears duplicated.
Docs: ZH
packages/docs/zh/cookbook/testing.md
Adds Chinese section explaining selective stubbing, examples, precedence, default behavior, and manual mocking guidance.
Online playground package rename
packages/online-playground/package.json
Renames package "name" from "@pinia/playground" to "@pinia/online-playground".

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor T as Test
  participant P as createTestingPinia
  participant S as Store
  participant A as Action

  T->>P: createTestingPinia({ stubActions })
  activate P
  P->>P: For each action, compute shouldStub
  note over P: If object:<br/>- include (non-empty) → only listed stubbed<br/>- else if exclude (non-empty) → all but listed stubbed<br/>- else → all stubbed<br/>Boolean true → all stubbed<br/>Boolean false → none stubbed
  P->>S: Install spies/stubs per shouldStub
  deactivate P

  T->>S: Call action A()
  alt shouldStub = true
    S->>A: Spy/stub invoked (no state change)
  else shouldStub = false
    S->>A: Real implementation runs (mutates state)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I twitch my ears at include and exclude,
A hop selects which actions to elude.
Some paths are stubbed, some scamper free—
A burrow of tests for certainty.
New name on the warren’s sign I see,
Thump-thump! Shipping with selective glee.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Pre-merge checks

✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues Check ✅ Passed The changes implement the objectives of issue #2970: the TestingOptions.stubActions type is extended to boolean
Out of Scope Changes Check ✅ Passed Most changes are within the linked-issue scope (API, implementation, tests, docs) and the package.json name change is described in the PR objectives, however the English cookbook file contains the new "Selective action stubbing" section duplicated twice which appears accidental and should be cleaned up.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: add selective action stubbing support" is concise and accurately summarizes the primary change in the changeset—adding selective action stubbing to the testing utilities (with related tests and docs). It is specific, directly aligned with the PR objectives and the modified files, and readable for teammates scanning history.

@doubledare704 doubledare704 changed the title style: fix formatting with prettier feat: add selective action stubbing support Sep 14, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
packages/docs/zh/cookbook/testing.md (1)

176-239: 新增“选择性 action 存根”章节内容与实现一致。建议补充对 $reset 的特殊说明。

实现中 $resetstubReset 控制,stubActions(含 include/exclude)不会影响 $reset。为避免读者误解,建议在本节加一句明确说明。

应用此编辑(在提示块后增加一行):

 ::: tip
 如果同时提供了 `include` 和 `exclude`,`include` 优先。如果两者都没有提供或两个数组都为空,所有 action 都将被存根(等同于 `stubActions: true`)。
 :::
+> 注意:内置方法 `$reset` 不受 `stubActions`(包括 include/exclude)影响,请使用 `stubReset` 选项控制其是否存根。
packages/docs/cookbook/testing.md (1)

169-232: Selective stubbing docs match behavior. Add a short note about $reset being controlled via stubReset.

Code excludes $reset from stubActions handling and wires it via stubReset. A one-liner will prevent confusion.

Apply after the tip block:

 ::: tip
 If both `include` and `exclude` are provided, `include` takes precedence. If neither is provided or both arrays are empty, all actions will be stubbed (equivalent to `stubActions: true`).
 :::
+> Note: the built-in `$reset` is not affected by `stubActions` (including `include`/`exclude`). Use the `stubReset` option to control it.
packages/testing/src/testing.ts (2)

32-39: Clarify TSDoc to fully specify precedence and defaults for include/exclude.

Docs are correct but can be more explicit (matches implementation and user docs).

-   * not being executed. When set to an object with `include` or `exclude` arrays,
-   * only the specified actions will be stubbed or excluded from stubbing.
-   * Defaults to true. NOTE: when providing `createSpy()`,
+   * not being executed.
+   * When set to an object, you can pass `include` and/or `exclude` arrays for per‑action control:
+   * - if `include` is non‑empty, only listed actions are stubbed
+   * - else if `exclude` is non‑empty, all actions except those are stubbed
+   * - if both are omitted or empty, all actions are stubbed (equivalent to `true`)
+   * Defaults to `true`. NOTE: when providing `createSpy()`,

145-162: Logic is correct; small perf/readability tweak by precomputing sets.

Precompute include/exclude Sets once per store to avoid repeated array scans and tighten the branching.

-    Object.keys(options.actions).forEach((action) => {
-      if (action === '$reset') return
-
-      let shouldStub: boolean
-      if (typeof stubActions === 'boolean') {
-        shouldStub = stubActions
-      } else {
-        // Handle include/exclude logic
-        const { include, exclude } = stubActions
-        if (include && include.length > 0) {
-          shouldStub = include.includes(action)
-        } else if (exclude && exclude.length > 0) {
-          shouldStub = !exclude.includes(action)
-        } else {
-          // If both include and exclude are empty or undefined, default to true
-          shouldStub = true
-        }
-      }
-
-      store[action] = shouldStub ? createSpy() : createSpy(store[action])
-    })
+    const includeSet =
+      typeof stubActions === 'object' && stubActions.include?.length
+        ? new Set(stubActions.include)
+        : undefined
+    const excludeSet =
+      typeof stubActions === 'object' && stubActions.exclude?.length
+        ? new Set(stubActions.exclude)
+        : undefined
+
+    Object.keys(options.actions).forEach((action) => {
+      if (action === '$reset') return
+
+      const shouldStub =
+        typeof stubActions === 'boolean'
+          ? stubActions
+          : includeSet
+            ? includeSet.has(action)
+            : excludeSet
+              ? !excludeSet.has(action)
+              : true
+
+      store[action] = shouldStub ? createSpy() : createSpy(store[action])
+    })
packages/testing/src/testing.spec.ts (1)

412-594: Comprehensive coverage of include/exclude semantics; add one setup‑store case.

All primary paths are covered (include, exclude, empty arrays, precedence, booleans, unknown names). To guarantee parity for setup stores too, add one test exercising stubActions with a setup store’s actions.

Example to append:

it('applies selective stubbing to setup stores', () => {
  setActivePinia(
    createTestingPinia({
      stubActions: { include: ['increment'] },
      createSpy: vi.fn,
    })
  )
  const useSetup = defineStore('s', () => {
    const n = ref(0)
    function increment() { n.value++ }
    function decrement() { n.value-- }
    return { n, increment, decrement }
  })

  const s = useSetup()
  s.increment()
  expect(s.n).toBe(0)
  s.decrement()
  expect(s.n).toBe(-1)
})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57bec95 and e40f969.

📒 Files selected for processing (5)
  • packages/docs/cookbook/testing.md (1 hunks)
  • packages/docs/zh/cookbook/testing.md (1 hunks)
  • packages/online-playground/package.json (1 hunks)
  • packages/testing/src/testing.spec.ts (2 hunks)
  • packages/testing/src/testing.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/testing/src/testing.spec.ts (1)
packages/testing/src/testing.ts (1)
  • createTestingPinia (95-186)
🔇 Additional comments (2)
packages/testing/src/testing.spec.ts (1)

27-44: Good focused fixture store for multi-action scenarios.

Covers a representative mix (mutating counters and value).

packages/docs/cookbook/testing.md (1)

169-232: AI summary incorrect — no duplicate found

Search shows a single occurrence at packages/docs/cookbook/testing.md:169; no action required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow stubbing specific actions only
1 participant