puppet-strings 0.99.0 → 1.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile +7 -6
  4. data/JSON.md +193 -20
  5. data/README.md +231 -140
  6. data/lib/puppet-strings/json.rb +19 -10
  7. data/lib/puppet-strings/tasks/gh_pages.rb +15 -4
  8. data/lib/puppet-strings/yard/code_objects/function.rb +13 -3
  9. data/lib/puppet-strings/yard/code_objects/provider.rb +5 -6
  10. data/lib/puppet-strings/yard/code_objects/type.rb +2 -1
  11. data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +9 -4
  12. data/lib/puppet-strings/yard/handlers/ruby/function_handler.rb +13 -4
  13. data/lib/puppet-strings/yard/handlers/ruby/provider_handler.rb +11 -6
  14. data/lib/puppet-strings/yard/handlers/ruby/type_handler.rb +3 -3
  15. data/lib/puppet-strings/yard/parsers/puppet/statement.rb +8 -0
  16. data/lib/puppet-strings/yard/tags/overload_tag.rb +2 -2
  17. data/lib/puppet-strings/yard/templates/default/fulldoc/html/css/common.css +8 -0
  18. data/lib/puppet-strings/yard/templates/default/puppet_provider/html/collection.erb +9 -2
  19. data/lib/puppet-strings/yard/templates/default/tags/html/puppet_overload.erb +1 -1
  20. data/lib/puppet-strings/yard/util.rb +17 -0
  21. data/spec/acceptance/emit_json_options.rb +15 -1
  22. data/spec/fixtures/unit/json/output.json +220 -9
  23. data/spec/fixtures/unit/json/output_without_puppet_function.json +179 -8
  24. data/spec/spec_helper.rb +3 -0
  25. data/spec/unit/puppet-strings/json_spec.rb +15 -4
  26. data/spec/unit/puppet-strings/yard/handlers/puppet/function_handler_spec.rb +72 -0
  27. data/spec/unit/puppet-strings/yard/handlers/ruby/function_handler_spec.rb +44 -0
  28. data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +20 -2
  29. data/spec/unit/puppet-strings/yard/handlers/ruby/type_handler_spec.rb +25 -1
  30. data/spec/unit/puppet-strings/yard/parsers/puppet/parser_spec.rb +38 -0
  31. data/spec/unit/puppet-strings/yard/util_spec.rb +31 -0
  32. metadata +5 -2
@@ -84,7 +84,7 @@
84
84
  {
85
85
  "name": "database",
86
86
  "file": "(stdin)",
87
- "line": 43,
87
+ "line": 54,
88
88
  "docstring": {
89
89
  "text": "An example database server resource type."
90
90
  },
@@ -154,7 +154,7 @@
154
154
  "name": "linux",
155
155
  "type_name": "database",
156
156
  "file": "(stdin)",
157
- "line": 33,
157
+ "line": 43,
158
158
  "docstring": {
159
159
  "text": "An example provider on Linux."
160
160
  },
@@ -166,9 +166,24 @@
166
166
  "implements_some_feature",
167
167
  "some_other_feature"
168
168
  ],
169
- "defaults": {
170
- "kernel": "Linux"
171
- },
169
+ "defaults": [
170
+ [
171
+ [
172
+ "kernel",
173
+ "Linux"
174
+ ]
175
+ ],
176
+ [
177
+ [
178
+ "osfamily",
179
+ "RedHat"
180
+ ],
181
+ [
182
+ "operatingsystemmajrelease",
183
+ "7"
184
+ ]
185
+ ]
186
+ ],
172
187
  "commands": {
173
188
  "foo": "/usr/bin/foo"
174
189
  }
@@ -180,7 +195,39 @@
180
195
  "file": "(stdin)",
181
196
  "line": 1,
182
197
  "type": "ruby3x",
