rantly 0.3.1 → 0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8db5bd7182d7f9e17c430588587617eaa712dd6d
4
+ data.tar.gz: 5812264178d1640909ba3ea004b777ecea8e78e6
5
+ SHA512:
6
+ metadata.gz: 36ffb950c9e4f23e5a7e02183bf7a4e7de2c35eac5431ffb4adb96266289097133c44ee7de1dd56db18a6553f45e36b580de1f4c91b9f1ad413adfae6b9a3744
7
+ data.tar.gz: b04342e87f28f5ef185ee6798bb8e7a119444c27d4b1fb0146cccd3e43ca13654fba3925ecc7914501b3336ead47055fa147d74f83874fb26b236a2522474f14
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.6
6
+ - 2.2.2
7
+ - rbx-2
8
+ - jruby
data/Gemfile CHANGED
@@ -1,5 +1,8 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
+
2
3
  group :development, :test do
4
+ gem 'minitest', "~> 5.7.0"
3
5
  gem 'jeweler'
4
- gem 'shoulda'
6
+ gem 'simplecov'
7
+ gem 'coveralls', :require => false
5
8
  end
@@ -1,3 +1,21 @@
1
+ !https://travis-ci.org/hayeah/rantly.png?branch=master!:https://travis-ci.org/hayeah/rantly
2
+
3
+ h1. Repository move (Beginning 2015-07-07)
4
+
5
+ The official _rantly_ repository has moved from "hayeah/rantly":https://github.com/hayeah/rantly to "abargnesi/rantly":https://github.com/abargnesi/rantly. The creator of _rantly_ is "Howard Yeh":https://github.com/hayeah. "Anthony Bargnesi":https://github.com/abargnesi is the current maintainer.
6
+
7
+ New development will occur in "abargnesi/rantly":https://github.com/abargnesi/rantly.
8
+
9
+ The transition plan is as follows:
10
+
11
+ * [x] Investigate and move open issues from "hayeah/rantly":https://github.com/hayeah/rantly to "abargnesi/rantly":https://github.com/abargnesi/rantly.
12
+ * [x] Evaluate and likely merge pull requests into hayeah/rantly. Push these changes to "abargnesi/rantly":https://github.com/abargnesi/rantly.
13
+ * [x] Move over any closed issues that have relevant discourse.
14
+ * [ ] Fix open issues.
15
+ * [x] Push new gem version after testing functionality.
16
+ * [ ] Continue new development; Changes will be pushed back upstream to "hayeah/rantly":https://github.com/hayeah/rantly over the course of the next month.
17
+ * [x] Added CHANGELOG markdown file. Includes what was added between 0.3.1 (2011-12-15) and 0.3.2 (2015-09-16).
18
+
1
19
  h1. Imperative Random Data Generator and Quickcheck
2
20
 
3
21
  You can use Rant to generate random test data, and use its Test::Unit extension for property-based testing.
@@ -19,7 +37,7 @@ $ irb -rrantly
19
37
  > Rantly { [integer,float]}
20
38
  => [-376856492, 0.452245765751706]
21
39
  > Rantly(5) { integer } # same as Rantly.map(5) { integer }
22
- => [-1843396915550491870, -1683855015308353854, -2291347782549033959, -951461511269053584, 483265231542292652]
40
+ => [-1843396915550491870, -1683855015308353854, -2291347782549033959, -951461511269053584, 483265231542292652]
23
41
  </code></pre>
24
42
 
25
43
  h1. Data Generation
@@ -91,7 +109,7 @@ Rantly#range(lo,hi)
91
109
  random integer between lo and hi.
92
110
  Rantly#float
93
111
  random float
94
- Rantly#bool
112
+ Rantly#boolean
95
113
  true or false
96
114
  Rantly#literal(value)
97
115
  No-op. returns value.
@@ -252,41 +270,96 @@ Rantly::TooManyTries: Exceed gen limit 60: 60 failed guards)
252
270
 
253
271
  h1. Property Testing
254
272
 
255
- Rantly extends Test::Unit for property testing. The extension is in its own module. So you need to require it.
273
+ Rantly extends Test::Unit and MiniTest::Test (5.0)/MiniTest::Unit::TestCase (< 5.0) for property testing. The extensions are in their own modules. So you need to require them explicitly:
256
274
 
257
275
  <pre><code>
258
- require 'rant/check'
276
+ require 'rantly/testunit_extensions' # for 'test/unit'
277
+ require 'rantly/minitest_extensions' # for 'minitest'
278
+ require 'rantly/rspec_extensions' # for RSpec
259
279
  </code></pre>
260
280
 
261
- It defines,
281
+ They define:
262
282
 
263
283
  <pre><code>
264
284
  Test::Unit::Assertions#property_of(&block)
265
285
  The block is used to generate random data with a generator. The method returns a Rantly::Property instance, that has the method 'check'.
266
286
  </code></pre>
267
287
 
