Как глобально изменить LC_COLLATE=C для всех тестов в testthat?

Добавлено некоторое время спустя: теперь мы выбираем вариант 2 из здесь вместо изменения теста. Оглядываясь назад, кроссплатформенная воспроизводимость важнее ;-)


Как описано здесь, логика сортировки изменилась. Мой вопрос в том, как я могу пройти следующий тест на LC_COLLATE=German_Switzerland.1252?

Воспроизводимый пример: создайте пакет, назовите его testort, добавьте test-environment с помощью usethis::use_testthat() и добавьте файл test-sort.R в /testsort/tests/testthat/

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))))

Из документов:

Временно измените порядок сортировки, изменив значение локали LC_COLLATE.
Использование with_collate(new, code)

Временно изменить глобальные параметры.
Использование with_options(new, code)

Временно изменить переменные системной среды.
Использование with_envvar(new, code, action = replace)


person Christoph    schedule 10.08.2020    source источник
comment
Почему этот вопрос получает отрицательный голос без комментария?   -  person Christoph    schedule 12.08.2020


Ответы (1)


Как насчет

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))
})

person Keith McNulty    schedule 10.08.2020
comment
Затем я должен изменить настройку в каждом тесте. Я подумал, что могу использовать файл helper для сохранения набора текста, но это не сработает, если правильно понять (см. мое редактирование). Вы понимаете, почему они изменили тест таким образом, что в testthat используется поведение, которое НЕ используется в обычном режиме работы? - person Christoph; 11.08.2020