Back to Multiple platform build/check report for BioC 3.23:   simplified   long
ABCDE[F]GHIJKLMNOPQRSTUVWXYZ

This page was generated on 2026-03-25 11:34 -0400 (Wed, 25 Mar 2026).

HostnameOSArch (*)R versionInstalled pkgs
nebbiolo1Linux (Ubuntu 24.04.3 LTS)x86_64R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences" 4876
kjohnson3macOS 13.7.7 Venturaarm64R Under development (unstable) (2026-03-20 r89666) -- "Unsuffered Consequences" 4573
Click on any hostname to see more info about the system (e.g. compilers)      (*) as reported by 'uname -p', except on Windows and Mac OS X

Package 785/2372HostnameOS / ArchINSTALLBUILDCHECKBUILD BIN
fraq 0.99.2  (landing page)
Travers Ching
Snapshot Date: 2026-03-24 13:40 -0400 (Tue, 24 Mar 2026)
git_url: https://git.bioconductor.org/packages/fraq
git_branch: devel
git_last_commit: d2f1ab3
git_last_commit_date: 2026-02-12 21:25:53 -0400 (Thu, 12 Feb 2026)
nebbiolo1Linux (Ubuntu 24.04.3 LTS) / x86_64  OK    OK    OK  YES
kjohnson3macOS 13.7.7 Ventura / arm64  OK    OK    OK    ERROR  
See other builds for fraq in R Universe.


CHECK results for fraq on nebbiolo1

To the developers/maintainers of the fraq package:
- Allow up to 24 hours (and sometimes 48 hours) for your latest push to git@git.bioconductor.org:packages/fraq.git to reflect on this report. See Troubleshooting Build Report for more information.
- Use the following Renviron settings to reproduce errors and warnings.
- If 'R CMD check' started to fail recently on the Linux builder(s) over a missing dependency, add the missing dependency to 'Suggests:' in your DESCRIPTION file. See Renviron.bioc for more information.

raw results


Summary

Package: fraq
Version: 0.99.2
Command: /home/biocbuild/bbs-3.23-bioc/R/bin/R CMD check --install=check:fraq.install-out.txt --library=/home/biocbuild/bbs-3.23-bioc/R/site-library --timings fraq_0.99.2.tar.gz
StartedAt: 2026-03-24 23:38:06 -0400 (Tue, 24 Mar 2026)
EndedAt: 2026-03-24 23:42:38 -0400 (Tue, 24 Mar 2026)
EllapsedTime: 271.4 seconds
RetCode: 0
Status:   OK  
CheckDir: fraq.Rcheck
Warnings: 0

Command output

##############################################################################
##############################################################################
###
### Running command:
###
###   /home/biocbuild/bbs-3.23-bioc/R/bin/R CMD check --install=check:fraq.install-out.txt --library=/home/biocbuild/bbs-3.23-bioc/R/site-library --timings fraq_0.99.2.tar.gz
###
##############################################################################
##############################################################################


