Pakete in R können verschiedene Arten von Abhängigkeiten von anderen Paketen haben. Einige dieser Typen geben harte Anforderungen an, d. H.% Co_de%, Depends
und Imports
.
Es gibt jedoch eine zweite Kategorie, die eine weichere Abhängigkeit anzeigt, d. h. LinkingTo
und Suggests
. In beiden Fällen bietet das Paket zusätzliche Funktionen, wenn das vorgeschlagene / erweiterte Paket verfügbar ist.
Hier ein konkretes Beispiel: Das Paket Enhances
importiert checkpoint
weil knitr
knitr
hilft, checkpoint
files zu analysieren.
Aber jetzt überlege ich, rmarkdown
in eine knitr
Abhängigkeit zu ändern, d. h. stelle nur diese Funktionalität zur Verfügung, wenn Suggests
tatsächlich installiert ist.
Für einen korrekten Komponententest bedeutet dies, dass ich beide Szenarien testen muss:
knitr
verfügbar ist, dann tu was. knitr
nicht verfügbar ist, dann warnen Sie und machen Sie nichts. Der eigentliche R-Code ist einfach:
%Vor%Frage
Aber wie kann ich Komponententests für beide Szenarien einrichten?
So wie ich es sehe, wird die einfache Tatsache, nach knitr
zu suchen, das require(knitr)
-Paket laden, wenn es in der lokalen Bibliothek verfügbar ist.
Um also Fall 1 zu testen, muss ich knitr
lokal installieren, was bedeutet, dass ich nicht nach Fall 2 testen kann.
Gibt es eine Möglichkeit, knitr
(oder ein anderes Einheitentestframework) für diesen Anwendungsfall zu konfigurieren?
Um zu testen, welcher Zweig bei Verwendung von require(knitr)
fehlschlägt, verwenden Sie trace()
, um require()
vorübergehend zu ändern, damit knitr nicht gefunden wird, auch wenn es in .libPaths()
vorhanden ist. . Setzen Sie den Wert von require()
im Körper von lib.loc=
auf R.home()
zurück - ein vorhandenes Verzeichnis, das kein knitr
-Paket enthält.
Dies scheint in einem Paket genauso gut zu funktionieren wie in einer interaktiven Sitzung, in der Sie Folgendes ausführen:
%Vor% Wenn ich das verstanden habe, haben Sie eine Funktion mit zwei Zweigen, von denen eine in R-Sitzungen ausgeführt werden soll, für die require(knitr)
erfolgreich ist, und die andere in Sitzungen, in denen sie fehlschlägt. Sie möchten diese Funktion dann "in beide Richtungen" von einer einzigen R-Instanz testen, in der knitr tatsächlich auf .libPaths()
steht.
Sie brauchen also eine Möglichkeit, um den Aufruf require(knitr)
vorübergehend auf das tatsächliche Vorhandensein von knitr zu blenden. Das vollständige und zeitweilige Zurücksetzen des von .libPaths()
zurückgegebenen Werts sah vielversprechend aus, scheint jedoch nicht möglich zu sein.
Ein weiterer vielversprechender Weg besteht darin, den Standardwert von lib.loc
in Aufrufen von require()
von NULL
(was "Wert von .libPaths()
verwendet") auf einen anderen Ort zurückzusetzen, wo knitr ist nicht verfügbar Sie können dies nicht erreichen, indem Sie base::require()
oder (in einem Paket) überschreiben, indem Sie eine lokale Maskierungsversion von require()
mit dem gewünschten Wert von lib.loc
definieren.
Es sieht jedoch so aus, als könnten Sie trace()
verwenden, um require()
temporär zu modifizieren (blenden Sie die Verfügbarkeit von knitr ein, indem Sie lib.loc=R.home()
setzen). Dann machen Sie untrace()
, um require()
auf die Vanilla-Version wiederherzustellen, die weitergeht und knitr findet.
So sah das in dem Dummy-Paket aus, mit dem ich es getestet habe. Zuerst eine R-Funktion, die es uns ermöglicht, den Erfolg entlang der beiden Zweige zu testen
%Vor%Dann ein paar Tests, einen für jeden Zweig:
%Vor% Um dies zu testen, habe ich pkgKitten::kitten("dummy")
verwendet, um ein Quellverzeichnis zu erstellen, in diese beiden Dateien kopiert, Suggests: knitr
zur Datei DESCRIPTION
hinzugefügt und dann devtools::install()
und devtools::check()
vom entsprechenden Verzeichnis ausgeführt . Das Paket wird problemlos installiert und übergibt alle Prüfungen.