quby 4.0.3 → 5.0.0.pre1

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/lib/quby/questionnaires.rb +1 -0
  3. data/lib/quby/questionnaires/api.rb +5 -1
  4. data/lib/quby/questionnaires/deserializer.rb +433 -0
  5. data/lib/quby/questionnaires/dsl.rb +10 -15
  6. data/lib/quby/questionnaires/entities.rb +1 -0
  7. data/lib/quby/questionnaires/entities/charting/line_chart.rb +23 -0
  8. data/lib/quby/questionnaires/entities/charting/overview_chart.rb +3 -1
  9. data/lib/quby/questionnaires/entities/definition.rb +3 -5
  10. data/lib/quby/questionnaires/entities/fields.rb +0 -15
  11. data/lib/quby/questionnaires/entities/question.rb +9 -32
  12. data/lib/quby/questionnaires/entities/questionnaire.rb +4 -15
  13. data/lib/quby/questionnaires/entities/questions/checkbox_question.rb +0 -24
  14. data/lib/quby/questionnaires/entities/questions/date_question.rb +0 -8
  15. data/lib/quby/questionnaires/entities/score_calculation.rb +36 -3
  16. data/lib/quby/questionnaires/repos.rb +1 -0
  17. data/lib/quby/questionnaires/repos/bundle_disk_repo.rb +51 -0
  18. data/lib/quby/version.rb +1 -1
  19. data/spec/internal/log/test-events.log +166 -0
  20. data/spec/internal/log/test.log +6170 -0
  21. data/spec/internal/tmp/capybara/screenshot_2020-10-27-14-25-21.063.html +207 -0
  22. data/spec/internal/tmp/capybara/screenshot_2020-10-27-14-25-21.063.png +0 -0
  23. data/spec/quby/answers/services/answer_validations_spec.rb +8 -8
  24. data/spec/quby/questionnaires/deserializer/questionnaire_spec.rb +237 -0
  25. data/spec/quby/questionnaires/dsl_spec.rb +0 -9
  26. data/spec/quby/questionnaires/entities/fields_spec.rb +3 -3
  27. data/spec/quby/questionnaires/entities/question_spec.rb +0 -8
  28. data/spec/quby/questionnaires/entities/questionnaire_spec.rb +2 -26
  29. data/spec/quby/table_backend/range_tree_spec.rb +7 -0
  30. data/spec/spec_helper.rb +1 -0
  31. metadata +25 -46
  32. data/lib/quby/questionnaires/dsl/base.rb +0 -20
  33. data/lib/quby/questionnaires/dsl/calls_custom_methods.rb +0 -29
  34. data/lib/quby/questionnaires/dsl/charting/bar_chart_builder.rb +0 -18
  35. data/lib/quby/questionnaires/dsl/charting/chart_builder.rb +0 -91
  36. data/lib/quby/questionnaires/dsl/charting/line_chart_builder.rb +0 -57
  37. data/lib/quby/questionnaires/dsl/charting/overview_chart_builder.rb +0 -31
  38. data/lib/quby/questionnaires/dsl/charting/radar_chart_builder.rb +0 -18
  39. data/lib/quby/questionnaires/dsl/helpers.rb +0 -51
  40. data/lib/quby/questionnaires/dsl/panel_builder.rb +0 -80
  41. data/lib/quby/questionnaires/dsl/question_builder.rb +0 -40
  42. data/lib/quby/questionnaires/dsl/questionnaire_builder.rb +0 -252
  43. data/lib/quby/questionnaires/dsl/questions/base.rb +0 -179
  44. data/lib/quby/questionnaires/dsl/questions/checkbox_question_builder.rb +0 -20
  45. data/lib/quby/questionnaires/dsl/questions/date_question_builder.rb +0 -18
  46. data/lib/quby/questionnaires/dsl/questions/deprecated_question_builder.rb +0 -18
  47. data/lib/quby/questionnaires/dsl/questions/float_question_builder.rb +0 -21
  48. data/lib/quby/questionnaires/dsl/questions/integer_question_builder.rb +0 -21
  49. data/lib/quby/questionnaires/dsl/questions/radio_question_builder.rb +0 -20
  50. data/lib/quby/questionnaires/dsl/questions/select_question_builder.rb +0 -18
  51. data/lib/quby/questionnaires/dsl/questions/string_question_builder.rb +0 -20
  52. data/lib/quby/questionnaires/dsl/questions/text_question_builder.rb +0 -22
  53. data/lib/quby/questionnaires/dsl/score_builder.rb +0 -22
  54. data/lib/quby/questionnaires/dsl/standardized_panel_generators.rb +0 -33
  55. data/lib/quby/questionnaires/dsl/table_builder.rb +0 -48
  56. data/lib/quby/questionnaires/services/definition_validator.rb +0 -298
  57. data/spec/quby/questionnaires/dsl/calls_custom_methods_spec.rb +0 -38
  58. data/spec/quby/questionnaires/dsl/charting/bar_chart_builder_spec.rb +0 -41
  59. data/spec/quby/questionnaires/dsl/charting/chart_builder_spec.rb +0 -127
  60. data/spec/quby/questionnaires/dsl/charting/line_chart_builder_spec.rb +0 -66
  61. data/spec/quby/questionnaires/dsl/charting/radar_chart_builder_spec.rb +0 -41
  62. data/spec/quby/questionnaires/dsl/helpers_spec.rb +0 -80
  63. data/spec/quby/questionnaires/dsl/questionnaire_builder_spec.rb +0 -480
  64. data/spec/quby/questionnaires/services/definition_validator_spec.rb +0 -793
  65. data/spec/support/examples_for_chart_builders.rb +0 -59
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Quby::Questionnaires::DSL
6
- describe LineChartBuilder do
7
- it_behaves_like ChartBuilder
8
-
9
- let(:questionnaire) { double(key: 'questionnaire_key') }
10
-
11
- it 'sets y-axis label' do
12
- expect(dsl { y_axis_label 'Label' }.y_label).to eq 'Label'
13
- end
14
-
15
- it 'sets y-axis range' do
16
- expect(dsl { range 0..40 }.y_range).to eq (0..40)
17
- end
18
-
19
- it 'sets y-axis tick interval' do
20
- expect(dsl { tick_interval 1 }.tick_interval).to eq 1
21
- end
22
-
23
- it 'raises when y-axis range is not specified' do
24
- expect { dsl(:test, {}) { } }.to raise_error(/no range specified/)
25
- end
26
-
27
- it 'sets tonality' do
28
- expect(dsl { tonality :higher_is_better }.tonality).to eq :higher_is_better
29
- end
30
-
31
- it 'sets baseline to constant value' do
32
- expect(dsl { baseline 5 }.baseline.call(1, :male)).to eq 5.0
33
- end
34
-
35
- it 'sets baseline by hash', :aggregate_failures do
36
- chart = dsl { baseline({(0..1000) => {female: 5, default: 3}, default: {female: 1, default: 2}}) }
37
- expect(chart.baseline.call(1, :female)).to eq(5)
38
- expect(chart.baseline.call(1, :two_spirit)).to eq(3)
39
- expect(chart.baseline.call(5000, nil)).to eq(2)
40
- expect(chart.baseline.call(nil, :female)).to eq(1)
41
- end
42
-
43
- it 'sets baseline to proc' do
44
- expect(dsl { baseline { |age, gender| age } }.baseline.call(5, :male)).to eq(5.0)
45
- expect { dsl { baseline { |age| age } } }.to raise_error(ArgumentError, /must take two arguments/)
46
- end
47
-
48
- it 'raises error if not giving baseline value or block' do
49
- expect { dsl { baseline } }.to raise_error(ArgumentError, /either value or a block/)
50
- expect { dsl { baseline(5.0) { |age, gender| age } } }.to raise_error(ArgumentError, /either value or a block/)
51
- end
52
-
53
- it 'sets clinically relevant change' do
54
- expect(dsl { clinically_relevant_change 5 }.clinically_relevant_change).to eq 5.0
55
- end
56
-
57
- it 'makes a line chart' do
58
- expect(dsl { }).to be_an_instance_of(::Quby::Questionnaires::Entities::Charting::LineChart)
59
- end
60
-
61
- def dsl(key = :test, options = {y_range: (0..20)}, &block)
62
- builder = LineChartBuilder.new(questionnaire, key, options)
63
- builder.build(&block)
64
- end
65
- end
66
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Quby::Questionnaires::DSL
6
- describe RadarChartBuilder do
7
- it_behaves_like ChartBuilder
8
-
9
- let(:questionnaire) { double(key: 'questionnaire_key') }
10
-
11
- it 'makes a radar chart' do
12
- expect(dsl { }).to be_an_instance_of(::Quby::Questionnaires::Entities::Charting::RadarChart)
13
- end
14
-
15
- it 'sets y-axis range' do
16
- expect(dsl { range 0..40 }.y_range).to eq (0..40)
17
- end
18
-
19
- it 'sets y-axis tick interval' do
20
- expect(dsl { tick_interval 1 }.tick_interval).to eq 1
21
- end
22
-
23
- it 'sets plotlines' do
24
- plotlines =
25
- dsl {
26
- plotline 40, :orange
27
- plotline 60, :red
28
- }.plotlines
29
-
30
- expect(plotlines).to eq [
31
- {value: 40, color: :orange, width: 1, zIndex: 3},
32
- {value: 60, color: :red, width: 1, zIndex: 3}
33
- ]
34
- end
35
-
36
- def dsl(key = :test, options = {}, &block)
37
- builder = RadarChartBuilder.new(questionnaire, key, options)
38
- builder.build(&block)
39
- end
40
- end
41
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Quby::Questionnaires::DSL
6
- describe Helpers do
7
- let(:questionnaire) { Quby::Questionnaires::Entities::Questionnaire.new("example") }
8
- let(:builder) { QuestionnaireBuilder.new(questionnaire) }
9
-
10
- # this helper has some extra tests to check that helpers are included everywhere
11
- describe '.image_tag' do
12
- let(:expected_html) { %r{<p><img alt=\"Happy face\" src=\"/assets/quby/happy-face.*.png\" /></p>} }
13
-
14
- it 'builds image tags outside of panels' do
15
- dsl { text image_tag('quby/happy-face.png') }
16
- expect(questionnaire.panels.first.items.first.text).to match(expected_html)
17
- end
18
-
19
- it 'builds image tags inside of panels' do
20
- dsl do
21
- panel do
22
- text image_tag('quby/happy-face.png')
23
- end
24
- end
25
-
26
- expect(questionnaire.panels.first.items.first.text).to match(expected_html)
27
- end
28
-
29
- it 'builds image tags inside of questions' do
30
- # this one is different because markdown/maruku transforms double quotes into single quotes
31
- # and question descriptions are not passed through markdown/maruku
32
- expected_html = %r{<img .*?src="/assets/quby/happy-face.*.png"}
33
- dsl do
34
- panel do
35
- question :v_1, type: :radio do
36
- option :a1, description: image_tag('quby/happy-face.png')
37
- end
38
- end
39
- end
40
- expect(questionnaire.panels.first.items.first.options.first.description).to match(expected_html)
41
- end
42
- end
43
-
44
- describe 'video_tag' do
45
- it 'makes a text item with a html 5 video player for the given video source urls' do
46
- html = builder.video_tag 'https://www.example.com/video.mp4', 'https://www.example.com/video.webm'
47
-
48
- expect(html).to \
49
- eq("<video width=\"100%\" preload=\"none\" controls=\"controls\"><source src=\"https://www.example.com/video.mp4\" type=\"video/mp4\">\
50
- <source src=\"https://www.example.com/video.webm\" type=\"video/webm\">\
51
- Helaas kan je browser dit filmpje niet afspelen. Probeer een andere browser te gebruiken.</video>")
52
- end
53
-
54
- it 'can add a autoplay attribute (with muted added to allow chrome autoplay)' do
55
- html = builder.video_tag 'https://www.example.com/video.mp4', autoplay: true
56
-
57
- expect(html).to \
58
- include('<video width="100%" preload="none" autoplay="autoplay" muted="muted" controls="controls">')
59
- end
60
-
61
- it 'can add a loop attribute' do
62
- html = builder.video_tag 'https://www.example.com/video.mp4', loop: true
63
-
64
- expect(html).to \
65
- include('<video width="100%" preload="none" loop="loop" controls="controls">')
66
- end
67
-
68
- it 'can add a poster url' do
69
- html = builder.video_tag 'https://www.example.com/video.mp4', poster: 'https://www.example.com/poster.jpg'
70
-
71
- expect(html).to \
72
- include('<video width="100%" preload="none" poster="https://www.example.com/poster.jpg" controls="controls">')
73
- end
74
- end
75
-
76
- def dsl(&block)
77
- builder.instance_eval(&block)
78
- end
79
- end
80
- end
@@ -1,480 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- module Quby::Questionnaires::DSL
6
- describe QuestionnaireBuilder do
7
- let(:questionnaire) { Quby::Questionnaires::Entities::Questionnaire.new("example") }
8
- let(:builder) { QuestionnaireBuilder.new(questionnaire) }
9
-
10
- it 'sets title' do
11
- dsl { title 'Foo' }
12
- expect(questionnaire.title).to eq('Foo')
13
- end
14
-
15
- it 'sets description' do
16
- dsl { description 'This is a questionnaire description' }
17
- expect(questionnaire.description).to eq('This is a questionnaire description')
18
- end
19
-
20
- it 'sets outcome_description' do
21
- dsl { outcome_description 'Outcome description' }
22
- expect(questionnaire.outcome_description).to eq('Outcome description')
23
- end
24
-
25
- it 'can disable checking key clashes' do
26
- expect(questionnaire.check_key_clashes).to eq(true)
27
- dsl { do_not_check_key_clashes }
28
- expect(questionnaire.check_key_clashes).to eq(false)
29
- end
30
-
31
- it 'set sbg_key' do
32
- dsl { sbg_key 'foo' }
33
- expect(questionnaire.sbg_key).to eq('foo')
34
- end
35
-
36
- it 'can request outcome regeneration' do
37
- timestamp = Time.local(2020, 5, 12, 4, 28, 19)
38
- dsl { outcome_regeneration_requested_at timestamp }
39
- expect(questionnaire.outcome_regeneration_requested_at).to eq(timestamp)
40
- end
41
-
42
- it 'can request answers to be deactivated' do
43
- timestamp = Time.local(2020, 5, 12, 4, 28, 19)
44
- dsl { deactivate_answers_requested_at timestamp }
45
- expect(questionnaire.deactivate_answers_requested_at).to eq(timestamp)
46
- end
47
-
48
- describe 'roqua keys' do
49
- it 'defaults to key' do
50
- dsl {}
51
- expect(questionnaire.roqua_keys).to eq(["example"])
52
- end
53
-
54
- it 'sets roqua keys' do
55
- dsl { roqua_keys :alg_o, :alg_o2 }
56
- expect(questionnaire.roqua_keys).to eq([:alg_o, :alg_o2])
57
- end
58
- end
59
-
60
- describe 'sbg_domain' do
61
- it 'sets sbg_domain' do
62
- dsl do
63
- sbg_domain '02', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'OQ45-sd', primary: true
64
- end
65
- expect(questionnaire.sbg_domains).to eq(
66
- [
67
- {sbg_code: '02', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'OQ45-sd', primary: true}
68
- ]
69
- )
70
- end
71
-
72
- it 'sets multiple sbg_domains with optional attributes' do
73
- dsl do
74
- sbg_domain '02', outcome: '01', sbg_key: 'OQ45-sd', primary: false
75
- sbg_domain '03', outcome: '02', from: '2000-01-01', till: '2099-12-31'
76
- end
77
- expect(questionnaire.sbg_domains).to eq(
78
- [
79
- {sbg_code: '02', from: nil, till: nil, outcome: '01', sbg_key: 'OQ45-sd', primary: false},
80
- {sbg_code: '03', from: '2000-01-01', till: '2099-12-31', outcome: '02', sbg_key: nil, primary: false}
81
- ]
82
- )
83
- end
84
-
85
- it 'defaults the sbg_key to the sbg_key of the questionnaire' do
86
- dsl do
87
- sbg_key 'example'
88
- sbg_domain '03', from: '2000-01-01', till: '2099-12-31', outcome: '01'
89
- end
90
- expect(questionnaire.sbg_domains).to eq(
91
- [
92
- {sbg_code: '03', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'example', primary: false}
93
- ]
94
- )
95
- end
96
- end
97
-
98
- it 'does not accept invalid sbg_domains options' do
99
- expect { dsl { sbg_domain '02', foo: 'bar' } }.to raise_exception(ArgumentError, "missing keyword: outcome")
100
- end
101
-
102
- it 'can be abortable' do
103
- expect(questionnaire.abortable).to be_falsey
104
- dsl { abortable }
105
- expect(questionnaire.abortable).to be_truthy
106
- end
107
-
108
- it 'can allow hotkeys' do
109
- dsl { allow_hotkeys }
110
- expect(questionnaire.allow_hotkeys).to eq("all")
111
- end
112
-
113
- it 'can set license' do
114
- dsl { license :free }
115
- expect(questionnaire.license).to eq(:free)
116
- expect(questionnaire.licensor).to be_nil
117
- end
118
-
119
- it 'can set licensor' do
120
- dsl { license :free, licensor: 'FOO' }
121
- expect(questionnaire.licensor).to eq('FOO')
122
- end
123
-
124
- it 'can set language' do
125
- dsl { language :en }
126
- expect(questionnaire.language).to eq(:en)
127
- end
128
-
129
- it 'defaults to Dutch language' do
130
- dsl { }
131
- expect(questionnaire.language).to eq(:nl)
132
- end
133
-
134
- it 'can set respondent_types' do
135
- dsl { respondent_types :patient, :parent }
136
- expect(questionnaire.respondent_types).to eq([:patient, :parent])
137
- end
138
-
139
- it 'can set tags' do
140
- dsl { tags :diary }
141
- expect(questionnaire.tags.diary).to be_truthy
142
- expect(questionnaire.tags.another_tag).to be_falsey
143
- end
144
-
145
- it 'builds panels' do
146
- dsl { panel { title 'My Title' } }
147
- expect(questionnaire.panels.first.title).to eq('My Title')
148
- end
149
-
150
- it 'builds line charts' do
151
- dsl { line_chart(:tot) { title 'My Title'; range 0..40 } }
152
- expect(questionnaire.charts.find(:tot).title).to eq('My Title')
153
- end
154
-
155
- it 'builds bar charts' do
156
- dsl { bar_chart(:tot) { title 'My Title' } }
157
- expect(questionnaire.charts.find(:tot).title).to eq('My Title')
158
- end
159
-
160
- it 'builds radar charts' do
161
- dsl { radar_chart(:tot) { title 'My Title' } }
162
- expect(questionnaire.charts.find(:tot).title).to eq('My Title')
163
- end
164
-
165
- it 'checks for duplicate question keys' do
166
- expect do
167
- dsl do
168
- question :v_1, type: :string
169
- question :v_1, type: :string
170
- end
171
- end.to raise_exception(RuntimeError, "example:v_1: A question or option with input key v_1 is already defined.")
172
- end
173
-
174
- it 'checks for subquestion clashing with parent question' do
175
- skip
176
- expect do
177
- dsl do
178
- question :v_1, type: :radio do
179
- option :a1 do
180
- question :v_1, type: :string
181
- end
182
- end
183
- end
184
- end.to raise_exception
185
- end
186
-
187
- it 'checks for duplicate option keys' do
188
- expect do
189
- dsl do
190
- question :v_1, type: :radio do
191
- option :a1
192
- option :a1
193
- end
194
- end
195
- end.to raise_exception(RuntimeError, "example:v_1:a1: A question or option with input key v_1_a1 is already defined.")
196
- end
197
-
198
- it 'checks for duplicate option input keys' do
199
- expect do
200
- dsl do
201
- question :v_1_a, type: :radio do
202
- option :a1
203
- end
204
-
205
- question :v_1, type: :radio do
206
- option :a_a1
207
- end
208
- end
209
- end.to raise_exception(RuntimeError, "example:v_1:a_a1: A question or option with input key v_1_a_a1 is already defined.")
210
- end
211
-
212
- it 'checks for duplicates in past date input keys' do
213
- expect do
214
- dsl do
215
- question :v_1_a, type: :date do
216
- option :a1
217
- end
218
-
219
- question :v_1_yyyy, type: :text
220
- end
221
- end.to raise_exception(NoMethodError, /undefined method `option'/)
222
- end
223
-
224
- it 'checks for duplicates when creating date input keys' do
225
- expect do
226
- dsl do
227
- question :v_1_yyyy, type: :text
228
-
229
- question :v_1_a, type: :date do
230
- option :a1
231
- end
232
- end
233
- end.to raise_exception(KeyError, "key not found: \"text\"")
234
- end
235
-
236
- it 'checks for checkbox option keys clashing with question keys' do
237
- expect do
238
- dsl do
239
- question :v_1, type: :string
240
- question :v_2, type: :check_box do
241
- option :v_1
242
- end
243
- end
244
- end.to raise_exception(RuntimeError, "example:v_2:v_1: A question or option with input key v_1 is already defined.")
245
- end
246
-
247
- it 'checks for checkbox option keys clashing with their own question key' do
248
- expect do
249
- dsl do
250
- question :v_1, type: :check_box do
251
- option :v_2
252
- option :v_1
253
- end
254
- end
255
- end.to raise_exception(RuntimeError, "example:v_1:v_1: A question or option with input key v_1 is already defined.")
256
- end
257
-
258
- it 'checks for checkbox option keys clashing with input keys' do
259
- expect do
260
- dsl do
261
- question :v_1, type: :radio do
262
- option :a1
263
- end
264
- question :v_2, type: :check_box do
265
- option :v_1_a1
266
- end
267
- end
268
- end.to raise_exception(RuntimeError, "example:v_2:v_1_a1: A question or option with input key v_1_a1 is already defined.")
269
- end
270
-
271
- it 'sets a depends_on key correctly' do
272
- dsl do
273
- question :v_1, type: :check_box do
274
- option :v_1_a
275
- end
276
- question :v_2, type: :string, depends_on: [:v_1]
277
- end
278
- questionnaire.callback_after_dsl_enhance_on_questions
279
- expect(questionnaire.question_hash[:v_2].depends_on).to eq [:v_1_a]
280
- end
281
-
282
- it 'raises when a depends_on key does not exist in the questionnaire' do
283
- expect do
284
- dsl do
285
- question :v_1, type: :string, depends_on: [:unknown]
286
- end
287
- questionnaire.callback_after_dsl_enhance_on_questions
288
- end.to raise_exception(Quby::Questionnaires::Entities::Questionnaire::UnknownInputKey, "Question v_1 depends_on contains an error: Unknown input key unknown")
289
- end
290
-
291
- it 'sets the parent option key on subquestions correctly' do
292
- dsl do
293
- question :v_1, type: :check_box do
294
- option :v_1a do
295
- question :v_2, type: :string
296
- end
297
- option :v_1b
298
- end
299
- end
300
- expect(questionnaire.question_hash[:v_2].parent_option_key).to eq(:v_1a)
301
- end
302
-
303
- describe 'flag' do
304
- before do
305
- allow_any_instance_of(Quby::Questionnaires::Entities::Questionnaire).to receive(:add_flag)
306
- end
307
-
308
- it 'defines flags' do
309
- dsl do
310
- flag key: :test, description: 'test flag'
311
- end
312
- expect(questionnaire).to have_received(:add_flag).with(key: :test, description: 'test flag')
313
- end
314
- end
315
-
316
- describe '#question' do
317
- it 'does not overwrite the @default_question_options' do
318
- dsl do
319
- default_question_options required: false, type: :checkbox
320
- question :v_1, type: :string, required: true
321
- end
322
- expect(builder.default_question_options[:required]).to eq false
323
- end
324
- end
325
-
326
- describe '#do_not_check_score_keys_consistency' do
327
- it 'sets check_score_keys_consistency flag to false' do
328
- dsl do
329
- do_not_check_score_keys_consistency
330
- end
331
- expect(questionnaire.check_score_keys_consistency).to eq false
332
- end
333
- it 'flag is true on the questionnaire if not altered' do
334
- expect(questionnaire.check_score_keys_consistency).to eq true
335
- end
336
- end
337
-
338
- describe '#custom_method' do
339
- context 'valid definition' do
340
- before do
341
- dsl do
342
- custom_method :zzl_question do |question_key, question_title|
343
- question question_key, type: :scale do
344
- title question_title
345
- option :a1, value: 1
346
- option :a2, value: 2
347
- end
348
- end
349
- end
350
- end
351
-
352
- it 'can build a question with options' do
353
- dsl do
354
- panel do
355
- zzl_question :v_1, 'zzl title'
356
- end
357
- end
358
- expect(questionnaire.question_hash[:v_1].title).to eq 'zzl title'
359
- expect(questionnaire.question_hash[:v_1].type).to eq :scale
360
- expect(questionnaire.question_hash[:v_1].options[0].key).to eq :a1
361
- end
362
-
363
- it 'can be used within a table' do
364
- dsl do
365
- panel do
366
- table columns: 4 do
367
- zzl_question :v_1, 'zzl title'
368
- end
369
- end
370
- end
371
- expect(questionnaire.question_hash[:v_1].title).to eq 'zzl title'
372
- expect(questionnaire.question_hash[:v_1].type).to eq :scale
373
- expect(questionnaire.question_hash[:v_1].options[0].key).to eq :a1
374
- end
375
- end
376
-
377
- it 'fails when specifying an existing method' do
378
- expect do
379
- dsl do
380
- custom_method :question do |question_key, question_title|
381
- question question_key, type: :string, title: question_title
382
- end
383
- panel do
384
- zzl_question :v_1, 'zzl title'
385
- end
386
- end
387
- end.to raise_exception(RuntimeError, "Custom method trying to override existing method")
388
- end
389
-
390
- it 'fails when specifying a a method twice' do
391
- expect do
392
- dsl do
393
- custom_method :zzl_question do |question_key, question_title|
394
- question question_key, type: :string, title: question_title
395
- end
396
- custom_method :zzl_question do |question_key, question_title|
397
- question question_key, type: :string, title: question_title
398
- end
399
- panel do
400
- zzl_question :v_1, 'zzl title'
401
- end
402
- end
403
- end.to raise_exception(RuntimeError, "Custom method trying to override existing method")
404
- end
405
- end
406
-
407
- describe '#add_lookup_tree' do
408
- it 'can add a lookup tree' do
409
- dsl do
410
- add_lookup_tree :interpretations,
411
- levels: ['score', 'interpretation'],
412
- tree: {
413
- 0..24 => 'low',
414
- 25..50 => 'high'
415
- }
416
- end
417
-
418
- expect(questionnaire.lookup_tables[:interpretations].lookup(score: 26)).to eq 'high'
419
- end
420
- end
421
-
422
- describe '#score' do
423
- it 'requires scores to have a label' do
424
- dsl do
425
- score :totaal do
426
- {value: 100}
427
- end
428
- end
429
-
430
- expect(questionnaire.errors.full_messages).to eq(["Score totaal misses label in score call"])
431
- end
432
- end
433
-
434
- describe '#score_schema' do
435
- let(:subschema_options) { [{key: :value, export_key: :tot, label: 'Score'}] }
436
- let(:set_dsl) do
437
- options = subschema_options
438
- dsl do
439
- score :totaal, label: 'totaal' do
440
- {value: 100}
441
- end
442
-
443
- score_schema :totaal, 'Totaal', options
444
- end
445
- end
446
-
447
- it 'calls #add_score_schema with the given arguments' do
448
- expect(questionnaire).to receive(:add_score_schema).with :totaal, 'Totaal', subschema_options
449
- set_dsl
450
- end
451
- end
452
-
453
- describe '#outcome_table' do
454
- it 'calls questionnaire.add_outcome_table with the given arguments' do
455
- expect(questionnaire).to receive(:add_outcome_table).with(score_keys: [:a], subscore_keys: [:b])
456
- dsl do
457
- outcome_table score_keys: [:a], subscore_keys: [:b]
458
- end
459
- end
460
- end
461
-
462
- describe '#video' do
463
- it 'passes arguments to a video tag call, and puts the result in a text item' do
464
- expect_any_instance_of(PanelBuilder).to receive(:video_tag).with('https://example.com/video.mp4', looping: true).and_return 'foo'
465
-
466
- dsl do
467
- panel do
468
- video 'https://example.com/video.mp4', looping: true
469
- end
470
- end
471
- expect(questionnaire.panels.first.items.first.raw_content).to eq('foo')
472
- end
473
-
474
- end
475
-
476
- def dsl(&block)
477
- builder.instance_eval(&block)
478
- end
479
- end
480
- end