rushcheck 0.3 → 0.4
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.
- data/Rakefile +1 -1
- data/data/rushcheck/doc/policy.txt +107 -0
- data/data/rushcheck/doc/rushcheck.thtml +832 -0
- data/data/rushcheck/examples/candy.rb +6 -8
- data/data/rushcheck/examples/printf.rb +3 -3
- data/data/rushcheck/examples/proc.rb +4 -4
- data/data/rushcheck/examples/roguetile.rb +16 -16
- data/data/rushcheck/examples/sample.rb +10 -10
- data/data/rushcheck/rdoc/classes/Arbitrary.html +5 -5
- data/data/rushcheck/rdoc/classes/Arbitrary.src/M000082.html +18 -0
- data/data/rushcheck/rdoc/classes/Assertion.html +11 -11
- data/data/rushcheck/rdoc/classes/Assertion.src/M000019.html +20 -0
- data/data/rushcheck/rdoc/classes/Assertion.src/M000020.html +50 -0
- data/data/rushcheck/rdoc/classes/Coarbitrary.html +5 -5
- data/data/rushcheck/rdoc/classes/Coarbitrary.src/M000105.html +18 -0
- data/data/rushcheck/rdoc/classes/FalseClass.html +15 -15
- data/data/rushcheck/rdoc/classes/FalseClass.src/M000022.html +18 -0
- data/data/rushcheck/rdoc/classes/FalseClass.src/M000023.html +18 -0
- data/data/rushcheck/rdoc/classes/FalseClass.src/M000024.html +18 -0
- data/data/rushcheck/rdoc/classes/Float.html +20 -20
- data/data/rushcheck/rdoc/classes/Float.src/M000052.html +21 -0
- data/data/rushcheck/rdoc/classes/Float.src/M000053.html +18 -0
- data/data/rushcheck/rdoc/classes/Float.src/M000054.html +22 -0
- data/data/rushcheck/rdoc/classes/Float.src/M000055.html +20 -0
- data/data/rushcheck/rdoc/classes/Gen.html +102 -102
- data/data/rushcheck/rdoc/classes/Gen.src/M000030.html +4 -10
- data/data/rushcheck/rdoc/classes/Gen.src/M000031.html +29 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000032.html +6 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000033.html +14 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000034.html +10 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000035.html +4 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000036.html +4 -10
- data/data/rushcheck/rdoc/classes/Gen.src/M000037.html +4 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000038.html +4 -7
- data/data/rushcheck/rdoc/classes/Gen.src/M000039.html +4 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000040.html +10 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000041.html +4 -9
- data/data/rushcheck/rdoc/classes/Gen.src/M000042.html +7 -5
- data/data/rushcheck/rdoc/classes/Gen.src/M000043.html +4 -4
- data/data/rushcheck/rdoc/classes/Gen.src/M000044.html +4 -10
- data/data/rushcheck/rdoc/classes/Gen.src/M000045.html +23 -0
- data/data/rushcheck/rdoc/classes/Gen.src/M000046.html +19 -0
- data/data/rushcheck/rdoc/classes/Gen.src/M000047.html +18 -0
- data/data/rushcheck/rdoc/classes/Gen.src/M000048.html +24 -0
- data/data/rushcheck/rdoc/classes/Guard.html +10 -10
- data/data/rushcheck/rdoc/classes/Guard.src/M000028.html +27 -0
- data/data/rushcheck/rdoc/classes/Guard.src/M000029.html +18 -0
- data/data/rushcheck/rdoc/classes/HsRandom.html +20 -20
- data/data/rushcheck/rdoc/classes/HsRandom.src/M000088.html +22 -0
- data/data/rushcheck/rdoc/classes/HsRandom.src/M000089.html +32 -0
- data/data/rushcheck/rdoc/classes/HsRandom.src/M000090.html +18 -0
- data/data/rushcheck/rdoc/classes/Integer.html +20 -20
- data/data/rushcheck/rdoc/classes/Integer.src/M000010.html +18 -0
- data/data/rushcheck/rdoc/classes/Integer.src/M000011.html +18 -0
- data/data/rushcheck/rdoc/classes/Integer.src/M000012.html +21 -0
- data/data/rushcheck/rdoc/classes/Integer.src/M000013.html +19 -0
- data/data/rushcheck/rdoc/classes/NilClass.html +15 -15
- data/data/rushcheck/rdoc/classes/NilClass.src/M000064.html +18 -0
- data/data/rushcheck/rdoc/classes/NilClass.src/M000065.html +18 -0
- data/data/rushcheck/rdoc/classes/NilClass.src/M000066.html +18 -0
- data/data/rushcheck/rdoc/classes/Property.html +10 -10
- data/data/rushcheck/rdoc/classes/Property.src/M000077.html +26 -0
- data/data/rushcheck/rdoc/classes/Property.src/M000078.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomArray.html +15 -15
- data/data/rushcheck/rdoc/classes/RandomArray.src/M000025.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomArray.src/M000026.html +35 -0
- data/data/rushcheck/rdoc/classes/RandomArray.src/M000027.html +22 -0
- data/data/rushcheck/rdoc/classes/RandomBool.html +10 -10
- data/data/rushcheck/rdoc/classes/RandomBool.src/M000086.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomBool.src/M000087.html +19 -0
- data/data/rushcheck/rdoc/classes/RandomGen.html +20 -20
- data/data/rushcheck/rdoc/classes/RandomGen.src/M000083.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomGen.src/M000084.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomGen.src/M000085.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomHash.html +16 -16
- data/data/rushcheck/rdoc/classes/RandomHash.src/M000049.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomHash.src/M000050.html +26 -0
- data/data/rushcheck/rdoc/classes/RandomHash.src/M000051.html +22 -0
- data/data/rushcheck/rdoc/classes/RandomProc.html +20 -20
- data/data/rushcheck/rdoc/classes/RandomProc.src/M000060.html +18 -0
- data/data/rushcheck/rdoc/classes/RandomProc.src/M000061.html +30 -0
- data/data/rushcheck/rdoc/classes/RandomProc.src/M000062.html +26 -0
- data/data/rushcheck/rdoc/classes/RandomProc.src/M000063.html +20 -0
- data/data/rushcheck/rdoc/classes/Result.html +19 -19
- data/data/rushcheck/rdoc/classes/Result.src/M000056.html +18 -0
- data/data/rushcheck/rdoc/classes/Result.src/M000057.html +18 -0
- data/data/rushcheck/rdoc/classes/Result.src/M000058.html +18 -0
- data/data/rushcheck/rdoc/classes/RushCheckConfig.html +41 -11
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000001.html +1 -1
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000002.html +1 -1
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000003.html +8 -4
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000004.html +4 -24
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000005.html +22 -39
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000006.html +55 -0
- data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000007.html +50 -0
- data/data/rushcheck/rdoc/classes/SpecialString.html +5 -5
- data/data/rushcheck/rdoc/classes/SpecialString.src/M000021.html +37 -0
- data/data/rushcheck/rdoc/classes/StdGen.html +27 -27
- data/data/rushcheck/rdoc/classes/StdGen.src/M000014.html +9 -4
- data/data/rushcheck/rdoc/classes/StdGen.src/M000015.html +21 -0
- data/data/rushcheck/rdoc/classes/StdGen.src/M000016.html +21 -0
- data/data/rushcheck/rdoc/classes/StdGen.src/M000017.html +18 -0
- data/data/rushcheck/rdoc/classes/StdGen.src/M000018.html +18 -0
- data/data/rushcheck/rdoc/classes/String.html +20 -20
- data/data/rushcheck/rdoc/classes/String.src/M000073.html +24 -0
- data/data/rushcheck/rdoc/classes/String.src/M000074.html +18 -0
- data/data/rushcheck/rdoc/classes/String.src/M000075.html +25 -0
- data/data/rushcheck/rdoc/classes/String.src/M000076.html +22 -0
- data/data/rushcheck/rdoc/classes/TestExausted.html +113 -0
- data/data/rushcheck/rdoc/classes/TestFailed.html +155 -0
- data/data/rushcheck/rdoc/classes/TestFailed.src/M000067.html +18 -0
- data/data/rushcheck/rdoc/classes/TestOk.html +113 -0
- data/data/rushcheck/rdoc/classes/TestOptions.html +180 -0
- data/data/rushcheck/rdoc/classes/TestOptions.src/M000008.html +18 -0
- data/data/rushcheck/rdoc/classes/TestOptions.src/M000009.html +18 -0
- data/data/rushcheck/rdoc/classes/TestResult.html +164 -0
- data/data/rushcheck/rdoc/classes/TestResult.src/M000068.html +18 -0
- data/data/rushcheck/rdoc/classes/Testable.html +96 -51
- data/data/rushcheck/rdoc/classes/Testable.src/M000091.html +4 -4
- data/data/rushcheck/rdoc/classes/Testable.src/M000092.html +4 -4
- data/data/rushcheck/rdoc/classes/Testable.src/M000095.html +4 -4
- data/data/rushcheck/rdoc/classes/Testable.src/M000096.html +18 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000097.html +18 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000099.html +19 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000100.html +21 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000101.html +18 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000103.html +18 -0
- data/data/rushcheck/rdoc/classes/Testable.src/M000104.html +18 -0
- data/data/rushcheck/rdoc/classes/TheStdGen.html +20 -20
- data/data/rushcheck/rdoc/classes/TheStdGen.src/M000069.html +18 -0
- data/data/rushcheck/rdoc/classes/TheStdGen.src/M000070.html +20 -0
- data/data/rushcheck/rdoc/classes/TheStdGen.src/M000071.html +21 -0
- data/data/rushcheck/rdoc/classes/TheStdGen.src/M000072.html +18 -0
- data/data/rushcheck/rdoc/classes/TrueClass.html +15 -15
- data/data/rushcheck/rdoc/classes/TrueClass.src/M000079.html +18 -0
- data/data/rushcheck/rdoc/classes/TrueClass.src/M000080.html +18 -0
- data/data/rushcheck/rdoc/classes/TrueClass.src/M000081.html +18 -0
- data/data/rushcheck/rdoc/created.rid +1 -1
- data/data/rushcheck/rdoc/files/rushcheck/config_rb.html +8 -1
- data/data/rushcheck/rdoc/files/rushcheck/testable_rb.html +3 -1
- data/data/rushcheck/rdoc/files/rushcheck/testoptions_rb.html +109 -0
- data/data/rushcheck/rdoc/files/rushcheck/testresult_rb.html +105 -0
- data/data/rushcheck/rdoc/files/rushcheck_rb.html +127 -0
- data/data/rushcheck/rdoc/fr_class_index.html +5 -0
- data/data/rushcheck/rdoc/fr_file_index.html +3 -1
- data/data/rushcheck/rdoc/fr_method_index.html +103 -94
- data/lib/rushcheck/arbitrary.rb +16 -12
- data/lib/rushcheck/array.rb +7 -6
- data/lib/rushcheck/assertion.rb +53 -50
- data/lib/rushcheck/bool.rb +26 -24
- data/lib/rushcheck/config.rb +131 -81
- data/lib/rushcheck/float.rb +4 -4
- data/lib/rushcheck/gen.rb +194 -182
- data/lib/rushcheck/guard.rb +9 -10
- data/lib/rushcheck/hash.rb +4 -3
- data/lib/rushcheck/integer.rb +11 -6
- data/lib/rushcheck/proc.rb +7 -7
- data/lib/rushcheck/property.rb +19 -15
- data/lib/rushcheck/random.rb +162 -159
- data/lib/rushcheck/result.rb +16 -12
- data/lib/rushcheck/string.rb +12 -12
- data/lib/rushcheck/testable.rb +99 -25
- data/lib/rushcheck/testoptions.rb +20 -0
- data/lib/rushcheck/testresult.rb +25 -0
- data/lib/{rushcheck/rushcheck.rb → rushcheck.rb} +2 -1
- metadata +93 -4
- data/data/rushcheck/doc/rushcheck.txt +0 -670
data/lib/rushcheck/gen.rb
CHANGED
|
@@ -4,223 +4,235 @@
|
|
|
4
4
|
# Therefore check also the Haskell implementation.
|
|
5
5
|
|
|
6
6
|
require 'rushcheck/gen'
|
|
7
|
+
require 'rushcheck/integer'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
class Gen
|
|
9
|
+
module RushCheck
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
# Gen provides functions for generating test instances.
|
|
12
|
+
class Gen
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
# choose returns a Gen object which generates a random value in the
|
|
15
|
-
# bound. It may useful to implement arbitrary method into your class.
|
|
16
|
-
def self.choose(lo=nil, hi=nil)
|
|
17
|
-
rand.fmap {|x| lo.class.random(x, lo, hi)[0] }
|
|
18
|
-
end
|
|
14
|
+
@@max_create = 10000
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
# choose is one of primitive generators to create a random Gen object.
|
|
17
|
+
# choose returns a Gen object which generates a random value in the
|
|
18
|
+
# bound. It may useful to implement arbitrary method into your class.
|
|
19
|
+
def self.choose(lo=nil, hi=nil)
|
|
20
|
+
rand.fmap {|x| lo.class.random(x, lo, hi)[0] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# create_gen is one of primitive generators to create a random Gen object.
|
|
24
|
+
# create_gen takes an array of Gen objects, and any block to generate object.
|
|
25
|
+
# Then create_gen returns a Gen object. It may useful to implement
|
|
26
|
+
# arbitrary method into your class.
|
|
27
|
+
def self.create_by_gen(xs, &f)
|
|
28
|
+
raise ArgumentError unless f.arity == xs.length
|
|
29
|
+
self.new do |n, r|
|
|
30
|
+
r2 = r
|
|
31
|
+
|
|
32
|
+
try = 0
|
|
33
|
+
begin
|
|
34
|
+
if try > @@max_create
|
|
35
|
+
raise(RuntimeError, "Failed to guards too many in the assertion.")
|
|
36
|
+
end
|
|
37
|
+
args = xs.map do |gen|
|
|
38
|
+
r1, r2 = r2.split
|
|
39
|
+
gen.value(n, r1)
|
|
40
|
+
end
|
|
41
|
+
f.call(*args)
|
|
42
|
+
rescue Exception => ex
|
|
43
|
+
case ex
|
|
44
|
+
when RushCheck::GuardException
|
|
45
|
+
try += 1
|
|
46
|
+
retry
|
|
47
|
+
else
|
|
48
|
+
raise(ex, ex.to_s)
|
|
49
|
+
end
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
|
-
end
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
# create is one of primitive generators to create a random Gen object.
|
|
55
|
+
# create takes an array of classes, and any block to generate object.
|
|
56
|
+
# Then create returns a Gen object. It may useful to implement
|
|
57
|
+
# arbitrary method into your class.
|
|
58
|
+
def self.create(cs, &f)
|
|
59
|
+
self.create_by_gen(cs.map {|c| c.arbitrary}) { yield f }
|
|
60
|
+
end
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
# elements is one of primitive generators to create a random Gen
|
|
63
|
+
# object. elements requires an array and returns a Gen object which
|
|
64
|
+
# generates an object in the array randomly. It may useful to
|
|
65
|
+
# implement arbitrary method into your class.
|
|
66
|
+
def self.elements(xs)
|
|
67
|
+
raise(RuntimeError, "given argument is empty") if xs.empty?
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
xs.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
choose(0, xs.length - 1).fmap {|i| xs[i] }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# frequency is one of primitive generators to create a random Gen
|
|
73
|
+
# object. frequency requires an array of pairs and returns a Gen
|
|
74
|
+
# object. The first component of pair should be a positive Integer
|
|
75
|
+
# and the second one should be a Gen object. The integer acts as a
|
|
76
|
+
# weight for choosing random Gen object in the array. For example,
|
|
77
|
+
# frequency([[1, Gen.rand], [2, Integer.arbitrary]]) returns the
|
|
78
|
+
# random generator Gen.rand in 33%, while another random generator
|
|
79
|
+
# of Integer (Integer.arbitrary) in 67%.
|
|
80
|
+
def self.frequency(xs)
|
|
81
|
+
tot = xs.inject(0) {|r, pair| r + pair[0]}
|
|
82
|
+
raise(RuntimeError, "Illegal frequency:#{xs.inspect}") if tot == 0
|
|
83
|
+
choose(0, tot - 1).bind do |n|
|
|
84
|
+
m = n
|
|
85
|
+
xs.each do |pair|
|
|
86
|
+
if m <= pair[0]
|
|
87
|
+
then break pair[1]
|
|
88
|
+
else m -= pair[0]
|
|
89
|
+
end
|
|
80
90
|
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
84
93
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
# lift_array is one of primitive generators to create a randam Gen
|
|
95
|
+
# object. lift_array takes an array and a block which has a
|
|
96
|
+
# variable. The block should return a Gen object. lift_array returns
|
|
97
|
+
# a Gen object which generates an array of the result of given block
|
|
98
|
+
# for applying each member of given array.
|
|
99
|
+
def self.lift_array(xs)
|
|
100
|
+
self.new do |n, r|
|
|
101
|
+
r2 = r
|
|
102
|
+
xs.map do |c|
|
|
103
|
+
r1, r2 = r2.split
|
|
104
|
+
yield.value(n, r1)
|
|
105
|
+
end
|
|
96
106
|
end
|
|
97
107
|
end
|
|
98
|
-
end
|
|
99
108
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
# oneof is /one of/ primitive generators to create a random Gen object.
|
|
110
|
+
# oneof requires an array of Gen objects, and returns a Gen object
|
|
111
|
+
# which choose a Gen object in the array randomly.
|
|
112
|
+
# It may useful to implement arbitrary method into your class.
|
|
113
|
+
def self.oneof(gens)
|
|
114
|
+
elements(gens).bind {|x| x}
|
|
115
|
+
end
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
# promote is the function to create a Gen object which generates a
|
|
118
|
+
# procedure (Proc). promote requires a block which takes one
|
|
119
|
+
# variable and the block should be return a Gen object.
|
|
120
|
+
# promote returns a Gen object which generate a new procedure
|
|
121
|
+
# with the given block.
|
|
122
|
+
# It may useful to implement coarbitrary method into your class.
|
|
123
|
+
def self.promote
|
|
124
|
+
new {|n, r| Proc.new {|a| yield(a).value(n, r) } }
|
|
125
|
+
end
|
|
117
126
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
# rand returns a Gen object which generates a random number
|
|
128
|
+
# generator.
|
|
129
|
+
def self.rand
|
|
130
|
+
new {|n, r| r}
|
|
131
|
+
end
|
|
123
132
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
133
|
+
# sized is a combinator which the programmer can use to access the
|
|
134
|
+
# size bound. It requires a block which takes a variable as an
|
|
135
|
+
# integer for size. The block should be a function which changes the
|
|
136
|
+
# size of random instances.
|
|
137
|
+
def self.sized
|
|
138
|
+
new {|n, r| yield(n).value(n, r) }
|
|
139
|
+
end
|
|
131
140
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
# unit is a monadic function which equals the return function in
|
|
142
|
+
# the Haskell's monad. It requires one variable and returns a Gen
|
|
143
|
+
# object which generates the given object.
|
|
144
|
+
def self.unit(x)
|
|
145
|
+
new {|n, r| x}
|
|
146
|
+
end
|
|
138
147
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
# vector is one of primitive generators to create a Gen object.
|
|
149
|
+
# vector takes two variables, while the first one should be class,
|
|
150
|
+
# and the second one should be length. vector returns a Gen object
|
|
151
|
+
# which generates an array whose components belongs the given class
|
|
152
|
+
# and given length.
|
|
153
|
+
def self.vector(c, len)
|
|
154
|
+
new do |n, r|
|
|
155
|
+
r2 = r
|
|
156
|
+
(1..len).map do
|
|
157
|
+
r1, r2 = r2.split
|
|
158
|
+
c.arbitrary.value(n, r1)
|
|
159
|
+
end
|
|
150
160
|
end
|
|
151
161
|
end
|
|
152
|
-
end
|
|
153
162
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
# to initialize Gen object, it requires a block which takes two
|
|
164
|
+
# variables. The first argument of block is assumed as an integer,
|
|
165
|
+
# and the second one is assumed as a random generator of RandomGen.
|
|
166
|
+
def initialize(&f)
|
|
167
|
+
@proc = f
|
|
168
|
+
end
|
|
160
169
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
170
|
+
# bind is a monadic function such as Haskel's (>>=).
|
|
171
|
+
# bind takes a block which has two variables where the first one
|
|
172
|
+
# is assumed as an integer, and the second one is assumed as a
|
|
173
|
+
# random generator of RandomGen.
|
|
174
|
+
def bind
|
|
175
|
+
self.class.new do |n, r|
|
|
176
|
+
r1, r2 = r.split
|
|
177
|
+
yield(value(n, r1)).value(n, r2)
|
|
178
|
+
end
|
|
169
179
|
end
|
|
170
|
-
end
|
|
171
180
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
# value is a method to get the value of the internal procedure.
|
|
182
|
+
# value takes two variables where the first argument is assumed as
|
|
183
|
+
# an integer and the second one is assumed as a random generator of
|
|
184
|
+
# RandomGen.
|
|
185
|
+
def value(n, g)
|
|
186
|
+
@proc.call(n, g)
|
|
187
|
+
end
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
189
|
+
# fmap is a categorical function as same in Haskell.
|
|
190
|
+
# fmap requires a block which takes one variable.
|
|
191
|
+
def fmap
|
|
192
|
+
bind {|x| self.class.unit(yield(x)) }
|
|
193
|
+
end
|
|
185
194
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
# forall is a function to create a Gen object.
|
|
196
|
+
# forall requires a block which takes any variables
|
|
197
|
+
# and returns a Property object. Then forall returns
|
|
198
|
+
# a generator of the property.
|
|
199
|
+
def forall
|
|
200
|
+
bind do |*a|
|
|
201
|
+
yield(*a).property.bind do |res|
|
|
202
|
+
res.arguments.push(a.to_s)
|
|
203
|
+
self.class.unit(res)
|
|
204
|
+
end
|
|
195
205
|
end
|
|
196
206
|
end
|
|
197
|
-
end
|
|
198
207
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
# generate returns the random instance. generates takes two
|
|
209
|
+
# variables, where the first one should be an integer and the second
|
|
210
|
+
# should be the random number generator such as StdGen.
|
|
211
|
+
def generate(n, rnd)
|
|
212
|
+
s, r = Integer.random(rnd, 0, n)
|
|
213
|
+
value(s, r)
|
|
214
|
+
end
|
|
206
215
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
# resize returns another Gen object which resized by the given
|
|
217
|
+
# paramater. resize takes one variable in Integer.
|
|
218
|
+
def resize(n)
|
|
219
|
+
self.class.new {|x, r| value(n, r) }
|
|
220
|
+
end
|
|
212
221
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
222
|
+
# variant constructs a generator which transforms the random number
|
|
223
|
+
# seed. variant takes one variable which should be an
|
|
224
|
+
# Integer. variant is needed to generate rundom functions.
|
|
225
|
+
def variant(v)
|
|
226
|
+
self.class.new do |n, r|
|
|
227
|
+
g = (1..v).inject(r) do |gen, i|
|
|
228
|
+
gen, dummy = gen.split
|
|
229
|
+
gen
|
|
230
|
+
end
|
|
231
|
+
value(n, g)
|
|
221
232
|
end
|
|
222
|
-
value(n, g)
|
|
223
233
|
end
|
|
234
|
+
|
|
224
235
|
end
|
|
225
236
|
|
|
226
237
|
end
|
|
238
|
+
|
data/lib/rushcheck/guard.rb
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# = guard.rb
|
|
2
|
-
# This provides
|
|
2
|
+
# This provides module functions guard and its friends
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
module RushCheck
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
class GuardException < StandardError; end
|
|
7
|
+
|
|
8
|
+
def guard
|
|
9
|
+
raise RushCheck::GuardException unless yield
|
|
10
|
+
end
|
|
9
11
|
|
|
10
12
|
def guard_raise(c)
|
|
11
13
|
begin
|
|
@@ -13,15 +15,12 @@ class Guard
|
|
|
13
15
|
rescue Exception => ex
|
|
14
16
|
case ex
|
|
15
17
|
when c
|
|
16
|
-
raise
|
|
18
|
+
raise RushCheck::GuardException
|
|
17
19
|
else
|
|
18
20
|
raise ex
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
|
-
|
|
23
|
-
def guard
|
|
24
|
-
raise RushCheckGuard unless yield
|
|
25
|
-
end
|
|
24
|
+
module_function :guard, :guard_raise
|
|
26
25
|
|
|
27
26
|
end
|
data/lib/rushcheck/hash.rb
CHANGED
|
@@ -9,8 +9,8 @@ require 'rushcheck/testable'
|
|
|
9
9
|
# defined random generator of Hash.
|
|
10
10
|
class RandomHash < Hash
|
|
11
11
|
|
|
12
|
-
extend Arbitrary
|
|
13
|
-
include Coarbitrary
|
|
12
|
+
extend RushCheck::Arbitrary
|
|
13
|
+
include RushCheck::Coarbitrary
|
|
14
14
|
|
|
15
15
|
# class method set_pattern takes a hash object of
|
|
16
16
|
# random pattern. For example, the following pattern
|
|
@@ -20,10 +20,11 @@ class RandomHash < Hash
|
|
|
20
20
|
# has indicated random object as its values.
|
|
21
21
|
def self.set_pattern(pat)
|
|
22
22
|
@@pat = pat
|
|
23
|
+
self
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def self.arbitrary
|
|
26
|
-
Gen.new do |n, r|
|
|
27
|
+
RushCheck::Gen.new do |n, r|
|
|
27
28
|
h = {}
|
|
28
29
|
r2 = r
|
|
29
30
|
@@pat.keys.each do |k|
|
data/lib/rushcheck/integer.rb
CHANGED
|
@@ -9,9 +9,10 @@ require 'rushcheck/random'
|
|
|
9
9
|
# ruby's Integer class is extended to use RushCheck library.
|
|
10
10
|
# See also HsRandom, Arbitrary and Coarbitrary.
|
|
11
11
|
class Integer
|
|
12
|
-
extend HsRandom
|
|
13
|
-
extend Arbitrary
|
|
14
|
-
|
|
12
|
+
extend RushCheck::HsRandom
|
|
13
|
+
extend RushCheck::Arbitrary
|
|
14
|
+
|
|
15
|
+
include RushCheck::Coarbitrary
|
|
15
16
|
|
|
16
17
|
@@max_bound = 2**30 - 1
|
|
17
18
|
@@min_bound = -(2**30)
|
|
@@ -23,15 +24,19 @@ class Integer
|
|
|
23
24
|
|
|
24
25
|
# this method is needed to use Arbitrary.
|
|
25
26
|
def self.arbitrary
|
|
26
|
-
Gen.sized {|n| Gen.choose(-n, n) }
|
|
27
|
+
RushCheck::Gen.sized {|n| RushCheck::Gen.choose(-n, n) }
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
# this method is needed to include HsRandom.
|
|
30
31
|
def self.random_range(gen, lo=@@min_bound, hi=@@max_bound)
|
|
31
|
-
|
|
32
|
+
hi, lo = lo, hi if hi < lo
|
|
32
33
|
v, g = gen.gen_next
|
|
34
|
+
d = hi - lo + 1
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
if d == 1
|
|
37
|
+
then [lo, g]
|
|
38
|
+
else [(v % d) + lo, g]
|
|
39
|
+
end
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
# this method is needed to use Coarbitrary.
|
data/lib/rushcheck/proc.rb
CHANGED
|
@@ -8,16 +8,16 @@ require 'rushcheck/testable'
|
|
|
8
8
|
|
|
9
9
|
class RandomProc < Proc
|
|
10
10
|
|
|
11
|
-
extend Arbitrary
|
|
12
|
-
include Coarbitrary
|
|
13
|
-
include Testable
|
|
11
|
+
extend RushCheck::Arbitrary
|
|
12
|
+
include RushCheck::Coarbitrary
|
|
13
|
+
include RushCheck::Testable
|
|
14
14
|
|
|
15
15
|
def self.set_pattern(inputs, outputs)
|
|
16
16
|
@@inputs, @@outputs = inputs, outputs
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def self.arbitrary
|
|
20
|
-
Gen.new do |n, r|
|
|
20
|
+
RushCheck::Gen.new do |n, r|
|
|
21
21
|
Proc.new do |*args|
|
|
22
22
|
gens = if args.empty?
|
|
23
23
|
then @@outputs.map {|c| c.arbitrary }
|
|
@@ -27,13 +27,13 @@ class RandomProc < Proc
|
|
|
27
27
|
end
|
|
28
28
|
end.flatten
|
|
29
29
|
end
|
|
30
|
-
Gen.oneof(gens).value(n, r)
|
|
30
|
+
RushCheck::Gen.oneof(gens).value(n, r)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def coarbitrary(g)
|
|
36
|
-
Gen.new do |n, r|
|
|
36
|
+
RushCheck::Gen.new do |n, r|
|
|
37
37
|
r2 = r
|
|
38
38
|
args = @@inputs.map do |c|
|
|
39
39
|
r1, r2 = r2.split
|
|
@@ -45,7 +45,7 @@ class RandomProc < Proc
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def property
|
|
48
|
-
Gen.lift_array(@@inputs) {|c| c.arbitrary }.forall do |*args|
|
|
48
|
+
RushCheck::Gen.lift_array(@@inputs) {|c| c.arbitrary }.forall do |*args|
|
|
49
49
|
call(*args)
|
|
50
50
|
end
|
|
51
51
|
end
|
data/lib/rushcheck/property.rb
CHANGED
|
@@ -5,25 +5,29 @@ require 'rushcheck/gen'
|
|
|
5
5
|
require 'rushcheck/result'
|
|
6
6
|
require 'rushcheck/testable'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
module RushCheck
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
class Property
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
include RushCheck::Testable
|
|
13
|
+
|
|
14
|
+
attr_reader :gen
|
|
15
|
+
def initialize(obj=nil, stamp=[], arguments=[])
|
|
16
|
+
case obj
|
|
17
|
+
when nil, true, false
|
|
18
|
+
result = RushCheck::Result.new(obj, stamp, arguments)
|
|
19
|
+
@gen = RushCheck::Gen.unit(result)
|
|
20
|
+
when Gen
|
|
21
|
+
@gen = obj
|
|
22
|
+
else
|
|
23
|
+
raise(RuntimeError, "illegal arguments")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def property
|
|
28
|
+
self
|
|
22
29
|
end
|
|
23
|
-
end
|
|
24
30
|
|
|
25
|
-
def property
|
|
26
|
-
self
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
end
|