Skip to content

Commit 90182c9

Browse files
authored
Merge pull request #209 from glennsarti/maint-fix-datatype
(PDOC-285) Fix data_type_handler for errors and numbers
2 parents 41ca7f1 + 47ebd87 commit 90182c9

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

lib/puppet-strings/yard/handlers/ruby/data_type_handler.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
1414
return unless ruby_module_name == 'Puppet::DataTypes' || ruby_module_name == 'DataTypes' # rubocop:disable Style/MultipleComparison This reads better
1515
object = get_datatype_yard_object(get_name(statement, 'Puppet::DataTypes.create_type'))
1616

17-
actual_params = extract_params_for_data_type # populate_data_type_data(object)
17+
actual_params = extract_params_for_data_type
1818

1919
# Mark the data type as public if it doesn't already have an api tag
2020
object.add_tag YARD::Tags::Tag.new(:api, 'public') unless object.has_tag? :api
@@ -65,7 +65,13 @@ def extract_params_for_data_type
6565
interface_string = node_as_string(parameters[0])
6666
next unless interface_string
6767
# Ref - https://github.com/puppetlabs/puppet/blob/ba4d1a1aba0095d3c70b98fea5c67434a4876a61/lib/puppet/datatypes.rb#L159
68-
parsed_interface = Puppet::Pops::Parser::EvaluatingParser.new.parse_string("{ #{interface_string} }").body
68+
parsed_interface = nil
69+
begin
70+
parsed_interface = Puppet::Pops::Parser::EvaluatingParser.new.parse_string("{ #{interface_string} }").body
71+
rescue Puppet::Error => e
72+
log.warn "Invalid datatype definition at #{statement.file}:#{statement.line}: #{e.basic_message}"
73+
next
74+
end
6975
next unless parsed_interface
7076

7177
# Now that we parsed the Puppet code (as a string) into a LiteralHash PCore type (Puppet AST),
@@ -146,6 +152,10 @@ def literal_LiteralNumber(o) # rubocop:disable Naming/UncommunicativeMethodParam
146152
o.value
147153
end
148154

155+
def literal_UnaryMinusExpression(o) # rubocop:disable Naming/UncommunicativeMethodParamName
156+
-1 * literal(o.expr)
157+
end
158+
149159
def literal_LiteralBoolean(o) # rubocop:disable Naming/UncommunicativeMethodParamName
150160
o.value
151161
end

spec/unit/puppet-strings/yard/handlers/ruby/data_type_handler_spec.rb

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,83 @@ def suppress_yard_logging
189189
end
190190
end
191191

192+
testcases = [
193+
{ :value => '-1', :expected => -1 },
194+
{ :value => '0', :expected => 0 },
195+
{ :value => '10', :expected => 10 },
196+
{ :value => '0777', :expected => 511 },
197+
{ :value => '0xFF', :expected => 255 },
198+
{ :value => '0.1', :expected => 0.1 },
199+
{ :value => '31.415e-1', :expected => 3.1415 },
200+
{ :value => '0.31415e1', :expected => 3.1415 }
201+
].each do |testcase|
202+
describe "parsing a valid data type definition with numeric default #{testcase[:value]}" do
203+
let(:source) { <<-SOURCE
204+
# An example Puppet Data Type in Ruby.
205+
# @param num1 A numeric parameter
206+
Puppet::DataTypes.create_type('RubyDataType') do
207+
interface <<-PUPPET
208+
attributes => {
209+
num1 => { type => Numeric, value => #{testcase[:value]} },
210+
}
211+
PUPPET
212+
end
213+
SOURCE
214+
}
215+
216+
it 'should register a data type object' do
217+
expect(subject.size).to eq(1)
218+
object = subject.first
219+
expect(object).to be_a(PuppetStrings::Yard::CodeObjects::DataType)
220+
expect(object.parameters.size).to eq(1)
221+
expect(object.parameters[0]).to eq(['num1', testcase[:expected]])
222+
end
223+
end
224+
end
225+
226+
describe 'parsing a invalid data type definition' do
227+
let(:source) { <<-SOURCE
228+
# The msg attribute is missing a comma.
229+
#
230+
# @param msg A message parameter5.
231+
# @param arg1 Optional String parameter5. Defaults to 'param'.
232+
Puppet::DataTypes.create_type('RubyDataType') do
233+
interface <<-PUPPET
234+
attributes => {
235+
msg => Variant[Numeric, String[1,2]]
236+
arg1 => { type => Optional[String[1]], value => "param" }
237+
}
238+
PUPPET
239+
end
240+
SOURCE
241+
}
242+
243+
it 'should register a partial data type object' do
244+
expect(subject.size).to eq(1)
245+
object = subject.first
246+
expect(object).to be_a(PuppetStrings::Yard::CodeObjects::DataType)
247+
expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::DataTypes.instance)
248+
expect(object.name).to eq(:RubyDataType)
249+
expect(object.docstring).to eq('The msg attribute is missing a comma.')
250+
# The attributes will be missing therefore only one tag
251+
expect(object.docstring.tags.size).to eq(1)
252+
tags = object.docstring.tags(:api)
253+
expect(tags.size).to eq(1)
254+
expect(tags[0].text).to eq('public')
255+
256+
# Check that the param tags are removed
257+
tags = object.docstring.tags(:param)
258+
expect(tags.size).to eq(0)
259+
260+
# Check for default values
261+
expect(object.parameters.size).to eq(0)
262+
end
263+
264+
it 'should log a warning' do
265+
expect{ subject }.to output(/\[warn\]: Invalid datatype definition at (.+):[0-9]+: Syntax error at 'arg1'/).to_stdout_from_any_process
266+
end
267+
end
268+
192269
describe 'parsing a data type with a summary' do
193270
context 'when the summary has fewer than 140 characters' do
194271
let(:source) { <<-SOURCE

0 commit comments

Comments
 (0)