[med-svn] [r-cran-checkmate] 13/15: New upstream version 1.8.2

Andreas Tille tille at debian.org
Mon Oct 9 09:34:23 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository r-cran-checkmate.

commit b01d94db138a8bce78f88a214ec0cf4646ba8b36
Author: Andreas Tille <tille at debian.org>
Date:   Mon Oct 9 11:32:20 2017 +0200

    New upstream version 1.8.2
---
 DESCRIPTION                             |  47 +++
 LICENSE                                 |   3 +
 MD5                                     | 199 ++++++++++++
 NAMESPACE                               | 342 ++++++++++++++++++++
 NEWS.md                                 | 167 ++++++++++
 R/AssertCollection.R                    |  60 ++++
 R/allMissing.R                          |  14 +
 R/anyInfinite.R                         |  18 ++
 R/anyMissing.R                          |  29 ++
 R/anyNaN.R                              |  18 ++
 R/asInteger.R                           |  49 +++
 R/assert.R                              |  60 ++++
 R/checkAccess.R                         |  73 +++++
 R/checkArray.R                          |  56 ++++
 R/checkAtomic.R                         |  47 +++
 R/checkAtomicVector.R                   |  66 ++++
 R/checkCharacter.R                      |  77 +++++
 R/checkChoice.R                         |  53 +++
 R/checkClass.R                          |  82 +++++
 R/checkComplex.R                        |  46 +++
 R/checkCount.R                          |  53 +++
 R/checkDataFrame.R                      |  48 +++
 R/checkDataTable.R                      |  82 +++++
 R/checkDate.R                           |  76 +++++
 R/checkDirectoryExists.R                |  84 +++++
 R/checkEnvironment.R                    |  60 ++++
 R/checkFactor.R                         | 105 ++++++
 R/checkFileExists.R                     |  99 ++++++
 R/checkFlag.R                           |  49 +++
 R/checkFunction.R                       |  92 ++++++
 R/checkInt.R                            |  48 +++
 R/checkInteger.R                        |  49 +++
 R/checkIntegerish.R                     |  54 ++++
 R/checkList.R                           |  72 +++++
 R/checkLogical.R                        |  46 +++
 R/checkMatrix.R                         |  67 ++++
 R/checkNamed.R                          |  56 ++++
 R/checkNames.R                          |  90 ++++++
 R/checkNull.R                           |  45 +++
 R/checkNumber.R                         |  49 +++
 R/checkNumeric.R                        |  49 +++
 R/checkOS.R                             |  51 +++
 R/checkPathForOutput.R                  |  74 +++++
 R/checkScalar.R                         |  46 +++
 R/checkScalarNA.R                       |  51 +++
 R/checkSetEqual.R                       |  65 ++++
 R/checkString.R                         |  51 +++
 R/checkSubset.R                         |  61 ++++
 R/checkTibble.R                         |  55 ++++
 R/checkVector.R                         |  65 ++++
 R/coalesce.R                            |  19 ++
 R/helper.R                              |  24 ++
 R/isIntegerish.R                        |   4 +
 R/makeAssertion.R                       |  66 ++++
 R/makeExpectation.R                     |  61 ++++
 R/makeTest.R                            |  52 +++
 R/matchArg.R                            |  38 +++
 R/qassert.R                             | 133 ++++++++
 R/qassertr.R                            |  69 ++++
 R/vname.R                               |  12 +
 R/wfwl.R                                |  30 ++
 R/zzz.R                                 | 125 ++++++++
 README.md                               |  38 +++
 build/vignette.rds                      | Bin 0 -> 198 bytes
 debian/README.test                      |  10 -
 debian/changelog                        |  54 ----
 debian/compat                           |   1 -
 debian/control                          |  25 --
 debian/copyright                        |  42 ---
 debian/docs                             |   3 -
 debian/rules                            |  12 -
 debian/source/format                    |   1 -
 debian/tests/control                    |   3 -
 debian/tests/run-unit-test              |  11 -
 debian/watch                            |   2 -
 inst/doc/checkmate.R                    | 146 +++++++++
 inst/doc/checkmate.Rmd                  | 284 +++++++++++++++++
 inst/doc/checkmate.html                 | 369 +++++++++++++++++++++
 inst/include/checkmate.h                |  21 ++
 inst/include/checkmate_stub.c           |  15 +
 man/AssertCollection.Rd                 |  43 +++
 man/anyInfinite.Rd                      |  25 ++
 man/anyMissing.Rd                       |  46 +++
 man/anyNaN.Rd                           |  25 ++
 man/asInteger.Rd                        |  88 +++++
 man/assert.Rd                           |  42 +++
 man/checkAccess.Rd                      |  83 +++++
 man/checkArray.Rd                       | 117 +++++++
 man/checkAtomic.Rd                      | 117 +++++++
 man/checkAtomicVector.Rd                | 111 +++++++
 man/checkCharacter.Rd                   | 151 +++++++++
 man/checkChoice.Rd                      |  86 +++++
 man/checkClass.Rd                       |  99 ++++++
 man/checkComplex.Rd                     | 128 ++++++++
 man/checkCount.Rd                       | 106 ++++++
 man/checkDataFrame.Rd                   | 145 +++++++++
 man/checkDataTable.Rd                   | 148 +++++++++
 man/checkDate.Rd                        | 120 +++++++
 man/checkDirectoryExists.Rd             | 105 ++++++
 man/checkEnvironment.Rd                 |  94 ++++++
 man/checkFactor.Rd                      | 158 +++++++++
 man/checkFileExists.Rd                  | 112 +++++++
 man/checkFlag.Rd                        |  91 ++++++
 man/checkFunction.Rd                    | 106 ++++++
 man/checkInt.Rd                         | 108 +++++++
 man/checkInteger.Rd                     | 139 ++++++++
 man/checkIntegerish.Rd                  | 147 +++++++++
 man/checkList.Rd                        | 138 ++++++++
 man/checkLogical.Rd                     | 127 ++++++++
 man/checkMatrix.Rd                      | 141 ++++++++
 man/checkNamed.Rd                       |  77 +++++
 man/checkNames.Rd                       | 108 +++++++
 man/checkNull.Rd                        |  70 ++++
 man/checkNumber.Rd                      | 104 ++++++
 man/checkNumeric.Rd                     | 139 ++++++++
 man/checkOS.Rd                          |  70 ++++
 man/checkPathForOutput.Rd               |  91 ++++++
 man/checkScalar.Rd                      |  91 ++++++
 man/checkScalarNA.Rd                    |  81 +++++
 man/checkSetEqual.Rd                    |  92 ++++++
 man/checkString.Rd                      | 113 +++++++
 man/checkSubset.Rd                      |  94 ++++++
 man/checkTibble.Rd                      | 136 ++++++++
 man/checkVector.Rd                      | 130 ++++++++
 man/checkmate-package.Rd                | 104 ++++++
 man/coalesce.Rd                         |  27 ++
 man/makeAssertion.Rd                    |  69 ++++
 man/makeExpectation.Rd                  |  65 ++++
 man/makeTest.Rd                         |  57 ++++
 man/matchArg.Rd                         |  37 +++
 man/qassert.Rd                          | 132 ++++++++
 man/qassertr.Rd                         |  63 ++++
 man/vname.Rd                            |  21 ++
 man/wf.Rd                               |  34 ++
 src/all_missing.c                       |  97 ++++++
 src/all_missing.h                       |  22 ++
 src/all_nchar.c                         |  17 +
 src/all_nchar.h                         |  10 +
 src/any_infinite.c                      |  44 +++
 src/any_infinite.h                      |  11 +
 src/any_missing.c                       | 117 +++++++
 src/any_missing.h                       |  22 ++
 src/any_nan.c                           |  43 +++
 src/any_nan.h                           |  11 +
 src/checkmate_init.c                    |   8 +
 src/checks.c                            | 544 +++++++++++++++++++++++++++++++
 src/checks.h                            |  33 ++
 src/guess_type.c                        |  34 ++
 src/guess_type.h                        |  11 +
 src/helper.c                            |  88 +++++
 src/helper.h                            |  18 ++
 src/is_integerish.c                     |  42 +++
 src/is_integerish.h                     |  12 +
 src/qassert.c                           | 548 ++++++++++++++++++++++++++++++++
 src/qassert.h                           |  13 +
 src/which_first.c                       |  49 +++
 src/which_first.h                       |  11 +
 tests/test-all.R                        |   2 +
 tests/testthat/helper.R                 | 103 ++++++
 tests/testthat/test_AssertCollection.R  |  38 +++
 tests/testthat/test_anyInfinite.R       |  33 ++
 tests/testthat/test_anyMissing.R        |  95 ++++++
 tests/testthat/test_anyNaN.R            |  33 ++
 tests/testthat/test_asType.R            |  83 +++++
 tests/testthat/test_assert.R            |  33 ++
 tests/testthat/test_checkArray.R        |  52 +++
 tests/testthat/test_checkAtomic.R       |  51 +++
 tests/testthat/test_checkAtomicVector.R |  50 +++
 tests/testthat/test_checkCharacter.R    |  40 +++
 tests/testthat/test_checkChoice.R       |  23 ++
 tests/testthat/test_checkClass.R        |  31 ++
 tests/testthat/test_checkComplex.R      |  21 ++
 tests/testthat/test_checkCount.R        |  27 ++
 tests/testthat/test_checkDataFrame.R    |  91 ++++++
 tests/testthat/test_checkDataTable.R    |  35 ++
 tests/testthat/test_checkDate.R         |  32 ++
 tests/testthat/test_checkEnvironment.R  |  24 ++
 tests/testthat/test_checkFactor.R       |  49 +++
 tests/testthat/test_checkFilesystem.R   |  87 +++++
 tests/testthat/test_checkFlag.R         |  19 ++
 tests/testthat/test_checkFunction.R     |  42 +++
 tests/testthat/test_checkInt.R          |  30 ++
 tests/testthat/test_checkInteger.R      |  31 ++
 tests/testthat/test_checkIntegerish.R   |  61 ++++
 tests/testthat/test_checkList.R         |  32 ++
 tests/testthat/test_checkLogical.R      |  21 ++
 tests/testthat/test_checkMatrix.R       |  91 ++++++
 tests/testthat/test_checkNamed.R        |  55 ++++
 tests/testthat/test_checkNames.R        | 102 ++++++
 tests/testthat/test_checkNull.R         |  13 +
 tests/testthat/test_checkNumber.R       |  38 +++
 tests/testthat/test_checkNumeric.R      |  49 +++
 tests/testthat/test_checkOS.R           |  29 ++
 tests/testthat/test_checkScalar.R       |  19 ++
 tests/testthat/test_checkScalarNA.R     |  12 +
 tests/testthat/test_checkSetEqual.R     |  35 ++
 tests/testthat/test_checkString.R       |  26 ++
 tests/testthat/test_checkSubset.R       |  23 ++
 tests/testthat/test_checkTibble.R       |  13 +
 tests/testthat/test_checkVector.R       |  72 +++++
 tests/testthat/test_deparse.R           |  12 +
 tests/testthat/test_guessType.R         |  41 +++
 tests/testthat/test_include.R           |  17 +
 tests/testthat/test_interoperability.R  |  27 ++
 tests/testthat/test_makeFunction.R      |  42 +++
 tests/testthat/test_matchArg.R          |  18 ++
 tests/testthat/test_messages.R          |   7 +
 tests/testthat/test_qassert.R           | 274 ++++++++++++++++
 tests/testthat/test_qassertr.R          |  72 +++++
 tests/testthat/test_wf.R                |  34 ++
 vignettes/checkmate.Rmd                 | 284 +++++++++++++++++
 211 files changed, 14534 insertions(+), 164 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100644
index 0000000..5f2d17d
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,47 @@
+Package: checkmate
+Type: Package
+Title: Fast and Versatile Argument Checks
+Description: Tests and assertions to perform frequent argument checks. A
+    substantial part of the package was written in C to minimize any worries
+    about execution time overhead.
+Version: 1.8.2
+Authors at R: c(
+    person("Michel", "Lang", NULL, "michellang at gmail.com", role = c("cre", "aut")),
+    person("Bernd", "Bischl", NULL, "bernd_bischl at gmx.de", role = "ctb")
+    )
+URL: https://github.com/mllg/checkmate
+URLNote: https://github.com/mllg/checkmate
+BugReports: https://github.com/mllg/checkmate/issues
+NeedsCompilation: yes
+ByteCompile: yes
+Encoding: UTF-8
+Depends: R (>= 3.0.0)
+Imports: backports, utils
+Suggests: data.table, devtools, ggplot2, knitr, rmarkdown, magrittr,
+        microbenchmark, testthat (>= 0.11.0), tibble
+License: BSD_3_clause + file LICENSE
+VignetteBuilder: knitr
+RoxygenNote: 5.0.1
+Collate: 'AssertCollection.R' 'allMissing.R' 'anyInfinite.R'
+        'anyMissing.R' 'anyNaN.R' 'asInteger.R' 'assert.R' 'helper.R'
+        'makeExpectation.R' 'makeTest.R' 'makeAssertion.R'
+        'checkAccess.R' 'checkArray.R' 'checkAtomic.R'
+        'checkAtomicVector.R' 'checkCharacter.R' 'checkChoice.R'
+        'checkClass.R' 'checkComplex.R' 'checkCount.R'
+        'checkDataFrame.R' 'checkDataTable.R' 'checkDate.R'
+        'checkDirectoryExists.R' 'checkEnvironment.R' 'checkFactor.R'
+        'checkFileExists.R' 'checkFlag.R' 'checkFunction.R'
+        'checkInt.R' 'checkInteger.R' 'checkIntegerish.R' 'checkList.R'
+        'checkLogical.R' 'checkMatrix.R' 'checkNamed.R' 'checkNames.R'
+        'checkNull.R' 'checkNumber.R' 'checkNumeric.R' 'checkOS.R'
+        'checkPathForOutput.R' 'checkScalar.R' 'checkScalarNA.R'
+        'checkSetEqual.R' 'checkString.R' 'checkSubset.R'
+        'checkTibble.R' 'checkVector.R' 'coalesce.R' 'isIntegerish.R'
+        'matchArg.R' 'qassert.R' 'qassertr.R' 'vname.R' 'wfwl.R'
+        'zzz.R'
+Packaged: 2016-11-02 09:34:07 UTC; lang
+Author: Michel Lang [cre, aut],
+  Bernd Bischl [ctb]
+Maintainer: Michel Lang <michellang at gmail.com>
+Repository: CRAN
+Date/Publication: 2016-11-02 18:15:25
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f0d38dd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,3 @@
+YEAR: 2016
+COPYRIGHT HOLDER: Michel Lang
+ORGANIZATION: TU Dortmund University
diff --git a/MD5 b/MD5
new file mode 100644
index 0000000..ded0570
--- /dev/null
+++ b/MD5
@@ -0,0 +1,199 @@
+0193c109400e6c52ba3fbec2c5e6482a *DESCRIPTION
+b0b6dd0a52cf41d9eb9eef17c4014538 *LICENSE
+c3c1ba41ff9f85381b7fd46b66b1a1b1 *NAMESPACE
+6d91eb2907ee1bf234fb540e68ff304b *NEWS.md
+f0fc2aeb92b3d2014f6357308fd80954 *R/AssertCollection.R
+a7fc65b769f9477797c56c8c2af12339 *R/allMissing.R
+d4b005e269d2845ff89bed357a4e3d5f *R/anyInfinite.R
+4e5ba9b259b46bf424e3ce1000f68e90 *R/anyMissing.R
+65edb5b66b8a66217713a6aa2df5f3b9 *R/anyNaN.R
+dfee030e0ab9b5152e1b4e09c1823ff9 *R/asInteger.R
+5ddf157b76c71ab46ca7848dc0dd8a9f *R/assert.R
+38dddb2ec8e44940351a239af16701b8 *R/checkAccess.R
+7b56d45a334baf5ed3df5351e21f7beb *R/checkArray.R
+a7bc9e4293f16479733b9c62a06fae89 *R/checkAtomic.R
+54b07d2e24590aa90dba84b7c4ab4b55 *R/checkAtomicVector.R
+f8d12e0a4e649ff526589c3ed0789941 *R/checkCharacter.R
+ac55cf18b08a273e784282efcdd1434a *R/checkChoice.R
+adeb8894c3536a12dc037b30014f1041 *R/checkClass.R
+7e2a0da23501614b4a5234c7716c387a *R/checkComplex.R
+e70bad27622e217fa60952d45b2ce1e3 *R/checkCount.R
+ee5ad9523512931c12c6fafa0af82511 *R/checkDataFrame.R
+b4f872829e2192130345d8f524e3210d *R/checkDataTable.R
+2a4fc16432143d06eae0e85dd1256666 *R/checkDate.R
+d32c00660ef9c4b43866f454670736fe *R/checkDirectoryExists.R
+9774a3bc179500c6433cd36a2c2caa35 *R/checkEnvironment.R
+1030793675597a52ecaffe09b113085f *R/checkFactor.R
+96f53778f75a3e3309a3780479114a33 *R/checkFileExists.R
+9e3dac4031f2b1a2538a3c6f8be8d1f7 *R/checkFlag.R
+6713455828332e3e08bcf3f20b9ddf55 *R/checkFunction.R
+ff4e60653844fc698b0ab6e219839219 *R/checkInt.R
+65e40b037e973393d9c8aee5ae9728e8 *R/checkInteger.R
+7b0608524f1f136715dc8e7fc03a5e7d *R/checkIntegerish.R
+a7a992b2dd3fefc453b129585044047b *R/checkList.R
+44429c270ff2a07a54ccda66a89e712a *R/checkLogical.R
+a77907ff924cf709c17dc5f9fec7a64b *R/checkMatrix.R
+be0a58caf1587d565bd2e4a220bec9f9 *R/checkNamed.R
+771b8e32022efeea127bbe6ade14f116 *R/checkNames.R
+0b8ae1aa94964c09014463b1b684d381 *R/checkNull.R
+304c2c610fe9f23a383e478b202158c6 *R/checkNumber.R
+22f90d22934205b58607457387dabe02 *R/checkNumeric.R
+489644560780caf623590aa036f74ef9 *R/checkOS.R
+3a28b57223df126616e2a9ef247163b5 *R/checkPathForOutput.R
+6153863470172efebe1f720d99a55069 *R/checkScalar.R
+e595ea93726a9bb38111f19f76349374 *R/checkScalarNA.R
+1c3bff5a57df9af3496ca00b9378c0d4 *R/checkSetEqual.R
+94bf1562cf0d489287575536c1880f39 *R/checkString.R
+4e38f1166137bbb356650117908d42c9 *R/checkSubset.R
+880ba9eb1b3515066f4f93a6ebdb81bf *R/checkTibble.R
+444955685dac38375d5843f1b603b83b *R/checkVector.R
+80ae11a07596493bea7960e2eb65dd73 *R/coalesce.R
+70aa7f27fcf8bbc86e2308f07e74f91f *R/helper.R
+bd5ff342b970d92b9fa99f437af82b72 *R/isIntegerish.R
+ff84258ed1df90286590f258ac0fb831 *R/makeAssertion.R
+b64dfbf277899287a6ed1a67ba0655d0 *R/makeExpectation.R
+81ed256883d6f8b55f9d1278c230997f *R/makeTest.R
+bb9920804c833240611d116614878467 *R/matchArg.R
+ff4363de4c36a2bc34aa0a9aa5be7db2 *R/qassert.R
+6e854ef50da86998ead1aff70307ebdf *R/qassertr.R
+3f12a573026bdfe1a99ccd4678f2f4b1 *R/vname.R
+e461317d090f6344d1e56dc1cbfd4c20 *R/wfwl.R
+9868d692fc49021dce20ddbc673aaa70 *R/zzz.R
+0893877bc2d2b4f97690b53461f25b52 *README.md
+4248993c2fe38bf5d861ef0a52988595 *build/vignette.rds
+7553992bbffab1702dbb096f24d05b3d *inst/doc/checkmate.R
+e05bcd2c1512c7632a9607f9632dd5ff *inst/doc/checkmate.Rmd
+6a98953bdfcacad4f6c67454abc24f9e *inst/doc/checkmate.html
+022139fefe30297f3f1ef95ae27f3901 *inst/include/checkmate.h
+d6a785640832fcd3d6ca78ed101cfdb7 *inst/include/checkmate_stub.c
+28bd8a79ba13344f3e35f6e765fa5610 *man/AssertCollection.Rd
+14427c399c124c522039ca392985a90c *man/anyInfinite.Rd
+2bd1e1737a875d4b6211235645c2c11b *man/anyMissing.Rd
+97b1d46159b7a40fef373d56d4e213aa *man/anyNaN.Rd
+f31c487005ee85ced1c30e5605fb1729 *man/asInteger.Rd
+8c5d6d3c64ba54a23c861cb19f11479c *man/assert.Rd
+97d54daa72a28f5bae94069809b42375 *man/checkAccess.Rd
+1f452772d7fed32c66564e206b846b8b *man/checkArray.Rd
+b50bd25a2b7750040ddc1052ead57425 *man/checkAtomic.Rd
+4ae48a3afb490e36303710df87bb075b *man/checkAtomicVector.Rd
+892eb8a29ba6346e180f4b252484a045 *man/checkCharacter.Rd
+bee5880f5573d5804c73432d32c4b9e6 *man/checkChoice.Rd
+4ea1200f82305bf20345c111298590d8 *man/checkClass.Rd
+c32eaac939edbfc419285703e92e4f90 *man/checkComplex.Rd
+86846062e2aa1831307147fcdf39b279 *man/checkCount.Rd
+6e56b2b7f800fdaf1224c12dba58b843 *man/checkDataFrame.Rd
+f265d9d6c00e977fbe6babf3ce0b86d5 *man/checkDataTable.Rd
+5b86e7f263cf420dc32648b0a950cf4e *man/checkDate.Rd
+59e2cd22b02d5caf72190bb4e1acf6bd *man/checkDirectoryExists.Rd
+7a997b32380f5c3758c37a5b277e03b3 *man/checkEnvironment.Rd
+5ba4ced722edf2c4b086022fbae07f8a *man/checkFactor.Rd
+046d14a0340e003cb33fba85ce0a8885 *man/checkFileExists.Rd
+bf611ac4c01e06bfb64ee94d9f6e7ee8 *man/checkFlag.Rd
+68a9a178bb73ccec387c9782069bebd0 *man/checkFunction.Rd
+57be1623f3104297eb2c3d07c1ed5417 *man/checkInt.Rd
+a8c4994092627fae92ab76d0631c47ce *man/checkInteger.Rd
+d3fc142f3ff330c55618facf396cb5fa *man/checkIntegerish.Rd
+4265abc1e0bd7e346ccb77af94ba35f1 *man/checkList.Rd
+587c14b481b84e37d44ef4114d299f83 *man/checkLogical.Rd
+7439058a85062a5ee701edd771186fd5 *man/checkMatrix.Rd
+3b18bee8b0b7dc17d3c1b5065be606e7 *man/checkNamed.Rd
+2c0a82ef3ab27810b52dc7f45b2c6b4e *man/checkNames.Rd
+3bf879a369c312fc16a8467f443b2dfb *man/checkNull.Rd
+9aad98b6e9f8e5f883c8509e83709837 *man/checkNumber.Rd
+8ac31d0e05c832f82990ab90d964db43 *man/checkNumeric.Rd
+1508713ee4549fc2eadae21a72153e5e *man/checkOS.Rd
+38d0ec9b44949c99ddd80579b4f7e303 *man/checkPathForOutput.Rd
+44c2a9cd944574c11e711ee0b1f1ec87 *man/checkScalar.Rd
+91f057de80081e1aaec589c27cb52ccd *man/checkScalarNA.Rd
+234b03a7ac11c373350e40c68b527a67 *man/checkSetEqual.Rd
+5e20e2bf82a3574c74c1dfc102ca7a63 *man/checkString.Rd
+39432a694e26cf9f9a5dc15d64caf7a6 *man/checkSubset.Rd
+62e036129a90eba3ea343b9deecf67cc *man/checkTibble.Rd
+ba0b9b5fceef00d293a5741c794da380 *man/checkVector.Rd
+9937530320d8a2eff40ec40d1f0b2b6d *man/checkmate-package.Rd
+999e104b727901446d630de2e97d8491 *man/coalesce.Rd
+c9a2e0f04386e03e6cfcf4007dbd8ade *man/makeAssertion.Rd
+732f8188f436856ffcfb6ddf9e57aa54 *man/makeExpectation.Rd
+7e67c63286ad9c675dc9c2e914dfb6ac *man/makeTest.Rd
+a7ffe767232a4dea7a32c0108b23b42d *man/matchArg.Rd
+4443efda93dccea1bc31e0242343b84c *man/qassert.Rd
+54ff00ae512007e252569e2864bb43b5 *man/qassertr.Rd
+773c91e04a029b6373a7f45a03e92136 *man/vname.Rd
+86c9c577e0c85a9e4b12953b428db231 *man/wf.Rd
+7364cb13c05a9a9949cf92dfe621bf55 *src/all_missing.c
+a45e4bb72c61c5b56c40ed0c9c4f8e2d *src/all_missing.h
+558e74eba624ee9b62d5d257eba00370 *src/all_nchar.c
+05d000d647e2b41ccf98b15ea80ee30f *src/all_nchar.h
+9c0140c7ad89352ccd91567fc2e955d7 *src/any_infinite.c
+009448e71f30cd62e70c0ecc541dafac *src/any_infinite.h
+893a462499191663e9d31e160a48514c *src/any_missing.c
+12ca1bba9b80d4831738124f0f44f47a *src/any_missing.h
+6bf8d91bdc2a807f3c3311c5af864c32 *src/any_nan.c
+ee727f245cb4f038f97363dc4774907d *src/any_nan.h
+fdf494fdb57b43b0dfef772e3c9a7911 *src/checkmate_init.c
+767a61939ab1853659f06ad5f041b24a *src/checks.c
+ac315930c4cf3cc1282261cfa9e31b12 *src/checks.h
+4b5f96e9b2eb4ef7d1fc821933ce1c60 *src/guess_type.c
+ed5f21e3cd4c7ed5977fb8d8a4a60fd9 *src/guess_type.h
+830f7df048851f3ef2b11b87b740771a *src/helper.c
+05a21400ec5f4885402112b503d7c9b3 *src/helper.h
+db4e042d2d527f3f5a4f9885ede7c925 *src/is_integerish.c
+37a844b2b1e1e911ee04c708eac97d7e *src/is_integerish.h
+5a0437d1bc45fe09a2e1f9c95ee6c934 *src/qassert.c
+cd08a3a5aaa6423ae4a0cfbe9417423e *src/qassert.h
+5ef1508b1b9c1a281aa9250e341f91dc *src/which_first.c
+e2b31960d1f37134ec1a1ea7261f5826 *src/which_first.h
+44694bd86ba5d694433561ccfac56fc5 *tests/test-all.R
+d08cc925e8934c327878bbeb66668234 *tests/testthat/helper.R
+c74b3874797c89c2ea1cfc9592ffab6e *tests/testthat/test_AssertCollection.R
+88a300e6dcc491c577f62eb8d664dcd9 *tests/testthat/test_anyInfinite.R
+ba67b4d1d4a8943f802f1182e9dcfd42 *tests/testthat/test_anyMissing.R
+a4cdd9e64bb3ccbb6b6443142960b529 *tests/testthat/test_anyNaN.R
+547027ffd3e1ab24d4cfe0c9bd72c260 *tests/testthat/test_asType.R
+ddaec2c7773e4d847cd1c41ce8747e07 *tests/testthat/test_assert.R
+7b1fc897c76160a3e179c3b24148b657 *tests/testthat/test_checkArray.R
+52088640fa738f4ab7e657e8b9b4cd02 *tests/testthat/test_checkAtomic.R
+ad416dbe956f3e6eb38ff46f77a4d8b1 *tests/testthat/test_checkAtomicVector.R
+9febffcd26ff60e4a0d383e6e0a8aafb *tests/testthat/test_checkCharacter.R
+41d56e1b483893433d81e3da011a6d90 *tests/testthat/test_checkChoice.R
+f314c946ccfe0bff0d3264925be79716 *tests/testthat/test_checkClass.R
+2501bf94e2f24021d01db9931f0f0e5d *tests/testthat/test_checkComplex.R
+0bb3a368b5686c4917c154dacc7a3ceb *tests/testthat/test_checkCount.R
+23620252e0e5d18793e1a54df4e86f6c *tests/testthat/test_checkDataFrame.R
+eab5a4c0df22854764a92ccb0a94f4ce *tests/testthat/test_checkDataTable.R
+5c5d9baa5e349abd01352fea2271c4c0 *tests/testthat/test_checkDate.R
+34c6dc60267982609546dfc50cdc58a5 *tests/testthat/test_checkEnvironment.R
+d48dcd64af88c011a8b25197d3ac5bdf *tests/testthat/test_checkFactor.R
+44fc347e841d8d87fc5a116ec9c32468 *tests/testthat/test_checkFilesystem.R
+2ca8bc06283a7c62bdd32f28ccdbda2a *tests/testthat/test_checkFlag.R
+a62888d365c865a34f1f2b5b5550702b *tests/testthat/test_checkFunction.R
+e4b3ab35eb4fe35849251783f8151fcd *tests/testthat/test_checkInt.R
+dad63a92acafbb9d1d9dba9731ffbd0f *tests/testthat/test_checkInteger.R
+34e95b11c942a27b1f2935a28d686100 *tests/testthat/test_checkIntegerish.R
+c79e76785947395d680243b0ab46ec83 *tests/testthat/test_checkList.R
+edd75ed2d26e8ab74c186bff3511a403 *tests/testthat/test_checkLogical.R
+a65129dc7218fa3d5c5f0721d0232b51 *tests/testthat/test_checkMatrix.R
+518e6fd2f482c4a07c49cab98893528a *tests/testthat/test_checkNamed.R
+1f690e6787fd6ce8827b33175e9e91ad *tests/testthat/test_checkNames.R
+5ca56038ba855cffb5996db49724663b *tests/testthat/test_checkNull.R
+522c310bf5964325aff7e7f94b89c8c8 *tests/testthat/test_checkNumber.R
+8990bf7504382c626a46346aed0f920e *tests/testthat/test_checkNumeric.R
+9c9459e3ca644bc36cd29bac722ad1b5 *tests/testthat/test_checkOS.R
+de75d8d474ee541b05666065f39378fd *tests/testthat/test_checkScalar.R
+97f0622df0ea56467eecde699a8f5ba6 *tests/testthat/test_checkScalarNA.R
+d9bd89a962bf68893d16de2c4da40437 *tests/testthat/test_checkSetEqual.R
+6165b8f711cf10ac1400c4e0475395e8 *tests/testthat/test_checkString.R
+88c672b769859b687cca682373b13fdb *tests/testthat/test_checkSubset.R
+a055eae13e5682a19c59a85427d5e45b *tests/testthat/test_checkTibble.R
+7e3bd43a9d03e3e6156c5f0f3d94a6d6 *tests/testthat/test_checkVector.R
+8753de609ab6604b57b1c752ccf6b7d0 *tests/testthat/test_deparse.R
+44e25d51ee7e69b021bb6900a89d62ac *tests/testthat/test_guessType.R
+e73813f27373c2c3449037dca2a36cac *tests/testthat/test_include.R
+04a628f6abd687e087711af1ee88868d *tests/testthat/test_interoperability.R
+bd4632191649731cd59073f4005a4b2c *tests/testthat/test_makeFunction.R
+a43ada07c4347a5d2ba63dc04d49e5a0 *tests/testthat/test_matchArg.R
+52e95aa8ecb54c145d49f0950e5311ac *tests/testthat/test_messages.R
+00cbeec1a63a971705a89308f0e2d708 *tests/testthat/test_qassert.R
+ac5db60f84be6d837df71444b6b1d767 *tests/testthat/test_qassertr.R
+98d5ba13378e03edbc92debb3f37772e *tests/testthat/test_wf.R
+e05bcd2c1512c7632a9607f9632dd5ff *vignettes/checkmate.Rmd
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..c124e88
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,342 @@
+# Generated by roxygen2: do not edit by hand
+
+S3method(print,AssertCollection)
+export("%??%")
+export(allMissing)
+export(anyInfinite)
+export(anyMissing)
+export(anyNaN)
+export(asCount)
+export(asInt)
+export(asInteger)
+export(assert)
+export(assertAccess)
+export(assertArray)
+export(assertAtomic)
+export(assertAtomicVector)
+export(assertCharacter)
+export(assertChoice)
+export(assertClass)
+export(assertComplex)
+export(assertCount)
+export(assertDataFrame)
+export(assertDataTable)
+export(assertDate)
+export(assertDirectory)
+export(assertDirectoryExists)
+export(assertEnvironment)
+export(assertFactor)
+export(assertFile)
+export(assertFileExists)
+export(assertFlag)
+export(assertFunction)
+export(assertInt)
+export(assertInteger)
+export(assertIntegerish)
+export(assertList)
+export(assertLogical)
+export(assertMatrix)
+export(assertNamed)
+export(assertNames)
+export(assertNull)
+export(assertNumber)
+export(assertNumeric)
+export(assertOS)
+export(assertPathForOutput)
+export(assertScalar)
+export(assertScalarNA)
+export(assertSetEqual)
+export(assertString)
+export(assertSubset)
+export(assertTibble)
+export(assertVector)
+export(assert_access)
+export(assert_array)
+export(assert_atomic)
+export(assert_atomic_vector)
+export(assert_character)
+export(assert_choice)
+export(assert_class)
+export(assert_complex)
+export(assert_count)
+export(assert_data_frame)
+export(assert_data_table)
+export(assert_date)
+export(assert_directory)
+export(assert_directory_exists)
+export(assert_environment)
+export(assert_factor)
+export(assert_file)
+export(assert_file_exists)
+export(assert_flag)
+export(assert_function)
+export(assert_int)
+export(assert_integer)
+export(assert_integerish)
+export(assert_list)
+export(assert_logical)
+export(assert_matrix)
+export(assert_named)
+export(assert_names)
+export(assert_null)
+export(assert_number)
+export(assert_numeric)
+export(assert_os)
+export(assert_path_for_output)
+export(assert_scalar)
+export(assert_scalar_na)
+export(assert_set_equal)
+export(assert_string)
+export(assert_subset)
+export(assert_tibble)
+export(assert_vector)
+export(checkAccess)
+export(checkArray)
+export(checkAtomic)
+export(checkAtomicVector)
+export(checkCharacter)
+export(checkChoice)
+export(checkClass)
+export(checkComplex)
+export(checkCount)
+export(checkDataFrame)
+export(checkDataTable)
+export(checkDate)
+export(checkDirectory)
+export(checkDirectoryExists)
+export(checkEnvironment)
+export(checkFactor)
+export(checkFile)
+export(checkFileExists)
+export(checkFlag)
+export(checkFunction)
+export(checkInt)
+export(checkInteger)
+export(checkIntegerish)
+export(checkList)
+export(checkLogical)
+export(checkMatrix)
+export(checkNamed)
+export(checkNames)
+export(checkNull)
+export(checkNumber)
+export(checkNumeric)
+export(checkOS)
+export(checkPathForOutput)
+export(checkScalar)
+export(checkScalarNA)
+export(checkSetEqual)
+export(checkString)
+export(checkSubset)
+export(checkTibble)
+export(checkVector)
+export(check_access)
+export(check_array)
+export(check_atomic)
+export(check_atomic_vector)
+export(check_character)
+export(check_choice)
+export(check_class)
+export(check_complex)
+export(check_count)
+export(check_data_frame)
+export(check_data_table)
+export(check_date)
+export(check_directory_exists)
+export(check_environment)
+export(check_factor)
+export(check_file_exists)
+export(check_flag)
+export(check_function)
+export(check_int)
+export(check_integer)
+export(check_integerish)
+export(check_list)
+export(check_logical)
+export(check_matrix)
+export(check_named)
+export(check_names)
+export(check_null)
+export(check_number)
+export(check_numeric)
+export(check_os)
+export(check_path_for_output)
+export(check_scalar)
+export(check_scalar_na)
+export(check_set_equal)
+export(check_string)
+export(check_subset)
+export(check_tibble)
+export(check_vector)
+export(expect_access)
+export(expect_array)
+export(expect_atomic)
+export(expect_atomic_vector)
+export(expect_character)
+export(expect_choice)
+export(expect_class)
+export(expect_complex)
+export(expect_count)
+export(expect_data_frame)
+export(expect_data_table)
+export(expect_date)
+export(expect_directory)
+export(expect_directory_exists)
+export(expect_environment)
+export(expect_factor)
+export(expect_file)
+export(expect_file_exists)
+export(expect_flag)
+export(expect_function)
+export(expect_int)
+export(expect_integer)
+export(expect_integerish)
+export(expect_list)
+export(expect_logical)
+export(expect_matrix)
+export(expect_names)
+export(expect_number)
+export(expect_numeric)
+export(expect_os)
+export(expect_path_for_output)
+export(expect_scalar)
+export(expect_scalar_na)
+export(expect_set_equal)
+export(expect_string)
+export(expect_subset)
+export(expect_tibble)
+export(expect_vector)
+export(makeAssertCollection)
+export(makeAssertion)
+export(makeAssertionFunction)
+export(makeExpectation)
+export(makeExpectationFunction)
+export(makeTest)
+export(makeTestFunction)
+export(matchArg)
+export(qassert)
+export(qassertr)
+export(qexpect)
+export(qexpectr)
+export(qtest)
+export(qtestr)
+export(reportAssertions)
+export(testAccess)
+export(testArray)
+export(testAtomic)
+export(testAtomicVector)
+export(testCharacter)
+export(testChoice)
+export(testClass)
+export(testComplex)
+export(testCount)
+export(testDataFrame)
+export(testDataTable)
+export(testDate)
+export(testDirectory)
+export(testDirectoryExists)
+export(testEnvironment)
+export(testFactor)
+export(testFile)
+export(testFileExists)
+export(testFlag)
+export(testFunction)
+export(testInt)
+export(testInteger)
+export(testIntegerish)
+export(testList)
+export(testLogical)
+export(testMatrix)
+export(testNamed)
+export(testNames)
+export(testNull)
+export(testNumber)
+export(testNumeric)
+export(testOS)
+export(testPathForOutput)
+export(testScalar)
+export(testScalarNA)
+export(testSetEqual)
+export(testString)
+export(testSubset)
+export(testTibble)
+export(testVector)
+export(test_access)
+export(test_array)
+export(test_atomic)
+export(test_atomic_vector)
+export(test_character)
+export(test_choice)
+export(test_class)
+export(test_complex)
+export(test_count)
+export(test_data_frame)
+export(test_data_table)
+export(test_date)
+export(test_directory)
+export(test_directory_exists)
+export(test_environment)
+export(test_factor)
+export(test_file_exists)
+export(test_flag)
+export(test_function)
+export(test_int)
+export(test_integer)
+export(test_integerish)
+export(test_list)
+export(test_logical)
+export(test_matrix)
+export(test_named)
+export(test_names)
+export(test_null)
+export(test_number)
+export(test_numeric)
+export(test_os)
+export(test_path_for_output)
+export(test_scalar)
+export(test_scalar_na)
+export(test_set_equal)
+export(test_string)
+export(test_subset)
+export(test_tibble)
+export(test_vector)
+export(vname)
+export(wf)
+export(wl)
+import(backports)
+importFrom(utils,getFromNamespace)
+importFrom(utils,head)
+importFrom(utils,packageVersion)
+importFrom(utils,tail)
+useDynLib(checkmate,c_all_missing)
+useDynLib(checkmate,c_any_infinite)
+useDynLib(checkmate,c_any_missing)
+useDynLib(checkmate,c_any_nan)
+useDynLib(checkmate,c_check_array)
+useDynLib(checkmate,c_check_atomic)
+useDynLib(checkmate,c_check_atomic_vector)
+useDynLib(checkmate,c_check_character)
+useDynLib(checkmate,c_check_complex)
+useDynLib(checkmate,c_check_count)
+useDynLib(checkmate,c_check_dataframe)
+useDynLib(checkmate,c_check_factor)
+useDynLib(checkmate,c_check_flag)
+useDynLib(checkmate,c_check_int)
+useDynLib(checkmate,c_check_integer)
+useDynLib(checkmate,c_check_integerish)
+useDynLib(checkmate,c_check_list)
+useDynLib(checkmate,c_check_logical)
+useDynLib(checkmate,c_check_matrix)
+useDynLib(checkmate,c_check_named)
+useDynLib(checkmate,c_check_names)
+useDynLib(checkmate,c_check_number)
+useDynLib(checkmate,c_check_numeric)
+useDynLib(checkmate,c_check_scalar)
+useDynLib(checkmate,c_check_string)
+useDynLib(checkmate,c_check_vector)
+useDynLib(checkmate,c_guess_type)
+useDynLib(checkmate,c_is_integerish)
+useDynLib(checkmate,c_qassert)
+useDynLib(checkmate,c_qtest)
+useDynLib(checkmate,c_which_first)
+useDynLib(checkmate,c_which_last)
diff --git a/NEWS.md b/NEWS.md
new file mode 100644
index 0000000..99c8af1
--- /dev/null
+++ b/NEWS.md
@@ -0,0 +1,167 @@
+# Version 1.8.2 (2016-xx-xx)
+* `*Matrix` and `*Array` now additionally allow to check for integerish storage
+  type via argument "mode".
+* Functions `*Count`, `*Int`, `*Number`, `*Integer`, `*Integerish` and
+  `*Numeric` do not accept logical values any more.
+* `checkAtomicVector` is now more restrictive and prohibits a dimension symbol.
+  Thus, a matrix is not considered an atomic vector any more.
+* Dropped support for AssertCollections in convert functions (`asInt`,
+  `asInteger` and `asCount`).
+* Added `checkTibble`.
+
+# Version 1.8.1 (2016-06-27)
+* Function `test_file` is longer exported.
+* `*Function` does not longer lookup functions with `match.fun`. As a result,
+  passing functions via the string of the function name stopped working.
+* In `qassert` using `f` as first char in a rule now specifies factor (before:
+  function).
+
+# Version 1.8.0 (2016-06-06)
+* Most functions now support the handling of default arguments encoded as `NULL`
+  via argument `null.ok`.
+* Functions `*File` and `*Directory` are deprecated due to name clashes and will
+  be removed in a future version. Please use `*FileExists` or `*DirectoryExists`
+  instead.
+* New helper function `matchArg` to provide a simple an easy way for partial
+  argument matching in combination with an AssertCollection.
+* Added alias functions for all check functions (`check_*`)
+  to provide support for the underscore programming style in `assert()`.
+
+# Version 1.7.4 (2016-04-08)
+* Compatibility with the upcoming testthat version.
+* `expect_` functions now return the checked object invisibly.
+* Changed default of argument `.var.name` for assertions and `label` for
+  expectations: They now default to the return value of the exported function
+  `vname` (instead of missing which confuses some linters).
+* Fixed error message in convert functions: Variable name was not properly
+  looked up by the heuristic.
+* Fixed a bug in `qassertr` and `qtestr` where the error message was not
+  properly generated if multiple rules were provided.
+* New argument `depth` for `qtestr` to control the recursion depth while
+  checking nested lists.
+
+# Version 1.7.3 (2016-03-10)
+* Added `checkDate()`.
+* Argument `.var.name` of assert functions now has \code{NULL} as default value
+  (instead of missing).
+* Fixed a bug in `*OS` functions.
+* Fixed a bug in `*Directory` functions.
+* New argument `extension` for the `*File` family of functions.
+
+# Version 1.7.2 (2016-02-25)
+* Added `checkOS()`.
+* Argument `fixed` for `*Character` functions now accepts a string instead of a
+  boolean value and thus can directly be used for a substring search.
+* New arguments `min.chars`, `pattern`, `fixed` and `ignore.case`  for the
+  `*String` family of functions.
+* Exported helper functions `wf` (which.first) and `wl` (which.last).
+* Now importing the new backports package for functions `lengths()` and
+  `dir.exists`.
+
+# Version 1.7.1 (2016-02-02)
+* Fixed a segfault while checking an upper bound in qassert/qtest.
+* Some minor speedups
+
+# Version 1.7.0 (2016-01-23)
+* Added alias functions for all functions to support the underscore style, e.g.
+  `assert_numeric` is the new alias for `assertNumeric` and `test_matrix` is the
+  alias for `test_matrix`.
+* All assert functions now invisibly return the tested object instead of `TRUE`
+  and thus can be used with magrittr pipes.
+* Improved speed for most functions by reducing the .Call overhead (Thanks to
+  Hadley Wickham).
+* Added `*DataTable` functions to properly test primary and secondary keys of
+  data tables.
+* Removed `*Percentage` family of functions.
+* Exported functions `makeAssertion`, `makeTest` and `makeExpectation` to assist
+  expanding the package with user-generated checks.
+* Added functions `makeAssertionFunction`, `makeTestFunction` and
+  `makeExpectationFunction` to automatically create the respective functions
+  based on a provided check function.
+
+# Version 1.6.3 (2015-10-23)
+* Assertions can now be collected (via `makeAssertCollection()`) and reported
+  (via `reportAssertions()`).
+* `qassert()` can now perform bound checks on strings.
+* The default for the parameter "ordered" of the `*SetEqual` functions is now
+  set to FALSE, as described in the documentation.
+
+# Version 1.6.2 (2015-07-26)
+* Fixed a compile-time warning.
+* checkmate does not import `testthat` anymore in order to speed up package
+  loading times and to keep the dependencies at a minimum. The `expect_*`
+  family of functions can still be used, the namespace will be loaded on
+  demand.
+
+# Version 1.6.1 (2015-07-16)
+* New family of functions: `expect_*` is intended to be used in combination
+  with testthat. But note that functions `expect_null()` and `expect_named()`
+  are not provided to avoid name clashes with testthat.
+* Added `qexpect()` and `qexpectr()`.
+* Added argument `all.missing` for checks of matricies and data frames.
+* Added `anyNaN()`.
+* Clarified documentation for `assert()` and `allMissing()`.
+* Fixed a bug where bound checks were performed on missing values.
+* Fixed a bug where missingness was not correctly detected in data frames.
+
+# Version 1.6.0 (2015-06-19)
+* Started to support long vectors.
+* Added a short vignette.
+* Improved documentation.
+* New argument "combine" for `assert()` to allow combining check functions with
+  an AND instead of an OR.
+
+# Version 1.5.3 (2015-05-13)
+* Fixed a bug regarding the number of rows in zero-column data frames.
+* Fixed a bug where the type of lists with dimension attribute where reported
+  as "array" or "matrix".
+* Family *Array: new arguments "min.d" and "max.d".
+* Family *Array and *Matrix: Argument "mode" now additionally accepts strings
+  "list" and "atomic".
+
+# Version 1.5.2 (2015-03-19)
+* Fixed: `(assert|check|test)Character(NA_character_, min.chars = 1)` does not
+  eval to TRUE anymore.
+* New arguments for `*Factor` functions: `(n|min|max).levels`.
+* Improved error messages for type and length checks.
+* Improved error messages for missing arguments.
+
+# Version 1.5.1 (2014-12-13)
+* Included a workaround for R's nrow and ncol to properly work with data frames.
+* Fixed a bug handling complex number in checks for integerish values.
+* Improved documentation.
+
+# Version 1.5.0 (2014-10-18)
+* Added `checkNames()`.
+* Added `checkPercentage()`.
+* Added `anyInfinite()`.
+* Fixed error messages for some dimension checks.
+* Fixed an error while checking numerics for finiteness.
+
+# Version 1.4 (2014-09-03)
+* Fixed a bug where rownames and colnames of data.frames where not retrieved
+  correctly.
+* Fixed a bug in `checkVector()` (wrong order of arguments in call to C).
+* Filesystem access: checks for write and executable rights are now disabled
+  on windows.
+
+# Version 1.3 (2014-08-15)
+* Fixed a bug where logical values passed a check for numerics in `qassert`.
+* Family `*SetEqual`: new argument "ordered".
+* `checkPathForOutput`: new argument "overwrite".
+
+# Version 1.2 (2014-07-21)
+* Fixed bug in checkList.
+* Fixed dimnames check on empty matrices and data frames.
+* Added `*SetEqual` functions.
+
+# Version 1.1 (2014-06-28)
+* Improved error messages in `assert*` functions.
+* New argument 'empty.ok' for `*Subset` functions.
+* `assert()` now returns TRUE invisibly (as documented).
+* Fixed handling of zero-length arguments in `checkFunction()`.
+* Fixed error message if duplicated values where found.
+* Fixed a missing check for row names in `checkMatrix()` and `checkDataFrame()`.
+
+# Version 1.0 (2014-06-17)
+* Initial release on CRAN.
diff --git a/R/AssertCollection.R b/R/AssertCollection.R
new file mode 100644
index 0000000..3a9dc75
--- /dev/null
+++ b/R/AssertCollection.R
@@ -0,0 +1,60 @@
+#' Collect multiple assertions
+#' @name AssertCollection
+#'
+#' @param collection [\code{AssertCollection}]\cr
+#'  Object of type \dQuote{AssertCollection} (constructed via \code{makeAssertCollection}).
+#' @description
+#' The function \code{makeAssertCollection()} returns a simple stack-like
+#' closure you can pass to all functions of the \code{assert*}-family.
+#' All messages get collected and can be reported with \code{reportAssertions()}.
+#' Alternatively, you can easily write your own report function or customize the the output of
+#' the report function to a certain degree.
+#' See the example on how to push custom messages or retrieve all stored messages.
+#' @return \code{makeAssertCollection()} returns an object of class \dQuote{AssertCollection} and
+#'  \code{reportCollection} returns invisibly \code{TRUE} if no error is thrown (i.e., no message was
+#'  collected).
+#' @examples
+#' x = "a"
+#' coll = makeAssertCollection()
+#'
+#' print(coll$isEmpty())
+#' assertNumeric(x, add = coll)
+#' coll$isEmpty()
+#' coll$push("Custom error message")
+#' coll$getMessages()
+#' \dontrun{
+#'   reportAssertions(coll)
+#' }
+NULL
+
+#' @export
+#' @rdname AssertCollection
+makeAssertCollection = function() {
+  msgs = character(0L)
+  x = list(push = function(msg) msgs <<- c(msgs, msg), getMessages = function() msgs, isEmpty = function() length(msgs) == 0L)
+  class(x) = "AssertCollection"
+  x
+}
+
+#' @export
+print.AssertCollection = function(x, ...) {
+  n = length(x$getMessages())
+  if (n == 0L) {
+    cat("Empty collection\n")
+  } else {
+    cat(sprintf("Collection of %i assertion%s.\n", n, ifelse(n > 1L, "s", "")))
+  }
+}
+
+#' @export
+#' @rdname AssertCollection
+reportAssertions = function(collection) {
+  assertClass(collection, "AssertCollection")
+  if (!collection$isEmpty()) {
+    msgs = collection$getMessages()
+    context = "%i assertions failed:"
+    err = c(sprintf(context, length(msgs)), strwrap(msgs, prefix = " * "))
+    stop(simpleError(paste0(err, collapse = "\n"), call = sys.call(1L)))
+  }
+  invisible(TRUE)
+}
diff --git a/R/allMissing.R b/R/allMissing.R
new file mode 100644
index 0000000..9a92e2d
--- /dev/null
+++ b/R/allMissing.R
@@ -0,0 +1,14 @@
+#' @rdname anyMissing
+#' @useDynLib checkmate c_all_missing
+#' @export
+#' @examples
+#' allMissing(1:2)
+#' allMissing(c(1, NA))
+#' allMissing(c(NA, NA))
+#' x = data.frame(a = 1:2, b = NA)
+#' # Note how allMissing combines the results for data frames:
+#' allMissing(x)
+#' all(sapply(x, allMissing))
+allMissing = function(x) {
+  .Call(c_all_missing, x)
+}
diff --git a/R/anyInfinite.R b/R/anyInfinite.R
new file mode 100644
index 0000000..8b04ce1
--- /dev/null
+++ b/R/anyInfinite.R
@@ -0,0 +1,18 @@
+#' Check if an object contains infinite values
+#'
+#' @description
+#' Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+#'
+#' @param x [\code{ANY}]\cr
+#'  Object to check.
+#' @return [\code{logical(1)}] Returns \code{TRUE} if any element is \code{-Inf} or \code{Inf}.
+#' @useDynLib checkmate c_any_infinite
+#' @export
+#' @examples
+#' anyInfinite(1:10)
+#' anyInfinite(c(1:10, Inf))
+#' iris[3, 3] = Inf
+#' anyInfinite(iris)
+anyInfinite = function(x) {
+  .Call(c_any_infinite, x)
+}
diff --git a/R/anyMissing.R b/R/anyMissing.R
new file mode 100644
index 0000000..be07582
--- /dev/null
+++ b/R/anyMissing.R
@@ -0,0 +1,29 @@
+#' Check if an object contains missing values
+#'
+#' @description
+#' Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+#' Missingness is defined as \code{NA} or \code{NaN} for atomic types and data frame columns,
+#' \code{NULL} is defined as missing for lists.\cr
+#' \code{allMissing} applied to a \code{data.frame} returns \code{TRUE} if at least one column has
+#' only non-missing values. If you want to perform the less frequent check that there is not a single
+#' non-missing observation present in the \code{data.frame}, use \code{all(sapply(df, allMissing))}
+#' instead.
+#'
+#' @param x [\code{ANY}]\cr
+#'  Object to check.
+#' @return [\code{logical(1)}] Returns \code{TRUE} if any (\code{anyMissing}) or all (\code{allMissing})
+#'  elements of \code{x} are missing (see details), \code{FALSE} otherwise.
+#' @useDynLib checkmate c_any_missing
+#' @export
+#' @examples
+#' anyMissing(c(1, 1))
+#' anyMissing(c(1, NA))
+#' anyMissing(list(1, NULL))
+#'
+#' x = iris
+#' x[, "Species"] = NA
+#' anyMissing(x)
+#' allMissing(x)
+anyMissing = function(x) {
+  .Call(c_any_missing, x)
+}
diff --git a/R/anyNaN.R b/R/anyNaN.R
new file mode 100644
index 0000000..749aab8
--- /dev/null
+++ b/R/anyNaN.R
@@ -0,0 +1,18 @@
+#' Check if an object contains NaN values
+#'
+#' @description
+#' Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+#'
+#' @param x [\code{ANY}]\cr
+#'  Object to check.
+#' @return [\code{logical(1)}] Returns \code{TRUE} if any element is \code{NaN}.
+#' @useDynLib checkmate c_any_nan
+#' @export
+#' @examples
+#' anyNaN(1:10)
+#' anyNaN(c(1:10, NaN))
+#' iris[3, 3] = NaN
+#' anyNaN(iris)
+anyNaN = function(x) {
+  .Call(c_any_nan, x)
+}
diff --git a/R/asInteger.R b/R/asInteger.R
new file mode 100644
index 0000000..753058c
--- /dev/null
+++ b/R/asInteger.R
@@ -0,0 +1,49 @@
+#' Convert an argument to an integer
+#'
+#' @description
+#' \code{asInteger} is intended to be used for vectors while \code{asInt} is
+#' a specialization for scalar integers and \code{asCount} for scalar
+#' non-negative integers.
+#' Convertible are (a) atomic vectors with all elements \code{NA}
+#' and (b) double vectors with all elements being within \code{tol}
+#' range of an integer.
+#'
+#' @param x [any]\cr
+#'  Object to convert.
+#' @template na-handling
+#' @inheritParams checkInteger
+#' @inheritParams checkVector
+#' @template tol
+#' @template var.name
+#' @return Converted \code{x}.
+#' @export
+#' @examples
+#' asInteger(c(1, 2, 3))
+#' asCount(1)
+#' asInt(1)
+asInteger = function(x, tol = sqrt(.Machine$double.eps), lower = -Inf, upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, .var.name = vname(x)) {
+  assertIntegerish(x, tol = tol, lower = lower, upper = upper, any.missing = any.missing, all.missing = all.missing, len = len, min.len = min.len, max.len = max.len, unique = unique, names = names, null.ok = FALSE, .var.name = .var.name)
+  storage.mode(x) = "integer"
+  x
+}
+
+#' @rdname asInteger
+#' @param positive [\code{logical(1)}]\cr
+#'  Must \code{x} be positive (>= 1)?
+#'  Default is \code{FALSE}.
+#' @template na.ok
+#' @export
+asCount = function(x, na.ok = FALSE, positive = FALSE, tol = sqrt(.Machine$double.eps), .var.name = vname(x)) {
+  assertCount(x, na.ok, positive, tol, .var.name = .var.name)
+  storage.mode(x) = "integer"
+  x
+}
+
+#' @rdname asInteger
+#' @template bounds
+#' @export
+asInt = function(x, na.ok = FALSE, lower = -Inf, upper = Inf, tol = sqrt(.Machine$double.eps), .var.name = vname(x)) {
+  assertInt(x, na.ok, lower, upper, tol, .var.name = .var.name)
+  storage.mode(x) = "integer"
+  x
+}
diff --git a/R/assert.R b/R/assert.R
new file mode 100644
index 0000000..77ea17b
--- /dev/null
+++ b/R/assert.R
@@ -0,0 +1,60 @@
+#' Combine multiple checks into one assertion
+#'
+#' @description
+#' You can call this function with an arbitrary number of of \code{check*}
+#' functions, i.e. functions provided by this package or your own functions which
+#' return \code{TRUE} on success and the error message as \code{character(1)} otherwise.
+#' The resulting assertion is successful, if \code{combine} is
+#' \dQuote{or} (default) and at least one check evaluates to \code{TRUE} or
+#' \code{combine} is \dQuote{and} and all checks evaluate to \code{TRUE}.
+#' Otherwise, \code{assert} throws an informative error message.
+#'
+#' @param ... [any]\cr
+#'  List of calls to check functions.
+#' @param combine [\code{character(1)}]\cr
+#'  \dQuote{or} or \dQuote{and} to combine the check functions with an OR
+#'  or AND, respectively.
+#' @template var.name
+#' @return Throws an error if all checks fail and invisibly returns
+#'  \code{TRUE} otherwise.
+#' @export
+#' @examples
+#' x = 1:10
+#' assert(checkNull(x), checkInteger(x, any.missing = FALSE))
+#' \dontrun{
+#' x = 1
+#' assert(checkChoice(x, c("a", "b")), checkDataFrame(x))
+#' }
+assert = function(..., combine = "or", .var.name = NULL) {
+  assertChoice(combine, c("or", "and"))
+  dots = match.call(expand.dots = FALSE)$...
+  env = parent.frame()
+  if (combine == "or") {
+    msgs = character(length(dots))
+    for (i in seq_along(dots)) {
+      val = eval(dots[[i]], envir = env)
+      if (identical(val, TRUE))
+        return(invisible(TRUE))
+      msgs[i] = as.character(val)
+    }
+    if (is.null(.var.name))
+      .var.name = vapply(dots, function(x) as.character(x)[2L], FUN.VALUE = NA_character_)
+    if (length(msgs) > 1L) {
+      msgs = sprintf("%s(%s): %s", vapply(dots, function(x) as.character(x)[1L], FUN.VALUE = NA_character_), .var.name, msgs)
+      msgs = paste0(c("One of the following must apply:", strwrap(msgs, prefix = " * ")), collapse = "\n")
+      mstop("Assertion failed. %s", msgs)
+    } else {
+      mstop("Assertion on '%s' failed. %s.", .var.name, msgs)
+    }
+  } else {
+    for (i in seq_along(dots)) {
+      val = eval(dots[[i]], envir = env)
+      if (!identical(val, TRUE)) {
+        if (is.null(.var.name))
+          .var.name = as.character(dots[[1L]])[2L]
+        mstop("Assertion on '%s' failed. %s.", .var.name, val)
+      }
+    }
+  }
+  invisible(TRUE)
+}
diff --git a/R/checkAccess.R b/R/checkAccess.R
new file mode 100644
index 0000000..e1fb8cd
--- /dev/null
+++ b/R/checkAccess.R
@@ -0,0 +1,73 @@
+#' Check file system access rights
+#'
+#' @templateVar fn Access
+#' @template x
+#' @param access [\code{character(1)}]\cr
+#'  Single string containing possible characters \sQuote{r}, \sQuote{w} and \sQuote{x} to
+#'  force a check for read, write or execute access rights, respectively.
+#'  Write and executable rights are not checked on Windows.
+#' @template checker
+#' @family filesystem
+#' @export
+#' @examples
+#' # Is R's home directory readable?
+#' testAccess(R.home(), "r")
+#'
+#' # Is R's home directory writeable?
+#' testAccess(R.home(), "w")
+checkAccess = function(x, access = "") {
+  qassert(access, "S1")
+  if (nzchar(access)) {
+    access = match(strsplit(access, "")[[1L]], c("r", "w", "x"))
+    if (anyMissing(access) || anyDuplicated(access) > 0L)
+      stop("Access pattern invalid, allowed are 'r', 'w' and 'x'")
+
+    if (1L %in% access) {
+      w = wf(file.access(x, 4L) != 0L)
+      if (length(w) > 0L)
+        return(sprintf("'%s' not readable", x[w]))
+    }
+    if (.Platform$OS.type != "windows") {
+      if (2L %in% access) {
+        w = wf(file.access(x, 2L) != 0L)
+        if (length(w) > 0L)
+          return(sprintf("'%s' not writeable", x[w]))
+      }
+      if (3L %in% access) {
+        w = wf(file.access(x, 1L) != 0L)
+        if (length(w) > 0L)
+          return(sprintf("'%s' not executeable", x[w]))
+      }
+    }
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkAccess
+check_access = checkAccess
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkAccess
+assertAccess = makeAssertionFunction(checkAccess)
+
+#' @export
+#' @rdname checkAccess
+assert_access = assertAccess
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkAccess
+testAccess = makeTestFunction(checkAccess)
+
+#' @export
+#' @rdname checkAccess
+test_access = testAccess
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkAccess
+expect_access = makeExpectationFunction(checkAccess)
diff --git a/R/checkArray.R b/R/checkArray.R
new file mode 100644
index 0000000..22a85a0
--- /dev/null
+++ b/R/checkArray.R
@@ -0,0 +1,56 @@
+#' Check if an argument is an array
+#'
+#' @templateVar fn Array
+#' @template x
+#' @template mode
+#' @param any.missing [\code{logical(1)}]\cr
+#'  Are missing values allowed? Default is \code{TRUE}.
+#' @param d [\code{integer(1)}]\cr
+#'  Exact number of dimensions of array \code{x}.
+#'  Default is \code{NULL} (no check).
+#' @param min.d [\code{integer(1)}]\cr
+#'  Minimum number of dimensions of array \code{x}.
+#'  Default is \code{NULL} (no check).
+#' @param max.d [\code{integer(1)}]\cr
+#'  Maximum number of dimensions of array \code{x}.
+#'  Default is \code{NULL} (no check).
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @family compound
+#' @useDynLib checkmate c_check_array
+#' @export
+#' @examples
+#' checkArray(array(1:27, dim = c(3, 3, 3)), d = 3)
+checkArray = function(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL, max.d = NULL, null.ok = FALSE) {
+  .Call(c_check_array, x, mode, any.missing, d, min.d, max.d, null.ok)
+}
+
+#' @export
+#' @rdname checkArray
+check_array = checkArray
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkArray
+assertArray = makeAssertionFunction(checkArray, c.fun = "c_check_array")
+
+#' @export
+#' @rdname checkArray
+assert_array = assertArray
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkArray
+testArray = makeTestFunction(checkArray, c.fun = "c_check_array")
+
+#' @export
+#' @rdname checkArray
+test_array = testArray
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkArray
+expect_array = makeExpectationFunction(checkArray, c.fun = "c_check_array")
diff --git a/R/checkAtomic.R b/R/checkAtomic.R
new file mode 100644
index 0000000..98511b3
--- /dev/null
+++ b/R/checkAtomic.R
@@ -0,0 +1,47 @@
+#' Check that an argument is an atomic vector
+#'
+#' @description
+#' For the definition of \dQuote{atomic}, see \code{\link[base]{is.atomic}}.
+#'
+#' @templateVar fn Atmoic
+#' @template x
+#' @inheritParams checkVector
+#' @template checker
+#' @useDynLib checkmate c_check_atomic
+#' @export
+#' @family basetypes
+#' @family atomicvector
+#' @examples
+#' testAtomic(letters, min.len = 1L, any.missing = FALSE)
+checkAtomic = function(x, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL) {
+  .Call(c_check_atomic, x, any.missing, all.missing, len, min.len, max.len, unique, names)
+}
+
+#' @export
+#' @rdname checkAtomic
+check_atomic = checkAtomic
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkAtomic
+assertAtomic = makeAssertionFunction(checkAtomic, c.fun = "c_check_atomic")
+
+#' @export
+#' @rdname checkAtomic
+assert_atomic = assertAtomic
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkAtomic
+testAtomic = makeTestFunction(checkAtomic, c.fun = "c_check_atomic")
+
+#' @export
+#' @rdname checkAtomic
+test_atomic = testAtomic
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkAtomic
+expect_atomic = makeExpectationFunction(checkAtomic, c.fun = "c_check_atomic")
diff --git a/R/checkAtomicVector.R b/R/checkAtomicVector.R
new file mode 100644
index 0000000..420140d
--- /dev/null
+++ b/R/checkAtomicVector.R
@@ -0,0 +1,66 @@
+#' Check that an argument is an atomic vector
+#'
+#' @description
+#' An atomic vector is defined slightly different from specifications in
+#' \code{\link[base]{is.atomic}} and \code{\link[base]{is.vector}}:
+#' An atomic vector is either \code{logical}, \code{integer}, \code{numeric},
+#' \code{complex}, \code{character} or \code{raw} and can have any attributes except a
+#' dimension attribute (like matrices).
+#' I.e., a \code{factor} is an atomic vector, but a matrix or \code{NULL} are not.
+#' In short, this is mostly equivalent to \code{is.atomic(x) && !is.null(x) && is.null(dim(x))}.
+#'
+#' @templateVar fn AtomicVector
+#' @template x
+#' @param any.missing [\code{logical(1)}]\cr
+#'  Are vectors with missing values allowed? Default is \code{TRUE}.
+#' @param all.missing [\code{logical(1)}]\cr
+#'  Are vectors with only missing values allowed? Default is \code{TRUE}.
+#' @param len [\code{integer(1)}]\cr
+#'  Exact expected length of \code{x}.
+#' @param min.len [\code{integer(1)}]\cr
+#'  Minimal length of \code{x}.
+#' @param max.len [\code{integer(1)}]\cr
+#'  Maximal length of \code{x}.
+#' @param unique [\code{logical(1)}]\cr
+#'  Must all values be unique? Default is \code{FALSE}.
+#' @param names [\code{character(1)}]\cr
+#'  Check for names. See \code{\link{checkNamed}} for possible values.
+#'  Default is \dQuote{any} which performs no check at all.
+#' @template checker
+#' @family atomicvector
+#' @useDynLib checkmate c_check_atomic_vector
+#' @export
+#' @examples
+#' testAtomicVector(letters, min.len = 1L, any.missing = FALSE)
+checkAtomicVector = function(x, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL) {
+  .Call(c_check_atomic_vector, x, any.missing, all.missing, len, min.len, max.len, unique, names)
+}
+
+#' @export
+#' @rdname checkAtomicVector
+check_atomic_vector = checkAtomicVector
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkAtomicVector
+assertAtomicVector = makeAssertionFunction(checkAtomicVector, c.fun = "c_check_atomic_vector")
+
+#' @export
+#' @rdname checkAtomicVector
+assert_atomic_vector = assertAtomicVector
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkAtomicVector
+testAtomicVector = makeTestFunction(checkAtomicVector, c.fun = "c_check_atomic_vector")
+
+#' @export
+#' @rdname checkAtomicVector
+test_atomic_vector = testAtomicVector
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkAtomicVector
+expect_atomic_vector = makeExpectationFunction(checkAtomicVector, c.fun = "c_check_atomic_vector")
diff --git a/R/checkCharacter.R b/R/checkCharacter.R
new file mode 100644
index 0000000..3218517
--- /dev/null
+++ b/R/checkCharacter.R
@@ -0,0 +1,77 @@
+#' Check if an argument is a vector of type character
+#'
+#' @templateVar fn Character
+#' @template x
+#' @template na-handling
+#' @inheritParams checkVector
+#' @param pattern [\code{character(1L)}]\cr
+#'  Regular expression as used in \code{\link[base]{grepl}}.
+#'  All elements of \code{x} must comply to this pattern.
+#' @param fixed [\code{character(1)}]\cr
+#'  Substring to detect in \code{x}. Will be used as \code{pattern} in \code{\link[base]{grepl}}
+#'  with option \code{fixed} set to \code{TRUE}.
+#'  All elements of \code{x} must contain this substring.
+#' @param ignore.case [\code{logical(1)}]\cr
+#'  See \code{\link[base]{grepl}}. Default is \code{FALSE}.
+#' @param min.chars [\code{integer(1)}]\cr
+#'  Minimum number of characters in each element of \code{x}.
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_character
+#' @export
+#' @examples
+#' testCharacter(letters, min.len = 1, any.missing = FALSE)
+#' testCharacter(letters, min.chars = 2)
+#' testCharacter("example", pattern = "xa")
+checkCharacter = function(x, min.chars = NULL, pattern = NULL, fixed = NULL, ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_character, x, min.chars, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok) %and%
+  checkCharacterPattern(x, pattern, fixed, ignore.case)
+}
+
+checkCharacterPattern = function(x, pattern = NULL, fixed = NULL, ignore.case = FALSE) {
+  if (!is.null(x)) {
+    if (!is.null(pattern)) {
+      qassert(pattern, "S1")
+      ok = grepl(pattern, x, fixed = FALSE, ignore.case = ignore.case)
+      if(!all(ok))
+        return(sprintf("Must comply to pattern '%s'", pattern))
+    }
+    if (!is.null(fixed)) {
+      qassert(fixed, "S1")
+      ok = grepl(fixed, x, fixed = TRUE, ignore.case = ignore.case)
+      if(!all(ok))
+        return(sprintf("Must contain substring '%s'", fixed))
+    }
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkCharacter
+check_character = checkCharacter
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkCharacter
+assertCharacter = makeAssertionFunction(checkCharacter)
+
+#' @export
+#' @rdname checkCharacter
+assert_character = assertCharacter
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkCharacter
+testCharacter = makeTestFunction(checkCharacter)
+
+#' @export
+#' @rdname checkCharacter
+test_character = testCharacter
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkCharacter
+expect_character = makeExpectationFunction(checkCharacter)
diff --git a/R/checkChoice.R b/R/checkChoice.R
new file mode 100644
index 0000000..7c8bd93
--- /dev/null
+++ b/R/checkChoice.R
@@ -0,0 +1,53 @@
+#' Check if an object is an element of a given set
+#'
+#' @templateVar fn Choice
+#' @template x
+#' @param choices [\code{atomic}]\cr
+#'  Set of possible values.
+#' @template checker
+#' @template set
+#' @family set
+#' @export
+#' @examples
+#' testChoice("x", letters)
+#'
+#' # x is converted before the comparison if necessary
+#' # note that this is subject to change in a future version
+#' testChoice(factor("a"), "a")
+#' testChoice(1, "1")
+#' testChoice(1, as.integer(1))
+checkChoice = function(x, choices) {
+  qassert(choices, "a")
+  if (!qtest(x, "a1") || x %nin% choices)
+    return(sprintf("Must be element of set {'%s'}", paste0(unique(choices), collapse = "','")))
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkChoice
+check_choice = checkChoice
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkChoice
+assertChoice = makeAssertionFunction(checkChoice)
+
+#' @export
+#' @rdname checkChoice
+assert_choice = assertChoice
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkChoice
+testChoice = makeTestFunction(checkChoice)
+
+#' @export
+#' @rdname checkChoice
+test_choice = testChoice
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkChoice
+expect_choice = makeExpectationFunction(checkChoice)
diff --git a/R/checkClass.R b/R/checkClass.R
new file mode 100644
index 0000000..3de4e54
--- /dev/null
+++ b/R/checkClass.R
@@ -0,0 +1,82 @@
+#' Check the class membership of an argument
+#'
+#' @templateVar fn Class
+#' @template x
+#' @param classes [\code{character}]\cr
+#'  Class names to check for inheritance with \code{\link[base]{inherits}}.
+#' @param ordered [\code{logical(1)}]\cr
+#'  Expect \code{x} to be specialized in provided order.
+#'  Default is \code{FALSE}.
+#' @template checker
+#' @family attributes
+#' @export
+#' @examples
+#' # Create an object with classes "foo" and "bar"
+#' x = 1
+#' class(x) = c("foo", "bar")
+#'
+#' # is x of class "foo"?
+#' testClass(x, "foo")
+#'
+#' # is x of class "foo" and "bar"?
+#' testClass(x, c("foo", "bar"))
+#'
+#' # is x of class "foo" or "bar"?
+#' \dontrun{
+#' assert(
+#'   checkClass(x, "foo"),
+#'   checkClass(x, "bar")
+#' )
+#' }
+#' # is x most specialized as "bar"?
+#' testClass(x, "bar", ordered = TRUE)
+checkClass = function(x, classes, ordered = FALSE) {
+  qassert(classes, "S")
+  qassert(ordered, "B1")
+  ord = inherits(x, classes, TRUE)
+  w = wf(ord == 0L)
+
+  if (length(w) > 0L) {
+    cl = class(x)
+    return(sprintf("Must have class '%s', but has class%s '%s'",
+        classes[w], if (length(cl) > 1L) "es" else "", paste0(cl, collapse = "','")))
+  }
+  if (ordered) {
+    w = wf(ord != seq_along(ord))
+    if (length(w) > 0L) {
+      cl = class(x)
+      return(sprintf("Must have class '%s' in position %i, but has class%s '%s'",
+        classes[w], w, if (length(cl) > 1L) "es" else "", paste0(cl, collapse = "','")))
+    }
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkClass
+check_class = checkClass
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkClass
+assertClass = makeAssertionFunction(checkClass)
+
+#' @export
+#' @rdname checkClass
+assert_class = assertClass
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkClass
+testClass = makeTestFunction(checkClass)
+
+#' @export
+#' @rdname checkClass
+test_class = testClass
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkClass
+expect_class = makeExpectationFunction(checkClass)
diff --git a/R/checkComplex.R b/R/checkComplex.R
new file mode 100644
index 0000000..995dae2
--- /dev/null
+++ b/R/checkComplex.R
@@ -0,0 +1,46 @@
+#' Check if an argument is a vector of type complex
+#'
+#' @templateVar fn Complex
+#' @template x
+#' @template na-handling
+#' @inheritParams checkVector
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_complex
+#' @export
+#' @examples
+#' testComplex(1)
+#' testComplex(1+1i)
+checkComplex = function(x, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_complex, x, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkComplex
+check_complex = checkComplex
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkComplex
+assertComplex = makeAssertionFunction(checkComplex, c.fun = "c_check_complex")
+
+#' @export
+#' @rdname checkComplex
+assert_complex = assertComplex
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkComplex
+testComplex = makeTestFunction(checkComplex, c.fun = "c_check_complex")
+
+#' @export
+#' @rdname checkComplex
+test_complex = testComplex
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkComplex
+expect_complex = makeExpectationFunction(checkComplex, c.fun = "c_check_complex")
diff --git a/R/checkCount.R b/R/checkCount.R
new file mode 100644
index 0000000..1c3f7d4
--- /dev/null
+++ b/R/checkCount.R
@@ -0,0 +1,53 @@
+#' Check if an argument is a count
+#'
+#' @description
+#' A count is defined as non-negative integerish value.
+#'
+#' @templateVar fn Count
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @param positive [\code{logical(1)}]\cr
+#'  Must \code{x} be positive (>= 1)?
+#'  Default is \code{FALSE}, allowing 0.
+#' @template tol
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @useDynLib checkmate c_check_count
+#' @export
+#' @examples
+#' testCount(1)
+#' testCount(-1)
+checkCount = function(x, na.ok = FALSE, positive = FALSE, tol = sqrt(.Machine$double.eps), null.ok = FALSE) {
+  .Call(c_check_count, x, na.ok, positive, tol, null.ok)
+}
+
+#' @export
+#' @rdname checkCount
+check_count = checkCount
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkCount
+assertCount = makeAssertionFunction(checkCount, c.fun = "c_check_count")
+
+#' @export
+#' @rdname checkCount
+assert_count = assertCount
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkCount
+testCount = makeTestFunction(checkCount, c.fun = "c_check_count")
+
+#' @export
+#' @rdname checkCount
+test_count = testCount
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkCount
+expect_count = makeExpectationFunction(checkCount, c.fun = "c_check_count")
diff --git a/R/checkDataFrame.R b/R/checkDataFrame.R
new file mode 100644
index 0000000..d5a43ab
--- /dev/null
+++ b/R/checkDataFrame.R
@@ -0,0 +1,48 @@
+#' Check if an argument is a data frame
+#'
+#' @templateVar fn DataFrame
+#' @template x
+#' @inheritParams checkMatrix
+#' @inheritParams checkList
+#' @template null.ok
+#' @template checker
+#' @family compound
+#' @family basetypes
+#' @export
+#' @useDynLib checkmate c_check_dataframe
+#' @examples
+#' testDataFrame(iris)
+#' testDataFrame(iris, types = c("numeric", "factor"), min.rows = 1, col.names = "named")
+checkDataFrame = function(x, types = character(0L), any.missing = TRUE, all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE) {
+  .Call(c_check_dataframe, x, any.missing, all.missing, min.rows, min.cols, nrows, ncols, row.names, col.names, null.ok) %and%
+  checkListTypes(x, types)
+}
+
+#' @export
+#' @rdname checkDataFrame
+check_data_frame = checkDataFrame
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkDataFrame
+assertDataFrame = makeAssertionFunction(checkDataFrame)
+
+#' @export
+#' @rdname checkDataFrame
+assert_data_frame = assertDataFrame
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkDataFrame
+testDataFrame = makeTestFunction(checkDataFrame)
+
+#' @export
+#' @rdname checkDataFrame
+test_data_frame = testDataFrame
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkDataFrame
+expect_data_frame = makeExpectationFunction(checkDataFrame)
diff --git a/R/checkDataTable.R b/R/checkDataTable.R
new file mode 100644
index 0000000..6826180
--- /dev/null
+++ b/R/checkDataTable.R
@@ -0,0 +1,82 @@
+#' Check if an argument is a data table
+#'
+#' @templateVar fn DataTable
+#' @template x
+#' @inheritParams checkMatrix
+#' @inheritParams checkList
+#' @inheritParams checkDataFrame
+#' @param key [\code{character}]\cr
+#'   Expected primary key(s) of the data table.
+#' @param index [\code{character}]\cr
+#'   Expected secondary key(s) of the data table.
+#' @template null.ok
+#' @template checker
+#' @family compound
+#' @export
+#' @examples
+#' library(data.table)
+#' dt = as.data.table(iris)
+#' setkeyv(dt, "Species")
+#' setkeyv(dt, "Sepal.Length", physical = FALSE)
+#' testDataTable(dt)
+#' testDataTable(dt, key = "Species", index = "Sepal.Length", any.missing = FALSE)
+checkDataTable = function(x, key = NULL, index = NULL, types = character(0L), any.missing = TRUE, all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE) {
+  checkDataFrame(x, types, any.missing, all.missing, min.rows, min.cols, nrows, ncols, row.names, col.names, null.ok) %and%
+    checkDataTableProps(x, key, index)
+}
+
+checkDataTableProps = function(x, key = NULL, index = NULL) {
+  if (!is.null(x)) {
+    if (!requireNamespace("data.table", quietly = TRUE))
+      stop("Install 'data.table' to perform checks of data tables")
+    if (!data.table::is.data.table(x))
+      return("Must be a data.table")
+    if (!is.null(key)) {
+      qassert(key, "S")
+      if (!setequal(data.table::key(x) %??% character(0L), key))
+        return(sprintf("Must have primary keys: %s", paste0(key, collapse = ",")))
+    }
+    if (!is.null(index)) {
+      qassert(index, "S")
+      indices = strsplit(getDataTableIndexFun()(x) %??% "", "__", fixed = TRUE)[[1L]]
+      if (!setequal(indices, index))
+        return(sprintf("Must have secondary keys (indices): %s", paste0(index, collapse = ",")))
+    }
+  }
+  return(TRUE)
+}
+
+getDataTableIndexFun = function() {
+  if (is.null(checkmate$data.table.index.fun))
+    checkmate$data.table.index.fun = if (packageVersion("data.table") >= "1.9.7") getFromNamespace("indices", "data.table") else data.table::key2
+  checkmate$data.table.index.fun
+}
+
+#' @export
+#' @rdname checkDataTable
+check_data_table = checkDataTable
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkDataTable
+assertDataTable = makeAssertionFunction(checkDataTable)
+
+#' @export
+#' @rdname checkDataTable
+assert_data_table = assertDataTable
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkDataTable
+testDataTable = makeTestFunction(checkDataTable)
+
+#' @export
+#' @rdname checkDataTable
+test_data_table = testDataTable
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkDataTable
+expect_data_table = makeExpectationFunction(checkDataTable)
diff --git a/R/checkDate.R b/R/checkDate.R
new file mode 100644
index 0000000..42605f5
--- /dev/null
+++ b/R/checkDate.R
@@ -0,0 +1,76 @@
+#' Check that an argument is a Date
+#'
+#' @description
+#' Checks that an object is of class \code{\link[base]{Date}}.
+#'
+#'
+#' @templateVar fn Atmoic
+#' @template x
+#' @param lower [\code{\link[base]{Date}}]\cr
+#'  All dates in \code{x} must be after this date. Comparison is done via \code{\link[base]{Ops.Date}}.
+#' @param upper [\code{\link[base]{Date}}]\cr
+#'  All dates in \code{x} must be before this date. Comparison is done via \code{\link[base]{Ops.Date}}.
+#' @template null.ok
+#' @inheritParams checkVector
+#' @template checker
+#' @family basetypes
+#' @export
+checkDate = function(x, lower = NULL, upper = NULL, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, null.ok = FALSE) {
+  if (is.null(x)) {
+    if (isTRUE(null.ok))
+      return(TRUE)
+    return("Must be of class 'Date', not 'NULL'")
+  }
+  if (!inherits(x, "Date"))
+    return(sprintf("Must be of class 'Date'%s, not '%s'", if (isTRUE(null.ok)) " (or 'NULL')" else "", guessType(x)))
+  checkInteger(as.integer(x), any.missing = any.missing, all.missing = all.missing, len = len, min.len = min.len, max.len = max.len, unique = unique) %and%
+    checkDateBounds(x, lower, upper)
+}
+
+checkDateBounds = function(x, lower, upper) {
+  if (!is.null(lower)) {
+    lower = as.Date(lower, origin = "1970-01-01")
+    if (length(lower) != 1L || is.na(lower))
+      stop("Argument 'lower' must be a single (non-missing) date")
+    if (any(x < lower))
+      return(sprintf("Date must be >= %s", lower))
+  }
+
+  if (!is.null(upper)) {
+    upper = as.Date(upper, origin = "1970-01-01")
+    if (length(upper) != 1L || is.na(upper))
+      stop("Argument 'upper' must be a single (non-missing) date")
+    if (any(x > upper))
+      return(sprintf("Date must be <= %s", upper))
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkDate
+check_date = checkDate
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkDate
+assertDate = makeAssertionFunction(checkDate)
+
+#' @export
+#' @rdname checkDate
+assert_date = assertDate
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkDate
+testDate = makeTestFunction(checkDate)
+
+#' @export
+#' @rdname checkDate
+test_date = testDate
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkDate
+expect_date = makeExpectationFunction(checkDate)
diff --git a/R/checkDirectoryExists.R b/R/checkDirectoryExists.R
new file mode 100644
index 0000000..21e9e9c
--- /dev/null
+++ b/R/checkDirectoryExists.R
@@ -0,0 +1,84 @@
+#' Check for existence and access rights of directories
+#'
+#' @note
+#' The functions without the suffix \dQuote{exists} are deprecated and will be removed
+#' from the package in a future version due to name clashes.
+#'
+#' @templateVar fn DirectoryExists
+#' @template x
+#' @inheritParams checkAccess
+#' @inheritParams checkFile
+#' @template checker
+#' @family filesystem
+#' @export
+#' @examples
+#' # Is R's home directory readable?
+#' testDirectory(R.home(), "r")
+#'
+#' # Is R's home directory readable and writable?
+#' testDirectory(R.home(), "rw")
+checkDirectoryExists = function(x, access = "") {
+  if (!qtest(x, "S+"))
+    return("No directory provided")
+
+  w = wf(!file.exists(x))
+  if (length(w) > 0L)
+    return(sprintf("Directory '%s' does not exists", x[w]))
+
+  w = wf(!dir.exists(x))
+  if (length(w) > 0L)
+    return(sprintf("Directory expected, but file in place: '%s'", x[w]))
+
+  checkAccess(x, access)
+}
+
+#' @export
+#' @rdname checkDirectoryExists
+check_directory_exists = checkDirectoryExists
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkDirectoryExists
+assertDirectoryExists = makeAssertionFunction(checkDirectoryExists)
+
+#' @export
+#' @rdname checkDirectoryExists
+assert_directory_exists = assertDirectoryExists
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkDirectoryExists
+testDirectoryExists = makeTestFunction(checkDirectoryExists)
+
+#' @export
+#' @rdname checkDirectoryExists
+test_directory_exists = testDirectoryExists
+
+#' @export
+#' @rdname checkDirectoryExists
+expect_directory_exists = makeExpectationFunction(checkDirectoryExists)
+
+#' @export
+#' @rdname checkDirectoryExists
+checkDirectory = checkDirectoryExists
+
+#' @export
+#' @rdname checkDirectoryExists
+assertDirectory = assertDirectoryExists
+
+#' @export
+#' @rdname checkDirectoryExists
+assert_directory = assert_directory_exists
+
+#' @export
+#' @rdname checkDirectoryExists
+testDirectory = testDirectoryExists
+
+#' @export
+#' @rdname checkDirectoryExists
+test_directory = test_directory_exists
+
+#' @export
+#' @rdname checkDirectoryExists
+expect_directory = expect_directory_exists
diff --git a/R/checkEnvironment.R b/R/checkEnvironment.R
new file mode 100644
index 0000000..4fd3b51
--- /dev/null
+++ b/R/checkEnvironment.R
@@ -0,0 +1,60 @@
+#' Check if an argument is an environment
+#'
+#' @templateVar fn Environment
+#' @template x
+#' @param contains [\code{character}]\cr
+#'  Vector of object names expected in the environment.
+#'  Defaults to \code{character(0)}.
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @export
+#' @examples
+#' ee = as.environment(list(a = 1))
+#' testEnvironment(ee)
+#' testEnvironment(ee, contains = "a")
+checkEnvironment = function(x, contains = character(0L), null.ok = FALSE) {
+  qassert(contains, "S")
+  if (is.null(x)) {
+    if (identical(null.ok, TRUE))
+      return(TRUE)
+    return("Must be an environment, not 'NULL'")
+  }
+  if (!is.environment(x))
+    return(sprintf("Must be an environment%s, not '%s'", if (isTRUE(null.ok)) " (or 'NULL')" else "", guessType(x)))
+  if (length(contains) > 0L) {
+    w = wf(contains %nin% ls(x, all.names = TRUE))
+    if (length(w) > 0L)
+      return(sprintf("Must contain an object with name '%s'", contains[w]))
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkEnvironment
+check_environment = checkEnvironment
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkEnvironment
+assertEnvironment = makeAssertionFunction(checkEnvironment)
+
+#' @export
+#' @rdname checkEnvironment
+assert_environment = assertEnvironment
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkEnvironment
+testEnvironment = makeTestFunction(checkEnvironment)
+
+#' @export
+#' @rdname checkEnvironment
+test_environment = testEnvironment
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkEnvironment
+expect_environment = makeExpectationFunction(checkEnvironment)
diff --git a/R/checkFactor.R b/R/checkFactor.R
new file mode 100644
index 0000000..d654805
--- /dev/null
+++ b/R/checkFactor.R
@@ -0,0 +1,105 @@
+#' Check if an argument is a factor
+#'
+#' @templateVar fn Factor
+#' @template x
+#' @inheritParams checkVector
+#' @param levels [\code{character}]\cr
+#'  Vector of allowed factor levels.
+#' @param ordered [\code{logical(1)}]\cr
+#'  Check for an ordered factor? If \code{FALSE} or \code{TRUE}, checks explicitly
+#'  for an unordered or ordered factor, respectively.
+#'  Default is \code{NA} which does not perform any additional check.
+#' @param empty.levels.ok [\code{logical(1)}]\cr
+#'  Are empty levels allowed?
+#'  Default is \code{TRUE}.
+#' @param n.levels [\code{integer(1)}]\cr
+#'  Exact number of factor levels.
+#'  Default is \code{NULL} (no check).
+#' @param min.levels [\code{integer(1)}]\cr
+#'  Minimum number of factor levels.
+#'  Default is \code{NULL} (no check).
+#' @param max.levels [\code{integer(1)}]\cr
+#'  Maximum number of factor levels.
+#'  Default is \code{NULL} (no check).
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_factor
+#' @export
+#' @examples
+#' x = factor("a", levels = c("a", "b"))
+#' testFactor(x)
+#' testFactor(x, empty.levels.ok = FALSE)
+checkFactor = function(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL, unique = FALSE, names = NULL, null.ok =  FALSE) {
+  .Call(c_check_factor, x, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok) %and%
+    checkFactorLevels(x, levels, ordered, empty.levels.ok, n.levels, min.levels, max.levels)
+}
+
+checkFactorLevels = function(x , levels = NULL, ordered = NA, empty.levels.ok = TRUE, n.levels = NULL, min.levels = NULL, max.levels = NULL) {
+  if (!is.null(x)) {
+    if (!is.null(levels)) {
+      qassert(levels, "S")
+      if (!setequal(levels(x), levels))
+        return(sprintf("Must have levels: %s", paste0(levels, collapse = ",")))
+    }
+    qassert(ordered, "b1")
+    if (!is.na(ordered)) {
+      x.ordered = is.ordered(x)
+      if (ordered && !x.ordered)
+        return("Must be an ordered factor, but is unordered")
+      else if (!ordered && x.ordered)
+        return("Must be an unordered factor, but is ordered")
+    }
+    qassert(empty.levels.ok, "B1")
+    if (!empty.levels.ok) {
+      empty = setdiff(levels(x), levels(droplevels(x)))
+      if (length(empty) > 0L)
+        return(sprintf("Has has empty levels '%s'", paste0(empty, collapse = "','")))
+    }
+    if (!is.null(n.levels)) {
+      qassert(n.levels, "X1")
+      if (length(levels(x)) != n.levels)
+        return(sprintf("Must have exactly %i levels", n.levels))
+    }
+    if (!is.null(min.levels)) {
+      qassert(min.levels, "X1")
+      if (length(levels(x)) < min.levels)
+        return(sprintf("Must have at least %i levels", min.levels))
+    }
+    if (!is.null(max.levels)) {
+      qassert(max.levels, "X1")
+      if (length(levels(x)) > max.levels)
+        return(sprintf("Must have at most %i levels", max.levels))
+    }
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkFactor
+check_factor = checkFactor
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkFactor
+assertFactor = makeAssertionFunction(checkFactor)
+
+#' @export
+#' @rdname checkFactor
+assert_factor = assertFactor
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkFactor
+testFactor = makeTestFunction(checkFactor)
+
+#' @export
+#' @rdname checkFactor
+test_factor = testFactor
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkFactor
+expect_factor = makeExpectationFunction(checkFactor)
diff --git a/R/checkFileExists.R b/R/checkFileExists.R
new file mode 100644
index 0000000..29bd4a9
--- /dev/null
+++ b/R/checkFileExists.R
@@ -0,0 +1,99 @@
+#' Check existence and access rights of files
+#'
+#' @note
+#' The functions without the suffix \dQuote{exists} are deprecated and will be removed
+#' from the package in a future version due to name clashes.
+#' \code{test_file} has been unexported already.
+#'
+#' @templateVar fn FileExists
+#' @template x
+#' @inheritParams checkAccess
+#' @param extension [\code{character}]\cr
+#'  Vector of allowed file extensions, matched case insensitive.
+#' @template checker
+#' @family filesystem
+#' @export
+#' @examples
+#' # Check if R's COPYING file is readable
+#' testFileExists(file.path(R.home(), "COPYING"), access = "r")
+#'
+#' # Check if R's COPYING file is readable and writable
+#' testFileExists(file.path(R.home(), "COPYING"), access = "rw")
+checkFileExists = function(x, access = "", extension = NULL) {
+  if (!qtest(x, "S+"))
+    return("No file provided")
+
+  w = wf(dir.exists(x))
+  if (length(w) > 0L)
+    return(sprintf("File expected, but directory in place: '%s'", x[w]))
+
+  w = wf(!file.exists(x))
+  if (length(w) > 0L)
+    return(sprintf("File does not exist: '%s'", x[w]))
+
+  checkAccess(x, access) %and% checkFileExtension(x, extension)
+}
+
+checkFileExtension = function(x, extension = NULL) {
+  if (!is.null(extension)) {
+    qassert(extension, "S+")
+    pos = regexpr("\\.([[:alnum:]]+)$", x)
+    ext = ifelse(pos > -1L, tolower(substring(x, pos + 1L)), "")
+    if (any(ext %nin% tolower(extension)))
+      return(sprintf("File extension must be in {'%s'}", paste0(extension, collapse = "','")))
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkFileExists
+check_file_exists = checkFileExists
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkFileExists
+assertFileExists = makeAssertionFunction(checkFileExists)
+
+#' @export
+#' @rdname checkFileExists
+assert_file_exists = assertFileExists
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkFileExists
+testFileExists = makeTestFunction(checkFileExists)
+
+#' @export
+#' @rdname checkFileExists
+test_file_exists = testFileExists
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkFileExists
+expect_file_exists = makeExpectationFunction(checkFileExists)
+
+#' @export
+#' @rdname checkFileExists
+checkFile = checkFileExists
+
+#' @export
+#' @rdname checkFileExists
+assertFile = assertFileExists
+
+#' @export
+#' @rdname checkFileExists
+assert_file = assert_file_exists
+
+#' @export
+#' @rdname checkFileExists
+testFile = testFileExists
+
+##' @export
+##' @rdname checkFileExists
+## test_file = test_file_exists
+
+#' @export
+#' @rdname checkFileExists
+expect_file = expect_file_exists
diff --git a/R/checkFlag.R b/R/checkFlag.R
new file mode 100644
index 0000000..50ab840
--- /dev/null
+++ b/R/checkFlag.R
@@ -0,0 +1,49 @@
+#' Check if an argument is a flag
+#'
+#' @description
+#' A flag is defined as single logical value.
+#'
+#' @templateVar fn Flag
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @useDynLib checkmate c_check_flag
+#' @export
+#' @examples
+#' testFlag(TRUE)
+#' testFlag(1)
+checkFlag = function(x, na.ok = FALSE, null.ok = FALSE) {
+  .Call(c_check_flag, x, na.ok, null.ok)
+}
+
+#' @export
+#' @rdname checkFlag
+check_flag = checkFlag
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkFlag
+assertFlag = makeAssertionFunction(checkFlag, c.fun = "c_check_flag")
+
+#' @export
+#' @rdname checkFlag
+assert_flag = assertFlag
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkFlag
+testFlag = makeTestFunction(checkFlag, c.fun = "c_check_flag")
+
+#' @export
+#' @rdname checkFlag
+test_flag = testFlag
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkFlag
+expect_flag = makeExpectationFunction(checkFlag, c.fun = "c_check_flag")
diff --git a/R/checkFunction.R b/R/checkFunction.R
new file mode 100644
index 0000000..135fb9e
--- /dev/null
+++ b/R/checkFunction.R
@@ -0,0 +1,92 @@
+#' Check if an argument is a function
+#'
+#' @templateVar fn Function
+#' @template x
+#' @param args [\code{character}]\cr
+#'  Expected formal arguments. Checks that a function has no arguments if
+#'  set to \code{character(0)}.
+#'  Default is \code{NULL} (no check).
+#' @param ordered [\code{logical(1)}]\cr
+#'  Flag whether the arguments provided in \code{args} must be the first
+#'  \code{length(args)} arguments of the function in the specified order.
+#'  Default is \code{FALSE}.
+#' @param nargs [\code{integer(1)}]\cr
+#'  Required number of arguments, without \code{...}.
+#'  Default is \code{NULL} (no check).
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @export
+#' @examples
+#' testFunction(mean)
+#' testFunction(mean, args = "x")
+checkFunction = function(x, args = NULL, ordered = FALSE, nargs = NULL, null.ok = FALSE) {
+  if (is.null(x)) {
+    if (identical(null.ok, TRUE))
+      return(TRUE)
+    return("Must be a function, not 'NULL'")
+  }
+
+  if (!is.function(x))
+    return(sprintf("Must be a function%s, not '%s'", if (isTRUE(null.ok)) " (or 'NULL')" else "", guessType(x)))
+
+  if (!is.null(args)) {
+    qassert(args, "S")
+    fargs = names(formals(x)) %??% character(0L)
+
+    if (length(args) == 0L) {
+      if (length(fargs) > 0L)
+        return("May not have any arguments")
+      return(TRUE)
+    }
+
+    qassert(ordered, "B1")
+    if (ordered) {
+      if (any(args != head(fargs, length(args)))) {
+        return(sprintf("Must have first formal arguments (ordered): %s", paste0(args, collapse = ",")))
+      }
+    } else {
+      tmp = setdiff(args, fargs)
+      if (length(tmp))
+        return(sprintf("Must have formal arguments: %s", paste0(tmp, collapse = ",")))
+    }
+  }
+
+  if (!is.null(nargs)) {
+    nargs = asCount(nargs)
+    fnargs = length(setdiff(names(formals(x)) %??% character(0L), "..."))
+    if (nargs != fnargs)
+      return(sprintf("Must have exactly %i formal arguments, but has %i", nargs, fnargs))
+  }
+
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkFunction
+check_function = checkFunction
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkFunction
+assertFunction = makeAssertionFunction(checkFunction)
+
+#' @export
+#' @rdname checkFunction
+assert_function = assertFunction
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkFunction
+testFunction = makeTestFunction(checkFunction)
+
+#' @export
+#' @rdname checkFunction
+test_function = testFunction
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkFunction
+expect_function = makeExpectationFunction(checkFunction)
diff --git a/R/checkInt.R b/R/checkInt.R
new file mode 100644
index 0000000..bf1c7ae
--- /dev/null
+++ b/R/checkInt.R
@@ -0,0 +1,48 @@
+#' Check if an argument is a single integerish value
+#'
+#' @templateVar fn Int
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @template bounds
+#' @template tol
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @useDynLib checkmate c_check_int
+#' @export
+#' @examples
+#' testInt(1)
+#' testInt(-1, lower = 0)
+checkInt = function(x, na.ok = FALSE, lower = -Inf, upper = Inf, tol = sqrt(.Machine$double.eps), null.ok = FALSE) {
+  .Call(c_check_int, x, na.ok, lower, upper, tol, null.ok)
+}
+
+#' @export
+#' @rdname checkInt
+check_int = checkInt
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkInt
+assertInt = makeAssertionFunction(checkInt, c.fun = "c_check_int")
+
+#' @export
+#' @rdname checkInt
+assert_int = assertInt
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkInt
+testInt = makeTestFunction(checkInt, c.fun = "c_check_int")
+
+#' @export
+#' @rdname checkInt
+test_int = testInt
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkInt
+expect_int = makeExpectationFunction(checkInt, c.fun = "c_check_int")
diff --git a/R/checkInteger.R b/R/checkInteger.R
new file mode 100644
index 0000000..82fa4c0
--- /dev/null
+++ b/R/checkInteger.R
@@ -0,0 +1,49 @@
+#' Check if an argument is vector of type integer
+#'
+#' @templateVar fn Integer
+#' @template x
+#' @template na-handling
+#' @inheritParams checkVector
+#' @template bounds
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @seealso \code{\link{asInteger}}
+#' @useDynLib checkmate c_check_integer
+#' @export
+#' @examples
+#' testInteger(1L)
+#' testInteger(1.)
+#' testInteger(1:2, lower = 1, upper = 2, any.missing = FALSE)
+checkInteger = function(x, lower = -Inf, upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_integer, x, lower, upper, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkInteger
+check_integer = checkInteger
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkInteger
+assertInteger = makeAssertionFunction(checkInteger, c.fun = "c_check_integer")
+
+#' @export
+#' @rdname checkInteger
+assert_integer = assertInteger
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkInteger
+testInteger = makeTestFunction(checkInteger, c.fun = "c_check_integer")
+
+#' @export
+#' @rdname checkInteger
+test_integer = testInteger
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkInteger
+expect_integer = makeExpectationFunction(checkInteger, c.fun = "c_check_integer")
diff --git a/R/checkIntegerish.R b/R/checkIntegerish.R
new file mode 100644
index 0000000..51febd9
--- /dev/null
+++ b/R/checkIntegerish.R
@@ -0,0 +1,54 @@
+#' @title Check if an object is an integerish vector
+#'
+#' @description
+#' An integerish value is defined as value safely convertible to integer.
+#' This includes integers and numeric values which are close to an integer
+#' w.r.t. a numeric tolerance.
+#'
+#' @templateVar fn Integerish
+#' @template x
+#' @template na-handling
+#' @inheritParams checkInteger
+#' @inheritParams checkVector
+#' @template tol
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_integerish
+#' @export
+#' @examples
+#' testIntegerish(1L)
+#' testIntegerish(1.)
+#' testIntegerish(1:2, lower = 1L, upper = 2L, any.missing = FALSE)
+checkIntegerish = function(x, tol = sqrt(.Machine$double.eps), lower = -Inf, upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_integerish, x, tol, lower, upper, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkIntegerish
+check_integerish = checkIntegerish
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkIntegerish
+assertIntegerish = makeAssertionFunction(checkIntegerish, c.fun = "c_check_integerish")
+
+#' @export
+#' @rdname checkIntegerish
+assert_integerish = assertIntegerish
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkIntegerish
+testIntegerish = makeTestFunction(checkIntegerish, c.fun = "c_check_integerish")
+
+#' @export
+#' @rdname checkIntegerish
+test_integerish = testIntegerish
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkIntegerish
+expect_integerish = makeExpectationFunction(checkIntegerish, c.fun = "c_check_integerish")
diff --git a/R/checkList.R b/R/checkList.R
new file mode 100644
index 0000000..783f085
--- /dev/null
+++ b/R/checkList.R
@@ -0,0 +1,72 @@
+#' Check if an argument is a list
+#'
+#' @templateVar fn List
+#' @template x
+#' @inheritParams checkVector
+#' @param ... [any]\cr
+#'  Additional parameters used in a call of \code{\link{checkVector}}.
+#' @param types [\code{character}]\cr
+#'  Character vector of class names. Each list element must inherit
+#'  from at least one of the provided types.
+#'  The types \dQuote{logical}, \dQuote{integer}, \dQuote{integerish}, \dQuote{double},
+#'  \dQuote{numeric}, \dQuote{complex}, \dQuote{character}, \dQuote{factor}, \dQuote{atomic}, \dQuote{vector}
+#'  \dQuote{atomicvector}, \dQuote{array}, \dQuote{matrix}, \dQuote{list}, \dQuote{function},
+#'  \dQuote{environment} and \dQuote{null} are supported.
+#'  For other types \code{\link[base]{inherits}} is used as a fallback to check \code{x}'s inheritance.
+#'  Defaults to \code{character(0)} (no check).
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @export
+#' @useDynLib checkmate c_check_list
+#' @examples
+#' testList(list())
+#' testList(as.list(iris), types = c("numeric", "factor"))
+checkList = function(x, types = character(0L), any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_list, x, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok) %and%
+  checkListTypes(x, types)
+}
+
+checkListTypes = function(x, types = character(0L)) {
+  if (is.null(x) || length(types) == 0L)
+    return(TRUE)
+  qassert(types, "S")
+
+  ind = seq_along(x)
+  for (type in types) {
+    f = checkmate$listtypefuns[[type]] %??% function(x) inherits(x, type)
+    ind = ind[!vapply(x[ind], f, FUN.VALUE = NA, USE.NAMES = FALSE)]
+    if (length(ind) == 0L)
+      return(TRUE)
+  }
+  return(sprintf("May only contain the following types: %s", paste0(types, collapse = ",")))
+}
+
+#' @export
+#' @rdname checkList
+check_list = checkList
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkList
+assertList = makeAssertionFunction(checkList)
+
+#' @export
+#' @rdname checkList
+assert_list = assertList
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkList
+testList = makeTestFunction(checkList)
+
+#' @export
+#' @rdname checkList
+test_list = testList
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkList
+expect_list = makeExpectationFunction(checkList)
diff --git a/R/checkLogical.R b/R/checkLogical.R
new file mode 100644
index 0000000..c28fd3c
--- /dev/null
+++ b/R/checkLogical.R
@@ -0,0 +1,46 @@
+#' Check if an argument is a vector of type logical
+#'
+#' @templateVar fn Logical
+#' @template x
+#' @template na-handling
+#' @inheritParams checkVector
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_logical
+#' @export
+#' @examples
+#' testLogical(TRUE)
+#' testLogical(TRUE, min.len = 1)
+checkLogical = function(x, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_logical, x, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkLogical
+check_logical = checkLogical
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkLogical
+assertLogical = makeAssertionFunction(checkLogical, c.fun = "c_check_logical")
+
+#' @export
+#' @rdname checkLogical
+assert_logical = assertLogical
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkLogical
+testLogical = makeTestFunction(checkLogical, c.fun = "c_check_logical")
+
+#' @export
+#' @rdname checkLogical
+test_logical = testLogical
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkLogical
+expect_logical = makeExpectationFunction(checkLogical, c.fun = "c_check_logical")
diff --git a/R/checkMatrix.R b/R/checkMatrix.R
new file mode 100644
index 0000000..39fe70b
--- /dev/null
+++ b/R/checkMatrix.R
@@ -0,0 +1,67 @@
+#' Check if an argument is a matrix
+#'
+#' @templateVar fn Matrix
+#' @template x
+#' @template mode
+#' @param any.missing [\code{logical(1)}]\cr
+#'  Are missing values allowed? Default is \code{TRUE}.
+#' @param all.missing [\code{logical(1)}]\cr
+#'  Are matrices with only missing values allowed? Default is \code{TRUE}.
+#' @param min.rows [\code{integer(1)}]\cr
+#'  Minimum number of rows.
+#' @param min.cols [\code{integer(1)}]\cr
+#'  Minimum number of columns.
+#' @param nrows [\code{integer(1)}]\cr
+#'  Exact number of rows.
+#' @param ncols [\code{integer(1)}]\cr
+#'  Exact number of columns.
+#' @param row.names [\code{character(1)}]\cr
+#'  Check for row names. Default is \dQuote{NULL} (no check).
+#'  See \code{\link{checkNamed}} for possible values.
+#'  Note that you can use \code{\link{checkSubset}} to check for a specific set of names.
+#' @param col.names [\code{character(1)}]\cr
+#'  Check for column names. Default is \dQuote{NULL} (no check).
+#'  See \code{\link{checkNamed}} for possible values.
+#'  Note that you can use \code{\link{checkSubset}} to test for a specific set of names.
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @family compound
+#' @useDynLib checkmate c_check_matrix
+#' @export
+#' @examples
+#' x = matrix(1:9, 3)
+#' colnames(x) = letters[1:3]
+#' testMatrix(x, nrows = 3, min.cols = 1, col.names = "named")
+checkMatrix = function(x, mode = NULL, any.missing = TRUE, all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE) {
+  .Call(c_check_matrix, x, mode, any.missing, all.missing, min.rows, min.cols, nrows, ncols, row.names, col.names, null.ok)
+}
+
+#' @export
+#' @rdname checkMatrix
+check_matrix = checkMatrix
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkMatrix
+assertMatrix = makeAssertionFunction(checkMatrix, c.fun = "c_check_matrix")
+
+#' @export
+#' @rdname checkMatrix
+assert_matrix = assertMatrix
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkMatrix
+testMatrix = makeTestFunction(checkMatrix, c.fun = "c_check_matrix")
+
+#' @export
+#' @rdname checkMatrix
+test_matrix = testMatrix
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkMatrix
+expect_matrix = makeExpectationFunction(checkMatrix, c.fun = "c_check_matrix")
diff --git a/R/checkNamed.R b/R/checkNamed.R
new file mode 100644
index 0000000..a6d8bae
--- /dev/null
+++ b/R/checkNamed.R
@@ -0,0 +1,56 @@
+#' Check if an argument is named
+#'
+#' @templateVar fn Named
+#' @template x
+#' @param type [character(1)]\cr
+#'  Select the check(s) to perform.
+#'  \dQuote{unnamed} checks \code{x} to be unnamed.
+#'  \dQuote{named} (default) checks \code{x} to be named which excludes names to be \code{NA} or empty (\code{""}).
+#'  \dQuote{unique} additionally tests for non-duplicated names.
+#'  \dQuote{strict} checks for unique names which comply to R's variable name restrictions.
+#'  Note that for zero-length \code{x} every name check evaluates to \code{TRUE}.
+#' @template checker
+#' @note
+#' These function are deprecated and will be removed in a future version.
+#' Please use \code{\link{checkNames}} instead.
+#' @useDynLib checkmate c_check_named
+#' @family attributes
+#' @export
+#' @examples
+#' x = 1:3
+#' testNamed(x, "unnamed")
+#' names(x) = letters[1:3]
+#' testNamed(x, "unique")
+checkNamed = function(x, type = "named") {
+  .Call(c_check_named, x, type)
+}
+
+#' @export
+#' @rdname checkNamed
+check_named = checkNamed
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkNamed
+assertNamed = makeAssertionFunction(checkNamed, c.fun = "c_check_named")
+
+#' @export
+#' @rdname checkNamed
+assert_named = assertNamed
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkNamed
+testNamed = makeTestFunction(checkNamed, c.fun = "c_check_named")
+
+#' @export
+#' @rdname checkNamed
+test_named = testNamed
+
+# This function is already provided by testthat
+# #' @export
+# #' @include makeExpectation.R
+# #' @template expect
+# #' @rdname checkNamed
+expect_named = makeExpectationFunction(checkNamed, c.fun = "c_check_named")
diff --git a/R/checkNames.R b/R/checkNames.R
new file mode 100644
index 0000000..767b03b
--- /dev/null
+++ b/R/checkNames.R
@@ -0,0 +1,90 @@
+#' Check names to comply to specific rules
+#'
+#' @description
+#' Similar to \code{\link{checkNamed}} but you can pass the names directly.
+#'
+#' @templateVar fn Named
+#' @param x [\code{character} || \code{NULL}]\cr
+#'  Names to check using rules defined via \code{type}.
+#' @param type [character(1)]\cr
+#'  Type of formal check(s) to perform on the names.
+#'  \dQuote{unnamed} checks \code{x} to be \code{NULL}.
+#'  \dQuote{named} (default) checks \code{x} for regular names which excludes names to be \code{NA} or empty (\code{""}).
+#'  \dQuote{unique} additionally tests for non-duplicated names.
+#'  \dQuote{strict} checks for unique names which comply to R's variable name restrictions.
+#'  Note that for zero-length \code{x} all these name checks evaluate to \code{TRUE}.
+#' @param permutation.of [\code{character}]\cr
+#'  Names provided in \code{x} must be a permutation of the set \code{permutation.of}.
+#'  Duplicated names in \code{permutation.of} are stripped out and duplicated names in \code{x}
+#'  thus lead to a failed check.
+#'  Use this argument instead of \code{identical.to} if the order of the names is not relevant.
+#' @param subset.of [\code{character}]\cr
+#'  Names provided in \code{x} must be subset of the set \code{subset.of}.
+#'  Use this argument if duplicated names are okay.
+#' @param identical.to [\code{character}]\cr
+#'  Names provided in \code{x} must be identical to the vector \code{identical.to}.
+#'  Use this argument instead of \code{permutation.of} if the order of the names is relevant.
+#' @template checker
+#' @useDynLib checkmate c_check_names
+#' @family attributes
+#' @export
+#' @examples
+#' x = 1:3
+#' testNames(x, "unnamed")
+#' names(x) = letters[1:3]
+#' testNames(x, "unique")
+#'
+#' cn = c("Species", "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
+#' assertNames(names(iris), permutation.of = cn)
+checkNames = function(x, type = "named", permutation.of = NULL, subset.of = NULL, identical.to = NULL) {
+  .Call(c_check_names, x, type) %and%
+    checkNamesCmp(x, permutation.of, subset.of, identical.to)
+}
+
+checkNamesCmp = function(x, permutation.of, subset.of, identical.to) {
+  if (!is.null(permutation.of)) {
+    permutation.of = unique(qassert(permutation.of, "S"))
+    if (length(x) != length(permutation.of) || !setequal(x, permutation.of))
+      return(sprintf("Must be a permutation of set {%s}", paste0(permutation.of, collapse = ",")))
+  }
+  if (!is.null(subset.of)) {
+    qassert(subset.of, "S")
+    if (anyMissing(match(x, subset.of)))
+      return(sprintf("Must be a subset of set {%s}", paste0(subset.of, collapse = ",")))
+  }
+  if (!is.null(identical.to)) {
+    qassert(identical.to, "S")
+    if (!identical(x, identical.to))
+      return(sprintf("Must be a identical to (%s)", paste0(identical.to, collapse = ",")))
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkNames
+check_names = checkNames
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkNames
+assertNames = makeAssertionFunction(checkNames)
+
+#' @export
+#' @rdname checkNames
+assert_names = assertNames
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkNames
+testNames = makeTestFunction(checkNames)
+
+#' @export
+#' @rdname checkNames
+test_names = testNames
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkNames
+expect_names = makeExpectationFunction(checkNames)
diff --git a/R/checkNull.R b/R/checkNull.R
new file mode 100644
index 0000000..a5b6bcc
--- /dev/null
+++ b/R/checkNull.R
@@ -0,0 +1,45 @@
+#' Check if an argument is NULL
+#'
+#' @templateVar fn Null
+#' @template x
+#' @template checker
+#' @family basetypes
+#' @export
+#' @examples
+#' testNull(NULL)
+#' testNull(1)
+checkNull = function(x) {
+  if (!is.null(x))
+    return("Must be NULL")
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkNull
+check_null = checkNull
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkNull
+assertNull = makeAssertionFunction(checkNull)
+
+#' @export
+#' @rdname checkNull
+assert_null = assertNull
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkNull
+testNull = makeTestFunction(checkNull)
+
+#' @export
+#' @rdname checkNull
+test_null = testNull
+
+# This function is already provided by testthat
+# #' @export
+# #' @include makeExpectation.R
+# #' @template expect
+# #' @rdname checkNull
+expect_null = makeExpectationFunction(checkNull)
diff --git a/R/checkNumber.R b/R/checkNumber.R
new file mode 100644
index 0000000..814a086
--- /dev/null
+++ b/R/checkNumber.R
@@ -0,0 +1,49 @@
+#' Check if an argument is a single numeric value
+#'
+#' @templateVar fn Number
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @template bounds
+#' @param finite [\code{logical(1)}]\cr
+#'  Check for only finite values? Default is \code{FALSE}.
+#' @template null.ok
+#' @template checker
+#' @useDynLib checkmate c_check_number
+#' @family scalars
+#' @export
+#' @examples
+#' testNumber(1)
+#' testNumber(1:2)
+checkNumber = function(x, na.ok = FALSE, lower = -Inf, upper = Inf, finite = FALSE, null.ok = FALSE) {
+  .Call(c_check_number, x, na.ok, lower, upper, finite, null.ok)
+}
+
+#' @export
+#' @rdname checkNumber
+check_number = checkNumber
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkNumber
+assertNumber = makeAssertionFunction(checkNumber, c.fun = "c_check_number")
+
+#' @export
+#' @rdname checkNumber
+assert_number = assertNumber
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkNumber
+testNumber = makeTestFunction(checkNumber, c.fun = "c_check_number")
+
+#' @export
+#' @rdname checkNumber
+test_number = testNumber
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkNumber
+expect_number = makeExpectationFunction(checkNumber, c.fun = "c_check_number")
diff --git a/R/checkNumeric.R b/R/checkNumeric.R
new file mode 100644
index 0000000..2d3b28f
--- /dev/null
+++ b/R/checkNumeric.R
@@ -0,0 +1,49 @@
+#' Check that an argument is a vector of type numeric
+#'
+#' @templateVar fn Numeric
+#' @template x
+#' @template na-handling
+#' @inheritParams checkVector
+#' @template bounds
+#' @param finite [\code{logical(1)}]\cr
+#'  Check for only finite values? Default is \code{FALSE}.
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @useDynLib checkmate c_check_numeric
+#' @export
+#' @examples
+#' testNumeric(1)
+#' testNumeric(1, min.len = 1, lower = 0)
+checkNumeric = function(x, lower = -Inf, upper = Inf, finite = FALSE, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_numeric, x, lower, upper, finite, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkNumeric
+check_numeric = checkNumeric
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkNumeric
+assertNumeric = makeAssertionFunction(checkNumeric, c.fun = "c_check_numeric")
+
+#' @export
+#' @rdname checkNumeric
+assert_numeric = assertNumeric
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkNumeric
+testNumeric = makeTestFunction(checkNumeric, c.fun = "c_check_numeric")
+
+#' @export
+#' @rdname checkNumeric
+test_numeric = testNumeric
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkNumeric
+expect_numeric = makeExpectationFunction(checkNumeric, c.fun = "c_check_numeric")
diff --git a/R/checkOS.R b/R/checkOS.R
new file mode 100644
index 0000000..95aec38
--- /dev/null
+++ b/R/checkOS.R
@@ -0,0 +1,51 @@
+#' Check the operating system
+#'
+#' @templateVar fn OS
+#' @param os [\code{character(1)}]\cr
+#'  Check the operating system to be in a set with possible elements \dQuote{windows},
+#'  \dQuote{mac}, \dQuote{linux} and \dQuote{solaris}.
+#' @template checker
+#' @export
+#' @examples
+#' testOS("linux")
+checkOS = function(os) {
+  ok = match.arg(os, c("windows", "mac", "linux", "solaris"), several.ok = TRUE)
+  if (checkmate$os %nin% ok)
+    return(sprintf("OS must be %s", paste0(ok, collapse = " or ")))
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkOS
+check_os = checkOS
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkOS
+assertOS = function(os, add = NULL, .var.name = NULL) {
+  res = checkOS(os)
+  makeAssertion(os, res, .var.name %??% "Operating System", add)
+}
+
+#' @export
+#' @rdname checkOS
+assert_os = assertOS
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkOS
+testOS = makeTestFunction(checkOS)
+
+#' @export
+#' @rdname checkOS
+test_os = testOS
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkOS
+expect_os = function(os, info = NULL, label = NULL) {
+  res = checkOS(os)
+  makeExpectation(checkmate$os, res, info, label = label %??% "Operating System")
+}
diff --git a/R/checkPathForOutput.R b/R/checkPathForOutput.R
new file mode 100644
index 0000000..4322bd3
--- /dev/null
+++ b/R/checkPathForOutput.R
@@ -0,0 +1,74 @@
+#' @title Check if a path is suited for creating an output file
+#'
+#' @description
+#' Check if a file path can be safely be used to create a file and write to it.
+#'
+#' This is checked:
+#' \itemize{
+#'  \item{Does \code{dirname(x)} exist?}
+#'  \item{Does no file under path \code{x} exist?}
+#'  \item{Is \code{dirname(x)} writeable?}
+#' }
+#' Paths are relative to the current working directory.
+#'
+#' @templateVar fn PathForOutput
+#' @template x
+#' @param overwrite [\code{logical(1)}]\cr
+#'  If \code{TRUE}, an existing file in place is allowed if it
+#'  it is both readable and writeable.
+#'  Default is \code{FALSE}.
+#' @template checker
+#' @family filesystem
+#' @export
+#' @examples
+#' # Can we create a file in the tempdir?
+#' testPathForOutput(file.path(tempdir(), "process.log"))
+checkPathForOutput = function(x, overwrite = FALSE) {
+  if (!qtest(x, "S+"))
+    return("No path provided")
+  qassert(overwrite, "B1")
+
+  x = normalizePath(x, mustWork = FALSE)
+  dn = dirname(x)
+
+  w = wf(!dir.exists(dn))
+  if (length(w) > 0L)
+    return(sprintf("Path to file (dirname) does not exist: '%s' of '%s'", dn[w], x[w]))
+
+  w = which(file.exists(x))
+  if (length(w) > 0L) {
+    if (overwrite)
+      return(checkAccess(dn, "w") %and% checkAccess(x[w], "rw"))
+    return(sprintf("File at path already exists: '%s'", x[w]))
+  }
+  return(checkAccess(dn, "w"))
+}
+
+#' @export
+#' @rdname checkPathForOutput
+check_path_for_output = checkPathForOutput
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkPathForOutput
+assertPathForOutput = makeAssertionFunction(checkPathForOutput)
+
+#' @export
+#' @rdname checkPathForOutput
+assert_path_for_output = assertPathForOutput
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkPathForOutput
+testPathForOutput = makeTestFunction(checkPathForOutput)
+
+#' @export
+#' @rdname checkPathForOutput
+test_path_for_output = testPathForOutput
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkPathForOutput
+expect_path_for_output = makeExpectationFunction(checkPathForOutput)
diff --git a/R/checkScalar.R b/R/checkScalar.R
new file mode 100644
index 0000000..df0f6e1
--- /dev/null
+++ b/R/checkScalar.R
@@ -0,0 +1,46 @@
+#' Check if an argument is a single atomic value
+#'
+#' @templateVar fn Scalar
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @useDynLib checkmate c_check_scalar
+#' @export
+#' @examples
+#' testScalar(1)
+#' testScalar(1:10)
+checkScalar = function(x, na.ok = FALSE, null.ok = FALSE) {
+  .Call(c_check_scalar, x, na.ok, null.ok)
+}
+
+#' @export
+#' @rdname checkScalar
+check_scalar = checkScalar
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkScalar
+assertScalar = makeAssertionFunction(checkScalar, c.fun = "c_check_scalar")
+
+#' @export
+#' @rdname checkScalar
+assert_scalar = assertScalar
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkScalar
+testScalar = makeTestFunction(checkScalar, c.fun = "c_check_scalar")
+
+#' @export
+#' @rdname checkScalar
+test_scalar = testScalar
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkScalar
+expect_scalar = makeExpectationFunction(checkScalar, c.fun = "c_check_scalar")
diff --git a/R/checkScalarNA.R b/R/checkScalarNA.R
new file mode 100644
index 0000000..f587d11
--- /dev/null
+++ b/R/checkScalarNA.R
@@ -0,0 +1,51 @@
+#' Check if an argument is a single missing value
+#'
+#' @templateVar fn ScalarNA
+#' @template x
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @export
+#' @examples
+#' testScalarNA(1)
+#' testScalarNA(NA_real_)
+#' testScalarNA(rep(NA, 2))
+checkScalarNA = function(x, null.ok = FALSE) {
+  if (is.null(x)) {
+    if (identical(null.ok, TRUE))
+      return(TRUE)
+    return("Must be a scalar missing value, not 'NULL'")
+  }
+  if (length(x) != 1L || !is.na(x))
+    return(paste0("Must be a scalar missing value", if (isTRUE(null.ok)) " (or 'NULL')" else ""))
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkScalarNA
+check_scalar_na = checkScalarNA
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkScalarNA
+assertScalarNA = makeAssertionFunction(checkScalarNA)
+
+#' @export
+#' @rdname checkScalarNA
+assert_scalar_na = assertScalarNA
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkScalarNA
+testScalarNA = makeTestFunction(checkScalarNA)
+
+#' @export
+#' @rdname checkScalarNA
+test_scalar_na = testScalarNA
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkScalarNA
+expect_scalar_na = makeExpectationFunction(checkScalarNA)
diff --git a/R/checkSetEqual.R b/R/checkSetEqual.R
new file mode 100644
index 0000000..1f4f1e5
--- /dev/null
+++ b/R/checkSetEqual.R
@@ -0,0 +1,65 @@
+#' Check if an argument is equal to a given set
+#'
+#' @templateVar fn Subset
+#' @template x
+#' @param y [\code{atomic}]\cr
+#'  Set to compare with.
+#' @param ordered [\code{logical(1)}]\cr
+#' Check \code{x} to have the same length and order as \code{y}, i.e.
+#' check using \dQuote{==} while handling \code{NA}s nicely.
+#' Default is \code{FALSE}.
+#' @template checker
+#' @template set
+#' @family set
+#' @export
+#' @examples
+#' testSetEqual(c("a", "b"), c("a", "b"))
+#' testSetEqual(1:3, 1:4)
+#'
+#' # x is converted before the comparison if necessary
+#' # note that this is subject to change in a future version
+#' testSetEqual(factor("a"), "a")
+#' testSetEqual(1, "1")
+#' testSetEqual(1, as.integer(1))
+checkSetEqual = function(x, y, ordered = FALSE) {
+  qassert(x, "a")
+  qassert(y, "a")
+  qassert(ordered, "B1")
+  if (ordered) {
+    if (length(x) != length(y) || any(xor(is.na(x), is.na(y)) | x != y, na.rm = TRUE))
+      return(sprintf("Must be equal to {'%s'}", paste0(y, collapse = "','")))
+  } else {
+    if (any(match(x, y, 0L) == 0L) || any(match(y, x, 0L) == 0L))
+      return(sprintf("Must be equal to set {'%s'}", paste0(y, collapse = "','")))
+  }
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkSetEqual
+check_set_equal = checkSetEqual
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkSetEqual
+assertSetEqual = makeAssertionFunction(checkSetEqual)
+
+#' @export
+#' @rdname checkSetEqual
+assert_set_equal = assertSetEqual
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkSetEqual
+testSetEqual = makeTestFunction(checkSetEqual)
+
+#' @export
+#' @rdname checkSetEqual
+test_set_equal = testSetEqual
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkSetEqual
+expect_set_equal = makeExpectationFunction(checkSetEqual)
diff --git a/R/checkString.R b/R/checkString.R
new file mode 100644
index 0000000..2216400
--- /dev/null
+++ b/R/checkString.R
@@ -0,0 +1,51 @@
+#' Check if an argument is a string
+#'
+#' @description
+#' A string is defined as a scalar character vector.
+#'
+#' @templateVar fn String
+#' @template x
+#' @template na-handling
+#' @template na.ok
+#' @inheritParams checkCharacter
+#' @template null.ok
+#' @template checker
+#' @family scalars
+#' @export
+#' @useDynLib checkmate c_check_string
+#' @examples
+#' testString("a")
+#' testString(letters)
+checkString = function(x, na.ok = FALSE, min.chars = NULL, pattern = NULL, fixed = NULL, ignore.case = FALSE, null.ok = FALSE) {
+  .Call(c_check_string, x, na.ok, min.chars, null.ok) %and%
+  checkCharacterPattern(x, pattern, fixed, ignore.case)
+}
+
+#' @export
+#' @rdname checkString
+check_string = checkString
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkString
+assertString = makeAssertionFunction(checkString)
+
+#' @export
+#' @rdname checkString
+assert_string = assertString
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkString
+testString = makeTestFunction(checkString)
+
+#' @export
+#' @rdname checkString
+test_string = testString
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkString
+expect_string = makeExpectationFunction(checkString)
diff --git a/R/checkSubset.R b/R/checkSubset.R
new file mode 100644
index 0000000..a090a10
--- /dev/null
+++ b/R/checkSubset.R
@@ -0,0 +1,61 @@
+#' Check if an argument is a subset of a given set
+#'
+#' @templateVar fn Subset
+#' @template x
+#' @param choices [\code{atomic}]\cr
+#'  Set of possible values.
+#' @param empty.ok [\code{logical(1)}]\cr
+#'  Treat zero-length \code{x} as subset of any set \code{choices}?
+#'  Default is \code{TRUE}.
+#' @template checker
+#' @template set
+#' @family set
+#' @export
+#' @examples
+#' testSubset(c("a", "z"), letters)
+#' testSubset("ab", letters)
+#' testSubset("Species", names(iris))
+#'
+#' # x is converted before the comparison if necessary
+#' # note that this is subject to change in a future version
+#' testSubset(factor("a"), "a")
+#' testSubset(1, "1")
+#' testSubset(1, as.integer(1))
+checkSubset = function(x, choices, empty.ok = TRUE) {
+  qassert(choices, "a+")
+  qassert(empty.ok, "B1")
+  if (!empty.ok && length(x) == 0L)
+    return(sprintf("Must be a subset of {'%s'}, not empty", paste0(choices, collapse = "','")))
+  if (!is.null(x) && any(x %nin% choices))
+    return(sprintf("Must be a subset of {'%s'}", paste0(choices, collapse = "','")))
+  return(TRUE)
+}
+
+#' @export
+#' @rdname checkSubset
+check_subset = checkSubset
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkSubset
+assertSubset = makeAssertionFunction(checkSubset)
+
+#' @export
+#' @rdname checkSubset
+assert_subset = assertSubset
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkSubset
+testSubset = makeTestFunction(checkSubset)
+
+#' @export
+#' @rdname checkSubset
+test_subset = testSubset
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkSubset
+expect_subset = makeExpectationFunction(checkSubset)
diff --git a/R/checkTibble.R b/R/checkTibble.R
new file mode 100644
index 0000000..1e51579
--- /dev/null
+++ b/R/checkTibble.R
@@ -0,0 +1,55 @@
+#' Check if an argument is a tibble
+#'
+#' @templateVar fn Tibble
+#' @template x
+#' @inheritParams checkMatrix
+#' @inheritParams checkList
+#' @inheritParams checkDataFrame
+#' @template null.ok
+#' @template checker
+#' @family compound
+#' @export
+#' @examples
+#' library(tibble)
+#' x = as_tibble(iris)
+#' testTibble(x)
+#' testTibble(x, nrow = 150, any.missing = FALSE)
+checkTibble = function(x, types = character(0L), any.missing = TRUE, all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE) {
+  if (is.null(x)) {
+    if (identical(null.ok, TRUE))
+      return(TRUE)
+    return("Must be a tibble, not 'NULL'")
+  }
+  if (!inherits(x, "tbl_df"))
+    return(paste0("Must be a tibble", if (isTRUE(null.ok)) " (or 'NULL')" else "", sprintf(", not %s", guessType(x))))
+  checkDataFrame(x, types, any.missing, all.missing, min.rows, min.cols, nrows, ncols, row.names, col.names, null.ok)
+}
+
+#' @export
+#' @rdname checkTibble
+check_tibble = checkTibble
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkTibble
+assertTibble = makeAssertionFunction(checkTibble)
+
+#' @export
+#' @rdname checkTibble
+assert_tibble = assertTibble
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkTibble
+testTibble = makeTestFunction(checkTibble)
+
+#' @export
+#' @rdname checkTibble
+test_tibble = testTibble
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkTibble
+expect_tibble = makeExpectationFunction(checkTibble)
diff --git a/R/checkVector.R b/R/checkVector.R
new file mode 100644
index 0000000..1780be7
--- /dev/null
+++ b/R/checkVector.R
@@ -0,0 +1,65 @@
+#' Check if an argument is a vector
+#'
+#' @templateVar fn Vector
+#' @template x
+#' @param strict [\code{logical(1)}]\cr
+#'  May the vector have additional attributes or perform a
+#'  check for additional attributes like \code{\link[base]{is.vector}}?
+#'  Default is \code{FALSE} which allows e.g. \code{factor}s or \code{data.frame}s
+#'  to be recognized as vectors.
+#' @param any.missing [\code{logical(1)}]\cr
+#'  Are vectors with missing values allowed? Default is \code{TRUE}.
+#' @param all.missing [\code{logical(1)}]\cr
+#'  Are vectors with only missing values allowed? Default is \code{TRUE}.
+#' @param len [\code{integer(1)}]\cr
+#'  Exact expected length of \code{x}.
+#' @param min.len [\code{integer(1)}]\cr
+#'  Minimal length of \code{x}.
+#' @param max.len [\code{integer(1)}]\cr
+#'  Maximal length of \code{x}.
+#' @param unique [\code{logical(1)}]\cr
+#'  Must all values be unique? Default is \code{FALSE}.
+#' @param names [\code{character(1)}]\cr
+#'  Check for names. See \code{\link{checkNamed}} for possible values.
+#'  Default is \dQuote{any} which performs no check at all.
+#'  Note that you can use \code{\link{checkSubset}} to check for a specific set of names.
+#' @template null.ok
+#' @template checker
+#' @family basetypes
+#' @family atomicvector
+#' @useDynLib checkmate c_check_vector
+#' @export
+#' @examples
+#' testVector(letters, min.len = 1L, any.missing = FALSE)
+checkVector = function(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE) {
+  .Call(c_check_vector, x, strict, any.missing, all.missing, len, min.len, max.len, unique, names, null.ok)
+}
+
+#' @export
+#' @rdname checkVector
+check_vector = checkVector
+
+#' @export
+#' @include makeAssertion.R
+#' @template assert
+#' @rdname checkVector
+assertVector = makeAssertionFunction(checkVector, c.fun = "c_check_vector")
+
+#' @export
+#' @rdname checkVector
+assert_vector = assertVector
+
+#' @export
+#' @include makeTest.R
+#' @rdname checkVector
+testVector = makeTestFunction(checkVector, c.fun = "c_check_vector")
+
+#' @export
+#' @rdname checkVector
+test_vector = testVector
+
+#' @export
+#' @include makeExpectation.R
+#' @template expect
+#' @rdname checkVector
+expect_vector = makeExpectationFunction(checkVector, c.fun = "c_check_vector")
diff --git a/R/coalesce.R b/R/coalesce.R
new file mode 100644
index 0000000..13cf243
--- /dev/null
+++ b/R/coalesce.R
@@ -0,0 +1,19 @@
+#' @title Coalesce operator
+#' @rdname coalesce
+#'
+#' @description
+#' Returns the left hand side if not missing nor \code{NULL}, and
+#' the right hand side otherwise.
+#'
+#' @param lhs [any]\cr
+#' Left hand side of the operator. Is returned if not missing or \code{NULL}.
+#' @param rhs [any]\cr
+#' Right hand side of the operator. Is returned if \code{lhs} is missing or \code{NULL}.
+#' @return Either \code{lhs} or \code{rhs}.
+#' @export
+#' @examples
+#' print(NULL %??% 1 %??% 2)
+#' print(names(iris) %??% letters[seq_len(ncol(iris))])
+"%??%" = function(lhs, rhs) {
+  if (missing(lhs) || is.null(lhs)) rhs else lhs
+}
diff --git a/R/helper.R b/R/helper.R
new file mode 100644
index 0000000..5d75e1d
--- /dev/null
+++ b/R/helper.R
@@ -0,0 +1,24 @@
+mstop = function(msg, ...) {
+  stop(simpleError(message = sprintf(msg, ...), call = sys.call(1L)))
+}
+
+"%and%" = function(lhs, rhs) {
+  if (identical(lhs, TRUE)) rhs else lhs
+}
+
+"%nin%" = function(x, y) {
+  !match(x, y, nomatch = 0L)
+}
+
+convertCamelCase = function(x) {
+  tolower(gsub("((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))", "_\\1", x, perl = TRUE))
+}
+
+#' @useDynLib checkmate c_guess_type
+guessType = function(x) {
+  .Call(c_guess_type, x)
+}
+
+isSameType = function(x, y) {
+  identical(typeof(x), typeof(y)) || (is.numeric(x) && is.numeric(y))
+}
diff --git a/R/isIntegerish.R b/R/isIntegerish.R
new file mode 100644
index 0000000..0764720
--- /dev/null
+++ b/R/isIntegerish.R
@@ -0,0 +1,4 @@
+#' @useDynLib checkmate c_is_integerish
+isIntegerish = function(x, tol = sqrt(.Machine$double.eps)) {
+  .Call(c_is_integerish, x, tol)
+}
diff --git a/R/makeAssertion.R b/R/makeAssertion.R
new file mode 100644
index 0000000..8637169
--- /dev/null
+++ b/R/makeAssertion.R
@@ -0,0 +1,66 @@
+#' @title Turn a Check into an Assertion
+#'
+#' @description
+#' \code{makeAssertion} is the internal function used to evaluate the result of a
+#' check and throw an exception if necessary.
+#' \code{makeAssertionFunction} can be used to automatically create an assertion
+#' function based on a check function (see example).
+#'
+#' @template x
+#' @param res [\code{TRUE} | \code{character(1)}]\cr
+#'  The result of a check function: \code{TRUE} for successful checks,
+#'  and an error message as string otherwise.
+#' @param var.name [\code{character(1)}]\cr
+#'  The custom name for \code{x} as passed to any \code{assert*} function.
+#'  Defaults to a heuristic name lookup.
+#' @param collection [\code{\link{AssertCollection}}]\cr
+#'  If an \code{\link{AssertCollection}} is provided, the error message is stored
+#'  in it. If \code{NULL}, an exception is raised if \code{res} is not
+#'  \code{TRUE}.
+#' @return \code{makeAssertion} invisibly returns the checked object if the check was successful,
+#'  and an exception is raised (or its message stored in the collection) otherwise.
+#'  \code{makeAssertionFunction} returns a \code{function}.
+#' @export
+#' @family CustomConstructors
+#' @include helper.R
+#' @examples
+#' # Simple custom check function
+#' checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+#'
+#' # Create the respective assert function
+#' assertFalse = function(x, .var.name = vname(x), add = NULL) {
+#'   res = checkFalse(x)
+#'   makeAssertion(x, res, .var.name, add)
+#' }
+#'
+#' # Alternative: Automatically create such a function
+#' assertFalse = makeAssertionFunction(checkFalse)
+#' print(assertFalse)
+makeAssertion = function(x, res, var.name, collection) {
+  if (!identical(res, TRUE)) {
+    if (is.null(collection))
+      mstop("Assertion on '%s' failed: %s.", var.name, res)
+    collection$push(sprintf("Variable '%s': %s.", var.name, res))
+  }
+  return(invisible(x))
+}
+
+#' @rdname makeAssertion
+#' @template makeFunction
+#' @export
+makeAssertionFunction = function(check.fun, c.fun = NULL, env = parent.frame()) {
+  fn.name = if (!is.character(check.fun)) deparse(substitute(check.fun)) else check.fun
+  check.fun = match.fun(check.fun)
+  x = NULL
+
+  new.fun = function() TRUE
+  formals(new.fun) = c(formals(check.fun), alist(.var.name = vname(x), add = NULL))
+  tmpl = "{ res = %s(%s); makeAssertion(x, res, .var.name, add) }"
+  if (is.null(c.fun)) {
+    body(new.fun) = parse(text = sprintf(tmpl, fn.name, paste0(names(formals(check.fun)), collapse = ", ")))
+  } else {
+    body(new.fun) = parse(text = sprintf(tmpl, ".Call", paste0(c(c.fun, names(formals(check.fun))), collapse = ", ")))
+  }
+  environment(new.fun) = env
+  return(new.fun)
+}
diff --git a/R/makeExpectation.R b/R/makeExpectation.R
new file mode 100644
index 0000000..c503496
--- /dev/null
+++ b/R/makeExpectation.R
@@ -0,0 +1,61 @@
+#' @title Turn a Check into an Expectation
+#'
+#' @description
+#' \code{makeExpectation} is the internal function used to evaluate the result of a
+#' check and turn it into an \code{\link[testthat]{expectation}}.
+#' \code{makeExceptionFunction} can be used to automatically create an expectation
+#' function based on a check function (see example).
+#'
+#' @template x
+#' @param res [\code{TRUE} | \code{character(1)}]\cr
+#'  The result of a check function: \code{TRUE} for successful checks,
+#'  and an error message as string otherwise.
+#' @param info [\code{character(1)}]\cr
+#'   See \code{\link[testthat]{expect_that}}
+#' @param label [\code{character(1)}]\cr
+#'   See \code{\link[testthat]{expect_that}}
+#' @return \code{makeExpectation} invisibly returns the checked object.
+#'   \code{makeExpectationFunction} returns a \code{function}.
+#' @export
+#' @family CustomConstructors
+#' @include helper.R
+#' @examples
+#' # Simple custom check function
+#' checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+#'
+#' # Create the respective expect function
+#' expect_false = function(x, info = NULL, label = vname(x)) {
+#'   res = checkFalse(x)
+#'   makeExpectation(x, res, info = info, label = label)
+#' }
+#'
+#' # Alternative: Automatically create such a function
+#' expect_false = makeExpectationFunction(checkFalse)
+#' print(expect_false)
+makeExpectation = function(x, res, info, label) {
+  if (!requireNamespace("testthat", quietly = TRUE))
+    stop("Package 'testthat' is required for checkmate's 'expect_*' extensions")
+  info = if (is.null(info)) res else sprintf("%s\nAdditional info: %s", res, info)
+  testthat::expect_true(res, info = info, label = sprintf("Check on %s", label))
+  invisible(x)
+}
+
+#' @rdname makeExpectation
+#' @template makeFunction
+#' @export
+makeExpectationFunction = function(check.fun, c.fun = NULL, env = parent.frame()) {
+  fn.name = if (!is.character(check.fun)) deparse(substitute(check.fun)) else check.fun
+  check.fun = match.fun(check.fun)
+  x = NULL
+
+  new.fun = function() TRUE
+  formals(new.fun) = c(formals(check.fun), alist(info = NULL, label = vname(x)))
+  tmpl = "{ res = %s(%s); makeExpectation(x, res, info, label) }"
+  if (is.null(c.fun)) {
+    body(new.fun) = parse(text = sprintf(tmpl, fn.name, paste0(names(formals(check.fun)), collapse = ", ")))
+  } else {
+    body(new.fun) = parse(text = sprintf(tmpl, ".Call", paste0(c(c.fun, names(formals(check.fun))), collapse = ", ")))
+  }
+  environment(new.fun) = env
+  return(new.fun)
+}
diff --git a/R/makeTest.R b/R/makeTest.R
new file mode 100644
index 0000000..ecd5bca
--- /dev/null
+++ b/R/makeTest.R
@@ -0,0 +1,52 @@
+#' @title Turn a Check into a Test
+#'
+#' @description
+#' \code{makeTest} is the internal function used to evaluate the result of a
+#' check and throw an exception if necessary.
+#' This function is currently only a stub and just calls \code{\link[base]{isTRUE}}.
+#' \code{makeTestFunction} can be used to automatically create an assertion
+#' function based on a check function (see example).
+#'
+#' @param res [\code{TRUE} | \code{character(1)}]\cr
+#'  The result of a check function: \code{TRUE} for successful checks,
+#'  and an error message as string otherwise.
+#' @return \code{makeTest} returns \code{TRUE} if the check is successful and \code{FALSE} otherwise.
+#'  \code{makeTestFunction} returns a \code{function}.
+#' @export
+#' @family CustomConstructors
+#' @include helper.R
+#' @examples
+#' # Simple custom check function
+#' checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+#'
+#' # Create the respective test function
+#' testFalse = function(x) {
+#'   res = checkFalse(x)
+#'   makeTest(res)
+#' }
+#'
+#' # Alternative: Automatically create such a function
+#' testFalse = makeTestFunction(checkFalse)
+#' print(testFalse)
+makeTest = function(res) {
+  identical(res, TRUE)
+}
+
+#' @rdname makeTest
+#' @template makeFunction
+#' @export
+makeTestFunction = function(check.fun, c.fun = NULL, env = parent.frame()) {
+  fn.name = if (!is.character(check.fun)) deparse(substitute(check.fun)) else check.fun
+  check.fun = match.fun(check.fun)
+
+  new.fun = function() TRUE
+  formals(new.fun) = formals(check.fun)
+  tmpl = "{ identical(%s(%s), TRUE) }"
+  if (is.null(c.fun)) {
+    body(new.fun) = parse(text = sprintf(tmpl, fn.name, paste0(names(formals(check.fun)), collapse = ", ")))
+  } else {
+    body(new.fun) = parse(text = sprintf(tmpl, ".Call", paste0(c(c.fun, names(formals(check.fun))), collapse = ", ")))
+  }
+  environment(new.fun) = env
+  return(new.fun)
+}
diff --git a/R/matchArg.R b/R/matchArg.R
new file mode 100644
index 0000000..7e2e148
--- /dev/null
+++ b/R/matchArg.R
@@ -0,0 +1,38 @@
+#' Partial Argument Matching
+#'
+#' @description
+#' This is an extensions to \code{\link[base]{match.arg}} with support for \code{\link{AssertCollection}}.
+#' The behaviour is very similar to \code{\link[base]{match.arg}}, except that \code{NULL} is not
+#' a valid value for \code{x}.
+#'
+#' @param x [character]\cr
+#'  User provided argument to match.
+#' @param choices [character()]\cr
+#'  Candidates to match \code{x} with.
+#' @param several.ok [logical(1)]\cr
+#'  If \code{TRUE}, multiple matches are allowed, cf. \code{\link[base]{match.arg}}.
+#' @template add
+#' @template var.name
+#' @return Subset of \code{choices}.
+#' @export
+#' @examples
+#' matchArg("k", choices = c("kendall", "pearson"))
+matchArg = function(x, choices, several.ok = FALSE, .var.name = vname(x), add = NULL) {
+  assertCharacter(choices, min.len = 1L)
+  assertFlag(several.ok)
+
+  if (several.ok) {
+    if (identical(x, choices))
+      return(x)
+    assertCharacter(x, min.len = 1L, .var.name = .var.name, add = add)
+    x = choices[pmatch(x, choices, nomatch = 0L, duplicates.ok = TRUE)]
+    assertSubset(x, choices, empty.ok = FALSE, .var.name = .var.name, add = add)
+  } else {
+    if (identical(x, choices))
+      return(x[1L])
+    assertCharacter(x, len = 1L, .var.name = .var.name, add = add)
+    x = choices[pmatch(x, choices, nomatch = 0L, duplicates.ok = FALSE)]
+    assertChoice(x, choices, .var.name = .var.name, add = add)
+  }
+  x
+}
diff --git a/R/qassert.R b/R/qassert.R
new file mode 100644
index 0000000..b23bfe4
--- /dev/null
+++ b/R/qassert.R
@@ -0,0 +1,133 @@
+#' @title Quick argument checks on (builtin) R types
+#'
+#' @description
+#' The provided functions parse rules which allow to express some of the most
+#' frequent argument checks by typing just a few letters.
+#'
+#' @param x [any]\cr
+#'  Object the check.
+#' @param rules [\code{character}]\cr
+#'   Set of rules. See details.
+#' @template var.name
+#' @return
+#'  \code{qassert} throws an \code{R} exception if object \code{x} does
+#'  not comply to at least one of the \code{rules} and returns the tested object invisibly
+#'  otherwise.
+#'  \code{qtest} behaves the same way but returns \code{FALSE} if none of the
+#'  \code{rules} comply.
+#'  \code{qexpect} is intended to be inside the unit test framework \code{\link[testthat]{testthat}} and
+#'  returns an \code{\link[testthat]{expectation}}.
+#'
+#' @details
+#' The rule is specified in up to three parts.
+#' \enumerate{
+#'  \item{
+#'    Class and missingness check.
+#'    The first letter is an abbreviation for the class. If it is
+#'    provided uppercase, missing values are prohibited.
+#'    Supported abbreviations:
+#'    \tabular{rl}{
+#'      \code{[bB]} \tab Bool / logical.\cr
+#'      \code{[iI]} \tab Integer.\cr
+#'      \code{[xX]} \tab Integerish (numeric convertible to integer, see \code{\link{checkIntegerish}}).\cr
+#'      \code{[rR]} \tab Real / double.\cr
+#'      \code{[cC]} \tab Complex.\cr
+#'      \code{[nN]} \tab Numeric (integer or double).\cr
+#'      \code{[sS]} \tab String / character.\cr
+#'      \code{[fF]} \tab Factor\cr
+#'      \code{[aA]} \tab Atomic.\cr
+#'      \code{[vV]} \tab Atomic vector (see \code{\link{checkAtomicVector}}).\cr
+#'      \code{[lL]} \tab List. Missingness is defined as \code{NULL} element.\cr
+#'      \code{[mM]} \tab Matrix.\cr
+#'      \code{[dD]} \tab Data.frame. Missingness is checked recursively on columns.\cr
+#'      \code{[e]}  \tab Environment.\cr
+#'      \code{[0]}  \tab \code{NULL}.\cr
+#'      \code{[*]}  \tab placeholder to allow any type.
+#'    }
+#'    Note that the check for missingness does not distinguish between
+#'    \code{NaN} and \code{NA}. Infinite values are not treated as missing, but
+#'    can be caught using boundary checks (part 3).
+#'    }
+#'  \item{
+#'    Length definition. This can be one of
+#'    \tabular{rl}{
+#'      \code{[*]} \tab any length,\cr
+#'      \code{[?]} \tab length of zero or one,\cr
+#'      \code{[+]} \tab length of at least one, or\cr
+#'      \code{[0-9]+} \tab exact length specified as integer.
+#'    }
+#'    Preceding the exact length with one of the comparison operators \code{=}/\code{==},
+#'    \code{<}, \code{<=}, \code{>=} or \code{>} is also supported.
+#'  }
+#'  \item{
+#'    Range check as two numbers separated by a comma, enclosed by square brackets
+#'    (endpoint included) or parentheses (endpoint excluded).
+#'    For example, \dQuote{[0, 3)} results in \code{all(x >= 0 & x < 3)}.
+#'    The lower and upper bound may be omitted which is the equivalent of a negative or
+#'    positive infinite bound, respectively.
+#'    By definition \code{[0,]} contains \code{Inf}, while \code{[0,)} does not.
+#'    The same holds for the left (lower) boundary and \code{-Inf}.
+#'    E.g., the rule \dQuote{N1()} checks for a single finite numeric which is not NA,
+#'    while \dQuote{N1[)} allows \code{-Inf}.
+#'  }
+#' }
+#' @note
+#' The functions are inspired by the blog post of Bogumił Kamiński:
+#' \url{http://rsnippets.blogspot.de/2013/06/testing-function-agruments-in-gnu-r.html}.
+#' The implementation is mostly written in C to minimize the overhead.
+#' @seealso \code{\link{qtestr}} and \code{\link{qassertr}} for efficient checks
+#' of list elements and data frame columns.
+#' @useDynLib checkmate c_qassert
+#' @export
+#' @examples
+#' # logical of length 1
+#' qtest(NA, "b1")
+#'
+#' # logical of length 1, NA not allowed
+#' qtest(NA, "B1")
+#'
+#' # logical of length 0 or 1, NA not allowed
+#' qtest(TRUE, "B?")
+#'
+#' # numeric with length > 0
+#' qtest(runif(10), "n+")
+#'
+#' # integer with length > 0, NAs not allowed, all integers >= 0 and < Inf
+#' qtest(1:3, "I+[0,)")
+#'
+#' # either an emtpy list or a character vector with <=5 elements
+#' qtest(1, c("l0", "s<=5"))
+#'
+#' # data frame with at least one column and no missing value in any column
+#' qtest(iris, "D+")
+qassert = function(x, rules, .var.name = vname(x)) {
+  res = .Call(c_qassert, x, rules, FALSE)
+  if (!identical(res, TRUE))
+    mstop(qmsg(res, .var.name))
+  invisible(x)
+}
+
+#' @useDynLib checkmate c_qtest
+#' @rdname qassert
+#' @export
+qtest = function(x, rules) {
+  .Call(c_qtest, x, rules, FALSE)
+}
+
+#' @useDynLib checkmate c_qassert
+#' @template expect
+#' @rdname qassert
+#' @include makeExpectation.R
+#' @export
+qexpect = function(x, rules, info = NULL, label = vname(x)) {
+  res = .Call(c_qassert, x, rules, FALSE)
+  if (!identical(res, TRUE))
+    res = qmsg(res, label)
+  makeExpectation(x, res, info = info, label = label)
+}
+
+qmsg = function(msg, vname) {
+  if (length(msg) > 1L)
+    msg = paste0(c("One of the following must apply:", strwrap(msg, prefix = " * ")), collapse = "\n")
+  sprintf("Assertion on '%s' failed. %s.", vname, msg)
+}
diff --git a/R/qassertr.R b/R/qassertr.R
new file mode 100644
index 0000000..cc4eaab
--- /dev/null
+++ b/R/qassertr.R
@@ -0,0 +1,69 @@
+#' @title Quick recursive arguments checks on lists and data frames
+#'
+#' @description
+#' These functions are the tuned counterparts of \code{\link{qtest}},
+#' \code{\link{qassert}} and \code{\link{qexpect}} tailored for recursive
+#' checks of list elements or data frame columns.
+#'
+#' @param x [\code{list} or \code{data.frame}]\cr
+#'   List or data frame to check for compliance with at least one of \code{rules}.
+#'   See details of \code{\link{qtest}} for rule explanation.
+#' @param rules [\code{character}]\cr
+#'   Set of rules. See \code{\link{qtest}}
+#' @template var.name
+#' @return See \code{\link{qassert}}.
+#' @seealso \code{\link{qtest}}, \code{\link{qassert}}
+#' @useDynLib checkmate c_qassert
+#' @export
+#' @examples
+#' # All list elements are integers with length >= 1?
+#' qtestr(as.list(1:10), "i+")
+#'
+#' # All list elements (i.e. data frame columns) are numeric?
+#' qtestr(iris, "n")
+#'
+#' # All list elements are numeric, w/o NAs?
+#' qtestr(list(a = 1:3, b = rnorm(1), c = letters), "N+")
+#'
+#' # All list elements are numeric OR character
+#' qtestr(list(a = 1:3, b = rnorm(1), c = letters), c("N+", "S+"))
+qassertr = function(x, rules, .var.name = vname(x)) {
+  res = .Call(c_qassert, x, rules, TRUE, 1L)
+  if (!identical(res, TRUE))
+    mstop(qrmsg(x, res, .var.name))
+  invisible(x)
+}
+
+#' @rdname qassertr
+#' @param depth [\code{integer(1)}]\cr
+#'   Maximum recursion depth. Defaults to \dQuote{1} to directly check list elements or
+#'   data frame columns. Set to a higher value to check lists of lists of elements.
+#' @useDynLib checkmate c_qtest
+#' @export
+qtestr = function(x, rules, depth = 1L) {
+  .Call(c_qtest, x, rules, TRUE, depth)
+}
+
+#' @rdname qassertr
+#' @template expect
+#' @include makeExpectation.R
+#' @useDynLib checkmate c_qassert
+#' @export
+qexpectr = function(x, rules, info = NULL, label = vname(x)) {
+  res = .Call(c_qassert, x, rules, TRUE, 1L)
+  if (!identical(res, TRUE))
+    res = qrmsg(x, res, label)
+  makeExpectation(x, res, info = info, label = label)
+}
+
+qrmsg = function(x, msg, var.name) {
+  pos = attr(msg, "pos")
+  if (testNamed(x)) {
+    item = sprintf(", element '%s' (%i),", names(x)[pos], pos)
+  } else {
+    item = sprintf(", element %i,", pos)
+  }
+  if (length(msg) > 1L)
+    msg = paste0(c("One of the following must apply:", strwrap(msg, prefix = " * ")), collapse = "\n")
+  sprintf("Assertion on '%s'%s failed. %s.", var.name, item, msg)
+}
diff --git a/R/vname.R b/R/vname.R
new file mode 100644
index 0000000..ba694cc
--- /dev/null
+++ b/R/vname.R
@@ -0,0 +1,12 @@
+#' @title Lookup a variable name
+#' @description
+#' Tries to heuristically determine the variable name of \code{x} in the parent frame
+#' with a combination of \code{\link[base]{deparse}} and \code{\link[base]{substitute}}.
+#' Used for checkmate's error messages.
+#' @param x [ANY]\cr
+#'   Object.
+#' @return [\code{character(1)}] Variable name.
+#' @export
+vname = function(x) {
+  paste0(deparse(substitute(x, parent.frame(1L)), width.cutoff = 500), collapse = "\n")
+}
diff --git a/R/wfwl.R b/R/wfwl.R
new file mode 100644
index 0000000..5ec40db
--- /dev/null
+++ b/R/wfwl.R
@@ -0,0 +1,30 @@
+#' @title Get the index of the first/last TRUE
+#'
+#' @description
+#' A quick C implementation for \dQuote{which.first} (\code{head(which(x), 1)}) and
+#' \dQuote{which.last} (\code{tail(which(x), 1)}).
+#'
+#' @param x [\code{logical}]\cr
+#'  Logical vector.
+#' @param use.names [\code{logical(1)}]\cr
+#'  If \code{TRUE} and \code{x} is named, the result is also
+#'  named.
+#' @return [\code{integer(1)} | \code{integer(0)}].
+#'  Returns the index of the first/last \code{TRUE} value in \code{x} or
+#'  an empty integer vector if none is found. NAs are ignored.
+#' @useDynLib checkmate c_which_first
+#' @export
+#' @examples
+#' wf(c(FALSE, TRUE))
+#' wl(c(FALSE, FALSE))
+#' wf(NA)
+wf = function(x, use.names = TRUE) {
+  .Call(c_which_first, x, use.names)
+}
+
+#' @rdname wf
+#' @export
+#' @useDynLib checkmate c_which_last
+wl = function(x, use.names = TRUE) {
+  .Call(c_which_last, x, use.names)
+}
diff --git a/R/zzz.R b/R/zzz.R
new file mode 100644
index 0000000..37936ec
--- /dev/null
+++ b/R/zzz.R
@@ -0,0 +1,125 @@
+#' @description
+#'
+#' \describe{
+#'   \item{Homepage:}{\url{https://github.com/mllg/checkmate}}
+#'   \item{Bug Reports:}{\url{https://github.com/mllg/checkmate/issues}}
+#' }
+#'
+#' @section Overview of implemented functions:
+#'
+#' Check scalars:
+#' \itemize{
+#'   \item{\code{\link{checkFlag}}}
+#'   \item{\code{\link{checkCount}}}
+#'   \item{\code{\link{checkNumber}}}
+#'   \item{\code{\link{checkInt}}}
+#'   \item{\code{\link{checkString}}}
+#'   \item{\code{\link{checkScalar}}}
+#'   \item{\code{\link{checkScalarNA}}}
+#' }
+#'
+#' Check vectors:
+#' \itemize{
+#'   \item{\code{\link{checkLogical}}}
+#'   \item{\code{\link{checkNumeric}}}
+#'   \item{\code{\link{checkInteger}}}
+#'   \item{\code{\link{checkIntegerish}}}
+#'   \item{\code{\link{checkComplex}}}
+#'   \item{\code{\link{checkFactor}}}
+#'   \item{\code{\link{checkList}}}
+#'   \item{\code{\link{checkVector}}}
+#'   \item{\code{\link{checkAtomic}}}
+#'   \item{\code{\link{checkAtomicVector}}}
+#' }
+#'
+#' Check attributes:
+#' \itemize{
+#'   \item{\code{\link{checkClass}}}
+#'   \item{\code{\link{checkNames}}}
+#'   \item{\code{\link{checkNamed}}}
+#' }
+#'
+#' Check compound types:
+#' \itemize{
+#'   \item{\code{\link{checkMatrix}}}
+#'   \item{\code{\link{checkArray}}}
+#'   \item{\code{\link{checkDataFrame}}}
+#'   \item{\code{\link{checkDataTable}}}
+#'   \item{\code{\link{checkTibble}}}
+#' }
+#'
+#' Check other built-in R types:
+#' \itemize{
+#'   \item{\code{\link{checkNull}}}
+#'   \item{\code{\link{checkEnvironment}}}
+#'   \item{\code{\link{checkFunction}}}
+#'   \item{\code{\link{checkDate}}}
+#' }
+#'
+#' Check sets:
+#' \itemize{
+#'   \item{\code{\link{checkChoice}}}
+#'   \item{\code{\link{checkSubset}}}
+#'   \item{\code{\link{checkSetEqual}}}
+#' }
+#'
+#' File IO:
+#' \itemize{
+#'   \item{\code{\link{checkFileExists}}}
+#'   \item{\code{\link{checkDirectoryExists}}}
+#'   \item{\code{\link{checkPathForOutput}}}
+#'   \item{\code{\link{checkAccess}}}
+#' }
+#'
+#' Safe coercion to integer:
+#' \itemize{
+#'   \item{\code{\link{asCount}}}
+#'   \item{\code{\link{asInt}}}
+#'   \item{\code{\link{asInteger}}}
+#' }
+#'
+#' Quick argument checks using a DSL:
+#' \itemize{
+#'   \item{\code{\link{qassert}}}
+#'   \item{\code{\link{qassertr}}}
+#' }
+#'
+#' Misc:
+#' \itemize{
+#'   \item{\code{\link{checkOS}} (check operating system)}
+#'   \item{\code{\link{assert}} (combine multiple checks into an assertion)}
+#'   \item{\code{\link{anyMissing}}}
+#'   \item{\code{\link{allMissing}}}
+#'   \item{\code{\link{anyNaN}}}
+#'   \item{\code{\link{wf}} (which.first and which.last)}
+#' }
+#'
+#' @import backports
+#' @importFrom utils head tail packageVersion getFromNamespace
+"_PACKAGE"
+
+checkmate = new.env(parent = emptyenv())
+checkmate$os = c("windows", "mac", "linux", "solaris")[match(tolower(Sys.info()["sysname"]), c("windows", "darwin", "linux", "sunos"))]
+checkmate$listtypefuns = list2env(list(
+  "logical"      = is.logical,
+  "integer"      = is.integer,
+  "integerish"   = isIntegerish,
+  "double"       = is.double,
+  "numeric"      = is.numeric,
+  "complex"      = is.complex,
+  "character"    = is.character,
+  "factor"       = is.factor,
+  "atomic"       = is.atomic,
+  "vector"       = is.vector,
+  "atomicvector" = function(x) !is.null(x) && is.atomic(x),
+  "array"        = is.array,
+  "matrix"       = is.matrix,
+  "function"     = is.function,
+  "environment"  = is.environment,
+  "list"         = is.list,
+  "null"         = is.null
+))
+
+.onUnload <- function (libpath) {
+  library.dynam.unload("checkmate", libpath) # nocov
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5b2efd1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,38 @@
+# checkmate
+
+[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/checkmate)](https://cran.r-project.org/package=checkmate)
+[![Build Status](https://travis-ci.org/mllg/checkmate.svg?branch=master)](https://travis-ci.org/mllg/checkmate)
+[![Build status](https://ci.appveyor.com/api/projects/status/y4ayps61hjd3375o/branch/master?svg=true)](https://ci.appveyor.com/project/mllg/checkmate/branch/master)
+[![Coverage Status](https://img.shields.io/coveralls/mllg/checkmate.svg)](https://coveralls.io/r/mllg/checkmate?branch=master)
+
+Fast and versatile argument checks for R.
+
+Ever used an R function that produced a not-very-helpful error message,
+just to discover after minutes of debugging that you simply passed a wrong argument?
+
+Blaming the laziness of the package author for not doing such standard checks
+(in a dynamically typed language such as R) is at least partially unfair, as R makes theses types of checks
+cumbersome and annoying. Well, that's how it was in the past.
+
+Enter checkmate.
+
+Virtually **every standard type of user error** when passing arguments into function can be
+caught with a simple, readable line which produces an **informative error message** in case.
+A substantial part of the package was written in C to **minimize any worries about execution time overhead**.
+Furthermore, the package provides over 30 expectations to extend the popular [testthat package](https://cran.r-project.org/package=testthat) for unit tests.
+
+
+## Installation
+For the stable release, just install the latest version from [CRAN](https://cran.r-project.org/package=checkmate):
+```{R}
+install.packages("checkmate")
+```
+For the development version, use [devtools](https://cran.r-project.org/package=devtools):
+```{R}
+devtools::install_github("mllg/checkmate")
+```
+
+## Resources
+* [NEWS](https://github.com/mllg/checkmate/blob/master/NEWS.md)
+* [Documentation/Vignettes](https://mllg.github.io/checkmate/)
+* [Grouped function reference](https://mllg.github.io/checkmate/reference/checkmate-package)
diff --git a/build/vignette.rds b/build/vignette.rds
new file mode 100644
index 0000000..e17f3cb
Binary files /dev/null and b/build/vignette.rds differ
diff --git a/debian/README.test b/debian/README.test
deleted file mode 100644
index 470f807..0000000
--- a/debian/README.test
+++ /dev/null
@@ -1,10 +0,0 @@
-Notes on how this package can be tested.
-────────────────────────────────────────
-
-To run the unit tests provided by the package you can do
-
-   sh  run-unit-test
-
-in this directory.
-
-
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index e7ffd70..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,54 +0,0 @@
-r-cran-checkmate (1.8.2-2) UNRELEASED; urgency=medium
-
-  * Fix Vcs-Browser
-
- -- Andreas Tille <tille at debian.org>  Mon, 02 Jan 2017 16:14:53 +0100
-
-r-cran-checkmate (1.8.2-1) unstable; urgency=medium
-
-  * New upstream version
-  * debhelper 10
-  * d/watch: version=4
-
- -- Andreas Tille <tille at debian.org>  Wed, 30 Nov 2016 11:00:03 +0100
-
-r-cran-checkmate (1.8.1-1) unstable; urgency=medium
-
-  * New upstream version
-  * Convert to dh-r
-  * Canonical homepage for CRAN
-  * New Build-Depends: r-cran-backports
-
- -- Andreas Tille <tille at debian.org>  Tue, 01 Nov 2016 10:59:40 +0100
-
-r-cran-checkmate (1.6.0-1) unstable; urgency=medium
-
-  * New upstream version
-
- -- Andreas Tille <tille at debian.org>  Sat, 27 Jun 2015 11:29:01 +0200
-
-r-cran-checkmate (1.5.0-1) unstable; urgency=medium
-
-  * New upstream version
-
- -- Andreas Tille <tille at debian.org>  Sat, 25 Oct 2014 19:49:06 +0200
-
-r-cran-checkmate (1.4-1) unstable; urgency=medium
-
-  * New upstream version
-  * cme fix dpkg-control
-  * d/copyright: fix DEP5 license name
-
- -- Andreas Tille <tille at debian.org>  Thu, 02 Oct 2014 13:08:17 +0200
-
-r-cran-checkmate (1.2-1) unstable; urgency=medium
-
-  * New upstream version
-
- -- Andreas Tille <tille at debian.org>  Fri, 08 Aug 2014 15:19:14 +0200
-
-r-cran-checkmate (1.1-1) unstable; urgency=low
-
-  * Initial release (Closes: #754509)
-
- -- Andreas Tille <tille at debian.org>  Mon, 07 Jul 2014 11:49:34 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index f599e28..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 7171027..0000000
--- a/debian/control
+++ /dev/null
@@ -1,25 +0,0 @@
-Source: r-cran-checkmate
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: gnu-r
-Priority: optional
-Build-Depends: debhelper (>= 10),
-               dh-r,
-               r-base-dev (>= 3.0.0),
-               r-cran-backports
-Standards-Version: 3.9.8
-Vcs-Browser: https://anonscm.debian.org/viewvc/debian-med/trunk/packages/R/r-cran-checkmate/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/R/r-cran-checkmate/trunk/
-Homepage: https://cran.r-project.org/package=checkmate
-
-Package: r-cran-checkmate
-Architecture: any
-Depends: ${shlibs:Depends},
-         ${misc:Depends},
-         ${R:Depends}
-Recommends: ${R:Recommends}
-Suggests: ${R:Suggests}
-Description: GNU R fast and versatile argument checks
- This GNU R package tests and assertions to perform frequent argument
- checks. A substantial part of the package was written in C to minimize
- any worries about execution time overhead.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 5717195..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,42 +0,0 @@
-Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: checkmate
-Upstream-Contact: Bernd Bischl <bernd_bischl at gmx.net>
-Source: https://cran.r-project.org/package=checkmate
-
-Files: *
-Copyright: 2012-2016 Bernd Bischl, Michel Lang
-License: BSD-3-Clause
-
-Files: debian/*
-Copyright: 2016 Andreas Tille <tille at debian.org>
-License: BSD-3-Clause
-
-License: BSD-3-Clause
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- .
-    Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
- .
-    Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
- .
-    Neither the name of the <ORGANIZATION> nor the names of its
-    contributors may be used to endorse or promote products derived
-    from this software without specific prior written permission.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 960011c..0000000
--- a/debian/docs
+++ /dev/null
@@ -1,3 +0,0 @@
-tests
-debian/README.test
-debian/tests/run-unit-test
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 64f3903..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/make -f
-
-%:
-	dh $@ --buildsystem R
-
-override_dh_install:
-	dh_install
-	find debian -name LICENSE -delete
-
-override_dh_fixperms:
-	dh_fixperms
-	find debian -name "*.md" -exec chmod -x \{\} \;
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/tests/control b/debian/tests/control
deleted file mode 100644
index b044b0c..0000000
--- a/debian/tests/control
+++ /dev/null
@@ -1,3 +0,0 @@
-Tests: run-unit-test
-Depends: @, r-cran-testthat
-Restrictions: allow-stderr
diff --git a/debian/tests/run-unit-test b/debian/tests/run-unit-test
deleted file mode 100644
index 2edc98f..0000000
--- a/debian/tests/run-unit-test
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh -e
-
-pkg=r-cran-checkmate
-if [ "$ADTTMP" = "" ] ; then
-  ADTTMP=`mktemp -d /tmp/${pkg}-test.XXXXXX`
-  trap "rm -rf $ADTTMP" 0 INT QUIT ABRT PIPE TERM
-fi
-cd $ADTTMP
-cp -a /usr/share/doc/${pkg}/tests/* $ADTTMP
-gunzip -r *
-cat test-all.[Rr] | LC_ALL=C R --no-save
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index a443e51..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=4
-http://cran.r-project.org/src/contrib/checkmate_([-\d.]*)\.tar\.gz
diff --git a/inst/doc/checkmate.R b/inst/doc/checkmate.R
new file mode 100644
index 0000000..da3f8ce
--- /dev/null
+++ b/inst/doc/checkmate.R
@@ -0,0 +1,146 @@
+## ----include=FALSE-------------------------------------------------------
+library(checkmate)
+
+## ------------------------------------------------------------------------
+fact <- function(n, method = "stirling") {
+  if (length(n) != 1)
+    stop("Argument 'n' must have length 1")
+  if (!is.numeric(n))
+    stop("Argument 'n' must be numeric")
+  if (is.na(n))
+    stop("Argument 'n' may not be NA")
+  if (is.double(n)) {
+    if (is.nan(n))
+      stop("Argument 'n' may not be NaN")
+    if (is.infinite(n))
+      stop("Argument 'n' must be finite")
+    if (abs(n - round(n, 0)) > sqrt(.Machine$double.eps))
+      stop("Argument 'n' must be an integerish value")
+    n <- as.integer(n)
+  }
+  if (n < 0)
+    stop("Argument 'n' must be >= 0")
+  if (length(method) != 1)
+    stop("Argument 'method' must have length 1")
+  if (!is.character(method) || !method %in% c("stirling", "factorial"))
+    stop("Argument 'method' must be either 'stirling' or 'factorial'")
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+
+## ------------------------------------------------------------------------
+fact <- function(n, method = "stirling") {
+  assertCount(n)
+  assertChoice(method, c("stirling", "factorial"))
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+
+## ------------------------------------------------------------------------
+f <- function(x) {
+  assert(
+    checkClass(x, "foo"),
+    checkClass(x, "bar")
+  )
+}
+
+## ----eval=FALSE----------------------------------------------------------
+#  # file: tests/test-all.R
+#  library(testthat)
+#  library(checkmate) # for testthat extensions
+#  test_check("mypkg")
+
+## ----eval=FALSE----------------------------------------------------------
+#  test_that("checkmate is a sweet extension for testthat", {
+#    x = runif(100)
+#    expect_numeric(x, len = 100, any.missing = FALSE, lower = 0, upper = 1)
+#    # or, equivalent, using the lazy style:
+#    qexpect(x, "N100[0,1]")
+#  })
+
+## ----dev="svg",fig.width=6,fig.height=4----------------------------------
+library(ggplot2)
+library(microbenchmark)
+
+x = TRUE
+r = function(x, na.ok = FALSE) { stopifnot(is.logical(x), length(x) == 1, na.ok || !is.na(x)) }
+cm = function(x) assertFlag(x)
+cmq = function(x) qassert(x, "B1")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+## ----dev="svg",fig.width=6,fig.height=4----------------------------------
+x = runif(1000)
+r = function(x) stopifnot(is.numeric(x) && length(x) == 1000 && all(!is.na(x) & x >= 0 & x <= 1))
+cm = function(x) assertNumeric(x, len = 1000, any.missing = FALSE, lower = 0, upper = 1)
+cmq = function(x) qassert(x, "N1000[0,1]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+## ----dev="svg",fig.width=6,fig.height=4----------------------------------
+x = sample(letters, 10000, replace = TRUE)
+r = function(x) stopifnot(is.character(x) && !any(is.na(x)) && all(nchar(x) > 0))
+cm = function(x) assertCharacter(x, any.missing = FALSE, min.chars = 1)
+cmq = function(x) qassert(x, "S+[1,]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+## ----dev="svg",fig.width=6,fig.height=4----------------------------------
+N = 10000
+x = data.frame(a = runif(N), b = sample(letters[1:5], N, replace = TRUE), c = sample(c(FALSE, TRUE), N, replace = TRUE))
+r = function(x) is.data.frame(x) && !any(sapply(x, function(x) any(is.na(x))))
+cm = function(x) testDataFrame(x, any.missing = FALSE)
+cmq = function(x) qtest(x, "D")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+# checkmate tries to stop as early as possible
+x$a[1] = NA
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+## ------------------------------------------------------------------------
+checkSquareMatrix = function(x, mode = NULL) {
+  # check functions must return TRUE on success
+  # and a custom error message otherwise
+  res = checkMatrix(x, mode = mode)
+  if (!isTRUE(res))
+    return(res)
+  if (nrow(x) != ncol(x))
+    return("Must be square")
+  return(TRUE)
+}
+
+# a quick test:
+X = matrix(1:9, nrow = 3)
+checkSquareMatrix(X)
+checkSquareMatrix(X, mode = "character")
+checkSquareMatrix(X[1:2, ])
+
+## ------------------------------------------------------------------------
+# For assertions:
+assert_square_matrix = assertSquareMatrix = makeAssertionFunction(checkSquareMatrix)
+print(assertSquareMatrix)
+
+# For tests:
+test_square_matrix = testSquareMatrix = makeTestFunction(checkSquareMatrix)
+print(testSquareMatrix)
+
+# For expectations:
+expect_square_matrix = makeExpectationFunction(checkSquareMatrix)
+print(expect_square_matrix)
+
+## ------------------------------------------------------------------------
+sessionInfo()
+
diff --git a/inst/doc/checkmate.Rmd b/inst/doc/checkmate.Rmd
new file mode 100644
index 0000000..6a4b1ea
--- /dev/null
+++ b/inst/doc/checkmate.Rmd
@@ -0,0 +1,284 @@
+---
+title: "Checkmate"
+author: "Michel Lang"
+date: "`r Sys.Date()`"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{checkmate}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+```{r,include=FALSE}
+library(checkmate)
+```
+
+Ever used an R function that produced a not-very-helpful error message, just to discover after minutes of debugging that you simply passed a wrong argument?
+
+Blaming the laziness of the package author for not doing such standard checks (in a dynamically typed language such as R) is at least partially unfair, as R makes theses types of checks cumbersome and annoying. Well, that's how it was in the past.
+
+Enter checkmate.
+
+Virtually **every standard type of user error** when passing arguments into function can be caught with a simple, readable line which produces an **informative error message** in case.
+A substantial part of the package was written in C to **minimize any worries about execution time overhead**.
+
+## Intro
+As a motivational example, consider you have a function to calculate the faculty of a natural number and the user may choose between using either the stirling approximation or R's `factorial` function (which internally uses the gamma function).
+Thus, you have two arguments, `n` and `method`.
+Argument `n` must obviously be a positive natural number and `method` must be either `"stirling"` or `"factorial"`.
+Here is a version of all the hoops you need to jump through to ensure that these simple requirements are met:
+```{r}
+fact <- function(n, method = "stirling") {
+  if (length(n) != 1)
+    stop("Argument 'n' must have length 1")
+  if (!is.numeric(n))
+    stop("Argument 'n' must be numeric")
+  if (is.na(n))
+    stop("Argument 'n' may not be NA")
+  if (is.double(n)) {
+    if (is.nan(n))
+      stop("Argument 'n' may not be NaN")
+    if (is.infinite(n))
+      stop("Argument 'n' must be finite")
+    if (abs(n - round(n, 0)) > sqrt(.Machine$double.eps))
+      stop("Argument 'n' must be an integerish value")
+    n <- as.integer(n)
+  }
+  if (n < 0)
+    stop("Argument 'n' must be >= 0")
+  if (length(method) != 1)
+    stop("Argument 'method' must have length 1")
+  if (!is.character(method) || !method %in% c("stirling", "factorial"))
+    stop("Argument 'method' must be either 'stirling' or 'factorial'")
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+```
+And for comparison, here is the same function using checkmate:
+```{r}
+fact <- function(n, method = "stirling") {
+  assertCount(n)
+  assertChoice(method, c("stirling", "factorial"))
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+```
+
+## Function overview
+The functions can be split into four functional groups, indicated by their prefix.
+
+If prefixed with `assert`, an error is thrown if the corresponding check fails.
+Otherwise, the checked object is returned invisibly.
+There are many different coding styles out there in the wild, but most R programmers stick to either `camelBack` or `underscore_case`.
+Therefore, `checkmate` offers all functions in both flavors: `assert_count` is just an alias for `assertCount` but allows you to retain your favorite style.
+
+The family of functions prefixed with `test` always return the check result as logical value.
+Again, you can use `test_count` and `testCount` interchangeably.
+
+Functions starting with `check` return the error message as a string (or `TRUE` otherwise) and can be used if you need more control and, e.g., want to grep on the returned error message.
+
+`expect` is the last family of functions and is intended to be used with the [testthat package](https://cran.r-project.org/package=testthat).
+All performed checks are logged into the `testthat` reporter.
+Because `testthat` uses the `underscore_case`, the extension functions only come in the underscore style.
+
+All functions are categorized into objects to check on the [package help page](https://mllg.github.io/checkmate/reference/checkmate-package).
+
+## In case you miss flexibility
+
+You can use [assert](https://mllg.github.io/checkmate/reference/assert) to perform multiple checks at once and throw an assertion if all checks fail.
+
+Here is an example where we check that x is either of class `foo` or class `bar`:
+
+```{r}
+f <- function(x) {
+  assert(
+    checkClass(x, "foo"),
+    checkClass(x, "bar")
+  )
+}
+```
+
+Note that `assert(, combine = "or")` and `assert(, combine = "and")` allow to control the logical
+combination of the specified checks, and that the former is the default.
+
+
+## Argument Checks for the Lazy
+
+The following functions allow a special syntax to define argument checks using a special format specification.
+E.g., `qassert(x, "I+")` asserts that `x` is an integer vector with at least one element and no missing values.
+This very simple domain specific language covers a large variety of frequent argument checks with only a few keystrokes.
+You choose what you like best.
+
+* [qassert](https://mllg.github.io/checkmate/reference/qassert)
+* [qassertr](https://mllg.github.io/checkmate/reference/qassert)
+
+
+## checkmate as testthat extension
+To extend [testthat](https://cran.r-project.org/package=testthat), you need to IMPORT, DEPEND or SUGGEST on the `checkmate` package.
+Here is a minimal example:
+```{r,eval=FALSE}
+# file: tests/test-all.R
+library(testthat)
+library(checkmate) # for testthat extensions
+test_check("mypkg")
+```
+Now you are all set and can use more than 30 new expectations in your tests.
+```{r,eval=FALSE}
+test_that("checkmate is a sweet extension for testthat", {
+  x = runif(100)
+  expect_numeric(x, len = 100, any.missing = FALSE, lower = 0, upper = 1)
+  # or, equivalent, using the lazy style:
+  qexpect(x, "N100[0,1]")
+})
+```
+
+## Speed considerations
+
+In comparison with tediously writing the checks yourself in R (c.f. factorial example at the beginning of the vignette), R is sometimes a tad faster while performing checks on scalars.
+This seems odd at first, because checkmate is mostly written in C and should be comparably fast.
+Yet many of the functions in the `base` package are not regular functions, but primitives.
+While primitives jump directly into the C code, checkmate has to use the considerably slower `.Call` interface.
+As a result, it is possible to write (very simple) checks using only the base functions which, under some circumstances, slightly outperform checkmate.
+However, if you go one step further and wrap the custom check into a function to convenient re-use it, the performance gain is often lost (see benchmark 1).
+
+For larger objects the tide has turned because checkmate avoids many unnecessary intermediate variables.
+Also note that the quick/lazy implementation in `qassert`/`qtest`/`qexpect` is often a tad faster because only two arguments have to be evaluated (the object and the rule) to determine the set of checks to perform.
+
+Below you find some (probably unrepresentative) benchmark.
+But also note that this one here has been executed from inside `knitr` which is often the cause for outliers in the measured execution time.
+Better run the benchmark yourself to get unbiased results.
+
+
+### Benchmark 1: Assert that `x` is a flag
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+library(ggplot2)
+library(microbenchmark)
+
+x = TRUE
+r = function(x, na.ok = FALSE) { stopifnot(is.logical(x), length(x) == 1, na.ok || !is.na(x)) }
+cm = function(x) assertFlag(x)
+cmq = function(x) qassert(x, "B1")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 2: Assert that `x` is a numeric of length 1000 with no missing nor NaN values
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+x = runif(1000)
+r = function(x) stopifnot(is.numeric(x) && length(x) == 1000 && all(!is.na(x) & x >= 0 & x <= 1))
+cm = function(x) assertNumeric(x, len = 1000, any.missing = FALSE, lower = 0, upper = 1)
+cmq = function(x) qassert(x, "N1000[0,1]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 3: Assert that `x` is a character vector with no missing values nor empty strings
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+x = sample(letters, 10000, replace = TRUE)
+r = function(x) stopifnot(is.character(x) && !any(is.na(x)) && all(nchar(x) > 0))
+cm = function(x) assertCharacter(x, any.missing = FALSE, min.chars = 1)
+cmq = function(x) qassert(x, "S+[1,]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 4: Assert that `x` is a data frame with no missing values
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+N = 10000
+x = data.frame(a = runif(N), b = sample(letters[1:5], N, replace = TRUE), c = sample(c(FALSE, TRUE), N, replace = TRUE))
+r = function(x) is.data.frame(x) && !any(sapply(x, function(x) any(is.na(x))))
+cm = function(x) testDataFrame(x, any.missing = FALSE)
+cmq = function(x) qtest(x, "D")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+# checkmate tries to stop as early as possible
+x$a[1] = NA
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+## Extending checkmate
+
+To extend checkmate a custom `check*` function has to be written.
+For example, to check for a square matrix one can re-use parts of checkmate and extend the check with additional functionality:
+```{r}
+checkSquareMatrix = function(x, mode = NULL) {
+  # check functions must return TRUE on success
+  # and a custom error message otherwise
+  res = checkMatrix(x, mode = mode)
+  if (!isTRUE(res))
+    return(res)
+  if (nrow(x) != ncol(x))
+    return("Must be square")
+  return(TRUE)
+}
+
+# a quick test:
+X = matrix(1:9, nrow = 3)
+checkSquareMatrix(X)
+checkSquareMatrix(X, mode = "character")
+checkSquareMatrix(X[1:2, ])
+```
+The respective counterparts to the `check`-function can be created using the constructors [makeAssertionFunction](https://mllg.github.io/checkmate/reference/makeAssertion), [makeTestFunction](https://mllg.github.io/checkmate/reference/makeTest) and [makeExpectationFunction](https://mllg.github.io/checkmate/reference/makeExpectation):
+```{r}
+# For assertions:
+assert_square_matrix = assertSquareMatrix = makeAssertionFunction(checkSquareMatrix)
+print(assertSquareMatrix)
+
+# For tests:
+test_square_matrix = testSquareMatrix = makeTestFunction(checkSquareMatrix)
+print(testSquareMatrix)
+
+# For expectations:
+expect_square_matrix = makeExpectationFunction(checkSquareMatrix)
+print(expect_square_matrix)
+```
+Note that all the additional arguments `.var.name`, `add`, `info` and `label` are automatically joined with the function arguments of your custom check function.
+Also note that if you define these functions inside an R package, the constructors are called at build-time (thus, there is no negative impact on the runtime).
+
+## Calling checkmate from C/C++
+
+The package registers two functions which can be used in other packages' C/C++ code for argument checks.
+```{c,eval=FALSE}
+SEXP qassert(SEXP x, const char *rule, const char *name);
+Rboolean qtest(SEXP x, const char *rule);
+```
+These are the counterparts to [qassert](https://mllg.github.io/checkmate/reference/qassert) and [qtest](https://mllg.github.io/checkmate/reference/qassert).
+Due to their simplistic interface, they perfectly suit the requirements of most type checks in C/C++.
+
+For detailed background information on the register mechanism, see the [Exporting C Code](http://r-pkgs.had.co.nz/src.html#clang) section in Hadley's Book "R Packages" or [WRE](https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Registering-native-routines).
+Here is a step-by-step guide to get you started:
+
+1. Add `checkmate` to your "Imports" and LinkingTo" sections in your DESCRIPTION file.
+2. Create a stub file C source file which pulls in the provided C functions in order to compile them for your package. See example below.
+3. Include the provided header file `<checkmate.h>` in each compilation unit where you want to use checkmate.
+
+```{c,eval=FALSE}
+/* Example for (2), "checkmate_stub.c":*/
+#include <checkmate.h>
+#include <checkmate_stub.c>
+```
+
+## Session Info
+For the sake of completeness, here the `sessionInfo()` for the benchmark (but remember the note before on `knitr` possibly biasing the results).
+```{r}
+sessionInfo()
+```
diff --git a/inst/doc/checkmate.html b/inst/doc/checkmate.html
new file mode 100644
index 0000000..348e9a0
--- /dev/null
+++ b/inst/doc/checkmate.html
@@ -0,0 +1,369 @@
+<!DOCTYPE html>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+
+<meta charset="utf-8">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="pandoc" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1">
+
+<meta name="author" content="Michel Lang" />
+
+<meta name="date" content="2016-11-02" />
+
+<title>Checkmate</title>
+
+
+
+<style type="text/css">code{white-space: pre;}</style>
+<style type="text/css">
+div.sourceCode { overflow-x: auto; }
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+  margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; line-height: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
+td.sourceCode { padding-left: 5px; }
+code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
+code > span.dt { color: #902000; } /* DataType */
+code > span.dv { color: #40a070; } /* DecVal */
+code > span.bn { color: #40a070; } /* BaseN */
+code > span.fl { color: #40a070; } /* Float */
+code > span.ch { color: #4070a0; } /* Char */
+code > span.st { color: #4070a0; } /* String */
+code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
+code > span.ot { color: #007020; } /* Other */
+code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
+code > span.fu { color: #06287e; } /* Function */
+code > span.er { color: #ff0000; font-weight: bold; } /* Error */
+code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
+code > span.cn { color: #880000; } /* Constant */
+code > span.sc { color: #4070a0; } /* SpecialChar */
+code > span.vs { color: #4070a0; } /* VerbatimString */
+code > span.ss { color: #bb6688; } /* SpecialString */
+code > span.im { } /* Import */
+code > span.va { color: #19177c; } /* Variable */
+code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
+code > span.op { color: #666666; } /* Operator */
+code > span.bu { } /* BuiltIn */
+code > span.ex { } /* Extension */
+code > span.pp { color: #bc7a00; } /* Preprocessor */
+code > span.at { color: #7d9029; } /* Attribute */
+code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
+code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
+code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
+code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
+</style>
+
+
+
+<link href="data:text/css;charset=utf-8,body%20%7B%0Abackground%2Dcolor%3A%20%23fff%3B%0Amargin%3A%201em%20auto%3B%0Amax%2Dwidth%3A%20700px%3B%0Aoverflow%3A%20visible%3B%0Apadding%2Dleft%3A%202em%3B%0Apadding%2Dright%3A%202em%3B%0Afont%2Dfamily%3A%20%22Open%20Sans%22%2C%20%22Helvetica%20Neue%22%2C%20Helvetica%2C%20Arial%2C%20sans%2Dserif%3B%0Afont%2Dsize%3A%2014px%3B%0Aline%2Dheight%3A%201%2E35%3B%0A%7D%0A%23header%20%7B%0Atext%2Dalign%3A%20center%3B%0A%7D%0A%23TOC%20%7B%0Aclear%3A%20bot [...]
+
+</head>
+
+<body>
+
+
+
+
+<h1 class="title toc-ignore">Checkmate</h1>
+<h4 class="author"><em>Michel Lang</em></h4>
+<h4 class="date"><em>2016-11-02</em></h4>
+
+
+
+<p>Ever used an R function that produced a not-very-helpful error message, just to discover after minutes of debugging that you simply passed a wrong argument?</p>
+<p>Blaming the laziness of the package author for not doing such standard checks (in a dynamically typed language such as R) is at least partially unfair, as R makes theses types of checks cumbersome and annoying. Well, that’s how it was in the past.</p>
+<p>Enter checkmate.</p>
+<p>Virtually <strong>every standard type of user error</strong> when passing arguments into function can be caught with a simple, readable line which produces an <strong>informative error message</strong> in case. A substantial part of the package was written in C to <strong>minimize any worries about execution time overhead</strong>.</p>
+<div id="intro" class="section level2">
+<h2>Intro</h2>
+<p>As a motivational example, consider you have a function to calculate the faculty of a natural number and the user may choose between using either the stirling approximation or R’s <code>factorial</code> function (which internally uses the gamma function). Thus, you have two arguments, <code>n</code> and <code>method</code>. Argument <code>n</code> must obviously be a positive natural number and <code>method</code> must be either <code>"stirling"</code> or <code>"factori [...]
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">fact <-<span class="st"> </span>function(n, <span class="dt">method =</span> <span class="st">"stirling"</span>) {
+  if (<span class="kw">length</span>(n) !=<span class="st"> </span><span class="dv">1</span>)
+    <span class="kw">stop</span>(<span class="st">"Argument 'n' must have length 1"</span>)
+  if (!<span class="kw">is.numeric</span>(n))
+    <span class="kw">stop</span>(<span class="st">"Argument 'n' must be numeric"</span>)
+  if (<span class="kw">is.na</span>(n))
+    <span class="kw">stop</span>(<span class="st">"Argument 'n' may not be NA"</span>)
+  if (<span class="kw">is.double</span>(n)) {
+    if (<span class="kw">is.nan</span>(n))
+      <span class="kw">stop</span>(<span class="st">"Argument 'n' may not be NaN"</span>)
+    if (<span class="kw">is.infinite</span>(n))
+      <span class="kw">stop</span>(<span class="st">"Argument 'n' must be finite"</span>)
+    if (<span class="kw">abs</span>(n -<span class="st"> </span><span class="kw">round</span>(n, <span class="dv">0</span>)) ><span class="st"> </span><span class="kw">sqrt</span>(.Machine$double.eps))
+      <span class="kw">stop</span>(<span class="st">"Argument 'n' must be an integerish value"</span>)
+    n <-<span class="st"> </span><span class="kw">as.integer</span>(n)
+  }
+  if (n <<span class="st"> </span><span class="dv">0</span>)
+    <span class="kw">stop</span>(<span class="st">"Argument 'n' must be >= 0"</span>)
+  if (<span class="kw">length</span>(method) !=<span class="st"> </span><span class="dv">1</span>)
+    <span class="kw">stop</span>(<span class="st">"Argument 'method' must have length 1"</span>)
+  if (!<span class="kw">is.character</span>(method) ||<span class="st"> </span>!method %in%<span class="st"> </span><span class="kw">c</span>(<span class="st">"stirling"</span>, <span class="st">"factorial"</span>))
+    <span class="kw">stop</span>(<span class="st">"Argument 'method' must be either 'stirling' or 'factorial'"</span>)
+
+  if (method ==<span class="st"> "factorial"</span>)
+    <span class="kw">factorial</span>(n)
+  else
+    <span class="kw">sqrt</span>(<span class="dv">2</span> *<span class="st"> </span>pi *<span class="st"> </span>n) *<span class="st"> </span>(n /<span class="st"> </span><span class="kw">exp</span>(<span class="dv">1</span>))^n
+}</code></pre></div>
+<p>And for comparison, here is the same function using checkmate:</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">fact <-<span class="st"> </span>function(n, <span class="dt">method =</span> <span class="st">"stirling"</span>) {
+  <span class="kw">assertCount</span>(n)
+  <span class="kw">assertChoice</span>(method, <span class="kw">c</span>(<span class="st">"stirling"</span>, <span class="st">"factorial"</span>))
+
+  if (method ==<span class="st"> "factorial"</span>)
+    <span class="kw">factorial</span>(n)
+  else
+    <span class="kw">sqrt</span>(<span class="dv">2</span> *<span class="st"> </span>pi *<span class="st"> </span>n) *<span class="st"> </span>(n /<span class="st"> </span><span class="kw">exp</span>(<span class="dv">1</span>))^n
+}</code></pre></div>
+</div>
+<div id="function-overview" class="section level2">
+<h2>Function overview</h2>
+<p>The functions can be split into four functional groups, indicated by their prefix.</p>
+<p>If prefixed with <code>assert</code>, an error is thrown if the corresponding check fails. Otherwise, the checked object is returned invisibly. There are many different coding styles out there in the wild, but most R programmers stick to either <code>camelBack</code> or <code>underscore_case</code>. Therefore, <code>checkmate</code> offers all functions in both flavors: <code>assert_count</code> is just an alias for <code>assertCount</code> but allows you to retain your favorite style.</p>
+<p>The family of functions prefixed with <code>test</code> always return the check result as logical value. Again, you can use <code>test_count</code> and <code>testCount</code> interchangeably.</p>
+<p>Functions starting with <code>check</code> return the error message as a string (or <code>TRUE</code> otherwise) and can be used if you need more control and, e.g., want to grep on the returned error message.</p>
+<p><code>expect</code> is the last family of functions and is intended to be used with the <a href="https://cran.r-project.org/package=testthat">testthat package</a>. All performed checks are logged into the <code>testthat</code> reporter. Because <code>testthat</code> uses the <code>underscore_case</code>, the extension functions only come in the underscore style.</p>
+<p>All functions are categorized into objects to check on the <a href="https://mllg.github.io/checkmate/reference/checkmate-package">package help page</a>.</p>
+</div>
+<div id="in-case-you-miss-flexibility" class="section level2">
+<h2>In case you miss flexibility</h2>
+<p>You can use <a href="https://mllg.github.io/checkmate/reference/assert">assert</a> to perform multiple checks at once and throw an assertion if all checks fail.</p>
+<p>Here is an example where we check that x is either of class <code>foo</code> or class <code>bar</code>:</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">f <-<span class="st"> </span>function(x) {
+  <span class="kw">assert</span>(
+    <span class="kw">checkClass</span>(x, <span class="st">"foo"</span>),
+    <span class="kw">checkClass</span>(x, <span class="st">"bar"</span>)
+  )
+}</code></pre></div>
+<p>Note that <code>assert(, combine = "or")</code> and <code>assert(, combine = "and")</code> allow to control the logical combination of the specified checks, and that the former is the default.</p>
+</div>
+<div id="argument-checks-for-the-lazy" class="section level2">
+<h2>Argument Checks for the Lazy</h2>
+<p>The following functions allow a special syntax to define argument checks using a special format specification. E.g., <code>qassert(x, "I+")</code> asserts that <code>x</code> is an integer vector with at least one element and no missing values. This very simple domain specific language covers a large variety of frequent argument checks with only a few keystrokes. You choose what you like best.</p>
+<ul>
+<li><a href="https://mllg.github.io/checkmate/reference/qassert">qassert</a></li>
+<li><a href="https://mllg.github.io/checkmate/reference/qassert">qassertr</a></li>
+</ul>
+</div>
+<div id="checkmate-as-testthat-extension" class="section level2">
+<h2>checkmate as testthat extension</h2>
+<p>To extend <a href="https://cran.r-project.org/package=testthat">testthat</a>, you need to IMPORT, DEPEND or SUGGEST on the <code>checkmate</code> package. Here is a minimal example:</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># file: tests/test-all.R</span>
+<span class="kw">library</span>(testthat)
+<span class="kw">library</span>(checkmate) <span class="co"># for testthat extensions</span>
+<span class="kw">test_check</span>(<span class="st">"mypkg"</span>)</code></pre></div>
+<p>Now you are all set and can use more than 30 new expectations in your tests.</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">test_that</span>(<span class="st">"checkmate is a sweet extension for testthat"</span>, {
+  x =<span class="st"> </span><span class="kw">runif</span>(<span class="dv">100</span>)
+  <span class="kw">expect_numeric</span>(x, <span class="dt">len =</span> <span class="dv">100</span>, <span class="dt">any.missing =</span> <span class="ot">FALSE</span>, <span class="dt">lower =</span> <span class="dv">0</span>, <span class="dt">upper =</span> <span class="dv">1</span>)
+  <span class="co"># or, equivalent, using the lazy style:</span>
+  <span class="kw">qexpect</span>(x, <span class="st">"N100[0,1]"</span>)
+})</code></pre></div>
+</div>
+<div id="speed-considerations" class="section level2">
+<h2>Speed considerations</h2>
+<p>In comparison with tediously writing the checks yourself in R (c.f. factorial example at the beginning of the vignette), R is sometimes a tad faster while performing checks on scalars. This seems odd at first, because checkmate is mostly written in C and should be comparably fast. Yet many of the functions in the <code>base</code> package are not regular functions, but primitives. While primitives jump directly into the C code, checkmate has to use the considerably slower <code>.Call< [...]
+<p>For larger objects the tide has turned because checkmate avoids many unnecessary intermediate variables. Also note that the quick/lazy implementation in <code>qassert</code>/<code>qtest</code>/<code>qexpect</code> is often a tad faster because only two arguments have to be evaluated (the object and the rule) to determine the set of checks to perform.</p>
+<p>Below you find some (probably unrepresentative) benchmark. But also note that this one here has been executed from inside <code>knitr</code> which is often the cause for outliers in the measured execution time. Better run the benchmark yourself to get unbiased results.</p>
+<div id="benchmark-1-assert-that-x-is-a-flag" class="section level3">
+<h3>Benchmark 1: Assert that <code>x</code> is a flag</h3>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">library</span>(ggplot2)
+<span class="kw">library</span>(microbenchmark)
+
+x =<span class="st"> </span><span class="ot">TRUE</span>
+r =<span class="st"> </span>function(x, <span class="dt">na.ok =</span> <span class="ot">FALSE</span>) { <span class="kw">stopifnot</span>(<span class="kw">is.logical</span>(x), <span class="kw">length</span>(x) ==<span class="st"> </span><span class="dv">1</span>, na.ok ||<span class="st"> </span>!<span class="kw">is.na</span>(x)) }
+cm =<span class="st"> </span>function(x) <span class="kw">assertFlag</span>(x)
+cmq =<span class="st"> </span>function(x) <span class="kw">qassert</span>(x, <span class="st">"B1"</span>)
+mb =<span class="st"> </span><span class="kw">microbenchmark</span>(<span class="kw">r</span>(x), <span class="kw">cm</span>(x), <span class="kw">cmq</span>(x))
+<span class="kw">print</span>(mb)</code></pre></div>
+<pre><code>## Unit: microseconds
+##    expr   min     lq    mean median     uq     max neval cld
+##    r(x) 6.297 6.6145 8.13963 6.8615 7.5025  35.795   100   b
+##   cm(x) 1.603 1.7575 4.00172 1.9265 2.1035 169.700   100  a 
+##  cmq(x) 1.029 1.1395 1.66973 1.2515 1.4320  34.927   100  a</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">autoplot</span>(mb)</code></pre></div>
+<p><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDMycHQiIGhlaWdodD0iMjg4cHQiIHZpZXdCb3g9IjAgMCA0MzIgMjg4IiB2ZXJzaW9uPSIxLjEiPgo8ZGVmcz4KPGc+CjxzeW1ib2wgb3ZlcmZsb3c9InZpc2libGUiIGlkPSJnbHlwaDAtMCI+CjxwYXRoIHN0eWxlPSJzdHJva2U6bm9uZTsiIGQ9IiIvPgo8L3N5bWJvbD4KPHN5bWJvbCBvdmVyZmxvdz0idmlzaWJsZSIgaWQ9ImdseXBoMC0xIj4KPHBhdGggc3R5bGU9I [...]
+</div>
+<div id="benchmark-2-assert-that-x-is-a-numeric-of-length-1000-with-no-missing-nor-nan-values" class="section level3">
+<h3>Benchmark 2: Assert that <code>x</code> is a numeric of length 1000 with no missing nor NaN values</h3>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">x =<span class="st"> </span><span class="kw">runif</span>(<span class="dv">1000</span>)
+r =<span class="st"> </span>function(x) <span class="kw">stopifnot</span>(<span class="kw">is.numeric</span>(x) &&<span class="st"> </span><span class="kw">length</span>(x) ==<span class="st"> </span><span class="dv">1000</span> &&<span class="st"> </span><span class="kw">all</span>(!<span class="kw">is.na</span>(x) &<span class="st"> </span>x >=<span class="st"> </span><span class="dv">0</span> &<span class="st"> </span>x <=<span class="st"> </span><span cl [...]
+cm =<span class="st"> </span>function(x) <span class="kw">assertNumeric</span>(x, <span class="dt">len =</span> <span class="dv">1000</span>, <span class="dt">any.missing =</span> <span class="ot">FALSE</span>, <span class="dt">lower =</span> <span class="dv">0</span>, <span class="dt">upper =</span> <span class="dv">1</span>)
+cmq =<span class="st"> </span>function(x) <span class="kw">qassert</span>(x, <span class="st">"N1000[0,1]"</span>)
+mb =<span class="st"> </span><span class="kw">microbenchmark</span>(<span class="kw">r</span>(x), <span class="kw">cm</span>(x), <span class="kw">cmq</span>(x))
+<span class="kw">print</span>(mb)</code></pre></div>
+<pre><code>## Unit: microseconds
+##    expr    min      lq     mean  median     uq    max neval cld
+##    r(x) 17.949 18.5330 20.23758 18.8110 19.346 43.093   100   b
+##   cm(x)  6.295  6.4850  7.80275  6.8155  7.094 75.240   100  a 
+##  cmq(x)  5.655  5.8005  6.67053  6.0675  6.245 25.272   100  a</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">autoplot</span>(mb)</code></pre></div>
+<p><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDMycHQiIGhlaWdodD0iMjg4cHQiIHZpZXdCb3g9IjAgMCA0MzIgMjg4IiB2ZXJzaW9uPSIxLjEiPgo8ZGVmcz4KPGc+CjxzeW1ib2wgb3ZlcmZsb3c9InZpc2libGUiIGlkPSJnbHlwaDAtMCI+CjxwYXRoIHN0eWxlPSJzdHJva2U6bm9uZTsiIGQ9IiIvPgo8L3N5bWJvbD4KPHN5bWJvbCBvdmVyZmxvdz0idmlzaWJsZSIgaWQ9ImdseXBoMC0xIj4KPHBhdGggc3R5bGU9I [...]
+</div>
+<div id="benchmark-3-assert-that-x-is-a-character-vector-with-no-missing-values-nor-empty-strings" class="section level3">
+<h3>Benchmark 3: Assert that <code>x</code> is a character vector with no missing values nor empty strings</h3>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">x =<span class="st"> </span><span class="kw">sample</span>(letters, <span class="dv">10000</span>, <span class="dt">replace =</span> <span class="ot">TRUE</span>)
+r =<span class="st"> </span>function(x) <span class="kw">stopifnot</span>(<span class="kw">is.character</span>(x) &&<span class="st"> </span>!<span class="kw">any</span>(<span class="kw">is.na</span>(x)) &&<span class="st"> </span><span class="kw">all</span>(<span class="kw">nchar</span>(x) ><span class="st"> </span><span class="dv">0</span>))
+cm =<span class="st"> </span>function(x) <span class="kw">assertCharacter</span>(x, <span class="dt">any.missing =</span> <span class="ot">FALSE</span>, <span class="dt">min.chars =</span> <span class="dv">1</span>)
+cmq =<span class="st"> </span>function(x) <span class="kw">qassert</span>(x, <span class="st">"S+[1,]"</span>)
+mb =<span class="st"> </span><span class="kw">microbenchmark</span>(<span class="kw">r</span>(x), <span class="kw">cm</span>(x), <span class="kw">cmq</span>(x))
+<span class="kw">print</span>(mb)</code></pre></div>
+<pre><code>## Unit: microseconds
+##    expr      min        lq       mean    median        uq      max neval
+##    r(x) 1166.335 1168.1965 1303.36054 1184.8910 1399.4770 2069.396   100
+##   cm(x)   28.874   29.6705   34.96495   30.4835   34.3575  229.213   100
+##  cmq(x)   40.891   43.5615   48.42563   44.3015   49.7410   90.307   100
+##  cld
+##    b
+##   a 
+##   a</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">autoplot</span>(mb)</code></pre></div>
+<p><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDMycHQiIGhlaWdodD0iMjg4cHQiIHZpZXdCb3g9IjAgMCA0MzIgMjg4IiB2ZXJzaW9uPSIxLjEiPgo8ZGVmcz4KPGc+CjxzeW1ib2wgb3ZlcmZsb3c9InZpc2libGUiIGlkPSJnbHlwaDAtMCI+CjxwYXRoIHN0eWxlPSJzdHJva2U6bm9uZTsiIGQ9IiIvPgo8L3N5bWJvbD4KPHN5bWJvbCBvdmVyZmxvdz0idmlzaWJsZSIgaWQ9ImdseXBoMC0xIj4KPHBhdGggc3R5bGU9I [...]
+</div>
+<div id="benchmark-4-assert-that-x-is-a-data-frame-with-no-missing-values" class="section level3">
+<h3>Benchmark 4: Assert that <code>x</code> is a data frame with no missing values</h3>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">N =<span class="st"> </span><span class="dv">10000</span>
+x =<span class="st"> </span><span class="kw">data.frame</span>(<span class="dt">a =</span> <span class="kw">runif</span>(N), <span class="dt">b =</span> <span class="kw">sample</span>(letters[<span class="dv">1</span>:<span class="dv">5</span>], N, <span class="dt">replace =</span> <span class="ot">TRUE</span>), <span class="dt">c =</span> <span class="kw">sample</span>(<span class="kw">c</span>(<span class="ot">FALSE</span>, <span class="ot">TRUE</span>), N, <span class="dt">replace =</ [...]
+r =<span class="st"> </span>function(x) <span class="kw">is.data.frame</span>(x) &&<span class="st"> </span>!<span class="kw">any</span>(<span class="kw">sapply</span>(x, function(x) <span class="kw">any</span>(<span class="kw">is.na</span>(x))))
+cm =<span class="st"> </span>function(x) <span class="kw">testDataFrame</span>(x, <span class="dt">any.missing =</span> <span class="ot">FALSE</span>)
+cmq =<span class="st"> </span>function(x) <span class="kw">qtest</span>(x, <span class="st">"D"</span>)
+mb =<span class="st"> </span><span class="kw">microbenchmark</span>(<span class="kw">r</span>(x), <span class="kw">cm</span>(x), <span class="kw">cmq</span>(x))
+<span class="kw">print</span>(mb)</code></pre></div>
+<pre><code>## Unit: microseconds
+##    expr    min      lq      mean   median       uq      max neval cld
+##    r(x) 72.386 75.5275 105.74166 100.9505 105.4205 1312.374   100   b
+##   cm(x) 18.697 19.5600  22.95351  20.4065  20.8585  177.918   100  a 
+##  cmq(x) 14.255 14.5525  15.50605  14.8595  15.2120   59.144   100  a</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">autoplot</span>(mb)</code></pre></div>
+<p><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDMycHQiIGhlaWdodD0iMjg4cHQiIHZpZXdCb3g9IjAgMCA0MzIgMjg4IiB2ZXJzaW9uPSIxLjEiPgo8ZGVmcz4KPGc+CjxzeW1ib2wgb3ZlcmZsb3c9InZpc2libGUiIGlkPSJnbHlwaDAtMCI+CjxwYXRoIHN0eWxlPSJzdHJva2U6bm9uZTsiIGQ9IiIvPgo8L3N5bWJvbD4KPHN5bWJvbCBvdmVyZmxvdz0idmlzaWJsZSIgaWQ9ImdseXBoMC0xIj4KPHBhdGggc3R5bGU9I [...]
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># checkmate tries to stop as early as possible</span>
+x$a[<span class="dv">1</span>] =<span class="st"> </span><span class="ot">NA</span>
+mb =<span class="st"> </span><span class="kw">microbenchmark</span>(<span class="kw">r</span>(x), <span class="kw">cm</span>(x), <span class="kw">cmq</span>(x))
+<span class="kw">print</span>(mb)</code></pre></div>
+<pre><code>## Unit: nanoseconds
+##    expr   min      lq     mean  median      uq     max neval cld
+##    r(x) 64301 66390.0 91347.12 69911.0 95435.0 1224736   100   b
+##   cm(x)  3916  4354.5  5843.08  4926.5  5341.0   23976   100  a 
+##  cmq(x)   762   921.5  1333.89  1256.0  1621.5    3985   100  a</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">autoplot</span>(mb)</code></pre></div>
+<p><img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iNDMycHQiIGhlaWdodD0iMjg4cHQiIHZpZXdCb3g9IjAgMCA0MzIgMjg4IiB2ZXJzaW9uPSIxLjEiPgo8ZGVmcz4KPGc+CjxzeW1ib2wgb3ZlcmZsb3c9InZpc2libGUiIGlkPSJnbHlwaDAtMCI+CjxwYXRoIHN0eWxlPSJzdHJva2U6bm9uZTsiIGQ9IiIvPgo8L3N5bWJvbD4KPHN5bWJvbCBvdmVyZmxvdz0idmlzaWJsZSIgaWQ9ImdseXBoMC0xIj4KPHBhdGggc3R5bGU9I [...]
+</div>
+</div>
+<div id="extending-checkmate" class="section level2">
+<h2>Extending checkmate</h2>
+<p>To extend checkmate a custom <code>check*</code> function has to be written. For example, to check for a square matrix one can re-use parts of checkmate and extend the check with additional functionality:</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">checkSquareMatrix =<span class="st"> </span>function(x, <span class="dt">mode =</span> <span class="ot">NULL</span>) {
+  <span class="co"># check functions must return TRUE on success</span>
+  <span class="co"># and a custom error message otherwise</span>
+  res =<span class="st"> </span><span class="kw">checkMatrix</span>(x, <span class="dt">mode =</span> mode)
+  if (!<span class="kw">isTRUE</span>(res))
+    <span class="kw">return</span>(res)
+  if (<span class="kw">nrow</span>(x) !=<span class="st"> </span><span class="kw">ncol</span>(x))
+    <span class="kw">return</span>(<span class="st">"Must be square"</span>)
+  <span class="kw">return</span>(<span class="ot">TRUE</span>)
+}
+
+<span class="co"># a quick test:</span>
+X =<span class="st"> </span><span class="kw">matrix</span>(<span class="dv">1</span>:<span class="dv">9</span>, <span class="dt">nrow =</span> <span class="dv">3</span>)
+<span class="kw">checkSquareMatrix</span>(X)</code></pre></div>
+<pre><code>## [1] TRUE</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">checkSquareMatrix</span>(X, <span class="dt">mode =</span> <span class="st">"character"</span>)</code></pre></div>
+<pre><code>## [1] "Must store characters"</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">checkSquareMatrix</span>(X[<span class="dv">1</span>:<span class="dv">2</span>, ])</code></pre></div>
+<pre><code>## [1] "Must be square"</code></pre>
+<p>The respective counterparts to the <code>check</code>-function can be created using the constructors <a href="https://mllg.github.io/checkmate/reference/makeAssertion">makeAssertionFunction</a>, <a href="https://mllg.github.io/checkmate/reference/makeTest">makeTestFunction</a> and <a href="https://mllg.github.io/checkmate/reference/makeExpectation">makeExpectationFunction</a>:</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># For assertions:</span>
+assert_square_matrix =<span class="st"> </span>assertSquareMatrix =<span class="st"> </span><span class="kw">makeAssertionFunction</span>(checkSquareMatrix)
+<span class="kw">print</span>(assertSquareMatrix)</code></pre></div>
+<pre><code>## function (x, mode = NULL, .var.name = vname(x), add = NULL) 
+## {
+##     res = checkSquareMatrix(x, mode)
+##     makeAssertion(x, res, .var.name, add)
+## }</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># For tests:</span>
+test_square_matrix =<span class="st"> </span>testSquareMatrix =<span class="st"> </span><span class="kw">makeTestFunction</span>(checkSquareMatrix)
+<span class="kw">print</span>(testSquareMatrix)</code></pre></div>
+<pre><code>## function (x, mode = NULL) 
+## {
+##     identical(checkSquareMatrix(x, mode), TRUE)
+## }</code></pre>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># For expectations:</span>
+expect_square_matrix =<span class="st"> </span><span class="kw">makeExpectationFunction</span>(checkSquareMatrix)
+<span class="kw">print</span>(expect_square_matrix)</code></pre></div>
+<pre><code>## function (x, mode = NULL, info = NULL, label = vname(x)) 
+## {
+##     res = checkSquareMatrix(x, mode)
+##     makeExpectation(x, res, info, label)
+## }</code></pre>
+<p>Note that all the additional arguments <code>.var.name</code>, <code>add</code>, <code>info</code> and <code>label</code> are automatically joined with the function arguments of your custom check function. Also note that if you define these functions inside an R package, the constructors are called at build-time (thus, there is no negative impact on the runtime).</p>
+</div>
+<div id="calling-checkmate-from-cc" class="section level2">
+<h2>Calling checkmate from C/C++</h2>
+<p>The package registers two functions which can be used in other packages’ C/C++ code for argument checks.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c">SEXP qassert(SEXP x, <span class="dt">const</span> <span class="dt">char</span> *rule, <span class="dt">const</span> <span class="dt">char</span> *name);
+Rboolean qtest(SEXP x, <span class="dt">const</span> <span class="dt">char</span> *rule);</code></pre></div>
+<p>These are the counterparts to <a href="https://mllg.github.io/checkmate/reference/qassert">qassert</a> and <a href="https://mllg.github.io/checkmate/reference/qassert">qtest</a>. Due to their simplistic interface, they perfectly suit the requirements of most type checks in C/C++.</p>
+<p>For detailed background information on the register mechanism, see the <a href="http://r-pkgs.had.co.nz/src.html#clang">Exporting C Code</a> section in Hadley’s Book “R Packages” or <a href="https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Registering-native-routines">WRE</a>. Here is a step-by-step guide to get you started:</p>
+<ol style="list-style-type: decimal">
+<li>Add <code>checkmate</code> to your “Imports” and LinkingTo" sections in your DESCRIPTION file.</li>
+<li>Create a stub file C source file which pulls in the provided C functions in order to compile them for your package. See example below.</li>
+<li>Include the provided header file <code><checkmate.h></code> in each compilation unit where you want to use checkmate.</li>
+</ol>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Example for (2), "checkmate_stub.c":*/</span>
+<span class="pp">#include </span><span class="im"><checkmate.h></span>
+<span class="pp">#include </span><span class="im"><checkmate_stub.c></span></code></pre></div>
+</div>
+<div id="session-info" class="section level2">
+<h2>Session Info</h2>
+<p>For the sake of completeness, here the <code>sessionInfo()</code> for the benchmark (but remember the note before on <code>knitr</code> possibly biasing the results).</p>
+<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">sessionInfo</span>()</code></pre></div>
+<pre><code>## R version 3.3.1 (2016-06-21)
+## Platform: x86_64-pc-linux-gnu (64-bit)
+## Running under: Arch Linux
+## 
+## locale:
+##  [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C              
+##  [3] LC_TIME=de_DE.UTF-8        LC_COLLATE=C              
+##  [5] LC_MONETARY=de_DE.UTF-8    LC_MESSAGES=de_DE.UTF-8   
+##  [7] LC_PAPER=de_DE.UTF-8       LC_NAME=C                 
+##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
+## [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       
+## 
+## attached base packages:
+## [1] stats     graphics  grDevices utils     datasets  methods   base     
+## 
+## other attached packages:
+## [1] microbenchmark_1.4-2.1 ggplot2_2.1.0          checkmate_1.8.2       
+## 
+## loaded via a namespace (and not attached):
+##  [1] Rcpp_0.12.7        knitr_1.14         magrittr_1.5      
+##  [4] MASS_7.3-45        splines_3.3.1      munsell_0.4.3     
+##  [7] colorspace_1.2-7   lattice_0.20-34    multcomp_1.4-6    
+## [10] stringr_1.1.0      plyr_1.8.4         tools_3.3.1       
+## [13] grid_3.3.1         gtable_0.2.0       TH.data_1.0-7     
+## [16] htmltools_0.3.5    survival_2.40-1    yaml_2.1.13       
+## [19] assertthat_0.1     rprojroot_1.1      digest_0.6.10     
+## [22] tibble_1.2         Matrix_1.2-7.1     formatR_1.4       
+## [25] codetools_0.2-15   evaluate_0.10      rmarkdown_1.1.9012
+## [28] sandwich_2.3-4     stringi_1.1.2      scales_0.4.0      
+## [31] backports_1.0.5    mvtnorm_1.0-5      zoo_1.7-13</code></pre>
+</div>
+
+
+
+<!-- dynamically load mathjax for compatibility with self-contained -->
+<script>
+  (function () {
+    var script = document.createElement("script");
+    script.type = "text/javascript";
+    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    document.getElementsByTagName("head")[0].appendChild(script);
+  })();
+</script>
+
+</body>
+</html>
diff --git a/inst/include/checkmate.h b/inst/include/checkmate.h
new file mode 100644
index 0000000..984e827
--- /dev/null
+++ b/inst/include/checkmate.h
@@ -0,0 +1,21 @@
+#ifndef _CHECKMATE_H_
+#define _CHECKMATE_H_
+
+#include <R.h>
+#include <Rinternals.h>
+#include <Rdefines.h>
+#include <R_ext/Rdynload.h>
+#include <R_ext/Visibility.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+Rboolean attribute_hidden qtest(SEXP x, const char *rule);
+SEXP attribute_hidden qassert(SEXP x, const char *rule, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/inst/include/checkmate_stub.c b/inst/include/checkmate_stub.c
new file mode 100644
index 0000000..1f27b53
--- /dev/null
+++ b/inst/include/checkmate_stub.c
@@ -0,0 +1,15 @@
+#include "checkmate.h"
+
+Rboolean attribute_hidden qtest(SEXP x, const char *rule) {
+  static Rboolean(*fun)(SEXP, const char *) = NULL;
+  if (fun == NULL)
+    fun = (Rboolean(*)(SEXP, const char *)) R_GetCCallable("checkmate", "qtest");
+  return fun(x, rule);
+}
+
+SEXP attribute_hidden qassert(SEXP x, const char *rule, const char *name) {
+  static SEXP(*fun)(SEXP, const char *, const char *) = NULL;
+  if (fun == NULL)
+    fun = (SEXP(*)(SEXP, const char *, const char *)) R_GetCCallable("checkmate", "qassert");
+  return fun(x, rule, name);
+}
diff --git a/man/AssertCollection.Rd b/man/AssertCollection.Rd
new file mode 100644
index 0000000..fbdbf6b
--- /dev/null
+++ b/man/AssertCollection.Rd
@@ -0,0 +1,43 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/AssertCollection.R
+\name{AssertCollection}
+\alias{AssertCollection}
+\alias{makeAssertCollection}
+\alias{reportAssertions}
+\title{Collect multiple assertions}
+\usage{
+makeAssertCollection()
+
+reportAssertions(collection)
+}
+\arguments{
+\item{collection}{[\code{AssertCollection}]\cr
+Object of type \dQuote{AssertCollection} (constructed via \code{makeAssertCollection}).}
+}
+\value{
+\code{makeAssertCollection()} returns an object of class \dQuote{AssertCollection} and
+ \code{reportCollection} returns invisibly \code{TRUE} if no error is thrown (i.e., no message was
+ collected).
+}
+\description{
+The function \code{makeAssertCollection()} returns a simple stack-like
+closure you can pass to all functions of the \code{assert*}-family.
+All messages get collected and can be reported with \code{reportAssertions()}.
+Alternatively, you can easily write your own report function or customize the the output of
+the report function to a certain degree.
+See the example on how to push custom messages or retrieve all stored messages.
+}
+\examples{
+x = "a"
+coll = makeAssertCollection()
+
+print(coll$isEmpty())
+assertNumeric(x, add = coll)
+coll$isEmpty()
+coll$push("Custom error message")
+coll$getMessages()
+\dontrun{
+  reportAssertions(coll)
+}
+}
+
diff --git a/man/anyInfinite.Rd b/man/anyInfinite.Rd
new file mode 100644
index 0000000..5a583de
--- /dev/null
+++ b/man/anyInfinite.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/anyInfinite.R
+\name{anyInfinite}
+\alias{anyInfinite}
+\title{Check if an object contains infinite values}
+\usage{
+anyInfinite(x)
+}
+\arguments{
+\item{x}{[\code{ANY}]\cr
+Object to check.}
+}
+\value{
+[\code{logical(1)}] Returns \code{TRUE} if any element is \code{-Inf} or \code{Inf}.
+}
+\description{
+Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+}
+\examples{
+anyInfinite(1:10)
+anyInfinite(c(1:10, Inf))
+iris[3, 3] = Inf
+anyInfinite(iris)
+}
+
diff --git a/man/anyMissing.Rd b/man/anyMissing.Rd
new file mode 100644
index 0000000..fc3f4e5
--- /dev/null
+++ b/man/anyMissing.Rd
@@ -0,0 +1,46 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/allMissing.R, R/anyMissing.R
+\name{allMissing}
+\alias{allMissing}
+\alias{anyMissing}
+\title{Check if an object contains missing values}
+\usage{
+allMissing(x)
+
+anyMissing(x)
+}
+\arguments{
+\item{x}{[\code{ANY}]\cr
+Object to check.}
+}
+\value{
+[\code{logical(1)}] Returns \code{TRUE} if any (\code{anyMissing}) or all (\code{allMissing})
+ elements of \code{x} are missing (see details), \code{FALSE} otherwise.
+}
+\description{
+Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+Missingness is defined as \code{NA} or \code{NaN} for atomic types and data frame columns,
+\code{NULL} is defined as missing for lists.\cr
+\code{allMissing} applied to a \code{data.frame} returns \code{TRUE} if at least one column has
+only non-missing values. If you want to perform the less frequent check that there is not a single
+non-missing observation present in the \code{data.frame}, use \code{all(sapply(df, allMissing))}
+instead.
+}
+\examples{
+allMissing(1:2)
+allMissing(c(1, NA))
+allMissing(c(NA, NA))
+x = data.frame(a = 1:2, b = NA)
+# Note how allMissing combines the results for data frames:
+allMissing(x)
+all(sapply(x, allMissing))
+anyMissing(c(1, 1))
+anyMissing(c(1, NA))
+anyMissing(list(1, NULL))
+
+x = iris
+x[, "Species"] = NA
+anyMissing(x)
+allMissing(x)
+}
+
diff --git a/man/anyNaN.Rd b/man/anyNaN.Rd
new file mode 100644
index 0000000..1e5ff80
--- /dev/null
+++ b/man/anyNaN.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/anyNaN.R
+\name{anyNaN}
+\alias{anyNaN}
+\title{Check if an object contains NaN values}
+\usage{
+anyNaN(x)
+}
+\arguments{
+\item{x}{[\code{ANY}]\cr
+Object to check.}
+}
+\value{
+[\code{logical(1)}] Returns \code{TRUE} if any element is \code{NaN}.
+}
+\description{
+Supported are atomic types (see \code{\link[base]{is.atomic}}), lists and data frames.
+}
+\examples{
+anyNaN(1:10)
+anyNaN(c(1:10, NaN))
+iris[3, 3] = NaN
+anyNaN(iris)
+}
+
diff --git a/man/asInteger.Rd b/man/asInteger.Rd
new file mode 100644
index 0000000..2d23535
--- /dev/null
+++ b/man/asInteger.Rd
@@ -0,0 +1,88 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/asInteger.R
+\name{asInteger}
+\alias{asCount}
+\alias{asInt}
+\alias{asInteger}
+\title{Convert an argument to an integer}
+\usage{
+asInteger(x, tol = sqrt(.Machine$double.eps), lower = -Inf, upper = Inf,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, .var.name = vname(x))
+
+asCount(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), .var.name = vname(x))
+
+asInt(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), .var.name = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to convert.}
+
+\item{tol}{[\code{double(1)}]\cr
+Numerical tolerance used to check whether a double or complex can be converted.
+Default is \code{sqrt(.Machine$double.eps)}.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in error messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{positive}{[\code{logical(1)}]\cr
+Must \code{x} be positive (>= 1)?
+Default is \code{FALSE}.}
+}
+\value{
+Converted \code{x}.
+}
+\description{
+\code{asInteger} is intended to be used for vectors while \code{asInt} is
+a specialization for scalar integers and \code{asCount} for scalar
+non-negative integers.
+Convertible are (a) atomic vectors with all elements \code{NA}
+and (b) double vectors with all elements being within \code{tol}
+range of an integer.
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+asInteger(c(1, 2, 3))
+asCount(1)
+asInt(1)
+}
+
diff --git a/man/assert.Rd b/man/assert.Rd
new file mode 100644
index 0000000..b04654c
--- /dev/null
+++ b/man/assert.Rd
@@ -0,0 +1,42 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/assert.R
+\name{assert}
+\alias{assert}
+\title{Combine multiple checks into one assertion}
+\usage{
+assert(..., combine = "or", .var.name = NULL)
+}
+\arguments{
+\item{...}{[any]\cr
+List of calls to check functions.}
+
+\item{combine}{[\code{character(1)}]\cr
+\dQuote{or} or \dQuote{and} to combine the check functions with an OR
+or AND, respectively.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in error messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Throws an error if all checks fail and invisibly returns
+ \code{TRUE} otherwise.
+}
+\description{
+You can call this function with an arbitrary number of of \code{check*}
+functions, i.e. functions provided by this package or your own functions which
+return \code{TRUE} on success and the error message as \code{character(1)} otherwise.
+The resulting assertion is successful, if \code{combine} is
+\dQuote{or} (default) and at least one check evaluates to \code{TRUE} or
+\code{combine} is \dQuote{and} and all checks evaluate to \code{TRUE}.
+Otherwise, \code{assert} throws an informative error message.
+}
+\examples{
+x = 1:10
+assert(checkNull(x), checkInteger(x, any.missing = FALSE))
+\dontrun{
+x = 1
+assert(checkChoice(x, c("a", "b")), checkDataFrame(x))
+}
+}
+
diff --git a/man/checkAccess.Rd b/man/checkAccess.Rd
new file mode 100644
index 0000000..b02d92e
--- /dev/null
+++ b/man/checkAccess.Rd
@@ -0,0 +1,83 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkAccess.R
+\name{checkAccess}
+\alias{assertAccess}
+\alias{assert_access}
+\alias{checkAccess}
+\alias{check_access}
+\alias{expect_access}
+\alias{testAccess}
+\alias{test_access}
+\title{Check file system access rights}
+\usage{
+checkAccess(x, access = "")
+
+check_access(x, access = "")
+
+assertAccess(x, access = "", .var.name = vname(x), add = NULL)
+
+assert_access(x, access = "", .var.name = vname(x), add = NULL)
+
+testAccess(x, access = "")
+
+test_access(x, access = "")
+
+expect_access(x, access = "", info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{access}{[\code{character(1)}]\cr
+Single string containing possible characters \sQuote{r}, \sQuote{w} and \sQuote{x} to
+force a check for read, write or execute access rights, respectively.
+Write and executable rights are not checked on Windows.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertAccess}/\code{assert_access} return 
+ \code{x} invisibly, whereas
+ \code{checkAccess}/\code{check_access} and 
+ \code{testAccess}/\code{test_access} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertAccess}/\code{assert_access}
+ throws an error message, 
+ \code{testAccess}/\code{test_access}
+ returns \code{FALSE},
+ and \code{checkAccess} returns a string with the error message.
+ The function \code{expect_access} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check file system access rights
+}
+\examples{
+# Is R's home directory readable?
+testAccess(R.home(), "r")
+
+# Is R's home directory writeable?
+testAccess(R.home(), "w")
+}
+\seealso{
+Other filesystem: \code{\link{checkDirectoryExists}},
+  \code{\link{checkFileExists}},
+  \code{\link{checkPathForOutput}}
+}
+
diff --git a/man/checkArray.Rd b/man/checkArray.Rd
new file mode 100644
index 0000000..c643223
--- /dev/null
+++ b/man/checkArray.Rd
@@ -0,0 +1,117 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkArray.R
+\name{checkArray}
+\alias{assertArray}
+\alias{assert_array}
+\alias{checkArray}
+\alias{check_array}
+\alias{expect_array}
+\alias{testArray}
+\alias{test_array}
+\title{Check if an argument is an array}
+\usage{
+checkArray(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE)
+
+check_array(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE)
+
+assertArray(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_array(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testArray(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE)
+
+test_array(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE)
+
+expect_array(x, mode = NULL, any.missing = TRUE, d = NULL, min.d = NULL,
+  max.d = NULL, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{mode}{[\code{character(1)}]\cr
+Storage mode of the array. Arrays can hold vectors, i.e. \dQuote{logical},
+\dQuote{integer}, \dQuote{integerish}, \dQuote{double}, \dQuote{numeric}, \dQuote{complex},
+\dQuote{character} and \dQuote{list}. You can also specify \dQuote{atomic}
+here to explicitly prohibit lists. Default is \code{NULL} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{TRUE}.}
+
+\item{d}{[\code{integer(1)}]\cr
+Exact number of dimensions of array \code{x}.
+Default is \code{NULL} (no check).}
+
+\item{min.d}{[\code{integer(1)}]\cr
+Minimum number of dimensions of array \code{x}.
+Default is \code{NULL} (no check).}
+
+\item{max.d}{[\code{integer(1)}]\cr
+Maximum number of dimensions of array \code{x}.
+Default is \code{NULL} (no check).}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertArray}/\code{assert_array} return 
+ \code{x} invisibly, whereas
+ \code{checkArray}/\code{check_array} and 
+ \code{testArray}/\code{test_array} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertArray}/\code{assert_array}
+ throws an error message, 
+ \code{testArray}/\code{test_array}
+ returns \code{FALSE},
+ and \code{checkArray} returns a string with the error message.
+ The function \code{expect_array} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is an array
+}
+\examples{
+checkArray(array(1:27, dim = c(3, 3, 3)), d = 3)
+}
+\seealso{
+Other basetypes: \code{\link{checkAtomic}},
+  \code{\link{checkCharacter}}, \code{\link{checkComplex}},
+  \code{\link{checkDataFrame}}, \code{\link{checkDate}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+
+Other compound: \code{\link{checkDataFrame}},
+  \code{\link{checkDataTable}}, \code{\link{checkMatrix}},
+  \code{\link{checkTibble}}
+}
+
diff --git a/man/checkAtomic.Rd b/man/checkAtomic.Rd
new file mode 100644
index 0000000..a078286
--- /dev/null
+++ b/man/checkAtomic.Rd
@@ -0,0 +1,117 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkAtomic.R
+\name{checkAtomic}
+\alias{assertAtomic}
+\alias{assert_atomic}
+\alias{checkAtomic}
+\alias{check_atomic}
+\alias{expect_atomic}
+\alias{testAtomic}
+\alias{test_atomic}
+\title{Check that an argument is an atomic vector}
+\usage{
+checkAtomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+check_atomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+assertAtomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  .var.name = vname(x), add = NULL)
+
+assert_atomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  .var.name = vname(x), add = NULL)
+
+testAtomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+test_atomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+expect_atomic(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertAtmoic}/\code{assert_atmoic} return 
+ \code{x} invisibly, whereas
+ \code{checkAtmoic}/\code{check_atmoic} and 
+ \code{testAtmoic}/\code{test_atmoic} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertAtmoic}/\code{assert_atmoic}
+ throws an error message, 
+ \code{testAtmoic}/\code{test_atmoic}
+ returns \code{FALSE},
+ and \code{checkAtmoic} returns a string with the error message.
+ The function \code{expect_atmoic} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+For the definition of \dQuote{atomic}, see \code{\link[base]{is.atomic}}.
+}
+\examples{
+testAtomic(letters, min.len = 1L, any.missing = FALSE)
+}
+\seealso{
+Other atomicvector: \code{\link{checkAtomicVector}},
+  \code{\link{checkVector}}
+
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkCharacter}}, \code{\link{checkComplex}},
+  \code{\link{checkDataFrame}}, \code{\link{checkDate}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkAtomicVector.Rd b/man/checkAtomicVector.Rd
new file mode 100644
index 0000000..8ea803a
--- /dev/null
+++ b/man/checkAtomicVector.Rd
@@ -0,0 +1,111 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkAtomicVector.R
+\name{checkAtomicVector}
+\alias{assertAtomicVector}
+\alias{assert_atomic_vector}
+\alias{checkAtomicVector}
+\alias{check_atomic_vector}
+\alias{expect_atomic_vector}
+\alias{testAtomicVector}
+\alias{test_atomic_vector}
+\title{Check that an argument is an atomic vector}
+\usage{
+checkAtomicVector(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+check_atomic_vector(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+assertAtomicVector(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  .var.name = vname(x), add = NULL)
+
+assert_atomic_vector(x, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, .var.name = vname(x), add = NULL)
+
+testAtomicVector(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+test_atomic_vector(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL)
+
+expect_atomic_vector(x, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertAtomicVector}/\code{assert_atomic_vector} return 
+ \code{x} invisibly, whereas
+ \code{checkAtomicVector}/\code{check_atomic_vector} and 
+ \code{testAtomicVector}/\code{test_atomic_vector} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertAtomicVector}/\code{assert_atomic_vector}
+ throws an error message, 
+ \code{testAtomicVector}/\code{test_atomic_vector}
+ returns \code{FALSE},
+ and \code{checkAtomicVector} returns a string with the error message.
+ The function \code{expect_atomic_vector} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+An atomic vector is defined slightly different from specifications in
+\code{\link[base]{is.atomic}} and \code{\link[base]{is.vector}}:
+An atomic vector is either \code{logical}, \code{integer}, \code{numeric},
+\code{complex}, \code{character} or \code{raw} and can have any attributes except a
+dimension attribute (like matrices).
+I.e., a \code{factor} is an atomic vector, but a matrix or \code{NULL} are not.
+In short, this is mostly equivalent to \code{is.atomic(x) && !is.null(x) && is.null(dim(x))}.
+}
+\examples{
+testAtomicVector(letters, min.len = 1L, any.missing = FALSE)
+}
+\seealso{
+Other atomicvector: \code{\link{checkAtomic}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkCharacter.Rd b/man/checkCharacter.Rd
new file mode 100644
index 0000000..a06329d
--- /dev/null
+++ b/man/checkCharacter.Rd
@@ -0,0 +1,151 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkCharacter.R
+\name{checkCharacter}
+\alias{assertCharacter}
+\alias{assert_character}
+\alias{checkCharacter}
+\alias{check_character}
+\alias{expect_character}
+\alias{testCharacter}
+\alias{test_character}
+\title{Check if an argument is a vector of type character}
+\usage{
+checkCharacter(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+check_character(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+assertCharacter(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_character(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testCharacter(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+test_character(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+expect_character(x, min.chars = NULL, pattern = NULL, fixed = NULL,
+  ignore.case = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{min.chars}{[\code{integer(1)}]\cr
+Minimum number of characters in each element of \code{x}.}
+
+\item{pattern}{[\code{character(1L)}]\cr
+Regular expression as used in \code{\link[base]{grepl}}.
+All elements of \code{x} must comply to this pattern.}
+
+\item{fixed}{[\code{character(1)}]\cr
+Substring to detect in \code{x}. Will be used as \code{pattern} in \code{\link[base]{grepl}}
+with option \code{fixed} set to \code{TRUE}.
+All elements of \code{x} must contain this substring.}
+
+\item{ignore.case}{[\code{logical(1)}]\cr
+See \code{\link[base]{grepl}}. Default is \code{FALSE}.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertCharacter}/\code{assert_character} return 
+ \code{x} invisibly, whereas
+ \code{checkCharacter}/\code{check_character} and 
+ \code{testCharacter}/\code{test_character} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertCharacter}/\code{assert_character}
+ throws an error message, 
+ \code{testCharacter}/\code{test_character}
+ returns \code{FALSE},
+ and \code{checkCharacter} returns a string with the error message.
+ The function \code{expect_character} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a vector of type character
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testCharacter(letters, min.len = 1, any.missing = FALSE)
+testCharacter(letters, min.chars = 2)
+testCharacter("example", pattern = "xa")
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkComplex}},
+  \code{\link{checkDataFrame}}, \code{\link{checkDate}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkChoice.Rd b/man/checkChoice.Rd
new file mode 100644
index 0000000..7a4dd3e
--- /dev/null
+++ b/man/checkChoice.Rd
@@ -0,0 +1,86 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkChoice.R
+\name{checkChoice}
+\alias{assertChoice}
+\alias{assert_choice}
+\alias{checkChoice}
+\alias{check_choice}
+\alias{expect_choice}
+\alias{testChoice}
+\alias{test_choice}
+\title{Check if an object is an element of a given set}
+\usage{
+checkChoice(x, choices)
+
+check_choice(x, choices)
+
+assertChoice(x, choices, .var.name = vname(x), add = NULL)
+
+assert_choice(x, choices, .var.name = vname(x), add = NULL)
+
+testChoice(x, choices)
+
+test_choice(x, choices)
+
+expect_choice(x, choices, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{choices}{[\code{atomic}]\cr
+Set of possible values.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertChoice}/\code{assert_choice} return 
+ \code{x} invisibly, whereas
+ \code{checkChoice}/\code{check_choice} and 
+ \code{testChoice}/\code{test_choice} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertChoice}/\code{assert_choice}
+ throws an error message, 
+ \code{testChoice}/\code{test_choice}
+ returns \code{FALSE},
+ and \code{checkChoice} returns a string with the error message.
+ The function \code{expect_choice} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an object is an element of a given set
+}
+\note{
+The object \code{x} must be of the same type as the set w.r.t. \code{\link[base]{typeof}}.
+Integers and doubles are both treated as numeric.
+}
+\examples{
+testChoice("x", letters)
+
+# x is converted before the comparison if necessary
+# note that this is subject to change in a future version
+testChoice(factor("a"), "a")
+testChoice(1, "1")
+testChoice(1, as.integer(1))
+}
+\seealso{
+Other set: \code{\link{checkSetEqual}},
+  \code{\link{checkSubset}}
+}
+
diff --git a/man/checkClass.Rd b/man/checkClass.Rd
new file mode 100644
index 0000000..be1f3ab
--- /dev/null
+++ b/man/checkClass.Rd
@@ -0,0 +1,99 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkClass.R
+\name{checkClass}
+\alias{assertClass}
+\alias{assert_class}
+\alias{checkClass}
+\alias{check_class}
+\alias{expect_class}
+\alias{testClass}
+\alias{test_class}
+\title{Check the class membership of an argument}
+\usage{
+checkClass(x, classes, ordered = FALSE)
+
+check_class(x, classes, ordered = FALSE)
+
+assertClass(x, classes, ordered = FALSE, .var.name = vname(x), add = NULL)
+
+assert_class(x, classes, ordered = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testClass(x, classes, ordered = FALSE)
+
+test_class(x, classes, ordered = FALSE)
+
+expect_class(x, classes, ordered = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{classes}{[\code{character}]\cr
+Class names to check for inheritance with \code{\link[base]{inherits}}.}
+
+\item{ordered}{[\code{logical(1)}]\cr
+Expect \code{x} to be specialized in provided order.
+Default is \code{FALSE}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertClass}/\code{assert_class} return 
+ \code{x} invisibly, whereas
+ \code{checkClass}/\code{check_class} and 
+ \code{testClass}/\code{test_class} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertClass}/\code{assert_class}
+ throws an error message, 
+ \code{testClass}/\code{test_class}
+ returns \code{FALSE},
+ and \code{checkClass} returns a string with the error message.
+ The function \code{expect_class} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check the class membership of an argument
+}
+\examples{
+# Create an object with classes "foo" and "bar"
+x = 1
+class(x) = c("foo", "bar")
+
+# is x of class "foo"?
+testClass(x, "foo")
+
+# is x of class "foo" and "bar"?
+testClass(x, c("foo", "bar"))
+
+# is x of class "foo" or "bar"?
+\dontrun{
+assert(
+  checkClass(x, "foo"),
+  checkClass(x, "bar")
+)
+}
+# is x most specialized as "bar"?
+testClass(x, "bar", ordered = TRUE)
+}
+\seealso{
+Other attributes: \code{\link{checkNamed}},
+  \code{\link{checkNames}}
+}
+
diff --git a/man/checkComplex.Rd b/man/checkComplex.Rd
new file mode 100644
index 0000000..3dc5c09
--- /dev/null
+++ b/man/checkComplex.Rd
@@ -0,0 +1,128 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkComplex.R
+\name{checkComplex}
+\alias{assertComplex}
+\alias{assert_complex}
+\alias{checkComplex}
+\alias{check_complex}
+\alias{expect_complex}
+\alias{testComplex}
+\alias{test_complex}
+\title{Check if an argument is a vector of type complex}
+\usage{
+checkComplex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+check_complex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+assertComplex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_complex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testComplex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+test_complex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+expect_complex(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertComplex}/\code{assert_complex} return 
+ \code{x} invisibly, whereas
+ \code{checkComplex}/\code{check_complex} and 
+ \code{testComplex}/\code{test_complex} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertComplex}/\code{assert_complex}
+ throws an error message, 
+ \code{testComplex}/\code{test_complex}
+ returns \code{FALSE},
+ and \code{checkComplex} returns a string with the error message.
+ The function \code{expect_complex} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a vector of type complex
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testComplex(1)
+testComplex(1+1i)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkDataFrame}}, \code{\link{checkDate}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkCount.Rd b/man/checkCount.Rd
new file mode 100644
index 0000000..1b3d312
--- /dev/null
+++ b/man/checkCount.Rd
@@ -0,0 +1,106 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkCount.R
+\name{checkCount}
+\alias{assertCount}
+\alias{assert_count}
+\alias{checkCount}
+\alias{check_count}
+\alias{expect_count}
+\alias{testCount}
+\alias{test_count}
+\title{Check if an argument is a count}
+\usage{
+checkCount(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+check_count(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+assertCount(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_count(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testCount(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+test_count(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+expect_count(x, na.ok = FALSE, positive = FALSE,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{positive}{[\code{logical(1)}]\cr
+Must \code{x} be positive (>= 1)?
+Default is \code{FALSE}, allowing 0.}
+
+\item{tol}{[\code{double(1)}]\cr
+Numerical tolerance used to check whether a double or complex can be converted.
+Default is \code{sqrt(.Machine$double.eps)}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertCount}/\code{assert_count} return 
+ \code{x} invisibly, whereas
+ \code{checkCount}/\code{check_count} and 
+ \code{testCount}/\code{test_count} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertCount}/\code{assert_count}
+ throws an error message, 
+ \code{testCount}/\code{test_count}
+ returns \code{FALSE},
+ and \code{checkCount} returns a string with the error message.
+ The function \code{expect_count} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+A count is defined as non-negative integerish value.
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testCount(1)
+testCount(-1)
+}
+\seealso{
+Other scalars: \code{\link{checkFlag}},
+  \code{\link{checkInt}}, \code{\link{checkNumber}},
+  \code{\link{checkScalarNA}}, \code{\link{checkScalar}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkDataFrame.Rd b/man/checkDataFrame.Rd
new file mode 100644
index 0000000..bc4c192
--- /dev/null
+++ b/man/checkDataFrame.Rd
@@ -0,0 +1,145 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkDataFrame.R
+\name{checkDataFrame}
+\alias{assertDataFrame}
+\alias{assert_data_frame}
+\alias{checkDataFrame}
+\alias{check_data_frame}
+\alias{expect_data_frame}
+\alias{testDataFrame}
+\alias{test_data_frame}
+\title{Check if an argument is a data frame}
+\usage{
+checkDataFrame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+check_data_frame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+assertDataFrame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_data_frame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testDataFrame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+test_data_frame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+expect_data_frame(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{types}{[\code{character}]\cr
+Character vector of class names. Each list element must inherit
+from at least one of the provided types.
+The types \dQuote{logical}, \dQuote{integer}, \dQuote{integerish}, \dQuote{double},
+\dQuote{numeric}, \dQuote{complex}, \dQuote{character}, \dQuote{factor}, \dQuote{atomic}, \dQuote{vector}
+\dQuote{atomicvector}, \dQuote{array}, \dQuote{matrix}, \dQuote{list}, \dQuote{function},
+\dQuote{environment} and \dQuote{null} are supported.
+For other types \code{\link[base]{inherits}} is used as a fallback to check \code{x}'s inheritance.
+Defaults to \code{character(0)} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are matrices with only missing values allowed? Default is \code{TRUE}.}
+
+\item{min.rows}{[\code{integer(1)}]\cr
+Minimum number of rows.}
+
+\item{min.cols}{[\code{integer(1)}]\cr
+Minimum number of columns.}
+
+\item{nrows}{[\code{integer(1)}]\cr
+Exact number of rows.}
+
+\item{ncols}{[\code{integer(1)}]\cr
+Exact number of columns.}
+
+\item{row.names}{[\code{character(1)}]\cr
+Check for row names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{col.names}{[\code{character(1)}]\cr
+Check for column names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to test for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertDataFrame}/\code{assert_data_frame} return 
+ \code{x} invisibly, whereas
+ \code{checkDataFrame}/\code{check_data_frame} and 
+ \code{testDataFrame}/\code{test_data_frame} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertDataFrame}/\code{assert_data_frame}
+ throws an error message, 
+ \code{testDataFrame}/\code{test_data_frame}
+ returns \code{FALSE},
+ and \code{checkDataFrame} returns a string with the error message.
+ The function \code{expect_data_frame} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a data frame
+}
+\examples{
+testDataFrame(iris)
+testDataFrame(iris, types = c("numeric", "factor"), min.rows = 1, col.names = "named")
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDate}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+
+Other compound: \code{\link{checkArray}},
+  \code{\link{checkDataTable}}, \code{\link{checkMatrix}},
+  \code{\link{checkTibble}}
+}
+
diff --git a/man/checkDataTable.Rd b/man/checkDataTable.Rd
new file mode 100644
index 0000000..49ec1fc
--- /dev/null
+++ b/man/checkDataTable.Rd
@@ -0,0 +1,148 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkDataTable.R
+\name{checkDataTable}
+\alias{assertDataTable}
+\alias{assert_data_table}
+\alias{checkDataTable}
+\alias{check_data_table}
+\alias{expect_data_table}
+\alias{testDataTable}
+\alias{test_data_table}
+\title{Check if an argument is a data table}
+\usage{
+checkDataTable(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE)
+
+check_data_table(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE)
+
+assertDataTable(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_data_table(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testDataTable(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE)
+
+test_data_table(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE)
+
+expect_data_table(x, key = NULL, index = NULL, types = character(0L),
+  any.missing = TRUE, all.missing = TRUE, min.rows = NULL,
+  min.cols = NULL, nrows = NULL, ncols = NULL, row.names = NULL,
+  col.names = NULL, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{key}{[\code{character}]\cr
+Expected primary key(s) of the data table.}
+
+\item{index}{[\code{character}]\cr
+Expected secondary key(s) of the data table.}
+
+\item{types}{[\code{character}]\cr
+Character vector of class names. Each list element must inherit
+from at least one of the provided types.
+The types \dQuote{logical}, \dQuote{integer}, \dQuote{integerish}, \dQuote{double},
+\dQuote{numeric}, \dQuote{complex}, \dQuote{character}, \dQuote{factor}, \dQuote{atomic}, \dQuote{vector}
+\dQuote{atomicvector}, \dQuote{array}, \dQuote{matrix}, \dQuote{list}, \dQuote{function},
+\dQuote{environment} and \dQuote{null} are supported.
+For other types \code{\link[base]{inherits}} is used as a fallback to check \code{x}'s inheritance.
+Defaults to \code{character(0)} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are matrices with only missing values allowed? Default is \code{TRUE}.}
+
+\item{min.rows}{[\code{integer(1)}]\cr
+Minimum number of rows.}
+
+\item{min.cols}{[\code{integer(1)}]\cr
+Minimum number of columns.}
+
+\item{nrows}{[\code{integer(1)}]\cr
+Exact number of rows.}
+
+\item{ncols}{[\code{integer(1)}]\cr
+Exact number of columns.}
+
+\item{row.names}{[\code{character(1)}]\cr
+Check for row names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{col.names}{[\code{character(1)}]\cr
+Check for column names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to test for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertDataTable}/\code{assert_data_table} return 
+ \code{x} invisibly, whereas
+ \code{checkDataTable}/\code{check_data_table} and 
+ \code{testDataTable}/\code{test_data_table} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertDataTable}/\code{assert_data_table}
+ throws an error message, 
+ \code{testDataTable}/\code{test_data_table}
+ returns \code{FALSE},
+ and \code{checkDataTable} returns a string with the error message.
+ The function \code{expect_data_table} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a data table
+}
+\examples{
+library(data.table)
+dt = as.data.table(iris)
+setkeyv(dt, "Species")
+setkeyv(dt, "Sepal.Length", physical = FALSE)
+testDataTable(dt)
+testDataTable(dt, key = "Species", index = "Sepal.Length", any.missing = FALSE)
+}
+\seealso{
+Other compound: \code{\link{checkArray}},
+  \code{\link{checkDataFrame}}, \code{\link{checkMatrix}},
+  \code{\link{checkTibble}}
+}
+
diff --git a/man/checkDate.Rd b/man/checkDate.Rd
new file mode 100644
index 0000000..951dd11
--- /dev/null
+++ b/man/checkDate.Rd
@@ -0,0 +1,120 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkDate.R
+\name{checkDate}
+\alias{assertDate}
+\alias{assert_date}
+\alias{checkDate}
+\alias{check_date}
+\alias{expect_date}
+\alias{testDate}
+\alias{test_date}
+\title{Check that an argument is a Date}
+\usage{
+checkDate(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE)
+
+check_date(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE)
+
+assertDate(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_date(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testDate(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE)
+
+test_date(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE)
+
+expect_date(x, lower = NULL, upper = NULL, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{lower}{[\code{\link[base]{Date}}]\cr
+All dates in \code{x} must be after this date. Comparison is done via \code{\link[base]{Ops.Date}}.}
+
+\item{upper}{[\code{\link[base]{Date}}]\cr
+All dates in \code{x} must be before this date. Comparison is done via \code{\link[base]{Ops.Date}}.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertAtmoic}/\code{assert_atmoic} return 
+ \code{x} invisibly, whereas
+ \code{checkAtmoic}/\code{check_atmoic} and 
+ \code{testAtmoic}/\code{test_atmoic} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertAtmoic}/\code{assert_atmoic}
+ throws an error message, 
+ \code{testAtmoic}/\code{test_atmoic}
+ returns \code{FALSE},
+ and \code{checkAtmoic} returns a string with the error message.
+ The function \code{expect_atmoic} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Checks that an object is of class \code{\link[base]{Date}}.
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkDirectoryExists.Rd b/man/checkDirectoryExists.Rd
new file mode 100644
index 0000000..b22a95b
--- /dev/null
+++ b/man/checkDirectoryExists.Rd
@@ -0,0 +1,105 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkDirectoryExists.R
+\name{checkDirectoryExists}
+\alias{assertDirectory}
+\alias{assertDirectoryExists}
+\alias{assert_directory}
+\alias{assert_directory_exists}
+\alias{checkDirectory}
+\alias{checkDirectoryExists}
+\alias{check_directory_exists}
+\alias{expect_directory}
+\alias{expect_directory_exists}
+\alias{testDirectory}
+\alias{testDirectoryExists}
+\alias{test_directory}
+\alias{test_directory_exists}
+\title{Check for existence and access rights of directories}
+\usage{
+checkDirectoryExists(x, access = "")
+
+check_directory_exists(x, access = "")
+
+assertDirectoryExists(x, access = "", .var.name = vname(x), add = NULL)
+
+assert_directory_exists(x, access = "", .var.name = vname(x), add = NULL)
+
+testDirectoryExists(x, access = "")
+
+test_directory_exists(x, access = "")
+
+expect_directory_exists(x, access = "", info = NULL, label = vname(x))
+
+checkDirectory(x, access = "")
+
+assertDirectory(x, access = "", .var.name = vname(x), add = NULL)
+
+assert_directory(x, access = "", .var.name = vname(x), add = NULL)
+
+testDirectory(x, access = "")
+
+test_directory(x, access = "")
+
+expect_directory(x, access = "", info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{access}{[\code{character(1)}]\cr
+Single string containing possible characters \sQuote{r}, \sQuote{w} and \sQuote{x} to
+force a check for read, write or execute access rights, respectively.
+Write and executable rights are not checked on Windows.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertDirectoryExists}/\code{assert_directory_exists} return 
+ \code{x} invisibly, whereas
+ \code{checkDirectoryExists}/\code{check_directory_exists} and 
+ \code{testDirectoryExists}/\code{test_directory_exists} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertDirectoryExists}/\code{assert_directory_exists}
+ throws an error message, 
+ \code{testDirectoryExists}/\code{test_directory_exists}
+ returns \code{FALSE},
+ and \code{checkDirectoryExists} returns a string with the error message.
+ The function \code{expect_directory_exists} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check for existence and access rights of directories
+}
+\note{
+The functions without the suffix \dQuote{exists} are deprecated and will be removed
+from the package in a future version due to name clashes.
+}
+\examples{
+# Is R's home directory readable?
+testDirectory(R.home(), "r")
+
+# Is R's home directory readable and writable?
+testDirectory(R.home(), "rw")
+}
+\seealso{
+Other filesystem: \code{\link{checkAccess}},
+  \code{\link{checkFileExists}},
+  \code{\link{checkPathForOutput}}
+}
+
diff --git a/man/checkEnvironment.Rd b/man/checkEnvironment.Rd
new file mode 100644
index 0000000..c9980b8
--- /dev/null
+++ b/man/checkEnvironment.Rd
@@ -0,0 +1,94 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkEnvironment.R
+\name{checkEnvironment}
+\alias{assertEnvironment}
+\alias{assert_environment}
+\alias{checkEnvironment}
+\alias{check_environment}
+\alias{expect_environment}
+\alias{testEnvironment}
+\alias{test_environment}
+\title{Check if an argument is an environment}
+\usage{
+checkEnvironment(x, contains = character(0L), null.ok = FALSE)
+
+check_environment(x, contains = character(0L), null.ok = FALSE)
+
+assertEnvironment(x, contains = character(0L), null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_environment(x, contains = character(0L), null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testEnvironment(x, contains = character(0L), null.ok = FALSE)
+
+test_environment(x, contains = character(0L), null.ok = FALSE)
+
+expect_environment(x, contains = character(0L), null.ok = FALSE,
+  info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{contains}{[\code{character}]\cr
+Vector of object names expected in the environment.
+Defaults to \code{character(0)}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertEnvironment}/\code{assert_environment} return 
+ \code{x} invisibly, whereas
+ \code{checkEnvironment}/\code{check_environment} and 
+ \code{testEnvironment}/\code{test_environment} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertEnvironment}/\code{assert_environment}
+ throws an error message, 
+ \code{testEnvironment}/\code{test_environment}
+ returns \code{FALSE},
+ and \code{checkEnvironment} returns a string with the error message.
+ The function \code{expect_environment} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is an environment
+}
+\examples{
+ee = as.environment(list(a = 1))
+testEnvironment(ee)
+testEnvironment(ee, contains = "a")
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkFactor}},
+  \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkFactor.Rd b/man/checkFactor.Rd
new file mode 100644
index 0000000..f7b33a3
--- /dev/null
+++ b/man/checkFactor.Rd
@@ -0,0 +1,158 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkFactor.R
+\name{checkFactor}
+\alias{assertFactor}
+\alias{assert_factor}
+\alias{checkFactor}
+\alias{check_factor}
+\alias{expect_factor}
+\alias{testFactor}
+\alias{test_factor}
+\title{Check if an argument is a factor}
+\usage{
+checkFactor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+check_factor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+assertFactor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_factor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testFactor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+test_factor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+expect_factor(x, levels = NULL, ordered = NA, empty.levels.ok = TRUE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, n.levels = NULL, min.levels = NULL, max.levels = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{levels}{[\code{character}]\cr
+Vector of allowed factor levels.}
+
+\item{ordered}{[\code{logical(1)}]\cr
+Check for an ordered factor? If \code{FALSE} or \code{TRUE}, checks explicitly
+for an unordered or ordered factor, respectively.
+Default is \code{NA} which does not perform any additional check.}
+
+\item{empty.levels.ok}{[\code{logical(1)}]\cr
+Are empty levels allowed?
+Default is \code{TRUE}.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{n.levels}{[\code{integer(1)}]\cr
+Exact number of factor levels.
+Default is \code{NULL} (no check).}
+
+\item{min.levels}{[\code{integer(1)}]\cr
+Minimum number of factor levels.
+Default is \code{NULL} (no check).}
+
+\item{max.levels}{[\code{integer(1)}]\cr
+Maximum number of factor levels.
+Default is \code{NULL} (no check).}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertFactor}/\code{assert_factor} return 
+ \code{x} invisibly, whereas
+ \code{checkFactor}/\code{check_factor} and 
+ \code{testFactor}/\code{test_factor} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertFactor}/\code{assert_factor}
+ throws an error message, 
+ \code{testFactor}/\code{test_factor}
+ returns \code{FALSE},
+ and \code{checkFactor} returns a string with the error message.
+ The function \code{expect_factor} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a factor
+}
+\examples{
+x = factor("a", levels = c("a", "b"))
+testFactor(x)
+testFactor(x, empty.levels.ok = FALSE)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkFileExists.Rd b/man/checkFileExists.Rd
new file mode 100644
index 0000000..f0c1aee
--- /dev/null
+++ b/man/checkFileExists.Rd
@@ -0,0 +1,112 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkFileExists.R
+\name{checkFileExists}
+\alias{assertFile}
+\alias{assertFileExists}
+\alias{assert_file}
+\alias{assert_file_exists}
+\alias{checkFile}
+\alias{checkFileExists}
+\alias{check_file_exists}
+\alias{expect_file}
+\alias{expect_file_exists}
+\alias{testFile}
+\alias{testFileExists}
+\alias{test_file_exists}
+\title{Check existence and access rights of files}
+\usage{
+checkFileExists(x, access = "", extension = NULL)
+
+check_file_exists(x, access = "", extension = NULL)
+
+assertFileExists(x, access = "", extension = NULL, .var.name = vname(x),
+  add = NULL)
+
+assert_file_exists(x, access = "", extension = NULL, .var.name = vname(x),
+  add = NULL)
+
+testFileExists(x, access = "", extension = NULL)
+
+test_file_exists(x, access = "", extension = NULL)
+
+expect_file_exists(x, access = "", extension = NULL, info = NULL,
+  label = vname(x))
+
+checkFile(x, access = "", extension = NULL)
+
+assertFile(x, access = "", extension = NULL, .var.name = vname(x),
+  add = NULL)
+
+assert_file(x, access = "", extension = NULL, .var.name = vname(x),
+  add = NULL)
+
+testFile(x, access = "", extension = NULL)
+
+expect_file(x, access = "", extension = NULL, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{access}{[\code{character(1)}]\cr
+Single string containing possible characters \sQuote{r}, \sQuote{w} and \sQuote{x} to
+force a check for read, write or execute access rights, respectively.
+Write and executable rights are not checked on Windows.}
+
+\item{extension}{[\code{character}]\cr
+Vector of allowed file extensions, matched case insensitive.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertFileExists}/\code{assert_file_exists} return 
+ \code{x} invisibly, whereas
+ \code{checkFileExists}/\code{check_file_exists} and 
+ \code{testFileExists}/\code{test_file_exists} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertFileExists}/\code{assert_file_exists}
+ throws an error message, 
+ \code{testFileExists}/\code{test_file_exists}
+ returns \code{FALSE},
+ and \code{checkFileExists} returns a string with the error message.
+ The function \code{expect_file_exists} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check existence and access rights of files
+}
+\note{
+The functions without the suffix \dQuote{exists} are deprecated and will be removed
+from the package in a future version due to name clashes.
+\code{test_file} has been unexported already.
+}
+\examples{
+# Check if R's COPYING file is readable
+testFileExists(file.path(R.home(), "COPYING"), access = "r")
+
+# Check if R's COPYING file is readable and writable
+testFileExists(file.path(R.home(), "COPYING"), access = "rw")
+}
+\seealso{
+Other filesystem: \code{\link{checkAccess}},
+  \code{\link{checkDirectoryExists}},
+  \code{\link{checkPathForOutput}}
+}
+
diff --git a/man/checkFlag.Rd b/man/checkFlag.Rd
new file mode 100644
index 0000000..a19038f
--- /dev/null
+++ b/man/checkFlag.Rd
@@ -0,0 +1,91 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkFlag.R
+\name{checkFlag}
+\alias{assertFlag}
+\alias{assert_flag}
+\alias{checkFlag}
+\alias{check_flag}
+\alias{expect_flag}
+\alias{testFlag}
+\alias{test_flag}
+\title{Check if an argument is a flag}
+\usage{
+checkFlag(x, na.ok = FALSE, null.ok = FALSE)
+
+check_flag(x, na.ok = FALSE, null.ok = FALSE)
+
+assertFlag(x, na.ok = FALSE, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_flag(x, na.ok = FALSE, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testFlag(x, na.ok = FALSE, null.ok = FALSE)
+
+test_flag(x, na.ok = FALSE, null.ok = FALSE)
+
+expect_flag(x, na.ok = FALSE, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertFlag}/\code{assert_flag} return 
+ \code{x} invisibly, whereas
+ \code{checkFlag}/\code{check_flag} and 
+ \code{testFlag}/\code{test_flag} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertFlag}/\code{assert_flag}
+ throws an error message, 
+ \code{testFlag}/\code{test_flag}
+ returns \code{FALSE},
+ and \code{checkFlag} returns a string with the error message.
+ The function \code{expect_flag} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+A flag is defined as single logical value.
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testFlag(TRUE)
+testFlag(1)
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkInt}}, \code{\link{checkNumber}},
+  \code{\link{checkScalarNA}}, \code{\link{checkScalar}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkFunction.Rd b/man/checkFunction.Rd
new file mode 100644
index 0000000..1d3f05a
--- /dev/null
+++ b/man/checkFunction.Rd
@@ -0,0 +1,106 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkFunction.R
+\name{checkFunction}
+\alias{assertFunction}
+\alias{assert_function}
+\alias{checkFunction}
+\alias{check_function}
+\alias{expect_function}
+\alias{testFunction}
+\alias{test_function}
+\title{Check if an argument is a function}
+\usage{
+checkFunction(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE)
+
+check_function(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE)
+
+assertFunction(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_function(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testFunction(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE)
+
+test_function(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE)
+
+expect_function(x, args = NULL, ordered = FALSE, nargs = NULL,
+  null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{args}{[\code{character}]\cr
+Expected formal arguments. Checks that a function has no arguments if
+set to \code{character(0)}.
+Default is \code{NULL} (no check).}
+
+\item{ordered}{[\code{logical(1)}]\cr
+Flag whether the arguments provided in \code{args} must be the first
+\code{length(args)} arguments of the function in the specified order.
+Default is \code{FALSE}.}
+
+\item{nargs}{[\code{integer(1)}]\cr
+Required number of arguments, without \code{...}.
+Default is \code{NULL} (no check).}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertFunction}/\code{assert_function} return 
+ \code{x} invisibly, whereas
+ \code{checkFunction}/\code{check_function} and 
+ \code{testFunction}/\code{test_function} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertFunction}/\code{assert_function}
+ throws an error message, 
+ \code{testFunction}/\code{test_function}
+ returns \code{FALSE},
+ and \code{checkFunction} returns a string with the error message.
+ The function \code{expect_function} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a function
+}
+\examples{
+testFunction(mean)
+testFunction(mean, args = "x")
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkInt.Rd b/man/checkInt.Rd
new file mode 100644
index 0000000..d0644d4
--- /dev/null
+++ b/man/checkInt.Rd
@@ -0,0 +1,108 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkInt.R
+\name{checkInt}
+\alias{assertInt}
+\alias{assert_int}
+\alias{checkInt}
+\alias{check_int}
+\alias{expect_int}
+\alias{testInt}
+\alias{test_int}
+\title{Check if an argument is a single integerish value}
+\usage{
+checkInt(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+check_int(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+assertInt(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_int(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testInt(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+test_int(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE)
+
+expect_int(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  tol = sqrt(.Machine$double.eps), null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{tol}{[\code{double(1)}]\cr
+Numerical tolerance used to check whether a double or complex can be converted.
+Default is \code{sqrt(.Machine$double.eps)}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertInt}/\code{assert_int} return 
+ \code{x} invisibly, whereas
+ \code{checkInt}/\code{check_int} and 
+ \code{testInt}/\code{test_int} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertInt}/\code{assert_int}
+ throws an error message, 
+ \code{testInt}/\code{test_int}
+ returns \code{FALSE},
+ and \code{checkInt} returns a string with the error message.
+ The function \code{expect_int} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a single integerish value
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testInt(1)
+testInt(-1, lower = 0)
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkFlag}}, \code{\link{checkNumber}},
+  \code{\link{checkScalarNA}}, \code{\link{checkScalar}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkInteger.Rd b/man/checkInteger.Rd
new file mode 100644
index 0000000..2ae720d
--- /dev/null
+++ b/man/checkInteger.Rd
@@ -0,0 +1,139 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkInteger.R
+\name{checkInteger}
+\alias{assertInteger}
+\alias{assert_integer}
+\alias{checkInteger}
+\alias{check_integer}
+\alias{expect_integer}
+\alias{testInteger}
+\alias{test_integer}
+\title{Check if an argument is vector of type integer}
+\usage{
+checkInteger(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+check_integer(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+assertInteger(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_integer(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testInteger(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+test_integer(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+expect_integer(x, lower = -Inf, upper = Inf, any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertInteger}/\code{assert_integer} return 
+ \code{x} invisibly, whereas
+ \code{checkInteger}/\code{check_integer} and 
+ \code{testInteger}/\code{test_integer} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertInteger}/\code{assert_integer}
+ throws an error message, 
+ \code{testInteger}/\code{test_integer}
+ returns \code{FALSE},
+ and \code{checkInteger} returns a string with the error message.
+ The function \code{expect_integer} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is vector of type integer
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testInteger(1L)
+testInteger(1.)
+testInteger(1:2, lower = 1, upper = 2, any.missing = FALSE)
+}
+\seealso{
+\code{\link{asInteger}}
+
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkIntegerish.Rd b/man/checkIntegerish.Rd
new file mode 100644
index 0000000..358e34d
--- /dev/null
+++ b/man/checkIntegerish.Rd
@@ -0,0 +1,147 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkIntegerish.R
+\name{checkIntegerish}
+\alias{assertIntegerish}
+\alias{assert_integerish}
+\alias{checkIntegerish}
+\alias{check_integerish}
+\alias{expect_integerish}
+\alias{testIntegerish}
+\alias{test_integerish}
+\title{Check if an object is an integerish vector}
+\usage{
+checkIntegerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+check_integerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+assertIntegerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_integerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testIntegerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+test_integerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+expect_integerish(x, tol = sqrt(.Machine$double.eps), lower = -Inf,
+  upper = Inf, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{tol}{[\code{double(1)}]\cr
+Numerical tolerance used to check whether a double or complex can be converted.
+Default is \code{sqrt(.Machine$double.eps)}.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertIntegerish}/\code{assert_integerish} return 
+ \code{x} invisibly, whereas
+ \code{checkIntegerish}/\code{check_integerish} and 
+ \code{testIntegerish}/\code{test_integerish} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertIntegerish}/\code{assert_integerish}
+ throws an error message, 
+ \code{testIntegerish}/\code{test_integerish}
+ returns \code{FALSE},
+ and \code{checkIntegerish} returns a string with the error message.
+ The function \code{expect_integerish} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+An integerish value is defined as value safely convertible to integer.
+This includes integers and numeric values which are close to an integer
+w.r.t. a numeric tolerance.
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testIntegerish(1L)
+testIntegerish(1.)
+testIntegerish(1:2, lower = 1L, upper = 2L, any.missing = FALSE)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}},
+  \code{\link{checkVector}}
+}
+
diff --git a/man/checkList.Rd b/man/checkList.Rd
new file mode 100644
index 0000000..192e331
--- /dev/null
+++ b/man/checkList.Rd
@@ -0,0 +1,138 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkList.R
+\name{checkList}
+\alias{assertList}
+\alias{assert_list}
+\alias{checkList}
+\alias{check_list}
+\alias{expect_list}
+\alias{testList}
+\alias{test_list}
+\title{Check if an argument is a list}
+\usage{
+checkList(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+check_list(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+assertList(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_list(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testList(x, types = character(0L), any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+test_list(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE)
+
+expect_list(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, len = NULL, min.len = NULL, max.len = NULL,
+  unique = FALSE, names = NULL, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{types}{[\code{character}]\cr
+Character vector of class names. Each list element must inherit
+from at least one of the provided types.
+The types \dQuote{logical}, \dQuote{integer}, \dQuote{integerish}, \dQuote{double},
+\dQuote{numeric}, \dQuote{complex}, \dQuote{character}, \dQuote{factor}, \dQuote{atomic}, \dQuote{vector}
+\dQuote{atomicvector}, \dQuote{array}, \dQuote{matrix}, \dQuote{list}, \dQuote{function},
+\dQuote{environment} and \dQuote{null} are supported.
+For other types \code{\link[base]{inherits}} is used as a fallback to check \code{x}'s inheritance.
+Defaults to \code{character(0)} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{...}{[any]\cr
+Additional parameters used in a call of \code{\link{checkVector}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertList}/\code{assert_list} return 
+ \code{x} invisibly, whereas
+ \code{checkList}/\code{check_list} and 
+ \code{testList}/\code{test_list} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertList}/\code{assert_list}
+ throws an error message, 
+ \code{testList}/\code{test_list}
+ returns \code{FALSE},
+ and \code{checkList} returns a string with the error message.
+ The function \code{expect_list} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a list
+}
+\examples{
+testList(list())
+testList(as.list(iris), types = c("numeric", "factor"))
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkLogical}},
+  \code{\link{checkMatrix}}, \code{\link{checkNull}},
+  \code{\link{checkNumeric}}, \code{\link{checkVector}}
+}
+
diff --git a/man/checkLogical.Rd b/man/checkLogical.Rd
new file mode 100644
index 0000000..546fef0
--- /dev/null
+++ b/man/checkLogical.Rd
@@ -0,0 +1,127 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkLogical.R
+\name{checkLogical}
+\alias{assertLogical}
+\alias{assert_logical}
+\alias{checkLogical}
+\alias{check_logical}
+\alias{expect_logical}
+\alias{testLogical}
+\alias{test_logical}
+\title{Check if an argument is a vector of type logical}
+\usage{
+checkLogical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+check_logical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+assertLogical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_logical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testLogical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+test_logical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE)
+
+expect_logical(x, any.missing = TRUE, all.missing = TRUE, len = NULL,
+  min.len = NULL, max.len = NULL, unique = FALSE, names = NULL,
+  null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertLogical}/\code{assert_logical} return 
+ \code{x} invisibly, whereas
+ \code{checkLogical}/\code{check_logical} and 
+ \code{testLogical}/\code{test_logical} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertLogical}/\code{assert_logical}
+ throws an error message, 
+ \code{testLogical}/\code{test_logical}
+ returns \code{FALSE},
+ and \code{checkLogical} returns a string with the error message.
+ The function \code{expect_logical} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a vector of type logical
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testLogical(TRUE)
+testLogical(TRUE, min.len = 1)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkMatrix}}, \code{\link{checkNull}},
+  \code{\link{checkNumeric}}, \code{\link{checkVector}}
+}
+
diff --git a/man/checkMatrix.Rd b/man/checkMatrix.Rd
new file mode 100644
index 0000000..df212b8
--- /dev/null
+++ b/man/checkMatrix.Rd
@@ -0,0 +1,141 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkMatrix.R
+\name{checkMatrix}
+\alias{assertMatrix}
+\alias{assert_matrix}
+\alias{checkMatrix}
+\alias{check_matrix}
+\alias{expect_matrix}
+\alias{testMatrix}
+\alias{test_matrix}
+\title{Check if an argument is a matrix}
+\usage{
+checkMatrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+check_matrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+assertMatrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_matrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testMatrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+test_matrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+expect_matrix(x, mode = NULL, any.missing = TRUE, all.missing = TRUE,
+  min.rows = NULL, min.cols = NULL, nrows = NULL, ncols = NULL,
+  row.names = NULL, col.names = NULL, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{mode}{[\code{character(1)}]\cr
+Storage mode of the array. Arrays can hold vectors, i.e. \dQuote{logical},
+\dQuote{integer}, \dQuote{integerish}, \dQuote{double}, \dQuote{numeric}, \dQuote{complex},
+\dQuote{character} and \dQuote{list}. You can also specify \dQuote{atomic}
+here to explicitly prohibit lists. Default is \code{NULL} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are matrices with only missing values allowed? Default is \code{TRUE}.}
+
+\item{min.rows}{[\code{integer(1)}]\cr
+Minimum number of rows.}
+
+\item{min.cols}{[\code{integer(1)}]\cr
+Minimum number of columns.}
+
+\item{nrows}{[\code{integer(1)}]\cr
+Exact number of rows.}
+
+\item{ncols}{[\code{integer(1)}]\cr
+Exact number of columns.}
+
+\item{row.names}{[\code{character(1)}]\cr
+Check for row names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{col.names}{[\code{character(1)}]\cr
+Check for column names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to test for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertMatrix}/\code{assert_matrix} return 
+ \code{x} invisibly, whereas
+ \code{checkMatrix}/\code{check_matrix} and 
+ \code{testMatrix}/\code{test_matrix} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertMatrix}/\code{assert_matrix}
+ throws an error message, 
+ \code{testMatrix}/\code{test_matrix}
+ returns \code{FALSE},
+ and \code{checkMatrix} returns a string with the error message.
+ The function \code{expect_matrix} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a matrix
+}
+\examples{
+x = matrix(1:9, 3)
+colnames(x) = letters[1:3]
+testMatrix(x, nrows = 3, min.cols = 1, col.names = "named")
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkNull}},
+  \code{\link{checkNumeric}}, \code{\link{checkVector}}
+
+Other compound: \code{\link{checkArray}},
+  \code{\link{checkDataFrame}},
+  \code{\link{checkDataTable}}, \code{\link{checkTibble}}
+}
+
diff --git a/man/checkNamed.Rd b/man/checkNamed.Rd
new file mode 100644
index 0000000..905c1dd
--- /dev/null
+++ b/man/checkNamed.Rd
@@ -0,0 +1,77 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkNamed.R
+\name{checkNamed}
+\alias{assertNamed}
+\alias{assert_named}
+\alias{checkNamed}
+\alias{check_named}
+\alias{testNamed}
+\alias{test_named}
+\title{Check if an argument is named}
+\usage{
+checkNamed(x, type = "named")
+
+check_named(x, type = "named")
+
+assertNamed(x, type = "named", .var.name = vname(x), add = NULL)
+
+assert_named(x, type = "named", .var.name = vname(x), add = NULL)
+
+testNamed(x, type = "named")
+
+test_named(x, type = "named")
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{type}{[character(1)]\cr
+Select the check(s) to perform.
+\dQuote{unnamed} checks \code{x} to be unnamed.
+\dQuote{named} (default) checks \code{x} to be named which excludes names to be \code{NA} or empty (\code{""}).
+\dQuote{unique} additionally tests for non-duplicated names.
+\dQuote{strict} checks for unique names which comply to R's variable name restrictions.
+Note that for zero-length \code{x} every name check evaluates to \code{TRUE}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertNamed}/\code{assert_named} return 
+ \code{x} invisibly, whereas
+ \code{checkNamed}/\code{check_named} and 
+ \code{testNamed}/\code{test_named} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertNamed}/\code{assert_named}
+ throws an error message, 
+ \code{testNamed}/\code{test_named}
+ returns \code{FALSE},
+ and \code{checkNamed} returns a string with the error message.
+ The function \code{expect_named} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is named
+}
+\note{
+These function are deprecated and will be removed in a future version.
+Please use \code{\link{checkNames}} instead.
+}
+\examples{
+x = 1:3
+testNamed(x, "unnamed")
+names(x) = letters[1:3]
+testNamed(x, "unique")
+}
+\seealso{
+Other attributes: \code{\link{checkClass}},
+  \code{\link{checkNames}}
+}
+
diff --git a/man/checkNames.Rd b/man/checkNames.Rd
new file mode 100644
index 0000000..80051ea
--- /dev/null
+++ b/man/checkNames.Rd
@@ -0,0 +1,108 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkNames.R
+\name{checkNames}
+\alias{assertNames}
+\alias{assert_names}
+\alias{checkNames}
+\alias{check_names}
+\alias{expect_names}
+\alias{testNames}
+\alias{test_names}
+\title{Check names to comply to specific rules}
+\usage{
+checkNames(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL)
+
+check_names(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL)
+
+assertNames(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL, .var.name = vname(x), add = NULL)
+
+assert_names(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL, .var.name = vname(x), add = NULL)
+
+testNames(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL)
+
+test_names(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL)
+
+expect_names(x, type = "named", permutation.of = NULL, subset.of = NULL,
+  identical.to = NULL, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[\code{character} || \code{NULL}]\cr
+Names to check using rules defined via \code{type}.}
+
+\item{type}{[character(1)]\cr
+Type of formal check(s) to perform on the names.
+\dQuote{unnamed} checks \code{x} to be \code{NULL}.
+\dQuote{named} (default) checks \code{x} for regular names which excludes names to be \code{NA} or empty (\code{""}).
+\dQuote{unique} additionally tests for non-duplicated names.
+\dQuote{strict} checks for unique names which comply to R's variable name restrictions.
+Note that for zero-length \code{x} all these name checks evaluate to \code{TRUE}.}
+
+\item{permutation.of}{[\code{character}]\cr
+Names provided in \code{x} must be a permutation of the set \code{permutation.of}.
+Duplicated names in \code{permutation.of} are stripped out and duplicated names in \code{x}
+thus lead to a failed check.
+Use this argument instead of \code{identical.to} if the order of the names is not relevant.}
+
+\item{subset.of}{[\code{character}]\cr
+Names provided in \code{x} must be subset of the set \code{subset.of}.
+Use this argument if duplicated names are okay.}
+
+\item{identical.to}{[\code{character}]\cr
+Names provided in \code{x} must be identical to the vector \code{identical.to}.
+Use this argument instead of \code{permutation.of} if the order of the names is relevant.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertNamed}/\code{assert_named} return 
+ \code{x} invisibly, whereas
+ \code{checkNamed}/\code{check_named} and 
+ \code{testNamed}/\code{test_named} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertNamed}/\code{assert_named}
+ throws an error message, 
+ \code{testNamed}/\code{test_named}
+ returns \code{FALSE},
+ and \code{checkNamed} returns a string with the error message.
+ The function \code{expect_named} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Similar to \code{\link{checkNamed}} but you can pass the names directly.
+}
+\examples{
+x = 1:3
+testNames(x, "unnamed")
+names(x) = letters[1:3]
+testNames(x, "unique")
+
+cn = c("Species", "Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
+assertNames(names(iris), permutation.of = cn)
+}
+\seealso{
+Other attributes: \code{\link{checkClass}},
+  \code{\link{checkNamed}}
+}
+
diff --git a/man/checkNull.Rd b/man/checkNull.Rd
new file mode 100644
index 0000000..21560cb
--- /dev/null
+++ b/man/checkNull.Rd
@@ -0,0 +1,70 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkNull.R
+\name{checkNull}
+\alias{assertNull}
+\alias{assert_null}
+\alias{checkNull}
+\alias{check_null}
+\alias{testNull}
+\alias{test_null}
+\title{Check if an argument is NULL}
+\usage{
+checkNull(x)
+
+check_null(x)
+
+assertNull(x, .var.name = vname(x), add = NULL)
+
+assert_null(x, .var.name = vname(x), add = NULL)
+
+testNull(x)
+
+test_null(x)
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertNull}/\code{assert_null} return 
+ \code{x} invisibly, whereas
+ \code{checkNull}/\code{check_null} and 
+ \code{testNull}/\code{test_null} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertNull}/\code{assert_null}
+ throws an error message, 
+ \code{testNull}/\code{test_null}
+ returns \code{FALSE},
+ and \code{checkNull} returns a string with the error message.
+ The function \code{expect_null} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is NULL
+}
+\examples{
+testNull(NULL)
+testNull(1)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNumeric}}, \code{\link{checkVector}}
+}
+
diff --git a/man/checkNumber.Rd b/man/checkNumber.Rd
new file mode 100644
index 0000000..38e944c
--- /dev/null
+++ b/man/checkNumber.Rd
@@ -0,0 +1,104 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkNumber.R
+\name{checkNumber}
+\alias{assertNumber}
+\alias{assert_number}
+\alias{checkNumber}
+\alias{check_number}
+\alias{expect_number}
+\alias{testNumber}
+\alias{test_number}
+\title{Check if an argument is a single numeric value}
+\usage{
+checkNumber(x, na.ok = FALSE, lower = -Inf, upper = Inf, finite = FALSE,
+  null.ok = FALSE)
+
+check_number(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  finite = FALSE, null.ok = FALSE)
+
+assertNumber(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  finite = FALSE, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_number(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  finite = FALSE, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testNumber(x, na.ok = FALSE, lower = -Inf, upper = Inf, finite = FALSE,
+  null.ok = FALSE)
+
+test_number(x, na.ok = FALSE, lower = -Inf, upper = Inf, finite = FALSE,
+  null.ok = FALSE)
+
+expect_number(x, na.ok = FALSE, lower = -Inf, upper = Inf,
+  finite = FALSE, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{finite}{[\code{logical(1)}]\cr
+Check for only finite values? Default is \code{FALSE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertNumber}/\code{assert_number} return 
+ \code{x} invisibly, whereas
+ \code{checkNumber}/\code{check_number} and 
+ \code{testNumber}/\code{test_number} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertNumber}/\code{assert_number}
+ throws an error message, 
+ \code{testNumber}/\code{test_number}
+ returns \code{FALSE},
+ and \code{checkNumber} returns a string with the error message.
+ The function \code{expect_number} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a single numeric value
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testNumber(1)
+testNumber(1:2)
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkFlag}}, \code{\link{checkInt}},
+  \code{\link{checkScalarNA}}, \code{\link{checkScalar}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkNumeric.Rd b/man/checkNumeric.Rd
new file mode 100644
index 0000000..14e22b4
--- /dev/null
+++ b/man/checkNumeric.Rd
@@ -0,0 +1,139 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkNumeric.R
+\name{checkNumeric}
+\alias{assertNumeric}
+\alias{assert_numeric}
+\alias{checkNumeric}
+\alias{check_numeric}
+\alias{expect_numeric}
+\alias{testNumeric}
+\alias{test_numeric}
+\title{Check that an argument is a vector of type numeric}
+\usage{
+checkNumeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE)
+
+check_numeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE)
+
+assertNumeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_numeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testNumeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE)
+
+test_numeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE)
+
+expect_numeric(x, lower = -Inf, upper = Inf, finite = FALSE,
+  any.missing = TRUE, all.missing = TRUE, len = NULL, min.len = NULL,
+  max.len = NULL, unique = FALSE, names = NULL, null.ok = FALSE,
+  info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{lower}{[\code{numeric(1)}]\cr
+Lower value all elements of \code{x} must be greater than.}
+
+\item{upper}{[\code{numeric(1)}]\cr
+Upper value all elements of \code{x} must be lower than.}
+
+\item{finite}{[\code{logical(1)}]\cr
+Check for only finite values? Default is \code{FALSE}.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertNumeric}/\code{assert_numeric} return 
+ \code{x} invisibly, whereas
+ \code{checkNumeric}/\code{check_numeric} and 
+ \code{testNumeric}/\code{test_numeric} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertNumeric}/\code{assert_numeric}
+ throws an error message, 
+ \code{testNumeric}/\code{test_numeric}
+ returns \code{FALSE},
+ and \code{checkNumeric} returns a string with the error message.
+ The function \code{expect_numeric} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check that an argument is a vector of type numeric
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testNumeric(1)
+testNumeric(1, min.len = 1, lower = 0)
+}
+\seealso{
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkVector}}
+}
+
diff --git a/man/checkOS.Rd b/man/checkOS.Rd
new file mode 100644
index 0000000..858264b
--- /dev/null
+++ b/man/checkOS.Rd
@@ -0,0 +1,70 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkOS.R
+\name{checkOS}
+\alias{assertOS}
+\alias{assert_os}
+\alias{checkOS}
+\alias{check_os}
+\alias{expect_os}
+\alias{testOS}
+\alias{test_os}
+\title{Check the operating system}
+\usage{
+checkOS(os)
+
+check_os(os)
+
+assertOS(os, add = NULL, .var.name = NULL)
+
+assert_os(os, add = NULL, .var.name = NULL)
+
+testOS(os)
+
+test_os(os)
+
+expect_os(os, info = NULL, label = NULL)
+}
+\arguments{
+\item{os}{[\code{character(1)}]\cr
+Check the operating system to be in a set with possible elements \dQuote{windows},
+\dQuote{mac}, \dQuote{linux} and \dQuote{solaris}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertOS}/\code{assert_os} return 
+ \code{x} invisibly, whereas
+ \code{checkOS}/\code{check_os} and 
+ \code{testOS}/\code{test_os} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertOS}/\code{assert_os}
+ throws an error message, 
+ \code{testOS}/\code{test_os}
+ returns \code{FALSE},
+ and \code{checkOS} returns a string with the error message.
+ The function \code{expect_os} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check the operating system
+}
+\examples{
+testOS("linux")
+}
+
diff --git a/man/checkPathForOutput.Rd b/man/checkPathForOutput.Rd
new file mode 100644
index 0000000..ae4367d
--- /dev/null
+++ b/man/checkPathForOutput.Rd
@@ -0,0 +1,91 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkPathForOutput.R
+\name{checkPathForOutput}
+\alias{assertPathForOutput}
+\alias{assert_path_for_output}
+\alias{checkPathForOutput}
+\alias{check_path_for_output}
+\alias{expect_path_for_output}
+\alias{testPathForOutput}
+\alias{test_path_for_output}
+\title{Check if a path is suited for creating an output file}
+\usage{
+checkPathForOutput(x, overwrite = FALSE)
+
+check_path_for_output(x, overwrite = FALSE)
+
+assertPathForOutput(x, overwrite = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_path_for_output(x, overwrite = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testPathForOutput(x, overwrite = FALSE)
+
+test_path_for_output(x, overwrite = FALSE)
+
+expect_path_for_output(x, overwrite = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{overwrite}{[\code{logical(1)}]\cr
+If \code{TRUE}, an existing file in place is allowed if it
+it is both readable and writeable.
+Default is \code{FALSE}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertPathForOutput}/\code{assert_path_for_output} return 
+ \code{x} invisibly, whereas
+ \code{checkPathForOutput}/\code{check_path_for_output} and 
+ \code{testPathForOutput}/\code{test_path_for_output} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertPathForOutput}/\code{assert_path_for_output}
+ throws an error message, 
+ \code{testPathForOutput}/\code{test_path_for_output}
+ returns \code{FALSE},
+ and \code{checkPathForOutput} returns a string with the error message.
+ The function \code{expect_path_for_output} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if a file path can be safely be used to create a file and write to it.
+
+This is checked:
+\itemize{
+ \item{Does \code{dirname(x)} exist?}
+ \item{Does no file under path \code{x} exist?}
+ \item{Is \code{dirname(x)} writeable?}
+}
+Paths are relative to the current working directory.
+}
+\examples{
+# Can we create a file in the tempdir?
+testPathForOutput(file.path(tempdir(), "process.log"))
+}
+\seealso{
+Other filesystem: \code{\link{checkAccess}},
+  \code{\link{checkDirectoryExists}},
+  \code{\link{checkFileExists}}
+}
+
diff --git a/man/checkScalar.Rd b/man/checkScalar.Rd
new file mode 100644
index 0000000..1a465ec
--- /dev/null
+++ b/man/checkScalar.Rd
@@ -0,0 +1,91 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkScalar.R
+\name{checkScalar}
+\alias{assertScalar}
+\alias{assert_scalar}
+\alias{checkScalar}
+\alias{check_scalar}
+\alias{expect_scalar}
+\alias{testScalar}
+\alias{test_scalar}
+\title{Check if an argument is a single atomic value}
+\usage{
+checkScalar(x, na.ok = FALSE, null.ok = FALSE)
+
+check_scalar(x, na.ok = FALSE, null.ok = FALSE)
+
+assertScalar(x, na.ok = FALSE, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+assert_scalar(x, na.ok = FALSE, null.ok = FALSE, .var.name = vname(x),
+  add = NULL)
+
+testScalar(x, na.ok = FALSE, null.ok = FALSE)
+
+test_scalar(x, na.ok = FALSE, null.ok = FALSE)
+
+expect_scalar(x, na.ok = FALSE, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertScalar}/\code{assert_scalar} return 
+ \code{x} invisibly, whereas
+ \code{checkScalar}/\code{check_scalar} and 
+ \code{testScalar}/\code{test_scalar} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertScalar}/\code{assert_scalar}
+ throws an error message, 
+ \code{testScalar}/\code{test_scalar}
+ returns \code{FALSE},
+ and \code{checkScalar} returns a string with the error message.
+ The function \code{expect_scalar} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a single atomic value
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testScalar(1)
+testScalar(1:10)
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkFlag}}, \code{\link{checkInt}},
+  \code{\link{checkNumber}}, \code{\link{checkScalarNA}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkScalarNA.Rd b/man/checkScalarNA.Rd
new file mode 100644
index 0000000..3863094
--- /dev/null
+++ b/man/checkScalarNA.Rd
@@ -0,0 +1,81 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkScalarNA.R
+\name{checkScalarNA}
+\alias{assertScalarNA}
+\alias{assert_scalar_na}
+\alias{checkScalarNA}
+\alias{check_scalar_na}
+\alias{expect_scalar_na}
+\alias{testScalarNA}
+\alias{test_scalar_na}
+\title{Check if an argument is a single missing value}
+\usage{
+checkScalarNA(x, null.ok = FALSE)
+
+check_scalar_na(x, null.ok = FALSE)
+
+assertScalarNA(x, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_scalar_na(x, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testScalarNA(x, null.ok = FALSE)
+
+test_scalar_na(x, null.ok = FALSE)
+
+expect_scalar_na(x, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertScalarNA}/\code{assert_scalar_na} return 
+ \code{x} invisibly, whereas
+ \code{checkScalarNA}/\code{check_scalar_na} and 
+ \code{testScalarNA}/\code{test_scalar_na} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertScalarNA}/\code{assert_scalar_na}
+ throws an error message, 
+ \code{testScalarNA}/\code{test_scalar_na}
+ returns \code{FALSE},
+ and \code{checkScalarNA} returns a string with the error message.
+ The function \code{expect_scalar_na} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a single missing value
+}
+\examples{
+testScalarNA(1)
+testScalarNA(NA_real_)
+testScalarNA(rep(NA, 2))
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkFlag}}, \code{\link{checkInt}},
+  \code{\link{checkNumber}}, \code{\link{checkScalar}},
+  \code{\link{checkString}}
+}
+
diff --git a/man/checkSetEqual.Rd b/man/checkSetEqual.Rd
new file mode 100644
index 0000000..5d7d390
--- /dev/null
+++ b/man/checkSetEqual.Rd
@@ -0,0 +1,92 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkSetEqual.R
+\name{checkSetEqual}
+\alias{assertSetEqual}
+\alias{assert_set_equal}
+\alias{checkSetEqual}
+\alias{check_set_equal}
+\alias{expect_set_equal}
+\alias{testSetEqual}
+\alias{test_set_equal}
+\title{Check if an argument is equal to a given set}
+\usage{
+checkSetEqual(x, y, ordered = FALSE)
+
+check_set_equal(x, y, ordered = FALSE)
+
+assertSetEqual(x, y, ordered = FALSE, .var.name = vname(x), add = NULL)
+
+assert_set_equal(x, y, ordered = FALSE, .var.name = vname(x), add = NULL)
+
+testSetEqual(x, y, ordered = FALSE)
+
+test_set_equal(x, y, ordered = FALSE)
+
+expect_set_equal(x, y, ordered = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{y}{[\code{atomic}]\cr
+Set to compare with.}
+
+\item{ordered}{[\code{logical(1)}]\cr
+Check \code{x} to have the same length and order as \code{y}, i.e.
+check using \dQuote{==} while handling \code{NA}s nicely.
+Default is \code{FALSE}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertSubset}/\code{assert_subset} return 
+ \code{x} invisibly, whereas
+ \code{checkSubset}/\code{check_subset} and 
+ \code{testSubset}/\code{test_subset} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertSubset}/\code{assert_subset}
+ throws an error message, 
+ \code{testSubset}/\code{test_subset}
+ returns \code{FALSE},
+ and \code{checkSubset} returns a string with the error message.
+ The function \code{expect_subset} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is equal to a given set
+}
+\note{
+The object \code{x} must be of the same type as the set w.r.t. \code{\link[base]{typeof}}.
+Integers and doubles are both treated as numeric.
+}
+\examples{
+testSetEqual(c("a", "b"), c("a", "b"))
+testSetEqual(1:3, 1:4)
+
+# x is converted before the comparison if necessary
+# note that this is subject to change in a future version
+testSetEqual(factor("a"), "a")
+testSetEqual(1, "1")
+testSetEqual(1, as.integer(1))
+}
+\seealso{
+Other set: \code{\link{checkChoice}},
+  \code{\link{checkSubset}}
+}
+
diff --git a/man/checkString.Rd b/man/checkString.Rd
new file mode 100644
index 0000000..eae0dcd
--- /dev/null
+++ b/man/checkString.Rd
@@ -0,0 +1,113 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkString.R
+\name{checkString}
+\alias{assertString}
+\alias{assert_string}
+\alias{checkString}
+\alias{check_string}
+\alias{expect_string}
+\alias{testString}
+\alias{test_string}
+\title{Check if an argument is a string}
+\usage{
+checkString(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE)
+
+check_string(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE)
+
+assertString(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_string(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testString(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE)
+
+test_string(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE)
+
+expect_string(x, na.ok = FALSE, min.chars = NULL, pattern = NULL,
+  fixed = NULL, ignore.case = FALSE, null.ok = FALSE, info = NULL,
+  label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{na.ok}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{FALSE}.}
+
+\item{min.chars}{[\code{integer(1)}]\cr
+Minimum number of characters in each element of \code{x}.}
+
+\item{pattern}{[\code{character(1L)}]\cr
+Regular expression as used in \code{\link[base]{grepl}}.
+All elements of \code{x} must comply to this pattern.}
+
+\item{fixed}{[\code{character(1)}]\cr
+Substring to detect in \code{x}. Will be used as \code{pattern} in \code{\link[base]{grepl}}
+with option \code{fixed} set to \code{TRUE}.
+All elements of \code{x} must contain this substring.}
+
+\item{ignore.case}{[\code{logical(1)}]\cr
+See \code{\link[base]{grepl}}. Default is \code{FALSE}.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertString}/\code{assert_string} return 
+ \code{x} invisibly, whereas
+ \code{checkString}/\code{check_string} and 
+ \code{testString}/\code{test_string} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertString}/\code{assert_string}
+ throws an error message, 
+ \code{testString}/\code{test_string}
+ returns \code{FALSE},
+ and \code{checkString} returns a string with the error message.
+ The function \code{expect_string} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+A string is defined as a scalar character vector.
+}
+\details{
+This function does not distinguish between
+\code{NA}, \code{NA_integer_}, \code{NA_real_}, \code{NA_complex_}
+\code{NA_character_} and \code{NaN}.
+}
+\examples{
+testString("a")
+testString(letters)
+}
+\seealso{
+Other scalars: \code{\link{checkCount}},
+  \code{\link{checkFlag}}, \code{\link{checkInt}},
+  \code{\link{checkNumber}}, \code{\link{checkScalarNA}},
+  \code{\link{checkScalar}}
+}
+
diff --git a/man/checkSubset.Rd b/man/checkSubset.Rd
new file mode 100644
index 0000000..782437c
--- /dev/null
+++ b/man/checkSubset.Rd
@@ -0,0 +1,94 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkSubset.R
+\name{checkSubset}
+\alias{assertSubset}
+\alias{assert_subset}
+\alias{checkSubset}
+\alias{check_subset}
+\alias{expect_subset}
+\alias{testSubset}
+\alias{test_subset}
+\title{Check if an argument is a subset of a given set}
+\usage{
+checkSubset(x, choices, empty.ok = TRUE)
+
+check_subset(x, choices, empty.ok = TRUE)
+
+assertSubset(x, choices, empty.ok = TRUE, .var.name = vname(x),
+  add = NULL)
+
+assert_subset(x, choices, empty.ok = TRUE, .var.name = vname(x),
+  add = NULL)
+
+testSubset(x, choices, empty.ok = TRUE)
+
+test_subset(x, choices, empty.ok = TRUE)
+
+expect_subset(x, choices, empty.ok = TRUE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{choices}{[\code{atomic}]\cr
+Set of possible values.}
+
+\item{empty.ok}{[\code{logical(1)}]\cr
+Treat zero-length \code{x} as subset of any set \code{choices}?
+Default is \code{TRUE}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertSubset}/\code{assert_subset} return 
+ \code{x} invisibly, whereas
+ \code{checkSubset}/\code{check_subset} and 
+ \code{testSubset}/\code{test_subset} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertSubset}/\code{assert_subset}
+ throws an error message, 
+ \code{testSubset}/\code{test_subset}
+ returns \code{FALSE},
+ and \code{checkSubset} returns a string with the error message.
+ The function \code{expect_subset} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a subset of a given set
+}
+\note{
+The object \code{x} must be of the same type as the set w.r.t. \code{\link[base]{typeof}}.
+Integers and doubles are both treated as numeric.
+}
+\examples{
+testSubset(c("a", "z"), letters)
+testSubset("ab", letters)
+testSubset("Species", names(iris))
+
+# x is converted before the comparison if necessary
+# note that this is subject to change in a future version
+testSubset(factor("a"), "a")
+testSubset(1, "1")
+testSubset(1, as.integer(1))
+}
+\seealso{
+Other set: \code{\link{checkChoice}},
+  \code{\link{checkSetEqual}}
+}
+
diff --git a/man/checkTibble.Rd b/man/checkTibble.Rd
new file mode 100644
index 0000000..e4384e2
--- /dev/null
+++ b/man/checkTibble.Rd
@@ -0,0 +1,136 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkTibble.R
+\name{checkTibble}
+\alias{assertTibble}
+\alias{assert_tibble}
+\alias{checkTibble}
+\alias{check_tibble}
+\alias{expect_tibble}
+\alias{testTibble}
+\alias{test_tibble}
+\title{Check if an argument is a tibble}
+\usage{
+checkTibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+check_tibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+assertTibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+assert_tibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  .var.name = vname(x), add = NULL)
+
+testTibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+test_tibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE)
+
+expect_tibble(x, types = character(0L), any.missing = TRUE,
+  all.missing = TRUE, min.rows = NULL, min.cols = NULL, nrows = NULL,
+  ncols = NULL, row.names = NULL, col.names = NULL, null.ok = FALSE,
+  info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{types}{[\code{character}]\cr
+Character vector of class names. Each list element must inherit
+from at least one of the provided types.
+The types \dQuote{logical}, \dQuote{integer}, \dQuote{integerish}, \dQuote{double},
+\dQuote{numeric}, \dQuote{complex}, \dQuote{character}, \dQuote{factor}, \dQuote{atomic}, \dQuote{vector}
+\dQuote{atomicvector}, \dQuote{array}, \dQuote{matrix}, \dQuote{list}, \dQuote{function},
+\dQuote{environment} and \dQuote{null} are supported.
+For other types \code{\link[base]{inherits}} is used as a fallback to check \code{x}'s inheritance.
+Defaults to \code{character(0)} (no check).}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are matrices with only missing values allowed? Default is \code{TRUE}.}
+
+\item{min.rows}{[\code{integer(1)}]\cr
+Minimum number of rows.}
+
+\item{min.cols}{[\code{integer(1)}]\cr
+Minimum number of columns.}
+
+\item{nrows}{[\code{integer(1)}]\cr
+Exact number of rows.}
+
+\item{ncols}{[\code{integer(1)}]\cr
+Exact number of columns.}
+
+\item{row.names}{[\code{character(1)}]\cr
+Check for row names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{col.names}{[\code{character(1)}]\cr
+Check for column names. Default is \dQuote{NULL} (no check).
+See \code{\link{checkNamed}} for possible values.
+Note that you can use \code{\link{checkSubset}} to test for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertTibble}/\code{assert_tibble} return 
+ \code{x} invisibly, whereas
+ \code{checkTibble}/\code{check_tibble} and 
+ \code{testTibble}/\code{test_tibble} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertTibble}/\code{assert_tibble}
+ throws an error message, 
+ \code{testTibble}/\code{test_tibble}
+ returns \code{FALSE},
+ and \code{checkTibble} returns a string with the error message.
+ The function \code{expect_tibble} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a tibble
+}
+\examples{
+library(tibble)
+x = as_tibble(iris)
+testTibble(x)
+testTibble(x, nrow = 150, any.missing = FALSE)
+}
+\seealso{
+Other compound: \code{\link{checkArray}},
+  \code{\link{checkDataFrame}},
+  \code{\link{checkDataTable}}, \code{\link{checkMatrix}}
+}
+
diff --git a/man/checkVector.Rd b/man/checkVector.Rd
new file mode 100644
index 0000000..52c96de
--- /dev/null
+++ b/man/checkVector.Rd
@@ -0,0 +1,130 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/checkVector.R
+\name{checkVector}
+\alias{assertVector}
+\alias{assert_vector}
+\alias{checkVector}
+\alias{check_vector}
+\alias{expect_vector}
+\alias{testVector}
+\alias{test_vector}
+\title{Check if an argument is a vector}
+\usage{
+checkVector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+check_vector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+assertVector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+assert_vector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, .var.name = vname(x), add = NULL)
+
+testVector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+test_vector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE)
+
+expect_vector(x, strict = FALSE, any.missing = TRUE, all.missing = TRUE,
+  len = NULL, min.len = NULL, max.len = NULL, unique = FALSE,
+  names = NULL, null.ok = FALSE, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{strict}{[\code{logical(1)}]\cr
+May the vector have additional attributes or perform a
+check for additional attributes like \code{\link[base]{is.vector}}?
+Default is \code{FALSE} which allows e.g. \code{factor}s or \code{data.frame}s
+to be recognized as vectors.}
+
+\item{any.missing}{[\code{logical(1)}]\cr
+Are vectors with missing values allowed? Default is \code{TRUE}.}
+
+\item{all.missing}{[\code{logical(1)}]\cr
+Are vectors with only missing values allowed? Default is \code{TRUE}.}
+
+\item{len}{[\code{integer(1)}]\cr
+Exact expected length of \code{x}.}
+
+\item{min.len}{[\code{integer(1)}]\cr
+Minimal length of \code{x}.}
+
+\item{max.len}{[\code{integer(1)}]\cr
+Maximal length of \code{x}.}
+
+\item{unique}{[\code{logical(1)}]\cr
+Must all values be unique? Default is \code{FALSE}.}
+
+\item{names}{[\code{character(1)}]\cr
+Check for names. See \code{\link{checkNamed}} for possible values.
+Default is \dQuote{any} which performs no check at all.
+Note that you can use \code{\link{checkSubset}} to check for a specific set of names.}
+
+\item{null.ok}{[\code{logical(1)}]\cr
+If set to \code{TRUE}, \code{x} may also be \code{NULL}.
+In this case only a type check of \code{x} is performed, all additional checks are disabled.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in assertions. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertion messages. See \code{\link{AssertCollection}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+Depending on the function prefix:
+ If the check is successful, the functions 
+ \code{assertVector}/\code{assert_vector} return 
+ \code{x} invisibly, whereas
+ \code{checkVector}/\code{check_vector} and 
+ \code{testVector}/\code{test_vector} return 
+ \code{TRUE}.
+ If the check is not successful, 
+ \code{assertVector}/\code{assert_vector}
+ throws an error message, 
+ \code{testVector}/\code{test_vector}
+ returns \code{FALSE},
+ and \code{checkVector} returns a string with the error message.
+ The function \code{expect_vector} always returns an
+ \code{\link[testthat]{expectation}}.
+}
+\description{
+Check if an argument is a vector
+}
+\examples{
+testVector(letters, min.len = 1L, any.missing = FALSE)
+}
+\seealso{
+Other atomicvector: \code{\link{checkAtomicVector}},
+  \code{\link{checkAtomic}}
+
+Other basetypes: \code{\link{checkArray}},
+  \code{\link{checkAtomic}}, \code{\link{checkCharacter}},
+  \code{\link{checkComplex}}, \code{\link{checkDataFrame}},
+  \code{\link{checkDate}}, \code{\link{checkEnvironment}},
+  \code{\link{checkFactor}}, \code{\link{checkFunction}},
+  \code{\link{checkIntegerish}},
+  \code{\link{checkInteger}}, \code{\link{checkList}},
+  \code{\link{checkLogical}}, \code{\link{checkMatrix}},
+  \code{\link{checkNull}}, \code{\link{checkNumeric}}
+}
+
diff --git a/man/checkmate-package.Rd b/man/checkmate-package.Rd
new file mode 100644
index 0000000..633bdb8
--- /dev/null
+++ b/man/checkmate-package.Rd
@@ -0,0 +1,104 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/zzz.R
+\docType{package}
+\name{checkmate-package}
+\alias{checkmate}
+\alias{checkmate-package}
+\title{Fast and Versatile Argument Checks}
+\description{
+\describe{
+  \item{Homepage:}{\url{https://github.com/mllg/checkmate}}
+  \item{Bug Reports:}{\url{https://github.com/mllg/checkmate/issues}}
+}
+}
+\section{Overview of implemented functions}{
+
+
+Check scalars:
+\itemize{
+  \item{\code{\link{checkFlag}}}
+  \item{\code{\link{checkCount}}}
+  \item{\code{\link{checkNumber}}}
+  \item{\code{\link{checkInt}}}
+  \item{\code{\link{checkString}}}
+  \item{\code{\link{checkScalar}}}
+  \item{\code{\link{checkScalarNA}}}
+}
+
+Check vectors:
+\itemize{
+  \item{\code{\link{checkLogical}}}
+  \item{\code{\link{checkNumeric}}}
+  \item{\code{\link{checkInteger}}}
+  \item{\code{\link{checkIntegerish}}}
+  \item{\code{\link{checkComplex}}}
+  \item{\code{\link{checkFactor}}}
+  \item{\code{\link{checkList}}}
+  \item{\code{\link{checkVector}}}
+  \item{\code{\link{checkAtomic}}}
+  \item{\code{\link{checkAtomicVector}}}
+}
+
+Check attributes:
+\itemize{
+  \item{\code{\link{checkClass}}}
+  \item{\code{\link{checkNames}}}
+  \item{\code{\link{checkNamed}}}
+}
+
+Check compound types:
+\itemize{
+  \item{\code{\link{checkMatrix}}}
+  \item{\code{\link{checkArray}}}
+  \item{\code{\link{checkDataFrame}}}
+  \item{\code{\link{checkDataTable}}}
+  \item{\code{\link{checkTibble}}}
+}
+
+Check other built-in R types:
+\itemize{
+  \item{\code{\link{checkNull}}}
+  \item{\code{\link{checkEnvironment}}}
+  \item{\code{\link{checkFunction}}}
+  \item{\code{\link{checkDate}}}
+}
+
+Check sets:
+\itemize{
+  \item{\code{\link{checkChoice}}}
+  \item{\code{\link{checkSubset}}}
+  \item{\code{\link{checkSetEqual}}}
+}
+
+File IO:
+\itemize{
+  \item{\code{\link{checkFileExists}}}
+  \item{\code{\link{checkDirectoryExists}}}
+  \item{\code{\link{checkPathForOutput}}}
+  \item{\code{\link{checkAccess}}}
+}
+
+Safe coercion to integer:
+\itemize{
+  \item{\code{\link{asCount}}}
+  \item{\code{\link{asInt}}}
+  \item{\code{\link{asInteger}}}
+}
+
+Quick argument checks using a DSL:
+\itemize{
+  \item{\code{\link{qassert}}}
+  \item{\code{\link{qassertr}}}
+}
+
+Misc:
+\itemize{
+  \item{\code{\link{checkOS}} (check operating system)}
+  \item{\code{\link{assert}} (combine multiple checks into an assertion)}
+  \item{\code{\link{anyMissing}}}
+  \item{\code{\link{allMissing}}}
+  \item{\code{\link{anyNaN}}}
+  \item{\code{\link{wf}} (which.first and which.last)}
+}
+}
+
diff --git a/man/coalesce.Rd b/man/coalesce.Rd
new file mode 100644
index 0000000..2ed21eb
--- /dev/null
+++ b/man/coalesce.Rd
@@ -0,0 +1,27 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/coalesce.R
+\name{\%??\%}
+\alias{\%??\%}
+\title{Coalesce operator}
+\usage{
+lhs \%??\% rhs
+}
+\arguments{
+\item{lhs}{[any]\cr
+Left hand side of the operator. Is returned if not missing or \code{NULL}.}
+
+\item{rhs}{[any]\cr
+Right hand side of the operator. Is returned if \code{lhs} is missing or \code{NULL}.}
+}
+\value{
+Either \code{lhs} or \code{rhs}.
+}
+\description{
+Returns the left hand side if not missing nor \code{NULL}, and
+the right hand side otherwise.
+}
+\examples{
+print(NULL \%??\% 1 \%??\% 2)
+print(names(iris) \%??\% letters[seq_len(ncol(iris))])
+}
+
diff --git a/man/makeAssertion.Rd b/man/makeAssertion.Rd
new file mode 100644
index 0000000..a22a761
--- /dev/null
+++ b/man/makeAssertion.Rd
@@ -0,0 +1,69 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeAssertion.R
+\name{makeAssertion}
+\alias{makeAssertion}
+\alias{makeAssertionFunction}
+\title{Turn a Check into an Assertion}
+\usage{
+makeAssertion(x, res, var.name, collection)
+
+makeAssertionFunction(check.fun, c.fun = NULL, env = parent.frame())
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{res}{[\code{TRUE} | \code{character(1)}]\cr
+The result of a check function: \code{TRUE} for successful checks,
+and an error message as string otherwise.}
+
+\item{var.name}{[\code{character(1)}]\cr
+The custom name for \code{x} as passed to any \code{assert*} function.
+Defaults to a heuristic name lookup.}
+
+\item{collection}{[\code{\link{AssertCollection}}]\cr
+If an \code{\link{AssertCollection}} is provided, the error message is stored
+in it. If \code{NULL}, an exception is raised if \code{res} is not
+\code{TRUE}.}
+
+\item{check.fun}{[\code{function}]\cr
+Function which checks the input. Must return \code{TRUE} on success and a string with the error message otherwise.}
+
+\item{c.fun}{[\code{character(1)}]\cr
+If not \code{NULL}, instead of calling the function \code{check.fun}, use \code{.Call} to call a C function \dQuote{c.fun} with the identical
+set of parameters. The C function must be registered as a native symbol, see \code{\link[base]{.Call}}.
+Useful if \code{check.fun} is just a simple wrapper.}
+
+\item{env}{[\code{environment}]\cr
+The environment of the created function. Default is the \code{\link[base]{parent.frame}}.}
+}
+\value{
+\code{makeAssertion} invisibly returns the checked object if the check was successful,
+ and an exception is raised (or its message stored in the collection) otherwise.
+ \code{makeAssertionFunction} returns a \code{function}.
+}
+\description{
+\code{makeAssertion} is the internal function used to evaluate the result of a
+check and throw an exception if necessary.
+\code{makeAssertionFunction} can be used to automatically create an assertion
+function based on a check function (see example).
+}
+\examples{
+# Simple custom check function
+checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+
+# Create the respective assert function
+assertFalse = function(x, .var.name = vname(x), add = NULL) {
+  res = checkFalse(x)
+  makeAssertion(x, res, .var.name, add)
+}
+
+# Alternative: Automatically create such a function
+assertFalse = makeAssertionFunction(checkFalse)
+print(assertFalse)
+}
+\seealso{
+Other CustomConstructors: \code{\link{makeExpectation}},
+  \code{\link{makeTest}}
+}
+
diff --git a/man/makeExpectation.Rd b/man/makeExpectation.Rd
new file mode 100644
index 0000000..3ccdade
--- /dev/null
+++ b/man/makeExpectation.Rd
@@ -0,0 +1,65 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeExpectation.R
+\name{makeExpectation}
+\alias{makeExpectation}
+\alias{makeExpectationFunction}
+\title{Turn a Check into an Expectation}
+\usage{
+makeExpectation(x, res, info, label)
+
+makeExpectationFunction(check.fun, c.fun = NULL, env = parent.frame())
+}
+\arguments{
+\item{x}{[any]\cr
+Object to check.}
+
+\item{res}{[\code{TRUE} | \code{character(1)}]\cr
+The result of a check function: \code{TRUE} for successful checks,
+and an error message as string otherwise.}
+
+\item{info}{[\code{character(1)}]\cr
+See \code{\link[testthat]{expect_that}}}
+
+\item{label}{[\code{character(1)}]\cr
+See \code{\link[testthat]{expect_that}}}
+
+\item{check.fun}{[\code{function}]\cr
+Function which checks the input. Must return \code{TRUE} on success and a string with the error message otherwise.}
+
+\item{c.fun}{[\code{character(1)}]\cr
+If not \code{NULL}, instead of calling the function \code{check.fun}, use \code{.Call} to call a C function \dQuote{c.fun} with the identical
+set of parameters. The C function must be registered as a native symbol, see \code{\link[base]{.Call}}.
+Useful if \code{check.fun} is just a simple wrapper.}
+
+\item{env}{[\code{environment}]\cr
+The environment of the created function. Default is the \code{\link[base]{parent.frame}}.}
+}
+\value{
+\code{makeExpectation} invisibly returns the checked object.
+  \code{makeExpectationFunction} returns a \code{function}.
+}
+\description{
+\code{makeExpectation} is the internal function used to evaluate the result of a
+check and turn it into an \code{\link[testthat]{expectation}}.
+\code{makeExceptionFunction} can be used to automatically create an expectation
+function based on a check function (see example).
+}
+\examples{
+# Simple custom check function
+checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+
+# Create the respective expect function
+expect_false = function(x, info = NULL, label = vname(x)) {
+  res = checkFalse(x)
+  makeExpectation(x, res, info = info, label = label)
+}
+
+# Alternative: Automatically create such a function
+expect_false = makeExpectationFunction(checkFalse)
+print(expect_false)
+}
+\seealso{
+Other CustomConstructors: \code{\link{makeAssertion}},
+  \code{\link{makeTest}}
+}
+
diff --git a/man/makeTest.Rd b/man/makeTest.Rd
new file mode 100644
index 0000000..4ba6bd7
--- /dev/null
+++ b/man/makeTest.Rd
@@ -0,0 +1,57 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/makeTest.R
+\name{makeTest}
+\alias{makeTest}
+\alias{makeTestFunction}
+\title{Turn a Check into a Test}
+\usage{
+makeTest(res)
+
+makeTestFunction(check.fun, c.fun = NULL, env = parent.frame())
+}
+\arguments{
+\item{res}{[\code{TRUE} | \code{character(1)}]\cr
+The result of a check function: \code{TRUE} for successful checks,
+and an error message as string otherwise.}
+
+\item{check.fun}{[\code{function}]\cr
+Function which checks the input. Must return \code{TRUE} on success and a string with the error message otherwise.}
+
+\item{c.fun}{[\code{character(1)}]\cr
+If not \code{NULL}, instead of calling the function \code{check.fun}, use \code{.Call} to call a C function \dQuote{c.fun} with the identical
+set of parameters. The C function must be registered as a native symbol, see \code{\link[base]{.Call}}.
+Useful if \code{check.fun} is just a simple wrapper.}
+
+\item{env}{[\code{environment}]\cr
+The environment of the created function. Default is the \code{\link[base]{parent.frame}}.}
+}
+\value{
+\code{makeTest} returns \code{TRUE} if the check is successful and \code{FALSE} otherwise.
+ \code{makeTestFunction} returns a \code{function}.
+}
+\description{
+\code{makeTest} is the internal function used to evaluate the result of a
+check and throw an exception if necessary.
+This function is currently only a stub and just calls \code{\link[base]{isTRUE}}.
+\code{makeTestFunction} can be used to automatically create an assertion
+function based on a check function (see example).
+}
+\examples{
+# Simple custom check function
+checkFalse = function(x) if (!identical(x, FALSE)) "Must be FALSE" else TRUE
+
+# Create the respective test function
+testFalse = function(x) {
+  res = checkFalse(x)
+  makeTest(res)
+}
+
+# Alternative: Automatically create such a function
+testFalse = makeTestFunction(checkFalse)
+print(testFalse)
+}
+\seealso{
+Other CustomConstructors: \code{\link{makeAssertion}},
+  \code{\link{makeExpectation}}
+}
+
diff --git a/man/matchArg.Rd b/man/matchArg.Rd
new file mode 100644
index 0000000..76d604b
--- /dev/null
+++ b/man/matchArg.Rd
@@ -0,0 +1,37 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/matchArg.R
+\name{matchArg}
+\alias{matchArg}
+\title{Partial Argument Matching}
+\usage{
+matchArg(x, choices, several.ok = FALSE, .var.name = vname(x), add = NULL)
+}
+\arguments{
+\item{x}{[character]\cr
+User provided argument to match.}
+
+\item{choices}{[character()]\cr
+Candidates to match \code{x} with.}
+
+\item{several.ok}{[logical(1)]\cr
+If \code{TRUE}, multiple matches are allowed, cf. \code{\link[base]{match.arg}}.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in error messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{add}{[\code{AssertCollection}]\cr
+Collection to store assertions. See \code{\link{AssertCollection}}.}
+}
+\value{
+Subset of \code{choices}.
+}
+\description{
+This is an extensions to \code{\link[base]{match.arg}} with support for \code{\link{AssertCollection}}.
+The behaviour is very similar to \code{\link[base]{match.arg}}, except that \code{NULL} is not
+a valid value for \code{x}.
+}
+\examples{
+matchArg("k", choices = c("kendall", "pearson"))
+}
+
diff --git a/man/qassert.Rd b/man/qassert.Rd
new file mode 100644
index 0000000..a73b148
--- /dev/null
+++ b/man/qassert.Rd
@@ -0,0 +1,132 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/qassert.R
+\name{qassert}
+\alias{qassert}
+\alias{qexpect}
+\alias{qtest}
+\title{Quick argument checks on (builtin) R types}
+\usage{
+qassert(x, rules, .var.name = vname(x))
+
+qtest(x, rules)
+
+qexpect(x, rules, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[any]\cr
+Object the check.}
+
+\item{rules}{[\code{character}]\cr
+Set of rules. See details.}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in error messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+\code{qassert} throws an \code{R} exception if object \code{x} does
+ not comply to at least one of the \code{rules} and returns the tested object invisibly
+ otherwise.
+ \code{qtest} behaves the same way but returns \code{FALSE} if none of the
+ \code{rules} comply.
+ \code{qexpect} is intended to be inside the unit test framework \code{\link[testthat]{testthat}} and
+ returns an \code{\link[testthat]{expectation}}.
+}
+\description{
+The provided functions parse rules which allow to express some of the most
+frequent argument checks by typing just a few letters.
+}
+\details{
+The rule is specified in up to three parts.
+\enumerate{
+ \item{
+   Class and missingness check.
+   The first letter is an abbreviation for the class. If it is
+   provided uppercase, missing values are prohibited.
+   Supported abbreviations:
+   \tabular{rl}{
+     \code{[bB]} \tab Bool / logical.\cr
+     \code{[iI]} \tab Integer.\cr
+     \code{[xX]} \tab Integerish (numeric convertible to integer, see \code{\link{checkIntegerish}}).\cr
+     \code{[rR]} \tab Real / double.\cr
+     \code{[cC]} \tab Complex.\cr
+     \code{[nN]} \tab Numeric (integer or double).\cr
+     \code{[sS]} \tab String / character.\cr
+     \code{[fF]} \tab Factor\cr
+     \code{[aA]} \tab Atomic.\cr
+     \code{[vV]} \tab Atomic vector (see \code{\link{checkAtomicVector}}).\cr
+     \code{[lL]} \tab List. Missingness is defined as \code{NULL} element.\cr
+     \code{[mM]} \tab Matrix.\cr
+     \code{[dD]} \tab Data.frame. Missingness is checked recursively on columns.\cr
+     \code{[e]}  \tab Environment.\cr
+     \code{[0]}  \tab \code{NULL}.\cr
+     \code{[*]}  \tab placeholder to allow any type.
+   }
+   Note that the check for missingness does not distinguish between
+   \code{NaN} and \code{NA}. Infinite values are not treated as missing, but
+   can be caught using boundary checks (part 3).
+   }
+ \item{
+   Length definition. This can be one of
+   \tabular{rl}{
+     \code{[*]} \tab any length,\cr
+     \code{[?]} \tab length of zero or one,\cr
+     \code{[+]} \tab length of at least one, or\cr
+     \code{[0-9]+} \tab exact length specified as integer.
+   }
+   Preceding the exact length with one of the comparison operators \code{=}/\code{==},
+   \code{<}, \code{<=}, \code{>=} or \code{>} is also supported.
+ }
+ \item{
+   Range check as two numbers separated by a comma, enclosed by square brackets
+   (endpoint included) or parentheses (endpoint excluded).
+   For example, \dQuote{[0, 3)} results in \code{all(x >= 0 & x < 3)}.
+   The lower and upper bound may be omitted which is the equivalent of a negative or
+   positive infinite bound, respectively.
+   By definition \code{[0,]} contains \code{Inf}, while \code{[0,)} does not.
+   The same holds for the left (lower) boundary and \code{-Inf}.
+   E.g., the rule \dQuote{N1()} checks for a single finite numeric which is not NA,
+   while \dQuote{N1[)} allows \code{-Inf}.
+ }
+}
+}
+\note{
+The functions are inspired by the blog post of Bogumił Kamiński:
+\url{http://rsnippets.blogspot.de/2013/06/testing-function-agruments-in-gnu-r.html}.
+The implementation is mostly written in C to minimize the overhead.
+}
+\examples{
+# logical of length 1
+qtest(NA, "b1")
+
+# logical of length 1, NA not allowed
+qtest(NA, "B1")
+
+# logical of length 0 or 1, NA not allowed
+qtest(TRUE, "B?")
+
+# numeric with length > 0
+qtest(runif(10), "n+")
+
+# integer with length > 0, NAs not allowed, all integers >= 0 and < Inf
+qtest(1:3, "I+[0,)")
+
+# either an emtpy list or a character vector with <=5 elements
+qtest(1, c("l0", "s<=5"))
+
+# data frame with at least one column and no missing value in any column
+qtest(iris, "D+")
+}
+\seealso{
+\code{\link{qtestr}} and \code{\link{qassertr}} for efficient checks
+of list elements and data frame columns.
+}
+
diff --git a/man/qassertr.Rd b/man/qassertr.Rd
new file mode 100644
index 0000000..c291940
--- /dev/null
+++ b/man/qassertr.Rd
@@ -0,0 +1,63 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/qassertr.R
+\name{qassertr}
+\alias{qassertr}
+\alias{qexpectr}
+\alias{qtestr}
+\title{Quick recursive arguments checks on lists and data frames}
+\usage{
+qassertr(x, rules, .var.name = vname(x))
+
+qtestr(x, rules, depth = 1L)
+
+qexpectr(x, rules, info = NULL, label = vname(x))
+}
+\arguments{
+\item{x}{[\code{list} or \code{data.frame}]\cr
+List or data frame to check for compliance with at least one of \code{rules}.
+See details of \code{\link{qtest}} for rule explanation.}
+
+\item{rules}{[\code{character}]\cr
+Set of rules. See \code{\link{qtest}}}
+
+\item{.var.name}{[\code{character(1)}]\cr
+Name of the checked object to print in error messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+
+\item{depth}{[\code{integer(1)}]\cr
+Maximum recursion depth. Defaults to \dQuote{1} to directly check list elements or
+data frame columns. Set to a higher value to check lists of lists of elements.}
+
+\item{info}{[character(1)]\cr
+Extra information to be included in the message for the testthat reporter.
+See \code{\link[testthat]{expect_that}}.}
+
+\item{label}{[\code{character(1)}]\cr
+Name of the checked object to print in messages. Defaults to
+the heuristic implemented in \code{\link{vname}}.}
+}
+\value{
+See \code{\link{qassert}}.
+}
+\description{
+These functions are the tuned counterparts of \code{\link{qtest}},
+\code{\link{qassert}} and \code{\link{qexpect}} tailored for recursive
+checks of list elements or data frame columns.
+}
+\examples{
+# All list elements are integers with length >= 1?
+qtestr(as.list(1:10), "i+")
+
+# All list elements (i.e. data frame columns) are numeric?
+qtestr(iris, "n")
+
+# All list elements are numeric, w/o NAs?
+qtestr(list(a = 1:3, b = rnorm(1), c = letters), "N+")
+
+# All list elements are numeric OR character
+qtestr(list(a = 1:3, b = rnorm(1), c = letters), c("N+", "S+"))
+}
+\seealso{
+\code{\link{qtest}}, \code{\link{qassert}}
+}
+
diff --git a/man/vname.Rd b/man/vname.Rd
new file mode 100644
index 0000000..9d1fcc9
--- /dev/null
+++ b/man/vname.Rd
@@ -0,0 +1,21 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/vname.R
+\name{vname}
+\alias{vname}
+\title{Lookup a variable name}
+\usage{
+vname(x)
+}
+\arguments{
+\item{x}{[ANY]\cr
+Object.}
+}
+\value{
+[\code{character(1)}] Variable name.
+}
+\description{
+Tries to heuristically determine the variable name of \code{x} in the parent frame
+with a combination of \code{\link[base]{deparse}} and \code{\link[base]{substitute}}.
+Used for checkmate's error messages.
+}
+
diff --git a/man/wf.Rd b/man/wf.Rd
new file mode 100644
index 0000000..f653157
--- /dev/null
+++ b/man/wf.Rd
@@ -0,0 +1,34 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/wfwl.R
+\name{wf}
+\alias{wf}
+\alias{wl}
+\title{Get the index of the first/last TRUE}
+\usage{
+wf(x, use.names = TRUE)
+
+wl(x, use.names = TRUE)
+}
+\arguments{
+\item{x}{[\code{logical}]\cr
+Logical vector.}
+
+\item{use.names}{[\code{logical(1)}]\cr
+If \code{TRUE} and \code{x} is named, the result is also
+named.}
+}
+\value{
+[\code{integer(1)} | \code{integer(0)}].
+ Returns the index of the first/last \code{TRUE} value in \code{x} or
+ an empty integer vector if none is found. NAs are ignored.
+}
+\description{
+A quick C implementation for \dQuote{which.first} (\code{head(which(x), 1)}) and
+\dQuote{which.last} (\code{tail(which(x), 1)}).
+}
+\examples{
+wf(c(FALSE, TRUE))
+wl(c(FALSE, FALSE))
+wf(NA)
+}
+
diff --git a/src/all_missing.c b/src/all_missing.c
new file mode 100644
index 0000000..cd1e9fd
--- /dev/null
+++ b/src/all_missing.c
@@ -0,0 +1,97 @@
+#include "all_missing.h"
+
+Rboolean all_missing_logical(SEXP x) {
+    const int * xp = LOGICAL(x);
+    const int * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (*xp != NA_LOGICAL)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_integer(SEXP x) {
+    const int * xp = INTEGER(x);
+    const int * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (*xp != NA_INTEGER)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_double(SEXP x) {
+    const double * xp = REAL(x);
+    const double * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (!ISNAN(*xp))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_complex(SEXP x) {
+    const Rcomplex * xp = COMPLEX(x);
+    const Rcomplex * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (!ISNAN((*xp).r) || !ISNAN((*xp).i))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_string(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (STRING_ELT(x, i) != NA_STRING)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_atomic(SEXP x) {
+    switch(TYPEOF(x)) {
+        case LGLSXP: return all_missing_logical(x);
+        case INTSXP: return all_missing_integer(x);
+        case REALSXP: return all_missing_double(x);
+        case CPLXSXP: return all_missing_complex(x);
+        case STRSXP: return all_missing_string(x);
+        default: return FALSE;
+    }
+}
+
+Rboolean all_missing_list(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (!isNull(VECTOR_ELT(x, i)))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean all_missing_frame(SEXP x) {
+    const R_xlen_t nc = xlength(x);
+    for (R_xlen_t i = 0; i < nc; i++) {
+        if (all_missing_atomic(VECTOR_ELT(x, i)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean all_missing(SEXP x) {
+    switch(TYPEOF(x)) {
+        case LGLSXP: return all_missing_logical(x);
+        case INTSXP: return all_missing_integer(x);
+        case REALSXP: return all_missing_double(x);
+        case CPLXSXP: return all_missing_complex(x);
+        case STRSXP: return all_missing_string(x);
+        case NILSXP: return FALSE;
+        case VECSXP: return isFrame(x) ? all_missing_frame(x) : all_missing_list(x);
+        case RAWSXP: return FALSE;
+        default: error("Object of type '%s' not supported", type2char(TYPEOF(x)));
+    }
+}
+
+SEXP c_all_missing(SEXP x) {
+    return ScalarLogical(all_missing(x));
+}
diff --git a/src/all_missing.h b/src/all_missing.h
new file mode 100644
index 0000000..34caeb1
--- /dev/null
+++ b/src/all_missing.h
@@ -0,0 +1,22 @@
+#ifndef CHECKMATE_ALL_MISSING_H_
+#define CHECKMATE_ALL_MISSING_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+Rboolean all_missing_logical(SEXP);
+Rboolean all_missing_integer(SEXP);
+Rboolean all_missing_integerish(SEXP);
+Rboolean all_missing_double(SEXP);
+Rboolean all_missing_numeric(SEXP);
+Rboolean all_missing_complex(SEXP);
+Rboolean all_missing_string(SEXP);
+Rboolean all_missing_atomic(SEXP);
+Rboolean all_missing_list(SEXP);
+Rboolean all_missing_matrix(SEXP);
+Rboolean all_missing_frame(SEXP);
+Rboolean all_missing(SEXP);
+SEXP c_all_missing(SEXP);
+
+#endif
diff --git a/src/all_nchar.c b/src/all_nchar.c
new file mode 100644
index 0000000..b813dc9
--- /dev/null
+++ b/src/all_nchar.c
@@ -0,0 +1,17 @@
+#include "all_nchar.h"
+
+Rboolean all_nchar(SEXP x, const R_xlen_t n) {
+    if (!isString(x)) {
+        SEXP xs = PROTECT(coerceVector(x, STRSXP));
+        Rboolean res = all_nchar(xs, n);
+        UNPROTECT(1);
+        return res;
+    }
+
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (STRING_ELT(x, i) == NA_STRING || xlength(STRING_ELT(x, i)) < n)
+            return FALSE;
+    }
+    return TRUE;
+}
diff --git a/src/all_nchar.h b/src/all_nchar.h
new file mode 100644
index 0000000..54fc307
--- /dev/null
+++ b/src/all_nchar.h
@@ -0,0 +1,10 @@
+#ifndef CHECKMATE_ALL_NCHAR_H_
+#define CHECKMATE_ALL_NCHAR_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+Rboolean all_nchar(SEXP, R_xlen_t);
+
+#endif
diff --git a/src/any_infinite.c b/src/any_infinite.c
new file mode 100644
index 0000000..6dd5872
--- /dev/null
+++ b/src/any_infinite.c
@@ -0,0 +1,44 @@
+#include "any_infinite.h"
+
+static Rboolean any_infinite_double(SEXP x) {
+    const double * xp = REAL(x);
+    const double * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (*xp == R_PosInf || *xp == R_NegInf)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static Rboolean any_infinite_complex(SEXP x) {
+    const Rcomplex * xp = COMPLEX(x);
+    const Rcomplex * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if ((*xp).r == R_PosInf || (*xp).i == R_PosInf ||
+            (*xp).r == R_NegInf || (*xp).i == R_NegInf)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static Rboolean any_infinite_list(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (any_infinite(VECTOR_ELT(x, i)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_infinite(SEXP x) {
+    switch(TYPEOF(x)) {
+        case REALSXP: return any_infinite_double(x);
+        case CPLXSXP: return any_infinite_complex(x);
+        case VECSXP:  return any_infinite_list(x);
+    }
+    return FALSE;
+}
+
+SEXP c_any_infinite(SEXP x) {
+    return ScalarLogical(any_infinite(x));
+}
diff --git a/src/any_infinite.h b/src/any_infinite.h
new file mode 100644
index 0000000..4af3b25
--- /dev/null
+++ b/src/any_infinite.h
@@ -0,0 +1,11 @@
+#ifndef CHECKMATE_ANY_INFINITE_H_
+#define CHECKMATE_ANY_INFINITE_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+SEXP c_any_infinite(SEXP);
+Rboolean any_infinite(SEXP);
+
+#endif
diff --git a/src/any_missing.c b/src/any_missing.c
new file mode 100644
index 0000000..15fe68d
--- /dev/null
+++ b/src/any_missing.c
@@ -0,0 +1,117 @@
+#include "any_missing.h"
+
+Rboolean any_missing_logical(SEXP x) {
+    const int * xp = LOGICAL(x);
+    const int * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (*xp == NA_LOGICAL)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_integer(SEXP x) {
+    const int * xp = INTEGER(x);
+    const int * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (*xp == NA_INTEGER)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_integerish(SEXP x) {
+    switch(TYPEOF(x)) {
+        case LGLSXP: return any_missing_logical(x);
+        case INTSXP: return any_missing_integer(x);
+        case REALSXP: return any_missing_double(x);
+        default: error("Error in any_missing_integerish: x is not logical or numeric");
+    }
+}
+
+Rboolean any_missing_double(SEXP x) {
+    const double * xp = REAL(x);
+    const double * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (ISNAN(*xp))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_numeric(SEXP x) {
+    switch(TYPEOF(x)) {
+        case INTSXP: return any_missing_integer(x);
+        case REALSXP: return any_missing_double(x);
+        default: error("Error in any_missing_numeric: x is not integer or double");
+    }
+}
+
+Rboolean any_missing_complex(SEXP x) {
+    const Rcomplex * xp = COMPLEX(x);
+    const Rcomplex * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (ISNAN((*xp).r) || ISNAN((*xp).i))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_string(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (STRING_ELT(x, i) == NA_STRING)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_atomic(SEXP x) {
+    switch(TYPEOF(x)) {
+        case LGLSXP:  return any_missing_logical(x);
+        case INTSXP:  return any_missing_integer(x);
+        case REALSXP: return any_missing_double(x);
+        case CPLXSXP: return any_missing_complex(x);
+        case STRSXP:  return any_missing_string(x);
+        default:      return FALSE;
+    }
+}
+
+Rboolean any_missing_list(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (isNull(VECTOR_ELT(x, i)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing_matrix(SEXP x) {
+    return any_missing_atomic(x);
+}
+
+Rboolean any_missing_frame(SEXP x) {
+    const R_xlen_t nc = xlength(x);
+    for (R_xlen_t i = 0; i < nc; i++) {
+        if (any_missing_atomic(VECTOR_ELT(x, i)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_missing(SEXP x) {
+    switch(TYPEOF(x)) {
+        case LGLSXP:  return any_missing_logical(x);
+        case INTSXP:  return any_missing_integer(x);
+        case REALSXP: return any_missing_double(x);
+        case CPLXSXP: return any_missing_complex(x);
+        case STRSXP:  return any_missing_string(x);
+        case NILSXP:  return FALSE;
+        case VECSXP:  return isFrame(x) ? any_missing_frame(x) : any_missing_list(x);
+        case RAWSXP:  return FALSE;
+        default: error("Object of type '%s' not supported", type2char(TYPEOF(x)));
+    }
+}
+SEXP c_any_missing(SEXP x) {
+    return ScalarLogical(any_missing(x));
+}
diff --git a/src/any_missing.h b/src/any_missing.h
new file mode 100644
index 0000000..0c97c62
--- /dev/null
+++ b/src/any_missing.h
@@ -0,0 +1,22 @@
+#ifndef CHECKMATE_ANY_MISSING_H_
+#define CHECKMATE_ANY_MISSING_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+Rboolean any_missing_logical(SEXP);
+Rboolean any_missing_integer(SEXP);
+Rboolean any_missing_integerish(SEXP);
+Rboolean any_missing_double(SEXP);
+Rboolean any_missing_numeric(SEXP);
+Rboolean any_missing_complex(SEXP);
+Rboolean any_missing_string(SEXP);
+Rboolean any_missing_atomic(SEXP);
+Rboolean any_missing_list(SEXP);
+Rboolean any_missing_matrix(SEXP);
+Rboolean any_missing_frame(SEXP);
+Rboolean any_missing(SEXP);
+SEXP c_any_missing(SEXP);
+
+#endif
diff --git a/src/any_nan.c b/src/any_nan.c
new file mode 100644
index 0000000..ed9dece
--- /dev/null
+++ b/src/any_nan.c
@@ -0,0 +1,43 @@
+#include "any_nan.h"
+
+static Rboolean any_nan_double(SEXP x) {
+    const double * xp = REAL(x);
+    const double * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (R_IsNaN(*xp))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static Rboolean any_nan_complex(SEXP x) {
+    const Rcomplex * xp = COMPLEX(x);
+    const Rcomplex * const xe = xp + xlength(x);
+    for (; xp != xe; xp++) {
+        if (R_IsNaN((*xp).r) || R_IsNaN((*xp).i))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static Rboolean any_nan_list(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (any_nan(VECTOR_ELT(x, i)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+Rboolean any_nan(SEXP x) {
+    switch(TYPEOF(x)) {
+        case REALSXP: return any_nan_double(x);
+        case CPLXSXP: return any_nan_complex(x);
+        case VECSXP:  return any_nan_list(x);
+    }
+    return FALSE;
+}
+
+SEXP c_any_nan(SEXP x) {
+    return ScalarLogical(any_nan(x));
+}
diff --git a/src/any_nan.h b/src/any_nan.h
new file mode 100644
index 0000000..1a8728c
--- /dev/null
+++ b/src/any_nan.h
@@ -0,0 +1,11 @@
+#ifndef CHECKMATE_ANY_NAN_H_
+#define CHECKMATE_ANY_NAN_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+SEXP c_any_nan(SEXP);
+Rboolean any_nan(SEXP);
+
+#endif
diff --git a/src/checkmate_init.c b/src/checkmate_init.c
new file mode 100644
index 0000000..d688ed8
--- /dev/null
+++ b/src/checkmate_init.c
@@ -0,0 +1,8 @@
+#include "qassert.h"
+#include <R_ext/Rdynload.h>
+
+void R_init_checkmate(DllInfo *info) {
+  R_RegisterCCallable("checkmate", "qtest",  (DL_FUNC) &qtest);
+  R_RegisterCCallable("checkmate", "qassert",  (DL_FUNC) &qassert);
+}
+
diff --git a/src/checks.c b/src/checks.c
new file mode 100644
index 0000000..9d63a04
--- /dev/null
+++ b/src/checks.c
@@ -0,0 +1,544 @@
+#include "checks.h"
+#include <ctype.h>
+#include <string.h>
+#include "is_integerish.h"
+#include "any_missing.h"
+#include "any_infinite.h"
+#include "all_missing.h"
+#include "all_nchar.h"
+#include "helper.h"
+#include "guess_type.h"
+
+static char msg[255] = "";
+
+#define HANDLE_TYPE(expr, expected) \
+    if (!(expr)) { \
+        snprintf(msg, 255, "Must be of type '%s', not '%s'", expected, guess_type(x)); \
+        return ScalarString(mkChar(msg)); \
+    }
+
+#define HANDLE_TYPE_NULL(expr, expected, null_ok) \
+    if (isNull((x))) { \
+        if (asFlag((null_ok), "null.ok")) \
+            return ScalarLogical(TRUE); \
+        snprintf(msg, 255, "Must be of type '%s', not 'NULL'", expected); \
+        return ScalarString(mkChar(msg)); \
+    } else { \
+        if (!(expr)) { \
+            snprintf(msg, 255, "Must be of type '%s'%s, not '%s'", expected, asFlag(null_ok, "null_ok") ? " (or 'NULL')" : "", guess_type(x)); \
+            return ScalarString(mkChar(msg)); \
+        } \
+    }
+
+#define HANDLE_NA(x, na_ok) \
+    if (is_scalar_na((x))) { \
+        if (asFlag((na_ok), "na.ok")) \
+            return ScalarLogical(TRUE); \
+        return result("May not be NA"); \
+    };
+
+#define ASSERT_TRUE(x) if (!(x)) return ScalarString(mkChar(msg));
+
+
+/*********************************************************************************************************************/
+/* Some helpers                                                                                                      */
+/*********************************************************************************************************************/
+static Rboolean message(const char *fmt, ...) {
+    va_list vargs;
+    va_start(vargs, fmt);
+    vsnprintf(msg, 255, fmt, vargs);
+    va_end(vargs);
+    return FALSE;
+}
+
+static SEXP result(const char *fmt, ...) {
+    va_list vargs;
+    va_start(vargs, fmt);
+    vsnprintf(msg, 255, fmt, vargs);
+    va_end(vargs);
+    return ScalarString(mkChar(msg));
+}
+
+static Rboolean check_bounds(SEXP x, SEXP lower, SEXP upper) {
+    double tmp = asNumber(lower, "lower");
+    if (R_FINITE(tmp)) {
+        if (isReal(x)) {
+            const double *xp = REAL(x);
+            const double * const xend = xp + xlength(x);
+            for (; xp != xend; xp++) {
+                if (!ISNAN(*xp) && *xp < tmp)
+                    return message("All elements must be >= %g", tmp);
+            }
+        } else if (isInteger(x)) {
+            const int *xp = INTEGER(x);
+            const int * const xend = xp + xlength(x);
+            for (; xp != xend; xp++) {
+                if (*xp != NA_INTEGER && *xp < tmp)
+                    return message("All elements must be >= %g", tmp);
+            }
+        }
+    }
+
+    tmp = asNumber(upper, "upper");
+    if (R_FINITE(tmp)) {
+        if (isReal(x)) {
+            const double *xp = REAL(x);
+            const double * const xend = xp + xlength(x);
+            for (; xp != xend; xp++) {
+                if (!ISNAN(*xp) && *xp > tmp)
+                    return message("All elements must be <= %g", tmp);
+            }
+        } else if (isInteger(x)) {
+            const int *xp = INTEGER(x);
+            const int * const xend = xp + xlength(x);
+            for (; xp != xend; xp++) {
+                if (*xp != NA_INTEGER && *xp > tmp)
+                    return message("All elements must be <= %g", tmp);
+            }
+        }
+    }
+    return TRUE;
+}
+
+static Rboolean check_strict_names(SEXP x) {
+    const R_xlen_t nx = xlength(x);
+    const char *str;
+    for (R_xlen_t i = 0; i < nx; i++) {
+        str = CHAR(STRING_ELT(x, i));
+        while (*str == '.')
+            str++;
+        if (!isalpha(*str))
+            return FALSE;
+        for (; *str != '\0'; str++) {
+            if (!isalnum(*str) && *str != '.' && *str != '_')
+                return FALSE;
+        }
+    }
+    return TRUE;
+}
+static Rboolean check_names(SEXP nn, const char * type, const char * what) {
+    typedef enum { T_NAMED, T_UNIQUE, T_STRICT } name_t;
+    name_t checks;
+
+    if (strcmp(type, "unnamed") == 0)
+        return isNull(nn) ? TRUE : message("%s must be unnamed, but has names", what);
+
+    if (strcmp(type, "named") == 0) {
+        checks = T_NAMED;
+    } else if (strcmp(type, "unique") == 0) {
+        checks = T_UNIQUE;
+    } else if (strcmp(type, "strict") == 0) {
+        checks = T_STRICT;
+    } else {
+        error("Unknown type '%s' to specify check for names. Supported are 'unnamed', 'named', 'unique' and 'strict'.", type);
+    }
+
+    if (isNull(nn) || any_missing_string(nn) || !all_nchar(nn, 1))
+        return message("%s must be named", what);
+    if (checks >= T_UNIQUE) {
+        if (any_duplicated(nn, FALSE) != 0)
+            return message("%s must be uniquely named", what);
+        if (checks >= T_STRICT && !check_strict_names(nn))
+            return message("%s must be named according to R's variable naming rules", what);
+    }
+    return TRUE;
+}
+
+static Rboolean check_vector_len(SEXP x, SEXP len, SEXP min_len, SEXP max_len) {
+    if (!isNull(len)) {
+        R_xlen_t n = asCount(len, "len");
+        if (xlength(x) != n)
+            return message("Must have length %g, but has length %g", (double)n, (double)xlength(x));
+    }
+    if (!isNull(min_len)) {
+        R_xlen_t n = asCount(min_len, "min.len");
+        if (xlength(x) < n)
+            return message("Must have length >= %g, but has length %g", (double)n, (double)xlength(x));
+    }
+    if (!isNull(max_len)) {
+        R_xlen_t n = asCount(max_len, "max.len");
+        if (xlength(x) > n)
+            return message("Must have length <= %g, but has length %g", (double)n, (double)xlength(x));
+    }
+    return TRUE;
+}
+
+static Rboolean check_vector_missings(SEXP x, SEXP any_missing, SEXP all_missing) {
+    if (!asFlag(any_missing, "any.missing") && any_missing_atomic(x))
+        return message("Contains missing values");
+    if (!asFlag(all_missing, "all.missing") && all_missing_atomic(x))
+        return message("Contains only missing values");
+    return TRUE;
+}
+
+static Rboolean check_vector_unique(SEXP x, SEXP unique) {
+    if (asFlag(unique, "unique") && any_duplicated(x, FALSE) > 0)
+        return message("Contains duplicated values");
+    return TRUE;
+}
+
+static Rboolean check_vector_names(SEXP x, SEXP names) {
+    if (!isNull(names) && xlength(x) > 0)
+        return check_names(getAttrib(x, R_NamesSymbol), asString(names, "names"), "Vector");
+    return TRUE;
+}
+
+static Rboolean check_vector_finite(SEXP x, SEXP finite) {
+    if (asFlag(finite, "finite") && any_infinite(x))
+        return message("Must be finite");
+    return TRUE;
+}
+
+static Rboolean check_matrix_dims(SEXP x, SEXP min_rows, SEXP min_cols, SEXP rows, SEXP cols) {
+    if (!isNull(min_rows) || !isNull(rows)) {
+        R_len_t xrows = get_nrows(x);
+        if (!isNull(min_rows)) {
+            R_len_t cmp = asCount(min_rows, "min.rows");
+            if (xrows < cmp)
+                return message("Must have at least %i rows, but has %i rows", cmp, xrows);
+        }
+        if (!isNull(rows)) {
+            R_len_t cmp = asCount(rows, "rows");
+            if (xrows != cmp)
+                return message("Must have exactly %i rows, but has %i rows", cmp, xrows);
+        }
+    }
+    if (!isNull(min_cols) || !isNull(cols)) {
+        R_len_t xcols = get_ncols(x);
+        if (!isNull(min_cols)) {
+            R_len_t cmp = asCount(min_cols, "min.cols");
+            if (xcols < cmp)
+                return message("Must have at least %i cols, but has %i cols", cmp, xcols);
+        }
+        if (!isNull(cols)) {
+            R_len_t cmp = asCount(cols, "cols");
+            if (xcols != cmp)
+                return message("Must have exactly %i cols, but has %i cols", cmp, xcols);
+        }
+    }
+    return TRUE;
+}
+
+static Rboolean check_storage(SEXP x, SEXP mode) {
+    if (!isNull(mode)) {
+        const char * const storage = asString(mode, "mode");
+        if (strcmp(storage, "logical") == 0) {
+            if (!isLogical(x))
+                return message("Must store logicals");
+        } else if (strcmp(storage, "integer") == 0) {
+            if (!isInteger(x))
+                return message("Must store integers");
+        } else if (strcmp(storage, "double") == 0) {
+            if (!isReal(x))
+                return message("Must store doubles");
+        } else if (strcmp(storage, "integerish") == 0) {
+            if (!isIntegerish(x, INTEGERISH_DEFAULT_TOL, FALSE))
+                return message("Must store integerish values");
+        } else if (strcmp(storage, "numeric") == 0) {
+            if (!isStrictlyNumeric(x))
+                return message("Must store numerics");
+        } else if (strcmp(storage, "complex") == 0) {
+            if (!isComplex(x))
+                return message("Must store complexs");
+        } else if (strcmp(storage, "character") == 0) {
+            if (!isString(x))
+                return message("Must store characters");
+        } else if (strcmp(storage, "list") == 0) {
+            if (!isRList(x))
+                return message("Must store a list");
+        } else if (strcmp(storage, "atomic") == 0) {
+            if (!isVectorAtomic(x))
+                return message("Must be atomic");
+        } else {
+            error("Invalid argument 'mode'. Must be one of 'logical', 'integer', 'integerish', 'double', 'numeric', 'complex', 'character', 'list' or 'atomic'");
+        }
+    }
+    return TRUE;
+}
+
+static inline Rboolean is_scalar_na(SEXP x) {
+    if (xlength(x) == 1) {
+        switch(TYPEOF(x)) {
+            case LGLSXP: return (LOGICAL(x)[0] == NA_LOGICAL);
+            case INTSXP: return (INTEGER(x)[0] == NA_INTEGER);
+            case REALSXP: return ISNAN(REAL(x)[0]);
+            case STRSXP: return (STRING_ELT(x, 0) == NA_STRING);
+        }
+    }
+    return FALSE;
+}
+
+
+/*********************************************************************************************************************/
+/* Exported check functions                                                                                          */
+/*********************************************************************************************************************/
+SEXP c_check_character(SEXP x, SEXP min_chars, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isString(x) || all_missing_atomic(x), "character", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    if (!isNull(min_chars)) {
+        R_xlen_t n = asCount(min_chars, "min.chars");
+        if (n > 0 && !all_nchar(x, n))
+            return result("All elements must have at least %i characters", n);
+    }
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_complex(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isComplex(x) || all_missing_atomic(x), "complex", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_dataframe(SEXP x, SEXP any_missing, SEXP all_missing, SEXP min_rows, SEXP min_cols, SEXP rows, SEXP cols, SEXP row_names, SEXP col_names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isFrame(x), "data.frame", null_ok);
+    ASSERT_TRUE(check_matrix_dims(x, min_rows, min_cols, rows, cols));
+
+    if (!isNull(row_names)) {
+        SEXP nn = getAttrib(x, install("row.names"));
+        if (isInteger(nn)) {
+            nn = PROTECT(coerceVector(nn, STRSXP));
+            Rboolean ok = check_names(nn, asString(row_names, "row.names"), "Rows");
+            UNPROTECT(1);
+            if (!ok)
+                return ScalarString(mkChar(msg));
+        } else {
+            ASSERT_TRUE(check_names(nn, asString(row_names, "row.names"), "Rows"));
+        }
+    }
+
+    if (!isNull(col_names))
+        ASSERT_TRUE(check_names(getAttrib(x, R_NamesSymbol), asString(col_names, "col.names"), "Columns"));
+    if (!asFlag(any_missing, "any.missing") && any_missing_frame(x))
+        return result("Contains missing values");
+    if (!asFlag(all_missing, "all.missing") && all_missing_frame(x))
+        return result("Contains only missing values");
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_factor(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isFactor(x) || all_missing_atomic(x), "factor", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_integer(SEXP x, SEXP lower, SEXP upper, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isInteger(x) || all_missing_atomic(x), "integer", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_bounds(x, lower, upper));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_integerish(SEXP x, SEXP tol, SEXP lower, SEXP upper, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    double dtol = asNumber(tol, "tol");
+    HANDLE_TYPE_NULL(isIntegerish(x, dtol, FALSE) || all_missing_atomic(x), "integerish", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_bounds(x, lower, upper));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_list(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isRList(x), "list", null_ok)
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_logical(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isLogical(x) || all_missing_atomic(x), "logical", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_matrix(SEXP x, SEXP mode, SEXP any_missing, SEXP all_missing, SEXP min_rows, SEXP min_cols, SEXP rows, SEXP cols, SEXP row_names, SEXP col_names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isMatrix(x), "matrix", null_ok);
+    ASSERT_TRUE(check_storage(x, mode));
+    ASSERT_TRUE(check_matrix_dims(x, min_rows, min_cols, rows, cols));
+
+    if (!isNull(row_names) && xlength(x) > 0) {
+        SEXP nn = getAttrib(x, R_DimNamesSymbol);
+        if (!isNull(nn))
+            nn = VECTOR_ELT(nn, 0);
+        ASSERT_TRUE(check_names(nn, asString(row_names, "row.names"), "Rows"));
+    }
+
+    if (!isNull(col_names) && xlength(x) > 0) {
+        SEXP nn = getAttrib(x, R_DimNamesSymbol);
+        if (!isNull(nn))
+            nn = VECTOR_ELT(nn, 1);
+        ASSERT_TRUE(check_names(nn, asString(col_names, "col.names"), "Columns"));
+    }
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_array(SEXP x, SEXP mode, SEXP any_missing, SEXP d, SEXP min_d, SEXP max_d, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isArray(x), "array", null_ok);
+    ASSERT_TRUE(check_storage(x, mode));
+
+    if (!asFlag(any_missing, "any.missing") && any_missing_atomic(x))
+        return result("Contains missing values");
+
+    R_len_t ndim = length(getAttrib(x, R_DimSymbol));
+    if (!isNull(d)) {
+        R_len_t di = asCount(d, "d");
+        if (ndim != di)
+            return result("Must be a %i-d array, but has dimension %i", di, ndim);
+    }
+
+    if (!isNull(min_d)) {
+        R_len_t di = asCount(min_d, "min.d");
+        if (ndim < di)
+            return result("Must have >=%i dimensions, but has dimension %i", di, ndim);
+    }
+
+    if (!isNull(max_d)) {
+        R_len_t di = asCount(max_d, "max.d");
+        if (ndim > di)
+            return result("Must have <=%i dimensions, but has dimension %i", di, ndim);
+    }
+
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_named(SEXP x, SEXP type) {
+    if (!isNull(type) && xlength(x) > 0)
+        ASSERT_TRUE(check_names(getAttrib(x, R_NamesSymbol), asString(type, "type"), "Object"));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_names(SEXP x, SEXP type) {
+    if (!isString(x))
+        return result("Must be a character vector of names");
+    ASSERT_TRUE(check_names(x, asString(type, "type"), "Names"));
+    return ScalarLogical(TRUE);
+}
+
+
+SEXP c_check_numeric(SEXP x, SEXP lower, SEXP upper, SEXP finite, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isStrictlyNumeric(x) || all_missing_atomic(x), "numeric", null_ok);
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_bounds(x, lower, upper));
+    ASSERT_TRUE(check_vector_finite(x, finite));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_vector(SEXP x, SEXP strict, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names, SEXP null_ok) {
+    HANDLE_TYPE_NULL(isVector(x), "vector", null_ok);
+    if (asFlag(strict, "strict")) {
+        SEXP attr = ATTRIB(x);
+        HANDLE_TYPE( (length(attr) == 0 || (TAG(attr) == R_NamesSymbol)) && CDR(attr) == R_NilValue, "vector");
+    }
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_atomic(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names) {
+    HANDLE_TYPE(isNull(x) || isVectorAtomic(x), "atomic");
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_atomic_vector(SEXP x, SEXP any_missing, SEXP all_missing, SEXP len, SEXP min_len, SEXP max_len, SEXP unique, SEXP names) {
+    HANDLE_TYPE(isAtomicVector(x), "atomic vector");
+    ASSERT_TRUE(check_vector_len(x, len, min_len, max_len));
+    ASSERT_TRUE(check_vector_names(x, names));
+    ASSERT_TRUE(check_vector_missings(x, any_missing, all_missing));
+    ASSERT_TRUE(check_vector_unique(x, unique));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_flag(SEXP x, SEXP na_ok, SEXP null_ok) {
+    HANDLE_NA(x, na_ok);
+    HANDLE_TYPE_NULL(isLogical(x), "logical flag", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_count(SEXP x, SEXP na_ok, SEXP positive, SEXP tol, SEXP null_ok) {
+    HANDLE_NA(x, na_ok)
+    double dtol = asNumber(tol, "tol");
+    HANDLE_TYPE_NULL(isIntegerish(x, dtol, FALSE), "count", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    const int pos = (int) asFlag(positive, "positive");
+    if (asInteger(x) < pos)
+        return result("Must be >= %i", pos);
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_int(SEXP x, SEXP na_ok, SEXP lower, SEXP upper, SEXP tol, SEXP null_ok) {
+    double dtol = asNumber(tol, "tol");
+    HANDLE_NA(x, na_ok);
+    HANDLE_TYPE_NULL(isIntegerish(x, dtol, FALSE), "single integerish value", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    ASSERT_TRUE(check_bounds(x, lower, upper));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_number(SEXP x, SEXP na_ok, SEXP lower, SEXP upper, SEXP finite, SEXP null_ok) {
+    HANDLE_NA(x, na_ok);
+    HANDLE_TYPE_NULL(isStrictlyNumeric(x), "number", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    ASSERT_TRUE(check_vector_finite(x, finite));
+    ASSERT_TRUE(check_bounds(x, lower, upper));
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_string(SEXP x, SEXP na_ok, SEXP min_chars, SEXP null_ok) {
+    HANDLE_NA(x, na_ok);
+    HANDLE_TYPE_NULL(isString(x), "string", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    if (!isNull(min_chars)) {
+        R_xlen_t n = asCount(min_chars, "min.chars");
+        if (!all_nchar(x, n))
+            return result("Must have at least %i characters", n);
+    }
+
+    return ScalarLogical(TRUE);
+}
+
+SEXP c_check_scalar(SEXP x, SEXP na_ok, SEXP null_ok) {
+    HANDLE_NA(x, na_ok);
+    HANDLE_TYPE_NULL(isVectorAtomic(x), "atomic scalar", null_ok);
+    if (xlength(x) != 1)
+        return result("Must have length 1");
+    return ScalarLogical(TRUE);
+}
+
+#undef HANDLE_TYPE
+#undef HANDLE_TYPE_NULL
+#undef HANDLE_NA
+#undef ASSERT_TRUE
diff --git a/src/checks.h b/src/checks.h
new file mode 100644
index 0000000..2e83d04
--- /dev/null
+++ b/src/checks.h
@@ -0,0 +1,33 @@
+#ifndef CHECKMATE_CHECKS_H_
+#define CHECKMATE_CHECKS_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+SEXP c_check_array(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_atomic(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_atomic_vector(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_character(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_complex(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_dataframe(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_factor(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_integer(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_integerish(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_list(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_logical(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_matrix(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_named(SEXP, SEXP);
+SEXP c_check_names(SEXP, SEXP);
+SEXP c_check_numeric(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_vector(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+
+
+SEXP c_check_count(SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_flag(SEXP, SEXP, SEXP);
+SEXP c_check_int(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_number(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
+SEXP c_check_scalar(SEXP, SEXP, SEXP);
+SEXP c_check_string(SEXP, SEXP, SEXP, SEXP);
+
+#endif
diff --git a/src/guess_type.c b/src/guess_type.c
new file mode 100644
index 0000000..6e8abbf
--- /dev/null
+++ b/src/guess_type.c
@@ -0,0 +1,34 @@
+#include "guess_type.h"
+#include <string.h>
+
+const char * guess_type(SEXP x) {
+    SEXP attr = getAttrib(x, R_ClassSymbol);
+    if (!isNull(attr)) {
+        const R_len_t n = length(attr);
+        if (n == 1)
+            return CHAR(STRING_ELT(attr, 0));
+
+        /* Constuct name using [class1]/[class2]/... */
+        static char buf[512];
+        const char * tmp = CHAR(STRING_ELT(attr, 0));
+        strncpy(buf, tmp, 512);
+        R_len_t written = strlen(tmp);
+        for (R_len_t i = 1; i < n; i++) {
+            tmp = CHAR(STRING_ELT(attr, i));
+            if (strlen(tmp) > 512 - written - 1)
+                break;
+            written += snprintf(buf + written, 512 - written, "/%s", tmp);
+        }
+        return buf;
+    }
+
+    attr = getAttrib(x, R_DimSymbol);
+    if (!isNull(attr) && isVectorAtomic(x))
+        return length(attr) == 2 ? "matrix" : "array";
+
+    return type2char(TYPEOF(x));
+}
+
+SEXP c_guess_type(SEXP x) {
+    return ScalarString(mkChar(guess_type(x)));
+}
diff --git a/src/guess_type.h b/src/guess_type.h
new file mode 100644
index 0000000..9917ec8
--- /dev/null
+++ b/src/guess_type.h
@@ -0,0 +1,11 @@
+#ifndef CHECKMATE_GUESS_TYPE_H_
+#define CHECKMATE_GUESS_TYPE_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+const char * guess_type(SEXP);
+SEXP c_guess_type(SEXP);
+
+#endif
diff --git a/src/helper.c b/src/helper.c
new file mode 100644
index 0000000..8ed8551
--- /dev/null
+++ b/src/helper.c
@@ -0,0 +1,88 @@
+#include "helper.h"
+#include "any_missing.h"
+#include "is_integerish.h"
+
+Rboolean isStrictlyNumeric(SEXP x) {
+    switch(TYPEOF(x)) {
+        case REALSXP: return TRUE;
+        case INTSXP: return !inherits(x, "factor");
+    }
+    return FALSE;
+}
+
+Rboolean isAtomicVector(SEXP x) {
+    if (!isVectorAtomic(x))
+        return FALSE;
+    return isNull(getAttrib(x, R_DimSymbol));
+}
+
+/* Checks for a regular list, i.e. not a data frame, not NULL */
+Rboolean isRList(SEXP x) {
+    if (TYPEOF(x) == VECSXP) {
+        SEXP cl = getAttrib(x, R_ClassSymbol);
+        const R_len_t n = length(cl);
+        for (R_len_t i = 0; i < n; i++) {
+            if (strcmp(CHAR(STRING_ELT(cl, i)), "data.frame") == 0)
+                return FALSE;
+        }
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/* ncols and nrows is bugged for data frames:
+ * (a) data.frames are treated like lists and thus you get length() back
+ * (b) reports wrong dimension for zero-column data frames
+ * Here are our own wrappers
+ * */
+R_len_t get_nrows(SEXP x) {
+    if (isFrame(x))
+        return length(getAttrib(x, R_RowNamesSymbol));
+    SEXP dim = getAttrib(x, R_DimSymbol);
+    return (dim == R_NilValue) ? length(x) : INTEGER(dim)[0];
+}
+
+R_len_t get_ncols(SEXP x) {
+    if (isFrame(x))
+        return length(x);
+    SEXP dim = getAttrib(x, R_DimSymbol);
+    return (length(dim) >= 2) ? INTEGER(dim)[1] : 1;
+}
+
+
+double asNumber(SEXP x, const char *vname) {
+    if (!isNumeric(x) || xlength(x) != 1)
+        error("Argument '%s' must be a number", vname);
+    double xd = asReal(x);
+    if (ISNAN(xd))
+        error("Argument '%s' may not be missing", vname);
+    return xd;
+}
+
+const char * asString(SEXP x, const char *vname) {
+    if (!isString(x) || xlength(x) != 1)
+        error("Argument '%s' must be a string", vname);
+    if (any_missing_string(x))
+        error("Argument '%s' may not be missing", vname);
+    return CHAR(STRING_ELT(x, 0));
+}
+
+R_xlen_t asCount(SEXP x, const char *vname) {
+    if (!isIntegerish(x, INTEGERISH_DEFAULT_TOL, FALSE) || xlength(x) != 1)
+        error("Argument '%s' must be a count", vname);
+    int xi = asInteger(x);
+    if (xi == NA_INTEGER)
+        error("Argument '%s' may not be missing", vname);
+    if (xi < 0)
+        error("Argument '%s' must be >= 0", vname);
+    return xi;
+}
+
+Rboolean asFlag(SEXP x, const char *vname) {
+    if (!isLogical(x) || xlength(x) != 1)
+        error("Argument '%s' must be a flag", vname);
+    Rboolean xb = LOGICAL(x)[0];
+    if (xb == NA_LOGICAL)
+        error("Argument '%s' may not be missing", vname);
+    return xb;
+}
diff --git a/src/helper.h b/src/helper.h
new file mode 100644
index 0000000..f987897
--- /dev/null
+++ b/src/helper.h
@@ -0,0 +1,18 @@
+#ifndef CHECKMATE_HELPER_H_
+#define CHECKMATE_HELPER_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+Rboolean isStrictlyNumeric(SEXP);
+Rboolean isAtomicVector(SEXP);
+Rboolean isRList(SEXP);
+R_len_t get_ncols(SEXP);
+R_len_t get_nrows(SEXP);
+double asNumber(SEXP, const char *);
+const char * asString(SEXP, const char *);
+R_xlen_t asCount(SEXP, const char *);
+Rboolean asFlag(SEXP, const char *);
+
+#endif
diff --git a/src/is_integerish.c b/src/is_integerish.c
new file mode 100644
index 0000000..d6a21f3
--- /dev/null
+++ b/src/is_integerish.c
@@ -0,0 +1,42 @@
+#include "is_integerish.h"
+#include <math.h>
+#include <limits.h>
+
+static inline Rboolean is_unconvertible(const double x, const double tol) {
+    return (!ISNAN(x) && (x <= INT_MIN || x > INT_MAX || fabs(x - nearbyint(x)) >= tol));
+}
+
+static Rboolean is_integerish_double(SEXP x, const double tol) {
+    const double *xr = REAL(x);
+    const double * const xend = xr + length(x);
+
+    for (; xr != xend; xr++) {
+        if (is_unconvertible(*xr, tol))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+static Rboolean is_integerish_complex(SEXP x, const double tol) {
+    const Rcomplex * xc = COMPLEX(x);
+    const Rcomplex * const xe = xc + length(x);
+    for (; xc != xe; xc++) {
+        if (fabs((*xc).i) >= tol || is_unconvertible((*xc).r, tol))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+Rboolean isIntegerish(SEXP x, const double tol, Rboolean logicals_ok) {
+    switch(TYPEOF(x)) {
+        case LGLSXP: return logicals_ok;
+        case INTSXP: return TRUE;
+        case REALSXP: return is_integerish_double(x, tol);
+        case CPLXSXP: return is_integerish_complex(x, tol);
+    }
+    return FALSE;
+}
+
+SEXP c_is_integerish(SEXP x, SEXP tolerance) {
+    return ScalarLogical(isIntegerish(x, REAL(tolerance)[0], FALSE));
+}
diff --git a/src/is_integerish.h b/src/is_integerish.h
new file mode 100644
index 0000000..6518bad
--- /dev/null
+++ b/src/is_integerish.h
@@ -0,0 +1,12 @@
+#ifndef CHECKMATE_IS_INTEGERISH_H_
+#define CHECKMATE_IS_INTEGERISH_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+#define INTEGERISH_DEFAULT_TOL sqrt(DOUBLE_EPS)
+Rboolean isIntegerish(SEXP, double, Rboolean);
+SEXP c_is_integerish(SEXP, SEXP);
+
+#endif
diff --git a/src/qassert.c b/src/qassert.c
new file mode 100644
index 0000000..dd4d0f7
--- /dev/null
+++ b/src/qassert.c
@@ -0,0 +1,548 @@
+#include "qassert.h"
+#include "helper.h"
+#include "guess_type.h"
+#include "any_missing.h"
+#include "is_integerish.h"
+
+typedef enum {
+    CL_LOGICAL, CL_INTEGER, CL_INTEGERISH, CL_NUMERIC, CL_DOUBLE, CL_STRING, CL_FACTOR, CL_LIST, CL_COMPLEX,
+    CL_ATOMIC, CL_ATOMIC_VECTOR, CL_MATRIX, CL_DATAFRAME, CL_FUNCTION, CL_ENVIRONMENT, CL_NULL, CL_NONE
+} class_t;
+
+static const char * CLSTR[] = {
+     "logical", "integer", "integerish", "numeric", "double", "string", "factor", "list", "complex",
+     "atomic", "atomic vector", "matrix", "data frame", "function", "environment", "NULL"
+};
+
+typedef enum { LT, LE, EQ, GE, GT, NE, NONE } cmp_t;
+static const char * CMPSTR[] = { "<", "<=", "==", ">=", ">", "!=" };
+
+typedef Rboolean(*dd_cmp)(double, double);
+typedef Rboolean(*ll_cmp)(R_xlen_t, R_xlen_t);
+typedef struct { dd_cmp fun; double cmp; cmp_t op; } bound_t;
+
+typedef struct {
+    struct {
+        Rboolean(*fun)(SEXP);
+        class_t name;
+    } class;
+    struct {
+        Rboolean(*fun)(SEXP);
+    } missing;
+    struct {
+        ll_cmp fun;
+        R_xlen_t cmp;
+        cmp_t op;
+    } len;
+    bound_t lower;
+    bound_t upper;
+} checker_t;
+
+typedef struct {
+    Rboolean ok;
+    char msg[255];
+} msg_t;
+
+
+static inline Rboolean ii_eq(const R_xlen_t x, const R_xlen_t y) { return x == y; }
+static inline Rboolean ii_lt(const R_xlen_t x, const R_xlen_t y) { return x <  y; }
+static inline Rboolean ii_gt(const R_xlen_t x, const R_xlen_t y) { return x >  y; }
+static inline Rboolean ii_le(const R_xlen_t x, const R_xlen_t y) { return x <= y; }
+static inline Rboolean ii_ge(const R_xlen_t x, const R_xlen_t y) { return x >= y; }
+static inline Rboolean dd_lt(const double x, const double y) { return x <  y; }
+static inline Rboolean dd_gt(const double x, const double y) { return x >  y; }
+static inline Rboolean dd_le(const double x, const double y) { return x <= y; }
+static inline Rboolean dd_ge(const double x, const double y) { return x >= y; }
+static inline Rboolean dd_ne(const double x, const double y) { return x != y; }
+static inline Rboolean is_class_logical(SEXP x) { return isLogical(x); }
+static inline Rboolean is_class_integer(SEXP x) { return isInteger(x); }
+static inline Rboolean is_class_integerish(SEXP x) { return isIntegerish(x, INTEGERISH_DEFAULT_TOL, TRUE); }
+static inline Rboolean is_class_double(SEXP x) { return isReal(x); }
+static inline Rboolean is_class_numeric(SEXP x) { return isStrictlyNumeric(x); }
+static inline Rboolean is_class_complex(SEXP x) { return isComplex(x); }
+static inline Rboolean is_class_string(SEXP x) { return isString(x); }
+static inline Rboolean is_class_factor(SEXP x) { return isFactor(x); }
+static inline Rboolean is_class_atomic(SEXP x) { return isNull(x) || isVectorAtomic(x); }
+static inline Rboolean is_class_atomic_vector(SEXP x) { return isAtomicVector(x); }
+static inline Rboolean is_class_list(SEXP x) { return isRList(x); }
+static inline Rboolean is_class_matrix(SEXP x) { return isMatrix(x); }
+static inline Rboolean is_class_frame(SEXP x) { return isFrame(x); }
+static inline Rboolean is_class_function(SEXP x) { return isFunction(x); }
+static inline Rboolean is_class_environment(SEXP x) { return isEnvironment(x); }
+static inline Rboolean is_class_null(SEXP x) { return isNull(x); }
+
+static const msg_t MSGT = { .ok = TRUE };
+static const msg_t MSGF = { .ok = FALSE };
+
+static msg_t message(const char *fmt, ...) {
+    msg_t msg = { .ok = FALSE };
+    va_list vargs;
+    va_start(vargs, fmt);
+    vsnprintf(msg.msg, 255, fmt, vargs);
+    va_end(vargs);
+    return msg;
+}
+
+/*********************************************************************************************************************/
+/* Some helper functions                                                                                             */
+/*********************************************************************************************************************/
+static msg_t check_bound(SEXP x, const bound_t bound) {
+    if (isReal(x)) {
+        const double *xp = REAL(x);
+        const double * const xend = xp + xlength(x);
+        for (; xp != xend; xp++) {
+            if (!ISNAN(*xp) && !bound.fun(*xp, bound.cmp)) {
+                if (bound.cmp == R_PosInf)
+                    return message("All elements must be %s Inf", CMPSTR[bound.op]);
+                if (bound.cmp == R_NegInf)
+                    return message("All elements must be %s -Inf", CMPSTR[bound.op]);
+                return message("All elements must be %s %g", CMPSTR[bound.op], bound.cmp);
+            }
+        }
+    } else if (isInteger(x)) {
+        const int *xp = INTEGER(x);
+        const int * const xend = xp + xlength(x);
+        for (; xp != xend; xp++) {
+            if (*xp != NA_INTEGER && !bound.fun((double) *xp, bound.cmp))
+                return message("All elements must be %s %g", CMPSTR[bound.op], bound.cmp);
+        }
+    } else if (isString(x)) {
+        const R_xlen_t nx = xlength(x);
+        double nchar;
+        for (R_xlen_t i = 0; i < nx; i++) {
+            nchar = STRING_ELT(x, i) == NA_STRING ? 0. : (double)length(STRING_ELT(x, i));
+            if (!bound.fun(nchar, bound.cmp))
+                return message("All elements must have %s %g chars", CMPSTR[bound.op], bound.cmp);
+        }
+    } else if (isFactor(x)) {
+        return check_bound(getAttrib(x, R_LevelsSymbol), bound);
+    } else {
+        error("Bound checks only possible for numeric variables, strings and factors, not %s", guess_type(x));
+    }
+
+    return MSGT;
+}
+
+/*********************************************************************************************************************/
+/* First step: Parse string and built checker_t object                                                               */
+/*********************************************************************************************************************/
+static int parse_class(checker_t *checker, const char *rule) {
+    checker->missing.fun = NULL;
+    switch(rule[0]) {
+        case 'B':
+            checker->missing.fun = &any_missing_logical;
+        case 'b':
+            checker->class.fun = &is_class_logical;
+            checker->class.name = CL_LOGICAL;
+            break;
+        case 'I':
+            checker->missing.fun = &any_missing_integer;
+        case 'i':
+            checker->class.fun = &is_class_integer;
+            checker->class.name = CL_INTEGER;
+            break;
+        case 'X':
+            checker->missing.fun = &any_missing_integerish;
+        case 'x':
+            checker->class.fun = &is_class_integerish;
+            checker->class.name = CL_INTEGERISH;
+            break;
+        case 'N':
+            checker->missing.fun = &any_missing_numeric;
+        case 'n':
+            checker->class.fun = &is_class_numeric;
+            checker->class.name = CL_NUMERIC;
+            break;
+        case 'R':
+            checker->missing.fun = &any_missing_double;
+        case 'r':
+            checker->class.fun = &is_class_double;
+            checker->class.name = CL_DOUBLE;
+            break;
+        case 'S':
+            checker->missing.fun = &any_missing_string;
+        case 's':
+            checker->class.fun = &is_class_string;
+            checker->class.name = CL_STRING;
+            break;
+        case 'F':
+            checker->missing.fun = &any_missing_integer;
+        case 'f':
+            checker->class.fun = &is_class_factor;
+            checker->class.name = CL_FACTOR;
+            break;
+        case 'L':
+            checker->missing.fun = &any_missing_list;
+        case 'l':
+            checker->class.fun = &is_class_list;
+            checker->class.name = CL_LIST;
+            break;
+        case 'C':
+            checker->missing.fun = &any_missing_complex;
+        case 'c':
+            checker->class.fun = &is_class_complex;
+            checker->class.name = CL_COMPLEX;
+            break;
+        case 'A':
+            checker->missing.fun = &any_missing_atomic;
+        case 'a':
+            checker->class.fun = &is_class_atomic;
+            checker->class.name = CL_ATOMIC;
+            break;
+        case 'V':
+            checker->missing.fun = &any_missing_atomic;
+        case 'v':
+            checker->class.fun = &is_class_atomic_vector;
+            checker->class.name = CL_ATOMIC_VECTOR;
+            break;
+        case 'M':
+            checker->missing.fun = &any_missing_matrix;
+        case 'm':
+            checker->class.fun = &is_class_matrix;
+            checker->class.name = CL_MATRIX;
+            break;
+        case 'D':
+            checker->missing.fun = &any_missing_frame;
+        case 'd':
+            checker->class.fun = &is_class_frame;
+            checker->class.name = CL_DATAFRAME;
+            break;
+        /* case 'g': */
+        /*     checker->class.fun = &is_class_function; */
+        /*     checker->class.name = CL_FUNCTION; */
+        /*     break; */
+        case 'e':
+            checker->class.fun = &is_class_environment;
+            checker->class.name = CL_ENVIRONMENT;
+            break;
+        case '0':
+            checker->class.fun = &is_class_null;
+            checker->class.name = CL_NULL;
+            break;
+        case '*':
+            checker->class.fun = NULL;
+            checker->class.name = CL_NONE;
+            break;
+        default:
+            error("Unknown class identifier '%c'", rule[0]);
+    }
+    return 1;
+}
+
+static int parse_length(checker_t *checker, const char *rule) {
+    switch(rule[0]) {
+        case '*':
+            checker->len.fun = NULL;
+            return 1;
+        case '?':
+            checker->len.fun = &ii_le;
+            checker->len.cmp = 1;
+            checker->len.op = LE;
+            return 1;
+        case '+':
+            checker->len.fun = &ii_ge;
+            checker->len.cmp = 1;
+            checker->len.op = GE;
+            return 1;
+        case '(':
+        case '[':
+        case '\0':
+            checker->len.fun = NULL;
+            checker->len.op = NONE;
+            return 0;
+    }
+
+    const char *start = rule;
+    switch(rule[0]) {
+        case '=':
+            checker->len.fun = &ii_eq;
+            checker->len.op = EQ;
+            start += 1 + (rule[1] == '=');
+            break;
+        case '<':
+            if (rule[1] == '=') {
+                checker->len.fun = &ii_le;
+                checker->len.op = LE;
+                start += 2;
+            } else {
+                checker->len.fun = &ii_lt;
+                checker->len.op = LE;
+                start += 1;
+            }
+            break;
+        case '>':
+            if (rule[1] == '=') {
+                checker->len.fun = &ii_ge;
+                checker->len.op = GE;
+                start += 2;
+            } else {
+                checker->len.fun = &ii_gt;
+                checker->len.op = GT;
+                start += 1;
+            }
+            break;
+        default:
+            checker->len.fun = &ii_eq;
+            checker->len.op = EQ;
+            break;
+    }
+
+    char *end;
+    long int cmp = strtol(start, &end, 10);
+    if (start == end)
+        error("Invalid length definition: %s", rule);
+    if (cmp >= INT_MAX)
+        error("Cannot handle length >= %i", INT_MAX);
+    if (cmp < 0)
+        error("Cannot check for negative length");
+
+    checker->len.cmp = (int)cmp;
+    return end - rule;
+}
+
+static int parse_bounds(checker_t *checker, const char *rule) {
+    switch(rule[0]) {
+        case '\0':
+            checker->lower.fun = NULL;
+            checker->upper.fun = NULL;
+            return 0;
+        case '(':
+            checker->lower.fun = &dd_gt;
+            checker->lower.op = GT;
+            break;
+        case '[':
+            checker->lower.fun = &dd_ge;
+            checker->lower.op = GE;
+            break;
+        default:
+            error("Invalid bound definition, missing opening '(' or '[': %s", rule);
+    }
+
+    char *end;
+    const char *start = rule + 1;
+    double cmp = strtod(start, &end);
+    if (start == end) {
+        if (checker->lower.op == GT) {
+            checker->lower.fun = &dd_ne;
+            checker->lower.cmp = R_NegInf;
+            checker->lower.op  = NE;
+        } else {
+            checker->lower.fun = NULL;
+        }
+    } else {
+        checker->lower.cmp = cmp;
+    }
+
+    switch(*end) {
+        case ',' : start = end + 1;
+        case ')' :
+        case ']' : break;
+        default  : error("Invalid bound definition, error parsing lower bound, missing separator ',' or missing closing ')' or ']': %s", rule);
+    }
+
+    cmp = strtod(start, &end);
+    if (*end == ')') {
+        if (start == end) {
+            checker->upper.fun = &dd_ne;
+            checker->upper.cmp = R_PosInf;
+            checker->upper.op = NE;
+        } else {
+            checker->upper.fun = &dd_lt;
+            checker->upper.cmp = cmp;
+            checker->upper.op = LT;
+        }
+    } else if (*end == ']') {
+        if (start == end) {
+            checker->upper.fun = NULL;
+        } else {
+            checker->upper.fun = &dd_le;
+            checker->upper.cmp = cmp;
+            checker->upper.op = LE;
+        }
+    } else {
+        error("Invalid bound definition, error parsing upper bound or missing closing ')' or ']': %s", rule);
+    }
+
+    return end - rule + 1;
+}
+
+static void parse_rule(checker_t *checker, const char *rule) {
+    const R_len_t nchars = strlen(rule);
+    if (nchars == 0)
+        error("Empty rule");
+
+    rule += parse_class(checker, rule);
+    rule += parse_length(checker, rule);
+    rule += parse_bounds(checker, rule);
+    if (rule[0] == '\0')
+        return;
+    error("Additional chars found!");
+}
+
+/*********************************************************************************************************************/
+/* Second step: check SEXP using a checker_t object                                                                  */
+/*********************************************************************************************************************/
+static msg_t check_rule(SEXP x, const checker_t *checker, const Rboolean err_msg) {
+    if (checker->class.fun != NULL && !checker->class.fun(x)) {
+        return err_msg ? message("Must be of class '%s', not '%s'", CLSTR[checker->class.name], guess_type(x)) : MSGF;
+    }
+
+    if (checker->missing.fun != NULL && checker->missing.fun(x)) {
+        return err_msg ? message("May not contain missing values") : MSGF;
+    }
+
+    if (checker->len.fun != NULL && !checker->len.fun(xlength(x), checker->len.cmp)) {
+        return err_msg ? message("Must be of length %s %i, but has length %g", CMPSTR[checker->len.op], checker->len.cmp, (double)xlength(x)) : MSGF;
+    }
+
+    if (checker->lower.fun != NULL) {
+        msg_t msg = check_bound(x, checker->lower);
+        if (!msg.ok)
+            return msg;
+    }
+
+    if (checker->upper.fun != NULL) {
+        msg_t msg = check_bound(x, checker->upper);
+        if (!msg.ok)
+            return msg;
+    }
+
+    return MSGT;
+}
+
+/*********************************************************************************************************************/
+/* qassert stuff                                                                                                     */
+/*********************************************************************************************************************/
+static inline R_len_t qassert1(SEXP x, const checker_t *checker, msg_t *result, const R_len_t nrules) {
+    for (R_len_t i = 0; i < nrules; i++) {
+        result[i] = check_rule(x, &checker[i], result[i].ok);
+        if (result[i].ok)
+            return 0;
+    }
+    return 1;
+}
+
+static inline R_len_t qassert_list(SEXP x, const checker_t *checker, msg_t *result, const R_len_t nrules) {
+    if (!isNewList(x) || isNull(x))
+        error("Argument 'x' must be a list or data.frame");
+
+    const R_len_t nx = xlength(x);
+    for (R_xlen_t i = 0; i < nx; i++) {
+        if (qassert1(VECTOR_ELT(x, i), checker, result, nrules) != 0)
+            return i + 1;
+    }
+    return 0;
+}
+
+/* exported for other packages */
+SEXP qassert(SEXP x, const char *rule, const char *name) {
+    checker_t checker;
+    parse_rule(&checker, rule);
+    msg_t result = check_rule(x, &checker, TRUE);
+    if (!result.ok)
+        error("Variable '%s': %s", name, result.msg);
+    return x;
+}
+
+SEXP c_qassert(SEXP x, SEXP rules, SEXP recursive) {
+    const Rboolean nrules = length(rules);
+    R_len_t failed;
+    if (!isString(rules))
+        error("Argument 'rules' must be a string");
+    if (nrules == 0)
+        return ScalarLogical(TRUE);
+
+    msg_t result[nrules];
+    checker_t checker[nrules];
+    SEXP tmp;
+    for (R_len_t i = 0; i < nrules; i++) {
+        tmp = STRING_ELT(rules, i);
+        if (tmp == NA_STRING)
+            error("Rule may not be NA");
+        parse_rule(&checker[i], CHAR(tmp));
+        result[i].ok = TRUE;
+    }
+
+    if (LOGICAL(recursive)[0]) {
+        failed = qassert_list(x, checker, result, nrules);
+    } else {
+        failed = qassert1(x, checker, result, nrules);
+    }
+
+    if (failed == 0)
+        return ScalarLogical(TRUE);
+
+    SEXP msgs = PROTECT(allocVector(STRSXP, nrules));
+    SEXP pos = PROTECT(ScalarInteger(failed));
+    setAttrib(msgs, install("pos"), pos);
+    for (R_len_t i = 0; i < nrules; i++)
+        SET_STRING_ELT(msgs, i, mkChar(result[i].msg));
+    UNPROTECT(2);
+    return msgs;
+}
+
+/*********************************************************************************************************************/
+/* qtest stuff                                                                                                       */
+/*********************************************************************************************************************/
+static inline Rboolean qtest1(SEXP x, const checker_t *checker, const R_len_t nrules) {
+    msg_t result;
+    for (R_len_t i = 0; i < nrules; i++) {
+        result = check_rule(x, &checker[i], FALSE);
+        if (result.ok)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+static inline Rboolean qtest_list(SEXP x, const checker_t *checker, const R_len_t nrules, R_len_t depth) {
+    if (!isNewList(x) || isNull(x))
+        error("Argument 'x' must be a list or data.frame");
+
+    const R_len_t nx = xlength(x);
+    if (depth > 1) {
+        for (R_xlen_t i = 0; i < nx; i++) {
+            if (isRList(VECTOR_ELT(x, i))) {
+                if (!qtest_list(VECTOR_ELT(x, i), checker, nrules, depth - 1))
+                    return FALSE;
+            } else {
+                if (!qtest1(VECTOR_ELT(x, i), checker, nrules))
+                    return FALSE;
+            }
+        }
+    } else {
+        for (R_xlen_t i = 0; i < nx; i++) {
+            if (!qtest1(VECTOR_ELT(x, i), checker, nrules))
+                return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/* exported for other packages */
+Rboolean qtest(SEXP x, const char *rule) {
+    checker_t checker;
+    parse_rule(&checker, rule);
+    return qtest1(x, &checker, 1);
+}
+
+SEXP c_qtest(SEXP x, SEXP rules, SEXP recursive, SEXP depth) {
+    const R_len_t nrules = length(rules);
+
+    if (!isString(rules))
+        error("Argument 'rules' must be a string");
+    if (nrules == 0)
+        return ScalarLogical(TRUE);
+
+    checker_t checker[nrules];
+    SEXP tmp;
+    for (R_len_t i = 0; i < nrules; i++) {
+        tmp = STRING_ELT(rules, i);
+        if (tmp == NA_STRING)
+            error("Rule may not be NA");
+        parse_rule(&checker[i], CHAR(STRING_ELT(rules, i)));
+    }
+
+    if (LOGICAL(recursive)[0])
+        return ScalarLogical(qtest_list(x, checker, nrules, asCount(depth, "depth")));
+    return ScalarLogical(qtest1(x, checker, nrules));
+}
diff --git a/src/qassert.h b/src/qassert.h
new file mode 100644
index 0000000..04ef9c1
--- /dev/null
+++ b/src/qassert.h
@@ -0,0 +1,13 @@
+#ifndef CHECKMATE_QASSERT_H_
+#define CHECKMATE_QASSERT_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+SEXP c_qassert(SEXP, SEXP, SEXP);
+SEXP c_qtest(SEXP, SEXP, SEXP, SEXP);
+SEXP qassert(SEXP, const char *, const char *);
+Rboolean qtest(SEXP, const char *);
+
+#endif
diff --git a/src/which_first.c b/src/which_first.c
new file mode 100644
index 0000000..c249a2a
--- /dev/null
+++ b/src/which_first.c
@@ -0,0 +1,49 @@
+#include "which_first.h"
+
+static inline SEXP named_return(R_len_t ind, SEXP names) {
+    if (isNull(names))
+        return ScalarInteger(ind + 1);
+
+    SEXP res;
+    PROTECT(res = ScalarInteger(ind + 1));
+    setAttrib(res, R_NamesSymbol, ScalarString(STRING_ELT(names, ind)));
+    UNPROTECT(1);
+    return res;
+}
+
+SEXP c_which_first(SEXP x, SEXP use_names) {
+    if (!isLogical(x))
+        error("Argument 'x' must be logical");
+    if (!isLogical(use_names) || length(use_names) != 1)
+        error("Argument 'use.names' must be a flag");
+    const R_len_t n = length(x);
+    int *xp = LOGICAL(x);
+
+    for (R_len_t i = 0; i < n; i++) {
+        if (xp[i] != NA_LOGICAL && xp[i]) {
+            if (LOGICAL(use_names)[0])
+                return named_return(i, getAttrib(x, R_NamesSymbol));
+            else
+                return ScalarInteger(i+1);
+        }
+    }
+    return allocVector(INTSXP, 0);
+}
+
+SEXP c_which_last(SEXP x, SEXP use_names) {
+    if (!isLogical(x))
+        error("Argument 'x' must be logical");
+    if (!isLogical(use_names) || length(use_names) != 1)
+        error("Argument 'use.names' must be a flag");
+    int *xp = LOGICAL(x);
+
+    for (R_len_t i = length(x) - 1; i >= 0; i--) {
+        if (xp[i] != NA_LOGICAL && xp[i]) {
+            if (LOGICAL(use_names)[0])
+                return named_return(i, getAttrib(x, R_NamesSymbol));
+            else
+                return ScalarInteger(i+1);
+        }
+    }
+    return allocVector(INTSXP, 0);
+}
diff --git a/src/which_first.h b/src/which_first.h
new file mode 100644
index 0000000..749cfab
--- /dev/null
+++ b/src/which_first.h
@@ -0,0 +1,11 @@
+#ifndef CHECKMATE_WHICH_FIRST_H_
+#define CHECKMATE_WHICH_FIRST_H_
+
+#define USE_RINTERNALS
+#include <R.h>
+#include <Rinternals.h>
+
+SEXP c_which_first(SEXP, SEXP);
+SEXP c_which_last(SEXP, SEXP);
+
+#endif
diff --git a/tests/test-all.R b/tests/test-all.R
new file mode 100755
index 0000000..78e828d
--- /dev/null
+++ b/tests/test-all.R
@@ -0,0 +1,2 @@
+library(testthat)
+test_check("checkmate")
diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R
new file mode 100644
index 0000000..f40d6cc
--- /dev/null
+++ b/tests/testthat/helper.R
@@ -0,0 +1,103 @@
+expect_expectation_successful = function(expr, info = NULL, label = NULL) {
+  res = tryCatch(expr, expectation = function(e) e)
+  expect_is(res, "expectation_success", info = info, label = label)
+}
+
+expect_expectation_failed = function(expr, pattern = NULL, info = NULL, label = NULL) {
+  x = tryCatch(expr, expectation = function(e) e)
+  expect_is(x, "expectation_failure", info = info, label = label)
+}
+
+expect_succ_all = function(part, x, ..., cc = as.character(substitute(part)), lc = convertCamelCase(cc)) {
+  xn = deparse(substitute(x))
+
+  # check null.ok if it is in formals
+  s = paste0("check", cc)
+  fun = match.fun(s)
+  if ("null.ok" %in% names(formals(fun))) {
+    dots = list(...)
+    dots["x"] = list(NULL)
+    dots$null.ok = TRUE
+    expect_true(do.call(fun, dots))
+  }
+
+  s = paste0("check", cc)
+  fun = match.fun(s)
+  expect_true(fun(x, ...), label = s)
+
+  s = paste0("check_", lc)
+  fun = match.fun(s)
+  expect_true(fun(x, ...), label = s)
+
+  s = paste0("test", cc)
+  fun = match.fun(s)
+  expect_true(fun(x, ...), info = s, label = xn)
+
+  s = paste0("test_", lc)
+  fun = match.fun(s)
+  expect_true(fun(x, ...), info = s, label = xn)
+
+  s = paste0("assert", cc)
+  fun = match.fun(s)
+  expect_identical(fun(x, ...), x, info = s, label = xn)
+
+  s = paste0("assert_", lc)
+  fun = match.fun(s)
+  expect_identical(fun(x, ...), x, info = s, label = xn)
+
+  s = paste0("expect_", lc)
+  fun = match.fun(s)
+  expect_expectation_successful(fun(x, ...), info = s, label = xn)
+
+  invisible(TRUE)
+}
+
+expect_fail_all = function(part, x, ..., cc = as.character(substitute(part)), lc = convertCamelCase(cc)) {
+  xn = deparse(substitute(x))
+
+  # check null.ok if it is in formals
+  s = paste0("check", cc)
+  fun = match.fun(s)
+  if ("null.ok" %in% names(formals(fun))) {
+    dots = list(...)
+    dots["x"] = list(NULL)
+    dots$null.ok = FALSE
+    expect_true(grepl("'NULL'", do.call(fun, dots), fixed = TRUE))
+  }
+
+  s = paste0("check", cc)
+  fun = match.fun(s)
+  res = fun(x, ...)
+  expect_true(is.character(res) && nzchar(res), info = s, label = xn)
+
+  s = paste0("test", cc)
+  fun = match.fun(s)
+  expect_false(fun(x, ...), info = s, label = xn)
+
+  s = paste0("test_", lc)
+  fun = match.fun(s)
+  expect_false(fun(x, ...), info = s, label = xn)
+
+  s = paste0("assert", cc)
+  fun = match.fun(s)
+  expect_error(fun(x, ..., .var.name = xn), xn, info = s, label = xn)
+  expect_error(fun(x, ...), "'x'", info = s, label = xn)
+  expect_is(tryCatch(fun(x, ...), condition = function(c) c), c("assertion_error", "error", "condition"))
+
+  s = paste0("assert_", lc)
+  fun = match.fun(s)
+  expect_error(fun(x, ..., .var.name = xn), xn, info = s, label = xn)
+  expect_error(fun(x, ...), "'x'", info = s, label = xn)
+  expect_is(tryCatch(fun(x, ...), condition = function(c) c), c("assertion_error", "error", "condition"))
+
+  s = paste0("expect_", lc)
+  fun = match.fun(s)
+  expect_expectation_failed(fun(x, ...), pattern = "x", info = s, label = xn)
+  expect_expectation_failed(fun(x, ..., label = xn), pattern = xn, info = s, label = xn)
+
+  invisible(TRUE)
+}
+
+vlapply = function (x, fun, ..., use.names = TRUE) {
+    vapply(X = x, FUN = fun, ..., FUN.VALUE = NA, USE.NAMES = use.names)
+}
diff --git a/tests/testthat/test_AssertCollection.R b/tests/testthat/test_AssertCollection.R
new file mode 100644
index 0000000..bc0a5b3
--- /dev/null
+++ b/tests/testthat/test_AssertCollection.R
@@ -0,0 +1,38 @@
+context("AssertCollection")
+
+test_that("Collection closure wors", {
+  coll = makeAssertCollection()
+  expect_is(coll, "AssertCollection")
+  expect_output(print(coll), "Empty collection")
+  expect_equal(coll$getMessages(), character(0L))
+  expect_true(coll$isEmpty())
+  coll$push("testing")
+  expect_equal(coll$getMessages(), "testing")
+  expect_false(coll$isEmpty())
+  expect_output(print(coll), "Collection of 1 assertion")
+  coll$push("foo")
+  expect_output(print(coll), "Collection of 2 assertions")
+  expect_equal(coll$getMessages(), c("testing", "foo"))
+})
+
+test_that("Reporter works", {
+  coll = makeAssertCollection()
+  expect_true(reportAssertions(coll))
+  coll$push("foo")
+  coll$push("bar")
+  expect_error(reportAssertions(coll), "foo")
+  expect_error(reportAssertions(coll), "bar")
+})
+
+test_that("asserts push to collection", {
+  coll = makeAssertCollection()
+  findme = "a"
+
+  assertString(findme, add = coll)
+  expect_true(coll$isEmpty())
+  expect_true(reportAssertions(coll))
+
+  assertNumeric(findme, add = coll)
+  expect_false(coll$isEmpty())
+  expect_error(reportAssertions(coll), "findme")
+})
diff --git a/tests/testthat/test_anyInfinite.R b/tests/testthat/test_anyInfinite.R
new file mode 100644
index 0000000..5e14030
--- /dev/null
+++ b/tests/testthat/test_anyInfinite.R
@@ -0,0 +1,33 @@
+context("anyInfinite")
+
+test_that("anyInfinite", {
+  xb = logical(10)
+  xi = integer(10)
+  xd = double(10)
+  xc = complex(10)
+  xl = as.list(1:10)
+  xm = matrix(1:9, 3)
+  xf = data.frame(a=1:5, b=1:5)
+
+  expect_false(anyInfinite(NULL))
+  expect_false(anyInfinite(mean))
+  expect_false(anyInfinite(double(0)))
+
+  expect_false(anyInfinite(xb))
+  expect_false(anyInfinite(xi))
+  expect_false(anyInfinite(xd))
+  expect_false(anyInfinite(xc))
+  expect_false(anyInfinite(xl))
+  expect_false(anyInfinite(xm))
+  expect_false(anyInfinite(xf))
+
+  xd[5] = xc[5] = xf$b[3] = Inf
+  xl[5] = -Inf
+  expect_true(anyInfinite(xd))
+  expect_true(anyInfinite(xc))
+  expect_true(anyInfinite(xl))
+  expect_true(anyInfinite(xf))
+
+  x = list(1, list(1, list(1, Inf)))
+  expect_true(anyInfinite(x))
+})
diff --git a/tests/testthat/test_anyMissing.R b/tests/testthat/test_anyMissing.R
new file mode 100644
index 0000000..04cd3bc
--- /dev/null
+++ b/tests/testthat/test_anyMissing.R
@@ -0,0 +1,95 @@
+context("anyMissing")
+
+xb = logical(10)
+xi = integer(10)
+xd = double(10)
+xc = complex(10)
+xs = letters[1:10]
+xl = as.list(1:10)
+xm = matrix(1:9, 3)
+xf = data.frame(a=1:5, b=1:5)
+
+
+test_that("anyMissing", {
+  expect_false(anyMissing(integer(0)))
+
+  expect_false(anyMissing(xb))
+  expect_false(anyMissing(xi))
+  expect_false(anyMissing(xd))
+  expect_false(anyMissing(xc))
+  expect_false(anyMissing(xs))
+  expect_false(anyMissing(xl))
+  expect_false(anyMissing(xm))
+  expect_false(anyMissing(xf))
+
+  xb[5] = xi[5] = xd[5] = xc[5] = xs[5] = xm[2, 2] = xf$b[3] = NA
+  xl[5] = list(NULL)
+  expect_true(anyMissing(xb))
+  expect_true(anyMissing(xi))
+  expect_true(anyMissing(xd))
+  expect_true(anyMissing(xc))
+  expect_true(anyMissing(xs))
+  expect_true(anyMissing(xl))
+  expect_true(anyMissing(xm))
+  expect_true(anyMissing(xf))
+
+
+  expect_false(anyMissing(as.raw(1)))
+  expect_false(anyMissing(NULL))
+  expect_error(anyMissing(as.symbol("a")), "supported")
+})
+
+test_that("allMissing", {
+  expect_true(allMissing(integer(0)))
+
+  expect_false(allMissing(xb))
+  expect_false(allMissing(xi))
+  expect_false(allMissing(xd))
+  expect_false(allMissing(xc))
+  expect_false(allMissing(xs))
+  expect_false(allMissing(xl))
+  expect_false(allMissing(xm))
+  expect_false(allMissing(xf))
+
+  xb[5] = xi[5] = xd[5] = xc[5] = xm[2, 2] = xf$b[3] = NA
+  xl[5] = list(NULL)
+
+  expect_false(allMissing(xb))
+  expect_false(allMissing(xi))
+  expect_false(allMissing(xd))
+  expect_false(allMissing(xc))
+  expect_false(allMissing(xs))
+  expect_false(allMissing(xl))
+  expect_false(allMissing(xm))
+  expect_false(allMissing(xf))
+
+  xb[] = xi[] = xd[] = xc[] = xm[] = xs = NA
+  xl = list(NULL, NULL)
+  xf$a = xf$b = NA
+
+  expect_true(allMissing(xb))
+  expect_true(allMissing(xi))
+  expect_true(allMissing(xd))
+  expect_true(allMissing(xc))
+  expect_true(allMissing(xs))
+  expect_true(allMissing(xl))
+  expect_true(allMissing(xm))
+  expect_true(allMissing(xf))
+
+  expect_false(allMissing(as.raw(1)))
+  expect_false(allMissing(NULL))
+  expect_error(allMissing(as.symbol("a")), "supported")
+})
+
+test_that("anyMissing and allMissing work correctly with data.frames", {
+  df = data.frame(a = 1:2, b = 2:1)
+  expect_false(anyMissing(df))
+  expect_false(allMissing(df))
+  df$b[1] = NA
+  expect_true(anyMissing(df))
+  expect_false(allMissing(df))
+  df$b[2] = NA
+  expect_true(anyMissing(df))
+  expect_true(allMissing(df))
+  expect_false(all(vlapply(df, allMissing)))
+})
diff --git a/tests/testthat/test_anyNaN.R b/tests/testthat/test_anyNaN.R
new file mode 100644
index 0000000..effdf05
--- /dev/null
+++ b/tests/testthat/test_anyNaN.R
@@ -0,0 +1,33 @@
+context("anyNaN")
+
+test_that("anyNaN", {
+  xb = logical(10)
+  xi = integer(10)
+  xd = double(10)
+  xc = complex(10)
+  xl = as.list(1:10)
+  xm = matrix(1:9, 3)
+  xf = data.frame(a=1:5, b=1:5)
+
+  expect_false(anyNaN(NULL))
+  expect_false(anyNaN(mean))
+  expect_false(anyNaN(double(0)))
+
+  expect_false(anyNaN(xb))
+  expect_false(anyNaN(xi))
+  expect_false(anyNaN(xd))
+  expect_false(anyNaN(xc))
+  expect_false(anyNaN(xl))
+  expect_false(anyNaN(xm))
+  expect_false(anyNaN(xf))
+
+  xd[5] = xc[5] = xf$b[3] = NaN
+  xl[5] = NaN
+  expect_true(anyNaN(xd))
+  expect_true(anyNaN(xc))
+  expect_true(anyNaN(xl))
+  expect_true(anyNaN(xf))
+
+  x = list(1, list(1, list(1, NaN)))
+  expect_true(anyNaN(x))
+})
diff --git a/tests/testthat/test_asType.R b/tests/testthat/test_asType.R
new file mode 100644
index 0000000..d696ccf
--- /dev/null
+++ b/tests/testthat/test_asType.R
@@ -0,0 +1,83 @@
+context("asType")
+
+test_that("asInteger", {
+  xi = 1:5
+  xd = as.double(1:5)
+  xc = as.complex(1:5)
+
+  expect_equal(asInteger(xi), xi)
+  expect_equal(asInteger(xd), xi)
+  expect_equal(asInteger(xc), xi)
+  expect_equal(asInteger(NA), NA_integer_)
+
+  expect_equal(names(asInteger(xi)), names(xi))
+  expect_equal(names(asInteger(xd)), names(xd))
+  expect_equal(names(asInteger(xc)), names(xc))
+  names(xi) = names(xd) = names(xc) = letters[1:5]
+  expect_equal(names(asInteger(xi)), names(xi))
+  expect_equal(names(asInteger(xd)), names(xd))
+  expect_equal(names(asInteger(xc)), names(xc))
+
+  y = "a"
+  expect_error(asInteger(y), "'y'")
+  expect_error(asInteger(3+1i))
+  expect_error(asInteger(iris))
+  expect_error(asInteger(NA, any.missing = FALSE), "missing")
+})
+
+test_that("asInt", {
+  xi = 1L
+  xd = 1.
+  xc = as.complex(1)
+
+  expect_equal(names(asInt(xi)), names(xi))
+  expect_equal(names(asInt(xd)), names(xd))
+  expect_equal(names(asInt(xc)), names(xc))
+  names(xi) = names(xd) = names(xc) = "a"
+  expect_equal(names(asInt(xi)), names(xi))
+  expect_equal(names(asInt(xd)), names(xd))
+  expect_equal(names(asInt(xc)), names(xc))
+
+  expect_error(asInt(letters[1:2]), "integerish")
+  expect_error(asInt(1:2), "length 1")
+  expect_equal(asInt(xi), xi)
+  expect_equal(asInt(xd), xi)
+  expect_equal(asInt(xc), xi)
+  expect_error(asInt(NA), "NA")
+  expect_equal(asInt(NA, na.ok = TRUE), NA_integer_)
+
+  y = "a"
+  expect_error(asInt(y), "'y'")
+  expect_error(asInt(3+1i))
+  expect_error(asInt(iris))
+  expect_error(asInt(xi, lower = 2), ">=")
+})
+
+test_that("asCount", {
+  xi = 1L
+  xd = 1.
+  xc = as.complex(1)
+
+  expect_equal(names(asCount(xi)), names(xi))
+  expect_equal(names(asCount(xd)), names(xd))
+  expect_equal(names(asCount(xc)), names(xc))
+  names(xi) = names(xd) = names(xc) = "a"
+  expect_equal(names(asCount(xi)), names(xi))
+  expect_equal(names(asCount(xd)), names(xd))
+  expect_equal(names(asCount(xc)), names(xc))
+
+  expect_error(asCount(letters[1:2]), "count")
+  expect_error(asCount(1:2), "length 1")
+  expect_equal(asCount(xi), xi)
+  expect_equal(asCount(xd), xi)
+  expect_equal(asCount(xc), xi)
+  expect_error(asCount(NA), "NA")
+  expect_equal(asCount(NA, na.ok = TRUE), NA_integer_)
+
+  y = "a"
+  expect_error(asCount(y), "'y'")
+  expect_error(asCount(3+1i))
+  expect_error(asCount(iris))
+  expect_error(asCount(0, positive = TRUE))
+  expect_equal(asCount(1, positive = FALSE), 1L)
+})
diff --git a/tests/testthat/test_assert.R b/tests/testthat/test_assert.R
new file mode 100644
index 0000000..ede095c
--- /dev/null
+++ b/tests/testthat/test_assert.R
@@ -0,0 +1,33 @@
+context("assert")
+
+test_that("assert w/ check*", {
+  x = NULL
+  expect_true(assert(checkNull(x), checkDataFrame(x)))
+  expect_true(assert(checkNull(x)))
+  grepme = iris
+  expect_true(assert(checkNull(grepme), checkDataFrame(grepme)))
+  expect_error(assert(checkNull(grepme), checkNumeric(grepme)), "One of")
+  expect_error(assert(checkNull(grepme), checkNumeric(grepme)), "grepme")
+
+  x = 1
+  expect_true(assert(checkNumeric(x), checkCount(x)))
+  expect_true(assert(checkNumeric(x), checkCount(x), combine = "or"))
+  expect_true(assert(checkNumeric(x), checkCount(x), combine = "and"))
+
+  x = 1.1
+  expect_true(assert(checkNumeric(x), checkCount(x), combine = "or"))
+  expect_error(assert(checkNumeric(x), checkCount(x), combine = "and"))
+
+  x = "a"
+  expect_true(assert(checkString(x)))
+  expect_error(assert(checkNumeric(x), checkCount(x), combine = "or"))
+  expect_error(assert(checkNumeric(x), checkCount(x), combine = "and"))
+})
+
+test_that("bug #69", {
+  sub = subset = 1:150
+  res = assert(checkIntegerish(subset), checkLogical(subset, len = 150))
+  expect_true(res)
+  res = assert(checkIntegerish(sub), checkLogical(sub, len = 150))
+  expect_true(res)
+})
diff --git a/tests/testthat/test_checkArray.R b/tests/testthat/test_checkArray.R
new file mode 100644
index 0000000..6d17583
--- /dev/null
+++ b/tests/testthat/test_checkArray.R
@@ -0,0 +1,52 @@
+context("checkArray")
+
+test_that("checkArray", {
+  myobj = array(1:2)
+  expect_succ_all(Array, myobj)
+  myobj = 1:2
+  expect_fail_all(Array, myobj)
+
+  x = array(dim = c(2, 3))
+  expect_true(testArray(x))
+  expect_true(testArray(x, d = 2L))
+  expect_false(testArray(x, d = 1L))
+  expect_true(testArray(x, min.d = 0L))
+  expect_true(testArray(x, min.d = 1L))
+  expect_true(testArray(x, max.d = 2L))
+  expect_true(testArray(x, max.d = 3L))
+  expect_false(testArray(x, min.d = 3L))
+  expect_false(testArray(x, max.d = 1L))
+
+  x[2,2] = NA
+  expect_true(testMatrix(x))
+  expect_false(testMatrix(x, any.missing = FALSE))
+  expect_false(testArray(x, any.missing = FALSE))
+  expect_error(assertArray(iris))
+
+  x = array(1:27, dim = c(3, 3, 3))
+  expect_true(testArray(x, mode = "integer"))
+  expect_true(testArray(x, mode = "numeric"))
+  expect_true(testArray(x, mode = "atomic"))
+  expect_false(testArray(x, mode = "double"))
+  expect_false(testArray(x, mode = "character"))
+  expect_false(testArray(x, mode = "list"))
+
+  x = array(list(1, 1), dim = c(1, 2))
+  expect_true(testArray(x))
+  expect_true(testArray(x, mode = "list"))
+  expect_false(testArray(x, mode = "atomic"))
+  expect_false(testArray(x, mode = "numeric"))
+
+  expect_error(assertArray(1:3), "array")
+})
+
+test_that("type guessing works", {
+  x = array(1:4)
+  expect_match(checkCharacter(x), "array")
+
+  x = array(1:4, dim = c(2, 2))
+  expect_match(checkCharacter(x), "matrix")
+
+  x = array(1:9, dim = c(3, 3, 3))
+  expect_match(checkCharacter(x), "array")
+})
diff --git a/tests/testthat/test_checkAtomic.R b/tests/testthat/test_checkAtomic.R
new file mode 100644
index 0000000..cb9b626
--- /dev/null
+++ b/tests/testthat/test_checkAtomic.R
@@ -0,0 +1,51 @@
+context("checkAtomic")
+
+li = list(
+  list = list(1, 2),
+  factor = factor("a"),
+  integer = 1:2,
+  NULL = NULL,
+  data.frame = iris
+)
+
+test_that("checkAtomic", {
+  myobj = 1:2
+  expect_succ_all(Atomic, myobj)
+  myobj = iris
+  expect_fail_all(Atomic, myobj)
+
+  expect_true(testAtomic(integer(0)))
+  expect_true(testAtomic(NULL))
+  expect_true(testAtomic(1))
+  expect_true(testAtomic(integer(0)))
+  expect_true(testAtomic(factor(1)))
+
+  expect_true(testAtomic(NA, any.missing = TRUE))
+  expect_false(testAtomic(NA, any.missing = FALSE))
+  expect_false(testAtomic(NA, all.missing = FALSE))
+
+  expect_true(testAtomic(1, len=1))
+  expect_false(testAtomic(1, len=0))
+
+  expect_true(testAtomic(1, min.len=0))
+  expect_false(testAtomic(1, min.len=2))
+  expect_true(testAtomic(1, max.len=1))
+  expect_false(testAtomic(1, max.len=0))
+
+  expect_true(testAtomic(1, unique=TRUE))
+  expect_false(testAtomic(1, min.len=2))
+  expect_true(testAtomic(1, max.len=1))
+  expect_false(testAtomic(1, max.len=0))
+
+  expect_true(testAtomic(1, unique=TRUE))
+  expect_true(testAtomic(c(1,1), unique=FALSE))
+  expect_false(testAtomic(c(1,1), unique=TRUE))
+
+  expect_true(testAtomic(1, names="unnamed"))
+  expect_true(testAtomic(setNames(1, "x"), names="named"))
+  expect_false(testAtomic(1, names="unique"))
+
+  expect_error(assertAtomic(iris), "atomic")
+
+  expect_equal(vlapply(li, is.atomic), vlapply(li, testAtomic))
+})
diff --git a/tests/testthat/test_checkAtomicVector.R b/tests/testthat/test_checkAtomicVector.R
new file mode 100644
index 0000000..fb3f566
--- /dev/null
+++ b/tests/testthat/test_checkAtomicVector.R
@@ -0,0 +1,50 @@
+context("checkAtomicVector")
+
+test_that("checkAtomicVector", {
+  myobj = 1:2
+  expect_succ_all(AtomicVector, myobj)
+  myobj = NULL
+  expect_fail_all(AtomicVector, myobj)
+
+  expect_true(testAtomicVector(integer(0)))
+  expect_false(testAtomicVector(NULL))
+  expect_true(testAtomicVector(1))
+  expect_true(testAtomicVector(integer(0)))
+  expect_true(testAtomicVector(factor(1)))
+
+  expect_true(testAtomicVector(NA, any.missing = TRUE))
+  expect_false(testAtomicVector(NA, any.missing = FALSE))
+  expect_false(testAtomicVector(NA, all.missing = FALSE))
+
+  expect_true(testAtomicVector(1, len=1))
+  expect_false(testAtomicVector(1, len=0))
+
+  expect_true(testAtomicVector(1, min.len=0))
+  expect_false(testAtomicVector(1, min.len=2))
+  expect_true(testAtomicVector(1, max.len=1))
+  expect_false(testAtomicVector(1, max.len=0))
+
+  expect_true(testAtomicVector(1, unique=TRUE))
+  expect_false(testAtomicVector(1, min.len=2))
+  expect_true(testAtomicVector(1, max.len=1))
+  expect_false(testAtomicVector(1, max.len=0))
+
+  expect_true(testAtomicVector(1, unique=TRUE))
+  expect_true(testAtomicVector(c(1,1), unique=FALSE))
+  expect_false(testAtomicVector(c(1,1), unique=TRUE))
+
+  expect_true(testAtomicVector(1, names="unnamed"))
+  expect_true(testAtomicVector(setNames(1, "x"), names="named"))
+  expect_false(testAtomicVector(1, names="unique"))
+
+  expect_error(assertAtomicVector(iris), "atomic")
+
+  li = list(list = list(1, 2), factor = factor("a"), integer = 1:2, NULL = NULL, data.frame = iris, matrix = matrix(1:9))
+  expected = setNames(c(FALSE, TRUE, TRUE, FALSE, FALSE, FALSE), names(li))
+  expect_equal(expected, vlapply(li, testAtomicVector))
+})
+
+test_that("type guessing works (#48)", {
+  x = structure(list(1:4, letters[1:3]), dim = c(2, 1))
+  expect_match(checkAtomic(x), "list")
+})
diff --git a/tests/testthat/test_checkCharacter.R b/tests/testthat/test_checkCharacter.R
new file mode 100644
index 0000000..b95fd7a
--- /dev/null
+++ b/tests/testthat/test_checkCharacter.R
@@ -0,0 +1,40 @@
+context("checkCharacter")
+
+test_that("checkCharacter", {
+  myobj = c("a", "b")
+  expect_succ_all(Character, myobj)
+  myobj = 0
+  expect_fail_all(Character, myobj)
+
+  expect_true(testCharacter(character(0)))
+  expect_false(testCharacter(NULL))
+  expect_true(testCharacter("a"))
+  expect_false(testCharacter(1))
+  expect_true(testCharacter(NA))
+  expect_true(testCharacter(NA_character_))
+
+  expect_true(testCharacter("a", min.chars = 1))
+  expect_false(testCharacter("a", min.chars = 2))
+  # treat NA_character_ as zero-length string
+  expect_true(testCharacter(NA_character_, min.chars = 0))
+  expect_false(testCharacter(NA_character_, min.chars = 1))
+  expect_false(testCharacter(NA, min.chars = 1))
+
+  x = c("abba", "baab")
+  expect_true(testCharacter(x, pattern="a"))
+  expect_true(testCharacter(x, pattern="ab"))
+  expect_false(testCharacter(x, pattern="aa"))
+  expect_false(testCharacter(x, pattern="^ab"))
+  expect_true(testCharacter(x, pattern="AB", ignore.case=TRUE))
+  expect_true(testCharacter(x, pattern="AB", ignore.case=TRUE))
+  expect_false(testCharacter(x, pattern="AB", ignore.case=FALSE))
+  expect_false(testCharacter(x, pattern="AB", ignore.case=FALSE))
+  expect_true(testCharacter(x, pattern="a+"))
+  expect_false(testCharacter(x, fixed="a+"))
+
+  x = letters[1:3]
+  expect_true(testCharacter(x, any.missing=FALSE, min.len=1L, max.len=3L))
+  expect_false(testCharacter(x, any.missing=FALSE, len=5))
+
+  expect_error(assertCharacter(1), "character")
+})
diff --git a/tests/testthat/test_checkChoice.R b/tests/testthat/test_checkChoice.R
new file mode 100644
index 0000000..e8214ec
--- /dev/null
+++ b/tests/testthat/test_checkChoice.R
@@ -0,0 +1,23 @@
+context("checkChoice")
+
+test_that("checkChoice", {
+  myobj = 1
+  expect_succ_all(Choice, myobj, 1:3)
+  myobj = 0
+  expect_fail_all(Choice, myobj, 1:3)
+
+  expect_false(testChoice(character(0), letters))
+  expect_false(testChoice(NULL, letters))
+  expect_false(testChoice(1, NULL))
+  expect_error(testChoice(list(1), as.list(iris)), "atomic")
+  expect_true(testChoice(factor("a"), letters))
+  expect_true(testChoice(factor("a"), factor(letters)))
+
+  expect_true(testChoice(1L, 1:10))
+  expect_false(testChoice("ab", letters))
+  expect_false(testChoice(NA_integer_, 1:10))
+  expect_false(testChoice(1:2, 1:10))
+
+  expect_error(assertChoice(-1, 1:2), "element of")
+  expect_error(assertChoice(1L, list()), "atomic")
+})
diff --git a/tests/testthat/test_checkClass.R b/tests/testthat/test_checkClass.R
new file mode 100644
index 0000000..8dbf7c9
--- /dev/null
+++ b/tests/testthat/test_checkClass.R
@@ -0,0 +1,31 @@
+context("checkClass")
+
+test_that("checkClass", {
+  myobj = 1
+  expect_succ_all(Class, myobj, "numeric")
+  expect_fail_all(Class, myobj, "integer")
+
+  expect_true(testClass(NULL, "NULL"))
+  expect_true(testClass(1, "numeric"))
+  expect_true(testClass(1L, "integer"))
+  expect_false(testClass(1, "integer"))
+
+  foo = 1
+  class(foo) = c("a", "b")
+  expect_true(testClass(foo, "a"))
+  expect_true(testClass(foo, "b"))
+  expect_false(testClass(foo, "c"))
+  expect_true(testClass(foo, "a", ordered=TRUE))
+  expect_false(testClass(foo, "b", ordered=TRUE))
+  expect_true(testClass(foo, c("a", "b"), ordered=TRUE))
+  expect_false(testClass(foo, c("b", "a"), ordered=TRUE))
+
+  foo = 1
+  class(foo) = c("a", "b")
+  expect_error(assertClass(foo, "c"), "Must have class 'c', but has classes 'a','b'")
+  expect_error(assertClass(foo, "b", ordered=TRUE), "Must have class 'b' in position 1, but has classes 'a','b'")
+
+  foo = 1
+  class(foo) = "a"
+  expect_error(assertClass(foo, "c"), "Must have class 'c', but has class 'a'")
+})
diff --git a/tests/testthat/test_checkComplex.R b/tests/testthat/test_checkComplex.R
new file mode 100644
index 0000000..a37e752
--- /dev/null
+++ b/tests/testthat/test_checkComplex.R
@@ -0,0 +1,21 @@
+context("checkComplex")
+
+test_that("checkComplex", {
+  myobj = 1+1i
+  expect_succ_all(Complex, myobj)
+  myobj = 1
+  expect_fail_all(Complex, myobj)
+
+  expect_true(testComplex(complex(0L)))
+  expect_false(testComplex(NULL))
+  expect_false(testComplex(TRUE))
+  expect_true(testComplex(NA))
+  expect_false(testComplex(NA, any.missing = FALSE))
+  expect_false(testComplex(NA, all.missing = FALSE))
+  expect_true(testComplex(NA_complex_))
+  expect_true(testComplex(1+1i))
+  expect_true(testComplex(as.complex(Inf)))
+  expect_true(testComplex(c(1+1i, 2+1i), any.missing = FALSE, min.len = 1L, max.len = 3L))
+
+  expect_error(assertComplex(1), "complex")
+})
diff --git a/tests/testthat/test_checkCount.R b/tests/testthat/test_checkCount.R
new file mode 100644
index 0000000..17cef97
--- /dev/null
+++ b/tests/testthat/test_checkCount.R
@@ -0,0 +1,27 @@
+context("checkCount")
+
+test_that("checkCount", {
+  myobj = 1
+  expect_succ_all(Count, myobj)
+  myobj = -1
+  expect_fail_all(Count, myobj)
+
+  expect_false(testCount(integer(0)))
+  expect_false(testCount(NULL))
+  expect_false(testCount(FALSE))
+  expect_false(testCount(TRUE))
+
+  expect_true(testCount(0L))
+  expect_false(testCount(0L, positive = TRUE))
+  expect_true(testCount(1L, positive = TRUE))
+  expect_true(testCount(1))
+  expect_true(testCount(0))
+  expect_false(testCount(-1))
+  expect_false(testCount(0.5))
+  expect_false(testCount(NA_integer_))
+  expect_true(testCount(NA, na.ok = TRUE))
+  expect_true(testCount(NA_integer_, na.ok = TRUE))
+  expect_false(testCount(1:2))
+
+  expect_error(assertCount(-1), ">= 0")
+})
diff --git a/tests/testthat/test_checkDataFrame.R b/tests/testthat/test_checkDataFrame.R
new file mode 100644
index 0000000..f67f11f
--- /dev/null
+++ b/tests/testthat/test_checkDataFrame.R
@@ -0,0 +1,91 @@
+context("checkDataFrame")
+
+test_that("checkDataFrame", {
+  myobj = iris
+  expect_succ_all(DataFrame, myobj)
+  myobj = TRUE
+  expect_fail_all(DataFrame, myobj)
+
+  expect_true(testDataFrame(data.frame()))
+  expect_false(testDataFrame(NULL))
+  expect_true(testDataFrame(data.frame(1)))
+  expect_true(testDataFrame(iris))
+  expect_false(testDataFrame(list(1)))
+
+  x = iris
+  expect_true(testDataFrame(x, types = c("numeric", "factor")))
+  expect_false(testDataFrame(x, types = c("integer", "factor")))
+  expect_false(testDataFrame(x, types = c("numeric", "character")))
+  expect_true(testDataFrame(data.frame(), types = "NULL"))
+
+  expect_true(testDataFrame(data.frame(), types = "numeric"))
+  expect_error(assertDataFrame(1), "data.frame")
+  expect_error(assertDataFrame(x, types = "numeric"), "types: numeric")
+
+  # check nrow and ncol constraints
+  expect_true(testDataFrame(x, nrows = 150L, ncols = 5L))
+  expect_false(testDataFrame(x, nrows = 150L, ncols = 7L))
+  expect_true(testDataFrame(x, min.rows = 2L, min.cols = 4L))
+  expect_false(testDataFrame(x, min.rows = 151L, min.cols = 4L))
+  expect_false(testDataFrame(x, min.rows = 1L, min.cols = 6L))
+})
+
+
+test_that("checkDataFrame name checking works", {
+  df = data.frame(x = 1:2, y = 1:2)
+  names(df) = c("x", "x")
+  expect_identical(assertDataFrame(df), df)
+  expect_error(assertDataFrame(df, col.names = "unnamed"), "unnamed")
+
+  names(df) = c("x", "")
+  expect_error(assertDataFrame(df, col.names = "named"), "named")
+
+  names(df) = c("x", "x")
+  expect_identical(assertDataFrame(df, col.names = "named"), df)
+  expect_error(assertDataFrame(df, col.names = "unique"), "uniquely")
+  expect_error(assertDataFrame(df, col.names = "strict"), "uniquely")
+  expect_error(assertDataFrame(df, col.names = "foo"), "unnamed")
+
+  names(df) = c("x", "1")
+  expect_identical(assertDataFrame(df, col.names = "named"), df)
+  expect_identical(assertDataFrame(df, col.names = "unique"), df)
+  expect_error(assertDataFrame(df, col.names = "strict"), "naming rules")
+
+  rownames(df) = letters[1:2]
+  expect_succ_all(DataFrame, df, row.names = "strict")
+  expect_succ_all(DataFrame, df, row.names = "unique")
+  expect_succ_all(DataFrame, df, row.names = "named")
+  expect_fail_all(DataFrame, df, row.names = "unnamed")
+
+  rownames(df) = NULL
+  expect_fail_all(DataFrame, df, row.names = "unnamed") # no names defaults to as.character(seq_row(x))
+  expect_succ_all(DataFrame, df, row.names = "named")
+  expect_succ_all(DataFrame, df, row.names = "unique")
+  expect_fail_all(DataFrame, df, row.names = "strict")
+})
+
+test_that("dimension checks work for empty frames", {
+  x = iris[, -c(1:5)]
+  expect_true(testDataFrame(x, min.rows = 5))
+  expect_true(testDataFrame(x, nrows = 150))
+  expect_false(testDataFrame(x, min.rows = 151))
+  expect_false(testDataFrame(x, nrows = 1))
+
+  x = iris[-c(1:150), ]
+  expect_true(testDataFrame(x, min.cols = 1))
+  expect_true(testDataFrame(x, ncols = 5))
+  expect_false(testDataFrame(x, min.cols = 6))
+  expect_false(testDataFrame(x, ncols = 1))
+})
+
+test_that("missing values are detected", {
+  x = data.frame(a = 1:2, b = c(1, 2))
+  expect_true(testDataFrame(x, any.missing = FALSE))
+  expect_true(testDataFrame(x, all.missing = FALSE))
+  x$b[1] = NA
+  expect_false(testDataFrame(x, any.missing = FALSE))
+  expect_true(testDataFrame(x, all.missing = FALSE))
+  x$b[2] = NA
+  expect_false(testDataFrame(x, any.missing = FALSE))
+  expect_false(testDataFrame(x, all.missing = FALSE))
+})
diff --git a/tests/testthat/test_checkDataTable.R b/tests/testthat/test_checkDataTable.R
new file mode 100644
index 0000000..9deeb20
--- /dev/null
+++ b/tests/testthat/test_checkDataTable.R
@@ -0,0 +1,35 @@
+context("checkDataTable")
+
+test_that("checkDataTable", {
+  skip_if_not_installed("data.table")
+  library(data.table)
+
+  dt = as.data.table(iris)
+  expect_succ_all("DataTable", dt)
+  expect_fail_all("DataTable", iris)
+
+  expect_true(testDataTable(dt, min.rows = 1, ncols = 5))
+  expect_false(testDataTable(dt, min.rows = 1000, ncols = 5))
+
+  expect_true(testDataTable(dt, key = character(0)))
+  expect_true(testDataTable(dt, index = character(0)))
+
+  setkeyv(dt, "Species")
+  expect_true(testDataTable(dt, key = "Species"))
+  expect_false(testDataTable(dt, index = "Species"))
+
+  dt = as.data.table(iris)
+  setkeyv(dt, "Species", physical = FALSE)
+  expect_false(testDataTable(dt, key = "Species"))
+  expect_true(testDataTable(dt, index = "Species"))
+
+  dt = as.data.table(iris)
+  setkeyv(dt, c("Petal.Width", "Petal.Length"), physical = TRUE)
+  setkeyv(dt, c("Sepal.Length", "Sepal.Width"), physical = FALSE)
+  expect_true(testDataTable(dt, key = c("Petal.Width", "Petal.Length"), index = c("Sepal.Width", "Sepal.Length")))
+
+  expect_error(testDataTable(dt, key = 1), "string")
+  expect_error(testDataTable(dt, index = 1), "string")
+  expect_error(assertDataTable(dt, key = "Species"), "primary keys")
+  expect_error(assertDataTable(dt, index = "Species"), "secondary keys")
+})
diff --git a/tests/testthat/test_checkDate.R b/tests/testthat/test_checkDate.R
new file mode 100644
index 0000000..66f1dc1
--- /dev/null
+++ b/tests/testthat/test_checkDate.R
@@ -0,0 +1,32 @@
+context("checkDate")
+
+test_that("checkDate", {
+  x = Sys.Date()
+  expect_succ_all(Date, x)
+  expect_fail_all(Date, 1)
+
+  expect_true(testDate(x, lower = 1))
+  expect_true(testDate(x, upper = as.integer(x + 2)))
+  expect_error(assertDate(x, lower = x + 2), ">=")
+  expect_error(assertDate(x, upper = x - 2), "<=")
+
+  expect_true(testDate(x, upper = x + 2))
+  expect_false(testDate(x, upper = x - 2))
+  expect_true(testDate(x, lower = x - 2))
+  expect_false(testDate(x, lower = x + 2))
+
+  expect_error(assertDate(x, lower = 1:2), "single")
+  expect_error(assertDate(x, lower = NA), "single")
+  expect_error(assertDate(x, lower = integer(0)), "single")
+  expect_error(assertDate(x, upper = 1:2), "single")
+  expect_error(assertDate(x, upper = NA), "single")
+  expect_error(assertDate(x, upper = integer(0)), "single")
+
+
+  x = as.Date(NA)
+  expect_error(assertDate(x, any.missing = FALSE), "missing")
+  x = rep(Sys.Date(), 2)
+  expect_error(assertDate(x, unique = TRUE), "duplicated")
+
+  expect_error(assertDate(letters, unique = TRUE), "character")
+})
diff --git a/tests/testthat/test_checkEnvironment.R b/tests/testthat/test_checkEnvironment.R
new file mode 100644
index 0000000..16e5651
--- /dev/null
+++ b/tests/testthat/test_checkEnvironment.R
@@ -0,0 +1,24 @@
+context("checkEnvironment")
+
+test_that("checkEnvironment", {
+  myobj = new.env()
+  expect_succ_all(Environment, myobj)
+  myobj = list()
+  expect_fail_all(Environment, myobj)
+
+  ee = new.env(parent = emptyenv())
+  ee$yyy = 1
+  ee$zzz = 1
+
+  expect_false(testEnvironment(NULL))
+  expect_false(testEnvironment(list()))
+  expect_true(testEnvironment(ee))
+
+  expect_false(testEnvironment(ee, contains = "xxx"))
+  expect_true(testEnvironment(ee, contains = "yyy"))
+  expect_true(testEnvironment(ee, contains = c("yyy", "zzz")))
+
+  expect_error(assertEnvironment(list()), "environment")
+  expect_error(assertEnvironment(ee, "xxx"), "with name")
+  expect_error(assertEnvironment(letters), "character")
+})
diff --git a/tests/testthat/test_checkFactor.R b/tests/testthat/test_checkFactor.R
new file mode 100644
index 0000000..f7e4a69
--- /dev/null
+++ b/tests/testthat/test_checkFactor.R
@@ -0,0 +1,49 @@
+context("checkFactor")
+
+test_that("checkFactor", {
+  myobj = factor(letters[1:2])
+  expect_succ_all(Factor, myobj)
+  myobj = letters[1:2]
+  expect_fail_all(Factor, myobj)
+
+  x = factor(c("a", "b"), levels = c("a", "b"))
+  expect_true(testFactor(x))
+  expect_false(testFactor(integer(1)))
+  expect_false(testFactor("a"))
+  expect_true(testFactor(factor()))
+  # expect_false(testFactor(integer(0)))
+  expect_false(testFactor(NULL))
+  expect_true(testFactor(x, levels = rev(levels(x))))
+  expect_true(testFactor(x, empty.levels.ok = FALSE))
+  expect_true(testFactor(x, ordered = FALSE))
+
+  expect_false(testFactor(x, levels = c("a")))
+  expect_false(testFactor(x, levels = c("a", "b", "c")))
+
+  x = factor(c("a", "b"), levels = c("a", "b", "c"), ordered = TRUE)
+  expect_true(testFactor(x, empty.levels.ok = TRUE))
+  expect_false(testFactor(x, empty.levels.ok = FALSE))
+  expect_true(testFactor(x, ordered = TRUE))
+  expect_false(testFactor(x, ordered = FALSE))
+
+
+  x = factor(c("a", "b"), levels = c("a", "b", "c"))
+  expect_error(assertFactor(1), "factor")
+  expect_error(assertFactor(x, levels = c("a")), "levels")
+  expect_error(assertFactor(x, empty.levels.ok = FALSE), "empty")
+  expect_error(assertFactor(x, ordered = TRUE), "ordered")
+  x = as.ordered(x)
+  expect_error(assertFactor(x, ordered = FALSE), "unordered")
+
+
+  x = factor(c("a", "b"))
+  expect_true(testFactor(x, n.levels = 2))
+  expect_true(testFactor(x, min.levels = 2))
+  expect_true(testFactor(x, max.levels = 2))
+  expect_false(testFactor(x, n.levels = 1))
+  expect_false(testFactor(x, min.levels = 3))
+  expect_false(testFactor(x, max.levels = 1))
+
+  expect_error(testFactor(x, n.levels = NA))
+  expect_error(assertFactor(x, n.levels = 1), "exactly 1 level")
+})
diff --git a/tests/testthat/test_checkFilesystem.R b/tests/testthat/test_checkFilesystem.R
new file mode 100644
index 0000000..fd6e237
--- /dev/null
+++ b/tests/testthat/test_checkFilesystem.R
@@ -0,0 +1,87 @@
+context("checkFile")
+
+td = tempfile("checkFile")
+dir.create(td, recursive=TRUE)
+fn = file.path(td, "myfile.ext")
+dn = file.path(td, "dir")
+ff = file.path(td, "xxx")
+file.create(fn)
+dir.create(dn)
+
+test_that("checkFile", {
+  myobj = fn
+  expect_succ_all(FileExists, myobj)
+  myobj = ff
+  expect_fail_all(FileExists, myobj)
+
+  expect_false(testFileExists(character(0)))
+  expect_false(testFileExists(NULL))
+  expect_false(testFileExists(dn))
+
+  expect_error(assertFileExists(character(0)), "provided")
+  expect_error(assertFileExists(ff), "exist")
+  expect_error(assertFileExists(dn))
+
+  expect_succ_all(FileExists, fn, extension = "ext")
+  expect_succ_all(FileExists, fn, extension = c("foo", "ext"))
+  expect_fail_all(FileExists, fn, extension = "foo")
+})
+
+test_that("check_directory", {
+  myobj = dn
+  expect_succ_all(DirectoryExists, myobj)
+  myobj = ff
+  expect_fail_all(DirectoryExists, myobj)
+
+  expect_false(testDirectoryExists(character(0)))
+  expect_false(testDirectoryExists(fn))
+
+  expect_error(assertDirectoryExists(character(0)), "provided")
+  expect_error(assertDirectoryExists(ff), "exist")
+  expect_error(assertDirectoryExists(fn))
+})
+
+test_that("check_access", {
+  myobj = R.home()
+  expect_succ_all(Access, myobj, "r")
+
+  if (.Platform$OS.type != "windows") {
+    Sys.chmod(fn, "0000")
+    expect_true(testAccess(fn, ""))
+    expect_false(testAccess(fn, "r"))
+    expect_false(testAccess(fn, "w"))
+    expect_false(testAccess(fn, "x"))
+    Sys.chmod(fn, "0700")
+    expect_true(testAccess(fn, ""))
+    expect_true(testAccess(fn, "r"))
+    expect_true(testAccess(fn, "w"))
+    expect_true(testAccess(fn, "x"))
+    Sys.chmod(fn, "0600")
+    expect_true(testAccess(fn, ""))
+    expect_true(testAccess(fn, "r"))
+    expect_true(testAccess(fn, "rw"))
+    expect_false(testAccess(fn, "rx"))
+    expect_false(testAccess(fn, "wx"))
+
+    expect_error(testAccess(fn, "a"))
+    expect_error(testAccess(fn, "rrr"))
+  }
+})
+
+test_that("check_path_for_output", {
+  myobj = ff
+  expect_succ_all(PathForOutput, myobj)
+  myobj = fn
+  expect_fail_all(PathForOutput, myobj)
+
+  expect_false(testPathForOutput(character(0)))
+  expect_false(testPathForOutput(NULL))
+
+  expect_error(assertPathForOutput(character(0)), "path provided")
+  expect_identical(assertPathForOutput(c("a", "b")), c("a", "b"))
+  expect_identical(assertPathForOutput(ff), ff)
+  expect_error(assertPathForOutput(fn), "exist")
+  expect_identical(assertPathForOutput(fn, overwrite = TRUE), fn)
+  expect_true(testPathForOutput(c(fn, ff, dn), overwrite = TRUE))
+  expect_false(testPathForOutput(c(fn, ff, dn), overwrite = FALSE))
+})
diff --git a/tests/testthat/test_checkFlag.R b/tests/testthat/test_checkFlag.R
new file mode 100644
index 0000000..9ec60ef
--- /dev/null
+++ b/tests/testthat/test_checkFlag.R
@@ -0,0 +1,19 @@
+context("checkFlag")
+
+test_that("checkFlag", {
+  myobj = TRUE
+  expect_succ_all(Flag, myobj)
+  myobj = NA
+  expect_fail_all(Flag, myobj)
+
+  expect_false(testFlag(logical(0)))
+  expect_false(testFlag(NULL))
+  expect_true(testFlag(TRUE))
+  expect_true(testFlag(FALSE))
+  expect_false(testFlag(NA))
+  expect_true(testFlag(NA, na.ok = TRUE))
+  expect_true(testFlag(NA_character_, na.ok = TRUE))
+  expect_false(testFlag(iris))
+
+  expect_error(assertFlag(1), "logical flag")
+})
diff --git a/tests/testthat/test_checkFunction.R b/tests/testthat/test_checkFunction.R
new file mode 100644
index 0000000..1c75800
--- /dev/null
+++ b/tests/testthat/test_checkFunction.R
@@ -0,0 +1,42 @@
+context("checkFunction")
+
+test_that("checkFunction", {
+  myobj = mean
+  expect_succ_all(Function, myobj)
+  myobj = TRUE
+  expect_fail_all(Function, myobj)
+
+  myfun = function(x, y, ...) x + y
+
+  expect_false(testFunction(NULL))
+  expect_true(testFunction(identity))
+  expect_true(testFunction(myfun))
+  expect_false(testFunction("myfun"))
+  expect_false(testFunction("myfun"))
+
+  expect_true(testFunction(myfun, args = "x"))
+  expect_true(testFunction(myfun, args = "..."))
+  expect_true(testFunction(myfun, args = "x", ordered=TRUE))
+  expect_true(testFunction(myfun, args = "y"))
+  expect_true(testFunction(myfun, args = c("x", "y")))
+  expect_true(testFunction(myfun, args = c("x", "y", "...")))
+  expect_true(testFunction(myfun, args = c("y", "x")))
+  expect_true(testFunction(myfun, args = c("x", "y"), ordered=TRUE))
+  expect_false(testFunction(myfun, args = "z"))
+  expect_false(testFunction(myfun, args = c("y"), ordered=TRUE))
+  expect_false(testFunction(myfun, args = c("y", "x"), ordered=TRUE))
+
+  expect_true(testFunction(myfun, nargs = 2))
+  expect_true(testFunction(myfun, args = "x", nargs = 2))
+  expect_true(testFunction(function() 1, nargs = 0))
+  expect_true(testFunction(function(...) 1, nargs = 0))
+  expect_false(testFunction(function(...) 1, nargs = 1))
+
+  expect_error(assertFunction(fff), "not found")
+  expect_error(assertFunction(myfun, "z"), "formal arguments")
+  expect_error(assertFunction(myfun, "y", ordered=TRUE), "first formal arguments")
+
+  expect_false(testFunction(function(x) x^2, args = character(0)))
+  expect_true(testFunction(function() x^2, args = character(0)))
+  expect_error(assertFunction(letters), "character")
+})
diff --git a/tests/testthat/test_checkInt.R b/tests/testthat/test_checkInt.R
new file mode 100644
index 0000000..9b1261f
--- /dev/null
+++ b/tests/testthat/test_checkInt.R
@@ -0,0 +1,30 @@
+context("checkInt")
+
+test_that("checkInt", {
+  myobj = 1L
+  expect_succ_all(Int, myobj)
+  myobj = 1.1
+  expect_fail_all(Int, myobj)
+
+  expect_false(testInt(integer(0)))
+  expect_false(testInt(NULL))
+  expect_false(testInt(FALSE))
+  expect_false(testInt(TRUE))
+
+  expect_true(testInt(1L))
+  expect_true(testInt(1.))
+  expect_false(testInt(NA))
+  expect_true(testInt(NA_real_, na.ok = TRUE))
+  expect_false(testInt(1:2))
+  expect_false(testInt(""))
+
+  expect_error(assertInt(2+3i), "integerish")
+})
+
+
+test_that("bounds of vectors with only missings are not checked", {
+  expect_true(checkInt(NA, na.ok = TRUE, lower = 1))
+  expect_true(checkInt(NA_character_, na.ok = TRUE, upper = 10))
+  expect_fail_all(Int, 0L, lower = 1L)
+  expect_fail_all(Int, 100L, upper = 10L)
+})
diff --git a/tests/testthat/test_checkInteger.R b/tests/testthat/test_checkInteger.R
new file mode 100644
index 0000000..ed59f57
--- /dev/null
+++ b/tests/testthat/test_checkInteger.R
@@ -0,0 +1,31 @@
+context("checkInteger")
+
+test_that("checkInteger", {
+  myobj = 1L
+  expect_succ_all(Integer, myobj)
+  myobj = 1
+  expect_fail_all(Integer, myobj)
+
+  expect_true(testInteger(integer(0)))
+  expect_false(testInteger(NULL))
+  expect_false(testInteger(TRUE))
+  expect_false(testInteger(FALSE))
+  expect_true(testInteger(NA))
+  expect_false(testInteger(NA, any.missing = FALSE))
+  expect_false(testInteger(NA, all.missing = FALSE))
+  expect_true(testInteger(1L))
+  expect_true(testInteger(1:3, any.missing = FALSE, min.len = 1L, max.len = 3L))
+  expect_false(testInteger(1:3, any.missing = FALSE, len = 5))
+  expect_true(testInteger(1:3, lower = 1L, upper = 3L))
+  expect_false(testInteger(1:3, lower = 5))
+  expect_false(testInteger(1:3, upper = 1))
+
+  expect_error(assertInteger(1), "integer")
+})
+
+test_that("bounds of vectors with only missings are not checked", {
+  expect_true(checkInteger(NA, lower = 1))
+  expect_true(checkInteger(NA_character_, upper = 10))
+  expect_fail_all(Integer, 0L, lower = 1L)
+  expect_fail_all(Integer, 100L, upper = 10L)
+})
diff --git a/tests/testthat/test_checkIntegerish.R b/tests/testthat/test_checkIntegerish.R
new file mode 100644
index 0000000..b1d50fb
--- /dev/null
+++ b/tests/testthat/test_checkIntegerish.R
@@ -0,0 +1,61 @@
+context("checkIntegerish")
+
+test_that("checkIntegerish", {
+  myobj = 1
+  expect_succ_all(Integerish, myobj)
+  myobj = 3.3
+  expect_fail_all(Integerish, myobj)
+
+  x = 1 - 0.9 -.1
+
+  expect_true(testIntegerish(integer(0)))
+  expect_false(testIntegerish(NULL))
+  expect_false(testIntegerish(TRUE))
+  expect_false(testIntegerish(FALSE))
+  expect_true(testIntegerish(1L))
+  expect_true(testIntegerish(c(-1, 0, 1)))
+  expect_true(testIntegerish(1.))
+  expect_true(testIntegerish(x))
+
+  expect_true(testIntegerish(NA))
+  expect_true(testIntegerish(NaN))
+  expect_true(testIntegerish(c(1L, NA)))
+  expect_true(testIntegerish(c(1, NA)))
+  expect_true(testIntegerish(c(1, NaN)))
+
+  expect_false(testIntegerish(1:2 + 0.0001))
+  expect_false(testIntegerish(-Inf))
+  expect_false(testIntegerish(Inf))
+
+  expect_true(testIntegerish(3+0i))
+  expect_false(testIntegerish(3-1i))
+  expect_true(testIntegerish(as.complex(NA)))
+  expect_false(testIntegerish(3+2i))
+  expect_false(testIntegerish(list()))
+
+  max = as.double(.Machine$integer.max)
+  min = as.double(-.Machine$integer.max)
+  expect_true(testIntegerish(min))
+  expect_true(testIntegerish(max))
+  expect_false(testIntegerish(min-1))
+  expect_false(testIntegerish(max+1))
+  expect_false(testIntegerish(min-.1))
+  expect_false(testIntegerish(max+.1))
+
+  expect_false(testIntegerish(NA, any.missing = FALSE))
+  expect_false(testIntegerish(NA, all.missing = FALSE))
+  expect_error(assertIntegerish(x, tol=0), "integerish")
+})
+
+test_that("bounds of vectors with only missings are not checked", {
+  expect_true(checkInteger(NA, lower = 1))
+  expect_true(checkInteger(NA_character_, upper = 10))
+  expect_fail_all(Integerish, 0, lower = 1L)
+  expect_fail_all(Integerish, 100, upper = 10L)
+})
+
+test_that("isIntegerish internal function", {
+  expect_true(isIntegerish(1))
+  expect_true(isIntegerish(1.))
+  expect_false(isIntegerish(1.1))
+})
diff --git a/tests/testthat/test_checkList.R b/tests/testthat/test_checkList.R
new file mode 100644
index 0000000..b3182c4
--- /dev/null
+++ b/tests/testthat/test_checkList.R
@@ -0,0 +1,32 @@
+context("checkList")
+
+test_that("checkList", {
+  myobj = list(1, 2, 3)
+  expect_succ_all(List, myobj)
+  myobj = TRUE
+  expect_fail_all(List, myobj)
+
+  expect_true(testList(list()))
+  expect_false(testList(NULL))
+  expect_true(testList(list(1)))
+  expect_false(testList(iris))
+
+  x = as.list(iris)
+  expect_true(testList(x, types = c("numeric", "factor")))
+  expect_false(testList(x, types = c("integer", "factor")))
+  expect_false(testList(x, types = c("numeric", "character")))
+  expect_true(testList(x, types = c("vector", "factor")))
+  expect_true(testList(list(NULL), types = "NULL"))
+  expect_true(testList(list(), types = "numeric"))
+  expect_false(testList(list(TRUE), types = "numeric"))
+  expect_error(assertList(x, types = "numeric"), "types: numeric")
+  expect_error(assertList(x, len = 33), "Must have length 33")
+
+  expect_true(testList(list(), names = "named"))
+
+  x = 1:3
+  class(x) = "foo"
+  x = list(x, 1:3)
+  expect_true(testList(x, types = c("foo", "integerish")))
+  expect_error(assertList(1), "list")
+})
diff --git a/tests/testthat/test_checkLogical.R b/tests/testthat/test_checkLogical.R
new file mode 100644
index 0000000..b554983
--- /dev/null
+++ b/tests/testthat/test_checkLogical.R
@@ -0,0 +1,21 @@
+context("checkLogical")
+
+test_that("checkLogical", {
+  myobj = TRUE
+  expect_succ_all(Logical, myobj)
+  myobj = 1
+  expect_fail_all(Logical, myobj)
+
+  expect_true(testLogical(logical(0)))
+  expect_false(testLogical(NULL))
+  expect_true(testLogical(TRUE))
+  expect_true(testLogical(NA))
+  expect_true(testLogical(NA_real_))
+  expect_true(testLogical(FALSE))
+  expect_false(testLogical(NA, any.missing=FALSE))
+  expect_false(testLogical(NA, all.missing=FALSE))
+  expect_false(testLogical(iris))
+  expect_true(testLogical(c(TRUE, FALSE), min.len = 2))
+
+  expect_error(assertLogical(1), "logical")
+})
diff --git a/tests/testthat/test_checkMatrix.R b/tests/testthat/test_checkMatrix.R
new file mode 100644
index 0000000..206a44a
--- /dev/null
+++ b/tests/testthat/test_checkMatrix.R
@@ -0,0 +1,91 @@
+context("checkMatrix")
+
+test_that("checkMatrix", {
+  myobj = matrix(1:9, 3)
+  expect_succ_all(Matrix, myobj)
+  myobj = TRUE
+  expect_fail_all(Matrix, myobj)
+
+  x = matrix(1:9, 3)
+  expect_true(testMatrix(x))
+  expect_true(testMatrix(matrix(nrow=0, ncol=0)))
+  expect_false(testMatrix(NULL))
+  x[2,2] = NA
+  expect_true(testMatrix(x))
+  expect_false(testMatrix(x, any.missing = FALSE))
+
+  xl = matrix(TRUE)
+  xi = matrix(1L)
+  xr = matrix(1.)
+  xs = matrix("a")
+  xc = matrix(1+1i)
+  xx = array(list(1, 1), dim = c(1, 2))
+  xe = matrix(nrow = 0, ncol = 0); storage.mode(xe) = "double"
+  expect_true(testMatrix(xl, "logical"))
+  expect_true(testMatrix(xi, "integer"))
+  expect_true(testMatrix(xr, "double"))
+  expect_true(testMatrix(xe, "double"))
+  expect_true(testMatrix(xr, "numeric"))
+  expect_true(testMatrix(xc, "complex"))
+  expect_true(testMatrix(xs, "character"))
+  expect_true(testMatrix(xx, "list"))
+  expect_false(testMatrix(xs, "logical"))
+  expect_false(testMatrix(xs, "integer"))
+  expect_false(testMatrix(xs, "double"))
+  expect_false(testMatrix(xe, "logical"))
+  expect_false(testMatrix(xs, "numeric"))
+  expect_false(testMatrix(xs, "complex"))
+  expect_false(testMatrix(xl, "character"))
+  expect_false(testMatrix(xx, "numeric"))
+  expect_false(testMatrix(xx, "atomic"))
+  expect_true(testMatrix(xi, "integerish"))
+  expect_true(testMatrix(xr, "integerish"))
+  expect_false(testMatrix(xi+0.1, "integerish"))
+
+  expect_true(testMatrix(x, min.rows = 1, min.cols = 1))
+  expect_true(testMatrix(x, nrows = 3, ncols = 3))
+  expect_true(testMatrix(xx, nrows = 1, ncols = 2))
+  expect_true(testMatrix(xe, nrows = 0, ncols = 0))
+  expect_false(testMatrix(x, min.rows = 5))
+  expect_false(testMatrix(x, min.cols = 5))
+  expect_false(testMatrix(x, nrows = 5))
+  expect_false(testMatrix(x, ncols = 5))
+
+  expect_false(testMatrix(x, row.names = "named"))
+  expect_false(testMatrix(x, col.names = "named"))
+  rownames(x) = letters[1:3]; colnames(x) = NULL
+  expect_true(testMatrix(x, row.names = "named"))
+  expect_false(testMatrix(x, col.names = "named"))
+  colnames(x) = letters[1:3]; rownames(x) = NULL
+  expect_false(testMatrix(x, row.names = "named"))
+  expect_true(testMatrix(x, col.names = "named"))
+  colnames(x) = rownames(x) = letters[1:3]
+  expect_true(testMatrix(x, row.names = "named"))
+  expect_true(testMatrix(x, col.names = "named"))
+
+  # named and unnamed is the same for "empty" matricies
+  expect_true(testMatrix(xe, row.names = "unnamed"))
+  expect_true(testMatrix(xe, col.names = "unnamed"))
+  expect_true(testMatrix(xe, row.names = "strict"))
+  expect_true(testMatrix(xe, col.names = "strict"))
+
+  expect_error(assertMatrix(iris), "matrix")
+  expect_error(assertMatrix(matrix(), min.rows = 99), "99")
+})
+
+test_that("dimension arugments are checked", {
+  x = matrix(1)
+  expect_error(checkMatrix(x, min.rows = 1.2), "count")
+  expect_error(checkMatrix(x, min.rows = NA_integer_), "missing")
+  expect_error(checkMatrix(x, min.rows = -1), ">= 0")
+})
+
+test_that("dimensions are reported correctly", {
+  x = matrix(1:42, ncol = 1)
+  expect_true(grepl(42, checkMatrix(x, nrows = 43)))
+  expect_true(grepl(42, checkMatrix(x, min.rows = 43)))
+
+  x = t(x)
+  expect_true(grepl(42, checkMatrix(x, ncols = 43)))
+  expect_true(grepl(42, checkMatrix(x, min.cols = 43)))
+})
diff --git a/tests/testthat/test_checkNamed.R b/tests/testthat/test_checkNamed.R
new file mode 100644
index 0000000..3e84f4d
--- /dev/null
+++ b/tests/testthat/test_checkNamed.R
@@ -0,0 +1,55 @@
+context("checkNamed")
+
+test_that("checkNamed", {
+  myobj = setNames(1:3, letters[1:3])
+  expect_succ_all(Named, myobj)
+  myobj = 1:3
+  expect_fail_all(Named, myobj)
+
+  expect_true(testNamed(integer(0)))
+  expect_true(testNamed(NULL))
+  expect_true(testNamed(setNames(integer(0), character(0))))
+
+  x = setNames(1:2, c("a", ".a"))
+  expect_true(testNamed(x))
+  expect_true(testNamed(x, "unique"))
+  expect_true(testNamed(x, "strict"))
+
+  expect_false(testNamed(1))
+  expect_false(testNamed(setNames(x, NA_character_)))
+  expect_false(testNamed(setNames(x, NA_integer_)))
+  expect_false(testNamed(setNames(x, "")))
+
+  x = setNames(1:2, c("a", "a"))
+  expect_true(testNamed(x))
+  expect_false(testNamed(x, "unique"))
+
+  x = setNames(1:2, c("a", "1"))
+  expect_true(testNamed(x))
+  expect_false(testNamed(x, "strict"))
+
+  x = setNames(1:2, c("a", "..1"))
+  expect_true(testNamed(x))
+  expect_false(testNamed(x, "strict"))
+
+
+  x = setNames(1, "")
+  expect_error(assertNamed(x), "named")
+
+  x = setNames(1:2, c("a", "a"))
+  expect_error(assertNamed(x, "unique"), "uniquely")
+
+  expect_true(testNamed(setNames(1, "x"), type = "strict"))
+  expect_true(testNamed(setNames(1, "..x"), type = "strict"))
+  expect_true(testNamed(setNames(1, "x_1"), type = "strict"))
+  expect_true(testNamed(setNames(1, "x."), type = "strict"))
+  expect_false(testNamed(setNames(1, "1"), type = "strict"))
+  expect_false(testNamed(setNames(1, ".1"), type = "strict"))
+  expect_false(testNamed(setNames(1, "..1"), type = "strict"))
+  expect_false(testNamed(setNames(1, "x "), type = "strict"))
+  expect_false(testNamed(setNames(1, "ä"), type = "strict"))
+  expect_error(assertNamed(x, "unique"), "uniquely")
+
+  x = setNames(1:2, c("a", "1"))
+  expect_error(assertNamed(x, "strict"), "naming rules")
+})
diff --git a/tests/testthat/test_checkNames.R b/tests/testthat/test_checkNames.R
new file mode 100644
index 0000000..bfdf737
--- /dev/null
+++ b/tests/testthat/test_checkNames.R
@@ -0,0 +1,102 @@
+context("checkNames")
+
+test_that("checkNames", {
+  nn = letters[1:3]
+  expect_succ_all(Names, nn)
+  expect_fail_all(Names, nn, type = "unnamed")
+
+  expect_true(testNames(character(0)))
+  expect_false(testNames(NULL))
+  expect_false(testNames(integer(0)))
+
+  x = c("a", ".a")
+  expect_true(testNames(x))
+  expect_true(testNames(x, "unique"))
+  expect_true(testNames(x, "strict"))
+
+  expect_false(testNames(1))
+  expect_false(testNames(NA_character_))
+  expect_false(testNames(NA_integer_))
+  expect_false(testNames(""))
+
+  x = c("a", "a")
+  expect_true(testNames(x))
+  expect_false(testNames(x, "unique"))
+
+  expect_true(testNames("x", type = "strict"))
+  expect_true(testNames("..x", type = "strict"))
+  expect_true(testNames("x_1", type = "strict"))
+  expect_true(testNames("x.", type = "strict"))
+  expect_false(testNames("1", type = "strict"))
+  expect_false(testNames(".1", type = "strict"))
+  expect_false(testNames("..1", type = "strict"))
+  expect_false(testNames("x ", type = "strict"))
+  expect_false(testNames("ä", type = "strict"))
+  expect_error(assertNames(c("a", "a"), "unique"), "unique")
+
+  x = c("a", "1")
+  expect_error(assertNames(x, "strict"), "naming rules")
+})
+
+test_that("argument 'type' is checked", {
+  expect_error(checkNames("x", type = 1), "string")
+  expect_error(checkNames("x", type = NA_character_), "missing")
+})
+
+
+test_that("checkNames / subset.of", {
+  x = 1:3
+  names(x) = letters[1:3]
+
+  expect_true(testNames(names(x), subset.of = letters[1:3]))
+  expect_true(testNames(names(x), subset.of = letters[3:1]))
+  expect_true(testNames(names(x), subset.of = letters))
+  expect_false(testNames(names(x), subset.of = letters[1:2]))
+  expect_false(testNames(names(x), subset.of = character(0)))
+  expect_false(testNames(NULL, subset.of = character(0)))
+  expect_true(testNames(character(0), subset.of = character(0)))
+  expect_true(testNames(character(0), subset.of = NULL))
+})
+
+test_that("checkNames / identical.to", {
+  x = 1:3
+  names(x) = letters[1:3]
+
+  expect_true(testNames(names(x), identical.to = letters[1:3]))
+  expect_false(testNames(names(x), identical.to = letters[3:1]))
+  expect_false(testNames(names(x), identical.to = letters))
+  expect_false(testNames(names(x), identical.to = letters[1:2]))
+  expect_false(testNames(names(x), identical.to = character(0)))
+  expect_false(testNames(NULL, identical.to = character(0)))
+  expect_true(testNames(character(0), identical.to = character(0)))
+  expect_true(testNames(character(0), identical.to = NULL))
+  expect_false(testNames(NULL, identical.to = NULL))
+})
+
+test_that("checkNames / permutation.of", {
+  x = 1:3
+  names(x) = letters[1:3]
+
+  expect_true(testNames(names(x), permutation.of = letters[1:3]))
+  expect_true(testNames(names(x), permutation.of = letters[3:1]))
+  expect_false(testNames(names(x), permutation.of = letters))
+  expect_false(testNames(names(x), permutation.of = letters[1:2]))
+  expect_false(testNames(names(x), permutation.of = character(0)))
+  expect_false(testNames(NULL, permutation.of = character(0)))
+  expect_true(testNames(character(0), permutation.of = character(0)))
+  expect_true(testNames(character(0), permutation.of = NULL))
+  expect_false(testNames(NULL, permutation.of = NULL))
+
+})
+
+test_that("checkNames / errors are useful", {
+  foo = matrix(1:9)
+  expect_error(
+    assertNames(colnames(foo), permutation.of = letters),
+    "colnames\\(foo\\)"
+  )
+  expect_error(
+    assertNames(rownames(foo), permutation.of = letters),
+    "rownames\\(foo\\)"
+  )
+})
diff --git a/tests/testthat/test_checkNull.R b/tests/testthat/test_checkNull.R
new file mode 100644
index 0000000..6c6a6b1
--- /dev/null
+++ b/tests/testthat/test_checkNull.R
@@ -0,0 +1,13 @@
+context("checkNull")
+
+test_that("checkNull", {
+  myobj = NULL
+  expect_succ_all(Null, myobj)
+  myobj = TRUE
+  expect_fail_all(Null, myobj)
+
+  expect_false(testNull(integer(0)))
+  expect_true(testNull(NULL))
+
+  expect_error(assertNull(-1), "NULL")
+})
diff --git a/tests/testthat/test_checkNumber.R b/tests/testthat/test_checkNumber.R
new file mode 100644
index 0000000..1c7d526
--- /dev/null
+++ b/tests/testthat/test_checkNumber.R
@@ -0,0 +1,38 @@
+context("checkNumber")
+
+test_that("checkNumber", {
+  myobj = 1
+  expect_succ_all(Number, myobj)
+  myobj = "a"
+  expect_fail_all(Number, myobj)
+
+  expect_false(testNumber(integer(0)))
+  expect_false(testNumber(NULL))
+
+  expect_false(testNumber(TRUE))
+  expect_false(testNumber(FALSE))
+  expect_true(testNumber(1L))
+  expect_true(testNumber(1.))
+  expect_false(testNumber(NA))
+  expect_false(testNumber(NaN))
+  expect_true(testNumber(NaN, na.ok = TRUE))
+  expect_true(testNumber(NA_real_, na.ok = TRUE))
+  expect_false(testNumber(1:2))
+  expect_false(testNumber(""))
+
+  expect_true(testNumber(Inf))
+  expect_true(testNumber(-Inf))
+  expect_error(assertNumber(Inf, finite = TRUE), "finite")
+  expect_error(assertNumber(-Inf, finite = TRUE), "finite")
+
+  expect_false(testNumber(TRUE))
+
+  expect_error(assertNumber(2+3i), "number")
+})
+
+test_that("bounds of vectors with only missings are not checked", {
+  expect_true(checkNumber(NA, na.ok = TRUE, lower = 1))
+  expect_true(checkNumber(NA_character_, na.ok = TRUE, upper = 10))
+  expect_fail_all(Number, 0, lower = 1)
+  expect_fail_all(Number, 100, upper = 10)
+})
diff --git a/tests/testthat/test_checkNumeric.R b/tests/testthat/test_checkNumeric.R
new file mode 100644
index 0000000..c7015a9
--- /dev/null
+++ b/tests/testthat/test_checkNumeric.R
@@ -0,0 +1,49 @@
+context("checkNumeric")
+
+test_that("checkNumeric", {
+  myobj = 1
+  expect_succ_all(Numeric, myobj)
+  myobj = "a"
+  expect_fail_all(Numeric, myobj)
+
+  expect_true(testNumeric(integer(0)))
+  expect_false(testNumeric(NULL))
+  expect_false(testNumeric(TRUE))
+  expect_false(testNumeric(FALSE))
+  expect_true(testNumeric(NA_character_))
+  expect_true(testNumeric(NA_real_))
+  expect_true(testNumeric(NaN))
+  expect_false(testNumeric(NA_real_, any.missing = FALSE))
+  expect_false(testNumeric(NA_real_, all.missing = FALSE))
+  expect_false(testNumeric(NaN, any.missing = FALSE))
+  expect_false(testNumeric(NaN, all.missing = FALSE))
+  expect_true(testNumeric(1L))
+  expect_true(testNumeric(1))
+  expect_true(testNumeric(Inf))
+  expect_true(testNumeric(-Inf))
+  expect_identical(assertNumeric(1:2, finite = TRUE), 1:2)
+  expect_error(assertNumeric(c(1, Inf), finite = TRUE), "finite")
+  expect_error(assertNumeric(c(1, -Inf), finite = TRUE), "finite")
+  expect_true(testNumeric(1:3, any.missing=FALSE, min.len=1L, max.len=3L))
+  expect_false(testNumeric(1:3, any.missing=FALSE, len=5))
+  expect_true(testNumeric(1:3, lower = 1L, upper = 3L))
+  expect_false(testNumeric(1:3, lower = 5))
+
+  expect_error(assertNumeric("a"), "numeric")
+})
+
+test_that("bounds are checked", {
+  expect_error(checkNumeric(1, lower = "a"), "number")
+  expect_error(checkNumeric(1, lower = 1:2), "number")
+  expect_error(checkNumeric(1, lower = NA_real_), "missing")
+  expect_error(checkNumeric(1, upper = "a"), "number")
+  expect_error(checkNumeric(1, upper = 1:2), "number")
+  expect_error(checkNumeric(1, upper = NA_real_), "missing")
+})
+
+test_that("bounds of vectors with only missings are not checked", {
+  expect_true(checkNumeric(NA, lower = 1))
+  expect_true(checkNumeric(NA_character_, upper = 10))
+  expect_fail_all(Numeric, 0:5, lower = 1L)
+  expect_fail_all(Numeric, 5:15, upper = 10L)
+})
diff --git a/tests/testthat/test_checkOS.R b/tests/testthat/test_checkOS.R
new file mode 100644
index 0000000..09a5fae
--- /dev/null
+++ b/tests/testthat/test_checkOS.R
@@ -0,0 +1,29 @@
+context("checkOS")
+
+test_that("checkOS", {
+  expect_succ_all(OS, c("linux", "mac", "windows", "solaris"))
+})
+
+test_that("checkOS linux", {
+  skip_on_os("windows")
+  skip_on_os("solaris")
+  skip_on_os("mac")
+  expect_succ_all(OS, "linux", lc = "os")
+  expect_string(checkOS("windows"), fixed = "windows")
+})
+
+test_that("checkOS mac", {
+  skip_on_os("windows")
+  skip_on_os("solaris")
+  skip_on_os("linux")
+  expect_succ_all(OS, "mac", lc = "os")
+  expect_string(checkOS("windows"), fixed = "windows")
+})
+
+test_that("checkOS win", {
+  skip_on_os("mac")
+  skip_on_os("solaris")
+  skip_on_os("linux")
+  expect_succ_all(OS, "windows", lc = "os")
+  expect_string(checkOS("mac"), fixed = "mac")
+})
diff --git a/tests/testthat/test_checkScalar.R b/tests/testthat/test_checkScalar.R
new file mode 100644
index 0000000..42f3b9e
--- /dev/null
+++ b/tests/testthat/test_checkScalar.R
@@ -0,0 +1,19 @@
+context("checkScalar")
+
+test_that("checkScalar", {
+  myobj = "a"
+  expect_succ_all(Scalar, myobj)
+  myobj = 1:2
+  expect_fail_all(Scalar, myobj)
+
+  expect_true(testScalar(TRUE))
+  expect_true(testScalar(1L))
+  expect_true(testScalar(1))
+  expect_true(testScalar(1+1i))
+  expect_false(testScalar(list(1)))
+  expect_false(testScalar(NA, na.ok = FALSE))
+  expect_true(testScalar(NA, na.ok = TRUE))
+
+  expect_error(assertScalar(integer(0)), "length 1")
+  expect_error(assertScalar(iris), "scalar")
+})
diff --git a/tests/testthat/test_checkScalarNA.R b/tests/testthat/test_checkScalarNA.R
new file mode 100644
index 0000000..42e3718
--- /dev/null
+++ b/tests/testthat/test_checkScalarNA.R
@@ -0,0 +1,12 @@
+context("checkScalarNA")
+
+test_that("checkScalarNA", {
+  expect_succ_all("ScalarNA", NA)
+  expect_fail_all("ScalarNA", 1)
+  expect_true(testScalarNA(NA_real_))
+  expect_false(testScalarNA(1))
+  expect_false(testScalarNA(rep(NA_character_, 2)))
+  expect_expectation_successful(expect_scalar_na(NA), label = NULL)
+
+  expect_error(assertScalarNA(integer(0)), "missing value")
+})
diff --git a/tests/testthat/test_checkSetEqual.R b/tests/testthat/test_checkSetEqual.R
new file mode 100644
index 0000000..cb89f57
--- /dev/null
+++ b/tests/testthat/test_checkSetEqual.R
@@ -0,0 +1,35 @@
+context("checkSetEqual")
+
+test_that("checkSetEqual", {
+  myobj = letters[3:1]
+  expect_succ_all(SetEqual, myobj, letters[1:3])
+  expect_fail_all(SetEqual, myobj, letters[1:3], ordered = TRUE)
+  myobj = letters[1:2]
+  expect_fail_all(String, myobj, letters[1:3])
+
+  expect_true(testSetEqual(character(0), character(0)))
+  expect_true(testSetEqual(character(0), character(0), ordered = TRUE))
+  expect_false(testSetEqual(character(0), letters))
+  expect_false(testSetEqual(letters, character(0)))
+  expect_false(testSetEqual(NULL, letters))
+  expect_false(testSetEqual(NULL, letters, ordered = TRUE))
+  expect_false(testSetEqual(factor("a"), letters))
+  expect_true(testSetEqual(factor(letters), factor(letters)))
+  expect_true(testSetEqual(letters, factor(letters)))
+
+  expect_true(testSetEqual(1L, 1L))
+  expect_true(testSetEqual(1, 1L))
+  expect_true(testSetEqual(3:4, 3:4))
+  expect_true(testSetEqual(NA_integer_, NA_integer_))
+
+  expect_true(testSetEqual(1:2, 1:2, ordered = TRUE))
+  expect_false(testSetEqual(1:2, 2:1, ordered = TRUE))
+  expect_true(testSetEqual(NA, NA, ordered = TRUE))
+  expect_false(testSetEqual(NA_integer_, 1L, ordered = TRUE))
+  expect_false(testSetEqual(1L, NA_integer_, ordered = TRUE))
+  expect_false(testSetEqual(c(NA_integer_, 2L), 1:2, ordered = TRUE))
+  expect_true(testSetEqual(c(NA_integer_, 2L), c(NA_real_, 2), ordered = TRUE))
+
+  expect_error(assertSetEqual(1, 1:2), "equal to")
+  expect_error(assertSetEqual(1L, list()), "atomic")
+})
diff --git a/tests/testthat/test_checkString.R b/tests/testthat/test_checkString.R
new file mode 100644
index 0000000..5c00bc0
--- /dev/null
+++ b/tests/testthat/test_checkString.R
@@ -0,0 +1,26 @@
+context("checkString")
+
+test_that("checkString", {
+  expect_succ_all(String, "a")
+  expect_succ_all(String, "")
+  expect_fail_all(String, "", min.chars = 1)
+  expect_fail_all(String, 1L)
+  expect_succ_all(String, NA_character_, na.ok = TRUE, min.chars = 99)
+  expect_succ_all(String, "xxxfooxxx", pattern = "foo")
+  expect_succ_all(String, "xxxfooxxx", fixed = "foo")
+  expect_fail_all(String, "xxxfooxxx", pattern = "bar")
+  expect_fail_all(String, "xxxfooxxx", fixed = "bar")
+  expect_succ_all(String, "xxxfooxxx", pattern = "FOO", ignore.case = TRUE)
+  expect_fail_all(String, "xxxfooxxx", fixed = "FOO", ignore.case = FALSE)
+
+  expect_false(testString(character(0)))
+  expect_false(testString(NULL))
+  expect_true(testString(""))
+  expect_true(testString("foo"))
+  expect_true(testString(NA, na.ok = TRUE))
+  expect_false(testString(NA_character_))
+  expect_true(testString(NA_character_, na.ok = TRUE))
+  expect_true(testString(NA, na.ok = TRUE))
+
+  expect_error(assertString(1))
+})
diff --git a/tests/testthat/test_checkSubset.R b/tests/testthat/test_checkSubset.R
new file mode 100644
index 0000000..e9c77f5
--- /dev/null
+++ b/tests/testthat/test_checkSubset.R
@@ -0,0 +1,23 @@
+context("checkSubset")
+
+test_that("checkSubset", {
+  myobj = letters[1:3]
+  expect_succ_all(Subset, myobj, letters)
+  myobj = 1:2
+  expect_fail_all(Subset, myobj, letters)
+
+  expect_false(testSubset(character(0), letters, empty.ok = FALSE))
+  expect_true(testSubset(character(0), letters, empty.ok = TRUE))
+  expect_false(testSubset(NULL, letters, empty.ok = FALSE))
+  expect_true(testSubset(character(0), letters, empty.ok = TRUE))
+  expect_true(testSubset(factor("a"), letters))
+  expect_true(testSubset(factor("a"), factor(letters)))
+
+  expect_true(testSubset(1L, 1:10))
+  expect_true(testSubset(3:4, 1:10))
+  expect_false(testSubset("ab", letters))
+  expect_false(testSubset(NA_integer_, 1:10))
+
+  expect_error(assertSubset(-1, 1:2), "subset of")
+  expect_error(assertSubset(1L, list()), "atomic")
+})
diff --git a/tests/testthat/test_checkTibble.R b/tests/testthat/test_checkTibble.R
new file mode 100644
index 0000000..8d31c07
--- /dev/null
+++ b/tests/testthat/test_checkTibble.R
@@ -0,0 +1,13 @@
+context("checkTibble")
+
+test_that("checkTibble", {
+  skip_if_not_installed("tibble")
+  library(tibble)
+
+  x = as_tibble(iris)
+  expect_succ_all("Tibble", x)
+  expect_fail_all("Tibble", iris)
+
+  expect_true(testTibble(x, min.rows = 1, ncols = 5))
+  expect_false(testTibble(x, min.rows = 1000, ncols = 5))
+})
diff --git a/tests/testthat/test_checkVector.R b/tests/testthat/test_checkVector.R
new file mode 100644
index 0000000..7b5fe81
--- /dev/null
+++ b/tests/testthat/test_checkVector.R
@@ -0,0 +1,72 @@
+context("checkVector")
+
+li = list(
+  list = list(1, 2),
+  factor = factor("a"),
+  integer = 1:2,
+  NULL = NULL,
+  data.frame = iris
+)
+
+test_that("checkVector", {
+  myobj = 1:3
+  expect_succ_all(Vector, myobj)
+  myobj = NULL
+  expect_fail_all(Vector, myobj)
+
+  expect_true(testVector(integer(0)))
+  expect_false(testVector(NULL))
+  expect_true(testVector(1))
+  expect_true(testVector(integer(0)))
+  expect_true(testVector(factor(1), strict = FALSE))
+  expect_false(testVector(factor(1), strict = TRUE))
+
+  expect_true(testVector(NA, any.missing = TRUE))
+  expect_false(testVector(NA, any.missing = FALSE))
+  expect_false(testVector(NA, all.missing = FALSE))
+
+  expect_true(testVector(1, len=1))
+  expect_false(testVector(1, len=0))
+
+  expect_true(testVector(1, min.len=0))
+  expect_false(testVector(1, min.len=2))
+  expect_true(testVector(1, max.len=1))
+  expect_false(testVector(1, max.len=0))
+
+  expect_true(testVector(1, unique=TRUE))
+  expect_false(testVector(1, min.len=2))
+  expect_true(testVector(1, max.len=1))
+  expect_false(testVector(1, max.len=0))
+
+  expect_true(testVector(1, unique=TRUE))
+  expect_true(testVector(c(1,1), unique=FALSE))
+  expect_false(testVector(c(1,1), unique=TRUE))
+
+  expect_true(testVector(1, names="unnamed"))
+  expect_true(testVector(setNames(1, "x"), names="named"))
+  expect_false(testVector(1, names="unique"))
+
+  expect_equal(vlapply(li, is.vector), vlapply(li, testVector, strict = TRUE))
+  expected = setNames(c(TRUE, TRUE, TRUE, FALSE, TRUE), c("list", "factor", "integer", "NULL", "data.frame"))
+  expect_equal(expected, vlapply(li, testVector, strict = FALSE))
+
+  expect_error(assertVector(iris, strict = TRUE), "vector")
+})
+
+test_that("arguments any.missing and all.missing are checked", {
+  x = 1
+  expect_error(checkVector(x, any.missing = 1), "flag")
+  expect_error(checkVector(x, any.missing = NA), "missing")
+  expect_error(checkVector(x, all.missing = 1), "flag")
+  expect_error(checkVector(x, all.missing = NA), "missing")
+})
+
+test_that("length is correctly reported", {
+  x = 1:42
+  expect_true(grepl(42, checkVector(x, len = 1), fixed = TRUE))
+  expect_true(grepl(42, checkVector(x, min.len = 43), fixed = TRUE))
+  expect_true(grepl(42, checkVector(x, max.len = 1), fixed = TRUE))
+  expect_true(grepl(43, checkVector(x, len = 43), fixed = TRUE))
+  expect_true(grepl(43, checkVector(x, min.len = 43), fixed = TRUE))
+  expect_true(grepl(41, checkVector(x, max.len = 41), fixed = TRUE))
+})
diff --git a/tests/testthat/test_deparse.R b/tests/testthat/test_deparse.R
new file mode 100644
index 0000000..1900c00
--- /dev/null
+++ b/tests/testthat/test_deparse.R
@@ -0,0 +1,12 @@
+context("deparse")
+
+test_that("deparse", {
+  f = function(num, na.ok) {
+    assertNumber(num)
+    qassert(na.ok, "B1")
+  }
+
+  expect_true(f(1, TRUE))
+  expect_error(f(NULL, TRUE), "num")
+  expect_error(f(1, NULL), "na.ok")
+})
diff --git a/tests/testthat/test_guessType.R b/tests/testthat/test_guessType.R
new file mode 100644
index 0000000..fa08acf
--- /dev/null
+++ b/tests/testthat/test_guessType.R
@@ -0,0 +1,41 @@
+context("guessType")
+
+test_that("guessType", {
+  xb = logical(10)
+  xi = integer(10)
+  xd = double(10)
+  xc = complex(10)
+  xs = letters[1:10]
+  xl = as.list(1:10)
+  xm = matrix(1:9, 3)
+  xa = array(1:3)
+  xf = data.frame(a=1:5, b=1:5)
+  xx = 1; class(xx) = "Foo"
+  xxx = 1; class(xxx) = c("Foo", "Bar")
+
+  expect_equal(guessType(xb), "logical")
+  expect_equal(guessType(xi), "integer")
+  expect_equal(guessType(xd), "double")
+  expect_equal(guessType(xc), "complex")
+  expect_equal(guessType(xs), "character")
+  expect_equal(guessType(xl), "list")
+  expect_equal(guessType(xm), "matrix")
+  expect_equal(guessType(xa), "array")
+  expect_equal(guessType(xf), "data.frame")
+  expect_equal(guessType(xx), "Foo")
+  expect_equal(guessType(xxx), "Foo/Bar")
+
+  expect_true(grepl("NULL'$", checkLogical(NULL)))
+  expect_true(grepl("logical'$", checkInteger(xb)))
+  expect_true(grepl("integer'$", checkLogical(xi)))
+  expect_true(grepl("double'$", checkLogical(xd)))
+  expect_true(grepl("complex'$", checkLogical(xc)))
+  expect_true(grepl("character'$", checkLogical(xs)))
+  expect_true(grepl("factor'$", checkLogical(factor(xs))))
+  expect_true(grepl("list'$", checkLogical(xl)))
+  expect_true(grepl("matrix'$", checkLogical(xm)))
+  expect_true(grepl("array'$", checkLogical(xa)))
+  expect_true(grepl("frame'$", checkLogical(xf)))
+  expect_true(grepl("Foo'$", checkLogical(xx)))
+  expect_true(grepl("Foo/Bar'$", checkLogical(xxx)))
+})
diff --git a/tests/testthat/test_include.R b/tests/testthat/test_include.R
new file mode 100644
index 0000000..2238029
--- /dev/null
+++ b/tests/testthat/test_include.R
@@ -0,0 +1,17 @@
+context("registered c functions")
+
+test_that("include of registered C functions works", {
+  skip_on_cran()
+  if (length(find.package("checkmate.test.include", quiet = TRUE)) == 0L) {
+    requireNamespace("devtools")
+    devtools::install_github("mllg/checkmate-test-include")
+  }
+  library(checkmate.test.include)
+
+  expect_true(reexported_qtest(1, "N1"))
+  expect_false(reexported_qtest(1, "b"))
+
+  x = pi
+  expect_identical(reexported_qassert(x, "N1"), x)
+  expect_error(reexported_qassert(x, "b", "foo"), "foo")
+})
diff --git a/tests/testthat/test_interoperability.R b/tests/testthat/test_interoperability.R
new file mode 100644
index 0000000..3ecdcbc
--- /dev/null
+++ b/tests/testthat/test_interoperability.R
@@ -0,0 +1,27 @@
+context("Interoperability")
+
+test_that("data.table is supported", {
+  skip_if_not_installed("data.table")
+  library(data.table)
+  myobj = as.data.table(iris)
+  expect_succ_all(DataFrame, myobj)
+  expect_true(testDataFrame(myobj, nrow = 150, min.cols = 2, any.missing = FALSE, col.names = "strict"))
+  expect_true(testDataFrame(data.table()))
+})
+
+test_that("tibble is supported", {
+  skip_if_not_installed("tibble")
+  library(tibble)
+  myobj = as_tibble(iris)
+  expect_succ_all(DataFrame, myobj)
+  expect_true(testDataFrame(myobj, nrow = 150, min.cols = 2, any.missing = FALSE, col.names = "strict"))
+  expect_true(testDataFrame(data_frame()))
+})
+
+test_that("magrittr is supported", {
+  skip_if_not_installed("magrittr")
+  library(magrittr)
+  x = runif(10)
+  expect_identical(x %>% assert_numeric(lower = 0, upper = 1), x)
+  expect_identical(iris %>% assert_data_frame(min.rows = 1) %>% ncol, 5L)
+})
diff --git a/tests/testthat/test_makeFunction.R b/tests/testthat/test_makeFunction.R
new file mode 100644
index 0000000..32098b5
--- /dev/null
+++ b/tests/testthat/test_makeFunction.R
@@ -0,0 +1,42 @@
+context("makeXFunction")
+
+test_that("makeAssertion", {
+  x = assertFlag
+  y = makeAssertionFunction(checkFlag, c.fun = "c_check_flag")
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+
+  x = assertList
+  y = makeAssertionFunction(checkList)
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+})
+
+test_that("makeTest", {
+  x = testFlag
+  y = makeTestFunction(checkFlag, c.fun = "c_check_flag")
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+
+  x = testList
+  y = makeTestFunction(checkList)
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+
+  x = testFlag
+  y = function(x) makeTest(checkFlag(x))
+  expect_equal(x(TRUE), y(TRUE))
+  expect_equal(x(FALSE), y(FALSE))
+})
+
+test_that("makeExpectation", {
+  x = expect_flag
+  y = makeExpectationFunction(checkFlag, c.fun = "c_check_flag")
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+
+  x = expect_list
+  y = makeExpectationFunction(checkList)
+  expect_identical(formals(x), formals(y))
+  expect_equal(body(x), body(y))
+})
diff --git a/tests/testthat/test_matchArg.R b/tests/testthat/test_matchArg.R
new file mode 100644
index 0000000..af57f0a
--- /dev/null
+++ b/tests/testthat/test_matchArg.R
@@ -0,0 +1,18 @@
+context("matchArg")
+
+test_that("matchArg", {
+  x = c("pearson", "kendall", "spearman")
+  choices = x
+  expect_equal(matchArg(x, choices), choices[1])
+  expect_equal(matchArg(x, choices, several.ok = TRUE), choices)
+
+  x = substr(x, 1, 1)
+  expect_equal(matchArg(x[2], choices, several.ok = FALSE), choices[2])
+  expect_equal(matchArg(x[c(1, 3)], choices, several.ok = TRUE), choices[c(1, 3)])
+
+  expect_error(matchArg(1, 1:10), "character")
+  expect_error(matchArg(1, letters), "character")
+  expect_error(matchArg(letters, 1:10), "character")
+  expect_error(matchArg(x[1:2], choices), "length")
+  expect_error(matchArg(x[0], choices), "length 0")
+})
diff --git a/tests/testthat/test_messages.R b/tests/testthat/test_messages.R
new file mode 100644
index 0000000..aeaa500
--- /dev/null
+++ b/tests/testthat/test_messages.R
@@ -0,0 +1,7 @@
+context("generated messages")
+
+test_that("No extra strings attached to generated error messages", {
+  foo = function(XX) assertFlag(XX)
+  expect_error(foo(iris), "^Assertion on 'XX'")
+  expect_error(foo(iris), "not 'data.frame'\\.$")
+})
diff --git a/tests/testthat/test_qassert.R b/tests/testthat/test_qassert.R
new file mode 100644
index 0000000..5911fb4
--- /dev/null
+++ b/tests/testthat/test_qassert.R
@@ -0,0 +1,274 @@
+context("qtest")
+
+xb = logical(10); xb[5] = NA
+xi = integer(10); xi[5] = NA
+xr = double(10); xr[5] = NA
+xc = complex(10); xc[5] = NA
+xl = as.list(1:10); xl[5] = list(NULL)
+xm = matrix(1:9, 3); xm[2, 3] = NA
+xd = data.frame(a=1:5, b=1:5); xd$b[3] = NA
+xf = factor(letters[1:10]); xf[5] = NA
+xe = new.env(); xe$foo = 1
+
+expect_succ_all = function(x, rules) {
+  xn = deparse(substitute(x))
+  expect_true(qtest(x, rules),
+    info = sprintf("rules: %s", paste(rules, collapse=",")), label = xn)
+  expect_identical(qassert(x, rules), x,
+    info = sprintf("rules: %s", paste(rules, collapse=",")), label = xn)
+  expect_expectation_successful(qexpect(x, rules),
+    info = sprintf("rules: %s", paste(rules, collapse=",")), label = xn)
+}
+
+expect_fail_all = function(x, rules, pattern = NULL) {
+  xn = deparse(substitute(x))
+  expect_false(qtest(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_error(qassert(x, rules), regex = pattern,
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_expectation_failed(qexpect(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+}
+
+test_that("type and missingness", {
+  expect_succ_all(xb, "b")
+  expect_fail_all(xb, "B")
+  expect_succ_all(xi, "i")
+  expect_fail_all(xi, "I")
+  expect_succ_all(xr, "r")
+  expect_fail_all(xr, "R")
+  expect_succ_all(xc, "c")
+  expect_fail_all(xc, "C")
+  expect_succ_all(xl, "l")
+  expect_fail_all(xl, "L")
+  expect_succ_all(xm, "m")
+  expect_fail_all(xm, "M")
+  expect_succ_all(xd, "d")
+  expect_fail_all(xd, "D")
+  expect_succ_all(xe, "e")
+  expect_succ_all(xf, "f")
+  expect_fail_all(xf, "F")
+
+  expect_fail_all(xd, "b")
+  expect_fail_all(xd, "i")
+  expect_fail_all(xd, "r")
+  expect_fail_all(xd, "c")
+  expect_fail_all(xd, "l")
+  expect_fail_all(xd, "m")
+  expect_fail_all(xl, "e")
+  expect_fail_all(xm, "r")
+  expect_fail_all(xl, "d")
+  expect_fail_all(xl, "f")
+
+  expect_fail_all(xl, c("f", "n"), "One of")
+  expect_error(qassert(1, "O"), "Unknown class identifier")
+})
+
+test_that("integerish", {
+  expect_succ_all(xb, "x")
+  expect_succ_all(xi, "x")
+  expect_succ_all(xi, "x")
+  expect_fail_all(xi, "X")
+  expect_succ_all(xr, "x")
+  expect_fail_all(xr, "X")
+  expect_fail_all(1:3+.0001, "x")
+  expect_fail_all(xd, "x")
+})
+
+test_that("length", {
+  expect_succ_all(xb, "b+")
+  expect_succ_all(xb, "b10")
+  expect_succ_all(logical(1), "b+")
+  expect_succ_all(logical(1), "b?")
+  expect_succ_all(logical(1), "b1")
+  expect_fail_all(xb, "b?")
+  expect_fail_all(xb, "b5")
+  expect_fail_all(xb, "b>=50")
+  expect_succ_all(xb, "b<=50")
+  expect_succ_all(xe, "e1")
+  expect_fail_all(xe, "e>=2")
+  expect_fail_all(xe, "f+")
+
+  expect_error(qassert(1, "n9999999999999"), "handle length")
+  expect_error(qassert(1, "n-1"), "negative length")
+})
+
+test_that("bounds", {
+  xx = 1:3
+  expect_succ_all(xx, "i+(0,4)")
+  expect_succ_all(xx, "i+(0.9999,3.0001)")
+  expect_succ_all(xx, "i+(0,1e2)")
+  expect_succ_all(1, "n[0, 100]")
+
+  expect_fail_all(xx, "i+[1,2)")
+  expect_fail_all(xx, "i+[1,2]")
+  expect_fail_all(xx, "i+[1,3)")
+  expect_succ_all(xx, "i+[1,3]")
+
+  expect_fail_all(xx, "i+(2,3]")
+  expect_fail_all(xx, "i+[2,2]")
+  expect_fail_all(xx, "i+(1,3)")
+  expect_succ_all(xx, "i+[1,3]")
+
+  expect_succ_all(xx, "i[1,)")
+  expect_succ_all(xx, "i[,3]")
+  expect_succ_all(Inf, "n(1,]")
+  expect_succ_all(-Inf, "n[,1]")
+  expect_succ_all(c(-Inf, 0, Inf), "n[,]")
+  expect_fail_all(Inf, "n(1,)")
+  expect_fail_all(-Inf, "n(,0]")
+  expect_fail_all(c(-Inf, 0, Inf), "n(,]")
+  expect_fail_all(c(-Inf, 0, Inf), "n(,)")
+
+  xx = letters[1:3]
+  expect_succ_all(xx, "s+[1,]")
+  expect_succ_all(xx, "s+[1,1]")
+  expect_fail_all(xx, "s+[2]")
+  expect_fail_all(NA_character_, "s+[1]")
+  expect_fail_all(NA, "s+[1]")
+
+  xx = factor(letters[1:3])
+  expect_succ_all(xx, "f+[1,]")
+  expect_succ_all(xx, "f+[1,1]")
+  expect_fail_all(xx, "f+[2]")
+  expect_fail_all(NA_integer_, "f+[1]")
+  expect_fail_all(NA_character_, "f+[1]")
+  expect_fail_all(NA, "f+[1]")
+
+  expect_succ_all(1, "n+()")
+  expect_succ_all(1, "n+[]")
+  expect_succ_all(Inf, "n+[]")
+  expect_succ_all(Inf, "n+(]")
+  expect_succ_all(-Inf, "n+[)")
+  expect_fail_all(Inf, "n+()")
+  expect_fail_all(Inf, "n+[)")
+  expect_fail_all(-Inf, "n+(]")
+
+  expect_error(qassert(iris, "d+[1]"), "Bound checks")
+})
+
+test_that("non-atomic types", {
+  expect_succ_all(function() 1, "*")
+  expect_fail_all(function() 1, "b")
+  expect_succ_all(function() 1, "*")
+  expect_succ_all(NULL, "0?")
+  expect_fail_all(xi, "0")
+  expect_fail_all(NULL, "0+")
+  expect_succ_all(NULL, "00")
+  expect_fail_all(xe, "b")
+  expect_fail_all(xf, "b")
+  expect_fail_all(as.symbol("x"), "n")
+  expect_fail_all(xd, "a")
+})
+
+test_that("atomic types", {
+  expect_succ_all(NULL, "a")
+  expect_succ_all(xb, "a+")
+  expect_fail_all(xb, "A+")
+  expect_succ_all(xi, "a+")
+  expect_fail_all(xi, "A+")
+  expect_succ_all(xi, "n+")
+  expect_fail_all(xi, "N+")
+  expect_succ_all(xr, "n+")
+  expect_fail_all(xr, "N+")
+  expect_succ_all(xr, "a+")
+  expect_fail_all(xr, "A+")
+  expect_succ_all(xm, "a+")
+  expect_fail_all(xm, "A+")
+  expect_fail_all(xl, "a+")
+  expect_fail_all(xl, "A+")
+  expect_fail_all(xe, "a+")
+  expect_succ_all(xf, "a+")
+
+  expect_fail_all(NULL, "v")
+  expect_succ_all(xb, "v+")
+  expect_fail_all(xb, "V+")
+  expect_succ_all(xi, "v+")
+  expect_fail_all(xi, "V+")
+  expect_succ_all(xr, "v+")
+  expect_fail_all(xr, "V+")
+  expect_fail_all(xm, "v+")
+  expect_fail_all(xm, "V+")
+  expect_fail_all(xl, "v+")
+  expect_fail_all(xl, "V+")
+  expect_fail_all(xe, "v+")
+  expect_fail_all(xf, "V+")
+})
+
+test_that("optional chars", {
+  expect_succ_all(TRUE, "b*")
+  expect_succ_all(TRUE, "b=1")
+  expect_succ_all(TRUE, "b>=0")
+  expect_succ_all(TRUE, "b>0")
+  expect_succ_all(TRUE, "b<2")
+  expect_fail_all(TRUE, "b=2")
+  expect_fail_all(TRUE, "b>=2")
+  expect_fail_all(TRUE, "b>2")
+  expect_fail_all(TRUE, "b<0")
+})
+
+test_that("malformated pattern", {
+  expect_error(qassert(1, ""), "[Ee]mpty")
+  # expect_warning(expect_error(qassert(1, "ä")), "locale")
+  expect_error(qassert(1, "nn"), "length definition")
+  expect_error(qassert(1, "n="), "length definition")
+  expect_error(qassert(1, "n=="), "length definition")
+  expect_error(qassert(1, "n==="), "length definition")
+  expect_error(qassert(1, "n?1"), "bound definition")
+  expect_error(qassert(1, "n>"))
+  expect_error(qassert(1, "nö"))
+  expect_error(qassert(1, "n\n"))
+  expect_error(qassert(1, "n+a"), "opening")
+  expect_error(qassert(1, "n+["), "bound")
+  expect_error(qassert(1, "n+[1"), "lower")
+  expect_error(qassert(1, "n+[x,]"), "lower")
+  expect_error(qassert(1, "n+[,y]"), "upper")
+  expect_error(qassert(1, "n*("), "bound definition")
+  expect_error(qassert(1, "n*]"), "bound definition")
+  expect_error(qassert(1, "n*(1)xx"), "Additional chars found")
+  expect_error(qassert(1, TRUE), "be a string")
+  expect_error(qassert(1, NA_character_), "not be NA")
+  expect_error(qtest(1, TRUE), "be a string")
+  expect_error(qtest(1, NA_character_), "not be NA")
+})
+
+test_that("we get some output", {
+  expect_error(qassert(1, "b"), "logical")
+  expect_error(qassert(1, "l"), "list")
+  expect_error(qassert(1:2, "n?"), "length <=")
+})
+
+test_that("empty vectors", {
+  expect_succ_all(integer(0), "i*")
+  expect_succ_all(integer(0), "i*[0,0]")
+  expect_succ_all(integer(0), "n[0,0]")
+  expect_fail_all(integer(0), "r[0,0]")
+  expect_fail_all(integer(0), "*+")
+  expect_succ_all(TRUE, character(0))
+})
+
+test_that("logicals are not numeric", {
+  expect_fail_all(TRUE, "i")
+  expect_fail_all(TRUE, "I")
+  expect_fail_all(TRUE, "n")
+  expect_fail_all(TRUE, "N")
+})
+
+test_that("data frames are not lists", {
+  expect_fail_all(iris, "l")
+  expect_fail_all(iris, "L")
+})
+
+test_that("error messages are properly generated", {
+  expect_error(qassert(1, "N22"), "== 22")
+  expect_error(qassert(1:3, "N?"), "<= 1")
+  expect_error(qassert(integer(0), "N+"), ">= 1")
+
+  expect_error(qassert(1, "N[2,]"), ">= 2")
+  expect_error(qassert(1, "N(2,]"), "> 2")
+  expect_error(qassert(1, "N[,0]"), "<= 0")
+  expect_error(qassert(1, "N[,0)"), "< 0")
+
+  expect_error(qassert(Inf, "N[)"), "!= Inf")
+  expect_error(qassert(-Inf, "N(]"), "!= -Inf")
+})
diff --git a/tests/testthat/test_qassertr.R b/tests/testthat/test_qassertr.R
new file mode 100644
index 0000000..4e83d34
--- /dev/null
+++ b/tests/testthat/test_qassertr.R
@@ -0,0 +1,72 @@
+context("qtestr")
+
+expect_succ_all = function(x, rules) {
+  xn = deparse(substitute(x))
+  expect_true(qtestr(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_identical(qassertr(x, rules), x,
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_expectation_successful(qexpectr(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+}
+
+expect_fail_all = function(x, rules, pattern = NULL) {
+  xn = deparse(substitute(x))
+  expect_false(qtestr(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_error(qassertr(x, rules), regex = pattern,
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+  expect_expectation_failed(qexpectr(x, rules),
+    info = sprintf("rules: %s", paste0(rules, collapse=",")), label = xn)
+}
+
+test_that("qassertr / qtestr", {
+  x = list(a = 1:10, b = rnorm(10))
+  expect_succ_all(x, "n+")
+  expect_succ_all(x, "n10")
+  expect_succ_all(x, "n>=1")
+  expect_fail_all(x, "i+")
+  expect_fail_all(x, "l")
+
+  x = list(a = NULL, b = 10)
+  expect_succ_all(x, "*")
+  expect_fail_all(x, "0")
+  expect_fail_all(x, "n")
+
+  x = list(a = NULL, b = NULL)
+  expect_succ_all(x, "0")
+  expect_fail_all(x, "0+")
+
+  x = list()
+  expect_succ_all(x, "n+")
+  expect_succ_all(x, "0+")
+
+  x = list(1, 2)
+  expect_fail_all(x, "S1", pattern = "string")
+
+  x = list(1:10, NULL)
+  expect_succ_all(x, c("v", "l", "0"))
+  rules = c("v", "l")
+  expect_fail_all(x, c("v", "l"), pattern = "One of")
+
+  expect_succ_all(iris, c("f", "n"))
+  expect_fail_all(iris, c("s", "n"), pattern = "One of")
+
+  x = NULL
+  expect_error(qassertr(x, "x"), "list or data.frame")
+  expect_error(qtestr(x, "x"), "list or data.frame")
+})
+
+test_that("qtestr / depth", {
+  x = list(letters, 1:10, list(letters, 2:3, runif(10)))
+  rules = c("v", "l")
+  expect_true(qtestr(x, rules, depth = 1L))
+  expect_true(qtestr(x, rules, depth = 2L))
+  expect_true(qtestr(x, rules, depth = 3L))
+
+  x[[3]][[2]] = iris
+  expect_true(qtestr(x, rules, depth = 1L))
+  expect_true(qtestr(x, c(rules, "d"), depth = 1L))
+  expect_false(qtestr(x, rules, depth = 2L))
+  expect_false(qtestr(x, rules, depth = 3L))
+})
diff --git a/tests/testthat/test_wf.R b/tests/testthat/test_wf.R
new file mode 100644
index 0000000..bb84842
--- /dev/null
+++ b/tests/testthat/test_wf.R
@@ -0,0 +1,34 @@
+context("wf / wl")
+
+test_that("wf / wl", {
+  x = c(FALSE, TRUE, FALSE, TRUE)
+  expect_equal(wf(x), 2L)
+  expect_equal(wl(x), 4L)
+
+  x = c(NA, TRUE, NA, TRUE, NA)
+  expect_equal(wf(x), 2L)
+  expect_equal(wl(x), 4L)
+
+  x = logical(0L)
+  expect_equal(wf(x), integer(0L))
+  expect_equal(wl(x), integer(0L))
+  expect_equal(wf(x), integer(0L))
+  expect_equal(wl(x), integer(0L))
+
+  x = c(NA, NA)
+  expect_equal(wf(x), integer(0L))
+  expect_equal(wl(x), integer(0L))
+
+  x = setNames(c(NA, FALSE, TRUE, FALSE, TRUE, FALSE, NA), letters[1:7])
+  expect_identical(wf(x, TRUE), setNames(3L, "c"))
+  expect_identical(wf(x, FALSE), 3L)
+  expect_identical(wl(x), setNames(5L, "e"))
+  expect_identical(wl(x, FALSE), 5L)
+  expect_equal(wf(logical(0)), integer(0))
+  expect_equal(wl(logical(0)), integer(0))
+
+  expect_error(wf(42), "logical")
+  expect_error(wl(42), "logical")
+  expect_error(wf(NA, iris), "use.names")
+  expect_error(wl(NA, iris), "use.names")
+})
diff --git a/vignettes/checkmate.Rmd b/vignettes/checkmate.Rmd
new file mode 100644
index 0000000..6a4b1ea
--- /dev/null
+++ b/vignettes/checkmate.Rmd
@@ -0,0 +1,284 @@
+---
+title: "Checkmate"
+author: "Michel Lang"
+date: "`r Sys.Date()`"
+output: rmarkdown::html_vignette
+vignette: >
+  %\VignetteIndexEntry{checkmate}
+  %\VignetteEngine{knitr::rmarkdown}
+  %\VignetteEncoding{UTF-8}
+---
+```{r,include=FALSE}
+library(checkmate)
+```
+
+Ever used an R function that produced a not-very-helpful error message, just to discover after minutes of debugging that you simply passed a wrong argument?
+
+Blaming the laziness of the package author for not doing such standard checks (in a dynamically typed language such as R) is at least partially unfair, as R makes theses types of checks cumbersome and annoying. Well, that's how it was in the past.
+
+Enter checkmate.
+
+Virtually **every standard type of user error** when passing arguments into function can be caught with a simple, readable line which produces an **informative error message** in case.
+A substantial part of the package was written in C to **minimize any worries about execution time overhead**.
+
+## Intro
+As a motivational example, consider you have a function to calculate the faculty of a natural number and the user may choose between using either the stirling approximation or R's `factorial` function (which internally uses the gamma function).
+Thus, you have two arguments, `n` and `method`.
+Argument `n` must obviously be a positive natural number and `method` must be either `"stirling"` or `"factorial"`.
+Here is a version of all the hoops you need to jump through to ensure that these simple requirements are met:
+```{r}
+fact <- function(n, method = "stirling") {
+  if (length(n) != 1)
+    stop("Argument 'n' must have length 1")
+  if (!is.numeric(n))
+    stop("Argument 'n' must be numeric")
+  if (is.na(n))
+    stop("Argument 'n' may not be NA")
+  if (is.double(n)) {
+    if (is.nan(n))
+      stop("Argument 'n' may not be NaN")
+    if (is.infinite(n))
+      stop("Argument 'n' must be finite")
+    if (abs(n - round(n, 0)) > sqrt(.Machine$double.eps))
+      stop("Argument 'n' must be an integerish value")
+    n <- as.integer(n)
+  }
+  if (n < 0)
+    stop("Argument 'n' must be >= 0")
+  if (length(method) != 1)
+    stop("Argument 'method' must have length 1")
+  if (!is.character(method) || !method %in% c("stirling", "factorial"))
+    stop("Argument 'method' must be either 'stirling' or 'factorial'")
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+```
+And for comparison, here is the same function using checkmate:
+```{r}
+fact <- function(n, method = "stirling") {
+  assertCount(n)
+  assertChoice(method, c("stirling", "factorial"))
+
+  if (method == "factorial")
+    factorial(n)
+  else
+    sqrt(2 * pi * n) * (n / exp(1))^n
+}
+```
+
+## Function overview
+The functions can be split into four functional groups, indicated by their prefix.
+
+If prefixed with `assert`, an error is thrown if the corresponding check fails.
+Otherwise, the checked object is returned invisibly.
+There are many different coding styles out there in the wild, but most R programmers stick to either `camelBack` or `underscore_case`.
+Therefore, `checkmate` offers all functions in both flavors: `assert_count` is just an alias for `assertCount` but allows you to retain your favorite style.
+
+The family of functions prefixed with `test` always return the check result as logical value.
+Again, you can use `test_count` and `testCount` interchangeably.
+
+Functions starting with `check` return the error message as a string (or `TRUE` otherwise) and can be used if you need more control and, e.g., want to grep on the returned error message.
+
+`expect` is the last family of functions and is intended to be used with the [testthat package](https://cran.r-project.org/package=testthat).
+All performed checks are logged into the `testthat` reporter.
+Because `testthat` uses the `underscore_case`, the extension functions only come in the underscore style.
+
+All functions are categorized into objects to check on the [package help page](https://mllg.github.io/checkmate/reference/checkmate-package).
+
+## In case you miss flexibility
+
+You can use [assert](https://mllg.github.io/checkmate/reference/assert) to perform multiple checks at once and throw an assertion if all checks fail.
+
+Here is an example where we check that x is either of class `foo` or class `bar`:
+
+```{r}
+f <- function(x) {
+  assert(
+    checkClass(x, "foo"),
+    checkClass(x, "bar")
+  )
+}
+```
+
+Note that `assert(, combine = "or")` and `assert(, combine = "and")` allow to control the logical
+combination of the specified checks, and that the former is the default.
+
+
+## Argument Checks for the Lazy
+
+The following functions allow a special syntax to define argument checks using a special format specification.
+E.g., `qassert(x, "I+")` asserts that `x` is an integer vector with at least one element and no missing values.
+This very simple domain specific language covers a large variety of frequent argument checks with only a few keystrokes.
+You choose what you like best.
+
+* [qassert](https://mllg.github.io/checkmate/reference/qassert)
+* [qassertr](https://mllg.github.io/checkmate/reference/qassert)
+
+
+## checkmate as testthat extension
+To extend [testthat](https://cran.r-project.org/package=testthat), you need to IMPORT, DEPEND or SUGGEST on the `checkmate` package.
+Here is a minimal example:
+```{r,eval=FALSE}
+# file: tests/test-all.R
+library(testthat)
+library(checkmate) # for testthat extensions
+test_check("mypkg")
+```
+Now you are all set and can use more than 30 new expectations in your tests.
+```{r,eval=FALSE}
+test_that("checkmate is a sweet extension for testthat", {
+  x = runif(100)
+  expect_numeric(x, len = 100, any.missing = FALSE, lower = 0, upper = 1)
+  # or, equivalent, using the lazy style:
+  qexpect(x, "N100[0,1]")
+})
+```
+
+## Speed considerations
+
+In comparison with tediously writing the checks yourself in R (c.f. factorial example at the beginning of the vignette), R is sometimes a tad faster while performing checks on scalars.
+This seems odd at first, because checkmate is mostly written in C and should be comparably fast.
+Yet many of the functions in the `base` package are not regular functions, but primitives.
+While primitives jump directly into the C code, checkmate has to use the considerably slower `.Call` interface.
+As a result, it is possible to write (very simple) checks using only the base functions which, under some circumstances, slightly outperform checkmate.
+However, if you go one step further and wrap the custom check into a function to convenient re-use it, the performance gain is often lost (see benchmark 1).
+
+For larger objects the tide has turned because checkmate avoids many unnecessary intermediate variables.
+Also note that the quick/lazy implementation in `qassert`/`qtest`/`qexpect` is often a tad faster because only two arguments have to be evaluated (the object and the rule) to determine the set of checks to perform.
+
+Below you find some (probably unrepresentative) benchmark.
+But also note that this one here has been executed from inside `knitr` which is often the cause for outliers in the measured execution time.
+Better run the benchmark yourself to get unbiased results.
+
+
+### Benchmark 1: Assert that `x` is a flag
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+library(ggplot2)
+library(microbenchmark)
+
+x = TRUE
+r = function(x, na.ok = FALSE) { stopifnot(is.logical(x), length(x) == 1, na.ok || !is.na(x)) }
+cm = function(x) assertFlag(x)
+cmq = function(x) qassert(x, "B1")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 2: Assert that `x` is a numeric of length 1000 with no missing nor NaN values
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+x = runif(1000)
+r = function(x) stopifnot(is.numeric(x) && length(x) == 1000 && all(!is.na(x) & x >= 0 & x <= 1))
+cm = function(x) assertNumeric(x, len = 1000, any.missing = FALSE, lower = 0, upper = 1)
+cmq = function(x) qassert(x, "N1000[0,1]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 3: Assert that `x` is a character vector with no missing values nor empty strings
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+x = sample(letters, 10000, replace = TRUE)
+r = function(x) stopifnot(is.character(x) && !any(is.na(x)) && all(nchar(x) > 0))
+cm = function(x) assertCharacter(x, any.missing = FALSE, min.chars = 1)
+cmq = function(x) qassert(x, "S+[1,]")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+
+### Benchmark 4: Assert that `x` is a data frame with no missing values
+
+```{r,dev="svg",fig.width=6,fig.height=4}
+N = 10000
+x = data.frame(a = runif(N), b = sample(letters[1:5], N, replace = TRUE), c = sample(c(FALSE, TRUE), N, replace = TRUE))
+r = function(x) is.data.frame(x) && !any(sapply(x, function(x) any(is.na(x))))
+cm = function(x) testDataFrame(x, any.missing = FALSE)
+cmq = function(x) qtest(x, "D")
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+
+# checkmate tries to stop as early as possible
+x$a[1] = NA
+mb = microbenchmark(r(x), cm(x), cmq(x))
+print(mb)
+autoplot(mb)
+```
+
+## Extending checkmate
+
+To extend checkmate a custom `check*` function has to be written.
+For example, to check for a square matrix one can re-use parts of checkmate and extend the check with additional functionality:
+```{r}
+checkSquareMatrix = function(x, mode = NULL) {
+  # check functions must return TRUE on success
+  # and a custom error message otherwise
+  res = checkMatrix(x, mode = mode)
+  if (!isTRUE(res))
+    return(res)
+  if (nrow(x) != ncol(x))
+    return("Must be square")
+  return(TRUE)
+}
+
+# a quick test:
+X = matrix(1:9, nrow = 3)
+checkSquareMatrix(X)
+checkSquareMatrix(X, mode = "character")
+checkSquareMatrix(X[1:2, ])
+```
+The respective counterparts to the `check`-function can be created using the constructors [makeAssertionFunction](https://mllg.github.io/checkmate/reference/makeAssertion), [makeTestFunction](https://mllg.github.io/checkmate/reference/makeTest) and [makeExpectationFunction](https://mllg.github.io/checkmate/reference/makeExpectation):
+```{r}
+# For assertions:
+assert_square_matrix = assertSquareMatrix = makeAssertionFunction(checkSquareMatrix)
+print(assertSquareMatrix)
+
+# For tests:
+test_square_matrix = testSquareMatrix = makeTestFunction(checkSquareMatrix)
+print(testSquareMatrix)
+
+# For expectations:
+expect_square_matrix = makeExpectationFunction(checkSquareMatrix)
+print(expect_square_matrix)
+```
+Note that all the additional arguments `.var.name`, `add`, `info` and `label` are automatically joined with the function arguments of your custom check function.
+Also note that if you define these functions inside an R package, the constructors are called at build-time (thus, there is no negative impact on the runtime).
+
+## Calling checkmate from C/C++
+
+The package registers two functions which can be used in other packages' C/C++ code for argument checks.
+```{c,eval=FALSE}
+SEXP qassert(SEXP x, const char *rule, const char *name);
+Rboolean qtest(SEXP x, const char *rule);
+```
+These are the counterparts to [qassert](https://mllg.github.io/checkmate/reference/qassert) and [qtest](https://mllg.github.io/checkmate/reference/qassert).
+Due to their simplistic interface, they perfectly suit the requirements of most type checks in C/C++.
+
+For detailed background information on the register mechanism, see the [Exporting C Code](http://r-pkgs.had.co.nz/src.html#clang) section in Hadley's Book "R Packages" or [WRE](https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Registering-native-routines).
+Here is a step-by-step guide to get you started:
+
+1. Add `checkmate` to your "Imports" and LinkingTo" sections in your DESCRIPTION file.
+2. Create a stub file C source file which pulls in the provided C functions in order to compile them for your package. See example below.
+3. Include the provided header file `<checkmate.h>` in each compilation unit where you want to use checkmate.
+
+```{c,eval=FALSE}
+/* Example for (2), "checkmate_stub.c":*/
+#include <checkmate.h>
+#include <checkmate_stub.c>
+```
+
+## Session Info
+For the sake of completeness, here the `sessionInfo()` for the benchmark (but remember the note before on `knitr` possibly biasing the results).
+```{r}
+sessionInfo()
+```

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-checkmate.git



More information about the debian-med-commit mailing list