268
- It's like this, using the gem 'shoulda'
288
+ Property assertions within Test::Unit could be done like this,
289
+
290
+ <pre><code>
291
+ # checks that integer only generates fixnum.
292
+ property_of {
293
+ integer
294
+ }.check { |i|
295
+ assert(i.is_a?(Integer), "integer property did not return Integer type")
296
+ }
297
+ </code></pre>
298
+
299
+ Property assertions within Minitest could be done like this,
300
+
301
+ <pre><code>
302
+ # checks that integer only generates fixnum.
303
+ property_of {
304
+ integer
305
+ }.check { |i|
306
+ assert_kind_of Integer, i, "integer property did not return Integer type"
307
+ }
308
+ </code></pre>
309
+
310
+ Property assertions within RSpec could be done like this,
269
311
 
270
312
  <pre><code>
271
313
  # checks that integer only generates fixnum.
272
- should "generate Fixnum only" do
273
- property_of { integer }.check { |i| assert i.is_a?(Integer) }
314
+ it "integer property only returns Integer type" do
315
+ property_of {
316
+ integer
317
+ }.check { |i|
318
+ expect(i).to be_a(Integer)
319
+ }
274
320
  end
275
321
  </code></pre>
276
322
 
277
323
  The check block takes the generated data as its argument. One idiom I find useful is to include a parameter of the random data for the check argument. For example, if I want to check that Rantly#array generates the right sized array, I could say,
278
324
 
279
325
  <pre><code>
280
- should "generate right sized array" do
281
- property_of {
282
- len = integer
283
- [len,array(len){integer}]
284
- }.check { |(len,arr)|
285
- assert_equal len, arr.length
286
- }
287
- end
326
+ property_of {
327
+ len = integer
328
+ [len,array(len){integer}]
329
+ }.check { |(len,arr)|
330
+ assert_equal len, arr.length
331
+ }
332
+ </code></pre>
333
+
334
+ If you wish to have quiet output from Rantly, set environmental variable:
335
+ <pre><code>
336
+ RANTLY_VERBOSE=0 # silent
337
+ RANTLY_VERBOSE=1 # verbose and default if env is not set
338
+ </code></pre>
339
+ This will silence the puts, print, and pretty_print statements in property.rb.
340
+
341
+ h1. Shrinking
342
+
343
+ Shrinking reduces the value of common types to some terminal lower bound. These functions are added to the Ruby types <code>Integer</code>, <code>String</code>, <code>Array</code>, and <code>Hash</code>.
344
+
345
+ For example a <code>String</code> is shrinkable until it is empty (e.g. <code>""</code>),
346
+
347
+ <pre><code>
348
+ "foo".shrink # => "fo"
349
+ "foo".shrink.shrink # => "f"
350
+ "foo".shrink.shrink.shrink # => ""
351
+ "".shrinkable? # => false
352
+ </code></pre>
353
+
354
+ Shrinking allows <code>Property#check</code> to find the minimum value that still fails the condition.
355
+
356
+ Enable shrinking with
357
+
358
+ <pre><code>
359
+ require 'rantly/shrinks'
288
360
  </code></pre>
289
361
 
362
+
290
363
  That's about it. Enjoy :)
291
364
 
292
365
 
data/Rakefile CHANGED
@@ -6,9 +6,9 @@ begin
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "rantly"
8
8
  gem.summary = %Q{Ruby Imperative Random Data Generator and Quickcheck}
9
- gem.email = "hayeah@gmail.com"
10
- gem.homepage = "http://github.com/hayeah/rantly"
11
- gem.authors = ["Howard Yeh"]
9
+ gem.email = ["hayeah@gmail.com", "abargnesi@gmail.com"]
10
+ gem.homepage = "https://github.com/abargnesi/rantly"
11
+ gem.authors = ["Howard Yeh", "Anthony Bargnesi"]
12
12
 
13
13
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
14
  end
@@ -23,23 +23,9 @@ Rake::TestTask.new(:test) do |test|
23
23
  test.verbose = true
24
24
  end
25
25
 
26
- begin
27
- require 'rcov/rcovtask'
28
- Rcov::RcovTask.new do |test|
29
- test.libs << 'test'
30
- test.pattern = 'test/**/*_test.rb'
31
- test.verbose = true
32
- end
33
- rescue LoadError
34
- task :rcov do
35
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
- end
37
- end
38
-
39
-
40
26
  task :default => :test
41
27
 
42
- require 'rake/rdoctask'
28
+ require 'rdoc/task'
43
29
  Rake::RDocTask.new do |rdoc|
44
30
  require 'yaml'
45
31
  if File.exist?('VERSION.yml')
@@ -54,4 +40,3 @@ Rake::RDocTask.new do |rdoc|
54
40
  rdoc.rdoc_files.include('README*')
55
41
  rdoc.rdoc_files.include('lib/**/*.rb')
56
42
  end
57
-
@@ -1,5 +1,5 @@
1
- ---
1
+ ---
2
+ :build:
2
3
  :major: 0
3
4
  :minor: 3
4
- :patch: 1
5
- :build:
5
+ :patch: 2
@@ -22,7 +22,7 @@ class Rantly
22
22
  def value(limit=10,&block)
23
23
  gen.value(limit,&block)
24
24
  end
25
-
25
+
26
26
  def gen
27
27
  self.singleton
