From 580dd4c10599dc6cd92c8c0e9b6166d2e11c1bac Mon Sep 17 00:00:00 2001 From: Tim Sharpe Date: Tue, 11 Jul 2017 15:41:17 +1000 Subject: [PATCH] (maint) Add unit tests for PDK::Validate::PuppetSyntax --- lib/pdk/validators/puppet/puppet_syntax.rb | 10 +-- spec/pdk/validate/puppet_syntax_spec.rb | 94 ++++++++++++++++++++++ spec/support/it_accepts_pp_targets.rb | 72 +++++++++++++++++ 3 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 spec/pdk/validate/puppet_syntax_spec.rb create mode 100644 spec/support/it_accepts_pp_targets.rb diff --git a/lib/pdk/validators/puppet/puppet_syntax.rb b/lib/pdk/validators/puppet/puppet_syntax.rb index c6853ad69..72025c1e7 100644 --- a/lib/pdk/validators/puppet/puppet_syntax.rb +++ b/lib/pdk/validators/puppet/puppet_syntax.rb @@ -44,7 +44,7 @@ def self.parse_output(report, result, targets) attributes = { source: name, message: message.strip, - state: 'failure', + state: :failure, } attributes[:severity] = severity.strip unless severity.nil? @@ -57,14 +57,14 @@ def self.parse_output(report, result, targets) results_data << attributes end - # puppet-lint does not include files without problems in its JSON + # puppet parser validate does not include files without problems in its # output, so we need to go through the list of targets and add passing - # events to the report for any target not listed in the JSON output. + # events to the report for any target not listed in the output. targets.reject { |target| results_data.any? { |j| j[:file] == target } }.each do |target| report.add_event( file: target, - source: 'puppet-syntax', - severity: 'ok', + source: name, + severity: :ok, state: :passed, ) end diff --git a/spec/pdk/validate/puppet_syntax_spec.rb b/spec/pdk/validate/puppet_syntax_spec.rb new file mode 100644 index 000000000..ef622ca28 --- /dev/null +++ b/spec/pdk/validate/puppet_syntax_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' + +describe PDK::Validate::PuppetSyntax do + let(:module_root) { File.join('path', 'to', 'test', 'module') } + + before(:each) do + allow(PDK::Util).to receive(:module_root).and_return(module_root) + allow(File).to receive(:directory?).with(module_root).and_return(true) + end + + it 'defines the base validator attributes' do + expect(described_class).to have_attributes( + name: 'puppet-syntax', + cmd: 'puppet', + spinner_text: a_string_matching(%r{puppet manifest syntax}i), + ) + end + + it_behaves_like 'it accepts .pp targets' + + describe '.parse_options' do + subject(:command_args) { described_class.parse_options(options, targets) } + + let(:options) { {} } + let(:targets) { %w[target1 target2.pp] } + + it 'invokes `puppet parser validate`' do + expect(command_args.first(2)).to eq(%w[parser validate]) + end + + it 'appends the targets to the command arguments' do + expect(command_args.last(targets.count)).to eq(targets) + end + + context 'when auto-correct is enabled' do + let(:options) { { auto_correct: true } } + + it 'has no effect' do + expect(command_args).to eq(%w[parser validate].concat(targets)) + end + end + end + + describe '.parse_output' do + subject(:parse_output) do + described_class.parse_output(report, { stderr: validate_output }, targets) + end + + let(:report) { PDK::Report.new } + let(:validate_output) do + [ + mock_validate('fail.pp', 1, 2, 'test message', 'error'), + ].join('') + end + let(:targets) { ['pass.pp', 'fail.pp'] } + + def mock_validate(file, line, column, message, severity) + "#{severity}: #{message} at #{file}:#{line}:#{column}\n" + end + + before(:each) do + allow(report).to receive(:add_event) + end + + context 'when the output contains no references to a target' do + it 'adds a passing event for the target to the report' do + expect(report).to receive(:add_event).with( + file: 'pass.pp', + source: described_class.name, + state: :passed, + severity: :ok, + ) + + parse_output + end + end + + context 'when the output contains a reference to a target' do + it 'adds a failure event for the referenced target to the report' do + expect(report).to receive(:add_event).with( + file: 'fail.pp', + source: described_class.name, + state: :failure, + message: 'test message', + severity: 'error', + line: '1', + column: '2', + ) + + parse_output + end + end + end +end diff --git a/spec/support/it_accepts_pp_targets.rb b/spec/support/it_accepts_pp_targets.rb new file mode 100644 index 000000000..8bf1df547 --- /dev/null +++ b/spec/support/it_accepts_pp_targets.rb @@ -0,0 +1,72 @@ +RSpec.shared_examples_for 'it accepts .pp targets' do + describe '.parse_targets' do + subject(:parsed_targets) { described_class.parse_targets(targets: targets) } + + let(:globbed_files) { [] } + let(:glob_pattern) { File.join(module_root, described_class.pattern) } + + before(:each) do + allow(Dir).to receive(:glob).with(glob_pattern).and_return(globbed_files) + end + + context 'when given no targets' do + let(:targets) { [] } + + context 'and the module contains .pp files' do + let(:globbed_files) do + [ + File.join(module_root, 'manifests', 'init.pp'), + File.join(module_root, 'manifests', 'params.pp'), + ] + end + + it 'returns the paths to all the .pp files in the module' do + expect(parsed_targets).to eq(globbed_files) + end + end + + context 'and the module contains no .pp files' do + it 'returns no targets' do + expect(parsed_targets).to eq([]) + end + end + end + + context 'when given specific target files' do + let(:targets) { ['manifest.pp', 'another.pp'] } + + before(:each) do + targets.each do |target| + allow(File).to receive(:directory?).with(target).and_return(false) + end + end + + it 'returns the targets' do + expect(parsed_targets).to eq(targets) + end + end + + context 'when given a specific target directory' do + let(:targets) { [File.join('path', 'to', 'target', 'directory')] } + let(:glob_pattern) { File.join(targets.first, described_class.pattern) } + + before(:each) do + allow(File).to receive(:directory?).with(targets.first).and_return(true) + end + + context 'and the directory contains .pp files' do + let(:globbed_files) { [File.join(targets.first, 'test.pp')] } + + it 'returns the paths to the .pp files in the directory' do + expect(parsed_targets).to eq(globbed_files) + end + end + + context 'and the directory contains no .pp files' do + it 'returns no targets' do + expect(parsed_targets).to eq([]) + end + end + end + end +end