smartdown 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/smartdown CHANGED
@@ -17,7 +17,6 @@ if ARGV.size == 0
17
17
  else
18
18
  coversheet_path, *responses = ARGV
19
19
  begin
20
- #TODO: use same object as smartdown-frontend will be using here
21
20
  input = Smartdown::Parser::DirectoryInput.new(coversheet_path)
22
21
  flow = Smartdown::Parser::FlowInterpreter.new(input).interpret
23
22
  engine = Smartdown::Engine.new(flow)
@@ -75,10 +75,10 @@ module Smartdown
75
75
  if node.elements.any?{|element| element.is_a? Smartdown::Model::Element::StartButton}
76
76
  Smartdown::Api::Coversheet.new(node)
77
77
  elsif node.elements.any?{|element| element.is_a? Smartdown::Model::NextNodeRules}
78
- if node.elements.any?{|element| element.is_a? Smartdown::Model::Element::MultipleChoice}
78
+ if node.elements.any?{|element| element.class.to_s.include?("Smartdown::Model::Element::Question")}
79
79
  Smartdown::Api::QuestionPage.new(node)
80
80
  else
81
- #TODO: support other types of questions
81
+ raise("Unknown node type: #{node.elements.map(&:class)}")
82
82
  end
83
83
  else
84
84
  Smartdown::Api::Outcome.new(node)
@@ -4,22 +4,17 @@ module Smartdown
4
4
  module Api
5
5
  class MultipleChoice < Question
6
6
  def options
7
- question = elements.find{|element| element.is_a? Smartdown::Model::Element::MultipleChoice}
7
+ question = elements.find{|element| element.is_a? Smartdown::Model::Element::Question::MultipleChoice}
8
8
  question.choices.map do |choice|
9
9
  OpenStruct.new(:label => choice[1], :value => choice[0])
10
10
  end
11
11
  end
12
12
 
13
13
  def name
14
- question = elements.find{|element| element.is_a? Smartdown::Model::Element::MultipleChoice}
14
+ question = elements.find{|element| element.is_a? Smartdown::Model::Element::Question::MultipleChoice}
15
15
  question.name
16
16
  end
17
17
 
18
- #TODO: move to presenters in smart-answer app
19
- def partial_template_name
20
- "multiple_choice_question"
21
- end
22
-
23
18
  end
24
19
  end
25
20
  end
@@ -6,33 +6,26 @@ module Smartdown
6
6
 
7
7
  def initialize(node)
8
8
  node_elements = node.elements.clone
