knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) local({ source_hook <- knitr::knit_hooks$get("source") knitr::knit_hooks$set(source = function(x, options) { old_opts <- options(width = 120L) on.exit(options(old_opts)) source_hook(x, options) }) })
library(covtracer)
library(withr) library(covr) withr::with_temp_libpaths({ options(keep.source = TRUE, keep.source.pkg = TRUE, covr.record_tests = TRUE) examplepkg_source_path <- system.file("examplepkg", package = "covtracer") install.packages( examplepkg_source_path, type = "source", repos = NULL, quiet = TRUE, INSTALL_opts = c("--with-keep.source", "--install-tests") ) examplepkg_cov <- covr::package_coverage(examplepkg_source_path) examplepkg_ns <- getNamespace("examplepkg") })
srcref
objects?print(examplepkg_ns$hypotenuse)
srcref
s are a base R data type that is used frequently for working with
package code. When you install a package using the --with-keep.source
flag,
data about the package's source code representation is bound to the objects that
the namespace attaches or loads. In short, srcref
s are simple data structures
which store the file path of the source code and information about where to find
the relevant bits in that file including line and character columns of the start
and end of the source code.
For extensive details, refer to
?getSrcref
and?srcref
.
Lets see it in action:
getSrcref(covtracer::test_trace_df)
# get line and column ranges (for details see ?srcref) as.numeric(getSrcref(covtracer::test_trace_df))
getSrcFilename(covtracer::test_trace_df)
srcref
sInstead of working with these objects directly, there are a few helper functions
for making these objects easier to extract. For tracing coverage paths, there
are three important classes of srcref
s:
srcref
ssrcref
ssrcref
sBefore we begin, we'll get a package test coverage object and store the package namespace. We take extra precaution to use a temporary library for the sake of example, but this is only necessary when we want to avoid installing the package into our working library.
library(withr) library(covr) withr::with_temp_libpaths({ options(keep.source = TRUE, keep.source.pkg = TRUE, covr.record_tests = TRUE) examplepkg_source_path <- system.file("examplepkg", package = "covtracer") install.packages( examplepkg_source_path, type = "source", repos = NULL, INSTALL_opts = c("--with-keep.source", "--install-tests") ) examplepkg_cov <- covr::package_coverage(examplepkg_source_path) examplepkg_ns <- getNamespace("examplepkg") })
srcref
sThere are a few functions for teasing out this information succinctly. These
include pkg
, trace
, and test
flavors for *_srcefs
and *_srcrefs_df
families of functions (eg, pkg_srcrefs_df()
). *_srcrefs()
functions return a
more primitive list
objects. Because these can be a bit cumbersome to read
through, *_srcrefs_df()
alternatives are provided for improved introspection
and readability.
data.frame
results contain asrcref
column, where each element is asrcref
object. Even though this appears as a succinct text, it contains all thesrcref
data.
srcref
sGetting a list
of srcref
s
pkg_srcrefs(examplepkg_ns)[1] # for brevity, only showing first srcref
pkg_srcrefs(examplepkg_ns)["test_description.character"]
Viewing results as a data.frame
head(pkg_srcrefs_df(examplepkg_ns))
Extracing individual srcref
s from the resulting data.frame
df <- pkg_srcrefs_df(examplepkg_ns) df$srcref[[1L]]
srcref
sSimilarly, we can extract test srcrefs
using equivalent functions for tests.
However, to get test traces, we must first run the package coverage, which
records exactly which tests were actually run by the test suite. Starting from
coverage omits any skipped tests or unevaluated test lines, only presenting test
code that is actually run.
Note that the original source files will no longer exist, as covr
will install
the package into a temporary location for testing. Because of this, test
"srcrefs" are actually call
objects with a with_pseudo_srcref
, allowing them
to be treated like a srcref
s for consistency.
examplepkg_test_srcrefs <- test_srcrefs(examplepkg_cov)
Despite not having a valid srcfile
, we can still use all of our favorite
srcref
functions because of the with_pseudo_scref
subclass:
getSrcFilename(examplepkg_test_srcrefs[[1]])
# execute this code instead, which avoids a vignette error on R devel getSrcFilename(examplepkg_test_srcrefs[1][[1]])
And finally, there is a corresponding *_df
function to make this information
easier to see at a glance:
head(examplepkg_test_srcrefs)
srcref
sThe final piece of the puzzle is the coverage traces. These are the simplest to
find, since covr
stores this information with every coverage object. Even
without any helper functions, you can find this information by indexing into a
coverage object to explore for yourself.
examplepkg_cov[[1]]$srcref
Nevertheless, we provide simple alternatives for restructuring this data into something more consistent with the rest of the pacakge.
examplepkg_trace_srcrefs <- trace_srcrefs(examplepkg_cov) examplepkg_trace_srcrefs[1]
And just like the other functions in the family, this too comes with a *_df
companion function.
head(trace_srcrefs_df(examplepkg_cov))
With all of this information, we can match related code blocks to one another to retrospectively evaluate the relationship between package code and tests.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.