puppet-strings 1.2.1 → 2.0.0

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 (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.