From b644ba127b1d3326b5fa1e5091454a1d4e0fa41c Mon Sep 17 00:00:00 2001 From: David Crosby Date: Mon, 12 Jan 2026 18:54:21 -0800 Subject: [PATCH] Add initial tests to reports (#10) Summary: Pull Request resolved: https://github.com/facebook/bookworm/pull/10 These are happy-path tests for the open-source Bookworm reports. I'm doing the CookbookDepShaker in a separate diff so that I can refactor it a bit. Also renamed helper.rb to spec_helper.rb to make the linter happy. Differential Revision: D90255959 --- spec/reports/AllJsonRecipes_spec.rb | 59 ++++++++++++ spec/reports/AllReferencedRecipes_spec.rb | 70 +++++++++++++++ spec/reports/AllRoleDescriptions_spec.rb | 49 ++++++++++ spec/reports/CookbookDependencyDot_spec.rb | 59 ++++++++++++ .../CookbookNameAndMaintainerEmail_spec.rb | 67 ++++++++++++++ spec/reports/DynamicRecipeInclusion_spec.rb | 66 ++++++++++++++ spec/reports/LeafCookbooks_spec.rb | 78 ++++++++++++++++ ...aryDefinedModulesAndClassConstants_spec.rb | 51 +++++++++++ spec/reports/MissingReferencedRecipes_spec.rb | 78 ++++++++++++++++ spec/reports/NoParsedRuby_spec.rb | 87 ++++++++++++++++++ spec/reports/NotReferencedRecipes_spec.rb | 77 ++++++++++++++++ spec/reports/RecipeOnlyCookbooks_spec.rb | 89 +++++++++++++++++++ .../reports/RecipesAssigningConstants_spec.rb | 52 +++++++++++ spec/reports/ResourceNotifications_spec.rb | 70 +++++++++++++++ spec/reports/RoleRecipeEntrypoints_spec.rb | 62 +++++++++++++ spec/reports/RoleReferencedRoles_spec.rb | 62 +++++++++++++ spec/reports/spec_helper.rb | 66 ++++++++++++++ spec/rules/CookbookPropertyLiterals_spec.rb | 2 +- spec/rules/ExplicitMetadataDepends_spec.rb | 2 +- spec/rules/IncludeRecipeDynamic_spec.rb | 2 +- spec/rules/IncludeRecipeLiterals_spec.rb | 2 +- .../LibraryDefinedClassConstants_spec.rb | 2 +- .../LibraryDefinedModuleConstants_spec.rb | 2 +- .../rules/MetadatarbAttributeLiterals_spec.rb | 2 +- spec/rules/NoParsedRuby_spec.rb | 2 +- spec/rules/RecipeConstantAssignments_spec.rb | 2 +- spec/rules/ResourceNotifications_spec.rb | 2 +- spec/rules/RoleDescription_spec.rb | 2 +- spec/rules/RoleExplicitRoles_spec.rb | 2 +- spec/rules/RoleName_spec.rb | 2 +- spec/rules/RoleRunListRecipes_spec.rb | 2 +- spec/rules/RoleRunList_spec.rb | 2 +- spec/rules/{helper.rb => spec_helper.rb} | 11 ++- 33 files changed, 1164 insertions(+), 19 deletions(-) create mode 100644 spec/reports/AllJsonRecipes_spec.rb create mode 100644 spec/reports/AllReferencedRecipes_spec.rb create mode 100644 spec/reports/AllRoleDescriptions_spec.rb create mode 100644 spec/reports/CookbookDependencyDot_spec.rb create mode 100644 spec/reports/CookbookNameAndMaintainerEmail_spec.rb create mode 100644 spec/reports/DynamicRecipeInclusion_spec.rb create mode 100644 spec/reports/LeafCookbooks_spec.rb create mode 100644 spec/reports/LibraryDefinedModulesAndClassConstants_spec.rb create mode 100644 spec/reports/MissingReferencedRecipes_spec.rb create mode 100644 spec/reports/NoParsedRuby_spec.rb create mode 100644 spec/reports/NotReferencedRecipes_spec.rb create mode 100644 spec/reports/RecipeOnlyCookbooks_spec.rb create mode 100644 spec/reports/RecipesAssigningConstants_spec.rb create mode 100644 spec/reports/ResourceNotifications_spec.rb create mode 100644 spec/reports/RoleRecipeEntrypoints_spec.rb create mode 100644 spec/reports/RoleReferencedRoles_spec.rb create mode 100644 spec/reports/spec_helper.rb rename spec/rules/{helper.rb => spec_helper.rb} (72%) diff --git a/spec/reports/AllJsonRecipes_spec.rb b/spec/reports/AllJsonRecipes_spec.rb new file mode 100644 index 0000000..68c4b27 --- /dev/null +++ b/spec/reports/AllJsonRecipes_spec.rb @@ -0,0 +1,59 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::AllJsonRecipes do + let(:mock_kb) { MockKnowledgeBase.new(:recipejsons => recipejsons) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no JSON recipes' do + let(:recipejsons) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with JSON recipes' do + let(:recipejsons) do + { + 'fb_helpers::default' => { 'path' => '/path/to/default.json' }, + 'fb_init::default' => { 'path' => '/path/to/init.json' }, + 'fb_aaa::setup' => { 'path' => '/path/to/aaa.json' }, + } + end + + it 'returns sorted recipe names' do + expect(report.to_a).to eq([ + 'fb_aaa::setup', + 'fb_helpers::default', + 'fb_init::default', + ]) + end + + it 'output returns sorted recipe names' do + expect(report.output).to eq([ + 'fb_aaa::setup', + 'fb_helpers::default', + 'fb_init::default', + ]) + end + end +end diff --git a/spec/reports/AllReferencedRecipes_spec.rb b/spec/reports/AllReferencedRecipes_spec.rb new file mode 100644 index 0000000..45ac471 --- /dev/null +++ b/spec/reports/AllReferencedRecipes_spec.rb @@ -0,0 +1,70 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::AllReferencedRecipes do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles, :recipes => recipes) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no roles or recipes' do + let(:roles) { {} } + let(:recipes) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with roles and recipes referencing recipes' do + let(:roles) do + { + 'base_role' => { + 'RoleRunListRecipes' => ['fb_init::default', 'fb_helpers::default'], + }, + } + end + let(:recipes) do + { + 'fb_init::default' => { + 'IncludeRecipeLiterals' => ['fb_sysctl::default', 'fb_helpers::default'], + }, + 'fb_helpers::default' => { + 'IncludeRecipeLiterals' => [], + }, + } + end + + it 'returns sorted unique recipes from roles and recipes' do + expect(report.to_a).to eq([ + 'fb_helpers::default', + 'fb_init::default', + 'fb_sysctl::default', + ]) + end + + it 'output returns sorted unique recipes' do + expect(report.output).to eq([ + 'fb_helpers::default', + 'fb_init::default', + 'fb_sysctl::default', + ]) + end + end +end diff --git a/spec/reports/AllRoleDescriptions_spec.rb b/spec/reports/AllRoleDescriptions_spec.rb new file mode 100644 index 0000000..bd24281 --- /dev/null +++ b/spec/reports/AllRoleDescriptions_spec.rb @@ -0,0 +1,49 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::AllRoleDescriptions do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no roles' do + let(:roles) { {} } + + it 'returns empty string' do + expect(report.to_plain).to eq('') + end + end + + describe 'with roles having descriptions' do + let(:roles) do + { + 'web_role' => { + 'RoleDescription' => 'Web server configuration', + }, + 'base_role' => { + 'RoleDescription' => 'Base system settings', + }, + } + end + + it 'returns sorted roles with descriptions' do + output = report.to_plain + expect(output).to include('role: base_role desc: Base system settings') + expect(output).to include('role: web_role desc: Web server configuration') + expect(output.index('base_role')).to be < output.index('web_role') + end + end +end diff --git a/spec/reports/CookbookDependencyDot_spec.rb b/spec/reports/CookbookDependencyDot_spec.rb new file mode 100644 index 0000000..5a0bbfe --- /dev/null +++ b/spec/reports/CookbookDependencyDot_spec.rb @@ -0,0 +1,59 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::CookbookDependencyDot do + let(:mock_kb) { MockKnowledgeBase.new(:metadatarbs => metadatarbs) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no metadata.rb files' do + let(:metadatarbs) { {} } + + it 'returns empty digraph' do + expect(report.to_s).to eq("digraph deps {\n\n}") + end + + it 'output returns empty digraph' do + expect(report.output).to eq("digraph deps {\n\n}") + end + end + + describe 'with metadata.rb files having dependencies' do + let(:metadatarbs) do + { + 'fb_helpers::metadata.rb' => { + 'ExplicitMetadataDepends' => ['fb_init'], + }, + 'fb_apache::metadata.rb' => { + 'ExplicitMetadataDepends' => ['fb_helpers', 'fb_sysctl'], + }, + } + end + + it 'returns DOT format with dependencies' do + output = report.to_s + expect(output).to start_with('digraph deps {') + expect(output).to end_with('}') + expect(output).to include('fb_helpers->fb_init') + expect(output).to include('fb_apache->fb_helpers') + expect(output).to include('fb_apache->fb_sysctl') + end + + it 'output returns DOT format' do + expect(report.output).to eq(report.to_s) + end + end +end diff --git a/spec/reports/CookbookNameAndMaintainerEmail_spec.rb b/spec/reports/CookbookNameAndMaintainerEmail_spec.rb new file mode 100644 index 0000000..0c1823b --- /dev/null +++ b/spec/reports/CookbookNameAndMaintainerEmail_spec.rb @@ -0,0 +1,67 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::CookbookNameAndMaintainerEmail do + let(:mock_kb) { MockKnowledgeBase.new(:metadatarbs => metadatarbs) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no metadata.rb files' do + let(:metadatarbs) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with metadata.rb files having name and maintainer_email' do + let(:metadatarbs) do + { + 'fb_helpers::metadata.rb' => { + 'MetadatarbAttributeLiterals' => { + :name => 'fb_helpers', + :maintainer_email => 'team@example.com', + }, + }, + 'fb_apache::metadata.rb' => { + 'MetadatarbAttributeLiterals' => { + :name => 'fb_apache', + :maintainer_email => 'webteam@example.com', + }, + }, + } + end + + it 'returns sorted CSV format' do + result = report.to_a + expect(result).to eq([ + 'fb_apache,webteam@example.com', + 'fb_helpers,team@example.com', + ]) + end + + it 'output returns sorted CSV format' do + expect(report.output).to eq([ + 'fb_apache,webteam@example.com', + 'fb_helpers,team@example.com', + ]) + end + end +end diff --git a/spec/reports/DynamicRecipeInclusion_spec.rb b/spec/reports/DynamicRecipeInclusion_spec.rb new file mode 100644 index 0000000..b0ff2ce --- /dev/null +++ b/spec/reports/DynamicRecipeInclusion_spec.rb @@ -0,0 +1,66 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::DynamicRecipeInclusion do + let(:mock_kb) { MockKnowledgeBase.new(:recipes => recipes) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no recipes' do + let(:recipes) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with recipes having dynamic inclusion' do + let(:recipes) do + { + 'fb_helpers::default' => { + 'IncludeRecipeDynamic' => false, + }, + 'fb_init::default' => { + 'IncludeRecipeDynamic' => true, + }, + 'fb_apache::setup' => { + 'IncludeRecipeDynamic' => true, + }, + 'fb_nginx::default' => { + 'IncludeRecipeDynamic' => nil, + }, + } + end + + it 'returns sorted recipes with dynamic inclusion' do + expect(report.to_a).to eq([ + 'fb_apache::setup', + 'fb_init::default', + ]) + end + + it 'output returns sorted recipes with dynamic inclusion' do + expect(report.output).to eq([ + 'fb_apache::setup', + 'fb_init::default', + ]) + end + end +end diff --git a/spec/reports/LeafCookbooks_spec.rb b/spec/reports/LeafCookbooks_spec.rb new file mode 100644 index 0000000..ba19e0a --- /dev/null +++ b/spec/reports/LeafCookbooks_spec.rb @@ -0,0 +1,78 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::LeafCookbooks do + let(:mock_kb) do + MockKnowledgeBase.new(:metadatarbs => metadatarbs, :metadatajsons => metadatajsons, :cookbooks => cookbooks) + end + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no cookbooks' do + let(:metadatarbs) { {} } + let(:metadatajsons) { {} } + let(:cookbooks) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with cookbooks having dependencies' do + let(:metadatarbs) do + { + 'fb_apache::metadata.rb' => { + 'ExplicitMetadataDepends' => ['fb_helpers', 'fb_sysctl'], + }, + 'fb_helpers::metadata.rb' => { + 'ExplicitMetadataDepends' => ['fb_init'], + }, + 'fb_init::metadata.rb' => { + 'ExplicitMetadataDepends' => [], + }, + 'fb_sysctl::metadata.rb' => { + 'ExplicitMetadataDepends' => [], + }, + 'fb_unused::metadata.rb' => { + 'ExplicitMetadataDepends' => [], + }, + } + end + let(:metadatajsons) { {} } + let(:cookbooks) do + { + 'fb_apache' => {}, + 'fb_helpers' => {}, + 'fb_init' => {}, + 'fb_sysctl' => {}, + 'fb_unused' => {}, + } + end + + it 'returns cookbooks that no other cookbook depends on' do + result = report.to_a + expect(result).to include('fb_apache') + expect(result).to include('fb_unused') + expect(result).not_to include('fb_helpers') + expect(result).not_to include('fb_init') + expect(result).not_to include('fb_sysctl') + end + end +end diff --git a/spec/reports/LibraryDefinedModulesAndClassConstants_spec.rb b/spec/reports/LibraryDefinedModulesAndClassConstants_spec.rb new file mode 100644 index 0000000..7e23c7d --- /dev/null +++ b/spec/reports/LibraryDefinedModulesAndClassConstants_spec.rb @@ -0,0 +1,51 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::LibraryDefinedModulesAndClassConstants do + let(:mock_kb) { MockKnowledgeBase.new(:libraries => libraries) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no libraries' do + let(:libraries) { {} } + + it 'returns header only' do + expect(report.output).to eq("file\tmodules\tconstants\n") + end + end + + describe 'with libraries having modules and constants' do + let(:libraries) do + { + 'fb_helpers::default' => { + 'LibraryDefinedModuleConstants' => ['FB', 'FB::Helpers'], + 'LibraryDefinedClassConstants' => ['FB::Helpers::Utils'], + }, + 'fb_apache::helpers' => { + 'LibraryDefinedModuleConstants' => ['FB::Apache'], + 'LibraryDefinedClassConstants' => [], + }, + } + end + + it 'returns sorted libraries with modules and constants' do + output = report.output + expect(output).to start_with("file\tmodules\tconstants\n") + expect(output).to include("fb_apache::helpers:\tFB::Apache\t") + expect(output).to include("fb_helpers::default:\tFB,FB::Helpers\tFB::Helpers::Utils") + end + end +end diff --git a/spec/reports/MissingReferencedRecipes_spec.rb b/spec/reports/MissingReferencedRecipes_spec.rb new file mode 100644 index 0000000..15e7e65 --- /dev/null +++ b/spec/reports/MissingReferencedRecipes_spec.rb @@ -0,0 +1,78 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::MissingReferencedRecipes do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles, :recipes => recipes, :recipejsons => recipejsons) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no roles or recipes' do + let(:roles) { {} } + let(:recipes) { {} } + let(:recipejsons) { {} } + + it 'returns empty hash with roles and recipes keys' do + expect(report.to_h).to eq({ 'roles' => {}, 'recipes' => {} }) + end + + it 'to_plain indicates no missing recipes' do + output = report.to_plain + expect(output).to include('No missing recipes coming from the roles files') + expect(output).to include('No missing recipes coming from the recipe files') + end + end + + describe 'with references to missing recipes' do + let(:roles) do + { + 'base_role' => { + 'RoleRunListRecipes' => ['fb_init::default', 'fb_missing::default'], + }, + } + end + let(:recipes) do + { + 'fb_init::default' => { + 'IncludeRecipeLiterals' => ['fb_helpers::default', 'fb_nonexistent::setup'], + }, + 'fb_helpers::default' => { + 'IncludeRecipeLiterals' => [], + }, + } + end + let(:recipejsons) { {} } + + it 'returns missing recipes from roles' do + result = report.to_h + expect(result['roles']['base_role']).to eq(['fb_missing::default']) + end + + it 'returns missing recipes from recipes' do + result = report.to_h + expect(result['recipes']['fb_init::default']).to eq(['fb_nonexistent::setup']) + end + + it 'to_plain includes missing recipe information' do + output = report.to_plain + expect(output).to include('Roles:') + expect(output).to include('base_role') + expect(output).to include('fb_missing::default') + expect(output).to include('Recipes:') + expect(output).to include('fb_init::default') + expect(output).to include('fb_nonexistent::setup') + end + end +end diff --git a/spec/reports/NoParsedRuby_spec.rb b/spec/reports/NoParsedRuby_spec.rb new file mode 100644 index 0000000..3a6644f --- /dev/null +++ b/spec/reports/NoParsedRuby_spec.rb @@ -0,0 +1,87 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::NoParsedRuby do + let(:mock_kb) do + MockKnowledgeBase.new( + :recipes => recipes, + :attributes => attributes, + :libraries => libraries, + :resources => resources, + :providers => providers, + :metadatarbs => metadatarbs, + :roles => roles, + ) + end + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with empty collections' do + let(:recipes) { {} } + let(:attributes) { {} } + let(:libraries) { {} } + let(:resources) { {} } + let(:providers) { {} } + let(:metadatarbs) { {} } + let(:roles) { {} } + + it 'returns hash with empty arrays for each key type' do + result = report.to_h + expect(result['recipes']).to eq([]) + expect(result['attributes']).to eq([]) + expect(result['libraries']).to eq([]) + expect(result['resources']).to eq([]) + expect(result['providers']).to eq([]) + expect(result['metadatarbs']).to eq([]) + expect(result['roles']).to eq([]) + end + + it 'to_plain indicates no non-AST files' do + output = report.to_plain + expect(output).to include('No non-AST') + end + end + + describe 'with files having NoParsedRuby flag' do + let(:recipes) do + { + 'fb_helpers::default' => { 'NoParsedRuby' => false }, + 'fb_init::default' => { 'NoParsedRuby' => true }, + } + end + let(:attributes) do + { + 'fb_helpers::default' => { 'NoParsedRuby' => true }, + } + end + let(:libraries) { {} } + let(:resources) { {} } + let(:providers) { {} } + let(:metadatarbs) { {} } + let(:roles) { {} } + + it 'returns files with NoParsedRuby flag' do + result = report.to_h + expect(result['recipes']).to eq(['fb_init::default']) + expect(result['attributes']).to eq(['fb_helpers::default']) + end + + it 'to_plain includes flagged files' do + output = report.to_plain + expect(output).to include('fb_init::default') + end + end +end diff --git a/spec/reports/NotReferencedRecipes_spec.rb b/spec/reports/NotReferencedRecipes_spec.rb new file mode 100644 index 0000000..9f35c24 --- /dev/null +++ b/spec/reports/NotReferencedRecipes_spec.rb @@ -0,0 +1,77 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::NotReferencedRecipes do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles, :recipes => recipes, :recipejsons => recipejsons) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no recipes' do + let(:roles) { {} } + let(:recipes) { {} } + let(:recipejsons) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with some unreferenced recipes' do + let(:roles) do + { + 'base_role' => { + 'RoleRunListRecipes' => ['fb_init::default'], + }, + } + end + let(:recipes) do + { + 'fb_init::default' => { + 'IncludeRecipeLiterals' => ['fb_helpers::default'], + }, + 'fb_helpers::default' => { + 'IncludeRecipeLiterals' => [], + }, + 'fb_unused::default' => { + 'IncludeRecipeLiterals' => [], + }, + } + end + let(:recipejsons) do + { + 'fb_json_unused::default' => {}, + } + end + + it 'returns sorted unreferenced recipes' do + expect(report.to_a).to eq([ + 'fb_json_unused::default', + 'fb_unused::default', + ]) + end + + it 'output returns sorted unreferenced recipes' do + expect(report.output).to eq([ + 'fb_json_unused::default', + 'fb_unused::default', + ]) + end + end +end diff --git a/spec/reports/RecipeOnlyCookbooks_spec.rb b/spec/reports/RecipeOnlyCookbooks_spec.rb new file mode 100644 index 0000000..63e8314 --- /dev/null +++ b/spec/reports/RecipeOnlyCookbooks_spec.rb @@ -0,0 +1,89 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::RecipeOnlyCookbooks do + let(:mock_kb) do + MockKnowledgeBase.new( + :cookbooks => cookbooks, + :attributes => attributes, + :libraries => libraries, + :resources => resources, + :providers => providers, + ) + end + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no cookbooks' do + let(:cookbooks) { {} } + let(:attributes) { {} } + let(:libraries) { {} } + let(:resources) { {} } + let(:providers) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with mixed cookbooks' do + let(:cookbooks) do + { + 'fb_apache' => {}, + 'fb_helpers' => {}, + 'fb_init' => {}, + 'fb_sysctl' => {}, + } + end + let(:attributes) do + { + 'fb_apache::default' => { 'cookbook' => 'fb_apache' }, + } + end + let(:libraries) do + { + 'fb_helpers::helpers' => { 'cookbook' => 'fb_helpers' }, + } + end + let(:resources) do + { + 'fb_sysctl::sysctl' => { 'cookbook' => 'fb_sysctl' }, + } + end + let(:providers) { {} } + + it 'returns cookbooks with only recipes' do + result = report.to_a + expect(result).to eq(['fb_init']) + end + + it 'excludes cookbooks with attributes' do + expect(report.to_a).not_to include('fb_apache') + end + + it 'excludes cookbooks with libraries' do + expect(report.to_a).not_to include('fb_helpers') + end + + it 'excludes cookbooks with resources' do + expect(report.to_a).not_to include('fb_sysctl') + end + end +end diff --git a/spec/reports/RecipesAssigningConstants_spec.rb b/spec/reports/RecipesAssigningConstants_spec.rb new file mode 100644 index 0000000..aeb486c --- /dev/null +++ b/spec/reports/RecipesAssigningConstants_spec.rb @@ -0,0 +1,52 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::RecipesAssigningConstants do + let(:mock_kb) { MockKnowledgeBase.new(:recipes => recipes) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no recipes' do + let(:recipes) { {} } + + it 'returns empty string' do + expect(report.output).to eq('') + end + end + + describe 'with recipes assigning constants' do + let(:recipes) do + { + 'fb_helpers::default' => { + 'RecipeConstantAssignments' => [], + }, + 'fb_init::default' => { + 'RecipeConstantAssignments' => ['MY_CONSTANT'], + }, + 'fb_apache::setup' => { + 'RecipeConstantAssignments' => ['APACHE_CONFIG', 'VHOST_DEFAULT'], + }, + } + end + + it 'returns recipes with constants' do + output = report.output + expect(output).to include('fb_init::default MY_CONSTANT') + expect(output).to include('fb_apache::setup APACHE_CONFIG, VHOST_DEFAULT') + expect(output).not_to include('fb_helpers::default') + end + end +end diff --git a/spec/reports/ResourceNotifications_spec.rb b/spec/reports/ResourceNotifications_spec.rb new file mode 100644 index 0000000..15f08fd --- /dev/null +++ b/spec/reports/ResourceNotifications_spec.rb @@ -0,0 +1,70 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::ResourceNotifications do + let(:mock_kb) { MockKnowledgeBase.new(:resources => resources, :recipes => recipes) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no resources or recipes' do + let(:resources) { {} } + let(:recipes) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with resources and recipes having notifications' do + let(:resources) do + { + 'fb_apache::config' => { + 'ResourceNotifications' => ['service[apache2]', 'template[httpd.conf]'], + }, + } + end + let(:recipes) do + { + 'fb_helpers::default' => { + 'ResourceNotifications' => ['service[syslog]'], + }, + 'fb_apache::default' => { + 'ResourceNotifications' => ['service[apache2]'], + }, + } + end + + it 'returns sorted unique notifications' do + expect(report.to_a).to eq([ + 'service[apache2]', + 'service[syslog]', + 'template[httpd.conf]', + ]) + end + + it 'output returns sorted unique notifications' do + expect(report.output).to eq([ + 'service[apache2]', + 'service[syslog]', + 'template[httpd.conf]', + ]) + end + end +end diff --git a/spec/reports/RoleRecipeEntrypoints_spec.rb b/spec/reports/RoleRecipeEntrypoints_spec.rb new file mode 100644 index 0000000..d273577 --- /dev/null +++ b/spec/reports/RoleRecipeEntrypoints_spec.rb @@ -0,0 +1,62 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::RoleRecipeEntrypoints do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no roles' do + let(:roles) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with roles containing recipes' do + let(:roles) do + { + 'base_role' => { + 'RoleRunListRecipes' => ['fb_init::default', 'fb_helpers::default'], + }, + 'web_role' => { + 'RoleRunListRecipes' => ['fb_apache::default', 'fb_init::default'], + }, + } + end + + it 'returns sorted unique recipe names' do + expect(report.to_a).to eq([ + 'fb_apache::default', + 'fb_helpers::default', + 'fb_init::default', + ]) + end + + it 'output returns sorted unique recipe names' do + expect(report.output).to eq([ + 'fb_apache::default', + 'fb_helpers::default', + 'fb_init::default', + ]) + end + end +end diff --git a/spec/reports/RoleReferencedRoles_spec.rb b/spec/reports/RoleReferencedRoles_spec.rb new file mode 100644 index 0000000..d0b2def --- /dev/null +++ b/spec/reports/RoleReferencedRoles_spec.rb @@ -0,0 +1,62 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require_relative './spec_helper' + +describe Bookworm::Reports::RoleReferencedRoles do + let(:mock_kb) { MockKnowledgeBase.new(:roles => roles) } + let(:report) { described_class.allocate.tap { |r| r.instance_variable_set(:@kb, mock_kb) } } + + describe 'with no roles' do + let(:roles) { {} } + + it 'returns empty array' do + expect(report.to_a).to eq([]) + end + + it 'output returns empty array' do + expect(report.output).to eq([]) + end + end + + describe 'with roles referencing other roles' do + let(:roles) do + { + 'base_role' => { + 'RoleExplicitRoles' => ['common_role', 'security_role'], + }, + 'web_role' => { + 'RoleExplicitRoles' => ['base_role', 'common_role'], + }, + } + end + + it 'returns sorted unique role names' do + expect(report.to_a).to eq([ + 'base_role', + 'common_role', + 'security_role', + ]) + end + + it 'output returns sorted unique role names' do + expect(report.output).to eq([ + 'base_role', + 'common_role', + 'security_role', + ]) + end + end +end diff --git a/spec/reports/spec_helper.rb b/spec/reports/spec_helper.rb new file mode 100644 index 0000000..1b72bc3 --- /dev/null +++ b/spec/reports/spec_helper.rb @@ -0,0 +1,66 @@ +# Copyright (c) 2026-present, Meta Platforms, Inc. and affiliates +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# rubocop:disable Chef/Meta/SpecFilename +require 'pathname' + +require_relative '../spec_helper' + +require 'bookworm/keys' +require 'bookworm/crawler' +require 'bookworm/exceptions' +require 'bookworm/infer_engine' +require 'bookworm/report_builder' + +# Load all rule files (needed by some reports like NoParsedRuby) +# Guard against double-loading when running full spec suite +unless defined?(Bookworm::InferRules) && Bookworm::InferRules.constants.any? + rules_dir = "#{__dir__}/../../lib/bookworm/rules/" + files = Dir.glob("#{rules_dir}/*.rb") + files.each do |f| + name = Pathname(f).basename.to_s.gsub('.rb', '') + ::Bookworm.load_rule_class name, :dir => rules_dir + end +end + +# Load all report files +# Guard against double-loading when running full spec suite +unless defined?(Bookworm::Reports) && Bookworm::Reports.constants.any? + reports_dir = "#{__dir__}/../../lib/bookworm/reports/" + files = Dir.glob("#{reports_dir}/*.rb") + files.each do |f| + name = Pathname(f).basename.to_s.gsub('.rb', '') + ::Bookworm.load_report_class name, :dir => reports_dir + end +end + +# Mock KnowledgeBase for testing reports +class MockKnowledgeBase + attr_accessor :recipes, :recipejsons, :roles, :metadatarbs, :metadatajsons, + :cookbooks, :attributes, :libraries, :resources, :providers + + def initialize(opts = {}) + @recipes = opts[:recipes] || {} + @recipejsons = opts[:recipejsons] || {} + @roles = opts[:roles] || {} + @metadatarbs = opts[:metadatarbs] || {} + @metadatajsons = opts[:metadatajsons] || {} + @cookbooks = opts[:cookbooks] || {} + @attributes = opts[:attributes] || {} + @libraries = opts[:libraries] || {} + @resources = opts[:resources] || {} + @providers = opts[:providers] || {} + end +end diff --git a/spec/rules/CookbookPropertyLiterals_spec.rb b/spec/rules/CookbookPropertyLiterals_spec.rb index e50d8f5..1718a8d 100644 --- a/spec/rules/CookbookPropertyLiterals_spec.rb +++ b/spec/rules/CookbookPropertyLiterals_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::CookbookPropertyLiterals do it 'returns empty array when no cookbook property' do diff --git a/spec/rules/ExplicitMetadataDepends_spec.rb b/spec/rules/ExplicitMetadataDepends_spec.rb index 9333e7a..764acf1 100644 --- a/spec/rules/ExplicitMetadataDepends_spec.rb +++ b/spec/rules/ExplicitMetadataDepends_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::ExplicitMetadataDepends do let(:ast) do diff --git a/spec/rules/IncludeRecipeDynamic_spec.rb b/spec/rules/IncludeRecipeDynamic_spec.rb index 68eb45d..096b7c5 100644 --- a/spec/rules/IncludeRecipeDynamic_spec.rb +++ b/spec/rules/IncludeRecipeDynamic_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::IncludeRecipeDynamic do it 'returns false on no AST' do diff --git a/spec/rules/IncludeRecipeLiterals_spec.rb b/spec/rules/IncludeRecipeLiterals_spec.rb index edf4a7c..565d047 100644 --- a/spec/rules/IncludeRecipeLiterals_spec.rb +++ b/spec/rules/IncludeRecipeLiterals_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::IncludeRecipeLiterals do it 'returns empty array when no include_recipe' do diff --git a/spec/rules/LibraryDefinedClassConstants_spec.rb b/spec/rules/LibraryDefinedClassConstants_spec.rb index ba356ab..ae16ee4 100644 --- a/spec/rules/LibraryDefinedClassConstants_spec.rb +++ b/spec/rules/LibraryDefinedClassConstants_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::LibraryDefinedClassConstants do it 'returns empty array when no class defined' do diff --git a/spec/rules/LibraryDefinedModuleConstants_spec.rb b/spec/rules/LibraryDefinedModuleConstants_spec.rb index 87575d7..0d8d746 100644 --- a/spec/rules/LibraryDefinedModuleConstants_spec.rb +++ b/spec/rules/LibraryDefinedModuleConstants_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::LibraryDefinedModuleConstants do it 'returns empty array when no module defined' do diff --git a/spec/rules/MetadatarbAttributeLiterals_spec.rb b/spec/rules/MetadatarbAttributeLiterals_spec.rb index fcfe650..154b20a 100644 --- a/spec/rules/MetadatarbAttributeLiterals_spec.rb +++ b/spec/rules/MetadatarbAttributeLiterals_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::MetadatarbAttributeLiterals do let(:ast) do diff --git a/spec/rules/NoParsedRuby_spec.rb b/spec/rules/NoParsedRuby_spec.rb index e53ff2d..ad5ba2d 100644 --- a/spec/rules/NoParsedRuby_spec.rb +++ b/spec/rules/NoParsedRuby_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::NoParsedRuby do let(:no_ast) do diff --git a/spec/rules/RecipeConstantAssignments_spec.rb b/spec/rules/RecipeConstantAssignments_spec.rb index 4ca6405..1fda4eb 100644 --- a/spec/rules/RecipeConstantAssignments_spec.rb +++ b/spec/rules/RecipeConstantAssignments_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::RecipeConstantAssignments do it 'does not capture normal variables' do diff --git a/spec/rules/ResourceNotifications_spec.rb b/spec/rules/ResourceNotifications_spec.rb index f4550ae..9d91285 100644 --- a/spec/rules/ResourceNotifications_spec.rb +++ b/spec/rules/ResourceNotifications_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::ResourceNotifications do it 'captures nothing when there is no subscribes' do diff --git a/spec/rules/RoleDescription_spec.rb b/spec/rules/RoleDescription_spec.rb index 2fc28b8..3f92a42 100644 --- a/spec/rules/RoleDescription_spec.rb +++ b/spec/rules/RoleDescription_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::RoleDescription do let(:ast) do diff --git a/spec/rules/RoleExplicitRoles_spec.rb b/spec/rules/RoleExplicitRoles_spec.rb index 81a20f4..1d12b8f 100644 --- a/spec/rules/RoleExplicitRoles_spec.rb +++ b/spec/rules/RoleExplicitRoles_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::RoleExplicitRoles do let(:ast) do diff --git a/spec/rules/RoleName_spec.rb b/spec/rules/RoleName_spec.rb index afa1077..beef0b8 100644 --- a/spec/rules/RoleName_spec.rb +++ b/spec/rules/RoleName_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::RoleName do let(:ast) do diff --git a/spec/rules/RoleRunListRecipes_spec.rb b/spec/rules/RoleRunListRecipes_spec.rb index e8dde27..b683fbe 100644 --- a/spec/rules/RoleRunListRecipes_spec.rb +++ b/spec/rules/RoleRunListRecipes_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative 'helper' +require_relative 'spec_helper' describe Bookworm::InferRules::RoleRunListRecipes do let(:ast) do diff --git a/spec/rules/RoleRunList_spec.rb b/spec/rules/RoleRunList_spec.rb index ce2a94f..b4c4786 100644 --- a/spec/rules/RoleRunList_spec.rb +++ b/spec/rules/RoleRunList_spec.rb @@ -12,7 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -require_relative './helper' +require_relative './spec_helper' describe Bookworm::InferRules::RoleRunList do let(:ast) do diff --git a/spec/rules/helper.rb b/spec/rules/spec_helper.rb similarity index 72% rename from spec/rules/helper.rb rename to spec/rules/spec_helper.rb index bf79a25..0e3bae4 100644 --- a/spec/rules/helper.rb +++ b/spec/rules/spec_helper.rb @@ -19,10 +19,13 @@ require 'bookworm/infer_engine' # Load all rule files -files = Dir.glob("#{__dir__}/../../lib/bookworm/rules/*.rb") -files.each do |f| - name = Pathname(f).basename.to_s.gsub('.rb', '') - ::Bookworm.load_rule_class name, :dir => "#{__dir__}/../../lib/bookworm/rules" +# Guard against double-loading when running full spec suite +unless defined?(Bookworm::InferRules) && Bookworm::InferRules.constants.any? + files = Dir.glob("#{__dir__}/../../lib/bookworm/rules/*.rb") + files.each do |f| + name = Pathname(f).basename.to_s.gsub('.rb', '') + ::Bookworm.load_rule_class name, :dir => "#{__dir__}/../../lib/bookworm/rules" + end end require_relative '../spec_helper'