28
28
  end
@@ -32,7 +32,6 @@ class Rantly
32
32
  end
33
33
 
34
34
  class TooManyTries < RuntimeError
35
-
36
35
  def initialize(limit,nfailed)
37
36
  @limit = limit
38
37
  @nfailed = nfailed
@@ -84,7 +83,7 @@ class Rantly
84
83
  handler.call(val) if handler
85
84
  end
86
85
  end
87
-
86
+
88
87
  attr_accessor :classifiers
89
88
 
90
89
  def initialize
@@ -111,7 +110,7 @@ class Rantly
111
110
  def size
112
111
  @size || Rantly.default_size
113
112
  end
114
-
113
+
115
114
  def sized(n,&block)
116
115
  raise "size needs to be greater than zero" if n < 0
117
116
  old_size = @size
@@ -222,18 +221,15 @@ class Rantly
222
221
  end
223
222
 
224
223
  module Chars
225
-
224
+
226
225
  class << self
227
- ASCII = ""
228
- (0..127).to_a.each do |i|
229
- ASCII << i
230
- end
226
+ ASCII = (0..127).to_a.each_with_object("") { |i, obj| obj << i }
231
227
 
232
228
  def of(regexp)
233
229
  ASCII.scan(regexp).to_a.map! { |char| char[0].ord }
234
230
  end
235
231
  end
236
-
232
+
237
233
  ALNUM = Chars.of /[[:alnum:]]/
238
234
  ALPHA = Chars.of /[[:alpha:]]/
239
235
  BLANK = Chars.of /[[:blank:]]/
@@ -247,8 +243,8 @@ class Rantly
247
243
  UPPER = Chars.of /[[:upper:]]/
248
244
  XDIGIT = Chars.of /[[:xdigit:]]/
249
245
  ASCII = Chars.of /./
250
-
251
-
246
+
247
+
252
248
  CLASSES = {
253
249
  :alnum => ALNUM,
254
250
  :alpha => ALPHA,
@@ -264,7 +260,7 @@ class Rantly
264
260
  :xdigit => XDIGIT,
265
261
  :ascii => ASCII,
266
262
  }
267
-
263
+
268
264
  end
269
265
 
270
266
  def string(char_class=:print)
@@ -0,0 +1 @@
1
+ require 'rantly/minitest_extensions'
@@ -0,0 +1,14 @@
1
+ require 'minitest'
2
+ require 'rantly/property'
3
+
4
+ test_class = if defined?(MiniTest::Test)
5
+ MiniTest::Test
6
+ else
7
+ MiniTest::Unit::TestCase
8
+ end
9
+
10
+ test_class.class_eval do
11
+ def property_of(&blk)
12
+ Rantly::Property.new(blk)
13
+ end
14
+ end
@@ -1,13 +1,28 @@
1
1
  require 'rantly'
2
- require 'test/unit'
3
2
  require 'pp'
3
+ require 'stringio'
4
4
 
5
5
  class Rantly::Property
6
+ attr_reader :failed_data, :shrunk_failed_data, :io
7
+
8
+ VERBOSITY = ENV.fetch('RANTLY_VERBOSE'){ 1 }.to_i
9
+
10
+ def io
11
+ @io ||= if VERBOSITY >= 1
12
+ STDOUT
13
+ else
14
+ StringIO.new
15
+ end
16
+ end
17
+
18
+ def pretty_print(object)
19
+ PP.pp(object, io)
20
+ end
6
21
 
7
22
  def initialize(property)
8
23
  @property = property
9
24
  end
10
-
25
+
11
26
  def check(n=100,limit=10,&assertion)
12
27
  i = 0
13
28
  test_data = nil
@@ -15,24 +30,48 @@ class Rantly::Property
15
30
  Rantly.singleton.generate(n,limit,@property) do |val|
16
31
  test_data = val
17
32
  assertion.call(val) if assertion
18
- puts "" if i % 100 == 0
19
- print "." if i % 10 == 0
33
+ io.puts "" if i % 100 == 0
34
+ io.print "." if i % 10 == 0
20
35
  i += 1
21
36
  end
22
- puts
23
- puts "success: #{i} tests"
37
+ io.puts
38
+ io.puts "success: #{i} tests"
24
39
  rescue Rantly::TooManyTries => e
25
- puts
26
- puts "too many tries: #{e.tries}"
40
+ io.puts
41
+ io.puts "too many tries: #{e.tries}"
27
42
  raise e
28
- rescue => boom
29
- puts
30
- puts "failure: #{i} tests, on:"
31
- pp test_data
43
+ rescue Exception => boom
44
+ io.puts
45
+ io.puts "failure: #{i} tests, on:"
46
+ pretty_print test_data
47
+ @failed_data = test_data
48
+ if @failed_data.respond_to?(:shrink)
49
+ @shrunk_failed_data = shrinkify(assertion, @failed_data)
50
+ io.puts "minimal failed data is:"
51
+ pretty_print @shrunk_failed_data
52
+ end
32
53
  raise boom
33
54
  end
34
55
  end
35
56
 
