diff --git a/DESCRIPTION b/DESCRIPTION index c84be985a..1837b1623 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: grattan Type: Package Title: Australian Tax Policy Analysis -Version: 1.7.1.4 -Date: 2019-10-29 +Version: 1.8.0.0 +Date: 2019-11-02 Authors@R: c(person("Hugh", "Parsonage", role = c("aut", "cre"), email = "hugh.parsonage@gmail.com"), person("Tim", "Cameron", role = "aut"), person("Brendan", "Coates", role = "aut"), @@ -27,6 +27,7 @@ Imports: rsdmx, fastmatch, forecast, + fy (>= 0.2.0), assertthat (>= 0.1), magrittr (>= 1.5), Rcpp (>= 0.12.3), diff --git a/NAMESPACE b/NAMESPACE index 7f91b27a5..e7b1cd5be 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -86,6 +86,7 @@ import(data.table) importFrom(Rcpp,sourceCpp) importFrom(fastmatch,"%fin%") importFrom(fastmatch,fmatch) +importFrom(fy,validate_fys_permitted) importFrom(hutils,"%ein%") importFrom(hutils,"%notchin%") importFrom(hutils,AND) diff --git a/NEWS.md b/NEWS.md index e51a2b8bc..b9bb47a1e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,24 @@ +## 1.8.0.0 + +### Potentially breaking changes + +* Pacakage `fy` is now used for operations involving financial years, notably validation of + input. This has led to changes in error messages (below) as well as the weakening + of some tests to omit checks of class attributes which were never intended to be + relied on. + + ```r + # Prev: + fy2date("foo") + #> Error: fy.yr contains non-FYs. + + # Now + #> Error: `x = "foo"` was not a valid financial year. + ``` + + + + ## 1.7.1.4 * Fixed minor error that affected tax liability calculations for 2010-11 and 2011-12 financial years diff --git a/R/CG_inflator.R b/R/CG_inflator.R index bc9cc3d77..8814430a7 100644 --- a/R/CG_inflator.R +++ b/R/CG_inflator.R @@ -13,7 +13,8 @@ CG_population_inflator <- function(x = 1, to_fy, forecast.series = "mean", cg.series){ - stopifnot(all_fy(c(from_fy, to_fy))) + from_fy <- validate_fys_permitted(from_fy) + to_fy <- validate_fys_permitted(to_fy) stopifnot(forecast.series %in% c("mean", "lower", "upper", "custom")) last_fy <- max(from_fy, to_fy) @@ -43,16 +44,17 @@ CG_population_inflator <- function(x = 1, CG_inflator <- function(x = 1, from_fy, to_fy, forecast.series = "mean"){ prohibit_vector_recycling(x, from_fy, to_fy) - stopifnot(is.numeric(x), all_fy(from_fy), all_fy(to_fy)) + stopifnot(is.numeric(x)) + cg_fys <- union(cg_inflators_1213[["fy_year"]], + cg_inflators_1617[["fy_year"]]) + from_fy <- validate_fys_permitted(from_fy, permitted_fys = cg_fys) + to_fy <- validate_fys_permitted(to_fy, permitted_fys = cg_fys) + + nse_forecast_series <- forecast.series cg_inflators_tbl <- cg_inflators_1516[forecast.series == nse_forecast_series] - - - # Else NAs. - stopifnot(all(to_fy %in% cg_inflators_1516[["fy_year"]]), - all(from_fy %in% cg_inflators_1516[["fy_year"]])) # CRAN Note avoidance ordering <- NULL @@ -60,8 +62,6 @@ CG_inflator <- function(x = 1, from_fy, to_fy, forecast.series = "mean"){ data.table(x = x, from_fy = from_fy, to_fy = to_fy) %>% .[, ordering := 1:.N] - - raw_out <- input %>% merge(cg_inflators_tbl, by.y = "fy_year", by.x = "from_fy", all.x = TRUE) %>% diff --git a/R/append_custom_series.R b/R/append_custom_series.R index 32b8cf3fe..e9858adac 100644 --- a/R/append_custom_series.R +++ b/R/append_custom_series.R @@ -51,34 +51,27 @@ append_custom_series <- function(orig, # Is the following if (first_fy_in_custom_series == next_fy(last_full_fy_in_orig)) { last_obsValue_in_actual_series <- last(.subset2(orig, "obsValue")) - - obsValue <- r <- NULL - custom.series[, obsValue := last_obsValue_in_actual_series * cumprod(1 + r)] - - out <- - rbindlist(list(orig, - custom.series), - use.names = TRUE, - fill = TRUE) %>% - # Ensure the date falls appropriately - unique(by = "fy_year", fromLast = TRUE) } else { series_before_custom <- orig[fy_year < first_fy_in_custom_series] - last_obsValue_in_actual_series <- last(series_before_custom[["obsValue"]]) - custom.series[, obsValue := last_obsValue_in_actual_series * cumprod(1 + r)] - - out <- - rbindlist(list(orig, - custom.series), - use.names = TRUE, - fill = TRUE) %>% - # Ensure the date falls appropriately - unique(by = "fy_year", fromLast = TRUE) + } - out + obsValue <- r <- NULL + custom.series[, obsValue := last_obsValue_in_actual_series * cumprod(1 + r)] + + # TODO: make fy inherit character + if (inherits(.subset2(orig, "fy_year"), "fy") && + !inherits(.subset2(custom.series, "fy_year"), "fy")) { + orig <- copy(orig)[, fy_year := as.character(fy_year)] + } + rbindlist(list(orig, + custom.series), + use.names = TRUE, + fill = TRUE) %>% + # Ensure the date falls appropriately + unique(by = "fy_year", fromLast = TRUE) } diff --git a/R/carer_payment.R b/R/carer_payment.R index 45a26f51a..f99c44c92 100644 --- a/R/carer_payment.R +++ b/R/carer_payment.R @@ -75,6 +75,7 @@ carer_payment <- function(Date = NULL, } } + class(fy.year) <- c("fy", "character") # for cbind.data.frame method input <- data.table(do.call(cbind.data.frame, mget(ls()))) #Rates, income test, and asset test same as age pension diff --git a/R/cpi_inflator.R b/R/cpi_inflator.R index cdc9fab38..a7698214e 100644 --- a/R/cpi_inflator.R +++ b/R/cpi_inflator.R @@ -135,6 +135,7 @@ cpi_inflator <- function(from_nominal_price = 1, } + permitted_fys <- .subset2(cpi.indices, "fy_year") earliest_from_fy <- permitted_fys[[1L]] cpi_table_nom <- @@ -182,6 +183,10 @@ cpi_inflator <- function(from_nominal_price = 1, max_fy2yr(to_fy), by = 1L)), obsValue = cpi_index_forecast)) + + # TODO: fy should inherit 'character' + cpi.indices.new[, fy_year := as.character(fy_year)] + cpi.indices <- rbindlist(list(cpi.indices, cpi.indices.new), use.names = TRUE, diff --git a/R/fy.year.R b/R/fy.year.R index 56d075ed8..eada245c1 100644 --- a/R/fy.year.R +++ b/R/fy.year.R @@ -1,5 +1,7 @@ #' Convenience functions for dealing with financial years #' +#' @description From grattan v1.7.1.4, these are reexports from the \code{\link[fy]{fy-package}}. +#' #' @name is.fy #' @aliases fy.year yr2fy fy2yr fy2date date2fy #' @param yr_ending An integer representing a year. @@ -23,6 +25,7 @@ #' #' \code{date2fy} converts a date to the corresponding financial year. #' +#' @importFrom fy validate_fys_permitted #' #' @examples #' is.fy("2012-13") @@ -33,195 +36,29 @@ #' @export is.fy fy.year yr2fy fy2yr fy2date date2fy NULL +is.fy <- fy::is_fy - -is.fy <- function(fy.yr){ - out <- logical(length(fy.yr)) - potential_fys <- grepl("^([12][0-9]{3})[-\\s]?[0-9]{2}$", fy.yr, perl = TRUE) - out[potential_fys] <- - {as.integer(sub("^([12][0-9]{3})[-\\s]?[0-9]{2}$", "\\1", fy.yr[potential_fys], perl = TRUE)) + 1L} %% 100L == as.integer(sub("^[12][0-9]{3}[-\\s]?([0-9]{2})$", "\\1", fy.yr[potential_fys], perl = TRUE)) - out -} - -is_fy2 <- function(x) { - a <- c("1897-98", "1898-99", "1899-00", "1900-01", "1901-02", "1902-03", - "1903-04", "1904-05", "1905-06", "1906-07", "1907-08", "1908-09", - "1909-10", "1910-11", "1911-12", "1912-13", "1913-14", "1914-15", - "1915-16", "1916-17", "1917-18", "1918-19", "1919-20", "1920-21", - "1921-22", "1922-23", "1923-24", "1924-25", "1925-26", "1926-27", - "1927-28", "1928-29", "1929-30", "1930-31", "1931-32", "1932-33", - "1933-34", "1934-35", "1935-36", "1936-37", "1937-38", "1938-39", - "1939-40", "1940-41", "1941-42", "1942-43", "1943-44", "1944-45", - "1945-46", "1946-47", "1947-48", "1948-49", "1949-50", "1950-51", - "1951-52", "1952-53", "1953-54", "1954-55", "1955-56", "1956-57", - "1957-58", "1958-59", "1959-60", "1960-61", "1961-62", "1962-63", - "1963-64", "1964-65", "1965-66", "1966-67", "1967-68", "1968-69", - "1969-70", "1970-71", "1971-72", "1972-73", "1973-74", "1974-75", - "1975-76", "1976-77", "1977-78", "1978-79", "1979-80", "1980-81", - "1981-82", "1982-83", "1983-84", "1984-85", "1985-86", "1986-87", - "1987-88", "1988-89", "1989-90", "1990-91", "1991-92", "1992-93", - "1993-94", "1994-95", "1995-96", "1996-97", "1997-98", "1998-99", - "1999-00", "2000-01", "2001-02", "2002-03", "2003-04", "2004-05", - "2005-06", "2006-07", "2007-08", "2008-09", "2009-10", "2010-11", - "2011-12", "2012-13", "2013-14", "2014-15", "2015-16", "2016-17", - "2017-18", "2018-19", "2019-20", "2020-21", "2021-22", "2022-23", - "2023-24", "2024-25", "2025-26", "2026-27", "2027-28", "2028-29", - "2029-30", "2030-31", "2031-32", "2032-33", "2033-34", "2034-35", - "2035-36", "2036-37", "2037-38", "2038-39", "2039-40", "2040-41", - "2041-42", "2042-43", "2043-44", "2044-45", "2045-46", "2046-47", - "2047-48", "2048-49", "2049-50", "2050-51", "2051-52", "2052-53") - x %fin% a -} - -all_fy <- function(x, permitted = NULL) { - is.character(x) && length(x) && { - - - a <- if (is.null(permitted)) { - c("1897-98", "1898-99", "1899-00", "1900-01", "1901-02", "1902-03", - "1903-04", "1904-05", "1905-06", "1906-07", "1907-08", "1908-09", - "1909-10", "1910-11", "1911-12", "1912-13", "1913-14", "1914-15", - "1915-16", "1916-17", "1917-18", "1918-19", "1919-20", "1920-21", - "1921-22", "1922-23", "1923-24", "1924-25", "1925-26", "1926-27", - "1927-28", "1928-29", "1929-30", "1930-31", "1931-32", "1932-33", - "1933-34", "1934-35", "1935-36", "1936-37", "1937-38", "1938-39", - "1939-40", "1940-41", "1941-42", "1942-43", "1943-44", "1944-45", - "1945-46", "1946-47", "1947-48", "1948-49", "1949-50", "1950-51", - "1951-52", "1952-53", "1953-54", "1954-55", "1955-56", "1956-57", - "1957-58", "1958-59", "1959-60", "1960-61", "1961-62", "1962-63", - "1963-64", "1964-65", "1965-66", "1966-67", "1967-68", "1968-69", - "1969-70", "1970-71", "1971-72", "1972-73", "1973-74", "1974-75", - "1975-76", "1976-77", "1977-78", "1978-79", "1979-80", "1980-81", - "1981-82", "1982-83", "1983-84", "1984-85", "1985-86", "1986-87", - "1987-88", "1988-89", "1989-90", "1990-91", "1991-92", "1992-93", - "1993-94", "1994-95", "1995-96", "1996-97", "1997-98", "1998-99", - "1999-00", "2000-01", "2001-02", "2002-03", "2003-04", "2004-05", - "2005-06", "2006-07", "2007-08", "2008-09", "2009-10", "2010-11", - "2011-12", "2012-13", "2013-14", "2014-15", "2015-16", "2016-17", - "2017-18", "2018-19", "2019-20", "2020-21", "2021-22", "2022-23", - "2023-24", "2024-25", "2025-26", "2026-27", "2027-28", "2028-29", - "2029-30", "2030-31", "2031-32", "2032-33", "2033-34", "2034-35", - "2035-36", "2036-37", "2037-38", "2038-39", "2039-40", "2040-41", - "2041-42", "2042-43", "2043-44", "2044-45", "2045-46", "2046-47", - "2047-48", "2048-49", "2049-50", "2050-51", "2051-52", "2052-53") - } else { - permitted - } - if (anyNA(fmatch(x, a))) { - a <- NULL - FALSE - } else { - a <- NULL - TRUE - } - } -} - -range_fy2yr <- function(x) { - if (length(x) == 1L) { - y <- fmatch(x, fys1901) + 1900L - return(rep(y, times = 2L)) - } - if (!is.null(g_min_yr <- attr(x, "grattan_min_yr")) && - !is.null(g_max_yr <- attr(x, "grattan_max_yr"))) { - return(c(g_min_yr, g_max_yr)) - } - y <- fmatch(x, fys1901) + 1900L - miny <- min(y, na.rm = TRUE) - maxy <- max(y, na.rm = TRUE) - setattr(x, "grattan_min_yr", miny) - setattr(x, "grattan_max_yr", maxy) - c(miny, maxy) -} - -min_fy2yr <- function(x) { - range_fy2yr(x)[1L] -} - -max_fy2yr <- function(x) { - range_fy2yr(x)[2L] -} - -fy.year <- function(yr_ending){ +fy.year <- function(yr_ending) { paste0(as.integer(yr_ending) - 1, "-", substr(yr_ending, 3, 4)) } -yr2fy <- function(yr_ending, assume1901_2100 = .getOption("grattan.assume1901_2100", TRUE)) { - if (assume1901_2100 || - AND(min(yr_ending) > 1900L, - max(yr_ending) < 2100L)) { - fys1901[yr_ending - 1900L] - } else { - .yr2fy(yr_ending) - } -} - -.yr2fy <- function(yr_ending) { - if (length(yr_ending) > 10e3L) { - # Apparently quicker for > 1000 - accel_repetitive_input(yr_ending, .yr2fy) - } else { - sprintf("%d-%02d", as.integer(yr_ending) - 1L, as.integer(yr_ending) %% 100L) - } -} - -fy2yr <- function(fy.yr){ - if (!all(is.fy(fy.yr))){ - stop("fy.yr contains non-FYs") - } else { - 1L + as.integer(gsub("^.*([12][0-9]{3}).?[0-9]{2}.*$", "\\1", fy.yr)) - } -} - - - -fy2date <- function(x){ - if (!all(is.fy(x))){ - stop("fy.yr contains non-FYs") - } else { - date <- paste0(as.numeric(gsub("^([1-9][0-9]{3}).*", "\\1", x)) + 1, "-06-30") - as.Date(date) - } -} - +yr2fy <- fy::yr2fy +fy2yr <- fy::fy2yr +fy2date <- fy::fy2date +date2fy <- fy::date2fy +qtr2fy <- fy::qtr2fy -date2fy <- function(date) { - if_else(month(date) < 7L, - yr2fy(year(date)), - yr2fy(year(date) + 1L)) -} +max_fy2yr <- function(x) fy2yr(max(x)) +min_fy2yr <- function(x) fy2yr(min(x)) -qtr2fy <- function(yq) { - if (inherits(yq, "yearqtr")) { - yqn <- as.numeric(yq) - o <- - yr2fy(if_else(yqn %% 1 >= 0.5, - yqn + 1, - yqn)) - o - } else if (is.character(yq)) { - # Rely on the first element to determine the - # format - first_yq <- yq[1L] - if (is.na(first_yq)) { - yq_is_na <- is.na(yq) - first_yq <- first(yq[which.min(yq_is_na)]) - } - - y <- q <- NULL - cm <- CJ(y = 1901:2099, q = 1:4) - cm[, "YQ" := sprintf("%d%sQ%d", y, substr(first_yq, 5L, 5L), q)] - cm[, "fy_year" := yr2fy(y + q %in% 3:4)] - cmyq <- .subset2(cm, "YQ") - o <- .subset2(cm, "fy_year")[fmatch(yq, cmyq)] +all_fy <- function(x, permitted = NULL) { + if (is.null(permitted)) { + all(fy::is_fy(x), na.rm = TRUE) } else { - stop("Unknown class for `yq`.") + !anyNA(fmatch(x, permitted)) } - o } - - - +is_fy2 <- fy::is_fy diff --git a/R/generic_inflator.R b/R/generic_inflator.R index ac92c5192..934258f2e 100644 --- a/R/generic_inflator.R +++ b/R/generic_inflator.R @@ -18,10 +18,10 @@ generic_inflator <- function(vars, estimator = "mean", pred_interval = 80) { stopifnot(length(h) == 1L) + fy.year.of.sample.file <- validate_fys_permitted(fy.year.of.sample.file) stopifnot(is.integer(h), h >= 0, - length(fy.year.of.sample.file) == 1L, - all_fy(fy.year.of.sample.file)) + length(fy.year.of.sample.file) == 1L) if (h == 0L) { return(data.table(variable = vars, inflator = 1)) diff --git a/R/medicare_levy.R b/R/medicare_levy.R index 690e438d6..43e8fa4d5 100644 --- a/R/medicare_levy.R +++ b/R/medicare_levy.R @@ -44,11 +44,12 @@ medicare_levy <- function(income, family_status = "individual", n_dependants = 0, .checks = TRUE){ - if (.checks){ - stopifnot(all_fy(fy.year), all(family_status %in% c("family", "individual"))) + if (.checks) { + fy.year <- validate_fys_permitted(fy.year) + stopifnot(all(family_status %in% c("family", "individual"))) prohibit_vector_recycling(income, fy.year, family_status, Spouse_income, sapto.eligible, n_dependants) } - if (any(Spouse_income > 0 & family_status == "individual")){ + if (any(Spouse_income > 0 & family_status == "individual")) { stop("If Spouse_income is nonzero, family_status cannot be 'individual'.") } @@ -59,7 +60,7 @@ medicare_levy <- function(income, # Allow a join on a complete sato, pto, sapto key # To do this we need to make sato = sapto.eligible # and pto = !sato when required. - if (is.null(sato) && is.null(pto)){ + if (is.null(sato) && is.null(pto)) { sato <- sapto.eligible pto <- sapto.eligible & !sato } else { diff --git a/R/pension_supplement.R b/R/pension_supplement.R index 999a40e2a..b1c31d26c 100644 --- a/R/pension_supplement.R +++ b/R/pension_supplement.R @@ -60,6 +60,7 @@ pension_supplement <- function(has_partner = FALSE, # Convert arguments to data table ls_np <- ls()[ls() != "per"] + class(fy.year) <- c("fy", "character") input <- data.table(do.call(cbind.data.frame, mget(ls_np))) eligible <- NULL diff --git a/R/validate_fys_permitted.R b/R/validate_fys_permitted.R deleted file mode 100644 index 2a518f970..000000000 --- a/R/validate_fys_permitted.R +++ /dev/null @@ -1,211 +0,0 @@ -#' Verifying validity of financial years -#' -#' @description Many functions expect financial years. -#' Determining that they are validly entered is often quite -#' computationally costly, relative to the core calculations. -#' These internal functions provide mechanisms to check validity -#' quickly, while still providing clear, accurate error messages. -#' -#' @param to_verify A user-provided value, purporting to be -#' character vector of financial years. -#' @param permitted_fys A character vector of valid financial years. -#' @param min.yr,max.yr Integers specifying the range of \code{to_verify}. -#' If \code{NULL}, no restriction on the upper or lower bound of the range. -#' -#' @param deparsed A string indicating the argument that the user provided. -#' Should generally be provided explicitly as the default is unlikely -#' to be user-friendly. -#' @param allow.projection If \code{FALSE} emit a different error message. -#' @param earliest_permitted_financial_year,latest_permitted_financial_year Text -#' for earliest/latest permitted financial year when \code{min.yr}/\code{max.yr} -#' condition is violated. -#' -#' @return If \code{to_verify} contains valid financial years -#' they are returned all in the form \code{2013-14}. If they were -#' already in that form, they obtain the following attributes: -#' \describe{ -#' \item{\code{grattan_all_fy}}{\code{TRUE} if all the financial years are valid.} -#' \item{\code{grattan_min_yr}}{An integer, the earliest year ending in \code{to_verify}.} -#' \item{\code{grattan_max_yr}}{An integer, the latest year ending in \code{to_verify}.} -#' } -#' -#' -#' - - - -validate_fys_permitted <- function(to_verify, permitted_fys, - min.yr = NULL, max.yr = NULL, - deparsed = deparse(substitute(to_verify)), - allow.projection = TRUE, - earliest_permitted_financial_year = "earliest permitted financial year", - latest_permitted_financial_year = "latest permitted financial year") { - - if (!is.character(to_verify)) { - stopn("`", deparsed, "` was type ", typeof(to_verify), ", ", - "but must be type character. ", - "Ensure `", deparsed, "` is a character vector of financial years", - if (!is.null(min.yr) || !is.null(max.yr)) " satisfying ", - if (!is.null(min.yr)) paste0("`", yr2fy(min.yr), " <= "), - if (!is.null(min.yr) || !is.null(max.yr)) deparsed, - if (!is.null(max.yr)) paste0(" <= ", yr2fy(max.yr), "`"), - ".") - } - - if (isTRUE(attr(to_verify, "grattan_all_fy"))) { - # If min.yr and max.yr are fine, we're done - if (is.null(min.yr) && is.null(max.yr)) { - return(to_verify) - } - - # Otherwise we just have to check the ranges: either the ranges - # are no good (in which case error), or return to_verify - - # min - if (!is.null(min.yr)) { - - # Unlikely (misspecified), but should assert - if (is.null(attr(to_verify, "grattan_min_yr"))) { - min_to_verify_yr <- min_fy2yr(to_verify) - attr(to_verify, "grattan_min_yr") <- min_to_verify_yr - } - - if (min.yr > attr(to_verify, "grattan_min_yr")) { - min.k <- min.yr - 1900L - stopn("`", deparsed, - if (length(to_verify) == 1L) " = " else "` contained ", - '"', fys1901[attr(to_verify, "grattan_min_yr") - 1900L], '"', - if (length(to_verify) == 1L) "`", - " which ", - "is earlier than the ", - earliest_permitted_financial_year, - ": ", '"', fys1901[min.k], '"', ".") - } - } - - # max - if (!is.null(max.yr)) { - - # Unlikely (misspecified), but should assert - if (is.null(attr(to_verify, "grattan_max_yr"))) { - max_to_verify_yr <- max_fy2yr(to_verify) - attr(to_verify, "grattan_max_yr") <- max_to_verify_yr - } - - if (max.yr < attr(to_verify, "grattan_max_yr")) { - max.k <- max.yr - 1900L - stopn(if (!allow.projection) "`allow.projection = FALSE`, yet ", - "`", deparsed, - if (length(to_verify) == 1L) " = " else "` contained ", - '"', fys1901[attr(to_verify, "grattan_max_yr") - 1900L], '"', - if (length(to_verify) == 1L) "`", - " which ", - "is later than the ", - latest_permitted_financial_year, - ": ", '"', fys1901[max.k], '"', ".") - } - } - - return(to_verify) - } - - - fy.year <- to_verify - if (missing(permitted_fys)) { - if (anyNA(fmatches <- fmatch(to_verify, fys1901))) { - if (all(are_fy <- is.fy(to_verify))) { - nchar_to_verify <- nchar(to_verify) - out <- sprintf("%s-%s", - substr(to_verify, 1L, 4L), - substr(to_verify, nchar_to_verify - 1L, nchar_to_verify)) - return(out) - } - first_bad <- which.min(are_fy) - stopn("`", deparsed, - if (length(to_verify) == 1L) " = " else "` contained ", - '"', to_verify[first_bad], '"', - if (length(to_verify) == 1L) "` was " else " which is ", - "not a valid financial year.") - } else { - attr(to_verify, "grattan_all_fy") <- TRUE - if (!is.null(min.yr)) { - min.k <- min.yr - 1900L - min_fmatches <- min(fmatches) - if (min_fmatches < min.k) { - first_bad <- which.min(fmatches) - stopn("`", deparsed, - if (length(to_verify) == 1L) " = " else "` contained ", - '"', to_verify[first_bad], '"', - if (length(to_verify) == 1L) "`", - " which ", - "is earlier than the ", - earliest_permitted_financial_year, - ": ", '"', fys1901[min.k], '"', ".") - } - attr(to_verify, "grattan_min_yr") <- min_fmatches + 1900L - } - if (!is.null(max.yr)) { - max.k <- max.yr - 1900L - max_fmatches <- max(fmatches) - if (max_fmatches > max.k) { - first_bad <- which.max(fmatches) - stopn(if (!allow.projection) "`allow.projection = FALSE`, yet ", - "`", deparsed, - if (length(to_verify) == 1L) " = " else "` contained ", - '"', to_verify[first_bad], '"', - if (length(to_verify) == 1L) "`", - " which ", - "is later than the ", - latest_permitted_financial_year, - ": ", '"', fys1901[max.k], '"', ".") - } - attr(to_verify, "grattan_max_yr") <- max_fmatches + 1900L - } - return(invisible(to_verify)) - } - } - - - if (!all(fy.year %chin% permitted_fys)) { - if (any(!is.fy(fy.year))) { - i <- which(!is.fy(fy.year)) - i1 <- i[1] - if (length(i) > 1) { - stopn("`", deparsed, "` contained invalid FYs. ", - "There were ", - length(i), " invalid entries (", - round(100 * length(i) / length(fy.year)), "%).", - "\n\n", - "First invalid FY:\n\t", fy.year[i1], "\n", - "at position ", i) - } else { - if (length(fy.year) == 1L) { - stopn("`", deparsed, "` set to '", fy.year, "', was not a valid financial year. ", - "Select a valid fy.year between ", - permitted_fys[1], " and ", last(permitted_fys), ".") - } else { - stopn("`", deparsed, "` contained invalid entry ", - fy.year[i1], " at position ", i1, ".") - } - } - } - i <- which(fy.year %notin% permitted_fys) - i1 <- i[1] - - if (length(i) == 1L) { - stopn("`", deparsed, " = ", fy.year[i1], "` was not within the allowed range: ", - permitted_fys[1], " <= fy.year <= ", last(permitted_fys)) - } else { - stopn("`", deparsed, "` were not within the allowed range: ", - permitted_fys[1], " <= fy.year <= ", last(permitted_fys), "\n\n", - "First invalid FY:\n\t", fy.year[i1], "\n", - "at position ", i1) - } - } - return(to_verify) -} - - - - - diff --git a/man/is.fy.Rd b/man/is.fy.Rd index 43b264c27..c248c1d0a 100644 --- a/man/is.fy.Rd +++ b/man/is.fy.Rd @@ -33,7 +33,7 @@ For the inverses, a numeric corresponding to the year. \code{date2fy} converts a date to the corresponding financial year. } \description{ -Convenience functions for dealing with financial years +From grattan v1.7.1.4, these are reexports from the \code{\link[fy]{fy-package}}. } \details{ The following forms are permitted: \code{2012-13}, \code{201213}, \code{2012 13}, only. diff --git a/man/validate_fys_permitted.Rd b/man/validate_fys_permitted.Rd deleted file mode 100644 index c7fb08312..000000000 --- a/man/validate_fys_permitted.Rd +++ /dev/null @@ -1,48 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/validate_fys_permitted.R -\name{validate_fys_permitted} -\alias{validate_fys_permitted} -\title{Verifying validity of financial years} -\usage{ -validate_fys_permitted(to_verify, permitted_fys, min.yr = NULL, - max.yr = NULL, deparsed = deparse(substitute(to_verify)), - allow.projection = TRUE, - earliest_permitted_financial_year = "earliest permitted financial year", - latest_permitted_financial_year = "latest permitted financial year") -} -\arguments{ -\item{to_verify}{A user-provided value, purporting to be -character vector of financial years.} - -\item{permitted_fys}{A character vector of valid financial years.} - -\item{min.yr, max.yr}{Integers specifying the range of \code{to_verify}. -If \code{NULL}, no restriction on the upper or lower bound of the range.} - -\item{deparsed}{A string indicating the argument that the user provided. -Should generally be provided explicitly as the default is unlikely -to be user-friendly.} - -\item{allow.projection}{If \code{FALSE} emit a different error message.} - -\item{earliest_permitted_financial_year, latest_permitted_financial_year}{Text -for earliest/latest permitted financial year when \code{min.yr}/\code{max.yr} -condition is violated.} -} -\value{ -If \code{to_verify} contains valid financial years -they are returned all in the form \code{2013-14}. If they were -already in that form, they obtain the following attributes: -\describe{ -\item{\code{grattan_all_fy}}{\code{TRUE} if all the financial years are valid.} -\item{\code{grattan_min_yr}}{An integer, the earliest year ending in \code{to_verify}.} -\item{\code{grattan_max_yr}}{An integer, the latest year ending in \code{to_verify}.} -} -} -\description{ -Many functions expect financial years. -Determining that they are validly entered is often quite -computationally costly, relative to the core calculations. -These internal functions provide mechanisms to check validity -quickly, while still providing clear, accurate error messages. -} diff --git a/tests/testthat/test_isfy.R b/tests/testthat/test_isfy.R index def1e13dd..5170a3956 100644 --- a/tests/testthat/test_isfy.R +++ b/tests/testthat/test_isfy.R @@ -1,5 +1,11 @@ context("FY") +expect_equal <- function(left, right) { + testthat::expect_equal(unclass(left), + unclass(right), + check.attributes = FALSE) +} + test_that("is.fy() returns TRUE on FYs", { expect_true(is.fy("2012-13")) expect_true(is.fy("1999-00")) @@ -33,18 +39,9 @@ test_that("is_fy2", { expect_true(all(is_fy2(c("2000-01", "2010-11", "2013-14", "2020-21")))) }) -test_that("Correct logic when asserting fys", { - expect_error(fy2date(c("foo", "2015-16")), - regexp = "fy.yr contains non-FYs", - fixed = TRUE) - expect_error(fy2yr(c("foo", "2015-16")), - regexp = "fy.yr contains non-FYs", - fixed = TRUE) -}) - test_that("fy.year and yr2fy are identical", { x <- 1901:2099 - expect_identical(fy.year(x), yr2fy(x)) + expect_equal(fy.year(x), yr2fy(x)) }) test_that("grattan.assume1901_2100 options", { @@ -52,17 +49,10 @@ test_that("grattan.assume1901_2100 options", { skip_on_cran() x <- 1900:2099 rlang::with_options( - expect_identical(fy.year(x), yr2fy(x)), + expect_equal(fy.year(x), yr2fy(x)), grattan.assume1901_2100 = FALSE ) - expect_identical(fy.year(x), yr2fy(x, FALSE)) -}) - -test_that("yr2fy and .yr2fy", { - x <- 1900:2100 - expect_identical(fy.year(x), .yr2fy(x)) - x <- rep_len(x, 20e3) - expect_identical(fy.year(x), .yr2fy(x)) + expect_equal(fy.year(x), yr2fy(x, FALSE)) }) test_that("range_fy", { diff --git a/tests/testthat/test_next_fy.R b/tests/testthat/test_next_fy.R index 9d66b9e87..1ddf2bf6d 100644 --- a/tests/testthat/test_next_fy.R +++ b/tests/testthat/test_next_fy.R @@ -1,5 +1,10 @@ context("Next fy") +expect_equal <- function(left, right) { + testthat::expect_equal(unclass(left), + unclass(right), + check.attributes = FALSE) +} test_that("next_fy plus and minus", { expect_equal(next_fy("2015-16"), "2016-17") diff --git a/tests/testthat/test_validate_fys.R b/tests/testthat/test_validate_fys.R index 0a79bdf90..ae2f6dca9 100644 --- a/tests/testthat/test_validate_fys.R +++ b/tests/testthat/test_validate_fys.R @@ -1,5 +1,11 @@ context("validate_fys_permitted") +expect_equal <- function(left, right, check.attributes = FALSE) { + testthat::expect_equal(unclass(left), + unclass(right), + check.attributes = FALSE) +} + test_that("Error handling", { expect_error(validate_fys_permitted(c("2015-16", "2015-17", "2010-9"), c("2015-16", "2016-17")), regexp = "contained invalid FYs.", @@ -22,8 +28,8 @@ test_that("Error handling", { test_that("min or max years", { expect_error(validate_fys_permitted("1980-81", min.yr = 1982L)) expect_error(validate_fys_permitted("1980-81", max.yr = 1979L)) - expect_equal(validate_fys_permitted("1980-81", max.yr = 1982L), "1980-81", check.attributes = FALSE) - expect_equal(validate_fys_permitted("1984-85", min.yr = 1982L, max.yr = 1989L), "1984-85", check.attributes = FALSE) + expect_equal(validate_fys_permitted("1980-81", max.yr = 1982L), "1980-81") + expect_equal(validate_fys_permitted("1984-85", min.yr = 1982L, max.yr = 1989L), "1984-85") expect_error(validate_fys_permitted(c("1980-81", "1980-80"), min.yr = 1980L), regexp = 'contained "1980-80" which is not a valid financial year.') }) diff --git a/tests/testthat/test_wage_inflator.R b/tests/testthat/test_wage_inflator.R index d3ec2cebf..c2f7ec0f0 100644 --- a/tests/testthat/test_wage_inflator.R +++ b/tests/testthat/test_wage_inflator.R @@ -1,5 +1,11 @@ context("Wage inflator") +expect_equal <- function(left, right, check.attributes = FALSE, ...) { + testthat::expect_equal(unclass(left), + unclass(right), + check.attributes = FALSE, ...) +} + test_that("Default from_fy and to_fy", { expect_warning(wage_inflator(), regexp = "`from_fy` and `to_fy` are missing, using previous and current financial years respectively") @@ -101,8 +107,10 @@ test_that("ABS connection", { skip_if_not(packageVersion("rsdmx") >= package_version("0.5.10")) # Minimize false on errors on travis - skip_if(getRversion() >= "3.6") - skip_if(getRversion() <= "3.4") + # Skip travis tests (except oldrel) + nottravis_or_oldrel <- + Sys.getenv("TRAVIS_R_VERSION_STRING") %in% c("", "oldrel") + skip_if_not(nottravis_or_oldrel) internal_ans <- wage_inflator(from_fy = "2012-13", to_fy = "2013-14", @@ -126,7 +134,7 @@ test_that("ABS Connection (extras)", { to_fy = "2020 21", useABSConnection = TRUE) - expect_equal(internal_ans, external_ans, tol = 0.00001, scale = 1) + testthat::expect_equal(internal_ans, external_ans, tol = 0.00001, scale = 1) internal_ans <- wage_inflator(from_fy = yr2fy(2013:2016), to_fy = "2020-21", @@ -135,7 +143,7 @@ test_that("ABS Connection (extras)", { to_fy = "2020 21", useABSConnection = TRUE) - expect_equal(internal_ans, external_ans, tol = 0.00001, scale = 1) + testthat::expect_equal(internal_ans, external_ans, tol = 0.00001, scale = 1) }) test_that("accelerated", {