iba 0.0.2 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bc9ef58cc2d18bc4e74c789ebed62265cee83bfaf45ee7a7c5e21d2d73c216ca
4
+ data.tar.gz: cbae41b9fae66df4aa717008627d1478d54e4cc61a90d48371460a23357d4dee
5
+ SHA512:
6
+ metadata.gz: 7ba511885b585a67f8a8dec3b0792c2fd4bc63fd2e575580d22f9b1dab158b7f6e87ea32244ddb5461d2a36d3fcc8eb362c5944b28990728295e52f5ea192797
7
+ data.tar.gz: 9ef4e73638d5fe567b0ae77a0ac031b3772c71353287aa5fea8a6d3cfd960fb1a1d5b18ca36dd6d8547abeeeaf0b2037b1357b4556c2d55adf4329702910a295
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Iba
4
+ VERSION = "0.0.6"
5
+ end
data/lib/iba.rb CHANGED
@@ -1,186 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "iba/version"
4
+
1
5
  module Iba
6
+ class Combinator
7
+ def initialize(&blk)
8
+ @block = blk
9
+ end
2
10
 
3
- class Combinator
4
- def initialize &blk
5
- @block = blk
6
- end
11
+ def call
12
+ @block.call
13
+ end
7
14
 
8
- def call
9
- @block.call
10
- end
15
+ def to_s
16
+ expression._to_s
17
+ end
11
18
 
12
- def to_s
13
- expression._to_s
14
- end
19
+ def expression
20
+ @expression ||= EmptyExpression.new._parse(&@block)
21
+ end
15
22
 
16
- def expression
17
- @expression ||= EmptyExpression.new._parse(&@block)
23
+ def analyse
24
+ str = +"#{self} is #{call.inspect}"
25
+ sub = expression._display_subexpressions(@block.binding)
26
+ str << "\n#{sub}" if sub
27
+ str
28
+ end
18
29
  end
19
30
 
20
- def analyse
21
- str = "#{self.to_s} is #{self.call.inspect}"
22
- if expression.class == MethodCallExpression and expression._method == :==
23
- b = @block.binding
24
- lft = expression._reciever
25
- rgt = expression._args.first
26
- exprs = [lft, rgt].map {|e| display_subexpression e}.compact
27
- str << "\n"
28
- str << exprs.join(", ")
29
- end
30
- str
31
- end
31
+ class BaseExpression
32
+ def method_missing(method, *args)
33
+ # FIXME: Remove to_s once support for Ruby < 2.7 is dropped
34
+ super if method.to_s.start_with? "_"
35
+ MethodCallExpression.new self, method, args
36
+ end
37
+
38
+ def respond_to_missing?(method)
39
+ # FIXME: Remove to_s once support for Ruby < 2.7 is dropped
40
+ return super if method.to_s.start_with? "_"
41
+
42
+ true
43
+ end
44
+
45
+ def to_s
46
+ method_missing :to_s
47
+ end
48
+
49
+ def ==(other)
50
+ method_missing :==, other
51
+ end
52
+
53
+ def !=(other)
54
+ method_missing :!=, other
55
+ end
56
+
57
+ def _wrap(arg)
58
+ if arg.is_a? BaseExpression
59
+ arg
60
+ else
61
+ LiteralExpression.new arg
62
+ end
63
+ end
32
64
 
33
- private
65
+ def _display(_bnd)
66
+ nil
67
+ end
34
68
 
35
- def display_subexpression expr
36
- if expr.class == LiteralExpression
69
+ def _display_subexpressions(_bnd)
37
70
  nil
38
- else
39
- str = expr._to_s
40
- "#{str} is #{eval(str, @block.binding).inspect}"
71
+ end
72
+
73
+ # Handle numeric operator coersion
74
+ def coerce(other)
75
+ [_wrap(other), self]
41
76
  end
42
77
  end
43
78
 
44
- end
79
+ class EmptyExpression < BaseExpression
80
+ def _parse(&blk)
81
+ bnd = blk.binding
45
82
 