183
- "signature": "func3x(String $first, Any $second)",
198
+ "signatures": [
199
+ {
200
+ "signature": "func3x(String $first, Any $second)",
201
+ "docstring": {
202
+ "text": "An example 3.x function.",
203
+ "tags": [
204
+ {
205
+ "tag_name": "param",
206
+ "text": "The first parameter.",
207
+ "types": [
208
+ "String"
209
+ ],
210
+ "name": "first"
211
+ },
212
+ {
213
+ "tag_name": "param",
214
+ "text": "The second parameter.",
215
+ "types": [
216
+ "Any"
217
+ ],
218
+ "name": "second"
219
+ },
220
+ {
221
+ "tag_name": "return",
222
+ "text": "Returns nothing.",
223
+ "types": [
224
+ "Undef"
225
+ ]
226
+ }
227
+ ]
228
+ }
229
+ }
230
+ ],
184
231
  "docstring": {
185
232
  "text": "An example 3.x function.",
186
233
  "tags": [
@@ -216,6 +263,78 @@
216
263
  "file": "(stdin)",
217
264
  "line": 11,
218
265
  "type": "ruby4x",
266
+ "signatures": [
267
+ {
268
+ "signature": "func4x(Integer $param1, Any $param2, Optional[Array[String]] $param3)",
269
+ "docstring": {
270
+ "text": "The first overload.",
271
+ "tags": [
272
+ {
273
+ "tag_name": "param",
274
+ "text": "The first parameter.",
275
+ "types": [
276
+ "Integer"
277
+ ],
278
+ "name": "param1"
279
+ },
280
+ {
281
+ "tag_name": "param",
282
+ "text": "The second parameter.",
283
+ "types": [
284
+ "Any"
285
+ ],
286
+ "name": "param2"
287
+ },
288
+ {
289
+ "tag_name": "param",
290
+ "text": "The third parameter.",
291
+ "types": [
292
+ "Optional[Array[String]]"
293
+ ],
294
+ "name": "param3"
295
+ },
296
+ {
297
+ "tag_name": "return",
298
+ "text": "Returns nothing.",
299
+ "types": [
300
+ "Undef"
301
+ ]
302
+ }
303
+ ]
304
+ }
305
+ },
306
+ {
307
+ "signature": "func4x(Boolean $param, Callable &$block)",
308
+ "docstring": {
309
+ "text": "",
310
+ "tags": [
311
+ {
312
+ "tag_name": "param",
313
+ "text": "The first parameter.",
314
+ "types": [
315
+ "Boolean"
316
+ ],
317
+ "name": "param"
318
+ },
319
+ {
320
+ "tag_name": "param",
321
+ "text": "The block parameter.",
322
+ "types": [
323
+ "Callable"
324
+ ],
325
+ "name": "&block"
326
+ },
327
+ {
328
+ "tag_name": "return",
329
+ "text": "Returns a string.",
330
+ "types": [
331
+ "String"
332
+ ]
333
+ }
334
+ ]
335
+ }
336
+ }
337
+ ],
219
338
  "docstring": {
220
339
  "text": "An example 4.x function.",
221
340
  "tags": [
@@ -264,7 +383,7 @@
264
383
  "tag_name": "overload",
265
384
  "signature": "func4x(Boolean $param, Callable &$block)",
266
385
  "docstring": {
267
- "text": "The second overload.",
386
+ "text": "",
268
387
  "tags": [
269
388
  {
270
389
  "tag_name": "param",
@@ -295,7 +414,59 @@
295
414
  }
296
415
  ]
297
416
  },
298
- "source": "Puppet::Functions.create_function(:func4x) do\n # The first overload.\n # @param param1 The first parameter.\n # @param param2 The second parameter.\n # @param param3 The third parameter.\n # @return [Undef] Returns nothing.\n dispatch :foo do\n param 'Integer', :param1\n param 'Any', :param2\n optional_param 'Array[String]', :param3\n end\n\n # The second overload.\n # @param param The first parameter.\n # @param block The block parameter.\n # @return [String] Returns a string.\n dispatch :other do\n param 'Boolean', :param\n block_param\n end\nend"
417
+ "source": "Puppet::Functions.create_function(:func4x) do\n # The first overload.\n # @param param1 The first parameter.\n # @param param2 The second parameter.\n # @param param3 The third parameter.\n # @return Returns nothing.\n dispatch :foo do\n param 'Integer', :param1\n param 'Any', :param2\n optional_param 'Array[String]', :param3\n return_type 'Undef'\n end\n\n # @param param The first parameter.\n # @param block The block parameter.\n # @return Returns a string.\n dispatch :other do\n param 'Boolean', :param\n block_param\n return_type 'String'\n end\nend"
418
+ },
419
+ {
420
+ "name": "func4x_1",
421
+ "file": "(stdin)",
422
+ "line": 35,
423
+ "type": "ruby4x",
424
+ "signatures": [
425
+ {
426
+ "signature": "func4x_1(Integer $param1)",
427
+ "docstring": {
428
+ "text": "An example 4.x function with only one signature.",
429
+ "tags": [
430
+ {
431
+ "tag_name": "param",
432
+ "text": "The first parameter.",
433
+ "types": [
434
+ "Integer"
435
+ ],
436
+ "name": "param1"
437
+ },
438
+ {
439
+ "tag_name": "return",
440
+ "text": "Returns nothing.",
441
+ "types": [
442
+ "Undef"
443
+ ]
444
+ }
445
+ ]
446
+ }
447
+ }
448
+ ],
449
+ "docstring": {
450
+ "text": "An example 4.x function with only one signature.",
451
+ "tags": [
452
+ {
453
+ "tag_name": "param",
454
+ "text": "The first parameter.",
455
+ "types": [
456
+ "Integer"
457
+ ],
458
+ "name": "param1"
459
+ },
460
+ {
461
+ "tag_name": "return",
462
+ "text": "Returns nothing.",
463
+ "types": [
464
+ "Undef"
465
+ ]
466
+ }
467
+ ]
468
+ },
469
+ "source": "Puppet::Functions.create_function(:func4x_1) do\n # @param param1 The first parameter.\n # @return [Undef] Returns nothing.\n dispatch :foobarbaz do\n param 'Integer', :param1\n end\nend"
299
470
  }
300
471
  ]
301
472
  }
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,9 @@ PuppetStrings::Yard.setup!
10
10
  # Enable testing of Puppet functions if running against 4.1+
11
11
  TEST_PUPPET_FUNCTIONS = Gem::Dependency.new('', '>= 4.1.0').match?('', Puppet::PUPPETVERSION)
12
12
 
13
+ # Enable testing of Puppet language functions declared with return type if running against 4.8+
14
+ TEST_FUNCTION_RETURN_TYPE = Gem::Dependency.new('', '>= 4.8.0').match?('', Puppet::PUPPETVERSION)
15
+
13
16
  RSpec.configure do |config|
14
17
  config.mock_with :mocha
15
18
 
@@ -48,20 +48,30 @@ Puppet::Functions.create_function(:func4x) do
48
48
  # @param param1 The first parameter.
49
49
  # @param param2 The second parameter.
50
50
  # @param param3 The third parameter.
51
- # @return [Undef] Returns nothing.
51
+ # @return Returns nothing.
52
52
  dispatch :foo do
53
53
  param 'Integer', :param1
54
54
  param 'Any', :param2
55
55
  optional_param 'Array[String]', :param3
56
+ return_type 'Undef'
56
57
  end
57
58
 
58
- # The second overload.
59
59
  # @param param The first parameter.
60
60
  # @param block The block parameter.
61
- # @return [String] Returns a string.
61
+ # @return Returns a string.
62
62
  dispatch :other do
63
63
  param 'Boolean', :param
64
64
  block_param
65
+ return_type 'String'
66
+ end
67
+ end
68
+
69
+ # An example 4.x function with only one signature.
70
+ Puppet::Functions.create_function(:func4x_1) do
71
+ # @param param1 The first parameter.
72
+ # @return [Undef] Returns nothing.
73
+ dispatch :foobarbaz do
74
+ param 'Integer', :param1
65
75
  end
66
76
  end
67
77
 
@@ -69,7 +79,8 @@ Puppet::Type.type(:database).provide :linux do
69
79
  desc 'An example provider on Linux.'
70
80
  confine kernel: 'Linux'
71
81
  confine osfamily: 'RedHat'
72
- defaultfor kernel: 'Linux'
82
+ defaultfor :kernel => 'Linux'
83
+ defaultfor :osfamily => 'RedHat', :operatingsystemmajrelease => '7'
73
84
  has_feature :implements_some_feature
74
85
  has_feature :some_other_feature
75
86
  commands foo: /usr/bin/foo
@@ -68,6 +68,11 @@ SOURCE
68
68
  expect(tags[2].name).to eq('param3')
69
69
  expect(tags[2].text).to eq('Third param.')
70
70
  expect(tags[2].types).to eq(['String'])
71
+ tags = object.docstring.tags(:return)
72
+ expect(tags.size).to eq(1)
73
+ expect(tags[0].tag_name).to eq('return')
74
+ expect(tags[0].text).to eq('Returns nothing.')
75
+ expect(tags[0].types).to eq(['Undef'])
71
76
  tags = object.docstring.tags(:api)
72
77
  expect(tags.size).to eq(1)
73
78
  expect(tags[0].text).to eq('public')
@@ -166,4 +171,71 @@ SOURCE
166
171
  expect{ subject }.to output(/\[warn\]: Missing @return tag near \(stdin\):5\./).to_stdout_from_any_process
167
172
  end
168
173
  end
174
+
175
+ describe 'parsing a function with a missing @return tag and return type specified in the function definition', if: TEST_FUNCTION_RETURN_TYPE do
176
+ let(:source) { <<-SOURCE
177
+ # A simple foo function.
178
+ function foo() >> String {
179
+ notice 'hello world'
180
+ }
181
+ SOURCE
182
+ }
183
+
184
+ it 'should register a function object with the correct return type' do
185
+ expect{ subject }.to output(/\[warn\]: Missing @return tag near \(stdin\):2\./).to_stdout_from_any_process
186
+ expect(subject.size).to eq(1)
187
+ object = subject.first
188
+ expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Function)
189
+ tags = object.docstring.tags(:return)
190
+ expect(tags.size).to eq(1)
191
+ expect(tags[0].tag_name).to eq('return')
192
+ expect(tags[0].text).to eq('')
193
+ expect(tags[0].types).to eq(['String'])
194
+ end
195
+ end
196
+
197
+ describe 'parsing a function with a conflicting return tag and type in function definition', if: TEST_FUNCTION_RETURN_TYPE do
198
+ let(:source) { <<-SOURCE
199
+ # A simple foo function.
200
+ # @return [Integer] this is a lie.
201
+ function foo() >> Struct[{'a' => Integer[1, 10]}] {
202
+ notice 'hello world'
203
+ }
204
+ SOURCE
205
+ }
206
+
207
+ it 'should prefer the return type from the function definition' do
208
+ expect{ subject }.to output(/\[warn\]: Documented return type does not match return type in function definition near \(stdin\):3\./).to_stdout_from_any_process
209
+ expect(subject.size).to eq(1)
210
+ object = subject.first
211
+ expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Function)
212
+ tags = object.docstring.tags(:return)
213
+ expect(tags.size).to eq(1)
214
+ expect(tags[0].tag_name).to eq('return')
215
+ expect(tags[0].text).to eq('this is a lie.')
216
+ expect(tags[0].types).to eq(["Struct[{'a' => Integer[1, 10]}]"])
217
+ end
218
+ end
219
+
220
+ describe 'parsing a function without a return tag or return type in the function definition' do
221
+ let(:source) { <<-SOURCE
222
+ # A simple foo function.
223
+ function foo() {
224
+ notice 'hello world'
225
+ }
226
+ SOURCE
227
+ }
228
+
229
+ it 'should add a return tag with a default type value of Any' do
230
+ expect{ subject }.to output(/\[warn\]: Missing @return tag near \(stdin\):2\./).to_stdout_from_any_process
231
+ expect(subject.size).to eq(1)
232
+ object = subject.first
233
+ expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Function)
234
+ tags = object.docstring.tags(:return)
235
+ expect(tags.size).to eq(1)
236
+ expect(tags[0].tag_name).to eq('return')
237
+ expect(tags[0].text).to eq('')
238
+ expect(tags[0].types).to eq(['Any'])
239
+ end
240
+ end
169
241
  end
