iba 0.0.2 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []