rantly 0.2.0 → 3.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 +7 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +94 -0
- data/Gemfile +11 -0
- data/LICENSE +3 -0
- data/README.md +417 -0
- data/Rakefile +13 -30
- data/VERSION.yml +4 -4
- data/lib/rantly/data.rb +1 -1
- data/lib/rantly/generator.rb +126 -112
- data/lib/rantly/minitest.rb +1 -0
- data/lib/rantly/minitest_extensions.rb +15 -0
- data/lib/rantly/property.rb +60 -29
- data/lib/rantly/rspec.rb +1 -0
- data/lib/rantly/rspec_extensions.rb +8 -0
- data/lib/rantly/shrinks.rb +192 -0
- data/lib/rantly/silly.rb +42 -42
- data/lib/rantly/spec.rb +4 -4
- data/lib/rantly/testunit_extensions.rb +8 -0
- data/lib/rantly.rb +10 -2
- data/rantly.gemspec +36 -49
- data/test/rantly_test.rb +103 -225
- data/test/shrinks_test.rb +104 -0
- data/test/test_helper.rb +12 -8
- metadata +50 -45
- data/.gitignore +0 -5
- data/README.textile +0 -296
@@ -0,0 +1,192 @@
|
|
1
|
+
# Integer : shrink to zero
|
2
|
+
class Integer
|
3
|
+
def shrink
|
4
|
+
if self > 8
|
5
|
+
self / 2
|
6
|
+
elsif self > 0
|
7
|
+
self - 1
|
8
|
+
elsif self < -8
|
9
|
+
(self + 1) / 2
|
10
|
+
elsif self < 0
|
11
|
+
self + 1
|
12
|
+
else
|
13
|
+
0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def retry?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def shrinkable?
|
22
|
+
self != 0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# String : shrink to ""
|
27
|
+
class String
|
28
|
+
def shrink
|
29
|
+
shrunk = dup
|
30
|
+
unless empty?
|
31
|
+
idx = Random.rand(size)
|
32
|
+
shrunk[idx] = ''
|
33
|
+
end
|
34
|
+
shrunk
|
35
|
+
end
|
36
|
+
|
37
|
+
def retry?
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def shrinkable?
|
42
|
+
self != ''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Array where elements can be shrunk but not removed
|
47
|
+
class Tuple
|
48
|
+
def initialize(a)
|
49
|
+
@array = a
|
50
|
+
@position = a.size - 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def [](i)
|
54
|
+
@array[i]
|
55
|
+
end
|
56
|
+
|
57
|
+
def []=(i, value)
|
58
|
+
@array[i] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def length
|
62
|
+
@array.length
|
63
|
+
end
|
64
|
+
|
65
|
+
def size
|
66
|
+
length
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
@array.to_s.insert(1, 'T ')
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
def each(&block)
|
78
|
+
@array.each(&block)
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_reader :array
|
82
|
+
|
83
|
+
def shrink
|
84
|
+
shrunk = @array.dup
|
85
|
+
while @position >= 0
|
86
|
+
e = @array.at(@position)
|
87
|
+
break if e.respond_to?(:shrinkable?) && e.shrinkable?
|
88
|
+
|
89
|
+
@position -= 1
|
90
|
+
end
|
91
|
+
if @position >= 0
|
92
|
+
shrunk[@position] = e.shrink
|
93
|
+
@position -= 1
|
94
|
+
end
|
95
|
+
Tuple.new(shrunk)
|
96
|
+
end
|
97
|
+
|
98
|
+
def retry?
|
99
|
+
@position >= 0
|
100
|
+
end
|
101
|
+
|
102
|
+
def shrinkable?
|
103
|
+
@array.any? { |e| e.respond_to?(:shrinkable?) && e.shrinkable? }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Array where the elements that can't be shrunk are removed
|
108
|
+
class Deflating
|
109
|
+
def initialize(a)
|
110
|
+
@array = a
|
111
|
+
@position = a.size - 1
|
112
|
+
end
|
113
|
+
|
114
|
+
def [](i)
|
115
|
+
@array[i]
|
116
|
+
end
|
117
|
+
|
118
|
+
def []=(i, value)
|
119
|
+
@array[i] = value
|
120
|
+
end
|
121
|
+
|
122
|
+
def length
|
123
|
+
@array.length
|
124
|
+
end
|
125
|
+
|
126
|
+
def size
|
127
|
+
length
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_s
|
131
|
+
@array.to_s.insert(1, 'D ')
|
132
|
+
end
|
133
|
+
|
134
|
+
def inspect
|
135
|
+
to_s
|
136
|
+
end
|
137
|
+
|
138
|
+
def each(&block)
|
139
|
+
@array.each(&block)
|
140
|
+
end
|
141
|
+
|
142
|
+
attr_reader :array
|
143
|
+
|
144
|
+
def shrink
|
145
|
+
shrunk = @array.dup
|
146
|
+
if @position >= 0
|
147
|
+
e = @array.at(@position)
|
148
|
+
if e.respond_to?(:shrinkable?) && e.shrinkable?
|
149
|
+
shrunk[@position] = e.shrink
|
150
|
+
else
|
151
|
+
shrunk.delete_at(@position)
|
152
|
+
end
|
153
|
+
@position -= 1
|
154
|
+
end
|
155
|
+
Deflating.new(shrunk)
|
156
|
+
end
|
157
|
+
|
158
|
+
def retry?
|
159
|
+
@position >= 0
|
160
|
+
end
|
161
|
+
|
162
|
+
def shrinkable?
|
163
|
+
!@array.empty?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Hash
|
168
|
+
def shrink
|
169
|
+
if any? { |_, v| v.respond_to?(:shrinkable?) && v.shrinkable? }
|
170
|
+
key, = detect { |_, v| v.respond_to?(:shrinkable?) && v.shrinkable? }
|
171
|
+
clone = dup
|
172
|
+
clone[key] = clone[key].shrink
|
173
|
+
clone
|
174
|
+
elsif !empty?
|
175
|
+
key = keys.first
|
176
|
+
h2 = dup
|
177
|
+
h2.delete(key)
|
178
|
+
h2
|
179
|
+
else
|
180
|
+
self
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def shrinkable?
|
185
|
+
any? { |_, v| v.respond_to?(:shrinkable?) && v.shrinkable? } ||
|
186
|
+
!empty?
|
187
|
+
end
|
188
|
+
|
189
|
+
def retry?
|
190
|
+
false
|
191
|
+
end
|
192
|
+
end
|
data/lib/rantly/silly.rb
CHANGED
@@ -8,50 +8,52 @@ module Rantly::Silly
|
|
8
8
|
end
|
9
9
|
|
10
10
|
module Rantly::Silly::Love
|
11
|
+
def letter(n = 3)
|
12
|
+
body = array(n) { paragraph }.join "\n\n"
|
13
|
+
<<~EOS
|
14
|
+
#{address}:
|
11
15
|
|
12
|
-
|
13
|
-
body = sized(n) { array(:paragraph) }.join "\n\n"
|
14
|
-
<<-EOS
|
15
|
-
#{address}:
|
16
|
+
#{body}
|
16
17
|
|
17
|
-
#{
|
18
|
+
#{sign}
|
18
19
|
|
19
|
-
#{
|
20
|
-
|
21
|
-
#{post_script}
|
22
|
-
EOS
|
20
|
+
#{post_script}
|
21
|
+
EOS
|
23
22
|
end
|
24
|
-
|
23
|
+
|
25
24
|
def address
|
26
25
|
"my #{extremifier} #{pedestal_label}"
|
27
26
|
end
|
28
27
|
|
29
28
|
def extremifier
|
30
|
-
choose
|
29
|
+
choose 'most', 'ultimate', 'unbelievable', 'incredible', 'burning'
|
31
30
|
end
|
32
31
|
|
33
32
|
def pedestal_label
|
34
|
-
choose
|
33
|
+
choose 'beloved', 'desire', 'dove', 'virgin goddess', 'existential solution', 'lighthouse', 'beacon', 'holy mother', 'queen', 'mistress'
|
35
34
|
end
|
36
35
|
|
37
36
|
def double_plus_good
|
38
|
-
choose
|
37
|
+
choose 'holy', 'shiny', 'glittering', 'joyous', 'delicious'
|
39
38
|
end
|
40
39
|
|
41
40
|
def how_i_feel
|
42
|
-
choose
|
41
|
+
choose 'my heart aches', 'my spine pines', 'my spirit wanders and wonders', 'my soul is awed', 'my loin burns'
|
43
42
|
end
|
44
43
|
|
45
44
|
def paragraph
|
46
|
-
|
45
|
+
array(range(2, 4)) { sentence }.join ' '
|
47
46
|
end
|
48
47
|
|
49
48
|
def sentence
|
50
49
|
freq \
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
proc {
|
51
|
+
"when #{how_i_feel}, my #{pedestal_label}, i feel the need to #{stalk_action},"\
|
52
|
+
"but this is not because #{how_i_feel}, but rather a symptom of my being your #{whoami}."
|
53
|
+
},
|
54
|
+
proc { "because you are my #{pedestal_label}, and i am your #{whoami}, no, rather your #{whoami}, #{fragment}." },
|
55
|
+
proc { "do not think that saying '#{how_i_feel}' suffices to show the depth of how #{how_i_feel}, because more than that, #{fantasy}" },
|
56
|
+
proc { "as a #{whoami}, that #{how_i_feel} is never quite enough for you, my #{double_plus_good} #{pedestal_label}." }
|
55
57
|
end
|
56
58
|
|
57
59
|
def fragment
|
@@ -59,10 +61,8 @@ EOS
|
|
59
61
|
choose "i hope to god #{fun}", "i believe #{fun}", "i will that #{fun}"
|
60
62
|
end
|
61
63
|
|
62
|
-
def caused_by
|
63
|
-
|
64
|
-
end
|
65
|
-
|
64
|
+
def caused_by; end
|
65
|
+
|
66
66
|
def whoami
|
67
67
|
"#{extremifier} #{humbleizer} #{groveler}"
|
68
68
|
end
|
@@ -72,11 +72,11 @@ EOS
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def humbleizer
|
75
|
-
choose
|
75
|
+
choose 'undeserving', 'insignificant', 'unremarkable', 'fearful', 'menial'
|
76
76
|
end
|
77
77
|
|
78
78
|
def groveler
|
79
|
-
choose
|
79
|
+
choose 'slave', 'servant', 'captive', 'lapdog'
|
80
80
|
end
|
81
81
|
|
82
82
|
def post_script
|
@@ -89,28 +89,28 @@ EOS
|
|
89
89
|
|
90
90
|
def fantasy
|
91
91
|
freq \
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
92
|
+
proc {
|
93
|
+
make = choose 'raise', 'nurture', 'bring into the world'
|
94
|
+
babies = choose 'brood of babies', "#{double_plus_good} angels"
|
95
|
+
good = double_plus_good
|
96
|
+
effect = choose "the world becomes all the more #{good}",
|
97
|
+
"we may at the end of our lives rest in #{good} peace.",
|
98
|
+
"you, my #{pedestal_label}, would continue to live."
|
99
|
+
"we would #{make} #{babies}, so #{effect}."
|
100
|
+
},
|
101
|
+
proc {
|
102
|
+
do_thing = choose('kiss', 'hug', 'read poetry to each other', 'massage', "whisper empty nothings into each others' ears",
|
103
|
+
'be with each other, and oblivious to the entire world')
|
104
|
+
affect = choose 'joy', 'mindfulness', 'calm', 'sanctity'
|
105
|
+
"we would #{do_thing} with #{double_plus_good} #{affect}"
|
106
|
+
}
|
106
107
|
end
|
107
108
|
|
108
109
|
def stalk_action
|
109
|
-
choose
|
110
|
+
choose 'think of you', 'dream of us together', 'look at your picture and sigh'
|
110
111
|
end
|
111
112
|
|
112
113
|
def time_duration
|
113
|
-
choose
|
114
|
+
choose 'once in a while', 'night', 'day', 'hour', 'minute'
|
114
115
|
end
|
115
116
|
end
|
116
|
-
|
data/lib/rantly/spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'rantly'
|
2
2
|
module Rantly::Check
|
3
|
-
def check(n=100
|
4
|
-
Rantly.gen.each(n
|
3
|
+
def check(n = 100, &block)
|
4
|
+
Rantly.gen.each(n, &block)
|
5
5
|
end
|
6
6
|
|
7
|
-
def sample(n=100
|
8
|
-
Rantly.gen.map(n
|
7
|
+
def sample(n = 100, &block)
|
8
|
+
Rantly.gen.map(n, &block)
|
9
9
|
end
|
10
10
|
end
|
data/lib/rantly.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$LOAD_PATH.include?(File.dirname(__FILE__)) || $LOAD_PATH.include?(__dir__)
|
3
3
|
|
4
4
|
class Rantly
|
5
5
|
end
|
6
6
|
|
7
7
|
require 'rantly/generator'
|
8
|
+
|
9
|
+
def Rantly(n = 1, &block)
|
10
|
+
if n > 1
|
11
|
+
Rantly.map(n, &block)
|
12
|
+
else
|
13
|
+
Rantly.value(&block)
|
14
|
+
end
|
15
|
+
end
|
data/rantly.gemspec
CHANGED
@@ -1,55 +1,42 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
1
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.
|
9
|
-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
2
|
+
s.name = 'rantly'
|
3
|
+
s.summary = 'Ruby Imperative Random Data Generator and Quickcheck'
|
4
|
+
s.homepage = 'https://github.com/rantly-rb/rantly'
|
5
|
+
s.version = '3.0.0'
|
6
|
+
s.license = 'MIT'
|
7
|
+
s.require_paths = ['lib']
|
8
|
+
s.authors = ['Ana María Martínez Gómez', 'Howard Yeh', 'Anthony Bargnesi', 'Eric Bischoff']
|
9
|
+
s.email = ['anamma06@gmail.com', 'hayeah@gmail.com', 'abargnesi@gmail.com', 'ebischoff@nerim.net']
|
14
10
|
s.extra_rdoc_files = [
|
15
|
-
|
16
|
-
|
11
|
+
'LICENSE',
|
12
|
+
'README.md',
|
13
|
+
'CHANGELOG.md'
|
17
14
|
]
|
18
15
|
s.files = [
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
16
|
+
'.document',
|
17
|
+
'.travis.yml',
|
18
|
+
'Gemfile',
|
19
|
+
'LICENSE',
|
20
|
+
'README.md',
|
21
|
+
'CHANGELOG.md',
|
22
|
+
'Rakefile',
|
23
|
+
'VERSION.yml',
|
24
|
+
'lib/rantly.rb',
|
25
|
+
'lib/rantly/data.rb',
|
26
|
+
'lib/rantly/generator.rb',
|
27
|
+
'lib/rantly/minitest.rb',
|
28
|
+
'lib/rantly/minitest_extensions.rb',
|
29
|
+
'lib/rantly/property.rb',
|
30
|
+
'lib/rantly/rspec.rb',
|
31
|
+
'lib/rantly/rspec_extensions.rb',
|
32
|
+
'lib/rantly/shrinks.rb',
|
33
|
+
'lib/rantly/silly.rb',
|
34
|
+
'lib/rantly/spec.rb',
|
35
|
+
'lib/rantly/testunit_extensions.rb',
|
36
|
+
'rantly.gemspec',
|
37
|
+
'test/rantly_test.rb',
|
38
|
+
'test/shrinks_test.rb',
|
39
|
+
'test/test_helper.rb'
|
34
40
|
]
|
35
|
-
s.
|
36
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
37
|
-
s.require_paths = ["lib"]
|
38
|
-
s.rubygems_version = %q{1.3.5}
|
39
|
-
s.summary = %q{Ruby Imperative Random Data Generator and Quickcheck}
|
40
|
-
s.test_files = [
|
41
|
-
"test/rantly_test.rb",
|
42
|
-
"test/test_helper.rb"
|
43
|
-
]
|
44
|
-
|
45
|
-
if s.respond_to? :specification_version then
|
46
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
-
s.specification_version = 3
|
48
|
-
|
49
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
50
|
-
else
|
51
|
-
end
|
52
|
-
else
|
53
|
-
end
|
41
|
+
s.required_ruby_version = '>= 3.3.0'
|
54
42
|
end
|
55
|
-
|