# frozen_string_literal: true require_relative 'test_helper' class TestRuntimeVerifier < Minitest::Test # Hand-rolled fake status object; stands in for the Process::Status # returned by Open3.capture3. Minitest 6 moved Minitest::Mock out of # core (into the minitest-mock gem), so we avoid it entirely here. FakeStatus = Struct.new(:success) do def success? success end end # ─── snapshot (injected capture3) ───────────────────────────────────── def test_snapshot_parses_output_into_plugin_hash mock_output = <<~OUTPUT my-plugin@marketplace enabled other-plugin@marketplace disabled OUTPUT verifier = verifier_with_capture3(mock_output, success: true) result = verifier.snapshot assert_equal 'enabled', result['my-plugin@marketplace'] assert_equal 'disabled', result['other-plugin@marketplace'] end def test_snapshot_returns_empty_hash_on_failure verifier = verifier_with_capture3('', success: false) result = verifier.snapshot assert_equal({}, result) end def test_snapshot_returns_empty_hash_when_command_not_found verifier = PluginConfig::RuntimeVerifier.new( capture3: ->(*_args) { raise Errno::ENOENT, 'claude' } ) result = verifier.snapshot assert_equal({}, result) end # ─── verify_status (injected capture3) ──────────────────────────────── def test_verify_status_with_matching_status_returns_ok mock_output = "my-plugin@marketplace enabled\n" verifier = verifier_with_capture3(mock_output, success: true) result = verifier.verify_status('my-plugin@marketplace', 'enabled') assert result[:verified] end def test_verify_status_with_mismatched_status_returns_not_ok mock_output = "my-plugin@marketplace disabled\n" verifier = verifier_with_capture3(mock_output, success: true) result = verifier.verify_status('my-plugin@marketplace', 'enabled') refute result[:verified] assert_match(/expected 'enabled', got 'disabled'/, result[:details]) end def test_verify_status_missing_plugin_returns_not_present verifier = verifier_with_capture3('', success: true) result = verifier.verify_status('missing@marketplace', 'enabled') refute result[:verified] assert_match(/not_present/, result[:details]) end # ─── self.diff ─────────────────────────────────────────────────────── def test_diff_identifies_changes before = { 'a@m' => 'enabled', 'b@m' => 'enabled' } after = { 'a@m' => 'disabled', 'b@m' => 'enabled', 'c@m' => 'enabled' } result = PluginConfig::RuntimeVerifier.diff(before, after) assert_equal 2, result[:changed] # a changed, c added assert_equal 1, result[:unchanged] # b unchanged end def test_diff_identical_snapshots_returns_empty_changes snap = { 'a@m' => 'enabled', 'b@m' => 'disabled' } result = PluginConfig::RuntimeVerifier.diff(snap, snap) assert_equal 0, result[:changed] assert_equal 2, result[:unchanged] end private def verifier_with_capture3(stdout, success:) status = FakeStatus.new(success) PluginConfig::RuntimeVerifier.new(capture3: ->(*_args) { [stdout, '', status] }) end end