lint

Linting & diagnostics

lint

ORM::Factory.lint builds every registered factory through a chosen strategy and aggregates the failures. It is the simplest way to confirm a suite of factories still produces valid records:

ORM::Factory.lint;                    # every factory, create-strategy
ORM::Factory.lint(:strategy<build>);  # build-strategy only
ORM::Factory.lint(:variants);         # each factory Ɨ variant combination
ORM::Factory.lint(:verbose);          # one progress line per attempt
ORM::Factory.lint('user', 'post');    # only the named factories

Healthy factories return silently. Failures are collected — every factory is attempted, even if earlier ones failed — and the aggregated report is attached to a single X::ORM::Factory::LintFailures exception:

try {
  ORM::Factory.lint(:variants);
  CATCH {
    when X::ORM::Factory::LintFailures {
      say .message;
      for .failures -> $f {
        say "factory: $f<factory>, variant: $f<variant>, error: $f<error>";
      }
    }
  }
}

When the active persistence adapter implements is-valid and returns False, lint raises X::ORM::Factory::InvalidRecord for that factory and records it in the same report.

Introspection

The registry is queryable without touching the underlying hash:

methodreturns
factory-namesevery registered factory name (sorted)
sequence-namesevery registered sequence name (sorted)
global-variant-namesevery top-level variant name (sorted)
variant-names-for($name)variants visible to one factory (own + inherited)
dump-attributes($name, *@variants, *%overrides)each attribute's transient/association/dynamic flags
describe-factory($name){name, class-name, parent, ancestors, aliases, variants, attributes}
ORM::Factory.factory-names;                                # ('post', 'user')
ORM::Factory.describe-factory('user')<variants>;           # ('admin',)
ORM::Factory.dump-attributes('post')<author><association>; # True

Error taxonomy

Every error raised by the factory engine descends from X::ORM::Factory:

classraised when
X::ORM::Factory::UnknownFactorya factory or alias is not registered
X::ORM::Factory::DuplicateFactorydefine re-registers an existing name
X::ORM::Factory::UnknownVarianta variant name is not visible from the in-flight factory
X::ORM::Factory::DuplicateVariantvariant re-registers an existing name
X::ORM::Factory::DuplicateAliasan alias collides with another alias or a factory name
X::ORM::Factory::UnknownClassname → class resolution fails and no :class is supplied
X::ORM::Factory::UnknownAttributethe evaluator is asked for an attribute that is not declared
X::ORM::Factory::UnknownSequencegenerate is called with an unknown sequence name
X::ORM::Factory::DuplicateSequencesequence re-registers an existing name
X::ORM::Factory::MissingAssociationan association points at a factory that is not registered
X::ORM::Factory::CyclicAssociationassociations form a cycle while building
X::ORM::Factory::UnknownCallbacka custom callback name is referenced before it is registered
X::ORM::Factory::UnknownStrategystrategy-for is given an unregistered name
X::ORM::Factory::UsageErrorthe DSL is called with the wrong shape (e.g. wrong arity)
X::ORM::Factory::InvalidRecordan adapter reports validation failure (carries record, errors, factory-name)
X::ORM::Factory::LintFailureslint finished with one or more failures (carries failures)

Every exception carries a human-readable .message. Structured exceptions (InvalidRecord, LintFailures) carry extra fields you can pattern-match on instead of parsing the text.

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.