9
- headings = node_elements.select {
10
- |element| element.is_a? Smartdown::Model::Element::MarkdownHeading
9
+ headings = node_elements.select { |element|
10
+ element.is_a? Smartdown::Model::Element::MarkdownHeading
11
11
  }
12
12
  @title = headings.first.content.to_s if headings.first
13
- node_elements.delete(headings.first) #Remove page title
13
+ nb_questions = node_elements.select{ |element|
14
+ element.is_a? Smartdown::Model::Element::Question::MultipleChoice
15
+ }.count
16
+ if headings.count > nb_questions
17
+ node_elements.delete(headings.first) #Remove page title
18
+ end
14
19
  @elements = node_elements
15
20
  @front_matter = node.front_matter
16
21
  @name = node.name
17
22
  end
18
23
 
19
- def has_title?
20
- !!title
21
- end
22
-
23
24
  def body
24
25
  elements_before_smartdown = elements.take_while{|element| !smartdown_element?(element)}
25
26
  build_govspeak(elements_before_smartdown)
26
27
  end
27
28
 
28
- def has_body?
29
- !!body
30
- end
31
-
32
- def has_devolved_body?
33
- !!devolved_body
34
- end
35
-
36
29
  def devolved_body
37
30
  elements_after_smartdown = elements.drop_while{|element| !smartdown_element?(element)}
38
31
  build_govspeak(elements_after_smartdown)
@@ -2,10 +2,6 @@ module Smartdown
2
2
  module Api
3
3
  class Outcome < Node
4
4
 
5
- def has_next_steps?
6
- !!next_steps
7
- end
8
-
9
5
  def next_steps
10
6
  next_step_element = elements.find{|element| element.is_a? Smartdown::Model::Element::NextSteps}
11
7
  GovspeakPresenter.new(next_step_element.content).html if next_step_element
@@ -1,29 +1,17 @@
1
1
  module Smartdown
2
2
  module Api
3
3
  class PreviousQuestion
4
+ extend Forwardable
4
5
 
5
- attr_reader :response, :title
6
+ def_delegators :@question, :title, :options
6
7
 
7
- def initialize(title, question_element, response, modifiable)
8
- @title = title
9
- @question_element = question_element
10
- @response = response
11
- @modifiable = modifiable
12
- end
13
-
14
- #TODO: remove need for this method by impleemnting modification properly
15
- def modifiable?
16
- @modifiable
17
- end
8
+ attr_reader :response
18
9
 
19
- #TODO: to be moved to presenter
20
- def multiple_responses?
21
- false
22
- end
23
-
24
- #TODO: move to presenter, this object API should only expose question_element.choices
25
- def response_label(value=response)
26
- @question_element.choices.fetch(value)
10
+ def initialize(elements, response)
11
+ @response = response
12
+ if elements.find{|element| element.is_a? Smartdown::Model::Element::Question::MultipleChoice}
13
+ @question = MultipleChoice.new(elements)
14
+ end
27
15
  end
28
16
 
29
17
  end
@@ -0,0 +1,38 @@
1
+ require 'smartdown/api/previous_question'
2
+
3
+ module Smartdown
4
+ module Api
5
+ class PreviousQuestionPage
6
+
7
+ attr_reader :title
8
+
9
+ def initialize(node, responses)
10
+ node_elements = node.elements.clone
11
+ headings = node_elements.select {
12
+ |element| element.is_a? Smartdown::Model::Element::MarkdownHeading
13
+ }
14
+ @title = headings.first.content.to_s if headings.first
15
+ nb_questions = node_elements.select{ |element|
16
+ element.is_a? Smartdown::Model::Element::Question::MultipleChoice
17
+ }.count
18
+ if headings.count > nb_questions
19
+ node_elements.delete(headings.first) #Remove page title
20
+ end
21
+ @elements = node_elements
22
+ @responses = responses
23
+ end
24
+
25
+ def questions
26
+ elements.slice_before do |element|
27
+ element.is_a? Smartdown::Model::Element::MarkdownHeading
28
+ end.each_with_index.map do |question_element_group, index|
29
+ Smartdown::Api::PreviousQuestion.new(question_element_group, responses[index])
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :elements, :responses
36
+ end
37
+ end
38
+ end
@@ -2,57 +2,23 @@ module Smartdown
2
2
  module Api
3
3
  class Question
4
4
 
5
- attr_reader :number
6
-
7
- def initialize(elements, number=nil)
5
+ def initialize(elements)
8
6
  @elements = elements
9
- @number = number
10
7
  end
11
8
 
12
- #TODO: this assumes the title is the first element
13
9
  def title
14
10
  elements.first.content
15
11
  end
16
12
 
17
- def has_body?
18
- !!body
19
- end
20
-
21
13
  def body
22
14
  elements_before_smartdown = elements[1..-1].take_while{|element| !smartdown_element?(element)}
23
15
  build_govspeak(elements_before_smartdown)
24
16
  end
25
17
 
26
- def has_hint?
27
- !!hint
28
- end
29
-
30
- #TODO: confirm we can delete this
31
- # Usage TBC, most hints should actually be `body`s, semi-deprecated
32
- # As we transition content we should better define it, or remove it
18
+ #TODO: deprecate
33
19
  def hint
34
20
  end
35
21
 
36
- def prefix
37
- "todo prefix"
38
- end
39
-
40
- def suffix
41
- "todo suffix"
42
- end
43
-
44
- def subtitle
45
- "todo subtitle"
46
- end
47
-
48
- #TODO
49
- def error
50
- end
51
-
52
- #TODO: should not be needed
53
- def responses
54
- end
55
-
56
22
  private
57
23
 
58
24
  attr_reader :elements
@@ -6,8 +6,10 @@ module Smartdown
6
6
  def questions
7
7
  elements.slice_before do |element|
8
8
  element.is_a? Smartdown::Model::Element::MarkdownHeading
9
- end.each_with_index.map do |question_element_group, index|
10
- Smartdown::Api::MultipleChoice.new(question_element_group, index+1)
9
+ end.map do |question_element_group|
10
+ if question_element_group.find{|element| element.is_a? Smartdown::Model::Element::Question::MultipleChoice}
11
+ Smartdown::Api::MultipleChoice.new(question_element_group)
12
+ end
11
13
  end
12
14
  end
13
15
  end
@@ -1,4 +1,4 @@
1
- require 'smartdown/api/previous_question'
1
+ require 'smartdown/api/previous_question_page'
2
2
 
3
3
  module Smartdown
4
4
  module Api
@@ -8,7 +8,7 @@ module Smartdown
8
8
 
9
9
  def initialize(current_node, previous_questionpage_smartdown_nodes, responses)
10
10
  @current_node = current_node
11
- @previous_question_page_nodes = previous_questionpage_smartdown_nodes
11
+ @previous_questionpage_smartdown_nodes = previous_questionpage_smartdown_nodes
12
12
  @responses = responses
13
13
  end
14
14
 
@@ -20,29 +20,10 @@ module Smartdown
20
20
  current_node.is_a? Smartdown::Api::Outcome
21
21
  end
22
22
 
23
- #TODO: refactor this :-O
24
- def previous_questions
25
- response_index = 0
26
- previous_question_nodes.map.each_with_index do |previous_questions, node_index|
27
- previous_questions.map.each_with_index do |previous_question, index|
28
- previous_question = Smartdown::Api::PreviousQuestion.new(
29
- previous_question_title_nodes[node_index][index].content,
30
- previous_question,
31
- responses[response_index],
32
- index == 0
33
- )
34
- response_index+=1
35
- previous_question
36
- end
37
- end.flatten
38
- end
39
-
40
- def previous_question_nodes
41
- @previous_question_page_nodes.map(&:questions)
42
- end
43
-
44
- def previous_question_title_nodes
45
- @previous_question_page_nodes.map(&:question_titles)
23
+ def previous_question_pages(responses)
24
+ previous_questionpage_smartdown_nodes.map do |smartdown_questionpage_node|
25
+ Smartdown::Api::PreviousQuestionPage.new(smartdown_questionpage_node, responses)
26
+ end
46
27
  end
47
28
 
48
29
  def current_question_number
@@ -51,7 +32,7 @@ module Smartdown
51
32
 
52
33
  private
53
34
 
54
- attr_reader :smartdown_state, :previous_question_page_nodes
35
+ attr_reader :smartdown_state, :previous_questionpage_smartdown_nodes
55
36
 
56
37
  end
57
38
  end
@@ -38,7 +38,7 @@ module Smartdown
38
38
  end
39
39
 
40
40
  def input_variable_names_from_question
41
- questions = node.elements.select { |e| e.is_a?(Smartdown::Model::Element::MultipleChoice) }
41
+ questions = node.elements.select { |e| e.class.to_s.include?("Smartdown::Model::Element::Question") }
42
42
  questions.map(&:name)
43
43
  end
44
44
 
@@ -31,9 +31,8 @@ module Smartdown
31
31
  nb_questions = 0
32
32
  current_node = flow.node(state.get(:current_node))
33
33
  nb_questions += current_node.elements.select{|element|
34
- element.is_a? Smartdown::Model::Element::MultipleChoice
34
+ element.class.to_s.include?("Smartdown::Model::Element::Question")
35
35
  }.count
36
-
37
36
  #There is at least one relevant input per transition for now:
38
37
  #Transition from start to first question relies on an input, regardless of its value
39
38
  nb_relevant_inputs = [nb_questions, 1].max
@@ -0,0 +1,9 @@
1
+ module Smartdown
2
+ module Model
3
+ module Element
4
+ module Question
5
+ MultipleChoice = Struct.new(:name, :choices)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -8,15 +8,9 @@ module Smartdown
8
8
  end
9
9
 
10
10
  def questions
11
- elements_of_kind(Smartdown::Model::Element::MultipleChoice)
12
- end
13
-
14
- #Because question titles and page titles use the same markdown,
15
- #there are at least as many or more headings than questions on each page
16
- #To get only the question titles, we are assuming that all the headings that
17
- #are not question headings come first in the markdown, then question headings
18
- def question_titles
19
- h1s.drop(h1s.count - questions.count)
11
+ elements.select do |element|
12
+ element.class.to_s.include?("Smartdown::Model::Element::Question")
13
+ end
20
14
  end
21
15
 
22
16
  def title
@@ -4,7 +4,7 @@ require 'smartdown/model/front_matter'
4
4
  require 'smartdown/model/rule'
5
5
  require 'smartdown/model/nested_rule'
6
6
  require 'smartdown/model/next_node_rules'
7
- require 'smartdown/model/element/multiple_choice'
7
+ require 'smartdown/model/element/question/multiple_choice'
8
8
  require 'smartdown/model/element/start_button'
9
9
  require 'smartdown/model/element/markdown_heading'
10
10
  require 'smartdown/model/element/markdown_paragraph'
@@ -56,7 +56,7 @@ module Smartdown
56
56
  }
