From f61bcfdae999c084019b42ae36bbaea7f8f0e926 Mon Sep 17 00:00:00 2001 From: Mike Nelson Date: Wed, 13 Mar 2024 18:18:35 -0400 Subject: [PATCH] bump to beta7 --- Gemfile.lock | 2 +- lib/fixtury/definition_executor.rb | 35 ++++++++++++++++++++---- lib/fixtury/reference.rb | 7 +++-- lib/fixtury/store.rb | 6 ++-- lib/fixtury/version.rb | 2 +- test/fixtury/definition_executor_test.rb | 10 +++++++ test/fixtury/store_test.rb | 26 ++++++++++++++++-- 7 files changed, 73 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a2d846b..12595a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - fixtury (1.0.0.beta6) + fixtury (1.0.0.beta7) GEM remote: https://rubygems.org/ diff --git a/lib/fixtury/definition_executor.rb b/lib/fixtury/definition_executor.rb index ed5ff14..3fc6109 100644 --- a/lib/fixtury/definition_executor.rb +++ b/lib/fixtury/definition_executor.rb @@ -1,20 +1,33 @@ # frozen_string_literal: true +require "benchmark" + module Fixtury # A container that manages the execution of a definition in the context of a store. class DefinitionExecutor - attr_reader :value, :definition, :store + class Output + + attr_accessor :value, :metadata + + def initialize + @value = nil + @metadata = {} + end + + end + + attr_reader :output, :definition, :store def initialize(store: nil, definition:) @store = store @definition = definition - @value = nil + @output = Output.new end def call run_definition - value + output end private @@ -25,13 +38,13 @@ def call def run_definition callable = definition.callable - @value = if callable.arity.positive? + if callable.arity.positive? deps = build_dependency_store - ::Fixtury.hooks.call(:execution, self) do + around_execution do instance_exec(deps, &callable) end else - ::Fixtury.hooks.call(:execution, self) do + around_execution do instance_eval(&callable) end end @@ -41,6 +54,16 @@ def run_definition raise Errors::DefinitionExecutionError.new(definition.pathname, e) end + def around_execution(&block) + measure_timing do + @output.value = ::Fixtury.hooks.call(:execution, self, &block) + end + end + + def measure_timing(&block) + @output.metadata[:duration] = Benchmark.realtime(&block) + end + def build_dependency_store DependencyStore.new(definition: definition, store: store) end diff --git a/lib/fixtury/reference.rb b/lib/fixtury/reference.rb index e0c1bb3..8ee3038 100644 --- a/lib/fixtury/reference.rb +++ b/lib/fixtury/reference.rb @@ -15,13 +15,14 @@ def self.holder(name) new(name, HOLDER_KEY) end - attr_reader :name, :locator_key, :created_at, :options + attr_reader :name, :locator_key, :created_at, :metadata + alias options metadata # backwards compatibility - def initialize(name, locator_key, **options) + def initialize(name, locator_key, **metadata) @name = name @locator_key = locator_key @created_at = Time.now.to_i - @options = options + @metadata = metadata end def holder? diff --git a/lib/fixtury/store.rb b/lib/fixtury/store.rb index 379725a..600ef3f 100644 --- a/lib/fixtury/store.rb +++ b/lib/fixtury/store.rb @@ -159,7 +159,8 @@ def get(search) begin executor = ::Fixtury::DefinitionExecutor.new(store: self, definition: dfn) - value = executor.call + output = executor.call + value = output.value rescue StandardError clear_reference(pathname) raise @@ -167,8 +168,9 @@ def get(search) log("store #{pathname}", level: LOG_LEVEL_DEBUG) - locator_key = locator.dump(value, context: pathname) + locator_key = locator.dump(output.value, context: pathname) reference_opts = {} + reference_opts.merge!(output.metadata) reference_opts[:isolation_key] = isokey unless isokey == pathname references[pathname] = ::Fixtury::Reference.new( pathname, diff --git a/lib/fixtury/version.rb b/lib/fixtury/version.rb index fab5164..616ff80 100644 --- a/lib/fixtury/version.rb +++ b/lib/fixtury/version.rb @@ -2,6 +2,6 @@ module Fixtury - VERSION = "1.0.0.beta6" + VERSION = "1.0.0.beta7" end diff --git a/test/fixtury/definition_executor_test.rb b/test/fixtury/definition_executor_test.rb index de9fd9b..4295635 100644 --- a/test/fixtury/definition_executor_test.rb +++ b/test/fixtury/definition_executor_test.rb @@ -27,5 +27,15 @@ def test_definition_yields_a_dependency_store_if_arity_is_positive executor.call end + def test_return_value_is_an_output_object + dfn = ::Fixtury::Definition.new(name: "foo") { |s| s.get("thing") } + executor = ::Fixtury::DefinitionExecutor.new(definition: dfn) + Fixtury::DependencyStore.any_instance.expects(:get).with("thing").once.returns("foobar") + output = executor.call + assert_instance_of ::Fixtury::DefinitionExecutor::Output, output + assert_equal "foobar", output.value + assert output.metadata.key?(:duration) + end + end end diff --git a/test/fixtury/store_test.rb b/test/fixtury/store_test.rb index 1d83fb6..c2aaf50 100644 --- a/test/fixtury/store_test.rb +++ b/test/fixtury/store_test.rb @@ -37,7 +37,9 @@ def test_a_store_holds_references_to_fixtures def test_a_store_returns_an_existing_reference_rather_than_reinvoking_the_definition store = ::Fixtury::Store.new(schema: schema) - Fixtury::DefinitionExecutor.any_instance.expects(:call).once.returns("baz") + output = DefinitionExecutor::Output.new + output.stubs(:value).returns("baz") + Fixtury::DefinitionExecutor.any_instance.expects(:call).once.returns(output) assert_equal "baz", store["foo"] assert_equal "baz", store["foo"] @@ -68,6 +70,24 @@ def test_a_ttl_store_does_not_return_expired_refs refute_equal ref.created_at, new_ref.created_at end + def test_generated_references_hold_metadata + dfn = schema.get("foo") + dfn.stubs(:isolation_key).returns("some_isolation_key") + store = ::Fixtury::Store.new(schema: schema) + output = DefinitionExecutor::Output.new + output.stubs(:value).returns("baz") + output.stubs(:metadata).returns({ meta_foo: "metabar" }) + Fixtury::DefinitionExecutor.any_instance.expects(:call).once.returns(output) + + store.get("foo") + ref = store.references[dfn.pathname] + + assert_equal({ + isolation_key: "some_isolation_key", + meta_foo: "metabar" + }, ref.metadata) + end + def test_a_store_doesnt_allow_circular_references store = ::Fixtury::Store.new(schema: circular_schema) assert_raises Errors::CircularDependencyError do @@ -83,7 +103,9 @@ def test_a_store_doesnt_allow_circular_references def test_store_reloads_value_if_locator_cannot_find store = ::Fixtury::Store.new(schema: schema) - Fixtury::DefinitionExecutor.any_instance.expects(:call).twice.returns("baz") + output = DefinitionExecutor::Output.new + output.stubs(:value).returns("baz") + Fixtury::DefinitionExecutor.any_instance.expects(:call).twice.returns(output) assert_equal "baz", store["foo"] store.locator.stubs(:load).returns(nil)