stig 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 537946887fe8b354b53d3d239b4910b9bcf9064c
4
+ data.tar.gz: 9039195f3278ccdd1a8616899e4faf9851704234
5
+ SHA512:
6
+ metadata.gz: ec59581cf608be129b4b87f33d2bba035316c06a95c32f7f97569ffa145a8bf1e1bc1393e1091780f4a7e52fa7ae697cfb09610a0ee250d209b81e0829569790
7
+ data.tar.gz: 8f96bb1d14955d99a06f3b95a91c36170e65ec05236629962249425757d3a3c934cdfca9c46a84ec4d4533f95c23d85a86e3164bcd4cabb29410563c19fe72ce
@@ -0,0 +1,2 @@
1
+ vLg���>}�J������R��=�yP!t����:L���;����Ԣ��)ۻDPS`��/!����{�a[{��%�m1|䕿��:���kh���(y���G �$&kd���D
2
+ /<!f~�c�(��4���L��H/F�s�E#tGJw�(�^�9e��B��r�ox�k�!H'E᳇��Fuc�2I��PN�w⮙��h'8�$����@�o�EҤk�ॗ�a,*N�6�k��ڡ����thX_�����0�e��<
@@ -0,0 +1 @@
1
+ RKh':�R�R�t��w�����'|_ `t>f����|Y��Λk�Bz.��}��]9a�����`\�/�D{�D;�H��� *O�� ����dC�6=��s��b���f�ܯjtE�qh[n���n�>����\9`"{�AN�n�<����AlE2d>�K,��VK&2����D�.4�,�p��[�a�Ui��e9���B9��N�²�'g�Db�o��t���*%�?O�(CF��˴�{���;�Z+n/V�E�iA|�8N�
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Jip van Reijsen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,77 @@
1
+ # stig
2
+
3
+ Simple test input generation.
4
+
5
+ ## What is it
6
+
7
+ Stig is a small library for property based testing in Ruby. It runs a test
8
+ multiple times (100 by default) with randomly generated input. Stig is test
9
+ framework agnostic, so can be used with any test framework.
10
+
11
+ ## Usage
12
+
13
+ An example using [cutest][cutest]. `test` and `assert_raise` come from cutest.
14
+
15
+ ```ruby
16
+ require "stig"
17
+
18
+ test "doesn't parse random input" do
19
+ Stig.property(String) do |string|
20
+ assert_raise { Library.parse(string) }
21
+ end
22
+ end
23
+ ```
24
+
25
+ `Stig.property` takes one or more generators and a predicate block. A generator
26
+ is an object implementing `#call` or `#random`. A predicate block is a block
27
+ that returns `true` for passed tests and `false` for failed test.
28
+
29
+ **Note**: In the above example `String` is used as generator. Stig doesn't
30
+ monkey-patch any classes. Refinements are used instead.
31
+
32
+ Stig ships with a few built in generators, such as `Date`, `Integer` and
33
+ `String`. They can be found under the `Stig::Generators` namespace. It's easy to
34
+ write your own generators using `Stig.generator` and `Stig.generator_for`.
35
+
36
+ An example of creating a custom generator using `Stig.generator`.
37
+
38
+ ```ruby
39
+ Person = Struct.new(:name, :age)
40
+
41
+ person_generator = generator do
42
+ Person.new Generators::String.random, Generators::Integer.random(99)
43
+ end
44
+
45
+ person_generator.call
46
+ # => #<struct Person name="M#uVfd7\tx\x1Eri]\x1F\x7F", age=95>
47
+ ```
48
+
49
+ An example of creating a custom generator using `Stig.generator_for`.
50
+
51
+ ```ruby
52
+ Person = Struct.new(:name, :age) do
53
+ def self.random
54
+ new Generators::String.random, Generators::Integer.random(99)
55
+ end
56
+ end
57
+
58
+ person_generator = generator_for(Person)
59
+
60
+ person_generator.call
61
+ # => #<struct Person name="-\x069|\x0F\x03Llq", age=6>
62
+ ```
63
+
64
+ To configure the number of tests stig should run set the environment variable
65
+ `STIG_NUMBER_OF_RUNS` to the desired number of test runs.
66
+
67
+ [cutest]: https://github.com/djanowski/cutest
68
+
69
+ ## Installation
70
+
71
+ `gem install stig`
72
+
73
+ Stig requires Ruby 2.0.0 or higher.
74
+
75
+ ## License
76
+
77
+ See the LICENSE file.
@@ -0,0 +1,134 @@
1
+ require "stig/refinements"
2
+
3
+ using Stig::Refinements
4
+
5
+ module Stig
6
+ # Public: Number of tests that should be run.
7
+ NUMBER_OF_RUNS = (ENV["STIG_NUMBER_OF_RUNS"] || 100).to_i
8
+
9
+ # Public: Raised when a test failed.
10
+ class AssertionFailed < StandardError; end
11
+
12
+ module_function
13
+
14
+ # Public: Tests a property with randomly generated input. The input comes from
15
+ # Generators, which are passed as arguments. The property is described in the
16
+ # block. A test has failed when the block returns a falsy value (false or
17
+ # nil).
18
+ #
19
+ # types - An object implementing #call or #random.
20
+ # block - A block that describes the property.
21
+ #
22
+ # Examples
23
+ #
24
+ # property(String, String) do |a,b|
25
+ # assert (a + b).start_with?(a)
26
+ # end
27
+ #
28
+ # property(-> { rand(10) }) do |a|
29
+ # assert a.between?(0, 10)
30
+ # end
31
+ #
32
+ # Returns true.
33
+ # Raises ArgumentError when an invalid generator was supplied.
34
+ # Raises ArgumentError when no generators were supplied.
35
+ # Raises ArgumentError when a generator generates too few values.
36
+ # Raises ArgumentError when no block was supplied.
37
+ # Raises Stig::AssertionFailed when a test failed.
38
+ def property(*types, &block)
39
+ offenders = types.reject do |type|
40
+ type.respond_to?(:call) || type.respond_to?(:random)
41
+ end
42
+
43
+ unless offenders.empty?
44
+ msg = "no #call or #random implemented for #{offenders.join ", "}"
45
+ raise ArgumentError, msg
46
+ end
47
+
48
+ unless block_given?
49
+ raise ArgumentError, "a block is required"
50
+ end
51
+
52
+ if types.empty?
53
+ raise ArgumentError, "no generators given, consider a unit test"
54
+ end
55
+
56
+ methods = types.map do |type|
57
+ type.respond_to?(:call) ? :call : :random
58
+ end
59
+
60
+ types_and_method = types.zip(methods)
61
+
62
+ 1.upto(NUMBER_OF_RUNS) do |i|
63
+ input = types_and_method.map { |type, method| type.send(method) }
64
+
65
+ result = yield(*input)
66
+
67
+ unless result
68
+ parameters = block.parameters.map(&:last).first(input.size)
69
+ formatted = parameters.zip(input).map do |a,v|
70
+ "- #{a} => #{v.inspect} (#{v.class})"
71
+ end
72
+
73
+ message = "Failed after #{i} test(s) with input\n" \
74
+ "#{formatted.join "\n"}"
75
+
76
+ raise AssertionFailed, message
77
+ end
78
+ end
79
+
80
+ return true
81
+ rescue StopIteration
82
+ offender = types
83
+ .select { |type| type.respond_to?(:peek) }
84
+ .find { |gen| gen.peek && false rescue true }
85
+
86
+ raise ArgumentError, "#{offender} generates too few values"
87
+ end
88
+
89
+ # Public: Creates a generator from a block.
90
+ #
91
+ # args - Any arguments that should be passed to the block.
92
+ # block - A block returning a random value.
93
+ #
94
+ # Examples
95
+ #
96
+ # float_generator = Stig.generator do
97
+ # rand
98
+ # end
99
+ #
100
+ # number_generator = Stig.generator(1, 100) do |min, max
101
+ # rand(min..max)
102
+ # end
103
+ #
104
+ # Returns a Proc.
105
+ # Raises ArgumentError if no block was passed.
106
+ def generator(*args, &block)
107
+ unless block_given?
108
+ raise ArgumentError, "no block given"
109
+ end
110
+
111
+ args.empty? ? block : proc { yield(*args) }
112
+ end
113
+
114
+ # Public: Creates a generator from an object. The object should respond to
115
+ # #random.
116
+ #
117
+ # object - An object implementing #random.
118
+ # args - Any arguments that should be passed to object#random.
119
+ #
120
+ # Examples
121
+ #
122
+ # # Assuming Integer.random is implemented and takes two arguments.
123
+ # integer_generator = generator_for(Integer, 1, 10)
124
+ #
125
+ # Returns a Proc.
126
+ # Raises ArgumentError if `object` does not respond to #random.
127
+ def generator_for(object, *args)
128
+ unless object.respond_to?(:random)
129
+ raise ArgumentError, "no #random implemented for #{object}"
130
+ end
131
+
132
+ generator(*args, &object.method(:random))
133
+ end
134
+ end
@@ -0,0 +1,8 @@
1
+ require "stig/generators/array"
2
+ require "stig/generators/character"
3
+ require "stig/generators/date"
4
+ require "stig/generators/float"
5
+ require "stig/generators/integer"
6
+ require "stig/generators/string"
7
+ require "stig/generators/symbol"
8
+ require "stig/generators/time"
@@ -0,0 +1,31 @@
1
+ module Stig
2
+ module Generators
3
+ module Array
4
+ # Public: Generates an random Array. Elements are generated by a
5
+ # generator. Size is variable, use a Range with equal start and end for a
6
+ # fixed size.
7
+ #
8
+ # generator - An object implementing #call or #random.
9
+ # size - A maximum size Integer or Range (default: 1..10).
10
+ #
11
+ # Returns an Array.
12
+ # Raises ArgumentError when an invalid generator was supplied.
13
+ def self.random(generator, size = 1..10)
14
+ unless generator.respond_to?(:call) || generator.respond_to?(:random)
15
+ msg = "no #call or #random implemented for #{generator}"
16
+ raise ArgumentError, msg
17
+ end
18
+
19
+ method = generator.respond_to?(:call) ? :call : :random
20
+
21
+ array = []
22
+
23
+ rand(size).times do
24
+ array << generator.send(method)
25
+ end
26
+
27
+ array
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ module Stig
2
+ module Generators
3
+ module Character
4
+ ASCII = 0.upto(127).map(&:chr)
5
+ PRINTABLE = 32.upto(126).map(&:chr)
6
+ DIGITS = 48.upto(57).map(&:chr)
7
+ UPPERCASE = 65.upto(90).map(&:chr)
8
+ LOWERCASE = 97.upto(122).map(&:chr)
9
+ ALPHABET = UPPERCASE + LOWERCASE
10
+
11
+ # Public: Generates a random character.
12
+ #
13
+ # set - An Array of one character Strings.
14
+ #
15
+ # Returns a 1 character String.
16
+ # Raises ArgumentError when `set` is empty.
17
+ def self.random(set = ASCII)
18
+ set = set.sample || raise(ArgumentError, "character set is empty")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require "date"
2
+
3
+ module Stig
4
+ module Generators
5
+ module Date
6
+ extend self
7
+
8
+ DEFAULT_INTERVAL = ::Date.new..::Date.today
9
+
10
+ # Public: Generates a random Date.
11
+ #
12
+ # range - An interval Range (default: Date.new..Date.today).
13
+ #
14
+ # Returns a Date.
15
+ def random(range = DEFAULT_INTERVAL)
16
+ rand(range)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Stig
2
+ module Generators
3
+ module Float
4
+ extend self
5
+
6
+ # Public: Generates a random Float.
7
+ #
8
+ # max - A maximum Float or Range (default 0.0..1.0).
9
+ #
10
+ # Returns a Float.
11
+ def random(max = 0.0..1.0)
12
+ rand(max)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ module Stig
2
+ module Generators
3
+ module Hash
4
+ extend self
5
+
6
+ # Public: Generates a random Hash. If no keys are passed, a Hash with a
7
+ # default proc is returned.
8
+ #
9
+ # generator - An object implementing #call or #random.
10
+ # keys - Objects to use as Hash keys.
11
+ #
12
+ # Returns a Hash.
13
+ # Raises ArgumentError when an invalid generator was supplied.
14
+ def random(generator, *keys)
15
+ unless generator.respond_to?(:call) || generator.respond_to?(:random)
16
+ msg = "no #call or #random implemented for #{generator}"
17
+ raise ArgumentError, msg
18
+ end
19
+
20
+ method = generator.respond_to?(:call) ? :call : :random
21
+
22
+ if keys.empty?
23
+ hash = ::Hash.new { |hash, key| hash[key] = generator.send(method) }
24
+ else
25
+ hash = {}
26
+ keys.each { |key| hash[key] = generator.send(method) }
27
+ end
28
+
29
+ hash
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ module Stig
2
+ module Generators
3
+ module Integer
4
+ extend self
5
+
6
+ # Public: Generates a random Integer.
7
+ #
8
+ # max - A maximum Integer or Range (default: 100).
9
+ #
10
+ # Returns an Integer.
11
+ def random(max = 100)
12
+ rand(max)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ require "stig/generators/character"
2
+
3
+ module Stig
4
+ module Generators
5
+ module String
6
+ extend self
7
+
8
+ # Public: Generates a random String. Characters are picked from a
9
+ # character set (`set`). Size is variable, use a Range with equal start
10
+ # and end for a fixed size.
11
+ #
12
+ # set - An Array of one character Strings (default: ASCII).
13
+ # size - A maximum length Integer or Range (default: 25).
14
+ #
15
+ # Returns a String.
16
+ def random(set = Character::ASCII, size = 25)
17
+ result = ""
18
+
19
+ rand(size).times do
20
+ char = set.sample || raise(ArgumentError, "character set is empty")
21
+ result << char
22
+ end
23
+
24
+ result
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ module Stig
2
+ module Generators
3
+ module Symbol
4
+ extend self
5
+
6
+ # Public: Generates a random Symbol. See Stig::Generators::String for
7
+ # usage
8
+ #
9
+ # Returns a Symbol.
10
+ def random(*args)
11
+ Generators::String.random(*args).to_sym
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Stig
2
+ module Generators
3
+ module Time
4
+ extend self
5
+
6
+ DEFAULT_INTERVAL = ::Time.at(0)..::Time.now
7
+
8
+ # Public: Generates a random Time.
9
+ #
10
+ # interval - An interval Range (default: Time.at(0)..Time.now).
11
+ #
12
+ # Returns a Time.
13
+ def random(interval = DEFAULT_INTERVAL)
14
+ rand(interval)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,115 @@
1
+ require "stig/generators/date"
2
+ require "stig/generators/float"
3
+ require "stig/generators/integer"
4
+ require "stig/generators/string"
5
+ require "stig/generators/symbol"
6
+ require "stig/generators/time"
7
+
8
+ module Stig
9
+ # Public: Refinements for the core classes Array, Float, Integer and String.
10
+ module Refinements
11
+ # A note on refinements.
12
+ #
13
+ # There are a few issues with refinements:
14
+ #
15
+ # 1. Refined class methods are ignored. Calling them results in a
16
+ # NoMethodError.
17
+ # 2. #respond_to? ignores refined methods. It returns `false` for methods
18
+ # that have been refined.
19
+ # 3. #send ignores refined methods. It raises a NoMethodError when trying
20
+ # to invoke a refined method.
21
+ #
22
+ # Issues 2 and 3 aren't bugs, see: http://goo.gl/335ndw.
23
+ #
24
+ # Stig uses the following workarounds:
25
+ #
26
+ # 1. To refine class method, the singleton class is refined.
27
+ # 2. #respond_to? is refined. It checks for existing methods manually. The
28
+ # module Fix is included in the refinement.
29
+ # 3. #send is refined. Unfortunately, this cannot be done by including a
30
+ # module in the refinement. #send needs to be defined directly in the
31
+ # refinement or it will be ignored. It also requires any method it calls
32
+ # to be defined directly in the refinement.
33
+ #
34
+ # It's a pity.
35
+
36
+ # Internal: Fixes #respond_to? for refined classes.
37
+ module Fix
38
+ def respond_to?(method, *args)
39
+ method == :random ? true : super
40
+ end
41
+ end
42
+
43
+ refine Date.singleton_class do
44
+ include Fix
45
+
46
+ def random(*args, &block)
47
+ Generators::Date.random(*args, &block)
48
+ end
49
+
50
+ def send(method, *args, &block)
51
+ method == :random ? random(*args, &block) : super
52
+ end
53
+ end
54
+
55
+ refine Float.singleton_class do
56
+ include Fix
57
+
58
+ def random(*args, &block)
59
+ Generators::Float.random(*args, &block)
60
+ end
61
+
62
+ def send(method, *args, &block)
63
+ method == :random ? random(*args, &block) : super
64
+ end
65
+ end
66
+
67
+ refine Integer.singleton_class do
68
+ include Fix
69
+
70
+ def random(*args, &block)
71
+ Generators::Integer.random(*args, &block)
72
+ end
73
+
74
+ def send(method, *args, &block)
75
+ method == :random ? random(*args, &block) : super
76
+ end
77
+ end
78
+
79
+ refine String.singleton_class do
80
+ include Fix
81
+
82
+ def random(*args, &block)
83
+ Generators::String.random(*args, &block)
84
+ end
85
+
86
+ def send(method, *args, &block)
87
+ method == :random ? random(*args, &block) : super
88
+ end
89
+ end
90
+
91
+ refine Symbol.singleton_class do
92
+ include Fix
93
+
94
+ def random(*args, &block)
95
+ Generators::Symbol.random(*args, &block)
96
+ end
97
+
98
+ def send(method, *args, &block)
99
+ method == :random ? random(*args, &block) : super
100
+ end
101
+ end
102
+
103
+ refine Time.singleton_class do
104
+ include Fix
105
+
106
+ def random(*args, &block)
107
+ Generators::Time.random(*args, &block)
108
+ end
109
+
110
+ def send(method, *args, &block)
111
+ method == :random ? random(*args, &block) : super
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,3 @@
1
+ module Stig
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "lib/stig/version"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "stig"
5
+ s.version = Stig::VERSION
6
+ s.summary = "simple test input generation"
7
+ s.description = "Stig is a small library for property based testing in Ruby."
8
+ s.author = "Jip van Reijsen"
9
+ s.email = "jipvanreijsen@gmail.com"
10
+ s.homepage = "https://github.com/britishtea/stig"
11
+ s.license = "MIT"
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.extra_rdoc_files = ["README.md"]
15
+ s.required_ruby_version = '>= 2.0'
16
+
17
+ s.add_development_dependency "cutest", "~> 1.2"
18
+ end
@@ -0,0 +1,7 @@
1
+ # Testing
2
+
3
+ [Cutest](cutest) is used for testing.
4
+
5
+ Running the tests is simple: `cutest test/*/*.rb`.
6
+
7
+ [cutest]: https://github.com/djanowski/cutest
@@ -0,0 +1,55 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/array"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Array }
8
+
9
+ test "takes a generator" do |mod|
10
+ elements = generator { 1 }
11
+ generator = generator_for(mod, elements)
12
+
13
+ property(generator) do |array|
14
+ assert_equal array.uniq, [1]
15
+
16
+ true
17
+ end
18
+ end
19
+
20
+ test "doesn't take an invalid generator" do |mod|
21
+ assert_raise(ArgumentError) { mod.random("invalid") }
22
+ end
23
+
24
+ test "defaults to Arrays with length between 1 and 10" do |mod|
25
+ elements = generator { 1 }
26
+ generator = generator_for(mod, elements)
27
+
28
+ property(generator) do |array|
29
+ assert array.size.between?(1, 10)
30
+
31
+ true
32
+ end
33
+ end
34
+
35
+ test "takes a maximum size" do |mod|
36
+ elements = generator { 1 }
37
+ generator = generator_for(mod, elements, 5)
38
+
39
+ property(generator) do |array|
40
+ assert array.size.between?(0, 5)
41
+
42
+ true
43
+ end
44
+ end
45
+
46
+ test "takes a range" do |mod|
47
+ elements = generator { 1 }
48
+ generator = generator_for(mod, elements, 1..5)
49
+
50
+ property(generator) do |array|
51
+ assert array.size.between?(1, 5)
52
+
53
+ true
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/string"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Character }
8
+
9
+ test "defaults to all ASCII characters" do |mod|
10
+ property(mod) do |character|
11
+ assert_equal character.class, String
12
+
13
+ true
14
+ end
15
+
16
+ property(mod) do |character|
17
+ assert_equal character.size, 1
18
+
19
+ true
20
+ end
21
+
22
+ property(mod) do |character|
23
+ assert 0.upto(127).map(&:chr).include?(character)
24
+
25
+ true
26
+ end
27
+ end
28
+
29
+ test "takes a character set" do |mod|
30
+ generator = generator_for(mod, ["a"])
31
+
32
+ property(generator) do |character|
33
+ assert_equal character, "a"
34
+
35
+ true
36
+ end
37
+ end
38
+
39
+ test "doesn't take an empty character set" do |mod|
40
+ assert_raise(ArgumentError) { mod.random([]) }
41
+ end
@@ -0,0 +1,36 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/date"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Date }
8
+
9
+ test "generates Dates" do |mod|
10
+ property(mod) do |date|
11
+ assert_equal date.class, Date
12
+
13
+ true
14
+ end
15
+ end
16
+
17
+ test "defaults between January 1, 4713 BCE and Date.today" do |mod|
18
+ range = Date.new..Date.today
19
+
20
+ property(mod) do |date|
21
+ assert range.cover?(date)
22
+
23
+ true
24
+ end
25
+ end
26
+
27
+ test "takes a Date Range" do |mod|
28
+ range = Date.new(0)..Date.new(5)
29
+ generator = generator_for(mod, range)
30
+
31
+ property(generator) do |date|
32
+ assert range.cover?(date)
33
+
34
+ true
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/float"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Float }
8
+
9
+ test "takes a maximum value" do |mod|
10
+ generator = generator_for(mod, 10.0)
11
+
12
+ property(generator) do |integer|
13
+ assert integer.between?(0.0, 10.0)
14
+
15
+ true
16
+ end
17
+ end
18
+
19
+ test "takes a range" do |mod|
20
+ generator = generator_for(mod, 5.0..10.0)
21
+
22
+ property(generator) do |integer|
23
+ assert integer.between?(5.0, 10.0)
24
+
25
+ true
26
+ end
27
+ end
28
+
29
+ test "defaults to Floats between 0.0 and 1.0" do |mod|
30
+ property(mod) do |integer|
31
+ assert integer.between?(0.0, 1.0)
32
+
33
+ true
34
+ end
35
+ end
@@ -0,0 +1,48 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+
4
+ setup { Stig }
5
+
6
+ prepare { $test = nil }
7
+
8
+ test "without a block" do |stig|
9
+ assert_raise(ArgumentError) { stig.generator }
10
+ end
11
+
12
+ test "with a block" do |stig|
13
+ generator = stig.generator { 1 }
14
+
15
+ assert_equal generator.class, Proc
16
+ assert_equal generator.call, 1
17
+ end
18
+
19
+ test "with a block taking arguments" do |stig|
20
+ arguments = [:a, :b, :c]
21
+ generator = stig.generator(*arguments) { |*args| args }
22
+
23
+ assert_equal generator.call, arguments
24
+ end
25
+
26
+ test "with an object without a #random" do |stig|
27
+ assert_raise(ArgumentError) { stig.generator_for "no #random" }
28
+ end
29
+
30
+ test "with an object responding to #random" do |stig|
31
+ object = Object.new
32
+ object.define_singleton_method(:random) { 1 }
33
+
34
+ generator = stig.generator_for(object)
35
+
36
+ assert_equal generator.class, Proc
37
+ assert_equal generator.call, 1
38
+ end
39
+
40
+ test "with an object taking arguments" do |stig|
41
+ object = Object.new
42
+ object.define_singleton_method(:random) { |*args| args }
43
+
44
+ arguments = [:a, :b, :c]
45
+ generator = stig.generator_for(object, *arguments)
46
+
47
+ assert_equal generator.call, arguments
48
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/hash"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Hash }
8
+
9
+ test "takes a generator" do |mod|
10
+ keys = generator { rand }
11
+ values = generator { 1 }
12
+ generator = generator_for(mod, values)
13
+
14
+ property(generator, keys) do |hash, key|
15
+ assert_equal hash[key], 1
16
+
17
+ true
18
+ end
19
+ end
20
+
21
+ test "takes a generator and a list of keys" do |mod|
22
+ keys = [:a, :b, :c]
23
+ values = generator { 1 }
24
+ generator = generator_for(mod, values, *keys)
25
+
26
+ property(generator) do |hash|
27
+ assert_equal hash, :a => 1, :b => 1, :c => 1
28
+
29
+ true
30
+ end
31
+ end
32
+
33
+ test "doesn't take an invalid generator" do |mod|
34
+ assert_raise(ArgumentError) { mod.random(1) }
35
+ end
@@ -0,0 +1,35 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/integer"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Integer }
8
+
9
+ test "takes a maximum value" do |mod|
10
+ generator = generator_for(mod, 10)
11
+
12
+ property(generator) do |integer|
13
+ assert integer.between?(0, 10)
14
+
15
+ true
16
+ end
17
+ end
18
+
19
+ test "takes a range" do |mod|
20
+ generator = generator_for(mod, 5..10)
21
+
22
+ property(generator) do |integer|
23
+ assert integer.between?(5, 10)
24
+
25
+ true
26
+ end
27
+ end
28
+
29
+ test "defaults to Integers between 0 and 100" do |mod|
30
+ property(mod) do |integer|
31
+ assert integer.between?(0, 100)
32
+
33
+ true
34
+ end
35
+ end
@@ -0,0 +1,101 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+
4
+ GENERATOR = proc { 1 }
5
+ VERBOSITY = $VERBOSE
6
+
7
+ setup { Stig }
8
+
9
+ prepare do
10
+ $VERBOSE = VERBOSITY
11
+ $test = 0
12
+ end
13
+
14
+ test "no generators" do |stig|
15
+ assert_raise(ArgumentError) do
16
+ stig.property { true }
17
+ end
18
+ end
19
+
20
+ test "invalid generators" do |stig|
21
+ assert_raise(ArgumentError) do
22
+ stig.property("invalid", GENERATOR) { true }
23
+ end
24
+
25
+ assert_raise(ArgumentError) do
26
+ stig.property([].each) { true }
27
+ end
28
+ end
29
+
30
+ test "an object implementing #call as generator" do |stig|
31
+ generator = proc { 1 }
32
+
33
+ stig.property(generator) do |i|
34
+ assert_equal i, 1
35
+
36
+ true
37
+ end
38
+ end
39
+
40
+ test "an object implemeting #random as generator" do |stig|
41
+ generator = Object.new
42
+ generator.define_singleton_method(:random) { 1 }
43
+
44
+ stig.property(generator) do |i|
45
+ assert_equal i, 1
46
+
47
+ true
48
+ end
49
+ end
50
+
51
+ test "multiple generators" do |stig|
52
+ stig.property(GENERATOR, GENERATOR, GENERATOR) do |i,j,k|
53
+ assert_equal i, 1
54
+ assert_equal j, 1
55
+ assert_equal k, 1
56
+
57
+ true
58
+ end
59
+ end
60
+
61
+ test "no property" do |stig|
62
+ assert_raise(ArgumentError) { stig.property(GENERATOR) }
63
+ end
64
+
65
+ test "raises when a test fails" do |stig|
66
+ assert_raise(Stig::AssertionFailed) do
67
+ stig.property(GENERATOR) { false }
68
+ end
69
+ end
70
+
71
+ test "return true when all tests pass" do |stig|
72
+ assert stig.property(GENERATOR) { |i| true }
73
+ end
74
+
75
+ test "default number of runs" do |stig|
76
+ stig.property(GENERATOR) { $test += 1 }
77
+
78
+ assert_equal $test, 100
79
+ end
80
+
81
+ test "configure number of runs with constant" do |stig|
82
+ $VERBOSE = nil
83
+ stig::NUMBER_OF_RUNS = 2
84
+ $VERBOSE = VERBOSITY
85
+
86
+ stig.property(GENERATOR) { $test += 1 }
87
+
88
+ assert_equal $test, 2
89
+ end
90
+
91
+ test "configure number of runs with environment variable" do |stig|
92
+ ENV["STIG_NUMBER_OF_RUNS"] = "2"
93
+
94
+ $VERBOSE = nil
95
+ load "stig.rb"
96
+ $VERBOSE = VERBOSITY
97
+
98
+ stig.property(GENERATOR) { $test += 1 }
99
+
100
+ assert_equal $test, 2
101
+ end
@@ -0,0 +1,11 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+
4
+ test "doesn't pollute the global namespace" do
5
+ [Date, Float, Integer, String, Symbol, Time].each do |klass|
6
+ assert_equal klass.respond_to?(:random), false
7
+
8
+ # We just want this not to blow up.
9
+ Stig.property(klass) { true }
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/string"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::String }
8
+
9
+ test "defaults to all ASCII characters with maximum length 25" do |mod|
10
+ set = Stig::Generators::Character::ASCII
11
+
12
+ property(mod) do |string|
13
+ assert string.chars.all? { |char| set.include? char }
14
+
15
+ true
16
+ end
17
+
18
+ property(mod) do |string|
19
+ assert string.size.between?(0, 25)
20
+
21
+ true
22
+ end
23
+ end
24
+
25
+ test "takes character sets" do |mod|
26
+ generator = generator_for(mod, ["a"])
27
+
28
+ property(generator) do |string|
29
+ assert_equal string.class, String
30
+
31
+ true
32
+ end
33
+
34
+ property(generator) do |string|
35
+ assert [["a"], []].include?(string.chars.uniq)
36
+
37
+ true
38
+ end
39
+ end
40
+
41
+ test "doesn't take an empty character set" do |mod|
42
+ assert_raise(ArgumentError) { mod.random([]) }
43
+ end
44
+
45
+ test "takes a maximum length" do |mod|
46
+ generator = generator_for(mod, ["a"], 10)
47
+
48
+ property(generator) do |string|
49
+ assert string.size.between?(0, 10)
50
+
51
+ true
52
+ end
53
+ end
54
+
55
+ test "takes a range as length" do |mod|
56
+ generator = generator_for(mod, ["a"], 5..10)
57
+
58
+ property(generator) do |string|
59
+ assert string.size.between?(5, 10)
60
+
61
+ true
62
+ end
63
+ end
@@ -0,0 +1,63 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/symbol"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Symbol }
8
+
9
+ test "defaults to all ASCII characters with maximum length 25" do |mod|
10
+ set = Stig::Generators::Character::ASCII
11
+
12
+ property(mod) do |symbol|
13
+ assert symbol.to_s.chars.all? { |char| set.include? char }
14
+
15
+ true
16
+ end
17
+
18
+ property(mod) do |symbol|
19
+ assert symbol.size.between?(0, 25)
20
+
21
+ true
22
+ end
23
+ end
24
+
25
+ test "takes character sets" do |mod|
26
+ generator = generator_for(mod, ["a"])
27
+
28
+ property(generator) do |symbol|
29
+ assert_equal symbol.class, Symbol
30
+
31
+ true
32
+ end
33
+
34
+ property(generator) do |symbol|
35
+ assert [["a"], []].include?(symbol.to_s.chars.uniq)
36
+
37
+ true
38
+ end
39
+ end
40
+
41
+ test "doesn't take an empty character set" do |mod|
42
+ assert_raise(ArgumentError) { mod.random([]) }
43
+ end
44
+
45
+ test "takes a maximum length" do |mod|
46
+ generator = generator_for(mod, ["a"], 10)
47
+
48
+ property(generator) do |symbol|
49
+ assert symbol.size.between?(0, 10)
50
+
51
+ true
52
+ end
53
+ end
54
+
55
+ test "takes a range as length" do |mod|
56
+ generator = generator_for(mod, ["a"], 5..10)
57
+
58
+ property(generator) do |symbol|
59
+ assert symbol.size.between?(5, 10)
60
+
61
+ true
62
+ end
63
+ end
@@ -0,0 +1,34 @@
1
+ require_relative "../test_helper"
2
+ require "stig"
3
+ require "stig/generators/time"
4
+
5
+ include Stig
6
+
7
+ setup { Stig::Generators::Time }
8
+
9
+ test "defaults to dates between the UNIX epoch and \"now\"" do |mod|
10
+ range = Time.at(0)..Time.now
11
+
12
+ property(mod) do |time|
13
+ assert_equal time.class, Time
14
+
15
+ true
16
+ end
17
+
18
+ property(mod) do |time|
19
+ assert range.cover?(time)
20
+
21
+ true
22
+ end
23
+ end
24
+
25
+ test "takes a Range" do |mod|
26
+ range = Time.at(200)..Time.at(300)
27
+ generator = generator_for(mod, range)
28
+
29
+ property(generator) do |time|
30
+ assert range.cover?(time)
31
+
32
+ true
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stig
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jip van Reijsen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDhTCCAm2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1qaXB2
14
+ YW5yZWlqc2VuMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
15
+ FgNjb20wHhcNMTQwODIwMTcxOTMyWhcNMTUwODIwMTcxOTMyWjBEMRYwFAYDVQQD
16
+ DA1qaXB2YW5yZWlqc2VuMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
17
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsHlOk
18
+ 1hmzWghMsGRqmVXfBIYeJ6qZFOU9pYL+Zv7PkjqkC8O720+oXwMcANuT2IzHTdy+
19
+ rTEH8ctLioYGN5FI+lJPKsTtl3+KNwJdIP9h4W8t5RtxMTaPU1mI/jk6wKz2o2qy
20
+ u12J0cLKb7IWH19DAj2ZjAxmxQqTZsGt6VbAky2foZjo/x112wMSixzOEukW+O6W
21
+ fqBVnSjfOClhT+plelqlR5i1rz5YT6IL82D538AOU6tzLddH6XyHD+SygKpYKcV9
22
+ QUOXJGhTcUyA9WtgkaffIVlB5l4Ny6sT+CdEbI8N8htMziBjNcZul6/6CI+n0IDs
23
+ cJ4EorwzD5YXUAQzAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAd
24
+ BgNVHQ4EFgQUNWHVVURPyyrVLTYn664v3mAEXXQwIgYDVR0RBBswGYEXamlwdmFu
25
+ cmVpanNlbkBnbWFpbC5jb20wIgYDVR0SBBswGYEXamlwdmFucmVpanNlbkBnbWFp
26
+ bC5jb20wDQYJKoZIhvcNAQEFBQADggEBAEwhZPajKIKnMrZag4vojHM0KNiTFOFN
27
+ rKW875s0/ZQ0vZQ8XafR+9HPflRntkdGMoXG1Z48w1ocUGkeuqg8he4q3sjEPHXK
28
+ Jd3lAIrlZDIH5EBIUjzOWJz+vtH6LfPwl73sHJ8TZ/bxZnianWq4UMPIxQywfrba
29
+ vtLKKRzrUpWQP67o9e0yLrfIWUl8AkCpcqsHMfgAPwvgtv0e2Hqfo74uPZ/u5wll
30
+ WXFwPdOwdBBrxe80pFe980gybYXGDKG9qljoAy9n/Z09I0mLTqN+Qk3LyBfV9JpJ
31
+ GwazeZftMqpbXP5J5qZq3KDKKFABsUKmL68rdLwTA6BZBqPA2D063qs=
32
+ -----END CERTIFICATE-----
33
+ date: 2014-12-08 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: cutest
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.2'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.2'
49
+ description: Stig is a small library for property based testing in Ruby.
50
+ email: jipvanreijsen@gmail.com
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files:
54
+ - README.md
55
+ files:
56
+ - LICENSE
57
+ - README.md
58
+ - lib/stig.rb
59
+ - lib/stig/generators.rb
60
+ - lib/stig/generators/array.rb
61
+ - lib/stig/generators/character.rb
62
+ - lib/stig/generators/date.rb
63
+ - lib/stig/generators/float.rb
64
+ - lib/stig/generators/hash.rb
65
+ - lib/stig/generators/integer.rb
66
+ - lib/stig/generators/string.rb
67
+ - lib/stig/generators/symbol.rb
68
+ - lib/stig/generators/time.rb
69
+ - lib/stig/refinements.rb
70
+ - lib/stig/version.rb
71
+ - stig.gemspec
72
+ - test/README.md
73
+ - test/stig/array_generator.rb
74
+ - test/stig/character_generator.rb
75
+ - test/stig/date_generator.rb
76
+ - test/stig/float_generator.rb
77
+ - test/stig/generator.rb
78
+ - test/stig/hash_generator.rb
79
+ - test/stig/integer_generator.rb
80
+ - test/stig/property.rb
81
+ - test/stig/refinements.rb
82
+ - test/stig/string_generator.rb
83
+ - test/stig/symbol_generator.rb
84
+ - test/stig/time_generator.rb
85
+ - test/test_helper.rb
86
+ homepage: https://github.com/britishtea/stig
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '2.0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.2.2
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: simple test input generation
110
+ test_files: []
@@ -0,0 +1,2 @@
1
+ }�$�y��ɱ����{��tc�]`DoW��u ) �3�%�ɐM*fw�|)�}�zQ���������_n����i
2
+ Ҙ䣑5��(G=[A��I7�6�9�;��#���l:hXJ�����2�g�H��Ə�F�����;�䈬i#��G��+�7.���Ї������� u���]�R(��MՊK�%�DnX��r�����+��f/zA��T��$�6���߽�t_d��6�0�i�Z�x��.�9