[CHNOSZ-commits] r949 - in pkg/CHNOSZ: . inst/tinytest src
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Jan 6 08:59:04 CET 2026
Author: jedick
Date: 2026-01-06 08:59:03 +0100 (Tue, 06 Jan 2026)
New Revision: 949
Added:
pkg/CHNOSZ/inst/tinytest/test-taxonomy.R
pkg/CHNOSZ/inst/tinytest/test-util.legend.R
Removed:
pkg/CHNOSZ/src/count_letters.c
Modified:
pkg/CHNOSZ/DESCRIPTION
pkg/CHNOSZ/inst/tinytest/test-diagram.R
pkg/CHNOSZ/inst/tinytest/test-mix.R
Log:
Add tests for taxonomy, util.legend, diagram, and mix
Modified: pkg/CHNOSZ/DESCRIPTION
===================================================================
--- pkg/CHNOSZ/DESCRIPTION 2026-01-06 06:10:46 UTC (rev 948)
+++ pkg/CHNOSZ/DESCRIPTION 2026-01-06 07:59:03 UTC (rev 949)
@@ -1,6 +1,6 @@
Date: 2026-01-06
Package: CHNOSZ
-Version: 2.2.0-15
+Version: 2.2.0-16
Title: Thermodynamic Calculations and Diagrams for Geochemistry
Authors at R: c(
person("Jeffrey", "Dick", , "j3ffdick at gmail.com", role = c("aut", "cre"),
Modified: pkg/CHNOSZ/inst/tinytest/test-diagram.R
===================================================================
--- pkg/CHNOSZ/inst/tinytest/test-diagram.R 2026-01-06 06:10:46 UTC (rev 948)
+++ pkg/CHNOSZ/inst/tinytest/test-diagram.R 2026-01-06 07:59:03 UTC (rev 949)
@@ -1,12 +1,16 @@
# Load default settings for CHNOSZ
reset()
+# Save all plots to a temporary PNG file
+pngfile <- tempfile(fileext = ".png")
+png(pngfile)
+
info <- "Expected errors are produced for inconsistent arguments"
expect_error(diagram(list()), "'eout' is not the output from", info = info)
basis("CHNOS")
species(c("glycine", "alanine"))
a <- affinity()
-expect_message(diagram(a, plot.it = FALSE), "balance: on moles of CO2 in formation reactions", info = info)
+expect_message(diagram(a), "balance: on moles of CO2 in formation reactions", info = info)
e <- equilibrate(a)
expect_error(diagram(e, "Z"), "Z is not a valid diagram type", info = info)
@@ -22,10 +26,10 @@
# We can't calculate the equilibrium activity of a basis species if it's externally buffered
expect_error(diagram(a, "O2"), "is not numeric - was a buffer selected\\?", info = info)
# This one works - a barplot of A/2.303RT
-expect_message(diagram(a, plot.it = FALSE), "balance: on moles of CO2 in formation reactions", info = info)
+expect_message(diagram(a), "balance: on moles of CO2 in formation reactions", info = info)
# If we're plotting A/2.303RT the values can be divided by balancing coefficient or not
-d.1 <- diagram(a, balance = 1, plot.it = FALSE)
-d.CO2 <- diagram(a, plot.it = FALSE)
+expect_silent(d.1 <- diagram(a, balance = 1), info = info)
+expect_silent(d.CO2 <- diagram(a), info = info)
expect_equal(as.numeric(d.CO2$plotvals), as.numeric(d.1$plotvals)/c(1, 1, 2, 2), info = info)
# Now run the calculation over a range of O2
basis("O2", -90)
@@ -34,7 +38,7 @@
# Ask for the equilibrium activity of CO2
expect_error(diagram(a, "CO2", groups = list(1:2, 3:4)), "can't plot equilibrium activities of basis species for grouped species", info = info)
expect_error(diagram(a, "CO2", alpha = TRUE), "equilibrium activities of basis species not available with alpha = TRUE", info = info)
-d <- diagram(a, "CO2", plot.it = FALSE)
+expect_silent(d <- diagram(a, "CO2"), info = info)
# Test that the result does in fact correspond to zero affinity of formation, how about for acetate?
a <- affinity(O2 = d$vals[[1]], CO2 = d$plotvals[[4]])
expect_equal(a$values[[4]], array(numeric(256)), info = info)
@@ -46,13 +50,13 @@
a <- affinity(O2 = c(-80, -60))
e <- equilibrate(a)
# Group the species together
-d <- diagram(e, groups = list(1:2, 3:4), plot.it = FALSE)
+d <- diagram(e, groups = list(1:2, 3:4))
# We should find that their activities have been multiplied by the balance coefficients and summed
n.balance <- CHNOSZ:::balance(a)$n.balance
expect_equal(d$plotvals[[1]], log10(n.balance[1]*10^e$loga.equil[[1]] + n.balance[2]*10^e$loga.equil[[2]]), info = info)
expect_equal(d$plotvals[[2]], log10(n.balance[3]*10^e$loga.equil[[3]] + n.balance[4]*10^e$loga.equil[[4]]), info = info)
# Ask for degrees of formation instead of logarithms of activities
-d <- diagram(e, alpha = TRUE, plot.it = FALSE)
+d <- diagram(e, alpha = TRUE)
# We should find that the sum of alphas is one
expect_equal(Reduce("+", d$plotvals), array(rep(1, 256)), check.attributes = FALSE, info = info)
@@ -64,14 +68,14 @@
expect_error(diagram(a, normalize = TRUE), "can be TRUE only for a 2-D \\(predominance\\) diagram", info = info)
# 2-D
a <- affinity(H2O = c(-10, 0), O2 = c(-80, -70))
-d1 <- diagram(a, normalize = TRUE, plot.it = FALSE)
+d1 <- diagram(a, normalize = TRUE)
e <- equilibrate(a, normalize = TRUE)
-d2 <- diagram(e, plot.it = FALSE)
+expect_silent(d2 <- diagram(e), info = info)
expect_equal(d1$predominant, d2$predominant, info = info)
expect_error(diagram(e, normalize = TRUE), "can be TRUE only if 'eout' is the output from affinity\\(\\)", info = info)
-d3 <- diagram(a, as.residue = TRUE, plot.it = FALSE)
-e <- equilibrate(a, as.residue = TRUE)
-d4 <- diagram(e, plot.it = FALSE)
+expect_silent(d3 <- diagram(a, as.residue = TRUE), info = info)
+expect_silent(e <- equilibrate(a, as.residue = TRUE), info = info)
+expect_silent(d4 <- diagram(e), info = info)
expect_equal(d3$predominant, d4$predominant, info = info)
info <- "NaN values from equilibrate() are preserved (as NA in predominance calculation)"
@@ -80,7 +84,7 @@
species(c("n-hexadecanol", "n-hexadecanoic acid", "n-octadecanol", "n-octadecanoic acid"), c("liq", "liq", "liq", "liq"))
a <- affinity("H2" = c(-12, 0), "O2" = c(-90, -50), T = 30)
e <- equilibrate(a, balance = 1)
-d <- diagram(e, plot.it = FALSE)
+d <- diagram(e)
# equilibrate() here with default "boltzmann" method produces
# NaN at very high O2 + low H2 or very low O2 + high H2
expect_equal(d$predominant[1, 256], as.numeric(NA), info = info)
@@ -93,13 +97,13 @@
# "hematite", "pyrite", "pyrrhotite"))
#a <- affinity(S2 = c(-50, 0), O2 = c(-90, -10), T = 200)
## total range: all species are present
-#d <- diagram(a, fill = "heat", xlim = NULL, ylim = NULL, plot.it = FALSE)
+#d <- diagram(a, fill = "heat", xlim = NULL, ylim = NULL)
#expect_equal(sum(is.na(d$namesx)), 0, info = info)
## reduce y-range to exclude hematite
-#d <- diagram(a, fill = "heat", xlim = NULL, ylim = c(-90, -50), plot.it = FALSE)
+#d <- diagram(a, fill = "heat", xlim = NULL, ylim = c(-90, -50))
#expect_equal(sum(is.na(d$namesx)), 1, info = info)
## reduce x-range to exclude pyrite
-#d <- diagram(a, fill = "heat", xlim = c(-50, -20), ylim = c(-90, -50), plot.it = FALSE)
+#d <- diagram(a, fill = "heat", xlim = c(-50, -20), ylim = c(-90, -50))
#expect_equal(sum(is.na(d$namesx)), 2, info = info)
info <- "P-T diagram has expected geometry"
@@ -107,10 +111,14 @@
basis(c("corundum", "quartz", "oxygen"))
species(c("kyanite", "sillimanite", "andalusite"))
a <- affinity(T = c(200, 900, 50), P = c(0, 9000, 51), exceed.Ttr = TRUE)
-d <- diagram(a, plot.it = FALSE)
+expect_silent(d <- diagram(a), info = info)
expect_equal(species()$name[d$predominant[1, 1]], "andalusite", info = info)
expect_equal(species()$name[d$predominant[1, 51]], "kyanite", info = info)
expect_equal(species()$name[d$predominant[50, 51]], "sillimanite", info = info)
+# The location of the triple point - the algorithm gives an ambiguous location within a certain range
+tp <- find.tp(d$predominant)
+expect_equal(range(tp[, 1]), c(30, 32))
+expect_equal(range(tp[, 2]), c(22, 23))
info <- "diagram(type = .) and affinity(return.buffer = TRUE) give the same results"
# Extracted from ?buffer 20200811
@@ -121,7 +129,7 @@
species("acetic acid", -3)
species(1, -10)
a <- affinity(O2 = O2, T = T)
-d <- diagram(a, type = "CO2", plot.it = FALSE)
+d <- diagram(a, type = "CO2")
and <- as.numeric(d$plotvals[[1]])
# Now do the calculation with affinity(return.buffer = TRUE)
basis("CO2", "AC")
@@ -129,3 +137,15 @@
a.buffer <- affinity(O2 = O2, T = T, return.buffer = TRUE)
ana <- as.numeric(unlist(a.buffer[[1]]))
expect_equal(ana, and, info = info)
+
+# Tests added on 20260106
+info <- "Function works with 'dotted', 'lty.aq', and 'lty.cr' arguments"
+basis(c("Fe", "H2O", "H+", "e-"))
+species(c("Fe+2", "Fe+3", "magnetite", "hematite"))
+a <- affinity(pH = c(0, 12, 50), Eh = c(-1, 1, 50))
+expect_silent(diagram(a, dotted = 3), info = info)
+expect_silent(diagram(a, lty.cr = 2, lty.aq = 3), info = info)
+
+# Close the graphics device and remove the temporary PNG file
+dev.off()
+file.remove(pngfile)
Modified: pkg/CHNOSZ/inst/tinytest/test-mix.R
===================================================================
--- pkg/CHNOSZ/inst/tinytest/test-mix.R 2026-01-06 06:10:46 UTC (rev 948)
+++ pkg/CHNOSZ/inst/tinytest/test-mix.R 2026-01-06 07:59:03 UTC (rev 949)
@@ -30,16 +30,16 @@
species(c(iFe.aq, iFe.cr), 0)
# Increase the temperature so we get a ferrous oxide field
aFe <- affinity(pH = pH, Eh = Eh, T = 300)
-dFe <- diagram(aFe, fill = fill(aFe), plot.it = plot.it)
+dFe <- diagram(aFe, plot.it = plot.it)
# Cu-O-H diagram
species(c(iCu.aq, iCu.cr), 0)
aCu <- affinity(aFe) # argument recall
-dCu <- diagram(aCu, fill = fill(aCu), plot.it = plot.it)
+dCu <- diagram(aCu, plot.it = plot.it)
# Combine the diagrams for a 1:5 mixture of Fe:Cu
aFeCu15 <- mix(dFe, dCu, parts = c(1, 5))
-dFeCu15 <- diagram(aFeCu15, fill = fill(aFeCu15), min.area = 0.01, plot.it = FALSE)
+dFeCu15 <- diagram(aFeCu15, min.area = 0.01, plot.it = FALSE)
# Calculate affinity of bornite (Cu5FeS4)
species("bornite")
abornite <- affinity(aFe) # argument recall
@@ -64,3 +64,28 @@
# The test: values calculated both ways should be equal
expect_equal(abornite_vs_predominant.values, mbornite$A.species$values[[1]], tol = 1e-5, scale = 1, info = info)
+
+# Test added on 20250106
+info <- "Using d3 argument to add bimetallic species produces no errors"
+species("bornite")
+a3 <- affinity(aFe)
+d3 <- diagram(a3, plot.it = FALSE)
+# 1:1 mixture (Fe:Cu)
+expect_silent(a11 <- mix(dFe, dCu, d3, c(1, 1)), info = info)
+# We could visualize it like this:
+#diagram(a11)
+
+# Test added on 20250106
+info <- "maxh() and rebalance() produce no error"
+basis(c("Fe+2", "Cu+", "hydrogen sulfide", "oxygen", "H2O", "H+"))
+species(c("pyrite", "pyrrhotite", "magnetite", "hematite"))
+aFe <- affinity("Fe+2" = c(0, 12, 20), O2 = c(-40, -16, 20))
+dFe <- diagram(aFe)
+species(c("covellite", "chalcocite", "tenorite", "cuprite"))
+aCu <- affinity(aFe) # argument recall
+dCu <- diagram(aCu)
+expect_silent(ac <- mash(dFe, dCu), info = info)
+expect_silent(diagram(ac), info = info)
+expect_silent(ad <- rebalance(dFe, dCu), info = info)
+expect_silent(diagram(ad, balance = 1), info = info)
+
Added: pkg/CHNOSZ/inst/tinytest/test-taxonomy.R
===================================================================
--- pkg/CHNOSZ/inst/tinytest/test-taxonomy.R (rev 0)
+++ pkg/CHNOSZ/inst/tinytest/test-taxonomy.R 2026-01-06 07:59:03 UTC (rev 949)
@@ -0,0 +1,44 @@
+# Load default settings for CHNOSZ
+reset()
+
+# Tests added on 2026-01-06
+
+info <- "Can climb levels and extract taxonomic names"
+
+# Get information about Homo sapiens from the packaged taxonomy files
+taxdir <- system.file("extdata/taxonomy", package = "CHNOSZ")
+
+# Start with a species (taxonomic id for H. sapiens)
+id1 <- 9606
+expect_equal(getrank(id1, taxdir), "species", info = info)
+
+# Go up one level
+id2 <- parent(id1, taxdir)
+expect_equal(getrank(id2, taxdir), "genus", info = info)
+expect_equal(sciname(id2, taxdir), "Homo", info = info)
+
+# Go to an arbitrary level
+id3 <- parent(id1, taxdir, "phylum")
+expect_equal(sciname(id3, taxdir), "Chordata", info = info)
+
+# H. sapiens' complete taxonomy
+id4 <- allparents(id1, taxdir)
+expect_length(sciname(id4, taxdir), 31, info = info)
+
+info <- "Retrieves both 'species' and 'no rank'"
+id5 <- c(83333, 4932, 9606, 186497, 243232)
+expect_equal(unique(getrank(id5, taxdir)[2:3]), "species", info = info)
+expect_equal(unique(getrank(id5, taxdir)[c(1, 4, 5)]), "no rank", info = info)
+# Some of these have strain names, e.g. K-12 or DSM 2661
+expect_equal(range(sapply(strsplit(sciname(id5, taxdir), " "), length)), c(2, 4), info = info)
+
+info <- "Can go from 'no rank' to 'species'"
+id6 <- sapply(id5, function(x) parent(x, taxdir = taxdir, rank = "species"))
+expect_equal(unique(getrank(id6, taxdir)), "species", info = info)
+# All the speices names are binomials
+expect_equal(unique(sapply(strsplit(sciname(id6, taxdir), " "), length)), 2, info = info)
+
+info <- "Use getnodes to keep nodes in memory"
+taxdir <- system.file("extdata/taxonomy", package = "CHNOSZ")
+nodes <- getnodes(taxdir = taxdir)
+expect_equal(dim(nodes), c(63, 3), info = info)
Added: pkg/CHNOSZ/inst/tinytest/test-util.legend.R
===================================================================
--- pkg/CHNOSZ/inst/tinytest/test-util.legend.R (rev 0)
+++ pkg/CHNOSZ/inst/tinytest/test-util.legend.R 2026-01-06 07:59:03 UTC (rev 949)
@@ -0,0 +1,11 @@
+# Load default settings for CHNOSZ
+reset()
+
+# Tests added on 2026-01-06
+
+info <- "Functions for expressions used in legends give expected output"
+expect_equal(lNaCl(0.1), quote(italic(m) * NaCl == 0.1 ~ mol ~ kg^-1), info = info)
+expect_equal(lS(0.1), quote(sum(S) == 0.1 ~ mol ~ kg^-1), info = info)
+expect_equal(lT(25), quote(25 ~ degree * C), info = info)
+expect_equal(lP(1000), quote(1000 ~ bar), info = info)
+expect_equal(lTP(100, 2000), quote(list(100 ~ degree * C, 2000 ~ bar)), info = info)
Deleted: pkg/CHNOSZ/src/count_letters.c
===================================================================
--- pkg/CHNOSZ/src/count_letters.c 2026-01-06 06:10:46 UTC (rev 948)
+++ pkg/CHNOSZ/src/count_letters.c 2026-01-06 07:59:03 UTC (rev 949)
@@ -1,20 +0,0 @@
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* [20180217] adapted from https://stackoverflow.com/questions/13213422/count-the-number-of-occurrences-of-each-letter-in-string */
-
-void count_letters(char **chararray, int *counts) {
-
- char *str = chararray[0];
-
- int i;
- size_t len = strlen(str);
-
- for (i = 0; i < len; i++) {
- char c = str[i];
- if (!isalpha(c)) continue;
- counts[(int)(tolower(c) - 'a')]++;
- }
-
-}
More information about the CHNOSZ-commits
mailing list