rspec-apib 0.4.0 → 0.5.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
  SHA256:
3
- metadata.gz: 5289265f76974beae58b1b06e3007f80ab8675e9fc90adfb0d990f92b73497a2
4
- data.tar.gz: f5c304a0910a7b1e2ae167eae8d376669b8ca4e21015abadd6803d277de432b2
3
+ metadata.gz: 0e706322f5f6c369d0d71d2609b80eaed15bb8280f0607900a3e24954a9c09dd
4
+ data.tar.gz: 36b29966f316c3d8a72ace8ef7535e9cbebb14f05c19e9967d49461f56735b4b
5
5
  SHA512:
6
- metadata.gz: c144150644f21b7e6eb41278eb97ffdc98294900b8fbf049e848832e49af0f95ce68eed76e1675d438f2fa858640ca93b516d8b7e885e7b755ddb76ac6709888
7
- data.tar.gz: 182decedd6be6989b09519ba8aa75f0ffeae867b1abe24c52b5e8e7fb421fb9fe54a0b26348acfe09de285ff22f9cf01c859b9ac01b4135c050e48f795f4425d
6
+ metadata.gz: 3e28a021e3424fc5f52fccfae50acc27e878251dff387c0c3eb22648644e3d69f147bc442cf5704b41eefe49f0bb2e1a9e731ea131ff7c9ea2577ad983c9d8b5
7
+ data.tar.gz: 2cdd2a0ddc010c144a84b4fec591d642eed2587649c1b02635307bfe4a9b3d3f81848010646da5ffa56e539b7a5c4af5d514772100cc3276880a2d8bdb34f1cd
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.2
1
+ FROM ruby:2.6
2
2
 
3
3
  # Install dependencies
4
4
  RUN apt-get update -qq && \
