puppet-strings 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/CONTRIBUTING.md +3 -7
  4. data/JSON.md +126 -8
  5. data/README.md +16 -498
  6. data/lib/puppet-strings.rb +6 -0
  7. data/lib/puppet-strings/json.rb +2 -0
  8. data/lib/puppet-strings/markdown.rb +6 -1
  9. data/lib/puppet-strings/markdown/puppet_plan.rb +14 -0
  10. data/lib/puppet-strings/markdown/puppet_plans.rb +37 -0
  11. data/lib/puppet-strings/markdown/puppet_task.rb +24 -0
  12. data/lib/puppet-strings/markdown/puppet_tasks.rb +34 -0
  13. data/lib/puppet-strings/markdown/table_of_contents.rb +3 -1
  14. data/lib/puppet-strings/markdown/templates/classes_and_defines.erb +8 -5
  15. data/lib/puppet-strings/markdown/templates/function.erb +2 -3
  16. data/lib/puppet-strings/markdown/templates/puppet_task.erb +28 -0
  17. data/lib/puppet-strings/markdown/templates/resource_type.erb +9 -5
  18. data/lib/puppet-strings/markdown/templates/table_of_contents.erb +5 -0
  19. data/lib/puppet-strings/monkey_patches/display_object_command.rb +11 -0
  20. data/lib/puppet-strings/yard.rb +15 -1
  21. data/lib/puppet-strings/yard/code_objects.rb +2 -0
  22. data/lib/puppet-strings/yard/code_objects/plan.rb +56 -0
  23. data/lib/puppet-strings/yard/code_objects/task.rb +70 -0
  24. data/lib/puppet-strings/yard/handlers.rb +6 -0
  25. data/lib/puppet-strings/yard/handlers/json/base.rb +5 -0
  26. data/lib/puppet-strings/yard/handlers/json/task_handler.rb +31 -0
  27. data/lib/puppet-strings/yard/handlers/puppet/base.rb +1 -1
  28. data/lib/puppet-strings/yard/handlers/puppet/class_handler.rb +1 -1
  29. data/lib/puppet-strings/yard/handlers/puppet/defined_type_handler.rb +1 -1
  30. data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +1 -1
  31. data/lib/puppet-strings/yard/handlers/puppet/plan_handler.rb +27 -0
  32. data/lib/puppet-strings/yard/handlers/ruby/function_handler.rb +4 -1
  33. data/lib/puppet-strings/yard/handlers/ruby/rsapi_handler.rb +12 -2
  34. data/lib/puppet-strings/yard/parsers.rb +4 -0
  35. data/lib/puppet-strings/yard/parsers/json/parser.rb +33 -0
  36. data/lib/puppet-strings/yard/parsers/json/task_statement.rb +35 -0
  37. data/lib/puppet-strings/yard/parsers/puppet/parser.rb +11 -0
  38. data/lib/puppet-strings/yard/parsers/puppet/statement.rb +14 -0
  39. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_plan.erb +9 -0
  40. data/lib/puppet-strings/yard/templates/default/fulldoc/html/full_list_puppet_task.erb +9 -0
  41. data/lib/puppet-strings/yard/templates/default/fulldoc/html/setup.rb +18 -0
  42. data/lib/puppet-strings/yard/templates/default/layout/html/setup.rb +42 -2
  43. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/box_info.erb +10 -0
  44. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/header.erb +1 -0
  45. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/overview.erb +6 -0
  46. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/setup.rb +11 -0
  47. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/source.erb +12 -0
  48. data/lib/puppet-strings/yard/templates/default/puppet_plan/html/summary.erb +4 -0
  49. data/lib/puppet-strings/yard/templates/default/puppet_task/html/box_info.erb +9 -0
  50. data/lib/puppet-strings/yard/templates/default/puppet_task/html/header.erb +1 -0
  51. data/lib/puppet-strings/yard/templates/default/puppet_task/html/input.erb +5 -0
  52. data/lib/puppet-strings/yard/templates/default/puppet_task/html/overview.erb +6 -0
  53. data/lib/puppet-strings/yard/templates/default/puppet_task/html/parameters.erb +16 -0
  54. data/lib/puppet-strings/yard/templates/default/puppet_task/html/setup.rb +22 -0
  55. data/lib/puppet-strings/yard/templates/default/puppet_task/html/supports_noop.erb +3 -0
  56. data/lib/puppet-strings/yard/templates/default/tags/setup.rb +3 -1
  57. data/lib/puppet-strings/yard/util.rb +14 -0
  58. data/spec/fixtures/unit/json/output.json +50 -0
  59. data/spec/fixtures/unit/json/output_with_plan.json +689 -0
  60. data/spec/fixtures/unit/markdown/output.md +63 -8
  61. data/spec/fixtures/unit/markdown/output_with_plan.md +472 -0
  62. data/spec/spec_helper.rb +5 -2
  63. data/spec/unit/puppet-strings/json_spec.rb +42 -2
  64. data/spec/unit/puppet-strings/markdown_spec.rb +41 -8
  65. data/spec/unit/puppet-strings/yard/code_objects/task_spec.rb +92 -0
  66. data/spec/unit/puppet-strings/yard/handlers/json/task_handler_spec.rb +124 -0
  67. data/spec/unit/puppet-strings/yard/handlers/puppet/class_handler_spec.rb +1 -1
  68. data/spec/unit/puppet-strings/yard/handlers/puppet/defined_type_handler_spec.rb +19 -12
  69. data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +33 -0
  70. data/spec/unit/puppet-strings/yard/handlers/ruby/rsapi_handler_spec.rb +8 -7
  71. data/spec/unit/puppet-strings/yard/parsers/json/parser_spec.rb +70 -0
  72. data/spec/unit/puppet-strings/yard/parsers/json/task_statement_spec.rb +56 -0
  73. data/spec/unit/puppet-strings/yard/parsers/puppet/parser_spec.rb +1 -1
  74. data/spec/unit/puppet-strings/yard/util_spec.rb +17 -0
  75. metadata +38 -5
  76. data/MAINTAINERS +0 -17
