quby-compiler 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8a3b1948f1047978b5362a22a102cadcf1e73614008ab01ba4c9700ca8a2f49
4
- data.tar.gz: 854cd8345cf21de03ba5262ce08db475b39c106d9ea1874a2106c24a33196820
3
+ metadata.gz: 10321dd1aa2034171ba876aeb77622bde63eac65938ce0a0bec9663119461396
4
+ data.tar.gz: b98a34612065d23a611ae5d0437463fe20557fbc0c238d50034e528676565284
5
5
  SHA512:
6
- metadata.gz: df9bf74043519c50553993a151d30c75ad98d894ed56504705f32d525a5f927e67c54d8af83b287eafe6d05bfef5e744e107527b7dbeb2f898eb1665124b1c5f
7
- data.tar.gz: 2eae0ecda1fa65a11b0fb97189f006136f8c8bff684e6884b8b9b25cbd20c09ef143e3c6a4d0729a4c43b00718994b2d2c85fa2321a02fae6e1fad6cd1093f21
6
+ metadata.gz: a3544401b0db094144e7de1e0e172499a26a37111b73c01abd9ba027c33ac992c0c580e15b3fbd552bf196f70c1ed3dccab12ccb064dc68d3e3d80ff98740bc1
7
+ data.tar.gz: 0dd6d579368d571f57ea15dc20a5711ae8ba7e548049f8fd0abaaa43f15d1ca1454c1711f573e3d6b5143d198cbca8878f37399219a67c8330396c6fb57eb09e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 0.4.6
2
+
3
+ * Added type validations for boolean attributes
4
+ * roqua.json
5
+ * add unit to questions
6
+ * add title_question_key to questions
7
+ * add parent_question_key and parent_option_key to questions
8
+ * add child_question_keys to question_options
9
+ * models
10
+ * Made title_question attribute on question instead of adding options.last.questions.
11
+ * Made v1 serializer create backward compatible json (for now)
12
+ * Made v1 serializer add the full title_question json to question.title_question.
13
+
1
14
  # 0.4.5
2
15
 
3
16
  * roqua.json: Don't add inner titles and placeholder options
@@ -114,16 +114,6 @@ module Quby
114
114
  def initialize(key, **options, &block)
115
115
  super
116
116
  @default_question_options = options[:default_question_options] || {}
117
- @title_question = nil
118
- end
119
-
120
- def build
121
- if @title_question
122
- @question.options.last.questions << @title_question
123
- @title_question = nil
124
- end
125
-
126
- super
127
117
  end
128
118
 
129
119
  def title_question(key, **options, &block)
@@ -138,7 +128,7 @@ module Quby
138
128
  question = QuestionBuilder.build(key, **options, &block)
139
129
 
140
130
  @questionnaire.register_question(question)
141
- @title_question = question
131
+ @question.title_question = question
142
132
  end
143
133
 
144
134
  def question(key, **options, &block)
@@ -29,9 +29,11 @@ module Quby
29
29
 
30
30
  # To hide old questions
31
31
  attr_accessor :hidden
32
+ validates :hidden, inclusion: {in: [true, false, nil], message: "must be boolean"}
32
33
 
33
34
  # Whether to skip the uniqueness validation on radio and select option values
34
35
  attr_reader :allow_duplicate_option_values
36
+ validates :allow_duplicate_option_values, inclusion: {in: [true, false, nil], message: "must be boolean"}
35
37
 
36
38
  # In what modes do we display this question
37
39
  # NOTE We always display questions in print-view (if they have an answer)
@@ -40,9 +42,13 @@ module Quby
40
42
  # Multiple-choice questions have options to choose from
41
43
  attr_accessor :options
42
44
 
45
+ # string question that is displayed after the title of this question.
46
+ attr_accessor :title_question
47
+
43
48
  # Question validation fails when there are no title and no context_free_title.
44
49
  # When :allow_blank_titles => true passed, validation does not fail. Any other value will raise the failure.
45
50
  attr_accessor :allow_blank_titles
51
+ validates :allow_blank_titles, inclusion: {in: [true, false, nil], message: "must be boolean"}
46
52
 
47
53
  # Minimum and maximum values for float and integer types
48
54
  attr_accessor :minimum
@@ -72,6 +78,7 @@ module Quby
72
78
 
73
79
  # Whether this radio question is deselectable
74
80
  attr_accessor :deselectable
81
+ validates :deselectable, inclusion: {in: [true, false, nil], message: "must be boolean"}
75
82
 
76
83
  # Some questions are a tree.
77
84
  attr_accessor :parent
@@ -79,6 +86,7 @@ module Quby
79
86
 
80
87
  # Whether we can collapse this in bulk view
81
88
  attr_accessor :disallow_bulk
89
+ validates :disallow_bulk, inclusion: {in: [true, false, nil], message: "must be boolean"}
82
90
 
83
91
  # This question should not validate itself unless the depends_on question is answered.
84
92
  # May also be an array of "#{question_key}_#{option_key}" strings that specify options
@@ -115,6 +123,7 @@ module Quby
115
123
  attr_accessor :row_span
116
124
 
117
125
  attr_accessor :default_invisible
126
+ validates :default_invisible, inclusion: {in: [true, false], message: "must be boolean"}
118
127
 
119
128
  # Slider only: where to place the sliding thing by default
120
129
  # Can have value :hidden for a hidden handle.
@@ -247,6 +256,10 @@ module Quby
247
256
  end
248
257
  end
249
258
 
259
+ def title_question?
260
+ presentation == :next_to_title
261
+ end
262
+
250
263
  # Returns all keys belonging to html inputs generated by this question.
251
264
  def input_keys
252
265
  if options.blank?
@@ -4,6 +4,8 @@ module Quby
4
4
  module Compiler
5
5
  module Entities
6
6
  class QuestionOption
7
+ include ActiveModel::Validations
8
+
7
9
  MARKDOWN_ATTRIBUTES = %w(description).freeze
8
10
 
9
11
  attr_reader :key
@@ -11,16 +13,17 @@ module Quby
11
13
  attr_reader :description
12
14
  attr_reader :questions
13
15
  attr_reader :inner_title
16
+ validates :inner_title, inclusion: {in: [true, false, nil], message: "must be boolean"}
14
17
  attr_reader :hides_questions
15
18
  attr_reader :shows_questions
16
19
  attr_reader :hidden
20
+ validates :hidden, inclusion: {in: [true, false], message: "must be boolean"}
17
21
  attr_reader :placeholder
22
+ validates :placeholder, inclusion: {in: [true, false], message: "must be boolean"}
18
23
  attr_reader :question
19
24
  attr_reader :view_id
20
25
  attr_reader :input_key
21
26
 
22
- attr_reader :start_chosen
23
-
24
27
  def initialize(key, question, options = {})
25
28
  @key = key
26
29
  @question = question
@@ -61,6 +61,7 @@ module Quby
61
61
  question_type: question.type,
62
62
  key: question.key,
63
63
  title: question.title,
64
+ title_question: (question_as_json(question.title_question) if question.title_question),
64
65
  context_free_title: question.context_free_title,
65
66
  description: question.description,
66
67
  presentation: question.presentation,
@@ -96,7 +97,7 @@ module Quby
96
97
  case question
97
98
  when Quby::Compiler::Entities::Questions::CheckboxQuestion
98
99
  base_options.merge(
99
- options: question.options.map { |option| option_as_json(option) },
100
+ options: options_as_json(question),
100
101
  check_all_option: question.check_all_option,
101
102
  uncheck_all_option: question.uncheck_all_option,
102
103
  maximum_checked_allowed: question.maximum_checked_allowed,
@@ -114,7 +115,7 @@ module Quby
114
115
  )
115
116
  when Quby::Compiler::Entities::Questions::DeprecatedQuestion
116
117
  base_options.merge(
117
- options: question.options.map { |option| option_as_json(option) }
118
+ options: options_as_json(question)
118
119
  )
119
120
  when Quby::Compiler::Entities::Questions::FloatQuestion
120
121
  base_options.merge(
@@ -130,11 +131,11 @@ module Quby
130
131
  )
131
132
  when Quby::Compiler::Entities::Questions::RadioQuestion
132
133
  base_options.merge(
133
- options: question.options.map { |option| option_as_json(option) }
134
+ options: options_as_json(question)
134
135
  )
135
136
  when Quby::Compiler::Entities::Questions::SelectQuestion
136
137
  base_options.merge(
137
- options: question.options.map { |option| option_as_json(option) }
138
+ options: options_as_json(question)
138
139
  )
139
140
  when Quby::Compiler::Entities::Questions::StringQuestion
140
141
  base_options.merge(
@@ -177,6 +178,16 @@ module Quby
177
178
  end
178
179
  end
179
180
 
181
+ # Also adds the title question under the last option.
182
+ # TODO old dsl put it there, remove after quby gem uses title_question
183
+ def options_as_json(question)
184
+ question.options.map { |option| option_as_json(option) }.tap do |options_json|
185
+ if question.title_question
186
+ options_json.last[:questions] << question_as_json(question.title_question)
187
+ end
188
+ end
189
+ end
190
+
180
191
  def option_as_json(option)
181
192
  {
182
193
  key: option.key,
@@ -161,8 +161,12 @@ module Quby
161
161
  # type [string]
162
162
  # title [nil/string] no html
163
163
  # context_free_title [nil/string] no html, defaulted to title
164
+ # unit [nil/string] no html (not in quby either)
164
165
  # deprecated [nil/true] only show if filled for old answers
165
166
  # default_invisible [nil/true] only show if filled or when all questions are shown
167
+ # parent_question_key [nil/string] title_questions or question defined under option
168
+ # parent_option_key [nil/string] question defined under option
169
+ # title_question_key [nil/string]
166
170
  # date_parts [nil/{..}]
167
171
  # options: [nil/{..}]
168
172
  def questions
@@ -175,16 +179,20 @@ module Quby
175
179
  type: QUBY_TYPE_TO_ROQUA_TYPE.fetch(question.type),
176
180
  title: strip_tags_without_html_encode(question.title),
177
181
  context_free_title: strip_tags_without_html_encode(question.context_free_title),
182
+ unit: question.unit,
178
183
  deprecated: question.hidden.presence,
179
184
  default_invisible: question.default_invisible.presence,
185
+ parent_question_key: question.parent&.key,
186
+ parent_option_key: question.parent_option_key,
187
+ title_question_key: question.title_question&.key,
180
188
  date_parts: date_parts_for(question),
181
- options: options_for(question),
189
+ options: options_for(question)
182
190
  }.compact
183
191
  ]
184
192
  }
185
193
  end
186
194
 
187
- # {year_key: {key: "v_date_yyyy"}, ..}
195
+ # {year: {key: "v_date_yyyy"}, ..}
188
196
  # key [string]
189
197
  def date_parts_for(question)
190
198
  return nil unless question.type == :date
@@ -203,6 +211,7 @@ module Quby
203
211
  # key [string]
204
212
  # value [nil/string] nil for check_box, string otherwise
205
213
  # description [nil/string] context_free_description, no html
214
+ # child_question_keys [nil/[string]]
206
215
  def options_for(question)
207
216
  return nil if question.options.empty?
208
217
 
@@ -213,7 +222,8 @@ module Quby
213
222
  {
214
223
  key: option.key,
215
224
  value: (option.value.to_s unless question.type == :check_box),
216
- description: strip_tags_without_html_encode(option.context_free_description)
225
+ description: strip_tags_without_html_encode(option.context_free_description),
226
+ child_question_keys: option.questions.map(&:key).presence
217
227
  }.compact
218
228
  ]
219
229
  }
@@ -246,7 +256,7 @@ module Quby
246
256
  end
247
257
 
248
258
  def strip_tags_without_html_encode(html)
249
- Nokogiri::HTML(html).text
259
+ Nokogiri::HTML(html).text.presence
250
260
  end
251
261
  end
252
262
  end
@@ -100,6 +100,9 @@ module Quby
100
100
  def validate_question_options(questionnaire, question)
101
101
  question.options.each do |option|
102
102
  msg_base = "Question #{option.question.key} option #{option.key}"
103
+ unless option.valid?
104
+ fail "#{msg_base} #{option.errors.full_messages.to_sentence}"
105
+ end
103
106
  to_be_hidden_questions_exist_and_not_subquestion?(questionnaire, option, msg_base: msg_base)
104
107
  to_be_shown_questions_exist_and_not_subquestion?(questionnaire, option, msg_base: msg_base)
105
108
  end
@@ -1,5 +1,5 @@
1
1
  module Quby
2
2
  module Compiler
3
- VERSION = "0.4.5"
3
+ VERSION = "0.4.6"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quby-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-21 00:00:00.000000000 Z
11
+ date: 2022-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel