rushcheck 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. data/COPYING +515 -0
  2. data/INSTALL +14 -0
  3. data/LICENSE +5 -0
  4. data/README +49 -0
  5. data/Rakefile +39 -0
  6. data/copying.txt +23 -0
  7. data/data/rushcheck/doc/policy.txt +520 -0
  8. data/data/rushcheck/doc/rushcheck.txt +612 -0
  9. data/data/rushcheck/examples/printf.rb +22 -0
  10. data/data/rushcheck/examples/proc.rb +33 -0
  11. data/data/rushcheck/examples/roguetile.rb +153 -0
  12. data/data/rushcheck/examples/sample.rb +52 -0
  13. data/data/rushcheck/rdoc/classes/Arbitrary.html +148 -0
  14. data/data/rushcheck/rdoc/classes/Arbitrary.src/M000075.html +18 -0
  15. data/data/rushcheck/rdoc/classes/Assertion.html +183 -0
  16. data/data/rushcheck/rdoc/classes/Assertion.src/M000015.html +20 -0
  17. data/data/rushcheck/rdoc/classes/Assertion.src/M000016.html +45 -0
  18. data/data/rushcheck/rdoc/classes/Coarbitrary.html +135 -0
  19. data/data/rushcheck/rdoc/classes/Coarbitrary.src/M000095.html +18 -0
  20. data/data/rushcheck/rdoc/classes/FalseClass.html +177 -0
  21. data/data/rushcheck/rdoc/classes/FalseClass.src/M000018.html +18 -0
  22. data/data/rushcheck/rdoc/classes/FalseClass.src/M000019.html +18 -0
  23. data/data/rushcheck/rdoc/classes/FalseClass.src/M000020.html +18 -0
  24. data/data/rushcheck/rdoc/classes/Float.html +191 -0
  25. data/data/rushcheck/rdoc/classes/Float.src/M000047.html +21 -0
  26. data/data/rushcheck/rdoc/classes/Float.src/M000048.html +18 -0
  27. data/data/rushcheck/rdoc/classes/Float.src/M000049.html +22 -0
  28. data/data/rushcheck/rdoc/classes/Float.src/M000050.html +20 -0
  29. data/data/rushcheck/rdoc/classes/Gen.html +515 -0
  30. data/data/rushcheck/rdoc/classes/Gen.src/M000026.html +18 -0
  31. data/data/rushcheck/rdoc/classes/Gen.src/M000027.html +20 -0
  32. data/data/rushcheck/rdoc/classes/Gen.src/M000028.html +28 -0
  33. data/data/rushcheck/rdoc/classes/Gen.src/M000029.html +24 -0
  34. data/data/rushcheck/rdoc/classes/Gen.src/M000030.html +18 -0
  35. data/data/rushcheck/rdoc/classes/Gen.src/M000031.html +18 -0
  36. data/data/rushcheck/rdoc/classes/Gen.src/M000032.html +18 -0
  37. data/data/rushcheck/rdoc/classes/Gen.src/M000033.html +18 -0
  38. data/data/rushcheck/rdoc/classes/Gen.src/M000034.html +18 -0
  39. data/data/rushcheck/rdoc/classes/Gen.src/M000035.html +24 -0
  40. data/data/rushcheck/rdoc/classes/Gen.src/M000036.html +18 -0
  41. data/data/rushcheck/rdoc/classes/Gen.src/M000037.html +21 -0
  42. data/data/rushcheck/rdoc/classes/Gen.src/M000038.html +18 -0
  43. data/data/rushcheck/rdoc/classes/Gen.src/M000039.html +18 -0
  44. data/data/rushcheck/rdoc/classes/Gen.src/M000040.html +23 -0
  45. data/data/rushcheck/rdoc/classes/Gen.src/M000041.html +19 -0
  46. data/data/rushcheck/rdoc/classes/Gen.src/M000042.html +18 -0
  47. data/data/rushcheck/rdoc/classes/Gen.src/M000043.html +24 -0
  48. data/data/rushcheck/rdoc/classes/Guard.html +159 -0
  49. data/data/rushcheck/rdoc/classes/Guard.src/M000024.html +27 -0
  50. data/data/rushcheck/rdoc/classes/Guard.src/M000025.html +18 -0
  51. data/data/rushcheck/rdoc/classes/HsRandom.html +201 -0
  52. data/data/rushcheck/rdoc/classes/HsRandom.src/M000081.html +22 -0
  53. data/data/rushcheck/rdoc/classes/HsRandom.src/M000082.html +32 -0
  54. data/data/rushcheck/rdoc/classes/HsRandom.src/M000083.html +18 -0
  55. data/data/rushcheck/rdoc/classes/Integer.html +212 -0
  56. data/data/rushcheck/rdoc/classes/Integer.src/M000006.html +18 -0
  57. data/data/rushcheck/rdoc/classes/Integer.src/M000007.html +18 -0
  58. data/data/rushcheck/rdoc/classes/Integer.src/M000008.html +21 -0
  59. data/data/rushcheck/rdoc/classes/Integer.src/M000009.html +19 -0
  60. data/data/rushcheck/rdoc/classes/NilClass.html +177 -0
  61. data/data/rushcheck/rdoc/classes/NilClass.src/M000059.html +18 -0
  62. data/data/rushcheck/rdoc/classes/NilClass.src/M000060.html +18 -0
  63. data/data/rushcheck/rdoc/classes/NilClass.src/M000061.html +18 -0
  64. data/data/rushcheck/rdoc/classes/Property.html +174 -0
  65. data/data/rushcheck/rdoc/classes/Property.src/M000070.html +26 -0
  66. data/data/rushcheck/rdoc/classes/Property.src/M000071.html +18 -0
  67. data/data/rushcheck/rdoc/classes/RandomArray.html +184 -0
  68. data/data/rushcheck/rdoc/classes/RandomArray.src/M000021.html +18 -0
  69. data/data/rushcheck/rdoc/classes/RandomArray.src/M000022.html +35 -0
  70. data/data/rushcheck/rdoc/classes/RandomArray.src/M000023.html +22 -0
  71. data/data/rushcheck/rdoc/classes/RandomBool.html +146 -0
  72. data/data/rushcheck/rdoc/classes/RandomBool.src/M000079.html +18 -0
  73. data/data/rushcheck/rdoc/classes/RandomBool.src/M000080.html +19 -0
  74. data/data/rushcheck/rdoc/classes/RandomGen.html +196 -0
  75. data/data/rushcheck/rdoc/classes/RandomGen.src/M000076.html +18 -0
  76. data/data/rushcheck/rdoc/classes/RandomGen.src/M000077.html +18 -0
  77. data/data/rushcheck/rdoc/classes/RandomGen.src/M000078.html +18 -0
  78. data/data/rushcheck/rdoc/classes/RandomHash.html +197 -0
  79. data/data/rushcheck/rdoc/classes/RandomHash.src/M000044.html +18 -0
  80. data/data/rushcheck/rdoc/classes/RandomHash.src/M000045.html +26 -0
  81. data/data/rushcheck/rdoc/classes/RandomHash.src/M000046.html +22 -0
  82. data/data/rushcheck/rdoc/classes/RandomProc.html +192 -0
  83. data/data/rushcheck/rdoc/classes/RandomProc.src/M000055.html +18 -0
  84. data/data/rushcheck/rdoc/classes/RandomProc.src/M000056.html +30 -0
  85. data/data/rushcheck/rdoc/classes/RandomProc.src/M000057.html +26 -0
  86. data/data/rushcheck/rdoc/classes/RandomProc.src/M000058.html +20 -0
  87. data/data/rushcheck/rdoc/classes/Result.html +214 -0
  88. data/data/rushcheck/rdoc/classes/Result.src/M000051.html +18 -0
  89. data/data/rushcheck/rdoc/classes/Result.src/M000052.html +18 -0
  90. data/data/rushcheck/rdoc/classes/Result.src/M000053.html +18 -0
  91. data/data/rushcheck/rdoc/classes/RushCheckConfig.html +240 -0
  92. data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000001.html +23 -0
  93. data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000002.html +22 -0
  94. data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000003.html +18 -0
  95. data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000004.html +38 -0
  96. data/data/rushcheck/rdoc/classes/RushCheckConfig.src/M000005.html +55 -0
  97. data/data/rushcheck/rdoc/classes/RushCheckGuard.html +118 -0
  98. data/data/rushcheck/rdoc/classes/SpecialString.html +151 -0
  99. data/data/rushcheck/rdoc/classes/SpecialString.src/M000017.html +37 -0
  100. data/data/rushcheck/rdoc/classes/StdGen.html +252 -0
  101. data/data/rushcheck/rdoc/classes/StdGen.src/M000010.html +23 -0
  102. data/data/rushcheck/rdoc/classes/StdGen.src/M000011.html +21 -0
  103. data/data/rushcheck/rdoc/classes/StdGen.src/M000012.html +21 -0
  104. data/data/rushcheck/rdoc/classes/StdGen.src/M000013.html +18 -0
  105. data/data/rushcheck/rdoc/classes/StdGen.src/M000014.html +18 -0
  106. data/data/rushcheck/rdoc/classes/String.html +191 -0
  107. data/data/rushcheck/rdoc/classes/String.src/M000066.html +24 -0
  108. data/data/rushcheck/rdoc/classes/String.src/M000067.html +18 -0
  109. data/data/rushcheck/rdoc/classes/String.src/M000068.html +25 -0
  110. data/data/rushcheck/rdoc/classes/String.src/M000069.html +22 -0
  111. data/data/rushcheck/rdoc/classes/Testable.html +281 -0
  112. data/data/rushcheck/rdoc/classes/Testable.src/M000084.html +18 -0
  113. data/data/rushcheck/rdoc/classes/Testable.src/M000085.html +18 -0
  114. data/data/rushcheck/rdoc/classes/Testable.src/M000088.html +18 -0
  115. data/data/rushcheck/rdoc/classes/Testable.src/M000089.html +18 -0
  116. data/data/rushcheck/rdoc/classes/Testable.src/M000090.html +18 -0
  117. data/data/rushcheck/rdoc/classes/Testable.src/M000092.html +18 -0
  118. data/data/rushcheck/rdoc/classes/Testable.src/M000094.html +18 -0
  119. data/data/rushcheck/rdoc/classes/TheStdGen.html +200 -0
  120. data/data/rushcheck/rdoc/classes/TheStdGen.src/M000062.html +18 -0
  121. data/data/rushcheck/rdoc/classes/TheStdGen.src/M000063.html +20 -0
  122. data/data/rushcheck/rdoc/classes/TheStdGen.src/M000064.html +21 -0
  123. data/data/rushcheck/rdoc/classes/TheStdGen.src/M000065.html +18 -0
  124. data/data/rushcheck/rdoc/classes/TrueClass.html +177 -0
  125. data/data/rushcheck/rdoc/classes/TrueClass.src/M000072.html +18 -0
  126. data/data/rushcheck/rdoc/classes/TrueClass.src/M000073.html +18 -0
  127. data/data/rushcheck/rdoc/classes/TrueClass.src/M000074.html +18 -0
  128. data/data/rushcheck/rdoc/created.rid +1 -0
  129. data/data/rushcheck/rdoc/files/rushcheck/arbitrary_rb.html +114 -0
  130. data/data/rushcheck/rdoc/files/rushcheck/array_rb.html +117 -0
  131. data/data/rushcheck/rdoc/files/rushcheck/assertion_rb.html +120 -0
  132. data/data/rushcheck/rdoc/files/rushcheck/bool_rb.html +120 -0
  133. data/data/rushcheck/rdoc/files/rushcheck/config_rb.html +109 -0
  134. data/data/rushcheck/rdoc/files/rushcheck/float_rb.html +118 -0
  135. data/data/rushcheck/rdoc/files/rushcheck/gen_rb.html +111 -0
  136. data/data/rushcheck/rdoc/files/rushcheck/guard_rb.html +108 -0
  137. data/data/rushcheck/rdoc/files/rushcheck/hash_rb.html +117 -0
  138. data/data/rushcheck/rdoc/files/rushcheck/integer_rb.html +118 -0
  139. data/data/rushcheck/rdoc/files/rushcheck/proc_rb.html +118 -0
  140. data/data/rushcheck/rdoc/files/rushcheck/property_rb.html +119 -0
  141. data/data/rushcheck/rdoc/files/rushcheck/random_rb.html +126 -0
  142. data/data/rushcheck/rdoc/files/rushcheck/result_rb.html +118 -0
  143. data/data/rushcheck/rdoc/files/rushcheck/rushcheck_rb.html +123 -0
  144. data/data/rushcheck/rdoc/files/rushcheck/string_rb.html +121 -0
  145. data/data/rushcheck/rdoc/files/rushcheck/testable_rb.html +117 -0
  146. data/data/rushcheck/rdoc/fr_class_index.html +51 -0
  147. data/data/rushcheck/rdoc/fr_file_index.html +43 -0
  148. data/data/rushcheck/rdoc/fr_method_index.html +121 -0
  149. data/data/rushcheck/rdoc/index.html +24 -0
  150. data/data/rushcheck/rdoc/rdoc-style.css +208 -0
  151. data/lib/rushcheck/arbitrary.rb +28 -0
  152. data/lib/rushcheck/array.rb +49 -0
  153. data/lib/rushcheck/assertion.rb +67 -0
  154. data/lib/rushcheck/bool.rb +90 -0
  155. data/lib/rushcheck/config.rb +98 -0
  156. data/lib/rushcheck/float.rb +43 -0
  157. data/lib/rushcheck/gen.rb +189 -0
  158. data/lib/rushcheck/guard.rb +27 -0
  159. data/lib/rushcheck/hash.rb +45 -0
  160. data/lib/rushcheck/integer.rb +43 -0
  161. data/lib/rushcheck/proc.rb +53 -0
  162. data/lib/rushcheck/property.rb +29 -0
  163. data/lib/rushcheck/random.rb +215 -0
  164. data/lib/rushcheck/result.rb +26 -0
  165. data/lib/rushcheck/rushcheck.rb +17 -0
  166. data/lib/rushcheck/string.rb +100 -0
  167. data/lib/rushcheck/testable.rb +41 -0
  168. metadata +238 -0
