DBItest/ 0000755 0001762 0000144 00000000000 13232433022 011542 5 ustar ligges users DBItest/inst/ 0000755 0001762 0000144 00000000000 13232432047 012525 5 ustar ligges users DBItest/inst/doc/ 0000755 0001762 0000144 00000000000 13232432047 013272 5 ustar ligges users DBItest/inst/doc/test.html 0000644 0001762 0000144 00000034571 13232432047 015151 0 ustar ligges users
Testing a new backend
The test cases in the DBItest
package are structured very similarly to the sections in the “backend” vignette:
vignette("backend", package = "DBI")
Like the “backend” vignette, this vignette assumes that you are implementing the RKazam
package that has a Kazam()
function that creates a new DBIDriver
instance for connecting to a “Kazam” database.
You can add the tests in the DBItest
package incrementally, as you proceed with implementing the various parts of the DBI. The DBItest
package builds upon the testthat
package. To enable it, run the following in your package directory (after installing or updating devtools
):
devtools::use_testthat()
devtools::use_test("DBItest")
This creates, among others, a file test-DBItest.R
in the tests/testthat
directory. Replace its entire contents by the following:
DBItest::make_context(Kazam(), NULL)
DBItest::test_getting_started()
Now test your package with devtools::test()
. If you followed at least the “Getting started” section of the DBI
“backend” vignette, all tests should succeed.
By adding the corresponding test function to your tests/test-DBItest.R
file before implementing a section, you get immediate feedback which functionality of this section still needs to be implemented by running devtools::test()
again. Therefore, proceed by appending the following to tests/test-DBItest.R
, to include a test case for the forthcoming section:
Again, all tests should succeed when you are done with the “Driver” section. Add the call to the next tester function, implement the following section until all tests succeed, and so forth.
In this scenario, you are usually interested only in the first error the test suite finds. The StopReporter
of testthat
is most helpful here, activate it by passing reporter = "stop"
to devtools::test()
. Alternatively, call the relevant DBItest::test_()
function directly.
The tests are documented with the corresponding functions: For instance, ?test_driver
shows a coarse description of all tests for the “Driver” test case. Test failures will include the name of the test that is failing; in this case, investigating the documentation or the source code of the DBItest
package will usually lead to the cause of the error.
Not all tests can be satisfied: For example, there is one test that tests that logical
variables survive a write-read roundtrip to the database, whereas another test tests that logical
variables are converted to integer
in such a case. Tests can be skipped by adding regular expressions for the tests to skip as character vector to the call, as in the following[^termnull]:
DBItest::test_driver(skip = c(
"data_type" # Reason 1...
"constructor.*", # Reason 2...
NULL
))
[^termnull]: The terminating `NULL` allows appending new lines to the end by copy-pasting an existing line, without having to take care of the terminating comma.
Some other reasons to skip tests are: - your database does not support a feature - you want to postpone or avoid the implementation of a feature - the test takes too long to run
Testing an existing backend
For an existing backends, simply enabling all tests may be the quickest way to get started. Run the following in your package directory (after installing or updating devtools
):
devtools::use_testthat()
devtools::use_test("DBItest")
This creates, among others, a file test-DBItest.R
in the tests/testthat
directory. Replace its entire contents by the following:
DBItest::make_context(Kazam(), NULL)
DBItest::test_all()
The notes about “Kazam” and skipping tests from the previous section apply here as well. The test_all()
function simply calls all test cases.
DBItest/inst/doc/test.Rmd 0000644 0001762 0000144 00000010263 13071272237 014723 0 ustar ligges users ---
title: "Testing DBI backends"
author: "Kirill Müller"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Testing DBI backends}
%\VignetteEngine{knitr::rmarkdown}
\usepackage[utf8]{inputenc}
---
This document shows how to use the `DBItest` package when implementing a new `DBI` backend or when applying it to an existing backend. The `DBItest` package provides a large collection of automated tests.
## Testing a new backend
The test cases in the `DBItest` package are structured very similarly to the sections in the "backend" vignette:
```r
vignette("backend", package = "DBI")
```
Like the "backend" vignette, this vignette assumes that you are implementing the `RKazam` package that has a `Kazam()` function that creates a new `DBIDriver` instance for connecting to a "Kazam" database.
You can add the tests in the `DBItest` package incrementally, as you proceed with implementing the various parts of the DBI. The `DBItest` package builds upon the `testthat` package. To enable it, run the following in your package directory (after installing or updating `devtools`):
```r
devtools::use_testthat()
devtools::use_test("DBItest")
```
This creates, among others, a file `test-DBItest.R` in the `tests/testthat` directory. Replace its entire contents by the following:
```r
DBItest::make_context(Kazam(), NULL)
DBItest::test_getting_started()
```
Now test your package with `devtools::test()`. If you followed at least the "Getting started" section of the `DBI` "backend" vignette, all tests should succeed.
By adding the corresponding test function to your `tests/test-DBItest.R` file *before* implementing a section, you get immediate feedback which functionality of this section still needs to be implemented by running `devtools::test()` again. Therefore, proceed by appending the following to `tests/test-DBItest.R`, to include a test case for the forthcoming section:
```r
DBItest::test_driver()
```
Again, all tests should succeed when you are done with the "Driver" section. Add the call to the next tester function, implement the following section until all tests succeed, and so forth.
In this scenario, you are usually interested only in the first error the test suite finds. The `StopReporter` of `testthat` is most helpful here, activate it by passing `reporter = "stop"` to `devtools::test()`. Alternatively, call the relevant `DBItest::test_()` function directly.
The tests are documented with the corresponding functions: For instance, `?test_driver` shows a coarse description of all tests for the "Driver" test case. Test failures will include the name of the test that is failing; in this case, investigating the documentation or the source code of the `DBItest` package will usually lead to the cause of the error.
Not all tests can be satisfied: For example, there is one test that tests that `logical` variables survive a write-read roundtrip to the database, whereas another test tests that `logical` variables are converted to `integer` in such a case. Tests can be skipped by adding regular expressions for the tests to skip as character vector to the call, as in the following[^termnull]:
```r
DBItest::test_driver(skip = c(
"data_type" # Reason 1...
"constructor.*", # Reason 2...
NULL
))
[^termnull]: The terminating `NULL` allows appending new lines to the end by copy-pasting an existing line, without having to take care of the terminating comma.
```
Some other reasons to skip tests are:
- your database does not support a feature
- you want to postpone or avoid the implementation of a feature
- the test takes too long to run
## Testing an existing backend
For an existing backends, simply enabling all tests may be the quickest way to get started. Run the following in your package directory (after installing or updating `devtools`):
```r
devtools::use_testthat()
devtools::use_test("DBItest")
```
This creates, among others, a file `test-DBItest.R` in the `tests/testthat` directory. Replace its entire contents by the following:
```r
DBItest::make_context(Kazam(), NULL)
DBItest::test_all()
```
The notes about "Kazam" and skipping tests from the previous section apply here as well. The `test_all()` function simply calls all test cases.
DBItest/tests/ 0000755 0001762 0000144 00000000000 13071272235 012714 5 ustar ligges users DBItest/tests/testthat.R 0000644 0001762 0000144 00000000072 13071272235 014676 0 ustar ligges users library(testthat)
library(DBItest)
test_check("DBItest")
DBItest/tests/testthat/ 0000755 0001762 0000144 00000000000 13232433022 014544 5 ustar ligges users DBItest/tests/testthat/test-tweaks.R 0000644 0001762 0000144 00000000554 13071442207 017154 0 ustar ligges users context("tweaks")
test_that("tweaks work as expected", {
expect_true(names(formals(tweaks))[[1]] == "...")
expect_warning(tweaks(`_oooops` = 42, `_darn` = -1), "_oooops, _darn")
expect_warning(tweaks(), NA)
expect_warning(tweaks(5), "named")
expect_warning(tweaks(5, `_ooops` = 42), "named")
expect_warning(tweaks(constructor_name = "constr"), NA)
})
DBItest/tests/testthat/test-consistency.R 0000644 0001762 0000144 00000001602 13076746114 020223 0 ustar ligges users context("consistency")
test_that("no unnamed specs", {
tests <- spec_all[!vapply(spec_all, is.null, logical(1L))]
vicinity <- NULL
if (any(names(tests) == "")) {
vicinity <- sort(unique(unlist(
lapply(which(names(tests) == ""), "+", -1:1)
)))
vicinity <- vicinity[names(tests)[vicinity] != ""]
}
expect_null(vicinity)
})
test_that("no duplicate spec names", {
all_names <- names(spec_all)
dupe_names <- unique(all_names[duplicated(all_names)])
expect_equal(dupe_names, rep("", length(dupe_names)))
})
test_that("all specs used", {
env <- asNamespace("DBItest")
defined_spec_names <- ls(env, pattern = "^spec_")
defined_specs <- mget(defined_spec_names, env)
defined_spec_names <- unlist(sapply(defined_specs, names), use.names = FALSE)
new_names <- setdiff(defined_spec_names, names(spec_all))
expect_equal(new_names, rep("", length(new_names)))
})
DBItest/tests/testthat/test-context.R 0000644 0001762 0000144 00000000143 13071272235 017336 0 ustar ligges users context("context")
test_that("default context is NULL", {
expect_null(get_default_context())
})
DBItest/tests/testthat/test-lint.R 0000644 0001762 0000144 00000000474 13071272237 016631 0 ustar ligges users context("lint")
test_that("lintr is happy", {
skip_on_cran()
expect_false("package:DBI" %in% search())
require(DBI)
on.exit(detach(), add = TRUE)
expect_true("package:DBI" %in% search())
#lintr::expect_lint_free()
detach()
on.exit(NULL, add = FALSE)
expect_false("package:DBI" %in% search())
})
DBItest/NAMESPACE 0000644 0001762 0000144 00000003364 13232405532 012774 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method("$",DBItest_tweaks)
S3method(format,DBItest_tweaks)
S3method(print,DBItest_tweaks)
export(get_default_context)
export(make_context)
export(set_default_context)
export(test_all)
export(test_compliance)
export(test_connection)
export(test_driver)
export(test_getting_started)
export(test_meta)
export(test_result)
export(test_some)
export(test_sql)
export(test_stress)
export(test_transaction)
export(tweaks)
import(testthat)
importFrom(DBI,SQL)
importFrom(DBI,dbBegin)
importFrom(DBI,dbBind)
importFrom(DBI,dbBreak)
importFrom(DBI,dbCallProc)
importFrom(DBI,dbClearResult)
importFrom(DBI,dbColumnInfo)
importFrom(DBI,dbCommit)
importFrom(DBI,dbConnect)
importFrom(DBI,dbDataType)
importFrom(DBI,dbDisconnect)
importFrom(DBI,dbExecute)
importFrom(DBI,dbExistsTable)
importFrom(DBI,dbFetch)
importFrom(DBI,dbGetDBIVersion)
importFrom(DBI,dbGetInfo)
importFrom(DBI,dbGetQuery)
importFrom(DBI,dbGetRowCount)
importFrom(DBI,dbGetRowsAffected)
importFrom(DBI,dbGetStatement)
importFrom(DBI,dbHasCompleted)
importFrom(DBI,dbIsValid)
importFrom(DBI,dbListConnections)
importFrom(DBI,dbListFields)
importFrom(DBI,dbListTables)
importFrom(DBI,dbQuoteIdentifier)
importFrom(DBI,dbQuoteString)
importFrom(DBI,dbReadTable)
importFrom(DBI,dbRemoveTable)
importFrom(DBI,dbRollback)
importFrom(DBI,dbSendQuery)
importFrom(DBI,dbSendStatement)
importFrom(DBI,dbSetDataMappings)
importFrom(DBI,dbWithTransaction)
importFrom(DBI,dbWriteTable)
importFrom(desc,desc_get_deps)
importFrom(methods,extends)
importFrom(methods,findMethod)
importFrom(methods,getClass)
importFrom(methods,getClasses)
importFrom(methods,hasMethod)
importFrom(methods,is)
importFrom(stats,setNames)
importFrom(withr,with_output_sink)
importFrom(withr,with_temp_libpaths)
DBItest/NEWS.md 0000644 0001762 0000144 00000031456 13232407247 012663 0 ustar ligges users # DBItest 1.5-2 (2018-01-26)
- Fix test that fails with "noLD".
- Fix NOTEs on R-devel.
# DBItest 1.5-1 (2017-12-10)
- Remove `"cannot_forget_disconnect"` test that fails on R-devel (#150).
# DBItest 1.5 (2017-06-18)
Finalize specification. Most tests now come with a corresponding prose, only those where the behavior is not finally decided don't have a prose version yet (#88).
New tests
---------
- Test behavior of methods in presence of placeholders (#120).
- Test column name mismatch behavior for appending tables (#93).
- Test that `dbBind()` against factor works but raises a warning (#91).
- Test roundtrip of alternating empty and non-empty strings (#42).
- Test multiple columns of different types in one statement or table (#35).
- Test `field.types` argument to `dbWriteTable()` (#12).
- Added tests for invalid or closed connection argument to all methods that expect a connection as first argument (#117).
- Enabled test that tests a missing `dbDisconnect()`.
- Add test for unambiguous escaping of identifiers (rstats-db/RSQLite#123).
- Reenable tests for visibility (#89).
- Fix and specify 64-bit roundtrip test.
- 64-bit integers only need to be coercible to `numeric` and `character` (#74).
- Added roundtrip test for time values (#14).
- Added tweaks for handling date, time, timestamp, ... (#53, #76).
- Test that `dbFetch()` on update-only query returns warning (#66).
Adapted tests
-------------
- `NULL` is a valid value for the `row.names` argument, same as `FALSE`.
- A column named `row_names` receives no special handling (#54).
- A warning (not an error anymore) is expected when calling `dbDisconnect()` on a closed or invalid connection.
- `row.names = FALSE` is now the default for methods that read or write tables.
- Add `NA` to beginning and end of columns in table roundtrip tests (#24).
- Stricter tests for confusion of named and unnamed SQL parameters and placeholders (#107).
- Also check names of all returned data frames.
- The return value for all calls to `dbGetQuery()`, `dbFetch()`, and `dbReadTable()` is now checked for consistency (all columns have the same length, length matches number of rows) (#126).
- Removed stress tests that start a new session.
- Allow `hms` (or other subclasses of `difftime`) to be returned as time class (#135, @jimhester).
- Test that dates are of type `numeric` (#99, @jimhester).
- Replace `POSIXlt` by `POSIXct` (#100, @jimhester).
- Use `"PST8PDT"` instead of `"PST"` as time zone (#110, @thrasibule).
- Added tests for support of `blob` objects (input and output), but backends are not required to return `blob` objects (#98).
- The `logical_return`, `date_typed` and `timestamp_typed` tweaks are respected by the bind tests.
- Fixed tests involving time comparison; now uses UTC timezone and compares against a `difftime`.
- Tests for roundtrip of character values now includes tabs, in addition to many other special characters (#85).
- Make sure at least one table exists in the `dbListTables()` test.
- Fix roundtrip tests for raw columns: now expecting `NULL` and not `NA` entries for SQL NULL values.
- Fix `expect_equal_df()` for list columns.
- Testing that a warning is given if the user forgets to call `dbDisconnect()` or `dbClearResult()` (#103).
- Numeric roundtrip accepts conversion of `NaN` to `NA` (#79).
Internal
--------
- Fix R CMD check errors.
- Internal consistency checks (#114).
- Skip patterns that don't match any of the tests now raise a warning (#84).
- New `test_some()` to test individual tests (#136).
- Use desc instead of devtools (#40).
- All unexpected warnings are now reported as test failures (#113).
- `DBItest_tweaks` class gains a `$` method, accessing an undefined tweak now raises an error.
- The arguments of the `tweaks()` function now have default values that further describe their intended usage.
- New `with_closed_connection()`, `with_invalid_connection()`, `with_result()` and `with_remove_test_table()` helpers, and `expect_visible()`, `expect_inbisible_true()`, and `expect_equal_df()` expectations for more concise tests.
# DBItest 1.4 (2016-12-02)
## DBI specification
- Use markdown in documentation.
- Description of parametrized queries and statements (#88).
- New hidden `DBIspec-wip` page for work-in-progress documentation.
- Get rid of "Format" and "Usage" sections, and aliases, in the specs.
## Tests
- Not testing for presence of `max.connections` element in `dbGetInfo(Driver)` (rstats-db/DBI#56).
- Test multi-row binding for queries and statements (#96).
- New `ellipsis` check that verifies that all implemented DBI methods contain `...` in their formals. This excludes `show()` and all methods defined in this or other packages.
- Refactored `bind_` tests to use the new `parameter_pattern` tweak (#95).
- Rough draft of transaction tests (#36).
- New `fetch_zero_rows` test, split from `fetch_premature_close`.
- The "compliance" test tests that the backend package exports exactly one subclass of each DBI virtual class.
- Document and enhance test for `dbDataType("DBIDriver", "ANY")` (#88).
- Minor corrections for "bind" tests.
## Internal
- Isolate stress tests from main test suite (#92).
- Refactor test specification in smaller modules, isolated from actual test execution (#81). This breaks the documentation of the tests, which will be substituted by a DBI specification in prose.
- Align description of binding with code.
- Refactor tests for `dbBind()`, test is run by `BindTester` class, and behavior is specified by members and by instances of the new `BindTesterExtra` class.
- The `skip` argument to the `test_()` functions is again evaluated with `perl = TRUE` to support negative lookaheads (#33).
- Use `dbSendStatement()` and `dbExecute()` where appropriate.
- Avoid empty subsections in Rd documentation to satisfy `R CMD check` (#81).
# DBItest 1.3 (2016-07-07)
Bug fixes
---------
- Fix `read_table` test when the backend actually returns the data in a different order.
New tests
---------
- Test `dbDataType()` on connections (#69, #75, @imanuelcostigan).
- Check returned strings for UTF-8 encoding (#72).
- Repeated `dbBind()` + `dbFetch()` on the same result set (#51).
Features
--------
- `tweaks()` gains an `...` as first argument to support future/deprecated tweaks (with a warning), and also to avoid unnamed arguments (#83).
- `testthat` now shows a more accurate location for the source of errors, failures, and skips (#78).
- Aggregate skipped tests, only one `skip()` call per test function.
- Indicate that some tests are optional in documentation (#15).
Internal
--------
- New `constructor_relax_args` tweak, currently not queried.
- The `ctx` argument is now explicit in the test functions.
- Change underscores to dashes in file names.
- Remove `testthat` compatibility hack.
- New `all_have_utf8_or_ascii_encoding()` which vectorizes `has_utf8_or_ascii_encoding()`.
- Test on AppVeyor (#73).
- Work around regression in R 3.3.0 (fix scheduled for R 3.3.1) which affected stress tests.
# DBItest 1.2 (2016-05-21)
- Infrastructure
- Support names for contexts (@hoesler, #67).
- The `skip` argument to the test functions is now treated as a Perl regular expression to allow negative lookahead. Use `skip = "(?!test_regex).*"` to choose a single test to run (#33).
- Added encoding arguments to non-ASCII string constants (#60, @hoesler).
- Improve tests
- `simultaneous_connections` test always closes all connections on exit (@hoesler, #68).
- More generic compliance check (@hoesler, #61).
- Update documentation to reflect test condition (@imanuelcostigan, #70).
- `testthat` dependency
- Import all of `testthat` to avoid `R CMD check` warnings.
- Compatibility with dev version of `testthat` (#62).
- Improve Travis builds
- Use container-based builds on Travis.
- Install `RPostgres` and `RMySQL` from `rstats-db`.
- Install `DBI` and `testthat` from GitHub.
Version 1.1 (2016-02-12)
===
- New feature: tweaks
- New argument `tweaks` to `make_context()` (#49).
- New `tweaks()`, essentially constructs a named list of tweaks but with predefined and documented argument names.
- `constructor_name`, respected by the `constructor.*` tests.
- `strict_identifier`, if `TRUE` all identifier must be syntactic names even if quoted. The quoting test is now split, and a part is ignored conditional to this tweak. The `roundtrip_quotes` tests also respects this tweak.
- `omit_blob_tests` for DBMS that don't have a BLOB data type.
- `current_needs_parens` -- some SQL dialects (e.g., BigQuery) require parentheses for the functions `current_date`, `current_time` and `current_timestamp`.
- `union`, for specifying a nonstandard way of combining queries. All union queries now name each column in each subquery (required for `bigrquery`).
- New tests
- `dbGetInfo(Result)` (rstats-db/DBI#55).
- `dbListFields()` (#26).
- New `package_name` test in `test_getting_started()`.
- Improved tests
- Stress test now installs package in temporary library (before loading `DBI`) using `R CMD INSTALL` before loading DBI (rstats-db/RSQLite#128, #48).
- Row count is now tested for equality but not identity, so that backends can return a numeric value > 2^31 at their discretion.
- Call `dbRemoveTable()` instead of issuing `DROP` requests, the latter might be unsupported.
- Use subqueries in queries that use `WHERE`.
- Test that `dbClearResult()` on a closed result set raises a warning.
- Expect a warning instead of an error for double disconnect (#50).
- Move connection test that requires `dbFetch()` to `test_result()`.
- Split `can_connect_and_disconnect` test.
- Expect `DBI` to be in `Imports`, not in `Depends`.
- Removed tests
- Remove test for `dbGetException()` (rstats-db/DBI#51).
- Bug fixes
- Fix broken tests for quoting.
- Self-testing
- Test `RPostgres`, `RMySQL`, `RSQLite` and `RKazam` as part of the Travis-CI tests (#52).
- Travis CI now installs rstats-db/DBI, updated namespace imports (`dbiCheckCompliance()`, `dbListResults()`).
- Use fork of `testthat`.
- Utilities
- Return test results as named array of logical. Requires hadley/testthat#360, gracefully degrades with the CRAN version.
- Internal
- Refactored the `get_info_()` tests to use a vector of names.
- Use versioned dependency for DBI
- Use unqualified calls to `dbBind()` again
Version 1.0 (2015-12-17)
===
- CRAN release
- Eliminate errors on win-builder
- Satisfy R CMD check
- Use LGPL-2 license
- Add RStudio as copyright holder
- Move `devtools` package from "Imports" to "Suggests"
Version 0.3 (2015-11-15)
===
- Feature-complete, ready for review
- Tests from the proposal
- Add missing methods to compliance check
- Add simple read-only test (#27)
- Add stress tests for repeated load/unload (with and without connecting) in new R session (#2),
- Migrate all tests from existing backends (#28)
- Refactor `data_` tests to use a worker function `test_select()`
- Test tables with `NA` values above and below the non-`NA` value in `data_` tests
- Test return values and error conditions for `dbBind()` and `dbClearResult()` (#31)
- Test vectorization of `dbQuoteString()` and `dbQuoteIdentifier()` (#18)
- Test that dates have `integer` as underlying data type (#9)
- Roundtrip tests sort output table to be sure (#32)
- Test `NA` to `NULL` conversion in `dbQuoteString()`, and false friends (#23)
- Enhance test for `dbQuoteIdentifier()` (#30)
- Style
- Avoid using `data.frame()` for date and time columns (#10)
- Use `expect_identical()` instead of `expect_equal()` in many places (#13)
- Catch all errors in `on.exit()` handlers via `expect_error()` (#20).
- Combine "meta" tests into new `test_meta()` (#37)
- Documentation
- New "test" vignette (#16)
- Add package documentation (#38)
- Same as 0.2-5
Version 0.2 (2015-11-11)
===
- Tests from the proposal
- SQL
- Metadata
- DBI compliance (not testing read-only yet)
- Migrate most of the tests from RMySQL
- Test improvements
- Test BLOB data type (#17)
- Check actual availability of type returned by `dbDataType()` (#19)
- Testing infrastructure
- Disambiguate test names (#21)
- Use regex matching for deciding skipped tests, skip regex must match the entire test name
- Documentation
- Document all tests in each test function using the new inline documentation feature of roxygen2
- Improve documentation for `test_all()`: Tests are listed in new "Tests" section
- Add brief instructions to README
- Move repository to rstats-db namespace
- Same as 0.1-6
Version 0.1 (2015-10-11)
===
- First GitHub release
- Builds successfully on Travis
- Testing infrastructure
- Test context
- Skipped tests call `skip()`
- Function `test_all()` that runs all tests
- Tests from the proposal
- Getting started
- Driver
- Connection
- Results
- Code formatting is checked with lintr
- Same as 0.0-5
DBItest/R/ 0000755 0001762 0000144 00000000000 13232372773 011762 5 ustar ligges users DBItest/R/spec-result.R 0000644 0001762 0000144 00000001027 13232372770 014350 0 ustar ligges users #' @template dbispec
#' @format NULL
spec_result <- c(
spec_result_send_query,
spec_result_fetch,
spec_result_clear_result,
spec_result_get_query,
spec_result_send_statement,
spec_result_execute,
spec_result_create_table_with_data_type,
spec_result_roundtrip
)
# Helpers -----------------------------------------------------------------
union <- function(..., .order_by = NULL, .ctx) {
query <- .ctx$tweaks$union(c(...))
if (!missing(.order_by)) {
query <- paste(query, "ORDER BY", .order_by)
}
query
}
DBItest/R/spec-result-create-table-with-data-type.R 0000644 0001762 0000144 00000002207 13232372770 021536 0 ustar ligges users #' spec_result_create_table_with_data_type
#' @usage NULL
#' @format NULL
#' @keywords NULL
spec_result_create_table_with_data_type <- list(
#' @section Specification:
#' All data types returned by `dbDataType()` are usable in an SQL statement
#' of the form
data_type_create_table = function(ctx) {
with_connection({
check_connection_data_type <- function(value) {
with_remove_test_table({
#' `"CREATE TABLE test (a ...)"`.
query <- paste0("CREATE TABLE test (a ", dbDataType(con, value), ")")
eval(bquote(dbExecute(con, .(query))))
})
}
expect_conn_has_data_type <- function(value) {
eval(bquote(
expect_error(check_connection_data_type(.(value)), NA)))
}
expect_conn_has_data_type(logical(1))
expect_conn_has_data_type(integer(1))
expect_conn_has_data_type(numeric(1))
expect_conn_has_data_type(character(1))
expect_conn_has_data_type(Sys.Date())
expect_conn_has_data_type(Sys.time())
if (!isTRUE(ctx$tweaks$omit_blob_tests)) {
expect_conn_has_data_type(list(as.raw(1:10)))
}
})
},
NULL
)
DBItest/R/test-connection.R 0000644 0001762 0000144 00000000704 13156254271 015217 0 ustar ligges users #' @name test_all
#' @aliases NULL
#' @section Tests:
#' [test_connection()]:
#' Test the "Connection" class
NULL
#' Test the "Connection" class
#'
#' @inheritParams test_all
#' @include test-driver.R
#' @family tests
#' @importFrom withr with_temp_libpaths
#' @importFrom methods is
#' @export
test_connection <- function(skip = NULL, ctx = get_default_context()) {
test_suite <- "Connection"
run_tests(ctx, spec_connection, skip, test_suite)
}
DBItest/R/spec-stress.R 0000644 0001762 0000144 00000000122 13156254271 014350 0 ustar ligges users #' @template dbispec
#' @format NULL
spec_stress <- c(
spec_stress_connection
)
DBItest/R/utf8.R 0000644 0001762 0000144 00000001014 13232372770 012764 0 ustar ligges users text_cyrillic <- iconv(list(as.raw(
c(0xd0, 0x9a, 0xd0, 0xb8, 0xd1, 0x80, 0xd0, 0xb8, 0xd0, 0xbb, 0xd0, 0xbb))), from = "UTF-8", to = "UTF-8")
text_latin <- iconv(list(as.raw(c(0x4d, 0xc3, 0xbc, 0x6c, 0x6c, 0x65, 0x72))), from = "UTF-8", to = "UTF-8")
text_chinese <- iconv(list(as.raw(c(0xe6, 0x88, 0x91, 0xe6, 0x98, 0xaf, 0xe8,
0xb0, 0x81))), from = "UTF-8", to = "UTF-8")
text_ascii <- iconv("ASCII", to = "ASCII")
texts <- c(text_cyrillic, text_latin, text_chinese, text_ascii)
DBItest/R/utils.R 0000644 0001762 0000144 00000010460 13232372770 013243 0 ustar ligges users `%||%` <- function(a, b) if (is.null(a)) b else a
get_pkg_path <- function(ctx) {
pkg_name <- package_name(ctx)
expect_is(pkg_name, "character")
pkg_path <- find.package(pkg_name)
pkg_path
}
utils::globalVariables("con")
utils::globalVariables("con2")
# Expects a variable "ctx" in the environment env,
# evaluates the code inside local() after defining a variable "con"
# (can be overridden by specifying con argument)
# that points to a newly opened connection. Disconnects on exit.
with_connection <- function(code, con = "con", env = parent.frame()) {
code_sub <- substitute(code)
con <- as.name(con)
eval(bquote({
.(con) <- connect(ctx)
on.exit(try_silent(dbDisconnect(.(con))), add = TRUE)
local(.(code_sub))
}
), envir = env)
}
# Expects a variable "ctx" in the environment env,
# evaluates the code inside local() after defining a variable "con"
# (can be overridden by specifying con argument)
# that points to a newly opened and then closed connection. Disconnects on exit.
with_closed_connection <- function(code, con = "con", env = parent.frame()) {
code_sub <- substitute(code)
con <- as.name(con)
eval(bquote({
.(con) <- connect(ctx)
dbDisconnect(.(con))
local(.(code_sub))
}
), envir = env)
}
# Expects a variable "ctx" in the environment env,
# evaluates the code inside local() after defining a variable "con"
# (can be overridden by specifying con argument)
# that points to a newly opened but invalidated connection. Disconnects on exit.
with_invalid_connection <- function(code, con = "con", env = parent.frame()) {
code_sub <- substitute(code)
stopifnot(con != "..con")
con <- as.name(con)
eval(bquote({
..con <- connect(ctx)
on.exit(dbDisconnect(..con), add = TRUE)
.(con) <- unserialize(serialize(..con, NULL))
local(.(code_sub))
}
), envir = env)
}
# Evaluates the code inside local() after defining a variable "res"
# (can be overridden by specifying con argument)
# that points to a result set created by query. Clears on exit.
with_result <- function(query, code, res = "res", env = parent.frame()) {
code_sub <- substitute(code)
query_sub <- substitute(query)
res <- as.name(res)
eval(bquote({
.(res) <- .(query_sub)
on.exit(dbClearResult(.(res)), add = TRUE)
local(.(code_sub))
}
), envir = env)
}
# Evaluates the code inside local() after defining a variable "con"
# (can be overridden by specifying con argument)
# that points to a connection. Removes the table specified by name on exit,
# if it exists.
with_remove_test_table <- function(code, name = "test", con = "con", env = parent.frame()) {
code_sub <- substitute(code)
con <- as.name(con)
eval(bquote({
on.exit(
try_silent(
dbExecute(.(con), paste0("DROP TABLE ", dbQuoteIdentifier(.(con), .(name))))
),
add = TRUE
)
local(.(code_sub))
}
), envir = env)
}
# Evaluates the code inside local() after defining a variable "con"
# (can be overridden by specifying con argument)
# that points to a result set created by query. Clears on exit.
with_rollback_on_error <- function(code, con = "con", env = parent.frame()) {
code_sub <- substitute(code)
con <- as.name(con)
eval(bquote({
on.exit(
try_silent(
dbRollback(.(con))
),
add = TRUE
)
local(.(code_sub))
on.exit(NULL, add = FALSE)
}
), envir = env)
}
get_iris <- function(ctx) {
datasets_iris <- datasets::iris
if (isTRUE(ctx$tweaks$strict_identifier)) {
names(datasets_iris) <- gsub(".", "_", names(datasets_iris), fixed = TRUE)
}
datasets_iris
}
unrowname <- function(x) {
rownames(x) <- NULL
x
}
random_table_name <- function(n = 10) {
paste0(sample(letters, n, replace = TRUE), collapse = "")
}
compact <- function(x) {
x[!vapply(x, is.null, logical(1L))]
}
expand_char <- function(...) {
df <- expand.grid(..., stringsAsFactors = FALSE)
do.call(paste0, df)
}
try_silent <- function(code) {
tryCatch(
code,
error = function(e) NULL)
}
check_df <- function(df) {
expect_is(df, "data.frame")
if (length(df) >= 1L) {
lengths <- vapply(df, length, integer(1L), USE.NAMES = FALSE)
expect_equal(diff(lengths), rep(0L, length(lengths) - 1L))
expect_equal(nrow(df), lengths[[1]])
}
df_names <- names(df)
expect_true(all(df_names != ""))
expect_false(anyNA(df_names))
df
}
DBItest/R/spec-meta-get-rows-affected.R 0000644 0001762 0000144 00000004164 13232372770 017271 0 ustar ligges users #' spec_meta_get_rows_affected
#' @usage NULL
#' @format NULL
#' @keywords NULL
spec_meta_get_rows_affected <- list(
get_rows_affected_formals = function(ctx) {
#