tests/testthat/test-fracture.R

expect_comparable <- function(object, expected, ...) {
  testthat::expect_equal(object, expected, ..., ignore_attr = TRUE)
}

test_that("scalar fracture()", {
  expect_comparable(fracture(0.5), "1/2")
  expect_comparable(as.fracture(0.5), "1/2")
  expect_comparable(fracture(355/113), "355/113")
  expect_comparable(as.fracture(355/113), "355/113")
})

test_that("big fracture()", {
  expect_comparable(fracture((1e4 - 1) / 1e5), "9999/100000")
  expect_comparable(as.fracture((1e4 - 1) / 1e5), "9999/100000")
})

test_that("small fracture()", {
  expect_comparable(fracture(1 / 1e5), "1/100000")
  expect_comparable(as.fracture(1 / 1e5), "1/100000")
})

test_that("extreme fracture()", {
  expect_comparable(fracture(0), "0/1")
  expect_comparable(fracture(.Machine$double.eps), "0/10000000")
  expect_comparable(fracture(1), "1/1")
  expect_comparable(fracture(1 - .Machine$double.eps), "10000000/10000000")

  expect_comparable(
    fracture(
      c(0, .Machine$double.eps, 1/5, 1 - .Machine$double.eps, 1),
      common_denom = TRUE
    ),
    c("0/5", "0/5", "1/5", "5/5", "5/5")
  )
})

test_that("irrational fracture()", {
  expect_comparable(fracture(pi, max_denom = 100), "22/7")
})

test_that("vector fracture()", {
  expect_comparable(fracture(c(0.5, 0.75, 2/3)), c("1/2", "3/4", "2/3"))
  expect_comparable(as.fracture(c(0.5, 0.75, 2/3)), c("1/2", "3/4", "2/3"))
})

test_that("long vector fracture()", {
  withr::local_options(list(scipen = 1000))

  x <- expand.grid(
    c(1:100, sample(100:1e7, 100)), c(1:100, sample(100:1e7, 100))
  )

  test_decimal  <- x[, 1] / x[, 2]
  unique        <- match(unique(test_decimal), test_decimal)
  test_decimal  <- test_decimal[unique]

  x   <- x[unique, ]
  gcd <- apply(x, 1, frac_gcd)
  x   <- x / gcd

  test_fraction <- paste(x[, 1], x[, 2], sep = "/")

  expect_comparable(fracture(test_decimal), test_fraction)
})

test_that("really long vector fracture()", {
  skip_on_cran()
  withr::local_options(list(scipen = 1000))

  x <- expand.grid(
    c(1:1000, sample(1000:1e7, 1000)), c(1:1000, sample(1000:1e7, 1000))
  )

  test_decimal  <- x[, 1] / x[, 2]
  unique        <- match(unique(test_decimal), test_decimal)
  test_decimal  <- test_decimal[unique]

  x   <- x[unique, ]
  gcd <- apply(x, 1, frac_gcd)
  x   <- x / gcd

  test_fraction <- paste(x[, 1], x[, 2], sep = "/")

  expect_comparable(fracture(test_decimal), test_fraction)
})

test_that("explicit denom fracture()", {
  expect_comparable(fracture(2 / 11, denom = 10), "2/10")
  expect_comparable(
    fracture(rep(2 / 11, 2), denom = c(10, 12)), c("2/10", "2/12")
  )
  expect_comparable(
    fracture(24 / 11, denom = 10, mixed = TRUE), "2 2/10"
  )
  expect_comparable(
    fracture(c(6, 20) / 11, denom = 10, mixed = TRUE), c("5/10", "1 8/10")
  )
})

test_that("improper fracture()", {
  expect_comparable(fracture(c(1.5, 2)), c("3/2", "2/1"))
  expect_comparable(as.fracture(c(1.5, 2)), c("3/2", "2/1"))
})

test_that("negative fracture()", {
  expect_comparable(fracture(-0.5), "-1/2")
  expect_comparable(as.fracture(-0.5), "-1/2")
})

test_that("base_10 fracture()", {
  expect_comparable(fracture(0.5, base_10 = TRUE), "5/10")
  expect_comparable(fracture(1307.36, base_10 = TRUE), "130736/100")
})

test_that("really long base_10 fracture()", {
  withr::local_options(list(scipen = 1000))

  x <- expand.grid(c(1:100, sample(100:1e7, 100)), 10 ^ (0:7))

  test_decimal  <- x[, 1] / x[, 2]
  unique        <- match(unique(test_decimal), test_decimal)
  test_decimal  <- test_decimal[unique]

  x   <- x[unique, ]
  gcd <- apply(x, 1, frac_gcd)
  x   <- x / gcd

  test_fraction <- paste(x[, 1], x[, 2], sep = "/")

  expect_comparable(fracture(test_decimal), test_fraction)
})

