Skip to content

abstract struct Athena::Validator::Spec::ConstraintValidatorTestCase
inherits Athena::Spec::TestCase #

Test case designed to make testing AVD::ConstraintValidatorInterface easier.

Example#

Using the spec from AVD::Constraints::NotNil:

# Makes for a bit less typing when needing to reference the constraint.
private alias CONSTRAINT = AVD::Constraints::NotNil

# Define our test case inheriting from the abstract ConstraintValidatorTestCase.
struct NotNilValidatorTest < AVD::Spec::ConstraintValidatorTestCase
  @[DataProvider("valid_values")]
  def test_valid_values(value : _) : Nil
    # Validate the value against a new instance of the constraint.
    self.validator.validate value, self.new_constraint

    # Assert no violations were added to the context.
    self.assert_no_violation
  end

  # Use data providers to reduce duplication.
  def valid_values : NamedTuple
    {
      string:       {""},
      bool_false:   {false},
      bool_true:    {true},
      zero:         {0},
      null_pointer: {Pointer(Void).null},
    }
  end

  def test_nil_is_invalid
    # Validate an invalid value against a new instance of the constraint with a custom message.
    self.validator.validate nil, self.new_constraint message: "my_message"

    # Assert a violation with the expected message, code, and value parameter is added to the context.
    self
      .build_violation("my_message", CONSTRAINT::IS_NULL_ERROR, nil)
      .assert_violation
  end

  # Implement some abstract defs to return the validator and constraint class.
  private def create_validator : AVD::ConstraintValidatorInterface
    CONSTRAINT::Validator.new
  end

  private def constraint_class : AVD::Constraint.class
    CONSTRAINT
  end
end

This type is an extension of ASPEC::TestCase, see that type for more information on this testing approach. This approach also allows using ASPEC::TestCase::DataProviders for reducing duplication within your test.

Direct known subclasses

Athena::Validator::Spec::ComparisonConstraintValidatorTestCase

Methods#

#assert_no_violation(*, file : String = __FILE__, line : Int32 = __LINE__) : Nil#

Asserts that no violations were added to the context.

View source

#assert_violation(message : String, code : String, value : _) : Nil#

Asserts a violation with the provided message, code, and value parameter was added to the context.

View source

#assert_violation(message : String, code : String) : Nil#

Asserts a violation with the provided provided message, and code was added to the context.

View source

#assert_violation(message : String) : Nil#

Asserts a violation with the provided message was added to the context.

View source

#build_violation(message : String, code : String, value : _) : AVD::Spec::ConstraintValidatorTestCase::Assertion#

Returns an AVD::Spec::ConstraintValidatorTestCase::Assertion with the provided message, code, and value parameter preset.

View source

#build_violation(message : String, code : String) : AVD::Spec::ConstraintValidatorTestCase::Assertion#

Returns an AVD::Spec::ConstraintValidatorTestCase::Assertion with the provided message, and code preset.

View source

#build_violation(message : String) : AVD::Spec::ConstraintValidatorTestCase::Assertion#

Returns an AVD::Spec::ConstraintValidatorTestCase::Assertion with the provided message preset.

View source

abstract #constraint_class : AVD::Constraint.class#

Returns the class of the constraint being tested.

View source

#context : AVD::ExecutionContext#

Returns a reference to the context used for the current test.

View source

abstract #create_validator : AVD::ConstraintValidatorInterface#

Returns a new validator instance for the constraint being tested.

View source

#expect_validate_value_at(idx : Int32, property_path : String, value : _, constraints : Array(AVD::Constraint) | AVD::Constraint, groups : Array(String) | String | AVD::Constraints::GroupSequence | Nil = nil)#

Asserts that a validation within a specific context occurs with the provided property_path, value, constraints, and optionally groups.

See CollectionValidatorTestCase for an example.

View source

#expect_violation_at(idx : Int, value : _, constraint : AVD::Constraint) : AVD::Violation::ConstraintViolationListInterface#

Can be used to have a nested validator return the correct violations when used within another validator.

Creates a separate validation context, validating the provided value against the provided constraint, causing the resulting violations to be returned from the inner validator as they would be in a non-test context.

See AVD::Constraints::ISIN::Validator, and its related specs, for an example.

View source

#new_constraint : AVD::Constraint#

Returns a new constraint instance based on #constraint_class and the provided args.

View source

#validator : AVD::ConstraintValidatorInterface#

Returns the validator instance returned via #create_validator.

View source

#value=(value : Array(String) | String) : Nil#

Overrides the value/node currently being validated.

View source