@@ -27,10 +27,13 @@ require 'puppet-strings/yard'
27
27
  PuppetStrings::Yard.setup!
28
28
 
29
29
  # Enable testing of Puppet functions if running against 4.1+
30
- TEST_PUPPET_FUNCTIONS = Gem::Dependency.new('', '>= 4.1.0').match?('', Puppet::PUPPETVERSION)
30
+ TEST_PUPPET_FUNCTIONS = Puppet::Util::Package.versioncmp(Puppet.version, "4.1.0") >= 0
31
31
 
32
32
  # Enable testing of Puppet language functions declared with return type if running against 4.8+
33
- TEST_FUNCTION_RETURN_TYPE = Gem::Dependency.new('', '>= 4.8.0').match?('', Puppet::PUPPETVERSION)
33
+ TEST_FUNCTION_RETURN_TYPE = Puppet::Util::Package.versioncmp(Puppet.version, "4.8.0") >= 0
34
+
35
+ # Enable testing of Plans if Puppet version is greater than 5.0.0
36
+ TEST_PUPPET_PLANS = Puppet::Util::Package.versioncmp(Puppet.version, "5.0.0") >= 0
34
37
 
35
38
  RSpec.configure do |config|
36
39
  config.mock_with :mocha
@@ -19,6 +19,15 @@ class klass(Integer $param1, $param2, String $param3 = hi) inherits foo::bar {
19
19
  # @param param3 Third param.
20
20
  define dt(Integer $param1, $param2, String $param3 = hi) {
21
21
  }
22
+ SOURCE
23
+
24
+ YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet) if TEST_PUPPET_PLANS
25
+ # A simple plan.
26
+ # @param param1 First param.
27
+ # @param param2 Second param.
28
+ # @param param3 Third param.
29
+ plan plann(String $param1, $param2, Integer $param3 = 1) {
30
+ }
22
31
  SOURCE
23
32
 
24
33
  # Only include Puppet functions for 4.1+
@@ -30,6 +39,31 @@ SOURCE
30
39
  # @return [Undef] Returns nothing.
31
40
  function func(Integer $param1, $param2, String $param3 = hi) {
32
41
  }
