Class: Contracts::ContractBuilder
- Inherits:
-
Object
- Object
- Contracts::ContractBuilder
- Defined in:
- lib/contracts.rb
Instance Method Summary collapse
- #changes(*attributes) ⇒ Object
- #ensures(description = "postcondition", &block) ⇒ Object
- #example(**value) ⇒ Object
-
#initialize(contract) ⇒ ContractBuilder
constructor
A new instance of ContractBuilder.
- #must_change(*attributes, from: nil, to: nil) ⇒ Object
- #observe(*attributes, deep: false, compare_with: nil, &reader) ⇒ Object
- #on_raise(type, &block) ⇒ Object
- #params(**items) ⇒ Object
- #positional(*items) ⇒ Object
- #pure(scope: :receiver) ⇒ Object (also: #changes_nothing)
- #raises(*types, &block) ⇒ Object
- #requires(description = "precondition", &block) ⇒ Object
- #returns(constraint) ⇒ Object
- #returns!(constraint) ⇒ Object
- #snapshot(&block) ⇒ Object
- #unchanged_on_raise(*types) ⇒ Object
Constructor Details
#initialize(contract) ⇒ ContractBuilder
Returns a new instance of ContractBuilder.
351 |
# File 'lib/contracts.rb', line 351 def initialize(contract) = @contract = contract |
Instance Method Details
#changes(*attributes) ⇒ Object
367 368 369 370 371 372 373 374 375 376 |
# File 'lib/contracts.rb', line 367 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
355 |
# File 'lib/contracts.rb', line 355 def ensures(description = "postcondition", &block) = add(@contract.postconditions, description, block) |
#example(**value) ⇒ Object
409 |
# File 'lib/contracts.rb', line 409 def example(**value) = @contract.examples << value.freeze |
#must_change(*attributes, from: nil, to: nil) ⇒ Object
388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/contracts.rb', line 388 def must_change(*attributes, from: nil, to: nil) # Retain range constraints for the public DSL; enforcement is intentionally deferred. validate_mutation_mode!(:must_change) @contract.instance_variable_set(:@required_change_bounds, { attributes: attributes.map(&:to_sym), from: from, to: to }.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
378 379 380 381 382 383 384 385 386 |
# File 'lib/contracts.rb', line 378 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
365 |
# File 'lib/contracts.rb', line 365 def on_raise(type, &block) = @contract.allowed_exceptions << ExceptionRule.new(type: type, handler: block) |
#params(**items) ⇒ Object
352 |
# File 'lib/contracts.rb', line 352 def params(**items) = @contract.parameters = items |
#positional(*items) ⇒ Object
353 |
# File 'lib/contracts.rb', line 353 def positional(*items) = @contract.positionals = items |
#pure(scope: :receiver) ⇒ Object Also known as: changes_nothing
400 401 402 403 404 405 |
# File 'lib/contracts.rb', line 400 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
359 360 361 362 363 |
# File 'lib/contracts.rb', line 359 def raises(*types, &block) types.each do |type| @contract.allowed_exceptions << ExceptionRule.new(type: type, condition: block) end end |
#requires(description = "precondition", &block) ⇒ Object
354 |
# File 'lib/contracts.rb', line 354 def requires(description = "precondition", &block) = add(@contract.preconditions, description, block) |
#returns(constraint) ⇒ Object
356 |
# File 'lib/contracts.rb', line 356 def returns(constraint) = @contract.return_constraint = constraint |
#returns!(constraint) ⇒ Object
357 |
# File 'lib/contracts.rb', line 357 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
407 |
# File 'lib/contracts.rb', line 407 def snapshot(&block) = @contract.instance_variable_set(:@snapshot_block, block) |
#unchanged_on_raise(*types) ⇒ Object
408 |
# File 'lib/contracts.rb', line 408 def unchanged_on_raise(*types) = @contract.unchanged_on_raise_types.concat(types.empty? ? [StandardError] : types).uniq! |