puppet-strings 1.1.1 → 1.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile +4 -2
- data/README.md +53 -10
- data/codecov.yml +3 -0
- data/lib/puppet-strings.rb +30 -11
- data/lib/puppet-strings/json.rb +7 -0
- data/lib/puppet-strings/markdown.rb +35 -0
- data/lib/puppet-strings/markdown/base.rb +168 -0
- data/lib/puppet-strings/markdown/defined_type.rb +14 -0
- data/lib/puppet-strings/markdown/defined_types.rb +37 -0
- data/lib/puppet-strings/markdown/function.rb +52 -0
- data/lib/puppet-strings/markdown/functions.rb +38 -0
- data/lib/puppet-strings/markdown/puppet_class.rb +14 -0
- data/lib/puppet-strings/markdown/puppet_classes.rb +37 -0
- data/lib/puppet-strings/markdown/resource_type.rb +27 -0
- data/lib/puppet-strings/markdown/resource_types.rb +37 -0
- data/lib/puppet-strings/markdown/table_of_contents.rb +21 -0
- data/lib/puppet-strings/markdown/templates/classes_and_defines.erb +63 -0
- data/lib/puppet-strings/markdown/templates/function.erb +50 -0
- data/lib/puppet-strings/markdown/templates/resource_type.erb +114 -0
- data/lib/puppet-strings/markdown/templates/table_of_contents.erb +21 -0
- data/lib/puppet-strings/tasks/generate.rb +24 -5
- data/lib/puppet-strings/yard/code_objects/function.rb +3 -3
- data/lib/puppet-strings/yard/code_objects/type.rb +3 -1
- data/lib/puppet-strings/yard/handlers.rb +1 -0
- data/lib/puppet-strings/yard/handlers/puppet/function_handler.rb +1 -1
- data/lib/puppet-strings/yard/handlers/ruby/base.rb +1 -1
- data/lib/puppet-strings/yard/handlers/ruby/rsapi_handler.rb +141 -0
- data/lib/puppet/face/strings.rb +28 -7
- data/spec/acceptance/emit_json_options.rb +4 -4
- data/spec/acceptance/generate_markdown_spec.rb +49 -0
- data/spec/fixtures/unit/json/output.json +43 -0
- data/spec/fixtures/unit/markdown/output.md +383 -0
- data/spec/spec_helper.rb +19 -1
- data/spec/unit/puppet-strings/json_spec.rb +40 -0
- data/spec/unit/puppet-strings/markdown/base_spec.rb +146 -0
- data/spec/unit/puppet-strings/markdown_spec.rb +248 -0
- data/spec/unit/puppet-strings/yard/handlers/puppet/function_handler_spec.rb +16 -1
- data/spec/unit/puppet-strings/yard/handlers/ruby/provider_handler_spec.rb +1 -1
- data/spec/unit/puppet-strings/yard/handlers/ruby/rsapi_handler_spec.rb +213 -0
- metadata +38 -2
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PuppetStrings::Markdown::Base do
|
4
|
+
context 'basic class' do
|
5
|
+
before :each do
|
6
|
+
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
7
|
+
# An overview
|
8
|
+
# @api private
|
9
|
+
# @summary A simple class.
|
10
|
+
# @param param1 First param.
|
11
|
+
# @param param2 Second param.
|
12
|
+
# @param param3 Third param.
|
13
|
+
class klass(Integer $param1, $param2, String $param3 = hi) inherits foo::bar {
|
14
|
+
}
|
15
|
+
SOURCE
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:reg) { YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash)[0] }
|
19
|
+
let(:component) { PuppetStrings::Markdown::Base.new(reg, 'class') }
|
20
|
+
|
21
|
+
describe '#name' do
|
22
|
+
it 'returns the expected name' do
|
23
|
+
expect(component.name).to eq 'klass'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
[ 'examples',
|
28
|
+
'see',
|
29
|
+
'since',
|
30
|
+
'return_val',
|
31
|
+
'return_type',].each do |method|
|
32
|
+
describe "##{method}" do
|
33
|
+
it 'returns nil' do
|
34
|
+
expect(component.method(method.to_sym).call).to be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#private?' do
|
41
|
+
it do
|
42
|
+
expect(component.private?).to be true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#params' do
|
47
|
+
it 'returns the expected params' do
|
48
|
+
expect(component.params.size).to eq 3
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#summary' do
|
53
|
+
it 'returns the expected summary' do
|
54
|
+
expect(component.summary).to eq 'A simple class.'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#toc_info' do
|
59
|
+
let(:toc) { component.toc_info }
|
60
|
+
it 'returns a hash' do
|
61
|
+
expect(toc).to be_instance_of Hash
|
62
|
+
end
|
63
|
+
it 'prefers the summary for :desc' do
|
64
|
+
expect(toc[:desc]).to eq 'A simple class.'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
context 'less basic class' do
|
69
|
+
before :each do
|
70
|
+
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
71
|
+
# An overview
|
72
|
+
# It's a longer overview
|
73
|
+
# Ya know?
|
74
|
+
# @example A simple example.
|
75
|
+
# class { 'klass::yeah':
|
76
|
+
# param1 => 1,
|
77
|
+
# }
|
78
|
+
# @param param1 First param.
|
79
|
+
# @param param2 Second param.
|
80
|
+
# @param param3 Third param.
|
81
|
+
class klass::yeah(
|
82
|
+
Integer $param1,
|
83
|
+
$param2,
|
84
|
+
String $param3 = hi
|
85
|
+
) inherits foo::bar {
|
86
|
+
|
87
|
+
}
|
88
|
+
SOURCE
|
89
|
+
end
|
90
|
+
|
91
|
+
let(:reg) { YARD::Registry.all(:puppet_class).sort_by!(&:name).map!(&:to_hash)[0] }
|
92
|
+
let(:component) { PuppetStrings::Markdown::Base.new(reg, 'class') }
|
93
|
+
|
94
|
+
describe '#name' do
|
95
|
+
it 'returns the expected name' do
|
96
|
+
expect(component.name).to eq 'klass::yeah'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
['summary',
|
101
|
+
'see',
|
102
|
+
'since',
|
103
|
+
'return_val',
|
104
|
+
'return_type'].each do |method|
|
105
|
+
describe "##{method}" do
|
106
|
+
it 'returns nil' do
|
107
|
+
expect(component.method(method.to_sym).call).to be_nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#examples' do
|
113
|
+
it 'should return one example' do
|
114
|
+
expect(component.examples.size).to eq 1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#params' do
|
119
|
+
it 'returns the expected params' do
|
120
|
+
expect(component.params.size).to eq 3
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#private?' do
|
125
|
+
it do
|
126
|
+
expect(component.private?).to be false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#toc_info' do
|
131
|
+
let(:toc) { component.toc_info }
|
132
|
+
it 'returns a hash' do
|
133
|
+
expect(toc).to be_instance_of Hash
|
134
|
+
end
|
135
|
+
it 'uses overview for :desc in absence of summary' do
|
136
|
+
expect(toc[:desc]).to eq 'An overview It\'s a longer overview Ya know?'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '#link' do
|
141
|
+
it 'returns a valid link' do
|
142
|
+
expect(component.link).to eq 'klassyeah'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet-strings/markdown'
|
3
|
+
require 'puppet-strings/markdown/table_of_contents'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
describe PuppetStrings::Markdown do
|
7
|
+
before :each do
|
8
|
+
# Populate the YARD registry with both Puppet and Ruby source
|
9
|
+
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
10
|
+
# An overview for a simple class.
|
11
|
+
# @summary A simple class.
|
12
|
+
# @since 1.0.0
|
13
|
+
# @see www.puppet.com
|
14
|
+
# @example This is an example
|
15
|
+
# class { 'klass':
|
16
|
+
# param1 => 1,
|
17
|
+
# param3 => 'foo',
|
18
|
+
# }
|
19
|
+
# @example This is another example
|
20
|
+
# class { 'klass':
|
21
|
+
# param1 => 1,
|
22
|
+
# param3 => 'foo',
|
23
|
+
# }
|
24
|
+
# @raise SomeError
|
25
|
+
# @param param1 First param.
|
26
|
+
# @param param2 Second param.
|
27
|
+
# @option param2 [String] :opt1 something about opt1
|
28
|
+
# @option param2 [Hash] :opt2 a hash of stuff
|
29
|
+
# @param param3 Third param.
|
30
|
+
#
|
31
|
+
class klass (
|
32
|
+
Integer $param1 = 1,
|
33
|
+
$param2 = undef,
|
34
|
+
String $param3 = 'hi'
|
35
|
+
) inherits foo::bar {
|
36
|
+
}
|
37
|
+
|
38
|
+
# Overview for class noparams
|
39
|
+
# @api private
|
40
|
+
class noparams () {}
|
41
|
+
|
42
|
+
# An overview for a simple defined type.
|
43
|
+
# @summary A simple defined type.
|
44
|
+
# @since 1.1.0
|
45
|
+
# @see www.puppet.com
|
46
|
+
# @example Here's an example of this type:
|
47
|
+
# klass::dt { 'foo':
|
48
|
+
# param1 => 33,
|
49
|
+
# param4 => false,
|
50
|
+
# }
|
51
|
+
# @return shouldn't return squat
|
52
|
+
# @raise SomeError
|
53
|
+
# @param param1 First param.
|
54
|
+
# @param param2 Second param.
|
55
|
+
# @option param2 [String] :opt1 something about opt1
|
56
|
+
# @option param2 [Hash] :opt2 a hash of stuff
|
57
|
+
# @param param3 Third param.
|
58
|
+
# @param param4 Fourth param.
|
59
|
+
define klass::dt (
|
60
|
+
Integer $param1 = 44,
|
61
|
+
$param2,
|
62
|
+
String $param3 = 'hi',
|
63
|
+
Boolean $param4 = true
|
64
|
+
) {
|
65
|
+
}
|
66
|
+
SOURCE
|
67
|
+
|
68
|
+
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :puppet)
|
69
|
+
# A simple Puppet function.
|
70
|
+
# @param param1 First param.
|
71
|
+
# @param param2 Second param.
|
72
|
+
# @param param3 Third param.
|
73
|
+
# @option param3 [Array] :param3opt Something about this option
|
74
|
+
# @raise SomeError this is some error
|
75
|
+
# @return [Undef] Returns nothing.
|
76
|
+
function func(Integer $param1, $param2, String $param3 = hi) {
|
77
|
+
}
|
78
|
+
SOURCE
|
79
|
+
|
80
|
+
YARD::Parser::SourceParser.parse_string(<<-SOURCE, :ruby)
|
81
|
+
# An example 4.x function.
|
82
|
+
Puppet::Functions.create_function(:func4x) do
|
83
|
+
# An overview for the first overload.
|
84
|
+
# @raise SomeError this is some error
|
85
|
+
# @param param1 The first parameter.
|
86
|
+
# @param param2 The second parameter.
|
87
|
+
# @option param2 [String] :option an option
|
88
|
+
# @option param2 [String] :option2 another option
|
89
|
+
# @param param3 The third parameter.
|
90
|
+
# @return Returns nothing.
|
91
|
+
dispatch :foo do
|
92
|
+
param 'Integer', :param1
|
93
|
+
param 'Any', :param2
|
94
|
+
optional_param 'Array[String]', :param3
|
95
|
+
return_type 'Undef'
|
96
|
+
end
|
97
|
+
|
98
|
+
# An overview for the second overload.
|
99
|
+
# @param param The first parameter.
|
100
|
+
# @param block The block parameter.
|
101
|
+
# @return Returns a string.
|
102
|
+
dispatch :other do
|
103
|
+
param 'Boolean', :param
|
104
|
+
block_param
|
105
|
+
return_type 'String'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# An example 4.x function with only one signature.
|
110
|
+
Puppet::Functions.create_function(:func4x_1) do
|
111
|
+
# @param param1 The first parameter.
|
112
|
+
# @return [Undef] Returns nothing.
|
113
|
+
dispatch :foobarbaz do
|
114
|
+
param 'Integer', :param1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# An example 3.x function
|
119
|
+
Puppet::Parser::Functions.newfunction(:func3x, doc: <<-DOC
|
120
|
+
Documentation for an example 3.x function.
|
121
|
+
@param param1 [String] The first parameter.
|
122
|
+
@param param2 [Integer] The second parameter.
|
123
|
+
@return [Undef]
|
124
|
+
@example Calling the function.
|
125
|
+
func3x('hi', 10)
|
126
|
+
DOC
|
127
|
+
) do |*args|
|
128
|
+
#...
|
129
|
+
end
|
130
|
+
|
131
|
+
Puppet::Type.type(:database).provide :linux do
|
132
|
+
desc 'An example provider on Linux.'
|
133
|
+
confine kernel: 'Linux'
|
134
|
+
confine osfamily: 'RedHat'
|
135
|
+
defaultfor :kernel => 'Linux'
|
136
|
+
defaultfor :osfamily => 'RedHat', :operatingsystemmajrelease => '7'
|
137
|
+
has_feature :implements_some_feature
|
138
|
+
has_feature :some_other_feature
|
139
|
+
commands foo: '/usr/bin/foo'
|
140
|
+
end
|
141
|
+
|
142
|
+
Puppet::Type.newtype(:database) do
|
143
|
+
desc <<-DESC
|
144
|
+
An example database server type.
|
145
|
+
@option opts :foo bar
|
146
|
+
@raise SomeError
|
147
|
+
@example here's an example
|
148
|
+
database { 'foo':
|
149
|
+
address => 'qux.baz.bar',
|
150
|
+
}
|
151
|
+
DESC
|
152
|
+
feature :encryption, 'The provider supports encryption.', methods: [:encrypt]
|
153
|
+
ensurable do
|
154
|
+
desc 'What state the database should be in.'
|
155
|
+
defaultvalues
|
156
|
+
aliasvalue(:up, :present)
|
157
|
+
aliasvalue(:down, :absent)
|
158
|
+
defaultto :up
|
159
|
+
end
|
160
|
+
|
161
|
+
newparam(:address) do
|
162
|
+
isnamevar
|
163
|
+
desc 'The database server name.'
|
164
|
+
end
|
165
|
+
|
166
|
+
newparam(:encryption_key, required_features: :encryption) do
|
167
|
+
desc 'The encryption key to use.'
|
168
|
+
end
|
169
|
+
|
170
|
+
newparam(:encrypt, :parent => Puppet::Parameter::Boolean) do
|
171
|
+
desc 'Whether or not to encrypt the database.'
|
172
|
+
defaultto false
|
173
|
+
end
|
174
|
+
|
175
|
+
newproperty(:file) do
|
176
|
+
desc 'The database file to use.'
|
177
|
+
end
|
178
|
+
|
179
|
+
newproperty(:log_level) do
|
180
|
+
desc 'The log level to use.'
|
181
|
+
newvalue(:debug)
|
182
|
+
newvalue(:warn)
|
183
|
+
newvalue(:error)
|
184
|
+
defaultto 'warn'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
Puppet::ResourceApi.register_type(
|
189
|
+
name: 'apt_key',
|
190
|
+
desc: <<-EOS,
|
191
|
+
@summary Example resource type using the new API.
|
192
|
+
@raise SomeError
|
193
|
+
This type provides Puppet with the capabilities to manage GPG keys needed
|
194
|
+
by apt to perform package validation. Apt has it's own GPG keyring that can
|
195
|
+
be manipulated through the `apt-key` command.
|
196
|
+
@example here's an example
|
197
|
+
apt_key { '6F6B15509CF8E59E6E469F327F438280EF8D349F':
|
198
|
+
source => 'http://apt.puppetlabs.com/pubkey.gpg'
|
199
|
+
}
|
200
|
+
|
201
|
+
**Autorequires**:
|
202
|
+
If Puppet is given the location of a key file which looks like an absolute
|
203
|
+
path this type will autorequire that file.
|
204
|
+
EOS
|
205
|
+
attributes: {
|
206
|
+
ensure: {
|
207
|
+
type: 'Enum[present, absent]',
|
208
|
+
desc: 'Whether this apt key should be present or absent on the target system.'
|
209
|
+
},
|
210
|
+
id: {
|
211
|
+
type: 'Variant[Pattern[/\A(0x)?[0-9a-fA-F]{8}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{16}\Z/], Pattern[/\A(0x)?[0-9a-fA-F]{40}\Z/]]',
|
212
|
+
behaviour: :namevar,
|
213
|
+
desc: 'The ID of the key you want to manage.',
|
214
|
+
},
|
215
|
+
# ...
|
216
|
+
created: {
|
217
|
+
type: 'String',
|
218
|
+
behaviour: :read_only,
|
219
|
+
desc: 'Date the key was created, in ISO format.',
|
220
|
+
},
|
221
|
+
},
|
222
|
+
autorequires: {
|
223
|
+
file: '$source', # will evaluate to the value of the `source` attribute
|
224
|
+
package: 'apt',
|
225
|
+
},
|
226
|
+
)
|
227
|
+
SOURCE
|
228
|
+
end
|
229
|
+
|
230
|
+
let(:filename) { 'output.md' }
|
231
|
+
let(:baseline_path) { File.join(File.dirname(__FILE__), "../../fixtures/unit/markdown/#{filename}") }
|
232
|
+
let(:baseline) { File.read(baseline_path) }
|
233
|
+
|
234
|
+
describe 'rendering markdown to a file' do
|
235
|
+
it 'should output the expected markdown content' do
|
236
|
+
Tempfile.open('md') do |file|
|
237
|
+
PuppetStrings::Markdown.render(file.path)
|
238
|
+
expect(File.read(file.path)).to eq(baseline)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
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
|
+
end
|
@@ -20,7 +20,7 @@ describe PuppetStrings::Yard::Handlers::Puppet::FunctionHandler, if: TEST_PUPPET
|
|
20
20
|
let(:source) { 'function foo{' }
|
21
21
|
|
22
22
|
it 'should log an error' do
|
23
|
-
expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of
|
23
|
+
expect{ subject }.to output(/\[error\]: Failed to parse \(stdin\): Syntax error at end of/).to_stdout_from_any_process
|
24
24
|
expect(subject.empty?).to eq(true)
|
25
25
|
end
|
26
26
|
end
|
@@ -216,6 +216,21 @@ SOURCE
|
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
+
describe 'parsing a function with a non-conflicting return tag and type in function definition', if: TEST_FUNCTION_RETURN_TYPE do
|
220
|
+
let(:source) { <<-SOURCE
|
221
|
+
# A simple foo function
|
222
|
+
# @return [String] Hi there
|
223
|
+
function foo() >> String {
|
224
|
+
notice 'hi there'
|
225
|
+
}
|
226
|
+
SOURCE
|
227
|
+
}
|
228
|
+
|
229
|
+
it 'should not output a warning if return types match' do
|
230
|
+
expect{ subject }.not_to output(/Documented return type does not match return type in function definition/).to_stdout_from_any_process
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
219
234
|
describe 'parsing a function with a conflicting return tag and type in function definition', if: TEST_FUNCTION_RETURN_TYPE do
|
220
235
|
let(:source) { <<-SOURCE
|
221
236
|
# A simple foo function.
|
@@ -82,7 +82,7 @@ Puppet::Type.type(:custom).provide :linux do
|
|
82
82
|
defaultfor :osfamily => 'RedHat', :operatingsystemmajrelease => '7'
|
83
83
|
has_feature :implements_some_feature
|
84
84
|
has_feature :some_other_feature
|
85
|
-
commands foo: /usr/bin/foo
|
85
|
+
commands foo: '/usr/bin/foo'
|
86
86
|
end
|
87
87
|
SOURCE
|
88
88
|
}
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet-strings/yard'
|
3
|
+
|
4
|
+
describe PuppetStrings::Yard::Handlers::Ruby::RsapiHandler do
|
5
|
+
subject {
|
6
|
+
YARD::Parser::SourceParser.parse_string(source, :ruby)
|
7
|
+
YARD::Registry.all(:puppet_type)
|
8
|
+
}
|
9
|
+
|
10
|
+
describe 'parsing source without a type definition' do
|
11
|
+
let(:source) { 'puts "hi"' }
|
12
|
+
|
13
|
+
it 'no types should be in the registry' do
|
14
|
+
expect(subject.empty?).to eq(true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'parsing a type with a missing description' do
|
19
|
+
let(:source) { <<-SOURCE
|
20
|
+
Puppet::ResourceApi.register_type(
|
21
|
+
name: 'database'
|
22
|
+
)
|
23
|
+
SOURCE
|
24
|
+
}
|
25
|
+
|
26
|
+
it 'should log a warning' do
|
27
|
+
expect{ subject }.to output(/\[warn\]: Missing a description for Puppet resource type 'database' at \(stdin\):1\./).to_stdout_from_any_process
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'parsing a type with a valid docstring assignment' do
|
32
|
+
let(:source) { <<-SOURCE
|
33
|
+
Puppet::ResourceApi.register_type(
|
34
|
+
name: 'database',
|
35
|
+
docs: 'An example database server resource type.',
|
36
|
+
)
|
37
|
+
SOURCE
|
38
|
+
}
|
39
|
+
|
40
|
+
it 'should correctly detect the docstring' do
|
41
|
+
expect(subject.size).to eq(1)
|
42
|
+
object = subject.first
|
43
|
+
expect(object.docstring).to eq('An example database server resource type.')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'parsing a type with a docstring which uses ruby `%Q` notation' do
|
48
|
+
let(:source) { <<-'SOURCE'
|
49
|
+
test = 'hello world!'
|
50
|
+
|
51
|
+
Puppet::ResourceApi.register_type(
|
52
|
+
name: 'database',
|
53
|
+
docs: %Q{This is a multi-line
|
54
|
+
doc in %Q with #{test}},
|
55
|
+
)
|
56
|
+
SOURCE
|
57
|
+
}
|
58
|
+
|
59
|
+
it 'should strip the `%Q{}` and render the interpolation expression literally' do
|
60
|
+
expect(subject.size).to eq(1)
|
61
|
+
object = subject.first
|
62
|
+
expect(object.docstring).to eq("This is a multi-line\ndoc in %Q with \#{test}")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'parsing a type definition' do
|
67
|
+
let(:source) { <<-SOURCE
|
68
|
+
# @!puppet.type.param [value1, value2] dynamic_param Documentation for a dynamic parameter.
|
69
|
+
# @!puppet.type.property [foo, bar] dynamic_prop Documentation for a dynamic property.
|
70
|
+
Puppet::ResourceApi.register_type(
|
71
|
+
name: 'database',
|
72
|
+
docs: 'An example database server resource type.',
|
73
|
+
attributes: {
|
74
|
+
ensure: {
|
75
|
+
type: 'Enum[present, absent, up, down]',
|
76
|
+
desc: 'What state the database should be in.',
|
77
|
+
default: 'up',
|
78
|
+
},
|
79
|
+
address: {
|
80
|
+
type: 'String',
|
81
|
+
desc: 'The database server name.',
|
82
|
+
behaviour: :namevar,
|
83
|
+
},
|
84
|
+
encrypt: {
|
85
|
+
type: 'Boolean',
|
86
|
+
desc: 'Whether or not to encrypt the database.',
|
87
|
+
default: false,
|
88
|
+
behaviour: :parameter,
|
89
|
+
},
|
90
|
+
encryption_key: {
|
91
|
+
type: 'Optional[String]',
|
92
|
+
desc: 'The encryption key to use.',
|
93
|
+
behaviour: :parameter,
|
94
|
+
},
|
95
|
+
backup: {
|
96
|
+
type: 'Enum[daily, monthly, never]',
|
97
|
+
desc: 'How often to backup the database.',
|
98
|
+
default: 'never',
|
99
|
+
behaviour: :parameter,
|
100
|
+
},
|
101
|
+
file: {
|
102
|
+
type: 'String',
|
103
|
+
desc: 'The database file to use.',
|
104
|
+
},
|
105
|
+
log_level: {
|
106
|
+
type: 'Enum[debug, warn, error]',
|
107
|
+
desc: 'The log level to use.',
|
108
|
+
default: 'warn',
|
109
|
+
},
|
110
|
+
},
|
111
|
+
)
|
112
|
+
SOURCE
|
113
|
+
}
|
114
|
+
|
115
|
+
it 'should register a type object' do
|
116
|
+
expect(subject.size).to eq(1)
|
117
|
+
object = subject.first
|
118
|
+
expect(object).to be_a(PuppetStrings::Yard::CodeObjects::Type)
|
119
|
+
expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::Types.instance)
|
120
|
+
expect(object.name).to eq(:database)
|
121
|
+
expect(object.docstring).to eq('An example database server resource type.')
|
122
|
+
expect(object.docstring.tags.size).to eq(1)
|
123
|
+
tags = object.docstring.tags(:api)
|
124
|
+
expect(tags.size).to eq(1)
|
125
|
+
expect(tags[0].text).to eq('public')
|
126
|
+
expect(object.properties.map(&:name)).to eq(['dynamic_prop', 'ensure', 'file', 'log_level'])
|
127
|
+
expect(object.properties.size).to eq(4)
|
128
|
+
expect(object.properties[0].name).to eq('dynamic_prop')
|
129
|
+
expect(object.properties[0].docstring).to eq('Documentation for a dynamic property.')
|
130
|
+
expect(object.properties[0].isnamevar).to eq(false)
|
131
|
+
expect(object.properties[0].values).to eq(%w(foo bar))
|
132
|
+
expect(object.properties[1].name).to eq('ensure')
|
133
|
+
expect(object.properties[1].docstring).to eq('What state the database should be in.')
|
134
|
+
expect(object.properties[1].isnamevar).to eq(false)
|
135
|
+
expect(object.properties[1].default).to eq('up')
|
136
|
+
expect(object.properties[1].values).to eq(['Enum[present, absent, up, down]'])
|
137
|
+
expect(object.properties[1].aliases).to eq({})
|
138
|
+
expect(object.properties[2].name).to eq('file')
|
139
|
+
expect(object.properties[2].docstring).to eq('The database file to use.')
|
140
|
+
expect(object.properties[2].isnamevar).to eq(false)
|
141
|
+
expect(object.properties[2].default).to be_nil
|
142
|
+
expect(object.properties[2].values).to eq(['String'])
|
143
|
+
expect(object.properties[2].aliases).to eq({})
|
144
|
+
expect(object.properties[3].name).to eq('log_level')
|
145
|
+
expect(object.properties[3].docstring).to eq('The log level to use.')
|
146
|
+
expect(object.properties[3].isnamevar).to eq(false)
|
147
|
+
expect(object.properties[3].default).to eq('warn')
|
148
|
+
expect(object.properties[3].values).to eq(['Enum[debug, warn, error]'])
|
149
|
+
expect(object.properties[3].aliases).to eq({})
|
150
|
+
expect(object.parameters.size).to eq(5)
|
151
|
+
expect(object.parameters[0].name).to eq('dynamic_param')
|
152
|
+
expect(object.parameters[0].docstring).to eq('Documentation for a dynamic parameter.')
|
153
|
+
expect(object.parameters[0].isnamevar).to eq(false)
|
154
|
+
expect(object.parameters[0].values).to eq(%w(value1 value2))
|
155
|
+
expect(object.parameters[1].name).to eq('address')
|
156
|
+
expect(object.parameters[1].docstring).to eq('The database server name.')
|
157
|
+
expect(object.parameters[1].isnamevar).to eq(true)
|
158
|
+
expect(object.parameters[1].default).to be_nil
|
159
|
+
expect(object.parameters[1].values).to eq(['String'])
|
160
|
+
expect(object.parameters[1].aliases).to eq({})
|
161
|
+
expect(object.parameters[2].name).to eq('encrypt')
|
162
|
+
expect(object.parameters[2].docstring).to eq('Whether or not to encrypt the database.')
|
163
|
+
expect(object.parameters[2].isnamevar).to eq(false)
|
164
|
+
expect(object.parameters[2].default).to eq(false)
|
165
|
+
expect(object.parameters[2].values).to eq(["Boolean"])
|
166
|
+
expect(object.parameters[2].aliases).to eq({})
|
167
|
+
expect(object.parameters[3].name).to eq('encryption_key')
|
168
|
+
expect(object.parameters[3].docstring).to eq('The encryption key to use.')
|
169
|
+
expect(object.parameters[3].isnamevar).to eq(false)
|
170
|
+
expect(object.parameters[3].default).to be_nil
|
171
|
+
expect(object.parameters[3].values).to eq(["Optional[String]"])
|
172
|
+
expect(object.parameters[3].aliases).to eq({})
|
173
|
+
expect(object.parameters[4].name).to eq('backup')
|
174
|
+
expect(object.parameters[4].docstring).to eq('How often to backup the database.')
|
175
|
+
expect(object.parameters[4].isnamevar).to eq(false)
|
176
|
+
expect(object.parameters[4].default).to eq('never')
|
177
|
+
expect(object.parameters[4].values).to eq(["Enum[daily, monthly, never]"])
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'parsing a type with a summary' do
|
182
|
+
context 'when the summary has fewer than 140 characters' do
|
183
|
+
let(:source) { <<-SOURCE
|
184
|
+
Puppet::ResourceApi.register_type(
|
185
|
+
name: 'database',
|
186
|
+
docs: '@summary A short summary.',
|
187
|
+
)
|
188
|
+
SOURCE
|
189
|
+
}
|
190
|
+
|
191
|
+
it 'should parse the summary' do
|
192
|
+
expect{ subject }.to output('').to_stdout_from_any_process
|
193
|
+
expect(subject.size).to eq(1)
|
194
|
+
summary = subject.first.tags(:summary)
|
195
|
+
expect(summary.first.text).to eq('A short summary.')
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when the summary has more than 140 characters' do
|
200
|
+
let(:source) { <<-SOURCE
|
201
|
+
Puppet::ResourceApi.register_type(
|
202
|
+
name: 'database',
|
203
|
+
docs: '@summary A short summary that is WAY TOO LONG. AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH this is not what a summary is for! It should be fewer than 140 characters!!',
|
204
|
+
)
|
205
|
+
SOURCE
|
206
|
+
}
|
207
|
+
|
208
|
+
it 'should log a warning' do
|
209
|
+
expect{ subject }.to output(/\[warn\]: The length of the summary for puppet_type 'database' exceeds the recommended limit of 140 characters./).to_stdout_from_any_process
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|