fdoc 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,26 +18,32 @@ Add fdoc to your Gemfile.
18
18
 
19
19
  gem 'fdoc'
20
20
 
21
- Tell fdoc where to look for .fdoc files. By default, fdoc will look in `docs/fdoc`, but you can change this behavior to look anywhere. This fits best in something like a spec\_helper file.
21
+ Tell fdoc where to look for `.fdoc` files. By default, fdoc will look in `docs/fdoc`, but you can change this behavior to look anywhere. This fits best in something like a spec\_helper file.
22
22
 
23
- require 'fdoc'
23
+ ```ruby
24
+ require 'fdoc'
24
25
 
25
- Fdoc.service_path = "path/to/your/fdocs"
26
+ Fdoc.service_path = "path/to/your/fdocs"
27
+ ```
26
28
 
27
29
  fdoc is built to work around controller specs in rspec, and provides `Fdoc::SpecWatcher` as a mixin. Make sure to include it *inside* your top level describe.
28
30
 
29
- require 'fdoc/spec_watcher'
31
+ ```ruby
32
+ require 'fdoc/spec_watcher'
30
33
 
31
- describe MembersController do
32
- include Fdoc::SpecWatcher
33
- ...
34
- end
34
+ describe MembersController do
35
+ include Fdoc::SpecWatcher
36
+ # ...
37
+ end
38
+ ```
35
39
 
36
40
  To enable fdoc for an endpoint, add the `fdoc` option with the path to the endpoint. fdoc will intercept all calls to `get`, `post`, `put`, and `delete` and verify those parameters accordingly.
37
41
 
38
- context "#show", :fdoc => 'members/list' do
39
- ..
40
- end
42
+ ```ruby
43
+ context "#show", :fdoc => 'members/list' do
44
+ # ...
45
+ end
46
+ ```
41
47
 
42
48
  fdoc also has a scaffolding mode, where it attemps to infer the schema of a request based on sample responses. The interface is exactly the same as verifying, just set the environment variable `FDOC_SCAFFOLD=true`.
43
49
 
@@ -51,7 +57,7 @@ fdoc provides the `fdoc_to_html` script to transform a directory of `.fdoc` file
51
57
 
52
58
  In this repo, try running:
53
59
 
54
- bin/fdoc_to_html spec/fixtures html
60
+ bin/fdoc_to_html ./spec/fixtures ./html
55
61
 
56
62
  ## Example
57
63
 
@@ -60,37 +66,90 @@ In this repo, try running:
60
66
  - For more information on fdoc file naming conventions, please see the [fdoc file conventions guide][github_files].
61
67
  - For more information on how fdoc uses JSON schema, please see the [json schema usage document][github_json].
62
68
 
63
- Here is `members/list-POST.fdoc`:
64
-
65
- description: The list of members.
66
- requestParameters:
67
- properties:
68
- limit:
69
- type: integer
70
- required: no
71
- default: 50
72
- description: Limits the number of results returned, used for paging.
73
- responseParameters:
74
- properties:
75
- members:
76
- type: array
77
- items:
78
- title: member
79
- description: Representation of a member
80
- type: object
81
- properties:
82
- name:
83
- description: Member's name
84
- type: string
85
- required: yes
86
- example: Captain Smellypants
87
- responseCodes:
88
- - status: 200 OK
89
- successful: yes
90
- description: A list of current members
91
- - status: 400 Bad Request
92
- successful: no
93
- description: Indicates malformed parameters
69
+ Here is `docs/fdoc/members/list-GET.fdoc`:
70
+
71
+ ```yaml
72
+ description: The list of members.
73
+ requestParameters:
74
+ properties:
75
+ limit:
76
+ type: integer
77
+ required: no
78
+ default: 50
79
+ description: Limits the number of results returned, used for paging.
80
+ responseParameters:
81
+ properties:
82
+ members:
83
+ type: array
84
+ items:
85
+ title: member
86
+ description: Representation of a member
87
+ type: object
88
+ properties:
89
+ name:
90
+ description: Member's name
91
+ type: string
92
+ required: yes
93
+ example: Captain Smellypants
94
+ responseCodes:
95
+ - status: 200 OK
96
+ successful: yes
97
+ description: A list of current members
98
+ - status: 400 Bad Request
99
+ successful: no
100
+ description: Indicates malformed parameters
101
+ ```
102
+
103
+ If we run a test against our members controller with an undocumented parameter, `offset`, we'll get an error.
104
+
105
+ Our spec file, `spec/controllers/members_controller_spec.rb` looks like:
106
+
107
+ ```ruby
108
+ require 'fdoc/spec_watcher'
109
+
110
+ describe MembersController do
111
+ content "#show", :fdoc => "members/list" do
112
+ it "can take an offset" do
113
+ get :show, {
114
+ :offset => 5
115
+ }
116
+ end
117
+ end
118
+ end
119
+ ```
120
+
121
+ We run:
122
+
123
+ bundle exec rspec spec/controllers/members_controller_spec.rb
124
+
125
+ And since `offset` is undocumented, fdoc will fail the test:
126
+
127
+ Failures:
128
+
129
+ 1) MembersController#show can take an offset
130
+ Failure/Error: get :show, { :offset => 5 }
131
+ JSON::Schema::ValidationError:
132
+ The property '#/' contains additional properties ["offset"] outside of the schema when none are allowed in schema 8fcac6c4-294b-56a2-a3de-9342e2e729da#
133
+ # ./spec/controllers/members_controller_spec.rb:5:in `block (3 levels) in <top (required)>'
134
+
135
+ If we run the same spec in scaffold mode, it passes and fdoc will write changes to the correspoding `.fdoc` file:
136
+
137
+ FDOC_SCAFFOLD=true bundle exec spec/controllers/members_controller_spec.rb
138
+
139
+ The diff looks like:
140
+
141
+ ```diff
142
+ diff --git a/docs/fdoc/members/list-GET.fdoc b/docs/fdoc/members/list-GET.fdoc b2e3656..dfa363a 100644
143
+ --- a/docs/fdoc/members/list-GET.fdoc
144
+ +++ b/docs/fdoc/members/list-GET.fdoc
145
+ + offset:
146
+ + description: ???
147
+ + required: ???
148
+ + type: integer
149
+ + example: 5
150
+ ```
151
+
152
+ Notice how it infers a type, and copies an example, but leaves description and required blank. These fields are best left to humans to decide.
94
153
 
