tests/testthat/test-normalise.r

describe("normalise", {
  it("gives valid schemas with same-attributes reference pairs", {
    # table_dum and table_dee
    empty_fds <- functional_dependency(list(), attrs_order = character())
    empty_schema <- normalise(empty_fds)
    is_valid_database_schema(
      empty_schema,
      same_attr_name = TRUE,
      single_key_pairs = FALSE
    )

    forall(
      list(
        gen_flat_deps(7, 20, to = 20L),
        gen.element(c(FALSE, TRUE)),
        gen.element(c(FALSE, TRUE)),
        gen.element(c(FALSE, TRUE))
      ),
      \(fds, sng, el, ra) {
        normalise(fds, single_ref = sng, ensure_lossless = el, remove_avoidable = ra) |>
          is_valid_database_schema(
            same_attr_name = TRUE,
            single_key_pairs = sng
          )
      },
      curry = TRUE
    )
  })
  it("is the same as synthesise >> autoref", {
    forall(
      list(
        gen_flat_deps(7, 6, to = 6L) |>
          gen.with(list),
        gen.sample(c(FALSE, TRUE), size = 3, replace = TRUE) |>
          gen.with(as.list)
      ) |>
        gen.with(uncurry(c)),
      \(fds, sr, el, ra) {
        expect_identical(
          normalise(
            fds,
            single_ref = sr,
            ensure_lossless = el,
            remove_avoidable = ra
          ),
          synthesise(
            fds,
            ensure_lossless = el,
            remove_avoidable = ra
          ) |>
            autoref(single_ref = sr)
        )
      },
      curry = TRUE
    )
  })
  it("adds table with key with attributes in original order", {
    adds_ordered_primary_keys <- function(fds) {
      schema <- normalise(fds, ensure_lossless = TRUE)
      all_keys <- unlist(keys(schema), recursive = FALSE)
      key_indices <- lapply(all_keys, match, attrs_order(schema))
      expect_false(any(vapply(key_indices, is.unsorted, logical(1))))
    }
    forall(
      gen_flat_deps(7, 20, to = 20L),
      adds_ordered_primary_keys
    )
  })
  it("is equivalent to removing extraneous attributes separately", {
    forall(
      gen_flat_deps(7, 20, to = 20),
      expect_biidentical(
        normalise,
        remove_extraneous_attributes %>>%
          with_args(normalise, reduce_attributes = FALSE)
      )
    )
  })

  it("returns relations that return themselves if normalised again, if lossless", {
    gen.database_schema_single_lossless <- function(attr_names) {
      gen.choice(
        gen.pure(attr_names),
        gen.pure(attr_names[FALSE]),
        gen.subsequence(attr_names)
      ) |>
        gen.with(function(key) {
          nonkey <- setdiff(attr_names, key)
          attrs <- list(c(key, nonkey))
          keys <- list(list(key))
          nm <- if (length(key) == 0L)
            "constants"
          else
            paste(key, collapse = "_")
          database_schema(
            relation_schema(
              setNames(
                Map(list, attrs, keys),
                nm
              ),
              attrs_order = attr_names
            ),
            list()
          )
        })
    }
    returns_itself <- function(relation) {
      deps <- functional_dependency(
        unlist(synthesised_fds(attrs(relation), keys(relation)), recursive = FALSE),
        attrs_order(relation)
      )
      redo <- normalise(deps)
      expect_identical(redo, relation)
    }
    forall(
      gen.database_schema_single_lossless(letters[1:10]),
      returns_itself
    )
  })
})

Try the autodb package in your browser

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

autodb documentation built on April 4, 2025, 5:12 a.m.