* using log directory ‘/home/biocbuild/bbs-3.23-bioc/meat/fraq.Rcheck’
* using R Under development (unstable) (2026-03-05 r89546)
* using platform: x86_64-pc-linux-gnu
* R was compiled by
    gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
    GNU Fortran (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
* running under: Ubuntu 24.04.4 LTS
* using session charset: UTF-8
* current time: 2026-03-25 03:38:07 UTC
* checking for file ‘fraq/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘fraq’ version ‘0.99.2’
* package encoding: UTF-8
* checking package namespace information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking if there is a namespace ... OK
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package ‘fraq’ can be installed ... OK
* used C++ compiler: ‘g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0’
* checking installed package size ... INFO
  installed size is  7.4Mb
  sub-directories of 1Mb or more:
    libs   7.2Mb
* checking package directory ... OK
* checking ‘build’ directory ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking for left-over files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking code files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking whether startup messages can be suppressed ... OK
* checking dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking line endings in shell scripts ... OK
* checking line endings in C/C++/Fortran sources/headers ... OK
* checking line endings in Makefiles ... OK
* checking compilation flags in Makevars ... OK
* checking for GNU extensions in Makefiles ... INFO
GNU make is a SystemRequirements.
* checking for portable use of $(BLAS_LIBS) and $(LAPACK_LIBS) ... OK
* checking use of PKG_*FLAGS in Makefiles ... OK
* checking compiled code ... INFO
Note: information on .o files is not available
* checking files in ‘vignettes’ ... OK
* checking examples ... OK
* checking for unstated dependencies in ‘tests’ ... OK
* checking tests ...
  Running ‘fraq_concat_tests.R’
  Running ‘fraq_fifo_tests.R’
  Running ‘fraq_format_tests.R’
  Running ‘fraq_interrupt_tests.R’
  Running ‘fraq_prebuilt_tests.R’
  Running ‘fraq_utils_tests.R’
 OK
* checking for unstated dependencies in vignettes ... OK
* checking package vignettes ... OK
* checking re-building of vignette outputs ... OK
* checking PDF version of manual ... OK
* DONE

Status: OK


Installation output

fraq.Rcheck/00install.out

##############################################################################
##############################################################################
###
### Running command:
###
###   /home/biocbuild/bbs-3.23-bioc/R/bin/R CMD INSTALL fraq
###
##############################################################################
##############################################################################


* installing to library ‘/home/biocbuild/bbs-3.23-bioc/R/site-library’
* installing *source* package ‘fraq’ ...
** this is package ‘fraq’ version ‘0.99.2’
** using staged installation
checking for pkg-config... /usr/bin/pkg-config
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C++... yes
checking whether g++ -std=gnu++20 accepts -g... yes
checking for g++ -std=gnu++20 option to enable C++11 features... -std=gnu++11
C++ compiler: g++ -std=gnu++20
zstd 1.5.5 library detected but is lower than bundled version (1.5.2) -- compiling from source
Does not require -latomic flag
configure: creating ./config.status
config.status: creating src/Makevars
** libs
using C++ compiler: ‘g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0’
g++ -std=gnu++20 -I"/home/biocbuild/bbs-3.23-bioc/R/include" -DNDEBUG -DRCPP_USE_UNWIND_PROTECT -DRCPP_NO_RTTI -DRCPP_NO_SUGAR -I../inst/include -I. -IZSTD -IZSTD/common -IZSTD/decompress -IZSTD/compress -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/Rcpp/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/RcppParallel/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/edlibR/include' -I/usr/local/include   -DRCPP_PARALLEL_USE_TBB=1  -fpic  -g -O2  -Wall -Werror=format-security  -c RcppExports.cpp -o RcppExports.o
g++ -std=gnu++20 -I"/home/biocbuild/bbs-3.23-bioc/R/include" -DNDEBUG -DRCPP_USE_UNWIND_PROTECT -DRCPP_NO_RTTI -DRCPP_NO_SUGAR -I../inst/include -I. -IZSTD -IZSTD/common -IZSTD/decompress -IZSTD/compress -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/Rcpp/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/RcppParallel/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/edlibR/include' -I/usr/local/include   -DRCPP_PARALLEL_USE_TBB=1  -fpic  -g -O2  -Wall -Werror=format-security  -c fraq_functions.cpp -o fraq_functions.o
gcc -std=gnu2x -I"/home/biocbuild/bbs-3.23-bioc/R/include" -DNDEBUG -DRCPP_USE_UNWIND_PROTECT -DRCPP_NO_RTTI -DRCPP_NO_SUGAR -I../inst/include -I. -IZSTD -IZSTD/common -IZSTD/decompress -IZSTD/compress -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/Rcpp/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/RcppParallel/include' -I'/home/biocbuild/bbs-3.23-bioc/R/site-library/edlibR/include' -I/usr/local/include    -fpic  -g -O2  -Wall -Werror=format-security -c ZSTD/zstd.c -o ZSTD/zstd.o
ar rcs libQSZSTD.a ZSTD/zstd.o
g++ -std=gnu++20 -shared -L/home/biocbuild/bbs-3.23-bioc/R/lib -L/usr/local/lib -o fraq.so RcppExports.o fraq_functions.o -L. -lQSZSTD -L/home/biocbuild/bbs-3.23-bioc/R/lib -lR
installing to /home/biocbuild/bbs-3.23-bioc/R/site-library/00LOCK-fraq/00new/fraq/libs
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** checking absolute paths in shared objects and dynamic libraries
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (fraq)

Tests output

fraq.Rcheck/tests/fraq_concat_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> suppressPackageStartupMessages(library(fraq))
> 
> read_fastq_lines <- function(path) {
+     if (length(path) != 1L) {
+         stop("path must be scalar", call. = FALSE)
+     }
+     tmp <- tempfile(fileext = ".fastq")
+     on.exit(unlink(tmp), add = TRUE)
+     fraq_convert(path, tmp, nthreads = 1L)
+     readLines(tmp)
+ }
> 
> concat_identical <- function(
+     inputs,
+     output,
+     nthreads
+ ) {
+     fraq_concat(inputs, output, nthreads = as.integer(nthreads))
+     expected <- unlist(lapply(inputs, read_fastq_lines), use.names = FALSE)
+     observed <- read_fastq_lines(output)
+     stopifnot(identical(observed, expected))
+ }
> 
> set.seed(1)
> 
> # Test 1: plain/gz/zst serial
> plain <- tempfile(fileext = ".fastq")
> gz_src <- tempfile(fileext = ".fastq")
> zst_src <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     plain,
+     n_reads = 7,
+     read_length = 60,
+     name_prefix = "plain_"
+ )
> generate_random_fastq(
+     gz_src,
+     n_reads = 11,
+     read_length = 55,
+     name_prefix = "gz_"
+ )
> generate_random_fastq(
+     zst_src,
+     n_reads = 9,
+     read_length = 45,
+     name_prefix = "zst_"
+ )
> 
> gz_in <- tempfile(fileext = ".fastq.gz")
> zst_in <- tempfile(fileext = ".fastq.zst")
> fraq_convert(gz_src, gz_in, nthreads = 1L)
> fraq_convert(zst_src, zst_in, nthreads = 1L)
> 
> out_fastq <- tempfile(fileext = ".fastq")
> concat_identical(
+     c(plain, gz_in, zst_in),
+     out_fastq,
+     nthreads = 1L
+ )
> 
> # Test 2: fraq/gz/mem parallel
> fraq_src <- tempfile(fileext = ".fastq")
> gz_src2 <- tempfile(fileext = ".fastq")
> mem_src <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     fraq_src,
+     n_reads = 12,
+     read_length = 50,
+     name_prefix = "fraq_"
+ )
> generate_random_fastq(
+     gz_src2,
+     n_reads = 8,
+     read_length = 52,
+     name_prefix = "gz2_"
+ )
> generate_random_fastq(
+     mem_src,
+     n_reads = 5,
+     read_length = 48,
+     name_prefix = "mem_"
+ )
> 
> fraq_in <- tempfile(fileext = ".fraq")
> gz_in2 <- tempfile(fileext = ".fastq.gz")
> mem_in <- tempfile(fileext = ".mem")
> fraq_convert(fraq_src, fraq_in, nthreads = 2L)
> fraq_convert(gz_src2, gz_in2, nthreads = 2L)
> fraq_convert(mem_src, mem_in, nthreads = 2L)
> 
> out_fraq <- tempfile(fileext = ".fraq")
> concat_identical(
+     c(fraq_in, gz_in2, mem_in),
+     out_fraq,
+     nthreads = 3L
+ )
> 
> # Test 3: mixed inputs to mem output
> a_src <- tempfile(fileext = ".fastq")
> b_src <- tempfile(fileext = ".fastq")
> generate_random_fastq(a_src, n_reads = 10, read_length = 70, name_prefix = "a_")
> generate_random_fastq(b_src, n_reads = 6, read_length = 65, name_prefix = "b_")
> 
> a_fraq <- tempfile(fileext = ".fraq")
> b_zst <- tempfile(fileext = ".fastq.zst")
> fraq_convert(a_src, a_fraq, nthreads = 2L)
> fraq_convert(b_src, b_zst, nthreads = 2L)
> 
> out_mem <- tempfile(fileext = ".mem")
> concat_identical(
+     c(a_fraq, b_zst),
+     out_mem,
+     nthreads = 2L
+ )
> 
> cat("fraq_concat tests completed successfully\n")
fraq_concat tests completed successfully
> 
> proc.time()
   user  system elapsed 
 11.187   0.471  12.791 