95
154
 
96
155
  ## Goals
@@ -55,4 +55,15 @@ class Fdoc::HtmlPresenter
55
55
  html_path
56
56
  end
57
57
  end
58
+
59
+ def tag_with_anchor(tag, content, anchor_slug = nil)
60
+ anchor_slug ||= content.downcase.gsub(' ', '_')
61
+ <<-EOS
62
+ <#{tag} id="#{anchor_slug}">
63
+ <a href="##{anchor_slug}" class="anchor">
64
+ #{content}
65
+ </a>
66
+ </#{tag}>
67
+ EOS
68
+ end
58
69
  end
@@ -61,5 +61,6 @@ class Fdoc::MetaServicePresenter < Fdoc::HtmlPresenter
61
61
  presenter = Fdoc::EndpointPresenter.new(endpoint,
62
62
  options.merge(:prefix => (service_presenter.slug_name + "/")))
63
63
  presenter.service_presenter = service_presenter
64
+ presenter
64
65
  end
65
66
  end
@@ -128,11 +128,19 @@ class Fdoc::SchemaPresenter < Fdoc::HtmlPresenter
128
128
  properties.each do |key, property|
129
129
  next if property.nil?
130
130
  html << '<li>'
131
- html << '<tt>%s</tt>' % key
131
+ html << tag_with_anchor(
132
+ 'span',
133
+ '<tt>%s</tt>' % key,
134
+ schema_slug(key, property)
135
+ )
132
136
  html << self.class.new(property, options.merge(:nested => true)).to_html
133
137
  html << '</li>'
134
138
  end
135
139
 
136
140
  html
137
141
  end
142
+
143
+ def schema_slug(key, property)
144
+ "#{key}-#{property.hash}"
145
+ end
138
146
  end
@@ -28,27 +28,27 @@
28
28
  <%= description %>
29
29
 
30
30
  <% if show_request? %>
31
- <h2>Request</h2>
31
+ <%= tag_with_anchor('h2', 'Request') %>
32
32
 
33
- <h3>Example Request</h3>
33
+ <%= tag_with_anchor('h3', 'Example Request') %>
34
34
  <%= example_request %>
35
35
 
36
- <h3>Request Parameters</h3>
36
+ <%= tag_with_anchor('h3', 'Request Parameters') %>
37
37
  <%= request_parameters %>
38
38
  <% end %>
39
39
 
40
- <h2>Response</h2>
40
+ <%= tag_with_anchor('h2', 'Response') %>
41
41
  <% if show_response? %>
42
- <h3>Example Response</h3>
42
+ <%= tag_with_anchor('h3', 'Example Response') %>
43
43
  <%= example_response %>
44
44
 
45
- <h3>Response Parameters</h3>
45
+ <%= tag_with_anchor('h3', 'Response Parameters') %>
46
46
  <%= response_parameters %>
47
47
  <% end %>
48
48
 
49
- <h3>Response Codes</h3>
49
+ <%= tag_with_anchor('h3', 'Response Codes') %>
50
50
  <% if !successful_response_codes.empty? %>
51
- <h4>Successful Response Codes</h4>
51
+ <%= tag_with_anchor('h4', 'Successful Response Codes') %>
52
52
  <ul>
53
53
  <% successful_response_codes.each do |response_code| %>
54
54
  <li>
@@ -59,7 +59,7 @@
59
59
  <% end %>
60
60
 
61
61
  <% if !successful_response_codes.empty? %>
62
- <h4>Failure Response Codes</h4>
62
+ <%= tag_with_anchor('h4', 'Failure Response Codes') %>
63
63
  <ul>
64
64
  <% failure_response_codes.each do |response_code| %>
