ai-unit-test-generator 2.0.7 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,57 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.0.8] - 2025-01-11
9
+
10
+ ### ✨ Feature: Enhanced Framework Detection
11
+
12
+ **Problem**: `context-builder.mjs` framework detection was too simplistic, only detecting basic React/Vue/Angular.
13
+
14
+ **Solution**: Completely rewritten framework detection with comprehensive support:
15
+
16
+ **Supported Frameworks & Platforms**:
17
+ - ✅ **React Native** (including Expo)
18
+ - ✅ **Next.js** (SSR/SSG)
19
+ - ✅ **React Native + Next.js** (Monorepo detection)
20
+ - ✅ **Taro** (Mini-Program + H5 + RN)
21
+ - ✅ **Vue / Nuxt.js**
22
+ - ✅ **Angular**
23
+ - ✅ **Svelte / SvelteKit**
24
+ - ✅ **Electron** (Desktop apps)
25
+ - ✅ **Node.js** (Backend)
26
+
27
+ **UI Library Detection**:
28
+ - Ant Design, Material-UI, Chakra UI, Radix UI, Tailwind CSS
29
+ - styled-components, Emotion, Bootstrap
30
+ - React Native Paper, NativeBase
31
+
32
+ **State Management Detection**:
33
+ - Jotai, Zustand, Redux, MobX, Recoil, XState, Valtio
34
+ - TanStack Query, SWR, Apollo Client
35
+
36
+ **Testing Tools Detection**:
37
+ - Jest, Vitest
38
+ - Testing Library (React/RN), Enzyme
39
+ - Cypress, Playwright
40
+
41
+ **Enhanced AI Analysis Output**:
42
+ ```bash
43
+ ai-test analyze
44
+
45
+ 📦 Step 4: Reading project context...
46
+ Framework: React Native
47
+ Platforms: iOS, Android
48
+ State: Jotai, SWR
49
+ Testing: Jest
50
+ ```
51
+
52
+ **Benefits**:
53
+ - AI 分析时可以获得更精准的项目上下文
54
+ - 支持跨端、混合项目的识别
55
+ - 为测试生成提供更准确的技术栈信息
56
+
57
+ ---
58
+
8
59
  ## [2.0.7] - 2025-01-11
9
60
 
10
61
  ### 🐛 Hotfix
