Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove predicate functionality #2163

Merged
merged 23 commits into from
Nov 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23c8263
Update question_base_test.rb
chrisroos Nov 23, 2015
9a64913
Avoid using next_node_if from next_node
chrisroos Nov 23, 2015
aa84e1a
Don't iterate over next_node_function_chain in GraphPresenter
chrisroos Nov 23, 2015
5f2fde3
Remove unused responded_with_commonwealth_country? method
chrisroos Nov 23, 2015
5555e56
Update checksum data for marriage-abroad
chrisroos Nov 23, 2015
bc84bd0
Update checksum data for register-a-birth
chrisroos Nov 23, 2015
393d25f
Update checksum data for register-a-death
chrisroos Nov 23, 2015
2595c6c
Remove Question::Checkbox#response_is_one_of
chrisroos Nov 23, 2015
6c9debd
Remove Question::Checkbox#response_has_all_of
chrisroos Nov 23, 2015
a7dccc8
Remove Question::Checkbox#response_is_only
chrisroos Nov 23, 2015
d00ce6c
Remove Question::Base#responded_with
chrisroos Nov 23, 2015
1fe9dab
Remove Question::Base#variable_matches
chrisroos Nov 23, 2015
7412c0d
Remove Question::Base#define_predicate
chrisroos Nov 23, 2015
31237f7
Remove Question::Base#on_condition
chrisroos Nov 23, 2015
5e0d0ad
Remove Question::Base#next_node_if
chrisroos Nov 23, 2015
c135030
Remove Question::Base#normalize_predicates
chrisroos Nov 23, 2015
7171834
Remove Question::Base#method_missing
chrisroos Nov 23, 2015
c461aa2
Remove Question::Base#respond_to_missing?
chrisroos Nov 23, 2015
1b5c4cc
Remove Question::Base#next_node_from_function_chain
chrisroos Nov 23, 2015
cbacce2
Remove Predicate::Callable
chrisroos Nov 23, 2015
447b99e
Remove Predicate::Base
chrisroos Nov 23, 2015
1d4bff5
Remove the use of predicates from the docs
chrisroos Nov 23, 2015
91f9275
Remove smart-answers-predicates.md
chrisroos Nov 23, 2015
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
13 changes: 0 additions & 13 deletions doc/smart-answer-flows.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,6 @@ next_node(permitted: permitted_next_nodes) do |response|
end
```

#### DEPRECATED: Using predicates

This is the same example from above expressed using predicates:

```ruby
next_node_if(:green, responded_with('green')) )
next_node(:red)
```

The `responded_with` function actually returns a [predicate](http://en.wikipedia.org/wiki/Predicate_%28mathematical_logic%29) which will be invoked during processing. If the predicate returns `true` then the `:green` node will be next, otherwise the next rule will be evaluated. In this case the next rule says `:red` is the next node with no condition.

See [Smart Answer predicates](smart-answers-predicates.md) for more detailed information about this style.

### Storing data for later use

You can use the `precalculate`, `next_node_calculation`, `save_input_as` and `calculate` methods to store data for later use.
Expand Down
47 changes: 0 additions & 47 deletions doc/smart-answers-predicates.md

This file was deleted.

3 changes: 0 additions & 3 deletions lib/graph_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ def adjacency_list
adjacency_list = {}
@flow.questions.each do |node|
adjacency_list[node.name] = []
node.next_node_function_chain.each do |(nextnode, predicates)|
adjacency_list[node.name] << [nextnode, predicates.map(&:label).compact.join(" AND\n")]
end
node.permitted_next_nodes.each do |permitted_next_node|
existing_next_nodes = adjacency_list[node.name].map(&:first)
unless existing_next_nodes.include?(permitted_next_node)
Expand Down
4 changes: 0 additions & 4 deletions lib/smart_answer/calculators/registrations_data_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ def commonwealth_country?(country_slug)
COMMONWEALTH_COUNTRIES.include?(country_slug)
end

def responded_with_commonwealth_country?
SmartAnswer::Predicate::RespondedWith.new(COMMONWEALTH_COUNTRIES, "commonwealth country")
end

def has_consulate?(country_slug)
COUNTRIES_WITH_CONSULATES.include?(country_slug)
end
Expand Down
35 changes: 0 additions & 35 deletions lib/smart_answer/predicate/base.rb

This file was deleted.

18 changes: 0 additions & 18 deletions lib/smart_answer/predicate/callable.rb

This file was deleted.

22 changes: 0 additions & 22 deletions lib/smart_answer/predicate/responded_with.rb

This file was deleted.

17 changes: 0 additions & 17 deletions lib/smart_answer/predicate/response_has_all_of.rb

This file was deleted.

17 changes: 0 additions & 17 deletions lib/smart_answer/predicate/response_is_one_of.rb

This file was deleted.

53 changes: 0 additions & 53 deletions lib/smart_answer/predicate/variable_matches.rb

This file was deleted.

75 changes: 3 additions & 72 deletions lib/smart_answer/question/base.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
module SmartAnswer
module Question
class Base < Node
attr_reader :next_node_function_chain
class NextNodeUndefined < StandardError; end

def initialize(flow, name, options = {}, &block)
@save_input_as = nil
@validations ||= []
@next_node_function_chain ||= []
@default_next_node_function ||= lambda {|_|}
@permitted_next_nodes = []
@predicate_stack = []
@predicates = {}
@uses_erb_template = options[:use_erb_template]
super
end
Expand All @@ -24,18 +20,13 @@ def next_node(next_node = nil, permitted: [], &block)
@permitted_next_nodes += permitted
@default_next_node_function = block
elsif next_node
next_node_if(next_node)
@permitted_next_nodes = [next_node]
@default_next_node_function = proc { next_node }
else
raise ArgumentError
end
end

def next_node_if(next_node, *predicates, &block)
predicates << block if block_given?
@next_node_function_chain << [next_node, normalize_predicates(@predicate_stack + predicates)]
@permitted_next_nodes << next_node
end

def validate(message = nil, &block)
@validations << [message, block]
end
Expand All @@ -46,7 +37,7 @@ def permitted_next_nodes(*args)

def next_node_for(current_state, input)
validate!(current_state, input)
next_node = next_node_from_function_chain(current_state, input) || next_node_from_default_function(current_state, input)
next_node = next_node_from_default_function(current_state, input)
responses_and_input = current_state.responses + [input]
raise NextNodeUndefined.new("Next node undefined. Node: #{current_state.current_node}. Responses: #{responses_and_input}") unless next_node
unless @permitted_next_nodes.include?(next_node)
Expand Down Expand Up @@ -74,47 +65,6 @@ def transition(current_state, raw_input)
new_state
end

# Within an #on_condition block, all #next_node and #next_node_if
# clauses must additionally satisfy the given predicate. Nesting of
# #on_condition blocks is permitted.
#
# Example:
#
# on_condition(->(r) {r == 'tourism'}) do
# next_node_if(:outcome_visit_waiver) { %w(oman qatar united-arab-emirates).include?(passport_country) }
# next_node_if(:outcome_taiwan_exception) { %w(taiwan).include?(passport_country) }
# next_node_if(:outcome_school_n) do
# country_group_non_visa_national.include?(passport_country) or country_group_ukot.include?(passport_country))
# end
# next_node(:outcome_general_y)
# end
def on_condition(predicate, &block)
@predicate_stack << predicate
instance_eval(&block)
@predicate_stack.pop
end

def responded_with(acceptable_responses)
SmartAnswer::Predicate::RespondedWith.new(acceptable_responses)
end

def variable_matches(variable_name, acceptable_responses)
SmartAnswer::Predicate::VariableMatches.new(variable_name, acceptable_responses)
end

def define_predicate(identifier, label = nil, &block)
raise "method #{identifier} already defined" if self.class.method_defined?(identifier)
@predicates[identifier] = SmartAnswer::Predicate::Callable.new(label || identifier.to_s, &block)
end

def respond_to_missing?(method, include_private = false)
@predicates.has_key?(method)
end

def method_missing(method, *args, &block)
@predicates.fetch(method)
end

def parse_input(raw_input)
raw_input
end
Expand Down Expand Up @@ -148,25 +98,6 @@ def validate!(current_state, input)
end
end

def normalize_predicates(predicates)
predicates.map do |predicate|
if predicate.is_a?(SmartAnswer::Predicate::Base)
predicate
else
SmartAnswer::Predicate::Callable.new(nil, predicate)
end
end
end

def next_node_from_function_chain(current_state, input)
found = @next_node_function_chain.find do |(_, predicates)|
predicates.all? do |predicate|
predicate.call(current_state, input)
end
end
found && found.first
end

def next_node_from_default_function(current_state, input)
current_state.instance_exec(input, &@default_next_node_function)
end
Expand Down
Loading