65
65
  <li>
@@ -16,9 +16,7 @@
16
16
 
17
17
  <%= description %>
18
18
 
19
- <h2>
20
- Services
21
- </h2>
19
+ <%= tag_with_anchor('h2', 'Services') %>
22
20
 
23
21
  <ul>
24
22
  <% services.each do |serv| %>
@@ -30,14 +28,10 @@
30
28
  <% end %>
31
29
  </ul>
32
30
 
33
- <h2>
34
- Endpoints
35
- </h2>
31
+ <%= tag_with_anchor('h2', 'Endpoints') %>
36
32
 
37
33
  <% endpoints.each do |endpoint_ary| %>
38
- <h3>
39
- <%= endpoint_ary.first.prefix %>
40
- </h3>
34
+ <%= tag_with_anchor('h3', endpoint_ary.first.prefix) %>
41
35
  <ul>
42
36
  <% endpoint_ary.each do |endpoint| %>
43
37
  <li>
@@ -48,9 +42,7 @@
48
42
  <% end %>
49
43
 
50
44
  <% if discussion %>
51
- <h2>
52
- Discussion
53
- </h2>
45
+ <%= tag_with_anchor('h2', 'Discussion') %>
54
46
  <%= discussion %>
55
47
  <% end %>
56
48
  </div>
@@ -24,14 +24,10 @@
24
24
 
25
25
  <%= description %>
26
26
 
27
- <h2>
28
- Endpoints
29
- </h2>
27
+ <%= tag_with_anchor('h2', 'Endpoints') %>
30
28
 
31
29
  <% endpoints.each do |endpoint_ary| %>
32
- <h3>
33
- <%= endpoint_ary.first.prefix %>
34
- </h3>
30
+ <%= tag_with_anchor('h3', endpoint_ary.first.prefix) %>
35
31
  <ul>
36
32
  <% endpoint_ary.each do |endpoint| %>
37
33
  <li>
@@ -42,9 +38,7 @@
42
38
  <% end %>
43
39
 
44
40
  <% if discussion %>
45
- <h2>
46
- Discussion
47
- </h2>
41
+ <%= tag_with_anchor('h2', 'Discussion') %>
48
42
  <%= discussion %>
49
43
  <% end %>
50
44
  </div>
@@ -29,6 +29,18 @@ h1, h2, h3 { font-weight: 200; }
29
29
  a { text-decoration: none; color: #66f; }
30
30
  a:hover, a:active { text-decoration: underline; }
31
31
 
32
+ a.anchor { color: inherit; }
33
+ a.anchor:hover, a.anchor:active { text-decoration: none;}
34
+ a.anchor:hover::before, a.anchor.active::before {
35
+ background: white;
36
+ display: inline-block;
37
+ position: absolute;
38
+ content: '\0261E';
39
+ font-size: 120%;
40
+ font-weight: bold;
41
+ margin-left: -1.2em;
42
+ }
43
+
32
44
  ul {
33
45
  list-style: square;
34
46
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fdoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -15,7 +15,7 @@ date: 2011-11-07 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json
18
- requirement: &70339438797600 !ruby/object:Gem::Requirement
18
+ requirement: &70290789895620 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70339438797600
26
+ version_requirements: *70290789895620
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json-schema
29
- requirement: &70339438796920 !ruby/object:Gem::Requirement
29
+ requirement: &70290789911300 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 1.0.1
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70339438796920
37
+ version_requirements: *70290789911300
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: kramdown
40
- requirement: &70339438796340 !ruby/object:Gem::Requirement
40
+ requirement: &70290789910780 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '0'
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70339438796340
48
+ version_requirements: *70290789910780
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rake
51
- requirement: &70339438792260 !ruby/object:Gem::Requirement
51
+ requirement: &70290789910100 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *70339438792260
59
+ version_requirements: *70290789910100
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rspec
62
- requirement: &70339438791760 !ruby/object:Gem::Requirement
62
+ requirement: &70290789909420 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ~>
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: '2.5'
68
68
  type: :development
69
69
  prerelease: false
70
- version_requirements: *70339438791760
70
+ version_requirements: *70290789909420
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: nokogiri
73
- requirement: &70339438791300 !ruby/object:Gem::Requirement
73
+ requirement: &70290789908980 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '0'
79
79
  type: :development
80
80
  prerelease: false
81
- version_requirements: *70339438791300
81
+ version_requirements: *70290789908980
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: cane
84
- requirement: &70339438790760 !ruby/object:Gem::Requirement
84
+ requirement: &70290789908380 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,7 +89,7 @@ dependencies:
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
- version_requirements: *70339438790760
92
+ version_requirements: *70290789908380
93
93
  description: A tool for documenting API endpoints.
94
94
  email: support@squareup.com
95
95
  executables:
@@ -172,3 +172,4 @@ test_files:
172
172
  - spec/fixtures/members/members.fdoc.service
173
173
  - spec/fixtures/sample_group.fdoc.meta
174
174
  - spec/spec_helper.rb
175
+ has_rdoc: