@ranger1/dx 0.1.90 → 0.1.91

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.
@@ -1,3 +1,5 @@
1
+ import { existsSync, readFileSync } from 'node:fs'
2
+ import { join, relative } from 'node:path'
1
3
  import { logger } from '../../logger.js'
2
4
  import { confirmManager } from '../../confirm.js'
3
5
  import { execManager } from '../../exec.js'
@@ -132,6 +134,35 @@ export async function handleTest(cli, args) {
132
134
  : `运行单个E2E测试文件: ${testPath}`
133
135
  }
134
136
 
137
+ if (testNamePattern) {
138
+ logger.step(`运行 ${type} 测试用例: ${testNamePattern} (文件: ${testPath})`)
139
+ } else {
140
+ logger.step(`运行单个 ${type} 测试: ${testPath}`)
141
+ }
142
+ } else if (type === 'unit' && testPath) {
143
+ let command = String(testConfig.command).trim()
144
+ const useDirectPathArg = shouldUseDirectPathArg(command)
145
+ const normalizedTestPath = useDirectPathArg
146
+ ? normalizeUnitTestPathForCommand(cli, command, testPath)
147
+ : testPath
148
+ const forwardedArgs = useDirectPathArg
149
+ ? [shellEscape(normalizedTestPath)]
150
+ : [`--runTestsByPath ${shellEscape(normalizedTestPath)}`]
151
+
152
+ if (testNamePattern) {
153
+ forwardedArgs.push(`-t ${shellEscape(testNamePattern)}`)
154
+ }
155
+
156
+ command += ` ${forwardedArgs.join(' ')}`
157
+
158
+ testConfig = {
159
+ ...testConfig,
160
+ command,
161
+ description: testNamePattern
162
+ ? `运行单个单元测试文件的特定用例: ${testPath} -> ${testNamePattern}`
163
+ : `运行单个单元测试文件: ${testPath}`,
164
+ }
165
+
135
166
  if (testNamePattern) {
136
167
  logger.step(`运行 ${type} 测试用例: ${testNamePattern} (文件: ${testPath})`)
137
168
  } else {
@@ -148,6 +179,67 @@ function shellEscape(value) {
148
179
  return `'${String(value).replace(/'/g, `'\\''`)}'`
149
180
  }
150
181
 
182
+ function shouldUseDirectPathArg(command) {
183
+ const text = String(command || '')
184
+ return (
185
+ /\bnx\s+test\b/.test(text) ||
186
+ /\bnx\.js\s+test\b/.test(text) ||
187
+ /\bvitest\s+run\b/.test(text)
188
+ )
189
+ }
190
+
191
+ function normalizeUnitTestPathForCommand(cli, command, testPath) {
192
+ const rawPath = String(testPath || '')
193
+ if (!rawPath) return rawPath
194
+
195
+ if (/\bvitest\s+run\b/.test(String(command || ''))) {
196
+ return rawPath
197
+ }
198
+
199
+ const vitestProjectCwd = resolveNxVitestProjectCwd(cli, command)
200
+ if (!vitestProjectCwd) return rawPath
201
+
202
+ const projectRoot = cli?.projectRoot || process.cwd()
203
+ const absoluteProjectCwd = join(projectRoot, vitestProjectCwd)
204
+ const absoluteTestPath = join(projectRoot, rawPath)
205
+ const relativePath = relative(absoluteProjectCwd, absoluteTestPath)
206
+
207
+ if (!relativePath || relativePath.startsWith('..')) {
208
+ return rawPath
209
+ }
210
+
211
+ return relativePath
212
+ }
213
+
214
+ function resolveNxVitestProjectCwd(cli, command) {
215
+ const projectRoot = cli?.projectRoot || process.cwd()
216
+ const nxTarget = extractNxTestTarget(command)
217
+ if (!nxTarget) return null
218
+
219
+ const projectConfigPath = join(projectRoot, 'apps', nxTarget, 'project.json')
220
+ if (!existsSync(projectConfigPath)) return null
221
+
222
+ try {
223
+ const projectConfig = JSON.parse(readFileSync(projectConfigPath, 'utf8'))
224
+ const testTarget = projectConfig?.targets?.test
225
+ const command = String(testTarget?.options?.command || '')
226
+ const cwd = testTarget?.options?.cwd
227
+ if (!/\bvitest\s+run\b/.test(command)) return null
228
+ if (typeof cwd !== 'string' || cwd.trim().length === 0) return null
229
+ return cwd
230
+ } catch {
231
+ return null
232
+ }
233
+ }
234
+
235
+ function extractNxTestTarget(command) {
236
+ const text = String(command || '').trim()
237
+ const match =
238
+ text.match(/\bnx(?:\.js)?\s+test\s+([^\s]+)/) ||
239
+ text.match(/\bnx(?:\.js)?\s+run\s+([^:\s]+):test\b/)
240
+ return match?.[1] || null
241
+ }
242
+
151
243
  export async function handleLint(cli, args) {
152
244
  void args
153
245
  const baseConfig = cli.commands.lint
package/lib/cli/help.js CHANGED
@@ -95,6 +95,7 @@ export function showHelp() {
95
95
  ' dx test e2e backend apps/backend/e2e/activity/activity.admin.e2e-spec.ts # 运行单个E2E测试文件',
96
96
  ' dx test e2e backend apps/backend/e2e/activity/activity.admin.e2e-spec.ts -t "should list all activity definitions" # 运行特定测试用例',
97
97
  ' dx test e2e quantify apps/quantify/e2e/health/health.e2e-spec.ts # 运行 Quantify E2E 文件',
98
+ ' dx test unit backend apps/backend/src/modules/chat/chat.service.spec.ts # 运行单个后端单测文件',
98
99
  ' dx test e2e all # 不受支持,必须指定 target 和 path',
99
100
  ' dx deploy front --staging # 部署前端到 Vercel(staging)',
100
101
  ' dx deploy backend --prod # 构建 backend 制品并上传/部署到远端主机',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ranger1/dx",
3
- "version": "0.1.90",
3
+ "version": "0.1.91",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {