Collect.TestHelpers (Collect v0.1.0)

Copy Markdown

Test-support helpers for applications that use Collect.

These functions are intended for use in test suites only, not in production code.

Collect keeps document data current using database triggers, which need to see committed data. Tests that exercise incremental updates therefore run the Ecto SQL sandbox in :auto mode, where writes are committed, not rolled back. Because nothing is rolled back, document tables and their triggers persist between tests unless explicitly removed, and leftover triggers can fire during unrelated tests. reset_document_artifacts/3 clears them.

Stability

These helpers discover Collect's artifacts using internal naming conventions. They automatically adapt when those conventions change. However, because they are test support functions (not part of the core API) they may change with less notice. Any changes affecting them will be documented in the release notes.

Summary

Functions

Removes every document table Collect created, along with the triggers and functions it installed on source and joined tables.

Types

column()

@type column() :: %{
  from: String.t(),
  key: String.t() | nil,
  name: String.t(),
  transforms: [String.t()] | nil,
  type: String.t()
}

create_document_table_return()

@type create_document_table_return() ::
  {:ok, String.t()}
  | {:error, :column_not_found, String.t()}
  | {:error, :column_type_conflict, {String.t(), term(), term()}}
  | {:error, :configs_target_different_destinations, [String.t()]}
  | {:error, :document_table_exists, String.t()}
  | {:error, :duplicate_source_names, [String.t()]}
  | {:error, :identity_column_already_exists, String.t()}
  | {:error, :identity_column_invalid_type, String.t()}
  | {:error, :identity_column_not_found, String.t()}
  | {:error, :invalid_table_name, String.t()}
  | {:error, :no_configs}
  | {:error, :table_names_not_distinct}
  | {:error, Exception.t()}

data_field()

@type data_field() :: %{
  aggregate: :array | :first | :object_array | nil,
  columns: [object_array_column()] | nil,
  field_name: String.t(),
  join_table: String.t() | nil,
  joins: [join_spec()] | nil,
  value_column: String.t() | nil
}

database_options()

@type database_options() :: [{:repo, repo()} | postgrex_options()]

document_table_config()

@type document_table_config() ::
  %{
    add_identity_column_if_not_exists: boolean() | nil,
    columns: [column()] | nil,
    data_fields: [data_field()] | nil,
    identity_column: String.t(),
    indexes: [index()] | nil,
    language: String.t() | nil,
    scopes: [scope()] | nil,
    search_fields: [search_field()] | nil,
    source_name: String.t() | nil,
    source_table: String.t()
  }
  | keyword()

document_table_config_or_configs()

@type document_table_config_or_configs() ::
  document_table_config() | [document_table_config()]

index()

@type index() :: %{columns: [String.t()], using: String.t() | nil}

join_spec()

@type join_spec() :: %{
  table: String.t(),
  match: String.t(),
  to: String.t(),
  where: String.t() | nil
}

join_triggers()

@type join_triggers() :: %{
  required(String.t()) => %{
    delete_trigger: String.t(),
    trigger_fn: String.t(),
    trigger: String.t()
  }
}

object_array_column()

@type object_array_column() :: %{column: String.t(), key: String.t()}

postgrex_options()

@type postgrex_options() :: [{:timeout, integer() | :infinity}]

repo()

@type repo() :: module()

scope()

@type scope() :: %{
  join_table: String.t() | nil,
  joins: [join_spec()] | nil,
  where: String.t()
}

search_field()

@type search_field() :: %{
  field_name: String.t(),
  key: String.t() | nil,
  transforms: [String.t()] | nil,
  weight: 1 | 2 | 3 | 4 | nil
}

Functions

reset_document_artifacts(document_table, config_or_configs, opts \\ [])

@spec reset_document_artifacts(
  String.t(),
  document_table_config_or_configs(),
  database_options()
) :: :ok

Removes every document table Collect created, along with the triggers and functions it installed on source and joined tables.

Intended to be called from a setup block so each test starts from a clean state, regardless of whether the previous test cleaned up after itself. Pass a list of known configs that were used in tests.

setup do
  Collect.TestHelpers.reset_document_artifacts(document_table, config, repo: Repo)
  :ok
end

This removes only artifacts Collect created: document tables, their deltas tables, and the triggers and trigger functions Collect installed.

When cleaning up your own data tables, make sure to reset the auto-incrementing identity sequence. For example:

Repo.query!(~s(
  TRUNCATE products, categories, products_categories
  RESTART IDENTITY CASCADE
))

Options

  • repo - the Ecto repo to run against. Defaults to the configured repo.