Class: Contracts::ContractBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/contracts.rb

Instance Method Summary collapse

Constructor Details

#initialize(contract) ⇒ ContractBuilder

Returns a new instance of ContractBuilder.



408
# File 'lib/contracts.rb', line 408

def initialize(contract) = @contract = contract

Instance Method Details

#changes(*attributes) ⇒ Object



424
425
426
427
428
429
430
431
432
433
# File 'lib/contracts.rb', line 424

def changes(*attributes)
  validate_mutation_mode!(:changes)
  observe(*attributes.reject do |attribute|
    @contract.observed.any? do |item|
      item.name == attribute.to_sym
    end
  end)
  @contract.instance_variable_set(:@mutation_policy, :changes)
  @contract.permitted_changes = attributes
end

#ensures(description = "postcondition", &block) ⇒ Object



412
# File 'lib/contracts.rb', line 412

def ensures(description = "postcondition", &block) = add(@contract.postconditions, description, block)

#example(**value) ⇒ Object



469
# File 'lib/contracts.rb', line 469

def example(**value) = @contract.examples << value.freeze

#must_change(*attributes, from: nil, to: nil) ⇒ Object



445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/contracts.rb', line 445

def must_change(*attributes, from: nil, to: nil)
  validate_mutation_mode!(:must_change)
  bounds = @contract.instance_variable_get(:@required_change_bounds) || {}
  attributes.each do |attribute|
    bounds[attribute.to_sym] = { from: from, to: to }.freeze
  end
  @contract.instance_variable_set(:@required_change_bounds, bounds.freeze)
  observe(*attributes.reject do |attribute|
    @contract.observed.any? do |item|
      item.name == attribute.to_sym
    end
  end)
  @contract.required_changes.concat(attributes.map(&:to_sym)).uniq!
end

#observe(*attributes, deep: false, compare_with: nil, &reader) ⇒ Object



435
436
437
438
439
440
441
442
443
# File 'lib/contracts.rb', line 435

def observe(*attributes, deep: false, compare_with: nil, &reader)
  attributes.each do |attribute|
    existing = @contract.observed.find { |item| item.name == attribute.to_sym }
    raise DefinitionError, "duplicate observation for #{attribute}" if existing

    @contract.observed << Observation.new(name: attribute.to_sym, reader: reader, deep: deep,
                                          compare_with: compare_with)
  end
end

#on_raise(type, &block) ⇒ Object



422
# File 'lib/contracts.rb', line 422

def on_raise(type, &block) = @contract.allowed_exceptions << ExceptionRule.new(type: type, handler: block)

#params(**items) ⇒ Object



409
# File 'lib/contracts.rb', line 409

def params(**items) = @contract.parameters = items

#positional(*items) ⇒ Object



410
# File 'lib/contracts.rb', line 410

def positional(*items) = @contract.positionals = items

#pure(scope: :receiver) ⇒ Object Also known as: changes_nothing

Raises:



460
461
462
463
464
465
# File 'lib/contracts.rb', line 460

def pure(scope: :receiver)
  raise DefinitionError, "unsupported purity scope #{scope.inspect}" unless %i[receiver observed].include?(scope)

  validate_mutation_mode!(:pure)
  @contract.instance_variable_set(:@mutation_policy, :pure)
end

#raises(*types, &block) ⇒ Object



416
417
418
419
420
# File 'lib/contracts.rb', line 416

def raises(*types, &block)
  types.each do |type|
    @contract.allowed_exceptions << ExceptionRule.new(type: type, condition: block)
  end
end

#requires(description = "precondition", &block) ⇒ Object



411
# File 'lib/contracts.rb', line 411

def requires(description = "precondition", &block) = add(@contract.preconditions, description, block)

#returns(constraint) ⇒ Object



413
# File 'lib/contracts.rb', line 413

def returns(constraint) = @contract.return_constraint = constraint

#returns!(constraint) ⇒ Object



414
# File 'lib/contracts.rb', line 414

def returns!(constraint) = @contract.return_constraint = Constraints::Predicate.new("non-nil #{Constraints.coerce(constraint).description}") { |v| !v.nil? && Constraints.coerce(constraint).matches?(v) }

#snapshot(&block) ⇒ Object



467
# File 'lib/contracts.rb', line 467

def snapshot(&block) = @contract.instance_variable_set(:@snapshot_block, block)

#unchanged_on_raise(*types) ⇒ Object



468
# File 'lib/contracts.rb', line 468

def unchanged_on_raise(*types) = @contract.unchanged_on_raise_types.concat(types.empty? ? [StandardError] : types).uniq!