quby-compiler 0.4.0 → 0.4.4
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 +4 -4
- data/CHANGELOG.md +22 -0
- data/exe/quby-compile +14 -0
- data/lib/quby/compiler/entities/fields.rb +1 -1
- data/lib/quby/compiler/entities/question.rb +4 -3
- data/lib/quby/compiler/entities/questionnaire.rb +1 -1
- data/lib/quby/compiler/entities/questions/concerns/slider.rb +23 -0
- data/lib/quby/compiler/entities/questions/float_question.rb +9 -3
- data/lib/quby/compiler/entities/questions/integer_question.rb +9 -3
- data/lib/quby/compiler/outputs/roqua_serializer.rb +109 -1
- data/lib/quby/compiler/services/quby_proxy.rb +3 -3
- data/lib/quby/compiler/version.rb +1 -1
- data/lib/quby/compiler.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: affdedce52abd30377ecb0919b012353f6af8139cea5747acc4b82c67d9923a8
|
|
4
|
+
data.tar.gz: d21ad635fd6d232a58d0fd691b91d5f9f9a35f5fe36a024b3056e501870a05ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83a2a47a517f5666bd34b76d1528ca1ccb7f38e60991eda82c134bec2116640e191954cc643d588a3aa8f95c9bc779ddeabe2152d1d689f3dcdd53a7a029da35
|
|
7
|
+
data.tar.gz: e44964d5ea73973db1058018ce460fa0a5ef2da25d7acdf0ee6d1891ef7a42254cf55c2485b04af9fa02af881ae7ef6fb3c4c0e5b3ff452a39f6769d97f63bef
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
# 0.4.4
|
|
2
|
+
|
|
3
|
+
* quby-compile will now validate, not compile invalid questionnaires and return 1 when any invalid.
|
|
4
|
+
* roqua.json
|
|
5
|
+
* add questions hash
|
|
6
|
+
* quby2.json
|
|
7
|
+
* add `as` to all questions, defaulting to type.
|
|
8
|
+
* add `minimum` and `maximum` to integer/float questions.
|
|
9
|
+
* add `step`, `defaultPosition`, `startThumbHidden`, `valueTooltip` and `labels` to slider questions.
|
|
10
|
+
|
|
11
|
+
# 0.4.3
|
|
12
|
+
|
|
13
|
+
* roqua.json: add scores hash.
|
|
14
|
+
|
|
15
|
+
# 0.4.2
|
|
16
|
+
|
|
17
|
+
* quby2: Added labels to slider questions.
|
|
18
|
+
|
|
19
|
+
# 0.4.1
|
|
20
|
+
|
|
21
|
+
* seeds: Fix depends: :present rule being overridden.
|
|
22
|
+
|
|
1
23
|
# 0.4.0
|
|
2
24
|
|
|
3
25
|
* rename flag visibilty rule value to trigger_on
|
data/exe/quby-compile
CHANGED
|
@@ -30,11 +30,21 @@ end
|
|
|
30
30
|
|
|
31
31
|
lookup_tables = Quby::Compiler::Entities::LookupTables.new(lookup_tables_path)
|
|
32
32
|
|
|
33
|
+
validation_errors_found = false
|
|
33
34
|
paths.each do |path|
|
|
34
35
|
puts "Compiling #{path}"
|
|
35
36
|
|
|
36
37
|
key = File.basename(File.dirname(path))
|
|
37
38
|
sourcecode = File.read(path)
|
|
39
|
+
|
|
40
|
+
definition = Quby::Compiler.validate(key, sourcecode, lookup_tables: lookup_tables)
|
|
41
|
+
if definition.errors.any?
|
|
42
|
+
error = definition.errors[:sourcecode].first
|
|
43
|
+
STDERR.puts error[:message], error[:backtrace], ''
|
|
44
|
+
validation_errors_found = true
|
|
45
|
+
next # let's not create new output files for questionnaires with errors
|
|
46
|
+
end
|
|
47
|
+
|
|
38
48
|
compiled = Quby::Compiler.compile(key, sourcecode, path: path, lookup_tables: lookup_tables)
|
|
39
49
|
|
|
40
50
|
FileUtils.mkdir_p(File.join(output_path, key))
|
|
@@ -45,3 +55,7 @@ paths.each do |path|
|
|
|
45
55
|
end
|
|
46
56
|
end
|
|
47
57
|
end
|
|
58
|
+
|
|
59
|
+
if validation_errors_found
|
|
60
|
+
exit(1)
|
|
61
|
+
end
|
|
@@ -231,7 +231,6 @@ module Quby
|
|
|
231
231
|
title: Quby::MarkdownParser.new(title).to_html,
|
|
232
232
|
description: Quby::MarkdownParser.new(description).to_html,
|
|
233
233
|
type: type,
|
|
234
|
-
unit: unit,
|
|
235
234
|
size: size,
|
|
236
235
|
hidden: hidden?,
|
|
237
236
|
displayModes: display_modes,
|
|
@@ -241,9 +240,11 @@ module Quby
|
|
|
241
240
|
parentOptionKey: parent_option_key,
|
|
242
241
|
deselectable: deselectable,
|
|
243
242
|
presentation: presentation,
|
|
244
|
-
as: as,
|
|
243
|
+
as: as || type, # default to type so typescript can narrow on it.
|
|
245
244
|
questionGroup: question_group
|
|
246
|
-
)
|
|
245
|
+
).tap do |json|
|
|
246
|
+
json[:unit] = unit if %i[integer float string].include?(type) && as != :slider
|
|
247
|
+
end
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
# Returns all keys belonging to html inputs generated by this question.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Quby::Compiler::Entities::Questions::Concerns
|
|
2
|
+
module Slider
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
validates :minimum, :maximum, presence: true, if: -> { as == :slider }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def as_json(options = {})
|
|
10
|
+
if as == :slider
|
|
11
|
+
super.merge(
|
|
12
|
+
step: step,
|
|
13
|
+
defaultPosition: default_position.is_a?(Numeric) ? default_position : minimum,
|
|
14
|
+
startThumbHidden: default_position == :hidden,
|
|
15
|
+
valueTooltip: input_data[:value_tooltip] || false,
|
|
16
|
+
labels: labels
|
|
17
|
+
)
|
|
18
|
+
else
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'concerns/slider'
|
|
4
|
+
|
|
3
5
|
module Quby
|
|
4
6
|
module Compiler
|
|
5
7
|
module Entities
|
|
6
8
|
module Questions
|
|
7
9
|
class FloatQuestion < Question
|
|
10
|
+
include Concerns::Slider
|
|
11
|
+
|
|
8
12
|
def as_json(options = {})
|
|
9
13
|
super.merge(
|
|
10
14
|
minimum: minimum,
|
|
11
|
-
maximum: maximum
|
|
12
|
-
step: 0.01, # fixed in v1.
|
|
13
|
-
# defaultPosition: default_position # Needs discussion, can be number or string "hidden"
|
|
15
|
+
maximum: maximum
|
|
14
16
|
)
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def size
|
|
18
20
|
@size || 30
|
|
19
21
|
end
|
|
22
|
+
|
|
23
|
+
def step
|
|
24
|
+
0.01
|
|
25
|
+
end
|
|
20
26
|
end
|
|
21
27
|
end
|
|
22
28
|
end
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'concerns/slider'
|
|
4
|
+
|
|
3
5
|
module Quby
|
|
4
6
|
module Compiler
|
|
5
7
|
module Entities
|
|
6
8
|
module Questions
|
|
7
9
|
class IntegerQuestion < Question
|
|
10
|
+
include Concerns::Slider
|
|
11
|
+
|
|
8
12
|
def as_json(options = {})
|
|
9
13
|
super.merge(
|
|
10
14
|
minimum: minimum,
|
|
11
|
-
maximum: maximum
|
|
12
|
-
step: 1, # fixed in v1.
|
|
13
|
-
# defaultPosition: default_position # Needs discussion, can be number or string "hidden"
|
|
15
|
+
maximum: maximum
|
|
14
16
|
)
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def size
|
|
18
20
|
@size || 30
|
|
19
21
|
end
|
|
22
|
+
|
|
23
|
+
def step
|
|
24
|
+
1
|
|
25
|
+
end
|
|
20
26
|
end
|
|
21
27
|
end
|
|
22
28
|
end
|
|
@@ -2,6 +2,18 @@ module Quby
|
|
|
2
2
|
module Compiler
|
|
3
3
|
module Outputs
|
|
4
4
|
class RoquaSerializer
|
|
5
|
+
QUBY_TYPE_TO_ROQUA_TYPE = {
|
|
6
|
+
check_box: 'multi_select',
|
|
7
|
+
date: 'date_parts',
|
|
8
|
+
float: 'float',
|
|
9
|
+
integer: 'integer',
|
|
10
|
+
radio: 'single_select',
|
|
11
|
+
scale: 'single_select',
|
|
12
|
+
select: 'single_select',
|
|
13
|
+
string: 'text',
|
|
14
|
+
textarea: 'text'
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
attr_reader :questionnaire
|
|
6
18
|
|
|
7
19
|
def initialize(questionnaire)
|
|
@@ -22,6 +34,8 @@ module Quby
|
|
|
22
34
|
tags: questionnaire.tags.to_h.keys,
|
|
23
35
|
charts: charts,
|
|
24
36
|
outcome_tables_schema: outcome_tables_schema,
|
|
37
|
+
questions: questions,
|
|
38
|
+
scores: scores,
|
|
25
39
|
}
|
|
26
40
|
end
|
|
27
41
|
|
|
@@ -139,7 +153,101 @@ module Quby
|
|
|
139
153
|
tables: tables,
|
|
140
154
|
}
|
|
141
155
|
end
|
|
156
|
+
|
|
157
|
+
# {v_1: {.., options: {..}, date_parts: {..}}, ..}
|
|
158
|
+
# nils are removed from hash.
|
|
159
|
+
# key [string]
|
|
160
|
+
# sbg_key [nil/string] _not_ defaulted to key
|
|
161
|
+
# type [string]
|
|
162
|
+
# title [nil/string] no html
|
|
163
|
+
# context_free_title [nil/string] no html, defaulted to title
|
|
164
|
+
# deprecated [nil/true] only show if filled for old answers
|
|
165
|
+
# default_invisible [nil/true] only show if filled or when all questions are shown
|
|
166
|
+
# date_parts [nil/{..}]
|
|
167
|
+
# options: [nil/{..}]
|
|
168
|
+
def questions
|
|
169
|
+
questionnaire.questions.reject{_1.type == :hidden}.to_h { |question|
|
|
170
|
+
[
|
|
171
|
+
question.key,
|
|
172
|
+
{
|
|
173
|
+
key: question.key,
|
|
174
|
+
sbg_key: question.sbg_key,
|
|
175
|
+
type: QUBY_TYPE_TO_ROQUA_TYPE.fetch(question.type),
|
|
176
|
+
title: strip_tags_without_html_encode(question.title),
|
|
177
|
+
context_free_title: strip_tags_without_html_encode(question.context_free_title),
|
|
178
|
+
deprecated: question.hidden.presence,
|
|
179
|
+
default_invisible: question.default_invisible.presence,
|
|
180
|
+
date_parts: date_parts_for(question),
|
|
181
|
+
options: options_for(question),
|
|
182
|
+
}.compact
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# {year_key: {key: "v_date_yyyy"}, ..}
|
|
188
|
+
# key [string]
|
|
189
|
+
def date_parts_for(question)
|
|
190
|
+
return nil unless question.type == :date
|
|
191
|
+
|
|
192
|
+
question.components.to_h { |component|
|
|
193
|
+
[
|
|
194
|
+
component,
|
|
195
|
+
{
|
|
196
|
+
key: question.send("#{component}_key")
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# {a1: {..}}
|
|
203
|
+
# key [string]
|
|
204
|
+
# value [nil/string] nil for check_box, string otherwise
|
|
205
|
+
# description [nil/string] context_free_description, no html
|
|
206
|
+
def options_for(question)
|
|
207
|
+
return nil if question.options.empty?
|
|
208
|
+
|
|
209
|
+
question.options.to_h { |option|
|
|
210
|
+
[
|
|
211
|
+
option.key,
|
|
212
|
+
{
|
|
213
|
+
key: option.key,
|
|
214
|
+
value: (option.value.to_s unless question.type == :check_box),
|
|
215
|
+
description: strip_tags_without_html_encode(option.context_free_description)
|
|
216
|
+
}.compact
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# [{ key: { .., subscores: { subkey: {..} } } }]
|
|
222
|
+
def scores
|
|
223
|
+
questionnaire.score_schemas.transform_values { |score|
|
|
224
|
+
{
|
|
225
|
+
key: score.key,
|
|
226
|
+
label: score.label,
|
|
227
|
+
subscores: subscores_for(score)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# { subkey: {..} }
|
|
233
|
+
def subscores_for(score)
|
|
234
|
+
score.subscore_schemas.to_h { |subscore|
|
|
235
|
+
[
|
|
236
|
+
subscore.key,
|
|
237
|
+
{
|
|
238
|
+
key: subscore.key,
|
|
239
|
+
label: subscore.label,
|
|
240
|
+
export_key: subscore.export_key,
|
|
241
|
+
only_for_export: subscore.only_for_export.presence
|
|
242
|
+
}.compact
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def strip_tags_without_html_encode(html)
|
|
248
|
+
Nokogiri::HTML(html).text
|
|
249
|
+
end
|
|
142
250
|
end
|
|
143
251
|
end
|
|
144
252
|
end
|
|
145
|
-
end
|
|
253
|
+
end
|
|
@@ -30,9 +30,6 @@ module Quby
|
|
|
30
30
|
@hidden_questions = {} # hash containing questions hidden by other questions
|
|
31
31
|
|
|
32
32
|
for question in questions_flat
|
|
33
|
-
if question.hidden && question.type != :check_box
|
|
34
|
-
d_qtypes[question.key.to_s] = { depends: :present } unless options[:without_depends]
|
|
35
|
-
end
|
|
36
33
|
unless question.hidden && (question.type == :check_box || question.type == :hidden)
|
|
37
34
|
vars << question.key.to_s
|
|
38
35
|
end
|
|
@@ -184,6 +181,9 @@ module Quby
|
|
|
184
181
|
if hidden = @hidden_questions[question.key.to_s]
|
|
185
182
|
d_qtypes[question.key.to_s][:depends] ||= hidden unless options[:without_depends]
|
|
186
183
|
end
|
|
184
|
+
if question.hidden && question.type != :check_box
|
|
185
|
+
d_qtypes[question.key.to_s][:depends] = :present unless options[:without_depends]
|
|
186
|
+
end
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
def generate_question_titles
|
data/lib/quby/compiler.rb
CHANGED
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.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marten Veldthuis
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -204,6 +204,7 @@ files:
|
|
|
204
204
|
- lib/quby/compiler/entities/question_option.rb
|
|
205
205
|
- lib/quby/compiler/entities/questionnaire.rb
|
|
206
206
|
- lib/quby/compiler/entities/questions/checkbox_question.rb
|
|
207
|
+
- lib/quby/compiler/entities/questions/concerns/slider.rb
|
|
207
208
|
- lib/quby/compiler/entities/questions/date_question.rb
|
|
208
209
|
- lib/quby/compiler/entities/questions/deprecated_question.rb
|
|
209
210
|
- lib/quby/compiler/entities/questions/float_question.rb
|