# Tests generated by {testbot} by shikokuchuo # https://github.com/shikokuchuo/yyjsonr/blob/18434af4db63c5501207fd37668d0f370a34623b/tests/testthat/test-error-handling-comprehensive.R # # "Comprehensive error handling tests for 100% coverage # Focuses on error conditions, edge cases, and validation" test_that("JSON parsing error handling", { # Invalid JSON strings expect_error(read_json_str("")) expect_error(read_json_str("{")) expect_error(read_json_str("[")) capture_output(expect_error(read_json_str("null null"))) capture_output(expect_error(read_json_str("[,]"))) capture_output(expect_error(read_json_str('{"key": }'))) capture_output(expect_error(read_json_str('{"key" "value"}'))) capture_output(expect_error(read_json_str('[1, 2, 3,]'), "comma")) # Invalid raw vectors #expect_error(read_json_raw(raw(0))) capture_output(expect_error(read_json_raw(as.raw(c(123, 34, 107))))) # Invalid JSON bytes # File errors capture_output( expect_warning( expect_error(read_json_file("nonexistent_file.json")) )) # expect_warning( # expect_error(validate_json_file("nonexistent_file.json")) # ) # Connection errors if (capabilities("sockets")) { capture_output( expect_error(read_json_conn(textConnection(""))) ) } }) test_that("NDJSON parsing error handling", { # Invalid NDJSON #expect_error(read_ndjson_str("")) expect_error(read_ndjson_str("{")) expect_error(read_ndjson_str("{}\n{")) expect_error(read_ndjson_str('{"a": 1}\n{"b": }')) # File errors expect_error(read_ndjson_file("nonexistent_file.ndjson")) # Raw vector errors #expect_error(read_ndjson_raw(raw(0))) expect_error(read_ndjson_raw(as.raw(c(123, 34)))) }) test_that("GeoJSON parsing error handling", { # Invalid GeoJSON expect_error(read_geojson_str("")) expect_error(read_geojson_str("{}")) expect_error(read_geojson_str('{"type": "InvalidType"}')) # File errors expect_warning( expect_error(read_geojson_file("nonexistent_geojson.json")) ) }) test_that("JSON writing error handling", { # Create a temporary file in a non-existent directory bad_path <- file.path("nonexistent_dir", "test.json") expect_error(write_json_file(list(a = 1), bad_path)) # Create a temporary file in a non-existent directory for NDJSON expect_error(write_ndjson_file(list(a = 1), bad_path)) # Create a temporary file in a non-existent directory for GeoJSON # if (requireNamespace("sf", quietly = TRUE)) { # # Create a simple point # point <- sf::st_point(c(0, 0)) # sfc <- sf::st_sfc(point) # expect_error(write_geojson_file(sfc, bad_path)) # } }) test_that("Option validation errors", { # Invalid opts_read_json options expect_error(opts_read_json(int64 = "invalid")) expect_error(opts_read_json(str_specials = "invalid")) expect_error(opts_read_json(num_specials = "invalid")) # expect_error(opts_read_json(digits_promote = -1)) # Validated upon use. not creation. # expect_error(opts_read_json(digits_promote = 31)) # Validated upon use. not creation. # Invalid opts_write_json options expect_error(opts_write_json(dataframe = "invalid")) expect_error(opts_write_json(factor = "invalid")) expect_error(opts_write_json(name_repair = "invalid")) expect_error(opts_write_json(num_specials = "invalid")) expect_error(opts_write_json(str_specials = "invalid")) # expect_error(opts_write_json(digits_secs = -1)) # Validated upon use. not creation. # expect_error(opts_write_json(digits_secs = 7)) # Validated upon use. not creation. # Invalid GeoJSON options expect_error(opts_read_geojson(type = "invalid")) expect_error(opts_read_geojson(property_promotion = "invalid")) expect_error(opts_read_geojson(property_promotion_lgl = "invalid")) }) test_that("Edge case data handling", { # Empty data structures expect_identical(read_json_str("[]"), list()) expect_identical(read_json_str("{}"), setNames(list(), character(0))) expect_identical(read_json_str("null"), NULL) # Large integers large_int <- "9223372036854775807" # Max int64 expect_equal(read_json_str(large_int, int64 = "string"), large_int) expect_equal(read_json_str(large_int, int64 = "double"), 9223372036854775807) if (requireNamespace("bit64", quietly = TRUE)) { result <- read_json_str(large_int, int64 = "bit64") expect_s3_class(result, "integer64") } # Single null handling expect_null(read_json_str("null", single_null = NULL)) expect_equal(read_json_str("null", single_null = "NULL_VALUE"), "NULL_VALUE") expect_equal(read_json_str("null", single_null = 999), 999) }) test_that("Advanced flag combinations", { # Test multiple read flags multi_flags <- c(yyjson_read_flag$YYJSON_READ_ALLOW_TRAILING_COMMAS, yyjson_read_flag$YYJSON_READ_ALLOW_COMMENTS) expect_equal( read_json_str('[1,2,3,] // comment', yyjson_read_flag = multi_flags), c(1L, 2L, 3L) ) # Test multiple write flags multi_write_flags <- c(yyjson_write_flag$YYJSON_WRITE_PRETTY, yyjson_write_flag$YYJSON_WRITE_ESCAPE_SLASHES) result <- write_json_str("hello/world", yyjson_write_flag = multi_write_flags) expect_true(grepl("hello\\\\/world", result)) expect_true(grepl("\\n", result)) # Pretty formatting # Test conflicting flags conflict_flags <- c(yyjson_write_flag$YYJSON_WRITE_PRETTY, yyjson_write_flag$YYJSON_WRITE_PRETTY_TWO_SPACES) result <- write_json_str(list(a = 1, b = 2), yyjson_write_flag = conflict_flags) expect_true(grepl("\\n", result)) # Should use two spaces (overrides pretty) # Number as raw flag expect_equal( read_json_str('[123, 456.789]', yyjson_read_flag = yyjson_read_flag$YYJSON_READ_NUMBER_AS_RAW), c("123", "456.789") ) }) test_that("Memory and performance edge cases", { # Very long strings long_string <- paste0(rep("a", 10000), collapse = "") json_long <- write_json_str(long_string) expect_equal(read_json_str(json_long), long_string) # Large arrays large_array <- 1:1000 json_array <- write_json_str(large_array) expect_equal(read_json_str(json_array), large_array) # Deep nesting deep_list <- list() current <- deep_list for (i in 1:100) { current$nested <- list() current <- current$nested } current$value <- "deep" json_deep <- write_json_str(deep_list) expect_type(read_json_str(json_deep), "list") }) test_that("Unicode and encoding edge cases", { # Unicode characters unicode_str <- "\u00e9\u00e0\u00fc" # éàü json_unicode <- write_json_str(unicode_str) expect_equal(read_json_str(json_unicode), unicode_str) # Escape unicode flag json_escaped <- write_json_str(unicode_str, yyjson_write_flag = yyjson_write_flag$YYJSON_WRITE_ESCAPE_UNICODE) expect_true(grepl("\\\\u", json_escaped)) expect_equal(read_json_str(json_escaped), unicode_str) # Control characters control_chars <- "\n\t\r" json_control <- write_json_str(control_chars) expect_equal(read_json_str(json_control), control_chars) }) test_that("Type promotion edge cases", { # Mixed type arrays with promotion mixed_array <- '[1, "two", 3.0]' # Without promotion (default) result_list <- read_json_str(mixed_array, promote_num_to_string = FALSE) expect_type(result_list, "list") expect_equal(length(result_list), 3) # With promotion result_char <- read_json_str(mixed_array, promote_num_to_string = TRUE, digits_promote = 0) expect_type(result_char, "character") expect_equal(result_char, c("1", "two", "3")) # Digits promotion precision precise_array <- '[1.123456789, 2.987654321, "str"]' result_precise <- read_json_str(precise_array, promote_num_to_string = TRUE, digits_promote = 3) expect_equal(result_precise, c("1.123", "2.988", "str")) })