[Sciviews-commits] r12 - / komodo komodo/SciViews-K komodo/SciViews-K/R komodo/SciViews-K/_prj_internal_ komodo/SciViews-K/content komodo/SciViews-K/content/js komodo/SciViews-K/content/js/tools komodo/SciViews-K/locale komodo/SciViews-K/locale/en-GB komodo/SciViews-K/locale/fr-FR komodo/SciViews-K/skin komodo/SciViews-K/skin/images komodo/SciViews-K/templates komodo/SciViews-K/templates/All Languages komodo/SciViews-K/templates/Common komodo/SciViews-K/toolbox komodo/SciViews-K Unit komodo/SciViews-K Unit/_prj_internal_ komodo/SciViews-K Unit/content komodo/SciViews-K Unit/content/js komodo/SciViews-K Unit/locale komodo/SciViews-K Unit/locale/en-GB komodo/SciViews-K Unit/locale/fr-FR komodo/SciViews-K Unit/skin pkg/svGUI pkg/svGUI/R pkg/svGUI/man pkg/svIDE pkg/svIDE/R pkg/svMisc pkg/svSocket pkg/svUnit pkg/svUnit/R pkg/svUnit/inst pkg/svUnit/inst/komodo pkg/svUnit/inst/unitTests pkg/svUnit/inst/unitTests/VirtualClass pkg/svUnit/man
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Mon Jun 23 03:33:09 CEST 2008
Author: phgrosjean
Date: 2008-06-23 03:33:08 +0200 (Mon, 23 Jun 2008)
New Revision: 12
Added:
komodo/
komodo/.DS_Store
komodo/SciViews-K Unit/
komodo/SciViews-K Unit/.DS_Store
komodo/SciViews-K Unit/SciViews-K Unit.kpf
komodo/SciViews-K Unit/_prj_internal_/
komodo/SciViews-K Unit/_prj_internal_/setup.xul
komodo/SciViews-K Unit/chrome.manifest
komodo/SciViews-K Unit/content/
komodo/SciViews-K Unit/content/js/
komodo/SciViews-K Unit/content/js/.DS_Store
komodo/SciViews-K Unit/content/js/sciviewskunit.js
komodo/SciViews-K Unit/content/overlay.xul
komodo/SciViews-K Unit/install.rdf
komodo/SciViews-K Unit/locale/
komodo/SciViews-K Unit/locale/.DS_Store
komodo/SciViews-K Unit/locale/en-GB/
komodo/SciViews-K Unit/locale/en-GB/.DS_Store
komodo/SciViews-K Unit/locale/en-GB/sciviewskunit.dtd
komodo/SciViews-K Unit/locale/fr-FR/
komodo/SciViews-K Unit/locale/fr-FR/.DS_Store
komodo/SciViews-K Unit/locale/fr-FR/sciviewskunit.dtd
komodo/SciViews-K Unit/sciviewskunit-0.6.0-ko.xpi
komodo/SciViews-K Unit/skin/
komodo/SciViews-K Unit/skin/.DS_Store
komodo/SciViews-K Unit/skin/sciviewskunit.css
komodo/SciViews-K/
komodo/SciViews-K/.DS_Store
komodo/SciViews-K/R/
komodo/SciViews-K/R/Rprofile
komodo/SciViews-K/SciViews-K.kpf
komodo/SciViews-K/_prj_internal_/
komodo/SciViews-K/_prj_internal_/setup.xul
komodo/SciViews-K/chrome.manifest
komodo/SciViews-K/content/
komodo/SciViews-K/content/.DS_Store
komodo/SciViews-K/content/js/
komodo/SciViews-K/content/js/prefs.js
komodo/SciViews-K/content/js/r.js
komodo/SciViews-K/content/js/robjects.js
komodo/SciViews-K/content/js/sciviews.js
komodo/SciViews-K/content/js/socket.js
komodo/SciViews-K/content/js/tools/
komodo/SciViews-K/content/js/tools/array.js
komodo/SciViews-K/content/js/tools/e4x2dom.js
komodo/SciViews-K/content/js/tools/strings.js
komodo/SciViews-K/content/overlay.xul
komodo/SciViews-K/install.rdf
komodo/SciViews-K/locale/
komodo/SciViews-K/locale/.DS_Store
komodo/SciViews-K/locale/en-GB/
komodo/SciViews-K/locale/en-GB/.DS_Store
komodo/SciViews-K/locale/en-GB/sciviewsk.dtd
komodo/SciViews-K/locale/fr-FR/
komodo/SciViews-K/locale/fr-FR/.DS_Store
komodo/SciViews-K/locale/fr-FR/sciviewsk.dtd
komodo/SciViews-K/sciviewsk-0.6.0-ko.xpi
komodo/SciViews-K/skin/
komodo/SciViews-K/skin/.DS_Store
komodo/SciViews-K/skin/images/
komodo/SciViews-K/skin/images/.DS_Store
komodo/SciViews-K/skin/images/array.png
komodo/SciViews-K/skin/images/body_bg_sav.gif
komodo/SciViews-K/skin/images/character.png
komodo/SciViews-K/skin/images/data.frame.png
komodo/SciViews-K/skin/images/dist.png
komodo/SciViews-K/skin/images/factor.png
komodo/SciViews-K/skin/images/function.png
komodo/SciViews-K/skin/images/integer.png
komodo/SciViews-K/skin/images/list.png
komodo/SciViews-K/skin/images/logical.png
komodo/SciViews-K/skin/images/matrix.png
komodo/SciViews-K/skin/images/numeric.png
komodo/SciViews-K/skin/images/objects.png
komodo/SciViews-K/skin/images/package.png
komodo/SciViews-K/skin/images/ts.png
komodo/SciViews-K/skin/sciviewsk.css
komodo/SciViews-K/templates/
komodo/SciViews-K/templates/.DS_Store
komodo/SciViews-K/templates/All Languages/
komodo/SciViews-K/templates/All Languages/.DS_Store
komodo/SciViews-K/templates/All Languages/R.R
komodo/SciViews-K/templates/Common/
komodo/SciViews-K/templates/Common/.DS_Store
komodo/SciViews-K/templates/Common/R S3 object.R
komodo/SciViews-K/templates/Common/R.R
komodo/SciViews-K/toolbox/
komodo/SciViews-K/toolbox/SciViews-K 0.6.0.kpz
komodo/TODO
pkg/svUnit/R/Log.R
pkg/svUnit/R/check.R
pkg/svUnit/R/guiTestReport.R
pkg/svUnit/R/koUnit.R
pkg/svUnit/R/svSuite.R
pkg/svUnit/R/svSuiteData.R
pkg/svUnit/R/svTestData.R
pkg/svUnit/R/svUnit-internal.R
pkg/svUnit/inst/komodo/
pkg/svUnit/inst/komodo/sciviewskunit-ko.xpi
pkg/svUnit/inst/unitTests/VirtualClass/runitVirtualClass.R
pkg/svUnit/inst/unitTests/runitsvSuite.R
pkg/svUnit/inst/unitTests/runitsvTest.R
pkg/svUnit/man/Log.Rd
pkg/svUnit/man/check.Rd
pkg/svUnit/man/guiTestReport.Rd
pkg/svUnit/man/koUnit.Rd
pkg/svUnit/man/svSuite.Rd
pkg/svUnit/man/svSuiteData.Rd
pkg/svUnit/man/svTestData.Rd
pkg/svUnit/man/svUnit-package.Rd
Removed:
pkg/svUnit/R/runUnit.R
pkg/svUnit/R/svUnit.R
pkg/svUnit/inst/unitTests/VirtualClass/runit.VirtualClass.R
pkg/svUnit/inst/unitTests/runit.svTest.R
pkg/svUnit/inst/unitTests/runit.svUnit.R
pkg/svUnit/man/runUnit.Rd
pkg/svUnit/man/svUnit.Rd
Modified:
pkg/svGUI/DESCRIPTION
pkg/svGUI/NEWS
pkg/svGUI/R/guiInstall.R
pkg/svGUI/R/guiUninstall.R
pkg/svGUI/R/koCmd.R
pkg/svGUI/TODO
pkg/svGUI/man/guiInstall.Rd
pkg/svGUI/man/koCmd.Rd
pkg/svIDE/DESCRIPTION
pkg/svIDE/R/TinnR.R
pkg/svIDE/TODO
pkg/svMisc/TODO
pkg/svSocket/TODO
pkg/svUnit/DESCRIPTION
pkg/svUnit/NAMESPACE
pkg/svUnit/NEWS
pkg/svUnit/R/svTest.R
pkg/svUnit/TODO
pkg/svUnit/man/svTest.Rd
pkg/svUnit/man/unitTests.Rd
Log:
svUnit finalized, addition of SciViews-K and SciViews-K Unit Komodo extensions and various other corrections
Added: komodo/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/R/Rprofile
===================================================================
--- komodo/SciViews-K/R/Rprofile (rev 0)
+++ komodo/SciViews-K/R/Rprofile 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,160 @@
+### SciViews install begin ###
+# SciViews-R installation and startup for running R with Komodo/SciViews-K
+# Merge this with your .Rprofile file in your home directory to configure
+# R automatically at startup
+
+# Make sure we don't process this twice in case of duplicate items in .Rprofile
+if (!exists(".SciViewsReady", envir = .GlobalEnv)) {
+ .SciViewsReady <- FALSE
+ minVersion <- c(R = "2.7.0", svMisc = "0.9-42", svSocket = "0.9-41", svGUI = "0.9-42")
+
+ # Configure socket client/server
+ options(ko.serve = 8888) # Port used by the R socket server
+ options(ko.host = "localhost") # Machine where Komodo is running (local only for the moment)
+ options(ko.port = 7052) # Port used by the Komodo socket server
+ options(ko.id = "R") # The id used for this R kernel in Komodo
+ options(ko.activate = FALSE) # Do we start/activate Komodo at startup?
+ # Note: set ko.activate to TRUE causes problems currently!
+
+ # Load main R packages
+ res <- require(methods, quietly = TRUE)
+ if (res) res <- require(datasets, quietly = TRUE)
+ if (res) res <- require(utils, quietly = TRUE)
+ if (res) res <- require(grDevices, quietly = TRUE)
+ if (res) res <- require(graphics, quietly = TRUE)
+ if (res) res <- require(stats, quietly = TRUE)
+ if (res) {
+ if (capabilities("tcltk")) {
+ # Make sure tcltk can start: on Mac OS X < 10.5 only,
+ # that is, darwin < 9, we need to check that X11 is installed
+ # (optional!) and started!
+ if (regexpr("^darwin[5-8]", R.Version()$os) > -1) {
+ # First, is the DISPLAY environment variable defined?
+ dis <- Sys.getenv("DISPLAY")
+ if (dis == "") {
+ Sys.setenv(DISPLAY = ":0") # Local X11
+ dis <- Sys.getenv("DISPLAY")
+ }
+ # Second, if DISPLAY points to a default local X11, make sure
+ # X11 is installed and started on this machine
+ if (dis %in% c(":0", ":0.0", "localhost:0", "localhost:0.0",
+ "127.0.0.1:0", "127.0.0.1:0.0")) {
+ # X11 is optional on Mac OS X 10.3 Panther and 10.4 Tiger!
+ # We locate 'open-x11' and run it,... not X11 directly!
+ if (length(system('find /usr/bin/ -name "open-x11"',
+ intern = TRUE)) == 0){
+ cat("'open-x11' not found. Make sure you installed X11\n")
+ cat("(see http://developer.apple.com/opensource/tools/runningx11.html\n")
+ res <- FALSE
+ } else { # Make sure X11 is started (trick: we try opening a non X11 prog)
+ system("open-x11 more", intern = TRUE)
+ }
+ }
+ rm(dis)
+ }
+ if (res) {
+ res <- suppressPackageStartupMessages(require(tcltk, quietly = TRUE))
+ if (!res) {
+ cat("Error starting tcltk. Make sure Tcl/Tk is installed and can\n")
+ cat("be run on your machine. Then, with packages svMisc, svSocket\n")
+ cat("and svGUI installed, restart R or type require(svGUI)\n")
+ }
+ }
+ } else cat("Tcl/Tk is required by SciViews, but it is not supported by this R installation\n")
+ } else cat("Problem loading standard R packages, check R installation\n")
+
+ if (res) {
+ # Check for R version
+ res <- compareVersion(paste(R.Version()$major, R.Version()$minor,
+ sep = "."), minVersion["R"])
+ if (res < 0) {
+ cat("R is too old for this version of SciViews, please, upgrade it\n")
+ } else {
+ # Load packages svMisc, svSocket & svGUI (possibly after installing
+ # or upgrading them). User is supposed to have agreed
+
+ ## svMisc
+ desc <- system.file("DESCRIPTION", package = "svMisc")
+ if (desc == "") {
+ cat("Trying to install missing package 'svMisc'\n")
+ install.packages("svMisc", repos = "http://R-Forge.R-project.org")
+ res <- require(svMisc, quietly = TRUE)
+ } else { # Check version
+ if ((compareVersion(packageDescription("svMisc", fields = "Version"),
+ minVersion["svMisc"]) < 0)) {
+ cat("Trying to update package 'svMisc'\n")
+ install.packages("svMisc", repos = "http://R-Forge.R-project.org")
+ }
+ res <- require(svMisc, quietly = TRUE)
+ }
+
+ ## svSocket
+ desc <- system.file("DESCRIPTION", package = "svSocket")
+ if (desc == "") {
+ cat("Trying to install missing package 'svSocket'\n")
+ install.packages("svSocket", repos = "http://R-Forge.R-project.org")
+ res[2] <- require(svSocket, quietly = TRUE)
+ } else { # Check version
+ if ((compareVersion(packageDescription("svSocket", fields = "Version"),
+ minVersion["svSocket"]) < 0)) {
+ cat("Trying to update package 'svSocket'\n")
+ install.packages("svSocket", repos = "http://R-Forge.R-project.org")
+ }
+ res[2] <- require(svSocket, quietly = TRUE)
+ }
+
+ ## svGUI
+ desc <- system.file("DESCRIPTION", package = "svGUI")
+ if (desc == "") {
+ cat("Trying to install missing package 'svGUI'\n")
+ install.packages("svGUI", repos = "http://R-Forge.R-project.org")
+ } else { # Check version
+ if ((compareVersion(packageDescription("svGUI", fields = "Version"),
+ minVersion["svGUI"]) < 0)) {
+ cat("Trying to update package 'svGUI'\n")
+ install.packages("svGUI", repos = "http://R-Forge.R-project.org")
+ }
+ }
+ rm(desc)
+
+ # Try starting the R socket server
+ if (inherits(try(startSocketServer(port = getOption("ko.serve")),
+ silent = TRUE), "try-error")) {
+ cat("Impossible to start the SciViews R socket server\n(socket",
+ getOption("ko.serve"), "already in use?)\n")
+ cat("Solve the problem, then type: require(svGUI)\n")
+ } else {
+ # Finally, load svGUI
+ res[3] <- require(svGUI, quietly = TRUE)
+
+ if (all(res)) {
+ cat("R is SciViews ready!\n")
+ .SciViewsReady <- TRUE
+ if (is.null(getOption("ko.id"))) options(ko.id = "R") # Default
+ # Do we (re)activate Komodo now?
+ koact <- getOption("ko.activate")
+ if (is.null(koact)) koact <- FALSE
+ if (koact[1]) {
+ if ((.Platform$pkgType == "mac.binary")) {
+ Res <- system("osascript -e 'tell application \"Komodo\" to activate'",
+ intern = TRUE)
+ rm(Res)
+ } ### TODO: the same under Windows and Linux
+ # Indicate to Komodo that R is ready
+ koCmd('ko.statusBar.AddMessage("<<<data>>>", "R", 10000, true);',
+ data = paste("'", getOption("ko.id"), "' (R ", R.Version()$major, ".",
+ R.Version()$minor, ") connected", sep = ""))
+ }
+ rm(koact)
+ } else {
+ cat("R is not SciViews ready, install latest svMisc, svSocket & svGUI packages\n")
+ }
+ }
+ }
+ }
+
+ # Clean up .GlobalEnv
+ rm(minVersion, res)
+}
+
+### SciViews install end ###
\ No newline at end of file
Added: komodo/SciViews-K/SciViews-K.kpf
===================================================================
--- komodo/SciViews-K/SciViews-K.kpf (rev 0)
+++ komodo/SciViews-K/SciViews-K.kpf 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Komodo Project File - DO NOT EDIT -->
+<project id="6200c0ed-45ec-4f46-a159-284803d65c04" kpf_version="4" name="SciViews-K.kpf">
+<folder id="f5feb14c-33f6-a44d-ad41-ab38bf630926" idref="6200c0ed-45ec-4f46-a159-284803d65c04" name="Project">
+</folder>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/wrench.png" id="08af6b57-9cc0-4848-9775-1bbecb5ab2c0" idref="f5feb14c-33f6-a44d-ad41-ab38bf630926" keyboard_shortcut="" language="JavaScript" name="Configure" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+try {
+
+var libPart = ko.projects.findPart('macro', 'extension_lib', 'container');
+eval(libPart.value);
+
+var koExt = new extensionLib();
+
+var project = ko.macros.current.project;
+
+var setupWin = project.getChildByAttributeValue('name','setup.xul', 1);
+var rdf = project.getChildByAttributeValue('name','install.rdf', 1);
+var data = {};
+
+var prefset = project.prefset;
+
+if(prefset.hasPrefHere('configured')) {
+ var rdf_xml = koExt.readFile(rdf.getFile().URI);
+ data = {
+ 'valid': false,
+ 'configured': true,
+ 'vars': koExt.getRdfVars(rdf_xml)
+ };
+ data.vars['ext_name'] = koExt.getNiceName(data.vars.name);
+} else { // init data
+ data = {
+ 'valid': false,
+ 'configured': false,
+ 'vars': {
+ 'id': '',
+ 'name': 'My Extension',
+ 'creator': 'Me',
+ 'version': '0.1',
+ 'description': '',
+ 'homepageURL': '',
+ 'ext_name': ''
+ }
+ };
+}
+
+window.openDialog(
+ setupWin.getFile().URI,
+ "_blank",
+ "centerscreen,chrome,resizable,scrollbars,dialog=no,close,modal=yes",
+ data
+);
+
+if(data.valid) {
+ if(koExt.updateProject(data.vars)) {
+ prefset.setBooleanPref('configured', true);
+ var part = project.getChildByAttributeValue('name', 'oncreate',1);
+ if(part) { part.name = 'Configure'; }
+ var msg = 'Extension Project '+data.vars.name+' configured!';
+ ko.statusBar.AddMessage(msg, 'project', 3000, true);
+ ko.projects.manager.saveProject(project);
+ } else {
+ alert('Error encountered: '+koExt.error+"\nConfiguration aborted.");
+ }
+}
+
+} catch(e) {
+ alert(e);
+}
+</macro>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/brick.png" id="1ea22b28-e1b5-a44d-a3e2-40e33f456acf" idref="f5feb14c-33f6-a44d-ad41-ab38bf630926" keyboard_shortcut="" language="JavaScript" name="extension_lib" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+try {
+
+var extensionLib = function() {
+ this.os = Components.classes['@activestate.com/koOs;1'].
+ getService(Components.interfaces.koIOs);
+ this.error = false;
+}
+
+extensionLib.prototype.getPath = function(relative) {
+ try {
+ var prj_path = ko.interpolate.interpolateStrings('%p');
+ path = this.os.path.join(prj_path, relative);
+ return path;
+ } catch(e) {
+ alert(e+"\narg name: "+name);
+ }
+}
+
+extensionLib.prototype.readFile = function(filename) {
+ // read the template file
+ try {
+ var fileEx = Components.classes["@activestate.com/koFileEx;1"]
+ .createInstance(Components.interfaces.koIFileEx);
+ fileEx.URI = filename;
+ fileEx.open('rb');
+ var content = fileEx.readfile();
+ fileEx.close();
+ return content;
+ } catch(e) {
+ alert(e+"\narg filename: "+filename);
+ }
+}
+
+extensionLib.prototype.writeFile = function(filename, content) {
+ try {
+ var fileEx = Components.classes["@activestate.com/koFileEx;1"]
+ .createInstance(Components.interfaces.koIFileEx);
+ fileEx.URI = filename;
+ fileEx.open('wb+');
+ fileEx.puts(content);
+ fileEx.close();
+ } catch(e) {
+ alert(e+"\narg filename: "+filename);
+ }
+}
+
+extensionLib.prototype.getRdfVars = function(txt) {
+ try {
+ var Rx = /\<em\:([\w]+)[\ \S]*\>([\S\ ]+?)\<\//g;
+ var ext_vars = {};
+ while(results = Rx.exec(txt)) {
+ var idRx = /type|min|max|\{/;
+ if(!idRx.test(results[0])) { // filter out stuff we don't want
+ ext_vars[results[1]] = results[2];
+ }
+ }
+ return ext_vars;
+ } catch(e) {
+ alert(e+"\narg rdf_path: "+rdf_path);
+ }
+}
+
+extensionLib.prototype.getManifestVars = function(txt) {
+ try {
+ var rx1 = /content ([\S]+?) jar\:([\S]+?)\.jar/g;
+ var res1 = rx1.exec(txt);
+ var rx2 = /chrome:\/\/([\S]+?)\/content\/overlay\.xul/g;
+ var res2 = rx2.exec(txt);
+ return new Array(res1[1], res1[2], res2[1]);
+ } catch(e) {
+ alert(e+"\narg path: "+path);
+ }
+}
+
+extensionLib.prototype.getOverlayVars = function(txt) {
+ try {
+ var rx1 = /<overlay id="([\S]+?)"/g;
+ var res1 = rx1.exec(txt);
+ var rx2 = /<menuitem id="([\S]+?)"[\s]+?label="([\S\ ]+?)"/g;
+ var res2 = rx2.exec(txt);
+ return [res1[1], res2[1], res2[2]];
+ } catch(e) {
+ alert(e+"\narg path: "+path);
+ }
+}
+
+extensionLib.prototype.updateProject = function(vars) {
+ try {
+ var overlayPath = this.getPath('content/overlay.xul');
+ if(this.os.path.exists(overlayPath)) {
+ var ovl_str = this.readFile(overlayPath);
+ var ov_vars = this.getOverlayVars(ovl_str);
+ var ovl_new = [vars.ext_name+'Overlay', 'menu_'+vars.ext_name, vars.name];
+ this.writeFile(overlayPath, this.replaceAll(ov_vars, ovl_new, ovl_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ var manifestPath = this.getPath('chrome.manifest');
+ if(this.os.path.exists(manifestPath)) {
+ var man_str = this.readFile(manifestPath);
+ var man_vars = this.getManifestVars(man_str);
+ var man_new = [vars.ext_name, vars.ext_name, vars.ext_name];
+ this.writeFile(manifestPath, this.replaceAll(man_vars, man_new, man_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ var rdf_path = this.getPath('install.rdf');
+ if(this.os.path.exists(rdf_path)) {
+ var rdf_str = this.readFile(rdf_path);
+ var rdf_vars = this.getRdfVars(rdf_str);
+ this.writeFile(rdf_path, this.replaceAll(rdf_vars, vars, rdf_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ } catch(e) {
+ this.error = e;
+ return false;
+ }
+ return true;
+}
+
+extensionLib.prototype.replaceAll = function(orig_vars, new_vars, str) {
+ try {
+ var out = str;
+ for(v in orig_vars) {
+ out = out.replace(orig_vars[v], new_vars[v]);
+ }
+ return out;
+ } catch(e) {
+ alert(e);
+ }
+}
+
+extensionLib.prototype.getNiceName = function(name) {
+ return this.trim(name).replace(/[\W]/g,'').toLowerCase();
+}
+
+extensionLib.prototype.trim = function(str) {
+ return str.replace(/^\s*/, '').replace(/\s*$/, '');
+}
+
+extensionLib.prototype.clone = function(obj) {
+ var newobj = {}; for(i in obj) {
+ newobj[i] = obj[i];
+ } return newobj;
+}
+
+extensionLib.prototype._dump = function(obj) {
+ var str = ''; for(i in obj) {
+ str += i+': '+obj[i]+'\n';
+ } return(str);
+}
+
+extensionLib.prototype._keys = function(obj) {
+ var out = new Array(); for(i in obj) {
+ out.push(i);
+ } return out;
+}
+
+} catch(e) {
+ allert(e);
+}
+</macro>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/lightning_go.png" id="41904da6-0dd6-d747-8a6c-a2663e10578b" idref="f5feb14c-33f6-a44d-ad41-ab38bf630926" keyboard_shortcut="" language="JavaScript" name="Build" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+/**
+ * Script to build an xpi, running koext build in the current project root.
+ */
+
+var project = ko.macros.current.project;
+
+var os = Components.classes['@activestate.com/koOs;1'].
+ getService(Components.interfaces.koIOs);
+
+var koSysUtils = Components.classes["@activestate.com/koSysUtils;1"].
+ getService(Components.interfaces.koISysUtils);
+
+var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
+ getService(Components.interfaces.nsIXULRuntime);
+
+var koDirs = Components.classes['@activestate.com/koDirs;1'].
+ getService(Components.interfaces.koIDirs);
+
+var pythonExe = koDirs.pythonExe;
+var projectDir = ko.interpolate.interpolateStrings('%p');
+var scriptName = 'koext';
+
+if (appInfo.OS == 'WINNT') {
+ scriptName += ".py";
+}
+
+var arr = [koDirs.sdkDir, 'bin', scriptName]
+var app = os.path.joinlist(arr.length, arr);
+var cmd = '"'+pythonExe+'" "'+app+'" build -d "'+projectDir+'"';
+
+if (appInfo.OS == 'WINNT') {
+ cmd = '"' + cmd + '"';
+}
+var cwd = koDirs.mozBinDir;
+cmd += " {'cwd': u'"+cwd+"'}";
+
+ko.run.runEncodedCommand(window, cmd, function() {
+ ko.statusBar.AddMessage('Build complete', 'projects', 5000, true);
+ ko.projects.manager.saveProject(project);
+});
+</macro>
+<file id="ce09e80e-4f8e-784c-81c1-6564f46e2cf8" idref="f5feb14c-33f6-a44d-ad41-ab38bf630926" name="setup.xul" url="_prj_internal_/setup.xul">
+</file>
+<preference-set idref="6200c0ed-45ec-4f46-a159-284803d65c04">
+ <boolean id="configured">1</boolean>
+ <string id="import_exclude_matches">*.*~;*.bak;*.tmp;CVS;.#*;*.pyo;*.pyc;.svn;*%*;tmp*.html;.DS_Store;_prj_internal_</string>
+ <string id="import_include_matches"></string>
+ <boolean id="import_live">1</boolean>
+ <boolean id="import_recursive">1</boolean>
+ <string id="import_type">useFolders</string>
+</preference-set>
+</project>
Added: komodo/SciViews-K/_prj_internal_/setup.xul
===================================================================
--- komodo/SciViews-K/_prj_internal_/setup.xul (rev 0)
+++ komodo/SciViews-K/_prj_internal_/setup.xul 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/" type="text/css"?>
+
+<dialog
+ id="test"
+ title="Komodo Extension configuration"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="setup()"
+ width="400px"
+ height="480px"
+ buttons="accept,cancel"
+ buttonlabelcancel="Cancel"
+ buttonlabelaccept="Save"
+ ondialogaccept="return teardown();"
+ ondialogcancel="return cancel();"
+ defaultButton="accept"
+ buttonalign="horizontal"
+ buttonorient="horizontal"
+ orient="vertical"
+ >
+
+<script type="application/x-javascript">
+<![CDATA[
+
+var data = {};
+var ext_name = '';
+
+function get_id(strId) { return document.getElementById(strId); }
+function get_val(strId) { return get_id(strId).value; }
+function set_val(strId, val) { get_id(strId).value = val; }
+function get_nice_name(name) { return trim(name).replace(/[\W]/g,'').toLowerCase(); }
+// Added by PhG to allow uppercases in web site name
+function get_nice_name2(name) { return trim(name).replace(/[\W]/g,''); }
+
+function trim(str) { return str.replace(/^\s*/, '').replace(/\s*$/, ''); }
+function _dump(obj) {
+ try{
+ var str = ''; for(i in obj) {
+ str += i+': '+obj[i]+'\n';
+ }
+ } catch(e) {alert(e);}
+ return str;
+}
+
+function setup() {
+ try {
+ if(typeof(window.arguments) == 'undefined') {
+ alert('Error: No Window arguments?');
+ } else {
+ data = window.arguments[0];
+ var vars = data.vars;
+ for(i in vars) {
+ if(i == 'id' || i == 'ext_name') {
+ //pass
+ } else {
+ set_val(i, vars[i]);
+ }
+ }
+ if(vars['id']) {
+ var arr = vars.id.split('@');
+ if(arr.length < 2) {
+ alert('Extension Id is not in the correct format?');
+ return;
+ }
+ set_val('author-domain', arr[1]);
+ }
+ update_id();
+ if(!data.vars['homepageUrl']) {
+ update_url();
+ }
+ }
+ } catch(e) { alert(e); }
+}
+
+function update_url() {
+ var domain = get_id('author-domain').value;
+ //var ext_name = get_nice_name(get_val('name'));
+ var ext_name = get_nice_name2(get_val('name'));
+ set_val('homepageURL', 'http://'+domain+'/'+ext_name);
+}
+
+function update_id() {
+ try {
+ var name = get_val('name');
+ data.vars.ext_name = get_nice_name(name);
+
+ var domain = get_id('author-domain').value;
+ var newId = data.vars.ext_name+'@'+domain;
+
+ get_id('id').value = newId;
+ } catch(e) {
+ alert(e);
+ }
+}
+
+function teardown() {
+ try {
+ for(i in data.vars) {
+ if(i != 'ext_name') {
+ data.vars[i] = get_val(i);
+ }
+ }
+ data.vars.ext_name = get_nice_name(data.vars.name);
+ data.valid = true;
+ data.configured = true;
+ window.close();
+ } catch(e) {
+ alert(e);
+ }
+}
+
+function cancel() {
+ return confirm('Cancel Configuration?');
+}
+
+function keys(obj) {
+ var out = new Array(); for(i in obj) {
+ out.push(i);
+ } return out;
+}
+
+]]>
+</script>
+
+
+<commandset id="koext_commands">
+ <command id="update_id" oncommand="update_id();"/>
+</commandset>
+
+<vbox flex="1">
+ <caption label="Extension Options"/>
+ <grid flex="1">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="Name:"/>
+ <textbox id="name" type="timed" timeout="1000" command="update_id"/>
+ </row>
+ <row align="center">
+ <label value="Version:"/>
+ <textbox id="version"/>
+ </row>
+ <row align="top">
+ <label value="Description:"/>
+ <textbox id="description" multiline="true" value=""/>
+ </row>
+ <row align="center">
+ <label value="Author:"/>
+ <textbox id="creator" value=""/>
+ </row>
+ <row align="center">
+ <label value="Domain:"/>
+ <textbox id="author-domain" value="yourdomain.org" type="timed" timeout="1000" command="update_id"/>
+ </row>
+ <row align="center">
+ <label value="Home Page:"/>
+ <textbox id="homepageURL" value=""/>
+ </row>
+ <row align="center">
+ <label value="Extension Id:"/>
+ <label style="font-weight: bolder;" id="id"/>
+ </row>
+ </rows>
+ </grid>
+</vbox>
+
+</dialog>
Added: komodo/SciViews-K/chrome.manifest
===================================================================
--- komodo/SciViews-K/chrome.manifest (rev 0)
+++ komodo/SciViews-K/chrome.manifest 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,7 @@
+content sciviewsk jar:sciviewsk.jar!/content/ xpcnativewrappers=yes
+overlay chrome://komodo/content/komodo.xul chrome://sciviewsk/content/overlay.xul
+
+locale sciviewsk en-GB jar:sciviewsk.jar!/locale/en-GB/
+locale sciviewsk fr-FR jar:sciviewsk.jar!/locale/fr-FR/
+
+skin sciviewsk classic/1.0 jar:sciviewsk.jar!/skin/
\ No newline at end of file
Added: komodo/SciViews-K/content/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/content/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/content/js/prefs.js
===================================================================
--- komodo/SciViews-K/content/js/prefs.js (rev 0)
+++ komodo/SciViews-K/content/js/prefs.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,15 @@
+// SciViews-K functions
+// Define default preferences values for SciViews-K
+// Copyright (c) 2008, Ph. Grosjean (phgrosjean at sciviews.org)
+
+// Define default socket ports for the client and server, and other parameters
+sv.prefs.setString("sciviews.server.socket", "7052", false);
+sv.prefs.setString("sciviews.client.socket", "8888", false);
+sv.prefs.setString("sciviews.client.id", "SciViewsK", false);
+
+// Where do we want to display R help? In internal browser or not?
+sv.prefs.setString("sciviews.r.help", "internal", false);
+
+// This is the base path for the R Wiki context help feature of sv.helpContext()
+sv.prefs.setString("sciviews.rwiki.help.base",
+ "http:/wiki.r-project.org/rwiki/doku.php?id=", false);
Added: komodo/SciViews-K/content/js/r.js
===================================================================
--- komodo/SciViews-K/content/js/r.js (rev 0)
+++ komodo/SciViews-K/content/js/r.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,719 @@
+// SciViews-K R functions
+// Define functions to command R from Komodo Edit
+// Copyright (c) 2008, Ph. Grosjean (phgrosjean at sciviews.org)
+
+////////////////////////////////////////////////////////////////////////////////
+// To cope with versions incompatibilities, we define this:
+// alert(sv.r.RMinVersion); // Display minimum R version required
+//
+// These functions are available if you trigger this macro on startup
+// Then, you can use them in other macros, menus, toolbars, ...
+// sv.r.eval(cmd); // Evaluate 'cmd' in R
+// sv.r.evalHidden(cmd, earlyExit); // Evaluate 'cmd' in R in a hidden way
+// sv.r.evalCallback(cmd, procfun); // Evaluate 'cmd' in R and call 'procfun'
+// sv.r.escape(); // Escape R calculation or multiline mode
+// sv.r.setwd(); // Set the working dir (choose or set to current buffer)
+// sv.r.run(); // Run current selection or line in R and goto next line
+// sv.r.runEnter(); // Run current line to pos in R and add a line feed
+// sv.r.source(what); // Source various part of current buffer to R
+// sv.r.send(what); // Send various part of current buffer to R
+// sv.r.display(topic, what); // Display 'topic' according to 'what' type
+// sv.r.helpStart(); // Start R help in the default browser
+// sv.r.help(topic); // Get help in R for 'topic', 'topic' is facultative
+// sv.r.example(topic); // Run example in R for 'topic' (facultative)
+// sv.r.search(topic); // Search R help for 'topic'
+// sv.r.search_select(topics); // Callback function: display a list of
+ // choices to select help page from
+// sv.r.siteSearch(topic); // Search R web sites for 'topic'
+// sv.r.dataList(loaded); // List R datasets in "loaded" or "all" packages
+// sv.r.data(); // Select one dataset to load
+// sv.r.data_select(data); // Callback function for sv.r.data()
+//
+// sv.r.pck namespace: /////////////////////////////////////////////////////////
+// sv.r.pkg.repositories(); // Select repositories for installing R packages
+// sv.r.pkg.CRANmirror(); // Select preferred CRAN mirror
+// sv.r.pkg.available(); // List available R packages on selected repositories
+// sv.r.pkg.installed(); // List installed R packages
+// sv.r.pkg.install(); // Install one R package from the repositories
+// sv.r.pkg.install_select(pkgs); // Callback function for sv.r.pkg.install()
+// sv.r.pkg.installDef(); // Call the default package installation routine of R
+// sv.r.pkg.installLocal(); // Install one or more R packages from local files
+// sv.r.pkg.installSV(); // Install the Sciviews bundle from CRAN
+// sv.r.pkg.installSVrforge(); // Install development versions of SciViews
+ // from R-Forge
+// sv.r.pkg.new(); // List new R packages available on CRAN
+// sv.r.pkg.old(); // List older installed R packages than distributed versions
+// sv.r.pkg.update(); // Update installed R packages from the repositories
+// sv.r.pkg.status(); // Show status of installed R packages
+// sv.r.pkg.loaded(); // Show which R packages are loaded
+// sv.r.pkg.load(); // Load one R package
+// sv.r.pkg.load_select(pkgs); // Callback function for sv.r.pkg.load()
+// sv.r.pkg.unload(); // Unload one r package
+// sv.r.pkg.unload_select(pkgs); // Callback function for sv.r.pkg.unload()
+// sv.r.pkg.remove(); // Remove one R package
+// sv.r.pkg.remove_select(pkgs); // Callback function for sv.r.pkg.remove()
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.r' namespace
+if (typeof(sv.r) == 'undefined') sv.r = { RMinVersion: "2.7.0" };
+
+// Evaluate code in R
+sv.r.eval = function(cmd) {
+ // Store the current R command
+ if (sv.socket.prompt == ":> ") {
+ // This is a new command
+ sv.socket.cmd = cmd;
+ } else {
+ // We continue previous multiline command
+ sv.socket.cmd += '\n' + cmd;
+ }
+ if (sv.socket.cmdout) {
+ if (sv.socket.prompt == ":> ") {
+ sv.cmdout.clear();
+ sv.cmdout.append(":> " + cmd);
+ } else {
+ sv.cmdout.append(cmd);
+ }
+ }
+ var res = sv.socket.rCommand('<<<e>>>' + cmd, sv.socket.cmdout);
+ return(res);
+}
+
+// Evaluate code in R in a hidden way
+sv.r.evalHidden = function(cmd, earlyExit) {
+ var preCode = "<<<h>>>";
+ if (earlyExit) preCode = "<<<H>>>";
+ // Evaluate a command in hidden mode (contextual help, calltip, etc.)
+ var res = sv.socket.rCommand(preCode + cmd, false);
+ return(res);
+}
+// Tests:
+//sv.r.evalHidden("Sys.sleep(5); cat('done\n')");
+//sv.r.evalHidden("Sys.sleep(5); cat('done\n')", earlyExit = true);
+//sv.r.evalHidden("Sys.sleep(3); cat('done\n');" +
+// " koCmd('alert(\"koCmd is back\");')", earlyExit = true);
+
+// Evaluate R expression and call procfun in Komodo with the result as argument
+sv.r.evalCallback = function(cmd, procfun) {
+ // Evaluate a command in hidden mode (contextual help, calltip, etc.)
+ // and call 'procfun' at the end of the evaluation
+ var res = sv.socket.rCommand("<<<h>>>" + cmd, false, null, procfun);
+ return(res);
+}
+
+// Escape R calculation
+sv.r.escape = function() {
+ // Send an <<<esc>>> sequence that breaks multiline mode
+ sv.socket.cmd = "";
+ sv.socket.prompt == ":> ";
+ if (sv.socket.cmdout) { sv.cmdout.clear(); }
+ var listener = { finished: function(data) {} }
+ var res = sv.socket.rCommand('<<<esc>>>', false);
+ return(res);
+}
+
+// Set the current working directory (to current buffer dir, or ask for it)
+sv.r.setwd = function(ask) {
+ var res = false;
+ if (ask == null) {
+ // Set R working directory to current buffer path
+ var kv = ko.views.manager.currentView;
+ if (!kv) return; // No current view, do nothing!
+ kv.setFocus();
+ if(kv.document.isUntitled) {
+ alert("File is not saved yet. Unable to get its directory!");
+ } else {
+ // Make sure path name is in Unix convention under Windows
+ res = sv.r.eval('.odir <- setwd("' +
+ kv.document.file.dirName.replace(/\\/g, "//") + '")');
+ }
+ } else if (ask == "previous") {
+ // Produce an error in R if .odir is not defined, but it is fine!
+ res = sv.r.eval('if (exists(".odir")) .odir <- setwd(.odir); getwd()');
+ } else {
+ // TODO: a graphical setwd()
+ alert("Graphical selection of R working dir... not implemented yet!");
+ }
+ return(res);
+}
+
+// Run current selection or line buffer in R
+sv.r.run = function() {
+ try {
+ var kv = ko.views.manager.currentView;
+ if (!kv) return; // No current view, do nothing!
+ kv.setFocus();
+ var ke = kv.scimoz;
+ var currentLine = ke.lineFromPosition(ke.currentPos);
+ if (ke.selText == "") {
+ ke.home();
+ ke.lineEndExtend();
+ // while ke.selText contains no code, look for next line
+ while (ke.selText.replace(/^\s*$/, "") == "") {
+ //Are we at the last line?
+ currentLine = ke.lineFromPosition(ke.currentPos);
+ if( currentLine == ( ke.lineCount - 1 ) ) { return; }
+ // Select next line
+ ke.lineDown();
+ ke.home();
+ ke.lineEndExtend();
+ }
+ }
+ var res = sv.r.eval(ke.selText);
+ ke.lineDown();
+ ke.homeDisplay();
+ } catch(e) { return(e); }
+ return(res);
+}
+
+// Run current line up to position and add line feed
+sv.r.runEnter = function() {
+ try {
+ var res = false;
+ var kv = ko.views.manager.currentView;
+ if (!kv) return; // No current view, do nothing!
+ kv.setFocus();
+ var ke = kv.scimoz;
+ if (ke.selText == "") { // Only proceed if selection is empty
+ var pos = ke.currentPos;
+ ke.homeExtend();
+ if (ke.selText != "") res = sv.r.eval(ke.selText);
+ // Add a line feed at pos
+ ke.gotoPos(pos);
+ ke.newLine();
+ }
+ } catch(e) { return(e); }
+ return(res);
+}
+
+// Source the whole content of the current buffer
+sv.r.source = function(what) {
+ var res = false;
+ try {
+ var kv = ko.views.manager.currentView;
+ if (!kv) return; // No current view, do nothing!
+ kv.setFocus();
+ var ke = kv.scimoz;
+ if (what == null) what = "all"; // Default value
+ // Special case: if "all", then, try sourcing the original file directly
+ // (if saved, or ask to save it)
+ if (what == "all") {
+ // Is this file saved?
+ if (kv.document.isUntitled) {
+ var answer = ko.dialogs.okCancel("File has not been saved" +
+ " yet. Would you like to save it now?", "OK");
+ if (answer == "OK") {
+ ko.commands.doCommand('cmd_save');
+ // Check if it saved now
+ if (!kv.document.isDirty) {
+ // Source it (make sure its name is in Unix convention
+ // under Windows)
+ res = sv.r.eval('source("' +
+ kv.document.file.path.replace(/\\/g, "//") + '")');
+ ko.statusBar.AddMessage("Document sourced in R...",
+ "R", 5000, true);
+ }
+ }
+ } else if (kv.document.isDirty) { // Are last changes saved?
+ var answer = ko.dialogs.okCancel("Changes have not been saved" +
+ " yet. Would you like to save now?", "OK");
+ if (answer == "OK") {
+ ko.commands.doCommand('cmd_save');
+ // Check if it saved now
+ if (!kv.document.isDirty) {
+ // Source it (make sure its name is in Unix convention
+ // under Windows)
+ res = sv.r.eval('source("' +
+ kv.document.file.path.replace(/\\/g, "//") + '")');
+ ko.statusBar.AddMessage("Document sourced in R...",
+ "R", 5000, true);
+ }
+ }
+ } else {
+ // The document is saved => proceed with sourcing it
+ // (make sure its name is in Unix convention under Windows)
+ res = sv.r.eval('source("' +
+ kv.document.file.path.replace(/\\/g, "//") + '")');
+ ko.statusBar.AddMessage("Document sourced in R...",
+ "R", 5000, true);
+ }
+ }
+ // We will make a copy of the selected code in a temp file
+ // and source it in R
+ var code = sv.getPart(what, what != "all", true); // Copy to clipboard
+ res = sv.r.eval('clipsource()');
+ // If not selected all, para or block, then, change position
+ if (what != "all" & what != "para" & what != "block") {
+ var kv = ko.views.manager.currentView;
+ kv.setFocus();
+ var ke = kv.scimoz;
+ ke.lineDown();
+ ke.homeDisplay();
+ }
+ } catch(e) { return(e); }
+ return(res);
+}
+
+// Send whole or a part of the current buffer to R, place cursor at next line
+sv.r.send = function(what) {
+ try {
+ if (what == null) what = "all"; // Default value
+ var code = sv.getPart(what, what != "all"); // Change sel if not 'all'
+ var res = sv.r.eval(code);
+ // If not selected all, para or block, then, change position
+ if (what != "all" & what != "para" & what != "block") {
+ var kv = ko.views.manager.currentView;
+ kv.setFocus();
+ var ke = kv.scimoz;
+ ke.lineDown();
+ ke.homeDisplay();
+ }
+ } catch(e) { return(e); }
+ return(res);
+}
+
+// Display R objects in different ways
+// TODO: allow custom methods + arguments + forcevisible + affect to var
+sv.r.display = function(topic, what) {
+ var res = false;
+ if (typeof(topic) == "undefined" | topic == "") topic = sv.getText();
+ if (topic == "") {
+ alert("Nothing is selected!");
+ } else {
+ // Display data in different ways, depending on what
+ switch(what) {
+ case "names":
+ res = sv.r.eval("names(" + topic + ")");
+ break;
+ case "structure":
+ res = sv.r.eval("str(" + topic + ")");
+ break;
+ case "summary":
+ res = sv.r.eval("summary(" + topic + ")");
+ break;
+ case "plot":
+ res = sv.r.eval("plot(" + topic + ")");
+ break;
+ case "content":
+ case "print":
+ case "show":
+ default:
+ res = sv.r.eval(topic);
+ }
+ }
+ return(res);
+}
+
+// Start R help in the default browser
+sv.r.helpStart = function() {
+ var res = sv.r.eval("help.start()");
+ ko.statusBar.AddMessage("R help started... should display in browser soon",
+ "R", 5000, true);
+ return(res);
+}
+
+// Get help in R (HTML format)
+sv.r.help = function(topic) {
+ var res = false;
+ if (typeof(topic) == "undefined" | topic == "") topic = sv.getText();
+ if (topic == "") {
+ alert("Nothing is selected!");
+ } else {
+ res = sv.r.evalCallback('cat(unclass(help("' + topic +
+ '", htmlhelp = TRUE)))', sv.browseURI);
+ ko.statusBar.AddMessage("R help asked for '" + topic + "'",
+ "R", 5000, true);
+ }
+ return(res);
+}
+
+// Run the example for selected item
+sv.r.example = function(topic) {
+ var res = false;
+ if (typeof(topic) == "undefined" | topic == "") topic = sv.getText();
+ if (topic == "") {
+ alert("Nothing is selected!");
+ } else {
+ res = sv.r.eval("example(" + topic + ")");
+ ko.statusBar.AddMessage("R example run for '" + topic + "'",
+ "R", 5000, true);
+ }
+ return(res);
+}
+
+// Search R help for topic
+sv.r.search = function(topic, internal) {
+ var res = false;
+ if (typeof(topic) == "undefined" | topic == "") topic = sv.getText();
+ // Ask for the search string
+ topic = ko.dialogs.prompt("Search R objects using a regular expression" +
+ " (e.g., '^log' for objects starting with 'log')",
+ "Pattern", topic, "Search R help", "okRsearchPattern");
+ if (topic != null & topic != "") {
+ // Get list of matching items and evaluate it with sv.r.search_select()
+ res = sv.r.evalCallback('cat(apropos("' + topic + '"), sep = "\n")',
+ sv.r.search_select);
+ ko.statusBar.AddMessage("Searching R help for '" + topic + "'",
+ "R", 5000, true);
+ }
+ return(res);
+}
+
+// The callback for sv.r.search
+sv.r.search_select = function(topics) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(topics) == "") {
+ alert("No item found in R help!");
+ } else { // Something is returned
+ var items = topics.split("\n");
+ if (items.length == 1) {
+ // Only one item, show help for it
+ res = sv.r.help(sv.tools.strings.removeLastCRLF(topics));
+ } else {
+ // Select the item you want in the list
+ var topic = ko.dialogs.selectFromList("R help",
+ "Select a topic:", items, "one");
+ if (topic != null)
+ res = sv.r.help(sv.tools.strings.removeLastCRLF(topic.join("")));
+ }
+ }
+ return(res);
+}
+
+
+// Search R web sites for topic
+sv.r.siteSearch = function(topic) {
+ var res = false;
+ if (typeof(topic) == "undefined" | topic == "") topic = sv.getText();
+ if (topic == "") {
+ alert("Nothing is selected!");
+ } else {
+ res = sv.r.evalHidden('RSiteSearch("' + topic + '")', earlyExit = true);
+ ko.statusBar.AddMessage("R site search asked for '" + topic + "'",
+ "R", 5000, true);
+ }
+ return(res);
+}
+
+// List available datasets ("loaded" or not defined = loaded packages, or "all")
+sv.r.dataList = function(which) {
+ var res = false;
+ if (typeof(which) == "undefined" | which == "" | which == "loaded") {
+ var res = sv.r.eval('data()');
+ } else { // which == "all"
+ var res = sv.r.eval('data(package = .packages(all.available = TRUE))');
+ }
+ return(res);
+}
+
+// Load one R dataset
+sv.r.data = function() {
+ var res = false;
+ // Get list of all datasets
+ res = sv.r.evalCallback('.tmp <- data();' +
+ 'cat(paste(.tmp$results[, "Item"], .tmp$results[, "Title"], sep = "\t - "), sep = "\n");' +
+ 'rm(.tmp)', sv.r.data_select);
+ ko.statusBar.AddMessage("Listing available R datasets... please wait",
+ "R", 20000, true);
+ return(res);
+}
+
+// The callback for sv.r.data
+sv.r.data_select = function(data) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(data) == "") {
+ alert("Problem retrieving the list of R datasets!");
+ } else { // Something is returned
+ var items = data.split("\n");
+ // Select the item you want in the list
+ var item = ko.dialogs.selectFromList("R Datasets",
+ "Select one R dataset:", items, "one");
+ if (item != null) {
+ // We need to eliminate the definition
+ var dat = item[0].split("\t");
+ var datname = dat[0];
+ // Sometimes, we got 'item (data)' => retrieve 'data' in this case
+ datname = datname.replace(/^[a-zA-Z0-9._ ]*[(]/, "");
+ datname = datname.replace(/[)]$/, "");
+ res = sv.r.eval('data(' + datname + ')');
+ }
+ }
+ return(res);
+}
+
+
+// Define the 'sv.r.pkg' namespace /////////////////////////////////////////////
+if (typeof(sv.r.pkg) == 'undefined') sv.r.pkg = new Object();
+
+// List available packages on the selected repositories
+sv.r.pkg.available = function() {
+ var res = sv.r.eval('.pkgAvailable <- available.packages()\n' +
+ 'as.character(.pkgAvailable[, "Package"])');
+ ko.statusBar.AddMessage("Looking for available R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// List installed packages
+sv.r.pkg.installed = function() {
+ var res = sv.r.eval('.pkgInstalled <- installed.packages()\n' +
+ 'as.character(.pkgInstalled[, "Package"])');
+ ko.statusBar.AddMessage("Looking for installed R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// List new packages in the repositories
+sv.r.pkg.new = function() {
+ var res = sv.r.eval('(.pkgNew <- new.packages())');
+ ko.statusBar.AddMessage("Looking for new R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// List installed packages which are older than those in repositories (+ versions)
+sv.r.pkg.old = function() {
+ var res = sv.r.eval('.pkgOld <- old.packages()\n' +
+ 'noquote(.pkgOld[, c("Installed", "ReposVer")])');
+ ko.statusBar.AddMessage("Looking for old R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// Update installed packages
+sv.r.pkg.update = function() {
+ var res = sv.r.eval('update.packages(ask = "graphics")');
+ ko.statusBar.AddMessage("Updating R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// Some statistics about R packages
+sv.r.pkg.status = function() {
+ var res = sv.r.eval('(.pkgStatus <- packageStatus())');
+ ko.statusBar.AddMessage("Compiling R packages status... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// Which R packages are currently loaded?
+sv.r.pkg.loaded = function() {
+ var res = sv.r.eval('(.packages())');
+ return(res);
+}
+
+// Load one R package
+sv.r.pkg.load = function() {
+ var res = false;
+ // Get list of installed R packages that are not loaded yet
+ res = sv.r.evalCallback('.tmp <- .packages(all.available = TRUE);' +
+ 'cat(.tmp[!.tmp %in% .packages()], sep = "\n"); rm(.tmp)',
+ sv.r.pkg.load_select);
+ ko.statusBar.AddMessage("Listing available R packages... please wait",
+ "R", 20000, true);
+ return(res);
+}
+
+// The callback for sv.r.pkg.load
+sv.r.pkg.load_select = function(pkgs) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(pkgs) == "") {
+ alert("All installed R packages seem to be already loaded!");
+ } else { // Something is returned
+ var items = pkgs.split("\n");
+ // Select the item you want in the list
+ var topic = ko.dialogs.selectFromList("Load R package",
+ "Select one R package to load:", items, "one");
+ if (topic != null) {
+ res = sv.r.eval('library(' +
+ (sv.tools.strings.removeLastCRLF(topic.join(''))) + ')');
+ }
+ }
+ return(res);
+}
+
+// Unload one R package
+sv.r.pkg.unload = function() {
+ var res = false;
+ // Get list of loaded packages, minus required ones we cannot unload
+ res = sv.r.evalCallback('.tmp <- .packages();' +
+ 'cat(.tmp[!.tmp %in% c(.required, "base")], sep = "\n"); rm(.tmp)',
+ sv.r.pkg.unload_select);
+ ko.statusBar.AddMessage("Listing loaded R packages... please wait",
+ "R", 20000, true);
+ return(res);
+}
+
+// The callback for sv.r.pkg.unload
+sv.r.pkg.unload_select = function(pkgs) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(pkgs) == "") {
+ alert("None of the loaded packages are safe to unload!");
+ } else { // Something is returned
+ var items = pkgs.split("\n");
+ // Select the item you want in the list
+ var topic = ko.dialogs.selectFromList("Unload R package",
+ "Select one R package to unload:", items, "one");
+ if (topic != null) {
+ res = sv.r.eval('detach("package:' +
+ (sv.tools.strings.removeLastCRLF(topic.join(''))) + '")');
+ }
+ }
+ return(res);
+}
+
+// Remove one R package
+sv.r.pkg.remove = function() {
+ var res = false;
+ // Get list of all packages, minus required and recommended ones we cannot remove
+ res = sv.r.evalCallback('.tmp <- installed.packages(); ' +
+ '.tmp <- rownames(.tmp)[is.na(.tmp[, "Priority"])]; ' +
+ 'cat(.tmp[!.tmp %in% c(.required, "svMisc", "svIDE", "svGUI", "svSocket", "svIO", "svViews", "svWidgets", "svDialogs")], sep = "\n"); rm(.tmp)',
+ sv.r.pkg.remove_select);
+ ko.statusBar.AddMessage("Listing removable R packages... please wait",
+ "R", 20000, true);
+ return(res);
+}
+
+// The callback for sv.r.pkg.remove
+sv.r.pkg.remove_select = function(pkgs) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(pkgs) == "") {
+ alert("None of the installed R packages are safe to remove!");
+ } else { // Something is returned
+ var items = pkgs.split("\n");
+ // Select the item you want in the list
+ var topic = ko.dialogs.selectFromList("Remove R package",
+ "Select one R package to remove:", items, "one");
+ if (topic != null) {
+ var pkg = (sv.tools.strings.removeLastCRLF(topic.join('')));
+ var response = ko.dialogs.customButtons("You are about to remove the '" +
+ pkg + "' R package from disk! Are you sure?",
+ ["&Continue...", "Cancel"], // buttons
+ "Continue...", // default response
+ null, // text
+ "Removing an R package"); // title
+ if (response == "Cancel") { return res; }
+
+ res = sv.r.eval('remove.packages("' + pkg +
+ '", lib = installed.packages()["' + pkg + '", "LibPath"])');
+ }
+ }
+ return(res);
+}
+
+// Install one R package
+// TODO: allow installing more than one package at a time
+sv.r.pkg.install = function() {
+ var res = false;
+ // Get list of all packages, minus required and recommended ones we cannot remove
+ res = sv.r.evalCallback('cat(rownames(available.packages()), sep = "\n")',
+ sv.r.pkg.install_select);
+ ko.statusBar.AddMessage("Listing available R packages... please wait",
+ "R", 60000, true);
+ return(res);
+}
+
+// The callback for sv.r.pkg.install
+sv.r.pkg.install_select = function(pkgs) {
+ ko.statusBar.AddMessage("", "R");
+ var res = false;
+ if (sv.tools.strings.removeLastCRLF(pkgs) == "") {
+ alert("Don't find available R packages!");
+ } else { // Something is returned
+ var items = pkgs.split("\n");
+ // Select the item you want in the list
+ var topic = ko.dialogs.selectFromList("Install R package",
+ "Select one R package to install:", items, "one");
+ if (topic != null) {
+ var pkg = (sv.tools.strings.removeLastCRLF(topic.join('')));
+ res = sv.r.eval('install.packages("' + pkg + '")');
+ ko.statusBar.AddMessage("Install package and dependencies... please wait",
+ "R", 60000, true);
+ }
+ }
+ return(res);
+}
+
+// Select repositories
+// TODO: a Komodo version of this that returns pure R code
+sv.r.pkg.repositories = function() {
+ var res = sv.r.eval('setRepositories(TRUE)');
+ return(res);
+}
+
+// Select CRAN mirror
+// TODO: a Komodo version of this that returns pure R code
+sv.r.pkg.CRANmirror = function() {
+ var res = sv.r.eval('chooseCRANmirror(TRUE)');
+ return(res);
+}
+
+// Install packages (the default R version)
+// TODO: merge this with sv.r.pkg.install, but allow more than one package
+sv.r.pkg.installDef = function() {
+ var res = false;
+ res = sv.r.eval('install.packages()');
+ ko.statusBar.AddMessage("Listing available R packages... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// Install R packages from local zip files
+// TODO: set filter for R package files!
+// TODO: use R CMD INSTALL instead + R CMD BUILD (--binary) + R CMD REMOVE
+sv.r.pkg.installLocal = function() {
+ var res = false;
+ // Get list of files to install
+ var files = ko.filepicker.openFiles(null, null,
+ "Select R package(s) to install (.tar.gz, .zip or .tgz)");
+ if (files != null) {
+ var cmd = "install.packages("
+ if (files.length == 1) {
+ cmd += '"' + files.join("") + '", repos = NULL)';
+ } else {
+ cmd += 'c("' + files.join('", "') + '", repos = NULL))';
+ }
+ res = sv.r.eval(cmd);
+ ko.statusBar.AddMessage("Installing R package(s)... please wait",
+ "R", 5000, true);
+ }
+ return(res);
+}
+
+// Install the SciViews bundle from CRAN
+sv.r.pkg.installSV = function() {
+ var res = false;
+ var response = ko.dialogs.customButtons("Currently, CRAN hosts an old, incompatible\n" +
+ "version of the SciViews-R bundle.\nInstall it anyway?",
+ ["&Continue...", "Cancel"], // buttons
+ "Continue...", // default response
+ null, // text
+ "Install the SciViews-R bundle from CRAN"); // title
+ if (response == "Cancel") { return res; }
+ res = sv.r.eval('install.packages("SciViews")');
+ ko.statusBar.AddMessage("Installing SciViews R bundle... please wait",
+ "R", 5000, true);
+ return(res);
+}
+
+// Install the latest development version of Sciviews packages from R-Forge
+sv.r.pkg.installSVrforge = function() {
+ var res = false;
+ var response = ko.dialogs.customButtons("R-Forge distributes latest development\n" +
+ "version of the SciViews-R bundle.\nThis is NOT the lastest stable one!\nInstall it anyway?",
+ ["&Continue...", "Cancel"], // buttons
+ "Continue...", // default response
+ null, // text
+ "Install the SciViews-R bundle from R-Forge"); // title
+ if (response == "Cancel") { return res; }
+ res = sv.r.eval('install.packages(c("svMisc", "svSocket", "svGUI", "svIDE"), repos = "http://R-Forge.R-project.org")');
+ ko.statusBar.AddMessage("Installing SciViews R packages from R-Forge... please wait",
+ "R", 5000, true);
+ return(res);
+}
Added: komodo/SciViews-K/content/js/robjects.js
===================================================================
--- komodo/SciViews-K/content/js/robjects.js (rev 0)
+++ komodo/SciViews-K/content/js/robjects.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,217 @@
+// SciViews-K R objects functions
+// Define the 'sv.r.objects' namespace
+// Copyright (c) 2008, Romain Francois
+// Contribution from Philippe Grosjean
+
+////////////////////////////////////////////////////////////////////////////////
+// objectList // List of objects to display
+// searchPaths // List of serach paths in R
+// searchPathsSelected // List of currently selected search paths
+//
+// sv.r.objects.searchpath(); // Show/hide the search path listbox
+// sv.r.objects.getPackageList(); // Query R for the search path
+// sv.r.objects._processPackageList(data); // Callback to process this list
+// sv.r.objects.displayPackageList(goback); // Display the search path items
+// sv.r.objects.addObjectList(pack); // Get list of objects from R
+// sv.r.objects._processObjectList(data); // Callback to process list of objects
+// sv.r.objects.displayObjectList(goback); // Display the objects in the tree
+// sv.r.objects.packageSelectedEvent(event); // Process click event in the list
+// sv.r.objects.packageSelected(pack, status); // Change package selection
+// sv.r.objects.__isSelected(p); // Is a package selected?
+// sv.r.objects.__addPackageToSelection(p); // Add a package to the list of sel
+// sv.r.objects.__removePackageFromSelection(p); // Remove a package from sel
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// TODO:
+// Autorefresh of R Objects from R + do not refresh if R Objects is not visible
+// Remember the selection in the path list persitently
+// Tooltips for objects
+// Context menu calculated from R
+// Drag&drop of objects to a buffer
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.r.objects' namespace
+if (typeof(sv.r.objects) == 'undefined')
+ sv.r.objects = {
+ objectList: [],
+ searchPaths: [],
+ searchPathsSelected: []
+ }
+
+// Show/hide the search path listbox
+sv.r.objects.searchpath = function() {
+ var split = document.getElementById("sciviews_robjects_splitter");
+ var state = split.getAttribute("state");
+ if (state == "collapsed") {
+ state = "open";
+ } else {
+ state = "collapsed";
+ }
+ split.setAttribute("state", state);
+}
+
+// Get the list of packages on the search path from R
+sv.r.objects.getPackageList = function() {
+ var cmd = 'cat(objSearch(sep = ",", compare = FALSE))';
+ sv.r.evalCallback(cmd, sv.r.objects._processPackageList);
+};
+
+// Callback to process the list of packages in the search path from R
+sv.r.objects._processPackageList = function(data) {
+ if (data == "") { return; } // No changes
+ sv.r.objects.searchPaths = data.replace(/[\n\r]/g, "").split(/,/);
+ sv.r.objects.displayPackageList();
+};
+
+// Display the list of packages in the search path
+sv.r.objects.displayPackageList = function(goback) {
+ var pack;
+ var node = document.getElementById("sciviews_robjects_searchpath_listbox");
+ sv.tools.e4x2dom.clear(node);
+
+ var item;
+ var packs = sv.r.objects.searchPaths;
+ var k = 0;
+ var checked = "false";
+ for(var i = 0; i < packs.length; i++) {
+ pack = packs[i]
+ if (sv.r.objects.__isSelected(pack)) {
+ ischecked = "true";
+ } else {
+ ischecked = "false";
+ }
+ item =
+ <listitem type="checkbox" label={pack} checked={ischecked}
+ onclick="sv.r.objects.packageSelectedEvent(event)"
+ spid={packs[i]}
+ />;
+ sv.tools.e4x2dom.append(item, node, k);
+ k++;
+ }
+ sv.r.objects.displayObjectList(false);
+ // if(goback) tb.focus();
+};
+
+// Ask R for the list of objects in an environment
+sv.r.objects.addObjectList = function(pack) {
+ var id = sv.prefs.getString("sciviews.client.id", "SciViewsK");
+ var cmd = 'cat(objList(id = "' + id + '_' + pack + '", envir = "' + pack +
+ '", all.info = TRUE, sep = ","), sep = "\n")';
+ sv.r.evalCallback(cmd, sv.r.objects._processObjectList);
+};
+
+// Callback to process the list of objects in an environment
+sv.r.objects._processObjectList = function(data) {
+ if (data == "") { return; } //no changes
+ lines = data.split("\n");
+ var rx = /,/;
+ var item, line;
+ var pack;
+ var idx;
+
+ for (var i = 0; i < lines.length; i++) {
+ if (rx.test(lines[i])) {
+ line = lines[i].split(",");
+ pack = line[0];
+
+ if (sv.r.objects.objectList[pack] == undefined) {
+ sv.r.objects.objectList[pack] = [];
+ idx = 0;
+ } else {
+ idx = sv.r.objects.objectList[pack].length;
+ }
+ sv.r.objects.objectList[pack][idx] =
+ new Array(line[1], line[2], line[3], line[4], line[5]);
+ }
+ }
+ sv.r.objects.displayObjectList();
+};
+
+// Display the list of objects in the tree
+sv.r.objects.displayObjectList = function(goback) {
+ var tb = document.getElementById("sciviews_robjects_filterbox");
+ var obRx = new RegExp(tb.value);
+
+ var node = document.getElementById("sciviews_robjects_objects_tree_main");
+ var k = 0;
+ var currentPack;
+ var currentFun;
+
+ for (var pack in sv.r.objects.objectList) {
+ currentPack = sv.r.objects.objectList[pack];
+ item =
+ <treeitem container="true" open="true">
+ <treerow>
+ <treecell label={pack} properties="package" />
+ <treecell label="" />
+ <treecell label="" />
+ <treecell label="" />
+ </treerow>
+ <treechildren />
+ </treeitem>;
+ item.treechildren.treeitem = new XMLList();
+ for (var i = 0; i < currentPack.length; i++) {
+ currentFun = currentPack[i];
+ if (obRx.test(currentFun[0])) {
+ item.treechildren.treeitem +=
+ <treeitem >
+ <treerow>
+ <treecell label={currentFun[0]}
+ properties={currentFun[3].replace(".", "-" )} />
+ <treecell label={currentFun[1]} />
+ <treecell label={currentFun[2]} />
+ <treecell label={currentFun[3]} />
+ </treerow>
+ </treeitem>;
+ }
+ }
+ sv.tools.e4x2dom.append(item, node, k);
+ k++;
+ }
+ if(goback) tb.focus();
+};
+
+// Change the display status of a package by clicking an item in the list
+sv.r.objects.packageSelectedEvent = function(event) {
+ var cb = event.target;
+ var status = cb.checked;
+ var spid = cb.getAttribute("spid");
+ sv.r.objects.packageSelected(spid, status);
+};
+
+// Process selection/deselection of packages
+sv.r.objects.packageSelected = function(pack, status) {
+ if (status) {
+ if (!sv.r.objects.__isSelected(pack)) {
+ sv.r.objects.__addPackageToSelection(pack);
+ }
+ } else {
+ if (sv.r.objects.__isSelected(pack)) {
+ sv.r.objects.__removePackageFromSelection(pack);
+ }
+ }
+};
+
+// Function that indicates whether a package is selected
+sv.r.objects.__isSelected = function(p) {
+ return(sv.tools.array.contains(sv.r.objects.searchPathsSelected, p));
+};
+
+// Add content of package to the tree
+sv.r.objects.__addPackageToSelection = function(p) {
+ sv.r.objects.searchPathsSelected[sv.r.objects.searchPathsSelected.length] = p;
+ sv.r.objects.addObjectList(p);
+};
+
+// Remove content of the package from the tree
+sv.r.objects.__removePackageFromSelection = function(p) {
+ sv.tools.array.remove(sv.r.objects.searchPathsSelected, p);
+ sv.r.objects.objectList =
+ sv.tools.array.removeItem(sv.r.objects.objectList, p);
+ sv.r.objects.displayObjectList();
+};
+
+// Make sure to check .GlobalEnv at the beginning
+// TODO: persitently save user's selection using Komodo mechanism
+sv.r.objects.packageSelected(".GlobalEnv", true);
Added: komodo/SciViews-K/content/js/sciviews.js
===================================================================
--- komodo/SciViews-K/content/js/sciviews.js (rev 0)
+++ komodo/SciViews-K/content/js/sciviews.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,385 @@
+// SciViews-K general functions
+// Define the basic 'sv' namespace
+// Copyright (c) 2008, Ph. Grosjean (phgrosjean at sciviews.org)
+
+////////////////////////////////////////////////////////////////////////////////
+// sv.version; // Get current SciViews-K version (major.minor)
+// sv.release; // The release (bug fixes). Full version is "version.release"
+// sv.checkVersion(version); // Check if the OpenKore extension version is fine
+//
+// Various functions defined in the 'sv' namespace directly
+// sv.getText(); // Get current selection, or word under the cursor
+// sv.getLine(); // Get current line in the active buffer
+// sv.getPart(what, resel, clipboard); // Get a part of text in the buffer
+ // or copy it to the clipboard (reset selection if resel == false)
+// sv.browseURI(URI, internal); // Show URI in internal or external browser
+// sv.showFile(path, readonly); // Show a file in Komodo, possibly as read-only
+// sv.helpURL(URL); // Display URL help in the default browser
+// sv.helpContext(); // Get contextual help for selected word in buffer in R or
+ // for active snippet in toolbox/project (see Help context)
+//
+// SciViews-K preferences management ('sv.prefs' namespace)
+// sv.prefs.getString(pref, def); // Get a preference, use 'def' is not found
+// sv.prefs.setString(pref, value, overwrite); // Set a preference string
+// sv.prefs.askString(pref, defvalue): // Ask for the value of a preference
+//
+// OpenKore Command Output management ('sv.cmdout' namespace)
+// sv.cmdout.append(str, newline); // Append text to the Command Output pane
+// sv.cmdout.clear(); // Clear the Command Output pane
+//
+////////////////////////////////////////////////////////////////////////////////
+
+if (typeof(sv) == 'undefined') {
+ sv = {
+ // TODO: set this automatically according to the plugin version
+ version: 0.6,
+ release: 0,
+ checkVersion: function(version) {
+ if (this.version < version) {
+ var title = "SciViews-K"
+ var prompt = "Outdated SciViews-K extension..."
+ var text = "One or more macros require the SciViews-K extension "
+ text += version + ".x"
+ text += " but the currently installed version is "
+ text += this.version + "." + this.release
+ text += ". You should update it."
+ text += " Would you like to open the extension manager"
+ text += " and check for available updates now?"
+ var res = ko.dialogs.yesNo(prompt, "Yes", text, title);
+ if (res == "Yes") ko.launch.openAddonsMgr();
+ return(false);
+ } else return(true);
+ }
+ };
+}
+// Create the 'sv.tools' namespace
+if (typeof(sv.tools) == 'undefined') sv.tools = new Object();
+
+// Other functions directly defined in the 'sv' namespace //////////////////////
+
+// Gets current selection, or word under the cursor in the active buffer
+sv.getText = function() {
+ var kv = ko.views.manager.currentView;
+ if (!kv) return("");
+ kv.setFocus();
+ var ke = kv.scimoz;
+ var txt = ke.selText;
+ // If selection is empty, get the word under the cursor
+ if (txt == "") txt = ko.interpolate.getWordUnderCursor(ke);
+ return(txt);
+};
+
+// Get current line of text in the active buffer
+sv.getLine = function() {
+ var kv = ko.views.manager.currentView;
+ if (!kv) return("");
+ kv.setFocus();
+ var ke = kv.scimoz;
+ // retain these so we can reset the selection after the replacement
+ var curAnchor = ke.anchor;
+ var curPos = ke.currentPos;
+ // Get the text in the current line
+ ke.home();
+ ke.lineEndExtend();
+ var currentLine = ke.selText;
+ // Reset the selection
+ ke.setSel(curAnchor, curPos);
+ // Return the content of the current line
+ return(currentLine);
+};
+
+// Select a part of text in the current buffer and return it
+sv.getPart = function(what, resel, clipboard) {
+ var text = "";
+ var kv = ko.views.manager.currentView;
+ if (kv) {
+ kv.setFocus();
+ var ke = kv.scimoz;
+ // retain these so we can reset the selection after the extraction
+ var curAnchor = ke.anchor;
+ var curPos = ke.currentPos;
+ var curLine = ke.lineFromPosition(curPos);
+ // Depending on 'what', we select different parts of the file
+ // By default, we keep current selection
+ switch(what) {
+ case "sel":
+ // Simply retain current selection
+ break;
+ //case "function":
+ // Try to select an entire R function
+ // TODO...
+ //break;
+ case "block":
+ // Select all content between two bookmarks
+ var Mark1 = ke.markerPrevious(curLine, -1);
+ if (Mark1 == -1) Mark1 = 0; // Select from the start of the document
+ var Mark2 = ke.markerNext(curLine, -1);
+ if (Mark2 == -1) Mark2 = ke.lineCount - 1; // Select to end of doc
+ ke.selectionStart = ke.positionFromLine(Mark1);
+ ke.selectionEnd = ke.positionFromLine(Mark2);
+ ke.lineEndExtend();
+ break;
+ case "para":
+ // Select the entire paragraph
+ ke.paraDown();
+ ke.paraUpExtend();
+ break;
+ case "line":
+ // Select whole current line
+ ke.home();
+ ke.lineEndExtend();
+ break;
+ case "linetobegin":
+ // Select line content from beginning to anchor
+ ke.lineUpExtend();
+ ke.lineEndExtend();
+ ke.charRightExtend();
+ break;
+ case "linetoend":
+ // Select line from anchor to end of line
+ ke.lineEndExtend();
+ break;
+ case "end":
+ // take text from current line to the end
+ ke.home();
+ ke.documentEndExtend();
+ break;
+ case "all":
+ default:
+ // Take everything
+ ke.selectAll();
+ }
+ if (clipboard) {
+ // Copy to clipboard instead of returning the text
+ ke.copy();
+ } else text = ke.selText;
+ // Possibly reset the selection
+ if (resel == false) ke.setSel(curAnchor, curPos);
+ }
+ return(text);
+};
+
+// Browse for the URI, either in an internal, or external (default) browser
+sv.browseURI = function(URI, internal) {
+ if (URI == "") {
+ alert("Item not found!"); // Because we call this from other
+ // functions that returns "" in case it doesn't find it (see sv.r.help)
+ } else {
+ if (internal == null)
+ internal = (sv.prefs.getString("sciviews.r.help",
+ "internal") == "internal");
+ if (internal == true) {
+ // TODO: open this in the R help pane, or in a buffer
+ ko.open.URI(URI, "browser");
+ } else {
+ ko.browse.openUrlInDefaultBrowser(URI);
+ }
+ }
+};
+
+// Show a text file in a buffer, possibly in read-only mode
+sv.showFile = function(path, readonly) {
+ if (path == "") {
+ alert("Item not found!"); // Same remark as for sv.browseURI()
+ } else {
+ ko.open.URI(path, "editor");
+ if (readonly == true) {
+ var kv = ko.views.manager.currentView;
+ var ke = kv.scimoz;
+ ke.readOnly = true;
+ // Make the caret a block and hatch the fold margin as indicator
+ ke.caretStyle = 2;
+ ke.setFoldMarginColour(true, 100);
+ kv.setFocus();
+ }
+ }
+};
+
+// Show URL in the default browser with current selection or <keyword>
+sv.helpURL = function(URL) {
+ try {
+ var kv = ko.views.manager.currentView;
+ if (!kv) return(false);
+ kv.setFocus();
+ var ke = kv.scimoz;
+ var sel = ke.selText;
+ if (sel == "") {
+ // Try to get the URL-escaped word under the cursor
+ if (ko.interpolate.getWordUnderCursor(ke) == "") {
+ alert("Nothing is currently selected!");
+ return(false);
+ } else {
+ sel = ko.interpolate.interpolateStrings('%W');
+ }
+ } else {
+ // Get the URL-escaped selection
+ sel = ko.interpolate.interpolateStrings('%S');
+ }
+ var helpURL = URL.replace("<keyword>", sel);
+ ko.browse.openUrlInDefaultBrowser(helpURL);
+ return(true);
+ } catch(e) { alert(e); }
+};
+
+// Get contextual help for a word in the buffer, or for snippets
+sv.helpContext = function() {
+ try {
+ if (ko.window.focusedView() == null) {
+ if (ko.projects.active) {
+ var item = ko.projects.active.getSelectedItem();
+ var content = item.value;
+ // Look for a string defining the URL for associated help file
+ // This is something like: [[%pref:URL|R|RWiki-help:<value>]]
+
+ // Look for URL-help
+ var help = content.replace(/^.*\[\[%pref:URL-help:([^\]]*)]].*$/,
+ '$1');
+ if (help != content) { // Found!
+ // Show in default browser
+ // TODO: a quick 'R help' tab to show this
+ ko.browse.openUrlInDefaultBrowser(help);
+ return(true);
+ }
+
+ // Look for R-help
+ help = content.replace(/^.*\[\[%pref:R-help:([^\]]*)]].*$/,
+ '$1');
+ if (help != content) { // Found!
+ // Do the help command in R
+ sv.r.help(help);
+ return(true);
+ }
+
+ // Look for RWiki-help
+ help = content.replace(/^.*\[\[%pref:RWiki-help:([^\]]*)]].*$/,
+ '$1');
+ if (help != content) { // Found!
+ // Get the RWiki base URL
+ var baseURL = "http:/wiki.r-project.org/rwiki/doku.php?id="
+ baseURL = sv.prefs.getString("sciviews.rwiki.help.base",
+ baseURL);
+ // Display the RWiki page
+ // TODO: display this in the quick 'R help' tab
+ ko.browse.openUrlInDefaultBrowser(baseURL + help);
+ return(true);
+ }
+
+ // No help data found
+ var msg = "No help found for this tool!";
+ StatusBar_AddMessage(msg, "debugger", 5000, true);
+ return(false);
+ }
+ } else { // The focus is currently on a buffer
+ // Try to get R help for current word
+ topic = sv.getText();
+ if (topic == "") {
+ alert("Nothing is selected!");
+ } else sv.r.help(topic);
+ }
+ return(true);
+ } catch(e) {
+ alert("Error while trying to get contextual help");
+ return(false);
+ }
+};
+
+
+// Preferences management //////////////////////////////////////////////////////
+if (typeof(sv.prefs) == 'undefined') sv.prefs = new Object();
+
+// Get a string preference, or default value
+sv.prefs.getString = function(pref, def) {
+ var prefsSvc = Components.classes["@activestate.com/koPrefService;1"].
+ getService(Components.interfaces.koIPrefService);
+ var prefs = prefsSvc.prefs;
+ if (prefs.hasStringPref(pref)) {
+ return(prefs.getStringPref(pref));
+ } else return(def);
+};
+
+// Set a string preference
+sv.prefs.setString = function(pref, value, overwrite) {
+ var prefsSvc = Components.classes["@activestate.com/koPrefService;1"].
+ getService(Components.interfaces.koIPrefService);
+ var prefs = prefsSvc.prefs;
+ if (overwrite == false & prefs.hasStringPref(pref)) return;
+ prefs.setStringPref(pref, value);
+};
+
+// Display a dialog box to change a preference string
+sv.prefs.askString = function(pref, defvalue) {
+ var prefsSvc = Components.classes["@activestate.com/koPrefService;1"].
+ getService(Components.interfaces.koIPrefService);
+ var prefs = prefsSvc.prefs;
+ // If defvalue is defined, use it, otherwise, use current pref value
+ if (defvalue == null & prefs.hasStringPref(pref))
+ defvalue = prefs.getStringPref(pref);
+ if (defvalue == null) defvalue == "";
+ // Display a dialog box to change the preference value
+ newvalue = ko.dialogs.prompt("Change preference value for:", pref,
+ defvalue, "SciViews-K preference", "svPref" + pref)
+ if (newvalue != null) prefs.setStringPref(pref, newvalue);
+}
+
+
+// This is required by sv.helpContext() for attaching help to snippets (hack!)
+// Create empty preference sets to be used with snippet help system hack
+// [[%pref:R-help:value]] which displays nothing when the snippet is used
+// but can be used to retrieve value to display a particular help page
+// for this snippet
+// Help page triggered by a given URL
+sv.prefs.setString("URL-help", "", true);
+// R HTML help pages triggered with '?topic'
+sv.prefs.setString("R-help", "", true);
+// Help page on the R Wiki
+sv.prefs.setString("RWiki-help", "", true);
+
+
+// Control the command output tab //////////////////////////////////////////////
+if (typeof(sv.cmdout) == 'undefined') sv.cmdout = new Object();
+
+// Append text to the Command Output pane
+sv.cmdout.append = function(str, newline) {
+ try {
+ var runout = ko.run.output;
+ // Make sure the command output window is visible
+ runout.show(window, false);
+ // Make sure we're showing the output pane
+ var deckWidget = document.getElementById("runoutput-deck");
+ if (deckWidget.getAttribute("selectedIndex") != 0) {
+ runout.toggleView();
+ }
+ // Find out the newline sequence uses, and write the text to it.
+ var scimoz = document.getElementById("runoutput-scintilla").scimoz;
+ var prevLength = scimoz.length;
+ if (newline == null) str += ["\r\n", "\n", "\r"][scimoz.eOLMode];
+ var str_byte_length = ko.stringutils.bytelength(str);
+ var ro = scimoz.readOnly;
+ try {
+ scimoz.readOnly = false;
+ scimoz.appendText(str_byte_length, str);
+ } finally { scimoz.readOnly = ro; }
+ // Bring the new text into view
+ scimoz.gotoPos(prevLength + 1);
+ } catch(e) { alert("Problems printing [" + str + "]:" + e + "\n"); }
+};
+
+// Clear text in the Output Command pane
+sv.cmdout.clear = function() {
+ try {
+ var runout = ko.run.output;
+ // Make sure the command output window is visible
+ runout.show(window, false);
+ // Make sure we're showing the output pane
+ var deckWidget = document.getElementById("runoutput-deck");
+ if (deckWidget.getAttribute("selectedIndex") != 0) {
+ runout.toggleView();
+ }
+ var scimoz = document.getElementById("runoutput-scintilla").scimoz;
+ var ro = scimoz.readOnly;
+ try {
+ scimoz.readOnly = false;
+ scimoz.clearAll();
+ } finally { scimoz.readOnly = ro; }
+ } catch(e) { alert("problems clearing the Command Output pane\n"); }
+};
Added: komodo/SciViews-K/content/js/socket.js
===================================================================
--- komodo/SciViews-K/content/js/socket.js (rev 0)
+++ komodo/SciViews-K/content/js/socket.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,281 @@
+// SciViews-K socket client/server functions
+// Socket client and server functions to connect to R kernels
+// Copyright (c) 2008, Ph. Grosjean (phgrosjean at sciviews.org)
+
+////////////////////////////////////////////////////////////////////////////////
+// To cope with versions incompatibilities, we define this:
+// sv.socket.svSocketMinVersion // minimal svSocket version required
+//
+/////// Socket client //////
+// Parameters:
+// sv.socket.host; // The address of the R server host (local only for now)
+// sv.socket.cmdout // Do we echo exchange to the Output Command pane?
+// sv.socket.promt // Look at this to know if we are in multiline mode
+// sv.socket.cmd // In case of multiline mode, the partial command so far
+//
+// sv.socket.rClient(host, port, outputData, listener, echo); // Main client fct
+// sv.socket.rCommand(cmd); // Send cmd to the R socket server for evaluation
+//
+/////// Socket server //////
+// Parameters:
+// sv.socket.debug // Debugging mode (in Command Output)
+// sv.socket.serverIsLocal // Is the socket servicing only localhost?
+//
+// sv.socket.serverStart(); // Start the OpenKore socket server
+// sv.socket.serverStop(); // Stop the OpenKore socket server
+// sv.socket.serverIsStarted(); // Is the socket server currently started?
+// sv.socket.serverConfig(); // Get a short description of server config
+// sv.socket.serverWrite(data); // Write a string through the socket server
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.socket' namespace
+if (typeof(sv.socket) == 'undefined') sv.socket = new Object();
+
+// Will be used later for compatibility checking between R and Komodo tools
+sv.socket.svSocketMinVersion = "0.9-40";
+
+
+/////// Socket client //////////////////////////////////////////////////////////
+sv.socket.host = "127.0.0.1"; // Host to connect to (local host only, currently)
+sv.socket.cmdout = true; // Do we write to 'Command Output'?
+sv.socket.prompt = ":> "; // The prompt, could be changed o continue prompt
+sv.socket.cmd = ""; // The command to send to R
+
+// The main socket client function to connect to R socket server
+sv.socket.rClient = function(host, port, outputData, listener, echo, echofun) {
+ try {
+ var transportService = Components.
+ classes["@mozilla.org/network/socket-transport-service;1"]
+ .getService(Components.interfaces.nsISocketTransportService);
+ var transport = transportService.createTransport(null, 0,
+ host, port, null);
+
+ var outstream = transport.openOutputStream(0, 0, 0);
+ outstream.write(outputData, outputData.length);
+
+ var stream = transport.openInputStream(0, 0, 0);
+ var instream = Components.
+ classes["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Components.interfaces.nsIScriptableInputStream);
+ instream.init(stream);
+
+ var dataListener = {
+ data: "",
+ onStartRequest: function(request, context) { this.data = ""; },
+ onStopRequest: function(request, context, status) {
+ instream.close();
+ outstream.close();
+ this.data = sv.tools.strings.removeLastCRLF(this.data);
+ listener.finished(this.data);
+ },
+ onDataAvailable: function(request, context,
+ inputStream, offset, count) {
+ // TODO: limit the total amount of data send through the socket!
+ var chunk = instream.read(count);
+ // Determine if we have a prompt at the end
+ var cl = chunk.length;
+ if (chunk.substring(cl-5, cl-3) == "> " |
+ chunk.substring(cl-4, cl-2) == "> ") {
+ sv.socket.prompt = ":> ";
+ }
+ if (chunk.substring(cl-5, cl-3) == "+ " |
+ chunk.substring(cl-4, cl-2) == "+ ") {
+ sv.socket.prompt = ":+ ";
+ }
+ // Do we need to close the connection
+ // (\f received, followed by \n, \r, or both)?
+ if (chunk.match("\n\f") == "\n\f") {
+ instream.close();
+ outstream.close();
+ // Eliminate the trailing (\r)\n\f chars before the prompt
+ if (chunk.indexOf("\r\n\f") > -1) {
+ chunk = chunk.replace("\r\n\f", "");
+ } else {
+ chunk = chunk.replace("\n\f", "");
+ }
+ // Eliminate the last carriage return after the prompt
+ chunk = chunk.replace(/ \r?\n?$/, " ");
+ }
+ this.data += chunk;
+ // Do we "echo" these results somewhere?
+ if (echo) {
+ if (echofun == null) {
+ // Use default echo function (to the Command Output)
+ sv.cmdout.append(chunk, newline = false);
+ } else echofun(chunk);
+ }
+ },
+ }
+
+ var pump = Components.
+ classes["@mozilla.org/network/input-stream-pump;1"].
+ createInstance(Components.interfaces.nsIInputStreamPump);
+ pump.init(stream, -1, -1, 0, 0, false);
+ pump.asyncRead(dataListener, null);
+ } catch (e) { return(e); }
+ return(null);
+}
+
+// Send an R command through the socket
+sv.socket.rCommand = function(cmd, echo, echofun, procfun) {
+ cmd = sv.tools.strings.replaceCRLF(cmd, "<<<n>>>");
+ if (procfun == null) { // Do nothing at the end
+ var listener = { finished: function(data) {} }
+ } else { // Call procfun at the end
+ var listener = { finished: function(data) { procfun(data); } }
+ }
+ // TODO: deal with error checking for this command
+ var port = sv.prefs.getString("sciviews.client.socket", "8888");
+ var id = "<<<id=" + sv.prefs.getString("sciviews.client.id", "SciViewsK") +
+ ">>>";
+ var res = sv.socket.rClient(sv.socket.host, port, id + cmd + "\n",
+ listener, echo, echofun);
+ return(res);
+}
+//sv.socket.rCommand("<<<q>>>cat('library = '); str(library)");
+
+
+/////// Socket server //////////////////////////////////////////////////////////
+sv.socket.debug = false; // Set to true for debugging mode
+sv.socket.serverIsLocal = true; // Is the socket servicing only localhost?
+
+const nsITransport = Components.interfaces.nsITransport;
+
+var serverSocket; // The SviViews-K socket server object
+var serverStarted = false; // Is the socket server started?
+var inputString; // The string with the command send by the client
+var outputString; // The string with the result to send to the client
+
+// Core function for the SciViews-K socket server: create the serverSocket object
+sv.socket.serverStart = function() {
+ var listener = {
+ onSocketAccepted : function(socket, transport) {
+ try {
+ // Make sure to clean input and output strings before use
+ inputString = "";
+ outputString = "";
+ if (sv.socket.debug) {
+ sv.cmdout.clear();
+ sv.cmdout.append("#--# SciViews-K socket client: " +
+ transport.host + " on port " + transport.port + "\n");
+ }
+
+ // Then, read data from the client
+ var inputStream = transport.openInputStream(nsITransport.
+ OPEN_BLOCKING, 0, 0);
+ var sin = Components.
+ classes["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Components.interfaces.
+ nsIScriptableInputStream);
+ sin.init(inputStream);
+
+ // Wait for input up to 10 sec max, with synchroneous com only)
+ var millis = 10000;
+ var date = new Date();
+ var curDate = null;
+ do {
+ curDate = new Date();
+ inputString = sin.read(512);
+ } while(inputString == "" & curDate - date < millis)
+
+ // Read the complete data
+ while (sin.available() > 0)
+ inputString += sin.read(512);
+
+ // Is there data send?
+ if (inputString == "") {
+ outputString += "Error: no command send!\n"
+ } else {
+ // Process the command
+ if (sv.socket.debug) sv.cmdout.append("#--# Command send" +
+ " by the client:\n" + inputString);
+ try {
+ ko.commands.doCode(1, inputString);
+ } catch(cmderr) {
+ if (cmderr) outputString += "\nError: " + cmderr;
+ }
+ }
+ if (sv.socket.debug) {
+ if (outputString == "") {
+ sv.cmdout.append("#--# Nothing to return" +
+ " to the socket client");
+ } else {
+ sv.cmdout.append("#--# Result:\n" + outputString);
+ }
+ }
+
+ // And finally, return the result to the socket client
+ // (append \n at the end)
+ outputString += "\n";
+ var outputStream = transport.openOutputStream(nsITransport.
+ OPEN_BLOCKING, 0, 0);
+ outputStream.write(outputString, outputString.length);
+ } catch(e) {
+ dump(e);
+ } finally {
+ // Make sure that streams are closed
+ outputStream.close();
+ inputStream.close();
+ }
+ },
+
+ onStopListening : function(socket, status) {
+ // The connection is closed by the client
+ if (sv.socket.debug)
+ sv.cmdout.append("#--# SciViews-K socket closed");
+ }
+ };
+
+ try {
+ serverSocket = Components.
+ classes["@mozilla.org/network/server-socket;1"]
+ .createInstance(Components.interfaces.nsIServerSocket);
+ var port = sv.prefs.getString("sciviews.server.socket", "7052");
+ serverSocket.init(port, sv.socket.serverIsLocal, -1);
+ serverSocket.asyncListen(listener);
+ } catch(ex) { dump(ex); }
+ serverStarted = true;
+ if (sv.socket.debug)
+ ko.statusBar.AddMessage("SciViews-K socket server started", "svSock",
+ 2000, true);
+}
+
+// Stop the SciViews-K socket server
+sv.socket.serverStop = function() {
+ if (serverStarted) {
+ serverSocket.close();
+ serverStarted = false;
+ ko.statusBar.AddMessage("SciViews-K socket server stopped",
+ "svSock", 2000, true);
+ } else {
+ ko.statusBar.AddMessage("SciViews-K socket server is not started",
+ "svSock", 2000, true);
+ }
+}
+
+// Is the SciViews-K socket server started?
+sv.socket.serverIsStarted = function() {
+ return(serverStarted);
+}
+
+// What is the current SciViews-K socket server config?
+sv.socket.serverConfig = function() {
+ var serverStatus = " (stopped)"
+ if (serverStarted) serverStatus = " (started)"
+ var port = sv.prefs.getString("sciviews.server.socket", "7052");
+ if (sv.socket.serverIsLocal) {
+ return("Local socket server on port " + port + serverStatus);
+ } else {
+ return("Global socket server on port " + port + serverStatus);
+ }
+}
+
+// Write to the socket server, use this to return something to the client
+sv.socket.serverWrite = function(data) {
+ if (serverStarted) {
+ outputString += data;
+ } else {
+ alert("Trying to write data though the SciViews-K socket server" +
+ " that is not started!")
+ }
+}
Added: komodo/SciViews-K/content/js/tools/array.js
===================================================================
--- komodo/SciViews-K/content/js/tools/array.js (rev 0)
+++ komodo/SciViews-K/content/js/tools/array.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,38 @@
+// SciViews-K functions
+// Various functions to manipulate arrays
+// by Romain Francois
+
+////////////////////////////////////////////////////////////////////////////////
+// sv.tools.array.remove(a, s); // Eliminate 's' from 'a'
+// sv.tools.array.contains(a, s); // Does array 'a' contain 's'
+// sv.tools.array.removeItem(a, s); // Return an array with 's' removed from 'a'
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.tools.array' namespace
+if (typeof(sv.tools.array) == 'undefined') sv.tools.array = new Object();
+
+// Remove 's' from the array 'a'
+sv.tools.array.remove = function(a, s) {
+ for (i = 0; i < a.length; i++) {
+ if (s == a[i]) a.splice(i, 1);
+ }
+}
+
+// Does the array 'a' contain 's'?
+sv.tools.array.contains = function(a, s) {
+ for (i = 0; i< a.length; i++) {
+ if (s == a[i]) return(true);
+ }
+ return(false);
+}
+
+// Return an array from which 's' item is eliminated fro the array 'a'
+sv.tools.array.removeItem = function(a, s) {
+ b = [];
+ for (i in a) {
+ if (i != s) {
+ b[i] = a[i]
+ }
+ }
+ return(b);
+}
Added: komodo/SciViews-K/content/js/tools/e4x2dom.js
===================================================================
--- komodo/SciViews-K/content/js/tools/e4x2dom.js (rev 0)
+++ komodo/SciViews-K/content/js/tools/e4x2dom.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,75 @@
+// SciViews-K functions
+// From this post and modified by R. Francois so that it works with XUL:
+// http://ecmanaut.blogspot.com/2006/03/e4x-and-dom.html
+
+////////////////////////////////////////////////////////////////////////////////
+// sv.tools.e4x2dom.importNode(e4x, doc); // Translate e4x node to DOM node
+// sv.tools.e4x2dom.appendTo(e4x, node, doc); // Append e4x node to a DOM node
+// sv.tools.e4x2dom.setContent(e4x, node); // Idem, but clear DOM node first
+// sv.tools.e4x2dom.append(e4x, node, i); // Append at 'i'th position
+// sv.tools.e4x2dom.clear(node); // Clear a DOM node
+// sv.tools.e4x2dom.d4e(domNode); // Translate DOM node to e4x node
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.tools.e4x2dom' namespace
+if (typeof(sv.tools.e4x2dom) == 'undefined') sv.tools.e4x2dom = new Object();
+
+// Translate e4x (JavaScript) node into a DOM node
+sv.tools.e4x2dom.importNode = function(e4x, doc) {
+ var me = this.importNode, xhtml, domTree, importMe;
+ me.Const = me.Const || { mimeType: 'text/xml' };
+ me.Static = me.Static || {};
+ me.Static.parser = me.Static.parser || new DOMParser;
+ xhtml = <testing
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>;
+ xhtml.test = e4x;
+ domTree = me.Static.parser.parseFromString( xhtml.toXMLString().
+ replace( />\n *</g, "><" ), me.Const.mimeType);
+ importMe = domTree.documentElement.firstChild;
+ while(importMe && importMe.nodeType != 1)
+ importMe = importMe.nextSibling;
+ if(!doc) doc = document;
+ return importMe ? doc.importNode(importMe, true) : null;
+}
+
+// Append an e4x node to a DOM node
+sv.tools.e4x2dom.appendTo = function(e4x, node, doc) {
+ return(node.appendChild(this.importNode(e4x, doc || node.ownerDocument)));
+}
+
+// Append an e4x node to a DOM node, clearing it first
+sv.tools.e4x2dom.setContent = function(e4x, node) {
+ this.clear(node);
+ this.appendTo(e4x, node);
+}
+
+// Append an e4x node to a DOM node, clear first or not depending on 'i'
+sv.tools.e4x2dom.append = function(e4x, node, i) {
+ if (i == 0) {
+ this.setContent(e4x, node);
+ } else {
+ this.appendTo(e4x, node);
+ }
+}
+
+// Clear a DOM node
+sv.tools.e4x2dom.clear = function(node) {
+ while(node.firstChild)
+ node.removeChild(node.firstChild);
+}
+
+// Translate a DOM node into an e4x (JavaScript) node
+sv.tools.e4x2dom.d4e = function(domNode) {
+ var xmls = new XMLSerializer();
+ return(new XML(xmls.serializeToString(domNode)));
+}
+
+var HTML = "http://www.w3.org/1999/xhtml";
+var XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+var SVG = "http://www.w3.org/2000/svg";
+var RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+
+default xml namespace = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
Added: komodo/SciViews-K/content/js/tools/strings.js
===================================================================
--- komodo/SciViews-K/content/js/tools/strings.js (rev 0)
+++ komodo/SciViews-K/content/js/tools/strings.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,35 @@
+// SciViews-K functions
+// Various functions to manipulate strings
+// by Philippe Grosjean and Romain Francois
+
+////////////////////////////////////////////////////////////////////////////////
+// sv.tools.strings.replaceCRLF(str, code); // Replace LF and CR by 'code'
+// sv.tools.strings.removeLastCRLF(str); // Remove last CR and or LF
+////////////////////////////////////////////////////////////////////////////////
+
+// Define the 'sv.tools.strings' namespace
+if (typeof(sv.tools.strings) == 'undefined') sv.tools.strings = new Object();
+
+// Replace line feed and carriage return by 'code'
+sv.tools.strings.replaceCRLF = function(str, code) {
+ // Replace all \r\n by 'code' in cmd
+ while (str.indexOf("\r\n") > -1) {
+ str = str.replace("\r\n", code);
+ }
+ // Replace all \n by 'code' in cmd
+ while (str.indexOf("\n") > -1) {
+ str = str.replace("\n", code);
+ }
+ // Replace all \r by 'code' in cmd
+ while (str.indexOf("\r") > -1) {
+ str = str.replace("\r", code);
+ }
+ return(str);
+}
+
+// Remove the last line feed and or carriage return in the text
+sv.tools.strings.removeLastCRLF = function(str) {
+ str = str.replace( /[\n\r]{1,2}$/, "");
+ return(str);
+}
+
Added: komodo/SciViews-K/content/overlay.xul
===================================================================
--- komodo/SciViews-K/content/overlay.xul (rev 0)
+++ komodo/SciViews-K/content/overlay.xul 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,172 @@
+<?xml version="1.0"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is SciViews-K by Philippe Grosjean & Romain Francois.
+
+ Portions created by ActiveState Software Inc are Copyright (C) 2000-2008
+ ActiveState Software Inc. All Rights Reserved.
+
+ Contributor(s):
+ Philippe Grosjean
+ Romain Francois
+ ActiveState Software Inc
+
+ Alternatively, the contents of this file may be used under the terms of
+ either the GNU General Public License Version 2 or later (the "GPL"), or
+ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ in which case the provisions of the GPL or the LGPL are applicable instead
+ of those above. If you wish to allow use of your version of this file only
+ under the terms of either the GPL or the LGPL, and not to allow others to
+ use your version of this file under the terms of the MPL, indicate your
+ decision by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL or the LGPL. If you do not delete
+ the provisions above, a recipient may use your version of this file under
+ the terms of any one of the MPL, the GPL or the LGPL.
+
+ ***** END LICENSE BLOCK ***** -->
+<!DOCTYPE overlay PUBLIC "-//MOZILLA//DTD XUL V1.0//EN" "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" [
+ <!ENTITY % sciviewskDTD SYSTEM "chrome://sciviewsk/locale/sciviewsk.dtd">
+ %sciviewskDTD;
+]>
+
+<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/global/global.p.css" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/bindings/buttons.css" type="text/css"?>
+<?xml-stylesheet href="chrome://sciviewsk/skin/sciviewsk.css" type="text/css"?>
+
+<overlay id="sciviewskOverlay"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/sciviews.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/prefs.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/strings.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/e4x2dom.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/array.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/socket.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/r.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/robjects.js"/>
+
+ <commandset id="allcommands">
+ <command id="Tasks:svAbout" oncommand="alert('SciViews-K (Komodo R Editor) version ' + sv.version + '\na Komodo extension to interact with R\n(see http://www.sciviews.org/SciViews-K)');"/>
+ </commandset>
+
+ <menupopup id="popup_tools">
+ <menuitem id="menu_sciviews"
+ label="SciViews-K"
+ observes="Tasks:svAbout"
+ class="menu-iconic-wide"/>
+ </menupopup>
+
+ <menupopup id="tabPicker_popup">
+ <menuitem id="show_robjects_tab"
+ insertafter="show_codebrowser_tab"
+ oncommand="uilayout_ensureTabShown('sciviews_robjects_tab', true)"
+ label="&sciviews.robjects.tab;"
+ />
+ </menupopup>
+
+ <menupopup id="menu_view_tabs_popup">
+ <menuitem id="show_robjects_tab2"
+ insertafter="show_codebrowser_tab2"
+ class="menuitem-iconic-wide"
+ oncommand="uilayout_ensureTabShown('sciviews_robjects_tab', true)"
+ label="&sciviews.robjects.tab;"
+ />
+ </menupopup>
+
+ <tabbox id="leftTabBox">
+ <tabs id="project_toolbox_tabs">
+ <tab id="sciviews_robjects_tab"
+ label="&sciviews.robjects.tab;"
+ insertafter="codebrowser_tab"
+ tooltiptext="&sciviews.robjects.tip;"
+ onclick="sv.r.objects.getPackageList()" />
+ </tabs>
+ <tabpanels id="project_toolbox_tabpanels">
+ <tabpanel flex="1" id="sciviews_robjects_tabpanel"
+ insertafter="codebrowserviewbox">
+ <vbox flex="1" id="sciviews_robjects_vbox">
+ <hbox align="center"
+ id="sciviews_robjects_hbox"
+ style="margin: 0px 2px;">
+ <toolbarbutton
+ id="sciviews_robjects_refresh_button"
+ tooltiptext="&sciviews.robjects.refresh.tip;"
+ buttonstyle="pictures"
+ label="&sciviews.robjects.refresh;"
+ class="refresh-icon button-toolbar-a"
+ oncommand="sv.r.objects.getPackageList();"
+ />
+ <toolbarbutton
+ id="sciviews_robjects_searchpath_button"
+ tooltiptext="&sciviews.robjects.showHide.tip;"
+ buttonstyle="pictures"
+ label="&sciviews.robjects.showHide;"
+ class="searchPath-icon button-toolbar-a"
+ oncommand="sv.r.objects.searchpath();"
+ />
+ <toolbarseparator style="min-width:10px;" flex="1"/>
+ <image id="sciviews_robjects_filter_icon"
+ tooltiptext="&sciviews.robjects.filter.tip;"
+ class="codeintel-search"/>
+ <textbox
+ id="sciviews_robjects_filterbox"
+ style="min-width:40px; max-width:200px; margin-right:0px;"
+ flex="1"
+ type="timed"
+ timeout="500"
+ tooltiptext="&sciviews.robjects.filter.tip;"
+ oninput="sv.r.objects.displayObjectList(false);"
+ />
+ </hbox>
+ <vbox>
+ <listbox flex="1" id="sciviews_robjects_searchpath_listbox"/>
+ </vbox>
+ <splitter
+ id="sciviews_robjects_splitter"
+ collapse="before"
+ resizeafter="closest"
+ resizebefore="closest"
+ state="collapsed">
+ <grippy tooltiptext="&sciviews.robjects.showHide.tip;"/>
+ </splitter>
+ <vbox flex="5">
+ <tree flex="1" id="sciviews_robjects_objects_tree" >
+ <treecols>
+ <treecol label="&sciviews.robjects.Name;" primary="true" flex="4"/>
+ <treecol label="&sciviews.robjects.Dims;" flex="1"/>
+ <treecol label="&sciviews.robjects.Group;" flex="1" hidden="true" />
+ <treecol label="&sciviews.robjects.Class;" flex="1" hidden="true" />
+ </treecols>
+ <!--<treechildren id="sciviews_robjects_objects_tree_main" ondraggesture="nsDragAndDrop.startDrag(event,RObjectObserver);" />-->
+ <treechildren id="sciviews_robjects_objects_tree_main">
+ <treeitem>
+ <treerow>
+ <treecell label="" />
+ <treecell label="" />
+ <treecell label="" />
+ <treecell label="" />
+ </treerow>
+ </treeitem>
+ </treechildren>
+ </tree>
+ </vbox>
+ </vbox>
+ </tabpanel>
+ </tabpanels>
+ </tabbox>
+
+</overlay>
Added: komodo/SciViews-K/install.rdf
===================================================================
--- komodo/SciViews-K/install.rdf (rev 0)
+++ komodo/SciViews-K/install.rdf 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+ The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is OpenKore code for Komodo (from ActiveState Software Inc)
+ developed in the framework of the SciViews project, and sponsored by the
+ UNCOVER E.U. program.
+
+ Contributor(s):
+ Romain Francois (rfrancois at mango-solutions.com)
+ Philippe Grosjean (phgrosjean at sciviews.org)
+
+ Alternatively, the contents of this file may be used under the terms of
+ either the GNU General Public License Version 2 or later (the "GPL"), or
+ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ in which case the provisions of the GPL or the LGPL are applicable instead
+ of those above. If you wish to allow use of your version of this file only
+ under the terms of either the GPL or the LGPL, and not to allow others to
+ use your version of this file under the terms of the MPL, indicate your
+ decision by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL or the LGPL. If you do not delete
+ the provisions above, a recipient may use your version of this file under
+ the terms of any one of the MPL, the GPL or the LGPL.
+
+ ***** END LICENSE BLOCK ***** -->
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>sciviewsk at sciviews.org</em:id>
+ <em:name>SciViews-K</em:name>
+ <em:version>0.6.0</em:version>
+ <em:description>SciViews-K - Edit R (http://www.r-project.org) code in Komodo</em:description>
+ <em:creator>Philippe Grosjean and Romain Francois</em:creator>
+ <em:homepageURL>http://sciviews.org/SciViews-K</em:homepageURL>
+ <em:type>2</em:type> <!-- type=extension -->
+
+ <em:targetApplication>
+ <Description>
+ <!-- Komodo IDE's uuid -->
+ <em:id>{36E66FA0-F259-11D9-850E-000D935D3368}</em:id>
+ <em:minVersion>4.1</em:minVersion>
+ <em:maxVersion>4.4.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- Komodo Edit's uuid -->
+ <em:id>{b1042fb5-9e9c-11db-b107-000d935d3368}</em:id>
+ <em:minVersion>4.1</em:minVersion>
+ <em:maxVersion>4.4.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
Added: komodo/SciViews-K/locale/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/locale/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/locale/en-GB/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/locale/en-GB/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/locale/en-GB/sciviewsk.dtd
===================================================================
--- komodo/SciViews-K/locale/en-GB/sciviewsk.dtd (rev 0)
+++ komodo/SciViews-K/locale/en-GB/sciviewsk.dtd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,11 @@
+<!ENTITY sciviews.robjects.tab "R Objects">
+<!ENTITY sciviews.robjects.tip "R objects explorer">
+<!ENTITY sciviews.robjects.refresh "Refresh">
+<!ENTITY sciviews.robjects.refresh.tip "Refresh R objects">
+<!ENTITY sciviews.robjects.showHide "Search path">
+<!ENTITY sciviews.robjects.showHide.tip "Show/hide search path">
+<!ENTITY sciviews.robjects.filter.tip "Filter the names of the objects">
+<!ENTITY sciviews.robjects.Name "Name">
+<!ENTITY sciviews.robjects.Dims "Dims">
+<!ENTITY sciviews.robjects.Group "Group">
+<!ENTITY sciviews.robjects.Class "Class">
Added: komodo/SciViews-K/locale/fr-FR/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/locale/fr-FR/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/locale/fr-FR/sciviewsk.dtd
===================================================================
--- komodo/SciViews-K/locale/fr-FR/sciviewsk.dtd (rev 0)
+++ komodo/SciViews-K/locale/fr-FR/sciviewsk.dtd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,11 @@
+<!ENTITY sciviews.robjects.tab "R Objects">
+<!ENTITY sciviews.robjects.tip "Explorateur d'objets R">
+<!ENTITY sciviews.robjects.refresh "Ractualiser">
+<!ENTITY sciviews.robjects.refresh.tip "Ractualiser les objets R">
+<!ENTITY sciviews.robjects.showHide "Chemin de recherche">
+<!ENTITY sciviews.robjects.showHide.tip "Montrer/cacher le chemin de recherche">
+<!ENTITY sciviews.robjects.filter.tip "Filtrer le nom des objets">
+<!ENTITY sciviews.robjects.Name "Nom">
+<!ENTITY sciviews.robjects.Dims "Dims">
+<!ENTITY sciviews.robjects.Group "Groupe">
+<!ENTITY sciviews.robjects.Class "Classe">
Added: komodo/SciViews-K/sciviewsk-0.6.0-ko.xpi
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/sciviewsk-0.6.0-ko.xpi
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/array.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/array.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/body_bg_sav.gif
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/body_bg_sav.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/character.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/character.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/data.frame.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/data.frame.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/dist.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/dist.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/factor.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/factor.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/function.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/function.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/integer.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/integer.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/list.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/list.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/logical.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/logical.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/matrix.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/matrix.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/numeric.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/numeric.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/objects.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/objects.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/package.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/package.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/images/ts.png
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/skin/images/ts.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/skin/sciviewsk.css
===================================================================
--- komodo/SciViews-K/skin/sciviewsk.css (rev 0)
+++ komodo/SciViews-K/skin/sciviewsk.css 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,24 @@
+.searchPath-icon{
+ list-style-image: url("chrome://komodo/skin/images/bulletlist.png");
+}
+.searchPath-icon:hover{
+ list-style-image : url("chrome://komodo/skin/images/bulletlist_hover.png");
+}
+
+.refresh-icon{
+ list-style-image: url("chrome://komodo/skin/global/images/refresh.png");
+}
+treechildren::-moz-tree-cell-text(package) { font-weight: bold; }
+treechildren::-moz-tree-image(package){ list-style-image: url("chrome://sciviewsk/skin/images/package.png"); }
+treechildren::-moz-tree-image(matrix){ list-style-image: url("chrome://sciviewsk/skin/images/matrix.png"); }
+treechildren::-moz-tree-image(array){ list-style-image: url("chrome://sciviewsk/skin/images/array.png"); }
+treechildren::-moz-tree-image(character){ list-style-image: url("chrome://sciviewsk/skin/images/character.png"); }
+treechildren::-moz-tree-image(data-frame){ list-style-image: url("chrome://sciviewsk/skin/images/data.frame.png"); }
+treechildren::-moz-tree-image(numeric){ list-style-image: url("chrome://sciviewsk/skin/images/numeric.png"); }
+treechildren::-moz-tree-image(integer){ list-style-image: url("chrome://sciviewsk/skin/images/integer.png"); }
+treechildren::-moz-tree-image(dist){ list-style-image: url("chrome://sciviewsk/skin/images/dist.png"); }
+treechildren::-moz-tree-image(ts){ list-style-image: url("chrome://sciviewsk/skin/images/ts.png"); }
+treechildren::-moz-tree-image(function){ list-style-image: url("chrome://sciviewsk/skin/images/function.png"); }
+treechildren::-moz-tree-image(list){ list-style-image: url("chrome://sciviewsk/skin/images/list.png"); }
+treechildren::-moz-tree-image(factor){ list-style-image: url("chrome://sciviewsk/skin/images/factor.png"); }
+treechildren::-moz-tree-image(logical){ list-style-image: url("chrome://sciviewsk/skin/images/logical.png"); }
Added: komodo/SciViews-K/templates/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/templates/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/templates/All Languages/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/templates/All Languages/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/templates/All Languages/R.R
===================================================================
Added: komodo/SciViews-K/templates/Common/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/templates/Common/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K/templates/Common/R S3 object.R
===================================================================
--- komodo/SciViews-K/templates/Common/R S3 object.R (rev 0)
+++ komodo/SciViews-K/templates/Common/R S3 object.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,40 @@
+# S3 object: [[%ask1:Class]]
+# Author: [[%ask:Author]]
+
+# Creator or the S3 object (usually, a function with the same name)
+"[[%ask1]]"
+<- function() {
+ # Code to create the object here...
+ obj <- "[[%ask1]] object"
+ class(obj) <- [[%ask1]]
+ return(obj)
+
+}
+
+# Print method
+"print.[[%ask1]]"
+<- function(x, ...) {
+ # Code to print the object here...
+ cat ("[[%ask1]] object printed\n")
+ return(invisible(x))
+}
+
+# Summary method
+"summary.[[%ask1]]" <-
+function(object, ...)
+ structure(object, class = c("summary.[[%ask1]]", class(object)))
+
+"print.summary.[[%ask1]]" <-
+function(x, ...) {
+ # Code to print the summary of the object here...
+ cat ("[[%ask1]] object summarized\n")
+ return(invisible(x))
+}
+
+# Plot method
+"plot.[[%ask1]]"
+<- function(x, ...) {
+ # Code to plot the object here...
+ cat ("[[%ask1]] object plotted\n")
+ invisible()
+}
\ No newline at end of file
Added: komodo/SciViews-K/templates/Common/R.R
===================================================================
Added: komodo/SciViews-K/toolbox/SciViews-K 0.6.0.kpz
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K/toolbox/SciViews-K 0.6.0.kpz
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/SciViews-K Unit.kpf
===================================================================
--- komodo/SciViews-K Unit/SciViews-K Unit.kpf (rev 0)
+++ komodo/SciViews-K Unit/SciViews-K Unit.kpf 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Komodo Project File - DO NOT EDIT -->
+<project id="5434d89d-0d44-ff4a-a625-44da4954f8fc" kpf_version="4" name="SciViews-K Unit.kpf">
+<folder id="83d0643f-3826-d844-9c15-d9b56bcd3359" idref="5434d89d-0d44-ff4a-a625-44da4954f8fc" name="Project">
+</folder>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/brick.png" id="00a422ad-498a-db4f-8807-1dd82ba5713e" idref="83d0643f-3826-d844-9c15-d9b56bcd3359" keyboard_shortcut="" language="JavaScript" name="extension_lib" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+try {
+
+var extensionLib = function() {
+ this.os = Components.classes['@activestate.com/koOs;1'].
+ getService(Components.interfaces.koIOs);
+ this.error = false;
+}
+
+extensionLib.prototype.getPath = function(relative) {
+ try {
+ var prj_path = ko.interpolate.interpolateStrings('%p');
+ path = this.os.path.join(prj_path, relative);
+ return path;
+ } catch(e) {
+ alert(e+"\narg name: "+name);
+ }
+}
+
+extensionLib.prototype.readFile = function(filename) {
+ // read the template file
+ try {
+ var fileEx = Components.classes["@activestate.com/koFileEx;1"]
+ .createInstance(Components.interfaces.koIFileEx);
+ fileEx.URI = filename;
+ fileEx.open('rb');
+ var content = fileEx.readfile();
+ fileEx.close();
+ return content;
+ } catch(e) {
+ alert(e+"\narg filename: "+filename);
+ }
+}
+
+extensionLib.prototype.writeFile = function(filename, content) {
+ try {
+ var fileEx = Components.classes["@activestate.com/koFileEx;1"]
+ .createInstance(Components.interfaces.koIFileEx);
+ fileEx.URI = filename;
+ fileEx.open('wb+');
+ fileEx.puts(content);
+ fileEx.close();
+ } catch(e) {
+ alert(e+"\narg filename: "+filename);
+ }
+}
+
+extensionLib.prototype.getRdfVars = function(txt) {
+ try {
+ var Rx = /\<em\:([\w]+)[\ \S]*\>([\S\ ]+?)\<\//g;
+ var ext_vars = {};
+ while(results = Rx.exec(txt)) {
+ var idRx = /type|min|max|\{/;
+ if(!idRx.test(results[0])) { // filter out stuff we don't want
+ ext_vars[results[1]] = results[2];
+ }
+ }
+ return ext_vars;
+ } catch(e) {
+ alert(e+"\narg rdf_path: "+rdf_path);
+ }
+}
+
+extensionLib.prototype.getManifestVars = function(txt) {
+ try {
+ var rx1 = /content ([\S]+?) jar\:([\S]+?)\.jar/g;
+ var res1 = rx1.exec(txt);
+ var rx2 = /chrome:\/\/([\S]+?)\/content\/overlay\.xul/g;
+ var res2 = rx2.exec(txt);
+ return new Array(res1[1], res1[2], res2[1]);
+ } catch(e) {
+ alert(e+"\narg path: "+path);
+ }
+}
+
+extensionLib.prototype.getOverlayVars = function(txt) {
+ try {
+ var rx1 = /<overlay id="([\S]+?)"/g;
+ var res1 = rx1.exec(txt);
+ var rx2 = /<menuitem id="([\S]+?)"[\s]+?label="([\S\ ]+?)"/g;
+ var res2 = rx2.exec(txt);
+ return [res1[1], res2[1], res2[2]];
+ } catch(e) {
+ alert(e+"\narg path: "+path);
+ }
+}
+
+extensionLib.prototype.updateProject = function(vars) {
+ try {
+ var overlayPath = this.getPath('content/overlay.xul');
+ if(this.os.path.exists(overlayPath)) {
+ var ovl_str = this.readFile(overlayPath);
+ var ov_vars = this.getOverlayVars(ovl_str);
+ var ovl_new = [vars.ext_name+'Overlay', 'menu_'+vars.ext_name, vars.name];
+ this.writeFile(overlayPath, this.replaceAll(ov_vars, ovl_new, ovl_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ var manifestPath = this.getPath('chrome.manifest');
+ if(this.os.path.exists(manifestPath)) {
+ var man_str = this.readFile(manifestPath);
+ var man_vars = this.getManifestVars(man_str);
+ var man_new = [vars.ext_name, vars.ext_name, vars.ext_name];
+ this.writeFile(manifestPath, this.replaceAll(man_vars, man_new, man_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ var rdf_path = this.getPath('install.rdf');
+ if(this.os.path.exists(rdf_path)) {
+ var rdf_str = this.readFile(rdf_path);
+ var rdf_vars = this.getRdfVars(rdf_str);
+ this.writeFile(rdf_path, this.replaceAll(rdf_vars, vars, rdf_str));
+ } else { this.error = "Doesn't exist: "+overlayPath; return false; }
+
+ } catch(e) {
+ this.error = e;
+ return false;
+ }
+ return true;
+}
+
+extensionLib.prototype.replaceAll = function(orig_vars, new_vars, str) {
+ try {
+ var out = str;
+ for(v in orig_vars) {
+ out = out.replace(orig_vars[v], new_vars[v]);
+ }
+ return out;
+ } catch(e) {
+ alert(e);
+ }
+}
+
+extensionLib.prototype.getNiceName = function(name) {
+ return this.trim(name).replace(/[\W]/g,'').toLowerCase();
+}
+
+extensionLib.prototype.trim = function(str) {
+ return str.replace(/^\s*/, '').replace(/\s*$/, '');
+}
+
+extensionLib.prototype.clone = function(obj) {
+ var newobj = {}; for(i in obj) {
+ newobj[i] = obj[i];
+ } return newobj;
+}
+
+extensionLib.prototype._dump = function(obj) {
+ var str = ''; for(i in obj) {
+ str += i+': '+obj[i]+'\n';
+ } return(str);
+}
+
+extensionLib.prototype._keys = function(obj) {
+ var out = new Array(); for(i in obj) {
+ out.push(i);
+ } return out;
+}
+
+} catch(e) {
+ allert(e);
+}
+</macro>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/lightning_go.png" id="163bfade-9e58-9849-b2f9-90f6f6a4d017" idref="83d0643f-3826-d844-9c15-d9b56bcd3359" keyboard_shortcut="" language="JavaScript" name="Build" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+/**
+ * Script to build an xpi, running koext build in the current project root.
+ */
+
+var project = ko.macros.current.project;
+
+var os = Components.classes['@activestate.com/koOs;1'].
+ getService(Components.interfaces.koIOs);
+
+var koSysUtils = Components.classes["@activestate.com/koSysUtils;1"].
+ getService(Components.interfaces.koISysUtils);
+
+var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
+ getService(Components.interfaces.nsIXULRuntime);
+
+var koDirs = Components.classes['@activestate.com/koDirs;1'].
+ getService(Components.interfaces.koIDirs);
+
+var pythonExe = koDirs.pythonExe;
+var projectDir = ko.interpolate.interpolateStrings('%p');
+var scriptName = 'koext';
+
+if (appInfo.OS == 'WINNT') {
+ scriptName += ".py";
+}
+
+var arr = [koDirs.sdkDir, 'bin', scriptName]
+var app = os.path.joinlist(arr.length, arr);
+var cmd = '"'+pythonExe+'" "'+app+'" build -d "'+projectDir+'"';
+
+if (appInfo.OS == 'WINNT') {
+ cmd = '"' + cmd + '"';
+}
+var cwd = koDirs.mozBinDir;
+cmd += " {'cwd': u'"+cwd+"'}";
+
+ko.run.runEncodedCommand(window, cmd, function() {
+ ko.statusBar.AddMessage('Build complete', 'projects', 5000, true);
+ ko.projects.manager.saveProject(project);
+});
+</macro>
+<macro async="0" icon="chrome://famfamfamsilk/skin/icons/wrench.png" id="641fcb73-4b02-a343-bb92-e6b80641a44f" idref="83d0643f-3826-d844-9c15-d9b56bcd3359" keyboard_shortcut="" language="JavaScript" name="Configure" rank="100" trigger="trigger_postopen" trigger_enabled="0">
+try {
+
+var libPart = ko.projects.findPart('macro', 'extension_lib', 'container');
+eval(libPart.value);
+
+var koExt = new extensionLib();
+
+var project = ko.macros.current.project;
+
+var setupWin = project.getChildByAttributeValue('name','setup.xul', 1);
+var rdf = project.getChildByAttributeValue('name','install.rdf', 1);
+var data = {};
+
+var prefset = project.prefset;
+
+if(prefset.hasPrefHere('configured')) {
+ var rdf_xml = koExt.readFile(rdf.getFile().URI);
+ data = {
+ 'valid': false,
+ 'configured': true,
+ 'vars': koExt.getRdfVars(rdf_xml)
+ };
+ data.vars['ext_name'] = koExt.getNiceName(data.vars.name);
+} else { // init data
+ data = {
+ 'valid': false,
+ 'configured': false,
+ 'vars': {
+ 'id': '',
+ 'name': 'My Extension',
+ 'creator': 'Me',
+ 'version': '0.1',
+ 'description': '',
+ 'homepageURL': '',
+ 'ext_name': ''
+ }
+ };
+}
+
+window.openDialog(
+ setupWin.getFile().URI,
+ "_blank",
+ "centerscreen,chrome,resizable,scrollbars,dialog=no,close,modal=yes",
+ data
+);
+
+if(data.valid) {
+ if(koExt.updateProject(data.vars)) {
+ prefset.setBooleanPref('configured', true);
+ var part = project.getChildByAttributeValue('name', 'oncreate',1);
+ if(part) { part.name = 'Configure'; }
+ var msg = 'Extension Project '+data.vars.name+' configured!';
+ ko.statusBar.AddMessage(msg, 'project', 3000, true);
+ ko.projects.manager.saveProject(project);
+ } else {
+ alert('Error encountered: '+koExt.error+"\nConfiguration aborted.");
+ }
+}
+
+} catch(e) {
+ alert(e);
+}
+</macro>
+<file id="8aa93793-645c-7f4a-90f0-57ccdcbfd449" idref="83d0643f-3826-d844-9c15-d9b56bcd3359" name="setup.xul" url="_prj_internal_/setup.xul">
+</file>
+<preference-set idref="5434d89d-0d44-ff4a-a625-44da4954f8fc">
+ <boolean id="configured">1</boolean>
+ <string id="import_exclude_matches">*.*~;*.bak;*.tmp;CVS;.#*;*.pyo;*.pyc;.svn;*%*;tmp*.html;.DS_Store;_prj_internal_</string>
+ <string id="import_include_matches"></string>
+ <boolean id="import_live">1</boolean>
+ <boolean id="import_recursive">1</boolean>
+ <string id="import_type">useFolders</string>
+</preference-set>
+</project>
Added: komodo/SciViews-K Unit/_prj_internal_/setup.xul
===================================================================
--- komodo/SciViews-K Unit/_prj_internal_/setup.xul (rev 0)
+++ komodo/SciViews-K Unit/_prj_internal_/setup.xul 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,167 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/" type="text/css"?>
+
+<dialog
+ id="test"
+ title="Komodo Extension configuration"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="setup()"
+ width="400px"
+ height="480px"
+ buttons="accept,cancel"
+ buttonlabelcancel="Cancel"
+ buttonlabelaccept="Save"
+ ondialogaccept="return teardown();"
+ ondialogcancel="return cancel();"
+ defaultButton="accept"
+ buttonalign="horizontal"
+ buttonorient="horizontal"
+ orient="vertical"
+ >
+
+<script type="application/x-javascript">
+<![CDATA[
+
+var data = {};
+var ext_name = '';
+
+function get_id(strId) { return document.getElementById(strId); }
+function get_val(strId) { return get_id(strId).value; }
+function set_val(strId, val) { get_id(strId).value = val; }
+function get_nice_name(name) { return trim(name).replace(/[\W]/g,'').toLowerCase(); }
+function trim(str) { return str.replace(/^\s*/, '').replace(/\s*$/, ''); }
+function _dump(obj) {
+ try{
+ var str = ''; for(i in obj) {
+ str += i+': '+obj[i]+'\n';
+ }
+ } catch(e) {alert(e);}
+ return str;
+}
+
+function setup() {
+ try {
+ if(typeof(window.arguments) == 'undefined') {
+ alert('Error: No Window arguments?');
+ } else {
+ data = window.arguments[0];
+ var vars = data.vars;
+ for(i in vars) {
+ if(i == 'id' || i == 'ext_name') {
+ //pass
+ } else {
+ set_val(i, vars[i]);
+ }
+ }
+ if(vars['id']) {
+ var arr = vars.id.split('@');
+ if(arr.length < 2) {
+ alert('Extension Id is not in the correct format?');
+ return;
+ }
+ set_val('author-domain', arr[1]);
+ }
+ update_id();
+ if(!data.vars['homepageUrl']) {
+ update_url();
+ }
+ }
+ } catch(e) { alert(e); }
+}
+
+function update_url() {
+ var domain = get_id('author-domain').value;
+ var ext_name = get_nice_name(get_val('name'));
+ set_val('homepageURL', 'http://'+domain+'/'+ext_name);
+}
+
+function update_id() {
+ try {
+ var name = get_val('name');
+ data.vars.ext_name = get_nice_name(name);
+
+ var domain = get_id('author-domain').value;
+ var newId = data.vars.ext_name+'@'+domain;
+
+ get_id('id').value = newId;
+ } catch(e) {
+ alert(e);
+ }
+}
+
+function teardown() {
+ try {
+ for(i in data.vars) {
+ if(i != 'ext_name') {
+ data.vars[i] = get_val(i);
+ }
+ }
+ data.vars.ext_name = get_nice_name(data.vars.name);
+ data.valid = true;
+ data.configured = true;
+ window.close();
+ } catch(e) {
+ alert(e);
+ }
+}
+
+function cancel() {
+ return confirm('Cancel Configuration?');
+}
+
+function keys(obj) {
+ var out = new Array(); for(i in obj) {
+ out.push(i);
+ } return out;
+}
+
+]]>
+</script>
+
+
+<commandset id="koext_commands">
+ <command id="update_id" oncommand="update_id();"/>
+</commandset>
+
+<vbox flex="1">
+ <caption label="Extension Options"/>
+ <grid flex="1">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="Name:"/>
+ <textbox id="name" type="timed" timeout="1000" command="update_id"/>
+ </row>
+ <row align="center">
+ <label value="Version:"/>
+ <textbox id="version"/>
+ </row>
+ <row align="top">
+ <label value="Description:"/>
+ <textbox id="description" multiline="true" value=""/>
+ </row>
+ <row align="center">
+ <label value="Author:"/>
+ <textbox id="creator" value=""/>
+ </row>
+ <row align="center">
+ <label value="Domain:"/>
+ <textbox id="author-domain" value="yourdomain.org" type="timed" timeout="1000" command="update_id"/>
+ </row>
+ <row align="center">
+ <label value="Home Page:"/>
+ <textbox id="homepageURL" value=""/>
+ </row>
+ <row align="center">
+ <label value="Extension Id:"/>
+ <label style="font-weight: bolder;" id="id"/>
+ </row>
+ </rows>
+ </grid>
+</vbox>
+
+</dialog>
Added: komodo/SciViews-K Unit/chrome.manifest
===================================================================
--- komodo/SciViews-K Unit/chrome.manifest (rev 0)
+++ komodo/SciViews-K Unit/chrome.manifest 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,7 @@
+content sciviewskunit jar:sciviewskunit.jar!/content/ xpcnativewrappers=yes
+overlay chrome://komodo/content/komodo.xul chrome://sciviewskunit/content/overlay.xul
+
+locale sciviewskunit en-GB jar:sciviewskunit.jar!/locale/en-GB/
+locale sciviewskunit fr-FR jar:sciviewskunit.jar!/locale/fr-FR/
+
+skin sciviewskunit classic/1.0 jar:sciviewskunit.jar!/skin/
\ No newline at end of file
Added: komodo/SciViews-K Unit/content/js/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/content/js/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/content/js/sciviewskunit.js
===================================================================
--- komodo/SciViews-K Unit/content/js/sciviewskunit.js (rev 0)
+++ komodo/SciViews-K Unit/content/js/sciviewskunit.js 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,706 @@
+// SciViews-K R unit functions
+// Define the 'sv.r.unit' namespace
+// Copyright (c) 2008, Philippe Grosjean
+
+////////////////////////////////////////////////////////////////////////////////
+// sv.r.unit.version // Version of the svUnit R package it was designed for
+// sv.r.unit.release; // The release (bug fixes). Full version is "version.release"
+//
+// sv.r.unit.getRUnitList(); // Get the list of available units
+// sv.r.unit.showRUnitList(); // Show/hide the unit list
+// sv.r.unit.setAutoTest(state); // Change autoTest on/off
+// sv.r.unit.isAutoTest(); // Is it currently in autoTest mode?
+// sv.r.unit.autoTest(); // autoTest on/off, not supposed to be called directly
+// sv.r.unit.runTest(); // Run the R test suite
+// sv.r.unit.runTest_feedback(data); // Feedback during run of the R test suite
+// sv.r.unit.runTest_finished(data); // The test suite is done in R
+// sv.r.unit.showRUnitPane(); // Show the R Unit pane
+// sv.r.unit.jumpToObject(event); // Go to the corresponding object (user event)
+// sv.r.unit.fillInTooltip(event); // Change the tooltip content (user event)
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// TODO:
+// * Modify FileObserver to use run tests only if a R file changes (or even only
+// if R code is loaded in R, or a R package is installed!)
+// * In AutoMode, also trigger test units when something is submitted to R
+// * Allow for progression indication using sv.r.runTest_feedback()
+// * Bug: arrows in the tree do not change their orientation when nodes are
+// opened or closed
+// * Autoinstallation of the -ko.xpi and version checking when the svUnit R
+// package is loaded in R
+// * Finalize localization
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// Make sure that 'sv.r' is defined, i.e., the SciViews-K extension is loaded
+if (typeof(sv.r) == 'undefined') {
+ alert("You must install the SciViews-K extension to use SciViews-K Unit! Visit http://www.sciviews.org/SciViews-K to download it.")
+} else {
+
+// Define the 'sv.r.unit' namespace
+if (typeof(sv.r.unit) == 'undefined') sv.r.unit = {
+ version: 0.6,
+ release: 0,
+ debug: true
+};
+
+(function() { // 'sv.r.unit' namespace inside closure
+
+ var DEACTIVATED = 0;
+ var PASS = 1;
+ var FAIL = 2;
+ var ERROR = 3;
+
+ var CELLTEXT = 0;
+ var LEVEL = 1;
+ var ERRORTYPE = 2;
+ var ERRORTEXT = 3;
+ var OPEN = 4;
+ var PARENT = 5;
+ var ID = 6;
+ var URI = 7;
+
+ var gUnitTestRunning = false;
+ var gUnitTreeObject = null;
+ var gFileObserver = new _FileObserver();
+ var gPrefSvc = Components.classes["@activestate.com/koPrefService;1"].
+ getService(Components.interfaces.koIPrefService);
+
+ var gUnitList = [];
+ var gOldUnitList = [];
+ var gUnitListSelected = [];
+
+ this.showRUnitList = function() {
+ var splitter = document.getElementById("svunit_splitter");
+ var state = splitter.getAttribute("state");
+ if (state == "collapsed") {
+ state = "open";
+ this.getRUnitList();
+ } else {
+ state = "collapsed";
+ }
+ splitter.setAttribute("state", state);
+ }
+
+ this.getRUnitList = function() {
+ // TODO: a more sophisticated process looking (1) if svUnit R package
+ // is installed, and (2) if its version is correct. If not, propose to
+ // install or update it!
+ sv.r.evalHidden('require(svUnit, quietly = TRUE)', false); // Make sure svUnit is loaded
+ var cmd = 'cat(guiSuiteList(sep = ",", compare = FALSE))';
+ sv.r.evalCallback(cmd, sv.r.unit.getRUnitList_Callback);
+ }
+
+ this.getRUnitList_Callback = function(data) {
+ gUnitList = [];
+ if (data != "")
+ gUnitList = data.replace(/[\n\r]/g, "").split(/,/);
+ // Add unit tests in currently edited packages
+ // TODO: add items from all opened projects, not just active one
+ var numfiles = new Object();
+ var projfiles = new Array();
+ var project = ko.projects.manager.getCurrentProject();
+ if (project != null) {
+ project.getAllContainedURLs(projfiles, numfiles);
+ var files = projfiles.value;
+ for (var i=0; i<numfiles.value; i++) {
+ if (files[i].slice(0, 4) == "runit" &&
+ (files[i].slice(-2) == '.r' ||
+ files[i].slice(-2) == '.R'))
+ gUnitList.push("dir:" + files[i]);
+ }
+ }
+ // Display the unit list
+ var unit;
+ var node = document.getElementById("svunit_unitlist_listbox");
+ sv.tools.e4x2dom.clear(node);
+ var item;
+ var k = 0;
+ var checked = "false";
+ for(var i = 0; i < gUnitList.length; i++) {
+ unit = gUnitList[i];
+ if (isSelected(unit)) {
+ ischecked = "true";
+ if (!isInOldList(unit))
+ gOldUnitList[gOldUnitList.length] = unit; // Add it
+ } else if (isInOldList(unit)) {
+ ischecked = "false";
+ } else { // New items are automatically added to selected items
+ ischecked = "true";
+ gUnitListSelected[gUnitListSelected.length] = unit;
+ gOldUnitList[gOldUnitList.length] = unit;
+ }
+ item =
+ <listitem type="checkbox" label={unit} checked={ischecked}
+ onclick="sv.r.unit.unitSelect(event);"
+ spid={unit}
+ />;
+ sv.tools.e4x2dom.append(item, node, k);
+ k++;
+ }
+ }
+
+ this.unitSelect = function(event) {
+ var cb = event.target;
+ var status = cb.checked;
+ var unit = cb.getAttribute("spid");
+ if (status) {
+ if (!isSelected(unit)) {
+ gUnitListSelected[gUnitListSelected.length] = unit;
+ }
+ } else {
+ if (isSelected(unit)) {
+ sv.tools.array.remove(gUnitListSelected, unit);
+ }
+ }
+ }
+
+ function isSelected(unit) {
+ return(sv.tools.array.contains(gUnitListSelected, unit));
+ }
+
+ function isInOldList(unit) {
+ return(sv.tools.array.contains(gOldUnitList, unit));
+ }
+
+ this.setAutoTest = function(state) {
+ var autoTestButton = document.getElementById('svunit-auto-tests-button');
+ if (autoTestButton.checked != state) {
+ autoTestButton.checked = state;
+ this.autoTest();
+ }
+ }
+
+ this.isAutoTest = function() {
+ var autoTestButton = document.getElementById('svunit-auto-tests-button');
+ return(autoTestButton.checked);
+ }
+
+ this.autoTest = function() {
+ try {
+ var autoTestButton = document.getElementById('svunit-auto-tests-button');
+ var runTestsButton = document.getElementById('svunit-run-tests-button');
+ //runTestsButton.disabled = autoTestButton.checked;
+ if (autoTestButton.checked) {
+ gUnitTestRunning = false; // Reset testing flag TODO: what if test is running?
+ gFileObserver.addObserver();
+ this.runTest();
+ } else {
+ gFileObserver.removeObserver();
+ }
+ gPrefSvc.prefs.setBooleanPref("svunitAutoTest", autoTestButton.checked);
+ } catch (e) {
+ alert(e);
+ }
+ }
+
+ this.runTest = function () {
+ if (!gUnitTestRunning) {
+ try {
+ // Determine, among select test, which one are in the current list
+ var Selected = [];
+ k = 0;
+ for (var i = 0; i < gUnitList.length; i++) {
+ if (sv.tools.array.contains(gUnitListSelected, gUnitList[i])) {
+ Selected[k] = gUnitList[i];
+ k += 1;
+ }
+ }
+ if (Selected.length == 0) {
+ // If not autotest, issue a warning
+ ko.statusBar.AddMessage("No test selected. Do '?svUnit' in R to learn how to create tests...", "svUnit", 2000, true);
+ return;
+ }
+ // Start running the tests
+ gUnitTestRunning = true;
+ // Update the GUI
+ var pass_label = document.getElementById('svunit-pass-label');
+ pass_label.value = "Pass: -"
+ var fail_label = document.getElementById('svunit-fail-label');
+ fail_label.value = "Fail: -"
+ var error_label = document.getElementById('svunit-error-label');
+ error_label.value = "Errors: -"
+ var deact_img = document.getElementById('svunit-deactivated-image');
+ deact_img.setAttribute("tooltiptext", "");
+ deact_img.src = "";
+ var statusbar_pane = document.getElementById('statusbar-svunit');
+ statusbar_pane.src = "chrome://famfamfamsilk/skin/icons/hourglass.png";
+ statusbar_pane.setAttribute("tooltiptext", "R Unit Status: running");
+ var progressbar = document.getElementById('svunit-progress-bar');
+ progressbar.style.backgroundColor = "#E6E6E6";
+ // Collect together selected tests and run them
+ var cmd = 'require(svUnit, quietly = TRUE); createLog(deleteExisting = TRUE); runTest(svSuite(c("'
+ cmd = cmd + Selected.join('", "')
+ cmd = cmd + '")), name = "objects"); cat(guiTestReport(Log()))'
+// if (this.debug) alert("'" + cmd + "'");
+ var res = sv.r.evalCallback(cmd, sv.r.unit.runTest_finished);
+ ko.statusBar.AddMessage("R unit test started", "svUnit", 1000, true);
+ } catch(e) {
+ alert(e);
+ }
+ }
+ }
+
+ this.runTest_feedback = function(data) {
+ gUnitTestRunning = true;
+ // TODO: provide feedback about tests execution
+ }
+
+ this.runTest_finished = function(data) {
+ try {
+ ko.statusBar.AddMessage("", "svUnit");
+ gUnitTestRunning = false;
+
+ if (this.debug) { // For debugging purposes
+ gUnitData = data;
+ }
+
+ if (sv.tools.strings.removeLastCRLF(data) != "" &&
+ gUnitTreeObject) {
+ var items = data.split("\t");
+ var item = [];
+ var tests = [];
+ var nPass = 0;
+ var nFail = 0;
+ var nError = 0;
+ var nDeactivated = 0;
+ var k = 0;
+ for (var i = 0; i < items.length; i++) {
+ item = items[i].split("|||")
+ // svUnit items start with '<<<svUnit'
+ if (item[0] == "<<<svUnitSummary>>>") {
+ nPass = item[1];
+ nFail = item[2];
+ nError = item[3];
+ nDeactivated = item[4];
+ } else if (item[0] == "<<<svUnitFile>>>") {
+ // TODO: create a new file node
+ } else if (item[0] == "<<<svUnitTest>>>") {
+ tests[k] = item;
+ k += 1;
+ }
+ }
+ // Update the tree
+ gUnitTreeObject.UnitTreeView.loadTests(tests);
+ // Update the GUI
+ var pass_label = document.getElementById('svunit-pass-label');
+ pass_label.value = "Pass: " + nPass
+ var fail_label = document.getElementById('svunit-fail-label');
+ fail_label.value = "Fail: " + nFail
+ var error_label = document.getElementById('svunit-error-label');
+ error_label.value = "Errors: " + nError
+ var deact_img = document.getElementById('svunit-deactivated-image');
+ if (nDeactivated == 0) {
+ deact_img.setAttribute("tooltiptext", "");
+ deact_img.src = "";
+ } else if (nDeactivated == 1) {
+ deact_img.setAttribute("tooltiptext", "Warning: " +
+ nDeactivated + " test is deactivated!");
+ deact_img.src = "chrome://famfamfamsilk/skin/icons/help.png";
+ } else {
+ deact_img.setAttribute("tooltiptext", "Warning: " +
+ nDeactivated + " tests are deactivated!");
+ deact_img.src = "chrome://famfamfamsilk/skin/icons/help.png";
+ }
+ // Update bar in test pane
+ var progressbar = document.getElementById('svunit-progress-bar');
+ if (nFail > 0 || nError > 0)
+ progressbar.style.backgroundColor = "#C00000";
+ else
+ progressbar.style.backgroundColor = "#008000";
+ // update icon in statusbar
+ var statusbar_pane = document.getElementById('statusbar-svunit');
+ if (nError > 0) {
+ statusbar_pane.src = "chrome://famfamfamsilk/skin/icons/delete.png";
+ statusbar_pane.setAttribute("tooltiptext", "R Unit Status: error (" + nError + ")");
+ } else if (nFail > 0) {
+ statusbar_pane.src = "chrome://famfamfamsilk/skin/icons/error.png";
+ statusbar_pane.setAttribute("tooltiptext", "R Unit Status: fail (" + nFail + ")");
+ } else {
+ statusbar_pane.src = "chrome://famfamfamsilk/skin/icons/accept.png";
+ statusbar_pane.setAttribute("tooltiptext", "R Unit Status: ok");
+ }
+ }
+ } catch(e) {
+ alert(e);
+ }
+ }
+
+ this.showRUnitPane = function(state) {
+ if (state == null) {
+ // Toggle RUnit pane
+ ko.uilayout.togglePane('workspace_right_splitter',
+ 'right_toolbox_tabs', 'cmd_viewRightPane');
+ if (ko.uilayout.isPaneShown(document.getElementById('right_toolbox_tabs'))) {
+ // Make the R Unit tab the current tab that is shown
+ ko.uilayout.ensureTabShown("sciviews_svunit_tab", false);
+ }
+ } else if (state == true) {
+ // Make sure the R Unit tab is displayed
+ ko.uilayout.ensureTabShown("sciviews_svunit_tab", false);
+ } else {
+ if (ko.uilayout.isPaneShown(document.getElementById('right_toolbox_tabs'))) {
+ // Hide the R Unit tab
+ ko.uilayout.togglePane('workspace_right_splitter',
+ 'right_toolbox_tabs', 'cmd_viewRightPane');
+ }
+ }
+ }
+
+ function getRowForEvent(event) {
+ var row = new Object();
+ var colId = new Object();
+ var child = new Object();
+ var tree = document.getElementById('svunit_tree');
+ var boxObject = tree.boxObject;
+ boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
+ boxObject.getCellAt(event.clientX, event.clientY, row, colId, child);
+ return row.value;
+ }
+
+ this.jumpToObject = function(event) {
+ try {
+ var row = getRowForEvent(event);
+ var view = gUnitTreeObject.UnitTreeView;
+ if (!view.rows[row] ||
+ view.getChildren(row).length > 0) {
+ event.stopPropagation();
+ event.preventDefault();
+ event.cancelBubble = true;
+ }
+ if (view.rows[row][URI] && view.rows[row][URI] != ""
+ && view.getChildren(row).length == 0) {
+ var urilist = view.rows[row][URI].split("#");
+ // Look at urilist[1]: number => goto line, name => search for it
+ if (urilist[1]) {
+ if (parseInt(urilist[1]) > 0) { // Goto line...
+ gViewMgr.doFileOpenAtLine(urilist[0], urilist[1], 'editor');
+ } else { // Look for the function in the file
+ gViewMgr.doFileOpenAtLine(urilist[0], 1, 'editor');
+ var FindService = Components.classes['@activestate.com/koFindService;1'].
+ getService(Components.interfaces.koIFindService);
+ var FindContext = Components.classes['@activestate.com/koFindContext;1'].
+ createInstance(Components.interfaces.koIFindContext);
+ var FindSession = Components.classes['@activestate.com/koFindSession;1'].
+ getService(Components.interfaces.koIFindSession);
+ var FindOptions = FindService.options;
+ FindContext.type = FindOptions.preferredContextType;
+ FindOptions.patternType = FindOptions.FOT_REGEX_PYTHON;
+ FindOptions.searchBackward = false;
+ var FindPattern = urilist[1].replace(/[\n\r]/g, "") + '("|\'|`)?\\s*(<-|=)';
+ Find_FindNext(window, FindContext, FindPattern,
+ 'find', true, false);
+ }
+ } else {
+ gViewMgr.doFileOpen(urilist[0].replace(/[\n\r]/g, ""), 'editor');
+ }
+ var kv = ko.views.manager.currentView;
+ kv.setFocus();
+ kv.scimoz.homeDisplay();
+ }
+ }
+ catch (e) {
+ alert(e);
+ }
+ }
+
+ function fillInTooltip(event) {
+ try {
+ var row = getRowForEvent(event);
+ var tip = document.getElementById('svunit-tooltip');
+ var tree = document.getElementById('svunit_tree');
+ var view = gUnitTreeObject.UnitTreeView;
+ if (!view.rows[row] || view.getChildren(row).length > 0) {
+ event.stopPropagation();
+ event.preventDefault();
+ event.cancelBubble = true;
+ return false;
+ }
+ var etext = view.rows[row][ERRORTEXT];
+ var elist = etext.split('\n');
+ var textholder = document.getElementById('svunit-tooltip-container');
+ while (textholder.hasChildNodes())
+ textholder.removeChild(textholder.firstChild);
+ for (var i=0; i<elist.length; i++) {
+ var descriptionNode = document.createElement("description");
+ var linetext = document.createTextNode(elist[i]);
+ descriptionNode.appendChild(linetext);
+ textholder.appendChild(descriptionNode);
+ }
+ tip.setAttribute('style','height: 0px');
+ tip.showPopup(tree,event.clientX,event.clientY,
+ 'tooltip',"topleft","topleft");
+ var box = document.getBoxObjectFor(textholder);
+ tip.setAttribute('style','height: '+ box.height + 'px');
+ } catch (e) {
+ alert(e);
+ return false;
+ }
+ return true;
+ }
+
+ // File observer used to trigger tests of file/project changed
+ function _FileObserver() {
+ this.obsSvc = Components.classes["@mozilla.org/observer-service;1"].
+ getService(Components.interfaces.nsIObserverService);
+ this.added = false;
+ }
+
+ _FileObserver.prototype.constructor = _FileObserver;
+
+ _FileObserver.prototype.addObserver = function() {
+ if (!this.added) {
+ this.obsSvc.addObserver(this, "file_changed", false);
+ // this.obsSvc.addObserver(this, "file_project", false);
+ // this.obsSvc.addObserver(this, "current_project_changed", false);
+ this.added = true;
+ }
+ }
+
+ _FileObserver.prototype.removeObserver = function() {
+ if (this.added) {
+ this.obsSvc.removeObserver(this, "file_changed");
+ // this.obsSvc.removeObserver(this, "file_project");
+ // this.obsSvc.removeObserver(this, "current_project_changed");
+ this.added = false;
+ }
+ }
+
+ _FileObserver.prototype.finalize = function() {
+ this.removeObserver();
+ }
+
+ _FileObserver.prototype.observe = function(subject, topic, data) {
+ try {
+ if (topic == "file_changed") {
+ // If an R source file is changed; if auto mode, source it...
+ if (data.substr(-2, 2).toUpperCase() == ".R" &
+ sv.r.unit.isAutoTest()) {
+ // If data starts with "file://", eliminate this
+ if (data.substr(0, 7) == "file://")
+ data = data.substr(7);
+ sv.r.eval('source("' + data + '")');
+ // ... then, run the selected test
+ sv.r.unit.runTest();
+ }
+ }
+ } catch(e){
+ alert(e);
+ }
+ }
+
+ // Custom tree view for displaying tests performed by svUnit
+ function _UnitTreeView() {
+ this._debug = 0;
+ this._showHidden = false;
+ this.rows = [];
+ this.testItems = [];
+ }
+
+ _UnitTreeView.prototype = {
+ // The nsITreeView object for the tree view
+ getCellText : function(row, column) {
+ return this.rows[row][CELLTEXT];
+ },
+ get rowCount() { return this.rows.length; },
+
+ // Everything below here is just to satisfy the interface, and not all
+ // of it may be required
+ tree : null,
+ getLevel: function(row) {
+ return this.rows[row][LEVEL];
+ },
+ setTree : function(out) { this.tree = out; },
+ getRowProperties : function(row,prop) {},
+ getColumnProperties : function(column,prop){},
+ getCellProperties : function(row,column,props) {},
+ cycleCell: function(row, colId) {},
+ selectionChanged : function() {},
+ performAction : function(action) {},
+ isSorted : function() { return false; },
+ getImageSrc : function(row, col) {
+ var errorType = parseInt(this.rows[row][ERRORTYPE]);
+ if (errorType == PASS)
+ return "chrome://famfamfamsilk/skin/icons/bullet_green.png";
+ else if (errorType == FAIL)
+ return "chrome://famfamfamsilk/skin/icons/bullet_error.png";
+ else if (errorType == ERROR)
+ return "chrome://famfamfamsilk/skin/icons/bullet_delete.png";
+ else if (errorType == DEACTIVATED)
+ return "chrome://famfamfamsilk/skin/icons/bullet_white.png";
+ return null;
+ },
+ cycleHeader : function() {},
+ isSeparator : function(row) { return false; },
+
+ // Multi level tree functions
+ getParentIndex: function(row) {
+ return this.rows[row][PARENT];
+ },
+ isContainer : function(row) { return this.getChildren(row).length > 0; },
+ isContainerOpen: function(row) { return this.rows[row][OPEN]; },
+ isContainerEmpty: function(row) { return false; },
+
+ hasNextSibling: function(row, after) {
+ var level = this.getLevel(row);
+ // March on!
+ var l;
+ while (++row < this.rows.length) {
+ l = this.getLevel(row);
+ if (l < level)
+ return false;
+ else if (l == level && row > after)
+ return true;
+ }
+ return false;
+ },
+ toggleOpenState: function(row) {
+ window.setCursor("wait");
+ try {
+ var rowItem = this.rows[row];
+ if (rowItem[OPEN]) {
+ // close subtree
+ rowItem[OPEN] = false;
+
+ var thisLevel = rowItem[LEVEL];
+ var deletecount = 0;
+ for (var t = row + 1; t < this.rows.length; t++) {
+ if (this.getLevel(t) > thisLevel)
+ deletecount++;
+ else
+ break;
+ }
+ if (deletecount) {
+ this.rows.splice(row + 1, deletecount);
+ this.tree.rowCountChanged(row + 1, -deletecount);
+ }
+ } else {
+ // open subtree
+ rowItem[OPEN] = true;
+ var entries = this.getChildren(row);
+ var nodecount = 0;
+ for (var i = 0; i < entries.length; i++) {
+ child = entries[i];
+ this.rows.splice(row + nodecount + 1, 0, child);
+ nodecount += 1;
+ }
+ this.tree.rowCountChanged(row + 1, nodecount);
+ }
+ } catch (e) {
+ alert(e);
+ }
+ window.setCursor("auto");
+ }
+ }
+
+ _UnitTreeView.prototype.getChildren = function(row) {
+ var parentId = this.rows[row][ID];
+ var currLevel = this.rows[row][LEVEL];
+ var children = [];
+ for (var i=0; i<this._testItems.length; i++) {
+ var rowId = this._testItems[i][ID];
+ if (rowId == parentId) {
+ for (var j=i+1; j<this._testItems.length; j++) {
+ var rowItem = this._testItems[j];
+ if (rowItem[LEVEL] <= currLevel)
+ break;
+ children.push(rowItem);
+ }
+ break;
+ }
+ }
+ return children;
+ }
+
+ _UnitTreeView.prototype.loadTests = function(tests) {
+ try {
+ this.tree.rowCountChanged(0, -this.rows.length);
+ var new_rows = [];
+ var old_row = ['','',''];
+ var id = 0;
+ var k = 0;
+ var parentArray = [-1, 0, 1, 999]; // last value is unused
+ for (var i=0; i < tests.length; i++) {
+ var test = tests[i];
+ var subtree = test[1].split('>');
+ var errorType = parseInt(test[2]);
+ var errorText = test[3];
+ var URI = test[4];
+ var level = 0;
+ // Create a hierarchy in the test nodes (Unit > File > Function)
+ if (subtree[0] == old_row[0] && subtree[1] == old_row[1])
+ level = 2;
+ else if (subtree[0] == old_row[0])
+ level = 1;
+ for (k=level; k<subtree.length; k++) {
+ // nodetext, depth, errortype, errortext, open, parentIdx,
+ // id, linenum
+ new_rows.push([subtree[k], k, errorType, errorText, 1,
+ parentArray[k], id , URI]);
+ parentArray[k+1] = id;
+ id += 1;
+ }
+ var currParent = parentArray[subtree.length-1];
+ while (currParent != -1) {
+ if (new_rows[currParent][ERRORTYPE] < errorType)
+ new_rows[currParent][ERRORTYPE] = errorType;
+ currParent = new_rows[currParent][PARENT];
+ }
+ old_row = subtree;
+ }
+ this._testItems = new_rows.slice(0); // get a unique copy
+ this.rows = new_rows;
+ this._errors = errorText;
+
+ // Using rowCountChanged to notify rows were added
+ this.tree.rowCountChanged(0, this.rows.length);
+ } catch (e) {
+ alert(e);
+ }
+ }
+
+ function _UnitTree() {
+ try {
+ // Find some xul elements
+ // TODO: look in prefs if the unit list is visible or not and change
+ // its state accordingly
+ this.svunit_tree = document.getElementById("svunit_tree");
+ this.loadTree();
+ document.getElementById('svunit-tooltip').
+ addEventListener('popupshowing', fillInTooltip, true);
+ var autoTestSetting = true;
+ if (gPrefSvc.prefs.hasPref("svunitAutoTest"))
+ autoTestSetting = gPrefSvc.prefs.getBooleanPref("svunitAutoTest");
+ else
+ gPrefSvc.prefs.setBooleanPref("svunitAutoTest", autoTestSetting);
+ if (autoTestSetting == true) {
+ document.getElementById('svunit-auto-tests-button').checked = true;
+ } else {
+ document.getElementById('svunit-auto-tests-button').checked = false;
+ }
+ sv.r.unit.getRUnitList();
+ sv.r.unit.autoTest();
+ } catch (e) {
+ alert(e);
+ }
+ }
+
+ _UnitTree.prototype.loadTree = function() {
+ try {
+ this.UnitTreeView = new _UnitTreeView();
+ this.svunit_tree.treeBoxObject.view = this.UnitTreeView;
+ } catch (e) {
+ alert(e);
+ }
+ }
+
+ this.InitOverlay = function() {
+ gUnitTreeObject = new _UnitTree();
+ }
+
+}).apply(sv.r.unit);
+
+// Ensure we load the remote server information when the overlay is loaded
+addEventListener("load", sv.r.unit.InitOverlay, false);
+}
Property changes on: komodo/SciViews-K Unit/content/js/sciviewskunit.js
___________________________________________________________________
Name: svn:executable
+ *
Added: komodo/SciViews-K Unit/content/overlay.xul
===================================================================
--- komodo/SciViews-K Unit/content/overlay.xul (rev 0)
+++ komodo/SciViews-K Unit/content/overlay.xul 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,202 @@
+<?xml version="1.0"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ License: GPL 2.0
+
+ The contents of this file are subject to the GNU General Public License
+ Version 2.0 (the "License")
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ SciViews-K is inspired from kNose by Brandon Corfman, distributed under a
+ triple MPL 1.1/GPL 2.0/LGPL 2.1 license, thus compatible with the License.
+
+ The Initial Developer of SciViews-K Unit is Philippe Grosjean
+ (phgrosjean at sciviews.org).
+ Portions created by ActiveState Software Inc are Copyright (C) 2000-2008
+ ActiveState Software Inc. All Rights Reserved.
+
+ Contributor(s):
+ Philippe Grosjean
+ Brandon Corfman
+ ActiveState Software Inc
+
+ ***** END LICENSE BLOCK ***** -->
+<!DOCTYPE overlay PUBLIC "-//MOZILLA//DTD XUL V1.0//EN" "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" [
+ <!ENTITY % sciviewskunitDTD SYSTEM "chrome://sciviewskunit/locale/sciviewskunit.dtd">
+ %sciviewskunitDTD;
+]>
+
+<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/global/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://komodo/skin/bindings/buttons.css" type="text/css"?>
+<?xml-stylesheet href="chrome://sciviewskunit/skin/sciviewskunit.css" type="text/css"?>
+
+<overlay id="sciviewskunitOverlay"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/x-javascript" src="chrome://komodo/content/project/projectManager.js"/>
+ <script type="application/x-javascript" src="chrome://komodo/content/views.js"/>
+ <script type="application/x-javascript" src="chrome://komodo/content/library/open.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/sciviews.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/strings.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/e4x2dom.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/tools/array.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/socket.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewsk/content/js/r.js"/>
+ <script type="application/x-javascript" src="chrome://sciviewskunit/content/js/sciviewskunit.js"/>
+
+ <commandset id="allcommands">
+ <command id="Tasks:svUnitAbout"
+ oncommand="alert('SciViews-K Unit Tests for R, see http://www.sciviews.org/SciViews-K');"/>
+ </commandset>
+
+ <menupopup id="popup_tools">
+ <menuitem id="menu_sciviewsk"
+ label="SciViews-K Unit"
+ observes="Tasks:svUnitAbout"
+ class="menu-iconic-wide"/>
+ </menupopup>
+
+ <menupopup id="tabPicker_popup">
+ <menuitem id="show_svunit_tab"
+ insertafter="show_codebrowser_tab"
+ oncommand="uilayout_ensureTabShown('sciviews_svunit_tab', true)"
+ label="&sciviews.runit.tab;"/>
+ </menupopup>
+
+ <menupopup id="menu_view_tabs_popup">
+ <menuitem id="show_svunit_tab2"
+ insertafter="show_codebrowser_tab2"
+ class="menuitem-iconic-wide"
+ oncommand="uilayout_ensureTabShown('sciviews_svunit_tab', true)"
+ label="&sciviews.runit.tab;"/>
+ </menupopup>
+
+ <tabs id="right_toolbox_tabs">
+ <tab id="sciviews_svunit_tab"
+ label="&sciviews.runit.tab;"
+ insertafter="toolbox_tab"
+ tooltiptext="&sciviews.runit.tip;"/>
+ </tabs>
+
+ <tabpanels id="right_toolbox_tabpanels">
+ <tabpanel id="svunittreeviewbox"
+ flex="1"
+ insertafter="codebrowserviewbox">
+ <vbox id="svunittree-vbox"
+ flex="1">
+ <vbox flex="1">
+ <hbox id="svunittree-tabpanel-hbox"
+ align="center">
+ <toolbarbutton
+ id="svunit_refresh_button"
+ class="refresh-icon button-toolbar-a"
+ buttonstyle="pictures"
+ label="&sciviews.runit.refresh;"
+ tooltiptext="&sciviews.runit.refresh.tip;"
+ oncommand="sv.r.unit.getRUnitList();"/>
+ <toolbarbutton
+ id="svunit_unitlist_button"
+ class="searchPath-icon button-toolbar-a"
+ buttonstyle="pictures"
+ label="&sciviews.runit.showHide;"
+ tooltiptext="&sciviews.runit.showHide.tip;"
+ oncommand="sv.r.unit.showRUnitList();"/>
+ <checkbox
+ id="svunit-auto-tests-button"
+ label="&sciviews.runit.autoTest;"
+ tooltiptext="&sciviews.runit.autoTest.tip;"
+ checked="true"
+ oncommand="sv.r.unit.autoTest();"/>
+ <progressmeter
+ id="svunit-progress-bar"
+ mode="determined"
+ value="0%"/>
+ </hbox>
+ <vbox>
+ <listbox id="svunit_unitlist_listbox"
+ flex="1"/>
+ </vbox>
+ <splitter
+ id="svunit_splitter"
+ collapse="before"
+ resizeafter="farthest"
+ resizebefore="closest"
+ state="open">
+ <grippy tooltiptext="&sciviews.runit.showHide.tip;"/>
+ </splitter>
+ <hbox id="svunittree-tabpanel-hbox2"
+ align="center">
+ <toolbarbutton
+ id="svunit-run-tests-button"
+ image="chrome://famfamfamsilk/skin/icons/control_play_blue.png"
+ label="&sciviews.runit.run;"
+ tooltiptext="&sciviews.runit.run.tip;"
+ orient="horizontal"
+ disabled="false"
+ oncommand="sv.r.unit.runTest();"/>
+ <label
+ id="svunit-pass-label"
+ value="Pass: -"/>
+ <label
+ id="svunit-fail-label"
+ value="Fail: -"/>
+ <label
+ id="svunit-error-label"
+ value="Errors: -"/>
+ <image
+ id="svunit-deactivated-image"
+ tooltiptext=""
+ width="16"
+ src=""/>
+ </hbox>
+ <popupset id="svunitTooltipSet">
+ <popup
+ id="svunit-tooltip"
+ type="tooltip"
+ noautohide="true"
+ multiline="true">
+ <vbox id="svunit-tooltip-container"
+ align="left">
+ <description id="svunit-tooltip-desc"/>
+ </vbox>
+ </popup>
+ </popupset>
+ <tree id="svunit_tree"
+ flex="1"
+ seltype="single">
+ <treecols>
+ <treecol
+ id="tree_col_test_name"
+ label="&sciviews.runit.Name;"
+ primary="true"
+ flex="1"/>
+ </treecols>
+ <treechildren
+ tooltip="svunit-tooltip"
+ ondblclick="sv.r.unit.jumpToObject(event);"/>
+ </tree>
+ </vbox>
+ </vbox>
+ </tabpanel>
+ </tabpanels>
+
+ <statusbar
+ id="statusbarviewbox"
+ fullscreentoolbar="true"
+ orient="horizontal">
+ <statusbarpanel
+ id="statusbar-svunit"
+ class="statusbarpanel-iconic"
+ insertbefore="statusbar-check"
+ src="chrome://famfamfamsilk/skin/icons/help.png"
+ tooltiptext="R Unit Status: not run yet"
+ hidden="false"
+ onclick="sv.r.unit.showRUnitPane();"/>
+ </statusbar>
+</overlay>
Added: komodo/SciViews-K Unit/install.rdf
===================================================================
--- komodo/SciViews-K Unit/install.rdf (rev 0)
+++ komodo/SciViews-K Unit/install.rdf 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>sciviewskunit at sciviews.org</em:id>
+ <em:name>SciViews-K Unit</em:name>
+ <em:version>0.6.0</em:version>
+ <em:description>SciViews-K Unit - Interface to the svUnit R package</em:description>
+ <em:creator>Philippe Grosjean</em:creator>
+ <em:homepageURL>http://sciviews.org/SciViews-K</em:homepageURL>
+ <em:type>2</em:type> <!-- type=extension -->
+
+ <em:targetApplication>
+ <Description>
+ <!-- Komodo IDE's uuid -->
+ <em:id>{36E66FA0-F259-11D9-850E-000D935D3368}</em:id>
+ <em:minVersion>4.1</em:minVersion>
+ <em:maxVersion>4.4.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- Komodo Edit's uuid -->
+ <em:id>{b1042fb5-9e9c-11db-b107-000d935d3368}</em:id>
+ <em:minVersion>4.1</em:minVersion>
+ <em:maxVersion>4.4.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
Added: komodo/SciViews-K Unit/locale/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/locale/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/locale/en-GB/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/locale/en-GB/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/locale/en-GB/sciviewskunit.dtd
===================================================================
--- komodo/SciViews-K Unit/locale/en-GB/sciviewskunit.dtd (rev 0)
+++ komodo/SciViews-K Unit/locale/en-GB/sciviewskunit.dtd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,11 @@
+<!ENTITY sciviews.runit.tab "R Unit">
+<!ENTITY sciviews.runit.tip "R unit tests">
+<!ENTITY sciviews.runit.refresh "Refresh">
+<!ENTITY sciviews.runit.refresh.tip "Refresh the unit list">
+<!ENTITY sciviews.runit.showHide "R Unit List">
+<!ENTITY sciviews.runit.showHide.tip "Show/hide the unit list">
+<!ENTITY sciviews.runit.autoTest "Auto">
+<!ENTITY sciviews.runit.autoTest.tip "Source code and run tests whenever a R file is saved">
+<!ENTITY sciviews.runit.run "Run">
+<!ENTITY sciviews.runit.run.tip "Run unit tests manually">
+<!ENTITY sciviews.runit.Name "Name">
Added: komodo/SciViews-K Unit/locale/fr-FR/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/locale/fr-FR/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/locale/fr-FR/sciviewskunit.dtd
===================================================================
--- komodo/SciViews-K Unit/locale/fr-FR/sciviewskunit.dtd (rev 0)
+++ komodo/SciViews-K Unit/locale/fr-FR/sciviewskunit.dtd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,11 @@
+<!ENTITY sciviews.runit.tab "R Unit">
+<!ENTITY sciviews.runit.tip "Tests unit de R">
+<!ENTITY sciviews.runit.refresh "Ractualiser">
+<!ENTITY sciviews.runit.refresh.tip "Ractualiser le liste d'units">
+<!ENTITY sciviews.runit.showHide "Liste d'units R">
+<!ENTITY sciviews.runit.showHide.tip "Montrer/cacher la liste d'units">
+<!ENTITY sciviews.runit.autoTest "Auto">
+<!ENTITY sciviews.runit.autoTest.tip "Sourcer le code et lancer les tests chaque sauvegarde de fichier R">
+<!ENTITY sciviews.runit.run "Lancer">
+<!ENTITY sciviews.runit.run.tip "Lancer les tests manuellement">
+<!ENTITY sciviews.runit.Name "Nom">
Added: komodo/SciViews-K Unit/sciviewskunit-0.6.0-ko.xpi
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/sciviewskunit-0.6.0-ko.xpi
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/skin/.DS_Store
===================================================================
(Binary files differ)
Property changes on: komodo/SciViews-K Unit/skin/.DS_Store
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: komodo/SciViews-K Unit/skin/sciviewskunit.css
===================================================================
--- komodo/SciViews-K Unit/skin/sciviewskunit.css (rev 0)
+++ komodo/SciViews-K Unit/skin/sciviewskunit.css 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,10 @@
+#svunit-progress-bar
+{
+ -moz-appearance: none !important;
+ background-color: #E6E6E6;
+}
+
+toolbarbutton
+{
+ margin: 0px 2px;
+}
Property changes on: komodo/SciViews-K Unit/skin/sciviewskunit.css
___________________________________________________________________
Name: svn:executable
+ *
Added: komodo/TODO
===================================================================
--- komodo/TODO (rev 0)
+++ komodo/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,32 @@
+= SciViews-K To Do
+
+* Object explorer: refresh content, tooltip, menu, changer fonction refresh
+
+* sv.r.source() is buggy + add in menus/toolbars
+
+* Package help, vignettes, demos, packages management
+
+* doBraceMatch
+
+* setwd() with GUI
+
+* Finalize the R starting functions and place them in extensions; eliminate
+"R kernels"
+
+* R reference cards
+
+* R completion
+
+* All the Tinn-R function that are still missing
+
+* Make a Tinn-R GUI with simili-Tinn-R menus
+
+* Make ESS functions + the ESS GUI
+
+* Make R and Rd syntax highlighting; sweave later on
+
+* Allow for projects in packages (developments and binaries)
+
+* Make the User's and Developer's manuals
+
+* Update the web site
Modified: pkg/svGUI/DESCRIPTION
===================================================================
--- pkg/svGUI/DESCRIPTION 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/DESCRIPTION 2008-06-23 01:33:08 UTC (rev 12)
@@ -2,8 +2,8 @@
Title: SciViews GUI API - Functions to manage GUI client
Depends: R (>= 2.7.0), svMisc, svSocket
Description: Functions to manage the GUI client, like Komodo with the SciViews-K extension
-Version: 0.9-40
-Date: 2008-06-01
+Version: 0.9-42
+Date: 2008-06-23
Author: Philippe Grosjean
Maintainer: Philippe Grosjean <phgrosjean at sciviews.org>
License: GPL (>= 2)
Modified: pkg/svGUI/NEWS
===================================================================
--- pkg/svGUI/NEWS 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/NEWS 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,5 +1,14 @@
= svGUI News
+== Changes in svGUI 0.9-42
+* koCmd() is now more robust and do not issue a warning or an error if the
+Komodo server is not available (but the error message is returned by the
+function with a 'try-error' class, so that it can be processed by the caller)
+
+== Changes in svGUI 0.9-41
+* Correction of a bug in the first example of koCmd()
+* guiInstall() now creates a hook to koCmd(): .koCmd() in TempEnv environment
+
== Changes in svGUI 0.9-40
This is the first version distributed on R-forge. It is completely refactored
from older versions (on CRAN since 2003) to make it run with SciViews-K and
Modified: pkg/svGUI/R/guiInstall.R
===================================================================
--- pkg/svGUI/R/guiInstall.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/R/guiInstall.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,7 +1,7 @@
"guiInstall" <-
function() {
assignTemp(".guiCmd", function(command, ...) {
- switch(command, ### TODO: create these commands!
+ command <- switch(command, ## TODO: define these commands
load = "",
source = "",
save = "",
@@ -9,8 +9,7 @@
export = "",
report = "",
setwd = "",
- ""
- )
+ "")
})
assignTemp(".guiObjBrowse", function(id, data) {
koCmd('sv.objBrowse("<<<id>>>", "<<<dat>>>");', list(id = id, dat = data))
@@ -22,6 +21,17 @@
koCmd('sv.objMenu("<<<id>>>", "<<<dat>>>");', list(id = id, dat = data))
})
+ # Functions specific to Komodo as a GUI client
+ assignTemp(".koCmd", function(command, ...) {
+ # This mechanism avoids dependence on svGUI for packages that provide
+ # functionalities that work with or without Komodo (like svUnit)
+ # Instead of calling koCmd() directly, we look if .koCmd is defined
+ # in tempenv and we run it.
+ # This allows also redefining koCmd() without changing code in the
+ # packages that depend on .koCmd()
+ koCmd(command, ...)
+ })
+
# Register a TaskCallback to generate automatically informations for an object browser
# Use getTaskCallbackNames() to know if some tasks are registered
assignTemp(".guiObjCallback", function(...) {
Modified: pkg/svGUI/R/guiUninstall.R
===================================================================
--- pkg/svGUI/R/guiUninstall.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/R/guiUninstall.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -5,6 +5,8 @@
rmTemp(".guiObjBrowse")
rmTemp(".guiObjInfo")
rmTemp(".guiObjMenu")
+
+ rmTemp(".koCmd")
# Unregister the TaskCallback
# Use getTaskCallbackNames() to know if some tasks are registered
Modified: pkg/svGUI/R/koCmd.R
===================================================================
--- pkg/svGUI/R/koCmd.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/R/koCmd.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -10,14 +10,14 @@
return("")
}
# Do we need to paste data in the command?
- if (!is.null(data)) {
+ if (!is.null(data)) {
"rework" <- function(data) {
data <- as.character(data)
data <- gsub("\n", "\\\\\\\\n", data)
data <- paste(data, collapse = "\\\\n")
return(data)
}
-
+
n <- names(data)
if (is.null(n)) {
# We assume that we replace '<<<data>>>'
@@ -29,7 +29,16 @@
rework(data[[n[i]]]), cmd)
}
}
- con <- socketConnection(host = host, port = port, blocking = TRUE)
+ owarn <- getOption("warn")
+ options(warn = -1) # Eliminate warnings (in case the Komodo server is not available)
+ ret <- try(con <- socketConnection(host = host, port = port, blocking = TRUE),
+ silent = TRUE)
+ options(warn = owarn) # Restore warnings
+ if (inherits(ret, "try-error")) {
+ data <- "Komodo socket server is not available!"
+ class(data) <- "try-error"
+ return(data)
+ }
writeLines(cmd, con)
res <- readLines(con)
close(con)
Modified: pkg/svGUI/TODO
===================================================================
--- pkg/svGUI/TODO 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,5 +1,7 @@
= svGUI To Do list
+* The svGUI-package.Rd man page
+
* Write the whole API to access Komodo from R
* Translate this package
\ No newline at end of file
Modified: pkg/svGUI/man/guiInstall.Rd
===================================================================
--- pkg/svGUI/man/guiInstall.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/man/guiInstall.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -5,7 +5,7 @@
\title{ Install and uninstall hooks for communicating with the GUI client (Komodo) }
\description{
Install functions in TempEnv and callbacks required to communicate with Komodo
- Edit with the Sciviews-K extension.
+ Edit with the SciViews-K extension (see http://www.sciviews.org/SciViews-K).
}
\usage{
guiInstall()
@@ -18,18 +18,22 @@
\details{
The minimum instruction to set up everything in R to communication with Komodo
- and SciViews-K extension installed (see http://www.sciviews.org/SciViews-K)
- is to use: \code{option(ko.serve = 8888); require(svGUI)}. When the
- \code{ko.serve} option is set, svGUI load svSocket, starts the socket server
- litening to the port you give in \code{ko.serve} (8888 by default), and install
- the hooks and callbacks required to fully communicate with Komodo.
-
- Before loading svGUI, you can also set \code{option(ko.port = 7052)} or another
- port number where the Komodo SciViews-K server is listening (7052 is the
- default value). If the Komodo client is running on a different machine, you
- should also set \code{ko.host = "xxx.xxx.xxx.xxx"}, where xxx.xxx.xxx.xxx is
- the IP address of the Komodo client's machine, before loading svGUI.
-
+ and SciViews-K extension installed is to use:
+ \code{option(ko.serve = 8888); require(svGUI)}. When the \code{ko.serve}
+ option is set, svGUI load svSocket, starts the socket server litening to the
+ port you give in \code{ko.serve} (8888 by default), and install the hooks and
+ callbacks required to fully communicate with Komodo.
+
+ Before loading svGUI, you can also set \code{option(ko.port = 7052)} or
+ another port number where the Komodo SciViews-K server is listening (7052 is
+ the default value). If the Komodo client is running on a different machine,
+ you should also set \code{ko.host = "xxx.xxx.xxx.xxx"}, where xxx.xxx.xxx.xxx
+ is the IP address of the Komodo client's machine, before loading svGUI (note
+ that running R and Komodo on separate machines is not supported yet, but this
+ is a planned feature and corresponding configurations are already recognized;
+ just, distant server is currently locked until we will build a better security
+ mechanism in the server (SSL, TSL, ...).
+
All these operations are done by Komodo if you start R from Komodo with
SciViews-K extension installed.
}
Modified: pkg/svGUI/man/koCmd.Rd
===================================================================
--- pkg/svGUI/man/koCmd.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svGUI/man/koCmd.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -33,7 +33,7 @@
\value{
Returns the results of the evaluation of the javascript code in Komodo Edit if
\code{async = FALSE}. Note that \code{async = TRUE} is not supported yet.
-
+
If there is an error, or \code{cmd} is an invalid javascript code, an error
is returned with the class \'try-error\' (see last example).
}
@@ -48,7 +48,7 @@
(see http://www.sciviews.org/SciViews-R) in a platform independent solution
using Komodo with a specific extension named SciViews-K and the SciViews-R
bundle.
-
+
\code{koCmd()} can only talk to Komdo if the SciViews-K socket server is
installed. This server is contained in the SciViews-K extension that you can
download from http://www.sciviews.org/SciViews-K. See Komodo documentation to
@@ -63,7 +63,7 @@
Because of serious security issues, the SciViews-K server only allows
connections from local clients (running on the same computer). This limitation
would be relatively easy to eliminate, but at your own risks!
-
+
Data are returned to R by using the javascript function
\code{sv.socket.serverWrite()}, see the examples bellow.
}
@@ -79,8 +79,8 @@
# on the same machine you run R, and the socket server started and then...
# Alert box in Komodo, and then reply to R
-koCmd(c('alert("Hello from R!")',
- 'sv.socket.serverWrite("Hello from OpenKomodo (" + ko.interpolate.currentFilePath() + ")")'))
+koCmd(c('alert("Hello from R!");',
+ 'sv.socket.serverWrite("Hello from OpenKomodo (" + ko.interpolate.currentFilePath() + ")");'))
# Open a web page wih Komodo configuration
koCmd("ko.open.URI('about:config','browser');")
Modified: pkg/svIDE/DESCRIPTION
===================================================================
--- pkg/svIDE/DESCRIPTION 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svIDE/DESCRIPTION 2008-06-23 01:33:08 UTC (rev 12)
@@ -4,7 +4,7 @@
Depends: R (>= 2.7.0), tcltk, svMisc
Description: Function for the GUI API to interact with external IDE/code editors
Version: 0.9-43
-Date: 2008-06-12
+Date: 2008-06-23
Author: Philippe Grosjean
Maintainer: Philippe Grosjean <phgrosjean at sciviews.org>
License: GPL (>= 2)
Modified: pkg/svIDE/R/TinnR.R
===================================================================
--- pkg/svIDE/R/TinnR.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svIDE/R/TinnR.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -41,10 +41,9 @@
"list", "function", "NULL", "language",
"S3", "S4")
NewGroup <- GrpTable[res$Group]
- NewGroup[NewGroup == "vector" & (regexpr("x", res$Dims) > -1)] <- "array"
- NewGroup[NewGroup == "array" &
- (regexpr("^[0-9]+x[0-9]+$", res$Dims) > -1)] <- "matrix"
- NewGroup[res$Class == "table"] <- "table"
+ NewGroup[res$Class == "matrix"] <- "matrix"
+ NewGroup[res$Class == "array"] <- "array"
+ NewGroup[res$Class == "table"] <- "table"
res$Group <- NewGroup
# Filter according to group
Modified: pkg/svIDE/TODO
===================================================================
--- pkg/svIDE/TODO 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svIDE/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,3 +1,5 @@
= svIDE To Do list
+* The svIDE-package.Rd man page
+
* Translate this package
Modified: pkg/svMisc/TODO
===================================================================
--- pkg/svMisc/TODO 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svMisc/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,5 +1,7 @@
= svMisc To Do list
+* The svMisc-package.Rd man page
+
* Write the code in objList() to list content inside objects
* Rework mechanism to call .guiCmd() from objXXX() functions
@@ -7,8 +9,8 @@
* Make indeterminate progress()ion
* Use this in call tips to get the call for S3 method for given objects
- args(getS3method("predict", class(myobj), optional = TRUE)). + selectMethod
- for S4 object does the same thing!
+args(getS3method("predict", class(myobj), optional = TRUE)). + selectMethod
+for S4 object does the same thing!
* objMenu(): add copy name to clipboard, send name to editor in menu
Modified: pkg/svSocket/TODO
===================================================================
--- pkg/svSocket/TODO 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svSocket/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,15 +1,17 @@
= svSocket To Do list
+* svSocket-package.Rd man page
+
* Easy redefinition of options(width = ...) to adjust width of output to the
- GUI client R console
+GUI client R console
* Make use of a config file for the server + parSocketServer() to change (some!)
- parameters of the server
+parameters of the server
* Translation of all messages in the package
* Delete SocketClient_xxxx on disconnection + make sure they are all deleted
- on server stopping and on package detaching (in .Last.lib())
+on server stopping and on package detaching (in .Last.lib())
* Parse error => rework message a little bit + line number is 1 too much
@@ -24,12 +26,12 @@
* A mode that flags various parts of output
* Parse and executes one command at a time in case several commands are send at
- once (should we? The current way of working has some interesting features!)
+once (should we? The current way of working has some interesting features!)
* Unattended messages should be printed above command line
* Allow for remote connection + security?
- Use a tcl list:
+Use a tcl list:
% set xxxx_allow [list]
% llength $xxxx_allow
% lappend xxxx_allow "194.127.34.1"
@@ -64,7 +66,7 @@
* <<<E>>> with addition of the command in the R command history
* Check and solve possible clash when several clients submit commands at the
- same time
+same time
== Differences between CLI and processSocket()
@@ -73,63 +75,63 @@
* When successive commands are issued and the last one is incomplete like:
> search(); log(
- processSocket() waits for a complete last command before processing everything
- while other consoles process all the commands and then wait for last one to be
- completed (should be considered as a feature)
+processSocket() waits for a complete last command before processing everything
+while other consoles process all the commands and then wait for last one to be
+completed (should be considered as a feature)
* Same problem with multiple instructions send at once when there is an error:
- the first few correct instructions before the error should be evaluated, while
- they are not with processSocket() (considered as a feature). Compare this
+the first few correct instructions before the error should be evaluated, while
+they are not with processSocket() (considered as a feature). Compare this
> search(); log)
* For long calculations, processSocket() acts as a buffered console (like RGui)
- except that it does not understand (yet) flush.console!
+except that it does not understand (yet) flush.console!
* There are sometimes cosmetic differences in the way warnings are printed
- (essentially, truncation of call argument). For instance:
+(essentially, truncation of call argument). For instance:
> options(warn = 0)
> (function() {warning("Warn!"); 1:3})()
* There are slight differences in the way the error message is presented when
- incorrect code is processed. Moreover, R.app (Macintosh) does not print a
- descriptive error message, but only "syntax error". This is an old behaviour
- that remains only in R.app (among all tested consoles)
+incorrect code is processed. Moreover, R.app (Macintosh) does not print a
+descriptive error message, but only "syntax error". This is an old behaviour
+that remains only in R.app (among all tested consoles)
* R.app (Macintosh) always print prompts at the beginning of a line. So,
- cat("text") does not produce exactly the same result as in many other consoles
- including with processSocket() (should be considered wrong in R.app!)
+cat("text") does not produce exactly the same result as in many other consoles
+including with processSocket() (should be considered wrong in R.app!)
* R.app (Macintosh) incorrectly prints a continuation prompt after:
> options(warn = 2)
> (function() {warning("Warn!"); 1:3})()
* R.app (Macintosh) does not interpret \a and \b on the contrary to most other
- consoles. With processSocket(), it is the client that must decide how to
- interpret special characters. Most important ones are: \a => sound a bip and
- print nothing, \b = backspace, erase previous character, except if at the
- beginning of a line, \t = tabulation (4 spaces), \n = newline, \r = same as \n
- (but not interpreted on RGui), \r\n = same as \n, \r\r and \n\r are
- equivalent to \n\n (for portability) from one platform to the other. \f and \v
- are interpreted as \n (but not on RGui under Windows), \u and \x are also
- recognized but interpreted differently from one to the other console, as well
- as the other exotic escape sequences. It is better to ignore them, or to print
- a question mark instead.
+consoles. With processSocket(), it is the client that must decide how to
+interpret special characters. Most important ones are: \a => sound a bip and
+print nothing, \b = backspace, erase previous character, except if at the
+beginning of a line, \t = tabulation (4 spaces), \n = newline, \r = same as \n
+(but not interpreted on RGui), \r\n = same as \n, \r\r and \n\r are
+equivalent to \n\n (for portability) from one platform to the other. \f and \v
+are interpreted as \n (but not on RGui under Windows), \u and \x are also
+recognized but interpreted differently from one to the other console, as well
+as the other exotic escape sequences. It is better to ignore them, or to print
+a question mark instead.
* Regarding internationalization of error messages, there are two differences
- between messages at the CLI and issued by processSocket():
+between messages at the CLI and issued by processSocket():
- Warning message(s): is not translated at CLI bu it is translated by
- processSocket() (bug?) in:
+processSocket() (bug?) in:
> options(warn = 0)
> warning("Warn!")
- On the contrary, processSocket() fails to translate 'Error in' for most
- error messages, and I don't understand this bug:
+error messages, and I don't understand this bug:
> cos("a")
* If you define options(warning.expression), there will be a problem because
- processSocket() redefines it also, and thus, at best, you expression is
- ignored (must fix this!)
+processSocket() redefines it also, and thus, at best, you expression is
+ignored (must fix this!)
* On the MacOS X, there are many mismatches for string translation, bot at the
- command line and using processSocket(), but they are not same mismatches!
\ No newline at end of file
+command line and using processSocket(), but they are not same mismatches!
Modified: pkg/svUnit/DESCRIPTION
===================================================================
--- pkg/svUnit/DESCRIPTION 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/DESCRIPTION 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,10 +1,10 @@
Package: svUnit
Title: SciViews GUI API - Unit testing
-Depends: R (>= 1.9.0), RUnit
-Suggests: svGUI
-Description: Functions to implement the GUI part of a unit test system based on RUnit
-Version: 0.4-0
-Date: 2008-06-11
+Depends: R (>= 1.9.0)
+Suggests: svGUI, datasets, utils
+Description: A complete unit test system and functions to implement its GUI part
+Version: 0.6-0
+Date: 2008-06-23
Author: Philippe Grosjean
Maintainer: Philippe Grosjean <phgrosjean at sciviews.org>
License: GPL 2 or above
Modified: pkg/svUnit/NAMESPACE
===================================================================
--- pkg/svUnit/NAMESPACE 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/NAMESPACE 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,30 +1,63 @@
-import(RUnit)
+export( as.svSuite,
+ as.svTest,
+ checkEquals,
+ checkEqualsNumeric,
+ checkIdentical,
+ checkTrue,
+ checkException,
+ clearLog,
+ createLog,
+ DEACTIVATED,
+ errorLog,
+ guiSuiteAutoList,
+ guiSuiteList,
+ guiTestFeedback,
+ guiTestReport,
+ koUnit_isAutoTest,
+ koUnit_setAutoTest,
+ koUnit_runTest,
+ koUnit_showRUnitPane,
+ koUnit_version,
+ is.svSuite,
+ is.svSuiteData,
+ is.svTest,
+ is.svTestData,
+ is.test,
+ lastSuite,
+ lastTest,
+ Log,
+ makeUnit,
+ metadata,
+ protocol,
+ protocol_text,
+ runTest,
+ stats,
+ svSuite,
+ svSuiteList,
+ svTest,
+ test,
+ "test<-")
-export(svTest,
- as.svTest,
- is.svTest,
- is.test,
- test,
- "test<-",
- makeUnit,
- runTest,
- svUnit,
- as.svUnit,
- is.svUnit,
- svUnitList,
- runUnit,
- unitClear,
- unitError)
-
S3method(makeUnit, default)
S3method(makeUnit, svTest)
-S3method(makeUnit, svUnit)
+S3method(makeUnit, svSuite)
+S3method(metadata, svSuiteData)
+
+S3method(print, svSuite)
+S3method(print, svSuiteData)
+S3method(print, svTest)
+S3method(print, svTestData)
+
+S3method(protocol, default)
+S3method(protocol_text, svSuiteData)
+
S3method(runTest, default)
S3method(runTest, svTest)
-S3method(runTest, svUnit)
+S3method(runTest, svSuite)
-S3method(print, svUnit)
+S3method(stats, svSuiteData)
+S3method(stats, svTestData)
-S3method(print, svUnitData)
-S3method(summary, svUnitData)
+S3method(summary, svSuiteData)
+S3method(summary, svTestData)
Modified: pkg/svUnit/NEWS
===================================================================
--- pkg/svUnit/NEWS 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/NEWS 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,4 +1,36 @@
= svUnit News
-== svUnit 0.1-0
+== svUnit 0.6-0
+* The package does not depends any more from RUnit. It has his own checkXXX()
+function (they are compatible with those in RUnit 0.4.17, except that here the
+checkTrue() function is vectorized, but they operate very differently),
+
+* svUnit functions and objects are renamed svSuite, and there is a reworking of
+objects to end with svTest, svSuite, svTestData and svSuiteData, and many new
+methods for those objects (print, summary, stats, metadata, makeUnit, runTest)
+
+* print.svSuiteData and summary.svSuiteData are completely reworked.
+
+* svSuiteList() now accepts additional, dirs, manages an exclusion list and has
+an argument 'loadPackages' to force loading packages provided in the list.
+
+* Names for test units is now runit<name>.R, like in the RUnit package. Same for
+the test functions which are test<name>.R (used to be runit.<name>.R and
+test.<name.R).
+
+* The temporary directory is now emptied from old runit*.R files before making
+new ones, but not any more after running tests. That way, we avoid running old
+test definitions, while keeping the latest one available for inspection.
+
+* koUnit_xxx() functions have been added to manipulate the R Unit GUI in
+Komodo from within R.
+
+
+== svUnit 0.5-0
+* Added guiTestFeedback() and guiTestReport() functions.
+
+* A couple of other little changes.
+
+
+== svUnit 0.4-0
First version compiled as a package and distributed on R-Forge.
Added: pkg/svUnit/R/Log.R
===================================================================
--- pkg/svUnit/R/Log.R (rev 0)
+++ pkg/svUnit/R/Log.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,71 @@
+Log <-
+function (description = NULL) {
+ if (!exists(".Log", envir = .GlobalEnv, inherits = FALSE))
+ createLog(description = description)
+ return(get(".Log", envir = .GlobalEnv, inherits = FALSE))
+}
+
+createLog <-
+function (description = NULL, deleteExisting = FALSE) {
+ # Create a log consisting in an environment with class svSuiteData
+ if (isTRUE(deleteExisting) && exists(".Log", envir = .GlobalEnv,
+ inherits = FALSE)) rm(.Log, envir = .GlobalEnv)
+ if (!exists(".Log", envir = .GlobalEnv, inherits = FALSE)) {
+ .Log <<- structure(new.env(parent = .GlobalEnv),
+ class = c("svSuiteData", "environment"))
+ # Add general informations and variables to it
+ .Log$.time <- Sys.time() # Creation time of the log
+ .Log$.R.version <- R.version # R version
+ .Log$.sessionInfo <- sessionInfo() # Information about current session
+ .Log$.description <- description # Optional description of this log
+ # Create ..xxx variables used for test context
+ # Note: never delete or put NULL in these variables, use "" instead
+ .Log$..Unit <- ""
+ .Log$..Msg <- ""
+ .Log$..Obj <- ""
+ .Log$..File <- ""
+ .Log$..Tag <- ""
+ # Create .lastTest that contains details from last check...()
+ naChr <- as.character(NA)
+ .Log$.lastTest <- structure(
+ data.frame(msg = naChr, call = naChr,
+ timing = as.numeric(NA), kind = .kind(NA), res = naChr,
+ obj = naChr, file = naChr, tag = naChr,
+ stringsAsFactors = FALSE),
+ class = c("svTestData", "data.frame"))
+ # Create .lastSuite with an empty list of test units to run
+ .Log$.lastSuite <- list()
+ }
+}
+
+clearLog <-
+function () {
+ if (exists(".Log", envir = .GlobalEnv, inherits = FALSE)) {
+ rm(list = ".Log", envir = .GlobalEnv)
+ return(invisible(TRUE))
+ } else return(invisible(FALSE))
+}
+
+errorLog <-
+function (stopit = TRUE, summarize = TRUE) {
+ .Log <- Log()
+ Res <- table(stats(.Log)$kind)
+ if (isTRUE(stopit) && any(Res[2:3] > 0)) {
+ if (isTRUE(summarize)) summary(.Log)
+ msg <- paste(Res[2], "failure(s) and", Res[3], "error(s)")
+ stop(msg)
+ }
+ return(invisible(Res))
+}
+
+lastTest <-
+function () {
+ # Return a svTestData object with data from last recorded test
+ Log()$.lastTest
+}
+
+lastSuite <-
+function () {
+ # Return data about last suite run
+ Log()$.lastSuite
+}
Added: pkg/svUnit/R/check.R
===================================================================
--- pkg/svUnit/R/check.R (rev 0)
+++ pkg/svUnit/R/check.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,183 @@
+# Define check...() functions in a way they are compatible with same functions
+# in the 'RUnit' package (these functions are directly inspired from those
+# in RUnit). Make version that are more compatible with Komodo/SciViews-K Unit)
+
+checkEquals <-
+function (target, current, msg = "", tolerance = .Machine$double.eps^0.5,
+checkNames = TRUE, ...) {
+ val <- FALSE
+ timing <- as.numeric(system.time({
+ ret <- try({
+ # Run the test
+ if (isTRUE(checkNames)) {
+ cn <- "" # Since this is the default value
+ } else {
+ cn <- ", checkNames = FALSE"
+ names(target) <- NULL
+ names(current) <- NULL
+ }
+ if (!is.numeric(tolerance))
+ stop("tolerance has to be a numeric value")
+ if (length(tolerance) != 1)
+ stop("tolerance has to be a scalar")
+ res <- all.equal(target, current, tolerance = tolerance, ...)
+ val <- isTRUE(res)
+ }, silent = TRUE)
+ }, gcFirst = FALSE)[3])
+ # Log this test
+ test <- .logTest(timing)
+ # Decide if recording more info or not
+ minTiming <- getOption("svUnit.minTiming")
+ if (is.null(minTiming)) minTiming <- 0.1
+ if (!isTRUE(getOption("svUnit.recordAll")) && isTRUE(timing < minTiming)
+ && val) return(invisible(TRUE))
+ # Check for error
+ if (inherits(ret, "try-error")) {
+ val <- NA
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = -1,
+ res = as.character(ret))
+ } else {
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = val,
+ res = if (val) "" else paste(c(res, .formatResult(current)),
+ collapse = "\n"))
+ }
+ return(invisible(val))
+}
+
+checkEqualsNumeric <-
+function (target, current, msg = "", tolerance = .Machine$double.eps^0.5, ...) {
+ val <- FALSE
+ timing <- as.numeric(system.time({
+ ret <- try({
+ # Run the test
+ if (!is.numeric(tolerance))
+ stop("tolerance has to be a numeric value")
+ if (length(tolerance) != 1)
+ stop("tolerance has to be a scalar")
+ res <- all.equal.numeric(as.vector(target), as.vector(current),
+ tolerance = tolerance, ...)
+ val <- isTRUE(res)
+ }, silent = TRUE)
+ }, gcFirst = FALSE)[3])
+ # Log this test
+ test <- .logTest(timing)
+ # Decide if recording more info or not
+ minTiming <- getOption("svUnit.minTiming")
+ if (is.null(minTiming)) minTiming <- 0.1
+ if (!isTRUE(getOption("svUnit.recordAll")) && isTRUE(timing < minTiming)
+ && val) return(invisible(TRUE))
+ # Check for error
+ if (inherits(ret, "try-error")) {
+ val <- NA
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = -1,
+ res = as.character(ret))
+ } else {
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = val,
+ res = if (val) "" else paste(c(res, .formatResult(current)),
+ collapse = "\n"))
+ }
+ return(invisible(val))
+}
+
+checkIdentical <-
+function (target, current, msg = "") {
+ val <- FALSE
+ timing <- as.numeric(system.time({
+ ret <- try({
+ # Run the test
+ val <- identical(target, current)
+ }, silent = TRUE)
+ }, gcFirst = FALSE)[3])
+ # Log this test
+ test <- .logTest(timing)
+ # Decide if recording more info or not
+ minTiming <- getOption("svUnit.minTiming")
+ if (is.null(minTiming)) minTiming <- 0.1
+ if (!isTRUE(getOption("svUnit.recordAll")) && isTRUE(timing < minTiming)
+ && val) return(invisible(TRUE))
+ # Check for error
+ if (inherits(ret, "try-error")) {
+ val <- NA
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = -1,
+ res = as.character(ret))
+ } else {
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:3], nlines = 1), timing = timing, val = val,
+ res = .formatResult(current))
+ }
+ return(invisible(val))
+}
+
+checkTrue <-
+function (expr, msg = "") {
+ val <- FALSE
+ timing <- as.numeric(system.time({
+ ret <- try({
+ # Run the test
+ val <- isTRUE(all(expr == TRUE))
+ }, silent = TRUE)
+ }, gcFirst = FALSE)[3])
+ # Log this test
+ test <- .logTest(timing)
+ # Decide if recording more info or not
+ minTiming <- getOption("svUnit.minTiming")
+ if (is.null(minTiming)) minTiming <- 0.1
+ if (!isTRUE(getOption("svUnit.recordAll")) && isTRUE(timing < minTiming)
+ && val) return(invisible(TRUE))
+ # Get call, without msg
+ call <- sys.call()
+ call <- deparse(call[names(call) != "msg"])
+ # Check for error
+ if (inherits(ret, "try-error")) {
+ val <- NA
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:2], nlines = 1), timing = timing, val = -1,
+ res = as.character(ret))
+ } else {
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:2], nlines = 1), timing = timing, val = val,
+ res = .formatResult(expr))
+ }
+ return(invisible(val))
+}
+
+checkException <-
+function (expr, msg = "", silent = getOption("svUnit.silentException")) {
+ val <- FALSE
+ timing <- as.numeric(system.time({
+ ret <- try({
+ # Run the test
+ silent <- (is.null(silent) || isTRUE(silent))
+ val <- inherits(res <- try(expr, silent = silent), "try-error")
+ }, silent = TRUE)
+ }, gcFirst = FALSE)[3])
+ # Log this test
+ test <- .logTest(timing)
+ # Decide if recording more info or not
+ minTiming <- getOption("svUnit.minTiming")
+ if (is.null(minTiming)) minTiming <- 0.1
+ if (!isTRUE(getOption("svUnit.recordAll")) && isTRUE(timing < minTiming)
+ && val) return(invisible(TRUE))
+ # Check for error
+ if (inherits(ret, "try-error")) {
+ val <- NA
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:2], nlines = 1), timing = timing, val = -1,
+ res = as.character(ret))
+ } else {
+ .logTestData(test, msg = msg, call =
+ deparse(sys.call()[1:2], nlines = 1), timing = timing, val = val,
+ res = if (val) paste(res, collapse = "\n") else
+ "No exception generated!\n")
+ }
+ return(invisible(val))
+}
+
+DEACTIVATED <-
+function (msg = "")
+ stop(msg)
Added: pkg/svUnit/R/guiTestReport.R
===================================================================
--- pkg/svUnit/R/guiTestReport.R (rev 0)
+++ pkg/svUnit/R/guiTestReport.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,136 @@
+guiSuiteList <-
+function (sep = "\t", path = NULL, compare = TRUE) {
+ Suites <- svSuiteList()
+ if (compare) {
+ oldSuites <- .getTemp(".guiSuiteListCache", default = "")
+ # Compare both versions
+ if (!identical(Suites, oldSuites)) {
+ # Keep a copy of the last version in TempEnv
+ .assignTemp(".guiSuiteListCache", Suites)
+ Changed <- TRUE
+ } else Changed <- FALSE
+ } else {
+ Changed <- TRUE
+ .assignTemp(".guiSuiteListCache", Suites)
+ }
+ if (is.null(path)) { # Return result, as a single character string with sep
+ if (Changed) {
+ if (!is.null(sep)) Suites <- paste(Suites, collapse = sep)
+ return(Suites)
+ } else return(NULL)
+ } else { # Write to a file called 'Suites.txt' in this path
+ file <- file.path(path, "Suites.txt")
+ if (Changed) {
+ if (is.null(sep)) sep <- "\n"
+ cat(Suites, sep = sep, file = file)
+ }
+ return(invisible(Changed))
+ }
+}
+
+guiSuiteAutoList <-
+function (...) {
+ # Is koCmd() available?
+ if (!exists("koCmd", mode = "function")) return(TRUE)
+ # Is it something changed in the unit list?
+ res <- guiSuiteList(sep = ",", path = NULL, compare = TRUE)
+ if (!is.null(res))
+ ret <- get("koCmd")('sv.r.unit.getRUnitList_Callback("<<<data>>>");',
+ data = res)
+ return(TRUE)
+}
+
+guiTestFeedback <-
+function (object, path = NULL, ...) {
+ # Give feedback to client about the currently running tests
+ ### TODO: feedback about test run
+}
+
+guiTestReport <-
+function (object, sep = "\t", path = NULL, ...) {
+ # Report the results of a test to the GUI client
+ if (!is.svSuiteData(object))
+ stop("'object' must be a 'svSuiteData' object")
+
+ # For all 'svTestData' objects, create a table with test results for the GUI
+ # Indicate global results of the Unit Test
+ Tests <- ls(object)
+ if (length(Tests) == 0) {
+ Res <- "<<<svUnitSummary>>>|||0|||0|||0|||0"
+ } else {
+ # Get general information about the tests
+ Stats <- stats(object)
+ Tests <- rownames(Stats) # To make sure we use the same!
+ Stats$label <- paste(">", sub("^test", "", Tests), " (",
+ round(Stats$timing, 3), " sec)", sep = "")
+ State <- table(Stats$kind)
+ Res <- paste("<<<svUnitSummary>>>|||", State[1], "|||", State[2],
+ "|||", State[3], "|||", State[4], sep = "")
+ Kinds <- as.numeric(Stats$kind)
+ Kinds[Kinds == 4] <- 0 # Use 0 instead of 4 for deactivated tests
+ Stats$kind <- Kinds
+ # Get the type for the objects
+ Units <- Stats$unit
+ Types <- rep("units in packages", length(Units))
+ Types[Units == ""] <- "other objects"
+ ### TODO: include also dirs!
+ Dir1 <- dirname(Units)
+ Dir2 <- dirname(Dir1)
+ Dir3 <- dirname(Dir2)
+ Types[Dir1 == tempdir()] <- "objects in .GlobalEnv"
+ Types[tolower(basename(Dir2)) == "inst" ||
+ tolower(basename(Dir3)) == "inst"] <- "units in sources"
+ # Keep only "*" in Units
+ Units <- basename(Units)
+ Units[regexpr("^runit.+\\.[rR]$", Units) == -1] <- ""
+ Units[Dir1 == tempdir()] <- "" # No second level for objects in .GlobalEnv
+ Units <- sub("^runit(.+)\\.[rR]$", "\\1", Units)
+ change <- Units != ""
+ Units[change] <- paste(">unit", Units[change])
+ # Complete label is Type<Unit<Test (x.xxx sec)
+ Stats$label <- paste(Types, Units, Stats$label, sep = "")
+ # Sort Tests and Stats according to label alphabetically
+ ord <- order(Stats$label)
+ Stats <- Stats[ord, ]
+ Tests <- Tests[ord]
+ # Get detailed information about each test
+ lastUnit <- ""
+ for (Test in Tests) {
+ Data <- Stats[Test, ]
+ # Calculate Info
+ tData <- Log()[[Test]]
+ tStats <- stats(tData)
+ Info <- paste(c("Pass:", "Fail:", "Errors:"), tStats$kind[1:3],
+ collapse = " ")
+ # Don't print tests that succeed if !all
+ tData <- tData[tData$kind != "OK", ]
+ # Get info about each individual filtered test
+ if (nrow(tData) > 0) {
+ Result <- ifelse(tData$res == "", "",
+ paste("\n", tData$res, sep = ""))
+ Info <- paste(Info, "\n", paste("* ", tData$msg, ": ", tData$call,
+ .formatTime(tData$timing, secDigits = 3), " ... ",
+ as.character(tData$kind), Result, sep = "", collapse = "\n"),
+ sep = "")
+ }
+ # Calculate URI (currently, the name of the unit file # and
+ # the name of the test function)
+ if (Data$unit == "") URI <- Data$unit else
+ URI <- paste(Data$unit, Test, sep = "#")
+ if (Data$unit != lastUnit) {
+ lastUnit <- Data$unit
+ Res <- c(Res, paste("<<<svUnitFile>>>|||", Data$unit,
+ "|||||||||", sep = ""))
+ }
+ Res <- c(Res, paste("<<<svUnitTest>>>|||", Data$label, "|||",
+ Data$kind, "|||", Info, "|||", URI, sep = ""))
+ }
+ }
+ Res <- paste(gsub("\t", " ", Res), collapse = sep)
+ if (is.null(path)) {
+ return(Res)
+ } else {
+ cat(Res, file = path)
+ }
+ return(path)
+}
Added: pkg/svUnit/R/koUnit.R
===================================================================
--- pkg/svUnit/R/koUnit.R (rev 0)
+++ pkg/svUnit/R/koUnit.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,43 @@
+.koUnit <-
+function(cmd, warn = FALSE, ...) {
+ # Look if koCmd() exists, otherwise, we are probably not connected to Komodo
+ if (exists("koCmd", mode = "function")) {
+ res <- get("koCmd")(cmd, ...)
+ if (isTRUE(warn) & inherits(res, "try-error"))
+ warning("Komodo is not available or did not process this command correctly")
+ return(res)
+ } else {
+ if (isTRUE(warn))
+ warning("You must establish a connection with Komodo/SciViews-K to use this function")
+ }
+}
+
+koUnit_isAutoTest <-
+function () {
+ res <- .koUnit('sv.socket.serverWrite(sv.r.unit.isAutoTest());')
+ return(res == "true")
+}
+
+koUnit_setAutoTest <-
+function (state) {
+ if (isTRUE(state)) state <- "true" else state <- "false"
+ res <- .koUnit('sv.r.unit.setAutoTest(<<<data>>>);', data = state)
+}
+
+koUnit_runTest <-
+function () {
+ res <- .koUnit('sv.r.unit.runTest();')
+}
+
+koUnit_showRUnitPane <-
+function (state) {
+ if (missing(state)) state <- ""
+ else if (isTRUE(state)) state <- "true" else state <- "false"
+ res <- .koUnit('sv.r.unit.showRUnitPane(<<<data>>>);', data = state)
+}
+
+koUnit_version <-
+function () {
+ res <- .koUnit('sv.socket.serverWrite(sv.r.unit.version + "." + sv.r.unit.release);')
+ return(res)
+}
Deleted: pkg/svUnit/R/runUnit.R
===================================================================
--- pkg/svUnit/R/runUnit.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/R/runUnit.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,245 +0,0 @@
-runUnit <-
-function(name, dirs, print.errors = !interactive(), warn = print.errors,
- rngKind = "Marsaglia-Multicarry", rngNormalKind = "Kinderman-Ramage") {
- # Define a test suite and run it more silently than done in RUnit
- # Also, increment counters with errors, failings and deactivated
-
- # Define a test suite and run it (same as defineTestSuite() in RUnit)
- testSuite <- list(name = name, dirs = dirs,
- testFileRegexp = "^runit.+\\.[rR]$", testFuncRegexp = "^test.+",
- rngKind = rngKind, rngNormalKind = rngNormalKind)
- class(testSuite) <- "RUnitTestSuite"
-
- # runTestSuite() prints results of tests, but we prefer to run it
- # more silently than in RUnit
- runSuite <- function (testSuite) {
- file <- textConnection("rval", "w", local = TRUE)
- sink(file, type = "output")
- sink(file, type = "message")
- on.exit({
- sink(type = "output")
- sink(type = "message")
- close(file)
- })
- return(runTestSuite(testSuites = testSuite))
- }
- res <- runSuite(testSuite)
-
- # Check that res is a 'RUnitTestData' object
- if (!inherits(res, "RUnitTestData"))
- stop("Result of runTestSuite() is not a 'RUnitTestData' object")
-
- # If there are errors, failures or deactivated items, increment counters
- err <- list(nErr = 0, nDeactivated = 0, nFail = 0, nTestFunc = 0)
- for (i in seq(length = length(res))) {
- err$nErr <- err$nErr + res[[i]]$nErr
- err$nDeactivated <- err$nDeactivated + res[[i]]$nDeactivated
- err$nFail <- err$nFail + res[[i]]$nFail
- }
-
- if (err$nErr > 0) {
- if (exists(".tests.errors", envir = .GlobalEnv, inherits = FALSE)) {
- nErr <- get(".tests.errors", envir = .GlobalEnv, inherits = FALSE)
- } else nErr <- 0
- assign(".tests.errors", nErr + err$nErr, envir = .GlobalEnv)
- }
- if (err$nFail > 0) {
- if (exists(".tests.failures", envir = .GlobalEnv, inherits = FALSE)) {
- nFail <- get(".tests.failures", envir = .GlobalEnv, inherits = FALSE)
- } else nFail <- 0
- assign(".tests.failures", nFail + err$nFail, envir = .GlobalEnv)
- }
- if (err$nDeactivated > 0) {
- if (exists(".tests.deactivated", envir = .GlobalEnv, inherits = FALSE)) {
- nDeactivated <- get(".tests.deactivated", envir = .GlobalEnv,
- inherits = FALSE)
- } else nDeactivated <- 0
- assign(".tests.deactivated", nDeactivated + err$nDeactivated, envir = .GlobalEnv)
- if (warn) warning("Test unit '", name, "' has ", err$nDeactivated, " deactivated items")
- }
-
- # Change class to c('svUnitData', 'RUnitTestData') to overload summary()
- class(res) <- c('svUnitData', 'RUnitTestData')
-
- # Do we print a summary of these tests in case of errors or failures?
- if (print.errors && (err$nErr + err$nFail) > 0)
- summary(res)
-
- return(invisible(res))
-}
-
-print.svUnitData <-
-function(x, ...) {
- if (!inherits(x, "svUnitData"))
- stop("'x' must be a 'svUnitData' object")
- if (length(x) == 0) {
- cat("no test cases\n")
- return(invisible(TRUE))
- }
- err <- list(nErr = 0, nDeactivated = 0, nFail = 0, nTestFunc = 0)
- for (i in seq(length = length(x))) {
- err$nErr <- err$nErr + x[[i]]$nErr
- err$nDeactivated <- err$nDeactivated + x[[i]]$nDeactivated
- err$nFail <- err$nFail + x[[i]]$nFail
- err$nTestFunc <- err$nTestFunc + x[[i]]$nTestFunc
- }
- cat("Number of test functions:", err$nTestFunc, "\n")
- if (err$nDeactivated > 0)
- cat("Number of deactivated test functions:", err$nDeactivated, "\n")
- cat("Number of errors:", err$nErr, "\n")
- cat("Number of failures:", err$nFail, "\n")
- return(invisible(x))
-}
-
-summary.svUnitData <-
-function(object, ...) {
- if (!inherits(object, "svUnitData"))
- stop("'object' must be a 'svUnitData' object")
-
- sop <- function(number, word, plext = "s") {
- ifelse(number == 1, paste(number, word), paste(number,
- paste(word, plext, sep = "")))
- }
-
- if (length(object) == 0) {
- cat("no test cases\n")
- return(invisible(object))
- }
- err <- list(nErr = 0, nDeactivated = 0, nFail = 0, nTestFunc = 0)
- for (i in seq(length = length(object))) {
- err$nErr <- err$nErr + object[[i]]$nErr
- err$nDeactivated <- err$nDeactivated + object[[i]]$nDeactivated
- err$nFail <- err$nFail + object[[i]]$nFail
- err$nTestFunc <- err$nTestFunc + object[[i]]$nTestFunc
- }
- cat("Number of test functions:", err$nTestFunc, "\n")
- if (err$nDeactivated > 0)
- cat("Number of deactivated test functions:", err$nDeactivated, "\n")
- cat("Number of errors:", err$nErr, "\n")
- cat("Number of failures:", err$nFail, "\n")
-
- if (err$nErr + err$nDeactivated + err$nFail == 0)
- return(invisible(object))
-
- cat("Details:\n")
- traceBackCutOff <- 9 # Cut unintersting part of the traceBack
- for (tsName in names(object)) {
- tsList <- object[[tsName]]
- cat("===========================\n")
- cat("Test Suite:", tsName, "\n")
- if (length(tsList$dirs) == 0) {
- cat("No directories !\n")
- } else {
- res <- tsList$sourceFileResults
- testFileNames <- names(res)
- if (length(res) == 0) {
- cat("no test files\n")
- } else {
- for (testFileName in testFileNames) {
- testFuncNames <- names(res[[testFileName]])
- if (length(testFuncNames) > 0) {
- cat("---------------------------\n")
- cat("Test file:", testFileName, "\n")
- for (testFuncName in testFuncNames) {
- testFuncInfo <- res[[testFileName]][[testFuncName]]
- if (testFuncInfo$kind == "success") {
- cat(testFuncName, ":", " ... OK (", testFuncInfo$time,
- " seconds)\n", sep = "")
- } else {
- if (testFuncInfo$kind == "error") {
- cat(testFuncName, ": ERROR !!\n", sep = "")
- } else if (testFuncInfo$kind == "failure") {
- cat(testFuncName, ": FAILURE !! (check number ",
- testFuncInfo$checkNum, ")\n", sep = "")
- } else if (testFuncInfo$kind == "deactivated") {
- cat(testFuncName, ": DEACTIVATED, ")
- } else {
- cat(testFuncName, ": unknown error kind\n", sep = "")
- }
- cat(testFuncInfo$msg)
- if (length(testFuncInfo$traceBack) > 0) {
- cat(" Call Stack:\n")
- if (traceBackCutOff > length(testFuncInfo$traceBack)) {
- cat(" (traceBackCutOff argument larger than length of trace back: full trace back printed)")
- for (i in 1:length(testFuncInfo$traceBack)) {
- cat(" ", i, ": ", testFuncInfo$traceBack[i],
- "\n", sep = "")
- }
- } else {
- for (i in traceBackCutOff:length(testFuncInfo$traceBack)) {
- cat(" ", 1 + i - traceBackCutOff,
- ": ", testFuncInfo$traceBack[i],
- "\n", sep = "")
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return(invisible(TRUE))
-}
-
-unitClear <-
-function () {
- # Clear .tests.errors.tests.failures and .tests.deactivated from .GlobalEnv
- if (exists(".tests.errors", envir = .GlobalEnv, inherits = FALSE)) {
- nErr <- get(".tests.errors", envir = .GlobalEnv, inherits = FALSE)
- rm(".tests.errors", envir = .GlobalEnv, inherits = FALSE)
- } else nErr <- 0
- if (exists(".tests.failures", envir = .GlobalEnv, inherits = FALSE)) {
- nFail <- get(".tests.failures", envir = .GlobalEnv, inherits = FALSE)
- rm(".tests.failures", envir = .GlobalEnv, inherits = FALSE)
- } else nFail <- 0
- if (exists(".tests.deactivated", envir = .GlobalEnv, inherits = FALSE)) {
- nDeactivated <- get(".tests.deactivated", envir = .GlobalEnv,
- inherits = FALSE)
- rm(".tests.deactivated", envir = .GlobalEnv, inherits = FALSE)
- } else nDeactivated <- 0
- return(invisible(list(nErr = nErr, nDeactivated = nDeactivated,
- nFail = nFail)))
-}
-
-unitError <-
-function (errors = TRUE, failures = TRUE, deactivated = TRUE,
-stopit = TRUE) {
- # Read the content of .tests.errors and .tests.failures from .GlobalEnv
- allErr <- 0
- if (errors) {
- if (exists(".tests.errors", envir = .GlobalEnv, inherits = FALSE)) {
- nErr <- get(".tests.errors", envir = .GlobalEnv, inherits = FALSE)
- allErr <- nErr
- } else nErr <- 0
- } else nErr <- NA
-
- if (failures) {
- if (exists(".tests.failures", envir = .GlobalEnv, inherits = FALSE)) {
- nFail <- get(".tests.failures", envir = .GlobalEnv, inherits = FALSE)
- allErr <- allErr + nFail
- } else nFail <- 0
- } else nFail <- NA
-
- # Are there deactivated items?
- if (deactivated) {
- if (exists(".tests.deactivated", envir = .GlobalEnv, inherits = FALSE)) {
- nDeactivated <- get(".tests.deactivated", envir = .GlobalEnv,
- inherits = FALSE)
- if (stopit) # Issue a warning!
- warning("There are ", nDeactivated, " deactivated tests!")
- } else nDeactivated <- 0
- } else nDeactivated <- NA
-
- # Do we stop in case of any error?
- if (stopit && allErr > 0) {
- msg <- paste("\nUnit test errors: ", nErr, "\n")
- msg <- paste(msg, "Unit test failures: ", nFail, sep = "")
- stop(msg)
- }
- res <- (allErr == 0)
- attr(res, "errors") <- list(nErr = nErr, nDeactivated = nDeactivated,
- nFail = nFail)
- return(invisible(res))
-}
Added: pkg/svUnit/R/svSuite.R
===================================================================
--- pkg/svUnit/R/svSuite.R (rev 0)
+++ pkg/svUnit/R/svSuite.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,284 @@
+svSuite <-
+function (tests) {
+ # Check provided tests and build a 'svSuite' object
+ tests <- as.character(tests)
+ # Remove NAs and empty strings ("") from tests
+ tests <- tests[!is.na(tests) & !(tests == "")]
+ if (length(tests) > 0) {
+ # Tests must be character strings like:
+ # * package:PKG
+ # * package:PKG (TESTSUITE)
+ # * dir:MYDIR
+ # * test(OBJ) where OBJ is any object with a 'test' attribute
+ # * OBJ being a 'svTest' object (with non "exotic" name!),
+ # Syntax is checked, but not existence/validity of corresponding tests!
+ check1 <- (regexpr("^package:[a-zA-Z._]+$", tests) > -1)
+ check2 <- (regexpr("^package:[a-zA-Z._]+ *\\(.+\\)$", tests) > -1)
+ check3 <- (regexpr("^dir:.+", tests) > -1)
+ check4 <- (regexpr("^test\\(.+\\)$", tests) > -1)
+ check5 <- (regexpr("^[a-zA-Z0-9_.]+$", tests) > -1)
+ wrong <- ((check1 + check2 + check3 + check4 + check5) == 0)
+ if (any(wrong))
+ stop("Wrong 'tests' data: must be 'package:PKG', 'package:PKG (SUITE)',\n'dir:MYDIR', 'test(OBJ)' or 'OBJ'")
+ }
+ # This is a 'svSuite' object subclassing 'character'
+ class(tests) <- c("svSuite", "character")
+ return(tests)
+}
+
+as.svSuite <-
+function (x)
+ return(svSuite(x))
+
+is.svSuite <-
+function (x)
+ return(inherits(x, "svSuite"))
+
+print.svSuite <-
+function (x, ...) {
+ if (!is.svSuite(x))
+ stop("'x' must be a 'svSuite' object")
+ if (length(x) < 1) {
+ cat("An empty svUnit test suite\n")
+ } else {
+ cat("A svUnit test suite definition with:\n")
+ # Separate unit tests from tests embedded in objects
+ isSuite <- regexpr("^[package:|dir:]", x) > -1
+ if (any(isSuite)) {
+ Suites <- x[isSuite]
+ msg <- ifelse (length(Suites) == 1, "\n- Test suite:\n",
+ "\n- Test suites:\n")
+ cat(msg)
+ print(Suites)
+ }
+
+ if (any(!isSuite)) {
+ Objs <- x[!isSuite]
+ msg <- ifelse (length(Objs) == 1, "\n- Test function:\n",
+ "\n- Test functions:\n")
+ cat(msg)
+ print(Objs)
+ }
+ }
+ return(invisible(x))
+}
+
+svSuiteList <-
+function (packages = TRUE, objects = TRUE, dirs = getOption("svUnit.dirs"),
+ excludeList = getOption("svUnit.excludeList"), pos = .GlobalEnv,
+ loadPackages = FALSE) {
+ # List unit test (1) in loaded packages (2) in objects in pos and (3) in
+ # directories, possibly filtering them using an exclusion list
+ # Note: Komodo should list test unit files in loaded projects too!
+ if (length(packages) < 1)
+ stop("'package' cannot have zero length")
+ if (length(objects) < 1)
+ stop("'objects' cannot have zero length")
+
+ items <- character()
+
+ # 1) Unit test files in loaded packages
+ if (packages[1] != FALSE) {
+ if (is.character(packages)) { # We assume it is a list of packages
+ Pkgs <- packages
+ } else { # We use the list of all loaded packages
+ Pkgs <- .packages()
+ }
+ for (Pkg in Pkgs) {
+ # Look for test units in the package
+ path <- system.file(package = Pkg, "unitTests")
+ if (path != "" && file.info(path)$isdir) {
+ pkgname <- paste("package", Pkg, sep = ":")
+ items <- c(items, pkgname)
+ Files <- list.files(path = path, full.names = TRUE)
+ for (File in Files) { # Add all subdirectories too
+ if (file.info(File)$isdir)
+ items <- c(items, paste(pkgname, " (", basename(File),
+ ")", sep = ""))
+ }
+ }
+ }
+ }
+
+ # 2) Tests embedded in objects located in 'pos' environment
+ if (objects[1] != FALSE) {
+ envir = as.environment(pos)
+ if (is.character(objects)) {
+ tests <- character()
+ for (Oname in objects) {
+ if (exists(Oname, envir = envir, inherits = FALSE)) {
+ Obj <- get(Oname, envir = envir, inherits = FALSE)
+ if (is.svTest(Obj)) {
+ tests <- c(tests, Oname)
+ } else if (is.test(Obj)) {
+ tests <- c(tests, paste("test(", Oname, ")", sep = ""))
+ }
+ }
+ }
+ } else { # We list all objects in pos
+ Objs <- mget(ls(envir = envir), envir = envir)
+ Onames <- names(Objs)
+ tests <- character()
+ if (length(Objs) > 0) {
+ for (i in 1:length(Objs)) {
+ if (is.svTest(Objs[[i]])) {
+ tests <- c(tests, Onames[i])
+ } else if (is.test(Objs[[i]])) {
+ tests <- c(tests, paste("test(", Onames[i], ")", sep = ""))
+ }
+ }
+ }
+ }
+ items <- c(items, sort(tests))
+ }
+
+ # 3) Additional directories (check that they are valid and existing dirs)
+ if (!is.null(dirs)) {
+ # Check if each entry exists as a directory, exclude it if not
+ # Prepend "dir:" to tag them as additional directories
+ Dirs <- character()
+ for (Dir in dirs)
+ if (file.exists(Dir) && file.info(Dir)$isdir)
+ Dirs <- c(Dirs, paste("dir", Dir, sep = ":"))
+ items <- c(items, sort(Dirs))
+ }
+
+ # Filter the resulting list with 'excludeList'
+ if (!is.null(excludeList)) {
+ for (pattern in excludeList)
+ items <- items[regexpr(pattern, items) == -1]
+ }
+
+ # Do we load the package?
+ if (loadPackages) {
+ # Get a list of packages we need for the suite
+ Pkgs <- items[regexpr("^package:", items)]
+ PkgsSrch <- unique(sub(" +\\(.+$", "", Pkgs))
+ l <- length(PkgsSrch)
+ if (l > 0) {
+ PkgsName <- sub("^package:", "", PkgsSrch)
+ Search <- search()
+ for (i in 1:l) {
+ if (!PkgsSrch[i] %in% Search) {
+ res <- try(library(PkgsName[i], character.only = TRUE),
+ silent = TRUE)
+ if (inherits(res, "try-error"))
+ warning("Cannot load package '", PkgsName[i], "'")
+ }
+ }
+ }
+ }
+
+ # Make it a 'svSuite' object subclassing 'character'
+ class(items) <- c("svSuite", "character")
+ return(items)
+}
+
+makeUnit.svSuite <-
+function(x, name = make.names(deparse(substitute(x))), dir = tempdir(),
+objfile = "", codeSetUp = NULL, codeTearDown = NULL, pos = .GlobalEnv, ...) {
+ # Take an 'svSuite' object and make a unit from its function tests
+ # that are not written yet in a test unit in a file
+ # They are saved in a file named runit<name>.R in 'dir'
+ if (!is.svSuite(x))
+ stop("'x' must be a 'svSuite' object")
+ name <- as.character(name)[1]
+ # Collect all items that are not 'package:...' or 'dir:...'
+ isObj <- regexpr("^[package:|dir:]", x) == -1
+ Objs <- sub("^test[(](.+)[)]$", "\\1", x[isObj])
+ if (length(Objs) == 0) { # No objects, return NULL
+ return(NULL)
+ } else { # Make a sourceable test unit file with tests collected in Objs
+ Unit <- .prepareUnit(name, dir)
+ .writeSetUp(unit = Unit, file = objfile, code = codeSetUp)
+ .writeTearDown(unit = Unit, code = codeTearDown)
+ for (objname in Objs)
+ .writeTest(unit = Unit, objname = objname, pos = pos)
+ }
+ return(Unit)
+}
+
+runTest.svSuite <-
+function(x, name = make.names(deparse(substitute(x))), ...) {
+ # Compile and run the test for this 'svSuite' object
+ if (!is.svSuite(x))
+ stop("'x' must be a 'svSuite' object")
+ name <- as.character(name[1])
+
+ # Decode tests contained in x
+ tests <- as.character(x)
+ dirs <- character()
+ # Package suites...
+ isPkg <- regexpr("^package:", tests) > -1
+ if (any(isPkg)) {
+ Pkgs <- tests[isPkg]
+ Subdirs <- sub("^.+[(](.+)[)] *$", "\\1", Pkgs)
+ Subdirs[Subdirs == Pkgs] <- ""
+ Pkgs <- sub("^package:([^ ]+).*$", "\\1", Pkgs)
+ for (i in 1:length(Pkgs)) {
+ dir <- system.file(package = Pkgs[i], "unitTests", Subdirs[i])
+ if (dir != "") dirs <- c(dirs, dir)
+ }
+ }
+
+ # Add directories, and possibly make a temporary unit for test objects
+ if (any(!isPkg)) {
+ tests <- tests[!isPkg]
+ # Directories
+ isDir <- regexpr("^dir:", tests) > -1
+ if (any(isDir))
+ dirs <- c(sub("^dir:", "", tests[isDir]), dirs)
+ # Objects
+ if (any(!isDir)) {
+ # make a temporary unit for the tests of these objects
+ if (!is.null(Unit <- makeUnit(x, name = name))) {
+ # Add this path to dirs
+ dirs <- c(dirname(Unit), dirs)
+ }
+ }
+ }
+
+ # Now, list all files in these dirs with name being runit*.R
+ files <- character()
+ for (dir in dirs)
+ files <- c(files, list.files(dir, pattern = "^runit.+\\.[rR]$",
+ full.names = TRUE))
+ if (length(files) == 0) return(NULL) # Nothing to run!
+ # Run this test suite now, that is, source each file in .TestSuiteEnv
+ # and run each testxxx function in it, using .setUp and .tearDown too
+ # Record the list of tests
+ .lastSuite <- list()
+ for (file in files)
+ .lastSuite[[basename(file)]] <- list(file = file)
+ .Log <- Log()
+ .Log$.lastSuite <- .lastSuite
+
+ # Source each runit*.R file in turn
+ for (unit in names(.lastSuite)) {
+ # Create a new environment for this suite (created in .GlobalEnv so
+ # that we can inspect it in case of stop on error)
+ .TestSuiteEnv <<- new.env(parent = .GlobalEnv)
+ # Source the corresponding file
+ Unit <- .lastSuite[[unit]]$file
+ sys.source(Unit, envir = .TestSuiteEnv)
+ # Make sure there are .setUp() and .tearDown() functions
+ if (!exists(".setUp", envir = .TestSuiteEnv, mode = "function",
+ inherits = FALSE))
+ .TestSuiteEnv$.setUp <- function() {}
+ if (!exists(".tearDown", envir = .TestSuiteEnv, mode = "function",
+ inherits = FALSE))
+ .TestSuiteEnv$.tearDown <- function() {}
+ # List all test files in the unit
+ tests <- ls(.TestSuiteEnv, pattern = "^test.+$")
+ # Keep only 'test*' objects that are function
+ keep <- unlist(lapply(tests, function(n) exists(n,
+ envir = .TestSuiteEnv, mode = "function", inherits = FALSE)))
+ tests <- tests[keep]
+ .Log$.lastSuite[[unit]]$tests <- tests
+ # Run each test in turn
+ for (test in tests) {
+ .runTest(envir = .TestSuiteEnv, test = test, unit = Unit)
+ }
+ }
+ return(invisible(files))
+}
Added: pkg/svUnit/R/svSuiteData.R
===================================================================
--- pkg/svUnit/R/svSuiteData.R (rev 0)
+++ pkg/svUnit/R/svSuiteData.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,121 @@
+is.svSuiteData <-
+function (x) {
+ # It this a svSuiteData object
+ return(inherits(x, "svSuiteData"))
+}
+
+stats.svSuiteData <-
+function (object, ...) {
+ if (!is.svSuiteData(object))
+ stop("'object' must inherit from 'svSuiteData'")
+ # Get the list of tests
+ Tests <- ls(object)
+ if (length(Tests) == 0) {
+ # The object is empty!
+ Res <- data.frame(kind = .kind(logical()), timing = numeric(),
+ time = numeric(), unit = character(), tag = character(),
+ msg = character(), stringsAsFactors = FALSE)
+ } else {
+ # Functions to get data for each test
+ getKind <- function(x) .kindMax(x$kind)
+ getTiming <- function(x) attr(x, "stats")["timing"]
+ getTime <- function(x) attr(x, "time")
+ getContext <- function(x, item) attr(x, "context")[[item]]
+ Res <- data.frame(
+ kind = rev(sapply(object, getKind)),
+ timing = rev(sapply(object, getTiming)),
+ time = structure(rev(sapply(object, getTime)),
+ class = c("POSIXt", "POSIXct")),
+ unit = rev(sapply(object, getContext, "unit")),
+ msg = rev(sapply(object, getContext, "msg")),
+ stringsAsFactors = FALSE)
+ }
+ return(Res)
+}
+
+metadata <-
+function (object, ...)
+ UseMethod("metadata")
+
+metadata.svSuiteData <-
+function (object, fields = c("R.version", "sessionInfo", "time", "description"),
+...) {
+ # Extract metadata information from a 'svSuiteData' object
+ if (!is.svSuiteData(object))
+ stop("'object' must inherit from 'svSuiteData'")
+ # Return a list with all metadata elements found
+ fields <- paste(".", fields, sep = "")
+ Res <- list()
+ for (F in fields)
+ Res[[F]] <- object[[F]]
+ return(Res)
+}
+
+print.svSuiteData <-
+function (x, all = FALSE, file = "", append = FALSE, ...) {
+ if (!is.svSuiteData(x))
+ stop("'x' must inherit from 'svSuiteData'")
+ Tests <- ls(x)
+ if (length(Tests) == 0) {
+ cat("No test records!\n", file = file, append = append)
+ } else {
+ # Print general information about the tests
+ Stats <- stats(x)
+ Tests <- rownames(Stats) # To make sure we use the same!
+ Timing <- .formatTime(sum(Stats$timing, na.rm = TRUE), secDigits = 1)
+ cat("= A svUnit test suite", Timing, " with:\n\n", sep = "",
+ file = file, append = append)
+ cat(paste("* ", Tests, " ... ", as.character(Stats$kind), "",
+ sep = "", collapse = "\n"),
+ "\n\n", sep = "", file = file, append = TRUE)
+
+ # Print detailed information about each test
+ for (Test in Tests)
+ print(x[[Test]], all = all, file = file, append = TRUE, ...)
+ }
+ return(invisible(x))
+}
+
+summary.svSuiteData <-
+function (object, ...)
+ protocol_text.svSuiteData(object, ...)
+
+protocol <-
+function (object, type = "text", file = "", append = FALSE, ...)
+ UseMethod("protocol")
+
+protocol.default <-
+function (object, type = "text", file = "", append = FALSE, ...)
+ get(paste("protocol", type[1], sep = "_"))(object, file = file, append = append, ...)
+
+protocol.svSuiteData <-
+function (object, type = "text", file = "", append = FALSE, ...)
+ get(paste("protocol", type[1], sep = "_"))(object, file = file, append = append, ...)
+
+protocol_text <-
+function (object, file = "", append = FALSE, ...)
+ UseMethod("protocol_text")
+
+protocol_text.svSuiteData <-
+function (object, file = "", append = FALSE, ...) {
+ if (!is.svSuiteData(object))
+ stop("'object' must inherit from 'svSuiteData'")
+ Tests <- sort(ls(object))
+ if (length(Tests) == 0) {
+ cat("No test records!\n", file = file, append = append)
+ } else {
+ # Print general information about the tests
+ Stats <- stats(object)
+ Tests <- rownames(Stats) # To make sure we use the same!
+ Timing <- .formatTime(sum(Stats$timing, na.rm = TRUE), secDigits = 1)
+ cat("= A svUnit test suite", Timing, " with:\n\n", sep = "",
+ file = file, append = append)
+ cat(paste("* ", Tests, " ... ", as.character(Stats$kind), "",
+ sep = "", collapse = "\n"),
+ "\n\n", sep = "", file = file, append = TRUE)
+
+ # Summarize each test
+ for (Test in Tests)
+ summary(object[[Test]], file = file, append = TRUE)
+ }
+}
Modified: pkg/svUnit/R/svTest.R
===================================================================
--- pkg/svUnit/R/svTest.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/R/svTest.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,16 +1,24 @@
svTest <-
function (testFun) {
# Create a 'svTest' object, using testFun: a function without arguments
+ # that contains one or more checkXX() assertions
if (!is.function(testFun))
stop("'testFun' must be a function or a 'svTest' object")
# Check that there are no arguments
if (length(formals(testFun)) > 0)
stop("'testFun' must be a function without any arguments")
- # This is a S3 object of class 'svTest'
- class(testFun) <- "svTest"
+ # This is a S3 object of class 'svTest', subclassing 'function'
+ class(testFun) <- c("svTest", "function")
return(testFun)
}
+print.svTest <-
+function (x, ...) {
+ cat("svUnit test function:\n")
+ print(body(x))
+ return(invisible(x))
+}
+
as.svTest <-
function (x) {
# Coercion to a 'svTest' object
@@ -25,8 +33,8 @@
is.test <-
function (x) {
- # Is this a test object (indeed a 'svTest' one)
- # or do this object contain a non NULL 'test' attribute
+ # Is this a 'svTest'object
+ # or do this object contain a non NULL 'test' attribute?
return(is.svTest(x) || !is.null(attr(x, "test")))
}
@@ -37,93 +45,75 @@
if (is.svTest(x)) {
return(x)
} else {
- return(attr(x, "test"))
+ res <- attr(x, "test")
+ if (is.null(res)) {
+ # Create a dummy test with only a DEACTIVATED entry
+ res <- svTest(function() DEACTIVATED("Object has no tests!"))
+ }
+ return(res)
}
}
`test<-` <-
function (x, value) {
- # Add 'value' as a 'test' attribute to 'x' after coercing to 'svTest'
+ # Add 'value' as a 'test' attribute to 'x' after coercing it to 'svTest'
attr(x, "test") <- as.svTest(value)
return(x)
}
makeUnit <-
-function(x, ...)
+function (x, ...)
UseMethod("makeUnit")
makeUnit.default <-
-function(x, name = make.names(deparse(substitute(x))), dir = tempdir(), ...) {
+function (x, name = make.names(deparse(substitute(x))), dir = tempdir(),
+objfile = "", codeSetUp = NULL, codeTearDown = NULL, ...) {
# Take an object and make a unit from the tests it contains
- # It is saved in a file runit.<name>.R in 'dir'
- name <- as.character(name[1])
- dir <- as.character(dir[1])
- # Check that dir exists (do not create it!)
- if (!file.exists(dir) || !file.info(dir)$isdir)
- stop("'dir' must be an existing directory")
-
- Unit <- file.path(dir, paste("runit", name, "R", sep = "."))
- cat("# Test unit '", name, "'\n", sep = "", file = Unit)
-
+ # It is saved in a file runit<name>.R in 'dir'
+ name <- as.character(name)[1]
+ name <- sub("^test\\.(.+)\\.$", "\\1", name)
+ Unit <- .prepareUnit(name, dir)
# Just get the test from the object
Test <- test(x)
- # Make sure the name start with "test."
- if (regexpr("^test\\.", name) > -1) testname <- name else
- testname <- paste("test", name, sep = ".")
- testname <- make.names(testname)
- cat('\n"', testname, '" <-\n', sep = "", file = Unit, append = TRUE)
- if (is.null(Test)) {
- # Create a dummy test with DEACTIVATED entry
- body <- c(
- 'function() {',
- paste('\tDEACTIVATED("Object', deparse(substitute(x)), 'has no tests!")'),
- '}\n')
- } else {
- capture.body <-
- function(Data) {
- rval <- NULL
- File <- textConnection("rval", "w", local = TRUE)
- sink(File)
- on.exit({ sink(); close(File) })
- dput(Data, file = File, control = "useSource")
- on.exit()
- sink()
- close(File)
- return(rval)
- }
- body <- capture.body(Test)
- }
- cat(body, sep = "\n", file = Unit, append = TRUE)
-
+ # Make required initialisation to allow locating objects
+ .writeSetUp(unit = Unit, file = objfile, code = codeSetUp)
+ .writeTearDown(unit = Unit, code = codeTearDown)
+ # Write the test function in the file
+ .writeTest(unit = Unit, objname = name, obj = x)
+ # Return the name of the test function
return(Unit)
}
makeUnit.svTest <-
-function(x, name = make.names(deparse(substitute(x))), dir = tempdir(), ...)
- return(makeUnit.default(x, name = name, dir = dir, ...))
+function (x, name = make.names(deparse(substitute(x))), dir = tempdir(),
+objfile = "", codeSetUp = NULL, codeTearDown = NULL, ...) {
+ # I know: this is not needed, but it is there in case additional work
+ # would be needed in the future, and also to show that makeUnit is
+ # designed to work on 'svTest' objects
+ return(makeUnit.default(x, name = name, dir = dir, objfile = objfile,
+ codeSetUp = codeSetUp, codeTearDown = codeTearDown, ...))
+}
runTest <-
-function(x, ...)
+function (x, ...)
UseMethod("runTest")
runTest.default <-
-function(x, name = make.names(deparse(substitute(x))), ...) {
+function (x, name = deparse(substitute(x)), objfile = "", tag = "", msg = "",
+...) {
# Run the test for the 'test' attribute of this object
- Test <- test(x)
- if (is.null(Test) || !inherits(Test, "svTest"))
- Test <- svTest(function () DEACTIVATED("Object has no tests!"))
- return(runTest(Test, name = name, ...))
+ name <- paste("test(", name, ")", sep = "")
+ return(runTest(test(x), name = name, objfile = objfile, tag = tag, msg = msg, ...))
}
runTest.svTest <-
-function(x, name = make.names(deparse(substitute(x))), ...) {
- # Make a test unit with the test data
- Unit <- makeUnit(x, name = name, ...)
- if (is.null(Unit)) return(NULL) # No tests to run!
- # Make sure that the temporary test unit file is destroyed when done
- on.exit(unlink(Unit))
-
- # Run the tests now
- res <- runUnit(name = name, dirs = dirname(Unit), ...)
- return(res)
+function (x, name = deparse(substitute(x)), objfile = "", tag = "", msg = "",
+...) {
+ if (!is.svTest(x))
+ stop("'x' must be a 'svTest' object")
+ # Names of object and test
+ test <- as.character(name)[1]
+ test <- .runTest(x, test = test, objfile = objfile, tag = tag, msg = msg)
+ .Log <- Log()
+ return(invisible(.Log[[test]]))
}
Added: pkg/svUnit/R/svTestData.R
===================================================================
--- pkg/svUnit/R/svTestData.R (rev 0)
+++ pkg/svUnit/R/svTestData.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,85 @@
+is.svTestData <-
+function (x) {
+ # It this a svTestData object
+ return(inherits(x, "svTestData"))
+}
+
+stats <-
+function (object, ...)
+ UseMethod("stats")
+
+stats.svTestData <-
+function (object, ...) {
+ if (!is.svTestData(object))
+ stop("'object' must inherit from 'svTestData'")
+ Stats <- attr(object, "stats")
+ Table <- table(object$kind)
+ # Update the table with the total number of test
+ Kinds <- c(Stats["tests"] - sum(Table[2:4], na.rm = TRUE), Table[2:4])
+ names(Kinds) <- names(Table)
+ # Return a list with the table of kinds and the total timing
+ return(list(kind = Kinds, timing = Stats["timing"]))
+}
+
+print.svTestData <-
+function (x, all = FALSE, header = TRUE, file = "", append = FALSE, ...) {
+ # If there is a context attribute, print info about the tests
+ cat("", file = file, append = append)
+ Context <- attr(x, "context")
+ if (!is.null(Context)) {
+ unitStr <- if (Context["unit"] == "") "" else
+ paste(" (in ", basename(Context["unit"]), ")", sep = "")
+ Stats <- stats(x)
+ if (isTRUE(header))
+ cat("\n== ", Context["test"], unitStr, .formatTime(Stats$timing,
+ secDigits = 1), ": ", as.character(.kindMax(x$kind)), "\n",
+ Context["msg"], "\n", sep = "", file = file, append = TRUE)
+ cat(paste(c("//Pass:", "Fail:", "Errors:"), Stats$kind[1:3],
+ collapse = " "), "//\n\n", sep = "", file = file, append = TRUE)
+ # Don't print tests that succeed if !all
+ if (!isTRUE(all)) X <- x[x$kind != "OK", ] else X <- x
+ } else X <- x
+ # Print info about each individual filtered test
+ if (nrow(X) > 0) {
+ Res <- ifelse(X$res == "", "", paste("\n", X$res, sep = ""))
+ cat(paste("* ", X$msg, ": ", X$call, .formatTime(X$timing,
+ secDigits = 3), " ... ", as.character(X$kind), Res, sep = "",
+ collapse = "\n"), file = file, append = TRUE)
+ }
+ return(invisible(x))
+}
+
+summary.svTestData <-
+function (object, header = TRUE, file = "", append = FALSE, ...) {
+ # If there is a context attribute, print info about the tests
+ cat("", file = file, append = append)
+ Context <- attr(object, "context")
+ if (!is.null(Context)) {
+ unitStr <- if (Context["unit"] == "") "" else
+ paste(" (in ", basename(Context["unit"]), ")", sep = "")
+ Stats <- stats(object)
+ if (isTRUE(header))
+ cat("\n== ", Context["test"], unitStr, .formatTime(Stats$timing,
+ secDigits = 1), ": ", as.character(.kindMax(object$kind)), "\n",
+ Context["msg"], "\n", sep = "", file = file, append = TRUE)
+ cat(paste(c("//Pass:", "Fail:", "Errors:"), Stats$kind[1:3],
+ collapse = " "), "//\n\n", sep = "", file = file, append = TRUE)
+ }
+ # List tests that failed
+ Items <- rownames(object)
+ Fail <- object$kind == "**FAILS**"
+ if (any(Fail)) {
+ cat("=== Failures\n", file = file, append = TRUE)
+ cat(paste("[", Items[Fail], "] ", object$msg[Fail], ": ",
+ object$call[Fail], collapse = "\n", sep = ""), "\n\n",
+ sep = "", file = file, append = TRUE)
+ }
+ # List tests that give errors
+ Err <- object$kind == "**ERROR**"
+ if (any(Err)) {
+ cat("=== Errors\n", file = file, append = TRUE)
+ cat(paste("[", Items[Err], "] ", object$msg[Err], ": ",
+ object$call[Err], collapse = "\n", sep = ""), "\n\n",
+ sep = "", file = file, append = TRUE)
+ }
+}
Added: pkg/svUnit/R/svUnit-internal.R
===================================================================
--- pkg/svUnit/R/svUnit-internal.R (rev 0)
+++ pkg/svUnit/R/svUnit-internal.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,422 @@
+.onLoad <-
+function (lib, pkg) {
+ # The default exclusion list, if it is not defined yet
+ # Although there are unit tests defined in these packages (as examples),
+ # we don't want to include them, by default, in our test suite!
+ if (is.null(getOption("svUnit.excludeList")))
+ options(svUnit.excludeList = c("package:sv", "package:RUnit"))
+ # Look if the SciViews-K Unit Komodo extension is installed
+ .installUpgradeKomodoExtension()
+ # Install a callback to update the list of units automatically in the GUI
+ .assignTemp(".taskCallbackId", addTaskCallback(guiSuiteAutoList))
+}
+
+.onUnload <-
+function (libpath) {
+ # Delete the taskCallback
+ taskCallbackId <- .getTemp(".taskCallbackId", NULL)
+ if (!is.null(taskCallbackId)) removeTaskCallback(taskCallbackId)
+ # and clear the list of units in the GUI client
+ if (exists("koCmd", mode = "function"))
+ get("koCmd")('sv.r.unit.getRUnitList_Callback("");')
+}
+
+.packageName <- "svUnit"
+
+.komodoExtensionMinVersion <- "0.6.0"
+
+.installUpgradeKomodoExtension <-
+function () {
+ if (!exists("koCmd", mode = "function")) return()
+ # Look if the SciViews-K Unit Komodo extension is installed and is of the
+ # right version. Otherwise, propose to install, or update it
+ xpiFile <- system.file("komodo", "sciviewskunit-ko.xpi", package = "svUnit")
+ koVersion <- get("koCmd")('sv.socket.serverWrite(sv.r.unit.version + "." + sv.r.unit.release);')
+ if (inherits(koVersion, "try-error")) {
+ # We need to install the extension
+ cmd <- 'var res = ko.dialogs.okCancel("The SciViews-K Unit extension is required by svUnit",'
+ cmd <- paste(cmd, '"OK", "Do you want to install the SciViews-K Unit extension now in Komodo?')
+ cmd <- paste(cmd, 'You will be prompted for confirmation (click \'Install Now\')')
+ cmd <- paste(cmd, 'and will have to restart Komodo at the end of the installation')
+ cmd <- paste(cmd, '(click \'Restart Komodo\').", "svUnit");')
+ cmd <- paste(cmd, ' if (res == "OK") { ko.open.URI("<<<data>>>"); }', sep = "")
+ get("koCmd")(cmd, data = xpiFile)
+ } else if (.compareVersion(koVersion, .komodoExtensionMinVersion) == -1) {
+ # We need to upgrade the extension
+ cmd <- 'var res = ko.dialogs.okCancel("A newer SciViews-K Unit extension is required by svUnit",'
+ cmd <- paste(cmd, '"OK", "Your SciViews-K Unit extension is too old for this version of svUnit.')
+ cmd <- paste(cmd, 'Do you want to upgrade it now?')
+ cmd <- paste(cmd, 'You will be prompted for confirmation (click \'Install Now\')')
+ cmd <- paste(cmd, 'and will have to restart Komodo at the end of the installation')
+ cmd <- paste(cmd, '(click \'Restart Komodo\').", "svUnit");')
+ cmd <- paste(cmd, ' if (res == "OK") { ko.open.URI("<<<data>>>"); }', sep = "")
+ get("koCmd")(cmd, data = xpiFile)
+ }
+}
+
+.compareVersion <-
+function (a, b) {
+ # This is the same as compareVersion() in utils, but we don't want dependencies on utils
+ if (is.na(a))
+ return(-1)
+ if (is.na(b))
+ return(1)
+ a <- as.integer(strsplit(a, "[\\.-]")[[1]])
+ b <- as.integer(strsplit(b, "[\\.-]")[[1]])
+ for (k in 1:length(a)) {
+ if (k <= length(b)) {
+ if (a[k] > b[k])
+ return(1)
+ else if (a[k] < b[k])
+ return(-1)
+ }
+ else {
+ return(1)
+ }
+ }
+ if (length(b) > length(a))
+ return(-1)
+ else return(0)
+}
+
+.kindLevels <- c("OK", "**FAILS**", "**ERROR**", "DEACTIVATED")
+
+.kind <-
+function (val = TRUE) {
+ # TRUE or 1 -> 1 = "OK"
+ # FALSE or 0 -> 2 = "**FAILS**"
+ # -1 -> 3 = "**ERROR**"
+ # -2 -> 4 = "DEACTIVATED"
+ factor(.kindLevels[-(as.integer(val) - 2)], levels = .kindLevels)
+}
+
+.kindMax <-
+function (kinds) {
+ # If there are no record, must be because all tests succeed!
+ if (length(kinds) == 0) return(.kind(TRUE))
+ Kinds <- as.numeric(kinds)
+ if (sum(Kinds, na.rm = TRUE) == 0) return(.kind(NA))
+ factor(.kindLevels[max(as.numeric(kinds), na.rm = TRUE)],
+ levels = .kindLevels)
+}
+
+.formatTime <-
+function (x, secDigits = 0, minSec = 10^-secDigits, prepend = " run in") {
+ # x is given in seconds, and it returns a pretty formatted string with time
+ if (is.null(x) || is.na(x)[1]) return("")
+ x <- as.numeric(x)
+ Sec <- round(x %% 60, digits = secDigits)
+ Min <- x %/% 60
+ Hour <- Min %/% 60
+ Min <- Min %% 60
+ Time <- prepend
+ Time <- ifelse (Hour > 0, paste(Time, Hour, "h"), Time)
+ Time <- ifelse (Min > 0 | Time != prepend, paste(Time, Min, "min"), Time)
+ Time <- ifelse (Sec > minSec | Time != prepend, paste(Time, Sec, "sec"), Time)
+ Time <- ifelse (Time == prepend, paste(prepend, "less than", minSec, "sec"), Time)
+ Time[is.na(Time)] <- ""
+ return(Time)
+}
+# Test: .formatTime((0:10)*400 + 0.56)
+
+.formatResult <-
+function (result, level = getOption("svUnit.strLevel")) {
+ if (is.null(level)) level <- 1 else level <- as.integer(level[1])
+ if (level < 1) return("") # Return an empty string
+ # Capture the report returned by the str() function
+ capture.str <- function(data, level) {
+ rval <- NULL
+ file <- textConnection("rval", "w", local = TRUE)
+ sink(file, type = "output")
+ sink(file, type = "message")
+ on.exit({
+ sink(type = "output")
+ sink(type = "message")
+ close(file)
+ })
+ str(data, max.level = level)
+ cat("\n")
+ return(rval)
+ }
+ Str <- capture.str(result, level)
+ return(paste(Str, collapse = "\n"))
+}
+
+.logTest <-
+function (timing, test, msg = "", description = NULL) {
+ .Log <- Log(description = description)
+ # Determine the name of the test
+ if (missing(test)) { # Is it defined globally?
+ if (exists("..Test", envir = .Log, inherits = FALSE)) {
+ test <- .Log$..Test
+ } else { # Try to guess it from the call
+ ret <- try(test <- as.character(sys.call(-2))[1], silent = TRUE)
+ if (inherits(ret, "try-error") || is.na(test)) {
+ # check...() probably called directly at the command line
+ test <- "eval" # This is convenient for collecting these tests
+ # together with tests run directly inside runit*.R files (tests
+ # not embedded in test functions)
+ } else if (test == "runTest") {
+ # Special case for runTest(myTest) or runTest(test(foo))
+ test <- as.character(sys.call(-2))[2]
+ } else if (test == "eval.with.vis") {
+ test <- "eval"
+ }
+ }
+ }
+ # Do we need to create 'test'?
+ if (!exists(test, envir = .Log, inherits = FALSE)) {
+ if (msg == "") msg <- .Log$..Msg
+ .Log[[test]] <- structure(
+ data.frame(
+ msg = character(),
+ call = character(),
+ timing = numeric(),
+ kind = .kind(logical()),
+ res = character(),
+ obj = character(),
+ file = character(),
+ tag = character(),
+ stringsAsFactors = FALSE),
+ time = Sys.time(),
+ stats = c(tests = 1, timing = timing),
+ context = c(unit = as.character(.Log$..Unit), test = test,
+ msg = paste(msg, collapse = "\n")),
+ class = c("svTestData", "data.frame"))
+ } else {
+ # Just update stats
+ attr(.Log[[test]], "stats") <-
+ attr(.Log[[test]], "stats") + c(1, timing)
+ }
+ return(test)
+}
+
+.logTestData <-
+function (test, msg, call, timing, val, kind = .kind(val), res,
+obj = .Log$..Obj, file = .Log$..File, tag = .Log$..Tag,
+printTest = getOption("svUnit.printTest")) {
+ # Add these data to .lastTest
+ .Log$.lastTest <- structure(data.frame(
+ msg = msg, call = call, timing = timing, kind = kind, res = res,
+ obj = obj, file = file, tag = tag, stringsAsFactors = FALSE),
+ class = c("svTestData", "data.frame"),
+ row.names = as.character(attr(.Log[[test]], "stats")["tests"]))
+ # Add them also to the log of my test
+ .Log[[test]][nrow(.Log[[test]]) + 1, ] <- .Log$.lastTest
+ # Do we print detailed results for this test?
+ if (is.null(printTest)) printTest <- !interactive() # Guess it from context
+ if (isTRUE(printTest)) print(.Log$.lastTest)
+}
+
+.prepareUnit <-
+function (name, dir) {
+ # Prepare for writing a test unit file
+ dir <- as.character(dir)[1]
+ # Check that dir exists (do not create it!)
+ if (!file.exists(dir) || !file.info(dir)$isdir)
+ stop("'dir' must be an existing directory")
+ # If dir is tempdir(), then, make sure there are no other runit*.R files
+ # left (should not!) - One can store only one unit at a time in tempdir()!
+ if (dir == tempdir()) {
+ runitfiles <- list.files(dir, pattern = "^runit.*\\.[r|R]$",
+ full.names = TRUE)
+ unlink(runitfiles)
+ }
+ Unit <- file.path(dir, paste("runit", name, ".R", sep = ""))
+ cat("## Test unit '", name, "'\n", sep = "", file = Unit)
+ return(Unit)
+}
+
+.writeSetUp <-
+function (unit, file = "", msg = "", tag = "", code = NULL) {
+ # Write the .setUp() function in the test unit file
+ # Here, we write a context to localize tested objects and test unit files
+ catUnit <- function(...) cat(..., sep = "", file = unit, append = TRUE)
+ catUnit('\n.setUp <-\n')
+ catUnit('function () {\n')
+ catUnit('\t## Specific actions for svUnit: prepare context\n')
+ catUnit('\tif ("package:svUnit" %in% search()) {\n')
+ catUnit('\t\t.Log <- Log() ## Make sure .Log is created\n')
+ catUnit('\t\t.Log$..Unit <- "', unit, '"\n')
+ catUnit('\t\t.Log$..File <- "', as.character(file)[1], '"\n')
+ catUnit('\t\t.Log$..Obj <- ""\n')
+ catUnit('\t\t.Log$..Tag <- "', tag, '"\n')
+ catUnit('\t\t.Log$..Msg <- "', paste(msg, collapse = "\n"), '"\n')
+ catUnit('\t\trm(..Test, envir = .Log)\n')
+ catUnit('\t}\n')
+ if (!is.null(code)) catUnit(paste("\t", code, collapse = "\n"))
+ catUnit('}\n')
+}
+
+.writeTearDown <-
+function (unit, code = NULL, rm.unit = TRUE, rm.file = TRUE) {
+ # Write the .tearDown() function in the test unit file
+ # Here, we undo what was done in .setUp()
+ catUnit <- function(...) cat(..., sep = "", file = unit, append = TRUE)
+ catUnit('\n.tearDown <-\n')
+ catUnit('function () {\n')
+ if (!is.null(code)) catUnit(paste("\t", code, collapse = "\n"))
+ catUnit('\t## Specific actions for svUnit: clean up context\n')
+ catUnit('\tif ("package:svUnit" %in% search()) {\n')
+ catUnit('\t\t.Log$..Unit <- ""\n')
+ catUnit('\t\t.Log$..File <- ""\n')
+ catUnit('\t\t.Log$..Obj <- ""\n')
+ catUnit('\t\t.Log$..Tag <- ""\n')
+ catUnit('\t\t.Log$..Msg <- ""\n')
+ catUnit('\t\trm(..Test, envir = .Log)\n')
+ catUnit('\t}\n')
+ catUnit('}\n')
+}
+
+.writeTest <-
+function (unit, objname, pos = .GlobalEnv, obj = NULL) {
+ # Make sure that the name of a test function is syntactically correct
+ # and starts with 'test'
+ if (regexpr("^test", objname) > -1) {
+ testname <- objname
+ } else {
+ testname <- paste("test", objname, sep = "")
+ }
+ # Write the first line in the file
+ catUnit <- function(...) cat(..., file = unit, append = TRUE)
+ catUnit('\n"', testname, '" <-\n', sep = "")
+ # Get the object
+ if (missing(obj)) {
+ # Look for 'objname' in 'pos'
+ if (!exists(objname, where = pos)) {
+ Test <- ""
+ } else {
+ Test <- test(get(objname, pos = pos))
+ }
+ } else {
+ Test <- test(obj)
+ }
+ if (is.character(Test)) {
+ # Create a dummy test with DEACTIVATED entry indicating missing object
+ body <- c(
+ 'function() {',
+ paste('\tDEACTIVATED("Object', objname, 'not found!")'),
+ '}\n')
+ } else if (is.null(Test)) {
+ # Create a dummy test with DEACTIVATED entry indicating missing test
+ body <- c(
+ 'function() {',
+ paste('\tDEACTIVATED("Object', objname, 'has no tests!")'),
+ '}\n')
+ } else {
+ # Get the body of the test function
+ capture.body <- function(Data) {
+ rval <- NULL
+ File <- textConnection("rval", "w", local = TRUE)
+ sink(File)
+ on.exit({ sink(); close(File) })
+ dput(Data, file = File, control = "useSource")
+ on.exit()
+ sink()
+ close(File)
+ return(rval)
+ }
+ body <- capture.body(Test)
+ }
+ # Write the boby of the test function in the file
+ catUnit(body, sep = "\n")
+}
+
+.runTest <-
+function (x, envir, test, objfile = "", unit = "", tag = "", msg = "") {
+ # Run one test in a protected environment catching errors and warnings
+ # and preparing a suitable context
+ name <- sub("^test\\.(.+)\\.$", "\\1", test)
+
+ # The context is written in the .Log, but previous context is saved
+ # and restored on return
+ .Log <- Log() # Make sure that .Log exists, or create a new one
+ oContext <- c(Unit = .Log$..Unit, Obj = .Log$..Obj, File = .Log$..File,
+ Msg = .Log$..Msg, Tag = .Log$..Tag)
+ on.exit({
+ .Log$..Unit <- oContext[1]
+ .Log$..Obj <- oContext[2]
+ .Log$..File <- oContext[3]
+ .Log$..Msg <- oContext[4]
+ .Log$..Tag <- oContext[5]
+ })
+ .Log$..Unit <- unit # The unit file
+ .Log$..Obj <- name # Name of the tested object
+ .Log$..File <- objfile # Where is the code source of 'name'?
+ .Log$..Msg <- paste(msg, collapse = "\n") # Message for this test
+ .Log$..Tag <- tag # A tag in objfile to locate code
+ # Define the test and save possible existing definition to restore it
+ if (exists("..Test", envir = .Log, inherits = FALSE)) {
+ oTest <- .Log$..Test
+ on.exit(.Log$..Test <- oTest, add = TRUE)
+ } else on.exit(rm("..Test", envir = .Log), add = TRUE)
+ .Log$..Test <- test # Define the name of the test
+
+ if (missing(envir)) {
+ # The environment where the test is run
+ envir <- new.env(parent = .GlobalEnv)
+ envir[[test]] <- x # A copy of the test code
+ envir$.setUp <- function() {} # Fake .setUp
+ envir$.tearDown <- function() {} # Fake .tearDown
+ }
+ # We need this installed in our sandbox .TestEnv to run the test
+ envir$.LogWarnings <- list() # A list to collect warnings
+
+ # Clear the corresponding log, if it exists
+ if (exists(test, envir = .Log, inherits = FALSE))
+ rm(list = test, envir = .Log)
+
+ # Evaluate the test function in .testEnv, catching errors
+ owarn <- getOption("warn")
+ on.exit(options(warn = owarn), add = TRUE)
+ if (isTRUE(getOption("svUnit.StopOnWarning"))) nwarn <- 2 else nwarn <- -1
+ options(warn = nwarn)
+
+ # Evaluate the test function in the .TestEnv environment
+ cmd <- paste("evalq(.LogRes <- try( { .setUp(); ", test,
+ "(); .tearDown() }, silent = TRUE), envir = envir)", sep = "")
+ eval(parse(text = cmd))
+
+ # Analyze error => is it a deactivation or error in the code?
+ if (inherits(Res <- envir$.LogRes, "try-error")) {
+ # We record this as a test returning **ERROR** or DEACTIVATED
+ .logTest(0, test)
+ # Is it because we encountered a DEACTIVATED() command or something else?
+ if (regexpr("DEACTIVATED\\(", Res) > -1) {
+ Msg <- sub("^[^:]+: *", "", as.character(Res))
+ Msg <- sub("\n$", "", Msg)
+ .logTestData(test, msg = Msg, call = "", timing = NA,
+ val = -2, res = "\n")
+ } else {
+ # This is an error (something wrong with the code in the test fun)
+ .logTestData(test, msg = "", call = deparse(sys.call()),
+ timing = NA, val = -1, res = paste(Res, collapse = "\n"))
+ }
+ }
+ return(test)
+}
+
+.assignTemp <-
+function (x, value)
+ assign(x, value, envir = .TempEnv())
+
+.getTemp <-
+function (x, default = character(0)) {
+ if (exists(x, envir = .TempEnv(), inherits = FALSE)) {
+ return(get(x, envir = .TempEnv(), inherits = FALSE))
+ } else { # Variable not found, return the default value
+ return(default)
+ }
+}
+
+.TempEnv <-
+function() {
+ pos <- match("TempEnv", search())
+ if (is.na(pos)) { # Must create it
+ TempEnv <- list()
+ attach(TempEnv, pos = length(search()) - 1)
+ rm(TempEnv)
+ pos <- match("TempEnv", search())
+ }
+ return(pos.to.env(pos))
+}
Deleted: pkg/svUnit/R/svUnit.R
===================================================================
--- pkg/svUnit/R/svUnit.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/R/svUnit.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,245 +0,0 @@
-svUnit <-
-function (tests) {
- # Check provided tests and build a 'svUnit' object
- tests <- as.character(tests)
- # Remove NAs and empty strings ("") from tests
- tests <- tests[!is.na(tests) & !(tests == "")]
- if (length(tests) > 0) {
- # Tests must be character strings like:
- # * package:PKG
- # * package:PKG (TESTSUITE)
- # * dir:MYDIR
- # * test(OBJ) where OBJ is any object with a 'test' attribute
- # * OBJ being a 'svTest' object (with non "exotic" name!),
- # Syntax is checked, but not the existence/validity of corresponding tests!
- check1 <- (regexpr("^package:[a-zA-Z._]+$", tests) > -1)
- check2 <- (regexpr("^package:[a-zA-Z._]+ *\\(.+\\)$", tests) > -1)
- check3 <- (regexpr("^dir:.+", tests) > -1)
- check4 <- (regexpr("^test\\(.+\\)$", tests) > -1)
- check5 <- (regexpr("^[a-zA-Z0-9_.]+$", tests) > -1)
- wrong <- ((check1 + check2 + check3 + check4 + check5) == 0)
- if (any(wrong))
- stop("Wrong 'test' data: must be 'package:PKG', 'package:PKG (SUITE)',\n'dir:MYDIR', 'test(OBJ)' or 'OBJ'")
- }
- class(tests) <- "svUnit"
- return(tests)
-}
-
-as.svUnit <-
-function (x)
- return(svUnit(x))
-
-is.svUnit <-
-function (x)
- return(inherits(x, "svUnit"))
-
-print.svUnit <-
-function (x, ...) {
- if (!is.svUnit(x))
- stop("'x' must be a 'svUnit' object")
- if (length(x) < 1) {
- cat("An empty svUnit test suite\n")
- } else {
- cat("A svUnit test suite definition with:\n")
- # Separate unit tests from tests embedded in objects
- isSuite <- regexpr("^[package:|dir:]", x) > -1
- if (any(isSuite)) {
- Suites <- x[isSuite]
- msg <- ifelse (length(Suites) == 1, "\n- Test suite:\n",
- "\n- Test suites:\n")
- cat(msg)
- print(Suites)
- }
-
- if (any(!isSuite)) {
- Objs <- x[!isSuite]
- msg <- ifelse (length(Objs) == 1, "\n- Test function:\n",
- "\n- Test functions:\n")
- cat(msg)
- print(Objs)
- }
- }
- return(invisible(x))
-}
-
-svUnitList <-
-function (packages = TRUE, objects = TRUE, pos = .GlobalEnv) {
- # List unit test (1) in loaded packages and (2) in objects in pos
- # Note: Komodo should list test files in loaded projects too!
- if (length(packages) < 1)
- stop("'package' cannot have zero length")
- if (length(objects) < 1)
- stop("'objects' cannot have zero length")
-
- items <- character()
-
- # 1) Unit test files in loaded packages
- if (packages[1] != FALSE) {
- if (is.character(packages)) { # We assume it is a list of packages
- Pkgs <- packages
- } else { # We use the list of all loaded packages
- Pkgs <- .packages()
- }
- for (Pkg in Pkgs) {
- path <- system.file(package = Pkg, "unitTests")
- if (path != "" && file.info(path)$isdir) {
- pkgname <- paste("package", Pkg, sep = ":")
- items <- c(items, pkgname)
- Files <- list.files(path = path, full.names = TRUE)
- for (File in Files) { # Add all subdirectories too
- if (file.info(File)$isdir)
- items <- c(items, paste(pkgname, " (", basename(File),
- ")", sep = ""))
- }
- }
- }
- }
-
- # 2) Test embedded in objects located in 'pos' environment
- if (objects[1] != FALSE) {
- envir = as.environment(pos)
- if (is.character(objects)) {
- tests <- character()
- for (Oname in objects) {
- if (exists(Oname, envir = envir, inherits = FALSE)) {
- Obj <- get(Oname, envir = envir, inherits = FALSE)
- if (is.svTest(Obj)) {
- tests <- c(tests, Oname)
- } else if (is.test(Obj)) {
- tests <- c(tests, paste("test(", Oname, ")", sep = ""))
- }
- }
- }
- } else { # We list all objects in pos
- Objs <- mget(ls(envir = envir), envir = envir)
- Onames <- names(Objs)
- tests <- character()
- if (length(Objs) > 0) {
- for (i in 1:length(Objs)) {
- if (is.svTest(Objs[[i]])) {
- tests <- c(tests, Onames[i])
- } else if (is.test(Objs[[i]])) {
- tests <- c(tests, paste("test(", Onames[i], ")", sep = ""))
- }
- }
- }
- }
- items <- c(items, sort(tests))
- }
- # Make it a 'svUnit' object
- class(items) <- "svUnit"
- return(items)
-}
-
-makeUnit.svUnit <-
-function(x, name = make.names(deparse(substitute(x))), dir = tempdir(),
-pos = .GlobalEnv, ...) {
- # Take an 'svUnit' object and make a unit from its function tests
- # It is saved in a file runit.<name>.R in 'dir'
- if (!is.svUnit(x))
- stop("'x' must be a 'svUnit' object")
- name <- as.character(name[1])
- dir <- as.character(dir[1])
- # Check that dir exists (do not create it!)
- if (!file.exists(dir) || !file.info(dir)$isdir)
- stop("'dir' must be an existing directory")
-
- # Collect all items that are not 'package:...' or 'dir:...'
- isObj <- regexpr("^[package:|dir:]", x) == -1
- Objs <- sub("^test[(](.+)[)]$", "\\1", x[isObj])
- if (length(Objs) == 0) {
- # No objects, return NULL
- return(NULL)
- }
-
- Unit <- file.path(dir, paste("runit", name, "R", sep = "."))
- cat("# Test unit '", name, "'\n", sep = "", file = Unit)
-
- # Collect all tests from Objs together in the test unit
- # We provide the name of objects located in 'pos' environment
- for (objname in Objs) {
- if (regexpr("^test\\.", objname) > -1) testname <- objname else
- testname <- paste("test", objname, sep = ".")
- testname <- make.names(testname)
- cat('\n"', testname, '" <-\n', sep = "", file = Unit, append = TRUE)
- if (!exists(objname, where = pos)) {
- # Create a dummy test with DEACTIVATED entry
- body <- c(
- 'function() {',
- paste('\tDEACTIVATED("Object', objname, 'not found!")'),
- '}\n')
- } else {
- Test <- test(get(objname, pos = pos))
- if (is.null(Test)) {
- # Create a dummy test with DEACTIVATED entry
- body <- c(
- 'function() {',
- paste('\tDEACTIVATED("Object', objname, 'has no tests!")'),
- '}\n')
- } else {
- capture.body <-
- function(Data) {
- rval <- NULL
- File <- textConnection("rval", "w", local = TRUE)
- sink(File)
- on.exit({ sink(); close(File) })
- dput(Data, file = File, control = "useSource")
- on.exit()
- sink()
- close(File)
- return(rval)
- }
- body <- capture.body(Test)
- }
- }
- cat(body, sep = "\n", file = Unit, append = TRUE)
- }
- return(Unit)
-}
-
-runTest.svUnit <-
-function(x, name = make.names(deparse(substitute(x))), ...) {
- # Compile and run the test for this 'svUnit' object
- if (!is.svUnit(x))
- stop("'x' must be a 'svUnit' object")
- name <- as.character(name[1])
-
- # Decode tests contained in x
- tests <- as.character(x)
- dirs <- character()
- # Package suites...
- isPkg <- regexpr("^package:", tests) > -1
- if (any(isPkg)) {
- Pkgs <- tests[isPkg]
- Subdirs <- sub("^.+[(](.+)[)] *$", "\\1", Pkgs)
- Subdirs[Subdirs == Pkgs] <- ""
- Pkgs <- sub("^package:([^ ]+).*$", "\\1", Pkgs)
- for (i in 1:length(Pkgs)) {
- dir <- system.file(package = Pkgs[i], "unitTests", Subdirs[i])
- if (dir != "") dirs <- c(dirs, dir)
- }
- }
-
- # Add directories, and possibly make a temporary unit for test objects
- if (any(!isPkg)) {
- tests <- tests[!isPkg]
- # Directories
- isDir <- regexpr("^dir:", tests) > -1
- if (any(isDir))
- dirs <- c(dirs, sub("^dir:", "", tests[isDir]))
- # Objects
- if (any(!isDir)) {
- # make a temporary unit for the tests of these objects
- if (!is.null(Unit <- makeUnit(x, name = name))) {
- # Add this path to dirs, and make sure that the temporary file
- # is destroyed at the end
- dirs <- c(dirs, dirname(Unit))
- on.exit(unlink(Unit))
- }
- }
- }
-
- # Run these tests now
- res <- runUnit(name = name, dirs = dirs)
- return(invisible(res))
-}
Modified: pkg/svUnit/TODO
===================================================================
--- pkg/svUnit/TODO 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/TODO 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,31 +1,35 @@
= svUnit To Do list
-* Install SciViews-K Unit Komodo extension
+* guiTestFeedback() must be finished.
-* Mean to save and load vUnit objects; also automatically load concerned packages
+* Install SciViews-K Unit Komodo extension.
-* Output results in wiki format
+* Output results in htm, wiki, etc. format (summary.svSuiteData).
-* butler: benchmark and profiling => check it
+* Queue tests to run and run them asynchronously using tcltk and after() if
+this package is loaded and we are in interactive() mode.
-* Split example test into smaller test functions
+* RUnit code coverage functions.
-* Make a vignette (and perhaps a demo) for this package
+* People ask for checkWarning() function... But warnings are not part of code
+execution. Provide an example to show how, by using options(warning = ...) and
+checkException(), one can detect warnings.
-* Translate this package
+* butler: benchmark and profiling => check it.
-* In RUnit/share/R, there are checkCode.r and compareRUnitTestData.r. The former
- provides functions for test R code in R files, the latter does a comparison of
- timings in two test set runs, using a tolerance value. Worth checking and
- integrating later on!
+* Split example test into smaller test functions.
-* In RUnit: checkException() -> get silent argument value from
- getOption("RUnit.silent")
+* Make a vignette (and perhaps a demo) for this package.
-* In RUnit, make a CheckWarning() function
+* Translate this package.
+* In RUnit/share/R, there are checkCode.r and compareRUnitTestData.r. The former
+provides functions for test R code in R files, the latter does a comparison of
+timings in two test set runs, using a tolerance value. Worth checking and
+integrating later on!
+
* In RUnit: one bug is reported on RUnit SourceForge area for RUnit 0.4.17.
- Follow this to make sure it is corrected (or work on a patch!)
+Follow this to make sure it is corrected (or work on a patch!)
myfun <- function(a, b = 98, c = 99){
cat("a = ", a, ", b = ", b, ", c = ", c, "\n")
@@ -38,3 +42,6 @@
track$init()
inspect(myfun(1, c = 2), track = track)
# Here, we see that myfun is calld with argument not matched by names!
+
+* In svUnit checkTrue() is vectorized, but not in RUnit. I made a proposition to
+the RUnit maintainer => look what happens in future versions.
\ No newline at end of file
Added: pkg/svUnit/inst/komodo/sciviewskunit-ko.xpi
===================================================================
(Binary files differ)
Property changes on: pkg/svUnit/inst/komodo/sciviewskunit-ko.xpi
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: pkg/svUnit/inst/unitTests/VirtualClass/runit.VirtualClass.R
===================================================================
--- pkg/svUnit/inst/unitTests/VirtualClass/runit.VirtualClass.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/inst/unitTests/VirtualClass/runit.VirtualClass.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,118 +0,0 @@
-# runit.VirtualClass.R test suite
-# Just one example take from RUnit
-
-# --- Test setup ---
-
-if (FALSE) {
- # Not really needed, but can be handy when writing tests
- library("RUnit")
- library("testRUnit")
-}
-
-# package 'methods' is usually loaded, but make sure it is
-checkTrue(require(methods))
-
-# Define class (not exported yet by the program, and defined in .GlobalEnv!)
-className <- "MyVirtualBaseClass"
-setClass(className,
- representation("VIRTUAL",
- x = "numeric",
- y = "numeric",
- description = "character"),
- validity = NULL,
- sealed = FALSE,
- where = .GlobalEnv)
-
-if (!isGeneric("getX")) {
- setGeneric("getX", function(object, ...) standardGeneric("getX"),
- useAsDefault = TRUE, where = .GlobalEnv, valueClass = "numeric")
-}
-
-setMethod("getX", signature = className, function(object) return(object at x),
- where = .GlobalEnv)
-
-if (!isGeneric("setX<-")) {
- setGeneric("setX<-", function(object, value) standardGeneric("setX<-"),
- useAsDefault = TRUE, where = .GlobalEnv)
-}
-
-setMethod("setX<-", signature = signature(object = className, value = "numeric"),
- function(object, value) {
- if (length(value) < 1) {
- stop("value has to contain at least one element.")
- }
- if (any(is.na(value))) {
- stop("value may not contain NA(s).")
- }
- object at x <- value
- return(object)
- }, where = .GlobalEnv)
-
-
-# --- Test functions ---
-
-.setUp <- function() {
- # Executed before each test function
-}
-
-.tearDown <- function() {
- # Executed after each test function
-}
-
-test.createClass <- function() {
- setClass("A", contains = "numeric", where = .GlobalEnv)
- a <- new("A")
- checkTrue(validObject(a))
- removeClass("A", where = .GlobalEnv) # Better to use on.exit() here!
- checkException(new("A"))
-}
-
-testMyVirtualBaseClass.getX <- function() {
- testClassName <- "MyDerivedTestClass"
- setClass(testClassName,
- representation("MyVirtualBaseClass"),
- validity = NULL,
- sealed = FALSE,
- where = .GlobalEnv)
-
- on.exit(removeClass(testClassName, where = .GlobalEnv))
-
- # system constructor
- this <- new(testClassName)
-
- # constructor call succeeded?
- checkTrue(is(this, testClassName))
-
- ret <- getX(this)
- checkTrue(is(ret, "numeric"))
- # class default
- checkEquals(ret, numeric(0))
-}
-
-testMyVirtualBaseClass.setX <- function() {
- testClassName <- "MyDerivedTestClass"
- setClass(testClassName,
- representation("MyVirtualBaseClass"),
- validity = NULL,
- sealed = FALSE,
- where = .GlobalEnv)
-
- on.exit(removeClass(testClassName, where = .GlobalEnv))
-
- # system constructor
- this <- new(testClassName)
-
- # constructor call succeeded?
- checkTrue(is(this, testClassName))
-
- testSeq <- 1:23
- setX(this) <- testSeq
- ret <- getX(this)
- checkTrue(is(ret, "numeric"))
- checkEquals(ret, testSeq)
-
- # error handling
- checkException(setX(this) <- numeric(0))
- checkException(setX(this) <- as.numeric(NA))
- checkException(setX(this) <- c(1:4, NA))
-}
Added: pkg/svUnit/inst/unitTests/VirtualClass/runitVirtualClass.R
===================================================================
--- pkg/svUnit/inst/unitTests/VirtualClass/runitVirtualClass.R (rev 0)
+++ pkg/svUnit/inst/unitTests/VirtualClass/runitVirtualClass.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,118 @@
+# runit.VirtualClass.R test suite
+# Just one (little bit more complex) example taken from RUnit
+
+# --- Test setup ---
+if (FALSE) {
+ # Not really needed, but can be handy when writing tests
+ library("svUnit")
+}
+
+# package 'methods' is usually loaded, but make sure it is
+if (!require(methods)) stop("Package 'methods' is required!")
+
+# Define class (not exported yet by the program, and defined in .GlobalEnv!)
+className <- "MyVirtualBaseClass"
+setClass(className,
+ representation("VIRTUAL",
+ x = "numeric",
+ y = "numeric",
+ description = "character"),
+ validity = NULL,
+ sealed = FALSE,
+ where = .GlobalEnv)
+
+if (!isGeneric("getX")) {
+ setGeneric("getX", function(object, ...) standardGeneric("getX"),
+ useAsDefault = TRUE, where = .GlobalEnv, valueClass = "numeric")
+}
+
+setMethod("getX", signature = className, function(object) return(object at x),
+ where = .GlobalEnv)
+
+if (!isGeneric("setX<-")) {
+ setGeneric("setX<-", function(object, value) standardGeneric("setX<-"),
+ useAsDefault = TRUE, where = .GlobalEnv)
+}
+
+setMethod("setX<-", signature = signature(object = className, value = "numeric"),
+ function(object, value) {
+ if (length(value) < 1) {
+ stop("value has to contain at least one element.")
+ }
+ if (any(is.na(value))) {
+ stop("value may not contain NA(s).")
+ }
+ object at x <- value
+ return(object)
+ }, where = .GlobalEnv)
+
+
+# --- Test functions ---
+
+.setUp <- function() {
+ # Executed before each test function
+ # ...
+}
+
+.tearDown <- function() {
+ # Executed after each test function
+ # ...
+}
+
+testCreateClass <- function() {
+ setClass("A", contains = "numeric", where = .GlobalEnv)
+ a <- new("A")
+ checkTrue(validObject(a))
+ removeClass("A", where = .GlobalEnv) # Better to use on.exit() here!
+ checkException(new("A"))
+}
+
+testMyVirtualBaseClass.getX <- function() {
+ testClassName <- "MyDerivedTestClass"
+ setClass(testClassName,
+ representation("MyVirtualBaseClass"),
+ validity = NULL,
+ sealed = FALSE,
+ where = .GlobalEnv)
+
+ on.exit(removeClass(testClassName, where = .GlobalEnv))
+
+ # system constructor
+ this <- new(testClassName)
+
+ # constructor call succeeded?
+ checkTrue(is(this, testClassName))
+
+ ret <- getX(this)
+ checkTrue(is(ret, "numeric"))
+ # class default
+ checkEquals(numeric(0), ret)
+}
+
+testMyVirtualBaseClass.setX <- function() {
+ testClassName <- "MyDerivedTestClass"
+ setClass(testClassName,
+ representation("MyVirtualBaseClass"),
+ validity = NULL,
+ sealed = FALSE,
+ where = .GlobalEnv)
+
+ on.exit(removeClass(testClassName, where = .GlobalEnv))
+
+ # system constructor
+ this <- new(testClassName)
+
+ # constructor call succeeded?
+ checkTrue(is(this, testClassName))
+
+ testSeq <- 1:23
+ setX(this) <- testSeq
+ ret <- getX(this)
+ checkTrue(is(ret, "numeric"))
+ checkEquals(testSeq, ret)
+
+ # error handling
+ checkException(setX(this) <- numeric(0))
+ checkException(setX(this) <- as.numeric(NA))
+ checkException(setX(this) <- c(1:4, NA))
+}
Deleted: pkg/svUnit/inst/unitTests/runit.svTest.R
===================================================================
--- pkg/svUnit/inst/unitTests/runit.svTest.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/inst/unitTests/runit.svTest.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,82 +0,0 @@
-# runit.svTest.R test suite
-# by Ph. Grosjean <phgrosjean at sciviews.org>
-# run it simply by example(unitTests.svUnit)
-
-.setUp <- function () {
- # Executed before each test function
- # ... your code here
-}
-
-.tearDown <- function () {
- # Executed after each test function
- # ... your code here
-}
-
-test.svTest <- function () {
- # An R object
- mat <- matrix(rnorm(4), ncol = 2)
- # An example function
- foo <- function(x) return(x)
-
- checkTrue(!is.test(mat), "No associated test cases to 'mat'") #1
- checkTrue(!is.test(foo), "No associated test cases to 'foo'") #2
- checkTrue(is.null(test(foo)), "Return NULL if no test cases") #3
- checkTrue(!is.test(test(foo)), "No 'svTest' object if no test cases") #4
- checkTrue(!is.test(mat), "This is not a 'svTest' object (1)") #5
- checkTrue(!is.test(foo), "This is not a 'svTest' object (2)") #6
- checkTrue(!is.svTest(foo), "This is not a 'svTest' object (3)") #7
- checkTrue(!is.test("x"), "This is not a 'svTest' object (4)") #8
- checkTrue(!is.test(NULL), "This is not a 'svTest' object (5)") #9
- checkTrue(!is.test(NA), "This is not a 'svTest' object (6)") #10
-
- # Create very simple test cases for matrix 'mat' and function 'foo'
- test.mat <- svTest(function () {
- checkEqualsNumeric(nrow(mat), 2)
- checkTrue(is.numeric(mat))
- })
-
- test.foo <- function () {
- checkEqualsNumeric(foo(2), 2)
- checkException(foo("xx"))
- }
-
- checkTrue(is.test(svTest(test.foo)), "Creation of a 'svTest' object") #11
- checkTrue(is.test(as.svTest(test.foo)), "Coercion to a 'svTest' object") #12
- checkException(svTest(foo), "Functions with arguments not allowed") #13
- checkException(svTest("x"), "Strange argument to svTest") #14
-
- # Add test cases to an object
- test(mat) <- test.mat
-
- checkTrue(is.test(mat), "'mat' has associated test cases") #15
- checkIdentical(test(mat), test.mat, "test of 'mat' identical to 'test.mat'")#16
- checkTrue(is.test(test.mat), "Is this a 'svTest' object (1)?") #17
- checkTrue(is.svTest(test.mat), "Is this a 'svTest' object (2)?") #18
-
-
- # Use a function as test
- test(foo) <- test.foo
-
- checkTrue(has.test(foo), "'foo' has associated test cases") #19
- checkEquals(test(foo), svTest(test.foo), "test of 'foo' equals 'test.foo'") #20
- checkTrue(!is.test(test.foo), "Is this a 'svTest' object (3)?") #21
- checkTrue(is.svTest(test.foo), "Is this a 'svTest' object (4)?") #22
-
-
- # Transform into a svTest object and use it as test
- test.foo <- as.svTest(test.foo)
- test(foo) <- test.foo
-
- checkIdentical(test(test.foo), test.foo, "'test' returns a 'svTest' object") #23
- checkTrue(is.test(test.foo), "Is this a 'svTest' (5)?") #24
- checkTrue(is.test(foo), "'foo' has associated test cases") #25
- checkIdentical(test(foo), test.foo, "test of 'foo' identical to 'test.foo'")#26
-
- checkException(test(foo) <- "x", "Strange value to assign as 'test'") #27
- checkException(test(foo) <- function(y) y, "Try assign a function with arguments") #28
-
- # Strange,... but allowed
- test(test.foo) <- test.foo
-
- checkIdentical(test(test.foo), test.foo, "Assigning test to oneself") #29
-}
Deleted: pkg/svUnit/inst/unitTests/runit.svUnit.R
===================================================================
--- pkg/svUnit/inst/unitTests/runit.svUnit.R 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/inst/unitTests/runit.svUnit.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,51 +0,0 @@
-# runit.unitFunctions.R test suite
-# by Ph. Grosjean <phgrosjean at sciviews.org>
-# run it simply by example(unitTests.svUnit)
-
-.setUp <- function () {
- # Executed before each test function
- # ... your code here
-}
-
-.tearDown <- function () {
- # Executed after each test function
- # ... your code here
-}
-
-test.svUnit <- function () {
- checkTrue(is.svUnit(svUnitList()), "svUnitList() returns a 'svUnit' object")#1
- checkTrue("package:svUnit" %in% svUnitList(), "svUnitList() lists 'svUnit' package") #2
- checkTrue("package:svUnit (VirtualClass)" %in% svUnitList(), "svUnitList() lists 'VirtualClass' suite") #3
-
- # Create a 'svTest' object and another object containing a test in .GlobalEnv
- test.R <<- svTest(function () {
- checkTrue(1 < 2)
- })
-
- foo <- function(x) return(x)
- test(foo) <- function () {
- checkEqualsNumeric(foo(2), 2)
- checkException(foo("xx"))
- }
- Foo <<- foo # Place a copy of 'foo' in .GlobalEnv
-
- checkTrue("test.R" %in% svUnitList(), "svUnitList() lists 'svTest' objects") #4
- checkTrue("test(Foo)" %in% svUnitList(), "svUnitList() lists objects with tests") #5
- rm(foo)
- rm(test.R, Foo, pos = .GlobalEnv)
-}
-
-test.runTest <- function () {
- # A simple svTest object
- test.R <- svTest(function () {
- checkTrue(1 < 2)
- })
- checkTrue(inherits(runTest(test.R), "svUnitData"), "result of runTest(svTest) is svUnitData") #1
-
- ### TODO: more tests!
- rm(test.R)
-}
-
-test.unitErrorClear <- function() {
- ### TODO: tests for unitError() and unitClear()
-}
\ No newline at end of file
Added: pkg/svUnit/inst/unitTests/runitsvSuite.R
===================================================================
--- pkg/svUnit/inst/unitTests/runitsvSuite.R (rev 0)
+++ pkg/svUnit/inst/unitTests/runitsvSuite.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,64 @@
+# runitsvSuite.R test suite
+# by Ph. Grosjean <phgrosjean at sciviews.org>
+# run it simply by example(unitTests.svUnit)
+
+## Create a few objects we need for our tests
+
+# Save current exclusion list and clear it
+oex <- getOption("svUnit.excludeList")
+
+# Create a very simple 'svTest' object
+test_R <- svTest(function () {
+ checkTrue(1 < 2)
+})
+
+
+## The test cases
+
+.setUp <- function () {
+ # Executed before each test function
+ # Remove temporarily the exclusion list for our tests
+ options(svUnit.excludeList = NULL)
+
+ # Create an object with associated tests in .GlobalEnv
+ foo <- function(x) return(x)
+ test(foo) <- function () {
+ checkEqualsNumeric(2, foo(2), "foo(2) returns 2")
+ checkException(foo("x"), "foo(\"x\") raises an exception")
+ }
+ svSuite.foo <<- foo # Place a copy of 'foo' in .GlobalEnv
+
+ # Create an object without associated tests in .GlobalEnv
+ svSuite.bar <<- function(x) return(x^2)
+
+ # Create an integration test in .globalEnv
+ test_svSuite <<- svTest(function () {
+ checkTrue(1 == 1, "example test: 1 == 1")
+ checkException(nonexisting + 1, "exception when using non existing var")
+ })
+}
+
+.tearDown <- function () {
+ # Executed after each test function
+ # restore previous exclusion list
+ options(svUnit.excludeList = oex)
+ # Remove our object with tests in .GlobalEnv
+ rm(svSuite.foo, svSuite.bar, test_svSuite, envir = .GlobalEnv)
+}
+
+testsvSuite <- function () {
+ checkTrue(is.svSuite(svSuite("svSuite.foo")), "svSuite(\"svSuite.foo\") returns a 'svSuite' object")
+ checkTrue(is.svSuite(svSuite("svSuite.bar")), "svSuite(\"svSuite.bar\") returns a 'svSuite' object")
+ checkTrue(is.svSuite(svSuite("test_svSuite")), "svSuite(\"test_svSuite\") returns a 'svSuite' object")
+ checkTrue(is.svSuite(svSuite("nonexisting")), "svSuite(\"nonexisting\") returns a 'svSuite' object")
+ checkException(svSuite(nonexisting), "svSuite(nonexisting) raises an exception")
+}
+
+testsvSuiteList <- function () {
+ checkTrue(is.svSuite(svSuiteList()), "svSuiteList() returns a 'svSuite' object")
+ checkTrue("package:svUnit" %in% svSuiteList(), "svSuiteList() lists 'svSuite' package")
+ checkTrue("package:svUnit (VirtualClass)" %in% svSuiteList(), "svSuiteList() lists 'VirtualClass' suite")
+ checkTrue("test(svSuite.foo)" %in% svSuiteList(), "svSuiteList() lists objects with tests")
+ checkTrue("test_svSuite" %in% svSuiteList(), "svSuiteList() lists 'svTest' objects")
+ checkTrue("test_R" %in% svSuiteList(pos = parent.frame()), "svSuiteList() uses 'pos' correctly")
+}
Added: pkg/svUnit/inst/unitTests/runitsvTest.R
===================================================================
--- pkg/svUnit/inst/unitTests/runitsvTest.R (rev 0)
+++ pkg/svUnit/inst/unitTests/runitsvTest.R 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,96 @@
+# runitsvTest.R test suite
+# by Ph. Grosjean <phgrosjean at sciviews.org>
+# run it simply by example(unitTests.svUnit)
+
+## Create a few objects we need for tests
+
+# An R object (matrix)
+mat <- matrix(rnorm(4), ncol = 2)
+
+# Create very simple test cases for matrix 'mat'
+testmat <- svTest(function () {
+ checkEqualsNumeric(2, nrow(mat))
+ checkTrue(is.numeric(mat))
+})
+
+# An example function without test case
+foo <- function(x) return(x)
+
+# Another function with a test associated
+bar <- function(x) return(x^2)
+testbar <- svTest(function () {
+ checkEqualsNumeric(4, bar(2))
+ checkException(bar("xx"))
+})
+test(bar) <- testbar
+
+
+## The test cases
+
+.setUp <- function () {
+ # Executed before each test function
+ # ...
+}
+
+.tearDown <- function () {
+ # Executed after each test function
+ # ...
+}
+
+testis.test <- function () {
+ checkTrue(!is.test(foo), "No associated test cases to 'foo'")
+ checkTrue(is.test(testbar), "Is testbar a 'svTest'?")
+ checkTrue(is.test(bar), "Associated test cases to 'bar'")
+ checkTrue(!is.test(mat), "No associated test cases to 'mat'")
+ checkTrue(is.test(testmat), "Is an 'svTest' object a test?")
+
+ if (exists(".Log")) .Log$..Obj <- "test" # Switch the context to test()
+ checkTrue(is.test(test(foo)), "Return dummy test if no test cases")
+ checkIdentical(testbar, test(bar), "test of 'bar' identical to 'testbar'")
+
+ if (exists(".Log")) .Log$..Obj <- "test<-" # Switch the context to `test<-`()
+ checkException(test(foo) <- "x", "Strange value to assign as 'test'")
+ checkException(test(foo) <- function(y) y, "Try assign a function with arguments")
+ # Add test cases to an object
+ mat2 <- mat
+ checkTrue(is.test(test(mat2) <- testmat), "'mat2' valid test case association")
+ checkIdentical(testmat, test(mat2), "test of 'mat2' identical to 'testmat'")
+ # Strange,... but allowed
+ test(testbar) <- testbar
+ checkIdentical(testbar, test(testbar), "Assigning test cases to oneself")
+
+ if (exists(".Log")) .Log$..Obj <- "is.test" # Switch context back to is.test()
+ checkTrue(!is.test("x"), "'x' is is not a 'svTest' object")
+ checkTrue(!is.test(NULL), "NULL is not a 'svTest' object")
+ checkTrue(!is.test(NA), "NA is not a 'svTest' object")
+}
+
+testsvTest <- function () {
+ checkException(svTest(foo), "Functions with arguments not allowed")
+ checkException(svTest("x"), "Strange argument to svTest")
+ checkTrue(is.svTest(svTest(function() {})), "Creation of a minimal 'svTest' object")
+
+ if (exists(".Log")) .Log$..Obj <- "is.svTest" # Switch context to is.svTest()
+ checkTrue(is.svTest(testmat), "Is testmat a 'svTest' object?")
+ checkTrue(is.svTest(testbar), "Is testbar a 'svTest' object?")
+ checkTrue(is.svTest(test(bar)), "Is test(bar) a 'svTest' object?")
+ checkTrue(!is.svTest(foo), "'foo' is not a 'svTest' object")
+ checkTrue(!is.svTest("x"), "'x' is not a 'svTest' object")
+ checkTrue(!is.svTest(NULL), "NULL is not a 'svTest' object")
+ checkTrue(!is.svTest(NA), "NA is not a 'svTest' object")
+ checkTrue(!is.svTest(function () {}), "A function is not a 'svTest' object")
+
+ if (exists(".Log")) .Log$..Obj <- "as.svTest" # Switch context to as.svTest()
+ checkTrue(is.svTest(as.svTest(testmat)), "Coercion to a 'svTest' object")
+ checkException(as.svTest("x"), "Try coercion on wrong object")
+ checkException(as.svTest(function (y) y), "Try coercion on function with arguments")
+}
+
+testrunTest <- function () {
+ checkTrue(inherits(runTest(testbar), "svTestData"), "result of runTest(testbar) is 'svTestData'")
+ # Following tests fail currently for reasons I haven't spotted yet, but runTest() works wine
+ # outside of these tests... So, I deactivate them
+ DEACTIVATED("runTest(bar) does not work inside test functions")
+ checkTrue(inherits(runTest(test(bar)), "svTestData"), "result of runTest(test(bar)) is 'svTestData'")
+ checkTrue(inherits(runTest(bar), "svTestData"), "result of runTest(bar) is 'svTestData'")
+}
Added: pkg/svUnit/man/Log.Rd
===================================================================
--- pkg/svUnit/man/Log.Rd (rev 0)
+++ pkg/svUnit/man/Log.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,86 @@
+\name{Log}
+\alias{Log}
+\alias{createLog}
+\alias{clearLog}
+\alias{errorLog}
+\alias{lastTest}
+\alias{lastSuite}
+
+\title{ SciViews R log management functions }
+\description{
+ These functions define the code of test functions. They are designed to check
+ the result of some test calculation.
+}
+
+\usage{
+Log(description = NULL)
+createLog(description = NULL, deleteExisting = FALSE)
+clearLog()
+errorLog(stopit = TRUE, summarize = TRUE)
+lastTest()
+lastSuite()
+}
+
+\arguments{
+ \item{description}{ A (short) character string describing this test suite log }
+ \item{deleteExisting}{ Do we delete an existing a \code{.Log} object already
+ defined in \code{.GlobalEnv} (no, by default)? }
+ \item{stopit}{ Do we issue an error (\code{stop()} in case of any error or
+ failure? This is particularly useful if you want to interrupt R CMD check
+ on packages, when you included one or more test suites in examples (see
+ \code{?unitTests} }
+ \item{summarize}{ Should the summary of the log be printed in case we stop
+ execution of the code when an error is found (see \code{stopit} argument.
+ It is, indeed, useful to indicate at this time which tests failed or raised
+ an error. So, this argument should usually be left at its default value }
+}
+
+\value{
+ \code{Log()} and \code{createLog()} return the .Log object defined in
+ .GlobalEnv by reference (it is indeed an environment). So, you can use its
+ content (and change it, if you write functions to manipulate this log).
+
+ \code{clearLog()} return invisibly TRUE or FALSE, depending if an existing
+ log object was deleted or not.
+
+ \code{errorLog()} is mainly used for its side-effect of stopping code
+ execution and/or printing a summmary of the test runs in the context of
+ example massaging in R CMD check (see the \"Writing R extensions\" manual).
+ However, this function also returns invisibly a contingency table with the
+ number of successes, failures, errors and deactivated tests recorded so far.
+
+ \code{lastTest()} and \code{lastSuite()} recall results of last test and last
+ suite run, respectively.
+}
+
+\details{
+ svUnit records results of assertions (using the checkxxx() functions) in a
+ 'svSuiteData' object named \code{.Log} and located in .GlobalEnv. Hence, this
+ log is easy to access. However, in order to avoid errors in your code in case
+ this object was deleted, or not created, it is better to access it using
+ \code{Log()} which take care to create the object if it is missing.
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{svSuiteData}}, \code{\link{svSuite}}, \code{\link{svTest}},
+ \code{\link{check}} }
+
+\examples{
+clearLog() # Clear the svUnit log
+
+# Two correct tests
+(checkTrue(1 < 2))
+(checkException(log("a")))
+errorLog() # Nothing, because there is no error
+
+\dontrun{
+(checkTrue(1 > 2)) # This test fails
+lastTest() # Print results of last test
+errorLog() # Stop and summarize the tests run so far
+}
+
+clearLog()
+}
+
+\keyword{ utilities }
Added: pkg/svUnit/man/check.Rd
===================================================================
--- pkg/svUnit/man/check.Rd (rev 0)
+++ pkg/svUnit/man/check.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,116 @@
+\name{check}
+\alias{checkEquals}
+\alias{checkEqualsNumeric}
+\alias{checkIdentical}
+\alias{checkTrue}
+\alias{checkException}
+\alias{DEACTIVATED}
+
+\title{ SciViews R Unit check functions }
+\description{
+ These functions define the code of test functions. They are designed to check
+ the result of some test calculation.
+}
+
+\usage{
+checkEquals(target, current, msg = "", tolerance = .Machine$double.eps^0.5,
+ checkNames = TRUE, \dots)
+checkEqualsNumeric(target, current, msg = "",
+ tolerance = .Machine$double.eps^0.5, \dots)
+checkIdentical(target, current, msg = "")
+checkTrue(expr, msg = "")
+checkException(expr, msg = "", silent = getOption("svUnit.silentException"))
+DEACTIVATED(msg = "")
+}
+
+\arguments{
+ \item{current}{ An object created for comparison (not an S4 class object) }
+ \item{target}{ A target object as reference fo comparison }
+ \item{msg}{ An optional (short!) message to document a test. This message is
+ stored in the log and printed in front of each test report }
+ \item{tolerance}{ numeric >= 0. A numeric check does not fail if differences
+ are smaller than `tolerance' }
+ \item{checkNames}{ Flag, if \code{FALSE} the names attributes are set to
+ \code{NULL} for both \code{current} and \code{target} before performing
+ the check }
+ \item{expr}{ Syntactically valid R expression which can be evaluated and must
+ return a logical vector (\code{TRUE}|\code{FALSE}). A named expression is
+ also allowed but the name is disregarded. In \code{checkException()}, expr
+ is supposed to generate an error to pass the test }
+ \item{silent}{ Flag passed on to try, which determines if the error message
+ generated by the checked function is displayed at the R console. By default,
+ it is \code{FALSE} }
+ \item{\dots}{ Optional arguments passed to \code{all.equal()} or
+ \code{all.equal.numeric()} }
+}
+
+\value{
+ \code{TRUE} if the test succeeds, \code{FALSE} if it fails, possibly with a
+ 'result' attribute containing more information about the problem. This is
+ very different from corresponding functions in 'RUnit' that stop with an
+ error in case of test failure. Consequently, current functions do not require
+ the complex evaluation framework designed in 'RUnit' for that reason.
+}
+
+\details{
+ These check functions are equivalent to various methods of the class
+ junit.framework.Assert of Java junit framework. They should be code-compatible
+ with functions of same name in 'RUnit' 0.4.17, except for \code{checkTrue()}
+ that is vectorized here, but accept only a scalar result in 'RUnit'. For
+ scalar test, the behaviour of the function is the same in both packages.
+
+ See \code{svTest()} for examples of utilisation of these functions in actual
+ test cases attached to R objects.
+
+ See also the note about S4 objects in the \code{checkTrue()} online help of
+ the 'RUnit' package.
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> has adapted existing code
+ in 'RUnit' by Thomas Konig, Klaus Junemann & Matthias Burger and ported it
+ to 'svUnit' }
+
+\seealso{ \code{\link{svTest}}, \code{\link{Log}},
+ \code{\link{guiTestReport}}, \code{\link[RUnit]{checkTrue}} }
+
+\examples{
+library(datasets) # Make sure 'datasets' package is loaded
+clearLog() # Clear the svUnit log
+
+# All these tests are correct
+(checkEquals(c("A", "B", "C"), LETTERS[1:3]))
+(checkEqualsNumeric(1:10, seq(1, 10)))
+(checkIdentical(iris[1:50, ], iris[iris$Species == "setosa",]))
+(checkTrue(1 < 2))
+(checkException(log("a")))
+Log() # See what's recorded in the log
+
+# ... but these ones fail
+(checkEquals("A", LETTERS[1:3]))
+(checkEqualsNumeric(2:11, seq(1, 10)))
+(checkIdentical(iris[1:49, ], iris[iris$Species == "setosa",]))
+(checkTrue(1 > 2))
+(checkException(log(1)))
+Log() # See what's recorded in the log
+
+# Create a test function and run it
+foo <- function(x, y = 2) return(x * y)
+test(foo) <- function () {
+ #DEACTIVATED();
+ checkEqualsNumeric(5, foo(2))
+ checkEqualsNumeric(6, foo(2, 3))
+ checkTrue(is.test(foo))
+ checkTrue(is.test(test(foo)))
+ checkIdentical(test(foo), attr(foo, "test"))
+ checkException(foo("b"))
+ checkException(foo(2, "a"))
+}
+(runTest(foo))
+
+# Of course, everything is recorded in the log
+Log()
+
+clearLog()
+}
+
+\keyword{ utilities }
Added: pkg/svUnit/man/guiTestReport.Rd
===================================================================
--- pkg/svUnit/man/guiTestReport.Rd (rev 0)
+++ pkg/svUnit/man/guiTestReport.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,45 @@
+\name{guiTestReport}
+\alias{guiTestReport}
+\alias{guiTestFeedback}
+\alias{guiSuiteList}
+\alias{guiSuiteAutoList}
+
+\title{ Report or give feedback to the GUI client about running test units }
+\description{
+ These functions are usually not called from the command line. They return
+ data to compatible GUI clients, like Komodo Edit with the SciViews-K extension.
+}
+
+\usage{
+guiTestReport(object, sep = "\t", path = NULL, \dots)
+guiTestFeedback(object, path = NULL, \dots)
+guiSuiteList(sep = "\t", path = NULL, compare = TRUE)
+guiSuiteAutoList(\dots)
+}
+
+\arguments{
+ \item{object}{ A svUnitData object }
+ \item{\dots}{ Not used currently }
+ \item{sep}{ Field separator to use in the results }
+ \item{path}{ Path where to write a 'Suites.txt' file with the list of currently
+ available test suites (to be used by the GUI client). If \code{NULL}, no
+ file is written (by default) }
+ \item{compare}{ Do we compare the list of available test suite and return
+ something to the GUI client only if there are changes in the list? This is
+ used (when TRUE) to avoid unnecessary multiple processings of the same list
+ by the GUI client }
+}
+
+\value{
+ \code{guiSuiteList() returns thde list of available test suites invisibly.
+ \code{guiSuiteAutoList()} is used to establish a callback to automatically
+ list the available test suites in the GUI. It is not intended to be called
+ directly by the user. The other functions just return \code{TRUE} invisibly.
+ They are used for their side effect of sending data to compatible GUI clients. }
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{svTest}}, \code{\link{svSuite}}, \code{\link{koUnit_version}} }
+
+\keyword{ utilities }
Added: pkg/svUnit/man/koUnit.Rd
===================================================================
--- pkg/svUnit/man/koUnit.Rd (rev 0)
+++ pkg/svUnit/man/koUnit.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,79 @@
+\name{koUnit}
+\alias{koUnit_isAutoTest}
+\alias{koUnit_setAutoTest}
+\alias{koUnit_runTest}
+\alias{koUnit_showRUnitPane}
+\alias{koUnit_version}
+
+\title{ Interact with the test unit GUI in Komodo/SciViews-K }
+\description{
+ These functions allow controlling the test unit module (R Unit tab at right)
+ in Komodo with SciViews-K and SciViews-K Unit extensions
+ (see http://www.sciviews.org/SciViews-K). R must be correctly connected to
+ Komodo, meaning that the 'svGUI' package must be loaded with proper
+ configuration of client/server socket connections between R and Komodo. See
+ the manual about SciViews-K for more information. The functions defined here
+ are the same as JavaScript functions defined in the 'sv.r.unit' namespace in
+ Komodo/SciViews-K Unit. For instance, \code{koUnit_runTest()} is equivalent
+ to \code{sv.r.unit.runTest();} in a Javascript macro in Komodo.
+}
+
+\usage{
+koUnit_isAutoTest()
+koUnit_setAutoTest(state)
+koUnit_runTest()
+koUnit_showRUnitPane(state)
+koUnit_version()
+}
+
+\arguments{
+ \item{state}{ \code{TRUE} or \code{FALSE}, or missing for
+ \code{koUnit_showRUnitPane()}, in this case, the R Unit pane visibility is
+ toggled }
+}
+
+\value{
+ \code{koUnit_isAutoTest()} returns \code{TRUE} if the test unit is in auto
+ mode in Komodo (the selected tests are run automatically each time a .R file
+ edited in Komodo is saved).
+
+ \code{koUnit_version()} returns the version for which the SciViews-K Unit
+ extension was designed for. This allow to check if this version is compatible
+ with current 'svUnit' R package version, and to propose to update the Komodo
+ extension if needed (this mechanism is not running currently, but it will be
+ implemented in the future to avoid or limit incompatibilities between
+ respective R and Komodo extensions).
+
+ The other functions are invoked for their side effect and they return nothing.
+ Note, however, that correct execution of this code in Komodo is verified, and
+ the functions issue an error in R if they fail to execute correctly in Komodo.
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{guiTestReport}} }
+
+\examples{
+\dontrun{
+# Make sure R is communicating with Komodo before use, see ?koCmd in svGUI
+koUnit_version()
+
+# Toggle visibility of the R Unit pane in Komodo twice
+koUnit_showRUnitPane()
+koUnit_showRUnitPane()
+
+# Make sure that the R Unit pane is visible
+koUnit_showRUnitPane(TRUE)
+
+# Is the test unit running in auto mode?
+koUnit_isAutoTest()
+
+# Toggle auto test mode off
+koUnit_setAutoTest(FALSE)
+
+# Run the test units from within Komodo
+koUnit_runTest()
+}
+}
+
+\keyword{ utilities }
Deleted: pkg/svUnit/man/runUnit.Rd
===================================================================
--- pkg/svUnit/man/runUnit.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/man/runUnit.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,75 +0,0 @@
-\name{runUnit}
-\alias{runUnit}
-\alias{unitClear}
-\alias{unitError}
-\alias{print.svUnitData}
-\alias{summary.svUnitData}
-
-\title{ Compile and run a complete test unit }
-\description{
- Compile a test unit and run it silently. Increment counters for errors,
- failings, and deactivated items. Manage the errors and warnings in a
- different depending if we run in interactive mode, or not (R CMD check). In
- this last case, make sure to break checking of package in case of errors or
- failings, but not otherwise.
-}
-
-\usage{
-runUnit(name, dirs, print.errors = !interactive(), warn = print.errors,
- rngKind = "Marsaglia-Multicarry", rngNormalKind = "Kinderman-Ramage")
-
-unitClear()
-unitError(errors = TRUE, failures = TRUE, deactivated = TRUE, stopit = TRUE)
-
-\method{print}{svUnitData}(x, \dots)
-\method{summary}{svUnitData}(object, \dots)
-}
-
-\arguments{
- \item{name}{ The name of the test suite to build and run }
- \item{dirs}{ The directories where to look for \code{runit*.R} test files.
- These test files must be sourceable and must contain one or more
- \code{test.*()} functions implementing the different tests }
- \item{print.errors}{ Do we print explicit messages for each error of failing? }
- \item{warn}{ Do we issue a warning if there are deactivated items? }
- \item{rngKind}{ Name of a valid RNG version (see \code{RNGkind}) }
- \item{rngNormalKind}{ Name of a valid rnorm RNG version (see \code{RNGkind}) }
- \item{errors}{ If \code{TRUE}, check if there where errors in any test of all
- test suites run since last \code{unitClear()} }
- \item{failures}{ If \code{TRUE}, check if there where failures in any test of
- all test suites run since last \code{unitClear()} }
- \item{deactivated}{ If \code{TRUE}, check if there where deactivated tests in
- any test suites run since last \code{unitClear()} }
- \item{stopit}{ Do we stop execution of the code in case of any detected error
- or failure? }
- \item{x}{ A 'svUnitData' object to print }
- \item{object}{ A 'svUnitData' object to summarize }
- \item{\dots}{ Not used for\code{summary()} }
-}
-
-\value{
- \code{unitRun()} returns an object of class 'svUnitData', similar to
- 'RUnitTestData' in the RUnit package with all results from the tests run.
-
- \code{unitClear()} returns a list with the number of errors (nErr) and the
- number of deactivated tests (nDeactivated) and the number of failures (nFail)
- invisibly. The function is called for its side effect of clearing these counters.
-
- \code{unitError()} returns \code{TRUE} if there are any errors and/or failures
- recorded in the global counters. This function is useful for integrating your
- test units with the "R CMD check" mechanism of checking R packages (see the
- manual "Writing R extensions"). Just create an example that run all the test
- suites you want to integrate, and then, finish your example with
- \code{unitError()}. See \code{?unitTests.svUnit} for an example.
-}
-
-\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
-
-\seealso{ \code{\link{svTest}}, \code{\link{svUnit}},
- \code{\link[RUnit]{defineTestSuite}} }
-
-\examples{
-### TODO...
-}
-
-\keyword{ utilities }
Added: pkg/svUnit/man/svSuite.Rd
===================================================================
--- pkg/svUnit/man/svSuite.Rd (rev 0)
+++ pkg/svUnit/man/svSuite.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,204 @@
+\name{svSuite}
+\alias{svSuite}
+\alias{as.svSuite}
+\alias{is.svSuite}
+\alias{svSuiteList}
+\alias{print.svSuite}
+\alias{makeUnit.svSuite}
+\alias{runTest.svSuite}
+
+\title{ Create and run test suites by collecting together unit tests and
+ function tests defined in objects }
+\description{
+ A 'svSuite' object is essentially a list of test units directories (or
+ packages, in this case, corresponding directories are PKG/unitTests and its
+ subdirectories), and of object names containing tests to add temporarily to
+ the test suite. These must be formatted in a concise way as described for the
+ 'tests' argument.
+
+ \code{svSuiteList()} lists all loaded packages having /unitTests/runit*.R
+ files (or similar files in subdirectories), and all objects in the user
+ workspace that have a 'test' attribute, or are 'svTest' objects (by default).
+ It is a rather exhaustive list of all test items currently available in the
+ current R session, but restricted by \code{getOption("svUnit.excludeList")}.
+
+ \code{makeUnit()} writes a test unit on disk with the tests from the objects
+ lised in the 'svSuite' object that do not belong yet to a test unit.
+ \code{runTest()} runs all the test in packages, directories and objects listed
+ in the 'svSuite' object.
+}
+
+\usage{
+svSuite(tests)
+
+as.svSuite(x)
+is.svSuite(x)
+
+svSuiteList(packages = TRUE, objects = TRUE, dirs = getOption("svUnit.dirs"),
+ excludeList = getOption("svUnit.excludeList"), pos = .GlobalEnv,
+ loadPackages = FALSE)
+
+\method{print}{svSuite}(x, \dots)
+\method{makeUnit}{svSuite}(x, name = make.names(deparse(substitute(x))),
+ dir = tempdir(), objfile = "", codeSetUp = NULL, codeTearDown = NULL,
+ pos = .GlobalEnv, \dots)
+\method{runTest}{svSuite}(x, name = make.names(deparse(substitute(x))), \dots)
+}
+
+\arguments{
+ \item{tests}{ A character string with items to include in the test suite.
+ It could be 'package:PKG' for including test units located in the /unitTests
+ subdirectory of the package PGK, or 'package:PKG (SUITE)' for test units
+ located in the subdirectory /unitTests/SUITE of package PKG, or 'dir:MYDIR'
+ for including test units in MYDIR, or 'test(OBJ)' for tests embedded in an
+ object, or 'OBJ' for 'svTest' object directly }
+ \item{x}{ Any kind of object }
+ \item{packages}{ Do we list test units available in loaded packages?
+ Alternatively one can provide a character vector of package names, and it
+ will be used to filter packages (take care: in this case it will look at
+ installed packages, not only loaded packages!) }
+ \item{objects}{ Do we list test available in objects? Alternatively, one can
+ provide a character vector of object names, and it will filter objects in
+ 'pos' according to this vector }
+ \item{dirs}{ An additional list of directories where to look for more test
+ units. For convenience, this list can simply be saved as an 'svUnit.dirs'
+ options }
+ \item{excludeList}{ A list of items to exclude from the listing. The function
+ uses regular expression to match the exclusions. So, for instance, specifying
+ \code{"package:MYPKG"} will exclude all items from package 'MYPKG', while
+ using \code{"package:MYPKG$"} will exclude only tests suites defined in the
+ .../MYPKG/unitTests directory, bur not in its subdirectories. For
+ convenience, it can be saved in a 'svUnit.excludeList' option. By default,
+ all tests for packages whose name start with 'sv' or 'RUnit' are excluded,
+ that is, \code{c("package:sv", "package:RUnit")} }
+ \item{pos}{ The environment to look for 'objects' (environment, character
+ string with name of an environment, or interger with position of the
+ environment in the search path }
+ \item{loadPackages}{ In the case a list of packages is provided in
+ \code{packages =}, do we make sure that these packages are loaded? If yes,
+ the function will try to load all packages in that list that are not loaded
+ yet and will issue a warning for the packages not found. Default,
+ \code{FALSE} }
+ \item{name}{ The name of the test suite to build }
+ \item{dir}{ The directory where to create the test unit file }
+ \item{objfile}{ The path to the file containing the original source code of
+ the object being tested. This argument is used to bring a context for a
+ test and allow a GUI to automatically open the source file for edition when
+ the user clicks on a test that failed or raised an error }
+ \item{codeSetUp}{ An expression with some code you want to add to the
+ \code{.setUp() } function in your unit file (this function is executed
+ before each test }
+ \item{codeTearDown}{ An expression with some code you want to add to the
+ \code{.tearDown() } function in your unit file (this function is executed
+ after each test }
+ \item{\dots}{ Further arguments to pass to \code{makeUnit()} or
+ \code{runTest()} (not used yet) }
+}
+
+\value{
+ \code{svSuite()}, \code{as.svSuite()} and \code{svSuiteList} return a
+ 'svSuite' object. \code{is.svSuite()} returns \code{TRUE} if the object is an
+ 'svSuite'.
+
+ \code{makeUnit()} creates a test unit file on disk, and \code{runTest()} run
+ the tests in such a file. They are used for their side-effect, but the first
+ one also returns the file created, and the second one returns invisibly the
+ list of all test unit files that where sourced ans run.
+}
+
+\details{
+ Thanks to the variety of sources allowed for tests, it is possible to define
+ these tests in a structured way, inside packages, like for the 'RUnit'
+ package (but with automatic recognition of test units associated to packages,
+ in the present case). It is also easy to define tests more loosely by just
+ attaching those tests to the objects you want to check. Whenever there objects
+ are loaded in the user's workspace, their tests are available. In both cases,
+ a test unit file on disk is sourced in a local environment and test functions
+ are run (same approach as in the 'RUnit' package, and the same test unit files
+ should be compatibles with both 'RUnit' and 'svUnit' packages), but in the
+ case of a loosy definition of the tests by attachment to objects, the test
+ unit file is created on the fly in the temporary directory (by default).
+
+ At any time, you can transform a series of tests loosy attached to objects
+ into a test unit file by applying \code{makeUnit()} to a 'svSuite' object,
+ probably specifying another directory than the (default) temporary dir for
+ more permanent storage of your test unit file. The best choice is the
+ '/inst/unitTests' directory of a package source, or one of its subdirectories.
+ That way, your test unit file(s) will be automatically listed and available
+ each time you load the compiled package in R (if you list them using
+ \code{svSuiteList()}). Of course, you still can exclude tests from given
+ packages by adding 'package:PKG' in the exclusion list with something like:
+ \code{options(svUnit.excludeList = c(getOption("svUnit.excludeList"), "package:PKG"))}.
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{svSuiteData}}, \code{\link{svTest}}, \code{\link{Log}},
+ \code{\link{check}}, \code{\link[RUnit]{checkTrue}} }
+
+\examples{
+svSuiteList() # List all currently available test units and test cases
+# Exclusion list is used (regular expression filtering!). It contains:
+(oex <- getOption("svUnit.excludeList"))
+# clear it, and relist available test units
+options(svUnit.excludeList = NULL)
+svSuiteList()
+
+# Two functions that include their test cases
+Square <- function(x) return(x^2)
+test(Square) <- function() {
+ checkEquals(9, Square(3))
+ checkEquals(c(1, 4, 9), Square(1:3))
+ checkException(Square("xx"))
+}
+
+Cube <- function(x) return(x^3)
+test(Cube) <- function() {
+ checkEquals(27, Cube(3))
+ checkEquals(c(1, 8, 28), Cube(1:3))
+ checkException(Cube("xx"))
+}
+
+# A separate test case object (not attached to a particular object)
+# This is the simplest way to loosely define quick and durty integration tests
+test_Integrate <- svTest(function() {
+ checkTrue(1 < 2, "check1")
+ v <- 1:3 # The reference
+ w <- 1:3 # The value to compare to the reference
+ checkEquals(v, w)
+})
+
+# A function without test cases (will be filtered out of the suite list)
+foo <- function(x) return(x)
+
+# Look now what tests are available
+svSuiteList()
+
+# Only objects, no package units
+svSuiteList(packages = FALSE)
+
+\dontrun{
+# Create the test unit file for all objects with tests in .GlobalEnv
+myunit <- makeUnit(svSuiteList(), name = "AllTests")
+file.show(myunit, delete.file = TRUE)
+}
+
+# Filter objects using a list (object with/without tests and a nonexisting obj)
+svSuiteList(packages = FALSE, objects = c("Cube", "foo", "bar"))
+
+# Create another svSuite object with selected test items
+(mysuite <- svSuite(c("package:svUnit (VirtualClass)", "test(Cube)")))
+is.svSuite(mysuite) # Should be!
+
+\dontrun{
+# Run all the tests currently available
+(runTest(svSuiteList(), name = "AllTests"))
+summary(Log())
+}
+
+# Restore previous exclusion list, and clean up the environment
+options(svUnit.excludeList = oex)
+rm(Square, Cube, foo, test_Integrate, mysuite, myunit, oex)
+}
+
+\keyword{ utilities }
Added: pkg/svUnit/man/svSuiteData.Rd
===================================================================
--- pkg/svUnit/man/svSuiteData.Rd (rev 0)
+++ pkg/svUnit/man/svSuiteData.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,148 @@
+\name{svSuiteData}
+\alias{svSuiteData}
+\alias{is.svSuiteData}
+\alias{stats.svSuiteData}
+\alias{metadata}
+\alias{metadata.svSuiteData}
+\alias{print.svSuiteData}
+\alias{summary.svSuiteData}
+\alias{protocol}
+\alias{protocol.default}
+\alias{protocol.svSuiteData}
+\alias{protocol_text}
+\alias{protocol_text.svSuiteData}
+
+\title{ Objects of class 'svSuiteData' contain results from running test suites }
+\description{
+ The 'svSuiteData' object contains results of all test run in one or more test
+ suites. The \code{checkxxx()} functions and the \code{runTest()} method
+ generate data (objects 'svTestData') contained in the default 'svSuiteData'
+ named \code{.Log} and located in .GlobalEnv. It is then possible to display
+ and report information it contains in various ways to analyze the results.
+}
+
+\usage{
+is.svSuiteData(x)
+
+\method{stats}{svSuiteData}(object, \dots)
+
+metadata(object, \dots)
+\method{metadata}{svSuiteData}(object, fields = c("R.version", "sessionInfo",
+ "time", "description"), \dots)
+
+\method{print}{svSuiteData}(x, all = FALSE, file = "", append = FALSE, \dots)
+
+\method{summary}{svSuiteData}(object, ...)
+
+protocol(object, type = "text", file = "", append = FALSE, \dots)
+\method{protocol}{default}(object, type = "text", file = "", append = FALSE, \dots)
+\method{protocol}{svSuiteData}(object, type = "text", file = "", append = FALSE, \dots)
+protocol_text(object, file = "", append = FALSE, \dots)
+\method{protocol_text}{svSuiteData}(object, file = "", append = FALSE, ...)
+}
+
+\arguments{
+ \item{x}{ Any kind of object, or a 'svSuiteData' object in the case of
+ \code{print}. }
+ \item{object}{ a 'svSuiteData' object }
+ \item{fields}{ Character vector. The name of all metadata items you want to
+ extract for the object. The default value is an exhaustive list of all
+ available metadata (i.e., defined by default) in the object, but you
+ can add more: just add a corresponding attribute to your object. }
+ \item{all}{ Do we print concise report for all test, or only for the tests
+ that fail or produce an error? }
+ \item{file}{ Character. The path to the file where to write the report. If
+ \code{file = ""}, the protocol report is output to the console }
+ \item{append}{ Do we append to this file? }
+ \item{type}{ Character. The type of protocol report to create. For the moment,
+ only \code{type = "text"} is supported, but further types (HTML, LaTeX,
+ Wiki, etc.) will be provided later }
+ \item{\dots}{ Further arguments to pass to methods. Not used yet. }
+}
+
+\value{
+ \code{is.svSuiteData()} returns \code{TRUE} if the object is an 'svSuiteData'.
+ The various methods serve to extract or print content in the object.
+}
+
+\details{
+ A 'svSuiteData' is, indeed, an environment. The results for the various tests
+ runs are in non hidden (i.e., names not starting with a dot) objects that are
+ of class 'svTestData' in this environment. Various other objects that control
+ the execution of the test, their context, etc. are contained as hidden objects
+ with name starting with a dot. Note that using an environment instead of a
+ list for this object allows for a call by reference instead of a usual call by
+ value in R, when passing this object to a function. This property is largely
+ exploited in all svUnit functions to make sure results of test runs are
+ centralized in the same log ('svSuiteData' object).
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{svSuite}}, \code{\link{is.svTestData}}, \code{\link{check}},
+ \code{\link{Log}} }
+
+\examples{
+clearLog() # Clear any existing log
+
+# Run some tests
+checkTrue(1 < 2)
+checkException(log("a"))
+foo <- function(x, y = 2) return(x * y)
+test(foo) <- function () {
+ checkEqualsNumeric(4, foo(2))
+ checkEqualsNumeric(6, foo(2, nonexisting))
+ checkTrue(is.test(foo))
+ warning("This is a warning")
+ cat("Youhou from test!\n") # Don't use, except for debugging!
+ checkTrue(is.test(test(foo)))
+ checkIdentical(attr(foo, "test"), test(foo))
+ checkException(foo(2, nonexisting))
+ #DEACTIVATED("My deactivation message")
+ checkException(foo(2)) # This test fails
+}
+runTest(foo)
+
+# Now inspect the log, which is a 'svSuiteData' object
+is.svSuiteData(Log())
+stats(Log())
+metadata(Log())
+Log() # Print method
+summary(Log())
+
+# To get a print of the test protocol on file, use:
+protocol(Log(), type = "text", file = "RprofProtocol.out")
+file.show("RprofProtocol.out")
+unlink("RprofProtocol.out")
+
+rm(foo)
+
+\dontrun{
+# Profiling of very simple test runs
+library(utils)
+createLog(description = "test profiling", deleteExisting = TRUE)
+imax <- 3
+jmax <- 100
+l <- 50
+Rprof()
+for (i in 1:imax) {
+ # Change the context for these tests
+ .Log$..Test <- paste("Test", i, sep = "")
+ .Log$..Tag <- paste("#", i, sep = "")
+ res <- system.time({
+ for (j in 1:jmax) checkTrue(i <= j, "My test")
+ }, gcFirst = TRUE)[3]
+ print(res)
+ flush.console()
+}
+Rprof(NULL)
+# Look at profile
+summaryRprof()
+unlink("Rprof.out")
+
+# Look at the log
+summary(Log())
+}
+}
+
+\keyword{ utilities }
Modified: pkg/svUnit/man/svTest.Rd
===================================================================
--- pkg/svUnit/man/svTest.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/man/svTest.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -5,6 +5,7 @@
\alias{test}
\alias{test<-}
\alias{is.test}
+\alias{print.svTest}
\alias{makeUnit}
\alias{makeUnit.default}
\alias{makeUnit.svTest}
@@ -15,9 +16,10 @@
\title{ Create, attach to and manipulate test functions in R objects }
\description{
Test functions are functions without arguments with class 'svTest' containing
- one or more assertions using \code{checkXXX()} functions from RUnit (see
- examples). They can be attached to any object as a 'test' attribute, written
- to unit files or run.
+ one or more assertions using \code{checkxxx()} functions. They can
+ be attached to any object as a 'test' attribute. They can also be transferred
+ into a more formal test unit file on disk by applying the \code{makeUnit()}
+ method.
}
\usage{
@@ -29,26 +31,48 @@
test(x) <- value
is.test(x)
+\method{print}{svTest}(x, \dots)
+
makeUnit(x, \dots)
\method{makeUnit}{default}(x, name = make.names(deparse(substitute(x))),
- dir = tempdir(), \dots)
+ dir = tempdir(), objfile = "", codeSetUp = NULL, codeTearDown = NULL, \dots)
\method{makeUnit}{svTest}(x, name = make.names(deparse(substitute(x))),
- dir = tempdir(), \dots)
+ dir = tempdir(), objfile = "", codeSetUp = NULL, codeTearDown = NULL, \dots)
runTest(x, \dots)
-\method{runTest}{default}(x, name = make.names(deparse(substitute(x))), \dots)
-\method{runTest}{svTest}(x, name = make.names(deparse(substitute(x))), \dots)
+\method{runTest}{default}(x, name = deparse(substitute(x)), objfile = "",
+ tag = "", msg = "", \dots)
+\method{runTest}{svTest}(x, name = deparse(substitute(x)), objfile = "",
+ tag = "", msg = "", \dots)
}
\arguments{
- \item{testFun}{ A function without arguments defining assertions for tests to
- be transformed into a 'svTest' object }
+ \item{testFun}{ A function without arguments defining assertions (using
+ checkxxx() functions) for tests to be transformed into a 'svTest' object }
\item{x}{ Any kind of object }
- \item{value}{ The tests to place in the object (as 'test' attribute).
- Could be a 'svTest' object, or a function without arguments with assertions
- (\code{checkXXX()} functions) }
- \item{name}{ The name of a test unit }
- \item{dir}{ The directory where to create a test unit }
+ \item{value}{ The tests to place in the object (as 'test' attribute);
+ could be a 'svTest' object, or a function without arguments with assertions
+ (\code{checkxxx()} functions) }
+ \item{name}{ The name of a test }
+ \item{dir}{ The directory where to create the test unit file }
+ \item{objfile}{ The path to the file containing the original source code of
+ the object being tested. This argument is used to bring a context for a
+ test and allow a GUI to automatically open the source file for edition when
+ the user clicks on a test that failed or raised an error }
+ \item{codeSetUp}{ An expression with some code you want to add to the
+ \code{.setUp() } function in your unit file (this function is executed
+ before each test }
+ \item{codeTearDown}{ An expression with some code you want to add to the
+ \code{.tearDown() } function in your unit file (this function is executed
+ after each test }
+ \item{tag}{ A tag is a character string identifying a location in source code
+ files (either a test unit file, or the original source code of the tested
+ objects defined in \code{objfile}. This character string will be searched
+ by the text editor for easy location of the cursor near the corresponding`
+ test command, or near the location in the original object that is concerned
+ by this test. Use any string you want to uniquely identify your tag, both
+ in your files, and in this argument }
+ \item{msg}{ A message you want to associate with this test run }
\item{\dots}{ Further arguments to the method (not used yet) }
}
@@ -60,28 +84,30 @@
if it finds something there.
\code{makeUnit()} takes an object, extract its test function and write it in
- a sourceable test unit on the disk. RUnit functions need such files.
+ a sourceable test unit on the disk (it should be compatible with 'RUnit' test
+ unit files too).
- \code{runTest()} returns a 'svUnitData' object identical (for the moment) to
- the 'RUnitTestData' objects returned by \code{runTestSuite()} in package
- RUnit.
+ \code{runTest()} returns invisibly a 'svTestData' object with all results
+ after running specified tests.
}
\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
-\seealso{ \code{\link{svUnit}}, \code{\link{runUnit}},
- \code{\link[RUnit]{checkTrue}}, \code{\link[RUnit]{runTestSuite}} }
+\seealso{ \code{\link{svSuite}}, \code{\link{is.svTestData}},
+ \code{\link{check}}, \code{\link{Log}} }
\examples{
+clearLog() # Clear the log file
+
foo <- function(x, y = 2) return(x * y)
is.test(foo) # No
# Create test cases for this function
test(foo) <- function () {
- checkEqualsNumeric(foo(2), 4)
- checkEqualsNumeric(foo(2, 3), 6)
+ checkEqualsNumeric(4, foo(2))
+ checkEqualsNumeric(6, foo(2, 3))
checkTrue(is.test(foo))
checkTrue(is.test(test(foo)))
- checkIdentical(test(foo), attr(foo, "test"))
+ checkIdentical(attr(foo, "test"), test(foo))
checkException(foo(2, "aa"))
checkException(foo("bb"))
}
@@ -99,12 +125,19 @@
bar <- test(foo)
(runTest(bar))
+# How fast can we run 100 times such kind of tests (700 test in total)?
+# (just an indication because in real situation with test unit files, we
+# have also the time required to source the units!)
+system.time(for (i in 1:100) runTest(foo))[3]
+
is.svTest(test(foo)) # Yes, of course!
# When an object without associated test is passed to runTest(), a simple
# test containing only a DEACTIVATED entry is build
x <- 1:10
summary(runTest(x))
+summary(Log())
+
rm(foo, bar, x)
}
Added: pkg/svUnit/man/svTestData.Rd
===================================================================
--- pkg/svUnit/man/svTestData.Rd (rev 0)
+++ pkg/svUnit/man/svTestData.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,70 @@
+\name{svTestData}
+\alias{is.svTestData}
+\alias{stats}
+\alias{stats.svTestData}
+\alias{print.svTestData}
+\alias{summary.svTestData}
+
+\title{ Objects of class 'svTestData' contain results from running a test }
+\description{
+ The 'svTestData' contains results of test run. The \code{checkxxx()} functions
+ and the \code{runTest()} method generate one such object which is located in
+ the \code{.Log} object in .GlobalEnv. It is then possible to display and
+ report information it contains in various ways to analyze the results.
+}
+
+\usage{
+is.svTestData(x)
+
+stats(object, \dots)
+\method{stats}{svTestData}(object, \dots)
+
+\method{print}{svTestData}(x, all = FALSE, header = TRUE, file = "",
+ append = FALSE, \dots)
+\method{summary}{svTestData}(object, header = TRUE, file = "",
+ append = FALSE, \dots)
+}
+
+\arguments{
+ \item{x}{ Any kind of object, or a 'svTestData' object in the case of
+ \code{print}. }
+ \item{object}{ a 'svTestData' object }
+ \item{all}{ Do we print concise report for all test, or only for the tests
+ that fail or produce an error? }
+ \item{header}{ Do we print a header or not? }
+ \item{file}{ Character. The path to the file where to write the report. If
+ \code{file = ""}, the report is output to the console }
+ \item{append}{ Do we append to this file? }
+ \item{\dots}{ Further arguments to pass to methods. Not used yet. }
+}
+
+\value{
+ \code{is.svTestData()} returns \code{TRUE} if the object is an 'svTestData'.
+ The various methods serve to extract or print content in the object.
+}
+
+\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
+
+\seealso{ \code{\link{svTest}}, \code{\link{svSuiteData}}, \code{\link{check}},
+ \code{\link{Log}} }
+
+\examples{
+foo <- function(x, y = 2) return(x * y)
+is.test(foo) # No
+# Create test cases for this function
+test(foo) <- function () {
+ checkEqualsNumeric(4, foo(2))
+ checkEqualsNumeric(5, foo(2, 3))
+ checkEqualsNumeric(5, foo(nonexists))
+}
+# Generate a 'svTestData' object by running the test
+obj <- runTest(foo) # Equivalent to runTest(test(foo)), but shorter
+obj
+summary(obj)
+stats(obj)
+is.svTestData(obj)
+
+rm(foo, obj)
+}
+
+\keyword{ utilities }
Added: pkg/svUnit/man/svUnit-package.Rd
===================================================================
--- pkg/svUnit/man/svUnit-package.Rd (rev 0)
+++ pkg/svUnit/man/svUnit-package.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -0,0 +1,149 @@
+\name{svUnit-package}
+\alias{svUnit-package}
+\alias{svUnit}
+\docType{package}
+\title{
+A framework for test cases, test units and test suites in R
+}
+\description{
+The SciViews svUnit package defines a framework for testing R code, not unlike
+jUnit for Java. It is inspired on the \code{checkxxx()} functions from the RUnit
+package and the same test unit files should be compatible with both svUnit and
+RUnit.
+}
+\details{
+\tabular{ll}{
+Package: \tab svUnit\cr
+Type: \tab Package\cr
+Version: \tab 0.6-0\cr
+Date: \tab 2008-06-22\cr
+License: \tab GPL 2 or above, at your convenience\cr
+}
+The test unit framework provided in svUnit is based on tests, also called
+assertions, implemented in \code{checkxxx()} functions. For instance, the
+\code{checkTrue(expr)} function check if its 'expr' argument returns \code{TRUE}.
+Results of these assertions are collected in a centralized logger located in
+the \code{.Log} object in .GlobalEnv. This is a 'svSuiteData' object with data
+about the context of the tests (see for instance, \code{lastTest()},
+\code{lastSuite()} or \code{metadata(.Log)}).
+
+Assertions can give three results: (1) \code{TRUE} if success, (2) \code{FALSE}
+in case of failure (in our example, 'expr' in \code{checkTrue(expr)} did not
+return \code{TRUE}), and (3) \code{NA} if the code in 'expr' cannot be parsed or
+executed correctly. All these errors or failures are catch and recorded in the
+logger, as individual 'svTestData' objects.
+
+Both the logger ('svSuiteData' object) and test records inside it ('svTestData'
+objects) have convenient methods to visualize information they contain:
+\code{print()}, \code{summary()} and \code{stats()} methods. Access to the
+individual test records in the logger is done with list-like instructions:
+\code{.Log$mytest} returns the 'svTestData' object named 'mytest', itself the
+result of running test in the 'mytest' test function (i.e, \code{runTest(mytest)},
+see hereunder). Assertions run at the command line, outside of specific contexts
+provided by test functions, test units and test suites (see hereunder) are
+recorded under the 'eval' 'svTestData' object in the logger (i.e., \code{.Log$eval}).
+
+Since a 'svSuiteData' object (the logger) is also an environment, you can get the
+list of all test records it contains using \code{ls(.Log)}, and you can eliminate
+a given test record using something like: \code{rm(mytest, envir = .Log)}.
+
+Test cases are collections of assertions with the satellite code needed
+to build example or situations to be tested. They are collected together in
+argument-less functions with class being 'svTest'. See \code{?svTest} for further
+explanations and a couple of example test cases/test functions.
+
+In its simplest instance, a test function is defined as a separate R object loaded
+in memory (unlike RUnit where all test must be defined in files). You run it
+simply by using \code{runTest(mytest)}. A slightly more structured way to work
+is to attach the test function to the object it testes. You use
+\code{test(myobj) <- testmyobj} to do so, and retrieve it with \code{test(myobj)}.
+Now, the test function always follows the tested object. Testing the object is
+still simple by using \code{runTest(myobj)}, which is totally equivalent to
+\code{runTest(test(myobj))}. One can determine if an object has a test function
+associated, or is a test function itself by using \code{is.test(myobj)}.
+
+Several test functions can be collected together in so-called test units. A test
+unit only exists on disk. It is a file named 'runit*.R' containing sourceable R
+code with test functions having names starting with 'test' (unlike RUnit, the
+default convention of file names starting with 'runit' and test function names
+starting with 'test' is not customizable in svUnit). One can also define
+special \code{.setUp()} and \code{.tearDown()} functions in the unit. The first
+function will be run before each test function, and the latter one will be run
+after it. Test units are created manually, or from a collection of objects with
+associated test functions loaded in an environment (usually .GlobalEnv) thanks
+to the \code{makeUnit()} method. These units should be mutually compatible with
+those used in the RUnit package (at least with its version 0.4-17).
+
+Test units defined for packages should be located in the package /runitTests subdirectory
+ (/inst/runitTests for source of the package) or one of its subdirectories. That
+way, they are located automatically by the function \code{svSuiteList()} that
+also automatically detects all objects with associated test functions loaded
+in .GlobalEnv. Test suites are 'svSuite' objects with a list of test units or
+test objects to collect in the suite. Thus, \code{svSuiteList()}
+automatically builds such a suite with all tests it finds in R, with many
+possibilities to filter packages' test units, objects' test functions, or to add
+non standard directories with test units, for instance. See \code{?svSuite} for
+more details on creating and using these suites.
+
+A GUI (Graphical User Interface) is provided to automatically build and
+run tests suites and to get a graphical (tree) interactive report of the results
+in the Komodo Edit code editor, together with the SciViews-K extension. If you
+want to use this (optional) GUI, visit http://www.sciviews/org/SciViews-K to
+install required software components on your machine.
+
+Finally, the svUnit framework is compatible with R CMD check (see the manual
+"Writing R extensions"). You simply define man pages (.Rd files) with an example
+section running selected test units from your package. The function
+\code{errorLog()} is designed to generate and error if one or more tests failed
+or raised an error during R CMD check, and it should be used at the end of the
+example that runs your unit test(s). That way, R CMD check is interrupted and a
+detailed report of the tests that failed or raised an error is printed. See an
+example in \code{?unitTests.svUnit}.
+}
+\author{
+Written by Ph. Grosjean, inspired from the general design of the 'RUnit' package
+by Thomas Konig, Klaus Junemann & Matthias Burger.
+
+Maintainer: Ph. Grosjean <phgrosjean at sciviews.org>
+}
+\references{
+There is a huge litterature and unit testing. An easy starting point is:
+http://en.wikipedia.org/wiki/Unit\_test.
+}
+
+\keyword{ package }
+\keyword{ utilities }
+
+\seealso{
+ \code{\link[RUnit]{RUnit}}
+}
+\examples{
+# Clear the logger
+clearLog()
+
+# Design and attach a simple test function to an object
+foo <- function(x, y = 2) return(x * y)
+testfoo <- function () {
+ #DEACTIVATED(); # Use this to deactive the test (notice placed in the log)
+ checkEqualsNumeric(5, foo(2), "Check return of foo()")
+ checkException(foo("b"), "Wrong first argument")
+ checkException(foo(2, "a"), "Wrong second argument")
+
+}
+# Attach this to the foo function
+test(foo) <- testfoo
+
+# Run this test
+runTest(foo)
+
+# Inspect the result
+ls(.Log)
+.Log$"test(foo)"
+# This test fails. You see that the test function requires that foo(2) = 5 and
+# the actual implementation returns 4. This is a trivial, useless example, but
+# you are supposed to correct the function. For instance:
+foo <- function(x, y = 2) return(x * y + 1)
+test(foo) <- testfoo
+
+(runTest(foo)) # Now, that's fine!
+}
Deleted: pkg/svUnit/man/svUnit.Rd
===================================================================
--- pkg/svUnit/man/svUnit.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/man/svUnit.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -1,131 +0,0 @@
-\name{svUnit}
-\alias{svUnit}
-\alias{as.svUnit}
-\alias{is.svUnit}
-\alias{svUnitList}
-\alias{print.svUnit}
-\alias{makeUnit.svUnit}
-\alias{runTest.svUnit}
-
-\title{ Create and run test units by collecting together RUnit tests and tests
- defined in objects }
-\description{
- A 'svUnit' object is essentially a list of test units directories, and of
- object names containing tests to add to the test unit. These must be formatted
- in a concise way as described for the 'tests' argument.
-
- \code{svUnitList()} lists all loaded packages having /unitTests/runit*.R files
- (or similar files in subdirectories), and all objects in the user workspace
- that have a 'test' attribute, or are 'svTest' objects (by default). It is a
- rather exhaustive list of all test items currently available in this session.
-
- \code{makeUnit()} writes a test unit on disk with the tests from the objects
- lised in 'svUnit'. \code{runTest()} runs all the test in packages, directories
- and objects listed in the 'svUnit' object.
-}
-
-\usage{
-svUnit(tests)
-
-as.svUnit(x)
-is.svUnit(x)
-
-svUnitList(packages = TRUE, objects = TRUE, pos = .GlobalEnv)
-
-\method{print}{svUnit}(x, \dots)
-\method{makeUnit}{svUnit}(x, name = make.names(deparse(substitute(x))),
- dir = tempdir(), pos = .GlobalEnv, \dots)
-\method{runTest}{svUnit}(x, name = make.names(deparse(substitute(x))), \dots)
-}
-
-\arguments{
- \item{tests}{ A character string with items to include in the test suite.
- It could be 'package:PKG' for including test units located in the /unitTests
- subdirectory of the package PGK, or 'package:PKG (SUITE)' for test units
- located in the subdirectory /unitTests/SUITE of package PKG, or 'dir:MYDIR'
- for including test units in MYDIR, or 'test(OBJ)' for tests embedded in an
- object, or 'OBJ' for 'svTest' object directly }
- \item{x}{ Any kind of object }
- \item{packages}{ Do we list test units available in loaded packages?
- Alternatively one can provide a character vector of package names, and it
- will be used to filter packages (take care: in this case it will look at
- installed packages, not only loaded packages!) }
- \item{objects}{ Do we list test available in objects? Alternatively, one can
- provide a character vector of object names, and it will filter objects in
- 'pos' according to this vector }
- \item{pos}{ The environment to look for 'objects' (environment, character
- string with name of an environment, or interger with position of the
- environment in the search path }
- \item{\dots}{ Further arguments to pass to \code{makeUnit()} and
- \code{defineTestsuite()} from the RUnit package }
- \item{name}{ The name of the test suite to build. }
- \item{dir}{ The directory where to create the test unit file }
-}
-
-\value{
- \code{svUnit()}, \code{as.svUnit()} and \code{svUnitList} return a 'svUnit'
- object. \code{is.svUnit()} returns \code{TRUE} if the object is an 'svUnit'.
-}
-
-\author{ Philippe Grosjean <phgrosjean at sciviews.org> }
-
-\seealso{ \code{\link{runUnit}}, \code{\link{svTest}},
- \code{\link[RUnit]{defineTestSuite}} }
-
-\examples{
-svUnitList() # List all currently available test units and test cases
-
-# Two functions that include their test cases
-Square <- function(x) return(x^2)
-test(Square) <- function() {
- checkEquals(Square(3), 9)
- checkEquals(Square(1:3), c(1, 4, 9))
- checkException(Square("xx"))
-}
-
-Cube <- function(x) return(x^3)
-test(Cube) <- function() {
- checkEquals(Cube(3), 27)
- checkEquals(Cube(1:3), c(1, 8, 28))
- checkException(Cube("xx"))
-}
-
-# A separate test case object
-test.R <- svTest(function() {
- checkTrue(1 < 2, "check1")
- v <- 1:3
- w <- 1:3
- checkEquals(v, w)
-})
-
-# A function without test cases
-foo <- function(x) return(x)
-
-# Look now what tests are available
-svUnitList()
-
-# Only objects, no package units
-svUnitList(packages = FALSE)
-
-\dontrun{
-# Create the test unit file for the objects
-unit <- makeUnit(svUnitList(), name = "AllTests")
-file.show(unit, delete.file = TRUE)
-}
-
-# Filter objects using a list
-svUnitList(objects = c("foo", "bar"))
-
-# Create another svUnit object with selected test items
-(myunit <- svUnit(c("package:svUnit (VirtualClass)", "test(foo)")))
-is.svUnit(myunit) # Should be!
-
-\dontrun{
-# Run all the tests
-summary(runTest(svUnitList(), name = "AllTests"))
-}
-
-rm(Square, Cube, foo, test.R, myunit, unit)
-}
-
-\keyword{ utilities }
Modified: pkg/svUnit/man/unitTests.Rd
===================================================================
--- pkg/svUnit/man/unitTests.Rd 2008-06-13 10:43:26 UTC (rev 11)
+++ pkg/svUnit/man/unitTests.Rd 2008-06-23 01:33:08 UTC (rev 12)
@@ -13,21 +13,21 @@
\examples{
# Make sure to clear log of errors and failures first
-unitClear()
+clearLog()
# Run all test units defined in the 'svUnit' package
-(runTest(svUnit("package:svUnit"), "svUnit"))
+(runTest(svSuite("package:svUnit"), "svUnit"))
\donttest{
# Tests to run with example() but not with R CMD check
# Run all test units defined in the /unitTests/VirtualClass subdir of 'svUnit'
-(runTest(svUnit("package:svUnit (VirtualClass)"), "VirtualClass"))
+(runTest(svSuite("package:svUnit (VirtualClass)"), "VirtualClass"))
}
\dontrun{
# Tests to present in ?unitTests.svUnit but to never run automatically
# Run all currently loaded test cases and test suites of all loaded packages
-(runTest(svUnitList(), "AllTests"))
+(runTest(svSuiteList(), "AllTests"))
}
\dontshow{
@@ -35,8 +35,8 @@
# or run with example(unitTests.svUnit)
}
-# Check errors at the end of the process (needed for R CMD check)
-unitError()
+# Check errors at the end of the process (needed to interrupt R CMD check)
+errorLog()
}
\keyword{utilities}
More information about the Sciviews-commits
mailing list