Skip to content

Commit

Permalink
add test tree -1
Browse files Browse the repository at this point in the history
Signed-off-by: issacto <[email protected]>
  • Loading branch information
issacto committed Aug 18, 2023
1 parent 4780ae5 commit b62d213
Show file tree
Hide file tree
Showing 13 changed files with 527 additions and 76 deletions.
179 changes: 135 additions & 44 deletions vs code extension/client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { startCutLanguageClientServer, stopCutLanguageClientServer } from './ser
import { ResultWebView } from './services/ResultWebView';
import { handleCobolCheckOut } from './Helpers/ExtensionHelper';
import path = require('path');
import { getContentFromFilesystem, MarkdownTestData, TestCase, testData, TestFile } from "./services/testTree";
import { getContentFromFilesystem, MarkdownTestData, TestCase, testData, TestFile, TestHeading } from "./services/TestTree";


let externalVsCodeInstallationDir = vscode.extensions.getExtension("openmainframeproject.cobol-check-extension").extensionPath;
Expand Down Expand Up @@ -91,52 +91,62 @@ export function activate(context: ExtensionContext) {
return startTestRun(request);
}

const l = fileChangedEmitter.event(uri => startTestRun(
const l = fileChangedEmitter.event(uri => {

return startTestRun(

new vscode.TestRunRequest2(
[getOrCreateFile(ctrl, uri).file],
undefined,
request.profile,
true
),
));
)});
cancellation.onCancellationRequested(() => l.dispose());
};

