[Sciviews-commits] r138 - in pkg: svSocket/R svSocket/inst/etc svSocket/man svUnit/inst/doc
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Jun 5 11:25:44 CEST 2009
Author: phgrosjean
Date: 2009-06-05 11:25:43 +0200 (Fri, 05 Jun 2009)
New Revision: 138
Added:
pkg/svSocket/R/getServerObj.R
pkg/svSocket/inst/etc/SimpleClientSecure.Tcl
Modified:
pkg/svSocket/R/processSocket.R
pkg/svSocket/R/sendSocketServer.R
pkg/svSocket/R/startSocketServer.R
pkg/svSocket/man/sendSocketServer.Rd
pkg/svUnit/inst/doc/svUnit.Rnw
pkg/svUnit/inst/doc/svUnit.lyx
pkg/svUnit/inst/doc/svUnit.pdf
Log:
svUnit vignette in LyX 1.6 format + hyperref use in PDF
changes to svSocket (first step to secure server)
Added: pkg/svSocket/R/getServerObj.R
===================================================================
--- pkg/svSocket/R/getServerObj.R (rev 0)
+++ pkg/svSocket/R/getServerObj.R 2009-06-05 09:25:43 UTC (rev 138)
@@ -0,0 +1,63 @@
+getServerObj <-
+function (x, envir = parent.frame(), server.envir = .GlobalEnv, con = NULL,
+host = "localhost", port = 8888, ...)
+{
+ # Copy an R object from the server to the client
+ objname <- as.character(substitute(x))
+ servenv <- deparse(substitute(server.envir))
+ if (is.null(con)) {
+ # Use sendSocketServer() to open a connection to the serve, request the
+ # object, and close the connection
+ objdump <- sendSocketServer(paste('suppressWarnings(dump("', objname,
+ '", file = "", envir = ', servenv,
+ '))', sep = ""), host = host, port = port, ...)
+ } else {
+ # otherwise, use con to exchange data with the server, with a flag
+ # to indicate where the returned dumped version of the R object ends
+ writeLines(paste('suppressWarnings(dump("', objname,
+ '", file = "", envir = ', servenv,
+ ')); cat("<<<endflag>>>")', sep = ""), con)
+ objdump <- ""
+ while (regexpr("<<<endflag>>>", objdump) < 0)
+ objdump <- paste(objdump, readLines(con), sep = "", collapse = "\n")
+ objdump <- sub("<<<endflag>>>", "", objdump)
+ }
+ # Source the content of objdump, locally, or in .GlobalEnv on the client R
+ objcon <- textConnection(objdump)
+ on.exit(close(objcon))
+ res <- eval(source(objcon, local = TRUE, echo = FALSE,
+ verbose = FALSE), envir = envir)
+}
+
+setServerObj <-
+function (x, envir = .GlobalEnv, server.envir = .GlobalEnv, con = NULL,
+host = "localhost", port = 8888, ...)
+{
+ # Copy an R object from the client to the server
+ objname <- as.character(substitute(x))
+ # Get a dump of the local object
+ objdump <- suppressWarnings(dump(objname, file = "", envir = server.envir))
+
+ servenv <- deparse(substitute(server.envir))
+ if (is.null(con)) {
+ # Use sendSocketServer() to open a connection to the serve, request the
+ # object, and close the connection
+ objdump <- sendSocketServer(paste('suppressWarnings(dump("', objname,
+ '", file = "", envir = ', servenv,
+ '))', sep = ""), host = host, port = port, ...)
+ } else {
+ # otherwise, use con to exchange data with the server, with a flag
+ # to indicate where the returned dumped version of the R object ends
+ writeLines(paste('suppressWarnings(dump("', objname,
+ '", file = "", envir = ', servenv,
+ ')); cat("<<<endflag>>>")', sep = ""), con)
+ objdump <- ""
+ while (regexpr("<<<endflag>>>", objdump) < 0)
+ objdump <- paste(objdump, readLines(con), sep = "", collapse = "\n")
+ objdump <- sub("<<<endflag>>>", "", objdump)
+ }
+ # Source the content of objdump, locally, or in .GlobalEnv on the client R
+ objcon <- textConnection(objdump)
+ on.exit(close(objcon))
+ source(objcon, local = local, echo = FALSE, verbose = FALSE)
+}
\ No newline at end of file
Modified: pkg/svSocket/R/processSocket.R
===================================================================
--- pkg/svSocket/R/processSocket.R 2009-06-03 15:49:10 UTC (rev 137)
+++ pkg/svSocket/R/processSocket.R 2009-06-05 09:25:43 UTC (rev 138)
@@ -53,15 +53,22 @@
#timestamp("my R command", "", "", quiet = TRUE)
} else if (startmsg == "<<<h>>>") {
msg <- substr(msg, 8, 1000000)
+ # Do not echo command on the server (silent execution)
hiddenMode <- TRUE
parSocket(client, serverport, bare = TRUE, last = "\n\f")
} else if (startmsg == "<<<H>>>") {
msg <- substr(msg, 8, 1000000)
- # Indicate to the client that he can disconnect now
+ # Do not echo command on the server (silent execution with no return)
closeSocketClients(sockets = socket, serverport = serverport)
hiddenMode <- TRUE
returnResults <- FALSE
parSocket(client, serverport, bare = TRUE)
+ } else if (startmsg == "<<<u>>>") {
+ msg <- substr(msg, 8, 1000000)
+ # Silent execution, nothing is returned to the client (but still echoed to the server)
+ hiddenMode <- FALSE
+ returnResults <- FALSE
+ parSocket(client, serverport, bare = TRUE)
}
# Get parameters for the client
Modified: pkg/svSocket/R/sendSocketServer.R
===================================================================
--- pkg/svSocket/R/sendSocketServer.R 2009-06-03 15:49:10 UTC (rev 137)
+++ pkg/svSocket/R/sendSocketServer.R 2009-06-05 09:25:43 UTC (rev 138)
@@ -1,19 +1,19 @@
"sendSocketServer" <-
-function (text, serverhost = "localhost", serverport = 8888, ...)
+function (text, host = "localhost", port = 8888, ...)
{
# This function connects to a R socket server, evaluates a command in it
# get results and closes the connection. See example for a client that
# connects for a longer time and sends several commands to the server
if (!capabilities("sockets"))
stop("R must support socket connections")
- con <- socketConnection(host = serverhost, port = serverport,
+ con <- socketConnection(host = host, port = port,
blocking = FALSE, ...)
on.exit(close(con))
# <<<q>>> tells the R socket server to close the connection once results
# are send back to the client
writeLines(paste("<<<q>>>", text, sep = ""), con)
res <- ""
- while(regexpr("\n\f", res) < 0)
+ while(regexpr("\f", res) < 0)
res <- paste(res, readLines(con), sep = "", collapse = "\n")
- return(sub("\n\f", "", res))
+ return(sub("\f", "", res))
}
Modified: pkg/svSocket/R/startSocketServer.R
===================================================================
--- pkg/svSocket/R/startSocketServer.R 2009-06-03 15:49:10 UTC (rev 137)
+++ pkg/svSocket/R/startSocketServer.R 2009-06-05 09:25:43 UTC (rev 138)
@@ -1,5 +1,6 @@
"startSocketServer" <-
-function (port = 8888, server.name = "Rserver", procfun = processSocket)
+function (port = 8888, server.name = "Rserver", procfun = processSocket,
+secure = FALSE, local = !secure)
{
# OK, could be port = 80 to emulate a simple HTML server
# This is the main function that starts the server
@@ -9,8 +10,15 @@
# It is designed in a way that R can open simultaneously several ports and
# accept connection from multiple clients to each of them.
# Commands from each port can be processed differently
- # For security reasons, this server currently only accepts local connections
+ # Secure server requires the tcl-tls package!
+ if (isTRUE(secure)) {
+ # On Mac with AquaTclTk installed, I need: addTclPath("/System/Library/Tcl")
+ res <- tclRequire("tls")
+ if (!inherits(res, "tclObj"))
+ stop("You must install the tcl-tls package for using a secure server!")
+ }
+
is.function (procfun) || stop("'procfun' must be a function!")
# Note: the data send by the client is in the Tcl $::sockMsg variable
# Could a clash happen here if multiple clients send data at the
@@ -178,26 +186,55 @@
# Create the Tcl function that accepts input from a client
# (a different one for each server port)
- cmd <- paste(c(paste("proc sockAccept_", port, " {sock addr port} {",
- sep = ""),
- paste("global Rserver_", port, sep = ""),
- "# Configure the socket",
- "fconfigure $sock -buffering line -blocking 0",
- "# Accept only local clients",
- "if {$addr != \"127.0.0.1\"} {",
- " # puts $sock \"Error: Only local clients allowed!\"",
- " close $sock",
- " return",
- "}",
- paste("set Rserver_", port, "($sock) [list $addr, $port]", sep = ""),
- paste("fileevent $sock readable [list sockHandler_", port,
- " $sock] }", sep = "")),
- collapse = "\n")
+ # Code is slightly different if the server is only local or not
+ if (isTRUE(local)) {
+ cmd <- paste(c(paste("proc sockAccept_", port, " {sock addr port} {",
+ sep = ""),
+ paste("global Rserver_", port, sep = ""),
+ "# Configure the socket",
+ "fconfigure $sock -buffering line -blocking 0",
+ "# Accept only local clients",
+ "if {$addr != \"127.0.0.1\"} {",
+ " # puts $sock \"Error: Only local clients allowed!\"",
+ " close $sock",
+ " return",
+ "}",
+ paste("set Rserver_", port, "($sock) [list $addr, $port]", sep = ""),
+ paste("fileevent $sock readable [list sockHandler_", port,
+ " $sock] }", sep = "")),
+ collapse = "\n")
+ } else {
+ cmd <- paste(c(paste("proc sockAccept_", port, " {sock addr port} {",
+ sep = ""),
+ paste("global Rserver_", port, sep = ""),
+ "# Configure the socket",
+ "fconfigure $sock -buffering line -blocking 0",
+ paste("set Rserver_", port, "($sock) [list $addr, $port]", sep = ""),
+ paste("fileevent $sock readable [list sockHandler_", port,
+ " $sock] }", sep = "")),
+ collapse = "\n")
+ }
.Tcl(cmd)
# Create the socket server itself in Tcl (a different one for each port)
- .Tcl(paste("set Rserver_", port, "(main) [socket -server sockAccept_",
- port, " ", port, "]", sep =""))
+ # If we want a secure server, use the tls secured socket instead
+ if (isTRUE(secure)) {
+ .Tcl(paste("set Rserver_", port, "(main) [tls::socket -server sockAccept_",
+ #port, " -require 1 -cafile caPublic.pem -certfile ~/serverR.pem ",
+ port, " -certfile Rserver.pem -keyfile Rserver.pem -ssl2 1 -ssl3 1 -tls1 0 -require 0 -request 0 ",
+ port, "]", sep =""))
+ # For client, use:
+ # set chan [tls::socket -cafile caPublic.pem -certfile ~/clientR.pem server.site.net $port]
+ # To generate the keys:
+ # cd ~
+ # Copy /System/Library/OpenSSL/openssl.cnf on ~, and edit
+ # openssl genrsa -out serverR.pem 1024 # use -des3 to secure with a password
+ # openssl req -new -x509 -key serverR.pem -out clientR.pem -days 365 -config openssl.cnf
+ # ... and answer to a couple of questions
+ } else {
+ .Tcl(paste("set Rserver_", port, "(main) [socket -server sockAccept_",
+ port, " ", port, "]", sep =""))
+ }
# Add this port in the TempEnv variable 'SocketServers'
socks <- getSocketServers()
Added: pkg/svSocket/inst/etc/SimpleClientSecure.Tcl
===================================================================
--- pkg/svSocket/inst/etc/SimpleClientSecure.Tcl (rev 0)
+++ pkg/svSocket/inst/etc/SimpleClientSecure.Tcl 2009-06-05 09:25:43 UTC (rev 138)
@@ -0,0 +1,91 @@
+#!/usr/local/bin/tclsh8.4
+# Open a terminal and issue
+# $ tclsh SimpleClient.tcl
+# when the R socket server is running
+# (Under Windows, you need to install ActiveTcl8.4 first;
+# see http://www.activestate.com/Products/ActiveTcl/)
+
+# We use a TLS secure layer to communicate with the server
+package require tls
+# Start R socket server with startSocketServer(secure = TRUE)
+
+# These are parameters of the R socket server
+set rsHost "localhost" ;# localhost for example, but could be distant machine
+set rsPort 8888 ;# port is arbitrarily fixed at 8888 for the R server
+
+# Read data from a channel (the R socket server) and put it into stdout
+# this implements receiving and handling (viewing) a server reply
+proc read_sock {sock} {
+ if {[eof $sock] == 1 || [catch {gets $sock l}] || $l == "\f"} {
+ fileevent $sock readable {}
+ close $sock
+ # puts "\nR socket server closed!"
+ global eventLoop
+ set eventLoop "done"
+ } else {
+ foreach {out in} [split $l "\n"] {
+ if {$out == "> " || $out == "+ "} {
+ puts -nonewline stdout $out
+ flush stdout
+ } else {
+ ### TODO: a special command to insert a string before the command line!
+ puts stdout "$out"
+ }
+ }
+ }
+}
+
+# Read a line of text from stdin and send it to the R socket server,
+# on eof stdin closedown (ctrl-c) the R server client socket connection
+# this implements sending a message to the Server.
+proc read_stdin {wsock} {
+ set l [gets stdin]
+ if {[eof stdin] == 1} {
+ fileevent $wsock readable {}
+ close $wsock ;# close the socket client connection
+ global eventLoop
+ set eventLoop "done" ;# terminate the vwait (eventloop)
+ } else {
+ puts $wsock $l ;# send the data to the server
+ }
+}
+
+# Open the connection to the R socket server...
+# this is a synchronous connection:
+# The command does not return until the server responds to the
+# connection request
+set rsSock [tls::socket $rsHost $rsPort]
+
+if {[eof $rsSock] == 1} {
+ close $rsSock ;# connection closed ... abort
+} else {
+
+ # Setup monitoring on the socket so that when there is data to be
+ # read the proc "read_sock" is called
+ fileevent $rsSock readable [list read_sock $rsSock]
+
+ # configure channel modes
+ # ensure the socket is line buffered so we can get a line of text
+ # at a time (because that's what the server expects)...
+ # Depending on your needs you may also want this unbuffered so
+ # you don't block in reading a chunk larger than has been fed
+ # into the socket
+ # i.e fconfigure $esvrSock -blocking off
+ # but this requires some modifications in the R socket server!
+ fconfigure $rsSock -buffering line
+
+ # set up our keyboard read event handler:
+ # Vector stdin data to the socket
+ fileevent stdin readable [list read_stdin $rsSock]
+
+ # message indicating connection accepted and we're ready to go
+ puts "Connected to R socket server"
+ puts "...what you type should be send to R."
+ puts "Paste only one line of code at a time."
+ puts " hit <CTRL-C> to close the connection."
+
+ # wait for and handle either socket or stdin events...
+ vwait eventLoop
+
+ puts "\nConnection with R is closed!"
+}
Property changes on: pkg/svSocket/inst/etc/SimpleClientSecure.Tcl
___________________________________________________________________
Name: svn:executable
+ *
Modified: pkg/svSocket/man/sendSocketServer.Rd
===================================================================
--- pkg/svSocket/man/sendSocketServer.Rd 2009-06-03 15:49:10 UTC (rev 137)
+++ pkg/svSocket/man/sendSocketServer.Rd 2009-06-05 09:25:43 UTC (rev 138)
@@ -6,18 +6,19 @@
\description{
The text is send to one R socket server and evaluated there as a command in
\code{.GlobalEnv}. Results (text as it should be printed on the console) is
- returned to the client and the client then disconnects automatically.
+ returned to the client and the client then disconnects automatically (code
+ received for indicating to disconnect is \f... don't use it for other purposes)!
}
\usage{
-sendSocketServder(text, serverhost = "localhost", serverport = 8888)
+sendSocketServer(text, host = "localhost", port = 8888)
}
\arguments{
\item{text}{ The text (command) to send and evaluate in the server. }
- \item{serverhost}{ The name or address of the host where the R socket server
+ \item{host}{ The name or address of the host where the R socket server
is located. }
- \item{serverport}{ The port of the R socket server. }
+ \item{port}{ The port of the R socket server. }
}
\author{Philippe Grosjean (\email{phgrosjean at sciviews.org})}
@@ -30,6 +31,7 @@
# Start a R socket server in an instance #1 of R
# require(svSocket)
# startSocketServer()
+# data(iris) # To get something in .GlobalEnv
#
# Now, start an instance #2 of R on the same machine and do:
require(svSocket)
Modified: pkg/svUnit/inst/doc/svUnit.Rnw
===================================================================
--- pkg/svUnit/inst/doc/svUnit.Rnw 2009-06-03 15:49:10 UTC (rev 137)
+++ pkg/svUnit/inst/doc/svUnit.Rnw 2009-06-05 09:25:43 UTC (rev 138)
@@ -1,4 +1,4 @@
-%% LyX 1.5.6 created this file. For more info, see http://www.lyx.org/.
+%% LyX 1.6.3 created this file. For more info, see http://www.lyx.org/.
%% Do not edit unless you really know what you are doing.
\documentclass[a4paper,english]{article}
\usepackage{lmodern}
@@ -6,11 +6,37 @@
\renewcommand{\ttdefault}{lmtt}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
+\usepackage{color}
+\usepackage{babel}
+
\usepackage{framed}
\usepackage{url}
\usepackage{graphicx}
+\definecolor{shadecolor}{rgb}{0.7,0.7,0.7}
+\usepackage[unicode=true, pdfusetitle,
+ bookmarks=true,bookmarksnumbered=false,bookmarksopen=false,
+ breaklinks=true,pdfborder={0 0 1},backref=false,colorlinks=true]
+ {hyperref}
\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
+
+\providecommand{\proglang}[1]{\textsf{#1}}
+
+\providecommand{\file}[1]{`\textsf{#1}'}
+
+\providecommand{\command}[1]{\texttt{#1}}
+
+\providecommand{\pkg}[1]{{\fontseries{b}\selectfont #1}}
+
+\providecommand{\code}[1]{\texttt{#1}}
+
+\providecommand{\var}[1]{{\normalfont\textsl{#1}}}
+
+\providecommand{\kbd}[1]{\textsf{\textsc{#1}}}
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
\newenvironment{lyxSchunk}{}{}
\newenvironment{lyxlist}[1]
@@ -21,7 +47,7 @@
\renewcommand{\makelabel}[1]{##1\hfil}}}
{\end{list}}
\newenvironment{lyxcode}
-{\begin{list}{}{
+{\par\begin{list}{}{
\setlength{\rightmargin}{\leftmargin}
\setlength{\listparindent}{0pt}% needed for AMS classes
\raggedright
@@ -30,21 +56,12 @@
\normalfont\ttfamily}%
\item[]}
{\end{list}}
-\providecommand{\proglang}[1]{\textsf{#1}}
-\providecommand{\code}[1]{\texttt{#1}}
-\providecommand{\command}[1]{\texttt{#1}}
-\providecommand{\pkg}[1]{{\fontseries{b}\selectfont #1}}
-\providecommand{\var}[1]{{\normalfont\textsl{#1}}}
-\providecommand{\kbd}[1]{\textsf{\textsc{#1}}}
-\providecommand{\file}[1]{`\textsf{#1}'}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
% \VignetteIndexEntry{svUnit - A framework for unit testing in R}
\makeatother
-\usepackage{babel}
-
\begin{document}
\title{svUnit - A framework for unit testing in R }
@@ -71,7 +88,6 @@
However, the \proglang{R} approach lacks a certain number of features
to allow optimal use of unit tests as in extreme programming (test
first \textendash{} code second):
-
\begin{itemize}
\item Tests are related to package compilation and cannot easily be run
independently (for instance, for functions developed separately).
@@ -94,12 +110,12 @@
\subsection{Unit testing in R without svUnit}
-Besides the \char`\"{}regular\char`\"{} testing mechanism of \proglang{R}
-packages, one can find the \pkg{RUnit} package on CRAN (\url{http://cran.r-project.org}).
-Another package used to provide test unit, \pkg{butler}, but it is
-not maintained any more and seems to have given up in favor of \pkg{RUnit}.
-\pkg{RUnit} implements the following features:
-
+Besides the \textquotedbl{}regular\textquotedbl{} testing mechanism
+of \proglang{R} packages, one can find the \pkg{RUnit} package on
+CRAN (\url{http://cran.r-project.org}). Another package used to provide
+test unit, \pkg{butler}, but it is not maintained any more and seems
+to have given up in favor of \pkg{RUnit}. \pkg{RUnit} implements
+the following features:
\begin{itemize}
\item \textbf{Assertions} for tests (\code{checkEquals()}, \code{checkEqualsNumeric()},
\code{checkIdentical()} and \code{checkTrue()}) and negative tests
@@ -141,7 +157,7 @@
of the tests (for instance, nightly check of code in a server), rather
that real-time interaction with the tests.
-There is also no integration with the \char`\"{}regular\char`\"{}
+There is also no integration with the \textquotedbl{}regular\textquotedbl{}
\command{R CMD check} mechanism of \proglang{R} in \pkg{RUnit}.
There is an embryo of organization of these tests units to make them
compatible with the \command{R CMD check} mechanism of \proglang{R}
@@ -201,7 +217,6 @@
The \pkg{svUnit} package is not available on CRAN (\url{http://cran.r-project.org})
yet, but it is available from R-Forge (\url{http://r-forge.r-project.org}).
You can download it from \proglang{R} by:
-
\begin{lyxSchunk}
<<eval = FALSE>>=
@@ -216,7 +231,6 @@
Once the svUnit package is installed, you can check it is working
well with the following example code:
-
\begin{lyxSchunk}
<<>>=
@@ -245,14 +259,12 @@
@
\end{lyxSchunk}
%
-\begin{framed}
+\begin{framed}%
Although test unit code is compatible with both \pkg{svUnit} and
\pkg{RUnit}, do not load both packages in \proglang{R} memory at
-the same time, or you will badly mix incompatible code between them!
-\end{framed}
+the same time, or you will badly mix incompatible code between them!\end{framed}
-
\section{Overview of svUnit}
You ensure that code you write in \proglang{R} functions does work
@@ -266,7 +278,6 @@
}. Of course, you can also define batteries of tests that are independent
of any \proglang{R} object, or that check several of them together
(integration tests). Here is a couple of examples:
-
\begin{lyxSchunk}
<<>>=
@@ -327,7 +338,6 @@
using \code{summary(Log())}. So, to run test for your \code{Square()}
function as well as your \code{test\_Integrate} integration test,
you simply do the following:
-
\begin{lyxSchunk}
<<>>=
@@ -350,12 +360,12 @@
test code that should stop() in R. So, if that test does not raises
an exception, it is considered to have failed. This is useful to check
that your functions correctly trap wrong arguments, for instance,
-like in \code{checkException(Square(\char`\"{}xx\char`\"{}))} here
-above (a character string is provided where a numerical value is expected).
+like in \code{checkException(Square(\textquotedbl{}xx\textquotedbl{}))}
+here above (a character string is provided where a numerical value
+is expected).
Now, let's look what happen if we test the \code{Cube()} function
without clearing the logger:
-
\begin{lyxSchunk}
<<>>=
@@ -366,7 +376,6 @@
@
\end{lyxSchunk}
We note two things:
-
\begin{enumerate}
\item The results of the tests on \code{Cube()} are added to the previous
report. So, it is possible to build rather easily reports that summarize
@@ -386,7 +395,6 @@
The most basic item is an \textbf{assertion} represented by a \code{checkxxx()}
function in \pkg{svUnit}/\pkg{RUnit}. Five such functions are currently
defined:
-
\begin{lyxlist}{00.00.0000}
\item [{\code{checkEquals(current, target)}}] determines if data in \var{target}
is the same as data in \var{current}.
@@ -424,7 +432,6 @@
So, executing a series of assertions and getting a report is simply
done as (in its simplest form, you can use the checkxxx() functions
directly at the command line):
-
\begin{lyxSchunk}
<<>>=
@@ -478,13 +485,13 @@
\includegraphics{svUnit_wikiReport}
\caption{\label{fig:wikireport}a svUnit test report as it appears when inserted
-in a wiki page (DokuWiki engine with the \code{creole} plugin installed).
-Note the summary of results at the top lef of the page, and the clickable
-table of contents with exhaustive and detailed entries to easily navigate
-to the test results you want to consult). Timing of the test is also
-clearly indicated, since it is a complementary but important information
-(if a test succeeds, but calculation is way too long, it is good to
-know it)!}
+in a wiki page (DokuWiki engine with the \protect\code{creole} plugin
+installed). Note the summary of results at the top lef of the page,
+and the clickable table of contents with exhaustive and detailed entries
+to easily navigate to the test results you want to consult). Timing
+of the test is also clearly indicated, since it is a complementary
+but important information (if a test succeeds, but calculation is
+way too long, it is good to know it)!}
\end{figure}
@@ -497,7 +504,6 @@
\pkg{svUnit} provides a series of methods and tools to manipulate
the log file from the command line, in particular, \code{stats()},
\code{summary()}, \code{metadata()}, \code{ls()}:
-
\begin{lyxSchunk}
<<>>=
@@ -537,7 +543,6 @@
\code{\$} operator. There are, of course similar methods defined
for those \var{svTestData} objects, like \code{print()}, \code{summary()},
and \code{stats()}:
-
\begin{lyxSchunk}
<<>>=
@@ -557,7 +562,6 @@
test data the same way as objects in any other environment. For instance,
if you want to delete a particular test data without touching to the
rest, you can use:
-
\begin{lyxSchunk}
<<>>=
@@ -585,7 +589,6 @@
of assertions applied to one object, method, or function to be checked
(this is not obligatory, assertions are not restricted to one object,
but good practices strongly suggest it). Here is an example:
-
\begin{lyxSchunk}
<<>>=
@@ -615,7 +618,6 @@
(not \pkg{RUnit}), you run this test simply by using \code{runTest()},
which returns the results invisibly (and you are supposed to access
results from the logger):
-
\begin{lyxSchunk}
<<>>=
@@ -633,7 +635,6 @@
tested object conveniently form a single entity that one can manipulate,
copy, save, reload, etc. with all the usual tools in \proglang{R}.
This association is simply made using \code{test(myobj) <-}:
-
\begin{lyxSchunk}
<<>>=
@@ -660,7 +661,6 @@
@
\end{lyxSchunk}
One can retrieve the test associated with the object by using:
-
\begin{lyxSchunk}
<<>>=
@@ -670,7 +670,6 @@
\end{lyxSchunk}
And of course, running the test associated with an object is as easy
as:
-
\begin{lyxSchunk}
<<>>=
@@ -706,12 +705,11 @@
functions, plus possibly \code{.setUp()} and \code{.tearDown()}
functions (see the online help for further information on these special
functions). In \pkg{RUnit}, you must write such test unit files from
-scratch. With \pkg{svUnit}, you can \char`\"{}promote\char`\"{} one
-or several test functions (associated to other objects, or \char`\"{}living\char`\"{}
+scratch. With \pkg{svUnit}, you can \textquotedbl{}promote\textquotedbl{}
+one or several test functions (associated to other objects, or \textquotedbl{}living\textquotedbl{}
alone as separate \var{svTest} objects) by using the \code{makeUnit()}
method. Here is how you promote the test associated with our \code{Square()}
function to a simple unit test containing only one function:
-
\begin{lyxSchunk}
<<>>=
@@ -731,7 +729,6 @@
functions are constructed automatically for you. They specify the
context of these tests. This context is used by the GUI in Komodo
to locate the test function and the code being tested.
-
\begin{lyxcode}
\#\#~Test~unit~'Square'
@@ -743,19 +740,19 @@
~~~~\#\#~Specific~actions~for~svUnit:~prepare~context
-~~~~if~(\char`\"{}package:svUnit\char`\"{}~\%in\%~search())~\{
+~~~~if~(\textquotedbl{}package:svUnit\textquotedbl{}~\%in\%~search())~\{
~~~~~~~~.Log~<-~Log()~\#\#~Make~sure~.Log~is~created
-~~~~~~~~.Log\$..Unit~<-~\char`\"{}/tmp/RtmpBoZnId/runitSquare.R\char`\"{}
+~~~~~~~~.Log\$..Unit~<-~\textquotedbl{}/tmp/RtmpBoZnId/runitSquare.R\textquotedbl{}
-~~~~~~~~.Log\$..File~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..File~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Obj~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Obj~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Tag~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Tag~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Msg~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Msg~<-~\textquotedbl{}\textquotedbl{}
~~~~~~~~rm(..Test,~envir~=~.Log)
@@ -771,17 +768,17 @@
~~~~\#\#~Specific~actions~for~svUnit:~clean~up~context
-~~~~if~(\char`\"{}package:svUnit\char`\"{}~\%in\%~search())~\{
+~~~~if~(\textquotedbl{}package:svUnit\textquotedbl{}~\%in\%~search())~\{
-~~~~~~~~.Log\$..Unit~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Unit~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..File~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..File~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Obj~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Obj~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Tag~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Tag~<-~\textquotedbl{}\textquotedbl{}
-~~~~~~~~.Log\$..Msg~<-~\char`\"{}\char`\"{}
+~~~~~~~~.Log\$..Msg~<-~\textquotedbl{}\textquotedbl{}
~~~~~~~~rm(..Test,~envir~=~.Log)
@@ -791,7 +788,7 @@
-\char`\"{}testSquare\char`\"{}~<-
+\textquotedbl{}testSquare\textquotedbl{}~<-
function()~\{
@@ -799,14 +796,14 @@
~~~~checkEquals(c(1,~4,~9),~Square(1:3))
-~~~~checkException(Square(\char`\"{}xx\char`\"{}))
+~~~~checkException(Square(\textquotedbl{}xx\textquotedbl{}))
\}
\end{lyxcode}
Compatibility of these test unit files between \pkg{RUnit} and \pkg{svUnit}
was a major concern in the design of \pkg{svUnit}. Consequently,
code specific to \pkg{svUnit} (for managing the context of the test)
-is embedded in a \code{if (\char`\"{}package:svUnit\char`\"{} \%in\% search())}.
+is embedded in a \code{if (\textquotedbl{}package:svUnit\textquotedbl{} \%in\% search())}.
That way, if \pkg{svUnit} is not loaded in memory, this code is not
executed. \emph{Note that you should avoid loading in memory both
\pkg{svUnit} and \pkg{RUnit} at the same time. If you do so, you
@@ -819,7 +816,6 @@
If you intend to associate test units to \proglang{R} package, you
should respect the following conventions:
-
\begin{itemize}
\item Name your test units \file{runit{*}.R}.
\item Place them in the \file{/inst/unitTests} subdirectory of the package
@@ -847,7 +843,6 @@
which is not the case for \file{/tests}). Here is what you do to
associate some or all of your unit tests to \command{R CMD check}
(illustrated with the \pkg{svUnit} example):
-
\begin{itemize}
\item Define a \file{.Rd} file in \file{/man} called \file{unitTests.Rd}
(or whatever name you prefer).
@@ -865,8 +860,7 @@
your packages, that is, they will run silently each time you test
your package if no error occurs, but will produce a detailed report
in case of problems.
-\item Here is how your \file{.Rd} file should looks like:
-\end{itemize}
+\item Here is how your \file{.Rd} file should looks like:\end{itemize}
\begin{lyxcode}
\textbackslash{}name\{unitTests\}
@@ -912,7 +906,7 @@
\#~Run~all~test~units~defined~in~'svUnit'~package
-(runTest(svSuite(\char`\"{}package:svUnit\char`\"{}),~\char`\"{}svUnit\char`\"{}))~
+(runTest(svSuite(\textquotedbl{}package:svUnit\textquotedbl{}),~\textquotedbl{}svUnit\textquotedbl{}))~
@@ -928,9 +922,9 @@
\#~the~/unitTests/VirtualClass~subdir
-(runTest(svSuite(\char`\"{}package:svUnit~(VirtualClass)\char`\"{}),
+(runTest(svSuite(\textquotedbl{}package:svUnit~(VirtualClass)\textquotedbl{}),
-~~\char`\"{}VirtualClass\char`\"{}))
+~~\textquotedbl{}VirtualClass\textquotedbl{}))
\}
@@ -950,7 +944,6 @@
\end{lyxcode}
Also, you provide a very convenient and easy way to test a package
from the command line in an interactive session by running:
-
\begin{lyxSchunk}
<<>>=
@@ -1005,7 +998,6 @@
argument suggests it, the regular expression for list exclusion should
be kept in the \var{svUnit.excludeList} \proglang{R} option. Here
is how it works:
-
\begin{lyxSchunk}
<<>>=
@@ -1022,7 +1014,6 @@
and \code{package:svUnit (VirtualClass)} match first pattern and
are thus excluded. Now, let's clear the exclusion list to see what
happens:
-
\begin{lyxSchunk}
<<>>=
@@ -1038,7 +1029,6 @@
Now, you have noticed that svSuiteList() can also find \var{svTest}
objects, as well as tests attached to objects in the user's workspace.
You can create a suite by collecting all these items like this:
-
\begin{lyxSchunk}
<<>>=
@@ -1048,7 +1038,6 @@
\end{lyxSchunk}
Now let\textquoteright{}s make a more complex test unit using test
functions collected in this suite:
-
\begin{lyxSchunk}
<<>>=
@@ -1065,7 +1054,6 @@
in packages that are \textbf{not} in the exclusion list. Running tests
in your suite is also very simple. Always remember the \code{runTest()}
method, and the management of the logger:
-
\begin{lyxSchunk}
<<>>=
@@ -1101,18 +1089,17 @@
\includegraphics{svUnit_KomodoRUnit}
\caption{\label{fig:KomodoRUnit}Komodo Edit with SciViews-K and SciViews-K
-Unit after running tests. At right: the \kbd{R Unit} panel that display
-(at the top) the list of available tests, and test units where you
-can select the one to run, and at the bottom, a tree with the results
-from last tests run. The stripe at the very top is green if all tests
-succeed, and red (as here), if at least one tests failed or raised
-an error.}
+Unit after running tests. At right: the \protect\kbd{R Unit} panel
+that display (at the top) the list of available tests, and test units
+where you can select the one to run, and at the bottom, a tree with
+the results from last tests run. The stripe at the very top is green
+if all tests succeed, and red (as here), if at least one tests failed
+or raised an error.}
\end{figure}
-
\begin{itemize}
\item Select the tests you want to run in the top part,
\item Click the \kbd{Run} button each time you want to refresh the test
@@ -1131,17 +1118,14 @@
tests on the background while you type your code!
%
-\begin{framed}
+\begin{framed}%
Make sure also to look at the \code{koUnit\_xxx()} functions in the
\pkg{svUnit} package. These functions allow to control the GUI in
-Komodo remotely from within \proglang{R} and \proglang{R} code.
-\end{framed}
-
-
-\begin{thebibliography}{1}
+Komodo remotely from within \proglang{R} and \proglang{R} code.\end{framed}
+\begin{thebibliography}{6}
\bibitem{Grosjean}Grosjean, Ph., 2003. SciViews: an object-oriented
abstraction layer to design GUIs on top of various calculation kernels
-{[}online: \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003}]
+{[}online: \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003}{]}
\bibitem{IEEE}IEEE Standards Boards, 1993. IEEE standard for software
unit testing. ANSI/IEEE Std 1008-1987. 24 pp.
@@ -1157,7 +1141,7 @@
on CRAN. 11 pp.
\bibitem{Rcore}R Development Core Team, 2008. R: A language and environment
-for statistical computing. {[}online: \url{http://www.R-project.org}].
+for statistical computing. {[}online: \url{http://www.R-project.org}{]}.
\end{thebibliography}
\end{document}
Modified: pkg/svUnit/inst/doc/svUnit.lyx
===================================================================
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/sciviews -r 138
More information about the Sciviews-commits
mailing list