swagger_docs_generator 0.2.0 → 0.3.0.pre.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swagger_docs_generator/configuration/configuration.rb +14 -5
  3. data/lib/swagger_docs_generator/configuration/configuration_info.rb +4 -0
  4. data/lib/swagger_docs_generator/generator.rb +30 -47
  5. data/lib/swagger_docs_generator/info.rb +1 -1
  6. data/lib/swagger_docs_generator/metadata/controller.rb +3 -31
  7. data/lib/swagger_docs_generator/metadata/definition.rb +19 -10
  8. data/lib/swagger_docs_generator/metadata/jsons.rb +32 -0
  9. data/lib/swagger_docs_generator/metadata/metadata.rb +11 -1
  10. data/lib/swagger_docs_generator/parser/action.rb +15 -7
  11. data/lib/swagger_docs_generator/parser/actions/parameters/body.rb +31 -0
  12. data/lib/swagger_docs_generator/parser/actions/parameters/form.rb +20 -0
  13. data/lib/swagger_docs_generator/parser/actions/parameters/header.rb +27 -0
  14. data/lib/swagger_docs_generator/parser/actions/parameters/path.rb +27 -0
  15. data/lib/swagger_docs_generator/parser/actions/parameters/query.rb +28 -0
  16. data/lib/swagger_docs_generator/parser/actions/parameters.rb +31 -57
  17. data/lib/swagger_docs_generator/parser/actions/response.rb +3 -59
  18. data/lib/swagger_docs_generator/parser/actions/schema.rb +4 -0
  19. data/lib/swagger_docs_generator/parser/controller.rb +7 -7
  20. data/lib/swagger_docs_generator/parser/definition.rb +9 -7
  21. data/lib/swagger_docs_generator/parser/model.rb +0 -3
  22. data/lib/swagger_docs_generator/parser/parser.rb +12 -11
  23. data/lib/swagger_docs_generator.rb +6 -0
  24. data/lib/tasks/swagger.rake +6 -5
  25. data/spec/spec_helper.rb +1 -0
  26. data/spec/support/examples/parameters.rb +154 -0
  27. data/spec/swagger_docs_generator/configuration/configuration_customize_spec.rb +6 -6
  28. data/spec/swagger_docs_generator/configuration/configuration_default_spec.rb +8 -3
  29. data/spec/swagger_docs_generator/parser/parameters/param_body_spec.rb +62 -0
  30. data/spec/swagger_docs_generator/parser/parameters/param_form_spec.rb +52 -0
  31. data/spec/swagger_docs_generator/parser/parameters/param_header_spec.rb +62 -0
  32. data/spec/swagger_docs_generator/parser/parameters/param_path_spec.rb +62 -0
  33. data/spec/swagger_docs_generator/parser/parameters/param_query_spec.rb +62 -0
  34. metadata +18 -9
  35. data/lib/swagger_docs_generator/metadata/path.rb +0 -24
  36. data/lib/swagger_docs_generator/metadata/tag.rb +0 -24
  37. data/spec/swagger_docs_generator/metadata/controller_spec.rb +0 -18
  38. /data/lib/swagger_docs_generator/{parser/models → models}/active_record.rb +0 -0
  39. /data/lib/swagger_docs_generator/{parser/models → models}/mongo.rb +0 -0
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # :reek:UtilityFunction
4
+ # :reek:InstanceVariableAssumption
5
+ # :reek:TooManyStatements
6
+ # :reek:TooManyInstanceVariables
4
7
 
5
8
  module SwaggerDocsGenerator
6
9
  module Actions
@@ -50,65 +53,6 @@ module SwaggerDocsGenerator
50
53
  def schema(&block)
51
54
  @schema = SwaggerDocsGenerator::Actions::Schema.new(&block).to_hash
52
55
  end
