tests/testthat/test-internal-functions.R

# Test suite for 0.4.0 internal function architecture
# This tests the new internal fetch functions and updated get_dataset() behavior

test_that("registry has internal_function fields for all datasets", {
  registry <- load_dataset_registry()

  # All datasets should have internal_function field
  for (dataset_name in names(registry$datasets)) {
    dataset_info <- registry$datasets[[dataset_name]]

    expect_true(
      !is.null(dataset_info$internal_function) && dataset_info$internal_function != "",
      info = paste("Dataset", dataset_name, "missing internal_function field")
    )
  }
})

test_that("get_dataset uses internal functions for fresh downloads", {
  skip_if_offline()

  # Test that get_dataset with source="fresh" now uses internal functions
  # We'll test with abecip and verify error messages mention internal functions

  tryCatch({
    data <- get_dataset("abecip", source = "fresh", table = "sbpe")
    # If successful, verify we got data
    expect_true(!is.null(data), "Should get data from internal function")
  }, error = function(e) {
    # If fresh download fails, that's okay for testing purposes
    # We just want to verify the code path goes through internal functions
    expect_true(grepl("get_abecip_indicators|internal function", as.character(e)),
                "Error should mention internal function")
  })
})

test_that("internal functions have consistent parameter interface", {
  required_params <- c("table", "quiet", "max_retries")

  internal_functions <- c(
    "get_rppi", "get_abecip_indicators", "get_abrainc_indicators",
    "get_bcb_realestate", "get_bcb_series", "get_secovi", "get_rppi_bis"
  )

  for (func_name in internal_functions) {
    if (exists(func_name, mode = "function", envir = asNamespace("realestatebr"))) {
      func <- get(func_name, envir = asNamespace("realestatebr"))
      func_params <- names(formals(func))

      for (param in required_params) {
        expect_true(
          param %in% func_params,
          info = paste(func_name, "missing required parameter:", param)
        )
      }
    }
  }
})

test_that("RPPI hierarchical access works through internal functions", {
  skip_if_offline()

  # Test individual index access
  tryCatch({
    fipezap_data <- get_dataset("rppi", source = "fresh", table = "fipezap")
    expect_true(is.data.frame(fipezap_data) || is.list(fipezap_data))
  }, error = function(e) {
    # Fresh download might fail, but error should mention fetch_rppi
    expect_true(grepl("fetch_rppi|rppi", as.character(e), ignore.case = TRUE))
  })

  # Test aggregation access
  tryCatch({
    sales_data <- get_dataset("rppi", source = "fresh", table = "sales")
    expect_true(is.data.frame(sales_data) || is.list(sales_data))
  }, error = function(e) {
    # Fresh download might fail, but error should mention fetch_rppi
    expect_true(grepl("fetch_rppi|rppi", as.character(e), ignore.case = TRUE))
  })
})

test_that("dataset registry consolidated correctly", {
  registry <- load_dataset_registry()

  # rppi_indices should not exist anymore (consolidated into rppi)
  expect_false("rppi_indices" %in% names(registry$datasets))

  # rppi should have hierarchical structure
  rppi_info <- registry$datasets$rppi
  expect_true(!is.null(rppi_info$categories))
  expect_true("fipezap" %in% names(rppi_info$categories))
  expect_true("sale" %in% names(rppi_info$categories))
  expect_true("rent" %in% names(rppi_info$categories))
  expect_true("all" %in% names(rppi_info$categories))
})

test_that("internal functions handle errors gracefully", {
  # Test invalid table parameter using actual legacy functions
  expect_error(
    get_abecip_indicators(table = "invalid_table"),
    "Invalid table"
  )

  expect_error(
    get_abrainc_indicators(table = "invalid_table"),
    "Invalid table"
  )

  expect_error(
    get_rppi(table = "invalid_table"),
    "Invalid"
  )
})

test_that("internal functions validate input parameters", {
  expect_error(get_abecip_indicators(table = 123), "must be")
  expect_error(get_abecip_indicators(quiet = "no"), "logical")
})

test_that("internal functions return expected data structure", {
  skip_if_offline()

  tryCatch(
    {
      data <- get_dataset("abecip", table = "sbpe", source = "github")
      expect_true(!is.null(attr(data, "source")))
      expect_true(!is.null(attr(data, "download_time")))
      expect_true(!is.null(attr(data, "download_info")))
    },
    error = function(e) {
      skip("GitHub release not reachable")
    }
  )
})

test_that("BCB datasets have distinct dataset_function entries", {
  registry <- load_dataset_registry()

  expect_equal(
    registry$datasets$bcb_realestate$dataset_function,
    "get_bcb_realestate"
  )
  expect_equal(
    registry$datasets$bcb_series$dataset_function,
    "get_bcb_series"
  )
})

test_that("all datasets are accessible through get_dataset", {
  registry <- load_dataset_registry()

  # Test that get_dataset can at least attempt to load each dataset
  for (dataset_name in names(registry$datasets)) {
    tryCatch({
      # Try with GitHub cache first (fastest)
      data <- get_dataset(dataset_name, source = "github")
      expect_true(!is.null(data))
    }, error = function(e) {
      # If GitHub cache fails, try fresh download
      tryCatch({
        data <- get_dataset(dataset_name, source = "fresh")
        expect_true(!is.null(data))
      }, error = function(e2) {
        # If both fail, just check that error mentions the internal function
        dataset_info <- registry$datasets[[dataset_name]]
        internal_func <- dataset_info$internal_function

        error_msg <- paste(as.character(e), as.character(e2))
        expect_true(
          grepl(internal_func, error_msg, ignore.case = TRUE) ||
          grepl("internal function", error_msg, ignore.case = TRUE),
          info = paste("Dataset", dataset_name, "error doesn't mention internal function")
        )
      })
    })
  }
})

test_that("legacy function fallback still works", {
  skip_if_offline()

  # Temporarily remove internal_function from registry to test fallback
  registry <- load_dataset_registry()
  original_abecip <- registry$datasets$abecip

  # Create modified registry without internal_function
  modified_abecip <- original_abecip
  modified_abecip$internal_function <- NULL

  # Mock the registry loading
  original_load <- load_dataset_registry
  assign("load_dataset_registry", function() {
    reg <- original_load()
    reg$datasets$abecip <- modified_abecip
    return(reg)
  }, envir = globalenv())

  tryCatch({
    # This should fall back to legacy function
    data <- get_dataset("abecip", source = "fresh", table = "sbpe")
    expect_true(!is.null(data))
  }, error = function(e) {
    # Should mention legacy function if internal function is not available
    expect_true(grepl("legacy|get_abecip", as.character(e), ignore.case = TRUE))
  }, finally = {
    # Restore original function
    assign("load_dataset_registry", original_load, envir = globalenv())
  })
})

# Helper function for offline testing
skip_if_offline <- function() {
  # Simple connection test - try to resolve a domain
  tryCatch({
    con <- url("https://www.google.com", open = "rb")
    close(con)
  }, error = function(e) {
    testthat::skip("Offline - no internet connection")
  })
}

Try the realestatebr package in your browser

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

realestatebr documentation built on June 5, 2026, 5:07 p.m.