46
- class EmptyExpression
47
- def method_missing method, *args
48
- return MethodCallExpression.new self, method, args
49
- end
83
+ vars = bnd.local_variables
84
+ ivars = bnd.receiver.instance_variables
50
85
 
51
- def _parse &blk
52
- b = blk.binding
86
+ _override_instance_variables ivars
53
87
 
54
- vars = eval "local_variables", b
55
- ivars = eval "instance_variables", b
88
+ _override_local_variables vars, bnd
56
89
 
57
- _override_instance_variables ivars
90
+ result = instance_eval(&blk)
91
+ result = _wrap(result)
58
92
 
59
- _override_local_variables vars, b
93
+ _restore_local_variables vars, bnd
60
94
 
61
- result = self.instance_eval(&blk)
62
- unless result.class == MethodCallExpression
63
- result = LiteralExpression.new(result)
95
+ result
64
96
  end
65
97
 
66
- _restore_local_variables vars, b
98
+ def _override_instance_variables(vars)
99
+ vars.each do |v|
100
+ # FIXME: Remove to_s once support for Ruby < 2.7 is dropped
101
+ next if v.to_s.start_with? "@_"
67
102
 
68
- result
69
- end
103
+ instance_variable_set v, Iba::InstanceVariableExpression.new(v.to_sym)
104
+ end
105
+ end
70
106
 
71
- def _override_instance_variables vars
72
- vars.each do |v|
73
- next if v =~ /^@_/
74
- eval "#{v} = Iba::MethodCallExpression.new(Iba::EmptyExpression.new, :#{v}, [])"
107
+ def _override_local_variables(vars, bnd)
108
+ vars.each do |v|
109
+ # FIXME: Remove to_s once support for Ruby < 2.7 is dropped
110
+ next if v.to_s.start_with? "_"
111
+
112
+ bnd.local_variable_set "_#{v}", bnd.local_variable_get(v)
113
+ bnd.local_variable_set v, LocalVariableExpression.new(v.to_sym)
114
+ end
75
115
  end
76
- end
77
116
 
78
- def _override_local_variables vars, b
79
- vars.each do |v|
80
- next if v =~ /^_/
81
- eval "_#{v} = #{v}", b
82
- eval "#{v} = Iba::MethodCallExpression.new(Iba::EmptyExpression.new, :#{v}, [])", b
117
+ def _restore_local_variables(vars, bnd)
118
+ vars.each do |v|
119
+ # FIXME: Remove to_s once support for Ruby < 2.7 is dropped
120
+ next if v.to_s.start_with? "_"
121
+
122
+ bnd.local_variable_set v, bnd.local_variable_get("_#{v}")
123
+ end
83
124
  end
84
- end
85
125
 
86
- def _restore_local_variables vars, b
87
- vars.each do |v|
88
- next if v =~ /^_/
89
- eval "#{v} = _#{v}", b
126
+ def _to_s
127
+ ""
90
128
  end
91
129
  end
92
130
 
93
- def _to_s
94
- ""
131
+ class LiteralExpression < BaseExpression
132
+ def initialize(val)
133
+ super()
134
+ @value = val
135
+ end
136
+
137
+ def _to_s
138
+ @value.inspect
139
+ end
140
+
141
+ def _evaluate(_bnd)
142
+ @value
143
+ end
95
144
  end
96
- end
97
145
 
98
- class LiteralExpression
99
- def initialize val
100
- @value = val
146
+ class DisplayableExpression < BaseExpression
147
+ def _display(bnd)
148
+ str = _to_s
149
+ value = _evaluate(bnd).inspect
150
+ "#{str} is #{value}"
151
+ end
101
152
  end
102
153
 
103
- def _to_s
104
- @value.inspect
154
+ class InstanceVariableExpression < DisplayableExpression
155
+ def initialize(ivar_name)
156
+ super()
157
+ @_ivar_name = ivar_name
158
+ end
159
+
160
+ def _to_s
161
+ @_ivar_name.to_s
162
+ end
163
+
164
+ def _evaluate(bnd)
165
+ bnd.receiver.instance_variable_get @_ivar_name
166
+ end
105
167
  end