fraq.Rcheck/tests/fraq_fifo_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> suppressPackageStartupMessages(library(fraq))
> 
> default_blocksize <- 65535L
> extended <- identical(Sys.getenv("FRAQ_EXTENDED_TESTS"), "1")
> 
> if (extended) {
+     n_reads <- default_blocksize * 10L
+     read_length <- 100L
+     threads <- 4L
+     invisible(fraq_options("blocksize", default_blocksize))
+ } else {
+     n_reads <- 24L
+     read_length <- 60L
+     threads <- 1L
+     small_block <- 7L
+     invisible(fraq_options("blocksize", small_block))
+ }
> 
> is_fifo_really_supported <- function() {
+     if (!fraq_fifo_supported()) return(FALSE)
+     fifo_path <- tempfile("fraq_fifo_check_", fileext = ".fifo")
+     result <- tryCatch({
+         status <- system(
+             sprintf("mkfifo %s && echo ok || echo fail", shQuote(fifo_path)),
+             intern = TRUE
+         )
+         unlink(fifo_path)
+         identical(status, "ok")
+     }, error = function(e) {
+         unlink(fifo_path)
+         FALSE
+     })
+     isTRUE(result)
+ }
> 
> can_run_fifo_tests <- function() {
+     if (!requireNamespace("processx", quietly = TRUE)) {
+         cat("Skipping FIFO test: processx not available\n")
+         return(FALSE)
+     }
+     if (!is_fifo_really_supported()) {
+         cat("Skipping FIFO test: FIFO not supported in this environment\n")
+         return(FALSE)
+     }
+     TRUE
+ }
> 
> if (!can_run_fifo_tests()) {
+     quit(save = "no", status = 0)
+ }
> 
> fifo1 <- tempfile(fileext = ".fastq.fifo")
> fifo2 <- tempfile(fileext = ".fastq.fifo")
> stopifnot(system2("mkfifo", c(fifo1, fifo2)) == 0L)
> on.exit(unlink(c(fifo1, fifo2)), add = TRUE)
> 
> r1_src <- tempfile(fileext = ".fastq")
> r2_src <- tempfile(fileext = ".fastq")
> generate_random_fastq(r1_src, n_reads, read_length, "fifo_r1_")
> generate_random_fastq(r2_src, n_reads, read_length, "fifo_r2_")
> r1_hash <- tools::md5sum(r1_src)
> r2_hash <- tools::md5sum(r2_src)
> 
> r1_sink <- tempfile(fileext = ".fastq")
> r2_sink <- tempfile(fileext = ".fastq")
> 
> start_drain <- function(fifo_path, dest_path) {
+     processx::process$new(
+         "cat",
+         c(fifo_path),
+         stdin = NULL,
+         stdout = dest_path,
+         stderr = "|",
+         supervise = TRUE,
+         cleanup_tree = TRUE
+     )
+ }
> 
> drains <- list(
+     start_drain(fifo1, r1_sink),
+     start_drain(fifo2, r2_sink)
+ )
> on.exit(lapply(drains, function(p) if (p$is_alive()) p$kill_tree()), add = TRUE, after = FALSE)
> 
> fraq_convert(c(r1_src, r2_src), c(fifo1, fifo2), nthreads = threads)
> cat("Done writing to FIFO, waiting on reader\n")
Done writing to FIFO, waiting on reader
> 
> for (p in drains) {
+     p$wait(timeout = 200000) # 200s bail out instead of hanging forever
+     stopifnot(p$get_exit_status() == 0L)
+ }
> 
> stopifnot(identical(unname(tools::md5sum(r1_sink)), unname(r1_hash)))
> stopifnot(identical(unname(tools::md5sum(r2_sink)), unname(r2_hash)))
> cat("FIFO streaming validated\n")
FIFO streaming validated
> 
> proc.time()
   user  system elapsed 
  9.365   0.510   9.884 

