@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.
- package/lib/cli/commands/core.js +92 -0
- package/lib/cli/help.js +1 -0
- package/package.json +1 -1
package/lib/cli/commands/core.js
CHANGED
|
@@ -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 制品并上传/部署到远端主机',
|