rushcheck 0.2

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.
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