From d741b3327e51d8a8cb33079920a726f4ca37fae3 Mon Sep 17 00:00:00 2001 From: David Crosby Date: Wed, 14 Jan 2026 08:26:22 -0800 Subject: [PATCH] Add cookbookrspec key and CookbookRspecExists rule (#12) Summary: Pull Request resolved: https://github.com/facebook/bookworm/pull/12 Add a new bookworm key `cookbookrspec` to detect RSpec test files in cookbooks, and create a corresponding `CookbookRspecExists` rule. Since normal rspec and chefspec can be side-by-side, I opted for the more generic key. We're ignoring helper-type files, only focusing on _spec since that's where the tests need to reside. The key uses: - glob_pattern: */spec/*_spec.rb - path_name_regex: spec/(.*)_spec\.rb - determine_cookbook_name: true This enables bookworm to track which cookbooks have RSpec test files. Differential Revision: D90535240 --- lib/bookworm/keys.rb | 5 +++++ lib/bookworm/rules/CookbookRspecExists.rb | 22 +++++++++++++++++++ spec/knowledge_base_spec.rb | 11 ++++++++++ spec/lib/keys_spec.rb | 6 +++--- spec/rules/CookbookRspecExists_spec.rb | 26 +++++++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 lib/bookworm/rules/CookbookRspecExists.rb create mode 100644 spec/rules/CookbookRspecExists_spec.rb diff --git a/lib/bookworm/keys.rb b/lib/bookworm/keys.rb index 9910593..07b222b 100644 --- a/lib/bookworm/keys.rb +++ b/lib/bookworm/keys.rb @@ -80,6 +80,11 @@ module Bookworm 'determine_cookbook_name' => true, 'path_name_regex' => 'providers/(.*)\.rb', }, + 'cookbookrspec' => { + 'glob_pattern' => '*/spec/*_spec.rb', + 'determine_cookbook_name' => true, + 'path_name_regex' => 'spec/(.*)_spec\.rb', + }, }.freeze # Set defaults diff --git a/lib/bookworm/rules/CookbookRspecExists.rb b/lib/bookworm/rules/CookbookRspecExists.rb new file mode 100644 index 0000000..4d88655 --- /dev/null +++ b/lib/bookworm/rules/CookbookRspecExists.rb @@ -0,0 +1,22 @@ +# 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. +description 'Helper rule to show existence of a cookbook rspec file' +keys %w{ + cookbookrspec +} + +def output + true +end diff --git a/spec/knowledge_base_spec.rb b/spec/knowledge_base_spec.rb index e662984..e9b2cfd 100644 --- a/spec/knowledge_base_spec.rb +++ b/spec/knowledge_base_spec.rb @@ -111,6 +111,17 @@ } }) end + it 'holds all yer cookbookrspecs' do + kb = Bookworm::KnowledgeBase.new( + { 'cookbookrspec' => [['mycookbook/spec/default_spec.rb', '(ast)']] }, + ) + expect(kb.cookbookrspecs).to eq({ 'mycookbook::default' => { + 'path' => 'mycookbook/spec/default_spec.rb', + 'cookbook' => 'mycookbook', + 'ast' => '(ast)', + } }) + end + it 'handles empty input' do kb = Bookworm::KnowledgeBase.new({}) expect(kb.recipes).to eq({}) diff --git a/spec/lib/keys_spec.rb b/spec/lib/keys_spec.rb index b57a5a2..1318a7c 100644 --- a/spec/lib/keys_spec.rb +++ b/spec/lib/keys_spec.rb @@ -25,7 +25,7 @@ it 'contains expected key types' do expected_keys = %w{ cookbook role metadatarb metadatajson recipe recipejson - attribute library resource provider + attribute library resource provider cookbookrspec } expect(keys.keys).to match_array(expected_keys) end @@ -77,8 +77,8 @@ end describe 'determine_cookbook_name' do - it 'is true for recipe, attribute, library, resource, provider' do - %w{recipe attribute library resource provider}.each do |key| + it 'is true for recipe, attribute, library, resource, provider, cookbookrspec' do + %w{recipe attribute library resource provider cookbookrspec}.each do |key| expect(keys[key]['determine_cookbook_name']).to eq(true) end end diff --git a/spec/rules/CookbookRspecExists_spec.rb b/spec/rules/CookbookRspecExists_spec.rb new file mode 100644 index 0000000..74a15d2 --- /dev/null +++ b/spec/rules/CookbookRspecExists_spec.rb @@ -0,0 +1,26 @@ +# 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::InferRules::CookbookRspecExists do + it 'returns true when cookbookrspec file exists' do + ast = generate_ast(<<~RUBY) + describe 'my_cookbook::default' do + end + RUBY + rule = described_class.new({ 'ast' => ast }) + expect(rule.output).to eq(true) + end +end