spec/integration/util/rdoc/parser_spec.rb in puppet-3.3.2 vs spec/integration/util/rdoc/parser_spec.rb in puppet-3.4.0.rc1
- old
+ new
@@ -1,60 +1,261 @@
#! /usr/bin/env ruby
require 'spec_helper'
+require 'puppet/util/rdoc'
-describe "RDoc::Parser", :if => Puppet.features.rdoc1? do
+describe "RDoc::Parser" do
require 'puppet_spec/files'
include PuppetSpec::Files
- before :all do
- require 'puppet/resource/type_collection'
- require 'puppet/util/rdoc/parser'
- require 'puppet/util/rdoc'
- require 'puppet/util/rdoc/code_objects'
- require 'rdoc/options'
- require 'rdoc/rdoc'
+ let(:document_all) { false }
+ let(:tmp_dir) { tmpdir('rdoc_parser_tmp') }
+ let(:doc_dir) { File.join(tmp_dir, 'doc') }
+ let(:manifests_dir) { File.join(tmp_dir, 'manifests') }
+ let(:modules_dir) { File.join(tmp_dir, 'modules') }
+
+ let(:modules_and_manifests) do
+ {
+ :site => [
+ File.join(manifests_dir, 'site.pp'),
+ <<-EOF
+# The test class comment
+class test {
+ # The virtual resource comment
+ @notify { virtual: }
+ # The a_notify_resource comment
+ notify { a_notify_resource:
+ message => "a_notify_resource message"
+ }
+}
+
+# The includes_another class comment
+class includes_another {
+ include another
+}
+
+# The requires_another class comment
+class requires_another {
+ require another
+}
+
+# node comment
+node foo {
+ include test
+ $a_var = "var_value"
+ realize Notify[virtual]
+ notify { bar: }
+}
+ EOF
+ ],
+ :module_readme => [
+ File.join(modules_dir, 'a_module', 'README'),
+ <<-EOF
+The a_module README docs.
+ EOF
+ ],
+ :module_init => [
+ File.join(modules_dir, 'a_module', 'manifests', 'init.pp'),
+ <<-EOF
+# The a_module class comment
+class a_module {}
+
+class another {}
+ EOF
+ ],
+ :module_type => [
+ File.join(modules_dir, 'a_module', 'manifests', 'a_type.pp'),
+ <<-EOF
+# The a_type type comment
+define a_module::a_type() {}
+ EOF
+ ],
+ :module_plugin => [
+ File.join(modules_dir, 'a_module', 'lib', 'puppet', 'type', 'a_plugin.rb'),
+ <<-EOF
+# The a_plugin type comment
+Puppet::Type.newtype(:a_plugin) do
+ @doc = "Not presented"
+end
+ EOF
+ ],
+ :module_function => [
+ File.join(modules_dir, 'a_module', 'lib', 'puppet', 'parser', 'a_function.rb'),
+ <<-EOF
+# The a_function function comment
+module Puppet::Parser::Functions
+ newfunction(:a_function, :type => :rvalue) do
+ return
end
+end
+ EOF
+ ],
+ :module_fact => [
+ File.join(modules_dir, 'a_module', 'lib', 'facter', 'a_fact.rb'),
+ <<-EOF
+# The a_fact fact comment
+Facter.add("a_fact") do
+end
+ EOF
+ ],
+ }
+ end
- before :each do
- tmpdir = tmpfile('rdoc_parser_tmp')
- Dir.mkdir(tmpdir)
- @parsedfile = File.join(tmpdir, 'init.pp')
+ def write_file(file, content)
+ FileUtils.mkdir_p(File.dirname(file))
+ File.open(file, 'w') do |f|
+ f.puts(content)
+ end
+ end
- File.open(@parsedfile, 'w') do |f|
- f.puts '# comment'
- f.puts 'class ::test {}'
+ def prepare_manifests_and_modules
+ modules_and_manifests.each do |key,array|
+ write_file(*array)
end
+ end
- @top_level = stub_everything 'toplevel', :file_relative_name => @parsedfile
- @module = stub_everything 'module'
- @puppet_top_level = RDoc::PuppetTopLevel.new(@top_level)
- RDoc::PuppetTopLevel.stubs(:new).returns(@puppet_top_level)
- @puppet_top_level.expects(:add_module).returns(@module)
- @parser = RDoc::Parser.new(@top_level, @parsedfile, nil, Options.instance, RDoc::Stats.new)
+ def file_exists_and_matches_content(file, *content_patterns)
+ Puppet::FileSystem::File.exist?(file).should(be_true, "Cannot find #{file}")
+ content_patterns.each do |pattern|
+ content = File.read(file)
+ content.should match(pattern)
+ end
end
- after(:each) do
- File.unlink(@parsedfile)
+ def some_file_exists_with_matching_content(glob, *content_patterns)
+ Dir.glob(glob).select do |f|
+ contents = File.read(f)
+ content_patterns.all? { |p| p.match(contents) }
+ end.should_not(be_empty, "Could not match #{content_patterns} in any of the files found in #{glob}")
end
- def get_test_class(toplevel)
- # toplevel -> main -> test
- toplevel.classes[0].classes[0]
+ before :each do
+ prepare_manifests_and_modules
+ Puppet.settings[:document_all] = document_all
+ Puppet.settings[:modulepath] = modules_dir
+ Puppet::Util::RDoc.rdoc(doc_dir, [modules_dir, manifests_dir])
end
- it "should parse to RDoc data structure" do
- @parser.expects(:document_class).with { |n,k,c| n == "::test" and k.is_a?(Puppet::Resource::Type) }
- @parser.scan
+ module RdocTesters
+ def has_module_rdoc(module_name, *other_test_patterns)
+ file_exists_and_matches_content(module_path(module_name), /Module:? +#{module_name}/i, *other_test_patterns)
+ end
+
+ def has_node_rdoc(module_name, node_name, *other_test_patterns)
+ file_exists_and_matches_content(node_path(module_name, node_name), /#{node_name}/, /node comment/, *other_test_patterns)
+ end
+
+ def has_defined_type(module_name, type_name)
+ file_exists_and_matches_content(module_path(module_name), /#{type_name}.*?\(\s*\)/m, "The .*?#{type_name}.*? type comment")
+ end
+
+ def has_class_rdoc(module_name, class_name, *other_test_patterns)
+ file_exists_and_matches_content(class_path(module_name, class_name), /#{class_name}.*? class comment/, *other_test_patterns)
+ end
+
+ def has_plugin_rdoc(module_name, type, name)
+ file_exists_and_matches_content(plugin_path(module_name, type, name), /The .*?#{name}.*?\s*#{type} comment/m, /Type.*?#{type}/m)
+ end
end
- it "should get a PuppetClass for the main class" do
- @parser.scan.classes[0].should be_a(RDoc::PuppetClass)
+ shared_examples_for :an_rdoc_site do
+ it "documents the __site__ module" do
+ has_module_rdoc("__site__")
+ end
+
+ it "documents the __site__::test class" do
+ has_class_rdoc("__site__", "test")
+ end
+
+ it "documents the __site__::foo node" do
+ has_node_rdoc("__site__", "foo")
+ end
+
+ it "documents the a_module module" do
+ has_module_rdoc("a_module", /The .*?a_module.*? .*?README.*?docs/m)
+ end
+
+ it "documents the a_module::a_module class" do
+ has_class_rdoc("a_module", "a_module")
+ end
+
+ it "documents the a_module::a_type defined type" do
+ has_defined_type("a_module", "a_type")
+ end
+
+ it "documents the a_module::a_plugin type" do
+ has_plugin_rdoc("a_module", :type, 'a_plugin')
+ end
+
+ it "documents the a_module::a_function function" do
+ has_plugin_rdoc("a_module", :function, 'a_function')
+ end
+
+ it "documents the a_module::a_fact fact" do
+ has_plugin_rdoc("a_module", :fact, 'a_fact')
+ end
+
+ it "documents included classes" do
+ has_class_rdoc("__site__", "includes_another", /Included.*?another/m)
+ end
end
- it "should produce a PuppetClass whose name is test" do
- get_test_class(@parser.scan).name.should == "test"
+ shared_examples_for :an_rdoc1_site do
+ it "documents required classes" do
+ has_class_rdoc("__site__", "requires_another", /Required Classes.*?another/m)
+ end
+
+ it "documents realized resources" do
+ has_node_rdoc("__site__", "foo", /Realized Resources.*?Notify\[virtual\]/m)
+ end
+
+ it "documents global variables" do
+ has_node_rdoc("__site__", "foo", /Global Variables.*?a_var.*?=.*?var_value/m)
+ end
+
+ describe "when document_all is true" do
+ let(:document_all) { true }
+
+ it "documents virtual resource declarations" do
+ has_class_rdoc("__site__", "test", /Resources.*?Notify\[virtual\]/m, /The virtual resource comment/)
+ end
+
+ it "documents resources" do
+ has_class_rdoc("__site__", "test", /Resources.*?Notify\[a_notify_resource\]/m, /message => "a_notify_resource message"/, /The a_notify_resource comment/)
+ end
+ end
end
- it "should produce a PuppetClass whose comment is 'comment'" do
- get_test_class(@parser.scan).comment.should == "comment\n"
+ describe "rdoc1 support", :if => Puppet.features.rdoc1? do
+ def module_path(module_name); "#{doc_dir}/classes/#{module_name}.html" end
+ def node_path(module_name, node_name); "#{doc_dir}/nodes/**/*.html" end
+ def class_path(module_name, class_name); "#{doc_dir}/classes/#{module_name}/#{class_name}.html" end
+ def plugin_path(module_name, type, name); "#{doc_dir}/plugins/#{name}.html" end
+
+ include RdocTesters
+
+ def has_node_rdoc(module_name, node_name, *other_test_patterns)
+ some_file_exists_with_matching_content(node_path(module_name, node_name), /#{node_name}/, /node comment/, *other_test_patterns)
+ end
+
+ it_behaves_like :an_rdoc_site
+ it_behaves_like :an_rdoc1_site
+
+ it "references nodes and classes in the __site__ module" do
+ file_exists_and_matches_content("#{doc_dir}/classes/__site__.html", /Node.*__site__::foo/, /Class.*__site__::test/)
+ end
+
+ it "references functions, facts, and type plugins in the a_module module" do
+ file_exists_and_matches_content("#{doc_dir}/classes/a_module.html", /a_function/, /a_fact/, /a_plugin/, /Class.*a_module::a_module/)
+ end
+ end
+
+ describe "rdoc2 support", :if => !Puppet.features.rdoc1? do
+ def module_path(module_name); "#{doc_dir}/#{module_name}.html" end
+ def node_path(module_name, node_name); "#{doc_dir}/#{module_name}/__nodes__/#{node_name}.html" end
+ def class_path(module_name, class_name); "#{doc_dir}/#{module_name}/#{class_name}.html" end
+ def plugin_path(module_name, type, name); "#{doc_dir}/#{module_name}/__#{type}s__.html" end
+
+ include RdocTesters
+
+ it_behaves_like :an_rdoc_site
end
end