42
+ SOURCE
43
+
44
+ YARD::Parser::SourceParser.parse_string(<<-SOURCE, :json)
45
+ {
46
+ "description": "Allows you to backup your database to local file.",
47
+ "input_method": "stdin",
48
+ "parameters": {
49
+ "database": {
50
+ "description": "Database to connect to",
51
+ "type": "Optional[String[1]]"
52
+ },
53
+ "user": {
54
+ "description": "The user",
55
+ "type": "Optional[String[1]]"
56
+ },
57
+ "password": {
58
+ "description": "The password",
59
+ "type": "Optional[String[1]]"
60
+ },
61
+ "sql": {
62
+ "description": "Path to file you want backup to",
63
+ "type": "String[1]"
64
+ }
65
+ }
66
+ }
33
67
  SOURCE
34
68
 
35
69
  YARD::Parser::SourceParser.parse_string(<<-SOURCE, :ruby)
@@ -126,7 +160,7 @@ end
126
160
 
127
161
  Puppet::ResourceApi.register_type(
128
162
  name: 'apt_key',
129
- desc: <<-EOS,
163
+ docs: <<-EOS,
130
164
  @summary Example resource type using the new API.
131
165
  @raise SomeError
132
166
  This type provides Puppet with the capabilities to manage GPG keys needed
@@ -166,7 +200,13 @@ path this type will autorequire that file.
166
200
  SOURCE
167
201
  end
168
202
 
169
- let(:filename) { TEST_PUPPET_FUNCTIONS ? 'output.json' : 'output_without_puppet_function.json' }
203
+ let(:filename) do
204
+ if TEST_PUPPET_PLANS
205
+ 'output_with_plan.json'
206
+ else
207
+ TEST_PUPPET_FUNCTIONS ? 'output.json' : 'output_without_puppet_function.json'
208
+ end
209
+ end
170
210
  let(:baseline_path) { File.join(File.dirname(__FILE__), "../../fixtures/unit/json/#{filename}") }
171
211
  let(:baseline) { File.read(baseline_path) }
172
212
 
@@ -63,6 +63,39 @@ define klass::dt (
63
63
  Boolean $param4 = true
64
64
  ) {
65
65
  }
66
+ SOURCE
67
+ YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet) if TEST_PUPPET_PLANS
68
+ # A simple plan.
69
+ # @param param1 First param.
70
+ # @param param2 Second param.
71
+ # @param param3 Third param.
72
+ plan plann(String $param1, $param2, Integer $param3 = 1) {
73
+ }
74
+ SOURCE
75
+
76
+ YARD::Parser::SourceParser.parse_string(<<-SOURCE, :json)
77
+ {
78
+ "description": "Allows you to backup your database to local file.",
79
+ "input_method": "stdin",
80
+ "parameters": {
81
+ "database": {
82
+ "description": "Database to connect to",
83
+ "type": "Optional[String[1]]"
84
+ },
85
+ "user": {
86
+ "description": "The user",
87
+ "type": "Optional[String[1]]"
88
+ },
89
+ "password": {
90
+ "description": "The password",
91
+ "type": "Optional[String[1]]"
92
+ },
93
+ "sql": {
94
+ "description": "Path to file you want backup to",
95
+ "type": "String[1]"
96
+ }
97
+ }
98
+ }
66
99
  SOURCE
67
100
 
68
101
  YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
@@ -187,7 +220,7 @@ end
187
220
 
