Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: XRequest to support custom protocols #293

Merged
merged 17 commits into from
Dec 4, 2024
Merged

refactor: XRequest to support custom protocols #293

merged 17 commits into from
Dec 4, 2024

Conversation

YumoImer
Copy link
Collaborator

@YumoImer YumoImer commented Dec 2, 2024

fix: #284

Summary by CodeRabbit

  • 新功能

    • 更新了 XRequest 组件的文档,增加了中英文示例,提供了自定义转换器的配置说明。
    • 引入了新的 React 组件,支持通过模拟 API 进行聊天式交互。
  • 文档

    • 更新了 custom-transformer.mdindex.zh-CN.md 文件,增加了语言特定的说明和示例。
  • 测试

    • 增强了 xFetch 函数的错误处理测试,确保中间件返回有效的 Response 实例。
    • 更新了 XRequest 测试套件,改进了数据流的模拟和测试结构。

Copy link
Contributor

coderabbitai bot commented Dec 2, 2024

Warning

Rate limit exceeded

@YumoImer has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 1 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between d8bb0df and aca796b.

📝 Walkthrough
📝 Walkthrough

Walkthrough

该拉取请求对XRequest组件进行了多项修改,包括更新basic.tsx中的组件结构,添加文档以支持自定义转换流,并引入新的测试用例以增强错误处理能力。此外,XRequestClass的功能得到了增强,特别是在响应处理和错误管理方面。文档也进行了更新,增加了中文和英文部分,提供了更好的用户指导。

Changes

文件路径 变更摘要
components/x-request/demo/basic.tsx 替换Splitter组件为Space组件,更新lines状态变量类型为Record<string, string>[],移除Splitter.Panel
components/x-request/demo/custom-transformer.md 添加简体中文(zh-CN)和英文(en-US)部分,提供自定义transformStream的配置说明。
components/x-request/demo/custom-transformer.tsx 引入新的React组件,模拟API交互,定义mockFetch函数以生成NDJSON数据,更新请求处理逻辑。
components/x-request/index.en-US.md 更新文档,增加Custom Transformer示例,修改dangerouslyApiKey属性的描述以强调安全风险。
components/x-request/index.ts 更新XRequestClass,增强错误处理,重构create方法以支持不同响应类型的处理。
components/x-request/index.zh-CN.md 更新中文文档,翻译标题和示例,增加自定义转换器示例。
components/x-request/tests/x-fetch.test.tsx 添加新的测试用例以检查onResponse中间件的错误处理。
components/x-request/tests/index.test.tsx 更新测试套件以增强类型安全,重构数据流的模拟处理,更新成功和错误处理的测试。

Assessment against linked issues

Objective Addressed Explanation
支持application/x-ndjson内容 (#[284])

Possibly related PRs

Suggested reviewers

  • afc163

🐰 在草地上跳跃,
新变更如花绽放,
代码更清晰,功能强,
兔子欢呼,乐无疆!
让我们一起欢庆,
这次更新真精彩! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented Dec 2, 2024

Preview is ready

Copy link

codecov bot commented Dec 2, 2024

Bundle Report

Bundle size has no change ✅

Copy link

cloudflare-workers-and-pages bot commented Dec 2, 2024

Deploying ant-design-x with  Cloudflare Pages  Cloudflare Pages

Latest commit: aca796b
Status: ✅  Deploy successful!
Preview URL: https://c5ae1a7a.ant-design-x.pages.dev
Branch Preview URL: https://feat-nd-json.ant-design-x.pages.dev

View logs

Copy link

github-actions bot commented Dec 2, 2024

size-limit report 📦

Path Size
dist/antdx.min.js 40.62 KB (+70 B 🔺)

Copy link
Contributor

@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: 3

🧹 Outside diff range and nitpick comments (4)
components/x-request/index.ts (2)

118-119: 建议在 if 语句中添加花括号

为了提高代码的可读性和维护性,建议在 if 语句中添加花括号,即使其中只有一条语句。

建议修改如下:

- if (!options.baseURL || typeof options.baseURL !== 'string')
-   throw new Error('The baseURL is not valid!');
+ if (!options.baseURL || typeof options.baseURL !== 'string') {
+   throw new Error('The baseURL is not valid!');
+ }

168-169: 修正错误消息中的语法错误

错误消息中的语法应为 "is not supported!",而非 "is not support!"。

建议修改如下:

- throw new Error(`The response content-type: ${contentType} is not support!`);
+ throw new Error(`The response content-type: ${contentType} is not supported!`);
components/x-request/index.zh-CN.md (1)

Line range hint 59-65: 修正 API 文档中 XRequestCallbacks 的属性

在文档中,transformStream 并非 XRequestCallbacks 的属性,而是 XRequestFunction 的第三个可选参数。为避免误导,建议将 transformStreamXRequestCallbacks 的属性表中移除。

建议:

  1. XRequestCallbacks 的属性表中删除 transformStream

  2. XRequestFunction 的说明中,明确 transformStream 是第三个可选参数,并提供相关示例。

components/x-request/index.en-US.md (1)

Line range hint 58-64: 修正 API 文档中 XRequestCallbacks 的属性

在文档中,transformStream 不是 XRequestCallbacks 的属性,而是 XRequestFunction 的第三个可选参数。为避免混淆,建议从 XRequestCallbacks 的属性表中移除 transformStream

建议:

  1. XRequestCallbacks 的属性表中移除 transformStream

  2. XRequestFunction 的描述中,明确说明 transformStream 是第三个可选参数,并提供相应的使用示例。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a12d76e and 8a4765d.

📒 Files selected for processing (6)
  • components/x-request/demo/basic.tsx (2 hunks)
  • components/x-request/demo/custom-transformer.md (1 hunks)
  • components/x-request/demo/custom-transformer.tsx (1 hunks)
  • components/x-request/index.en-US.md (1 hunks)
  • components/x-request/index.ts (3 hunks)
  • components/x-request/index.zh-CN.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/x-request/demo/custom-transformer.md
🔇 Additional comments (1)
components/x-request/demo/basic.tsx (1)

54-78: 组件布局调整合理

已将 Splitter 组件替换为更简单的 Space 组件,简化了组件结构,代码清晰明了。

components/x-request/index.ts Show resolved Hide resolved
components/x-request/index.ts Show resolved Hide resolved
Copy link

codecov bot commented Dec 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.36%. Comparing base (9ff72b9) to head (aca796b).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #293      +/-   ##
==========================================
+ Coverage   91.17%   91.36%   +0.19%     
==========================================
  Files          66       66              
  Lines        1427     1447      +20     
  Branches      381      368      -13     
==========================================
+ Hits         1301     1322      +21     
+ Misses        126      125       -1     

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

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (3)
components/x-request/__tests__/index.test.tsx (3)

9-19: 建议添加注释说明测试数据的用途

为了提高代码可维护性,建议为以下内容添加注释说明:

  • SSE_SEPARATOR 和 ND_JSON_SEPARATOR 的使用场景
  • sseEvent、sseData 和 ndJsonData 的数据结构及用途
+// 用于分割SSE消息的分隔符
 const SSE_SEPARATOR = '\n\n';

+// 用于分割NDJSON消息的分隔符
 const ND_JSON_SEPARATOR = '\n';

+// 模拟SSE事件的示例数据
 const sseEvent: SSEOutput = { event: 'message', data: '{"id":"0","content":"He"}' };

Line range hint 29-49: 建议优化模拟流的实现方式

当前的实现方式可以工作,但建议使用异步生成器来简化代码并提高可读性。

-function mockSSEReadableStream() {
-  return new ReadableStream({
-    async start(controller) {
-      for (const chunk of sseData.split(SSE_SEPARATOR)) {
-        controller.enqueue(new TextEncoder().encode(chunk));
-      }
-      controller.close();
-    },
-  });
-}
+async function* generateSSEChunks() {
+  for (const chunk of sseData.split(SSE_SEPARATOR)) {
+    yield new TextEncoder().encode(chunk);
+  }
+}
+
+function mockSSEReadableStream() {
+  return new ReadableStream({
+    async start(controller) {
+      for await (const chunk of generateSSEChunks()) {
+        controller.enqueue(chunk);
+      }
+      controller.close();
+    },
+  });
+}
🧰 Tools
🪛 GitHub Check: CodeQL

[failure] 24-24: Hard-coded credentials
The hard-coded value "dangerouslyApiKey" is used as authorization header.


104-118: 建议补充边界情况测试

当前的自定义协议测试用例已经覆盖了基本功能,建议添加以下场景的测试:

  • 空数据流的处理
  • 格式错误的NDJSON数据
  • 超大数据块的处理

这些测试将确保自定义协议支持的健壮性。

需要我帮您生成这些额外的测试用例吗?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8a4765d and 7e467fc.

⛔ Files ignored due to path filters (2)
  • bun.lockb is excluded by !**/bun.lockb
  • components/x-request/__tests__/__snapshots__/demo.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • components/x-request/__tests__/index.test.tsx (2 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
components/x-request/__tests__/index.test.tsx

[failure] 24-24: Hard-coded credentials
The hard-coded value "dangerouslyApiKey" is used as authorization header.

🔇 Additional comments (2)
components/x-request/__tests__/index.test.tsx (2)

4-5: 类型导入完善且合理!

新增的类型导入增强了代码的类型安全性,使测试代码更加健壮。


52-60: 测试套件设置结构清晰!

回调函数和测试初始化的设置符合测试最佳实践,便于维护和扩展。

components/x-request/__tests__/index.test.tsx Show resolved Hide resolved
Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (3)
components/x-request/__tests__/index.test.tsx (1)

Line range hint 29-49: 建议重构以减少代码重复

mockSSEReadableStreammockNdJsonReadableStream 的实现逻辑非常相似,建议提取共同代码。

+ function createMockReadableStream(data: string, separator: string) {
+   return new ReadableStream({
+     async start(controller) {
+       for (const chunk of data.split(separator)) {
+         controller.enqueue(new TextEncoder().encode(chunk));
+       }
+       controller.close();
+     },
+   });
+ }
+
- function mockSSEReadableStream() {
-   return new ReadableStream({
-     async start(controller) {
-       for (const chunk of sseData.split(SSE_SEPARATOR)) {
-         controller.enqueue(new TextEncoder().encode(chunk));
-       }
-       controller.close();
-     },
-   });
- }
+ function mockSSEReadableStream() {
+   return createMockReadableStream(sseData, SSE_SEPARATOR);
+ }
+
- function mockNdJsonReadableStream() {
-   return new ReadableStream({
-     async start(controller) {
-       for (const chunk of ndJsonData.split(ND_JSON_SEPARATOR)) {
-         controller.enqueue(new TextEncoder().encode(chunk));
-       }
-       controller.close();
-     },
-   });
- }
+ function mockNdJsonReadableStream() {
+   return createMockReadableStream(ndJsonData, ND_JSON_SEPARATOR);
+ }
components/x-request/index.ts (2)

118-121: 建议增强URL验证

当前的URL验证比较基础,建议增加更严格的URL格式检查。

- if (!options.baseURL || typeof options.baseURL !== 'string')
-   throw new Error('The baseURL is not valid!');
+ if (!options.baseURL || typeof options.baseURL !== 'string' || !isValidUrl(options.baseURL))
+   throw new Error('The baseURL must be a valid URL string!');
+
+ function isValidUrl(url: string): boolean {
+   try {
+     new URL(url);
+     return true;
+   } catch {
+     return false;
+   }
+ }

182-227: 建议重构响应处理器以减少重复代码

customResponseHandlersseResponseHandlerjsonResponseHandler 包含重复的逻辑模式,建议提取共同代码。

+ private async handleStreamResponse<Output = SSEOutput>(
+   stream: AsyncIterable<Output>,
+   callbacks?: XRequestCallbacks<Output>,
+ ) {
+   const chunks: Output[] = [];
+   for await (const chunk of stream) {
+     chunks.push(chunk);
+     callbacks?.onUpdate?.(chunk);
+   }
+   callbacks?.onSuccess?.(chunks);
+ }
+
  private customResponseHandler = async <Output = SSEOutput>(
    response: Response,
    callbacks?: XRequestCallbacks<Output>,
    transformStream?: XStreamOptions<Output>['transformStream'],
  ) => {
-   const chunks: Output[] = [];
-   for await (const chunk of XStream({
+   await this.handleStreamResponse(XStream({
      readableStream: response.body!,
      transformStream,
-   })) {
-     chunks.push(chunk);
-     callbacks?.onUpdate?.(chunk);
-   }
-   callbacks?.onSuccess?.(chunks);
+   }), callbacks);
  };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7e467fc and 5827f70.

📒 Files selected for processing (2)
  • components/x-request/__tests__/index.test.tsx (2 hunks)
  • components/x-request/index.ts (3 hunks)
🧰 Additional context used
📓 Learnings (1)
components/x-request/__tests__/index.test.tsx (1)
Learnt from: YumoImer
PR: ant-design/x#293
File: components/x-request/__tests__/index.test.tsx:21-25
Timestamp: 2024-12-03T13:19:38.409Z
Learning: 在测试代码中,可以使用硬编码的测试 API 密钥作为测试值。
🔇 Additional comments (6)
components/x-request/__tests__/index.test.tsx (4)

4-19: 类型导入和常量定义结构清晰

类型导入明确,常量定义合理,测试数据构造方式易于维护。


21-28: 测试配置符合预期

根据之前的反馈,在测试环境中使用硬编码的API密钥是可以接受的。配置结构清晰,符合接口定义。


52-102: 测试用例结构完善

测试设置清晰,回调函数定义合理,基础功能测试覆盖全面。


104-139: 自定义协议测试用例完善,建议验证边界情况

测试用例很好地覆盖了新增的NDJSON支持,错误处理也很完整。建议增加对大数据量和异常数据格式的测试。

components/x-request/index.ts (2)

150-171: 响应处理逻辑改进合理

新增的自定义协议支持实现清晰,content-type的处理更加健壮。MIME类型的提取和匹配逻辑优化得当。


101-101: ⚠️ Potential issue

注意使用函数作为Map键的潜在问题

使用 fetch 函数作为 Map 的键可能导致缓存失效,因为即使是相同功能的函数实例也可能不同。建议考虑使用函数的某些唯一标识属性作为键。

- private static instanceBuffer: Map<string | typeof fetch, XRequestClass> = new Map();
+ private static instanceBuffer: Map<string, XRequestClass> = new Map();
+ private static getFetchKey(fetch?: typeof window.fetch): string {
+   if (!fetch) return 'default';
+   return fetch.name || fetch.toString();
+ }

Likely invalid or redundant comment.

Copy link
Contributor

@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: 0

🧹 Outside diff range and nitpick comments (5)
components/x-request/__tests__/x-fetch.test.tsx (1)

38-42: 建议添加更多协议相关的测试场景

为了更全面地支持自定义协议,建议增加以下测试场景:

  1. 验证 application/x-ndjson 内容类型的处理
  2. 测试自定义协议的响应转换
  3. 测试流式响应的处理

示例代码:

it('应该正确处理 application/x-ndjson 响应', async () => {
  const mockResponse = new Response('{"data": "test"}\n{"data": "test2"}', {
    status: 200,
    headers: {
      'content-type': 'application/x-ndjson'
    }
  });
  
  const middlewares = {
    onResponse: async (response: Response) => {
      const contentType = response.headers.get('content-type');
      if (contentType === 'application/x-ndjson') {
        // 处理 ndjson 响应
        return new Response(JSON.stringify({
          type: 'ndjson',
          data: await response.text()
        }));
      }
      return response;
    }
  };

  const response = await xFetch(baseURL, { middlewares });
  const data = await response.json();
  
  expect(data.type).toBe('ndjson');
});
components/x-request/__tests__/index.test.tsx (4)

Line range hint 29-49: 建议增加错误处理机制

mock流实现的逻辑没有问题,但建议添加错误处理来提高测试的健壮性。

建议这样修改:

 function mockSSEReadableStream() {
   return new ReadableStream({
     async start(controller) {
+      try {
         for (const chunk of sseData.split(SSE_SEPARATOR)) {
           controller.enqueue(new TextEncoder().encode(chunk));
         }
         controller.close();
+      } catch (error) {
+        controller.error(error);
+      }
     },
   });
 }

同样的修改也应用到mockNdJsonReadableStream函数。


52-73: 建议增加边界条件测试用例

基础测试覆盖了主要场景,但建议添加以下边界条件的测试:

  • 空model参数的处理
  • 特殊字符的baseURL
  • callbacks为空对象的情况

示例:

test('should handle empty model parameter', () => {
  const optionsWithoutModel = { ...options, model: '' };
  const request = XRequest(optionsWithoutModel);
  expect(request.model).toBe('');
});

104-119: 建议增强自定义响应处理测试的可读性

当前的NDJSON响应处理测试逻辑正确,但可以通过以下方式提高可读性:

  • 提取预期结果为常量
  • 添加更多注释说明转换流程
  • 验证转换后的数据格式

建议这样改进:

// 提取预期结果为常量
const expectedChunks = ndJsonData.split(ND_JSON_SEPARATOR);
const [firstChunk, secondChunk] = expectedChunks;

test('should create request and handle custom response, e.g. application/x-ndjson', async () => {
  // 设置mock响应
  mockedXFetch.mockResolvedValueOnce({
    headers: {
      get: jest.fn().mockReturnValue('application/x-ndjson'),
    },
    body: mockNdJsonReadableStream(),
  });

  // 验证转换流程
  await request.create(params, callbacks, new TransformStream());
  
  // 验证成功回调接收到完整的数据数组
  expect(callbacks.onSuccess).toHaveBeenCalledWith([firstChunk, secondChunk]);
  
  // 验证更新回调按顺序接收到每个数据块
  expect(callbacks.onUpdate).toHaveBeenCalledWith(firstChunk);
  expect(callbacks.onUpdate).toHaveBeenCalledWith(secondChunk);
  
  // 验证没有错误发生
  expect(callbacks.onError).not.toHaveBeenCalled();
  
  // 验证数据格式
  const parsedFirstChunk = JSON.parse(firstChunk);
  expect(parsedFirstChunk).toHaveProperty('event');
  expect(parsedFirstChunk).toHaveProperty('data');
});

121-148: 建议增加更多错误场景测试

当前的错误处理测试覆盖了基本场景,建议添加以下特定错误场景的测试:

  • 网络超时
  • 服务器返回5xx错误
  • 无效的响应格式

示例:

test('should handle network timeout', async () => {
  const timeoutError = new Error('Network timeout');
  mockedXFetch.mockRejectedValueOnce(timeoutError);
  
  await request.create(params, callbacks).catch(() => {});
  expect(callbacks.onError).toHaveBeenCalledWith(timeoutError);
});

test('should handle server error', async () => {
  mockedXFetch.mockResolvedValueOnce({
    ok: false,
    status: 500,
    statusText: 'Internal Server Error',
  });
  
  await request.create(params, callbacks).catch(() => {});
  expect(callbacks.onError).toHaveBeenCalledWith(
    expect.objectContaining({
      message: expect.stringContaining('500'),
    }),
  );
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5827f70 and e544482.

📒 Files selected for processing (2)
  • components/x-request/__tests__/index.test.tsx (2 hunks)
  • components/x-request/__tests__/x-fetch.test.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (1)
components/x-request/__tests__/index.test.tsx (1)
Learnt from: YumoImer
PR: ant-design/x#293
File: components/x-request/__tests__/index.test.tsx:21-25
Timestamp: 2024-12-03T13:19:38.409Z
Learning: 在测试代码中,可以使用硬编码的测试 API 密钥作为测试值。
🔇 Additional comments (3)
components/x-request/__tests__/x-fetch.test.tsx (1)

38-42: 测试用例设计合理且完善!

这个测试用例很好地验证了中间件返回值的类型检查,确保了自定义协议处理的安全性。

components/x-request/__tests__/index.test.tsx (2)

4-19: 类型导入和常量定义看起来不错!

新增的类型导入和常量定义提高了代码的类型安全性和可维护性。使用常量来定义分隔符是一个很好的做法。


21-28: 配置和参数设置合理

根据之前的反馈,在测试代码中使用硬编码的测试API密钥是可以接受的。配置和参数的结构清晰。

@YumoImer YumoImer requested a review from a team December 4, 2024 02:40
Copy link
Contributor

@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: 2

🧹 Outside diff range and nitpick comments (2)
components/x-request/demo/custom-transformer.tsx (2)

43-47: 优化 baseURL 的构建方式

建议使用 URL 构造函数或 path.join 来构建 URL,以确保路径分隔符的正确性:

- baseURL: BASE_URL + PATH,
+ baseURL: new URL(PATH, BASE_URL).toString(),

96-98: 优化滚动区域的实现

当前的滚动实现可能会导致性能问题,建议:

  1. 添加最大高度限制
  2. 使用虚拟滚动来处理大量数据
- <pre style={{ overflow: 'scroll' }}>
+ <pre style={{ 
+   overflow: 'auto',
+   maxHeight: '400px',
+   padding: '12px',
+   margin: 0,
+   backgroundColor: '#f5f5f5',
+   borderRadius: '4px'
+ }}>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e544482 and 3e592d2.

📒 Files selected for processing (3)
  • components/x-request/demo/custom-transformer.tsx (1 hunks)
  • components/x-request/index.en-US.md (1 hunks)
  • components/x-request/index.zh-CN.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/x-request/index.en-US.md
  • components/x-request/index.zh-CN.md
🔇 Additional comments (3)
components/x-request/demo/custom-transformer.tsx (3)

10-10: 请验证模型名称的正确性

MODEL 常量值 'gpt-4o' 可能是笔误。通常的模型名称应该是 'gpt-4'


64-64: 移除调试用的 console 语句

在生产代码中应移除所有的 console 语句。

Also applies to: 68-68, 72-72


15-19: ⚠️ Potential issue

修正模拟数据中的格式问题

  1. JSON 字符串格式不正确,缺少必要的引号
  2. created 时间戳值过大(1733129xxx),超出了合理范围
  3. 建议统一使用正确的模型名称

建议修改示例:

- const ndJsonData = `{data:{"id":"0","choices":[{"index":0,"delta":{"content":"Hello","role":"assistant"}}],"created":1733129200,"model":"gpt-4o"}}
+ const ndJsonData = `{"data":{"id":"0","choices":[{"index":0,"delta":{"content":"Hello","role":"assistant"}}],"created":1683129200,"model":"gpt-4"}}`

components/x-request/demo/custom-transformer.tsx Outdated Show resolved Hide resolved
@YumoImer
Copy link
Collaborator Author

YumoImer commented Dec 4, 2024

问题都解决了,大家再看下

Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (3)
components/x-request/demo/basic.tsx (1)

65-68: 建议优化条件判断逻辑

当前的描述判断逻辑较为复杂,建议提取为独立的函数或变量以提高可读性。

建议如下重构:

- description:
-   status === 'error' &&
-   exampleRequest.baseURL === BASE_URL + PATH &&
-   'Please replace the BASE_URL, PATH, MODEL, API_KEY with your own values.',
+ description: getErrorDescription(status, exampleRequest.baseURL),

然后在组件外部添加:

const getErrorDescription = (status: ThoughtChainItem['status'], baseURL: string) => {
  if (status === 'error' && baseURL === BASE_URL + PATH) {
    return 'Please replace the BASE_URL, PATH, MODEL, API_KEY with your own values.';
  }
  return undefined;
};
components/x-request/__tests__/x-request.test.tsx (2)

29-49: 建议增强模拟流的错误处理能力

当前的流模拟实现很好,但建议添加错误处理以提高测试的健壮性。

 function mockSSEReadableStream() {
   return new ReadableStream({
     async start(controller) {
+      try {
         for (const chunk of sseData.split(SSE_SEPARATOR)) {
           controller.enqueue(new TextEncoder().encode(chunk));
         }
         controller.close();
+      } catch (error) {
+        controller.error(error);
+      }
     },
   });
 }

104-119: 建议扩展自定义协议的测试用例

当前的 NDJSON 测试用例很好,但建议添加以下场景的测试:

  1. 空响应处理
  2. 格式错误的 NDJSON 数据
  3. 大数据量场景

这些测试对于支持 ollama 的 application/x-ndjson 响应特别重要。

示例测试用例:

test('should handle empty ndjson response', async () => {
  mockedXFetch.mockResolvedValueOnce({
    headers: {
      get: jest.fn().mockReturnValue('application/x-ndjson'),
    },
    body: new ReadableStream({
      start(controller) {
        controller.close();
      },
    }),
  });
  await request.create(params, callbacks, new TransformStream());
  expect(callbacks.onSuccess).toHaveBeenCalledWith([]);
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3e592d2 and 8cda2ff.

📒 Files selected for processing (3)
  • components/x-request/__tests__/x-request.test.tsx (1 hunks)
  • components/x-request/demo/basic.tsx (3 hunks)
  • components/x-request/demo/custom-transformer.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/x-request/demo/custom-transformer.tsx
🧰 Additional context used
🪛 GitHub Check: CodeQL
components/x-request/__tests__/x-request.test.tsx

[failure] 24-24: Hard-coded credentials
The hard-coded value "dangerouslyApiKey" is used as authorization header.

🔇 Additional comments (7)
components/x-request/demo/basic.tsx (3)

3-3: 导入声明更改看起来不错!

从 antd 导入 Space 组件是合理的,这与后续的组件结构改进相符。


26-26: 类型定义优化很棒!

lines 状态的类型从 any[] 改为 Record<string, string>[] 是很好的改进:

  • 消除了 any 类型的使用
  • 提供了更好的类型安全性
  • 使代码更易于维护

54-58: 组件结构改进合理!

使用 Space 组件替换原有的 Splitter 是个好选择:

  • 提供了更简洁的布局方案
  • 使用了 antd 的标准组件
components/x-request/__tests__/x-request.test.tsx (4)

1-8: 导入和模拟设置看起来不错!

导入语句简洁明了,xFetch 的模拟设置也很恰当。


13-19: 测试数据结构设计合理

测试数据很好地覆盖了 SSE 和 NDJSON 格式,符合支持自定义协议的需求。


51-66: 测试套件设置完善

很好地使用了 beforeEach 进行测试前清理,保持了测试的独立性。


130-149: 错误处理测试很完善

测试用例很好地覆盖了错误场景,包括网络错误和不支持的内容类型。

components/x-request/__tests__/x-request.test.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@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

🧹 Outside diff range and nitpick comments (2)
components/x-request/__tests__/index.test.tsx (2)

Line range hint 29-49: 建议重构模拟流函数以减少代码重复

mockSSEReadableStreammockNdJsonReadableStream 函数有很多相似的代码。建议提取共同逻辑到一个通用函数中。

+function createMockStream(data: string, separator: string) {
+  return new ReadableStream({
+    async start(controller) {
+      for (const chunk of data.split(separator)) {
+        controller.enqueue(new TextEncoder().encode(chunk));
+      }
+      controller.close();
+    },
+  });
+}

-function mockSSEReadableStream() {
-  return new ReadableStream({
-    async start(controller) {
-      for (const chunk of sseData.split(SSE_SEPARATOR)) {
-        controller.enqueue(new TextEncoder().encode(chunk));
-      }
-      controller.close();
-    },
-  });
-}

-function mockNdJsonReadableStream() {
-  return new ReadableStream({
-    async start(controller) {
-      for (const chunk of ndJsonData.split(ND_JSON_SEPARATOR)) {
-        controller.enqueue(new TextEncoder().encode(chunk));
-      }
-      controller.close();
-    },
-  });
-}

+const mockSSEReadableStream = () => createMockStream(sseData, SSE_SEPARATOR);
+const mockNdJsonReadableStream = () => createMockStream(ndJsonData, ND_JSON_SEPARATOR);

52-149: 建议优化测试用例的组织结构

当前的测试用例结构可以通过以下方式改进:

  1. 使用嵌套的 describe 块按功能分组测试用例
  2. 为不同的响应类型创建单独的测试组

建议的结构:

describe('XRequest Class', () => {
  // 设置和初始化测试
  describe('Initialization', () => {
    // 现有的初始化测试...
  });

  // 响应处理测试
  describe('Response Handling', () => {
    describe('JSON Responses', () => {
      // JSON 相关测试...
    });
    
    describe('SSE Responses', () => {
      // SSE 相关测试...
    });
    
    describe('NDJSON Responses', () => {
      // NDJSON 相关测试...
    });
  });

  // 错误处理测试
  describe('Error Handling', () => {
    // 错误处理相关测试...
  });
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8cda2ff and d8bb0df.

📒 Files selected for processing (1)
  • components/x-request/__tests__/index.test.tsx (2 hunks)
🧰 Additional context used
📓 Learnings (1)
components/x-request/__tests__/index.test.tsx (1)
Learnt from: YumoImer
PR: ant-design/x#293
File: components/x-request/__tests__/index.test.tsx:21-25
Timestamp: 2024-12-03T13:19:38.409Z
Learning: 在测试代码中,可以使用硬编码的测试 API 密钥作为测试值。
🔇 Additional comments (2)
components/x-request/__tests__/index.test.tsx (2)

4-11: 类型导入和常量定义看起来不错!

类型导入增强了类型安全性,常量定义提高了代码的可维护性。


13-28: 测试数据结构清晰,便于理解!

测试数据的设置方式合理:

  • SSE事件数据结构完整
  • NDJSON数据格式正确
  • 测试参数配置适当

关于 dangerouslyApiKey 的使用:根据之前的讨论,在测试环境中使用固定的测试值是可以接受的。

components/x-request/__tests__/index.test.tsx Show resolved Hide resolved
@YumoImer YumoImer merged commit 7d3d6a1 into main Dec 4, 2024
15 checks passed
@YumoImer YumoImer deleted the feat/nd-json branch December 4, 2024 07:13
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.

XRequest 能否支持 ollama 返回的 application/x-ndjson 内容
3 participants