Class: RLab::Assert::Syntax

Inherits:
Module
  • Object
show all
Defined in:
lib/rlab/assert/syntax.rb

Constant Summary collapse

MISSING =
:__rlab_assert_arg_missing__

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(assert, refute, observer) ⇒ Syntax

Returns a new instance of Syntax.



75
76
77
78
79
# File 'lib/rlab/assert/syntax.rb', line 75

def initialize assert, refute, observer
  @assert = assert
  @refute = refute
  @observer = observer
end

Class Method Details

.ambiguous_subject!Object

Raises:

  • (ArgumentError)


66
67
68
# File 'lib/rlab/assert/syntax.rb', line 66

def ambiguous_subject!
  raise ArgumentError, "cannot supply a block subject *and* a positional subject"
end

.decode_assert_arguments(subject_or_checks, checks, block) ⇒ Object

Public: assert is designed to be called a number of different ways, from 0 to 2 positional arguments, and maybe a block. Note that this method is a big nested ball of conditionals because I want it to perform well.

subject_or_checks - the first optional argument passed in checks - the second optional argument passed in block - the &block parameter

Valid examples:

assert :raises => Error do ̡… end
assert "foo"
assert 3, :included_in => [6, 3]
assert [6, 3], :includes => 3
assert :equal => 4 do 2 + 2 end

Invalid examples:

# Can't determine if the block or 2 is the subject
assert 2, :equals => 4 do ̒… end 
# There's no subject at all
assert :incuded_in => 4

Returns two arguments, the subject, and a checks hash. If the checks would be empty, returns { :truthy => true }. The subject will always be a Proc that gets lazy evaluated when the assertion is checked.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rlab/assert/syntax.rb', line 45

def decode_assert_arguments subject_or_checks, checks, block
  if checks == MISSING
    if subject_or_checks == MISSING
      missing_subject! unless block
      subject_thunk = block
      checks = { :truthy => true }
    elsif block
      ambiguous_subject! unless subject_or_checks.is_a? Hash
      subject_thunk = block
      checks = subject_or_checks
    else
      subject_thunk = -> do subject_or_checks end
      checks = { :truthy => true }
    end
  else
    ambiguous_subject! if block
    subject_thunk = -> do subject_or_checks end
  end
  [subject_thunk, checks]
end

.infect(target, params = {}) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/rlab/assert/syntax.rb', line 7

def infect target, params = {}
  assert, refute, observer = RLab::Util.extract_key_args params,
    :method => :assert, :refute => :refute, :observer => nil
  instance = new assert, refute, observer
  if target.is_a? Class
    target.send :include, instance
  else
    target.extend instance
  end
end

.missing_subject!Object

Raises:

  • (ArgumentError)


70
71
72
# File 'lib/rlab/assert/syntax.rb', line 70

def missing_subject!
  raise ArgumentError, "must supply either a positional subject *or* a block subject (but not both)"
end

Instance Method Details

#extended(base) ⇒ Object



85
86
87
# File 'lib/rlab/assert/syntax.rb', line 85

def extended base
  graft base.singleton_class
end

#graft(base) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/rlab/assert/syntax.rb', line 93

def graft base
  method_body = -> method_name, assertion_class, syntax, observer do
    define_method method_name do |arg1 = MISSING, arg2 = MISSING, &block|
    subject_thunk, checks = syntax.decode_assert_arguments arg1, arg2, block
    assertion = assertion_class.new subject_thunk, checks
    assertion.add_observer observer if observer
    assertion.source = self
    assertion.assert
    end
  end

  base.class_exec @assert, Assertion, self.class, @observer, &method_body
  base.class_exec @refute, Refutation,self.class, @observer, &method_body if refute?
end

#included(base) ⇒ Object



89
90
91
# File 'lib/rlab/assert/syntax.rb', line 89

def included base
  graft base
end

#refute?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/rlab/assert/syntax.rb', line 81

def refute?
  @refute ? true : false
end