106
- end
107
168
 
108
- class MethodCallExpression
109
- attr_reader :_method, :_reciever, :_args
169
+ class LocalVariableExpression < DisplayableExpression
170
+ def initialize(lvar_name)
171
+ super()
172
+ @_lvar_name = lvar_name
173
+ end
174
+
175
+ def _to_s
176
+ @_lvar_name.to_s
177
+ end
110
178
 
111
- def initialize reciever, methodname, args
112
- @_reciever = reciever
113
- @_method = methodname
114
- @_args = args.map {|a| _wrap(a)}
179
+ def _evaluate(bnd)
180
+ bnd.local_variable_get @_lvar_name
181
+ end
115
182
  end
116
183
 
117
- def _to_s
118
- rcv = @_reciever._to_s
119
- args = @_args.map {|a| a.respond_to?(:_to_s) ? a._to_s : a.to_s }
184
+ class MethodCallExpression < DisplayableExpression
185
+ attr_reader :_method, :_reciever, :_args
120
186
 
121
- if @_method == :[]
122
- "#{rcv}[#{args[0]}]"
123
- elsif method_is_operator?
124
- case @_args.length
125
- when 0
126
- "#{@_method.to_s.sub(/@$/, '')}#{rcv}"
127
- when 1
128
- "(#{rcv} #{@_method} #{args.first})"
187
+ def initialize(reciever, methodname, args)
188
+ super()
189
+ @_reciever = reciever
190
+ @_method = methodname
191
+ @_args = args.map { |a| _wrap(a) }
192
+ end
193
+
194
+ def _to_s
195
+ if @_method == :[]
196
+ _index_to_s
197
+ elsif _method_is_operator?
198
+ _operator_to_s
129
199
  else
130
- raise NotImplementedError
200
+ _regular_method_to_s
131
201
  end
132
- else
133
- str = rcv == "" ? "" : "#{rcv}."
134
- str << @_method.to_s
135
- unless @_args.empty?
136
- str << "(#{args.join(', ')})"
137
- end
138
- str
139
202
  end
140
- end
141
203
 
142
- def method_missing method, *args
143
- super if method.to_s =~ /^_/
144
- return MethodCallExpression.new self, method, args
145
- end
204
+ def _evaluate(bnd)
205
+ rcv = @_reciever._evaluate(bnd)
206
+ args = @_args.map { |arg| arg._evaluate(bnd) }
207
+ rcv.send @_method, *args
208
+ end
146
209
 
147
- def method_is_operator?
148
- @_method.to_s !~ /^[a-z]/
149
- end
210
+ def _display_subexpressions(bnd)
211
+ rcv = @_reciever._display(bnd)
212
+ args = @_args.map { |arg| arg._display(bnd) }
213
+ [rcv, *args].compact.join(", ")
214
+ end
150
215
 
151
- def to_s
152
- method_missing :to_s
153
- end
216
+ private
154
217
 
155
- def == other
156
- method_missing :==, other
157
- end
218
+ def _receiver_s
219
+ @_reciever._to_s
220
+ end
158
221
 
159
- private
222
+ def _args_s
223
+ @_args.map { |a| a.respond_to?(:_to_s) ? a._to_s : a.to_s }
224
+ end
160
225
 
161
- def _wrap arg
162
- if arg.class == MethodCallExpression
163
- arg
164
- else
165
- LiteralExpression.new arg
226
+ def _index_to_s
227
+ "#{_receiver_s}[#{_args_s[0]}]"
166
228
  end
167
- end
168
- end
169
229
 
170
- module BlockAssertion
171
- def assert *args
172
- if block_given?
173
- if yield
174
- assert_block("true") { true }
230
+ def _operator_to_s
231
+ case @_args.length
232
+ when 0
233
+ "#{@_method.to_s.sub(/@$/, '')}#{_receiver_s}"
234
+ when 1
235
+ "(#{_receiver_s} #{@_method} #{_args_s.first})"
175
236
  else
