covenant 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/covenant/version.rb +1 -1
  2. data/lib/covenant.rb +48 -130
  3. metadata +15 -4
@@ -1,3 +1,3 @@
1
1
  module Covenant
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/lib/covenant.rb CHANGED
@@ -1,15 +1,27 @@
1
+ require 'sourcify'
2
+
1
3
  module Covenant
2
4
  # Adds the Covenant DSL to base.
3
5
  #
4
6
  # @api public
5
7
  #
6
8
  # @param base where to add the Covenant DSL
7
- def self.abide(base = Object)
8
- case base
9
- when Class
10
- base.send :include, Covenant::DSL
11
- else
12
- base.extend Covenant::DSL
9
+ def self.abide(base = Object, as = [:assert, :asserting])
10
+ target = Class === base ? base : base.singleton_class
11
+
12
+ target.class_eval do
13
+ include Covenant::DSL
14
+
15
+ case as
16
+ when Array
17
+ as.each do |a|
18
+ alias_method a, :_assert
19
+ end
20
+ when Symbol, String
21
+ alias_method as, :_assert
22
+ else
23
+ raise ArgumentError, "cannot register `#{as.inspect}` as method names"
24
+ end
13
25
  end
14
26
  end
15
27
 
@@ -22,151 +34,57 @@ module Covenant
22
34
  # @param [#to_s] message the message that will be set if the test fails
23
35
  #
24
36
  # @return the wrapper object you can use to test your assertions
25
- def assert(target = self, message = nil)
26
- if block_given?
27
- Covenant::Assertion.new(target, message).test(yield target)
28
- else
29
- Covenant::Assertion.new(target, message)
30
- end
31
- end
32
-
33
- alias_method :asserting, :assert
37
+ def _assert(&block)
38
+ raise ArgumentError, "no block given" unless block_given?
34
39
 
35
- # Ensures that the condition on target evaluates to a false value.
36
- #
37
- # @api public
38
- #
39
- # @param target the target on which to test the condition
40
- # @param message the message that will be set if the test fails
41
- #
42
- # @return the wrapper object you can use to test your assertions
43
- def deny(target = self, message = nil)
44
- if block_given?
45
- Covenant::Denial.new(target, message).test(yield target)
46
- else
47
- Covenant::Denial.new(target, message)
48
- end
40
+ tap { yield self or raise AssertionFailed, ErrorMessage.new(block) }
49
41
  end
50
-
51
- alias_method :denying, :deny
52
42
  end
53
43
 
54
- class AssertionFailed < Exception; end
44
+ class AssertionFailed < StandardError; end
55
45
 
56
- class Statement < BasicObject
57
- def initialize(target, message)
58
- @target = target
59
- @message = message
46
+ class ErrorMessage
47
+ def initialize(block)
48
+ @block = block
60
49
  end
61
50
 
62
- def ==(other)
63
- test(target == other, ErrorMessage.new(target, :==, [other]))
51
+ def to_s
52
+ "block did not return true:\n\n#{source_block}\n\n#{variable_block}"
64
53
  end
65
54
 
66
- def !=(other)
67
- test(target != other, ErrorMessage.new(target, :!=, [other]))
68
- end
55
+ private
69
56
 
70
- def method_missing(name, *args)
71
- if target.respond_to?(name)
72
- return test(target.send(name, *args),
73
- ErrorMessage.new(target, name, args))
74
- end
75
-
76
- query = "#{name}?"
57
+ attr_reader :block
77
58
 
78
- if target.respond_to?(query)
79
- return test(target.send(query, *args),
80
- ErrorMessage.new(target, query, args))
81
- end
82
-
83
- no_is = name.to_s.sub(/^is_/, '')
84
- is_query = "#{no_is}?"
85
-
86
- if target.respond_to?(is_query)
87
- return test(target.send(is_query, *args),
88
- ErrorMessage.new(target, is_query, args))
89
- end
90
-
91
- super
59
+ def indent(str)
60
+ " " + str.gsub(/\n/, "\n ").strip
92
61
  end
93
62
 
94
- protected
95
-
96
- attr_reader :target, :message
97
-
98
- def raise_error(message)
99
- msg = self.message || message
100
-
101
- if msg
102
- ::Kernel.raise AssertionFailed, msg
103
- else
104
- ::Kernel.raise AssertionFailed
105
- end
63
+ def source
64
+ block.to_source
106
65
  end
107
66
 
108
- class NullErrorMessage
109
- def for_assertion; end
110
- def for_denial; end
67
+ def source_block
68
+ "Source:\n\n#{indent(source)}"
111
69
  end
112
70
 
113
- class ErrorMessage
114
- attr_reader :target, :message, :args
115
-
116
- def initialize(target, message, args)
117
- @target = target
118
- @message = message
119
- @args = args
120
- end
121
-
122
- def for_assertion
123
- error_message('should be true')
124
- end
71
+ def variable_block
72
+ b = variables.
73
+ inject("") { |a, (var, val)|
74
+ a << "#{var} = #{val.inspect}\n"
75
+ }
125
76
 
126
- def for_denial
127
- error_message('should be false')
128
- end
129
-
130
- private
131
-
132
- def error_message(expected)
133
- argl = args.map(&:inspect).join(", ")
134
-
135
- "#{target.inspect}.#{message} #{argl} #{expected}"
136
- end
77
+ "Variables:\n\n" + indent(b)
137
78
  end
138
- end
139
79
 
140
- class Assertion < Statement
141
- def test(condition, error_message = NullErrorMessage.new)
142
- if condition
143
- target
144
- else
145
- raise_error error_message.for_assertion
146
- end
147
- end
148
- end
80
+ def variables
81
+ s = source
82
+ b = block.binding
83
+ lv = b.eval('local_variables')
149
84
 
150
- class Denial < Statement
151
- def test(condition, error_message = NullErrorMessage.new)
152
- if ! condition
153
- target
154
- else
155
- raise_error error_message.for_denial
156
- end
85
+ lv.
86
+ select { |v| s =~ /\b#{v}\b/ }.
87
+ map { |v| [v, b.eval(v.to_s)] }
157
88
  end
158
89
  end
159
90
  end
160
-
161
- =begin
162
-
163
- require 'benchmark'
164
-
165
- Covenant.abide self
166
-
167
- Benchmark.bm do |x|
168
- x.report { 1_000_000.times { assert('aaa').start_with 'a' } }
169
- x.report { 1_000_000.times { 'aaa'.start_with? 'a' } }
170
- end
171
-
172
- =end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: covenant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-03 00:00:00.000000000 Z
12
+ date: 2013-03-17 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sourcify
16
+ requirement: &84448700 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.0.pre
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *84448700
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: rspec
16
- requirement: &86482920 !ruby/object:Gem::Requirement
27
+ requirement: &84448470 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ! '>='
@@ -21,7 +32,7 @@ dependencies:
21
32
  version: '2.11'
22
33
  type: :development
23
34
  prerelease: false
24
- version_requirements: *86482920
35
+ version_requirements: *84448470
25
36
  description:
26
37
  email:
27
38
  - gems@mojotech.com