57
+ # return the first success case
58
+ def shrinkify(assertion, data)
59
+ # We assume that data.shrink is non-destructive
60
+ return data if !data.shrinkable?
61
+ val = data.shrink
62
+ begin
63
+ assertion.call(val)
64
+ io.puts "found a reduced success:"
65
+ pretty_print val
66
+ return data
67
+ rescue Exception
68
+ io.puts "found a reduced failure case:"
69
+ pretty_print val
70
+ # recursively shrink failure case
71
+ return shrinkify(assertion,val)
72
+ end
73
+ end
74
+
36
75
  def report
37
76
  distribs = self.classifiers.sort { |a,b| b[1] <=> a[1] }
38
77
  total = distribs.inject(0) { |sum,pair| sum + pair[1]}
@@ -41,20 +80,3 @@ class Rantly::Property
41
80
  end
42
81
  end
43
82
  end
44
-
45
- module Test::Unit::Assertions
46
- def property_of(&block)
47
- Rantly::Property.new(block)
48
- end
49
- end
50
-
51
- begin
52
- require 'rspec'
53
- class RSpec::Core::ExampleGroup
54
- def property_of(&block)
55
- Rantly::Property.new(block)
56
- end
57
- end
58
- rescue LoadError
59
- "No RSpec loaded. Oh, well."
60
- end
@@ -0,0 +1 @@
1
+ require 'rantly/rspec_extensions'
@@ -0,0 +1,8 @@
1
+ require 'rspec'
2
+ require 'rantly/property'
3
+
4
+ class RSpec::Core::ExampleGroup
5
+ def property_of(&block)
6
+ Rantly::Property.new(block)
7
+ end
8
+ end
@@ -0,0 +1,77 @@
1
+ class Integer
2
+ def shrink
3
+ if self < 0 then (self / 2).floor + 1
4
+ elsif self <= 10 && self > 0 then self - 1
5
+ elsif self > 0 then ((self + 1) / 2).ceil - 1
6
+ else
7
+ return 0
8
+ end
9
+ end
10
+
11
+ def shrinkable?
12
+ self != 0
13
+ end
14
+ end
15
+
16
+ class String
17
+ def shrink
18
+ if self.size > 0
19
+ idx = Random::rand(self.size)
20
+ shrunk = self.dup
21
+ shrunk[idx] = ""
22
+ return shrunk
23
+ else
24
+ return ""
25
+ end
26
+ end
27
+
28
+ def shrinkable?
29
+ self != ""
30
+ end
31
+ end
32
+
33
+ class Array
34
+ def shrink
35
+ idx = find_index{|e| e.respond_to?(:shrinkable?) && e.shrinkable?}
36
+ if idx != nil
37
+ clone = self.dup
38
+ clone[idx] = clone[idx].shrink
39
+ return clone
40
+ elsif !self.empty?
41
+ i = Random::rand(self.length)
42
+ a2 = self.dup
43
+ a2.delete_at(i)
44
+ return a2
45
+ else
46
+ return self
47
+ end
48
+ end
49
+
50
+ def shrinkable?
51
+ self.any?{|e| e.respond_to?(:shrinkable?) && e.shrinkable? } ||
52
+ !self.empty?
53
+ end
54
+ end
55
+
56
+ class Hash
57
+ def shrink
58
+ if self.any?{|_,v| v.respond_to?(:shrinkable?) && v.shrinkable? }
59
+ key,_ = self.detect{|_,v| v.respond_to?(:shrinkable?) && v.shrinkable? }
60
+ clone = self.dup
61
+ clone[key] = clone[key].shrink
62
+ return clone
63
+ elsif !self.empty?
64
+ key = self.keys.first
65
+ h2 = self.dup
66
+ h2.delete(key)
67
+ return h2
68
+ else
69
+ return self
70
+ end
71
+ end
72
+
73
+ def shrinkable?
74
+ self.any?{|_,v| v.respond_to?(:shrinkable?) && v.shrinkable? } ||
75
+ !self.empty?
76
+ end
77
+ end
@@ -21,7 +21,7 @@ module Rantly::Silly::Love
21
21
  #{post_script}
22
22
  EOS
23
23
  end
24
-
24
+
25
25
  def address
26
26
  "my #{extremifier} #{pedestal_label}"
27
27
  end
@@ -60,9 +60,8 @@ EOS
60
60
  end
61
61
 
62
62
  def caused_by
63
-
64
63
  end
65
-
64
+
66
65
  def whoami
67
66
  "#{extremifier} #{humbleizer} #{groveler}"
68
67
  end
@@ -113,4 +112,3 @@ EOS
113
112
  choose "once in a while","night","day","hour","minute"
114
113
  end
115
114
  end
116
-
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'rantly/property'
3
+
4
+ module Test::Unit::Assertions
5
+ def property_of(&block)
6
+ Rantly::Property.new(block)
7
+ end
8
+ end
@@ -1,55 +1,70 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
+ # stub: rantly 0.3.2 ruby lib
5
6
 
6
7
  Gem::Specification.new do |s|
7
- s.name = %q{rantly}
8
- s.version = "0.3.0"
8
+ s.name = "rantly"
9
+ s.version = "0.3.2"
9
10
 
