puppet-strings 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|