Skip to content

Commit

Permalink
Allow smart answer flows to be defined at runtime not load time
Browse files Browse the repository at this point in the history
This makes it possible to define smart answer flows as a subclass of
`SmartAnswer::Flow` such that we can obtain test coverage data for the flow
logic.

This data was not previously available [1], because the flow files were being
read and eval'ed (at load time) rather than simply required. The latter is
necessary [2] for `SimpleCov` to record coverage data for the file.

By extracting the existing DSL code into a `define` method on a subclass of
`SmartAnswer::Flow`, we can safely require the file separately from
instantiating the flow. This feels like a better state of affairs in general,
but it specifically addresses the test coverage problem above.

We'd want to have this coverage data available so we can have confidence
that we're not breaking anything as we continue to refactor the app. No flows
have been converted in this commit, it just makes it possible to convert them.
The plan is to convert each flow one at a time in subsequent commits.

I've chosen to suffix the subclass name with the word `Flow`, because I hit
autoloading problems when running **all** the tests, because there are a bunch
of classes in the `SmartAnswer::Calculators` namespace with the same name as
flows.

[1]: https://ci-new.alphagov.co.uk/job/govuk_smart_answers/2396/rcov/
[2]: simplecov-ruby/simplecov#38
  • Loading branch information
floehopper committed May 18, 2015
1 parent 4eea66d commit 0800f52
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions lib/smart_answer/flow_registry.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
SMART_ANSWER_FLOW_NAMES = %w()

SMART_ANSWER_FLOW_NAMES.each do |name|
require "smart_answer_flows/#{name}"
end

module SmartAnswer
class FlowRegistry
class NotFound < StandardError; end
Expand Down Expand Up @@ -51,10 +57,18 @@ def available?(name)
end

def build_flow(name)
absolute_path = @load_path.join("#{name}.rb").to_s
Flow.new do
eval(File.read(absolute_path), binding, absolute_path)
name(name)
if SMART_ANSWER_FLOW_NAMES.include?(name)
class_prefix = name.gsub("-", "_").camelize
namespaced_class = "SmartAnswer::#{class_prefix}Flow".constantize
flow = namespaced_class.new
flow.define
flow
else
absolute_path = @load_path.join("#{name}.rb").to_s
Flow.new do
eval(File.read(absolute_path), binding, absolute_path)
name(name)
end
end
end

Expand Down

0 comments on commit 0800f52

Please sign in to comment.