test_that("really long base_10 fracture()", {
  skip_on_cran()
  withr::local_options(list(scipen = 1000))

  x <- expand.grid(c(1:1e4, sample(1e4:1e7, 1e4)), 10 ^ (0:7))

  test_decimal  <- x[, 1] / x[, 2]
  unique        <- match(unique(test_decimal), test_decimal)
  test_decimal  <- test_decimal[unique]

  x   <- x[unique, ]
  gcd <- apply(x, 1, frac_gcd)
  x   <- x / gcd

  test_fraction <- paste(x[, 1], x[, 2], sep = "/")

  expect_comparable(fracture(test_decimal), test_fraction)
})

test_that("common_denom fracture()", {
  expect_comparable(
    fracture(c(0.5, 0.75, 2/3), common_denom = TRUE), c("6/12", "9/12", "8/12")
  )
})

test_that("mixed fracture()", {
  expect_comparable(
    fracture(c(1.5, 0.5, 1), mixed = TRUE), c("1 1/2", "1/2", "1")
  )
})

test_that("mixed negative fracture()", {
  expect_comparable(fracture(c(-0.5, -4/3), mixed = TRUE), c("-1/2", "-1 1/3"))
})

test_that("max_denom fracture()", {
  expect_comparable(fracture(pi, max_denom = 100),  "22/7")
  expect_comparable(fracture(pi, max_denom = 1000), "355/113")
})

test_that("base_10 max_denom fracture()", {
  expect_comparable(
    fracture(c(1/2, 1/3, 1/4), base_10 = TRUE, max_denom = 1000),
    c("5/10", "333/1000", "25/100")
  )
})

test_that("base_10 common_denom max_denom fracture()", {
  expect_comparable(
    fracture(
      c(1/2, 1/3, 1/4), base_10 = TRUE, common_denom = TRUE, max_denom = 1000
    ),
    c("500/1000", "333/1000", "250/1000")
  )
})

test_that("epsilon without common_denom fracture()", {
  expect_comparable(
    fracture(c(1e-10, 1 - 1e-10), max_denom = 100), c("0/100", "100/100")
  )
})

test_that("epsilon with common_denom fracture()", {
  expect_comparable(
    fracture(c(1e-10, 1 - 1e-10, 1/3), common_denom = TRUE),
    c("0/3", "3/3", "1/3")
  )
})

test_that("big max_denom fracture()", {
  expect_warning(fracture(0.5, max_denom = 1e10))
})

test_that("as.fracture() from frac_mat()", {
  expect_equal(as.fracture(frac_mat(0.5)), fracture(0.5))
  expect_equal(
    as.fracture(frac_mat(c(0.5, 0.75, 2/3))), fracture(c(0.5, 0.75, 2/3))
  )
  expect_equal(as.fracture(frac_mat(c(1.5, 2))), fracture(c(1.5, 2)))
  expect_equal(
    as.fracture(frac_mat(0.5, base_10 = TRUE)), fracture(0.5, base_10 = TRUE)
  )
  expect_equal(
    as.fracture(frac_mat(c(0.5, 0.75, 2/3), common_denom = TRUE)),
    fracture(c(0.5, 0.75, 2/3), common_denom = TRUE)
  )
  expect_equal(
    as.fracture(frac_mat(c(1.5, 0.5, 1), mixed = TRUE)),
    fracture(c(1.5, 0.5, 1), mixed = TRUE)
  )
  expect_equal(
    as.fracture(frac_mat(c(-0.5, -4/3), mixed = TRUE)),
    fracture(c(-0.5, -4/3), mixed = TRUE)
  )
  expect_equal(
    as.fracture(frac_mat(pi, max_denom = 100)), fracture(pi, max_denom = 100)
  )
  expect_equal(
    as.fracture(frac_mat(pi, max_denom = 1000)), fracture(pi, max_denom = 1000)
  )
  expect_equal(
    as.fracture(frac_mat(c(1/2, 1/3, 1/4), base_10 = TRUE, max_denom = 1000)),
    fracture(c(1/2, 1/3, 1/4), base_10 = TRUE, max_denom = 1000)
  )
  expect_equal(
    as.fracture(
      frac_mat(
        c(1/2, 1/3, 1/4), base_10 = TRUE, common_denom = TRUE, max_denom = 1000
      )
    ),
    fracture(
      c(1/2, 1/3, 1/4), base_10 = TRUE, common_denom = TRUE, max_denom = 1000
    )
  )
  expect_equal(
    as.fracture(frac_mat(c(1e-10, 1 - 1e-10), max_denom = 100)),
    fracture(c(1e-10, 1 - 1e-10), max_denom = 100)
  )
  expect_equal(
    as.fracture(frac_mat(c(1e-10, 1 - 1e-10, 1/3), common_denom = TRUE)),
    fracture(c(1e-10, 1 - 1e-10, 1/3), common_denom = TRUE)
  )
})

frac_half <- fracture(0.5)

test_that("is.fracture()", {
  expect_true(is.fracture(frac_half))
  expect_true(is.fracture(as.fracture(0.5)))
})

test_that("as.character.fracture()", {
  chr <- as.character(frac_half)
  expect_equal(chr, "1/2")
  expect_type(chr, "character")
})

test_that("as.numeric.fracture()", {
  num <- as.numeric(frac_half)
  expect_equal(num, 0.5)
  expect_type(num, "double")
})

test_that("as.double.fracture()", {
  dbl <- as.double(frac_half)
  expect_equal(dbl, 0.5)
  expect_type(dbl, "double")
})

test_that("as.integer.fracture()", {
  int <- as.integer(frac_half)
  expect_equal(int, 0)
  expect_type(int, "integer")
})

test_that("print.fracture()", {
  expect_output(print(frac_half), "1/2")
})

test_that("Math.fracture()", {
  expect_comparable(abs(fracture(-0.5)), "1/2")
  expect_comparable(log(fracture(0.5), 4), "-1/2")
})

test_that("Ops.fracture()", {
  expect_comparable(fracture(0.5) * 3, "3/2")
  expect_comparable(3 * fracture(0.5), "3/2")
  expect_comparable(fracture(0.5) + 1, "3/2")
  expect_comparable(1 + fracture(0.5), "3/2")
  expect_comparable(fracture(0.5) * fracture(0.5), "1/4")
  expect_comparable(fracture(0.5) + fracture(0.25), "3/4")
  expect_comparable(fracture(0.5) + TRUE, "3/2")
  expect_comparable(TRUE + fracture(0.5), "3/2")
  expect_comparable(1i + fracture(0.5), 0.5 + 1i)
  expect_comparable(fracture(0.5) + 1i, 0.5 + 1i)
  expect_true(fracture(0.5) == "1/2")
  expect_true("1/2" == fracture(0.5))
  expect_true(fracture(0.5) == 0.5)
  expect_true(0.5 == fracture(0.5))
  expect_true(fracture(0.5) > 0)
  expect_true(0 < fracture(0.5))
  expect_true(fracture(1) == TRUE)
  expect_true(TRUE == fracture(1))
  expect_true(fracture(0) | TRUE)
  expect_true(TRUE | fracture(0))
  expect_false(fracture(0) & TRUE)
  expect_false(TRUE & fracture(0))
  expect_true(fracture(1.5) == fracture(1.5, base_10 = TRUE))
  expect_true(fracture(1.5) == fracture(1.5, mixed = TRUE))
  expect_false(is.na(fracture(0.5)))
  expect_length(fracture(0.5) + NULL, 0)
  expect_length(NULL + fracture(0.5), 0)

  expect_comparable(fracture(c(0.5, 1.5)) + 1, c("3/2", "5/2"))
})

test_that("recover_fracture_args()", {
  expect_null(recover_fracture_args(0, 0))
})

test_that("non-finite fracture()", {
  expect_comparable(fracture(NA), NA)
  expect_comparable(fracture(c(0.5, NA, 1.5)), c("1/2", NA, "3/2"))

  expect_comparable(fracture(Inf), "Inf/1")
  expect_comparable(fracture(-Inf), "-Inf/1")

  expect_comparable(fracture(Inf,  mixed = TRUE), "Inf")
  expect_comparable(fracture(-Inf, mixed = TRUE), "-Inf")
})

test_that("early returns", {
  expect_equal(fracture(numeric(0)), numeric(0))
  expect_equal(fracture(NA), NA)
  expect_equal(fracture(NA, mixed = TRUE), NA)
})

test_that("fracture() errors", {
  expect_error(fracture(character(1)))
  expect_error(fracture(1, denom = NA))
  expect_error(fracture(1, denom = Inf))
  expect_error(fracture(1, denom = 1:2))
  expect_error(fracture(1:10, denom = 1:2))
})

Try the fracture package in your browser

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

fracture documentation built on May 21, 2022, 9:05 a.m.