data/Gemfile.lock ADDED
@@ -0,0 +1,201 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rspec-apib (0.4.0)
5
+ rails (>= 4.2)
6
+ rspec-rails (~> 3.4)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (6.0.1)
12
+ actionpack (= 6.0.1)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (6.0.1)
16
+ actionpack (= 6.0.1)
17
+ activejob (= 6.0.1)
18
+ activerecord (= 6.0.1)
19
+ activestorage (= 6.0.1)
20
+ activesupport (= 6.0.1)
21
+ mail (>= 2.7.1)
22
+ actionmailer (6.0.1)
23
+ actionpack (= 6.0.1)
24
+ actionview (= 6.0.1)
25
+ activejob (= 6.0.1)
26
+ mail (~> 2.5, >= 2.5.4)
27
+ rails-dom-testing (~> 2.0)
28
+ actionpack (6.0.1)
29
+ actionview (= 6.0.1)
30
+ activesupport (= 6.0.1)
31
+ rack (~> 2.0)
32
+ rack-test (>= 0.6.3)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
35
+ actiontext (6.0.1)
36
+ actionpack (= 6.0.1)
37
+ activerecord (= 6.0.1)
38
+ activestorage (= 6.0.1)
39
+ activesupport (= 6.0.1)
40
+ nokogiri (>= 1.8.5)
41
+ actionview (6.0.1)
42
+ activesupport (= 6.0.1)
43
+ builder (~> 3.1)
44
+ erubi (~> 1.4)
45
+ rails-dom-testing (~> 2.0)
46
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
+ activejob (6.0.1)
48
+ activesupport (= 6.0.1)
49
+ globalid (>= 0.3.6)
50
+ activemodel (6.0.1)
51
+ activesupport (= 6.0.1)
52
+ activerecord (6.0.1)
53
+ activemodel (= 6.0.1)
54
+ activesupport (= 6.0.1)
55
+ activestorage (6.0.1)
56
+ actionpack (= 6.0.1)
57
+ activejob (= 6.0.1)
58
+ activerecord (= 6.0.1)
59
+ marcel (~> 0.3.1)
60
+ activesupport (6.0.1)
61
+ concurrent-ruby (~> 1.0, >= 1.0.2)
62
+ i18n (>= 0.7, < 2)
63
+ minitest (~> 5.1)
64
+ tzinfo (~> 1.1)
65
+ zeitwerk (~> 2.2)
66
+ builder (3.2.3)
67
+ coderay (1.1.2)
68
+ concurrent-ruby (1.1.5)
69
+ crass (1.0.5)
70
+ diff-lcs (1.3)
71
+ erubi (1.9.0)
72
+ ffi (1.11.1)
73
+ formatador (0.2.5)
74
+ globalid (0.4.2)
75
+ activesupport (>= 4.2.0)
76
+ guard (2.13.0)
77
+ formatador (>= 0.2.4)
78
+ listen (>= 2.7, <= 4.0)
79
+ lumberjack (~> 1.0)
80
+ nenv (~> 0.1)
81
+ notiffany (~> 0.0)
82
+ pry (>= 0.9.12)
83
+ shellany (~> 0.0)
84
+ thor (>= 0.18.1)
85
+ guard-compat (1.2.1)
86
+ guard-rspec (4.6.5)
87
+ guard (~> 2.1)
88
+ guard-compat (~> 1.1)
89
+ rspec (>= 2.99.0, < 4.0)
90
+ i18n (1.7.0)
91
+ concurrent-ruby (~> 1.0)
92
+ listen (3.2.0)
93
+ rb-fsevent (~> 0.10, >= 0.10.3)
94
+ rb-inotify (~> 0.9, >= 0.9.10)
95
+ loofah (2.3.1)
96
+ crass (~> 1.0.2)
97
+ nokogiri (>= 1.5.9)
98
+ lumberjack (1.0.13)
99
+ mail (2.7.1)
100
+ mini_mime (>= 0.1.1)
101
+ marcel (0.3.3)
102
+ mimemagic (~> 0.3.2)
103
+ method_source (0.9.2)
104
+ mimemagic (0.3.3)
105
+ mini_mime (1.0.2)
106
+ mini_portile2 (2.4.0)
107
+ minitest (5.13.0)
108
+ nenv (0.3.0)
109
+ nio4r (2.5.2)
110
+ nokogiri (1.10.5)
111
+ mini_portile2 (~> 2.4.0)
112
+ notiffany (0.1.3)
113
+ nenv (~> 0.1)
114
+ shellany (~> 0.0)
115
+ pry (0.12.2)
116
+ coderay (~> 1.1.0)
117
+ method_source (~> 0.9.0)
118
+ rack (2.0.7)
119
+ rack-test (1.1.0)
120
+ rack (>= 1.0, < 3)
121
+ rails (6.0.1)
122
+ actioncable (= 6.0.1)
123
+ actionmailbox (= 6.0.1)
124
+ actionmailer (= 6.0.1)
125
+ actionpack (= 6.0.1)
126
+ actiontext (= 6.0.1)
127
+ actionview (= 6.0.1)
128
+ activejob (= 6.0.1)
129
+ activemodel (= 6.0.1)
130
+ activerecord (= 6.0.1)
131
+ activestorage (= 6.0.1)
132
+ activesupport (= 6.0.1)
133
+ bundler (>= 1.3.0)
134
+ railties (= 6.0.1)
135
+ sprockets-rails (>= 2.0.0)
136
+ rails-dom-testing (2.0.3)
137
+ activesupport (>= 4.2.0)
138
+ nokogiri (>= 1.6)
139
+ rails-html-sanitizer (1.3.0)
140
+ loofah (~> 2.3)
141
+ railties (6.0.1)
142
+ actionpack (= 6.0.1)
143
+ activesupport (= 6.0.1)
144
+ method_source
145
+ rake (>= 0.8.7)
146
+ thor (>= 0.20.3, < 2.0)
147
+ rake (10.5.0)
148
+ rb-fsevent (0.10.3)
149
+ rb-inotify (0.10.0)
150
+ ffi (~> 1.0)
151
+ rspec (3.9.0)
152
+ rspec-core (~> 3.9.0)
153
+ rspec-expectations (~> 3.9.0)
154
+ rspec-mocks (~> 3.9.0)
155
+ rspec-core (3.9.0)
156
+ rspec-support (~> 3.9.0)
157
+ rspec-expectations (3.9.0)
158
+ diff-lcs (>= 1.2.0, < 2.0)
159
+ rspec-support (~> 3.9.0)
160
+ rspec-mocks (3.9.0)
161
+ diff-lcs (>= 1.2.0, < 2.0)
162
+ rspec-support (~> 3.9.0)
163
+ rspec-rails (3.9.0)
164
+ actionpack (>= 3.0)
165
+ activesupport (>= 3.0)
166
+ railties (>= 3.0)
167
+ rspec-core (~> 3.9.0)
168
+ rspec-expectations (~> 3.9.0)
169
+ rspec-mocks (~> 3.9.0)
170
+ rspec-support (~> 3.9.0)
171
+ rspec-support (3.9.0)
172
+ shellany (0.0.1)
173
+ sprockets (4.0.0)
174
+ concurrent-ruby (~> 1.0)
175
+ rack (> 1, < 3)
176
+ sprockets-rails (3.2.1)
177
+ actionpack (>= 4.0)
178
+ activesupport (>= 4.0)
179
+ sprockets (>= 3.0.0)
180
+ thor (0.20.3)
181
+ thread_safe (0.3.6)
182
+ tzinfo (1.2.5)
183
+ thread_safe (~> 0.1)
184
+ websocket-driver (0.7.1)
185
+ websocket-extensions (>= 0.1.0)
186
+ websocket-extensions (0.1.4)
187
+ zeitwerk (2.2.1)
188
+
189
+ PLATFORMS
190
+ ruby
191
+
192
+ DEPENDENCIES
193
+ bundler (~> 1.10)
194
+ guard (~> 2.13.0)
195
+ guard-rspec (~> 4.6.4)
196
+ pry
197
+ rake (~> 10.0)
198
+ rspec-apib!
199
+
200
+ BUNDLED WITH
201
+ 1.17.2
data/README.md CHANGED
@@ -40,6 +40,14 @@ RSpec::Apib.configure do |config|
40
40
 