@@ -70,6 +70,50 @@ SOURCE
70
70
  end
71
71
  end
72
72
 
73
+ describe 'parsing a function with a doc parameter which has a newline between the namespace and the newfunction call' do
74
+ let(:source) { <<-SOURCE
75
+ module Puppet::Parser::Functions
76
+ newfunction(:foo, doc: <<-DOC
77
+ An example 3.x function.
78
+ @param [String] first The first parameter.
79
+ @param second The second parameter.
80
+ @return [Undef] Returns nothing.
81
+ DOC
82
+ ) do |*args|
83
+ end
84
+ end
85
+ SOURCE
86
+ }
87
+
88
+ it 'should register a function object' do
89
+ expect(subject.size).to eq(1)
90
+ object = subject.first
91
+ expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Function)
92
+ expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::Functions.instance(PuppetStrings::Yard::CodeObjects::Function::RUBY_3X))
93
+ expect(object.name).to eq(:foo)
94
+ expect(object.signature).to eq('foo(String $first, Any $second)')
95
+ expect(object.parameters).to eq([['first', nil], ['second', nil]])
96
+ expect(object.docstring).to eq('An example 3.x function.')
97
+ expect(object.docstring.tags.size).to eq(4)
98
+ tags = object.docstring.tags(:param)
99
+ expect(tags.size).to eq(2)
100
+ expect(tags[0].name).to eq('first')
101
+ expect(tags[0].text).to eq('The first parameter.')
102
+ expect(tags[0].types).to eq(['String'])
103
+ expect(tags[1].name).to eq('second')
104
+ expect(tags[1].text).to eq('The second parameter.')
105
+ expect(tags[1].types).to eq(['Any'])
106
+ tags = object.docstring.tags(:return)
107
+ expect(tags.size).to eq(1)
108
+ expect(tags[0].name).to be_nil
109
+ expect(tags[0].text).to eq('Returns nothing.')
110
+ expect(tags[0].types).to eq(['Undef'])
111
+ tags = object.docstring.tags(:api)
112
+ expect(tags.size).to eq(1)
113
+ expect(tags[0].text).to eq('public')
114
+ end
115
+ end
116
+
73
117
  describe 'parsing a function with a missing @return tag' do
