diff --git a/lib/scientist/experiment.rb b/lib/scientist/experiment.rb index ec35a3a..ab38841 100644 --- a/lib/scientist/experiment.rb +++ b/lib/scientist/experiment.rb @@ -84,6 +84,7 @@ def raise_on_mismatches? # # Returns the configured block. def before_run(&block) + marshalize(block) @_scientist_before_run = block end @@ -99,6 +100,7 @@ def behaviors # # Returns the configured block. def clean(&block) + marshalize(block) @_scientist_cleaner = block end @@ -131,6 +133,7 @@ def clean_value(value) # # Returns the block. def compare(*args, &block) + marshalize(block) @_scientist_comparator = block end @@ -141,6 +144,7 @@ def compare(*args, &block) # # Returns the block. def compare_errors(*args, &block) + marshalize(block) @_scientist_error_comparator = block end @@ -159,6 +163,7 @@ def context(context = nil) # # This can be called more than once with different blocks to use. def ignore(&block) + marshalize(block) @_scientist_ignores ||= [] @_scientist_ignores << block end @@ -251,6 +256,7 @@ def run(name = nil) # Define a block that determines whether or not the experiment should run. def run_if(&block) + marshalize(block) @_scientist_run_if_block = block end @@ -276,6 +282,7 @@ def should_experiment_run? # Register a named behavior for this experiment, default "candidate". def try(name = nil, &block) + marshalize(block) name = (name || "candidate").to_s if behaviors.include?(name) @@ -287,6 +294,7 @@ def try(name = nil, &block) # Register the control behavior for this experiment. def use(&block) + marshalize(block) try "control", &block end @@ -318,4 +326,12 @@ def generate_result(name) control = observations.detect { |o| o.name == name } Scientist::Result.new(self, observations, control) end + + private + + def marshalize(block) + def block._dump(_) + to_s + end + end end diff --git a/test/scientist/experiment_test.rb b/test/scientist/experiment_test.rb index e102473..12462f6 100644 --- a/test/scientist/experiment_test.rb +++ b/test/scientist/experiment_test.rb @@ -491,6 +491,27 @@ def @ex.raised(op, exception) assert_raises(Scientist::Experiment::MismatchError) { runner.call } end + it "can be marshaled" do + Fake.raise_on_mismatches = true + @ex.before_run { "some block" } + @ex.clean { "some block" } + @ex.compare_errors { "some block" } + @ex.ignore { false } + @ex.run_if { "some block" } + @ex.try { "candidate" } + @ex.use { "control" } + @ex.compare { |control, candidate| control == candidate } + + mismatch = nil + begin + @ex.run + rescue Scientist::Experiment::MismatchError => e + mismatch = e + end + + assert_kind_of(String, Marshal.dump(mismatch)) + end + describe "#raise_on_mismatches?" do it "raises when there is a mismatch if the experiment instance's raise on mismatches is enabled" do Fake.raise_on_mismatches = false