53
- =begin
54
- def complete_hash(data)
55
- raw = data[key]
56
- hash[key] = raw.present? ? each_response(raw) : no_response
57
- end
58
-
59
- def each_response(raw)
60
- sh = {}
61
- raw.each do |code|
62
- case code
63
- when Array
64
- sh.merge!(one_response_with_schema(code))
65
- when Integer
66
- sh.merge!(one_response(code))
67
- end
68
- end
69
- sh
70
- end
71
-
72
- def no_response
73
- one_response(200)
74
- end
75
-
76
- def one_response(code)
77
- response = ActionDispatch::Response.new(code)
78
- { response.code => { description: response.message } }
79
- end
80
-
81
- # :reek:FeatureEnvy
82
- def one_response_with_schema(code)
83
- key = code[0]
84
- response = ActionDispatch::Response.new(key)
85
- {
86
- response.code => {
87
- 'description' => response.message,
88
- 'schema' => type_or_not(code)
89
- }
90
- }
91
- end
92
-
93
- def type_or_not(code)
94
- code.length.eql?(3) ? include_type(code) : no_type(code)
95
- end
96
-
97
- def include_type(code)
98
- {
99
- 'type' => code[1],
100
- 'items' => {
101
- '$ref' => code[2]
102
- }
103
- }
104
- end
105
-
106
- def no_type(code)
107
- {
108
- '$ref' => code[1]
109
- }
110
- end
111
- =end
112
56
  end
113
57
  end
114
58
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :reek:InstanceVariableAssumption
3
4
  module SwaggerDocsGenerator
4
5
  module Actions
6
+ # Object Schema
7
+ #
8
+ # Parse repsonse and create schema swagger object
5
9
  class Schema
6
10
  def initialize(&block)
7
11
  instance_eval(&block) if block_given?
@@ -7,14 +7,14 @@ module SwaggerDocsGenerator
7
7
  # and adding automaticaly tags element.
8
8
  class ParserController < Parser
9
9
  def initialize(description)
10
- super(binding.of_callers[1].klass::CONTROLLER)
11
- prepare_file
10
+ super(binding.of_callers[1].klass)
12
11
  @description = description
12
+ prepare_file
13
13
  end
14
14
 
15
15
  def adding_tag
16
- json = JSON.parse(File.read(controller_file))
17
- File.open(controller_file, 'w') do |file|
16
+ json = JSON.parse(File.read(temporary_file))
17
+ File.open(temporary_file, 'w') do |file|
18
18
  json['tags'].merge!(construct_tags)
19
19
  file.puts(JSON.pretty_generate(json))
20
20
  end
@@ -25,15 +25,15 @@ module SwaggerDocsGenerator
25
25
  def prepare_file
26
26
  delete_file
27
27
  base_file = { paths: {}, tags: {}, definitions: {} }
28
- File.open(controller_file, 'a+') { |file| file.puts(base_file.to_json) }
28
+ File.open(temporary_file, 'a+') { |file| file.puts(base_file.to_json) }
29
29
  end
30
30
 
31
31
  def delete_file
32
- File.delete(controller_file) if File.exist?(controller_file)
32
+ File.delete(temporary_file) if File.exist?(temporary_file)
33
33
  end
34
34
 
35
35
  def construct_tags
36
- { name: controller_name, description: @description }
36
+ { name: tag_name, description: @description }
37
37
  end
38
38
  end
39
39
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :reek:InstanceVariableAssumption
3
4
  module SwaggerDocsGenerator
4
5
  # # Parse Controller classes
5
6
  #
@@ -7,14 +8,14 @@ module SwaggerDocsGenerator
7
8
  # and adding automaticaly tags element.
8
9
  class ParserDefinition < Parser
9
10
  def initialize(name, &block)
10
- super(binding.of_callers[1].klass::CONTROLLER)
11
+ super(binding.of_callers[1].klass)
11
12
  @name = name
12
13
  instance_eval(&block)
13
14
  end
14
15
 
15
16
  def adding_defintion
16
- json = JSON.parse(File.read(controller_file))
17
- File.open(controller_file, 'w') do |file|
17
+ json = JSON.parse(File.read(temporary_file))
18
+ File.open(temporary_file, 'w') do |file|
18
19
  json['definitions'].merge!(construct_definition)
19
20
  file.puts(JSON.pretty_generate(json))
20
21
  end
@@ -39,10 +40,11 @@ module SwaggerDocsGenerator
39
40
  end
40
41
 
41
42
  def construct
42
- element = {}
43
- element.merge!(type: @type || 'object')
44
- element.merge!(required: @required) if @required.present?
45
- element.merge!(properties: @properties) if @properties.present?
43
+ {
44
+ type: @type || 'object',
45
+ required: @required || [],
46
+ properties: @properties
47
+ }
46
48
  end
47
49
 
48
50
  def format_name
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'swagger_docs_generator/parser/models/mongo'
4
- require 'swagger_docs_generator/parser/models/active_record'
5
-
6
3
  module SwaggerDocsGenerator
7
4
  # Parser models
8
5
  class Model
@@ -7,21 +7,18 @@ module SwaggerDocsGenerator
7
7
  #
8
8
  # @!attribute [r] controller
9
9
  # It's a name of controller parsed
10
- # @!attribute [r] path
11
- # It's a path to temporary file
12
- # @!attribute [r] version
13
- # It's a version to API documentation parsed
10
+ # @!attribute [r] tag_name
11
+ # It's a tag attaching to controller
14
12
  class Parser
15
- attr_reader :controller, :path, :version
13
+ attr_reader :controller, :tag_name
16
14
 
17
- def initialize(controller)
18
- @controller = controller
19
- @path = File.join(Dir.pwd, 'public')
20
- @version = SwaggerDocsGenerator.configure_info.version
15
+ def initialize(klass)
16
+ @controller = klass::CONTROLLER
17
+ @tag_name = defined?(klass::TAG) ? klass::TAG : controller_name
21
18
  end
22
19
 
23
- def controller_file
24
- File.join(@path, @version, "#{controller_name}.json")
20
+ def temporary_file
21
+ File.join(SwaggerDocsGenerator.temporary_folder, tmp_json)
25
22
  end
26
23
 
27
24
  private
@@ -29,6 +26,10 @@ module SwaggerDocsGenerator
29
26
  def controller_name
30
27
  @controller.controller_name
31
28
  end
29
+
30
+ def tmp_json
31
+ "#{@tag_name}.json"
32
+ end
32
33
  end
33
34
  end
34
35
 
@@ -13,6 +13,12 @@ require 'swagger_docs_generator/configuration/configuration_info'
13
13
 
14
14
  # Modules methods in a controller
15
15
  require 'swagger_docs_generator/methods'
16
+
17
+ # Models reader (ORM)
18
+ require 'swagger_docs_generator/models/mongo'
19
+ require 'swagger_docs_generator/models/active_record'
20
+
21
+ # Parser class
16
22
  require 'swagger_docs_generator/parser/parser'
17
23
 
18
24
  # Extractor verb
@@ -2,18 +2,19 @@
2
2
 
3
3
  namespace :swagger do
4
4
  desc 'Generate Swagger Documentation files'
5
+ # Execute task just for environment 'doc'
5
6
  task docs: :environment do
6
7
  swag = SwaggerDocsGenerator::Generator.new
7
8
 
9
+ puts 'Imports documentation file...'
10
+ swag.import_documentations
11
+
8
12
  puts 'Create Swagger File in :'
9
13
  puts swag.info_swagger_file
10
14
 
11
- # Reload all controller before parsing
12
- Rails.application.eager_load!
13
-
14
- # Generates files
15
15
  puts
16
- puts 'Generate doc file :'
16
+ puts 'Aggregate documentation data in `swagger.json` :'
17
+ swag.info_controller_parser { |info| puts info }
17
18
  swag.generate_swagger_file
18
19
 
19
20
  puts
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,7 @@ require 'bundler/setup'
7
7
  require 'swagger_docs_generator'
8
8
  require 'json-schema-rspec'
9
9
  require 'pry'
10
+ require 'faker'
10
11
 
11
12
  Dir['spec/supporrt/**/*.rb'].each do |f|
12
13
  require File.expand_path(f)
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Test for parameter BODY
4
+ RSpec.shared_examples 'parameters body haves' do
5
+ let(:test) { param.instance_variable_get(:@param) }
6
+
7
+ include_examples 'parameters haves'
8
+
9
+ context 'schema' do
10
+ let(:result) { param_schema }
11
+ include_examples 'parameter equal', :@schema
12
+ end
13
+
14
+ it do
15
+ name = param_name.nil? ? 'body' : param_name
16
+ description = param_description.nil? ? '' : param_description
17
+ required = param_required.nil? ? true : param_required
18
+ schema = param_schema.nil? ? '' : "#/definitions/#{param_schema.humanize}"
19
+
20
+ expect(param.to_hash).to eql(
21
+ in: :body,
22
+ name: name,
23
+ description: description,
24
+ required: required,
25
+ schema: { '$ref': schema }
26
+ )
27
+ end
28
+ end
29
+
30
+ # Test for parameter FORM
31
+ RSpec.shared_examples 'parameters form haves' do
32
+ let(:test) { param.instance_variable_get(:@param) }
33
+
34
+ include_examples 'parameters haves'
35
+
36
+ it do
37
+ name = param_name.nil? ? 'form' : param_name
38
+ description = param_description.nil? ? '' : param_description
39
+ required = param_required.nil? ? true : param_required
40
+
41
+ expect(param.to_hash).to eql(
42
+ in: :form,
43
+ name: name,
44
+ description: description,
45
+ required: required
46
+ )
47
+ end
48
+ end
49
+
50
+ # Test for parameter HEADER
51
+ RSpec.shared_examples 'parameters header haves' do
52
+ let(:test) { param.instance_variable_get(:@param) }
53
+
54
+ include_examples 'parameters haves'
55
+
56
+ context 'type' do
57
+ let(:result) { param_type }
58
+ include_examples 'parameter equal', :@type
59
+ end
60
+
61
+ it do
62
+ name = param_name.nil? ? 'header' : param_name
63
+ description = param_description.nil? ? '' : param_description
64
+ required = param_required.nil? ? true : param_required
65
+ type = param_type.nil? ? '' : param_type
66
+
67
+ expect(param.to_hash).to eql(
68
+ in: :header,
69
+ name: name,
70
+ description: description,
71
+ required: required,
72
+ type: type
73
+ )
74
+ end
75
+ end
76
+
77
+ # Test for parameter PATH
78
+ RSpec.shared_examples 'parameters path haves' do
79
+ let(:test) { param.instance_variable_get(:@param) }
80
+
81
+ include_examples 'parameters haves'
82
+
83
+ context 'type' do
84
+ let(:result) { param_type }
85
+ include_examples 'parameter equal', :@type
86
+ end
87
+
88
+ it do
89
+ name = param_name.nil? ? 'path' : param_name
90
+ description = param_description.nil? ? '' : param_description
91
+ required = param_required.nil? ? true : param_required
92
+ type = param_type.nil? ? '' : param_type
93
+
94
+ expect(param.to_hash).to eql(
95
+ in: :path,
96
+ name: name,
97
+ description: description,
98
+ required: required,
99
+ type: type
100
+ )
101
+ end
102
+ end
103
+
104
+ # Test for parameter QUERY
105
+ RSpec.shared_examples 'parameters query haves' do
106
+ let(:test) { param.instance_variable_get(:@param) }
107
+
108
+ include_examples 'parameters haves'
109
+
110
+ context 'type' do
111
+ let(:result) { param_type }
112
+ include_examples 'parameter equal', :@type
113
+ end
114
+
115
+ it do
116
+ name = param_name.nil? ? 'query' : param_name
117
+ description = param_description.nil? ? '' : param_description
118
+ required = param_required.nil? ? true : param_required
119
+ type = param_type.nil? ? 'array' : param_type
120
+
121
+ expect(param.to_hash).to eql(
122
+ in: :query,
123
+ name: name,
124
+ description: description,
125
+ required: required,
126
+ type: type,
127
+ items: { type: 'string' }
128
+ )
129
+ end
130
+ end
131
+
132
+ # Test for ALL parameters
133
+ RSpec.shared_examples 'parameters haves' do
134
+ it { expect(param.to_hash).to be_kind_of Hash }
135
+
136
+ context 'name' do
137
+ let(:result) { param_name }
138
+ include_examples 'parameter equal', :@name
139
+ end
140
+
141
+ context 'description' do
142
+ let(:result) { param_description }
143
+ include_examples 'parameter equal', :@description
144
+ end
145
+
146
+ context 'required' do
147
+ let(:result) { param_required }
148
+ include_examples 'parameter equal', :@required
149
+ end
150
+ end
151
+
152
+ RSpec.shared_examples 'parameter equal' do |parameter|
153
+ it { expect(test.instance_variable_get(parameter)).to eql(result) }
154
+ end
@@ -13,7 +13,7 @@ describe SwaggerDocsGenerator::Configuration, type: :gem,
13
13
  config.host = 'http://example.com'
