Permalink
Browse files

Add Writter to generate a compatible json output with I/O Docs tool

  • Loading branch information...
1 parent a8a0ccd commit 89fd214b554c02fe30a60440ba17d969a366d52a @areina areina committed Jul 27, 2012
@@ -0,0 +1,109 @@
+Feature: Json Iodocs
+ In order to serve the docs from my API
+ As Zipmark
+ I want to generate text files for each of my resources containing their combined docs
+
+ Background:
+ Given a file named "app.rb" with:
+ """
+ class App
+ def self.call(env)
+ request = Rack::Request.new(env)
+ response = Rack::Response.new
+ response["Content-Type"] = "text/plain"
+ response.write("Hello, #{request.params["target"]}!")
+ response.finish
+ end
+ end
+ """
+ And a file named "app_spec.rb" with:
+ """
+ require "rspec_api_documentation"
+ require "rspec_api_documentation/dsl"
+
+ RspecApiDocumentation.configure do |config|
+ config.app = App
+ config.api_name = "app"
+ config.format = :json_iodocs
+ end
+
+ resource "Greetings" do
+ get "/greetings" do
+ parameter :target, "The thing you want to greet"
+
+ example "Greeting your favorite gem" do
+ do_request :target => "rspec_api_documentation"
+
+ response_headers["Content-Type"].should eq("text/plain")
+ status.should eq(200)
+ response_body.should eq('Hello, rspec_api_documentation!')
+ end
+
+ example "Greeting your favorite developers of your favorite gem" do
+ do_request :target => "Sam & Eric"
+
+ response_headers["Content-Type"].should eq("text/plain")
+ status.should eq(200)
+ response_body.should eq('Hello, Sam & Eric!')
+ end
+ end
+ end
+ """
+ When I run `rspec app_spec.rb --require ./app.rb --format RspecApiDocumentation::ApiFormatter`
+
+ Scenario: Output helpful progress to the console
+ Then the output should contain:
+ """
+ Generating API Docs
+ Greetings
+ GET /greetings
+ * Greeting your favorite gem
+ * Greeting your favorite developers of your favorite gem
+ """
+ And the output should contain "2 examples, 0 failures"
+ And the exit status should be 0
+
+ Scenario: File should look like we expect
+ Then the file "docs/app.json" should contain JSON exactly like:
+ """
+ {
+ "endpoints": [
+ {
+ "name": "Greetings",
+ "methods": [
+ {
+ "MethodName": "Greeting your favorite developers of your favorite gem",
+ "Synopsis": null,
+ "HTTPMethod": "GET",
+ "URI": "/greetings?target=Sam+%26+Eric",
+ "RequiresOAuth": "N",
+ "parameters": [
+ {
+ "Name": "target",
+ "Description": "The thing you want to greet",
+ "Default": "",
+ "Required": "N"
+ }
+ ]
+ },
+ {
+ "MethodName": "Greeting your favorite gem",
+ "Synopsis": null,
+ "HTTPMethod": "GET",
+ "URI": "/greetings?target=rspec_api_documentation",
+ "RequiresOAuth": "N",
+ "parameters": [
+ {
+ "Name": "target",
+ "Description": "The thing you want to greet",
+ "Default": "",
+ "Required": "N"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ """
+
@@ -27,6 +27,7 @@ module RspecApiDocumentation
autoload :HtmlWriter
autoload :WurlWriter
autoload :JsonWriter
+ autoload :JsonIodocsWriter
autoload :IndexWriter
autoload :CombinedTextWriter
autoload :CombinedJsonWriter
@@ -0,0 +1,107 @@
+module RspecApiDocumentation
+ class JsonIodocsWriter
+ attr_accessor :index, :configuration, :api_key
+ delegate :docs_dir, :to => :configuration
+
+ def initialize(index, configuration)
+ self.index = index
+ self.configuration = configuration
+ self.api_key = configuration.api_name.parameterize
+ end
+
+ def self.write(index, configuration)
+ writer = new(index, configuration)
+ writer.write
+ end
+
+ def write
+ File.open(docs_dir.join("apiconfig.json"), "w+") do |file|
+ file.write ApiConfig.new(configuration).to_json
+ end
+ File.open(docs_dir.join("#{api_key}.json"), "w+") do |file|
+ file.write JsonIndex.new(index, configuration).to_json
+ end
+ end
+ end
+
+ class JsonIndex
+ def initialize(index, configuration)
+ @index = index
+ @configuration = configuration
+ end
+
+ def sections
+ IndexWriter.sections(examples, @configuration)
+ end
+
+ def examples
+ @index.examples.map { |example| JsonExample.new(example, @configuration) }
+ end
+
+ def to_json
+ sections.inject({:endpoints => []}) do |h, section|
+ h[:endpoints].push(
+ :name => section[:resource_name],
+ :methods => section[:examples].map do |example|
+ example.to_json
+ end
+ )
+ h
+ end.to_json
+ end
+ end
+
+ class JsonExample
+ def initialize(example, configuration)
+ @example = example
+ end
+
+ def method_missing(method, *args, &block)
+ @example.send(method, *args, &block)
+ end
+
+ def parameters
+ params = []
+ if @example.respond_to?(:parameters)
+ @example.parameters.map do |param|
+ params << {
+ "Name" => param[:name],
+ "Description" => param[:description],
+ "Default" => "",
+ "Required" => param[:required] ? "Y" : "N"
+ }
+ end
+ end
+ params
+ end
+
+ def to_json
+ {
+ :MethodName => description,
+ :Synopsis => explanation,
+ :HTTPMethod => http_method,
+ :URI => (requests.first[:request_path] rescue ""),
+ :RequiresOAuth => "N",
+ :parameters => parameters
+ }
+ end
+ end
+
+ class ApiConfig
+ def initialize(configuration)
+ @configuration = configuration
+ @api_key = configuration.api_name.parameterize
+ end
+
+ def to_json
+ {
+ @api_key.to_sym => {
+ :name => @configuration.api_name,
+ :protocol => "http",
+ :publicPath => "",
+ :baseURL => @configuration.curl_host
+ }
+ }.to_json
+ end
+ end
+end
@@ -0,0 +1,30 @@
+require 'spec_helper'
+
+describe RspecApiDocumentation::JsonIodocsWriter do
+ let(:index) { RspecApiDocumentation::Index.new }
+ let(:configuration) { RspecApiDocumentation::Configuration.new }
+
+ describe ".write" do
+ let(:writer) { stub }
+
+ it "should build a new writer and write the docs" do
+ described_class.stub!(:new).with(index, configuration).and_return(writer)
+ writer.should_receive(:write)
+ described_class.write(index, configuration)
+ end
+ end
+
+ describe "#write" do
+ let(:writer) { described_class.new(index, configuration) }
+
+ before do
+ FileUtils.mkdir_p(configuration.docs_dir)
+ end
+
+ it "should write the index" do
+ writer.write
+ index_file = File.join(configuration.docs_dir, "apiconfig.json")
+ File.exists?(index_file).should be_true
+ end
+ end
+end

0 comments on commit 89fd214

Please sign in to comment.