176
- msg = args.empty? ? "" : args.first
177
- ana = Combinator.new(&Proc.new).analyse
178
- assert_block(build_message(msg, "#{ana}.")) { false }
237
+ raise NotImplementedError
179
238
  end
180
- else
181
- super
239
+ end
240
+
241
+ def _regular_method_to_s
242
+ rcv = _receiver_s
243
+ str = rcv == "" ? +"" : +"#{rcv}."
244
+ str << @_method.to_s
245
+ str << "(#{_args_s.join(', ')})" unless @_args.empty?
246
+ str
247
+ end
248
+
249
+ def _method_is_operator?
250
+ @_method.to_s !~ /^[a-z]/
182
251
  end
183
252
  end
184
- end
185
253
 
254
+ module BlockAssertion
255
+ def assert(*args, &block)
256
+ if block
257
+ if yield
258
+ assert_block("true") { true }
259
+ else
260
+ msg = args.empty? ? "" : "#{args.first}.\n"
261
+ ana = Combinator.new(&block).analyse
262
+ assert_block("#{msg}#{ana}.") { false }
263
+ end
264
+ else
265
+ test, msg = *args
266
+ super test, msg
267
+ end
268
+ end
269
+ end
186
270
  end
metadata CHANGED
@@ -1,89 +1,142 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: iba
3
- version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Matijs van Zuijlen
14
- autorequire:
8
+ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-manifest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.25.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.25.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-packaging
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.5.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-performance
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.13.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.13.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.1'
97
+ description: 'Asserts blocks, prints introspective failure messages.
17
98
 
18
- date: 2011-02-25 00:00:00 +01:00
19
- default_executable:
20
- dependencies: []
21
-
22
- description: Asserts blocks, prints introspective failure messages.
23
- email:
99
+ '
100
+ email:
24
101
  - matijs@matijs.net
25
102
  executables: []
26
-
27
103
  extensions: []
28
-
29
- extra_rdoc_files:
104
+ extra_rdoc_files:
30
105
  - README.rdoc
31
106
  - LICENSE
32
107
  - COPYING.LESSER
33
- - COPYING
34
- files:
35
- - lib/iba.rb
36
- - test/analyse_test.rb
37
- - test/test_helper.rb
38
- - test/call_test.rb
39
- - test/assert_test.rb
40
- - test/display_test.rb
41
- - tasks/test.rake
42
- - tasks/setup.rb
43
- - tasks/notes.rake
108
+ files:
44
109
  - COPYING.LESSER
45
110
  - LICENSE
46
111
  - README.rdoc
47
- - Rakefile
48
- - COPYING
49
- has_rdoc: true
112
+ - lib/iba.rb
113
+ - lib/iba/version.rb
50
114
  homepage: http://www.github.com/mvz/iba
51
- licenses: []
52
-
53
- post_install_message:
54
- rdoc_options:
55
- - --main
115
+ licenses:
116
+ - LGPL-3.0+
117
+ metadata:
118
+ homepage_uri: http://www.github.com/mvz/iba
119
+ source_code_uri: https://github.com/mvz/iba
120
+ rubygems_mfa_required: 'true'
121
+ post_install_message:
122
+ rdoc_options:
123
+ - "--main"
56
124
  - README.rdoc
57
- require_paths:
125
+ require_paths:
58
126
  - lib
59
- required_ruby_version: !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
62
129
  - - ">="
63
- - !ruby/object:Gem::Version
64
- hash: 3
65
- segments:
66
- - 0
67
- version: "0"
68
- required_rubygems_version: !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
130
+ - !ruby/object:Gem::Version
131
+ version: 2.6.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
71
134
  - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
77
137
  requirements: []
78
-
79
- rubyforge_project:
80
- rubygems_version: 1.3.7
81
- signing_key:
82
- specification_version: 3
138
+ rubygems_version: 3.3.3
139
+ signing_key:
140
+ specification_version: 4
83
141
  summary: Introspective Block Assertions
84
- test_files:
85
- - test/analyse_test.rb
86
- - test/assert_test.rb
87
- - test/call_test.rb
88
- - test/display_test.rb
89
- - test/test_helper.rb
142
+ test_files: []