tests/testthat/test-ifcb_replace_mat_values.R

test_that("ifcb_replace_mat_values correctly updates the .mat classlist files", {
  skip_if_not_installed("R.matlab") # used as an independent cross-check below

  # Create a temporary directory for the manual_folder
  manual_folder <- file.path(tempdir(), "manual")
  out_folder <- file.path(tempdir(), "out")

  # Create a test .mat file with a classlist
  test_classlist <- matrix(c(1, 99, 3, 99, 5, 6, 99, 8, 9), ncol = 1, byrow = TRUE)
  test_file <- file.path(manual_folder, "test.mat")
  create_temp_mat_file(test_file, test_classlist)

  # Define the target and new IDs
  target_id <- 99
  new_id <- 1
  column_index <- 0 # Python uses 0-based indexing

  # Run the function
  ifcb_replace_mat_values(manual_folder, out_folder, target_id, new_id, column_index)

  # Verify the output file has the expected changes
  output_file <- file.path(out_folder, "test.mat")
  output_contents <- R.matlab::readMat(output_file)
  output_classlist <- output_contents$classlist

  expected_classlist <- matrix(c(1, 1, 3, 1, 5, 6, 1, 8, 9), ncol = 1, byrow = TRUE)
  expect_equal(output_classlist, expected_classlist)

  # Add empty file
  copy <- file.copy(system.file("exdata/D20220124T144202_IFCB139.mat", package = "iRfcb"),
                    file.path(manual_folder, "D20220124T144202_IFCB139.mat"))

  # Run the function
  expect_warning(ifcb_replace_mat_values(manual_folder, out_folder, target_id, new_id, column_index), "Empty")

  # Clean up the temporary directories
  unlink(manual_folder, recursive = TRUE)
  unlink(out_folder, recursive = TRUE)
})

test_that("ifcb_replace_mat_values handles missing manual folder gracefully", {

  manual_folder <- file.path(tempdir(), "nonexistent")
  out_folder <- file.path(tempdir(), "out")

  expect_error(ifcb_replace_mat_values(manual_folder, out_folder, 99, 1),
               "does not exist")

  unlink(manual_folder, recursive = TRUE)
})

test_that("ifcb_replace_mat_values handles missing files in manual folder gracefully", {

  manual_folder <- file.path(tempdir(), "manual")
  out_folder <- file.path(tempdir(), "out")

  manual_folder <- file.path(tempdir(), "empty_dir")

  if(!dir.exists(manual_folder)) {
    dir.create(manual_folder, recursive = TRUE)
  }

  if(!dir.exists(out_folder)) {
    dir.create(out_folder, recursive = TRUE)
  }

  expect_error(ifcb_replace_mat_values(manual_folder, out_folder, 99, 1, 0),
               "No .* files found")

  unlink(manual_folder, recursive = TRUE)
})

test_that("ifcb_replace_mat_values creates output directory if it does not exist", {

  manual_folder <- file.path(tempdir(), "manual")
  out_folder <- file.path(tempdir(), "new_output")

  # Create a test .mat file with a classlist
  test_classlist <- matrix(c(1, 99, 3, 99, 5, 6, 99, 8, 9), ncol = 1, byrow = TRUE)
  column_index <- 0 # Python uses 0-based indexing
  test_file <- file.path(manual_folder, "test.mat")
  create_temp_mat_file(test_file, test_classlist)

  # Run the function
  ifcb_replace_mat_values(manual_folder, out_folder, 99, 1, column_index)

  # Verify the output directory was created and contains the expected file
  expect_true(dir.exists(out_folder))
  output_file <- file.path(out_folder, "test.mat")
  expect_true(file.exists(output_file))

  # Clean up temporary directories
  unlink(manual_folder, recursive = TRUE)
  unlink(out_folder, recursive = TRUE)
})

test_that("ifcb_replace_mat_values handles different column indices correctly", {
  skip_if_not_installed("R.matlab") # used as an independent cross-check below

  manual_folder <- file.path(tempdir(), "manual")
  out_folder <- file.path(tempdir(), "out")

  # Create a test .mat file with a classlist having multiple columns
  test_classlist <- matrix(c(1, 2, 99, 3, 4, 99, 5, 6, 99), ncol = 3, byrow = TRUE)
  test_file <- file.path(manual_folder, "test.mat")
  create_temp_mat_file(test_file, test_classlist)

  # Define the target and new IDs
  target_id <- 99
  new_id <- 1
  column_index <- 2 # Update the third column

  # Run the function
  ifcb_replace_mat_values(manual_folder, out_folder, target_id, new_id, column_index)

  # Verify the output file has the expected changes
  output_file <- file.path(out_folder, "test.mat")
  output_contents <- R.matlab::readMat(output_file)
  output_classlist <- output_contents$classlist

  expected_classlist <- matrix(c(1, 2, 1, 3, 4, 1, 5, 6, 1), ncol = 3, byrow = TRUE)
  expect_equal(output_classlist, expected_classlist)

  # Clean up temporary directories
  unlink(manual_folder, recursive = TRUE)
  unlink(out_folder, recursive = TRUE)
})

test_that("ifcb_replace_mat_values errors clearly on an out-of-range column_index", {

  manual_folder <- file.path(tempdir(), "manual_oor")
  out_folder <- file.path(tempdir(), "out_oor")
  dir.create(manual_folder, showWarnings = FALSE, recursive = TRUE)

  # A single-column classlist; column_index 5 (0-based) has no matching column
  test_classlist <- matrix(c(1, 99, 3, 99, 5), ncol = 1)
  create_temp_mat_file(file.path(manual_folder, "test.mat"), test_classlist)

  expect_error(
    ifcb_replace_mat_values(manual_folder, out_folder, target_id = 99, new_id = 1,
                            column_index = 5),
    "out of range"
  )

  unlink(manual_folder, recursive = TRUE)
  unlink(out_folder, recursive = TRUE)
})

test_that("a classlist MATLAB stored as uint8 is widened rather than wrapped", {
  manual_folder <- file.path(tempdir(), "manual_uint8")
  out_folder <- file.path(tempdir(), "out_uint8")
  on.exit(unlink(c(manual_folder, out_folder), recursive = TRUE), add = TRUE)
  dir.create(manual_folder, showWarnings = FALSE, recursive = TRUE)

  # MATLAB stores a classlist whose values all fit in uint8 exactly like this;
  # writing a large id (ifcb_merge_manual() uses 50000 + i as placeholders)
  # used to wrap it silently: 50001 stored as 81.
  test_file <- file.path(manual_folder, "test.mat")
  write_mat_v5(test_file, list(
    classlist = mat_var_numeric(matrix(c(1, 99, 3), ncol = 1), 9L) # mxUINT8
  ))

  ifcb_replace_mat_values(manual_folder, out_folder, target_id = 99, new_id = 50001, column_index = 0)

  back <- read_mat_v5(file.path(out_folder, "test.mat"))
  expect_equal(as.vector(back$classlist$data), c(1, 50001, 3))
  expect_equal(back$classlist$class_code, 6L) # widened to mxDOUBLE
})

Try the iRfcb package in your browser

Any scripts or data that you put into this service are public.

iRfcb documentation built on Aug. 20, 2026, 1:06 a.m.