14
14
  config.swagger = '2.2.4'
15
15
  config.cleanning = false
16
- config.base_controller = []
16
+ config.doc_class = 'base.rb'
17
17
  end
18
18
  end
19
19
 
@@ -28,16 +28,16 @@ describe SwaggerDocsGenerator::Configuration, type: :gem,
28
28
  it_behaves_like 'variable exist', false
29
29
  end
30
30
 
31
- context 'base_controller' do
32
- let(:variable) { SwaggerDocsGenerator.config.base_controller }
33
- it_behaves_like 'variable exist', []
34
- end
35
-
36
31
  context 'base_path' do
37
32
  let(:variable) { SwaggerDocsGenerator.config.base_path }
38
33
  it_behaves_like 'variable exist', '/'
39
34
  end
40
35
 
36
+ context 'doc_class' do
37
+ let(:variable) { SwaggerDocsGenerator.config.doc_class }
38
+ it_behaves_like 'variable exist', 'base.rb'
39
+ end
40
+
41
41
  context 'schemes' do
42
42
  let(:variable) { SwaggerDocsGenerator.config.schemes }
43
43
  it_behaves_like 'variable exist', ['http']
@@ -15,9 +15,14 @@ describe SwaggerDocsGenerator::Configuration, type: :gem,
15
15
  it_behaves_like 'variable exist', true
16
16
  end
17
17
 
18
- context 'base_controller' do
19
- let(:variable) { SwaggerDocsGenerator.config.base_controller }
20
- it_behaves_like 'variable exist', ''
18
+ context 'doc_class' do
19
+ let(:variable) { SwaggerDocsGenerator.config.doc_class }
20
+ it_behaves_like 'variable does not exist'
21
+ end
22
+
23
+ context 'doc_folder' do
24
+ let(:variable) { SwaggerDocsGenerator.config.doc_folder }
25
+ it_behaves_like 'variable does not exist'
21
26
  end
22
27
 
