rspec-apigen 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|