Commit 3419a1b

mo khan <mo@mokhan.ca>
2026-03-23 20:15:14
refactor: extract SlashCommand class
1 parent 5f282b8
Changed files (2)
lib
spec
lib/elelem/commands.rb
@@ -1,9 +1,24 @@
 # frozen_string_literal: true
 
 module Elelem
+  class SlashCommand
+    attr_reader :name, :description, :completions
+
+    def initialize(name, description: "", completions: nil, handler:)
+      @name = name
+      @description = description
+      @completions = completions
+      @handler = handler
+    end
+
+    def call(args)
+    end
+  end
+
   class Commands
     include Enumerable
 
+
     def initialize(registry = {})
       @registry = registry
     end
@@ -12,6 +27,11 @@ module Elelem
       @registry[name] = { description: description, completions: completions, handler: handler }
     end
 
+    def command_for(name)
+      hash = @registry[name]
+      SlashCommand.new(name, description: hash[:description], completions: hash[:completions], handler: hash[:handler])
+    end
+
     def completions_for(name, partial = "")
       cmd = @registry[name]
       return [] unless cmd && cmd[:completions]
spec/elelem/commands_spec.rb
@@ -1,17 +1,17 @@
 # frozen_string_literal: true
 
 RSpec.describe Elelem::Commands do
-  subject { described_class.new }
+  subject(:commands) { described_class.new }
 
   describe "#register" do
     context "when registering a command without args" do
       before do
         @called = false
-        subject.register("example") { @called = true }
+        commands.register("example") { @called = true }
       end
 
       it "executes the command" do
-        expect(subject.run("example")).to be(true)
+        expect(commands.run("example")).to be(true)
         expect(@called).to be(true)
       end
     end
@@ -20,50 +20,67 @@ RSpec.describe Elelem::Commands do
       before do
         @called = false
         @args = {}
-        subject.register("example") { |args| @called = true; @args = args }
+        commands.register("example") { |args| @called = true; @args = args }
       end
 
       it "executes the command with args" do
         args = { ts: Time.now.to_i }
-        expect(subject.run("example", args)).to be(true)
+        expect(commands.run("example", args)).to be(true)
         expect(@called).to be(true)
         expect(@args).to eq(args)
       end
     end
 
     it "stores description" do
-      subject.register("test", description: "Test command") { }
-      expect(subject.include?("test")).to be true
+      commands.register("test", description: "Test command") { }
+      expect(commands.include?("test")).to be true
+    end
+  end
+
+  describe "#command_for" do
+    context "when the command is registered" do
+      subject(:command) { commands.command_for("raise") }
+
+      before do
+        commands.register("raise", description: "Raises an error", completions: ['heck']) do |args|
+          raise args.inspect
+        end
+      end
+
+      it { expect(command).not_to be_nil }
+      it { expect(command&.name).to eq("raise") }
+      it { expect(command&.description).to eq("Raises an error") }
+      it { expect(command&.completions).to match_array(['heck']) }
     end
   end
 
   describe "#run" do
     it "returns true when command exists" do
-      subject.register("test") { }
-      expect(subject.run("test")).to be true
+      commands.register("test") { }
+      expect(commands.run("test")).to be true
     end
 
     it "returns false when command does not exist" do
-      expect(subject.run("nonexistent")).to be false
+      expect(commands.run("nonexistent")).to be false
     end
   end
 
   describe "#names" do
     it "returns command names with slash prefix" do
-      subject.register("exit") { }
-      subject.register("help") { }
-      expect(subject.names).to contain_exactly("/exit", "/help")
+      commands.register("exit") { }
+      commands.register("help") { }
+      expect(commands.names).to contain_exactly("/exit", "/help")
     end
   end
 
   describe "#include?" do
     it "returns true for registered commands" do
-      subject.register("test") { }
-      expect(subject.include?("test")).to be true
+      commands.register("test") { }
+      expect(commands.include?("test")).to be true
     end
 
     it "returns false for unregistered commands" do
-      expect(subject.include?("test")).to be false
+      expect(commands.include?("test")).to be false
     end
   end
 end