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 +7 -0
- data/lib/iba/version.rb +5 -0
- data/lib/iba.rb +213 -129
- metadata +120 -67
- data/COPYING +0 -674
- data/Rakefile +0 -3
- data/tasks/notes.rake +0 -122
- data/tasks/setup.rb +0 -6
- data/tasks/test.rake +0 -14
- data/test/analyse_test.rb +0 -58
- data/test/assert_test.rb +0 -58
- data/test/call_test.rb +0 -18
- data/test/display_test.rb +0 -57
- data/test/test_helper.rb +0 -12
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
|
data/lib/iba/version.rb
ADDED
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
11
|
+
def call
|
12
|
+
@block.call
|
13
|
+
end
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
15
|
+
def to_s
|
16
|
+
expression._to_s
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
19
|
+
def expression
|
20
|
+
@expression ||= EmptyExpression.new._parse(&@block)
|
21
|
+
end
|
15
22
|
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
65
|
+
def _display(_bnd)
|
66
|
+
nil
|
67
|
+
end
|
34
68
|
|
35
|
-
|
36
|
-
if expr.class == LiteralExpression
|
69
|
+
def _display_subexpressions(_bnd)
|
37
70
|
nil
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
79
|
+
class EmptyExpression < BaseExpression
|
80
|
+
def _parse(&blk)
|
81
|
+
bnd = blk.binding
|
45
82
|
|
46
|
-
|
47
|
-
|
48
|
-
return MethodCallExpression.new self, method, args
|
49
|
-
end
|
83
|
+
vars = bnd.local_variables
|
84
|
+
ivars = bnd.receiver.instance_variables
|
50
85
|
|
51
|
-
|
52
|
-
b = blk.binding
|
86
|
+
_override_instance_variables ivars
|
53
87
|
|
54
|
-
|
55
|
-
ivars = eval "instance_variables", b
|
88
|
+
_override_local_variables vars, bnd
|
56
89
|
|
57
|
-
|
90
|
+
result = instance_eval(&blk)
|
91
|
+
result = _wrap(result)
|
58
92
|
|
59
|
-
|
93
|
+
_restore_local_variables vars, bnd
|
60
94
|
|
61
|
-
|
62
|
-
unless result.class == MethodCallExpression
|
63
|
-
result = LiteralExpression.new(result)
|
95
|
+
result
|
64
96
|
end
|
65
97
|
|
66
|
-
|
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
|
-
|
69
|
-
|
103
|
+
instance_variable_set v, Iba::InstanceVariableExpression.new(v.to_sym)
|
104
|
+
end
|
105
|
+
end
|
70
106
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
87
|
-
|
88
|
-
next if v =~ /^_/
|
89
|
-
eval "#{v} = _#{v}", b
|
126
|
+
def _to_s
|
127
|
+
""
|
90
128
|
end
|
91
129
|
end
|
92
130
|
|
93
|
-
|
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
|
99
|
-
|
100
|
-
|
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
|
-
|
104
|
-
|
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
|
109
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
118
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
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
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
152
|
-
method_missing :to_s
|
153
|
-
end
|
216
|
+
private
|
154
217
|
|
155
|
-
|
156
|
-
|
157
|
-
|
218
|
+
def _receiver_s
|
219
|
+
@_reciever._to_s
|
220
|
+
end
|
158
221
|
|
159
|
-
|
222
|
+
def _args_s
|
223
|
+
@_args.map { |a| a.respond_to?(:_to_s) ? a._to_s : a.to_s }
|
224
|
+
end
|
160
225
|
|
161
|
-
|
162
|
-
|
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
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
177
|
-
ana = Combinator.new(&Proc.new).analyse
|
178
|
-
assert_block(build_message(msg, "#{ana}.")) { false }
|
237
|
+
raise NotImplementedError
|
179
238
|
end
|
180
|
-
|
181
|
-
|
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
|
-
|
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
|
-
|
19
|
-
|
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
|
-
|
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
|
-
-
|
48
|
-
-
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
61
|
-
requirements:
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
62
129
|
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
74
|
-
segments:
|
75
|
-
- 0
|
76
|
-
version: "0"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
77
137
|
requirements: []
|
78
|
-
|
79
|
-
|
80
|
-
|
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: []
|