41
41
  # Example types to record
42
42
  config.record_types = [:request]
43
+
44
+ # Recording policy
45
+
46
+ # The default recording policy is `true`. This results in a recording of
47
+ # all matching specs. By changing this policy to `false`, you can selectively
48
+ # include certain specs by adding `apib: true` to your example options.
49
+ #
50
+ # config.default_recording_policy = false
43
51
  end
44
52
  # ...
45
53
  RSpec::Apib.start
@@ -51,18 +59,42 @@ By default, request specs get recorded and written to a `.apib` file afterwards.
51
59
  Rspec-apib is trying to make sense of the test run and generates a meaningful
52
60
  documentation out of it.
53
61
 
54
- * **Disable single examples:** Add `apib: false` to the examples meta data
62
+ - **Disable single examples:** Add `apib: false` to the examples meta data
63
+
55
64
  ```ruby
56
65
  it 'does something', apib: false do
57
66
  # ...
58
67
  end
59
68
  ```
60
69
 
61
- * **Custom example description:** Add an *apib* comment above the example
62
- ```ruby
70
+ - **Custom example description:** Add an _apib_ comment above the example
71
+ You can add a description for the request, response or both.
72
+
73
+ Description only for the request
74
+
75
+ ````ruby
76
+ # Not contained in the description
77
+ #
78
+ # --- apib:request
79
+ # Some awesome description of the request
80
+ #
81
+ # ```json
82
+ # {}
83
+ # ```
84
+ # ---
85
+ #
63
86
  # Not contained in the description
64
87
  #
65
- # --- apib
88
+ it 'has a custom description' do
89
+ # ...
90
+ end
91
+ ````
92
+
93
+ Description only for the response
94
+
95
+ ````ruby
96
+ # Not contained in the description
97
+ # -- apib:response
66
98
  # Some awesome description of the response
67
99
  #
68
100
  # ```json
@@ -75,7 +107,30 @@ documentation out of it.
75
107
  it 'has a custom description' do
76
108
  # ...
77
109
  end