@@ -0,0 +1,520 @@
1
+ 2006-07-26 start Daisuke IKEGAMI <ikegami@madscientist.jp>
2
+ 2006-08-09 add
3
+
4
+ porting policy
5
+ --------------
6
+
7
+ In this document, I compare between the original Haskell
8
+ implementation in ghc and RushCheck.
9
+
10
+ 1. Haskell98 System.Random
11
+
12
+ 1.1 type, type classes and functions in System.Random
13
+
14
+ class RandomGen g where
15
+ next :: g -> (Int, g)
16
+ split :: g -> (g, g)
17
+ genRange :: g -> (Int, Int)
18
+
19
+ data StdGen = StdGen Int Int
20
+ instance RandomGen StdGen
21
+ instance Show StdGen
22
+ instance Read StdGen
23
+
24
+ mkStdGen :: Int -> StdGen
25
+
26
+ class Random a where
27
+ random :: RandomGen g => g -> (a, g)
28
+ randomR :: RandomGen g => (a, a) -> g -> (a, g)
29
+ randoms :: RandomGen g => g -> [a]
30
+ randomRs :: RandomGen g => (a, a) -> g -> [a]
31
+ randomIO :: IO a
32
+ randomRIO :: (a, a) -> IO a
33
+ instance Random Int
34
+ instance Random Char
35
+ instance Random Bool
36
+ instance Random Integer
37
+ instance Random Double
38
+ instance Random Float
39
+
40
+ getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
41
+ getStdGen :: IO StdGen
42
+ setStdGen :: StdGen -> IO ()
43
+ newStdGen :: IO StdGen
44
+
45
+ 1.2 porting policy for System.Random in Haskell to Ruby
46
+
47
+ Haskell ruby
48
+ System.Random ---> rushcheck/random.rb
49
+
50
+ Haskell ruby
51
+ class RandomGen ---> module RandomGen
52
+ for instance methods
53
+
54
+ 'method RandomGen' is assumed to be included for making instance
55
+ methods.
56
+
57
+ Haskell
58
+ next :: g -> (Int, g)
59
+ split :: g -> (g, g)
60
+ genRange :: g -> (Int, Int)
61
+ --->
62
+ Ruby
63
+ RandomGen#gen_next :: [Fixnum, SELF]
64
+ RandomGen#split :: [SELF, SELF]
65
+ RandomGen#gen_range :: [Fixnum, Int]
66
+
67
+ - because 'next' is a reserved word of ruby, change it to 'gen_next'.
68
+ - SELF is the class which includes the module RandomGen.
69
+ - Haskell's Int is similar to Ruby's Fixnum
70
+
71
+ Haskell
72
+ data StdGen = StdGen Int Int
73
+ instance RandomGen StdGen
74
+ instance Show StdGen
75
+ instance Read StdGen
76
+ mkStdGen :: Int -> StdGen
77
+ --->
78
+ Ruby
79
+ class StdGen
80
+ StdGen#initialize(left::Fixnum=nil, right::Fixnum = nil)
81
+ StdGen includes module RandomGen
82
+ StdGen#to_s
83
+
84
+ - read is not implemented yet (maybe unnecessary?)
85
+ - StdGen requires two integers in default, but we can also create
86
+ StdGen with only one integer by mkStdGen. Therefore,
87
+ StdGen#initialize takes one/two integers. In addition, we can make
88
+ StdGen without any integers but they are generated randomly.
89
+
90
+ Haskell
91
+ class Random a where
92
+ random :: RandomGen g => g -> (a, g)
93
+ randomR :: RandomGen g => (a, a) -> g -> (a, g)
94
+ randoms :: RandomGen g => g -> [a]
95
+ randomRs :: RandomGen g => (a, a) -> g -> [a]
96
+ randomIO :: IO a
97
+ randomRIO :: (a, a) -> IO a
98
+ --->
99
+ Ruby
100
+ module HsRandom
101
+ HsRandom#random
102
+ (gen::RandomGen, lo::HsRandom=nil, hi::HsRandom=nil)
103
+ :: [HsRandom, RandomGen]
104
+ HsRandom#random_array
105
+ (gen::RandomGen, len::Integer=nil,
106
+ lo::HsRandom=nil, hi::HsRandom=nil)
107
+ :: [HsRandom, RandomGen]
108
+ HsRandom#random_std(lo::HsRandom=nil, hi::HsRandom=nil)
109
+ private
110
+ HsRandom#random_range
111
+ (gen::RandomGen, lo::HsRandom=nil, hi::HsRandom=nil)
112
+ :: [HsRandom, RandomGen]
113
+
114
+ Haskell
115
+ instance Random Int
116
+ instance Random Integer
117
+ --->
118
+ Ruby
119
+ class Integer includes the module HsRandom
120
+ why not Fixnum and Bignum?
121
+
122
+ Haskell
123
+ instance Random Char
124
+ -->
125
+ Ruby
126
+ class String includes the module HsRandom
127
+
128
+ Haskell
129
+ instance Random Double
130
+ instance Random Float
131
+ -->
132
+ Ruby
133
+ class Float includes the module HsRandom
134
+
135
+ Haskell
136
+ instance Random Bool
137
+ -->
138
+ Ruby
139
+ nop
140
+ why not TrueClass and FalseClass?
141
+ but what is the randomness of TrueClass?
142
+
143
+ Haskell
144
+ getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
145
+ -->
146
+ Ruby
147
+ nop
148
+
149
+ Haskell
150
+ newStdGen :: IO StdGen
151
+ setStdGen :: StdGen -> IO ()
152
+ getStdGen :: IO StdGen
153
+ -->
154
+ Ruby
155
+ class TheStdGen (singleton class)
156
+
157
+ 2.1 Test.QuickCheck
158
+
159
+ quickCheck :: Testable a => a -> IO () -- :: prop -> IO ()
160
+ verboseCheck :: Testable a => a -> IO () -- :: prop -> IO ()
161
+ test :: Testable a => a -> IO () -- :: prop -> IO ()
162
+
163
+ Config(..) -- :: *
164
+ data Config = Config
165
+ { configMaxTest :: Int
166
+ , configMaxFail :: Int
167
+ , configSize :: Int -> Int
168
+ , configEvery :: Int -> [String] -> String
169
+ }
170
+ defaultConfig :: Config
171
+ check :: Testable a => Config -> a -> IO ()
172
+ -- :: Config -> prop -> IO ()
173
+
174
+ -- property combinators
175
+ forAll :: (Show a, Testable b) => Gen a -> (a -> b) ->
176
+ Property
177
+ -- :: Gen a -> (a -> prop) -> prop
178
+ (==>) :: Testable a => Bool -> a -> Property
179
+ -- :: Bool -> prop -> prop
180
+
181
+ -- gathering test-case information
182
+ label :: Testable a => String -> a -> Property
183
+ -- :: String -> prop -> prop
184
+ collect :: (Show a, Testable b) => a -> b -> Property
185
+ -- :: Show a => a -> prop -> prop
186
+ classify :: Testable a => Bool -> String -> a -> Property
187
+ -- :: Bool -> String -> prop -> prop
188
+ trivial :: Testable a => Bool -> a -> Property
189
+ -- :: Bool -> prop -> prop
190
+
191
+ -- generator combinators
192
+ Gen -- :: * -> * ; Functor, Monad
193
+ newtype Gen a
194
+ = Gen (Int -> StdGen -> a)
195
+
196
+ elements :: [a] -> Gen a
197
+ two :: Gen a -> Gen (a,a)
198
+ three :: Gen a -> Gen (a,a,a)
199
+ four :: Gen a -> Gen (a,a,a,a)
200
+
201
+ sized :: (Int -> Gen a) -> Gen a
202
+ resize :: Int -> Gen a -> Gen a
203
+ choose :: Random a => (a, a) -> Gen a
204
+ oneof :: [Gen a] -> Gen a
205
+ frequency :: [(Int, Gen a)] -> Gen a
206
+
207
+ vector :: Arbitrary a => Int -> Gen [a]
208
+
209
+ -- default generators
210
+ Arbitrary(..) -- :: class
211
+ class Arbitrary a where
212
+ arbitrary :: Gen a
213
+ coarbitrary :: a -> Gen b -> Gen b
214
+ rand :: Gen StdGen
215
+ promote :: (a -> Gen b) -> Gen (a -> b)
216
+ variant :: Int -> Gen a -> Gen a
217
+
218
+ -- testable
219
+ Testable(..) -- :: class
220
+ class Testable a where
221
+ property :: a -> Property
222
+ Property -- :: *
223
+ newtype Property
224
+ = Prop (Gen Result)
225
+
226
+ -- For writing your own driver
227
+ Result(..) -- :: data
228
+ data Result
229
+ = Result { ok :: Maybe Bool,
230
+ stamp :: [String],
231
+ arguments :: [String] }
232
+ generate :: Int -> StdGen -> Gen a -> a
233
+ evaluate :: Testable a => a -> Gen Result
234
+
235
+ 2.2 porting policy for QuickCheck in Haskell to Ruby
236
+
237
+ Because Test.QuickCheck is not small, I decide to divide
238
+ implementation into several files.
239
+
240
+ = testable.rb
241
+ quickCheck :: Testable a => a -> IO () -- :: prop -> IO ()
242
+ verboseCheck :: Testable a => a -> IO () -- :: prop -> IO ()
243
+ test :: Testable a => a -> IO () -- :: prop -> IO ()
244
+ check :: Testable a => Config -> a -> IO ()
245
+ -- :: Config -> prop -> IO ()
246
+ (==>) :: Testable a => Bool -> a -> Property
247
+ -- :: Bool -> prop -> prop
248
+ -- gathering test-case information
249
+ label :: Testable a => String -> a -> Property
250
+ -- :: String -> prop -> prop
251
+ collect :: (Show a, Testable b) => a -> b -> Property
252
+ -- :: Show a => a -> prop -> prop
253
+ classify :: Testable a => Bool -> String -> a -> Property
254
+ -- :: Bool -> String -> prop -> prop
255
+ trivial :: Testable a => Bool -> a -> Property
256
+ -- :: Bool -> prop -> prop
257
+ -- testable
258
+ Testable(..) -- :: class
259
+ class Testable a where
260
+ property :: a -> Property
261
+
262
+ evaluate :: Testable a => a -> Gen Result
263
+
264
+ = config.rb
265
+ Config(..) -- :: *
266
+ data Config = Config
267
+ { configMaxTest :: Int
268
+ , configMaxFail :: Int
269
+ , configSize :: Int -> Int
270
+ , configEvery :: Int -> [String] -> String
271
+ }
272
+ defaultConfig :: Config
273
+
274
+ = gen.rb
275
+ -- property combinators
276
+ forAll :: (Show a, Testable b) => Gen a -> (a -> b) ->
277
+ Property
278
+ -- :: Gen a -> (a -> prop) -> prop
279
+ -- generator combinators
280
+ Gen -- :: * -> * ; Functor, Monad
281
+ newtype Gen a
282
+ = Gen (Int -> StdGen -> a)
283
+ elements :: [a] -> Gen a
284
+ two :: Gen a -> Gen (a,a)
285
+ three :: Gen a -> Gen (a,a,a)
286
+ four :: Gen a -> Gen (a,a,a,a)
287
+
288
+ sized :: (Int -> Gen a) -> Gen a
289
+ resize :: Int -> Gen a -> Gen a
290
+ choose :: Random a => (a, a) -> Gen a
291
+ oneof :: [Gen a] -> Gen a
292
+ frequency :: [(Int, Gen a)] -> Gen a
293
+
294
+ vector :: Arbitrary a => Int -> Gen [a]
295
+
296
+ rand :: Gen StdGen
297
+ promote :: (a -> Gen b) -> Gen (a -> b)
298
+ variant :: Int -> Gen a -> Gen a
299
+
300
+ generate :: Int -> StdGen -> Gen a -> a
301
+
302
+ = arbitrary.rb
303
+ Arbitrary(..) -- :: class
304
+ class Arbitrary a where
305
+ arbitrary :: Gen a
306
+ coarbitrary :: a -> Gen b -> Gen b
307
+
308
+ = property.rb
309
+ Property -- :: *
310
+ newtype Property
311
+ = Prop (Gen Result)
312
+
313
+ = result.rb
314
+ Result(..) -- :: data
315
+ data Result
316
+ = Result { ok :: Maybe Bool,
317
+ stamp :: [String],
318
+ arguments :: [String] }
319
+
320
+ 2.2.1 testable.rb
321
+
322
+ -- testable
323
+ Testable(..) -- :: class
324
+ class Testable a where
325
+ property :: a -> Property
326
+ type class Testable is translated into a module Testable.
327
+
328
+ Haskell
329
+ quickCheck :: Testable a => a -> IO () -- :: prop -> IO ()
330
+ verboseCheck :: Testable a => a -> IO () -- :: prop -> IO ()
331
+ test :: Testable a => a -> IO () -- :: prop -> IO ()
332
+ check :: Testable a => Config -> a -> IO ()
333
+ -- :: Config -> prop -> IO ()
334
+ --->
335
+ Ruby
336
+ Testable#quick_check :: [nil, [TrueClass, FalseClass]]
337
+ Testable#verbose_check :: [nil, [TrueClass, FalseClass]]
338
+ Testable#test :: [nil, [TrueClass, FalseClass]]
339
+ Testable#check :: [Config, [TrueClass, FalseClass]]
340
+
341
+ For using checking functions with unit testing framework, they
342
+ should return the result as a boolean value.
343
+
344
+ Haskell
345
+ (==>) :: Testable a => Bool -> a -> Property
346
+ -- :: Bool -> prop -> prop
347
+ --->
348
+ Ruby
349
+ Testable#imply :: []
350
+ method imply takes a block for the boolean property.
351
+
352
+ Haskell
353
+ -- gathering test-case information
354
+ label :: Testable a => String -> a -> Property
355
+ -- :: String -> prop -> prop
356
+ collect :: (Show a, Testable b) => a -> b -> Property
357
+ -- :: Show a => a -> prop -> prop
358
+ classify :: Testable a => Bool -> String -> a -> Property
359
+ -- :: Bool -> String -> prop -> prop
360
+ trivial :: Testable a => Bool -> a -> Property
361
+ -- :: Bool -> prop -> prop
362
+ --->
363
+ Ruby
364
+ Testable#label :: [Object, Property]
365
+ alias Testable#collect
366
+ Testable#classify :: [Object, Property] # Object -> String
367
+ Testable#trivial :: [nil, Property]
368
+
369
+ In ruby, label and collect can be regarded as same with 'to_s'.
370
+ classify and trivial take a block for boolean condition.
371
+ classify calls label internally.
372
+
373
+ Haskell
374
+ evaluate :: Testable a => a -> Gen Result
375
+ where property :: Testable a => a -> Property
376
+ Property = Prop (Gen Result)
377
+ --->
378
+ Ruby
379
+ nop
380
+ Because the name evaluate is similar to eval in Ruby, I decide to
381
+ not implement evaluate. evaluate is almost same to property.
382
+
383
+ 2.2.2 config.rb
384
+
385
+ Haskell
386
+ Config(..) -- :: *
387
+ data Config = Config
388
+ { configMaxTest :: Int
389
+ , configMaxFail :: Int
390
+ , configSize :: Int -> Int
391
+ , configEvery :: Int -> [String] -> String
392
+ }
393
+ defaultConfig :: Config
394
+ --->
395
+ Ruby
396
+ class Config
397
+ Config#initialize :: [[Integer, Integer, Proc, Proc], ...]
398
+
399
+ There is two ways to implement a method with functions.
400
+ Because the initialize takes two functions, I choose to implement
401
+ them as Proc objects and as not block (it is confused to use both
402
+ Proc and block)
403
+
404
+ 2.2.3 gen.rb
405
+
406
+ gen.rb is not a small file to implement almost all of features in
407
+ QuickCheck.
408
+
409
+ Haskell
410
+ -- generator combinators
411
+ Gen -- :: * -> * ; Functor, Monad
412
+ newtype Gen a
413
+ = Gen (Int -> StdGen -> a)
414
+ --->
415
+ Ruby
416
+ class Gen
417
+ Gen#initialize [nil, ...]
418
+ initialize takes a block {|n, r| } where n is an integer and r is a
419
+ random generator.
420
+
421
+ Haskell
422
+ -- property combinators
423
+ forAll :: (Show a, Testable b) => Gen a -> (a -> b) ->
424
+ Property
425
+ -- :: Gen a -> (a -> prop) -> prop
426
+ --->
427
+ Ruby
428
+ Gen#forall :: [nil, Property]
429
+ forall takes a block.
430
+
431
+ Haskell
432
+ elements :: [a] -> Gen a
433
+ --->
434
+ Ruby
435
+ Gen.elements :: [[Object], Gen]
436
+
437
+ Haskell
438
+ two :: Gen a -> Gen (a,a)
439
+ three :: Gen a -> Gen (a,a,a)
440
+ four :: Gen a -> Gen (a,a,a,a)
441
+ --->
442
+ Ruby
443
+ nop
444
+ Because Ruby does not have tuple (but has Array). I wonder whether
445
+ the monadic functions two, three and four in Ruby. So I deferred to
446
+ implement them until I need them.
447
+
448
+ Haskell
449
+ sized :: (Int -> Gen a) -> Gen a
450
+ resize :: Int -> Gen a -> Gen a
451
+ choose :: Random a => (a, a) -> Gen a
452
+ oneof :: [Gen a] -> Gen a
453
+ frequency :: [(Int, Gen a)] -> Gen a
454
+ vector :: Arbitrary a => Int -> Gen [a]
455
+ rand :: Gen StdGen
456
+ promote :: (a -> Gen b) -> Gen (a -> b)
457
+ variant :: Int -> Gen a -> Gen a
458
+ generate :: Int -> StdGen -> Gen a -> a
459
+ --->
460
+ Ruby
461
+ Gen#sized :: [nil, Gen], takes a block
462
+ Gen#resize :: [Integer, Gen]
463
+
464
+ Gen.choose :: [[lo::?, hi::?], Gen]
465
+ where lo and hi belongs Random
466
+ Gen.oneof :: [[Gen], Gen]
467
+ Gen.frequency :: [[Integer, Gen], Gen]
468
+ Gen.vector :: [Integer, Gen]
469
+ Gen.rand :: [nil, Gen]
470
+ Gen.promote :: [nil, Gen], takes a block
471
+
472
+ Gen#variant :: [Integer, Gen]
473
+ Gen#generate :: [[Integer, StdGen], ?]
474
+
475
+ 2.2.3 arbitrary.rb
476
+
477
+ Haskell
478
+ Arbitrary(..) -- :: class
479
+ class Arbitrary a where
480
+ arbitrary :: Gen a
481
+ coarbitrary :: a -> Gen b -> Gen b
482
+ --->
483
+ Ruby
484
+ module Arbitrary
485
+ module Coarbitrary
486
+
487
+ Because arbitrary should be implemented as a class method, while
488
+ coarbitrary as a instance method, they are included in different
489
+ modules.
490
+
491
+ 2.2.4 property.rb
492
+
493
+ Haskell
494
+ Property -- :: *
495
+ newtype Property
496
+ = Prop (Gen Result)
497
+ --->
498
+ Ruby
499
+ class Property
500
+
501
+ There are several ways to implement Property in Ruby:
502
+ - as a class independently <-- I choose
503
+ - as a subclass of Gen
504
+
505
+ At first implementation (experimentally), I tried to write Property
506
+ as a subclass of Gen. However, initialization is different and debug
507
+ is imprecated.
508
+
509
+ 2.2.5 result.rb
510
+
511
+ Haskell
512
+ Result(..) -- :: data
513
+ data Result
514
+ = Result { ok :: Maybe Bool,
515
+ stamp :: [String],
516
+ arguments :: [String] }
517
+ --->
518
+ Ruby
519
+ class Result
520
+ attr_reader :ok, :stamp, :arguments