rantly 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: