From 721036d8c1eacd9cf3a18a861c0a8151f37d7a05 Mon Sep 17 00:00:00 2001 From: Christopher Dwyer-Perkins Date: Sun, 11 Feb 2024 15:39:54 -0400 Subject: [PATCH] Added some FN tracking --- .../lib/rooibos/CodeCoverageProcessor.spec.ts | 176 +++++++++--------- .../src/lib/rooibos/CodeCoverageProcessor.ts | 66 +++++-- bsc-plugin/src/lib/rooibos/FileFactory.ts | 3 +- framework/src/source/CodeCoverage.brs | 15 +- framework/src/source/CodeCoverage.xml | 1 + framework/src/source/Coverage.bs | 4 +- 6 files changed, 164 insertions(+), 101 deletions(-) diff --git a/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.spec.ts b/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.spec.ts index 1a038d3d..e17b01ba 100644 --- a/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.spec.ts +++ b/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.spec.ts @@ -22,7 +22,7 @@ describe('RooibosPlugin', () => { return undent(contents); } - describe('CodeCoverageProcessor', () => { + describe.only('CodeCoverageProcessor', () => { beforeEach(() => { plugin = new RooibosPlugin(); options = { @@ -91,41 +91,42 @@ describe('RooibosPlugin', () => { let a = getContents('source/code.brs'); let b = undent(` function new(a1, a2) - RBS_CC_1_reportLine("2", 1) + RBS_CC_1_reportLine("2", 1, 0) c = 0 - RBS_CC_1_reportLine("3", 1) + RBS_CC_1_reportLine("3", 1, 0) text = "" - RBS_CC_1_reportLine("4", 1): for i = 0 to 10 - RBS_CC_1_reportLine("5", 1) + RBS_CC_1_reportLine("4", 1, 0): for i = 0 to 10 + RBS_CC_1_reportLine("5", 1, 0) text = text + "hello" - RBS_CC_1_reportLine("6", 1) + RBS_CC_1_reportLine("6", 1, 0) c++ - RBS_CC_1_reportLine("7", 1) + RBS_CC_1_reportLine("7", 1, 0) c += 1 - if RBS_CC_1_reportLine("8", 2) and (c = 2) - RBS_CC_1_reportLine("8", 3) - RBS_CC_1_reportLine("9", 1) + if RBS_CC_1_reportLine("8", 2, 0) and (c = 2) + RBS_CC_1_reportLine("8", 3, 0) + RBS_CC_1_reportLine("9", 1, 0) ? "is true" end if - if RBS_CC_1_reportLine("12", 2) and (c = 3) - RBS_CC_1_reportLine("12", 3) - RBS_CC_1_reportLine("13", 1) + if RBS_CC_1_reportLine("12", 2, 0) and (c = 3) + RBS_CC_1_reportLine("12", 3, 0) + RBS_CC_1_reportLine("13", 1, 0) ? "free" else - RBS_CC_1_reportLine("14", 3) - RBS_CC_1_reportLine("15", 1) + RBS_CC_1_reportLine("14", 3, 0) + RBS_CC_1_reportLine("15", 1, 0) ? "not free" end if end for end function - function RBS_CC_1_reportLine(lineNumber, reportType = 1) + function RBS_CC_1_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid _rbs_ccn.entry = { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } return true end if @@ -135,6 +136,7 @@ describe('RooibosPlugin', () => { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } m._rbs_ccn = _rbs_ccn return true @@ -175,41 +177,42 @@ describe('RooibosPlugin', () => { let a = getContents('source/code.brs'); let b = undent(` function new(a1, a2) - RBS_CC_1_reportLine("2", 1) + RBS_CC_1_reportLine("2", 1, 0) c = 0 - RBS_CC_1_reportLine("3", 1) + RBS_CC_1_reportLine("3", 1, 0) text = "" - RBS_CC_1_reportLine("4", 1): for i = 0 to 10 - RBS_CC_1_reportLine("5", 1) + RBS_CC_1_reportLine("4", 1, 0): for i = 0 to 10 + RBS_CC_1_reportLine("5", 1, 0) text = text + "hello" - RBS_CC_1_reportLine("6", 1) + RBS_CC_1_reportLine("6", 1, 0) c++ - RBS_CC_1_reportLine("7", 1) + RBS_CC_1_reportLine("7", 1, 0) c += 1 - if RBS_CC_1_reportLine("8", 2) and (c = 2) - RBS_CC_1_reportLine("8", 3) - RBS_CC_1_reportLine("9", 1) + if RBS_CC_1_reportLine("8", 2, 0) and (c = 2) + RBS_CC_1_reportLine("8", 3, 0) + RBS_CC_1_reportLine("9", 1, 0) ? "is true" end if - if RBS_CC_1_reportLine("12", 2) and (c = 3) - RBS_CC_1_reportLine("12", 3) - RBS_CC_1_reportLine("13", 1) + if RBS_CC_1_reportLine("12", 2, 0) and (c = 3) + RBS_CC_1_reportLine("12", 3, 0) + RBS_CC_1_reportLine("13", 1, 0) ? "free" else - RBS_CC_1_reportLine("14", 3) - RBS_CC_1_reportLine("15", 1) + RBS_CC_1_reportLine("14", 3, 0) + RBS_CC_1_reportLine("15", 1, 0) ? "not free" end if end for end function - function RBS_CC_1_reportLine(lineNumber, reportType = 1) + function RBS_CC_1_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid _rbs_ccn.entry = { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } return true end if @@ -219,6 +222,7 @@ describe('RooibosPlugin', () => { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } m._rbs_ccn = _rbs_ccn return true @@ -272,29 +276,29 @@ describe('RooibosPlugin', () => { instance.new = function(a1, a2) m.field1 = invalid m.field2 = invalid - RBS_CC_1_reportLine("6", 1) + RBS_CC_1_reportLine("6", 1, 0) c = 0 - RBS_CC_1_reportLine("7", 1) + RBS_CC_1_reportLine("7", 1, 0) text = "" - RBS_CC_1_reportLine("8", 1): for i = 0 to 10 - RBS_CC_1_reportLine("9", 1) + RBS_CC_1_reportLine("8", 1, 0): for i = 0 to 10 + RBS_CC_1_reportLine("9", 1, 0) text = text + "hello" - RBS_CC_1_reportLine("10", 1) + RBS_CC_1_reportLine("10", 1, 0) c++ - RBS_CC_1_reportLine("11", 1) + RBS_CC_1_reportLine("11", 1, 0) c += 1 - if RBS_CC_1_reportLine("12", 2) and (c = 2) - RBS_CC_1_reportLine("12", 3) - RBS_CC_1_reportLine("13", 1) + if RBS_CC_1_reportLine("12", 2, 0) and (c = 2) + RBS_CC_1_reportLine("12", 3, 0) + RBS_CC_1_reportLine("13", 1, 0) ? "is true" end if - if RBS_CC_1_reportLine("16", 2) and (c = 3) - RBS_CC_1_reportLine("16", 3) - RBS_CC_1_reportLine("17", 1) + if RBS_CC_1_reportLine("16", 2, 0) and (c = 3) + RBS_CC_1_reportLine("16", 3, 0) + RBS_CC_1_reportLine("17", 1, 0) ? "free" else - RBS_CC_1_reportLine("18", 3) - RBS_CC_1_reportLine("19", 1) + RBS_CC_1_reportLine("18", 3, 0) + RBS_CC_1_reportLine("19", 1, 0) ? "not free" end if end for @@ -307,13 +311,14 @@ describe('RooibosPlugin', () => { return instance end function - function RBS_CC_1_reportLine(lineNumber, reportType = 1) + function RBS_CC_1_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid _rbs_ccn.entry = { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } return true end if @@ -323,6 +328,7 @@ describe('RooibosPlugin', () => { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } m._rbs_ccn = _rbs_ccn return true @@ -351,25 +357,26 @@ describe('RooibosPlugin', () => { let a = getContents('source/code.brs'); let b = undent(` sub foo() - RBS_CC_1_reportLine("1", 1) + RBS_CC_1_reportLine("1", 1, 0) x = function(y) - if RBS_CC_1_reportLine("2", 2) and ((true)) then - RBS_CC_1_reportLine("2", 3) - RBS_CC_1_reportLine("3", 1) + if RBS_CC_1_reportLine("2", 2, 1) and ((true)) then + RBS_CC_1_reportLine("2", 3, 1) + RBS_CC_1_reportLine("3", 1, 1) return 1 end if - RBS_CC_1_reportLine("5", 1) + RBS_CC_1_reportLine("5", 1, 1) return 0 end function end sub - function RBS_CC_1_reportLine(lineNumber, reportType = 1) + function RBS_CC_1_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid _rbs_ccn.entry = { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } return true end if @@ -379,6 +386,7 @@ describe('RooibosPlugin', () => { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } m._rbs_ccn = _rbs_ccn return true @@ -425,56 +433,57 @@ describe('RooibosPlugin', () => { let a = getContents('source/code.brs'); let b = undent(` sub foo(action as string) - if RBS_CC_1_reportLine("2", 2) and (action = "action1") then - RBS_CC_1_reportLine("2", 3) - RBS_CC_1_reportLine("3", 1) + if RBS_CC_1_reportLine("2", 2, 0) and (action = "action1") then + RBS_CC_1_reportLine("2", 3, 0) + RBS_CC_1_reportLine("3", 1, 0) print "action1" - else if RBS_CC_1_reportLine("4", 2) and (action = "action2" or action = "action2") then - RBS_CC_1_reportLine("4", 3) - RBS_CC_1_reportLine("5", 1) + else if RBS_CC_1_reportLine("4", 2, 0) and (action = "action2" or action = "action2") then + RBS_CC_1_reportLine("4", 3, 0) + RBS_CC_1_reportLine("5", 1, 0) print "action2" - else if RBS_CC_1_reportLine("6", 2) and (action = "action3") then - RBS_CC_1_reportLine("6", 3) - RBS_CC_1_reportLine("7", 1) + else if RBS_CC_1_reportLine("6", 2, 0) and (action = "action3") then + RBS_CC_1_reportLine("6", 3, 0) + RBS_CC_1_reportLine("7", 1, 0) print "action3" - else if RBS_CC_1_reportLine("8", 2) and (action = "action4") then - RBS_CC_1_reportLine("8", 3) - else if RBS_CC_1_reportLine("9", 2) and (action = "action5") then - RBS_CC_1_reportLine("9", 3) - RBS_CC_1_reportLine("10", 1) + else if RBS_CC_1_reportLine("8", 2, 0) and (action = "action4") then + RBS_CC_1_reportLine("8", 3, 0) + else if RBS_CC_1_reportLine("9", 2, 0) and (action = "action5") then + RBS_CC_1_reportLine("9", 3, 0) + RBS_CC_1_reportLine("10", 1, 0) print "action5" - else if RBS_CC_1_reportLine("11", 2) and (action = "action6") then - RBS_CC_1_reportLine("11", 3) - RBS_CC_1_reportLine("12", 1) + else if RBS_CC_1_reportLine("11", 2, 0) and (action = "action6") then + RBS_CC_1_reportLine("11", 3, 0) + RBS_CC_1_reportLine("12", 1, 0) print "action6" - else if RBS_CC_1_reportLine("13", 2) and (action = "action7") then - RBS_CC_1_reportLine("13", 3) - RBS_CC_1_reportLine("14", 1) + else if RBS_CC_1_reportLine("13", 2, 0) and (action = "action7") then + RBS_CC_1_reportLine("13", 3, 0) + RBS_CC_1_reportLine("14", 1, 0) print "action7" - else if RBS_CC_1_reportLine("15", 2) and (action = "action8") then - RBS_CC_1_reportLine("15", 3) - RBS_CC_1_reportLine("16", 1) + else if RBS_CC_1_reportLine("15", 2, 0) and (action = "action8") then + RBS_CC_1_reportLine("15", 3, 0) + RBS_CC_1_reportLine("16", 1, 0) print "action8" - else if RBS_CC_1_reportLine("17", 2) and (action = "action9") then - RBS_CC_1_reportLine("17", 3) - RBS_CC_1_reportLine("18", 1) + else if RBS_CC_1_reportLine("17", 2, 0) and (action = "action9") then + RBS_CC_1_reportLine("17", 3, 0) + RBS_CC_1_reportLine("18", 1, 0) print "action9" - else if RBS_CC_1_reportLine("19", 2) and (action = "action10") then - RBS_CC_1_reportLine("19", 3) - RBS_CC_1_reportLine("20", 1) + else if RBS_CC_1_reportLine("19", 2, 0) and (action = "action10") then + RBS_CC_1_reportLine("19", 3, 0) + RBS_CC_1_reportLine("20", 1, 0) print "action10" else - RBS_CC_1_reportLine("21", 3) + RBS_CC_1_reportLine("21", 3, 0) end if end sub - function RBS_CC_1_reportLine(lineNumber, reportType = 1) + function RBS_CC_1_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid _rbs_ccn.entry = { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } return true end if @@ -484,6 +493,7 @@ describe('RooibosPlugin', () => { "f": "1" "l": lineNumber "r": reportType + "fn": funcId } m._rbs_ccn = _rbs_ccn return true diff --git a/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.ts b/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.ts index b0a48488..6507f1b7 100644 --- a/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.ts +++ b/bsc-plugin/src/lib/rooibos/CodeCoverageProcessor.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import type { BrsFile, Editor, ExpressionStatement, Program, ProgramBuilder, Statement } from 'brighterscript'; -import { Parser, WalkMode, createVisitor, BinaryExpression, createToken, TokenKind, GroupingExpression, isForStatement, isBlock } from 'brighterscript'; +import type { BrsFile, Editor, ExpressionStatement, FunctionExpression, Program, ProgramBuilder, Statement } from 'brighterscript'; +import { Parser, WalkMode, createVisitor, BinaryExpression, createToken, TokenKind, GroupingExpression, isForStatement, isBlock, isFunctionExpression, ParseMode } from 'brighterscript'; import type { RooibosConfig } from './RooibosConfig'; import { RawCodeStatement } from './RawCodeStatement'; import { BrsTranspileState } from 'brighterscript/dist/parser/BrsTranspileState'; @@ -18,16 +18,16 @@ export enum CodeCoverageLineType { export class CodeCoverageProcessor { private coverageBrsTemplate = ` - function RBS_CC_#ID#_reportLine(lineNumber, reportType = 1) + function RBS_CC_#ID#_reportLine(lineNumber, reportType = 1, funcId = -1) _rbs_ccn = m._rbs_ccn if _rbs_ccn <> invalid - _rbs_ccn.entry = { "f": "#ID#", "l": lineNumber, "r": reportType } + _rbs_ccn.entry = { "f": "#ID#", "l": lineNumber, "r": reportType, "fn": funcId } return true end if _rbs_ccn = m?.global?._rbs_ccn if _rbs_ccn <> invalid - _rbs_ccn.entry = { "f": "#ID#", "l": lineNumber, "r": reportType } + _rbs_ccn.entry = { "f": "#ID#", "l": lineNumber, "r": reportType, "fn": funcId } m._rbs_ccn = _rbs_ccn return true end if @@ -39,8 +39,11 @@ export class CodeCoverageProcessor { this.config = (builder.options as any).rooibos as RooibosConfig || {}; this.expectedCoverageMap = {}; this.filePathMap = {}; + this.functionMap = []; this.fileId = 0; + this.functionId = 0; this.fileFactory = fileFactory; + this.processedFunctions = new Set(); try { } catch (e) { console.log('Error:', e.stack); @@ -49,17 +52,20 @@ export class CodeCoverageProcessor { private config: RooibosConfig; private fileId: number; + private functionId: number; private filePathMap: any; + private functionMap: Array>; private expectedCoverageMap: any; private executableLines: Map; private transpileState: BrsTranspileState; private coverageMap: Map; private fileFactory: FileFactory; private processedStatements: Set; + private processedFunctions: Set; private astEditor: Editor; public generateMetadata(isUsingCoverage: boolean, program: Program) { - this.fileFactory.createCoverageComponent(program, this.expectedCoverageMap, this.filePathMap); + this.fileFactory.createCoverageComponent(program, this.expectedCoverageMap, this.filePathMap, this.functionMap); } public addCodeCoverage(file: BrsFile, astEditor: Editor) { @@ -79,12 +85,12 @@ export class CodeCoverageProcessor { file.ast.walk(createVisitor({ ForStatement: (ds, parent, owner, key) => { this.addStatement(ds); - ds.forToken.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code)}: for`; + ds.forToken.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code, ds)}: for`; }, IfStatement: (ifStatement, parent, owner, key) => { this.addStatement(ifStatement); (ifStatement as any).condition = new BinaryExpression( - new RawCodeExpression(this.getFuncCallText(ifStatement.condition.range.start.line, CodeCoverageLineType.condition)), + new RawCodeExpression(this.getFuncCallText(ifStatement.condition.range.start.line, CodeCoverageLineType.condition, ifStatement)), createToken(TokenKind.And), new GroupingExpression({ left: createToken(TokenKind.LeftParen), @@ -94,14 +100,14 @@ export class CodeCoverageProcessor { let blockStatements = ifStatement?.thenBranch?.statements; if (blockStatements) { - let coverageStatement = new RawCodeStatement(this.getFuncCallText(ifStatement.range.start.line, CodeCoverageLineType.branch)); + let coverageStatement = new RawCodeStatement(this.getFuncCallText(ifStatement.range.start.line, CodeCoverageLineType.branch, ifStatement)); blockStatements.splice(0, 0, coverageStatement); } // Handle the else blocks let elseBlock = ifStatement.elseBranch; if (isBlock(elseBlock) && elseBlock.statements) { - let coverageStatement = new RawCodeStatement(this.getFuncCallText(elseBlock.range.start.line - 1, CodeCoverageLineType.branch)); + let coverageStatement = new RawCodeStatement(this.getFuncCallText(elseBlock.range.start.line - 1, CodeCoverageLineType.branch, elseBlock)); elseBlock.statements.splice(0, 0, coverageStatement); } @@ -112,7 +118,7 @@ export class CodeCoverageProcessor { }, WhileStatement: (ds, parent, owner, key) => { - ds.tokens.while.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code)}: while`; + ds.tokens.while.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code, ds)}: while`; }, ReturnStatement: (ds, parent, owner, key) => { this.addStatement(ds); @@ -120,7 +126,7 @@ export class CodeCoverageProcessor { }, ForEachStatement: (ds, parent, owner, key) => { this.addStatement(ds); - ds.tokens.forEach.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code)}: for each`; + ds.tokens.forEach.text = `${this.getFuncCallText(ds.range.start.line, CodeCoverageLineType.code, ds)}: for each`; }, ExitWhileStatement: (ds, parent, owner, key) => { @@ -173,7 +179,7 @@ export class CodeCoverageProcessor { const lineNumber = statement.range.start.line; this.coverageMap.set(lineNumber, coverageType); - const parsed = Parser.parse(this.getFuncCallText(lineNumber, coverageType)).ast.statements[0] as ExpressionStatement; + const parsed = Parser.parse(this.getFuncCallText(lineNumber, coverageType, statement)).ast.statements[0] as ExpressionStatement; this.astEditor.arraySplice(owner, key, 0, parsed); // store the statement in a set to avoid handling again after inserting statement above this.processedStatements.add(statement); @@ -190,8 +196,38 @@ export class CodeCoverageProcessor { } } - private getFuncCallText(lineNumber: number, lineType: CodeCoverageLineType) { + private getFuncCallText(lineNumber: number, lineType: CodeCoverageLineType, statement: Statement) { + const funcId = this.getFunctionIdInFile(statement, ParseMode.BrighterScript); this.coverageMap.set(lineNumber, lineType); - return `RBS_CC_${this.fileId}_reportLine("${lineNumber.toString().trim()}", ${lineType.toString().trim()})`; + return `RBS_CC_${this.fileId}_reportLine("${lineNumber.toString().trim()}", ${lineType.toString().trim()}, ${funcId})`; + } + + private getFunctionIdInFile(statement: Statement, parseMode: ParseMode) { + let originalFunc: FunctionExpression = statement.findAncestor(isFunctionExpression); + let func: FunctionExpression = originalFunc; + + let nameParts = []; + while (func.parentFunction) { + let index = func.parentFunction.childFunctionExpressions.indexOf(func); + nameParts.unshift(`anon${index}`); + func = func.parentFunction; + } + //get the index of this function in its parent + nameParts.unshift( + func.functionStatement.getName(parseMode) + ); + + const name = nameParts.join('$'); + + if (!this.processedFunctions.has(originalFunc)) { + this.processedFunctions.add(originalFunc); + if (!this.functionMap[this.fileId]) { + this.functionMap[this.fileId] = []; + } + + this.functionMap[this.fileId].push(name); + } + + return this.functionMap[this.fileId].indexOf(name); } } diff --git a/bsc-plugin/src/lib/rooibos/FileFactory.ts b/bsc-plugin/src/lib/rooibos/FileFactory.ts index 82ff914d..dd84a4e4 100644 --- a/bsc-plugin/src/lib/rooibos/FileFactory.ts +++ b/bsc-plugin/src/lib/rooibos/FileFactory.ts @@ -100,10 +100,11 @@ export class FileFactory { return contents; } - public createCoverageComponent(program: Program, coverageMap: any, filepathMap: Map) { + public createCoverageComponent(program: Program, coverageMap: any, filepathMap: Map, functionMap: Array>) { let template = this.coverageComponentBrsTemplate; template = template.replace(/\"\#EXPECTED_MAP\#\"/g, JSON.stringify(coverageMap ?? {})); template = template.replace(/\"\#FILE_PATH_MAP\#\"/g, JSON.stringify(filepathMap ?? {})); + template = template.replace(/\"\#FUNCTION_MAP\#\"/g, JSON.stringify(functionMap ?? [])); this.addFileToRootDir(program, path.join('components/rooibos', 'CodeCoverage.brs'), template); this.addFileToRootDir(program, path.join('components/rooibos', 'CodeCoverage.xml'), this.coverageComponentXmlTemplate); diff --git a/framework/src/source/CodeCoverage.brs b/framework/src/source/CodeCoverage.brs index 38d47c18..3bc4ad60 100644 --- a/framework/src/source/CodeCoverage.brs +++ b/framework/src/source/CodeCoverage.brs @@ -17,6 +17,10 @@ function setFilePathMap() m.top.filePathMap = "#FILE_PATH_MAP#" end function +function setFunctionMap() + m.top.functionMap = "#FUNCTION_MAP#" +end function + function onEntryChange() entry = m.top.entry ' defer till later @@ -45,7 +49,15 @@ function onSave() lineMap = {} m.resolvedMap[fileId] = lineMap end if - lineMap[entry.l] = entry.r + + if lineMap[entry.l] = invalid + lineMap[entry.l] = [] + end if + + lineMap[entry.l].push({ + r: entry.r + fn: entry.fn + }) end if end for m.top.resolvedMap = m.resolvedMap @@ -71,4 +83,5 @@ function onSave() #end if setExpectedMap() setFilePathMap() + setFunctionMap() end function \ No newline at end of file diff --git a/framework/src/source/CodeCoverage.xml b/framework/src/source/CodeCoverage.xml index 3aaff6ee..ac60a9be 100644 --- a/framework/src/source/CodeCoverage.xml +++ b/framework/src/source/CodeCoverage.xml @@ -11,5 +11,6 @@ + diff --git a/framework/src/source/Coverage.bs b/framework/src/source/Coverage.bs index 1a989bf4..a0a7e6c4 100644 --- a/framework/src/source/Coverage.bs +++ b/framework/src/source/Coverage.bs @@ -78,6 +78,7 @@ namespace rooibos.Coverage cc = m.global._rbs_ccn expectedMap = cc.expectedMap filePathMap = cc.filePathMap + functionMap = cc.functionMap resolvedMap = cc.resolvedMap results = [] @@ -94,12 +95,13 @@ namespace rooibos.Coverage buffer += "TN:" + chr(10) buffer += "SF:" + sanitizedPath + chr(10) + functionName = "" for each expected in expectedMap[moduleNumber] lineNumber = val(expected) SHIFT = 1 if resolvedMap[moduleNumber] <> invalid and resolvedMap[moduleNumber].doesExist(expected) - buffer += "DA:" + str(lineNumber + SHIFT).trim() + "," + str(resolvedMap[moduleNumber][expected]).trim() + chr(10) + buffer += "DA:" + str(lineNumber + SHIFT).trim() + "," + str(resolvedMap[moduleNumber][expected].count()).trim() + chr(10) else buffer += "DA:" + str(lineNumber + SHIFT).trim() + ",0" + chr(10) end if