如何为testhat中的所有测试全局更改LC_COLLATE=C?

How to change LC_COLLATE=C globally for all tests in testhat?

稍后添加:我们现在选择 中的选项 2 而不是更改测试。回过头来看,跨平台的可重复性更重要;-)


所述,排序逻辑已更改。我的问题是,如何让以下测试通过 LC_COLLATE=German_Switzerland.1252?

可重现的示例:创建一个包,将其命名为 testsort,使用 usethis::use_testthat() 添加测试环境并在 /testsort/tests/testthat/

中添加一个文件“test-sort.R”
test_that("test sort", {
  xx <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
  expect_equal(sort(xx), c("Schaffhausen", "Schwyz", "Seespital", "SRZ")) # fails with new sort
})

背景:我们有许多项目,我们总是致力于 LC_COLLATE=German_Switzerland.1252 并对德语名称进行排序/比较,另请参见 。 在我们的逻辑中,“R”在“c”之后,我们想测试一下, 我们在项目中拥有/期望什么,因此是问题。此外,我们希望尽量减少对其他包的依赖,例如尽可能避免使用 stringr::str_sort(, locale = ...)


似乎关键部分只发生在 testthat/ testthat::test_dir 被调用时:

withr::with_collate("C", # new code
                    withr::with_options(c(useFancyQuotes = FALSE), # new code
                                        withr::with_envvar(c(r_env_vars(), TESTTHAT_PKG = pkg$package), # code
                                                           do.call(testthat::test_dir, testthat_args))))

来自文档:

Temporarily change collation order by changing the value of the LC_COLLATE locale.
Usage with_collate(new, code)

Temporarily change global options.
Usage with_options(new, code)

Temporarily change system environment variables.
Usage with_envvar(new, code, action = "replace")

怎么样

test_that("test sort", {
  # capture current locale
  locale <- Sys.getlocale("LC_COLLATE")

  # set desired locale for test (eg English)
  if (.Platform$OS.type == "windows") {
    invisible(Sys.setlocale("LC_COLLATE", "English")) 
  } else {
    invisible(Sys.setlocale("LC_COLLATE", "en_US.UTF-8")) 
  }
  
  # run test 
  xx <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
  expect_equal(sort(xx), c("Schaffhausen", "Schwyz", "Seespital", "SRZ")) 

  # return to original locale  
  invisible(Sys.setlocale("LC_COLLATE", locale))
})