rspec-document_requests 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 231e877c797beff56b6713d86e7247cf7e31ea72
4
- data.tar.gz: 06f5cbf0269fa7c3d5f772425081619327ef7ab7
3
+ metadata.gz: 7c1fd117650183a8e2b17f41acfeb19bcd011251
4
+ data.tar.gz: 582ddbaa7fd602d131b676747a10b084172fb479
5
5
  SHA512:
6
- metadata.gz: efc0c7d69098f85741a3cbc27e395e6addb62510226ac4398a4c27e624d3c910e8eeb4dbb488c5d27e0e1219c1852eda4b14749569ec7239392789cc9f7cf116
7
- data.tar.gz: 3cff5a55338cf639810fc696855c0aa9089f78e5629969447c7f5ddfa6eb157a7cf07c32fa419b9c1ffb17e65698c4ba4ec4a22f3e7b6683bed850fe8442f0d1
6
+ metadata.gz: e31e5dcc0518b3c6305ad60a8ac1f34dd2047ccd4a5759aaf4ffebc7a4b79764cce964edc29ca069338314e21a31e9bab892a269d2d8feeb63c50217f97bdd8b
7
+ data.tar.gz: 8952825398234193dc0dad866685978a5fd4e5e601bbd9a3258e91dc53ed6ed8835b6612df2acaa2993100972656849640e8b8e2c34f7e3f67e7f9eff829a103
data/README.md CHANGED
@@ -44,6 +44,8 @@ require 'rspec/document_requests/dsl' # <- this line
44
44
 
45
45
  ### Marking code to document
46
46
 
47
+ **NOTE:** The `nodoc` DSL is not available in example groups (`describe`/`context`) without `doc: true`.
48
+
47
49
  In your example group (`describe`/`context`), simply add the `doc: true` metadata:
48
50
 