78
- ```
110
+ ````
111
+
112
+ Description for both request and response
113
+
114
+ ````ruby
115
+ # Not contained in the description
116
+ #
117
+ # --- apib:request
118
+ # Some awesome description of the request
119
+ #
120
+ # -- apib:response
121
+ # Some awesome description of the response
122
+ #
123
+ # ```json
124
+ # {}
125
+ # ```
126
+ # ---
127
+ #
128
+ # Not contained in the description
129
+ #
130
+ it 'has a custom description' do
131
+ # ...
132
+ end
133
+ ````
79
134
 
80
135
  ## Development
81
136
 
@@ -88,7 +143,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
88
143
  To do continuous testing during development `guard` can be used. In order to
89
144
  test against multiple versions of Rails, the environment variable
90
145
  `RAILS_VERSION` can be used to choose a different dependency pattern then the
91
- default one specified in the *.gemspec* file.
146
+ default one specified in the _.gemspec_ file.
92
147
 
93
148
  ```
94
149
  RAILS_VERSION='~> 4.0' bundle install; bundle exec rspec
data/lib/rspec/apib.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'rails'
2
2
  require 'rspec/apib/version'
3
3
  require 'rspec/apib/configuration'
4
+ require 'rspec/apib/comments_parser'
4
5
  require 'rspec/apib/recorder'
5
6
  require 'rspec/apib/writer'
6
7
 
@@ -22,11 +23,9 @@ module RSpec
22
23
  end
23
24
 
24
25
  def start
25
- types = config.record_types
26
26
  RSpec.configure do |config|
27
27
  config.after :each do |example|
28
- if types.include?(example.metadata[:type]) &&
29
- !(example.metadata[:apib] === false)
28
+ if RSpec::Apib.record?(example)
30
29
  RSpec::Apib.record(example, request, response, @routes)
31
30
  end
32
31
  end
@@ -47,6 +46,15 @@ module RSpec
47
46
  writer = Writer.new(@_doc || {})
48
47
  writer.write
49
48
  end
49
+
50
+ def record?(example)
51
+ default_recording_policy = config.default_recording_policy
52
+ config.record_types.include?(example.metadata[:type]) &&
53
+ (
54
+ default_recording_policy && !(example.metadata[:apib] === false) ||
55
+ !default_recording_policy && (example.metadata[:apib] === true)
56
+ )
57
+ end
50
58
  end
51
59
  end
52
60
  end
@@ -0,0 +1,60 @@
1
+ module RSpec
2
+ module Apib
3
+ class CommentsParser
4
+ attr_reader :example
5
+
6
+ def initialize(example)
7
+ @example = example
8
+ end
9
+
10
+ def full_comment
11
+ line = example.metadata[:line_number]
12
+ return if line.nil? || line <= 0
13
+
14
+ lines = read_example_file
15
+ return if lines.count < line
16
+
17
+ i = line -2
18
+ result = []
19
+
20
+ while (i >= 0 && match = lines[i].match(/\A\s*#\s*(.*)/)) do
21
+ result.unshift(match[1])
22
+ i -= 1
23
+ end
24
+
25
+ result
26
+ end
27
+
28
+ def description(namespace = nil)
29
+ matcher = start_matcher(namespace)
30
+ comment = full_comment()
31
+ in_comment = false
32
+ return nil if comment.blank?
33
+
34
+ comment.select do |elem|
35
+ if elem == matcher
36
+ in_comment = true
37
+ elsif elem.match?(/\A---($|[^-])/)
38
+ in_comment = false
39
+ end
40
+
41
+ in_comment && elem != matcher
42
+ end.join("\n")
43
+ end
44
+
45
+ private
46
+
47
+ def read_example_file
48
+ file = example.metadata[:absolute_file_path]
49
+ return [] if file.nil? || file.empty?
50
+ return [] unless File.exists?(file)
51
+ IO.readlines(file)
52
+ end
53
+
54
+ def start_matcher(namespace)
55
+ return "--- apib" if namespace.blank?
56
+ "--- apib:#{namespace}"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Apib
3
3
  class Configuration < Struct.new(
4
4
  :dest_file, :pre_docs, :post_docs, :request_header_blacklist,
5
- :request_param_blacklist, :record_types
5
+ :request_param_blacklist, :record_types, :default_recording_policy
6
6
  )
7
7
  def initialize
8
8
  self.pre_docs = []
@@ -10,6 +10,7 @@ module RSpec
10
10
  self.request_header_blacklist = %w(host accept cookie)
11
11
  self.request_param_blacklist = %i(controller action)
12
12
  self.record_types = %i(request)
13
+ self.default_recording_policy = true
13
14
  end
14
15
 
15
16
  def dest_file
@@ -19,6 +19,10 @@ module RSpec
19
19
  document_response
20
20
  end
21
21
 
22
+ def comments_parser
23
+ @comments_parser ||= CommentsParser.new(example)
24
+ end
25
+
22
26
  private
23
27
 
24
28
  # Request headers contained in the blacklist will not be included in the
@@ -102,6 +106,7 @@ module RSpec
102
106
  def document_request
103
107
  document_request_params
104
108
  return if response.status >= action[:request][:_status]
109
+ action[:request][:description] = comments_parser.description("request")
105
110
  action[:request][:_status] = response.status
106
111
  action[:request][:path] = request.path
107
112
  action[:request][:body] = request.body.read
@@ -136,7 +141,7 @@ module RSpec
136
141
  def document_response
137
142
  data = {}
138
143
  return if response_exists?
139
- data[:description] = document_extended_description || example.description
144
+ data[:description] = comments_parser.description("response") || example.description
140
145
  data[:status] = response.status
141
146
  data[:content_type] = response.content_type.to_s
142
147
  data[:body] = response.body
@@ -144,35 +149,6 @@ module RSpec
144
149
  action[:response] << data
145
150
  end
146
151
 
147
- def document_extended_description
148
- file = example.metadata[:absolute_file_path]
149
- line = example.metadata[:line_number]
150
- return if file.nil? || file.empty?
151
- return if line.nil? || line <= 0
152
- return unless File.exists?(file)
153
- lines = IO.readlines(file)
154
- return if lines.count < line
155
- i = line -2
156
- m = false
157
- while (i >= 0 && lines[i].match(/\A\s*#/)) do
158
- if lines[i - 1].match(/\A\s*# --- apib/)
159
- m = true
160
- break
161
- end
162
- i -= 1
163
- end
164
- return unless m
165
- result = []
166
- while (i < line && lines[i].match(/\A\s*#/)) do
167
- if lines[i].match(/\A\s*# ---\s*\z/)
168
- break
169
- end
170
- result << lines[i].sub(/^\s*#( |)/, '').rstrip
171
- i += 1
172
- end
173
- return result.join("\n")
174
- end
175
-
176
152
  def response_exists?
177
153
  action[:response].any? { |r| r[:status] == response.status }
178
154
  end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module Apib
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -52,6 +52,7 @@ module RSpec
52
52
  end
53
53
 
54
54
  apib += "+ Request\n\n"
55
+ apib += "#{data[:request][:description].indent(2, ' ')}\n\n" if data[:request][:description]
55
56
  apib += " + Headers\n\n"
56
57
  data[:request][:headers].each do |header, value|
57
58
  apib += " #{header}: #{value}\n"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-apib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Spieker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-05 00:00:00.000000000 Z
11
+ date: 2019-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -127,6 +127,7 @@ files:
127
127
  - CODE_OF_CONDUCT.md
128
128
  - Dockerfile
129
129
  - Gemfile
130
+ - Gemfile.lock
130
131
  - Guardfile
131
132
  - LICENSE.txt
132
133
  - README.md
@@ -135,6 +136,7 @@ files:
135
136
  - bin/setup
136
137
  - docker-compose.yml
137
138
  - lib/rspec/apib.rb
139
+ - lib/rspec/apib/comments_parser.rb
138
140
  - lib/rspec/apib/configuration.rb
139
141
  - lib/rspec/apib/recorder.rb
140
142
  - lib/rspec/apib/version.rb