fraq.Rcheck/tests/fraq_format_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> suppressPackageStartupMessages(library(fraq))
> 
> write_fastq <- function(path, records) {
+     stopifnot(length(records) > 0L)
+     lines <- character(length(records) * 4L)
+     for (i in seq_along(records)) {
+         rec <- records[[i]]
+         idx <- (i - 1L) * 4L
+         lines[idx + 1L] <- paste0("@", rec$name)
+         lines[idx + 2L] <- rec$seq
+         lines[idx + 3L] <- "+"
+         lines[idx + 4L] <- rec$qual
+     }
+     con <- file(path, open = "wb")
+     on.exit(close(con), add = TRUE)
+     writeLines(lines, con = con, sep = "\n", useBytes = TRUE)
+     invisible(path)
+ }
> 
> expect_error_message <- function(expr, pattern) {
+     msg <- tryCatch(
+         {
+             expr
+             NULL
+         },
+         error = function(e) e$message
+     )
+     stopifnot(!is.null(msg))
+     stopifnot(grepl(pattern, msg, fixed = TRUE))
+ }
> 
> default_blocksize <- 65535L
> invisible(fraq_options("blocksize", default_blocksize))
> 
> extended <- identical(Sys.getenv("FRAQ_EXTENDED_TESTS"), "1")
> 
> if (extended) {
+     n_reads <- default_blocksize * 10L
+     read_length <- 100L
+     threads <- 4L
+     invisible(fraq_options("blocksize", default_blocksize))
+ } else {
+     n_reads <- 24L
+     read_length <- 60L
+     threads <- 1L
+     small_block <- 7L
+     invisible(fraq_options("blocksize", small_block))
+ }
> 
> cat("Generating source FASTQ for format tests...\n")
Generating source FASTQ for format tests...
> src_fastq <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     src_fastq,
+     n_reads = n_reads,
+     read_length = read_length,
+     name_prefix = "fmt_"
+ )
> hash_original <- tools::md5sum(src_fastq)
> 
> formats <- c(".fastq", ".fastq.gz", ".fastq.zst", ".fraq", ".mem")
> 
> for (fmt in formats) {
+     cat("Testing round-trip conversion through format:", fmt, "\n")
+     target <- tempfile(fileext = fmt)
+     fraq_convert(src_fastq, target, nthreads = threads)
+     back <- tempfile(fileext = ".fastq")
+     fraq_convert(target, back, nthreads = threads)
+     hash_back <- tools::md5sum(back)
+     stopifnot(identical(as.character(hash_back), as.character(hash_original)))
+ }
Testing round-trip conversion through format: .fastq 
Testing round-trip conversion through format: .fastq.gz 
Testing round-trip conversion through format: .fastq.zst 
Testing round-trip conversion through format: .fraq 
Testing round-trip conversion through format: .mem 
> 
> 
> cat("Testing format signature validation...\n")
Testing format signature validation...
> bogus_gz <- tempfile(fileext = ".fastq.gz")
> writeBin(charToRaw("not a gzip"), bogus_gz)
> expect_error_message(
+     fraq_convert(bogus_gz, tempfile(fileext = ".fastq"), nthreads = threads),
+     "valid gzip"
+ )
> 
> bogus_zst <- tempfile(fileext = ".fastq.zst")
> writeBin(charToRaw("not a zstd file"), bogus_zst)
> expect_error_message(
+     fraq_convert(bogus_zst, tempfile(fileext = ".fastq"), nthreads = threads),
+     "valid zstd"
+ )
> 
> bogus_fraq <- tempfile(fileext = ".fraq")
> writeBin(raw(4), bogus_fraq)
> expect_error_message(
+     fraq_convert(bogus_fraq, tempfile(fileext = ".fastq"), nthreads = threads),
+     "FRAQ"
+ )
> 
> cat("Testing fraq_mem helpers...\n")
Testing fraq_mem helpers...
> mem_src <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     mem_src,
+     n_reads = 12,
+     read_length = 40,
+     name_prefix = "mem_src_"
+ )
> mem_key <- tempfile(fileext = ".mem")
> mem_key <- normalizePath(mem_key, winslash = "/", mustWork = FALSE)
> fraq_mem_load(mem_src, mem_key, nthreads = 1L)
> mem_df <- fraq_mem_list()
> stopifnot(mem_key %in% mem_df$mem_key)
> row_idx <- which(mem_df$mem_key == mem_key)
> stopifnot(length(row_idx) == 1L)
> stopifnot(as.integer(mem_df$n_reads[row_idx]) == 12L)
> mem_removed <- fraq_mem_remove(c(mem_key, "nonexistent.mem"))
> stopifnot(identical(unname(mem_removed), c(TRUE, FALSE)))
> mem_df2 <- fraq_mem_list()
> stopifnot(!(mem_key %in% mem_df2$mem_key))
> 
> cat("Testing fraq_mem replacement and multi-load...\n")
Testing fraq_mem replacement and multi-load...
> mem_src_new <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     mem_src_new,
+     n_reads = 7,
+     read_length = 35,
+     name_prefix = "mem_replace_"
+ )
> fraq_mem_load(mem_src_new, mem_key, nthreads = 1L)
> mem_df3 <- fraq_mem_list()
> new_count <- as.integer(mem_df3$n_reads[mem_df3$mem_key == mem_key])
> stopifnot(new_count == 7L)
> 
> multi_inputs <- c(tempfile(fileext = ".fastq"), tempfile(fileext = ".fastq"))
> generate_random_fastq(
+     multi_inputs[1],
+     n_reads = 3,
+     read_length = 20,
+     name_prefix = "multi1_"
+ )
> generate_random_fastq(
+     multi_inputs[2],
+     n_reads = 3,
+     read_length = 25,
+     name_prefix = "multi2_"
+ )
> multi_keys <- c(tempfile(fileext = ".mem"), tempfile(fileext = ".mem"))
> multi_keys <- normalizePath(multi_keys, winslash = "/", mustWork = FALSE)
> fraq_mem_load(multi_inputs, multi_keys, nthreads = 1L)
> mem_df4 <- fraq_mem_list()
> stopifnot(all(mapply(
+     function(k, n) {
+         entries <- mem_df4[mem_df4$mem_key == k, , drop = FALSE]
+         length(entries$n_reads) == 1L && as.integer(entries$n_reads) == n
+     },
+     multi_keys,
+     c(3L, 3L)
+ )))
> 
> cat("Testing argument validation...\n")
Testing argument validation...
> invalid_in <- write_fastq(
+     tempfile(fileext = ".fastq"),
+     list(
+         list(name = "r1", seq = "ACGT", qual = "IIII")
+     )
+ )
> invalid_out <- tempfile(fileext = ".fastq")
> expect_error_message(
+     fraq_downsample(invalid_in, invalid_out, amount = 1.5, nthreads = 1L),
+     "amount must between 0 and 1"
+ )
> 
> concat_a <- tempfile(fileext = ".fastq")
> concat_b <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     concat_a,
+     n_reads = 3,
+     read_length = 20,
+     name_prefix = "ca_"
+ )
> generate_random_fastq(
+     concat_b,
+     n_reads = 2,
+     read_length = 20,
+     name_prefix = "cb_"
+ )
> expect_error_message(
+     fraq_concat(
+         c(concat_a, concat_b),
+         c("out1.fastq", "out2.fastq"),
+         nthreads = 1L
+     ),
+     "output must be a single file path or .mem key"
+ )
> 
> mem_len_mismatch <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     mem_len_mismatch,
+     n_reads = 2,
+     read_length = 20,
+     name_prefix = "mlm_"
+ )
> expect_error_message(
+     fraq_mem_load(
+         c(mem_len_mismatch, mem_len_mismatch),
+         tempfile(fileext = ".mem"),
+         nthreads = 1L
+     ),
+     "`mem_key` must match the length of `input`."
+ )
> 
> cat("Testing reader imbalance warnings...\n")
Testing reader imbalance warnings...
> imbal_r1 <- tempfile(fileext = ".fastq")
> imbal_r2 <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     imbal_r1,
+     n_reads = 6,
+     read_length = 40,
+     name_prefix = "imb1_"
+ )
> generate_random_fastq(
+     imbal_r2,
+     n_reads = 3,
+     read_length = 40,
+     name_prefix = "imb2_"
+ )
> imbal_out1 <- tempfile(fileext = ".fastq")
> imbal_out2 <- tempfile(fileext = ".fastq")
> imbal_msg <- capture.output(
+     fraq_convert(
+         c(imbal_r1, imbal_r2),
+         c(imbal_out1, imbal_out2),
+         nthreads = 1L
+     ),
+     type = "message"
+ )
> stopifnot(any(grepl("inputs: 0", imbal_msg)))
> 
> balanced_r1 <- tempfile(fileext = ".fastq")
> balanced_r2 <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     balanced_r1,
+     n_reads = 4,
+     read_length = 30,
+     name_prefix = "bal1_"
+ )
> generate_random_fastq(
+     balanced_r2,
+     n_reads = 4,
+     read_length = 30,
+     name_prefix = "bal2_"
+ )
> balanced_out1 <- tempfile(fileext = ".fastq")
> balanced_out2 <- tempfile(fileext = ".fastq")
> bal_msg <- capture.output(
+     fraq_convert(
+         c(balanced_r1, balanced_r2),
+         c(balanced_out1, balanced_out2),
+         nthreads = 1L
+     ),
+     type = "message"
+ )
> stopifnot(length(bal_msg) == 0L)
> 
> cat("fraq format round-trip tests completed successfully\n")
fraq format round-trip tests completed successfully
> 
> proc.time()
   user  system elapsed 
  9.305   0.409   9.701 

fraq.Rcheck/tests/fraq_interrupt_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> # NOTE: run this interactively and interrupt manually with Esc or Ctrl+C\n"
> 
> if(interactive()) {
+     suppressPackageStartupMessages(library(fraq))
+     invisible(fraq_options("blocksize", 10L))
+     input <- tempfile(fileext = ".fastq")
+     output <- tempfile(fileext = ".fastq.gz")
+     generate_random_fastq(
+         input,
+         n_reads = 2000,
+         read_length = 100,
+         name_prefix = "interrupt_"
+     )
+ 
+     cat("Interrupt test: single-threaded\n")
+     fraq:::rcpp_fraq_wait(input, output, sleep_ms = 10L, nthreads = 1L)
+ 
+     generate_random_fastq(
+         input,
+         n_reads = 2000,
+         read_length = 100,
+         name_prefix = "interrupt_"
+     )
+     cat("Interrupt test: multi-threaded\n")
+     fraq:::rcpp_fraq_wait(input, output, sleep_ms = 10L, nthreads = 2L)
+ }
> 
> proc.time()
   user  system elapsed 
  0.156   0.033   0.177 

