Skip to content

Commit

Permalink
Add spec for Graft::Hook.[] and Graft::Hook.add
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyCTHsu committed May 10, 2024
1 parent 9ea4e68 commit 44c5015
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 4 deletions.
32 changes: 28 additions & 4 deletions lib/graft/hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,33 @@ class Hook

@hooks = {}

def self.[](hook_point, strategy = DEFAULT_STRATEGY)
@hooks[hook_point] ||= new(hook_point, nil, strategy)
end

# NOTE: API Design - Should we push to ::Graft module?
# NOTE: API Design - Should we support a HookPoint object being injected?
#
# If the key exists:
# - add a callback to the hook.
# If the key does not exist:
# - add a new hook to the @hooks hash
# - add a callback to the hook.
def self.add(hook_point, strategy = DEFAULT_STRATEGY, &block)
self[hook_point, strategy].add(&block)
end

# NOTE: API Design - Should we push to ::Graft module?
# NOTE: API Design - Should we support a HookPoint object being injected?
# NOTE: Implementation Design - Hash key implementation
#
# If the key exists:
# - return the existing hook.
# If the key does not exist:
# - create a new hook and add it to the @hooks hash.
# - return the existing hook.
def self.[](hook_point, strategy = DEFAULT_STRATEGY)
@hooks[hook_point] ||= new(hook_point, nil, strategy)
end

# NOTE: API Design - Should we push to ::Graft module?
# NOTE: Is this used?
def self.ignore
Thread.current[:hook_entered] = true
yield
Expand All @@ -27,6 +46,7 @@ def self.ignore

attr_reader :point, :stack

# NOTE: Push logic upward ClassMethods
def initialize(hook_point, dependency_test = nil, strategy = DEFAULT_STRATEGY)
@disabled = false
@point = hook_point.is_a?(HookPoint) ? hook_point : HookPoint.new(hook_point, strategy)
Expand Down Expand Up @@ -80,6 +100,10 @@ def disabled?
@disabled
end

def enabled?
!disabled?
end

def install
return unless point.exist?

Expand Down
159 changes: 159 additions & 0 deletions spec/graft/hook_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
require "graft/hook"

RSpec.describe Graft::Hook do
describe ".[]" do
around do |example|
described_class.instance_variable_get(:@hooks).clear
example.run
described_class.instance_variable_get(:@hooks).clear
end

context "when given a string" do
it do
described_class["Dummy#dog"]

hooks = described_class.instance_variable_get(:@hooks)

expect(hooks.length).to eq(1)
expect(hooks).to have_key("Dummy#dog")
expect(hooks.values).to all(be_instance_of(described_class))

described_class["Dummy#dog"]

expect(hooks.length).to eq(1)
expect(hooks).to have_key("Dummy#dog")
expect(hooks.values).to all(be_instance_of(described_class))
end
end

context "when given a HookPoint" do
it do
hook_point = Graft::HookPoint.new("Dummy#dog")
described_class[hook_point]

hooks = described_class.instance_variable_get(:@hooks)

expect(hooks.length).to eq(1)
expect(hooks).to have_key(hook_point)
expect(hooks.values).to all(be_instance_of(described_class))

another_hook_point = Graft::HookPoint.new("Dummy#dog")
described_class[another_hook_point]

expect(hooks.length).to eq(2)
expect(hooks).to have_key(another_hook_point)
expect(hooks.values).to all(be_instance_of(described_class))
end
end
end

describe ".add" do
around do |example|
described_class.instance_variable_get(:@hooks).clear
example.run
described_class.instance_variable_get(:@hooks).clear
end

context "when given a string" do
it do
hooks = described_class.instance_variable_get(:@hooks)

invoked = false
self_within_the_block = nil

described_class.add("Dummy#dog") do
# Do something
invoked = true
self_within_the_block = self
end

expect(invoked).to be(true)
expect(self_within_the_block).to be_instance_of(described_class)

hooks = described_class.instance_variable_get(:@hooks)
expect(hooks.length).to eq(1)
end
end

context "when given a HookPoint" do
it do
hooks = described_class.instance_variable_get(:@hooks)
hook_point = Graft::HookPoint.new("Dummy#dog")

invoked = false
self_within_the_block = nil

described_class.add(hook_point) do
# Do something
invoked = true
self_within_the_block = self
end

expect(hooks.length).to eq(1)
expect(hooks).to have_key(hook_point)
expect(hooks.values).to all(be_instance_of(described_class))

another_hook_point = Graft::HookPoint.new("Dummy#dog")
described_class[another_hook_point]

expect(hooks.length).to eq(2)
expect(hooks).to have_key(another_hook_point)
expect(hooks.values).to all(be_instance_of(described_class))
end
end
end

describe ".ignore" do
context "when given a block" do
it do
expect(Thread.current[:hook_entered]).to be_falsey

described_class.ignore do
expect(Thread.current[:hook_entered]).to be_truthy
end

expect(Thread.current[:hook_entered]).to be_falsey
end
end

context "when given a block that raises an error" do
it do
expect(Thread.current[:hook_entered]).to be_falsey

expect do
described_class.ignore do
expect(Thread.current[:hook_entered]).to be_truthy
raise "Error"
end
end.to raise_error("Error")

expect(Thread.current[:hook_entered]).to be_falsey
end
end
end

describe "#initialize" do
context "when given a string" do
it do
hook = described_class.new("Dummy#dog")

expect(hook).to be_enabled

expect(hook.instance_variable_get(:@point)).to be_instance_of(Graft::HookPoint)
expect(hook.instance_variable_get(:@stack)).to be_instance_of(Graft::Stack)
end
end

context "when given a HookPoint" do
it do
hook_point = Graft::HookPoint.new("Dummy#dog")
hook = described_class.new(hook_point)

expect(hook).to be_enabled

expect(hook.instance_variable_get(:@point)).to be_instance_of(Graft::HookPoint)
expect(hook.instance_variable_get(:@stack)).to be_instance_of(Graft::Stack)
end
end
end
end
4 changes: 4 additions & 0 deletions spec/graft_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require "graft"

describe Graft do
end

0 comments on commit 44c5015

Please sign in to comment.