Gem でよく見る initializer で動作を変更する方法を備忘録として残しておく

環境

  • ruby: 3.0.4

前提

以下のような構成になっている想定

lib
├── sample_gem
│   └── configuration.rb
└── sample_gem.rb
spec
├── configration_spec.rb
└── spec_helper.rb

実際のコード

以下のようなクラスを定義する

module SampleGem # gem のクラス名
  class Configuration
    attr_accessor :sample_confime_name # config で使用する config 名

    def initialize
      @sample_confime_name = false
    end
  end

  def self.configuration
    @configuration ||= Configuration.new
  end

  def self.configuration=(config)
    @configuration = config
  end

  # ```
  # SampleGem.configure do |config|
  #   config.sample_confime_name = false
  # end
  # ```
  def self.configure
    yield configuration
  end
end

以下のように、require する

require 'sample_gem/configuration'

とすると initializer 側で以下のように設定を変更できる

SampleGem.configure do |config|
  config.sample_confime_name = true
end

RSpec

spec_helper で以下を設定しておかないと、設定が引き継がれた状態でテストが実行される

RSpec.configure do |config|
  config.before { restore_default_config }
end

def restore_default_config
  SampleGem.configuration = nil
end

設定のテストは以下のようにする

require File.expand_path('../lib/sample_gem/configuration', File.dirname(__FILE__))
require File.expand_path('spec_helper', File.dirname(__FILE__))

describe SampleGem::Configuration do
  let(:config) { SampleGem.configuration }

  context "when sample_confime_name is set to true" do
    it "returns true" do
      SampleGem.configure { |config| config.sample_confime_name = true }
      expect(SampleGem.configuration.sample_confime_name).to eq true
    end
  end

  context "when sample_confime_name is not specified" do
    it "defaults to false" do
      expect(SampleGem.configuration.sample_confime_name).to eq false
    end
  end
end