Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions R/check.R
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,36 @@ check_tif_dt_str <- function(tif_dt) {

return(TRUE)
}


check_pin_tif_dt_str <- function(pin_tif_dt) {
stopifnot(
is.data.frame(pin_tif_dt),
data.table::is.data.table(pin_tif_dt)
)

pin_tif_dt_str <- c(
"year" = "numeric", "pin" = "character", "tax_code" = "character",
"agency_num" = "character", "agency_name" = "character",
"agency_major_type" = "character", "agency_minor_type" = "character",
"tif_share" = "numeric"
)

if (!identical(pin_tif_dt_str, sapply(pin_tif_dt, mode))) {
stop(
"pin_tif_dt must be in the same format as the data returned by ",
"lookup_pin_tif(). Ensure all column names and types are the same"
)
}

keys <- c("year", "pin", "agency_num")
if (!all(keys %in% data.table::key(pin_tif_dt))) {
stop(
"pin_tif_dt must have the same data.table keys as the data returned by ",
"lookup_pin_tif(). Please ensure that the year, pin, and agency_num ",
"columns are set as data.table keys"
)
}

return(TRUE)
}
4 changes: 4 additions & 0 deletions R/lookup.R
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ lookup_tif <- function(year, tax_code, conn = ptaxsim_db_conn) {
check_db_sync(conn)
)

# Make sure to remove any years after 2023 from the year vector, since
# otherwise we risk silently returning null TIF shares for post-2024 TIFs
year <- year[year <= 2023]
Comment on lines +367 to +369

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change aligns the behavior of lookup_tif() with its docstring, which states:

Returns 0 rows for any input year after 2023. For tax years 2024 and later, use lookup_pin_tif to lookup a PIN's TIF share.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm - so this will ensure that even if a user inputs multiple years, such as 2022:2024 the output will include 2022 - 2023 and no rows for 2024?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right! I'm not sure if that's the most intuitive behavior for end users, but it at least conforms with the specification that we describe in the function documentation.


