Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,23 +199,23 @@ Options are available via `attr_reader :options` in `FixtureKit::Adapter`.

Register using configuration methods:

`config.on_cache_save { |cache| ... }`
`config.on_cache_save { |event| ... }`
- Runs before cache save.

`config.on_cache_saved { |cache, duration| ... }`
`config.on_cache_saved { |event, duration| ... }`
- Runs after cache save.
- `duration` is elapsed seconds as `Float`.

`config.on_cache_mount { |cache| ... }`
`config.on_cache_mount { |event| ... }`
- Runs before cache mount.

`config.on_cache_mounted { |cache, duration| ... }`
`config.on_cache_mounted { |event, duration| ... }`
- Runs after cache mount.
- `duration` is elapsed seconds as `Float`.

The `cache` argument is a `FixtureKit::Cache` instance. Useful methods:
- `cache.identifier` — String cache identifier (no `.json` suffix).
- `cache.path` — full file path to the cache JSON file.
The `event` argument is a `FixtureKit::Event` instance. Methods:
- `event.identifier` — String cache identifier (no `.json` suffix).
- `event.path` — file path where the fixture definition block was defined.

Behavior:
- Multiple callbacks per event supported.
Expand Down
1 change: 1 addition & 0 deletions lib/fixture_kit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class CircularFixtureInheritance < Error; end
autoload :Callbacks, File.expand_path("fixture_kit/callbacks", __dir__)
autoload :ConfigurationHelper, File.expand_path("fixture_kit/configuration_helper", __dir__)
autoload :Singleton, File.expand_path("fixture_kit/singleton", __dir__)
autoload :Event, File.expand_path("fixture_kit/event", __dir__)
autoload :Fixture, File.expand_path("fixture_kit/fixture", __dir__)
autoload :Definition, File.expand_path("fixture_kit/definition", __dir__)
autoload :Registry, File.expand_path("fixture_kit/registry", __dir__)
Expand Down
4 changes: 4 additions & 0 deletions lib/fixture_kit/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def initialize(extends: nil, &definition)
@extends = extends
end

def path
@definition.source_location.first
end

def evaluate(context, parent: nil)
context.singleton_class.prepend(mixin(parent))
context.instance_exec(&@definition)
Expand Down
19 changes: 19 additions & 0 deletions lib/fixture_kit/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module FixtureKit
class Event
attr_reader :fixture

def initialize(fixture)
@fixture = fixture
end

def identifier
fixture.cache.identifier
end

def path
fixture.definition.path
end
end
end
7 changes: 4 additions & 3 deletions lib/fixture_kit/fixture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,18 @@ def anonymous?
!identifier.is_a?(String)
end

def emit(event)
def emit(event_name)
fixture_event = Event.new(self)
unless block_given?
configuration.callbacks.run(event, @cache)
configuration.callbacks.run(event_name, fixture_event)
return
end

value = nil
elapsed = Benchmark.realtime do
value = yield
end
configuration.callbacks.run(event, @cache, elapsed)
configuration.callbacks.run(event_name, fixture_event, elapsed)
value
end
end
Expand Down
14 changes: 7 additions & 7 deletions spec/unit/callbacks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@
callbacks = described_class.new
callback_one = spy("callback_one")
callback_two = spy("callback_two")
cache = double("cache")
callbacks.register(:cache_saved) { |c, duration| callback_one.call(c, duration) }
callbacks.register(:cache_saved) { |c, duration| callback_two.call(c, duration) }
event = double("event")
callbacks.register(:cache_saved) { |e, duration| callback_one.call(e, duration) }
callbacks.register(:cache_saved) { |e, duration| callback_two.call(e, duration) }

expect(callback_one).to receive(:call).with(cache, 0.2).ordered
expect(callback_two).to receive(:call).with(cache, 0.2).ordered
expect(callback_one).to receive(:call).with(event, 0.2).ordered
expect(callback_two).to receive(:call).with(event, 0.2).ordered

callbacks.run(:cache_saved, cache, 0.2)
callbacks.run(:cache_saved, event, 0.2)
end

it "does nothing when there are no callbacks for a known key" do
expect do
described_class.new.run(:cache_mount, double("cache"))
described_class.new.run(:cache_mount, double("event"))
end.not_to raise_error
end

Expand Down
52 changes: 26 additions & 26 deletions spec/unit/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@
configuration = described_class.new
callback_one = spy("callback_one")
callback_two = spy("callback_two")
cache = double("cache")
event = double("event")

configuration.on_cache_save { |c| callback_one.call(c) }
configuration.on_cache_save { |c| callback_two.call(c) }
configuration.on_cache_save { |e| callback_one.call(e) }
configuration.on_cache_save { |e| callback_two.call(e) }

expect(callback_one).to receive(:call).with(cache).ordered
expect(callback_two).to receive(:call).with(cache).ordered
expect(callback_one).to receive(:call).with(event).ordered
expect(callback_two).to receive(:call).with(event).ordered

configuration.callbacks.run(:cache_save, cache)
configuration.callbacks.run(:cache_save, event)
end
end

Expand All @@ -63,19 +63,19 @@
expect(described_class.new.on_cache_saved).to eq([])
end

it "registers and runs callbacks in order with cache and duration" do
it "registers and runs callbacks in order with event and duration" do
configuration = described_class.new
callback_one = spy("callback_one")
callback_two = spy("callback_two")
cache = double("cache")
event = double("event")

configuration.on_cache_saved { |c, duration| callback_one.call(c, duration) }
configuration.on_cache_saved { |c, duration| callback_two.call(c, duration) }
configuration.on_cache_saved { |e, duration| callback_one.call(e, duration) }
configuration.on_cache_saved { |e, duration| callback_two.call(e, duration) }

expect(callback_one).to receive(:call).with(cache, 0.25).ordered
expect(callback_two).to receive(:call).with(cache, 0.25).ordered
expect(callback_one).to receive(:call).with(event, 0.25).ordered
expect(callback_two).to receive(:call).with(event, 0.25).ordered

configuration.callbacks.run(:cache_saved, cache, 0.25)
configuration.callbacks.run(:cache_saved, event, 0.25)
end
end

Expand All @@ -88,15 +88,15 @@
configuration = described_class.new
callback_one = spy("callback_one")
callback_two = spy("callback_two")
cache = double("cache")
event = double("event")

configuration.on_cache_mount { |c| callback_one.call(c) }
configuration.on_cache_mount { |c| callback_two.call(c) }
configuration.on_cache_mount { |e| callback_one.call(e) }
configuration.on_cache_mount { |e| callback_two.call(e) }

expect(callback_one).to receive(:call).with(cache).ordered
expect(callback_two).to receive(:call).with(cache).ordered
expect(callback_one).to receive(:call).with(event).ordered
expect(callback_two).to receive(:call).with(event).ordered

configuration.callbacks.run(:cache_mount, cache)
configuration.callbacks.run(:cache_mount, event)
end
end

Expand All @@ -105,19 +105,19 @@
expect(described_class.new.on_cache_mounted).to eq([])
end

it "registers and runs callbacks in order with cache and duration" do
it "registers and runs callbacks in order with event and duration" do
configuration = described_class.new
callback_one = spy("callback_one")
callback_two = spy("callback_two")
cache = double("cache")
event = double("event")

configuration.on_cache_mounted { |c, duration| callback_one.call(c, duration) }
configuration.on_cache_mounted { |c, duration| callback_two.call(c, duration) }
configuration.on_cache_mounted { |e, duration| callback_one.call(e, duration) }
configuration.on_cache_mounted { |e, duration| callback_two.call(e, duration) }

expect(callback_one).to receive(:call).with(cache, 0.15).ordered
expect(callback_two).to receive(:call).with(cache, 0.15).ordered
expect(callback_one).to receive(:call).with(event, 0.15).ordered
expect(callback_two).to receive(:call).with(event, 0.15).ordered

configuration.callbacks.run(:cache_mounted, cache, 0.15)
configuration.callbacks.run(:cache_mounted, event, 0.15)
end
end
end
8 changes: 8 additions & 0 deletions spec/unit/definition_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ def fixture_name
end
end

describe "#path" do
it "returns the file path where the definition block was defined" do
definition = described_class.new {}

expect(definition.path).to eq(__FILE__)
end
end

describe "#expose" do
it "raises when the same name is exposed twice" do
definition = described_class.new do
Expand Down
28 changes: 28 additions & 0 deletions spec/unit/event_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

require "spec_helper"

RSpec.describe FixtureKit::Event do
let(:cache_identifier) { "project_management" }
let(:cache) { instance_double(FixtureKit::Cache, identifier: cache_identifier) }
let(:definition) { FixtureKit.define {} }
let(:fixture) do
instance_double(FixtureKit::Fixture, cache: cache, definition: definition)
end

describe "#identifier" do
it "delegates to the fixture cache identifier" do
event = described_class.new(fixture)

expect(event.identifier).to eq("project_management")
end
end

describe "#path" do
it "returns the source location of the definition block" do
event = described_class.new(fixture)

