rspec-apigen 0.0.1
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/README.rdoc +186 -0
- data/lib/rspec-apigen/apigen.rb +114 -0
- data/lib/rspec-apigen/argument.rb +38 -0
- data/lib/rspec-apigen/config.rb +5 -0
- data/lib/rspec-apigen/fixture.rb +25 -0
- data/lib/rspec-apigen/formatter.rb +56 -0
- data/lib/rspec-apigen/given.rb +91 -0
- data/lib/rspec-apigen/meta_helper.rb +14 -0
- data/lib/rspec-apigen/method.rb +14 -0
- data/lib/rspec-apigen/version.rb +6 -0
- data/lib/rspec-apigen/version.rb~ +3 -0
- data/lib/rspec-apigen.rb +8 -0
- metadata +91 -0
data/README.rdoc
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
== What is this ?
|
2
|
+
|
3
|
+
A tool that generates an API documentation using RSpec and some DSL magic.
|
4
|
+
If successful I might use it for my own project (neo4j.rb)
|
5
|
+
<b>This is an early experiment !</b>
|
6
|
+
|
7
|
+
=== How ?
|
8
|
+
|
9
|
+
Instead of writing specs like this:
|
10
|
+
|
11
|
+
describe Account do
|
12
|
+
context "transfering money" do
|
13
|
+
it "deposits transfer amount to the other account" do
|
14
|
+
source = Account.new(50, :USD)
|
15
|
+
target = mock('target account')
|
16
|
+
target.should_receive(:deposit).with(Money.new(5, :USD))
|
17
|
+
source.transfer(5, :USD).to(target)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "reduces its balance by the transfer amount" do
|
21
|
+
source = Account.new(50, :USD)
|
22
|
+
target = stub('target account')
|
23
|
+
source.transfer(5, :USD).to(target)
|
24
|
+
source.balance.should == Money.new(45, :USD)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
Which generates the following output
|
30
|
+
|
31
|
+
$ spec ./spec/account_spec.rb --format nested
|
32
|
+
Account
|
33
|
+
transfering money
|
34
|
+
deposits transfer amount to the other account
|
35
|
+
reduces its balance by the transfer amount
|
36
|
+
|
37
|
+
2 examples, 0 failures
|
38
|
+
|
39
|
+
I (also) want to generate a detailed API documentation something like this from a RSpec Macro DSL:
|
40
|
+
Account
|
41
|
+
Public Static Methods
|
42
|
+
#new ()
|
43
|
+
Given
|
44
|
+
no arguments
|
45
|
+
Then
|
46
|
+
Return Account with 0 USD
|
47
|
+
has #balance == 0
|
48
|
+
has #currency == 'USD
|
49
|
+
#new (amount,currency)
|
50
|
+
Scenario account and currency has valid values
|
51
|
+
Given
|
52
|
+
arguments 50, USD
|
53
|
+
Then
|
54
|
+
Return an Account with given amount and currency
|
55
|
+
should == 50
|
56
|
+
should == "USD"
|
57
|
+
Public Instance Methods
|
58
|
+
#transfer (amount,currency)
|
59
|
+
Scenario transfer amount and currency have valid values
|
60
|
+
Given
|
61
|
+
arguments 5, USD
|
62
|
+
Then
|
63
|
+
should not change subject
|
64
|
+
Return A transfer of 5 USD from Account with 50 USD
|
65
|
+
should be a kind of TransferDSL
|
66
|
+
Finished in 0.00412 seconds
|
67
|
+
9 examples, 0 failures
|
68
|
+
|
69
|
+
TransferDSL
|
70
|
+
Public Static Methods
|
71
|
+
#new (source_account,amount,currency)
|
72
|
+
Given
|
73
|
+
arguments Account balance: 50 USD, 5, USD
|
74
|
+
Then
|
75
|
+
Return An TransferDSL instance with initialized source account, amount and currency
|
76
|
+
should == 50
|
77
|
+
Public Instance Methods
|
78
|
+
#to (target_account)
|
79
|
+
Given
|
80
|
+
arguments Account balance: 10 USD
|
81
|
+
Then it should add money on the target account
|
82
|
+
should add money to the target account
|
83
|
+
|
84
|
+
Finished in 0.00225 seconds
|
85
|
+
4 examples, 0 failures
|
86
|
+
|
87
|
+
The above is generated from the following RSpec file:
|
88
|
+
|
89
|
+
describe Account do
|
90
|
+
|
91
|
+
static_methods do
|
92
|
+
new do
|
93
|
+
Return("Account with 0 USD") do
|
94
|
+
# it_behaves_like "Account with 0 USD" can also be used
|
95
|
+
it("has #balance == 0") { subject.balance.should == 0 }
|
96
|
+
it("has #currency == 'USD") { subject.currency.should == 'USD' }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
new(arg(:amount), arg(:currency)) do
|
101
|
+
Scenario 'account and currency has valid values' do
|
102
|
+
Given do
|
103
|
+
arg.amount = 50
|
104
|
+
arg.currency = 'USD'
|
105
|
+
end
|
106
|
+
|
107
|
+
Return "an Account with given amount and currency" do
|
108
|
+
it { subject.balance.should == 50 } #given.amount }
|
109
|
+
it { subject.currency.should == 'USD' } # given.currency }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
instance_methods do
|
116
|
+
transfer(arg(:amount), arg(:currency)) do
|
117
|
+
# Description 'bla bla bla'
|
118
|
+
Scenario 'transfer amount and currency have valid values' do
|
119
|
+
subject { Account.new(50, 'USD') }
|
120
|
+
Given do
|
121
|
+
arg.amount = 5
|
122
|
+
arg.currency = 'USD'
|
123
|
+
end
|
124
|
+
Return "A transfer of 5 USD from Account with 50 USD" do
|
125
|
+
it { should be_kind_of(TransferDSL) }
|
126
|
+
end
|
127
|
+
Then do
|
128
|
+
it "should not change subject" do
|
129
|
+
given.subject.balance.should == subject.balance
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
describe TransferDSL do
|
139
|
+
static_methods do
|
140
|
+
new(arg(:source_account) do
|
141
|
+
Given do
|
142
|
+
arg.source_account = Account.new(50, 'USD')
|
143
|
+
end
|
144
|
+
Returns("A Transfer DSL with the given source account") do
|
145
|
+
it {subject.source_account.should == given.source_account}
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
instance_methods do
|
151
|
+
to(arg(:target_account, arg(:amount), arg(:currency)) do
|
152
|
+
Scenario 'source account has enough money' do
|
153
|
+
Given do
|
154
|
+
arg.target_account = Account.new(50, 'USD')
|
155
|
+
arg.amount = 5
|
156
|
+
arg.currency = 'USD'
|
157
|
+
subject{TransferDSL.new(Account.new(50, 'USD')}
|
158
|
+
end
|
159
|
+
|
160
|
+
# the following line describes the subject's source_account method
|
161
|
+
Then "it added money to the target account" do
|
162
|
+
it { subject.target_account.amount.should == given.arg.source_account.amount + given.arg.amount }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
Scenario 'source account does NOT have enough money' do
|
167
|
+
Given do
|
168
|
+
arg.target_account = Account.new(50, 'USD')
|
169
|
+
arg.amount = 100
|
170
|
+
arg.currency = 'USD'
|
171
|
+
subject{TransferDSL.new(Account.new(10, 'USD')}
|
172
|
+
end
|
173
|
+
Throws(Error)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
TODO: I will implement a new RSpec HTML formatter which will generate something similar to RDoc. I want
|
181
|
+
to write specification in my rspec code instead of using RDoc.
|
182
|
+
|
183
|
+
|
184
|
+
=== Example
|
185
|
+
gem install rspec --prerelease (2.0.0.beta.19)
|
186
|
+
rspec -f d -c spec
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module RSpec::ApiGen
|
2
|
+
|
3
|
+
def run_scenario(method, args, block)
|
4
|
+
# have we defined any scenarios ?
|
5
|
+
MetaHelper.create_singleton_method(self, :Scenario) do |*scenario_desc, &scenario_block|
|
6
|
+
context "Scenario #{scenario_desc[0]}" do
|
7
|
+
run_scenario(method, args, scenario_block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# create method to set the describe_return variable
|
12
|
+
describe_return = nil
|
13
|
+
MetaHelper.create_singleton_method(self, :Return) do |*example_desc, &example|
|
14
|
+
describe_return = {:example => example, :example_desc => example_desc}
|
15
|
+
end
|
16
|
+
|
17
|
+
# create method to set the given_block variable
|
18
|
+
given_block = nil
|
19
|
+
given_caller = nil # so that we can print correct line number if there is an exception
|
20
|
+
MetaHelper.create_singleton_method(self, :Given) { |*a, &b| given_block = b; given_caller = b.send(:caller)}
|
21
|
+
|
22
|
+
MetaHelper.create_singleton_method(self, :Description) { |desc| context(desc){} }
|
23
|
+
|
24
|
+
|
25
|
+
# create method to set the given_block variable
|
26
|
+
then_block = nil
|
27
|
+
then_desc = nil
|
28
|
+
MetaHelper.create_singleton_method(self, :Then) { |*desc, &b| then_block = b; then_desc = desc[0] if desc.size > 0}
|
29
|
+
|
30
|
+
# eval and set the given_block and describe_return variables
|
31
|
+
self.instance_eval(&block)
|
32
|
+
|
33
|
+
# if there are no then_block or describe_return then there is nothing to do
|
34
|
+
return if describe_return.nil? && then_block.nil? && then_desc.nil?
|
35
|
+
|
36
|
+
given = nil
|
37
|
+
context "Given" do
|
38
|
+
given = Given.new(self, method, args, given_caller, &given_block)
|
39
|
+
end
|
40
|
+
|
41
|
+
# todo should be possible to have several Then
|
42
|
+
context "Then #{then_desc}" do
|
43
|
+
self.send(:define_method, :given) { given }
|
44
|
+
self.send(:define_method, :arg) { given.arg }
|
45
|
+
self.send(:define_method, :fixtures) { given.fixtures }
|
46
|
+
|
47
|
+
|
48
|
+
# use the same subject as we used when calling the method on it in the given block
|
49
|
+
# self.send(:define_method, :subject) { given.subject }
|
50
|
+
|
51
|
+
context "Return #{describe_return[:example_desc][0]}" do
|
52
|
+
subject { given.return }
|
53
|
+
|
54
|
+
self.instance_eval(&describe_return[:example])
|
55
|
+
end if describe_return
|
56
|
+
|
57
|
+
self.instance_eval(&then_block) if then_block
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_scenarios_for(method, param, &block)
|
62
|
+
args = param[:args]
|
63
|
+
context "##{method}", Argument.describe(args) do
|
64
|
+
run_scenario(method, args, block)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def static_methods(&block)
|
70
|
+
clazz = describes
|
71
|
+
describe "Public Static Methods" do
|
72
|
+
static_context = Method.new
|
73
|
+
|
74
|
+
# TODO - how do I find which methods was defined on the clazz and not inherited ?
|
75
|
+
def_methods = clazz.public_methods - Object.methods + %w[new]
|
76
|
+
current_context = self
|
77
|
+
|
78
|
+
# add methods on the context - one for each public static method
|
79
|
+
def_methods.each do |meth_name|
|
80
|
+
MetaHelper.create_singleton_method(static_context, meth_name) do |*args, &example_group|
|
81
|
+
current_context.subject { clazz }
|
82
|
+
current_context.create_scenarios_for(meth_name, :args => args, &example_group)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
static_context.instance_eval(&block)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def instance_methods(&block)
|
90
|
+
clazz = describes
|
91
|
+
describe "Public Instance Methods" do
|
92
|
+
# Check if we are testing a module - in that case construct a new class that includes that Module
|
93
|
+
# so that we can test this Module
|
94
|
+
subject do
|
95
|
+
x = Class.new
|
96
|
+
x.send(:include, clazz)
|
97
|
+
x.new
|
98
|
+
end if clazz.class == Module
|
99
|
+
|
100
|
+
meth_ctx = Method.new
|
101
|
+
|
102
|
+
# TODO - how do I find which methods was defined on the clazz and not inherited ?
|
103
|
+
def_methods = clazz.public_instance_methods - Object.public_instance_methods
|
104
|
+
current_context = self
|
105
|
+
def_methods.each do |meth_name|
|
106
|
+
MetaHelper.create_singleton_method(meth_ctx, meth_name) do |*args, &example_group|
|
107
|
+
current_context.create_scenarios_for(meth_name, :args => args, &example_group)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
meth_ctx.instance_eval(&block)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RSpec::ApiGen
|
2
|
+
class Argument
|
3
|
+
attr_reader :name, :description
|
4
|
+
|
5
|
+
def initialize(name, description, accept_block = false)
|
6
|
+
@name = name
|
7
|
+
@description = description
|
8
|
+
@accept_block = accept_block
|
9
|
+
end
|
10
|
+
|
11
|
+
def accept_block?
|
12
|
+
@accept_block
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"Arg #{name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.inspect_args(args)
|
20
|
+
args.collect do |x|
|
21
|
+
case x
|
22
|
+
when Argument
|
23
|
+
x.name
|
24
|
+
when RSpec::Mocks::Mock
|
25
|
+
x.instance_variable_get('@name')
|
26
|
+
else
|
27
|
+
"#{x}:#{x.class}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.describe(args)
|
33
|
+
"(#{inspect_args(args).join(', ')})"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RSpec::ApiGen
|
2
|
+
class Fixture
|
3
|
+
attr_reader :description
|
4
|
+
attr_reader :create_proc
|
5
|
+
attr_reader :destroy_proc
|
6
|
+
|
7
|
+
#def initialize(description, create_proc, destroy_proc = nil)
|
8
|
+
def initialize(description, &block)
|
9
|
+
@description = description && ""
|
10
|
+
|
11
|
+
# initialize this instance
|
12
|
+
self.instance_eval &block
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(&block)
|
16
|
+
block.nil? ? @create_proc.call : @create_proc = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy(&block)
|
20
|
+
block.nil? ? @destroy_proc.call : @destroy_proc = block
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module RSpec::ApiGen
|
2
|
+
class Formatter
|
3
|
+
def method_missing(m, *a, &b)
|
4
|
+
puts "CALLED #{m}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize(output )
|
8
|
+
end
|
9
|
+
|
10
|
+
def start(example_count)
|
11
|
+
puts "start #{example_count}"
|
12
|
+
@current_method = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def example_group_started(example_group)
|
16
|
+
# is it a new class ?
|
17
|
+
if @current_class != example_group.describes
|
18
|
+
@current_class = example_group.describes
|
19
|
+
@current_method = nil
|
20
|
+
puts "#{@current_class.class} #{example_group.describes}"
|
21
|
+
elsif example_group.description == "Public Static Methods"
|
22
|
+
puts " Static Static Methods"
|
23
|
+
elsif example_group.description == "Public Instance Methods"
|
24
|
+
puts " Static Instance Methods"
|
25
|
+
elsif @current_method
|
26
|
+
puts " #{example_group.description}"
|
27
|
+
else
|
28
|
+
puts " Method #{example_group.description}"
|
29
|
+
@current_method = example_group.description
|
30
|
+
end
|
31
|
+
# puts "example_groupstarted #{example_group.describes.class} #{example_group.describes.object_id} #{example_group.description}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_dump
|
35
|
+
puts "start dump"
|
36
|
+
end
|
37
|
+
|
38
|
+
def example_started(example)
|
39
|
+
end
|
40
|
+
|
41
|
+
def example_passed(example)
|
42
|
+
puts " #{example.metadata[:description]}"
|
43
|
+
#puts " #{example.pretty_inspect}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def example_failed(example)
|
47
|
+
puts "failed"
|
48
|
+
end
|
49
|
+
|
50
|
+
def example_pending(example)
|
51
|
+
puts "pending"
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module RSpec::ApiGen
|
2
|
+
class Given
|
3
|
+
attr_reader :args # contains name of argument and its value
|
4
|
+
attr_reader :arg # the DSL object used to set the args
|
5
|
+
attr_reader :fixtures
|
6
|
+
attr_accessor :subject
|
7
|
+
attr_accessor :return
|
8
|
+
|
9
|
+
|
10
|
+
# list_of_args - the list of arguments current method accept
|
11
|
+
# When the given block is evaluated in this method
|
12
|
+
# the Given#args will return a hash of name or argument and its value.
|
13
|
+
def initialize(context, method, list_of_args, given_caller, &block)
|
14
|
+
this = self # so we can access it as closure
|
15
|
+
@arg = Object.new
|
16
|
+
@args = {}
|
17
|
+
@fixtures = {}
|
18
|
+
block_arg = nil
|
19
|
+
|
20
|
+
list_of_args.find_all { |a| a.kind_of?(Argument) }.each do |a|
|
21
|
+
MetaHelper.create_singleton_method(@arg, "#{a.name}=") do |val|
|
22
|
+
this.args[a.name] = val
|
23
|
+
end
|
24
|
+
if (a.accept_block?)
|
25
|
+
MetaHelper.create_singleton_method(@arg, "#{a.name}") do | &bl |
|
26
|
+
block_arg = bl
|
27
|
+
end
|
28
|
+
else
|
29
|
+
MetaHelper.create_singleton_method(@arg, "#{a.name}") do
|
30
|
+
this.args[a.name]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context.it "no arguments" do
|
36
|
+
# create the arguments
|
37
|
+
MetaHelper.create_singleton_method(self, :arg) { this.arg }
|
38
|
+
|
39
|
+
# accessor for setting fixture
|
40
|
+
MetaHelper.create_singleton_method(self, :fixtures) { this.fixtures }
|
41
|
+
|
42
|
+
begin
|
43
|
+
self.instance_eval &block
|
44
|
+
rescue Exception => e
|
45
|
+
this.set_backtrace(example, e, given_caller)
|
46
|
+
end if block
|
47
|
+
|
48
|
+
list_of_args.delete_if { |a| a.kind_of?(Argument) && a.accept_block? }
|
49
|
+
|
50
|
+
# now, the args hash should have been populated
|
51
|
+
# for each param we replace the args with the real value
|
52
|
+
list_of_args.collect! { |a| a.kind_of?(Argument) ? this.args[a.name] : a }
|
53
|
+
|
54
|
+
example.metadata[:description] = "arguments #{Argument.describe(list_of_args)}" unless list_of_args.empty?
|
55
|
+
|
56
|
+
# get the subject which we will use to test the method on, and store it so we can check it
|
57
|
+
this.subject = subject
|
58
|
+
|
59
|
+
begin
|
60
|
+
example.execution_result[:exception_encountered] = given_caller
|
61
|
+
|
62
|
+
if (block_arg)
|
63
|
+
# call the method on this instance which will will test
|
64
|
+
this.return = this.subject.send(method, *list_of_args, &block_arg)
|
65
|
+
else
|
66
|
+
this.return = this.subject.send(method, *list_of_args)
|
67
|
+
end
|
68
|
+
rescue Exception => e
|
69
|
+
this.set_backtrace(example, e, given_caller)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_backtrace(example, e, given_caller)
|
76
|
+
trace = e.backtrace
|
77
|
+
|
78
|
+
# TODO very ugly - don't know how to filter rspec own backtrace
|
79
|
+
# remove all lines containing ../lib/rspec
|
80
|
+
trace.delete_if {|line| line =~ /\/lib\/rspec\//}
|
81
|
+
trace.delete_if {|line| line =~ /\/rubygems\/custom_require/}
|
82
|
+
trace.delete_if {|line| line =~ /\/bin\/rspec/}
|
83
|
+
|
84
|
+
bt = trace + given_caller
|
85
|
+
e.set_backtrace(bt)
|
86
|
+
example.set_exception(e)
|
87
|
+
example.execution_result[:exception_encountered] = bt
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/lib/rspec-apigen.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'rspec-apigen/meta_helper'
|
2
|
+
require 'rspec-apigen/apigen'
|
3
|
+
require 'rspec-apigen/method'
|
4
|
+
require 'rspec-apigen/argument'
|
5
|
+
require 'rspec-apigen/fixture'
|
6
|
+
require 'rspec-apigen/given'
|
7
|
+
require 'rspec-apigen/config.rb'
|
8
|
+
require 'rspec-apigen/formatter'
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-apigen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Andreas Ronge
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-09-03 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
- beta
|
32
|
+
- 20
|
33
|
+
version: 2.0.0.beta.20
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: Write your API documentation using a custom RSpec DSL instead of using RDoc
|
37
|
+
email:
|
38
|
+
- andreas.ronge@gmail.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- lib/rspec-apigen.rb
|
47
|
+
- lib/rspec-apigen/given.rb
|
48
|
+
- lib/rspec-apigen/config.rb
|
49
|
+
- lib/rspec-apigen/argument.rb
|
50
|
+
- lib/rspec-apigen/version.rb~
|
51
|
+
- lib/rspec-apigen/apigen.rb
|
52
|
+
- lib/rspec-apigen/meta_helper.rb
|
53
|
+
- lib/rspec-apigen/method.rb
|
54
|
+
- lib/rspec-apigen/formatter.rb
|
55
|
+
- lib/rspec-apigen/fixture.rb
|
56
|
+
- lib/rspec-apigen/version.rb
|
57
|
+
- README.rdoc
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://github.com/andreasronge/rspec-apigen
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 1
|
80
|
+
- 3
|
81
|
+
- 6
|
82
|
+
version: 1.3.6
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.6
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: A plugin for RSpec for generating an API documentation
|
90
|
+
test_files: []
|
91
|
+
|