From 195374d2a70e591a950bf3ea8240c07d6fc49503 Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Tue, 19 Aug 2014 10:44:40 -0700 Subject: [PATCH 1/5] (PDOC-5) Add spec testing for face component Add spec tests for Puppet face component, mainly around error checking. Due to the use of `puppet module list`, the behavior of the `modules` and `server` actions are not very feasible to test via spec testing. Additionally, make a few minor changes to the gem file, and make a small change in `check_required_features` to reflect the fact that this module will no longer support anything earlier than Ruby 1.9. --- Gemfile | 3 +- lib/puppet/face/yardoc.rb | 4 +-- spec/classes/init_spec.rb | 7 ----- spec/spec_helper.rb | 9 +----- spec/unit/face_spec.rb | 63 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 18 deletions(-) delete mode 100644 spec/classes/init_spec.rb create mode 100644 spec/unit/face_spec.rb diff --git a/Gemfile b/Gemfile index ff3e997..f897512 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ source 'https://rubygems.org' gem 'yard' +gem 'puppet', '~> 3.6.2' gem 'rgen' group :test do gem 'rspec' gem 'mocha' - gem 'puppet' gem 'puppetlabs_spec_helper' + gem 'pry' end diff --git a/lib/puppet/face/yardoc.rb b/lib/puppet/face/yardoc.rb index f5809b6..d394335 100644 --- a/lib/puppet/face/yardoc.rb +++ b/lib/puppet/face/yardoc.rb @@ -12,8 +12,8 @@ Puppet::Face.define(:yardoc, '0.0.1') do raise RuntimeError, "The 'rgen' gem must be installed in order to use this face." end - if RUBY_VERSION < '1.9' && !Puppet.features.require_relative? - raise RuntimeError, "The 'backports' gem must be installed in order to use this face under Ruby 1.8.7." + if RUBY_VERSION.match(/^1\.8/) + raise RuntimeError, "This face requires Ruby 1.9 or greater." end end diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb deleted file mode 100644 index 5d4503c..0000000 --- a/spec/classes/init_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'spec_helper' -describe 'puppet_yardoc' do - - context 'with defaults for all parameters' do - it { should contain_class('puppet_yardoc') } - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5fda588..81921a0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,14 +4,7 @@ $LOAD_PATH.unshift File.join(dir, 'lib') require 'mocha' require 'puppet' require 'rspec' -require 'spec/autorun' -Spec::Runner.configure do |config| +RSpec.configure do |config| config.mock_with :mocha end - -# We need this because the RAL uses 'should' as a method. This -# allows us the same behaviour but with a different method name. -class Object - alias :must :should -end diff --git a/spec/unit/face_spec.rb b/spec/unit/face_spec.rb new file mode 100644 index 0000000..b60b6ef --- /dev/null +++ b/spec/unit/face_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper' +require 'puppet/face/yardoc' + +describe Puppet::Face do + + describe "YARDoc action" do + it "should raise an error if yard is absent" do + Puppet.features.stubs(:yard?).returns(false) + expect{Puppet::Face[:yardoc, :current].yardoc}.to raise_error(RuntimeError, "The 'yard' gem must be installed in order to use this face.") + end + + it "should raise an error if rgen is absent" do + Puppet.features.stubs(:rgen?).returns(false) + expect{Puppet::Face[:yardoc, :current].yardoc}.to raise_error(RuntimeError, "The 'rgen' gem must be installed in order to use this face.") + end + + it "should raise an error if the Ruby verion is less than 1.9", :if => RUBY_VERSION.match(/^1\.8/) do + expect{Puppet::Face[:yardoc, :current].yardoc}.to raise_error(RuntimeError, "This face requires Ruby 1.9 or greater.") + end + + it "should invoke Yardoc with MODULE_SOURCEFILES if no arguments are provided" do + YARD::CLI::Yardoc.expects(:run).with('manifests/**/*.pp', 'lib/**/*.rb') + Puppet::Face[:yardoc, :current].yardoc + end + + it "should invoke Yardoc with provided arguments" do + YARD::CLI::Yardoc.expects(:run).with('--debug', 'some_file.rb') + Puppet::Face[:yardoc, :current].yardoc('--debug', 'some_file.rb') + end + end + + describe "modules action" do + it "should raise an error if yard is absent" do + Puppet.features.stubs(:yard?).returns(false) + expect{Puppet::Face[:yardoc, :current].modules}.to raise_error(RuntimeError, "The 'yard' gem must be installed in order to use this face.") + end + + it "should raise an error if rgen is absent" do + Puppet.features.stubs(:rgen?).returns(false) + expect{Puppet::Face[:yardoc, :current].modules}.to raise_error(RuntimeError, "The 'rgen' gem must be installed in order to use this face.") + end + + it "should raise an error if the Ruby version is less than 1.9", :if => RUBY_VERSION.match(/^1\.8/) do + expect{Puppet::Face[:yardoc, :current].modules}.to raise_error(RuntimeError, "This face requires Ruby 1.9 or greater.") + end + end + + describe "server action" do + it "should raise an error if yard is absent" do + Puppet.features.stubs(:yard?).returns(false) + expect{Puppet::Face[:yardoc, :current].server}.to raise_error(RuntimeError, "The 'yard' gem must be installed in order to use this face.") + end + + it "should raise an error if rgen is absent" do + Puppet.features.stubs(:rgen?).returns(false) + expect{Puppet::Face[:yardoc, :current].server}.to raise_error(RuntimeError, "The 'rgen' gem must be installed in order to use this face.") + end + + it "should raise an error if the Ruby version is less than 1.9", :if => RUBY_VERSION.match(/^1\.8/) do + expect{Puppet::Face[:yardoc, :current].server}.to raise_error(RuntimeError, "This face requires Ruby 1.9 or greater.") + end + end +end From 766fd57ebe447b5dd52e62a092ab1d7381ff1f2e Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Thu, 21 Aug 2014 15:38:35 -0700 Subject: [PATCH 2/5] (PDOC-5) Add spec testing for pops component Prior to this commit there was no testing around the pops component. Since most of the API in the pops component is private, there aren't very many things to test, so add just a few test cases. Additionally rename a previous spec file and make some changes to the Gemfile. --- Gemfile | 6 +++- spec/unit/{ => puppet}/face_spec.rb | 0 spec/unit/puppetx/yardoc/pops_spec.rb | 43 +++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) rename spec/unit/{ => puppet}/face_spec.rb (100%) create mode 100644 spec/unit/puppetx/yardoc/pops_spec.rb diff --git a/Gemfile b/Gemfile index f897512..392ea17 100644 --- a/Gemfile +++ b/Gemfile @@ -8,5 +8,9 @@ group :test do gem 'rspec' gem 'mocha' gem 'puppetlabs_spec_helper' - gem 'pry' +end + +group :development do + gem 'pry' + gem 'pry-debugger' end diff --git a/spec/unit/face_spec.rb b/spec/unit/puppet/face_spec.rb similarity index 100% rename from spec/unit/face_spec.rb rename to spec/unit/puppet/face_spec.rb diff --git a/spec/unit/puppetx/yardoc/pops_spec.rb b/spec/unit/puppetx/yardoc/pops_spec.rb new file mode 100644 index 0000000..0407d99 --- /dev/null +++ b/spec/unit/puppetx/yardoc/pops_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' +require 'puppetx/yardoc/pops/yard_statement' + +describe Puppetx::Yardoc::Pops do + let(:parser) {Puppet::Pops::Parser::Parser.new()} + + describe "YARDstatement class" do + let(:manifest) {"#hello world\nclass foo { }"} + let(:model) {parser.parse_string(manifest).current.definitions.first} + let(:test_statement) {Puppetx::Yardoc::Pops::YARDStatement.new(model)} + + describe "when creating a new instance of YARDStatement" do + it "should raise an error if the argument is not a PopsObject" do + test_arg = 'foo bar' + expect{Puppetx::Yardoc::Pops::YARDStatement.new(test_arg)}.to raise_error(ArgumentError) + end + + it "should extract comments from the source code" do + expect(test_statement.comments).to match(/^#hello world/) + end + end + end + + describe "YARDTransfomer class" do + let(:manifest) {"#hello world\nclass foo($bar) { }"} + let(:manifest_default) {"#hello world\nclass foo($bar = 3) { }"} + let(:transformer) {Puppetx::Yardoc::Pops::YARDTransformer.new} + + describe "transform method" do + it "should perform the correct transformation with parameter defaults" do + model = parser.parse_string(manifest_default).current.definitions.first + statements = transformer.transform(model) + expect(statements.parameters[0][0].class).to be(Puppetx::Yardoc::Pops::YARDStatement) + end + + it "should perform the correct transofmration without parameter defaults" do + model = parser.parse_string(manifest).current.definitions.first + statements = transformer.transform(model) + expect(statements.parameters[0][1].class).to be(NilClass) + end + end + end +end From 8549bf7eff555fbe75542af1dff8f2e9dc6bed62 Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Tue, 26 Aug 2014 16:57:55 -0700 Subject: [PATCH 3/5] (PDOC-5) Test defined types and 4x functions Begin to test the YARD handlers written for the puppet language. Add basic tests for the defined type and puppet 4 function handlers. In addition, make changes to the spec helper to make it easier to work with YARD Registries for testing purposes. --- spec/spec_helper.rb | 12 +++++++ .../yardoc/yard/examples/defined_type.pp | 7 ++++ .../yardoc/yard/examples/puppet4_function.rb | 7 ++++ .../unit/puppetx/yardoc/yard/handlers_spec.rb | 33 +++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 spec/unit/puppetx/yardoc/yard/examples/defined_type.pp create mode 100644 spec/unit/puppetx/yardoc/yard/examples/puppet4_function.rb create mode 100644 spec/unit/puppetx/yardoc/yard/handlers_spec.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 81921a0..002b026 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -5,6 +5,18 @@ require 'mocha' require 'puppet' require 'rspec' +# This is neeeded so we can access a Registry if YARD creates one +require 'puppetx/yardoc/yard/plugin' +include YARD + RSpec.configure do |config| config.mock_with :mocha end + +# Borrwed from YARD spec helper +def parse_file(file, thisfile = __FILE__, log_level = log.level, ext = '.pp') + Registry.clear + path = File.join(File.dirname(thisfile), 'examples', file.to_s + ext) + YARD::Parser::SourceParser.parse(path, [], log_level) +end + diff --git a/spec/unit/puppetx/yardoc/yard/examples/defined_type.pp b/spec/unit/puppetx/yardoc/yard/examples/defined_type.pp new file mode 100644 index 0000000..6021a41 --- /dev/null +++ b/spec/unit/puppetx/yardoc/yard/examples/defined_type.pp @@ -0,0 +1,7 @@ +define wibbly::wobbly ($wimey) { + Notify ($wimey) +} + +wibbly::wobbly{ + 'timey': wimey => stuff + } diff --git a/spec/unit/puppetx/yardoc/yard/examples/puppet4_function.rb b/spec/unit/puppetx/yardoc/yard/examples/puppet4_function.rb new file mode 100644 index 0000000..fc65f89 --- /dev/null +++ b/spec/unit/puppetx/yardoc/yard/examples/puppet4_function.rb @@ -0,0 +1,7 @@ +require 'puppet' + +Puppet::Functions.create_function(:puppet4_function) do + def puppet4_function(x,y) + x >= y ? x : y + end +end diff --git a/spec/unit/puppetx/yardoc/yard/handlers_spec.rb b/spec/unit/puppetx/yardoc/yard/handlers_spec.rb new file mode 100644 index 0000000..e554347 --- /dev/null +++ b/spec/unit/puppetx/yardoc/yard/handlers_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'puppetx/yardoc/yard/handlers' + +describe Puppetx::Yardoc::YARD::Handlers do + describe "DefinedTypeHanlder" do + it "should add a defined type object in the Registry" do + parse_file :defined_type, __FILE__ + require 'pry' + #binding.pry + obj = Registry.at("wibbly::wobbly") + expect(obj.type).to be(:definedtype) + end + end + + describe "FutureParserDispatchHandler" do + before(:each) {parse_file :puppet4_function, __FILE__, log.level, '.rb'} + + it "should add a puppet namespace object to the Registry" do + namespace = Registry.at("FutureParserFunctions") + expect(namespace.type).to be(:puppetnamespace) + end + + it "should add a future parser function object to the Registry" do + function = Registry.at("FutureParserFunctions#puppet4_function") + expect(function.type).to be(:method) + end + + it "should add a method object to the Registry" do + method = Registry.at("#puppet4_function") + expect(method.type).to be(:method) + end + end +end From b2267fcfc6da9c494803764578bbd04a648724cf Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Tue, 2 Sep 2014 13:50:34 -0700 Subject: [PATCH 4/5] (PDOC-5) Test host classes and 3x functions Add tests for the remaining two Puppet-specific handlers that were not tested in the previous commit. Specifically, add tests for the 3.x function handler and the host class handler. --- spec/spec_helper.rb | 2 +- spec/unit/puppet/examples/test/Modulefile | 10 ++++++ .../puppet/examples/test/manifests/init.pp | 12 +++++++ .../puppetx/yardoc/yard/examples/class.pp | 5 +++ .../yardoc/yard/examples/puppet3_function.rb | 7 +++++ .../unit/puppetx/yardoc/yard/handlers_spec.rb | 31 +++++++++++++++++-- 6 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 spec/unit/puppet/examples/test/Modulefile create mode 100644 spec/unit/puppet/examples/test/manifests/init.pp create mode 100644 spec/unit/puppetx/yardoc/yard/examples/class.pp create mode 100644 spec/unit/puppetx/yardoc/yard/examples/puppet3_function.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 002b026..311484f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,7 +13,7 @@ RSpec.configure do |config| config.mock_with :mocha end -# Borrwed from YARD spec helper +# Borrowed from YARD spec helper def parse_file(file, thisfile = __FILE__, log_level = log.level, ext = '.pp') Registry.clear path = File.join(File.dirname(thisfile), 'examples', file.to_s + ext) diff --git a/spec/unit/puppet/examples/test/Modulefile b/spec/unit/puppet/examples/test/Modulefile new file mode 100644 index 0000000..5f73a2f --- /dev/null +++ b/spec/unit/puppet/examples/test/Modulefile @@ -0,0 +1,10 @@ +name 'username-test' +version '0.1.0' +source '' +author 'username' +license 'Apache 2.0' +summary '' +description '' +project_page '' + +dependency 'puppetlabs/stdlib' diff --git a/spec/unit/puppet/examples/test/manifests/init.pp b/spec/unit/puppet/examples/test/manifests/init.pp new file mode 100644 index 0000000..487cf30 --- /dev/null +++ b/spec/unit/puppet/examples/test/manifests/init.pp @@ -0,0 +1,12 @@ +class test ( + $package_name = $test::params::package_name, + $service_name = $test::params::service_name, +) inherits test::params { + + # validate parameters here + + class { 'test::install': } -> + class { 'test::config': } ~> + class { 'test::service': } -> + Class['test'] +} diff --git a/spec/unit/puppetx/yardoc/yard/examples/class.pp b/spec/unit/puppetx/yardoc/yard/examples/class.pp new file mode 100644 index 0000000..512b39f --- /dev/null +++ b/spec/unit/puppetx/yardoc/yard/examples/class.pp @@ -0,0 +1,5 @@ +class foo::bar { + file { '/test/file/path': + owner => 'baz', + } +} diff --git a/spec/unit/puppetx/yardoc/yard/examples/puppet3_function.rb b/spec/unit/puppetx/yardoc/yard/examples/puppet3_function.rb new file mode 100644 index 0000000..a9e352f --- /dev/null +++ b/spec/unit/puppetx/yardoc/yard/examples/puppet3_function.rb @@ -0,0 +1,7 @@ +require 'puppet' + +module Puppet::Parser::Functions + newfunction(:puppet3_function, :type => rvalue) do |args| + puts 'Hello World!' + end +end diff --git a/spec/unit/puppetx/yardoc/yard/handlers_spec.rb b/spec/unit/puppetx/yardoc/yard/handlers_spec.rb index e554347..adbbeb6 100644 --- a/spec/unit/puppetx/yardoc/yard/handlers_spec.rb +++ b/spec/unit/puppetx/yardoc/yard/handlers_spec.rb @@ -4,9 +4,7 @@ require 'puppetx/yardoc/yard/handlers' describe Puppetx::Yardoc::YARD::Handlers do describe "DefinedTypeHanlder" do it "should add a defined type object in the Registry" do - parse_file :defined_type, __FILE__ - require 'pry' - #binding.pry + parse_file :defined_type, __FILE__, log.level, '.pp' obj = Registry.at("wibbly::wobbly") expect(obj.type).to be(:definedtype) end @@ -30,4 +28,31 @@ describe Puppetx::Yardoc::YARD::Handlers do expect(method.type).to be(:method) end end + + describe "ParserFunctionHanlder" do + before(:each) {parse_file :puppet3_function, __FILE__, log.level, '.rb'} + + it "should add a module object to the Registry" do + puppet_module = Registry.at("Puppet::Parser::Functions") + expect(puppet_module.type).to be(:module) + end + + it "should add a puppet namespace object to the Registry" do + namespace = Registry.at("ParserFunctions") + expect(namespace.type).to be(:puppetnamespace) + end + + it "should add a method object to the Registry" do + method = Registry.at("ParserFunctions#puppet3_function") + expect(method.type).to be(:method) + end + end + + describe "HostClassDefintion" do + before(:each) {parse_file :class, __FILE__, log.level, '.pp'} + it "should add a host class object to the Registry" do + hostclass = Registry.at("foo::bar") + expect(hostclass.type).to be(:hostclass) + end + end end From 645f35ccfe3a85dda7c314c15411bfb0e2445163 Mon Sep 17 00:00:00 2001 From: Hailee Kenney Date: Wed, 3 Sep 2014 15:37:15 -0700 Subject: [PATCH 5/5] (PDOC-5) Remove unneeded test case Remove an unneeded test case. Since it would be caught even in a very basic system, an automated test case is not needed. --- spec/unit/puppetx/yardoc/pops_spec.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/spec/unit/puppetx/yardoc/pops_spec.rb b/spec/unit/puppetx/yardoc/pops_spec.rb index 0407d99..7b14ee9 100644 --- a/spec/unit/puppetx/yardoc/pops_spec.rb +++ b/spec/unit/puppetx/yardoc/pops_spec.rb @@ -10,11 +10,6 @@ describe Puppetx::Yardoc::Pops do let(:test_statement) {Puppetx::Yardoc::Pops::YARDStatement.new(model)} describe "when creating a new instance of YARDStatement" do - it "should raise an error if the argument is not a PopsObject" do - test_arg = 'foo bar' - expect{Puppetx::Yardoc::Pops::YARDStatement.new(test_arg)}.to raise_error(ArgumentError) - end - it "should extract comments from the source code" do expect(test_statement.comments).to match(/^#hello world/) end