49
51
  ```ruby
@@ -85,7 +87,7 @@ also exclude any specs without `doc: true` metadata to make this run faster.
85
87
 
86
88
  ### Explaining the request
87
89
 
88
- **NOTE:** This DSL is not available in `doc: false` example groups (`describe`/`context`).
90
+ **NOTE:** The `explain` DSL is not available in example groups (`describe`/`context`) without `doc: true`.
89
91
 
90
92
  Just before your request, it's a good idea to explain (everything is optional):
91
93
 
@@ -93,20 +95,20 @@ Just before your request, it's a good idea to explain (everything is optional):
93
95
  # spec/requests/session_spec.rb
94
96
 
95
97
  RSpec.describe "Session resource", type: :request, doc: true do
96
- describe "Create session" do
98
+ describe "Create session", explanation: "This is how you create a session." do
97
99
  before do
98
- explain "Creating the user"
100
+ explain { request "Creating a user" }
99
101
  post "/users", user: { username: "myuser", password: "123123" }
100
102
  end
101
103
 
102
104
  before do
103
- explain do # No request explanation
104
- request do
105
+ explain do
106
+ request do # No request explanation
105
107
  parameter 'session[username]', "The username", required: true, type: 'string'
106
108
  parameter 'session[password]', required: true, type: 'string' # No explanation
107
109
  header 'Content-Type', ... # you get the point
108
110
  end
109
- response do
111
+ response do # No response explanation
110
112
  parameter 'message', "Message from the server", required: true # No type
111
113
  parameter 'session_id', "The session ID" # Not required and no type
112
114
  header 'Set-Cookie', ...
@@ -30,8 +30,9 @@ module RSpec
30
30
  @writer = config.writer.new(file)
31
31
  write_breadcrumb
32
32
  write_title
33
- @current.ungrouped_children.each { |child| write_child(child) }
33
+ @current.ungrouped_children.each { |child| write_child(child, last: child == @current.ungrouped_children.last) }
34
34
  write_recursive_requests(@current)
35
+ @writer.close
35
36
  end
36
37
 
37
38
  @current.ungrouped_children.each do |child|
@@ -44,12 +45,18 @@ module RSpec
44
45
  missing_levels = []
45
46
  if not child == @current
46
47
  missing = child
47
- missing_levels.unshift(missing.description) while (missing = missing.parent) and missing != @current
48
+ missing_levels.unshift(missing) while (missing = missing.parent) and missing != @current
49
+ end
50
+ missing_levels = missing_levels.map do |organized_entry|
51
+ {
52
+ description: organized_entry.metadata[:description],
53
+ explanation: metadata_explanation(organized_entry.metadata),
54
+ }
48
55
  end
49
56
 
50
57
  child.example_requests.to_a.uniq { |e,| e.example_group }.each do |example, requests|
51
58
  write_example_title(example, missing_levels: missing_levels) unless child == @current
52
- requests.each { |request| write_request(request, missing_levels: missing_levels) }
59
+ requests.each { |request| write_request(request) }
53
60
  end
54
61
 
55
62
  child.grouped_children.each_with_index do |grandchild, i|
@@ -57,6 +64,10 @@ module RSpec
57
64
  end
58
65
  end
59
66
 
67
+ def metadata_explanation(metadata)
68
+ metadata[:explanation] if metadata[:parent_example_group].nil? or metadata[:explanation] != metadata[:parent_example_group][:explanation]
69
+ end
70
+
60
71
  def write_breadcrumb
61
72
  current = @current
62
73
  parent_tree = []
@@ -67,7 +78,7 @@ module RSpec
67
78
  parent_path = Pathname.new('.').join(*parent_tree.length.times.map { '..' })
68
79
  parent_tree.each do |parent|
69
80
  @writer.breadcrumb(
70
- description: parent.description,
81
+ description: parent.metadata[:description],
71
82
  filename: parent_path.join(parent.filename).sub_ext(config.writer::EXTENSION),
72
83
  last: parent == @current.parent,
73
84
  )
@@ -76,22 +87,37 @@ module RSpec
76
87
  end
77
88
 
78
89
  def write_title
79
- @writer.title(@current.description)
90
+ metadata = @current.metadata
91
+ @writer.title(description: metadata[:description], explanation: metadata_explanation(metadata))
80
92
  end
81
93
 
82
- def write_child(child)
94
+ def write_child(child, last:)
83
95
  @writer.child(
84
- description: child.description,
96
+ description: child.metadata[:description],
85
97
  filename: @current.filename.join(child.filename).sub_ext(config.writer::EXTENSION),
98
+ last: last,
86
99
  )
87
100
  end
88
101
 
89
102
  def write_example_title(example, missing_levels:)
90
- @writer.example_title(example.example_group.metadata[:description], missing_levels: missing_levels)
103
+ metadata = example.example_group.metadata
104
+ @writer.example_title(description: metadata[:description], explanation: metadata_explanation(metadata), missing_levels: missing_levels)
91
105
  end
92
106
 
93
- def write_request(request, missing_levels:)
94
- @writer.request(request, missing_levels: missing_levels)
107
+ def write_request(request)
108
+ # request
109
+ @writer.request.title(request.explanation.request.message)
110
+ @writer.request.path(request.method, request.path)
111
+ @writer.request.parameters(request.request_parameters) if request.request_parameters.present?
112
+ @writer.request.body(request.request_body) if request.request_body.present?
113
+ @writer.request.headers(request.request_headers) if request.request_headers.present?
114
+ # response
115
+ @writer.response.title(request.explanation.response.message)
116
+ @writer.response.status(request.response.status, request.response.status_message)
117
+ @writer.response.content_type(request.response.content_type)
118
+ @writer.response.parameters(request.response_parameters) if request.response_parameters.present?
119
+ @writer.response.body(request.response.body) if request.response.body.present?
120
+ @writer.response.headers(request.response_headers) if request.response_headers.present?
95
121
  end
96
122
  end
97
123
  end
@@ -28,9 +28,8 @@ module RSpec
28
28
  end
29
29
  end
30
30
 
31
- def explain(message = nil, &block)
32
- document_request_explanation.message = message if message
33
- document_request_explanation.instance_eval(&block) if block_given?
31
+ def explain(&block)
32
+ document_request_explanation.instance_eval(&block)
34
33
  end
35
34
 
36
35
  def document_request_explanation
@@ -2,7 +2,7 @@ module RSpec
2
2
  module DocumentRequests
3
3
  class Explanation
4
4
  class Side
5
- attr_accessor :parameters, :headers
5
+ attr_accessor :message, :parameters, :headers
6
6
 
7
7
  def initialize
8
8
  @parameters = {}
@@ -18,22 +18,22 @@ module RSpec
18
18
  end
19
19
  end
20
20
 
21
- attr_accessor :message
22
-
23
21
  def initialize
24
22
  @request = Side.new
25
23
  @response = Side.new
26
24
  end
27
25
 
28
- def request(&block)
29
- @request.instance_eval(&block) if block_given?
30
- @request
26
+ def self.build_side(side)
27
+ define_method(side) do |message = nil, &block|
28
+ instance = instance_variable_get(:"@#{side}")
29
+ instance.message = message if message
30
+ instance.instance_eval(&block) if block_given?
31
+ instance
32
+ end
31
33
  end
32
34
 
33
- def response(&block)
34
- @response.instance_eval(&block) if block_given?
35
- @response
36
- end
35
+ build_side :request
36
+ build_side :response
37
37
  end
38
38
  end
39
39
  end
@@ -1,19 +1,22 @@
1
1
  module RSpec
2
2
  module DocumentRequests
3
3
  class OrganizedRequest
4
- attr_reader :parent, :filename, :description, :example_requests, :children, :levels
5
- def initialize(description:, parent: nil)
6
- @description = description
4
+ attr_reader :parent, :metadata, :example_requests, :children, :levels
5
+ def initialize(metadata, parent: nil)
6
+ @metadata = metadata
7
7
  @parent = parent
8
- @filename = Pathname.new(DocumentRequests.configuration.filename_generator.call(description))
9
8
  @example_requests = Hash.new { |h, k| h[k] = [] }
10
9
  @children = {}
11
10
  @levels = Hash.new { |h, k| h[k] = 0 }
12
11
  @parent.increase_level(self) if @parent
13
12
  end
14
13
 
15
- def child(description)
16
- @children[DocumentRequests.configuration.filename_generator.call(description)] ||= OrganizedRequest.new(description: description, parent: self)
14
+ def filename
15
+ @filename ||= Pathname.new(DocumentRequests.configuration.filename_generator.call(@metadata[:description]))
16
+ end
17
+
18
+ def child(metadata)
19
+ @children[DocumentRequests.configuration.filename_generator.call(metadata[:description])] ||= OrganizedRequest.new(metadata, parent: self)
17
20
  end
18
21
 
19
22
  def increase_level(child)
@@ -44,7 +47,7 @@ module RSpec
44
47
 
45
48
  organized_request = root
46
49
  metadata_tree.each do |metadata|
47
- organized_request = organized_request.child(metadata[:description])
50
+ organized_request = organized_request.child(metadata)
48
51
  end
49
52
  organized_request.example_requests[request.example] << request
50
53
  end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module DocumentRequests
3
- VERSION = "1.1.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
@@ -4,28 +4,96 @@ module RSpec
4
4
  class Base
5
5
  #EXTENSION = ".something"
6
6
 
7
+ attr_reader :request, :response
8
+
7
9
  def initialize(file)
8
10
  @file = file
11
+ @request = self.class::Request.new(file)
12
+ @response = self.class::Response.new(file)
9
13
  end
10
14
 
11
15
  def breadcrumb(description:, filename:, last:)
12
16
  raise NotImplementedError
13
17
  end
14
18
 
15
- def title(description)
19
+ def title(description:, explanation:)
16
20
  raise NotImplementedError
17
21
  end
18
22
 
19
- def child(description:, filename:)
23
+ def child(description:, filename:, last:)
20
24
  raise NotImplementedError
21
25
  end
22
26
 
23
- def request_title(description, missing_levels:)
27
+ # missing_levels: [{ description: "", explanation: "" || nil }, ...]
28
+ def example_title(description:, explanation:, missing_levels:)
24
29
  raise NotImplementedError
25
30
  end
26
31
 
27
- def request(request, missing_levels:)
28
- raise NotImplementedError
32
+ def close
33
+ @request.close
34
+ @response.close
35
+ end
36
+
37
+ class Request
38
+ def initialize(file)
39
+ @file = file
40
+ end
41
+
42
+ def title(message)
43
+ raise NotImplementedError
44
+ end
45
+
46
+ def path(method, path)
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def parameters(parameters)
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def body(body)
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def headers(headers)
59
+ raise NotImplementedError
60
+ end
61
+
62
+ def close
63
+ end
64
+ end
65
+
66
+ class Response
67
+ def initialize(file)
68
+ @file = file
69
+ end
70
+
71
+ def title(message)
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def status(status, message)
76
+ raise NotImplementedError
77
+ end
78
+
79
+ def content_type(content_type)
80
+ raise NotImplementedError
81
+ end
82
+
83
+ def parameters(parameters)
84
+ raise NotImplementedError
85
+ end
86
+
87
+ def body(body)
88
+ raise NotImplementedError
89
+ end
90
+
91
+ def headers(headers)
92
+ raise NotImplementedError
93
+ end
94
+
95
+ def close
96
+ end
29
97
  end
30
98
  end
31
99
  end
@@ -14,100 +14,115 @@ module RSpec
14
14
  end
15
15
  end
16
16
 
17
- def title(description)
17
+ def title(description:, explanation:)
18
18
  @file.puts "# #{description}"
19
19
  @file.puts
20
+ if explanation
21
+ @file.puts explanation
22
+ @file.puts
23
+ end
20
24
  end
21
25
 
22
- def child(description:, filename:)
26
+ def child(description:, filename:, last:)
23
27
  @file.puts "* [#{description}](#{filename})"
28
+ @file.puts if last
24
29
  end
25
30
 
26
- def example_title(description, missing_levels:)
27
- @file.puts "## #{missing_levels.map { |l| "#{l} > " }.join} #{description}"
31
+ def example_title(description:, explanation:, missing_levels:)
32
+ @file.puts "## #{missing_levels.map { |l| "#{l[:description]} > " }.join}#{description}"
28
33
  @file.puts
34
+ if explanation
35
+ @file.puts explanation
36
+ @file.puts
37
+ end
29
38
  end
30
39
 
31
- def request(request, missing_levels:)
32
- @file.write <<FILE
33
- ### Request#{" (#{request.explanation.message})" if request.explanation.message}
34
-
35
- #{request.method} #{request.path}
36
-
37
- FILE
40
+ module ParametersTable
41
+ private
38
42
 
39
- if request.request_parameters and request.request_parameters.any?
40
- @file.write <<FILE
41
- #### Parameters
42
-
43
- FILE
44
- parameters_table(request.request_parameters)
45
- elsif request.request_body
46
- @file.write <<FILE
47
- #### Body
48
-
49
- #{request.request_body}
50
-
51
- FILE
43
+ def parameters_table(parameters)
44
+ @file.puts "| Name | Type | Required? | Value | |"
45
+ @file.puts "|------|------|-----------|-------|---|"
46
+ parameters.each do |name, parameter|
47
+ @file.puts "| #{name} | #{parameter.type} | #{"Required" if parameter.required} | #{parameter.value} | #{parameter.message} |"
48
+ end
49
+ @file.puts
52
50
  end
51
+ end
53
52
 
54
- if request.request_headers.any?
55
- @file.write <<FILE
56
- #### Headers
53
+ class Request < Base::Request
54
+ include ParametersTable
57
55
 
58
- FILE
59
- parameters_table(request.request_headers)
56
+ def title(message)
57
+ @file.puts "### Request#{" (#{message})" if message}"
58
+ @file.puts
60
59
  end
61
60
 
62
- @file.write <<FILE
63
- ### Response
64
-
65
- #### Status
66
-
67
- #{request.response.status} #{request.response.status_message}
68
-
69
- #### Content-Type
70
-
71
- #{request.response.content_type}
72
-
73
- FILE
61
+ def path(method, path)
62
+ @file.puts " #{method} #{path}"
63
+ @file.puts
64
+ end
74
65
 
75
- if request.response_parameters and request.response_parameters.any?
76
- @file.write <<FILE
77
- #### Parameters
66
+ def parameters(parameters)
67
+ @file.puts "#### Parameters"
68
+ @file.puts
69
+ parameters_table(parameters)
70
+ end
78
71
 
79
- FILE
80
- parameters_table(request.response_parameters)
72
+ def body(body)
73
+ @file.puts "#### Body"
74
+ @file.puts
75
+ @file.puts " #{body}"
76
+ @file.puts
81
77
  end
82
78
 
83
- @file.write <<FILE
84
- #### Body
79
+ def headers(headers)
80
+ @file.puts "#### Headers"
81
+ @file.puts
82
+ parameters_table(headers)
83
+ end
84
+ end
85
85
 
86
- #{request.response.body}
86
+ class Response < Base::Response
87
+ include ParametersTable
87
88
 
88
- FILE
89
+ def title(message)
90
+ @file.puts "### Response#{" (#{message})" if message}"
91
+ @file.puts
92
+ end
89
93
 
90
- if request.response_headers.any?
91
- @file.write <<FILE
92
- #### Headers
94
+ def status(status, message)
95
+ @file.puts "#### Status"
96
+ @file.puts
97
+ @file.puts " #{status} #{message}"
98
+ @file.puts
99
+ end
93
100
 
94
- FILE
95
- parameters_table(request.response_headers)
101
+ def content_type(content_type)
102
+ @file.puts "#### Content-Type"
103
+ @file.puts
104
+ @file.puts " #{content_type}"
105
+ @file.puts
96
106
  end
97
- end
98
107
 
99
- private
108
+ def parameters(parameters)
109
+ @file.puts "#### Parameters"
110
+ @file.puts
111
+ parameters_table(parameters)
112
+ end
100
113
 
101
- def parameters_table(parameters)
102
- @file.write <<FILE
103
- | Name | Type | Required? | Value | |
104
- |------|------|-----------|-------|---|
105
- FILE
114
+ def body(body)
115
+ @file.puts "#### Body"
116
+ @file.puts
117
+ @file.puts " #{body}"
118
+ @file.puts
119
+ end
106
120
 
107
- parameters.each do |name, parameter|
108
- @file.puts "| #{name} | #{parameter.type} | #{"Required" if parameter.required} | #{parameter.value} | #{parameter.message} |"
121
+ def headers(headers)
122
+ @file.puts "#### Headers"
123
+ @file.puts
124
+ parameters_table(headers)
109
125
  end
110
- @file.puts
111
126
  end
112
127
  end
113
128
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-document_requests
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oded Niv
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-06-23 00:00:00.000000000 Z
11
+ date: 2015-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails