ropensci / vcr

Record and replay HTTP requests
https://docs.ropensci.org/vcr
Other
77 stars 12 forks source link

helper fxn to get webmockr/vcr versions used to record each fixture #152

Open sckott opened 4 years ago

sckott commented 4 years ago

In going through the process of submitting a new version of a package that uses vcr, i was re-recording cassettes with the newest vcr and webmockr versions on cran. And i thought it would be easier if I could tell what fixtures had been recorded with old versions of webmockr/vcr

a draft function

stract <- function(str, pattern) regmatches(str, regexpr(pattern, str)) # fxn already in vcr

recorded_with <- function(dir = ".") {
  fixs <- list.files("tests/fixtures", full.names = TRUE)
  test_files <- list.files("tests/testthat/", "test-", full.names = TRUE)
  tests <- lapply(test_files, readLines)
  cas_names <- stats::setNames(lapply(tests, function(g) {
    tmp <- g[grep("use_cassette", g)]
    if (length(tmp) == 0) return(NULL)
    unlist(lapply(tmp, function(w) stract(strsplit(w, "use_cassette")[[1]][2], "[A-Za-z0-9_-]+")))
  }), test_files)

  ymls <- lapply(fixs, yaml::yaml.load_file)
  res <- stats::setNames(lapply(ymls, function(w) {
    tmp=unique(vapply(w$http_interactions, "[[", "", "recorded_with"))
  }), fixs)
  uniq_vers <- unique(unlist(unname(res)))

  for (i in seq_along(uniq_vers)) {
    fls <- names(res[res %in% uniq_vers[i]])
    fls_cas_nms <- gsub("tests/fixtures/|\\.yml", "", fls)
    fix_tests <- stats::setNames(lapply(fls_cas_nms, function(m) {
      chk <- vapply(cas_names, function(z) m %in% z, logical(1))
      if (any(chk)) chk[chk]
    }), fls)
    cli::cat_line(uniq_vers[i], col = "blue")
    for (i in seq_along(fls)) {
      cli::cat_line(paste0("  ", fls[i], collapse = "\n  "),
        col = "green")
      cli::cat_line(paste("    ", cli::symbol$arrow_right, names(fix_tests[[i]]), collapse = "\n  "),
        col = "red")
    }
  }
}
recorded_with()

gives (with some lines removed for brevity)

vcr/0.4.0, webmockr/0.5.0
  tests/fixtures/count_facet.yml
     → tests/testthat//test-count_facet.r
  tests/fixtures/dataset_metrics_error.yml
     → tests/testthat//test-dataset_metrics.r
  tests/fixtures/dataset_metrics.yml
     → tests/testthat//test-dataset_metrics.r
  tests/fixtures/dataset_search_keyword.yml
     → tests/testthat//test-dataset_search.r
  tests/fixtures/dataset_search_limit.yml
   ...
vcr/0.2.6, webmockr/0.3.4.9100
  tests/fixtures/installations_deleted.yml
     → tests/testthat//test-installations.r
  tests/fixtures/name_lookup_paging1.yml
     → tests/testthat//test-name_lookup.r
  tests/fixtures/name_lookup_paging2.yml
     → tests/testthat//test-name_lookup.r
  tests/fixtures/name_lookup_paging3.yml
     → tests/testthat//test-name_lookup.r
  tests/fixtures/name_lookup.yml
     → tests/testthat//test-name_lookup.r
    ...
vcr/0.2.6, webmockr/0.3.4
  tests/fixtures/installations_uuid_data.yml
     → tests/testthat//test-installations.r
  tests/fixtures/installations_uuid.yml
     → tests/testthat//test-installations.r
   ...
vcr/0.2.2, webmockr/0.3.0
  tests/fixtures/name_issues.yml
     → tests/testthat//test-name_issues.R
   ...
vcr/0.3.3.9110, webmockr/0.5.0
  tests/fixtures/occ_count.yml
     → tests/testthat//test-occ_count.r
vcr/0.3.0, webmockr/0.4.0
  tests/fixtures/occ_download_dataset_activity_error.yml
     → tests/testthat//test-occ_download_dataset_activity.R
   ...
vcr/0.1.0, webmockr/0.2.6, crul/0.6.0
  tests/fixtures/organizations.yml
     → tests/testthat//test-organizations.r

screenshot in brief for some color

Screen Shot 2020-02-12 at 9 57 08 AM

thoughts @maelle @aaronwolen ?

aaronwolen commented 4 years ago

I definitely see the utility and I love how your implementation leverages the cli package.

I'm wondering if we need a wholly new function for this since cassettes() already gets us pretty close:

> cassettes()
# $`create-dir-with-dot-prefix`
# <cassette> 
#   Recorded at: 2020-01-29 23:28:09 GMT
#   Recorded with: vcr/0.4.1.93.9000, webmockr/0.5.1.96
# 
# $`create-dir`
# <cassette> 
#   Recorded at: 2020-01-29 23:27:59 GMT
#   Recorded with: vcr/0.4.1.93.9000, webmockr/0.5.1.96
# 
# $`create-dir1`
# <cassette> 
#   Recorded at: 2020-01-29 23:27:23 GMT
#   Recorded with: vcr/0.4.1.93.9000, webmockr/0.5.1.96

Perhaps recorded_with() could be built on some of those existing helper functions.

sckott commented 4 years ago

good catch! totally forgot about that fxn. i'll see about leveraging cassettes() instead ...

aaronwolen commented 4 years ago

Sort of relates to our previous discussion re cassette helpers and cassette_files() vs vcr_files().

What do you think about adding something like list_cassettes() (the vcr equivalent of list.files()), that just returns a vector of filepaths for (true-positive) cassettes in vcr_c$dir?

My sense is it might be useful enough to export and could then be used internally by other functions like recorded_with().

sckott commented 4 years ago

a list_casettes function sounds good. would be nice if it could collect which vcr/webmockr version, and cassette names used in each file too - then recorded_with can use that output

vector of filepaths for (true-positive) cassettes

what does true-positive mean?

aaronwolen commented 4 years ago

what does true-positive mean?

I just meant it should filter out non-cassette files (false positives), which will probably require reading the first line and checking for http_interactions. Currently, cassettes() gives me

$appveyor
list()

$codecov
list()

would be nice if it could collect which vcr/webmockr version, and cassette names used in each file too

Maybe the output should be more inline with fs::file_info(): a data.frame with one row per cassette that includes columns for file path, modification date, vcr/webmockr version, etc.

Or that could be second helper function that builds on list_cassettes()? cassette_info()?

sckott commented 4 years ago

okay, agree on true thing.

right, cassettes() currently doesn't do what you'd expect when run from the root of a repo - we need to fix that so it figures out where the cassettes are stored and then can do the right thing. (Lets open an issue for this)

Yes, sounds good to have a data.frame like fs::file_info makes