/nvim-coverage

Displays test coverage data in the sign column

Primary LanguageLuaMIT LicenseMIT

nvim-coverage

Displays coverage information in the sign column.

markers

Displays a coverage summary report in a pop-up window.

summary

Currently supports:

  • C/C++ (lcov)
  • C# (lcov - see wiki for details)
  • Dart (lcov)
  • Go (coverprofile)
  • Javascript/Typescript (lcov): jest
  • Julia (lcov): Pkg.jl
  • Python (json): coverage.py
  • Ruby (json): SimpleCov
  • Rust (json): grcov
  • PHP (cobertura)
  • Lua (lcov)
  • Anything that generates lcov files

Branch (partial) coverage support:

Language Supported
C/C++
C#
Dart ✔️ (untested)
Go
Javascript/Typescript ✔️
Julia ✔️ (untested)
Python ✔️
Ruby
Rust
PHP
Lua

Note: This plugin does not run tests. It justs loads/displays a coverage report generated by a test suite. To run tests from neovim with coverage enabled, try one of these plugins:

Installation

This plugin depends on plenary and optionally on the lua-xmlreader luarock to parse the cobertura format.

Using vim-plug (not including the luarock dependency):

Plug 'nvim-lua/plenary.nvim'
Plug 'andythigpen/nvim-coverage'

The following lua is required to configure the plugin after installation.

require("coverage").setup()

Using packer:

use({
  "andythigpen/nvim-coverage",
  requires = "nvim-lua/plenary.nvim",
  -- Optional: needed for PHP when using the cobertura parser
  rocks = { 'lua-xmlreader' },
  config = function()
    require("coverage").setup()
  end,
})

Configuration

See docs for more info.

Example:

require("coverage").setup({
	commands = true, -- create commands
	highlights = {
		-- customize highlight groups created by the plugin
		covered = { fg = "#C3E88D" },   -- supports style, fg, bg, sp (see :h highlight-gui)
		uncovered = { fg = "#F07178" },
	},
	signs = {
		-- use your own highlight groups or text markers
		covered = { hl = "CoverageCovered", text = "" },
		uncovered = { hl = "CoverageUncovered", text = "" },
	},
	summary = {
		-- customize the summary pop-up
		min_coverage = 80.0,      -- minimum coverage threshold (used for highlighting)
	},
	lang = {
		-- customize language specific settings
	},
})

Extending to other languages

  1. Create a new lua module matching the pattern coverage.languages.<filetype> where <filetype> matches the vim filetype for the coverage language (ex. python).
  2. Implement the required methods listed below.

Required methods:

local M = {}

--- Loads a coverage report.
-- This method should perform whatever steps are necessary to generate a coverage report.
-- The coverage report results should passed to the callback, which will be cached by the plugin.
-- @param callback called with results of the coverage report
M.load = function(callback)
  -- TODO: callback(results)
end

--- Returns a list of signs that will be placed in buffers.
-- This method should use the coverage data (previously generated via the load method) to 
-- return a list of signs.
-- @return list of signs
M.sign_list = function(data)
  -- TODO: generate a list of signs using:
  -- require("coverage.signs").new_covered(bufnr, linenr)
  -- require("coverage.signs").new_uncovered(bufnr, linenr)
end

--- Returns a summary report.
-- @return summary report
M.summary = function(data)
  -- TODO: generate a summary report in the format
  return {
    files = {
      { -- all fields, except filename, are optional - the report will be blank if the field is nil
        filename = fname,            -- filename displayed in the report
        statements = statements,     -- number of total statements in the file
        missing = missing,           -- number of lines missing coverage (uncovered) in the file
        excluded = excluded,         -- number of lines excluded from coverage reporting in the file
        branches = branches,         -- number of total branches in the file
        partial = partial_branches,  -- number of branches that are partially covered in the file
        coverage = coverage,         -- coverage percentage (float) for this file
      }
    },
    totals = { -- optional
      statements = total_statements,     -- number of total statements in the report
      missing = total_missing,           -- number of lines missing coverage (uncovered) in the report
      excluded = total_excluded,         -- number of lines excluded from coverage reporting in the report
      branches = total_branches,         -- number of total branches in the report
      partial = total_partial_branches,  -- number of branches that are partially covered in the report
      coverage = total_coverage,         -- coverage percentage to display in the report
    }
  }
end

return M