From 2a14915fcbcbe63f381c8865fb8495128f45b7f9 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Sun, 14 Dec 2025 20:30:14 -0800 Subject: [PATCH] RR-583: Create non-nilable CodeTeams.find! --- lib/code_teams.rb | 17 ++++++++--------- spec/lib/code_teams_spec.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/code_teams.rb b/lib/code_teams.rb index c1f341c..a472a1f 100644 --- a/lib/code_teams.rb +++ b/lib/code_teams.rb @@ -13,28 +13,27 @@ module CodeTeams extend T::Sig class IncorrectPublicApiUsageError < StandardError; end + class TeamNotFoundError < StandardError; end UNKNOWN_TEAM_STRING = 'Unknown Team' @plugins_registered = T.let(false, T::Boolean) sig { returns(T::Array[Team]) } def self.all - @all = T.let(@all, T.nilable(T::Array[Team])) - @all ||= for_directory('config/teams') + @all ||= T.let(for_directory('config/teams'), T.nilable(T::Array[Team])) end sig { params(name: String).returns(T.nilable(Team)) } def self.find(name) - @index_by_name = T.let(@index_by_name, T.nilable(T::Hash[String, CodeTeams::Team])) - @index_by_name ||= begin - result = {} - all.each { |t| result[t.name] = t } - result - end - + @index_by_name ||= T.let(all.to_h { |t| [t.name, t] }, T.nilable(T::Hash[String, CodeTeams::Team])) @index_by_name[name] end + sig { params(name: String).returns(Team) } + def self.find!(name) + find(name) || raise(TeamNotFoundError, "No team found with name: #{name}") + end + sig { params(dir: String).returns(T::Array[Team]) } def self.for_directory(dir) unless @plugins_registered diff --git a/spec/lib/code_teams_spec.rb b/spec/lib/code_teams_spec.rb index ab18b93..14d7c87 100644 --- a/spec/lib/code_teams_spec.rb +++ b/spec/lib/code_teams_spec.rb @@ -37,6 +37,34 @@ end end + describe '.find' do + it 'returns the team when found' do + team = described_class.find('My Team') + expect(team).to be_a(CodeTeams::Team) + expect(team.name).to eq('My Team') + end + + it 'returns nil when the team is not found' do + team = described_class.find('Nonexistent Team') + expect(team).to be_nil + end + end + + describe '.find!' do + it 'returns the team when found' do + team = described_class.find!('My Team') + expect(team).to be_a(CodeTeams::Team) + expect(team.name).to eq('My Team') + end + + it 'raises TeamNotFoundError when the team is not found' do + expect { described_class.find!('Nonexistent Team') }.to raise_error( + CodeTeams::TeamNotFoundError, + 'No team found with name: Nonexistent Team' + ) + end + end + describe 'validation_errors' do subject(:validation_errors) { described_class.validation_errors(described_class.all) }