Class: ActiveSpec::Base

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

Overview

The ActiveSpec::Base class provides a more declarative way of creating specifications than using the low-level Specification classes. It essentially acts as a composite specification (it actually delegates to ActiveSpec::Specifications::CompositeSpecification when calling satisfied_by?) and allows you to create new specifications by sub-classing ActiveSpec::Base and calling the built-in macros to add individual specifications.

This declarative way of creating specifications will be more familiar to those who are used to using Rails’ built-in validates_* macros.

Example specification:

class UserSpecification < ActiveSpec::Base
  require_presence_of     :username, :email
  require_confirmation_of :password
  require_inclusion_in    18..30, :age
end

You can execute an ActiveSpec against an object by calling the class method satisfied_by?. There is no need to instantiate an ActiveSpec class.

user = User.new
UserSpecification.satisfied_by?(user)

Class Method Summary collapse

Class Method Details

.must_satisfy(specification = nil, &block) ⇒ Object

A generic method that lets you add arbitrary specifications in several formats. specification can be a specification class (that responds to satisfied_by?), a Symbol (which is used to find a specification class) or a Proc object. As an alternative to passing a Proc, you can simply call satisfy with a block. The Proc/block will be passed the object that is sent to satisfied_by? when satisfied_by? is called.

# Using a class
must_satisfy UserSpecification

# Using a symbol
must_satisfy :user_specification

# Using a Proc
must_satisfy proc{ |object| # do something with object }

# Passing in a block
must_satisfy { |object| # do something with object }

This method gives you the power to create very complicated specifications. Because you can pass in anything that responds to satisfied_by?, you can pass in your own low-level specification classes, ActiveSpec::Specifications::CompositeSpecification classes, or even other ActiveSpec classes, e.g.

class UserSpecification < ActiveSpec::Base
  require_presence_of :email
end

class AdvancedUserSpecification < ActiveSpec::Base
  must_satisfy :user_specification
  require_presence_of :something_else
end


97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/active_spec/base.rb', line 97

def must_satisfy(specification=nil, &block)
  case specification
  when Symbol
    add_specification Object.const_get(Inflector::classify(specification))
  when Proc
    add_specification ActiveSpec::Specifications::ProcSpecification.new(specification)
  when Class
    add_specification specification
  else
    if block_given?
      add_specification ActiveSpec::Specifications::ProcSpecification.new(block)
    else
      raise "satisfy must be passed a symbol, proc, class or block"
    end
  end
end

.requires_confirmation_of(*attributes) ⇒ Object

Adds a ActiveSpec::Specifications::ConfirmationSpecification for the given attributes.



50
51
52
# File 'lib/active_spec/base.rb', line 50

def requires_confirmation_of(*attributes)
  add_specification ActiveSpec::Specifications::ConfirmationSpecification.new(*attributes)
end

.requires_exclusion_from(collection, *attributes) ⇒ Object

Adds a ActiveSpec::Specifications::CollectionSpecification wrapped in a ActiveSpec::Specifications::NotSpecification decorator for the given collection and attributes.



43
44
45
46
47
# File 'lib/active_spec/base.rb', line 43

def requires_exclusion_from(collection, *attributes)
  add_specification ActiveSpec::Specifications::NotSpecification.new(
    ActiveSpec::Specifications::CollectionSpecification.new(collection, *attributes)
  )
end

.requires_inclusion_in(collection, *attributes) ⇒ Object

Adds a ActiveSpec::Specifications::CollectionSpecification for the given collection and attributes.



36
37
38
# File 'lib/active_spec/base.rb', line 36

def requires_inclusion_in(collection, *attributes)
  add_specification ActiveSpec::Specifications::CollectionSpecification.new(collection, *attributes)
end

.requires_match(regexp, *attributes) ⇒ Object

Adds a ActiveSpec::Specifications::MatchSpecification for the given regexp and attributes.



60
61
62
# File 'lib/active_spec/base.rb', line 60

def requires_match(regexp, *attributes)
  # TODO add_specification MatchSpecification.new(regexp, *attributes)
end

.requires_presence_of(*attributes) ⇒ Object

Adds a ActiveSpec::Specifications::PresenceSpecification for the given attributes.



31
32
33
# File 'lib/active_spec/base.rb', line 31

def requires_presence_of(*attributes)
  add_specification ActiveSpec::Specifications::PresenceSpecification.new(*attributes) 
end

.requires_size(size, *attributes) ⇒ Object

Adds a ActiveSpec::Specifications::SizeSpecification for the given attributes.



55
56
57
# File 'lib/active_spec/base.rb', line 55

def requires_size(size, *attributes)
  add_specification ActiveSpec::Specifications::SizeSpecification.new(size, *attributes)
end

.satisfied_by?(object) ⇒ Boolean

Calls satisfied_by? on each specification with the given object. Returns true if all of the specifications pass, otherwise it returns false.

Returns:

  • (Boolean)


117
118
119
# File 'lib/active_spec/base.rb', line 117

def satisfied_by?(object)
  composite_spec.satisfied_by?(object)
end