fraq.Rcheck/tests/fraq_prebuilt_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> suppressPackageStartupMessages(library(fraq))
> 
> write_fastq <- function(path, records) {
+     stopifnot(length(records) > 0L)
+     lines <- character(length(records) * 4L)
+     for (i in seq_along(records)) {
+         rec <- records[[i]]
+         idx <- (i - 1L) * 4L
+         lines[idx + 1L] <- paste0("@", rec$name)
+         lines[idx + 2L] <- rec$seq
+         lines[idx + 3L] <- "+"
+         lines[idx + 4L] <- rec$qual
+     }
+     con <- file(path, open = "wb")
+     on.exit(close(con), add = TRUE)
+     writeLines(lines, con = con, sep = "\n", useBytes = TRUE)
+     invisible(path)
+ }
> 
> read_fastq_records <- function(path) {
+     if (!file.exists(path)) {
+         return(list())
+     }
+     lines <- readLines(path)
+     if (length(lines) == 0L) {
+         return(list())
+     }
+     stopifnot(length(lines) %% 4L == 0L)
+     n <- length(lines) / 4L
+     lapply(seq_len(n), function(i) {
+         idx <- (i - 1L) * 4L
+         list(
+             name = substring(lines[idx + 1L], 2L),
+             seq = lines[idx + 2L],
+             qual = lines[idx + 4L]
+         )
+     })
+ }
> 
> test_reverse_complement <- function(seq) {
+     seq <- chartr("ACGTacgt", "TGCAtgca", seq)
+     intToUtf8(rev(utf8ToInt(seq)))
+ }
> 
> compare_fastq <- function(a, b) {
+     lines_a <- if (file.exists(a)) readLines(a) else character()
+     lines_b <- if (file.exists(b)) readLines(b) else character()
+     stopifnot(identical(lines_a, lines_b))
+ }
> 
> expect_error_message <- function(expr, pattern) {
+     msg <- tryCatch(
+         {
+             expr
+             NULL
+         },
+         error = function(e) e$message
+     )
+     stopifnot(!is.null(msg))
+     stopifnot(grepl(pattern, msg, fixed = TRUE))
+ }
> 
> default_blocksize <- 65535L
> invisible(fraq_options("blocksize", default_blocksize))
> 
> 
> cat("Testing generate_random_fastq paired-end output...\n")
Testing generate_random_fastq paired-end output...
> paired_r1 <- tempfile(fileext = ".fastq")
> paired_r2 <- tempfile(fileext = ".fastq")
> paired_reads <- 32L
> paired_length <- 80L
> generate_random_fastq(
+     c(paired_r1, paired_r2),
+     n_reads = paired_reads,
+     read_length = paired_length,
+     name_prefix = "paired_read_"
+ )
> r1_records <- read_fastq_records(paired_r1)
> r2_records <- read_fastq_records(paired_r2)
> stopifnot(length(r1_records) == paired_reads)
> stopifnot(length(r2_records) == paired_reads)
> stopifnot(all(endsWith(vapply(r1_records, `[[`, character(1), "name"), "/1")))
> stopifnot(all(endsWith(vapply(r2_records, `[[`, character(1), "name"), "/2")))
> overlap_lengths <- vapply(
+     seq_len(paired_reads),
+     function(i) {
+         r1_seq <- r1_records[[i]]$seq
+         r2_seq <- r2_records[[i]]$seq
+         r2_rc <- test_reverse_complement(r2_seq)
+         max_k <- 0L
+         for (k in paired_length:1L) {
+             if (
+                 substr(r1_seq, paired_length - k + 1L, paired_length) ==
+                     substr(r2_rc, 1L, k)
+             ) {
+                 max_k <- k
+                 break
+             }
+         }
+         max_k
+     },
+     integer(1)
+ )
> stopifnot(all(overlap_lengths >= 1L))
> 
> cat("Testing fraq_options...\n")
Testing fraq_options...
> old_val <- fraq_options("blocksize", 32L)
> stopifnot(old_val == default_blocksize)
> restored <- fraq_options("blocksize", default_blocksize)
> stopifnot(restored == 32L)
> 
> cat("Testing fraq_downsample...\n")
Testing fraq_downsample...
> downsample_records <- list(
+     list(name = "r1", seq = "ACGT", qual = "IIII"),
+     list(name = "r2", seq = "TGCA", qual = "HHHH"),
+     list(name = "r3", seq = "GGGG", qual = "JJJJ")
+ )
> down_in <- write_fastq(tempfile(fileext = ".fastq"), downsample_records)
> invisible(fraq_options("blocksize", 4L))
> down_keep <- tempfile(fileext = ".fastq")
> fraq_downsample(down_in, down_keep, amount = 1, nthreads = 1L)
> compare_fastq(down_in, down_keep)
> set.seed(123)
> down_drop <- tempfile(fileext = ".fastq")
> fraq_downsample(down_in, down_drop, amount = 0, nthreads = 1L)
> drop_records <- read_fastq_records(down_drop)
> stopifnot(identical(length(drop_records), 0L))
> invisible(fraq_options("blocksize", default_blocksize))
> 
> cat("Testing fraq_convert...\n")
Testing fraq_convert...
> conv_gz <- tempfile(fileext = ".fastq.gz")
> fraq_convert(down_in, conv_gz, nthreads = 1L)
> conv_back <- tempfile(fileext = ".fastq")
> fraq_convert(conv_gz, conv_back, nthreads = 1L)
> compare_fastq(down_in, conv_back)
> 
> cat("Testing fraq_chunk...\n")
Testing fraq_chunk...
> chunk_records <- lapply(seq_len(6), function(i) {
+     list(
+         name = paste0("c", i),
+         seq = paste(rep("A", 6), collapse = ""),
+         qual = "IIIIII"
+     )
+ })
> chunk_in <- write_fastq(tempfile(fileext = ".fastq"), chunk_records)
> chunk_prefix <- tempfile("fraq_chunk")
> fraq_chunk(
+     chunk_in,
+     chunk_prefix,
+     output_suffix = "fastq",
+     chunk_size = 2,
+     nthreads = 1L
+ )
> chunk_size <- 2L
> chunk_total <- ceiling(length(chunk_records) / chunk_size)
> expected_chunks <- sprintf(
+     "%s_chunk%d.fastq",
+     chunk_prefix,
+     0:(chunk_total - 1L)
+ )
> stopifnot(all(file.exists(expected_chunks)))
> chunk_counts <- as.integer(unname(vapply(
+     expected_chunks,
+     function(f) length(read_fastq_records(f)),
+     integer(1)
+ )))
> expected_counts <- rep.int(chunk_size, chunk_total)
> if (chunk_total > 0L) {
+     last_count <- as.integer(
+         length(chunk_records) - chunk_size * (chunk_total - 1L)
+     )
+     expected_counts[chunk_total] <- last_count
+ }
> stopifnot(identical(chunk_counts, expected_counts))
> 
> cat("Testing fraq_count_barcodes...\n")
Testing fraq_count_barcodes...
> barcodes <- c("ACG", "TTT", "AAC")
> count_barcodes <- function(records, allow_revcomp = FALSE) {
+     df <- fraq_count_barcodes(
+         write_fastq(tempfile(fileext = ".fastq"), records),
+         barcodes,
+         max_distance = 0L,
+         allow_revcomp = allow_revcomp,
+         nthreads = 1L
+     )
+     setNames(as.integer(df$count), as.character(df$barcode))
+ }
> count_lookup <- function(counts, key) {
+     if (key %in% names(counts)) counts[[key]] else 0L
+ }
> counts_acg <- count_barcodes(list(list(
+     name = "b1",
+     seq = "ACGAAAA",
+     qual = "IIIIIII"
+ )))
> stopifnot(count_lookup(counts_acg, "ACG") == 1L)
> stopifnot(count_lookup(counts_acg, "NO_MATCH") == 0L)
> counts_ttt <- count_barcodes(list(list(
+     name = "b2",
+     seq = "TTTCCCC",
+     qual = "HHHHHHH"
+ )))
> stopifnot(count_lookup(counts_ttt, "TTT") == 1L)
> stopifnot(count_lookup(counts_ttt, "NO_MATCH") == 0L)
> counts_revcomp <- count_barcodes(
+     list(list(name = "b3", seq = "GTTGGGG", qual = "GGGGGGG")),
+     allow_revcomp = TRUE
+ )
> stopifnot(count_lookup(counts_revcomp, "AAC") == 1L)
> stopifnot(count_lookup(counts_revcomp, "NO_MATCH") == 0L)
> counts_revcomp_off <- count_barcodes(
+     list(list(name = "b3b", seq = "GTTGGGG", qual = "GGGGGGG")),
+     allow_revcomp = FALSE
+ )
> stopifnot(count_lookup(counts_revcomp_off, "AAC") == 0L)
> stopifnot(count_lookup(counts_revcomp_off, "NO_MATCH") == 1L)
> counts_nomatch <- count_barcodes(list(list(
+     name = "b4",
+     seq = "CCCCCCC",
+     qual = "IIIIIII"
+ )))
> stopifnot(count_lookup(counts_nomatch, "NO_MATCH") == 1L)
> 
> cat("Testing barcode present in both mates does not trigger MULTI_MATCH...\n")
Testing barcode present in both mates does not trigger MULTI_MATCH...
> paired_inputs <- c(
+     write_fastq(tempfile(fileext = ".fastq"), list(
+         list(name = "pair/1", seq = "ACGTTTT", qual = "IIIIIII")
+     )),
+     write_fastq(tempfile(fileext = ".fastq"), list(
+         list(name = "pair/2", seq = "GGACGTG", qual = "IIIIIII")
+     ))
+ )
> paired_df <- fraq_count_barcodes(
+     paired_inputs,
+     c("ACG"),
+     max_distance = 0L,
+     allow_revcomp = FALSE,
+     nthreads = 1L
+ )
> paired_counts <- setNames(as.integer(paired_df$count), as.character(paired_df$barcode))
> stopifnot("ACG" %in% names(paired_counts))
> stopifnot(paired_counts[["ACG"]] == 1L)
> stopifnot(!("MULTI_MATCH" %in% paired_df$barcode))
> 
> cat("Testing fraq_demux...\n")
Testing fraq_demux...
> demux_records <- list(
+     list(name = "d1", seq = "AATTTT", qual = "IIIIII"),
+     list(name = "d2", seq = "CCGGGG", qual = "IIIIII"),
+     list(name = "d3", seq = "GGGGGG", qual = "IIIIII")
+ )
> demux_in <- write_fastq(tempfile(fileext = ".fastq"), demux_records)
> demux_template <- file.path(
+     tempdir(),
+     paste0("fraq_demux_", "{barcode}", ".fastq")
+ )
> fraq_demux(
+     demux_in,
+     demux_template,
+     c("AA", "CC"),
+     max_distance = 0L,
+     nthreads = 1L
+ )
> demux_files <- file.path(
+     tempdir(),
+     c("fraq_demux_AA.fastq", "fraq_demux_CC.fastq", "fraq_demux_NO_MATCH.fastq")
+ )
> stopifnot(all(file.exists(demux_files)))
> demux_counts <- vapply(
+     demux_files,
+     function(f) length(read_fastq_records(f)),
+     integer(1)
+ )
> stopifnot(identical(unname(demux_counts), c(1L, 1L, 1L)))
> 
> cat("Testing fraq_quality_filter...\n")
Testing fraq_quality_filter...
> qual_records <- list(
+     list(name = "q1", seq = "AAAA", qual = "IIII"),
+     list(name = "q2", seq = "CCCC", qual = "!!!!"),
+     list(name = "q3", seq = "GGGG", qual = "$$$$")
+ )
> qual_in <- write_fastq(tempfile(fileext = ".fastq"), qual_records)
> qual_out <- tempfile(fileext = ".fastq")
> fraq_quality_filter(
+     qual_in,
+     qual_out,
+     min_mean_quality = 30,
+     max_low_q_bases = 0L,
+     low_q_threshold = 20L,
+     nthreads = 1L
+ )
> qual_pass <- read_fastq_records(qual_out)
> stopifnot(length(qual_pass) == 1L)
> stopifnot(qual_pass[[1]]$name == "q1")
> 
> cat("Testing fraq_merge_pairs...\n")
Testing fraq_merge_pairs...
> merge_r1_records <- list(
+     list(name = "pair1", seq = "ACGTAC", qual = "IIIIII"),
+     list(name = "pair2", seq = "AAAAAA", qual = "IIIIII")
+ )
> merge_r2_records <- list(
+     list(name = "pair1", seq = "GTACGT", qual = "IIIIII"),
+     list(name = "pair2", seq = "CCCCCC", qual = "IIIIII")
+ )
> merge_r1 <- write_fastq(tempfile(fileext = ".fastq"), merge_r1_records)
> merge_r2 <- write_fastq(tempfile(fileext = ".fastq"), merge_r2_records)
> merged_out <- tempfile(fileext = ".fastq")
> unmerged_out <- c(tempfile(fileext = ".fastq"), tempfile(fileext = ".fastq"))
> merge_stats <- fraq_merge_pairs(
+     c(merge_r1, merge_r2),
+     merged_out,
+     unmerged_out,
+     min_overlap = 3L,
+     max_mismatch_rate = 0.0,
+     nthreads = 1L
+ )
> merged_records <- read_fastq_records(merged_out)
> stopifnot(length(merged_records) == 1L)
> stopifnot(merged_records[[1]]$seq == "ACGTAC")
> unmerged_records_r1 <- read_fastq_records(unmerged_out[1])
> unmerged_records_r2 <- read_fastq_records(unmerged_out[2])
> stopifnot(length(unmerged_records_r1) == 1L)
> stopifnot(length(unmerged_records_r2) == 1L)
> stopifnot(merge_stats$merged_reads == 1)
> stopifnot(merge_stats$unmerged_reads == 1)
> 
> cat("Testing fraq_trim_adapters...\n")
Testing fraq_trim_adapters...
> trim_records <- list(
+     list(name = "t1", seq = "AAACCC", qual = "IIIIII"),
+     list(name = "t2", seq = "GGGGGG", qual = "IIIIII"),
+     list(name = "t3", seq = "AAA", qual = "III")
+ )
> trim_in <- write_fastq(tempfile(fileext = ".fastq"), trim_records)
> trim_out <- tempfile(fileext = ".fastq")
> trim_df <- fraq_trim_adapters(
+     trim_in,
+     trim_out,
+     adapters = c("AAA"),
+     max_distance = 0L,
+     filter_untrimmed = TRUE,
+     nthreads = 1L
+ )
> trimmed_records <- read_fastq_records(trim_out)
> stopifnot(length(trimmed_records) == 2L)
> stopifnot(trimmed_records[[1]]$seq == "CCC")
> stopifnot(trimmed_records[[2]]$seq == "")
> trim_counts <- setNames(
+     as.integer(trim_df$count),
+     as.character(trim_df$adapter)
+ )
> stopifnot(trim_counts[["AAA"]] == 2L)
> stopifnot(trim_counts[["NO_ADAPTER"]] == 1L)
> 
> cat("Testing fraq_summary (single-end)...\n")
Testing fraq_summary (single-end)...
> summary_records <- list(
+     list(name = "s1", seq = "ACGT", qual = "IIII"),
+     list(name = "s2", seq = "GGGG", qual = "####")
+ )
> summary_in <- write_fastq(tempfile(fileext = ".fastq"), summary_records)
> summary_se <- fraq_summary(
+     summary_in,
+     phred33 = TRUE,
+     min_overlap = 2L,
+     max_mismatch_rate = 0.0,
+     nthreads = 1L
+ )
> stopifnot(summary_se$basic_stats_R1$total_sequences[1] == 2)
> stopifnot(
+     summary_se$length_distribution_R1$count[
+         summary_se$length_distribution_R1$length == 4
+     ] ==
+         2
+ )
> 
> cat("Testing fraq_summary (paired-end)...\n")
Testing fraq_summary (paired-end)...
> summary_pe <- fraq_summary(
+     c(merge_r1, merge_r2),
+     phred33 = TRUE,
+     min_overlap = 3L,
+     max_mismatch_rate = 0.0,
+     nthreads = 1L
+ )
> stopifnot(summary_pe$basic_stats_R1$total_sequences[1] == 2)
> stopifnot(summary_pe$basic_stats_R2$total_sequences[1] == 2)
> insert_sizes <- summary_pe$insert_size
> stopifnot(is.null(insert_sizes) || any(insert_sizes$insert_size == 6))
> 
> cat("Testing fraq_summary limit...\n")
Testing fraq_summary limit...
> limit_records <- list(
+     list(name = "l1", seq = "ACGT", qual = "IIII"),
+     list(name = "l2", seq = "TGCA", qual = "HHHH"),
+     list(name = "l3", seq = "GGGG", qual = "JJJJ")
+ )
> limit_in <- write_fastq(tempfile(fileext = ".fastq"), limit_records)
> limit_summary <- fraq_summary(limit_in, limit = 2L, nthreads = 1L)
> stopifnot(limit_summary$basic_stats_R1$total_sequences[1] == 2)
> 
> cat("Testing fraq_slice limit and select...\n")
Testing fraq_slice limit and select...
> slice_records <- list(
+     list(name = "s1", seq = "AAAA", qual = "IIII"),
+     list(name = "s2", seq = "CCCC", qual = "IIII"),
+     list(name = "s3", seq = "GGGG", qual = "IIII")
+ )
> slice_in <- write_fastq(tempfile(fileext = ".fastq"), slice_records)
> slice_limit_out <- tempfile(fileext = ".fastq")
> fraq_slice(slice_in, slice_limit_out, limit = 2L, nthreads = 1L)
> slice_limit_read <- read_fastq_records(slice_limit_out)
> stopifnot(length(slice_limit_read) == 2L)
> stopifnot(identical(slice_limit_read[[1]]$name, "s1"))
> stopifnot(identical(slice_limit_read[[2]]$name, "s2"))
> 
> slice_select_out <- tempfile(fileext = ".fastq")
> fraq_slice(slice_in, slice_select_out, select = c(0, 2), nthreads = 1L)
> slice_select_read <- read_fastq_records(slice_select_out)
> stopifnot(length(slice_select_read) == 2L)
> stopifnot(identical(slice_select_read[[1]]$name, "s1"))
> stopifnot(identical(slice_select_read[[2]]$name, "s3"))
> 
> cat("Testing fraq_slice uneven inputs emit excess read warning...\n")
Testing fraq_slice uneven inputs emit excess read warning...
> uneven_r1 <- write_fastq(tempfile(fileext = ".fastq"), list(
+     list(name = "u1", seq = "AAA", qual = "III"),
+     list(name = "u2", seq = "CCC", qual = "III"),
+     list(name = "u3", seq = "GGG", qual = "III"),
+     list(name = "u4", seq = "TTT", qual = "III")
+ ))
> uneven_r2 <- write_fastq(tempfile(fileext = ".fastq"), list(
+     list(name = "u1", seq = "AAA", qual = "III"),
+     list(name = "u2", seq = "CCC", qual = "III")
+ ))
> uneven_out1 <- tempfile(fileext = ".fastq")
> uneven_out2 <- tempfile(fileext = ".fastq")
> msgs <- character()
> msg_con <- textConnection("msgs", "w")
> sink(msg_con, type = "message")
> fraq_slice(
+     c(uneven_r1, uneven_r2),
+     c(uneven_out1, uneven_out2),
+     limit = 3L,
+     nthreads = 1L
+ )
> sink(type = "message")
> close(msg_con)
> stopifnot(any(grepl("excess reads", msgs)))
> uneven_reads1 <- read_fastq_records(uneven_out1)
> uneven_reads2 <- read_fastq_records(uneven_out2)
> stopifnot(length(uneven_reads1) == 2L)
> stopifnot(length(uneven_reads2) == 2L)
> 
> cat("fraq kernel tests completed successfully\n")
fraq kernel tests completed successfully
> 
> proc.time()
   user  system elapsed 
  9.066   0.419   9.473 