expect(event.path).to eq(__FILE__)
end
end
end
43 changes: 27 additions & 16 deletions spec/unit/fixture_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,37 @@
fixture = described_class.new(fixture_identifier, definition)
on_cache_save = spy("on_cache_save")
on_cache_saved = spy("on_cache_saved")
configuration.on_cache_save { |c| on_cache_save.call(c) }
configuration.on_cache_saved { |c, duration| on_cache_saved.call(c, duration) }
configuration.on_cache_save { |event| on_cache_save.call(event) }
configuration.on_cache_saved { |event, duration| on_cache_saved.call(event, duration) }
allow(Benchmark).to receive(:realtime) do |&block|
block.call
0.4
end

expect(on_cache_save).to receive(:call).with(cache).ordered
expect(on_cache_save).to receive(:call).with(an_instance_of(FixtureKit::Event)).ordered
expect(cache).to receive(:save).ordered
expect(on_cache_saved).to receive(:call).with(cache, be_within(0.001).of(0.4)).ordered
expect(on_cache_saved).to receive(:call).with(an_instance_of(FixtureKit::Event), be_within(0.001).of(0.4)).ordered

fixture.generate
end

it "provides identifier and path on the event" do
fixture = described_class.new(fixture_identifier, definition)
received_event = nil
configuration.on_cache_save { |event| received_event = event }

fixture.generate

expect(received_event.identifier).to eq(cache_identifier)
expect(received_event.path).to eq(definition.path)
end

it "does not call save callbacks when cache already exists and force is false" do
fixture = described_class.new(fixture_identifier, definition)
on_cache_save = spy("on_cache_save")
on_cache_saved = spy("on_cache_saved")
configuration.on_cache_save { |c| on_cache_save.call(c) }
configuration.on_cache_saved { |c, duration| on_cache_saved.call(c, duration) }
configuration.on_cache_save { |event| on_cache_save.call(event) }
configuration.on_cache_saved { |event, duration| on_cache_saved.call(event, duration) }
allow(cache).to receive(:exists?).and_return(true)

fixture.generate
Expand All @@ -62,17 +73,17 @@
fixture = described_class.new(fixture_identifier, definition)
on_cache_save = spy("on_cache_save")
on_cache_saved = spy("on_cache_saved")
configuration.on_cache_save { |c| on_cache_save.call(c) }
configuration.on_cache_saved { |c, duration| on_cache_saved.call(c, duration) }
configuration.on_cache_save { |event| on_cache_save.call(event) }
configuration.on_cache_saved { |event, duration| on_cache_saved.call(event, duration) }
allow(Benchmark).to receive(:realtime) do |&block|
block.call
0.25
end
allow(cache).to receive(:exists?).and_return(true)

expect(on_cache_save).to receive(:call).with(cache).ordered
expect(on_cache_save).to receive(:call).with(an_instance_of(FixtureKit::Event)).ordered
expect(cache).to receive(:save).ordered
expect(on_cache_saved).to receive(:call).with(cache, be_within(0.001).of(0.25)).ordered
expect(on_cache_saved).to receive(:call).with(an_instance_of(FixtureKit::Event), be_within(0.001).of(0.25)).ordered

fixture.generate(force: true)
end
Expand All @@ -97,17 +108,17 @@
fixture = described_class.new(fixture_identifier, definition)
on_cache_mount = spy("on_cache_mount")
on_cache_mounted = spy("on_cache_mounted")
configuration.on_cache_mount { |c| on_cache_mount.call(c) }
configuration.on_cache_mounted { |c, duration| on_cache_mounted.call(c, duration) }
configuration.on_cache_mount { |event| on_cache_mount.call(event) }
configuration.on_cache_mounted { |event, duration| on_cache_mounted.call(event, duration) }
allow(Benchmark).to receive(:realtime) do |&block|
block.call
0.3
end
allow(cache).to receive(:exists?).and_return(true)

expect(on_cache_mount).to receive(:call).with(cache).ordered
expect(on_cache_mount).to receive(:call).with(an_instance_of(FixtureKit::Event)).ordered
expect(cache).to receive(:load).ordered
expect(on_cache_mounted).to receive(:call).with(cache, be_within(0.001).of(0.3)).ordered
expect(on_cache_mounted).to receive(:call).with(an_instance_of(FixtureKit::Event), be_within(0.001).of(0.3)).ordered

fixture.mount
end
Expand All @@ -116,8 +127,8 @@
fixture = described_class.new(fixture_identifier, definition)
on_cache_mount = spy("on_cache_mount")
on_cache_mounted = spy("on_cache_mounted")
configuration.on_cache_mount { |c| on_cache_mount.call(c) }
configuration.on_cache_mounted { |c, duration| on_cache_mounted.call(c, duration) }
configuration.on_cache_mount { |event| on_cache_mount.call(event) }
configuration.on_cache_mounted { |event, duration| on_cache_mounted.call(event, duration) }

expect do
fixture.mount
Expand Down
Loading