Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PDOC-285) Fix data_type_handler for errors and numbers #209

Merged
merged 1 commit into from
Aug 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/puppet-strings/yard/handlers/ruby/data_type_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class PuppetStrings::Yard::Handlers::Ruby::DataTypeHandler < PuppetStrings::Yard
return unless ruby_module_name == 'Puppet::DataTypes' || ruby_module_name == 'DataTypes' # rubocop:disable Style/MultipleComparison This reads better
object = get_datatype_yard_object(get_name(statement, 'Puppet::DataTypes.create_type'))

actual_params = extract_params_for_data_type # populate_data_type_data(object)
actual_params = extract_params_for_data_type

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

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

def literal_UnaryMinusExpression(o) # rubocop:disable Naming/UncommunicativeMethodParamName
-1 * literal(o.expr)
end

def literal_LiteralBoolean(o) # rubocop:disable Naming/UncommunicativeMethodParamName
o.value
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,83 @@ def suppress_yard_logging
end
end

testcases = [
{ :value => '-1', :expected => -1 },
{ :value => '0', :expected => 0 },
{ :value => '10', :expected => 10 },
{ :value => '0777', :expected => 511 },
{ :value => '0xFF', :expected => 255 },
{ :value => '0.1', :expected => 0.1 },
{ :value => '31.415e-1', :expected => 3.1415 },
{ :value => '0.31415e1', :expected => 3.1415 }
].each do |testcase|
describe "parsing a valid data type definition with numeric default #{testcase[:value]}" do
let(:source) { <<-SOURCE
# An example Puppet Data Type in Ruby.
# @param num1 A numeric parameter
Puppet::DataTypes.create_type('RubyDataType') do
interface <<-PUPPET
attributes => {
num1 => { type => Numeric, value => #{testcase[:value]} },
}
PUPPET
end
SOURCE
}

it 'should register a data type object' do
expect(subject.size).to eq(1)
object = subject.first
expect(object).to be_a(PuppetStrings::Yard::CodeObjects::DataType)
expect(object.parameters.size).to eq(1)
expect(object.parameters[0]).to eq(['num1', testcase[:expected]])
end
end
end

describe 'parsing a invalid data type definition' do
let(:source) { <<-SOURCE
# The msg attribute is missing a comma.
#
# @param msg A message parameter5.
# @param arg1 Optional String parameter5. Defaults to 'param'.
Puppet::DataTypes.create_type('RubyDataType') do
interface <<-PUPPET
attributes => {
msg => Variant[Numeric, String[1,2]]
arg1 => { type => Optional[String[1]], value => "param" }
}
PUPPET
end
SOURCE
}

it 'should register a partial data type object' do
expect(subject.size).to eq(1)
object = subject.first
expect(object).to be_a(PuppetStrings::Yard::CodeObjects::DataType)
expect(object.namespace).to eq(PuppetStrings::Yard::CodeObjects::DataTypes.instance)
expect(object.name).to eq(:RubyDataType)
expect(object.docstring).to eq('The msg attribute is missing a comma.')
# The attributes will be missing therefore only one tag
expect(object.docstring.tags.size).to eq(1)
tags = object.docstring.tags(:api)
expect(tags.size).to eq(1)
expect(tags[0].text).to eq('public')

# Check that the param tags are removed
tags = object.docstring.tags(:param)
expect(tags.size).to eq(0)

# Check for default values
expect(object.parameters.size).to eq(0)
end

it 'should log a warning' do
expect{ subject }.to output(/\[warn\]: Invalid datatype definition at (.+):[0-9]+: Syntax error at 'arg1'/).to_stdout_from_any_process
end
end

describe 'parsing a data type with a summary' do
context 'when the summary has fewer than 140 characters' do
let(:source) { <<-SOURCE
Expand Down