74
118
  let(:source) { <<-SOURCE
75
119
  Puppet::Parser::Functions.newfunction(:foo, doc: <<-DOC) do |*args|
@@ -55,13 +55,31 @@ SOURCE
55
55
  end
56
56
  end
57
57
 
58
+ describe 'parsing a provider with a docstring which uses ruby `%Q` notation' do
59
+ let(:source) { <<-'SOURCE'
60
+ Puppet::Type.type(:custom).provide :linux do
61
+ test = 'hello world!'
62
+ desc %Q{This is a multi-line
63
+ doc in %Q with #{test}}
64
+ end
65
+ SOURCE
66
+ }
67
+
68
+ it 'should strip the `%Q{}` and render the interpolation expression literally' do
69
+ expect(subject.size).to eq(1)
70
+ object = subject.first
71
+ expect(object.docstring).to eq("This is a multi-line\ndoc in %Q with \#{test}")
72
+ end
73
+ end
74
+
58
75
  describe 'parsing a provider definition' do
59
76
  let(:source) { <<-SOURCE
60
77
  Puppet::Type.type(:custom).provide :linux do
61
78
  desc 'An example provider on Linux.'
62
79
  confine kernel: 'Linux'
63
80
  confine osfamily: 'RedHat'
64
- defaultfor kernel: 'Linux'
81
+ defaultfor :kernel => 'Linux'
82
+ defaultfor :osfamily => 'RedHat', :operatingsystemmajrelease => '7'
65
83
  has_feature :implements_some_feature
66
84
  has_feature :some_other_feature
67
85
  commands foo: /usr/bin/foo
@@ -82,7 +100,7 @@ SOURCE
82
100
  expect(tags.size).to eq(1)
83
101
  expect(tags[0].text).to eq('public')
84
102
  expect(object.confines).to eq({ 'kernel' => 'Linux', 'osfamily' => 'RedHat'})
85
- expect(object.defaults).to eq({ 'kernel' => 'Linux'})
103
+ expect(object.defaults).to eq([[["kernel", "Linux"]], [["osfamily", "RedHat"], ["operatingsystemmajrelease", "7"]]])
86
104
  expect(object.features).to eq(['implements_some_feature', 'some_other_feature'])
87
105
  expect(object.commands).to eq({'foo' => '/usr/bin/foo'})
88
106
  end