我目前正在使用在普通JavaScript上制作的样板之上的TypeScript配置项目。我的问题出现在preLaunchTask中的TS编译期间。我无法在本地导入的自定义EventEmitter上访问'report'属性。这是TS中的以下错误:
error TS2339: Property 'report' does not exist on type 'EventEmitter'.
下面是 testing.ts 文件:
'use strict';
import cors from 'cors';
import fs from 'fs';
import runner from '../../test-runner';
import express from 'express';
export default function (app: express.Application) {
app.route('/_api/server.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/server.js', function (err, data) {
if (err) return next(err);
res.send(data.toString());
});
});
app.route('/_api/routes/api.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/routes/api.js', function (err, data) {
if (err) return next(err);
res.type('txt').send(data.toString());
});
});
app.route('/_api/controllers/convertHandler.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/controllers/convertHandler.js', function (err, data) {
if (err) return next(err);
res.type('txt').send(data.toString());
});
});
var error;
app.get('/_api/get-tests', cors(), function (req: express.Request, res: express.Response, next) {
console.log(error);
if (!error && process.env.NODE_ENV === 'test') return next();
res.json({ status: 'unavailable' });
},
function (req: express.Request, res: express.Response, next: Function) {
if (!runner.report) return next();
res.json(testFilter(runner.report, req.query.type, req.query.n));
},
function (req: express.Request, res: express.Response) {
runner.on('done', function (report) {
process.nextTick(() => res.json(testFilter(runner.report, req.query.type, req.query.n)));
});
});
app.get('/_api/app-info', function (req: express.Request, res: express.Response) {
var hs = Object.keys(res.header)
.filter(h => !h.match(/^access-control-\w+/));
var hObj = {};
hs.forEach(h => { hObj[h] = res.header[h] });
delete res.header['strict-transport-security'];
res.json({ headers: hObj });
});
};
function testFilter(tests, type, n) {
var out;
switch (type) {
case 'unit':
out = tests.filter(t => t.context.match('Unit Tests'));
break;
case 'functional':
out = tests.filter(t => t.context.match('Functional Tests') && !t.title.match('#example'));
break;
default:
out = tests;
}
if (n !== undefined) {
return out[n] || out;
}
return out;
}
这是我正在尝试导入的测试运行器:
var analyser = require('./assertion-analyser');
var EventEmitter = require('events').EventEmitter;
var Mocha = require('mocha'),
fs = require('fs'),
path = require('path');
var mocha = new Mocha();
var testDir = './tests'
// Add each .js file to the mocha instance
fs.readdirSync(testDir).filter((file) => {
// Only keep the .js files
return file.substr(-3) === '.js';
}).forEach((file) => {
mocha.addFile(
path.join(testDir, file)
);
});
var emitter = new EventEmitter();
emitter.run = () => {
let tests = [];
var context = "";
var separator = ' -> ';
// Run the tests.
try {
var runner = mocha.ui('tdd').run()
.on('test end', (test) => {
// remove comments
var body = test.body.replace(/\/\/.*\n|\/\*.*\*\//g, '');
// collapse spaces
body = body.replace(/\s+/g,' ');
var obj = {
title: test.title,
context: context.slice(0, -separator.length),
state: test.state,
body: body,
assertions: analyser(body)
};
tests.push(obj);
})
.on('end', () => {
emitter.report = tests;
emitter.emit('done', tests)
})
.on('suite', (s) => {
context += (s.title + separator);
})
.on('suite end', (s) => {
context = context.slice(0, -(s.title.length + separator.length))
})
} catch(e) {
throw(e);
}
};
module.exports = emitter;
还有我的 tsconfig.json 文件:
{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"lib": [
"dom",
"es6"
],
"outDir": "public",
"sourceMap": true
},
"include": [
"src",
]
}
我试图尽我最大的努力来缩小问题的范围,但我对为什么进出口似乎没有对彼此的回应感到困惑。最近,我一直在解决许多重新配置错误,所以我的大脑可能对此太想了。请随时告诉我是否还有其他可用的代码。
答案 0 :(得分:0)
我调整了我的'preLaunchTask'以使其完全符合我的TS编译器脚本名称-这不是问题。我收到的TypeScript错误是我的测试运行器上的'report'属性为空,这是由于测试运行器文件中的语法较旧,这是由于原始测试运行器作者直接将属性分配给EventEmitter的一个实例。为了使TS编译器满意,我改为将测试运行程序代码调整为基于类的设置,在构造函数中添加“报告”,从而避免了原始测试运行程序的“ void”或“()=> void”返回值。 / p>
test-runner2.js :
import analyser from '../../assertion-analyser';
import { EventEmitter } from 'events';
import Mocha from 'mocha';
import fs from 'fs';
import path from 'path';
import { connect } from 'http2';
const mocha = new Mocha();
const testDir = './tests';
// Add each .js file to the mocha instance.
fs.readdirSync(testDir).filter(file => {
return file.substr(-3) === '.js';
}).forEach(file => {
mocha.addFile(
path.join(testDir, file)
);
});
class TestEmitter extends EventEmitter {
constructor() {
this.report = []
}
run = () => {
// Run the tests...
let tests = [];
let context = '';
let separator = ' ~> ';
try {
const runner = mocha.ui('tdd').run()
.on('test end', test => {
// remove comments
let body = test.body.replace(/\/\/.*\n|\/\*.*\\/g, '');
// collapse spaces
body = body.replace(/\s+/g, '');
const obj = {
title: test.title,
context: context.slice(0, -separator.length),
state: test.state,
body: body,
assertions: analyser(body)
};
tests.push(obj);
})
.on('end', () => {
emitter.report = tests;
emitter.emit('done', tests)
})
.on('suite', (s) => {
context += (s.title + separator);
})
.on('suite end', (s) => {
context = context.slice(0, -(s.title.length + separator.length))
});
} catch(err) {
throw(err);
}
}
}
export default TestEmitter;
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"lib": [
"dom",
"es6"
],
"outDir": "public",
"sourceMap": true
},
"include": [
"src",
]
}
希望这可以帮助其他尝试将TS添加到普通JS样板中的人。我也发布了我的配置文件。使用class
节点extends
默认类的EventEmitter
。