From bafa2ec1262730987f76bc09ee308c731ab36be1 Mon Sep 17 00:00:00 2001 From: Sam Ford <1584702+samford@users.noreply.github.com> Date: Sun, 6 Apr 2025 16:19:38 -0400 Subject: [PATCH] OnSystem: add tests `OnSystem` is exercised by other tests that include its modules but this adds some baseline tests to ensure some of these methods work as expected when tested in isolation. Between these added tests and existing tests, we should have 100% coverage when run on Homebrew/brew CI. --- .../Homebrew/test/extend/on_system_spec.rb | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 Library/Homebrew/test/extend/on_system_spec.rb diff --git a/Library/Homebrew/test/extend/on_system_spec.rb b/Library/Homebrew/test/extend/on_system_spec.rb new file mode 100644 index 0000000000..605c37f0d8 --- /dev/null +++ b/Library/Homebrew/test/extend/on_system_spec.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true + +require "extend/on_system" + +RSpec.describe OnSystem do + shared_examples "a class with on_arch methods" do + it "adds on_arch methods to class for `ARCH_OPTIONS`" do + OnSystem::ARCH_OPTIONS.each do |arch| + expect(subject.method_defined?(:"on_#{arch}")).to be true + end + end + end + + shared_examples "a class with on_base_os methods" do + it "adds on_os methods to class for `BASE_OS_OPTIONS`" do + OnSystem::BASE_OS_OPTIONS.each do |os| + expect(subject.method_defined?(:"on_#{os}")).to be true + end + end + end + + shared_examples "a class with on_macos methods" do + it "adds on_os methods to class for `MacOSVersion::SYMBOLS` keys" do + MacOSVersion::SYMBOLS.each_key do |os| + expect(subject.method_defined?(:"on_#{os}")).to be true + end + end + end + + describe "::arch_condition_met?" do + it "returns true if current arch equals provided arch" do + Homebrew::SimulateSystem.with(arch: :arm) do + expect(described_class.arch_condition_met?(:arm)).to be true + end + end + + it "returns false if current arch does not equal provided arch" do + Homebrew::SimulateSystem.with(arch: :arm) do + expect(described_class.arch_condition_met?(:intel)).to be false + end + end + + it "raises error if provided arch is not valid" do + expect { described_class.arch_condition_met?(:nonexistent_arch) } + .to raise_error(ArgumentError) + end + end + + describe "::os_condition_met?" do + let(:newest_macos) { MacOSVersion::SYMBOLS.keys.first } + + it "returns result of `SimulateSystem.simulating_or_running_on_` for supported OS" do + Homebrew::SimulateSystem.with(os: newest_macos) do + # This needs to use a value from `BASE_OS_OPTIONS` + expect(described_class.os_condition_met?(:macos)).to be true + end + end + + it "returns false if `os_name` is a macOS version but OS is Linux" do + Homebrew::SimulateSystem.with(os: :linux) do + expect(described_class.os_condition_met?(newest_macos)).to be false + end + end + + it "returns false if current OS is `:macos` and `os_name` is a macOS version" do + # A generic macOS version is treated as less than any other version. + Homebrew::SimulateSystem.with(os: :macos) do + expect(described_class.os_condition_met?(newest_macos)).to be false + end + end + + it "returns true if current OS equals the `os_name` macOS version" do + Homebrew::SimulateSystem.with(os: newest_macos) do + expect(described_class.os_condition_met?(newest_macos)).to be true + end + end + + it "returns true if current OS meets the `or_condition` for `os_name` macOS version" do + current_os = :ventura + Homebrew::SimulateSystem.with(os: current_os) do + expect(described_class.os_condition_met?(current_os, :or_newer)).to be true + expect(described_class.os_condition_met?(:big_sur, :or_newer)).to be true + expect(described_class.os_condition_met?(current_os, :or_older)).to be true + expect(described_class.os_condition_met?(newest_macos, :or_older)).to be true + end + end + + it "returns false if current OS does not meet the `or_condition` for `os_name` macOS version" do + Homebrew::SimulateSystem.with(os: :ventura) do + expect(described_class.os_condition_met?(newest_macos, :or_newer)).to be false + expect(described_class.os_condition_met?(:big_sur, :or_older)).to be false + end + end + + it "raises an error if `os_name` is not valid" do + expect { described_class.os_condition_met?(:nonexistent_os) } + .to raise_error(ArgumentError, /Invalid OS condition:/) + end + + it "raises an error if `os_name` is a macOS version but `or_condition` is not valid" do + expect do + described_class.os_condition_met?(newest_macos, :nonexistent_condition) + end.to raise_error(ArgumentError, /Invalid OS `or_\*` condition:/) + end + end + + describe "::condition_from_method_name" do + it "returns a symbol with any `on_` prefix removed" do + expect(described_class.condition_from_method_name(:on_arm)).to eq(:arm) + end + + it "returns provided symbol if there is no `on_` prefix" do + expect(described_class.condition_from_method_name(:arm)).to eq(:arm) + end + end + + describe "::setup_arch_methods" do + subject do + klass = Class.new + described_class.setup_arch_methods(klass) + klass + end + + it_behaves_like "a class with on_arch methods" + end + + describe "::setup_base_os_methods" do + subject do + klass = Class.new + described_class.setup_base_os_methods(klass) + klass + end + + it_behaves_like "a class with on_base_os methods" + end + + describe "::setup_macos_methods" do + subject do + klass = Class.new + described_class.setup_macos_methods(klass) + klass + end + + it_behaves_like "a class with on_macos methods" + end + + describe "::included" do + it "raises an error" do + expect { Class.new { include OnSystem } } + .to raise_error(/Do not include `OnSystem` directly/) + end + end + + describe "::MacOSAndLinux" do + subject { Class.new { include OnSystem::MacOSAndLinux } } + + it "can be included" do + expect { Class.new { include OnSystem::MacOSAndLinux } }.not_to raise_error + end + + it_behaves_like "a class with on_arch methods" + it_behaves_like "a class with on_base_os methods" + it_behaves_like "a class with on_macos methods" + end + + describe "::MacOSOnly" do + subject { Class.new { include OnSystem::MacOSAndLinux } } + + it "can be included" do + expect { Class.new { include OnSystem::MacOSOnly } }.not_to raise_error + end + + it_behaves_like "a class with on_arch methods" + it_behaves_like "a class with on_macos methods" + end +end