Skip to content

Commit

Permalink
[#148] Refactor findTopSection into findSection which uses relative path
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanluker committed Jul 29, 2018
1 parent 3860328 commit deee3d1
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 108 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ debug.log
npm-debug.log
__pycache__
.coverage
example/.vscode
example/.vscode
venv
4 changes: 2 additions & 2 deletions @types/cobertura-parse/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare namespace parse {
function parseContent(str: string, cb: (err: Error, data: Array<Section>) => void): void
function parseContent(str: string, cb: (err: Error, data: Array<Section>) => void, absPath: string): void

interface LineDetail {
hit: number,
Expand Down Expand Up @@ -47,4 +47,4 @@ declare namespace parse {

declare module "cobertura-parse" {
export = parse;
}
}
4 changes: 4 additions & 0 deletions example/python/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
python modules:
- `pytest`
- `pytest-cov`

Use the command below to generate a test xml file
```py.test foobar --cov-report xml:cov.xml --cov foobar```
4 changes: 2 additions & 2 deletions example/python/cov.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" ?>
<coverage branch-rate="0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.75" lines-covered="9" lines-valid="12" timestamp="1524417716681" version="4.4.1">
<coverage branch-rate="0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.75" lines-covered="9" lines-valid="12" timestamp="1532884218709" version="4.5.1">
<!-- Generated by coverage.py: https://coverage.readthedocs.io -->
<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
<sources>
<source>/home/ryanluker/dev/vscode-coverage-gutters/example/python/foobar</source>
<source>/home/ryan/dev/vscode-coverage-gutters/example/python/foobar</source>
</sources>
<packages>
<package branch-rate="0" complexity="0" line-rate="1" name=".">
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"coverage-gutters.altSfCompare": {
"type": "boolean",
"default": true,
"description": "uses a relative method of comparing lcov source file paths"
"description": "DEPRECATED: uses a relative method of comparing lcov source file paths"
},
"coverage-gutters.highlightlight": {
"type": "string",
Expand Down
8 changes: 4 additions & 4 deletions src/coverageservice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {FilesLoader} from "./filesloader";
import {LcovParser} from "./lcovparser";
import {Renderer} from "./renderer";
import {Reporter} from "./reporter";
import { TopSectionFinder } from "./topSectionFinder";
import {SectionFinder} from "./sectionFinder";

enum Status {
ready = "READY",
Expand All @@ -33,7 +33,7 @@ export class CoverageService {
private lcovWatcher: FileSystemWatcher;
private xmlWatcher: FileSystemWatcher;
private editorWatcher: Disposable;
private topSectionFinder: TopSectionFinder;
private sectionFinder: SectionFinder;

private cache: Map<string, Section>;
private status: Status;
Expand All @@ -49,13 +49,13 @@ export class CoverageService {
this.updateServiceState(Status.initializing);
this.cache = new Map();
this.filesLoader = new FilesLoader(configStore);
this.topSectionFinder = new TopSectionFinder(
this.sectionFinder = new SectionFinder(
this.outputChannel,
this.eventReporter,
);
this.renderer = new Renderer(
configStore,
this.topSectionFinder,
this.sectionFinder,
);
this.lcovParser = new LcovParser(configStore);
}
Expand Down
6 changes: 3 additions & 3 deletions src/filesloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ export class FilesLoader {
* Takes files and converts to data strings for coverage consumption
* @param files files that are to turned into data strings
*/
public async loadDataFiles(files: Set<string>): Promise<Set<string>> {
public async loadDataFiles(files: Set<string>): Promise<Map<string, string>> {
// Load the files and convert into data strings
const dataFiles = new Set<string>();
const dataFiles = new Map<string, string>();
for (const file of files) {
dataFiles.add(await this.load(file));
dataFiles.set(file, await this.load(file));
}
return dataFiles;
}
Expand Down
16 changes: 10 additions & 6 deletions src/lcovparser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ export class LcovParser {
* Extracts coverage sections of type xml and lcov
* @param files array of coverage files in string format
*/
public async filesToSections(files: Set<string>): Promise<Map<string, Section>> {
public async filesToSections(files: Map<string, string>): Promise<Map<string, Section>> {
let coverages = new Map<string, Section>();

for (const file of files) {
const value = file[1];
const key = file[0];

// file is an array
let coverage = new Map<string, Section>();
if (file.includes("<?xml")) {
coverage = await this.xmlExtract(file);
if (value.includes("<?xml")) {
coverage = await this.xmlExtract(value, key);
} else {
coverage = await this.lcovExtract(file);
coverage = await this.lcovExtract(value);
}
// add new coverage map to existing coverages generated so far
coverages = new Map([...coverages, ...coverage]);
Expand All @@ -30,7 +34,7 @@ export class LcovParser {
return coverages;
}

private xmlExtract(xmlFile: string) {
private xmlExtract(xmlFile: string, absolutePath: string) {
return new Promise<Map<string, Section>>((resolve, reject) => {
try {
parseContent(xmlFile, (err, data) => {
Expand All @@ -41,7 +45,7 @@ export class LcovParser {
sections.set(section.file, section);
});
return resolve(sections);
});
}, absolutePath);
} catch (error) {
return reject(error);
}
Expand Down
17 changes: 9 additions & 8 deletions src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from "vscode";
import {IConfigStore} from "./config";
import {setLastCoverageLines} from "./exportsapi";
import {TopSectionFinder} from "./topSectionFinder";
import {SectionFinder} from "./sectionFinder";

export interface ICoverageLines {
full: Range[];
Expand All @@ -15,14 +15,14 @@ export interface ICoverageLines {

export class Renderer {
private configStore: IConfigStore;
private topSectionFinder: TopSectionFinder;
private sectionFinder: SectionFinder;

constructor(
configStore: IConfigStore,
topSectionFinder: TopSectionFinder,
sectionFinder: SectionFinder,
) {
this.configStore = configStore;
this.topSectionFinder = topSectionFinder;
this.sectionFinder = sectionFinder;
}

/**
Expand Down Expand Up @@ -51,12 +51,13 @@ export class Renderer {
coverageLines.none = [];
coverageLines.partial = [];

// find best scoring section editor combo (or undefined if too low score)
const topSection = this.topSectionFinder.findTopSectionForEditor(textEditor, sections);
// find the section (or undefined) by looking relatively at each workspace
// users can also optional use absolute instead of relative for this
const section = this.sectionFinder.findSectionForEditor(textEditor, sections);

if (!topSection) { return ; }
if (!section) { return ; }

this.filterCoverage(topSection, coverageLines);
this.filterCoverage(section, coverageLines);
this.setDecorationsForEditor(textEditor, coverageLines);

// Cache last coverage lines for exports api
Expand Down
70 changes: 70 additions & 0 deletions src/sectionFinder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import {Section} from "lcov-parse";
import {extname} from "path";
import {TextEditor, Uri, workspace} from "vscode";
import {OutputChannel} from "vscode";
import {normalizeFileName} from "./helpers";
import {Reporter} from "./reporter";

export class SectionFinder {

private outputChannel: OutputChannel;
private eventReporter: Reporter;

constructor(
outputChannel: OutputChannel,
eventReporter: Reporter,
) {
this.outputChannel = outputChannel;
this.eventReporter = eventReporter;
}

/**
* Compare the paths using relative logic or absolute
* @param textEditor editor with current active file
* @param sections sections to compare against open editors
*/
public findSectionForEditor(
textEditor: TextEditor,
sections: Map<string, Section>,
): Section | undefined {
function findSection(section): boolean {
const editorFileUri = Uri.file(textEditor.document.fileName);
const workspaceFolder = workspace.getWorkspaceFolder(editorFileUri);
if (!workspaceFolder) { return false; }

const workspaceFolderName = workspaceFolder.name;
const sectionFile = normalizeFileName(section.file);
const editorFile = normalizeFileName(textEditor.document.fileName);

try {
const relativeSectionFile = sectionFile.split(workspaceFolderName)[1];
const relativeEditorFile = editorFile.split(workspaceFolderName)[1];

if (relativeSectionFile === relativeEditorFile) {
return true;
} else {
return false;
}
} catch (error) {
// catch possible index out of bounds errors
return false;
}
}

const sectionsArray = Array.from(sections.values());
const foundSection = sectionsArray.find(findSection);

if (!foundSection) { return ; }

const filePath = foundSection.file;
const template = `[${Date.now()}][renderer][section file path]: `;
const message = template + `${filePath}`;
this.outputChannel.appendLine(message);

// log file type
this.eventReporter.sendEvent("system", "renderer-fileType", extname(filePath));

return foundSection;
}

}
66 changes: 0 additions & 66 deletions src/topSectionFinder.ts

This file was deleted.

22 changes: 11 additions & 11 deletions test/renderer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {assert} from "chai";
import {Section} from "lcov-parse";
import {DecorationOptions, Range, TextEditor, TextEditorDecorationType} from "vscode";
import {Renderer} from "../src/renderer";
import { TopSectionFinder } from "../src/topSectionFinder";
import {SectionFinder} from "../src/sectionFinder";

suite("Renderer Tests", function() {
const fakeConfig = {
Expand All @@ -25,33 +25,33 @@ suite("Renderer Tests", function() {
};

test("Constructor should setup properly @unit", function(done) {
const topSectionFinder: TopSectionFinder = {} as TopSectionFinder;
assert.doesNotThrow(() => new Renderer(fakeConfig, topSectionFinder));
const sectionFinder: SectionFinder = {} as SectionFinder;
assert.doesNotThrow(() => new Renderer(fakeConfig, sectionFinder));
return done();
});

test("renderCoverage should not error with empty map and empty TextEditor array @unit", function(done) {
const topSectionFinder: TopSectionFinder = {} as TopSectionFinder;
const renderer: Renderer = new Renderer(fakeConfig, topSectionFinder);
const sectionFinder: SectionFinder = {} as SectionFinder;
const renderer: Renderer = new Renderer(fakeConfig, sectionFinder);
renderer.renderCoverage(new Map<string, Section>(), new Array<TextEditor>());
return done();
});

test("renderCoverage should not error with empty map and single textEditor @unit", function(done) {
const section: Section = {} as Section;

const topSectionFinder: TopSectionFinder = {
findTopSectionForEditor: (
const sectionFinder: SectionFinder = {
findSectionForEditor: (
functionTextEditor: TextEditor,
functionSections: Map<string, Section>,
): Section | undefined => {
assert.isNotNull(functionTextEditor);
assert.isNotNull(functionSections);
return section;
},
} as TopSectionFinder;
} as SectionFinder;

const renderer: Renderer = new Renderer(fakeConfig, topSectionFinder);
const renderer: Renderer = new Renderer(fakeConfig, sectionFinder);
const textEditor: TextEditor = {} as TextEditor;

textEditor.setDecorations = function(
Expand All @@ -74,8 +74,8 @@ suite("Renderer Tests", function() {
});

test("removeDecorationsForEditor should not error @unit", function(done) {
const topSectionFinder: TopSectionFinder = {} as TopSectionFinder;
const renderer: Renderer = new Renderer(fakeConfig, topSectionFinder);
const sectionFinder: SectionFinder = {} as SectionFinder;
const renderer: Renderer = new Renderer(fakeConfig, sectionFinder);
const textEditor: TextEditor = {} as TextEditor;
textEditor.setDecorations = function(
decorationType: TextEditorDecorationType,
Expand Down
Loading

0 comments on commit deee3d1

Please sign in to comment.