188
221
  Puppet::ResourceApi.register_type(
189
222
  name: 'apt_key',
190
- desc: <<-EOS,
223
+ docs: <<-EOS,
191
224
  @summary Example resource type using the new API.
192
225
  @raise SomeError
193
226
  This type provides Puppet with the capabilities to manage GPG keys needed
@@ -227,7 +260,13 @@ path this type will autorequire that file.
227
260
  SOURCE
228
261
  end
229
262
 
230
- let(:filename) { 'output.md' }
263
+ let(:filename) do
264
+ if TEST_PUPPET_PLANS
265
+ 'output_with_plan.md'
266
+ else
267
+ 'output.md'
268
+ end
269
+ end
231
270
  let(:baseline_path) { File.join(File.dirname(__FILE__), "../../fixtures/unit/markdown/#{filename}") }
232
271
  let(:baseline) { File.read(baseline_path) }
233
272
 
@@ -239,10 +278,4 @@ SOURCE
239
278
  end
240
279
  end
241
280
  end
242
-
243
- describe 'rendering markdown to stdout' do
244
- it 'should output the expected markdown content' do
245
- expect{ PuppetStrings::Markdown.render }.to output(baseline).to_stdout
246
- end
247
- end
248
281
  end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+ require 'puppet-strings/yard/code_objects/task'
3
+ require 'puppet-strings/yard/parsers/json/task_statement'
4
+
5
+ describe PuppetStrings::Yard::CodeObjects::Task do
6
+ let(:source) { <<-SOURCE
7
+ {
8
+ "description": "Allows you to backup your database to local file.",
9
+ "input_method": "stdin",
10
+ "parameters": {
11
+ "database": {
12
+ "description": "Database to connect to",
13
+ "type": "Optional[String[1]]"
14
+ },
15
+ "user": {
16
+ "description": "The user",
17
+ "type": "Optional[String[1]]"
18
+ },
19
+ "password": {
20
+ "description": "The password",
21
+ "type": "Optional[String[1]]"
22
+ },
23
+ "sql": {
24
+ "description": "Path to file you want backup to",
25
+ "type": "String[1]"
26
+ }
27
+ }
28
+ }
29
+ SOURCE
30
+ }
31
+ let(:json) { JSON.parse(source) }
32
+ let(:statement) { PuppetStrings::Yard::Parsers::JSON::TaskStatement.new(json, source, "test.json") }
33
+ subject { PuppetStrings::Yard::CodeObjects::Task.new(statement) }
34
+
35
+ describe '#type' do
36
+ it 'returns the correct type' do
37
+ expect(subject.type).to eq(:puppet_task)
38
+ end
39
+ end
40
+
41
+ describe '#source' do
42
+ it 'returns the source' do
43
+ expect(subject.source).to eq(source)
44
+ end
45
+ end
46
+
47
+ describe '#to_hash' do
48
+ let(:expected) do
49
+ {
50
+ :name => "test",
51
+ :supports_noop => false,
52
+ :docstring => {
53
+ :text=>"Allows you to backup your database to local file.",
54
+ :tags=> [
55
+ {
56
+ :name=>"database",
57
+ :tag_name=>"param",
58
+ :text=>"Database to connect to",
59
+ :types=> ["Optional[String[1]]"]
60
+ },
61
+ {
62
+ :name=>"user",
63
+ :tag_name=>"param",
64
+ :text=>"The user",
65
+ :types=> ["Optional[String[1]]"]
66
+ },
67
+ {
68
+ :name=>"password",
69
+ :tag_name=>"param",
70
+ :text=>"The password",
71
+ :types=> ["Optional[String[1]]"]
72
+ },
73
+ {
74
+ :name=>"sql",
75
+ :tag_name=>"param",
76
+ :text=>"Path to file you want backup to",
77
+ :types=>["String[1]"]
78
+ }
79
+ ]
80
+ },
81
+ :file => "test.json",
82
+ :input_method => "stdin",
83
+ :line => 0,
84
+ :source => "{\n \"description\": \"Allows you to backup your database to local file.\",\n \"input_method\": \"stdin\",\n \"parameters\": {\n \"database\": {\n \"description\": \"Database to connect to\",\n \"type\": \"Optional[String[1]]\"\n },\n \"user\": {\n \"description\": \"The user\",\n \"type\": \"Optional[String[1]]\"\n },\n \"password\": {\n \"description\": \"The password\",\n \"type\": \"Optional[String[1]]\"\n },\n \"sql\": {\n \"description\": \"Path to file you want backup to\",\n \"type\": \"String[1]\"\n }\n }\n}\n"
85
+ }
86
+ end
87
+
88
+ it 'returns the correct hash' do
89
+ expect(subject.to_hash).to eq(expected)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+ require 'puppet-strings/yard'
3
+
4
+ describe PuppetStrings::Yard::Handlers::JSON::TaskHandler do
5
+ subject {
6
+ YARD::Parser::SourceParser.parse_string(source, :json)
7
+ YARD::Registry.all(:puppet_task)
8
+ }
9
+
10
+ describe 'parsing source without a task definition' do
11
+ let(:source) { 'notice hi' }
12
+
13
+ it 'no defined types should be in the registry' do
14
+ expect(subject.empty?).to eq(true)
15
+ end
16
+ end
17
+
18
+ describe 'parsing source with a syntax error' do
19
+ let(:source) { <<-SOURCE
20
+ {
21
+ "input_method": "stdin",
22
+ "parameters":
23
+ "database": {
24
+ "description": "Database to connect to",
25
+ "type": "Optional[String[1]]"
26
+ }
27
+ }
28
+ }
29
+ SOURCE
30
+ }
31
+
32
+ it 'should log an error' do
33
+ expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\):/).to_stdout_from_any_process
34
+ expect(subject.empty?).to eq(true)
35
+ end
36
+ end
37
+
38
+ describe 'parsing a defined type with a missing docstring' do
39
+ let(:source) { <<-SOURCE
40
+ {
41
+ "input_method": "stdin",
42
+ "parameters": {
43
+ "database": {
44
+ "description": "Database to connect to",
45
+ "type": "Optional[String[1]]"
46
+ },
47
+ "user": {
48
+ "description": "The user",
49
+ "type": "Optional[String[1]]"
50
+ },
51
+ "password": {
52
+ "description": "The password",
53
+ "type": "Optional[String[1]]"
54
+ },
55
+ "sql": {
56
+ "description": "Path to file you want backup to",
57
+ "type": "String[1]"
58
+ }
59
+ }
60
+ }
61
+ SOURCE
62
+ }
63
+
64
+ it 'should log a warning' do
65
+ expect{ subject }.to output(/\[warn\]: Missing a description for Puppet Task \(stdin\)/).to_stdout_from_any_process
66
+ end
67
+ end
68
+
69
+ describe 'parsing a defined type with a docstring' do
70
+ let(:source) { <<-SOURCE
71
+ {
72
+ "description": "Allows you to backup your database to local file.",
73
+ "input_method": "stdin",
74
+ "parameters": {
75
+ "database": {
76
+ "description": "Database to connect to",
77
+ "type": "Optional[String[1]]"
78
+ },
79
+ "user": {
80
+ "description": "The user",
81
+ "type": "Optional[String[1]]"
82
+ },
83
+ "password": {
84
+ "description": "The password",
85
+ "type": "Optional[String[1]]"
86
+ },
87
+ "sql": {
88
+ "description": "Path to file you want backup to",
89
+ "type": "String[1]"
90
+ }
91
+ }
92
+ }
93
+
94
+ SOURCE
95
+ }
96
+
97
+ it 'should register a task object' do
98
+ expect(subject.size).to eq(1)
99
+ object = subject.first
100
+ expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Task)
101
+ expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::Tasks.instance)
102
+ end
103
+ end
104
+
105
+ describe 'parsing a Task with a missing parameter description' do
106
+ let(:source) { <<-SOURCE
107
+ {
108
+ "description": "Allows you to backup your database to local file.",
109
+ "input_method": "stdin",
110
+ "parameters": {
111
+ "database": {
112
+ "type": "Optional[String[1]]"
113
+ }
114
+ }
115
+ }
116
+ SOURCE
117
+ }
118
+
119
+ it 'should output a warning' do
120
+ expect{ subject }.to output(/\[warn\]: Missing description for param 'database' in Puppet Task \(stdin\)/).to_stdout_from_any_process
121
+ end
122
+ end
123
+
124
+ end
@@ -19,7 +19,7 @@ describe PuppetStrings::Yard::Handlers::Puppet::ClassHandler do
19
19
  let(:source) { 'class foo{' }
20
20
 
21
21
  it 'should log an error' do
22
- expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of file/).to_stdout_from_any_process
22
+ expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of (file|input)/).to_stdout_from_any_process
23
23
  expect(subject.empty?).to eq(true)
24
24
  end
25
25
  end
@@ -19,7 +19,7 @@ describe PuppetStrings::Yard::Handlers::Puppet::DefinedTypeHandler do
19
19
  let(:source) { 'define foo{' }
20
20
 
21
21
  it 'should log an error' do
22
- expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of file/).to_stdout_from_any_process
22
+ expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of (file|input)/).to_stdout_from_any_process
23
23
  expect(subject.empty?).to eq(true)
24
24
  end
25
25
  end
@@ -35,6 +35,7 @@ describe PuppetStrings::Yard::Handlers::Puppet::DefinedTypeHandler do
35
35
  describe 'parsing a defined type with a docstring' do
36
36
  let(:source) { <<-SOURCE
37
37
  # A simple foo defined type.
38
+ # @param name The type name.
38
39
  # @param param1 First param.
39
40
  # @param param2 Second param.
40
41
  # @param param3 Third param.
@@ -45,6 +46,9 @@ define foo(Integer $param1, $param2, String $param3 = hi) {
45
46
  }
46
47
  SOURCE
47
48
  }
