build / task (16.x, npm, macOS-latest) (push) Canceled after 0s
build / task (16.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, npm, windows-latest) (push) Canceled after 0s
build / task (16.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (16.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (16.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (16.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (16.x, yarn, windows-latest) (push) Canceled after 0s
build / task (18.x, npm, macOS-latest) (push) Canceled after 0s
build / task (18.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, npm, windows-latest) (push) Canceled after 0s
build / task (18.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (18.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (18.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (18.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (18.x, yarn, windows-latest) (push) Canceled after 0s
build / task (20.x, npm, macOS-latest) (push) Canceled after 0s
build / task (20.x, npm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, npm, windows-latest) (push) Canceled after 0s
build / task (20.x, pnpm, macOS-latest) (push) Canceled after 0s
build / task (20.x, pnpm, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, pnpm, windows-latest) (push) Canceled after 0s
build / task (20.x, yarn, macOS-latest) (push) Canceled after 0s
build / task (20.x, yarn, ubuntu-latest) (push) Canceled after 0s
build / task (20.x, yarn, windows-latest) (push) Canceled after 0s
152 lines
6.4 KiB
JavaScript
152 lines
6.4 KiB
JavaScript
const { test } = require("node:test")
|
|
const assert = require("node:assert/strict")
|
|
const fs = require("node:fs")
|
|
const path = require("node:path")
|
|
const ts = require("typescript")
|
|
const { parse, compileScript } = require("@vue/compiler-sfc")
|
|
const vue = require("vue")
|
|
|
|
// 执行页面真实的 setup 和 Vue 挂载/异步组件生命周期,子表只记录请求参数,无需新增浏览器测试依赖。
|
|
const filename = path.join(__dirname, "../src/views/hard/hard-sh/index.vue")
|
|
const descriptor = parse(fs.readFileSync(filename, "utf8"), { filename }).descriptor
|
|
const source = compileScript(descriptor, { id: "hard-sh-lifecycle-test" }).content
|
|
const compiled = ts.transpileModule(source, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020, esModuleInterop: true },
|
|
}).outputText
|
|
|
|
function mountPage() {
|
|
const requests = []
|
|
const exportQueries = []
|
|
const child = (kind) => vue.defineComponent({
|
|
setup(_, { expose }) {
|
|
const query = (params) => requests.push({ kind, params: JSON.parse(JSON.stringify(params)) })
|
|
expose({ doSearch: query, doCancel: query })
|
|
return () => vue.h("table")
|
|
},
|
|
})
|
|
const day = child("day")
|
|
const month = child("month")
|
|
const stubRequire = (id) => {
|
|
if (id.includes("hard-sh-by-day.vue")) return day
|
|
if (id.includes("hard-sh-by-month.vue")) return month
|
|
if (id.endsWith("AsyncTaskProgress.vue")) return {}
|
|
if (id.includes("hooks/batchExport")) return {
|
|
useBatchExport: () => ({ exportTaskConfig: {}, submitExport: query => exportQueries.push(JSON.parse(JSON.stringify(query))), handleExportSuccess() {}, handleExportFailure() {} }),
|
|
}
|
|
if (id.includes("api/hard/hard-total")) return {}
|
|
return require(id)
|
|
}
|
|
const loaded = { exports: {} }
|
|
const autoImports = ["ref", "reactive", "watch", "defineAsyncComponent", "onMounted", "nextTick"]
|
|
new Function("module", "exports", "require", ...autoImports, compiled)(
|
|
loaded, loaded.exports, stubRequire, ...autoImports.map((key) => vue[key]),
|
|
)
|
|
let bindings
|
|
const renderer = vue.createRenderer({
|
|
createElement: (type) => ({ type, children: [] }),
|
|
createText: (text) => ({ text }), createComment: (text) => ({ text }),
|
|
setText: (node, text) => { node.text = text }, setElementText: (node, text) => { node.text = text },
|
|
parentNode: (node) => node.parent,
|
|
nextSibling: (node) => node.parent?.children[node.parent.children.indexOf(node) + 1],
|
|
patchProp() {},
|
|
insert(node, parent, anchor = null) {
|
|
if (node.parent) node.parent.children.splice(node.parent.children.indexOf(node), 1)
|
|
node.parent = parent
|
|
const index = anchor ? parent.children.indexOf(anchor) : -1
|
|
parent.children.splice(index < 0 ? parent.children.length : index, 0, node)
|
|
},
|
|
remove(node) {
|
|
if (node.parent) node.parent.children.splice(node.parent.children.indexOf(node), 1)
|
|
},
|
|
})
|
|
const host = vue.defineComponent({
|
|
setup() {
|
|
bindings = loaded.exports.default.setup({}, { expose() {} })
|
|
bindings.draggableDepMchTreeRef.value = { resetData() {} }
|
|
return () => bindings.activeTab.value === "MCH"
|
|
? vue.h(bindings.HardShByDay, { ref: bindings.hardShByDayRef })
|
|
: vue.h(bindings.HardShByMonth, { ref: bindings.hardShByMonthRef })
|
|
},
|
|
})
|
|
const app = renderer.createApp(host)
|
|
app.mount({ children: [] })
|
|
return { bindings, requests, exportQueries, close: () => app.unmount() }
|
|
}
|
|
|
|
async function settle() {
|
|
await new Promise((resolve) => setImmediate(resolve))
|
|
await vue.nextTick()
|
|
}
|
|
|
|
test("初次打开异步子表只查询一次,挂载前点击查询也不会报错", async () => {
|
|
const page = mountPage()
|
|
try {
|
|
assert.doesNotThrow(() => page.bindings.search())
|
|
await settle()
|
|
assert.equal(page.requests.length, 1)
|
|
assert.equal(page.requests[0].kind, "day")
|
|
assert.equal(page.requests[0].params.payTimeList.length, 2)
|
|
assert.equal(page.requests[0].params.payTimeYearStr, "")
|
|
} finally { page.close() }
|
|
})
|
|
|
|
test("切换日/月子表每次只查询一次,查询条件重置后再发送", async () => {
|
|
const page = mountPage()
|
|
try {
|
|
await settle()
|
|
page.bindings.state.queryForm.merchantId = "999"
|
|
page.bindings.activeTab.value = "MONTH"
|
|
await settle()
|
|
assert.equal(page.requests.length, 2)
|
|
assert.equal(page.requests[1].kind, "month")
|
|
assert.equal(page.requests[1].params.merchantId, undefined)
|
|
assert.match(page.requests[1].params.payTimeYearStr, /^\d{4}$/)
|
|
assert.deepEqual(page.requests[1].params.payTimeList, [])
|
|
page.bindings.activeTab.value = "MCH"
|
|
await settle()
|
|
assert.equal(page.requests.length, 3)
|
|
assert.equal(page.requests[2].kind, "day")
|
|
assert.equal(page.requests[2].params.payTimeYearStr, "")
|
|
assert.equal(page.requests[2].params.payTimeList.length, 2)
|
|
} finally { page.close() }
|
|
})
|
|
|
|
test("按月重置和导出清除隐藏日范围,按商户导出保留精确时间边界", async () => {
|
|
const page = mountPage()
|
|
try {
|
|
await settle()
|
|
page.bindings.activeTab.value = "MONTH"
|
|
await settle()
|
|
page.bindings.cancel()
|
|
assert.deepEqual(page.requests.at(-1).params.payTimeList, [])
|
|
assert.match(page.requests.at(-1).params.payTimeYearStr, /^\d{4}$/)
|
|
page.bindings.state.queryForm.payTimeList = ["2026-09-01 00:00:00", "2026-10-01 00:00:00"]
|
|
page.bindings.exportExcel()
|
|
assert.deepEqual(page.exportQueries[0].payTimeList, [])
|
|
assert.equal(page.bindings.exportTaskConfig.redisKey, "hard:export:merchant-month")
|
|
page.bindings.activeTab.value = "MCH"
|
|
await settle()
|
|
const timeRange = ["2026-09-01 00:00:00", "2026-10-01 00:00:00"]
|
|
Object.assign(page.bindings.state.queryForm, { payTimeList: timeRange, payTimeYearStr: "2025", userDeptIds: ["1875013738914156546"], isInclude: false })
|
|
page.bindings.exportExcel()
|
|
assert.deepEqual(page.exportQueries[1].payTimeList, timeRange)
|
|
assert.equal(page.exportQueries[1].payTimeYearStr, "")
|
|
assert.deepEqual(page.exportQueries[1].userDeptIds, ["1875013738914156546"])
|
|
assert.equal(page.exportQueries[1].isInclude, false)
|
|
assert.equal(page.bindings.exportTaskConfig.redisKey, "hard:export:merchant")
|
|
} finally { page.close() }
|
|
})
|
|
|
|
test("部门筛选和手动刷新仍各发出一次请求", async () => {
|
|
const page = mountPage()
|
|
try {
|
|
await settle()
|
|
page.bindings.handleGetSelectNode({ id: "10" }, [{ id: "11" }], false, "DEPT")
|
|
assert.equal(page.requests.length, 2)
|
|
assert.deepEqual(page.requests[1].params.userDeptIds, ["11"])
|
|
assert.equal(page.requests[1].params.isInclude, true)
|
|
page.bindings.search()
|
|
assert.equal(page.requests.length, 3)
|
|
} finally { page.close() }
|
|
})
|