10
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Howard Yeh"]
12
- s.date = %q{2010-01-22}
13
- s.email = %q{hayeah@gmail.com}
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Howard Yeh", "Anthony Bargnesi"]
14
+ s.date = "2015-09-16"
15
+ s.email = ["hayeah@gmail.com", "abargnesi@gmail.com"]
14
16
  s.extra_rdoc_files = [
15
17
  "LICENSE",
16
- "README.textile"
18
+ "README.textile"
17
19
  ]
18
20
  s.files = [
19
21
  ".document",
20
- ".gitignore",
21
- "LICENSE",
22
- "README.textile",
23
- "Rakefile",
24
- "VERSION.yml",
25
- "lib/rantly.rb",
26
- "lib/rantly/data.rb",
27
- "lib/rantly/generator.rb",
28
- "lib/rantly/property.rb",
29
- "lib/rantly/silly.rb",
30
- "lib/rantly/spec.rb",
31
- "rantly.gemspec",
32
- "test/rantly_test.rb",
33
- "test/test_helper.rb"
34
- ]
35
- s.homepage = %q{http://github.com/hayeah/rantly}
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 = [
22
+ ".travis.yml",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.textile",
26
+ "Rakefile",
27
+ "VERSION.yml",
28
+ "lib/rantly.rb",
29
+ "lib/rantly/data.rb",
30
+ "lib/rantly/generator.rb",
31
+ "lib/rantly/minitest.rb",
32
+ "lib/rantly/minitest_extensions.rb",
33
+ "lib/rantly/property.rb",
34
+ "lib/rantly/rspec.rb",
35
+ "lib/rantly/rspec_extensions.rb",
36
+ "lib/rantly/shrinks.rb",
37
+ "lib/rantly/silly.rb",
38
+ "lib/rantly/spec.rb",
39
+ "lib/rantly/testunit_extensions.rb",
40
+ "rantly.gemspec",
41
41
  "test/rantly_test.rb",
42
- "test/test_helper.rb"
42
+ "test/shrinks_test.rb",
43
+ "test/test_helper.rb"
43
44
  ]
45
+ s.homepage = "https://github.com/abargnesi/rantly"
46
+ s.rubygems_version = "2.4.5.1"
47
+ s.summary = "Ruby Imperative Random Data Generator and Quickcheck"
44
48
 
45
49
  if s.respond_to? :specification_version then
46
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
- s.specification_version = 3
50
+ s.specification_version = 4
48
51
 
49
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ s.add_development_dependency(%q<minitest>, ["~> 5.7.0"])
54
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
55
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
56
+ s.add_development_dependency(%q<coveralls>, [">= 0"])
50
57
  else
58
+ s.add_dependency(%q<minitest>, ["~> 5.7.0"])
59
+ s.add_dependency(%q<jeweler>, [">= 0"])
60
+ s.add_dependency(%q<simplecov>, [">= 0"])
61
+ s.add_dependency(%q<coveralls>, [">= 0"])
51
62
  end
52
63
  else
64
+ s.add_dependency(%q<minitest>, ["~> 5.7.0"])
65
+ s.add_dependency(%q<jeweler>, [">= 0"])
66
+ s.add_dependency(%q<simplecov>, [">= 0"])
67
+ s.add_dependency(%q<coveralls>, [">= 0"])
53
68
  end
54
69
  end
55
70
 
@@ -1,23 +1,22 @@
1
- require 'test/test_helper'
2
- require 'rantly/property'
1
+ require 'test_helper'
2
+ require 'rantly/minitest_extensions'
3
3
 
4
4
  module RantlyTest
5
5
  end
6
6
 
7
- # check we generate the right kind of data.
8
- ## doesn't check for distribution
9
- class RantlyTest::Generator < Test::Unit::TestCase
10
- def setup
7
+ describe Rantly::Property do
8
+
9
+ before do
11
10
  Rantly.gen.reset
12
11
  end
13
-
14
- should "fail test generation" do
12
+
13
+ it "fail test generation" do
15
14
  assert_raises(Rantly::TooManyTries) {
16
15
  property_of { guard range(0,1) < 0 }.check
17
16
  }
18
17
  end
19
18
 
20
- should "generate literal value by returning itself" do
19
+ it "generate literal value by returning itself" do
21
20
  property_of {
22
21
  i = integer
23
22
  [i,literal(i)]
@@ -26,7 +25,7 @@ class RantlyTest::Generator < Test::Unit::TestCase
26
25
  }
27
26
  end
28
27
 
29
- should "generate integer in range" do
28
+ it "generate integer in range" do
30
29
  property_of {
31
30
  i = integer
32
31
  [i,range(i,i)]
@@ -37,15 +36,15 @@ class RantlyTest::Generator < Test::Unit::TestCase
37
36
  lo, hi = [integer(100),integer(100)].sort
38
37
  [lo,hi,range(lo,hi)]
39
38
  }.check { |(lo,hi,int)|
40
- assert((lo..hi).include?(int))
39
+ assert((lo..hi).include?(int))
41
40
  }
42
41
  end
43
42
 
44
- should "generate Fixnum only" do
43
+ it "generate Fixnum only" do
45
44
  property_of { integer }.check { |i| assert i.is_a?(Integer) }
46
45
  end
47
46
 
48
- should "generate integer less than abs(n)" do
47
+ it "generate integer less than abs(n)" do
49
48
  property_of {
50
49
  n = range(0,10)
51
50
  [n,integer(n)]
@@ -54,17 +53,17 @@ class RantlyTest::Generator < Test::Unit::TestCase
54
53
  }
55
54
  end
56
55
 
57
- should "generate Float" do
56
+ it "generate Float" do
58
57
  property_of { float }.check { |f| assert f.is_a?(Float)}
59
58
  end
60
59
 
61
- should "generate Boolean" do
60
+ it "generate Boolean" do
62
61
  property_of { boolean }.check { |t|
63
62
  assert t == true || t == false
64
63
  }
65
64
  end
66
65
 
67
- should "generate empty strings" do
66
+ it "generate empty strings" do
68
67
  property_of {
69
68
  sized(0) { string }
70
69
  }.check { |s|
@@ -72,7 +71,7 @@ class RantlyTest::Generator < Test::Unit::TestCase
72
71
  }
73
72
  end
74
73
 
75
- should "generate strings with the right regexp char classes" do
74
+ it "generate strings with the right regexp char classes" do
76
75
  char_classes = Rantly::Chars::CLASSES.keys
77
76
  property_of {
78
77
  char_class = choose(*char_classes)
@@ -92,7 +91,7 @@ class RantlyTest::Generator < Test::Unit::TestCase
92
91
  }
93
92
  end
94
93
 
95
- should "generate strings matching regexp" do
94
+ it "generate strings matching regexp" do
96
95
  property_of {
97
96
  sized(10) { string(/[abcd]/) }
98
97
  }.check { |s|
@@ -102,11 +101,11 @@ class RantlyTest::Generator < Test::Unit::TestCase
102
101
 
103
102
  # call
104
103
 
105
- should "call Symbol as method call (no arg)" do
104
+ it "call Symbol as method call (no arg)" do
106
105
  property_of {call(:integer)}.check { |i| i.is_a?(Integer)}
107
106
  end
108
107
 
109
- should "call Symbol as method call (with arg)" do
108
+ it "call Symbol as method call (with arg)" do
110
109
  property_of {
111
110
  n = range(0,100)
112
111
  [n,call(:integer,n)]
@@ -115,8 +114,8 @@ class RantlyTest::Generator < Test::Unit::TestCase
115
114
  }
116
115
  end
117
116
 
118
- should "call Array by calling first element as method, the rest as args" do
119
- assert_raise(RuntimeError) {
117
+ it "call Array by calling first element as method, the rest as args" do
118
+ assert_raises(RuntimeError) {
120
119
  Rantly.gen.value {
121
120
  call []
122
121
  }
@@ -128,8 +127,8 @@ class RantlyTest::Generator < Test::Unit::TestCase
128
127
  assert_equal a, b
129
128
  }
130
129
  end
131
-
132
- should "call Proc with generator.instance_eval" do
130
+
131
+ it "call Proc with generator.instance_eval" do
133
132
  property_of {
134
133
  call Proc.new { true }
135
134
  }.check { |o|
@@ -147,16 +146,16 @@ class RantlyTest::Generator < Test::Unit::TestCase
147
146
  assert i1 > i0
148
147
  }
149
148
  end
150
-
151
- should "raise if calling on any other value" do
152
- assert_raise(RuntimeError) {
149
+
150
+ it "raise if calling on any other value" do
151
+ assert_raises(RuntimeError) {
153
152
  Rantly.gen.call 0
154
153
  }
155
154
  end
156
155
 
157
156
  # branch
158
157
 
159
- should "branch by Rantly#calling one of the args" do
158
+ it "branch by Rantly#calling one of the args" do
160
159
  property_of {
161
160
  branch :integer, :integer, :integer
162
161
  }.check { |o|
@@ -169,10 +168,9 @@ class RantlyTest::Generator < Test::Unit::TestCase
169
168
  }
170
169
  end
171
170
 
172
-
173
171
  # choose
174
-
175
- should "choose a value from args " do
172
+
173
+ it "choose a value from args " do
176
174
  property_of {
177
175
  choose
178
176
  }.check {|o|
@@ -190,7 +188,7 @@ class RantlyTest::Generator < Test::Unit::TestCase
190
188
  }
191
189
  property_of {
192
190
  arr = sized(10) { array { integer } }
193
- choose(*arr)
191
+ choose(*arr)
194
192
  }.check { |o|
195
193
  assert o.is_a?(Fixnum)
196
194
  }
@@ -207,7 +205,7 @@ class RantlyTest::Generator < Test::Unit::TestCase
207
205
 
208
206
  # freq
209
207
 
210
- should "not pick an element with 0 frequency" do
208
+ it "not pick an element with 0 frequency" do
211
209
  property_of {
212
210
  sized(10) {
213
211
  array { freq([0,:string],[1,:integer]) }
@@ -217,8 +215,8 @@ class RantlyTest::Generator < Test::Unit::TestCase
217
215
  }
218
216
  end
219
217
 
220
- should "handle degenerate freq pairs" do
221
- assert_raise(RuntimeError) {
218
+ it "handle degenerate freq pairs" do
219
+ assert_raises(RuntimeError) {
222
220
  Rantly.gen.value {
223
221
  freq
224
222
  }
@@ -233,15 +231,15 @@ class RantlyTest::Generator < Test::Unit::TestCase
233
231
 
234
232
  # array
235
233
 
236
- should "generate empty array" do
234
+ it "generate empty array" do
237
235
  property_of {
238
236
  sized(0) { array { integer }}
239
237
  }.check { |o|
240
238
  assert o.empty?
241
239
  }
242
240
  end
243
-
244
- should "generate the right sized nested arrays" do
241
+
242
+ it "generate the right sized nested arrays" do
245
243
  property_of {
246
244
  size1 = range(5,10)
247
245
  size2 = range(0,size1-1)
@@ -252,8 +250,8 @@ class RantlyTest::Generator < Test::Unit::TestCase
252
250
  assert outter_array.all? { |inner_array| inner_array.size < size1 }
253
251
  }
254
252
  end
255
-
256
- should "generate array with right types" do
253
+
254
+ it "generate array with right types" do
257
255
  property_of {
258
256
  sized(10) { array { freq(:integer,:string,:float)} }
259
257
  }.check { |arr|
@@ -268,17 +266,24 @@ class RantlyTest::Generator < Test::Unit::TestCase
268
266
  }
269
267
  end
270
268
 
271
- # should "raise if generating an array without size" do
272
- # assert_raise(RuntimeError) {
273
- # Rantly.gen.value { array(:integer) }
274
- # }
275
- # end
269
+ # it "raise if generating an array without size" do
270
+ # assert_raises(RuntimeError) {
271
+ # Rantly.gen.value { array(:integer) }
272
+ # }
273
+ # end
276
274
 
277
275
  end
278
-
279
276
 
277
+ # TODO: Determine type of tests required here.
278
+
279
+ # check we generate the right kind of data.
280
+ ## doesn't check for distribution
281
+ class RantlyTest::Generator < Minitest::Test
282
+ def setup
283
+ Rantly.gen.reset
284
+ end
285
+ end
280
286
 
281
287
  # TODO: check that distributions of different methods look roughly correct.
282
- class RantlyTest::Distribution
283
-
288
+ class RantlyTest::Distribution < Minitest::Test
284
289
  end
@@ -0,0 +1,108 @@
1
+ require 'test_helper'
2
+ require 'rantly/shrinks'
3
+ require 'rantly/minitest_extensions'
4
+
5
+ module RantlyTest
6
+ end
7
+
8
+ module RantlyTest::Shrinkers
9
+ end
10
+
11
+ describe Integer do
12
+
13
+ it "not be able to shrink 0 integer" do
14
+ assert !0.shrinkable?
15
+ end
16
+
17
+ it "shrink positive integers to something less than itself" do
18
+ assert(3.shrink < 3)
19
+ assert(2.shrink < 2)
20
+ assert_equal(0,1.shrink)
21
+ end
22
+
23
+ it "shrink negative integers to something larger than itself" do
24
+ assert(-3.shrink > -3)
25
+ assert(-2.shrink > -2)
26
+ assert_equal(0,-1.shrink)
27
+ end
28
+
29
+ it "shrink 0 to itself" do
30
+ # hmm. should this be undefined?
31
+ assert_equal 0.shrink, 0
32
+ end
33
+ end
34
+
35
+ describe String do
36
+
37
+ it "not be able to shrink empty string" do
38
+ assert !"".shrinkable?
39
+ end
40
+
41
+ it "shrink a string one char shorter" do
42
+ property_of {
43
+ sized(10) { string }
44
+ }.check { |str|
45
+ assert_equal 9, str.shrink.length
46
+ }
47
+ end
48
+ end
49
+
50
+ describe Array do
51
+
52
+ it "not be able to shrink empty array" do
53
+ assert ![].shrinkable?
54
+ end
55
+
56
+ it "shrink array by trying to shrink the first shrinkable element available" do
57
+ assert_equal [0,1], [1,1].shrink
58
+ assert_equal [0,0,1], [0,1,1].shrink
59
+ end
60
+
61
+ it "shrink array by 1 if none of the element in it is shrinkable" do
62
+ property_of {
63
+ n = integer(1..10)
64
+ a = Array.new(n,0)
65
+ [n,a]
66
+ }.check { |n,a|
67
+ assert_equal n-1, a.shrink.length
68
+ }
69
+ end
70
+ end
71
+
72
+ describe Hash do
73
+
74
+ it "not be able to shrink empty hash" do
75
+ assert !{}.shrinkable?
76
+ end
77
+
78
+ it "shrink a value if one of the values is shrinkable" do
79
+ assert_equal({foo: 0, bar: 0}, {foo: 1, bar: 0}.shrink)
80
+ assert_equal({foo: 0, bar: 0}, {foo: 0, bar: 1}.shrink)
81
+ end
82
+
83
+ it "shrink by deleting an element in it if none of the values is shrinkable" do
84
+ assert_equal({},{foo: 0}.shrink)
85
+ end
86
+ end
87
+
88
+ describe "Shrinker Test" do
89
+
90
+ it "shrink data to smallest value that fails assertion" do
91
+ # We try to generate an array of 10 elements, filled with ones.
92
+ # The property we try to test is that non of the element is
93
+ # larger than 1, and the array's length is less than 4.
94
+ test = property_of {
95
+ a = Array.new(10,1)
96
+ i = Random::rand(a.length)
97
+ a[i] = 1
98
+ a
99
+ }
100
+ assert_raises MiniTest::Assertion do
101
+ test.check { |a|
102
+ assert(!a.any? { |e| e > 0 } && a.length < 4,"contains 1")
103
+ }
104
+ end
105
+
106
+ assert_equal [0,0,0,0], test.shrunk_failed_data
107
+ end
108
+ end
@@ -1,11 +1,18 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
2
+ require 'minitest/autorun'
4
3
 
5
4
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
5
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
6
 
8
- require 'rantly'
7
+ require 'simplecov'
8
+ SimpleCov.start
9
9
 
10
- class Test::Unit::TestCase
10
+ begin
11
+ # Coveralls is marked as an _optional_ dependency, so don't
12
+ # throw a fit if it's not there.
13
+ require 'coveralls'
14
+ Coveralls.wear!
15
+ rescue LoadError
11
16
  end
17
+
18
+ require 'rantly'
metadata CHANGED
@@ -1,47 +1,84 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rantly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Howard Yeh
8
+ - Anthony Bargnesi
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-15 00:00:00.000000000 Z
12
+ date: 2015-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 5.7.0
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 5.7.0
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: jeweler
16
- requirement: &2156578960 !ruby/object:Gem::Requirement
17
- none: false
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: simplecov
44
+ requirement: !ruby/object:Gem::Requirement
18
45
  requirements:
19
- - - ! '>='
46
+ - - ">="
20
47
  - !ruby/object:Gem::Version
21
48
  version: '0'
22
49
  type: :development
23
50
  prerelease: false
24
- version_requirements: *2156578960
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
25
56
  - !ruby/object:Gem::Dependency
26
- name: shoulda
27
- requirement: &2156578420 !ruby/object:Gem::Requirement
28
- none: false
57
+ name: coveralls
58
+ requirement: !ruby/object:Gem::Requirement
29
59
  requirements:
30
- - - ! '>='
60
+ - - ">="
31
61
  - !ruby/object:Gem::Version
32
62
  version: '0'
33
63
  type: :development
34
64
  prerelease: false
35
- version_requirements: *2156578420
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
36
70
  description:
37
- email: hayeah@gmail.com
71
+ email:
72
+ - hayeah@gmail.com
73
+ - abargnesi@gmail.com
38
74
  executables: []
39
75
  extensions: []
40
76
  extra_rdoc_files:
41
77
  - LICENSE
42
78
  - README.textile
43
79
  files:
44
- - .document
80
+ - ".document"
81
+ - ".travis.yml"
45
82
  - Gemfile
46
83
  - LICENSE
47
84
  - README.textile
@@ -50,34 +87,41 @@ files:
50
87
  - lib/rantly.rb
51
88
  - lib/rantly/data.rb
52
89
  - lib/rantly/generator.rb
90
+ - lib/rantly/minitest.rb
91
+ - lib/rantly/minitest_extensions.rb
53
92
  - lib/rantly/property.rb
93
+ - lib/rantly/rspec.rb
94
+ - lib/rantly/rspec_extensions.rb
95
+ - lib/rantly/shrinks.rb
54
96
  - lib/rantly/silly.rb
55
97
  - lib/rantly/spec.rb
98
+ - lib/rantly/testunit_extensions.rb
56
99
  - rantly.gemspec
57
100
  - test/rantly_test.rb
101
+ - test/shrinks_test.rb
58
102
  - test/test_helper.rb
59
- homepage: http://github.com/hayeah/rantly
103
+ homepage: https://github.com/abargnesi/rantly
60
104
  licenses: []
105
+ metadata: {}
61
106
  post_install_message:
62
107
  rdoc_options: []
63
108
  require_paths:
64
109
  - lib
65
110
  required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
111
  requirements:
68
- - - ! '>='
112
+ - - ">="
69
113
  - !ruby/object:Gem::Version
70
114
  version: '0'
71
115
  required_rubygems_version: !ruby/object:Gem::Requirement
72
- none: false
73
116
  requirements:
74
- - - ! '>='
117
+ - - ">="
75
118
  - !ruby/object:Gem::Version
76
119
  version: '0'
77
120
  requirements: []
78
121
  rubyforge_project:
79
- rubygems_version: 1.8.11
122
+ rubygems_version: 2.4.5.1
80
123
  signing_key:
81
- specification_version: 3
124
+ specification_version: 4
82
125
  summary: Ruby Imperative Random Data Generator and Quickcheck
83
126
  test_files: []
127
+ has_rdoc: