From fecf23b1643346f13a2fcf2d562063c36ec23109 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Thu, 4 Jul 2013 17:04:43 +0200 Subject: [PATCH 01/21] Ignore swp files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 94424fbc..8d585992 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ tmp example/docs example/public/docs *.gem +*.swp From 842a9756c417ccb1f49185ef3500c7afa2dc1ccb Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 5 Jul 2013 15:02:49 +0200 Subject: [PATCH 02/21] Generate api docs in json, combined_text and html. --- example/spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/spec/spec_helper.rb b/example/spec/spec_helper.rb index 868d2fb1..f617c197 100644 --- a/example/spec/spec_helper.rb +++ b/example/spec/spec_helper.rb @@ -33,7 +33,7 @@ end RspecApiDocumentation.configure do |config| - config.format = [:json, :combined_text] + config.format = [:json, :combined_text, :html] config.curl_host = 'http://localhost:3000' config.api_name = "Example App API" end From 397bd37758e5ff0606ed70a4cb45ca3f7c159c9e Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 5 Jul 2013 15:03:01 +0200 Subject: [PATCH 03/21] Added a GeneralMarkupWriter class as parent of HtmlWriter to prepare Textile and Markdown writers. --- lib/rspec_api_documentation.rb | 1 + .../writers/general_markup_writer.rb | 44 +++++++++++++++++++ .../writers/html_writer.rb | 27 ++++-------- 3 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 lib/rspec_api_documentation/writers/general_markup_writer.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index 23124a7b..a0b04241 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -28,6 +28,7 @@ module RspecApiDocumentation module Writers extend ActiveSupport::Autoload + autoload :GeneralMarkupWriter autoload :HtmlWriter autoload :JsonWriter autoload :JsonIodocsWriter diff --git a/lib/rspec_api_documentation/writers/general_markup_writer.rb b/lib/rspec_api_documentation/writers/general_markup_writer.rb new file mode 100644 index 00000000..2c0d5615 --- /dev/null +++ b/lib/rspec_api_documentation/writers/general_markup_writer.rb @@ -0,0 +1,44 @@ +require 'mustache' + +module RspecApiDocumentation + module Writers + class GeneralMarkupWriter + attr_accessor :index, :configuration + + INDEX_FILE_NAME = 'index' + + def initialize(index, configuration) + self.index = index + self.configuration = configuration + end + + def self.write(index, configuration) + writer = new(index, configuration) + writer.write + end + + def write + File.open(configuration.docs_dir.join(index_file_name + '.' + extension), "w+") do |f| + f.write markup_index_class.new(index, configuration).render + end + + index.examples.each do |example| + markup_example = markup_example_class.new(example, configuration) + FileUtils.mkdir_p(configuration.docs_dir.join(markup_example.dirname)) + + File.open(configuration.docs_dir.join(markup_example.dirname, markup_example.filename), "w+") do |f| + f.write markup_example.render + end + end + end + + def index_file_name + INDEX_FILE_NAME + end + + def extension + raise 'Parent class. This method should not be called.' + end + end + end +end diff --git a/lib/rspec_api_documentation/writers/html_writer.rb b/lib/rspec_api_documentation/writers/html_writer.rb index 2728ddb1..5fc9940b 100644 --- a/lib/rspec_api_documentation/writers/html_writer.rb +++ b/lib/rspec_api_documentation/writers/html_writer.rb @@ -2,30 +2,21 @@ module RspecApiDocumentation module Writers - class HtmlWriter + class HtmlWriter < GeneralMarkupWriter attr_accessor :index, :configuration - def initialize(index, configuration) - self.index = index - self.configuration = configuration + EXTENSION = 'html' + + def markup_index_class + HtmlIndex end - def self.write(index, configuration) - writer = new(index, configuration) - writer.write + def markup_example_class + HtmlExample end - def write - File.open(configuration.docs_dir.join("index.html"), "w+") do |f| - f.write HtmlIndex.new(index, configuration).render - end - index.examples.each do |example| - html_example = HtmlExample.new(example, configuration) - FileUtils.mkdir_p(configuration.docs_dir.join(html_example.dirname)) - File.open(configuration.docs_dir.join(html_example.dirname, html_example.filename), "w+") do |f| - f.write html_example.render - end - end + def extension + EXTENSION end end From c789f44ea05be5308ca2639f5a2678f62ce1ee1e Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 5 Jul 2013 16:28:03 +0200 Subject: [PATCH 04/21] Moved HtmlIndex and HtmlExample to a dedicated module Views. --- lib/rspec_api_documentation.rb | 7 ++ .../views/html_example.rb | 54 +++++++++++++ .../views/html_index.rb | 26 +++++++ .../writers/general_markup_writer.rb | 2 - .../writers/html_writer.rb | 76 +------------------ spec/views/html_example_spec.rb | 24 ++++++ spec/writers/html_writer_spec.rb | 21 ----- 7 files changed, 113 insertions(+), 97 deletions(-) create mode 100644 lib/rspec_api_documentation/views/html_example.rb create mode 100644 lib/rspec_api_documentation/views/html_index.rb create mode 100644 spec/views/html_example_spec.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index a0b04241..a1bd9de5 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -37,6 +37,13 @@ module Writers autoload :CombinedJsonWriter end + module Views + extend ActiveSupport::Autoload + + autoload :HtmlIndex + autoload :HtmlExample + end + def self.configuration @configuration ||= Configuration.new end diff --git a/lib/rspec_api_documentation/views/html_example.rb b/lib/rspec_api_documentation/views/html_example.rb new file mode 100644 index 00000000..188bc936 --- /dev/null +++ b/lib/rspec_api_documentation/views/html_example.rb @@ -0,0 +1,54 @@ +require 'mustache' + +module RspecApiDocumentation + module Views + class HtmlExample < Mustache + def initialize(example, configuration) + @example = example + @host = configuration.curl_host + self.template_path = configuration.template_path + self.template_name = "rspec_api_documentation/html_example" + end + + def method_missing(method, *args, &block) + @example.send(method, *args, &block) + end + + def respond_to?(method, include_private = false) + super || @example.respond_to?(method, include_private) + end + + def dirname + resource_name.downcase.gsub(/\s+/, '_') + end + + def filename + basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '') + basename = Digest::MD5.new.update(description).to_s if basename.blank? + "#{basename}.html" + end + + def requests + super.map do |hash| + hash[:request_headers_text] = format_hash(hash[:request_headers]) + hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters]) + hash[:response_headers_text] = format_hash(hash[:response_headers]) + if @host + hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl + else + hash[:curl] = nil + end + hash + end + end + + private + def format_hash(hash = {}) + return nil unless hash.present? + hash.collect do |k, v| + "#{k}: #{v}" + end.join("\n") + end + end + end +end diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb new file mode 100644 index 00000000..a01fa1ff --- /dev/null +++ b/lib/rspec_api_documentation/views/html_index.rb @@ -0,0 +1,26 @@ +require 'mustache' + +module RspecApiDocumentation + module Views + class HtmlIndex < Mustache + def initialize(index, configuration) + @index = index + @configuration = configuration + self.template_path = configuration.template_path + self.template_name = "rspec_api_documentation/html_index" + end + + def api_name + @configuration.api_name + end + + def sections + RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration) + end + + def examples + @index.examples.map { |example| HtmlExample.new(example, @configuration) } + end + end + end +end diff --git a/lib/rspec_api_documentation/writers/general_markup_writer.rb b/lib/rspec_api_documentation/writers/general_markup_writer.rb index 2c0d5615..93c94d05 100644 --- a/lib/rspec_api_documentation/writers/general_markup_writer.rb +++ b/lib/rspec_api_documentation/writers/general_markup_writer.rb @@ -1,5 +1,3 @@ -require 'mustache' - module RspecApiDocumentation module Writers class GeneralMarkupWriter diff --git a/lib/rspec_api_documentation/writers/html_writer.rb b/lib/rspec_api_documentation/writers/html_writer.rb index 5fc9940b..32348a95 100644 --- a/lib/rspec_api_documentation/writers/html_writer.rb +++ b/lib/rspec_api_documentation/writers/html_writer.rb @@ -1,5 +1,3 @@ -require 'mustache' - module RspecApiDocumentation module Writers class HtmlWriter < GeneralMarkupWriter @@ -8,86 +6,16 @@ class HtmlWriter < GeneralMarkupWriter EXTENSION = 'html' def markup_index_class - HtmlIndex + RspecApiDocumentation::Views::HtmlIndex end def markup_example_class - HtmlExample + RspecApiDocumentation::Views::HtmlExample end def extension EXTENSION end end - - class HtmlIndex < Mustache - def initialize(index, configuration) - @index = index - @configuration = configuration - self.template_path = configuration.template_path - self.template_name = "rspec_api_documentation/html_index" - end - - def api_name - @configuration.api_name - end - - def sections - IndexWriter.sections(examples, @configuration) - end - - def examples - @index.examples.map { |example| HtmlExample.new(example, @configuration) } - end - end - - class HtmlExample < Mustache - def initialize(example, configuration) - @example = example - @host = configuration.curl_host - self.template_path = configuration.template_path - self.template_name = "rspec_api_documentation/html_example" - end - - def method_missing(method, *args, &block) - @example.send(method, *args, &block) - end - - def respond_to?(method, include_private = false) - super || @example.respond_to?(method, include_private) - end - - def dirname - resource_name.downcase.gsub(/\s+/, '_') - end - - def filename - basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '') - basename = Digest::MD5.new.update(description).to_s if basename.blank? - "#{basename}.html" - end - - def requests - super.map do |hash| - hash[:request_headers_text] = format_hash(hash[:request_headers]) - hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters]) - hash[:response_headers_text] = format_hash(hash[:response_headers]) - if @host - hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl - else - hash[:curl] = nil - end - hash - end - end - - private - def format_hash(hash = {}) - return nil unless hash.present? - hash.collect do |k, v| - "#{k}: #{v}" - end.join("\n") - end - end end end diff --git a/spec/views/html_example_spec.rb b/spec/views/html_example_spec.rb new file mode 100644 index 00000000..98c85d8c --- /dev/null +++ b/spec/views/html_example_spec.rb @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe RspecApiDocumentation::Views::HtmlExample do + let(:metadata) { {} } + let(:group) { RSpec::Core::ExampleGroup.describe("Orders", metadata) } + let(:example) { group.example("Ordering a cup of coffee") {} } + let(:configuration) { RspecApiDocumentation::Configuration.new } + let(:html_example) { described_class.new(example, configuration) } + + it "should have downcased filename" do + html_example.filename.should == "ordering_a_cup_of_coffee.html" + end + + describe "multi charctor example name" do + let(:label) { "コーヒーが順番で並んでいること" } + let(:example) { group.example(label) {} } + + it "should have downcased filename" do + filename = Digest::MD5.new.update(label).to_s + html_example.filename.should == filename + ".html" + end + end +end diff --git a/spec/writers/html_writer_spec.rb b/spec/writers/html_writer_spec.rb index 89eaeafb..c4ccfb20 100644 --- a/spec/writers/html_writer_spec.rb +++ b/spec/writers/html_writer_spec.rb @@ -33,24 +33,3 @@ end end -describe RspecApiDocumentation::Writers::HtmlExample do - let(:metadata) { {} } - let(:group) { RSpec::Core::ExampleGroup.describe("Orders", metadata) } - let(:example) { group.example("Ordering a cup of coffee") {} } - let(:configuration) { RspecApiDocumentation::Configuration.new } - let(:html_example) { described_class.new(example, configuration) } - - it "should have downcased filename" do - html_example.filename.should == "ordering_a_cup_of_coffee.html" - end - - describe "multi charctor example name" do - let(:label) { "コーヒーが順番で並んでいること" } - let(:example) { group.example(label) {} } - - it "should have downcased filename" do - filename = Digest::MD5.new.update(label).to_s - html_example.filename.should == filename + ".html" - end - end -end From 6174372e24360feca318e88586518d81c376dbb1 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 5 Jul 2013 16:56:17 +0200 Subject: [PATCH 05/21] Added MarkupIndex and MarkupExample for views as parent of HtmlIndex and HtmlExample. --- lib/rspec_api_documentation.rb | 2 + .../views/html_example.rb | 50 ++-------------- .../views/html_index.rb | 20 +------ .../views/markup_example.rb | 58 +++++++++++++++++++ .../views/markup_index.rb | 25 ++++++++ 5 files changed, 93 insertions(+), 62 deletions(-) create mode 100644 lib/rspec_api_documentation/views/markup_example.rb create mode 100644 lib/rspec_api_documentation/views/markup_index.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index a1bd9de5..9961841b 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -40,6 +40,8 @@ module Writers module Views extend ActiveSupport::Autoload + autoload :MarkupIndex + autoload :MarkupExample autoload :HtmlIndex autoload :HtmlExample end diff --git a/lib/rspec_api_documentation/views/html_example.rb b/lib/rspec_api_documentation/views/html_example.rb index 188bc936..6b0f6009 100644 --- a/lib/rspec_api_documentation/views/html_example.rb +++ b/lib/rspec_api_documentation/views/html_example.rb @@ -1,53 +1,15 @@ -require 'mustache' - module RspecApiDocumentation module Views - class HtmlExample < Mustache + class HtmlExample < MarkupExample + EXTENSION = 'html' + def initialize(example, configuration) - @example = example - @host = configuration.curl_host - self.template_path = configuration.template_path + super self.template_name = "rspec_api_documentation/html_example" end - def method_missing(method, *args, &block) - @example.send(method, *args, &block) - end - - def respond_to?(method, include_private = false) - super || @example.respond_to?(method, include_private) - end - - def dirname - resource_name.downcase.gsub(/\s+/, '_') - end - - def filename - basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '') - basename = Digest::MD5.new.update(description).to_s if basename.blank? - "#{basename}.html" - end - - def requests - super.map do |hash| - hash[:request_headers_text] = format_hash(hash[:request_headers]) - hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters]) - hash[:response_headers_text] = format_hash(hash[:response_headers]) - if @host - hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl - else - hash[:curl] = nil - end - hash - end - end - - private - def format_hash(hash = {}) - return nil unless hash.present? - hash.collect do |k, v| - "#{k}: #{v}" - end.join("\n") + def extension + EXTENSION end end end diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb index a01fa1ff..c4f8a8bd 100644 --- a/lib/rspec_api_documentation/views/html_index.rb +++ b/lib/rspec_api_documentation/views/html_index.rb @@ -1,26 +1,10 @@ -require 'mustache' - module RspecApiDocumentation module Views - class HtmlIndex < Mustache + class HtmlIndex < MarkupIndex def initialize(index, configuration) - @index = index - @configuration = configuration - self.template_path = configuration.template_path + super self.template_name = "rspec_api_documentation/html_index" end - - def api_name - @configuration.api_name - end - - def sections - RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration) - end - - def examples - @index.examples.map { |example| HtmlExample.new(example, @configuration) } - end end end end diff --git a/lib/rspec_api_documentation/views/markup_example.rb b/lib/rspec_api_documentation/views/markup_example.rb new file mode 100644 index 00000000..6f9c72cb --- /dev/null +++ b/lib/rspec_api_documentation/views/markup_example.rb @@ -0,0 +1,58 @@ +require 'mustache' + +module RspecApiDocumentation + module Views + class MarkupExample < Mustache + def initialize(example, configuration) + @example = example + @host = configuration.curl_host + self.template_path = configuration.template_path + end + + def method_missing(method, *args, &block) + @example.send(method, *args, &block) + end + + def respond_to?(method, include_private = false) + super || @example.respond_to?(method, include_private) + end + + def dirname + resource_name.downcase.gsub(/\s+/, '_') + end + + def filename + basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '') + basename = Digest::MD5.new.update(description).to_s if basename.blank? + "#{basename}.#{extension}" + end + + def requests + super.map do |hash| + hash[:request_headers_text] = format_hash(hash[:request_headers]) + hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters]) + hash[:response_headers_text] = format_hash(hash[:response_headers]) + if @host + hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl + else + hash[:curl] = nil + end + hash + end + end + + def extension + raise 'Parent class. This method should not be called.' + end + + private + + def format_hash(hash = {}) + return nil unless hash.present? + hash.collect do |k, v| + "#{k}: #{v}" + end.join("\n") + end + end + end +end diff --git a/lib/rspec_api_documentation/views/markup_index.rb b/lib/rspec_api_documentation/views/markup_index.rb new file mode 100644 index 00000000..b0a3646b --- /dev/null +++ b/lib/rspec_api_documentation/views/markup_index.rb @@ -0,0 +1,25 @@ +require 'mustache' + +module RspecApiDocumentation + module Views + class MarkupIndex < Mustache + def initialize(index, configuration) + @index = index + @configuration = configuration + self.template_path = configuration.template_path + end + + def api_name + @configuration.api_name + end + + def sections + RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration) + end + + def examples + @index.examples.map { |example| HtmlExample.new(example, @configuration) } + end + end + end +end From 1a74b2aa6cf3fbb31052c86b006097fc4156b990 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Mon, 8 Jul 2013 00:42:27 +0200 Subject: [PATCH 06/21] Added textile views and writer. --- lib/rspec_api_documentation.rb | 3 ++ .../views/textile_example.rb | 16 +++++++++ .../views/textile_index.rb | 10 ++++++ .../writers/textile_writer.rb | 21 +++++++++++ spec/writers/textile_writer_spec.rb | 35 +++++++++++++++++++ 5 files changed, 85 insertions(+) create mode 100644 lib/rspec_api_documentation/views/textile_example.rb create mode 100644 lib/rspec_api_documentation/views/textile_index.rb create mode 100644 lib/rspec_api_documentation/writers/textile_writer.rb create mode 100644 spec/writers/textile_writer_spec.rb diff --git a/lib/rspec_api_documentation.rb b/lib/rspec_api_documentation.rb index 9961841b..a8bfcca4 100644 --- a/lib/rspec_api_documentation.rb +++ b/lib/rspec_api_documentation.rb @@ -30,6 +30,7 @@ module Writers autoload :GeneralMarkupWriter autoload :HtmlWriter + autoload :TextileWriter autoload :JsonWriter autoload :JsonIodocsWriter autoload :IndexWriter @@ -44,6 +45,8 @@ module Views autoload :MarkupExample autoload :HtmlIndex autoload :HtmlExample + autoload :TextileIndex + autoload :TextileExample end def self.configuration diff --git a/lib/rspec_api_documentation/views/textile_example.rb b/lib/rspec_api_documentation/views/textile_example.rb new file mode 100644 index 00000000..f872697b --- /dev/null +++ b/lib/rspec_api_documentation/views/textile_example.rb @@ -0,0 +1,16 @@ +module RspecApiDocumentation + module Views + class TextileExample < MarkupExample + EXTENSION = 'textile' + + def initialize(example, configuration) + super + self.template_name = "rspec_api_documentation/textile_example" + end + + def extension + EXTENSION + end + end + end +end diff --git a/lib/rspec_api_documentation/views/textile_index.rb b/lib/rspec_api_documentation/views/textile_index.rb new file mode 100644 index 00000000..eaca2f38 --- /dev/null +++ b/lib/rspec_api_documentation/views/textile_index.rb @@ -0,0 +1,10 @@ +module RspecApiDocumentation + module Views + class TextileIndex < MarkupIndex + def initialize(index, configuration) + super + self.template_name = "rspec_api_documentation/textile_index" + end + end + end +end diff --git a/lib/rspec_api_documentation/writers/textile_writer.rb b/lib/rspec_api_documentation/writers/textile_writer.rb new file mode 100644 index 00000000..6b79b209 --- /dev/null +++ b/lib/rspec_api_documentation/writers/textile_writer.rb @@ -0,0 +1,21 @@ +module RspecApiDocumentation + module Writers + class TextileWriter < GeneralMarkupWriter + attr_accessor :index, :configuration + + EXTENSION = 'textile' + + def markup_index_class + RspecApiDocumentation::Views::TextileIndex + end + + def markup_example_class + RspecApiDocumentation::Views::TextileExample + end + + def extension + EXTENSION + end + end + end +end diff --git a/spec/writers/textile_writer_spec.rb b/spec/writers/textile_writer_spec.rb new file mode 100644 index 00000000..8b3ab5af --- /dev/null +++ b/spec/writers/textile_writer_spec.rb @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe RspecApiDocumentation::Writers::TextileWriter 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 + template_dir = File.join(configuration.template_path, "rspec_api_documentation") + FileUtils.mkdir_p(template_dir) + File.open(File.join(template_dir, "textile_index.mustache"), "w+") { |f| f << "{{ mustache }}" } + FileUtils.mkdir_p(configuration.docs_dir) + end + + it "should write the index" do + writer.write + index_file = File.join(configuration.docs_dir, "index.textile") + File.exists?(index_file).should be_true + end + end + +end From a3780d1863cb21a3fd74179985243b5883ff83ee Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Sun, 28 Jul 2013 19:37:19 +0200 Subject: [PATCH 07/21] Textile Index and Example mustache templates with Textile Index Cucumber Feature and Steps. --- features/textile_documentation.feature | 98 +++++++++++++++++++ .../textile_example.mustache | 0 .../textile_index.mustache | 9 ++ 3 files changed, 107 insertions(+) create mode 100644 features/textile_documentation.feature create mode 100644 templates/rspec_api_documentation/textile_example.mustache create mode 100644 templates/rspec_api_documentation/textile_index.mustache diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature new file mode 100644 index 00000000..bc86b9bc --- /dev/null +++ b/features/textile_documentation.feature @@ -0,0 +1,98 @@ +Feature: Generate Textile documentation from test examples + + 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"] = "application/json" + response.write({ "hello" => request.params["target"] }.to_json) + 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 = "Example API" + config.format = :textile + 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("application/json") + status.should eq(200) + response_body.should eq('{"hello":"rspec_api_documentation"}') + 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 + """ + And the output should contain "1 example, 0 failures" + And the exit status should be 0 + + Scenario: Index file should look like we expect + Then the file "docs/index.textile" should contain exactly: + """ + h1. Example API + + h2. Greetings + + * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html + + """ + + # Scenario: Create an index of all API examples, including all resources + # When I open the index + # Then I should see the following resources: + # | Greetings | + # And I should see the api name "Example API" + + # Scenario: Example HTML documentation includes the parameters + # When I open the index + # And I navigate to "Greeting your favorite gem" + # Then I should see the following parameters: + # | name | description | + # | target | The thing you want to greet | + + # Scenario: Example HTML documentation includes the request information + # When I open the index + # And I navigate to "Greeting your favorite gem" + # Then I should see the route is "GET /greetings?target=rspec_api_documentation" + # And I should see the following request headers: + # | Host | example.org | + # | Cookie | | + # And I should see the following query parameters: + # | target | rspec_api_documentation | + + # Scenario: Example HTML documentation includes the response information + # When I open the index + # And I navigate to "Greeting your favorite gem" + # Then I should see the response status is "200 OK" + # And I should see the following response headers: + # | Content-Type | application/json | + # | Content-Length | 35 | + # And I should see the following response body: + # """ + # {"hello":"rspec_api_documentation"} + # """ diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache new file mode 100644 index 00000000..e69de29b diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache new file mode 100644 index 00000000..53ef0da6 --- /dev/null +++ b/templates/rspec_api_documentation/textile_index.mustache @@ -0,0 +1,9 @@ +h1. {{ api_name }} + +{{# sections }} +h2. {{ resource_name }} + +{{# examples }} +* "{{ description }}":{{ dirname }}/{{ filename }} +{{/ examples }} +{{/ sections }} From c03d6c8efca09ea1febcfce45cca7499a9f71161 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Mon, 29 Jul 2013 17:35:55 +0200 Subject: [PATCH 08/21] Added additional test cases in textile_documentation.feature. --- features/textile_documentation.feature | 34 ++++++++++++++++++- .../textile_index.mustache | 1 + 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index bc86b9bc..de4f465f 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -35,6 +35,28 @@ Feature: Generate Textile documentation from test examples status.should eq(200) response_body.should eq('{"hello":"rspec_api_documentation"}') end + + example "Greeting nothing" do + do_request :target => "" + + response_headers["Content-Type"].should eq("application/json") + status.should eq(200) + response_body.should eq('{"hello":""}') + end + end + end + + resource "Cucumbers" do + get "/cucumbers" do + parameter :target, "The thing in which you want to eat cucumbers" + + example "Eating cucumbers in a bowl" do + do_request :target => "bowl" + + response_headers["Content-Type"].should eq("application/json") + status.should eq(200) + response_body.should eq('{"hello":"bowl"}') + end end end """ @@ -47,8 +69,12 @@ Feature: Generate Textile documentation from test examples Greetings GET /greetings * Greeting your favorite gem + * Greeting nothing + Cucumbers + GET /cucumbers + * Eating cucumbers in a bowl """ - And the output should contain "1 example, 0 failures" + And the output should contain "3 examples, 0 failures" And the exit status should be 0 Scenario: Index file should look like we expect @@ -56,10 +82,16 @@ Feature: Generate Textile documentation from test examples """ h1. Example API + h2. Cucumbers + + * "Eating cucumbers in a bowl":cucumbers/eating_cucumbers_in_a_bowl.html + h2. Greetings + * "Greeting nothing":greetings/greeting_nothing.html * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html + """ # Scenario: Create an index of all API examples, including all resources diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache index 53ef0da6..cbb93d57 100644 --- a/templates/rspec_api_documentation/textile_index.mustache +++ b/templates/rspec_api_documentation/textile_index.mustache @@ -6,4 +6,5 @@ h2. {{ resource_name }} {{# examples }} * "{{ description }}":{{ dirname }}/{{ filename }} {{/ examples }} + {{/ sections }} From 3a717fc6777be7cfeee787d6fae2800aefc0774d Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 2 Aug 2013 10:36:12 +0200 Subject: [PATCH 09/21] Remove links in textile index towards textile examples pages. --- features/textile_documentation.feature | 6 +++--- templates/rspec_api_documentation/textile_index.mustache | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index de4f465f..a4e23ca4 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -84,12 +84,12 @@ Feature: Generate Textile documentation from test examples h2. Cucumbers - * "Eating cucumbers in a bowl":cucumbers/eating_cucumbers_in_a_bowl.html + * Eating cucumbers in a bowl h2. Greetings - * "Greeting nothing":greetings/greeting_nothing.html - * "Greeting your favorite gem":greetings/greeting_your_favorite_gem.html + * Greeting nothing + * Greeting your favorite gem """ diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache index cbb93d57..78d15ec2 100644 --- a/templates/rspec_api_documentation/textile_index.mustache +++ b/templates/rspec_api_documentation/textile_index.mustache @@ -4,7 +4,7 @@ h1. {{ api_name }} h2. {{ resource_name }} {{# examples }} -* "{{ description }}":{{ dirname }}/{{ filename }} +* {{ description }} {{/ examples }} {{/ sections }} From c16e673bf9a0e78e15b5a0194757802c8e3e5b08 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 2 Aug 2013 14:56:20 +0200 Subject: [PATCH 10/21] First version of the textile_example mustache template. --- features/textile_documentation.feature | 6 ++ .../textile_example.mustache | 71 +++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index a4e23ca4..a639051c 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -27,6 +27,7 @@ Feature: Generate Textile documentation from test examples resource "Greetings" do get "/greetings" do parameter :target, "The thing you want to greet" + required_parameters :target example "Greeting your favorite gem" do do_request :target => "rspec_api_documentation" @@ -94,6 +95,11 @@ Feature: Generate Textile documentation from test examples """ + Scenario: Example 'Greeting nothing' file should look like we expect + Then the file "docs/greetings/greeting_nothing.textile" should contain exactly: + """ + """ + # Scenario: Create an index of all API examples, including all resources # When I open the index # Then I should see the following resources: diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache index e69de29b..9abe17f9 100644 --- a/templates/rspec_api_documentation/textile_example.mustache +++ b/templates/rspec_api_documentation/textile_example.mustache @@ -0,0 +1,71 @@ +h1. {{ resource_name }} API + +h2. {{ description }} + +h3. {{ http_method }} {{ route }} + +{{# explanation }} +{{ explanation }} + +{{/ explanation }} + +{{# has_parameters? }} + +h3. Parameters +{{# parameters }} + +Name : {{ name }} {{# required }} *- required -* {{/ required }} +Description : {{ description }} + +{{/ parameters }} +{{/ has_parameters? }} + +{{# requests }} +h3. Request + +h4. Headers + +
{{ request_headers_text }}
+ +h4. Route + +
{{ request_method }} {{ request_path }}
+ +{{# request_query_parameters_text }} +h4. Query Parameters + +
{{ request_query_parameters_text }}
+{{/ request_query_parameters_text }} + +{{# request_body }} +h4. Body + +
{{{ request_body }}}
+{{/ request_body }} + +{{# curl }} +h4. cURL + +
{{ curl }}
+{{/ curl }} + +{{# response_status }} +h3. Response + +h4. Headers + +
{{ response_headers_text }}
+ +h4. Status + +
{{ response_status }} {{ response_status_text}}
+ +{{# response_body }} +h4. Body + +
{{{ response_body }}}
+{{/ response_body }} +{{/ response_status }} + +{{/ requests }} + From 1800a645dc9464b1bbe99e6f0723fb87bcc7b69b Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Sat, 3 Aug 2013 18:54:05 +0200 Subject: [PATCH 11/21] Cucumber steps definitions written for basic textile example. --- features/textile_documentation.feature | 85 +++++++++++-------- .../textile_example.mustache | 5 +- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index a639051c..ada0988c 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -95,42 +95,53 @@ Feature: Generate Textile documentation from test examples """ - Scenario: Example 'Greeting nothing' file should look like we expect - Then the file "docs/greetings/greeting_nothing.textile" should contain exactly: - """ + Scenario: Example 'Greeting your favorite gem' file should look like we expect + Then the file "docs/greetings/greeting_your_favorite_gem.textile" should contain exactly: """ + h1. Greetings API + + h2. Greeting your favorite gem + + h3. GET /greetings + + + h3. Parameters + + Name : target *- required -* + Description : The thing you want to greet + + h3. Request + + h4. Headers + +
Host: example.org
+    Cookie: 
+ + h4. Route + +
GET /greetings?target=rspec_api_documentation
+ + h4. Query Parameters + +
target: rspec_api_documentation
- # Scenario: Create an index of all API examples, including all resources - # When I open the index - # Then I should see the following resources: - # | Greetings | - # And I should see the api name "Example API" - - # Scenario: Example HTML documentation includes the parameters - # When I open the index - # And I navigate to "Greeting your favorite gem" - # Then I should see the following parameters: - # | name | description | - # | target | The thing you want to greet | - - # Scenario: Example HTML documentation includes the request information - # When I open the index - # And I navigate to "Greeting your favorite gem" - # Then I should see the route is "GET /greetings?target=rspec_api_documentation" - # And I should see the following request headers: - # | Host | example.org | - # | Cookie | | - # And I should see the following query parameters: - # | target | rspec_api_documentation | - - # Scenario: Example HTML documentation includes the response information - # When I open the index - # And I navigate to "Greeting your favorite gem" - # Then I should see the response status is "200 OK" - # And I should see the following response headers: - # | Content-Type | application/json | - # | Content-Length | 35 | - # And I should see the following response body: - # """ - # {"hello":"rspec_api_documentation"} - # """ + + + h3. Response + + h4. Headers + +
Content-Type: application/json
+    Content-Length: 35
+ + h4. Status + +
200 OK
+ + h4. Body + +
{"hello":"rspec_api_documentation"}
+ + + + """ diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache index 9abe17f9..9dc2e55c 100644 --- a/templates/rspec_api_documentation/textile_example.mustache +++ b/templates/rspec_api_documentation/textile_example.mustache @@ -6,17 +6,14 @@ h3. {{ http_method }} {{ route }} {{# explanation }} {{ explanation }} - {{/ explanation }} {{# has_parameters? }} - h3. Parameters {{# parameters }} -Name : {{ name }} {{# required }} *- required -* {{/ required }} +Name : {{ name }} {{# required }} *- required -*{{/ required }} Description : {{ description }} - {{/ parameters }} {{/ has_parameters? }} From 47502e4fe39d67f3fe8ffbecca233e17ae2a3795 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Thu, 15 Aug 2013 16:37:47 +0200 Subject: [PATCH 12/21] Use Sinatra dummy app for textile_documentation.feature. --- features/textile_documentation.feature | 30 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index ada0988c..1276dcdc 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -3,13 +3,19 @@ Feature: Generate Textile documentation from test examples 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"] = "application/json" - response.write({ "hello" => request.params["target"] }.to_json) - response.finish + require 'sinatra' + + class App < Sinatra::Base + get '/greetings' do + content_type :json + + [200, { 'hello' => params[:target] }.to_json ] + end + + get '/cucumbers' do + content_type :json + + [200, { 'hello' => params[:target] }.to_json ] end end """ @@ -32,7 +38,7 @@ Feature: Generate Textile documentation from test examples example "Greeting your favorite gem" do do_request :target => "rspec_api_documentation" - response_headers["Content-Type"].should eq("application/json") + response_headers["Content-Type"].should eq("application/json;charset=utf-8") status.should eq(200) response_body.should eq('{"hello":"rspec_api_documentation"}') end @@ -40,7 +46,7 @@ Feature: Generate Textile documentation from test examples example "Greeting nothing" do do_request :target => "" - response_headers["Content-Type"].should eq("application/json") + response_headers["Content-Type"].should eq("application/json;charset=utf-8") status.should eq(200) response_body.should eq('{"hello":""}') end @@ -54,7 +60,7 @@ Feature: Generate Textile documentation from test examples example "Eating cucumbers in a bowl" do do_request :target => "bowl" - response_headers["Content-Type"].should eq("application/json") + response_headers["Content-Type"].should eq("application/json;charset=utf-8") status.should eq(200) response_body.should eq('{"hello":"bowl"}') end @@ -131,7 +137,9 @@ Feature: Generate Textile documentation from test examples h4. Headers -
Content-Type: application/json
+    
X-Frame-Options: sameorigin
+    X-XSS-Protection: 1; mode=block
+    Content-Type: application/json;charset=utf-8
     Content-Length: 35
h4. Status From e5defdb38618d1b950b4b20bd819ac881fa91074 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Sun, 18 Aug 2013 17:13:04 +0200 Subject: [PATCH 13/21] Rewrote the spec dummy api and its related api spec. --- features/textile_documentation.feature | 120 ++++++++++++++++++------- 1 file changed, 87 insertions(+), 33 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 1276dcdc..f26e9018 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -6,16 +6,33 @@ Feature: Generate Textile documentation from test examples require 'sinatra' class App < Sinatra::Base - get '/greetings' do + get '/orders' do content_type :json - [200, { 'hello' => params[:target] }.to_json ] + [200, [{ name: 'Order 1', amount: 9.99, description: nil }, + { name: 'Order 2', amount: 100.0, description: 'A great order' }].to_json] end - get '/cucumbers' do + get '/orders/:id' do content_type :json - [200, { 'hello' => params[:target] }.to_json ] + [200, { order: { name: 'Order 1', amount: 100.0, description: 'A great order' } }.to_json] + end + + post '/orders' do + 201 + end + + put '/orders/:id' do + 200 + end + + delete '/orders/:id' do + 200 + end + + get '/help' do + [200, 'Welcome Henry !'] end end """ @@ -30,41 +47,71 @@ Feature: Generate Textile documentation from test examples config.format = :textile end - resource "Greetings" do - get "/greetings" do - parameter :target, "The thing you want to greet" - required_parameters :target - - example "Greeting your favorite gem" do - do_request :target => "rspec_api_documentation" + resource 'Orders' do + get '/orders' do - response_headers["Content-Type"].should eq("application/json;charset=utf-8") + example_request 'Getting a list of orders' do status.should eq(200) - response_body.should eq('{"hello":"rspec_api_documentation"}') + response_body.should eq('[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]') end + end - example "Greeting nothing" do - do_request :target => "" + get '/orders/:id' do + let(:id) { 1 } - response_headers["Content-Type"].should eq("application/json;charset=utf-8") + example_request 'Getting a specific order' do status.should eq(200) - response_body.should eq('{"hello":""}') + response_body.should == '{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}' end end - end - resource "Cucumbers" do - get "/cucumbers" do - parameter :target, "The thing in which you want to eat cucumbers" + post '/orders' do + parameter :name, 'Name of order' + parameter :amount, 'Amount paid' + parameter :description, 'Some comments on the order' - example "Eating cucumbers in a bowl" do - do_request :target => "bowl" + required_parameters :name, :amount - response_headers["Content-Type"].should eq("application/json;charset=utf-8") + let(:name) { "Order 3" } + let(:amount) { 33.0 } + + example_request 'Creating an order' do + status.should == 201 + end + end + + put '/orders/:id' do + parameter :name, 'Name of order' + parameter :amount, 'Amount paid' + parameter :description, 'Some comments on the order' + + required_parameters :name, :amount + + let(:id) { 2 } + let(:name) { "Updated name" } + + example_request 'Updating an order' do + status.should == 200 + end + end + + delete "/orders/:id" do + let(:id) { 1 } + + example_request "Deleting an order" do + status.should == 200 + end + end + end + + resource 'Help' do + get '/help' do + example_request 'Getting welcome message' do status.should eq(200) - response_body.should eq('{"hello":"bowl"}') + response_body.should == 'Welcome Henry !' end end + end """ When I run `rspec app_spec.rb --require ./app.rb --format RspecApiDocumentation::ApiFormatter` @@ -73,15 +120,22 @@ Feature: Generate Textile documentation from test examples Then the output should contain: """ Generating API Docs - Greetings - GET /greetings - * Greeting your favorite gem - * Greeting nothing - Cucumbers - GET /cucumbers - * Eating cucumbers in a bowl + Orders + GET /orders + * Getting a list of orders + GET /orders/:id + * Getting a specific order + POST /orders + * Creating an order + PUT /orders/:id + * Updating an order + DELETE /orders/:id + * Deleting an order + Help + GET /help + * Getting welcome message """ - And the output should contain "3 examples, 0 failures" + And the output should contain "6 examples, 0 failures" And the exit status should be 0 Scenario: Index file should look like we expect From 1e9ed3fba4c71a814cec32da0f45d49509a0e30a Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Sun, 18 Aug 2013 17:17:43 +0200 Subject: [PATCH 14/21] In textile_documentation.feature, contents retested with new api. --- features/textile_documentation.feature | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index f26e9018..28aec71b 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -143,14 +143,17 @@ Feature: Generate Textile documentation from test examples """ h1. Example API - h2. Cucumbers + h2. Help - * Eating cucumbers in a bowl + * Getting welcome message - h2. Greetings + h2. Orders - * Greeting nothing - * Greeting your favorite gem + * Creating an order + * Deleting an order + * Getting a list of orders + * Getting a specific order + * Updating an order """ From 3904c77762396a916ddabdce8bdc35b97f3f9bdf Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Mon, 19 Aug 2013 08:41:32 +0200 Subject: [PATCH 15/21] Check contents of 'Creating an order' example file in textile_documentation feature. --- features/textile_documentation.feature | 36 ++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 28aec71b..2be8875e 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -158,36 +158,43 @@ Feature: Generate Textile documentation from test examples """ - Scenario: Example 'Greeting your favorite gem' file should look like we expect - Then the file "docs/greetings/greeting_your_favorite_gem.textile" should contain exactly: + Scenario: Example 'Creating an order' file should look like we expect + Then the file "docs/orders/creating_an_order.textile" should contain exactly: """ - h1. Greetings API + h1. Orders API - h2. Greeting your favorite gem + h2. Creating an order - h3. GET /greetings + h3. POST /orders h3. Parameters - Name : target *- required -* - Description : The thing you want to greet + Name : name *- required -* + Description : Name of order + + Name : amount *- required -* + Description : Amount paid + + Name : description + Description : Some comments on the order h3. Request h4. Headers
Host: example.org
+    Content-Type: application/x-www-form-urlencoded
     Cookie: 
h4. Route -
GET /greetings?target=rspec_api_documentation
+
POST /orders
- h4. Query Parameters -
target: rspec_api_documentation
+ h4. Body +
name=Order+3&amount=33.0
h3. Response @@ -196,16 +203,13 @@ Feature: Generate Textile documentation from test examples
X-Frame-Options: sameorigin
     X-XSS-Protection: 1; mode=block
-    Content-Type: application/json;charset=utf-8
-    Content-Length: 35
+ Content-Type: text/html;charset=utf-8 + Content-Length: 0
h4. Status -
200 OK
- - h4. Body +
201 Created
-
{"hello":"rspec_api_documentation"}
From ae1eeb97a2a794762ce54a7dbcca69c2ddc1c754 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Mon, 19 Aug 2013 09:32:40 +0200 Subject: [PATCH 16/21] Added scenarios to test presence of generated examples textile for new test api. --- features/textile_documentation.feature | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 2be8875e..82f8a625 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -214,3 +214,20 @@ Feature: Generate Textile documentation from test examples """ + + Scenario: Example 'Deleting an order' file should exist + Then the file "docs/orders/deleting_an_order.textile" should exist + + Scenario: Example 'Getting a list of orders' file should exist + Then the file "docs/orders/getting_a_list_of_orders.textile" should exist + + Scenario: Example 'Getting a specific order' file should exist + Then the file "docs/orders/getting_a_specific_order.textile" should exist + + Scenario: Example 'Updating an order' file should exist + Then the file "docs/orders/updating_an_order.textile" should exist + + Scenario: Example 'Getting welcome message' file should exist + Then the file "docs/help/getting_welcome_message.textile" should exist + + From 1a99d050d7dbd7bc3cb08d6e6ac6d04e934cde9a Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Tue, 20 Aug 2013 15:57:52 +0200 Subject: [PATCH 17/21] Corrections on scenarios in textile_documentation.feature to test presence of generated examples. --- features/textile_documentation.feature | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 82f8a625..30f1619b 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -215,19 +215,19 @@ Feature: Generate Textile documentation from test examples """ - Scenario: Example 'Deleting an order' file should exist - Then the file "docs/orders/deleting_an_order.textile" should exist + Scenario: Example 'Deleting an order' file should be created + Then a file named "docs/orders/deleting_an_order.textile" should exist - Scenario: Example 'Getting a list of orders' file should exist - Then the file "docs/orders/getting_a_list_of_orders.textile" should exist + Scenario: Example 'Getting a list of orders' file should be created + Then a file named "docs/orders/getting_a_list_of_orders.textile" should exist - Scenario: Example 'Getting a specific order' file should exist - Then the file "docs/orders/getting_a_specific_order.textile" should exist + Scenario: Example 'Getting a specific order' file should be created + Then a file named "docs/orders/getting_a_specific_order.textile" should exist - Scenario: Example 'Updating an order' file should exist - Then the file "docs/orders/updating_an_order.textile" should exist + Scenario: Example 'Updating an order' file should be created + Then a file named "docs/orders/updating_an_order.textile" should exist - Scenario: Example 'Getting welcome message' file should exist - Then the file "docs/help/getting_welcome_message.textile" should exist + Scenario: Example 'Getting welcome message' file should be created + Then a file named "docs/help/getting_welcome_message.textile" should exist From 655329435c12a81ad52183aa46c67dfd6292a319 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Tue, 20 Aug 2013 16:14:40 +0200 Subject: [PATCH 18/21] Added TextileWriter test cases in api_documentation_spec.rb. --- spec/api_documentation_spec.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/api_documentation_spec.rb b/spec/api_documentation_spec.rb index 1c1087c3..47ab8676 100644 --- a/spec/api_documentation_spec.rb +++ b/spec/api_documentation_spec.rb @@ -60,14 +60,16 @@ describe "#writers" do class RspecApiDocumentation::Writers::HtmlWriter; end class RspecApiDocumentation::Writers::JsonWriter; end + class RspecApiDocumentation::Writers::TextileWriter; end context "multiple" do before do - configuration.format = [:html, :json] + configuration.format = [:html, :json, :textile] end it "should return the classes from format" do - subject.writers.should == [RspecApiDocumentation::Writers::HtmlWriter, RspecApiDocumentation::Writers::JsonWriter] + subject.writers.should == [RspecApiDocumentation::Writers::HtmlWriter, RspecApiDocumentation::Writers::JsonWriter, + RspecApiDocumentation::Writers::TextileWriter] end end @@ -85,14 +87,16 @@ class RspecApiDocumentation::Writers::JsonWriter; end describe "#write" do let(:html_writer) { stub } let(:json_writer) { stub } + let(:textile_writer) { stub } before do - subject.stub!(:writers => [html_writer, json_writer]) + subject.stub!(:writers => [html_writer, json_writer, textile_writer]) end it "should write the docs in each format" do html_writer.should_receive(:write).with(subject.index, configuration) json_writer.should_receive(:write).with(subject.index, configuration) + textile_writer.should_receive(:write).with(subject.index, configuration) subject.write end end From 48690633eb74169db4b6e4188fc87f1e8706aa74 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 30 Aug 2013 10:40:13 +0200 Subject: [PATCH 19/21] Updated textile_documentation.feature with the latest DSL and path generation changes. --- features/textile_documentation.feature | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 30f1619b..9b30c263 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -66,12 +66,10 @@ Feature: Generate Textile documentation from test examples end post '/orders' do - parameter :name, 'Name of order' - parameter :amount, 'Amount paid' + parameter :name, 'Name of order', :required => true + parameter :amount, 'Amount paid', :required => true parameter :description, 'Some comments on the order' - required_parameters :name, :amount - let(:name) { "Order 3" } let(:amount) { 33.0 } @@ -81,12 +79,10 @@ Feature: Generate Textile documentation from test examples end put '/orders/:id' do - parameter :name, 'Name of order' - parameter :amount, 'Amount paid' + parameter :name, 'Name of order', :required => true + parameter :amount, 'Amount paid', :required => true parameter :description, 'Some comments on the order' - required_parameters :name, :amount - let(:id) { 2 } let(:name) { "Updated name" } @@ -139,7 +135,7 @@ Feature: Generate Textile documentation from test examples And the exit status should be 0 Scenario: Index file should look like we expect - Then the file "docs/index.textile" should contain exactly: + Then the file "doc/api/index.textile" should contain exactly: """ h1. Example API @@ -159,7 +155,7 @@ Feature: Generate Textile documentation from test examples """ Scenario: Example 'Creating an order' file should look like we expect - Then the file "docs/orders/creating_an_order.textile" should contain exactly: + Then the file "doc/api/orders/creating_an_order.textile" should contain exactly: """ h1. Orders API @@ -216,18 +212,18 @@ Feature: Generate Textile documentation from test examples """ Scenario: Example 'Deleting an order' file should be created - Then a file named "docs/orders/deleting_an_order.textile" should exist + Then a file named "doc/api/orders/deleting_an_order.textile" should exist Scenario: Example 'Getting a list of orders' file should be created - Then a file named "docs/orders/getting_a_list_of_orders.textile" should exist + Then a file named "doc/api/orders/getting_a_list_of_orders.textile" should exist Scenario: Example 'Getting a specific order' file should be created - Then a file named "docs/orders/getting_a_specific_order.textile" should exist + Then a file named "doc/api/orders/getting_a_specific_order.textile" should exist Scenario: Example 'Updating an order' file should be created - Then a file named "docs/orders/updating_an_order.textile" should exist + Then a file named "doc/api/orders/updating_an_order.textile" should exist Scenario: Example 'Getting welcome message' file should be created - Then a file named "docs/help/getting_welcome_message.textile" should exist + Then a file named "doc/api/help/getting_welcome_message.textile" should exist From 5cd4d3ab3ce5dd0df13ff03547cd4f400e8601d3 Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 30 Aug 2013 11:52:04 +0200 Subject: [PATCH 20/21] Fix in MarkupIndex that should not use HtmlExample. --- lib/rspec_api_documentation/views/html_index.rb | 4 ++++ lib/rspec_api_documentation/views/markup_index.rb | 4 ---- lib/rspec_api_documentation/views/textile_index.rb | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/rspec_api_documentation/views/html_index.rb b/lib/rspec_api_documentation/views/html_index.rb index c4f8a8bd..3a56ccd4 100644 --- a/lib/rspec_api_documentation/views/html_index.rb +++ b/lib/rspec_api_documentation/views/html_index.rb @@ -5,6 +5,10 @@ def initialize(index, configuration) super self.template_name = "rspec_api_documentation/html_index" end + + def examples + @index.examples.map { |example| HtmlExample.new(example, @configuration) } + end end end end diff --git a/lib/rspec_api_documentation/views/markup_index.rb b/lib/rspec_api_documentation/views/markup_index.rb index b0a3646b..f0bd6c3d 100644 --- a/lib/rspec_api_documentation/views/markup_index.rb +++ b/lib/rspec_api_documentation/views/markup_index.rb @@ -16,10 +16,6 @@ def api_name def sections RspecApiDocumentation::Writers::IndexWriter.sections(examples, @configuration) end - - def examples - @index.examples.map { |example| HtmlExample.new(example, @configuration) } - end end end end diff --git a/lib/rspec_api_documentation/views/textile_index.rb b/lib/rspec_api_documentation/views/textile_index.rb index eaca2f38..d6aeb6ef 100644 --- a/lib/rspec_api_documentation/views/textile_index.rb +++ b/lib/rspec_api_documentation/views/textile_index.rb @@ -5,6 +5,10 @@ def initialize(index, configuration) super self.template_name = "rspec_api_documentation/textile_index" end + + def examples + @index.examples.map { |example| TextileExample.new(example, @configuration) } + end end end end From c8819f6841faab5e50036ea103df80dab4e86a1e Mon Sep 17 00:00:00 2001 From: Jonathan Pares Date: Fri, 30 Aug 2013 11:52:45 +0200 Subject: [PATCH 21/21] Added links to textile examples in textile index. --- features/textile_documentation.feature | 12 ++++++------ .../rspec_api_documentation/textile_index.mustache | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 9b30c263..fa668d7d 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -141,15 +141,15 @@ Feature: Generate Textile documentation from test examples h2. Help - * Getting welcome message + * "Getting welcome message":help/getting_welcome_message.textile h2. Orders - * Creating an order - * Deleting an order - * Getting a list of orders - * Getting a specific order - * Updating an order + * "Creating an order":orders/creating_an_order.textile + * "Deleting an order":orders/deleting_an_order.textile + * "Getting a list of orders":orders/getting_a_list_of_orders.textile + * "Getting a specific order":orders/getting_a_specific_order.textile + * "Updating an order":orders/updating_an_order.textile """ diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache index 78d15ec2..cbb93d57 100644 --- a/templates/rspec_api_documentation/textile_index.mustache +++ b/templates/rspec_api_documentation/textile_index.mustache @@ -4,7 +4,7 @@ h1. {{ api_name }} h2. {{ resource_name }} {{# examples }} -* {{ description }} +* "{{ description }}":{{ dirname }}/{{ filename }} {{/ examples }} {{/ sections }}