@@ -10,21 +10,46 @@ import { existsSync, readFileSync } from 'node:fs'
10
10
  export async function buildProjectContext() {
11
11
  const context = {
12
12
  framework: 'Unknown',
13
+ platforms: [],
14
+ uiLibraries: [],
15
+ stateManagement: [],
13
16
  criticalDeps: [],
14
- devDeps: []
17
+ devDeps: [],
18
+ testingTools: []
15
19
  }
16
20
 
17
21
  // 读取 package.json
18
22
  if (existsSync('package.json')) {
19
23
  try {
20
24
  const pkg = JSON.parse(readFileSync('package.json', 'utf-8'))
25
+ const allDeps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) }
21
26
 
22
27
  context.name = pkg.name
23
- context.framework = detectFramework(pkg.dependencies || {})
24
28
 
25
- // 识别关键依赖
29
+ // 检测框架和平台
30
+ const frameworkInfo = detectFramework(allDeps)
31
+ context.framework = frameworkInfo.framework
32
+ context.platforms = frameworkInfo.platforms
33
+
34
+ // 检测 UI 库
35
+ context.uiLibraries = detectUILibraries(allDeps)
36
+
37
+ // 检测状态管理
38
+ context.stateManagement = detectStateManagement(allDeps)
39
+
40
+ // 检测测试工具
41
+ context.testingTools = detectTestingTools(allDeps)
42
+
43
+ // 识别关键业务依赖
26
44
  const deps = Object.keys(pkg.dependencies || {})
27
- const criticalKeywords = ['stripe', 'payment', 'auth', 'prisma', 'db', 'axios', 'fetch', 'jotai', 'zustand', 'redux']
45
+ const criticalKeywords = [
46
+ 'stripe', 'payment', 'paypal', 'checkout',
47
+ 'auth', 'jwt', 'passport', 'oauth',
48
+ 'prisma', 'typeorm', 'sequelize', 'mongoose', 'db', 'sql',
49
+ 'axios', 'fetch', 'request', 'graphql', 'apollo',
50
+ 'socket', 'websocket', 'pusher', 'firebase',
51
+ 'sentry', 'datadog', 'analytics'
52
+ ]
28
53
 
29
54
  context.criticalDeps = deps.filter(dep =>
30
55
  criticalKeywords.some(kw => dep.toLowerCase().includes(kw))
@@ -40,13 +65,141 @@ export async function buildProjectContext() {
40
65
  }
41
66
 
42
67
  /**
43
- * 检测项目框架
68
+ * 检测项目框架和平台
44
69
  */
45
70
  function detectFramework(deps) {
46
- if (deps['next']) return 'Next.js'
47
- if (deps['react']) return 'React'
48
- if (deps['vue']) return 'Vue'
49
- if (deps['@angular/core']) return 'Angular'
50
- return 'Node.js'
71
+ const result = {
72
+ framework: 'Unknown',
73
+ platforms: []
74
+ }
75
+
76
+ // 检测 React Native
77
+ const hasRN = deps['react-native'] || deps['@react-native'] || deps['expo']
78
+
79
+ // 检测 Next.js
80
+ const hasNext = deps['next']
81
+
82
+ // 检测 React
83
+ const hasReact = deps['react']
84
+
85
+ // 检测 Vue
86
+ const hasVue = deps['vue'] || deps['@vue/core']
87
+ const hasNuxt = deps['nuxt']
88
+
89
+ // 检测 Angular
90
+ const hasAngular = deps['@angular/core']
91
+
92
+ // 检测 Svelte
93
+ const hasSvelte = deps['svelte']
94
+ const hasSvelteKit = deps['@sveltejs/kit']
95
+
96
+ // 检测 Taro (跨端框架)
97
+ const hasTaro = deps['@tarojs/taro'] || deps['@tarojs/runtime']
98
+
99
+ // 检测 Electron
100
+ const hasElectron = deps['electron']
101
+
102
+ // 组合判断
103
+ if (hasTaro) {
104
+ result.framework = 'Taro'
105
+ result.platforms.push('Mini-Program', 'H5', 'RN')
106
+ if (hasReact) result.framework = 'Taro (React)'
107
+ if (hasVue) result.framework = 'Taro (Vue)'
108
+ } else if (hasRN && hasNext) {
109
+ result.framework = 'React Native + Next.js (Monorepo)'
110
+ result.platforms.push('iOS', 'Android', 'Web')
111
+ } else if (hasRN) {
112
+ result.framework = 'React Native'
113
+ result.platforms.push('iOS', 'Android')
114
+ if (deps['expo']) result.framework = 'React Native (Expo)'
115
+ } else if (hasNext) {
116
+ result.framework = 'Next.js'
117
+ result.platforms.push('Web', 'SSR')
118
+ } else if (hasSvelteKit) {
119
+ result.framework = 'SvelteKit'
120
+ result.platforms.push('Web', 'SSR')
121
+ } else if (hasNuxt) {
122
+ result.framework = 'Nuxt.js'
123
+ result.platforms.push('Web', 'SSR')
124
+ } else if (hasAngular) {
125
+ result.framework = 'Angular'
126
+ result.platforms.push('Web')
127
+ } else if (hasSvelte) {
128
+ result.framework = 'Svelte'
129
+ result.platforms.push('Web')
130
+ } else if (hasVue) {
131
+ result.framework = 'Vue'
132
+ result.platforms.push('Web')
133
+ } else if (hasReact) {
134
+ result.framework = 'React'
135
+ result.platforms.push('Web')
136
+ } else if (hasElectron) {
137
+ result.framework = 'Electron'
138
+ result.platforms.push('Desktop')
139
+ } else if (Object.keys(deps).length > 0) {
140
+ result.framework = 'Node.js'
141
+ result.platforms.push('Backend')
142
+ }
143
+
144
+ return result
145
+ }
146
+
147
+ /**
148
+ * 检测 UI 库
149
+ */
150
+ function detectUILibraries(deps) {
151
+ const uiLibs = []
152
+
153
+ if (deps['antd']) uiLibs.push('Ant Design')
154
+ if (deps['@mui/material'] || deps['@material-ui/core']) uiLibs.push('Material-UI')
155
+ if (deps['@chakra-ui/react']) uiLibs.push('Chakra UI')
156
+ if (deps['@radix-ui/react-dialog']) uiLibs.push('Radix UI')
157
+ if (deps['tailwindcss']) uiLibs.push('Tailwind CSS')
158
+ if (deps['styled-components']) uiLibs.push('styled-components')
159
+ if (deps['@emotion/react']) uiLibs.push('Emotion')
160
+ if (deps['bootstrap']) uiLibs.push('Bootstrap')
161
+ if (deps['semantic-ui-react']) uiLibs.push('Semantic UI')
162
+ if (deps['react-native-paper']) uiLibs.push('React Native Paper')
163
+ if (deps['native-base']) uiLibs.push('NativeBase')
164
+
165
+ return uiLibs
166
+ }
167
+
168
+ /**
169
+ * 检测状态管理
170
+ */
171
+ function detectStateManagement(deps) {
172
+ const stateLibs = []
173
+
174
+ if (deps['jotai']) stateLibs.push('Jotai')
175
+ if (deps['zustand']) stateLibs.push('Zustand')
176
+ if (deps['redux'] || deps['@reduxjs/toolkit']) stateLibs.push('Redux')
177
+ if (deps['mobx'] || deps['mobx-react']) stateLibs.push('MobX')
178
+ if (deps['recoil']) stateLibs.push('Recoil')
179
+ if (deps['xstate'] || deps['@xstate/react']) stateLibs.push('XState')
180
+ if (deps['valtio']) stateLibs.push('Valtio')
181
+ if (deps['@tanstack/react-query']) stateLibs.push('TanStack Query')
182
+ if (deps['swr']) stateLibs.push('SWR')
183
+ if (deps['apollo-client'] || deps['@apollo/client']) stateLibs.push('Apollo Client')
184
+
185
+ return stateLibs
186
+ }
187
+
188
+ /**
189
+ * 检测测试工具
190
+ */
191
+ function detectTestingTools(deps) {
192
+ const testTools = []
193
+
194
+ if (deps['jest']) testTools.push('Jest')
195
+ if (deps['vitest']) testTools.push('Vitest')
196
+ if (deps['@testing-library/react']) testTools.push('@testing-library/react')
197
+ if (deps['@testing-library/react-native']) testTools.push('@testing-library/react-native')
198
+ if (deps['enzyme']) testTools.push('Enzyme')
199
+ if (deps['cypress']) testTools.push('Cypress')
200
+ if (deps['playwright']) testTools.push('Playwright')
201
+ if (deps['@playwright/test']) testTools.push('Playwright')
202
+
203
+ return testTools
51
204
  }
52
205
 
@@ -45,7 +45,22 @@ export async function analyze(options) {
45
45
  console.log('📦 Step 4: Reading project context...')
46
46
  const projectCtx = await buildProjectContext()
47
47
  console.log(` Framework: ${projectCtx.framework}`)
48
- console.log(` Critical deps: ${projectCtx.criticalDeps.length > 0 ? projectCtx.criticalDeps.join(', ') : 'None detected'}\n`)
48
+ if (projectCtx.platforms.length > 0) {
49
+ console.log(` Platforms: ${projectCtx.platforms.join(', ')}`)
50
+ }
51
+ if (projectCtx.uiLibraries.length > 0) {
52
+ console.log(` UI Libraries: ${projectCtx.uiLibraries.join(', ')}`)
53
+ }
54
+ if (projectCtx.stateManagement.length > 0) {
55
+ console.log(` State: ${projectCtx.stateManagement.join(', ')}`)
56
+ }
57
+ if (projectCtx.testingTools.length > 0) {
58
+ console.log(` Testing: ${projectCtx.testingTools.join(', ')}`)
59
+ }
60
+ if (projectCtx.criticalDeps.length > 0) {
61
+ console.log(` Critical deps: ${projectCtx.criticalDeps.join(', ')}`)
62
+ }
63
+ console.log()
49
64
 
50
65
  // 5. 构建 AI Prompt
51
66
  console.log('✍️ Step 5: Building AI analysis prompt...')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-unit-test-generator",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "description": "AI-powered unit test generator with smart priority scoring",
5
5
  "keywords": [
6
6
  "unit-test",