fraq.Rcheck/tests/fraq_utils_tests.Rout


R Under development (unstable) (2026-03-05 r89546) -- "Unsuffered Consequences"
Copyright (C) 2026 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> suppressPackageStartupMessages(library(fraq))
> suppressPackageStartupMessages(library(ShortRead))
> suppressPackageStartupMessages(library(Biostrings))
> 
> compare_fastq_records <- function(src_path, converted_path, nthreads = 1L) {
+     src_tmp <- tempfile(fileext = ".fastq")
+     recon_tmp <- tempfile(fileext = ".fastq")
+     fraq_convert(src_path, src_tmp, nthreads = nthreads)
+     fraq_convert(converted_path, recon_tmp, nthreads = nthreads)
+     stopifnot(identical(readLines(src_tmp), readLines(recon_tmp)))
+ }
> 
> cat("Testing ShortRead import/export helpers...\n")
Testing ShortRead import/export helpers...
> set.seed(1)
> nthreads <- 1L
> 
> # Single dataset round-trip --------------------------------------------------
> single_fastq <- tempfile(fileext = ".fastq")
> generate_random_fastq(
+     single_fastq,
+     n_reads = 24,
+     read_length = 60,
+     name_prefix = "srq_single_"
+ )
> single_fraq <- tempfile(fileext = ".fraq")
> fraq_convert(single_fastq, single_fraq, nthreads = nthreads)
> single_srq <- fraq_export_shortreadq(single_fraq, nthreads = nthreads)
> stopifnot(inherits(single_srq, "ShortReadQ"))
> stopifnot(length(single_srq) == 24L)
> 
> single_fastq_out <- tempfile(fileext = ".fastq.gz")
> fraq_import_shortreadq(single_srq, single_fastq_out, nthreads = nthreads)
> compare_fastq_records(single_fastq, single_fastq_out, nthreads = nthreads)
> 
> # Paired dataset round-trip --------------------------------------------------
> paired_fastq <- c(tempfile(fileext = ".fastq"), tempfile(fileext = ".fastq"))
> generate_random_fastq(
+     paired_fastq[1],
+     n_reads = 18,
+     read_length = 55,
+     name_prefix = "srq_pair1_"
+ )
> generate_random_fastq(
+     paired_fastq[2],
+     n_reads = 18,
+     read_length = 45,
+     name_prefix = "srq_pair2_"
+ )
> paired_mem <- c(tempfile(fileext = ".mem"), tempfile(fileext = ".mem"))
> fraq_convert(paired_fastq, paired_mem, nthreads = nthreads)
> paired_srq <- fraq_export_shortreadq(paired_mem, nthreads = nthreads)
> stopifnot(is.list(paired_srq))
> stopifnot(length(paired_srq) == 2L)
> stopifnot(all(vapply(paired_srq, inherits, logical(1), "ShortReadQ")))
> stopifnot(all(vapply(paired_srq, length, integer(1)) == 18L))
> 
> paired_out <- c(tempfile(fileext = ".fastq"), tempfile(fileext = ".fastq.gz"))
> fraq_import_shortreadq(paired_srq, paired_out, nthreads = nthreads)
> compare_fastq_records(paired_fastq[1], paired_out[1], nthreads = nthreads)
> compare_fastq_records(paired_fastq[2], paired_out[2], nthreads = nthreads)
> 
> cat("ShortRead helper tests completed successfully.\n")
ShortRead helper tests completed successfully.
> 
> cat("Testing fraq_align Biostrings integration...\n")
Testing fraq_align Biostrings integration...
> align_queries <- Biostrings::DNAStringSet(c("ACGTNT", "TTT"))
> align_targets <- Biostrings::DNAStringSet(c("ACGTAT", "GTTTGG"))
> align_res <- fraq_align(
+     align_queries,
+     align_targets,
+     max_distance = 2L,
+     boundary = "contains",
+     distance_metric = "lv"
+ )
> stopifnot(inherits(align_res$query, "BStringSet"))
> stopifnot(inherits(align_res$target, "BStringSet"))
> stopifnot(identical(names(align_res)[1:2], c("query", "target")))
> stopifnot(all(as.character(align_res$query) == as.character(align_queries)))
> stopifnot(all(as.character(align_res$target) == as.character(align_targets)))
> stopifnot(all(align_res$distance <= 2L))
> 
> align_hm <- fraq_align(
+     "ACGT",
+     "ACGG",
+     max_distance = 1L,
+     boundary = "global",
+     distance_metric = "hm"
+ )
> stopifnot(align_hm$distance[1] == 1L)
> stopifnot(inherits(align_hm$query, "BStringSet"))
> stopifnot(inherits(align_hm$target, "BStringSet"))
> stopifnot(align_hm$start[1] == 0L)
> stopifnot(align_hm$end[1] == 3L)
> 
> cat("Util function tests completed successfully.\n")
Util function tests completed successfully.
> 
> proc.time()
   user  system elapsed 
  9.374   0.423   9.787 

Example timings

fraq.Rcheck/fraq-Ex.timings

nameusersystemelapsed
fraq_align0.0550.0110.068
fraq_chunk0.0060.0040.011
fraq_concat0.0020.0000.003
fraq_convert0.0000.0000.001
fraq_count_barcodes0.0670.0110.078
fraq_demux0.0260.0010.027
fraq_downsample0.1020.0050.107
fraq_fifo_supported000
fraq_mem_list0.0030.0020.004
fraq_merge_pairs0.0070.0000.007
fraq_options0.0010.0000.001
fraq_quality_filter0.0260.0000.026
fraq_rcpp_template0.0010.0000.001
fraq_shortread0.0270.0010.028
fraq_slice0.0010.0000.001
fraq_summary0.1070.0010.108
fraq_trim_adapters0.0610.0020.063
generate_random_fastq0.0590.0010.060