ddt 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.
- data/LICENSE +24 -0
- data/README.md +208 -0
- data/Rakefile +18 -0
- data/lib/ddt.rb +17 -0
- data/lib/truth_test/truth_test.rb +151 -0
- data/lib/version/version.rb +9 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/truth_test/truth_test_spec.rb +121 -0
- data/truths/cat/pet_truths.yaml +8 -0
- data/truths/dog/parse!_truths.yaml +5 -0
- metadata +59 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2012 Dan Swain
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
|
data/README.md
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
# DDT
|
2
|
+
|
3
|
+
Data driven testing for Ruby with RSpec. DDT kills bugs.
|
4
|
+
|
5
|
+
DDT is a plugin for RSpec that makes data-driven testing easy. It
|
6
|
+
allows you to define a [YAML](http://www.yaml.org/) file for a
|
7
|
+
specific method that includes test input and expected outputs. See
|
8
|
+
below for an example.
|
9
|
+
|
10
|
+
## License
|
11
|
+
|
12
|
+
DDT is released under the
|
13
|
+
[MIT license](http://en.wikipedia.org/wiki/MIT_License).
|
14
|
+
See the LICENSE file.
|
15
|
+
|
16
|
+
## Requirements
|
17
|
+
|
18
|
+
DDT requires RSpec because, well, it's an RSpec plugin. In the
|
19
|
+
future, I may make DDT more general and let the RSpec part be
|
20
|
+
optional.
|
21
|
+
|
22
|
+
DDT should work on any Ruby. It's only been tested on Ruby
|
23
|
+
1.9.3 so far, though.
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
If your system is set up to allow it, you can just do
|
28
|
+
|
29
|
+
gem install ddt
|
30
|
+
|
31
|
+
Or, if you prefer a more hands-on approach or want to hack at the source:
|
32
|
+
|
33
|
+
git clone git://github.com/simplifi/ddt.git
|
34
|
+
cd ddt
|
35
|
+
rake install
|
36
|
+
|
37
|
+
If you are working on a system where you need to `sudo gem install`
|
38
|
+
you can do
|
39
|
+
|
40
|
+
rake gem
|
41
|
+
sudo gem install ddt
|
42
|
+
|
43
|
+
As always, you can `rake -T` to find out what other rake tasks we have
|
44
|
+
provided.
|
45
|
+
|
46
|
+
## Basic Usage
|
47
|
+
|
48
|
+
Right now, `DDT::TruthTesting` that is the main workhorse of DDT.
|
49
|
+
`DDT::TruthTesting` adds some methods to RSpec to enable a truth
|
50
|
+
testing. `DDT::TruthTest` automates the process of creating an
|
51
|
+
object, calling a method on it with some specified input, and checking
|
52
|
+
the state of the object afterwords against what is expected, i.e., the
|
53
|
+
"truth". `DDT::TruthTest` defines a class called `Truth` for the
|
54
|
+
class under test; the `Truth` class encapsulates the input and
|
55
|
+
expected output.
|
56
|
+
|
57
|
+
This example and the others below are taken from
|
58
|
+
spec/truth\_test/truth\_test\_spec.rb
|
59
|
+
|
60
|
+
First, include ddt in your test suite. Probably this just means
|
61
|
+
adding `require 'ddt'` to your spec\_helper.rb
|
62
|
+
|
63
|
+
Suppose we have a classed called `Cat` that has a state called
|
64
|
+
`disposition` and a method called `pet`:
|
65
|
+
|
66
|
+
class Cat
|
67
|
+
attr_accessor :disposition
|
68
|
+
|
69
|
+
def initialize
|
70
|
+
@disposition = "mrow."
|
71
|
+
end
|
72
|
+
|
73
|
+
# cats are temperamental. my cat does not
|
74
|
+
# like to be petted on the belly, but she
|
75
|
+
# won't let you know until afterwords.
|
76
|
+
def pet how
|
77
|
+
predisposition = @disposition
|
78
|
+
if how =~ /belly/
|
79
|
+
@disposition = "*hiss*"
|
80
|
+
end
|
81
|
+
predisposition
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
We can write a truth testing spec file for `Cat#pet` like this:
|
86
|
+
|
87
|
+
describe Cat do
|
88
|
+
truth_test :pet
|
89
|
+
end
|
90
|
+
|
91
|
+
When we run rspec, DDT will look for a file called
|
92
|
+
`truths/cat/pet_truths.yaml` containing YAML test cases. Here's an
|
93
|
+
example:
|
94
|
+
|
95
|
+
---
|
96
|
+
input: "on the head"
|
97
|
+
output: "mrow."
|
98
|
+
disposition: "mrow."
|
99
|
+
---
|
100
|
+
input: "on the belly"
|
101
|
+
output: "mrow."
|
102
|
+
disposition: "*hiss*"
|
103
|
+
|
104
|
+
For each of these test cases, `DDT::TruthTest` will create a new `Cat`
|
105
|
+
instance and call the `pet` method with "input" as the argument. It
|
106
|
+
then does an RSpec example that looks something like
|
107
|
+
|
108
|
+
cat.pet("on the head").should == "mrow."
|
109
|
+
|
110
|
+
as well as
|
111
|
+
|
112
|
+
cat.disposition.should == "mrow."
|
113
|
+
|
114
|
+
## Mapping test data
|
115
|
+
|
116
|
+
`DDT::TruthTest` lets us map test data using
|
117
|
+
`Object::define_truth`, which takes as arguments an instance of the
|
118
|
+
object under test and a hash corresponding to the YAML test case. As
|
119
|
+
an example, consider the `Dog` class here:
|
120
|
+
|
121
|
+
class Dog
|
122
|
+
attr_accessor :name, :weight, :age
|
123
|
+
|
124
|
+
def parse! str
|
125
|
+
d = str.split(",")
|
126
|
+
@name = d[0]
|
127
|
+
@weight = d[1].to_f
|
128
|
+
@age = d[2].to_i
|
129
|
+
self
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# example:
|
134
|
+
rover = Dog.new.parse! "rover", 31.5, 5
|
135
|
+
rover.name # => "rover"
|
136
|
+
rover.weight # => 31.5
|
137
|
+
rover.age # => 5
|
138
|
+
|
139
|
+
In our test data, the weight needs to be converted to a float and the
|
140
|
+
age needs to be converted to an int, so we'll manually add some
|
141
|
+
conversions to our truth class:
|
142
|
+
|
143
|
+
Dog::define_truth do |dog, data|
|
144
|
+
# make age an integer
|
145
|
+
dog.age = data["age"].to_i
|
146
|
+
|
147
|
+
# make weight a float
|
148
|
+
dog.weight = data["weight"].to_f
|
149
|
+
end
|
150
|
+
|
151
|
+
We can then define truths for `Dog#parse!` in
|
152
|
+
`truths/dog/parse\!_truths.yaml` (note the `\!`):
|
153
|
+
|
154
|
+
---
|
155
|
+
input: "Fido, 30.0, 3"
|
156
|
+
name: "Fido"
|
157
|
+
weight: 30.0
|
158
|
+
age: 3
|
159
|
+
|
160
|
+
And test in RSpec:
|
161
|
+
|
162
|
+
describe Dog do
|
163
|
+
truth_test :parse!
|
164
|
+
end
|
165
|
+
|
166
|
+
Note, in the `Cat` example above, `Cat::define_truth` is called
|
167
|
+
automatically by `truth_test`.
|
168
|
+
|
169
|
+
## Specifying the test instance
|
170
|
+
|
171
|
+
The `Truth` class also provides a method called `Truth#tester` that
|
172
|
+
supplies the instance to test. By default, `Object#new` is called
|
173
|
+
with no arguments to supply the instance. This method can be overridden to
|
174
|
+
specify other arguments:
|
175
|
+
|
176
|
+
class Wolf
|
177
|
+
attr_accessor :call
|
178
|
+
def initialize call
|
179
|
+
@call = call
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# we have to first create the truth class
|
184
|
+
Wolf::define_truth
|
185
|
+
|
186
|
+
# then we can monkey patch the tester method
|
187
|
+
class Wolf::Truth
|
188
|
+
def tester
|
189
|
+
self.class.tester || Wolf.new("AOOOO")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
It's also possible to use RSpec's stubbing to do this:
|
194
|
+
|
195
|
+
Wolf::Truth.should_receive(:tester).and_return(Wolf.new "draw blood")
|
196
|
+
|
197
|
+
## Contributing
|
198
|
+
|
199
|
+
The usual github process applies here:
|
200
|
+
|
201
|
+
1. Fork it
|
202
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
203
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
204
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
205
|
+
5. Create new Pull Request
|
206
|
+
|
207
|
+
You can also contribute to the author's ego by letting him know that
|
208
|
+
you find String Eater useful ;)
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
|
3
|
+
project_name = "ddt"
|
4
|
+
|
5
|
+
desc "Run rspec spec/ (compile if needed)"
|
6
|
+
task :test do
|
7
|
+
sh "rspec spec/"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Create gem"
|
11
|
+
task :gem => "#{project_name}.gemspec" do
|
12
|
+
sh "gem build #{project_name}.gemspec"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Install using 'gem install'"
|
16
|
+
task :install => :gem do
|
17
|
+
sh "gem install #{project_name}"
|
18
|
+
end
|
data/lib/ddt.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# defines DDT::TruthTest
|
2
|
+
require 'truth_test/truth_test'
|
3
|
+
|
4
|
+
module DDT
|
5
|
+
autoload :VERSION, 'version/version'
|
6
|
+
|
7
|
+
# copied from ActiveSupport
|
8
|
+
def underscore string
|
9
|
+
string.gsub(/::/, '/').
|
10
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
11
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
12
|
+
tr("-", "_").
|
13
|
+
downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
module_function :underscore
|
17
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class Object
|
5
|
+
def self.define_truth &block
|
6
|
+
DDT::TruthTest::define_truth_for self, &block
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
# @private
|
11
|
+
module DDT
|
12
|
+
module TruthTest
|
13
|
+
|
14
|
+
def define_truth_for the_klass, &block
|
15
|
+
klass = Class.new
|
16
|
+
|
17
|
+
klass.class_eval do
|
18
|
+
# defined so we can override it with should_receive
|
19
|
+
def self.tester
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_accessor :input, :output
|
24
|
+
end
|
25
|
+
|
26
|
+
if block_given?
|
27
|
+
pblock = block
|
28
|
+
else
|
29
|
+
pblock = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# this is a bit of trickery to get at the private method
|
33
|
+
# :define_method and also allow access to the_klass
|
34
|
+
klass.send(:define_method, :initialize) do |data={}|
|
35
|
+
data.each_pair do |attr, value|
|
36
|
+
instance_variable_set "@#{attr}", value
|
37
|
+
self.class.send(:attr_accessor, attr.to_sym)
|
38
|
+
end
|
39
|
+
|
40
|
+
instance_variable_set "@input", data["input"]
|
41
|
+
(instance_variable_set "@output", data["output"]) if data["output"]
|
42
|
+
|
43
|
+
if pblock
|
44
|
+
pblock.call(self, data)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
klass.send(:define_method, :tester) do
|
49
|
+
self.class.send(:tester) || the_klass.new
|
50
|
+
end
|
51
|
+
|
52
|
+
the_klass.const_set "Truth", klass
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
module_function :define_truth_for
|
57
|
+
|
58
|
+
class RSpec::Core::ExampleGroup
|
59
|
+
|
60
|
+
# Declare a truth test for a method of the class being described.
|
61
|
+
# If the class did not have define_truth called, it will be
|
62
|
+
# called automatically with no arguments.
|
63
|
+
#
|
64
|
+
# Example
|
65
|
+
# # truths/foo/do_stuff_truths.yaml
|
66
|
+
# ---
|
67
|
+
# input: blah
|
68
|
+
# bar: baz blah
|
69
|
+
# ---
|
70
|
+
# input: bam
|
71
|
+
# bar: baz bam
|
72
|
+
#
|
73
|
+
# # foo.rb
|
74
|
+
# class Foo
|
75
|
+
# attr_accessor :bar
|
76
|
+
#
|
77
|
+
# def do_stuff input
|
78
|
+
# @bar = "baz #{input}"
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# # foo_spec.rb
|
83
|
+
# Foo.define_truth
|
84
|
+
#
|
85
|
+
# describe Foo do
|
86
|
+
# truth_test :do_stuff
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# opts can either be an options hash or a filename in which to find the
|
90
|
+
# truth data. If opts is a hash and it includes :data as a key, the
|
91
|
+
# value of opts :data is a string to be parsed as YAML. If opts
|
92
|
+
# includes the :truth_file, then that file is used for truth (same
|
93
|
+
# as using a string instead of a hash).
|
94
|
+
#
|
95
|
+
# If no input is specified (i.e., if opts is omitted), then truth_test will
|
96
|
+
# look for a yaml file called ./truths/class_name/method_truths.yaml
|
97
|
+
# (class_name in snake case a la Rails).
|
98
|
+
def self.truth_test method, opts={}
|
99
|
+
unless described_class.const_defined?("Truth")
|
100
|
+
described_class.define_truth
|
101
|
+
end
|
102
|
+
|
103
|
+
if (opts.is_a? Hash) && opts[:data]
|
104
|
+
data = opts[:data]
|
105
|
+
else
|
106
|
+
filename = opts if opts.is_a? String
|
107
|
+
filename ||= (opts[:truth_file] || "./truths/#{DDT::underscore(described_class.name)}/#{method}_truths.yaml")
|
108
|
+
data = File.open(filename, "rb")
|
109
|
+
end
|
110
|
+
|
111
|
+
run_truth_test method, data
|
112
|
+
ensure
|
113
|
+
data.close if data.is_a? File
|
114
|
+
end
|
115
|
+
|
116
|
+
# @private
|
117
|
+
def self.run_truth_test method, data
|
118
|
+
truth_count = -1
|
119
|
+
YAML::load_documents(data).each do |datum|
|
120
|
+
truth_count += 1
|
121
|
+
truth = described_class::Truth.new datum
|
122
|
+
|
123
|
+
# don't use the value because we might want nil input
|
124
|
+
unless datum.has_key?("input")
|
125
|
+
puts "Skipping truth datum #{truth_count} with no input..."
|
126
|
+
next
|
127
|
+
end
|
128
|
+
|
129
|
+
if truth.output
|
130
|
+
it "should respond to '#{method}(#{truth.input})' with '#{truth.output}'" do
|
131
|
+
truth.tester.send(method, truth.input).should == truth.output
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# already tested these
|
136
|
+
datum.delete("input")
|
137
|
+
datum.delete("output")
|
138
|
+
|
139
|
+
datum.each_key do |attr|
|
140
|
+
it "when the input is '#{truth.input}', calling '#{attr}' should return '#{truth.send(attr)}'" do
|
141
|
+
obj = truth.tester
|
142
|
+
obj.send(method, truth.input)
|
143
|
+
obj.send(attr).should == truth.send(attr)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
Dog_attrs = [:name, :weight, :age]
|
4
|
+
|
5
|
+
# A class to test with
|
6
|
+
class Dog
|
7
|
+
attr_accessor *Dog_attrs
|
8
|
+
|
9
|
+
def parse! str
|
10
|
+
d = str.split(",")
|
11
|
+
@name = d[0]
|
12
|
+
@weight = d[1].to_f
|
13
|
+
@age = d[2].to_i
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Dog::define_truth do |dog, data|
|
19
|
+
# make age an integer
|
20
|
+
dog.age = data["age"].to_i
|
21
|
+
|
22
|
+
# make weight a float
|
23
|
+
dog.weight = data["weight"].to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
# we'll automatically generate a truth class for this
|
27
|
+
class Cat
|
28
|
+
attr_accessor :disposition
|
29
|
+
|
30
|
+
def initialize
|
31
|
+
@disposition = "mrow."
|
32
|
+
end
|
33
|
+
|
34
|
+
# cats are temperamental. my cat does not
|
35
|
+
# like to be petted on the belly, but she
|
36
|
+
# won't let you know until afterwords.
|
37
|
+
def pet how
|
38
|
+
predisposition = @disposition
|
39
|
+
if how =~ /belly/
|
40
|
+
@disposition = "*hiss*"
|
41
|
+
end
|
42
|
+
predisposition
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# a class that we'll define a specific tester for
|
47
|
+
class Wolf
|
48
|
+
attr_accessor :call
|
49
|
+
def initialize call
|
50
|
+
@call = call
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Wolf::define_truth
|
55
|
+
|
56
|
+
class Wolf::Truth
|
57
|
+
def tester
|
58
|
+
self.class.tester || Wolf.new("AOOOO")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe DDT::TruthTest do
|
63
|
+
it "should create a Truth class under Dog" do
|
64
|
+
Dog::Truth.should respond_to(:new)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should create an input attr_accessor" do
|
68
|
+
Dog::Truth.new.should respond_to(:input)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should create an output attr_accessor" do
|
72
|
+
Dog::Truth.new.should respond_to(:output)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should create a tester method" do
|
76
|
+
Dog::Truth.new.should respond_to(:tester)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should respond to tester with an instance of Dog" do
|
80
|
+
Dog::Truth.new.tester.class.should == Dog
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should allow us to set the tester method" do
|
84
|
+
Wolf::Truth.new.tester.call.should == "AOOOO"
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should allow us to override the tester method by intercepting Truth::tester" do
|
88
|
+
Wolf::Truth.should_receive(:tester).and_return(Wolf.new "draw blood")
|
89
|
+
Wolf::Truth.new.tester.call.should == "draw blood"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# this way we know that a truth was automatically defined
|
94
|
+
describe Cat do
|
95
|
+
truth_test :pet
|
96
|
+
end
|
97
|
+
|
98
|
+
# tests for truth_test
|
99
|
+
describe Dog do
|
100
|
+
Group = self
|
101
|
+
|
102
|
+
it "should not raise an error if we try to add a truth test" do
|
103
|
+
Group.should_receive(:run_truth_test)
|
104
|
+
Group.truth_test :parse!
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should raise an error if the truth file does not exist" do
|
108
|
+
lambda do
|
109
|
+
Group.truth_test :parse!, "nonexistent.yaml"
|
110
|
+
end.should raise_error
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should allow us to specify YAML directly" do
|
114
|
+
yaml = "input: foo"
|
115
|
+
Group.should_receive(:run_truth_test).with(:parse!, yaml)
|
116
|
+
Group.truth_test :parse!, :data => yaml
|
117
|
+
end
|
118
|
+
|
119
|
+
# test that we actually can run the test
|
120
|
+
truth_test :parse!
|
121
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ddt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Swain
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-27 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: DDT automates data driven testing. Test data is read from a YAML file.
|
15
|
+
email:
|
16
|
+
- dan@simpli.fi
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/ddt.rb
|
22
|
+
- lib/truth_test/truth_test.rb
|
23
|
+
- lib/version/version.rb
|
24
|
+
- spec/spec_helper.rb
|
25
|
+
- spec/truth_test/truth_test_spec.rb
|
26
|
+
- truths/cat/pet_truths.yaml
|
27
|
+
- truths/dog/parse!_truths.yaml
|
28
|
+
- LICENSE
|
29
|
+
- Rakefile
|
30
|
+
- README.md
|
31
|
+
homepage: http://github.com/simplifi/ddt
|
32
|
+
licenses: []
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
requirements: []
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.8.24
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: Data driven testing for Ruby with RSpec. DDT kills bugs.
|
55
|
+
test_files:
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
- spec/truth_test/truth_test_spec.rb
|
58
|
+
- truths/cat/pet_truths.yaml
|
59
|
+
- truths/dog/parse!_truths.yaml
|