| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- 'use strict';
- const assert = require('node:assert/strict');
- const fs = require('node:fs');
- const path = require('node:path');
- const vm = require('node:vm');
- /**
- * @param {string} source - 页面源码
- * @param {string} name - 导出函数名
- * @returns {string} 可独立执行的函数源码
- */
- function extractFunction(source, name) {
- const pattern = new RegExp('export function ' + name + '\\(');
- const match = pattern.exec(source);
- assert.ok(match, '缺少方法 ' + name);
- const nextExport = source.indexOf('\nexport function ', match.index + match[0].length);
- return source.slice(match.index, nextExport < 0 ? source.length : nextExport).replace(/^export /, '');
- }
- const defaultSource = path.resolve(__dirname, '../src/timecard-repair-lifecycle.oyd.jsx');
- const sourcePath = process.argv[2] ? path.resolve(process.argv[2]) : defaultSource;
- const source = fs.readFileSync(sourcePath, 'utf8');
- assert.doesNotMatch(source, /window\._this/, '渲染不得依赖跨页面共享的 window._this');
- assert.match(source, /var _this = this;[\s\S]*if \(!_this \|\| !_this\.state/, 'renderJsx 应使用当前页面实例');
- let removedEvent = null;
- let removedHandler = null;
- let clearedTimer = null;
- let releasedTimer = false;
- const methods = vm.runInNewContext(
- ['refreshTimecardView', 'forceUpdate', 'didUnmount']
- .map((name) => extractFunction(source, name)).join('\n')
- + '\n({refreshTimecardView, forceUpdate, didUnmount})',
- {
- window: {
- removeEventListener(event, handler) {
- removedEvent = event;
- removedHandler = handler;
- },
- },
- clearTimeout(timer) {
- clearedTimer = timer;
- },
- },
- );
- const resizeHandler = () => {};
- let setStateCount = 0;
- let forceUpdateCount = 0;
- const context = {
- _tcDisposed: false,
- _tcBeisenLeaveRequestKey: 'active-request',
- _tcRepairContextRequestKey: 'active-repair-request',
- _tcRepairContextPollTimers: [{
- timerId: 123,
- resolve() { releasedTimer = true; },
- }],
- _tcResizeHandler: resizeHandler,
- setState() { setStateCount += 1; },
- forceUpdate() { forceUpdateCount += 1; },
- };
- methods.didUnmount.call(context);
- assert.equal(context._tcDisposed, true);
- assert.equal(context._tcBeisenLeaveRequestKey, '__TIMECARD_PAGE_DISPOSED__');
- assert.equal(context._tcRepairContextRequestKey, '__TIMECARD_PAGE_DISPOSED__');
- assert.equal(context._tcRepairContextPollTimers.length, 0);
- assert.equal(clearedTimer, 123);
- assert.equal(releasedTimer, true);
- assert.equal(context._tcResizeHandler, null);
- assert.equal(removedEvent, 'resize');
- assert.equal(removedHandler, resizeHandler);
- methods.refreshTimecardView.call(context);
- methods.forceUpdate.call(context);
- assert.equal(forceUpdateCount, 0, '卸载后不得继续 forceUpdate');
- assert.equal(setStateCount, 0, '卸载后不得继续 setState');
- console.log('PASS 补填页面切换时清理实例、监听和异步刷新');
|