23
28
  context 'base_path' do
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SwaggerDocsGenerator::Actions::Body, type: :parser,
6
+ name: :params_body do
7
+ let(:param_name) { nil }
8
+ let(:param_description) { nil }
9
+ let(:param_required) { nil }
10
+ let(:param_schema) { nil }
11
+ let(:param) do
12
+ pname = param_name
13
+ pdescription = param_description
14
+ prequired = param_required
15
+ pschema = param_schema
16
+ SwaggerDocsGenerator::Actions::Parameter.new do
17
+ body do
18
+ name pname
19
+ description pdescription
20
+ required prequired
21
+ schema pschema
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'when attribute complete' do
27
+ let(:param_name) { Faker::Color.color_name }
28
+ let(:param_description) { Faker::Beer.name }
29
+ let(:param_required) { Faker::Boolean.boolean }
30
+ let(:param_schema) { Faker::Name.first_name }
31
+
32
+ it_behaves_like 'parameters body haves'
33
+ end
34
+
35
+ context 'when attribute is incomplete' do
36
+ it_behaves_like 'parameters body haves'
37
+ end
38
+
39
+ context 'when name attribute alone' do
40
+ let(:param_name) { Faker::Color.color_name }
41
+
42
+ it_behaves_like 'parameters body haves'
43
+ end
44
+
45
+ context 'when description attribute alone' do
46
+ let(:param_description) { Faker::Beer.name }
47
+
48
+ it_behaves_like 'parameters body haves'
49
+ end
50
+
51
+ context 'when required attribute alone' do
52
+ let(:param_required) { Faker::Boolean.boolean }
53
+
54
+ it_behaves_like 'parameters body haves'
55
+ end
56
+
57
+ context 'when schema attribute alone' do
58
+ let(:param_schema) { Faker::Name.first_name }
59
+
60
+ it_behaves_like 'parameters body haves'
61
+ end
62
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SwaggerDocsGenerator::Actions::Form, type: :parser,
6
+ name: :params_form do
7
+ let(:param_name) { nil }
8
+ let(:param_description) { nil }
9
+ let(:param_required) { nil }
10
+ let(:param) do
11
+ pname = param_name
12
+ pdescription = param_description
13
+ prequired = param_required
14
+ SwaggerDocsGenerator::Actions::Parameter.new do
15
+ form do
16
+ name pname
17
+ description pdescription
18
+ required prequired
19
+ end
20
+ end
21
+ end
22
+
23
+ context 'when attribute complete' do
24
+ let(:param_name) { Faker::Color.color_name }
25
+ let(:param_description) { Faker::Beer.name }
26
+ let(:param_required) { Faker::Boolean.boolean }
27
+
28
+ it_behaves_like 'parameters form haves'
29
+ end
30
+
31
+ context 'when attribute is incomplete' do
32
+ it_behaves_like 'parameters form haves'
33
+ end
34
+
35
+ context 'when name attribute alone' do
36
+ let(:param_name) { Faker::Color.color_name }
37
+
38
+ it_behaves_like 'parameters form haves'
39
+ end
40
+
41
+ context 'when description attribute alone' do
42
+ let(:param_description) { Faker::Beer.name }
43
+
44
+ it_behaves_like 'parameters form haves'
45
+ end
46
+
47
+ context 'when required attribute alone' do
48
+ let(:param_required) { Faker::Boolean.boolean }
49
+
50
+ it_behaves_like 'parameters form haves'
51
+ end
52
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe SwaggerDocsGenerator::Actions::Header, type: :parser,
6
+ name: :params_header do
7
+ let(:param_name) { nil }
8
+ let(:param_description) { nil }
9
+ let(:param_required) { nil }
10
+ let(:param_type) { nil }
11
+ let(:param) do
12
+ pname = param_name
13
+ pdescription = param_description
14
+ prequired = param_required
15
+ ptype = param_type
16
+ SwaggerDocsGenerator::Actions::Parameter.new do
17
+ header do
18
+ name pname
19
+ description pdescription
20
+ required prequired
21
+ type ptype
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'when attribute complete' do
27
+ let(:param_name) { Faker::Color.color_name }
28
+ let(:param_description) { Faker::Beer.name }
29
+ let(:param_required) { Faker::Boolean.boolean }
30
+ let(:param_type) { Faker::Name.first_name }
31
+
32
+ it_behaves_like 'parameters header haves'
33
+ end
34
+
35
+ context 'when attribute is incomplete' do
36
+ it_behaves_like 'parameters header haves'
37
+ end
38
+
39
+ context 'when name attribute alone' do
40
+ let(:param_name) { Faker::Color.color_name }
41
+
42
+ it_behaves_like 'parameters header haves'
43
+ end
44
+
45
+ context 'when description attribute alone' do
46
+ let(:param_description) { Faker::Beer.name }
47
+
48
+ it_behaves_like 'parameters header haves'
49
+ end
50
+
51
+ context 'when required attribute alone' do
52
+ let(:param_required) { Faker::Boolean.boolean }
53
+
54
+ it_behaves_like 'parameters header haves'
55
+ end
56
+
57
+ context 'when type attribute alone' do
58
+ let(:param_type) { Faker::Name.first_name }
59
+
60
+ it_behaves_like 'parameters header haves'
61
+ end
62
+ end