Skip to content

Commit

Permalink
Extract step_match caching to a decorator.
Browse files Browse the repository at this point in the history
I've left the creation of th cache explicit at construction for the
moment. There may be a better api we can use, but wanted to wait to see
if we can reuse it in plugins first.
  • Loading branch information
tooky authored and mattwynne committed Jul 8, 2015
1 parent 225e559 commit 88dbdcd
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 20 deletions.
2 changes: 1 addition & 1 deletion lib/cucumber/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Runtime

def initialize(configuration = Configuration.default)
@configuration = Configuration.parse(configuration)
@support_code = SupportCode.new(self, @configuration)
@support_code = SupportCode::CachesStepMatch.new SupportCode.new(self, @configuration)
@results = Formatter::LegacyApi::Results.new
end

Expand Down
26 changes: 14 additions & 12 deletions lib/cucumber/runtime/support_code.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,25 +148,16 @@ def find_around_hooks(test_case)
end
end

def step_match(step_name, name_to_report=nil) #:nodoc:
@match_cache ||= {}

match = @match_cache[[step_name, name_to_report]]
return match if match

@match_cache[[step_name, name_to_report]] = step_match_without_cache(step_name, name_to_report)
end

private

def step_match_without_cache(step_name, name_to_report=nil)
def step_match(step_name, name_to_report=nil)
matches = matches(step_name, name_to_report)
raise Undefined.new(step_name) if matches.empty?
matches = best_matches(step_name, matches) if matches.size > 1 && guess_step_matches?
raise Ambiguous.new(step_name, matches, guess_step_matches?) if matches.size > 1
matches[0]
end

private

def guess_step_matches?
@configuration.guess?
end
Expand Down Expand Up @@ -200,6 +191,17 @@ def log
Cucumber.logger
end

require 'delegate'
class CachesStepMatch < SimpleDelegator
def step_match(step_name, name_to_report=nil) #:nodoc:
@match_cache ||= {}

match = @match_cache[[step_name, name_to_report]]
return match if match

@match_cache[[step_name, name_to_report]] = super(step_name, name_to_report)
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/cucumber/step_definitions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Cucumber
class StepDefinitions
def initialize(configuration = Configuration.default)
configuration = Configuration.parse(configuration)
@support_code = Runtime::SupportCode.new(nil, configuration)
@support_code = Runtime::SupportCode::CachesStepMatch.new Runtime::SupportCode.new(nil, configuration)
@support_code.load_files_from_paths(configuration.autoload_code_paths)
end

Expand Down
16 changes: 10 additions & 6 deletions spec/cucumber/runtime/support_code_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ module Cucumber
expect(format).to eq "it [snows] in [april]"
end

it "caches step match results" do
dsl.Given(/it (.*) in (.*)/) { |what, month| }
context 'caching' do
let(:cached) { Runtime::SupportCode::CachesStepMatch.new(subject) }

it "caches step match results" do
dsl.Given(/it (.*) in (.*)/) { |what, month| }

step_match = subject.step_match("it snows in april")
step_match = cached.step_match("it snows in april")

expect(@rb).not_to receive(:step_matches)
second_step_match = subject.step_match("it snows in april")
expect(@rb).not_to receive(:step_matches)
second_step_match = cached.step_match("it snows in april")

expect(step_match).to equal(second_step_match)
expect(step_match).to equal(second_step_match)
end
end

describe "resolving step defintion matches" do
Expand Down

0 comments on commit 88dbdcd

Please sign in to comment.