57
57
 
58
58
  rule(:multiple_choice => {identifier: simple(:identifier), options: subtree(:choices)}) {
59
- Smartdown::Model::Element::MultipleChoice.new(
59
+ Smartdown::Model::Element::Question::MultipleChoice.new(
60
60
  identifier, Hash[choices]
61
61
  )
62
62
  }
@@ -1,3 +1,3 @@
1
1
  module Smartdown
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -88,7 +88,7 @@ EXPECTED
88
88
  end
89
89
 
90
90
  it "has a multiple choice question" do
91
- expect(question_node.questions).to match([instance_of(Smartdown::Model::Element::MultipleChoice)])
91
+ expect(question_node.questions).to match([instance_of(Smartdown::Model::Element::Question::MultipleChoice)])
92
92
  end
93
93
  end
94
94
  end
@@ -165,7 +165,7 @@ describe Smartdown::Engine::Transition do
165
165
  Smartdown::Model::Node.new(
166
166
  current_node_name,
167
167
  [
168
- Smartdown::Model::Element::MultipleChoice.new(question_name, {"a" => "Apple"}),
168
+ Smartdown::Model::Element::Question::MultipleChoice.new(question_name, {"a" => "Apple"}),
169
169
  Smartdown::Model::NextNodeRules.new(
170
170
  [Smartdown::Model::Rule.new(double("predicate1"), "o1")]
171
171
  )
@@ -32,7 +32,7 @@ describe Smartdown::Parser::Element::MultipleChoiceQuestion do
32
32
  Smartdown::Parser::NodeInterpreter.new(node_name, source, parser: parser).interpret
33
33
  }
34
34
 
35
- it { should eq(Smartdown::Model::Element::MultipleChoice.new("yes_or_no", {"yes"=>"Yes", "no"=>"No"})) }
35
+ it { should eq(Smartdown::Model::Element::Question::MultipleChoice.new("yes_or_no", {"yes"=>"Yes", "no"=>"No"})) }
36
36
  end
37
37
  end
38
38
 
@@ -123,7 +123,7 @@ SOURCE
123
123
  let(:expected_elements) {
124
124
  [
125
125
  Smartdown::Model::Element::MarkdownHeading.new("This is my title"),
126
- Smartdown::Model::Element::MultipleChoice.new("my_question", "yes"=>"Yes", "no"=>"No"),
126
+ Smartdown::Model::Element::Question::MultipleChoice.new("my_question", "yes"=>"Yes", "no"=>"No"),
127
127
  Smartdown::Model::Element::MarkdownHeading.new("Next node rules"),
128
128
  Smartdown::Model::NextNodeRules.new([
129
129
  Smartdown::Model::Rule.new(Smartdown::Model::Predicate::Named.new("pred1?"), "outcome")
@@ -3,7 +3,7 @@ require 'smartdown/model/node'
3
3
  require 'smartdown/model/element/markdown_heading'
4
4
  require 'smartdown/model/element/markdown_paragraph'
5
5
  require 'smartdown/model/element/start_button'
6
- require 'smartdown/model/element/multiple_choice'
6
+ require 'smartdown/model/element/question/multiple_choice'
7
7
  require 'smartdown/model/element/conditional'
8
8
  require 'smartdown/model/next_node_rules'
9
9
  require 'smartdown/model/rule'
@@ -48,7 +48,7 @@ class ModelBuilder
48
48
  def multiple_choice(name, options)
49
49
  @elements ||= []
50
50
  options_with_string_keys = ::Hash[options.map {|k,v| [k.to_s, v]}]
51
- @elements << Smartdown::Model::Element::MultipleChoice.new(name, options_with_string_keys)
51
+ @elements << Smartdown::Model::Element::Question::MultipleChoice.new(name, options_with_string_keys)
52
52
  @elements.last
53
53
  end
54
54
 
@@ -15,7 +15,7 @@ describe ModelBuilder do
15
15
  let(:node2) {
16
16
  Smartdown::Model::Node.new("what_passport_do_you_have?", [
17
17
  Smartdown::Model::Element::MarkdownHeading.new("What passport do you have?"),
18
- Smartdown::Model::Element::MultipleChoice.new("what_passport_do_you_have?", {"greek" => "Greek", "british" => "British"}),
18
+ Smartdown::Model::Element::Question::MultipleChoice.new("what_passport_do_you_have?", {"greek" => "Greek", "british" => "British"}),
19
19
  Smartdown::Model::NextNodeRules.new([
20
20
  Smartdown::Model::Rule.new(
21
21
  Smartdown::Model::Predicate::Named.new("eea_passport?"),
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2014-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parslet
16
- requirement: &20994400 !ruby/object:Gem::Requirement
16
+ requirement: &18315460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.6.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *20994400
24
+ version_requirements: *18315460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &20993600 !ruby/object:Gem::Requirement
27
+ requirement: &18314660 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *20993600
35
+ version_requirements: *18314660
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &20993000 !ruby/object:Gem::Requirement
38
+ requirement: &18314100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *20993000
46
+ version_requirements: *18314100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: gem_publisher
49
- requirement: &20992380 !ruby/object:Gem::Requirement
49
+ requirement: &18313460 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *20992380
57
+ version_requirements: *18313460
58
58
  description:
59
59
  email: david.heath@digital.cabinet-office.gov.uk
60
60
  executables:
@@ -89,6 +89,7 @@ files:
89
89
  - lib/smartdown/api/previous_question.rb
90
90
  - lib/smartdown/api/outcome.rb
91
91
  - lib/smartdown/api/multiple_choice.rb
92
+ - lib/smartdown/api/previous_question_page.rb
92
93
  - lib/smartdown/version.rb
93
94
  - lib/smartdown/engine/node_presenter.rb
94
95
  - lib/smartdown/engine/state.rb
@@ -108,7 +109,7 @@ files:
108
109
  - lib/smartdown/model/element/start_button.rb
109
110
  - lib/smartdown/model/element/next_steps.rb
110
111
  - lib/smartdown/model/element/markdown_heading.rb
111
- - lib/smartdown/model/element/multiple_choice.rb
112
+ - lib/smartdown/model/element/question/multiple_choice.rb
112
113
  - lib/smartdown/model/next_node_rules.rb
113
114
  - lib/smartdown/model/nested_rule.rb
114
115
  - lib/smartdown/model/rule.rb
@@ -167,7 +168,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
167
168
  version: '0'
168
169
  segments:
169
170
  - 0
170
- hash: 3595553799676610551
171
+ hash: -3191894024105276380
171
172
  required_rubygems_version: !ruby/object:Gem::Requirement
172
173
  none: false
173
174
  requirements:
@@ -176,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
177
  version: '0'
177
178
  segments:
178
179
  - 0
179
- hash: 3595553799676610551
180
+ hash: -3191894024105276380
180
181
  requirements: []
181
182
  rubyforge_project:
182
183
  rubygems_version: 1.8.11
@@ -1,7 +0,0 @@
1
- module Smartdown
2
- module Model
3
- module Element
4
- MultipleChoice = Struct.new(:name, :choices)
5
- end
6
- end
7
- end