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
@@ -0,0 +1,207 @@
1
+ <html class="no-js"><!-- <![endif]--><head>
2
+ <meta content="text/html; charset=utf-8" http-equiv="content-type">
3
+ <meta content="IE=edge" http-equiv="X-UA-Compatible">
4
+ <title>Vragenlijst</title>
5
+ <meta content="width=device-width, initial-scale=1.0 , user-scalable=no" name="viewport">
6
+ <link rel="stylesheet" media="screen, projection" href="/assets/quby/application-613d22026324a8ae8b7c205fd32e0719011164fdd9ca34aad1483b1b74721932.css">
7
+ <link rel="stylesheet" media="print" href="/assets/quby/print-2c9d02886ac8119671ccec3fe13a025efd1086b5355927d242d524ffbb358ab4.css">
8
+
9
+ <script src="/assets/quby/application-ac694f928c966ab7ccbc92caffa6581288a3669caf09163778be2cfaf3e47ba2.js"></script>
10
+ <script src="/assets/quby/disable_keys-72d21d5eab421fd3b0709bf0f5ead2bfe5e824a2060d20ce56e2c3ecf3edf8aa.js"></script>
11
+ <script src="/assets/quby/answers-72b3815aba9fa0fcc608ae7405efb641abedfa5cd62c60a8c824063a3ff22137.js"></script>
12
+ <style>
13
+
14
+ </style>
15
+ <script>
16
+ $(function() {
17
+ if (navigator.userAgent.indexOf("Trident/5") > -1)
18
+ $("html").addClass("lt-ie9")
19
+ });
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <div id="masthead"></div>
24
+ <div id="content">
25
+ <div class="flash">
26
+ </div>
27
+ <script>
28
+ window.panel_validations = {};
29
+ // for setting values of raw_content
30
+ window.extra_question_values = {};
31
+ // for showing validations of raw content
32
+ window.extra_failed_validations = {};
33
+ </script>
34
+ <form class="test paged" autocomplete="off" id="questionnaire-form" action="/quby/questionnaires/test/answers/77f75e2e-b040-4a3a-a6de-f3f55a868c32" accept-charset="UTF-8" data-remote="true" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="_method" value="put">
35
+ <input type="hidden" name="token" id="token">
36
+ <input type="hidden" name="hmac" id="hmac">
37
+ <input type="hidden" name="timestamp" id="timestamp">
38
+ <input type="hidden" name="return_url" id="return_url">
39
+ <input type="hidden" name="return_token" id="return_token">
40
+ <input type="hidden" name="display_mode" id="display_mode" value="paged">
41
+ <input type="hidden" name="rendered_at" id="rendered_at" value="1603805120">
42
+
43
+ <!-- Begin _panel.html.haml -->
44
+ <fieldset class="panel hidden first last-panel current" id="panel0" style="display: block;">
45
+ <div class="panel-action-links">
46
+
47
+ </div>
48
+ <script>
49
+ panel_validations["panel0"] = {"v_1_a1_val":[{"type":"requires_answer","explanation":null},{"type":"valid_integer","explanation":null}],"v_1_a2_val":[{"type":"requires_answer","explanation":null},{"type":"valid_integer","explanation":null}],"v_1":[{"type":"requires_answer","explanation":null}]};
50
+ </script>
51
+ <script>
52
+ $(function() {
53
+ Quby.currentPanelQuestions = new Quby.Collections.Questions;
54
+ var questions = [{"class":"Quby::Questionnaires::Entities::Questions::RadioQuestion","key":"v_1","title":"\u003cp\u003eA select box\u003c/p\u003e","description":"","type":"radio","unit":null,"size":null,"hidden":null,"displayModes":null,"defaultInvisible":false,"viewSelector":"#item_v_1","parentKey":null,"parentOptionKey":null,"deselectable":true,"presentation":"vertical","as":null,"questionGroup":null,"options":[{"key":"a1","value":1,"description":"\u003cp\u003eJa\u003c/p\u003e","context_free_description":"\u003cp\u003eJa\u003c/p\u003e","questions":[{"class":"Quby::Questionnaires::Entities::Questions::IntegerQuestion","key":"v_1_a1_val","title":"","description":"","type":"integer","unit":null,"size":30,"hidden":null,"displayModes":null,"defaultInvisible":false,"viewSelector":"#item_v_1_a1_val","parentKey":"v_1","parentOptionKey":"a1","deselectable":true,"presentation":"vertical","as":null,"questionGroup":null}],"innerTitle":null,"hidesQuestions":[],"showsQuestions":[],"hidden":false,"placeholder":false,"viewId":"answer_v_1_a1","startChosen":false},{"key":"a2","value":2,"description":"\u003cp\u003eNee\u003c/p\u003e","context_free_description":"\u003cp\u003eNee\u003c/p\u003e","questions":[{"class":"Quby::Questionnaires::Entities::Questions::IntegerQuestion","key":"v_1_a2_val","title":"","description":"","type":"integer","unit":null,"size":30,"hidden":null,"displayModes":null,"defaultInvisible":false,"viewSelector":"#item_v_1_a2_val","parentKey":"v_1","parentOptionKey":"a2","deselectable":true,"presentation":"vertical","as":null,"questionGroup":null}],"innerTitle":null,"hidesQuestions":[],"showsQuestions":[],"hidden":false,"placeholder":false,"viewId":"answer_v_1_a2","startChosen":true}]}];
55
+ var initializer = new Quby.Logic.InitQuestions(questions);
56
+ Quby.currentPanelQuestions = initializer.initializeQuestions();
57
+ Quby.questions.addQuestions(Quby.currentPanelQuestions);
58
+ panelProps = {panelId: 'panel0', questions: Quby.currentPanelQuestions}
59
+ Quby.panels.add(new Quby.Models.Panel(panelProps));
60
+ });
61
+ </script>
62
+
63
+ <!-- .panel_index= panel_counter + 1 -->
64
+ <!-- Begin _item.html.haml -->
65
+ <div class="item radio vertical" id="item_v_1">
66
+ <div class="error requires_answer hidden">Deze vraag moet beantwoord worden.</div>
67
+
68
+ <div class="main" data-for="v_1">
69
+ <label for="answer_v_1"><p>A select box</p></label>
70
+ </div>
71
+
72
+ <div class="description-and-fields">
73
+ <div class="description">
74
+ </div>
75
+ <div class="fields" id="answer_v_1_input">
76
+ <div class="option" for="v_1">
77
+ <div class="radiocheckwrapper">
78
+ <input class="radio deselectable" data-field-key="v_1" type="radio" value="a1" name="answer[v_1]" id="answer_v_1_a1">
79
+ </div>
80
+ <div class="labelwrapper">
81
+ <label for="answer_v_1_a1">
82
+ <span>
83
+ <p>Ja</p>
84
+ </span>
85
+ </label>
86
+ </div>
87
+ <div class="subquestions"><!-- Begin _item.html.haml -->
88
+ <div class="item integer vertical subitem" id="item_v_1_a1_val">
89
+ <div class="error requires_answer hidden">Deze vraag moet beantwoord worden.</div>
90
+ <div class="error valid_integer hidden">Uw antwoord moet een afgerond getal zijn.</div>
91
+
92
+
93
+
94
+ <div class="description-and-fields">
95
+ <div class="description">
96
+ </div>
97
+ <div class="fields" id="answer_v_1_a1_val_input">
98
+ <input autocomplete="off" class="integer subinput" disabled="disabled" size="30" data-show-values="false" data-field-key="v_1_a1_val" type="text" name="answer[v_1_a1_val]" id="answer_v_1_a1_val">
99
+ <span class="unit"></span>
100
+ </div>
101
+ </div>
102
+
103
+ </div>
104
+ <!-- End _item.html.haml -->
105
+ </div>
106
+ </div>
107
+ <div class="option" for="v_1">
108
+ <div class="radiocheckwrapper">
109
+ <input class="radio deselectable" data-field-key="v_1" type="radio" value="a2" checked="checked" name="answer[v_1]" id="answer_v_1_a2">
110
+ </div>
111
+ <div class="labelwrapper">
112
+ <label for="answer_v_1_a2">
113
+ <span>
114
+ <p>Nee</p>
115
+ </span>
116
+ </label>
117
+ </div>
118
+ <div class="subquestions"><!-- Begin _item.html.haml -->
119
+ <div class="item integer vertical subitem" id="item_v_1_a2_val">
120
+ <div class="error requires_answer hidden">Deze vraag moet beantwoord worden.</div>
121
+ <div class="error valid_integer hidden">Uw antwoord moet een afgerond getal zijn.</div>
122
+
123
+
124
+
125
+ <div class="description-and-fields">
126
+ <div class="description">
127
+ </div>
128
+ <div class="fields" id="answer_v_1_a2_val_input">
129
+ <input autocomplete="off" class="integer subinput" size="30" data-show-values="false" data-field-key="v_1_a2_val" type="text" name="answer[v_1_a2_val]" id="answer_v_1_a2_val">
130
+ <span class="unit"></span>
131
+ </div>
132
+ </div>
133
+
134
+ </div>
135
+ <!-- End _item.html.haml -->
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </div>
140
+
141
+ </div>
142
+ <!-- End _item.html.haml -->
143
+
144
+ <div class="buttons">
145
+ <div class="prev" style="visibility: hidden;">
146
+ <input type="submit" name="previous" value="← Terug" id="prevButton0" tabindex="-1" data-disable-with="← Terug">
147
+ </div>
148
+ <div class="abort">
149
+ &nbsp;
150
+ </div>
151
+ <div class="save">
152
+ <input type="submit" name="done" value="Klaar" id="done-button" data-disable-with="Klaar">
153
+ </div>
154
+ <div class="print">
155
+ <a class="print_button" data-url="/quby/questionnaires/test/answers/77f75e2e-b040-4a3a-a6de-f3f55a868c32/pdf" href="#" id="print-button">
156
+ <img src="/assets/quby/pdf-f359df32ce6a12283052679fb5f48e210c5441400f1ddee7edca611fdf722864.gif">
157
+ Download als PDF
158
+ </a>
159
+ <div class="hidden" id="ios-download-instruction">
160
+ Er opent een nieuw tabblad waarop de download wordt gestart.
161
+
162
+ Sla het bestand op in Boeken/iBooks. Keer dan terug naar de browser met de knop '&lt; Safari' geheel linksboven.
163
+
164
+ Ga in de browser terug met de terug knop '&lt;' en druk op 'Klaar' om je invulling vast te leggen.
165
+ </div>
166
+ </div>
167
+
168
+ </div>
169
+ </fieldset>
170
+ <!-- End _panel.html.haml -->
171
+
172
+ </form>
173
+
174
+ <script>
175
+ $(function() {
176
+ Quby.init({
177
+ questionnaire_key: "test",
178
+ answer_value: {"v_1":"a2"},
179
+ flag_definitions: {},
180
+ flag_values: {},
181
+ textvars: {}
182
+ });
183
+
184
+ // Initialize all panels in bulk, activate first panel otherwise
185
+ if(isBulkOrSinglePage) {
186
+ initShowsHides("all_panels");
187
+ } else {
188
+ activatePanel($(".panel:first"), true);
189
+ }
190
+ });
191
+ </script>
192
+
193
+ <div class="hidden" id="modalFrameDialog">
194
+ <iframe id="modalFrame"></iframe>
195
+ </div>
196
+
197
+
198
+ <div class="flash">
199
+ </div>
200
+ </div>
201
+ <div class="x_container"></div>
202
+ <noscript>
203
+ <div id='noscript-warning'>Deze vragenlijst heeft ondersteuning voor JavaScript nodig.</div>
204
+ </noscript>
205
+
206
+
207
+ </body></html>
@@ -148,14 +148,14 @@ module Quby::Answers::Services
148
148
  describe '#question_groups' do