const startTestRun = (request: vscode.TestRunRequest) => {
const queue: { test: vscode.TestItem; data: TestCase }[] = [];
const queue: { test: vscode.TestItem; data: TestCase | TestHeading }[] = [];
const run = ctrl.createTestRun(request);
// map of file uris to statements on each line:
const coveredLines = new Map</* file uri */ string, (vscode.StatementCoverage | undefined)[]>();

const discoverTests = async (tests: Iterable<vscode.TestItem>) => {
for (const test of tests) {
if (request.exclude?.includes(test)) {
continue;
}

const data = testData.get(test);
if (data instanceof TestCase) {
run.enqueued(test);
queue.push({ test, data });
} else {
if (data instanceof TestFile && !data.didResolve) {
await data.updateFromDisk(ctrl, test);
if(tests){
for (const test of tests) {
if (request.exclude?.includes(test)) {
continue;
}

await discoverTests(gatherTestItems(test.children));
}
const data = testData.get(test);
if (data instanceof TestCase
|| (data instanceof TestHeading && test.children.size==0)
) {
run.enqueued(test);
queue.push({ test, data });
} else {
if (data instanceof TestFile ) {
await data.updateFromDisk(ctrl, test);
}

await discoverTests(gatherTestItems(test));
}

if (test.uri && !coveredLines.has(test.uri.toString())) {
try {
const lines = (await getContentFromFilesystem(test.uri)).split('\n');
coveredLines.set(
test.uri.toString(),
lines.map((lineText, lineNo) =>
lineText.trim().length ? new vscode.StatementCoverage(0, new vscode.Position(lineNo, 0)) : undefined
)
);
} catch {
// ignored
if (test.uri && !coveredLines.has(test.uri.toString())) {
try {
const lines = (await getContentFromFilesystem(test.uri,true))
if(lines!=""){
const lineArr = lines.split('\n');
coveredLines.set(
test.uri.toString(),
lineArr.map((lineText, lineNo) =>
lineText.trim().length ? new vscode.StatementCoverage(0, new vscode.Position(lineNo, 0)) : undefined
)
);
}
} catch {
// ignored
}
}
}
}
Expand All @@ -151,7 +161,7 @@ export function activate(context: ExtensionContext) {
run.started(test);
await data.run(test, run);
}

const lineNo = test.range!.start.line;
const fileCoverage = coveredLines.get(test.uri!.toString());
if (fileCoverage) {
Expand All @@ -160,7 +170,6 @@ export function activate(context: ExtensionContext) {

run.appendOutput(`Completed ${test.id}\r\n`);
}

run.end();
};

Expand All @@ -180,7 +189,7 @@ export function activate(context: ExtensionContext) {
},
};

discoverTests(request.include ?? gatherTestItems(ctrl.items)).then(runTestQueue);
discoverTests(request.include ?? gatherTestItemsFromCollection(ctrl.items)).then(runTestQueue);
};

ctrl.refreshHandler = async () => {
Expand All @@ -205,7 +214,6 @@ export function activate(context: ExtensionContext) {
if (e.uri.scheme !== 'file') {
return;
}

if (!e.uri.path.endsWith('.cut')) {
return;
}
Expand All @@ -228,26 +236,108 @@ export function deactivate() {
stopCutLanguageClientServer();
}

function createDirItems( controller:vscode.TestController, uri: vscode.Uri){

const dirArr = vscode.workspace.asRelativePath(uri.fsPath).split("/")
const rootDir = uri.fsPath.replace(vscode.workspace.asRelativePath(uri.fsPath),"")
const rootUri = rootDir+dirArr[0]
let tmpUri = vscode.Uri.file(rootUri);

var file :vscode.TestItem = null;
controller.createTestItem
var data = null
if(!controller.items.get(rootUri)){
file = controller.createTestItem(rootUri, dirArr[0], tmpUri);
controller.items.add(file);
data = new TestFile()
testData.set(file, data);
file.canResolveChildren = true;
}
else{
file = controller.items.get(rootUri)
data = testData.get(file)
}


var prevFile: vscode.TestItem = file
var tmpDir = rootUri

for(var i =1;i<dirArr.length;i++){
tmpDir = tmpDir + "/" + dirArr[i]
const existing = file.children.get(tmpDir);
if(!existing){
tmpUri = vscode.Uri.file(tmpDir);
const tmpFile = controller.createTestItem(tmpDir, dirArr[i], tmpUri);
const tmpData = new TestFile();
testData.set(tmpFile, tmpData);
tmpFile.canResolveChildren = true;

// add to existing tree structure
prevFile.children.add(tmpFile)

prevFile=tmpFile;
}else{
prevFile = existing;
}
}
return {file,data};
}

function getDirItem( controller:vscode.TestController, uri: vscode.Uri){
const dirArr = vscode.workspace.asRelativePath(uri.fsPath).split("/")
const rootDir = uri.fsPath.replace(vscode.workspace.asRelativePath(uri.fsPath),"")

var tmpDir = rootDir+dirArr[0];

var existing :vscode.TestItem = controller.items.get(tmpDir);

if(!existing) return null

for(var i = 1; i<dirArr.length ;i++){
tmpDir = tmpDir + "/" + dirArr[i];
existing = existing.children.get(tmpDir);
if(!existing) return null
}
return existing;
}

// Functions for activating tests
function getOrCreateFile(controller: vscode.TestController, uri: vscode.Uri) {
const existing = controller.items.get(uri.toString());
const existing = getDirItem(controller,uri);
if (existing) {
return { file: existing, data: testData.get(existing) as TestFile };
}
return createDirItems(controller,uri);
}

const file = controller.createTestItem(uri.toString(), uri.path.split('/').pop()!, uri);
controller.items.add(file);

const data = new TestFile();
testData.set(file, data);
function gatherTestItems(test: vscode.TestItem) {
// testHeading
const data : MarkdownTestData = testData.get(test)
var items: vscode.TestItem[] = [];
if(data instanceof TestFile){
test.children.forEach(item => {items=items.concat(gatherTestItems(item))});
return items;
}
else if(data instanceof TestHeading && !test.children){
items.push(test)
return items;
}else if(data instanceof TestHeading && test.children){
test.children.forEach(item => items.push(item));
return items;
}
else if(data instanceof TestCase){
items.push(test);
return items;
}
return items;

file.canResolveChildren = true;
return { file, data };
}

function gatherTestItems(collection: vscode.TestItemCollection) {
const items: vscode.TestItem[] = [];
collection.forEach(item => items.push(item));
function gatherTestItemsFromCollection(collection: vscode.TestItemCollection) {
var items: vscode.TestItem[] = [];
collection.forEach(item => {
items = items.concat(gatherTestItems(item))
});
return items;
}

Expand All @@ -270,6 +360,7 @@ async function findInitialFiles(controller: vscode.TestController, pattern: vsco

function startWatchingWorkspace(controller: vscode.TestController, fileChangedEmitter: vscode.EventEmitter<vscode.Uri> ) {
return getWorkspaceTestPatterns().map(({ workspaceFolder, pattern }) => {

const watcher = vscode.workspace.createFileSystemWatcher(pattern);

watcher.onDidCreate(uri => {
Expand Down
41 changes: 22 additions & 19 deletions vs code extension/client/src/services/CobolCheckInputParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,30 @@ export const parseMarkdown = (text: string, events: {
onTest(range: vscode.Range, name: string): void;
onHeading(range: vscode.Range, name: string, depth: number): void;
}) => {
const lines = text.split('\n');

for (let lineNo = 0; lineNo < lines.length; lineNo++) {
const line = lines[lineNo];

const testCase = testCaseRegex.exec(line);
if (testCase) {
var [,pounds, name] = testCase;
name = name.replace(/['"]+/g, '');
const range = new vscode.Range(new vscode.Position(lineNo, 0), new vscode.Position(lineNo, testCase[0].length));
events.onTest(range, name);
continue;
}

if(text!=null){

const testSuite = testSuiteRegex.exec(line);
if (testSuite) {
var [,pounds, name] = testSuite;
name = name.replace(/['"]+/g, '');
const range = new vscode.Range(new vscode.Position(lineNo, line.indexOf(pounds)), new vscode.Position(lineNo, line.indexOf(name) + name.length));
events.onHeading(range, name, 1);
const lines = text.split('\n');
for (let lineNo = 0; lineNo < lines.length; lineNo++) {
const line = lines[lineNo];

const testCase = testCaseRegex.exec(line);
if (testCase) {
var [,pounds, name] = testCase;
name = name.replace(/['"]+/g, '');
const range = new vscode.Range(new vscode.Position(lineNo, 0), new vscode.Position(lineNo, testCase[0].length));
events.onTest(range, name);
continue;
}


const testSuite = testSuiteRegex.exec(line);
if (testSuite) {
var [,pounds, name] = testSuite;
name = name.replace(/['"]+/g, '');
const range = new vscode.Range(new vscode.Position(lineNo, line.indexOf(pounds)), new vscode.Position(lineNo, line.indexOf(name) + name.length));
events.onHeading(range, name, 1);
}
}
}
};
Loading

0 comments on commit b62d213

Please sign in to comment.