# Tests for parse_activity_file.R # Consolidated: redundant nonexistent-file tests merged into focused groups test_that("parse_activity_file handles missing and invalid files", { # Nonexistent files across all supported formats return NULL suppressWarnings({ expect_null(parse_activity_file("nonexistent.fit")) expect_null(parse_activity_file("nonexistent.tcx")) expect_null(parse_activity_file("nonexistent.gpx")) expect_null(parse_activity_file("nonexistent.fit.gz")) }) # Unsupported format temp_file <- tempfile(fileext = ".unknown") on.exit(unlink(temp_file)) writeLines("test", temp_file) expect_warning(parse_activity_file(temp_file), "Unsupported file format") # NULL and NA inputs error expect_error(parse_activity_file(NULL)) expect_error(parse_activity_file(NA)) # Empty string returns NULL suppressWarnings(expect_null(parse_activity_file(""))) }) test_that("parse_activity_file handles corrupted files", { # Empty file empty_file <- tempfile(fileext = ".fit") on.exit(unlink(empty_file), add = TRUE) file.create(empty_file) suppressWarnings(expect_null(parse_activity_file(empty_file))) # File with invalid content bad_file <- tempfile(fileext = ".fit") on.exit(unlink(bad_file), add = TRUE) writeLines("corrupted data", bad_file) suppressWarnings(expect_null(parse_activity_file(bad_file))) }) test_that("parse_activity_file with .gz compression", { skip_if_not_installed("R.utils") temp_tcx <- tempfile(fileext = ".tcx") on.exit(unlink(c(temp_tcx, paste0(temp_tcx, ".gz"))), add = TRUE) writeLines("test", temp_tcx) temp_gz <- paste0(temp_tcx, ".gz") R.utils::gzip(temp_tcx, destname = temp_gz, remove = FALSE) # Compressed file with invalid content should return NULL suppressWarnings(expect_null(parse_activity_file(temp_gz))) }) test_that("parse_activity_file handles export_dir parameter", { suppressWarnings({ expect_null(parse_activity_file("test.fit", export_dir = NULL)) expect_null(parse_activity_file("test.fit", export_dir = "/nonexistent/dir")) }) }) # ============================================================ # Real File Parsing (inst/extdata) # ============================================================ test_that("parse_activity_file parses real TCX file correctly", { tcx_path <- system.file("extdata", "activities", "example.tcx", package = "Athlytics") result <- suppressWarnings(parse_activity_file(tcx_path)) expect_s3_class(result, "data.frame") expect_gt(nrow(result), 0) expect_contains(names(result), c("time", "latitude", "longitude", "elevation")) expect_contains(names(result), "heart_rate") expect_contains(names(result), "distance") expect_true(any(!is.na(result$heart_rate))) expect_true(any(!is.na(result$distance))) }) test_that("parse_activity_file parses real GPX file correctly", { gpx_path <- system.file("extdata", "activities", "example.gpx", package = "Athlytics") result <- suppressWarnings(parse_activity_file(gpx_path)) expect_s3_class(result, "data.frame") expect_gt(nrow(result), 0) expect_contains(names(result), c("time", "latitude", "longitude", "elevation")) expect_true(any(!is.na(result$latitude))) expect_true(any(!is.na(result$longitude))) }) test_that("parse_activity_file with export_dir resolves path", { result <- suppressWarnings( parse_activity_file("activities/example.tcx", export_dir = extdata_dir) ) expect_s3_class(result, "data.frame") expect_gt(nrow(result), 0) }) test_that("parse_tcx_file handles empty/invalid XML content", { skip_if(!requireNamespace("xml2", quietly = TRUE), "xml2 not available") empty_file <- tempfile(fileext = ".tcx") on.exit(unlink(empty_file), add = TRUE) file.create(empty_file) suppressWarnings(expect_null(parse_activity_file(empty_file))) bad_file <- tempfile(fileext = ".tcx") on.exit(unlink(bad_file), add = TRUE) writeLines("this is not xml", bad_file) suppressWarnings(expect_null(parse_activity_file(bad_file))) }) test_that("parse_gpx_file handles empty/invalid XML content", { skip_if(!requireNamespace("xml2", quietly = TRUE), "xml2 not available") empty_file <- tempfile(fileext = ".gpx") on.exit(unlink(empty_file), add = TRUE) file.create(empty_file) suppressWarnings(expect_null(parse_activity_file(empty_file))) bad_file <- tempfile(fileext = ".gpx") on.exit(unlink(bad_file), add = TRUE) writeLines("not gpx content", bad_file) suppressWarnings(expect_null(parse_activity_file(bad_file))) }) test_that("parse_activity_file handles alternate TCX and GPX extension prefixes", { skip_if(!requireNamespace("xml2", quietly = TRUE), "xml2 not available") tcx_file <- tempfile(fileext = ".tcx") gpx_file <- tempfile(fileext = ".gpx") on.exit(unlink(c(tcx_file, gpx_file)), add = TRUE) writeLines(c( '', '', ' ', ' ', ' ', ' ', ' 31.1121.1', ' 10', ' 0', ' 140', ' 80', ' 220', ' ', ' ', ' ', '' ), tcx_file) tcx_result <- parse_activity_file(tcx_file) expect_s3_class(tcx_result, "data.frame") expect_true(any(!is.na(tcx_result$power))) expect_true(any(!is.na(tcx_result$heart_rate))) expect_true(any(!is.na(tcx_result$cadence))) writeLines(c( '', '', ' ', ' ', ' 10', ' ', ' 14281215', ' ', ' ', '' ), gpx_file) gpx_result <- parse_activity_file(gpx_file) expect_s3_class(gpx_result, "data.frame") expect_true(any(!is.na(gpx_result$heart_rate))) expect_true(any(!is.na(gpx_result$cadence))) expect_true(any(!is.na(gpx_result$power))) }) test_that("parse_activity_file accepts TCX timestamps with trailing Z", { skip_if(!requireNamespace("xml2", quietly = TRUE), "xml2 not available") tcx_file <- tempfile(fileext = ".tcx") on.exit(unlink(tcx_file), add = TRUE) writeLines(c( '', '', ' ', ' ', ' ', ' ', ' 0', ' ', ' ', ' ', ' 25', ' ', ' ', ' ', '' ), tcx_file) tcx_result <- parse_activity_file(tcx_file) expect_s3_class(tcx_result, "data.frame") expect_equal(nrow(tcx_result), 2) expect_false(any(is.na(tcx_result$time))) expect_equal(as.numeric(diff(tcx_result$time)), 10) })