rantly 1.2.0 → 2.0.0
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 +4 -4
- data/.travis.yml +9 -6
- data/CHANGELOG.md +33 -0
- data/Gemfile +4 -2
- data/README.md +10 -1
- data/Rakefile +15 -2
- data/VERSION.yml +2 -2
- data/lib/rantly.rb +4 -4
- data/lib/rantly/data.rb +1 -1
- data/lib/rantly/generator.rb +87 -95
- data/lib/rantly/property.rb +18 -21
- data/lib/rantly/shrinks.rb +40 -45
- data/lib/rantly/silly.rb +40 -38
- data/lib/rantly/spec.rb +4 -4
- data/rantly.gemspec +37 -42
- data/test/rantly_test.rb +85 -216
- data/test/shrinks_test.rb +38 -42
- metadata +5 -62
data/test/rantly_test.rb
CHANGED
@@ -5,277 +5,146 @@ module RantlyTest
|
|
5
5
|
end
|
6
6
|
|
7
7
|
describe Rantly::Property do
|
8
|
-
|
9
8
|
before do
|
10
9
|
Rantly.gen.reset
|
11
10
|
end
|
12
11
|
|
13
|
-
it
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
it "generate literal value by returning itself" do
|
20
|
-
property_of {
|
21
|
-
i = integer
|
22
|
-
[i,literal(i)]
|
23
|
-
}.check { |(a,b)|
|
24
|
-
assert_equal a, b
|
25
|
-
}
|
26
|
-
end
|
27
|
-
|
28
|
-
it "generate integer in range" do
|
29
|
-
property_of {
|
30
|
-
i = integer
|
31
|
-
[i,range(i,i)]
|
32
|
-
}.check { |(a,b)|
|
33
|
-
assert_equal a, b
|
34
|
-
}
|
35
|
-
property_of {
|
36
|
-
lo, hi = [integer(100),integer(100)].sort
|
37
|
-
[lo,hi,range(lo,hi)]
|
38
|
-
}.check { |(lo,hi,int)|
|
39
|
-
assert((lo..hi).include?(int))
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
it "generate Fixnum only" do
|
44
|
-
property_of { integer }.check { |i| assert i.is_a?(Integer) }
|
45
|
-
end
|
46
|
-
|
47
|
-
it "generate integer less than abs(n)" do
|
48
|
-
property_of {
|
49
|
-
n = range(0,10)
|
50
|
-
[n,integer(n)]
|
51
|
-
}.check {|(n,i)|
|
52
|
-
assert n.abs >= i.abs
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
it "generate Float" do
|
57
|
-
property_of { float }.check { |f| assert f.is_a?(Float)}
|
58
|
-
end
|
59
|
-
|
60
|
-
it "generate Float with normal distribution" do
|
61
|
-
property_of{
|
62
|
-
center = integer(100)
|
63
|
-
normal_points = Array.new(100){ float(:normal, { center: center }) }
|
64
|
-
[center, normal_points]
|
65
|
-
}.check{ |center, normal_points|
|
66
|
-
average_center = normal_points.reduce(0, :+) / 100
|
67
|
-
assert average_center.between?(center - 0.5, center + 0.5)
|
68
|
-
}
|
69
|
-
end
|
70
|
-
|
71
|
-
it "generate Boolean" do
|
72
|
-
property_of { boolean }.check { |t|
|
73
|
-
assert t == true || t == false
|
74
|
-
}
|
75
|
-
end
|
76
|
-
|
77
|
-
it "generate empty strings" do
|
78
|
-
property_of {
|
79
|
-
sized(0) { string }
|
80
|
-
}.check { |s|
|
81
|
-
assert s.empty?
|
82
|
-
}
|
83
|
-
end
|
84
|
-
|
85
|
-
it "generate strings with the right regexp char classes" do
|
86
|
-
char_classes = Rantly::Chars::CLASSES.keys
|
87
|
-
property_of {
|
88
|
-
char_class = choose(*char_classes)
|
89
|
-
len = range(0,10)
|
90
|
-
sized(len) { [len,char_class,string(char_class)]}
|
91
|
-
}.check { |(len,char_class,str)|
|
92
|
-
t = true
|
93
|
-
chars = Rantly::Chars::CLASSES[char_class]
|
94
|
-
str.each_byte { |c|
|
95
|
-
unless chars.include?(c)
|
96
|
-
t = false
|
97
|
-
break
|
98
|
-
end
|
99
|
-
}
|
100
|
-
assert_equal len, str.length
|
101
|
-
assert t
|
102
|
-
}
|
103
|
-
end
|
104
|
-
|
105
|
-
it "generate strings matching regexp" do
|
106
|
-
property_of {
|
107
|
-
sized(10) { string(/[abcd]/) }
|
108
|
-
}.check { |s|
|
109
|
-
assert s =~ /[abcd]+/
|
110
|
-
}
|
12
|
+
it 'fail test generation' do
|
13
|
+
print "\n### TESTING A FAILING CASE, do not get scared"
|
14
|
+
assert_raises(Rantly::TooManyTries) do
|
15
|
+
property_of { guard range(0, 1).negative? }.check
|
16
|
+
end
|
111
17
|
end
|
112
18
|
|
113
19
|
# call
|
114
20
|
|
115
|
-
it
|
116
|
-
property_of {call(:integer)}.check { |i| i.is_a?(Integer)}
|
21
|
+
it 'call Symbol as method call (no arg)' do
|
22
|
+
property_of { call(:integer) }.check { |i| i.is_a?(Integer) }
|
117
23
|
end
|
118
24
|
|
119
|
-
it
|
120
|
-
property_of
|
121
|
-
n = range(0,100)
|
122
|
-
[n,call(:integer,n)]
|
123
|
-
|
25
|
+
it 'call Symbol as method call (with arg)' do
|
26
|
+
property_of do
|
27
|
+
n = range(0, 100)
|
28
|
+
[n, call(:integer, n)]
|
29
|
+
end.check do |(n, i)|
|
124
30
|
assert n.abs >= i.abs
|
125
|
-
|
31
|
+
end
|
126
32
|
end
|
127
33
|
|
128
|
-
it
|
129
|
-
assert_raises(RuntimeError)
|
130
|
-
Rantly.gen.value
|
34
|
+
it 'call Array by calling first element as method, the rest as args' do
|
35
|
+
assert_raises(RuntimeError) do
|
36
|
+
Rantly.gen.value do
|
131
37
|
call []
|
132
|
-
|
133
|
-
|
134
|
-
property_of
|
38
|
+
end
|
39
|
+
end
|
40
|
+
property_of do
|
135
41
|
i = integer
|
136
|
-
[i,call(choose([:literal,i],[:range,i,i]))]
|
137
|
-
|
42
|
+
[i, call(choose([:literal, i], [:range, i, i]))]
|
43
|
+
end.check do |(a, b)|
|
138
44
|
assert_equal a, b
|
139
|
-
|
45
|
+
end
|
140
46
|
end
|
141
47
|
|
142
|
-
it
|
143
|
-
property_of
|
144
|
-
call
|
145
|
-
|
48
|
+
it 'call Proc with generator.instance_eval' do
|
49
|
+
property_of do
|
50
|
+
call proc { true }
|
51
|
+
end.check do |o|
|
146
52
|
assert_equal true, o
|
147
|
-
|
148
|
-
property_of
|
149
|
-
i0 = range(0,100)
|
150
|
-
i1 = call
|
151
|
-
range(i0+1,i0+100)
|
53
|
+
end
|
54
|
+
property_of do
|
55
|
+
i0 = range(0, 100)
|
56
|
+
i1 = call proc {
|
57
|
+
range(i0 + 1, i0 + 100)
|
152
58
|
}
|
153
|
-
[i0,i1]
|
154
|
-
|
155
|
-
assert i0.is_a?(
|
59
|
+
[i0, i1]
|
60
|
+
end.check do |(i0, i1)|
|
61
|
+
assert i0.is_a?(Integer) && i1.is_a?(Integer)
|
156
62
|
assert i1 > i0
|
157
63
|
assert i1 <= (i0 + 100)
|
158
|
-
|
64
|
+
end
|
159
65
|
end
|
160
66
|
|
161
|
-
it
|
162
|
-
assert_raises(RuntimeError)
|
67
|
+
it 'raise if calling on any other value' do
|
68
|
+
assert_raises(RuntimeError) do
|
163
69
|
Rantly.gen.call 0
|
164
|
-
|
70
|
+
end
|
165
71
|
end
|
166
72
|
|
167
73
|
# branch
|
168
74
|
|
169
|
-
it
|
170
|
-
property_of
|
75
|
+
it 'branch by Rantly#calling one of the args' do
|
76
|
+
property_of do
|
171
77
|
branch :integer, :integer, :integer
|
172
|
-
|
173
|
-
assert o.is_a?(
|
174
|
-
|
175
|
-
property_of
|
78
|
+
end.check do |o|
|
79
|
+
assert o.is_a?(Integer)
|
80
|
+
end
|
81
|
+
property_of do
|
176
82
|
sized(10) { branch :integer, :string }
|
177
|
-
|
178
|
-
assert o.is_a?(
|
179
|
-
|
83
|
+
end.check do |o|
|
84
|
+
assert o.is_a?(Integer) || o.is_a?(String)
|
85
|
+
end
|
180
86
|
end
|
181
87
|
|
182
88
|
# choose
|
183
89
|
|
184
|
-
it
|
185
|
-
property_of
|
90
|
+
it 'choose a value from args ' do
|
91
|
+
property_of do
|
186
92
|
choose
|
187
|
-
|
93
|
+
end.check do |o|
|
188
94
|
assert_nil o
|
189
|
-
|
190
|
-
property_of
|
95
|
+
end
|
96
|
+
property_of do
|
191
97
|
choose 1
|
192
|
-
|
98
|
+
end.check do |o|
|
193
99
|
assert_equal 1, o
|
194
|
-
|
195
|
-
property_of
|
196
|
-
choose 1,2
|
197
|
-
|
198
|
-
assert
|
199
|
-
|
200
|
-
property_of
|
100
|
+
end
|
101
|
+
property_of do
|
102
|
+
choose 1, 2
|
103
|
+
end.check do |o|
|
104
|
+
assert [1, 2].include? o
|
105
|
+
end
|
106
|
+
property_of do
|
201
107
|
arr = sized(10) { array { integer } }
|
202
108
|
choose(*arr)
|
203
|
-
|
204
|
-
assert o.is_a?(
|
205
|
-
|
206
|
-
property_of
|
109
|
+
end.check do |o|
|
110
|
+
assert o.is_a?(Integer)
|
111
|
+
end
|
112
|
+
property_of do
|
207
113
|
# array of array of ints
|
208
|
-
arr = sized(10) { array { array { integer }}}
|
114
|
+
arr = sized(10) { array { array { integer } } }
|
209
115
|
# choose an array from an array of arrays of ints
|
210
116
|
choose(*arr)
|
211
|
-
|
117
|
+
end.check do |arr|
|
212
118
|
assert arr.is_a?(Array)
|
213
|
-
assert arr.all? { |o| o.is_a?(
|
214
|
-
|
119
|
+
assert arr.all? { |o| o.is_a?(Integer) }
|
120
|
+
end
|
215
121
|
end
|
216
122
|
|
217
123
|
# freq
|
218
124
|
|
219
|
-
it
|
220
|
-
property_of
|
221
|
-
sized(10)
|
222
|
-
array { freq([0
|
223
|
-
|
224
|
-
|
225
|
-
assert arr.all? { |o| o.is_a?(Integer)}
|
226
|
-
|
125
|
+
it 'not pick an element with 0 frequency' do
|
126
|
+
property_of do
|
127
|
+
sized(10) do
|
128
|
+
array { freq([0, :string], [1, :integer]) }
|
129
|
+
end
|
130
|
+
end.check do |arr|
|
131
|
+
assert arr.all? { |o| o.is_a?(Integer) }
|
132
|
+
end
|
227
133
|
end
|
228
134
|
|
229
|
-
it
|
230
|
-
assert_raises(RuntimeError)
|
231
|
-
Rantly.gen.value
|
135
|
+
it 'handle degenerate freq pairs' do
|
136
|
+
assert_raises(RuntimeError) do
|
137
|
+
Rantly.gen.value do
|
232
138
|
freq
|
233
|
-
|
234
|
-
|
235
|
-
property_of
|
139
|
+
end
|
140
|
+
end
|
141
|
+
property_of do
|
236
142
|
i = integer
|
237
|
-
[i,freq([:literal,i])]
|
238
|
-
|
143
|
+
[i, freq([:literal, i])]
|
144
|
+
end.check do |(a, b)|
|
239
145
|
assert_equal a, b
|
240
|
-
|
146
|
+
end
|
241
147
|
end
|
242
|
-
|
243
|
-
# array
|
244
|
-
|
245
|
-
it "generate empty array" do
|
246
|
-
property_of {
|
247
|
-
sized(0) { array { integer }}
|
248
|
-
}.check { |o|
|
249
|
-
assert o.empty?
|
250
|
-
}
|
251
|
-
end
|
252
|
-
|
253
|
-
it "generate the right sized nested arrays" do
|
254
|
-
property_of {
|
255
|
-
size1 = range(5,10)
|
256
|
-
size2 = range(0,size1-1)
|
257
|
-
array = sized(size1) { array { array(size2) { integer }}}
|
258
|
-
[size1,array]
|
259
|
-
}.check { |(size1,outter_array)|
|
260
|
-
assert_equal size1, outter_array.size
|
261
|
-
assert outter_array.all? { |inner_array| inner_array.size < size1 }
|
262
|
-
}
|
263
|
-
end
|
264
|
-
|
265
|
-
it "generate array with right types" do
|
266
|
-
property_of {
|
267
|
-
sized(10) { array { freq(:integer,:string,:float)} }
|
268
|
-
}.check { |arr|
|
269
|
-
assert arr.all? { |o| [Fixnum, Float, String].include? o.class }
|
270
|
-
}
|
271
|
-
end
|
272
|
-
|
273
|
-
# it "raise if generating an array without size" do
|
274
|
-
# assert_raises(RuntimeError) {
|
275
|
-
# Rantly.gen.value { array(:integer) }
|
276
|
-
# }
|
277
|
-
# end
|
278
|
-
|
279
148
|
end
|
280
149
|
|
281
150
|
# TODO: Determine type of tests required here.
|
data/test/shrinks_test.rb
CHANGED
@@ -9,98 +9,94 @@ module RantlyTest::Shrinkers
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe Integer do
|
12
|
-
|
13
|
-
it "not be able to shrink 0 integer" do
|
12
|
+
it 'not be able to shrink 0 integer' do
|
14
13
|
assert !0.shrinkable?
|
15
14
|
end
|
16
15
|
|
17
|
-
it
|
16
|
+
it 'shrink positive integers to something less than itself' do
|
18
17
|
assert(3.shrink < 3)
|
19
18
|
assert(2.shrink < 2)
|
20
|
-
assert_equal(0,1.shrink)
|
19
|
+
assert_equal(0, 1.shrink)
|
21
20
|
end
|
22
21
|
|
23
|
-
it
|
22
|
+
it 'shrink negative integers to something larger than itself' do
|
24
23
|
assert(-3.shrink > -3)
|
25
24
|
assert(-2.shrink > -2)
|
26
|
-
assert_equal(0
|
25
|
+
assert_equal(0, -1.shrink)
|
27
26
|
end
|
28
27
|
|
29
|
-
it
|
28
|
+
it 'shrink 0 to itself' do
|
30
29
|
# hmm. should this be undefined?
|
31
30
|
assert_equal 0.shrink, 0
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
describe String do
|
36
|
-
|
37
|
-
|
38
|
-
assert !"".shrinkable?
|
35
|
+
it 'not be able to shrink empty string' do
|
36
|
+
assert !''.shrinkable?
|
39
37
|
end
|
40
38
|
|
41
|
-
it
|
42
|
-
property_of
|
39
|
+
it 'shrink a string one char shorter' do
|
40
|
+
property_of do
|
43
41
|
sized(10) { string }
|
44
|
-
|
42
|
+
end.check do |str|
|
45
43
|
assert_equal 9, str.shrink.length
|
46
|
-
|
44
|
+
end
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
50
48
|
describe Tuple do
|
51
|
-
|
52
|
-
it "not be able to shrink empty tuple" do
|
49
|
+
it 'not be able to shrink empty tuple' do
|
53
50
|
assert !Tuple.new([]).shrinkable?
|
54
51
|
end
|
55
52
|
|
56
|
-
it
|
57
|
-
assert_equal [1,0], Tuple.new([1,1]).shrink.array
|
58
|
-
assert_equal [1,0,0], Tuple.new([1,1,0]).shrink.array
|
53
|
+
it 'shrink tuple by trying to shrink the last shrinkable element available' do
|
54
|
+
assert_equal [1, 0], Tuple.new([1, 1]).shrink.array
|
55
|
+
assert_equal [1, 0, 0], Tuple.new([1, 1, 0]).shrink.array
|
59
56
|
end
|
60
57
|
|
61
|
-
it
|
62
|
-
property_of
|
58
|
+
it 'do not remove element from array when no element is shrinkable' do
|
59
|
+
property_of do
|
63
60
|
n = integer(1..10)
|
64
|
-
a = Tuple.new(Array.new(n,0))
|
65
|
-
[n,a]
|
66
|
-
|
61
|
+
a = Tuple.new(Array.new(n, 0))
|
62
|
+
[n, a]
|
63
|
+
end.check do |n, a|
|
67
64
|
assert_equal n, a.shrink.length
|
68
|
-
|
65
|
+
end
|
69
66
|
end
|
70
67
|
end
|
71
68
|
|
72
69
|
describe Hash do
|
73
|
-
|
74
|
-
it "not be able to shrink empty hash" do
|
70
|
+
it 'not be able to shrink empty hash' do
|
75
71
|
assert !{}.shrinkable?
|
76
72
|
end
|
77
73
|
|
78
|
-
it
|
79
|
-
assert_equal({foo: 0, bar: 0}, {foo: 1, bar: 0}.shrink)
|
80
|
-
assert_equal({foo: 0, bar: 0}, {foo: 0, bar: 1}.shrink)
|
74
|
+
it 'shrink a value if one of the values is shrinkable' do
|
75
|
+
assert_equal({ foo: 0, bar: 0 }, { foo: 1, bar: 0 }.shrink)
|
76
|
+
assert_equal({ foo: 0, bar: 0 }, { foo: 0, bar: 1 }.shrink)
|
81
77
|
end
|
82
78
|
|
83
|
-
it
|
84
|
-
assert_equal({},{foo: 0}.shrink)
|
79
|
+
it 'shrink by deleting an element in it if none of the values is shrinkable' do
|
80
|
+
assert_equal({}, { foo: 0 }.shrink)
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
88
|
-
describe
|
89
|
-
|
90
|
-
|
84
|
+
describe 'Shrinker Test' do
|
85
|
+
it 'shrink data to smallest value that fails assertion' do
|
86
|
+
print "\n### TESTING A FAILING CASE, do not get scared"
|
91
87
|
# We try to generate an array of 10 elements, filled with ones.
|
92
88
|
# The property we try to test is that non of the element is
|
93
89
|
# larger than 1, and the array's length is less than 4.
|
94
|
-
test = property_of
|
95
|
-
a = Deflating.new(Array.new(10,1))
|
96
|
-
i = Random
|
90
|
+
test = property_of do
|
91
|
+
a = Deflating.new(Array.new(10, 1))
|
92
|
+
i = Random.rand(a.length)
|
97
93
|
a[i] = 1
|
98
94
|
a
|
99
|
-
|
95
|
+
end
|
100
96
|
assert_raises MiniTest::Assertion do
|
101
|
-
test.check
|
102
|
-
assert(
|
103
|
-
|
97
|
+
test.check do |a|
|
98
|
+
assert(a.array.none?(&:positive?) && a.length < 4, 'contains 1')
|
99
|
+
end
|
104
100
|
end
|
105
101
|
|
106
102
|
assert_equal [1], test.shrunk_failed_data.array
|