149
149
  it 'sets the @question_groups attribute to a hash of the question groups' do
150
150
  expect(answer.question_groups).to eq({
151
- group1: [:v_answer_group_under_minimum, :v_answer_group_under_minimum1],
152
- group2: [:v_answer_group_over_minimum, :v_answer_group_over_minimum1],
153
- group3: [:v_answer_group_under_maximum, :v_answer_group_under_maximum1],
154
- group4: [:v_answer_group_over_maximum, :v_answer_group_over_maximum1],
155
- cgroup1: [:v_check_answer_group_under_minimum, :v_check_answer_group_under_minimum1],
156
- cgroup2: [:v_check_answer_group_over_minimum, :v_check_answer_group_over_minimum1],
157
- cgroup3: [:v_check_answer_group_under_maximum, :v_check_answer_group_under_maximum1],
158
- cgroup4: [:v_check_answer_group_over_maximum, :v_check_answer_group_over_maximum1]
151
+ "group1" => [:v_answer_group_under_minimum, :v_answer_group_under_minimum1],
152
+ "group2" => [:v_answer_group_over_minimum, :v_answer_group_over_minimum1],
153
+ "group3" => [:v_answer_group_under_maximum, :v_answer_group_under_maximum1],
154
+ "group4" => [:v_answer_group_over_maximum, :v_answer_group_over_maximum1],
155
+ "cgroup1" => [:v_check_answer_group_under_minimum, :v_check_answer_group_under_minimum1],
156
+ "cgroup2" => [:v_check_answer_group_over_minimum, :v_check_answer_group_over_minimum1],
157
+ "cgroup3" => [:v_check_answer_group_under_maximum, :v_check_answer_group_under_maximum1],
158
+ "cgroup4" => [:v_check_answer_group_over_maximum, :v_check_answer_group_over_maximum1]
159
159
  })
160
160
  end
161
161
  end
@@ -0,0 +1,237 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Quby::Questionnaires::Deserializer do
6
+ it 'sets title' do
7
+ questionnaire = dsl { title 'Foo' }
8
+ expect(questionnaire.title).to eq('Foo')
9
+ end
10
+
11
+ it 'sets description' do
12
+ questionnaire = dsl { description 'This is a questionnaire description' }
13
+ expect(questionnaire.description).to eq('This is a questionnaire description')
14
+ end
15
+
16
+ it 'sets outcome_description' do
17
+ questionnaire = dsl { outcome_description 'Outcome description' }
18
+ expect(questionnaire.outcome_description).to eq('Outcome description')
19
+ end
20
+
21
+ it 'set sbg_key' do
22
+ questionnaire = dsl { sbg_key 'foo' }
23
+ expect(questionnaire.sbg_key).to eq('foo')
24
+ end
25
+
26
+ it 'can request outcome regeneration' do
27
+ timestamp = Time.local(2020, 5, 12, 4, 28, 19)
28
+ questionnaire = dsl { outcome_regeneration_requested_at timestamp }
29
+ expect(questionnaire.outcome_regeneration_requested_at).to eq(timestamp)
30
+ end
31
+
32
+ it 'can request answers to be deactivated' do
33
+ timestamp = Time.local(2020, 5, 12, 4, 28, 19)
34
+ questionnaire = dsl { deactivate_answers_requested_at timestamp }
35
+ expect(questionnaire.deactivate_answers_requested_at).to eq(timestamp)
36
+ end
37
+
38
+ describe 'roqua keys' do
39
+ it 'defaults to key' do
40
+ questionnaire = dsl("example") {}
41
+ expect(questionnaire.roqua_keys).to eq(["example"])
42
+ end
43
+
44
+ it 'sets roqua keys' do
45
+ questionnaire = dsl { roqua_keys :alg_o, :alg_o2 }
46
+ expect(questionnaire.roqua_keys).to eq(["alg_o", "alg_o2"])
47
+ end
48
+ end
49
+
50
+ describe 'sbg_domain' do
51
+ it 'sets sbg_domain' do
52
+ questionnaire = dsl do
53
+ sbg_domain '02', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'OQ45-sd', primary: true
54
+ end
55
+ expect(questionnaire.sbg_domains).to eq(
56
+ [
57
+ {sbg_code: '02', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'OQ45-sd', primary: true}
58
+ ]
59
+ )
60
+ end
61
+
62
+ it 'sets multiple sbg_domains with optional attributes' do
63
+ questionnaire = dsl do
64
+ sbg_domain '02', outcome: '01', sbg_key: 'OQ45-sd', primary: false
65
+ sbg_domain '03', outcome: '02', from: '2000-01-01', till: '2099-12-31'
66
+ end
67
+ expect(questionnaire.sbg_domains).to eq(
68
+ [
69
+ {sbg_code: '02', from: nil, till: nil, outcome: '01', sbg_key: 'OQ45-sd', primary: false},
70
+ {sbg_code: '03', from: '2000-01-01', till: '2099-12-31', outcome: '02', sbg_key: nil, primary: false}
71
+ ]
72
+ )
73
+ end
74
+
75
+ it 'defaults the sbg_key to the sbg_key of the questionnaire' do
76
+ questionnaire = dsl do
77
+ sbg_key 'example'
78
+ sbg_domain '03', from: '2000-01-01', till: '2099-12-31', outcome: '01'
79
+ end
80
+ expect(questionnaire.sbg_domains).to eq(
81
+ [
82
+ {sbg_code: '03', from: '2000-01-01', till: '2099-12-31', outcome: '01', sbg_key: 'example', primary: false}
83
+ ]
84
+ )
85
+ end
86
+ end
87
+
88
+ it 'does not accept invalid sbg_domains options' do
89
+ expect { dsl { sbg_domain '02', foo: 'bar' } }.to raise_exception(ArgumentError, "missing keyword: outcome")
90
+ end
91
+
92
+ it 'can be abortable' do
93
+ questionnaire = dsl { }
94
+ expect(questionnaire.abortable).to be_falsey
95
+
96
+ questionnaire = dsl { abortable }
97
+ expect(questionnaire.abortable).to be_truthy
98
+ end
99
+
100
+ it 'can allow hotkeys' do
101
+ questionnaire = dsl { allow_hotkeys }
102
+ expect(questionnaire.allow_hotkeys).to eq("all")
103
+ end
104
+
105
+ it 'can set license' do
106
+ questionnaire = dsl { license :free }
107
+ expect(questionnaire.license).to eq(:free)
108
+ expect(questionnaire.licensor).to be_nil
109
+ end
110
+
111
+ it 'can set licensor' do
112
+ questionnaire = dsl { license :free, licensor: 'FOO' }
113
+ expect(questionnaire.licensor).to eq('FOO')
114
+ end
115
+
116
+ it 'can set language' do
117
+ questionnaire = dsl { language :en }
118
+ expect(questionnaire.language).to eq(:en)
119
+ end
120
+
121
+ it 'defaults to Dutch language' do
122
+ questionnaire = dsl { }
123
+ expect(questionnaire.language).to eq(:nl)
124
+ end
125
+
126
+ it 'can set respondent_types' do
127
+ questionnaire = dsl { respondent_types :patient, :parent }
128
+ expect(questionnaire.respondent_types).to eq([:patient, :parent])
129
+ end
130
+
131
+ it 'can set tags' do
132
+ questionnaire = dsl { tags :diary }
133
+ expect(questionnaire.tags.diary).to be_truthy
134
+ expect(questionnaire.tags.another_tag).to be_falsey
135
+ end
136
+
137
+ it 'builds panels' do
138
+ questionnaire = dsl { panel { title 'My Title' } }
139
+ expect(questionnaire.panels.first.title).to eq('My Title')
140
+ end
141
+
142
+ it 'builds line charts' do
143
+ questionnaire = dsl { line_chart(:tot) { title 'My Title'; range 0..40 } }
144
+ expect(questionnaire.charts.find(:tot).title).to eq('My Title')
145
+ end
146
+
147
+ it 'builds bar charts' do
148
+ questionnaire = dsl { bar_chart(:tot) { title 'My Title' } }
149
+ expect(questionnaire.charts.find(:tot).title).to eq('My Title')
150
+ end
151
+
152
+ it 'builds radar charts' do
153
+ questionnaire = dsl { radar_chart(:tot) { title 'My Title' } }
154
+ expect(questionnaire.charts.find(:tot).title).to eq('My Title')
155
+ end
156
+
157
+ it 'sets a depends_on key correctly' do
158
+ questionnaire = dsl do
159
+ question :v_1, type: :check_box do
160
+ option :v_1_a
161
+ end
162
+ question :v_2, type: :string, depends_on: [:v_1]
163
+ end
164
+ expect(questionnaire.question_hash[:v_2].depends_on).to eq [:v_1_a]
165
+ end
166
+
167
+ it 'sets the parent option key on subquestions correctly' do
168
+ questionnaire = dsl do
169
+ question :v_1, type: :check_box do
170
+ option :v_1a do
171
+ question :v_2, type: :string
172
+ end
173
+ option :v_1b
174
+ end
175
+ end
176
+ expect(questionnaire.question_hash[:v_2].parent_option_key).to eq(:v_1a)
177
+ end
178
+
179
+ describe 'flag' do
180
+ before do
181
+ allow_any_instance_of(Quby::Questionnaires::Entities::Questionnaire).to receive(:add_flag)
182
+ end
183
+
184
+ it 'defines flags' do
185
+ questionnaire = dsl do
186
+ flag key: :test, description: 'test flag'
187
+ end
188
+ expect(questionnaire.flags[:test_test].description).to eq("test flag")
189
+ end
190
+ end
191
+
192
+ describe '#add_lookup_tree' do
193
+ it 'can add a lookup tree' do
194
+ questionnaire = dsl do
195
+ add_lookup_tree :interpretations,
196
+ levels: ['score', 'interpretation'],
197
+ tree: {
198
+ 0..24 => 'low',
199
+ 25..50 => 'high'
200
+ }
201
+ end
202
+
203
+ expect(questionnaire.lookup_tables[:interpretations].lookup(score: 26)).to eq 'high'
204
+ end
205
+ end
206
+
207
+ describe '#score_schema' do
208
+ it 'calls #add_score_schema with the given arguments' do
209
+ options = [{key: :value, export_key: :tot, label: 'Score'}]
210
+ questionnaire = dsl do
211
+ score :totaal, label: 'totaal' do
212
+ {value: 100}
213
+ end
214
+
215
+ score_schema :totaal, 'Totaal', options
216
+ end
217
+
218
+ expect(questionnaire.score_schemas[:totaal].subscore_schemas[0].export_key).to eq(:tot)
219
+ end
220
+ end
221
+
222
+ describe '#outcome_table' do
223
+ it 'calls questionnaire.add_outcome_table with the given arguments' do
224
+ questionnaire = dsl do
225
+ outcome_table key: :default, score_keys: [:a], subscore_keys: [:b]
226
+ end
227
+ expect(questionnaire.outcome_tables[0].score_keys).to eq([:a])
228
+ expect(questionnaire.outcome_tables[0].subscore_keys).to eq([:b])
229
+ end
230
+ end
231
+
232
+ def dsl(key = "test", &block)
233
+ source = Quby::Compiler::DSL.build(key, "", &block)
234
+ json = Quby::Compiler::Outputs::QubyFrontendV1Serializer.new(source).to_json
235
+ described_class.from_json(JSON.parse(json))
236
+ end
237
+ end