49
+ it 'does not output a warning for title/name' do
50
+ expect{ subject }.not_to output(/\[warn\].*(name|title).*/).to_stdout_from_any_process
51
+ end
48
52
 
49
53
  it 'should register a defined type object' do
50
54
  expect(subject.size).to eq(1)
@@ -55,18 +59,21 @@ SOURCE
55
59
  expect(object.statement).not_to eq(nil)
56
60
  expect(object.parameters).to eq([['param1', nil], ['param2', nil], ['param3', 'hi']])
57
61
  expect(object.docstring).to eq('A simple foo defined type.')
58
- expect(object.docstring.tags.size).to eq(4)
62
+ expect(object.docstring.tags.size).to eq(5)
59
63
  tags = object.docstring.tags(:param)
60
- expect(tags.size).to eq(3)
61
- expect(tags[0].name).to eq('param1')
62
- expect(tags[0].text).to eq('First param.')
63
- expect(tags[0].types).to eq(['Integer'])
64
- expect(tags[1].name).to eq('param2')
65
- expect(tags[1].text).to eq('Second param.')
66
- expect(tags[1].types).to eq(['Any'])
67
- expect(tags[2].name).to eq('param3')
68
- expect(tags[2].text).to eq('Third param.')
69
- expect(tags[2].types).to eq(['String'])
64
+ expect(tags.size).to eq(4)
65
+ expect(tags[0].name).to eq('name')
66
+ expect(tags[0].text).to eq('The type name.')
67
+ expect(tags[0].types).to eq(nil)
68
+ expect(tags[1].name).to eq('param1')
69
+ expect(tags[1].text).to eq('First param.')
70
+ expect(tags[1].types).to eq(['Integer'])
71
+ expect(tags[2].name).to eq('param2')
72
+ expect(tags[2].text).to eq('Second param.')
73
+ expect(tags[2].types).to eq(['Any'])
74
+ expect(tags[3].name).to eq('param3')
75
+ expect(tags[3].text).to eq('Third param.')
76
+ expect(tags[3].types).to eq(['String'])
70
77
  tags = object.docstring.tags(:api)
71
78
  expect(tags.size).to eq(1)
72
79
  expect(tags[0].text).to eq('public')
@@ -267,6 +267,39 @@ SOURCE
267
267
  end
268
268
  end
269
269
 
270
+ describe 'parsing a function using only return_type' do
271
+ let(:source) { <<-SOURCE
272
+ # An example 4.x function.
273
+ Puppet::Functions.create_function(:foo) do
274
+ # @param param1 The first parameter.
275
+ # @param param2 The second parameter.
276
+ # @param param3 The third parameter.
277
+ dispatch :foo do
278
+ param 'Integer', :param1
279
+ param 'Any', :param2
280
+ optional_param 'Array[String]', :param3
281
+ return_type 'String'
282
+ end
283
+
284
+ def foo(param1, param2, param3 = nil)
285
+ "Bar"
286
+ end
287
+ end
288
+ SOURCE
289
+ }
290
+
291
+ it 'does not throw an error with no @return' do
292
+ expect { subject }.not_to raise_error NoMethodError
293
+ end
294
+
295
+ it 'contains a return data type' do
296
+ tags = subject.first.docstring.tags(:return)
297
+ expect(tags.size).to eq(1)
298
+ expect(tags[0].name).to be_nil
299
+ expect(tags[0].types).to eq(['String'])
300
+ end
301
+ end
302
+
270
303
  describe 'parsing a function with various dispatch parameters.' do
271
304
  let(:source) { <<-SOURCE
272
305
  # An example 4.x function.