Skip to content

Improve mocks for localStorage, Worker, and matchMedia#11682

Open
Riteshhh08 wants to merge 5 commits intoant-design:masterfrom
Riteshhh08:patch-1
Open

Improve mocks for localStorage, Worker, and matchMedia#11682
Riteshhh08 wants to merge 5 commits intoant-design:masterfrom
Riteshhh08:patch-1

Conversation

@Riteshhh08
Copy link
Copy Markdown

@Riteshhh08 Riteshhh08 commented Apr 15, 2026

Refactor localStorage and Worker mocks for better functionality. Update matchMedia polyfill and error handling in console.

Summary by CodeRabbit

发布说明

  • 测试
    • 优化了测试环境中的多个全局模拟实现,增强了测试框架的稳定性和兼容性。

Refactor localStorage and Worker mocks for better functionality. Update matchMedia polyfill and error handling in console.
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Apr 15, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 15, 2026

⚡️ Deploying PR Preview...

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

步骤说明

更新了测试环境中的全局对象模拟和多边形垫片,包括完善 localStorage、Worker、MessageChannel、matchMedia 和 ResizeObserver 的实现,以及调整控制台错误拦截机制,改进测试隔离性。

变更

内聚体 / 文件 摘要
localStorage 模拟
tests/setupTests.jsx
使用内存存储重构 localStorage 模拟,实现 getItem(返回存储值或 null)、setItem(序列化并存储)、removeItem(删除键)和 clear(清空所有键);从 global.localStorage 改为 globalThis.localStorage 分配。
Worker 和 MessageChannel 模拟
tests/setupTests.jsx
重命名 Worker 为 MockWorker,将 onmessage 默认值从无操作函数改为 null,postMessage 仅在 onmessage 为函数时调用;MessageChannel 现仅在 globalThis 上定义,新增两个端口的初始 onmessage: null 字段。
媒体和错误处理模拟
tests/setupTests.jsx
扩展 matchMedia 返回对象以包含 media、onchange、addEventListener、removeEventListener 和 dispatchEvent;调整控制台错误拦截,改为保存至 originalError 并直接修补 window.console.error。
全局对象分配
tests/setupTests.jsx
统一使用 globalThis 分配 Worker 和 ResizeObserver(替代 global),简化消息传递检查逻辑,保留 act 警告过滤行为。

🐰 轻拍键盘一阵阵,
模拟对象焕新生,
localStorage 存记忆,
Worker 准备齐步行,
测试环境更牢靠,
全局对象齐聚首。

代码审查工作量评估

🎯 2 (简单) | ⏱️ ~12 分钟

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题清晰地总结了主要更改内容,准确反映了PR中对localStorage、Worker和matchMedia这三个关键模块的改进。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@dosubot dosubot Bot added the javascript Pull requests that update Javascript code label Apr 15, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the test setup by migrating from global to globalThis and enhancing several mocks, including localStorage, Worker, MessageChannel, and matchMedia. The localStorage mock now maintains an internal state, and the matchMedia mock includes additional standard properties and methods. Feedback suggests further improving the MockWorker implementation by using jest.fn() for its methods and implementing a more robust event listener system to better support the EventTarget interface and allow for verification in tests.

Comment thread tests/setupTests.jsx
Comment on lines 28 to +41
constructor(stringUrl) {
this.url = stringUrl;
this.onmessage = () => {};
this.onmessage = null;
}

postMessage(msg) {
this.onmessage(msg);
if (typeof this.onmessage === 'function') {
this.onmessage({ data: msg });
}
}

