A plugin for RSpec for generating an API documentation
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
spec
.gitignore
Gemfile
README.rdoc
Rakefile
rspec-apigen.gemspec

README.rdoc

What is this ?

A tool that generates an API documentation using RSpec and some DSL magic. If successful I might use it for my own project (neo4j.rb) This is an early experiment !

How ?

Instead of writing specs like this:

describe Account do
    context "transfering money" do
      it "deposits transfer amount to the other account" do
        source = Account.new(50, :USD)
        target = mock('target account')
        target.should_receive(:deposit).with(Money.new(5, :USD))
        source.transfer(5, :USD).to(target)
      end

      it "reduces its balance by the transfer amount" do
        source = Account.new(50, :USD)
        target = stub('target account')
        source.transfer(5, :USD).to(target)
        source.balance.should == Money.new(45, :USD)
      end
    end
  end

Which generates the following output

$ spec ./spec/account_spec.rb --format nested
Account
  transfering money
    deposits transfer amount to the other account
    reduces its balance by the transfer amount

2 examples, 0 failures

I (also) want to generate a detailed API documentation something like this from a RSpec Macro DSL:

Account
  Public Static Methods
    #new ()
      Given
        no arguments
      Then
        Return Account with 0 USD
          has #balance == 0
          has #currency == 'USD
    #new (amount,currency)
      Scenario account and currency has valid values
        Given
          arguments 50, USD
        Then
          Return an Account with given amount and currency
            should == 50
            should == "USD"
  Public Instance Methods
    #transfer (amount,currency)
      Scenario transfer amount and currency have valid values
        Given
          arguments 5, USD
        Then
          should not change subject
          Return A transfer of 5 USD from Account with 50 USD
            should be a kind of TransferDSL
Finished in 0.00412 seconds
9 examples, 0 failures

TransferDSL
  Public Static Methods
    #new (source_account,amount,currency)
      Given
        arguments Account balance: 50 USD, 5, USD
      Then
        Return An TransferDSL instance with initialized source account, amount and currency
          should == 50
  Public Instance Methods
    #to (target_account)
      Given
        arguments Account balance: 10 USD
      Then it should add money on the target account
        should add money to the target account

Finished in 0.00225 seconds
4 examples, 0 failures

The above is generated from the following RSpec file:

describe Account do

  static_methods do
    new do
      Return("Account with 0 USD") do
        # it_behaves_like "Account with 0 USD" can also be used
        it("has #balance == 0") { subject.balance.should == 0 }
        it("has #currency == 'USD") { subject.currency.should == 'USD' }
      end
    end

    new(arg(:amount), arg(:currency)) do
      Scenario 'account and currency has valid values' do
        Given do
          arg.amount   = 50
          arg.currency = 'USD'
        end

        Return "an Account with given amount and currency" do
          it { subject.balance.should == 50 } #given.amount }
          it { subject.currency.should == 'USD' } # given.currency }
        end
      end
    end
  end

  instance_methods do
    transfer(arg(:amount), arg(:currency)) do
#      Description 'bla bla bla'
      Scenario 'transfer amount and currency have valid values' do
        subject { Account.new(50, 'USD') }
        Given do
          arg.amount = 5
          arg.currency = 'USD'
        end
        Return "A transfer of 5 USD from Account with 50 USD" do
          it { should be_kind_of(TransferDSL) }
        end
        Then do
         it "should not change subject" do
            given.subject.balance.should == subject.balance
          end
        end
      end
    end
  end
end

describe TransferDSL do
  static_methods do
    new(arg(:source_account) do
      Given do
        arg.source_account = Account.new(50, 'USD')
      end
      Returns("A Transfer DSL with the given source account") do
         it {subject.source_account.should  == given.source_account}
      end

  end

  instance_methods do
    to(arg(:target_account, arg(:amount), arg(:currency)) do
      Scenario 'source account has enough money' do
        Given do
          arg.target_account = Account.new(50, 'USD')
          arg.amount = 5
          arg.currency = 'USD'
          subject{TransferDSL.new(Account.new(50, 'USD')}
        end

        # the following line describes the subject's source_account method
        Then "it added money to the target account" do
           it { subject.target_account.amount.should == given.arg.source_account.amount + given.arg.amount }
        end
      end

      Scenario 'source account does NOT have enough money' do
        Given do
          arg.target_account = Account.new(50, 'USD')
          arg.amount = 100
          arg.currency = 'USD'
          subject{TransferDSL.new(Account.new(10, 'USD')}
        end
        Throws(Error)
    end
  end

end

TODO: I will implement a new RSpec HTML formatter which will generate something similar to RDoc. I want to write specification in my rspec code instead of using RDoc.

Example

gem install rspec --prerelease (2.0.0.beta.19)
rspec -f d -c spec