tif_share <- NULL
dt <- DBI::dbGetQuery(
conn,
Expand Down
3 changes: 2 additions & 1 deletion R/tax_bill.R
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ tax_bill <- function(year_vec,
stopifnot(
check_agency_dt_str(agency_dt),
check_pin_dt_str(pin_dt),
check_tif_dt_str(tif_dt)
check_tif_dt_str(tif_dt),
check_pin_tif_dt_str(pin_tif_dt)
)

# Create data.table from inputs. Use the Cartesian product if the inputs are
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test-check.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ assign("ptaxsim_db_conn_wrong", ptaxsim_db_conn_wrong, envir = .GlobalEnv)
pins <- c("14081020190000", "09274240240000", "07101010391078")
years <- c(2019, 2019, 2018)
tax_codes <- c("73105", "22031", "35011")
# pin_tif_distribution is only populated starting in 2024
pin_tif_dt_years <- 2024

test_that("lookups return correct checks", {
expect_true(check_agency_dt_str(lookup_agency(years, tax_codes)))
Expand All @@ -29,6 +31,7 @@ test_that("lookups return correct checks", {
expect_true(check_pin_dt_str(lookup_pin(years[1], pins)))
expect_true(check_tif_dt_str(lookup_tif(years, tax_codes)))
expect_true(check_tif_dt_str(lookup_tif(years[1], tax_codes)))
expect_true(check_pin_tif_dt_str(lookup_pin_tif(pin_tif_dt_years, pins)))
})


Expand All @@ -44,6 +47,10 @@ test_that("wrong column types throws error", {
tif <- lookup_tif(years, tax_codes) %>%
mutate(agency_num = as.integer(agency_num))
expect_error(check_tif_dt_str(tif))

pin_tif <- lookup_pin_tif(pin_tif_dt_years, pins) %>%
mutate(agency_num = as.integer(agency_num))
expect_error(check_pin_tif_dt_str(pin_tif))
})

test_that("outputs fail if not keyed data.table", {
Expand All @@ -70,6 +77,14 @@ test_that("outputs fail if not keyed data.table", {
expect_equal(key(tif), c("year", "tax_code", "agency_num"))
setkey(tif, NULL)
expect_error(check_tif_dt_str(tif))

pin_tif <- lookup_pin_tif(pin_tif_dt_years, pins) %>%
as_tibble()
expect_error(check_pin_tif_dt_str(pin_tif))
pin_tif <- lookup_pin_tif(pin_tif_dt_years, pins)
expect_equal(key(pin_tif), c("year", "pin", "agency_num"))
setkey(pin_tif, NULL)
expect_error(check_pin_tif_dt_str(pin_tif))
})


Expand Down
62 changes: 61 additions & 1 deletion tests/testthat/test-lookup.R
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ test_that("lookup values/data are correct", {
)
})

test_that("lookup_tif returns 0 rows for years >= 2024", {
expect_equal(nrow(lookup_tif(2024:max_year, "73105")), 0)
expect_equal(nrow(lookup_tif(2022:2023, "73105")), 2)
})

test_that("function returns expect data type/structure", {
expect_s3_class(
lookup_tif(2018, "73105"),
Expand Down Expand Up @@ -158,7 +163,10 @@ test_that("lookup values/data are correct", {
expect_equivalent(
lookup_pin(2018:max_year, sum_df$pin) %>%
mutate(
exe_vet_dis = exe_vet_dis_lt50 + exe_vet_dis_50_69 + exe_vet_dis_ge70,
exe_vet_dis = (
exe_vet_dis_lt50 + exe_vet_dis_50_69 +
exe_vet_dis_ge70 + exe_vet_dis_100
),
across(starts_with("exe_"), ~ .x != 0)
) %>%
select(year, pin, exe_homeowner:exe_disabled, exe_vet_dis) %>%
Expand Down Expand Up @@ -204,6 +212,58 @@ test_that("bad/incorrect inputs throw errors", {
})


context("test lookup_pin_tif()")

##### TEST lookup_pin_tif() #####

# Use PINs known to be in TIFs in 2024
pin_in_24_tif <- "01301000160000"
pin_in_24_tif_2 <- "01303000090000"
# A random PIN that is not in a TIF in 2024
pin_not_in_24_tif <- "01011000020000"

test_that("lookup_pin_tif returns 0 rows for pre-2024 years", {
expect_equal(nrow(lookup_pin_tif(2023, pin_in_24_tif)), 0)
})

test_that("lookup_pin_tif returns rows for 2024+", {
expect_equal(nrow(lookup_pin_tif(2024, pin_in_24_tif)), 1)
})

test_that("lookup_pin_tif returns expected data type/structure", {
pin_tif <- lookup_pin_tif(2024, pin_in_24_tif)
expect_s3_class(pin_tif, c("data.frame", "data.table"))
expect_named(pin_tif, c(
"year", "pin", "tax_code", "agency_num",
"agency_name", "agency_major_type", "agency_minor_type", "tif_share"
))
})

test_that("lookup_pin_tif returns correct values/data", {
expect_equal(
lookup_pin_tif(2024, pin_in_24_tif)$tif_share,
0.777,
tolerance = 0.001
)
})

test_that("lookup_pin_tif returns 0 rows for PIN not in any TIF", {
expect_equal(nrow(lookup_pin_tif(2024, pin_not_in_24_tif)), 0)
})

test_that("lookup_pin_tif bad/incorrect inputs throw errors", {
expect_error(lookup_pin_tif("2024", pin_in_24_tif)) # year not numeric
expect_error(lookup_pin_tif(2024, 2153010581083)) # PIN not character
expect_error(lookup_pin_tif(2024, "021530105810")) # PIN wrong length
})

test_that("lookup_pin_tif handles multiple PINs", {
# A second PIN that is in a TIF district in 2024
result <- lookup_pin_tif(2024, c(pin_in_24_tif, pin_in_24_tif_2))
expect_equal(nrow(result), 2)
})


context("test lookup_agency()")

##### TEST lookup_agency() #####
Expand Down
52 changes: 27 additions & 25 deletions tests/testthat/test-tax_bill.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,32 @@ det_dt <- sample_tax_bills_detail
pins <- c(
"14081020190000", "09274240240000", "07101010391078"
)
years <- c(2019, 2019, 2018)
years <- 2024:2022

test_that("bad/incorrect vector inputs throw errors", {
expect_error(tax_bill("2019", pins[1]))
expect_error(tax_bill("2024", pins[1]))
expect_error(tax_bill(numeric(0), pins[1]))
expect_error(tax_bill(2019, 14081020190000))
expect_error(tax_bill(c(2000, 2019), pins[1]))
expect_error(tax_bill(2019, c("1408102019000", pins[2])))
expect_error(tax_bill(2019, pins[1], tax_code_vec = 73105))
expect_error(tax_bill(2019, pins[1], tax_code_vec = "5454"))
expect_error(tax_bill(2019, pins[2], simplify = "yes"))
expect_error(tax_bill(2018:2019, pins[2:3], simplify = c(TRUE, FALSE)))
expect_error(tax_bill(years[1], 14081020190000))
expect_error(tax_bill(c(2000, years[1]), pins[1]))
expect_error(tax_bill(years[1], c("1408102019000", pins[2])))
expect_error(tax_bill(years[1], pins[1], tax_code_vec = 73105))
expect_error(tax_bill(years[1], pins[1], tax_code_vec = "5454"))
expect_error(tax_bill(years[1], pins[2], simplify = "yes"))
expect_error(tax_bill(years[2:1], pins[2:3], simplify = c(TRUE, FALSE)))
})

test_that("bad/incorrect data frame inputs throw errors", {
expect_error(tax_bill(2019, pins[1], pin_dt = c(23000, 959051)))
expect_error(tax_bill(2019, pins[1], agency_dt = c("3232", "TIF")))
expect_error(tax_bill(2019, pins[1], tif_dt = c(23000, 959051)))
expect_error(tax_bill(years[1], pins[1], pin_dt = c(23000, 959051)))
expect_error(tax_bill(years[1], pins[1], agency_dt = c("3232", "TIF")))
expect_error(tax_bill(years[1], pins[1], tif_dt = c(23000, 959051)))
expect_error(tax_bill(years[1], pins[1], pin_tif_dt = c(23000, 959051)))
})

test_that("non-unique values to main args throws error", {
expect_error(tax_bill(2019, pins[c(1, 1)]))
expect_error(tax_bill(c(2010, 2010), pins[1]))
expect_error(tax_bill(years[1], pins[c(1, 1)]))
expect_error(tax_bill(c(years[c(1, 1)]), pins[1]))
expect_error(
tax_bill(c(2010, 2010), pins[c(1, 2)], tax_code_vec = c("73105"))
tax_bill(years[c(1, 1)], pins[c(1, 2)], tax_code_vec = c("73105"))
)
})

Expand All @@ -52,20 +53,21 @@ test_that("incorrect size inputs throw errors", {
})

test_that("data frame inputs throw errors when required cols missing", {
expect_error(tax_bill(2019, pins[1], pin_dt = data.table()))
expect_error(tax_bill(2019, pins[1], agency_dt = data.table()))
expect_error(tax_bill(2019, pins[1], tif_dt = data.table()))
expect_error(tax_bill(years[1], pins[1], pin_dt = data.table()))
expect_error(tax_bill(years[1], pins[1], agency_dt = data.table()))
expect_error(tax_bill(years[1], pins[1], tif_dt = data.table()))
expect_error(tax_bill(years[1], pins[1], pin_tif_dt = data.table()))
})

test_that("function returns expected data type/structure", {
expect_s3_class(tax_bill(2018, pins[1]), "data.frame")
expect_s3_class(tax_bill(2018, pins[1]), "data.table")
expect_s3_class(tax_bill(years[1], pins[1]), "data.frame")
expect_s3_class(tax_bill(years[1], pins[1]), "data.table")
expect_equal(
key(tax_bill(2018, pins[1])),
key(tax_bill(years[1], pins[1])),
c("year", "pin", "agency_num")
)
expect_named(
tax_bill(2018:2019, pins[1:2]),
tax_bill(years[1:2], pins[1:2]),
c(
"year", "pin", "class", "tax_code", "av", "eav", "agency_num",
"agency_name", "agency_major_type", "agency_minor_type",
Expand All @@ -77,7 +79,7 @@ test_that("function returns expected data type/structure", {
0
)
expect_named(
tax_bill(2018:2019, pins[1:2], simplify = FALSE),
tax_bill(years[1:2], pins[1:2], simplify = FALSE),
c(
"year", "pin", "class", "tax_code", "av", "eav", "exe_total",
"agency_num", "agency_name", "agency_major_type", "agency_minor_type",
Expand All @@ -92,8 +94,8 @@ test_that("function returns expected data type/structure", {
sum(is.na(tax_bill(years[1], pins[1], simplify = FALSE))),
0
)
expect_equal(dim(tax_bill(years[1], pins[1], simplify = TRUE)), c(12, 12))
expect_equal(dim(tax_bill(years[1], pins[1], simplify = FALSE)), c(10, 25))
expect_equal(dim(tax_bill(years[1], pins[1], simplify = TRUE)), c(11, 12))
expect_equal(dim(tax_bill(years[1], pins[1], simplify = FALSE)), c(9, 25))
Comment on lines +97 to +98

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The number of agencies for these PINs has changed in the past few years, so we update the test to reflect the new count of agency line items.

})

test_that("returned amount/output correct for single PIN", {
Expand Down
Loading