terminate() {}
addEventListener() {}
removeEventListener() {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To improve the functionality of the MockWorker and make it consistent with the matchMedia mock, its methods should be jest.fn(). This allows tests to verify that these methods were called. Additionally, postMessage should ideally support listeners added via addEventListener to provide a more complete mock for code that uses the EventTarget interface.

  constructor(stringUrl) {
    this.url = stringUrl;
    this.onmessage = null;
    this._listeners = new Set();
  }

  postMessage = jest.fn((msg) => {
    const event = { data: msg };
    if (typeof this.onmessage === 'function') {
      this.onmessage(event);
    }
    this._listeners.forEach((listener) => listener(event));
  });

  terminate = jest.fn();
  addEventListener = jest.fn((type, listener) => {
    if (type === 'message') this._listeners.add(listener);
  });
  removeEventListener = jest.fn((type, listener) => {
    if (type === 'message') this._listeners.delete(listener);
  });

Copy link
Copy Markdown

@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 (1)
tests/setupTests.jsx (1)

33-41: MockWorker 为未使用的代码,完整性改进是可选重构。

验证显示 MockWorker 在整个测试套件中从未被实例化,因此其不完整的事件模型(缺少 transfer/portsaddEventListener 实现)对测试行为没有实际影响。实际使用的是 MessageChannel mock(PolyMessageChannel),其已正确实现 port1/port2 的消息传递机制,应对 src/global.tsx 中的 Service Worker 通信场景。

若保留 MockWorker 用于未来使用,建议补完其事件模型;或如无后续需求,可直接移除以简化 setup 代码。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/setupTests.jsx` around lines 33 - 41, MockWorker is never instantiated
in tests and provides an incomplete event model; either remove the MockWorker
declaration entirely from setupTests.jsx to simplify setup, or complete its
implementation by fully implementing postMessage semantics (including
transfer/ports), addEventListener/removeEventListener behavior, and proper
terminate handling so it mirrors MessageChannel behavior used by
PolyMessageChannel and the Service Worker communication in src/global.tsx;
update or remove references accordingly so tests use the existing
PolyMessageChannel mock.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/setupTests.jsx`:
- Around line 5-17: store is a plain object which can return inherited prototype
properties (so getItem('toString') can be wrong) and the clear implementation
uses a concise arrow that returns the delete expression (which trips Biome); fix
by making store a prototype-less object (e.g., use Object.create(null)) or use a
Map, change localStorageMock.getItem to check ownership (use
Object.prototype.hasOwnProperty.call(store, key) ? store[key] : null), and
rewrite clear to use a block arrow that performs deletion as a statement (e.g.,
Object.keys(store).forEach(key => { delete store[key]; })). Ensure references:
store, localStorageMock.getItem, localStorageMock.clear,
localStorageMock.setItem, localStorageMock.removeItem.

---

Nitpick comments:
In `@tests/setupTests.jsx`:
- Around line 33-41: MockWorker is never instantiated in tests and provides an
incomplete event model; either remove the MockWorker declaration entirely from
setupTests.jsx to simplify setup, or complete its implementation by fully
implementing postMessage semantics (including transfer/ports),
addEventListener/removeEventListener behavior, and proper terminate handling so
it mirrors MessageChannel behavior used by PolyMessageChannel and the Service
Worker communication in src/global.tsx; update or remove references accordingly
so tests use the existing PolyMessageChannel mock.
🪄 Autofix (Beta)

❌ Autofix failed (check again to retry)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e83b1f9d-d67a-45cd-8448-2b94bf02b261

📥 Commits

Reviewing files that changed from the base of the PR and between 74e8250 and f6cfb94.

📒 Files selected for processing (1)
  • tests/setupTests.jsx

Comment thread tests/setupTests.jsx
Comment on lines +5 to +17
const store = {};

const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
getItem: jest.fn((key) => store[key] ?? null),
setItem: jest.fn((key, value) => {
store[key] = String(value);
}),
removeItem: jest.fn((key) => {
delete store[key];
}),
clear: jest.fn(() => {
Object.keys(store).forEach((key) => delete store[key]);
}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

localStorage mock 在 Line 8 会误读原型链属性,且 Line 16 会触发 Biome 报错。

store 使用普通对象时,getItem('toString') 这类键会返回继承属性而不是 null,与真实 localStorage 语义不一致;另外 Line 16 的 forEach 回调返回了 delete 结果。

建议修复
-const store = {};
+const store = Object.create(null);

 const localStorageMock = {
-  getItem: jest.fn((key) => store[key] ?? null),
+  getItem: jest.fn((key) =>
+    Object.prototype.hasOwnProperty.call(store, key) ? store[key] : null,
+  ),
   setItem: jest.fn((key, value) => {
-    store[key] = String(value);
+    store[String(key)] = String(value);
   }),
   removeItem: jest.fn((key) => {
-    delete store[key];
+    delete store[String(key)];
   }),
   clear: jest.fn(() => {
-    Object.keys(store).forEach((key) => delete store[key]);
+    Object.keys(store).forEach((key) => {
+      delete store[key];
+    });
   }),
 };
🧰 Tools
🪛 Biome (2.4.11)

[error] 16-16: This callback passed to forEach() iterable method should not return a value.

(lint/suspicious/useIterableCallbackReturn)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/setupTests.jsx` around lines 5 - 17, store is a plain object which can
return inherited prototype properties (so getItem('toString') can be wrong) and
the clear implementation uses a concise arrow that returns the delete expression
(which trips Biome); fix by making store a prototype-less object (e.g., use
Object.create(null)) or use a Map, change localStorageMock.getItem to check
ownership (use Object.prototype.hasOwnProperty.call(store, key) ? store[key] :
null), and rewrite clear to use a block arrow that performs deletion as a
statement (e.g., Object.keys(store).forEach(key => { delete store[key]; })).
Ensure references: store, localStorageMock.getItem, localStorageMock.clear,
localStorageMock.setItem, localStorageMock.removeItem.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

❌ Failed to clone repository into sandbox. Please try again.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 38.72%. Comparing base (8d971c8) to head (847cb6b).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #11682   +/-   ##
=======================================
  Coverage   38.72%   38.72%           
=======================================
  Files         187      187           
  Lines        2298     2298           
  Branches      384      384           
=======================================
  Hits          890      890           
- Misses       1403     1407    +4     
+ Partials        5        1    -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@afc163
Copy link
Copy Markdown
Member

afc163 commented Apr 20, 2026

图片

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update Javascript code size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants