quby 4.0.4 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +0 -1
  3. data/lib/quby.rb +2 -10
  4. data/lib/quby/answers/entities/answer.rb +4 -2
  5. data/lib/quby/answers/services/score_calculator.rb +1 -3
  6. data/lib/quby/engine.rb +0 -1
  7. data/lib/quby/questionnaires.rb +1 -0
  8. data/lib/quby/questionnaires/api.rb +5 -1
  9. data/lib/quby/questionnaires/deserializer.rb +441 -0
  10. data/lib/quby/questionnaires/dsl.rb +12 -15
  11. data/lib/quby/questionnaires/entities.rb +1 -0
  12. data/lib/quby/questionnaires/entities/charting/line_chart.rb +23 -0
  13. data/lib/quby/questionnaires/entities/charting/overview_chart.rb +3 -1
  14. data/lib/quby/questionnaires/entities/definition.rb +3 -5
  15. data/lib/quby/questionnaires/entities/fields.rb +0 -15
  16. data/lib/quby/questionnaires/entities/question.rb +9 -32
  17. data/lib/quby/questionnaires/entities/questionnaire.rb +4 -15
  18. data/lib/quby/questionnaires/entities/questions/checkbox_question.rb +0 -24
  19. data/lib/quby/questionnaires/entities/questions/date_question.rb +0 -8
  20. data/lib/quby/questionnaires/entities/score_calculation.rb +40 -3
  21. data/lib/quby/questionnaires/repos.rb +1 -0
  22. data/lib/quby/questionnaires/repos/bundle_disk_repo.rb +51 -0
  23. data/lib/quby/table_backend/range_tree.rb +0 -51
  24. data/lib/quby/version.rb +1 -1
  25. data/spec/features/tables_spec.rb +40 -0
  26. data/spec/fixtures/score_test.rb +4 -0
  27. data/spec/internal/log/test-events.log +183 -0
  28. data/spec/internal/log/test.log +5522 -0
  29. data/spec/internal/tmp/cache/assets/sprockets/v3.0/00/00nglkSepN01iGiDa7URmJtWQP-xSWffZb9wJgBqUr4.cache +2 -0
  30. data/spec/internal/tmp/cache/assets/sprockets/v3.0/1V/1VQnRlqKBL0MybpMmC3EVtA2s6-ZX-GSGs2Cza3g3kI.cache +1 -0
  31. data/spec/internal/tmp/cache/assets/sprockets/v3.0/1_/1_J_3havMjJDCz3iAQXAXXBh6tBQRJ3OpdWm3W46ss8.cache +1 -0
  32. data/spec/internal/tmp/cache/assets/sprockets/v3.0/4G/4gcYvPHmPX3fZw9xr6plMl5Hfbo2xTWwcD7T7lIlD4Y.cache +2 -0
  33. data/spec/internal/tmp/cache/assets/sprockets/v3.0/4_/4_FK6PMcF1eyIQx7RtVQ5t8c6X7smPQmJWNN5YTImVc.cache +1 -0
  34. data/spec/internal/tmp/cache/assets/sprockets/v3.0/4d/4Dd15Upcg8_kiEsx_5wpQNrjM1sCk0tGTtWGhtmCKpg.cache +1 -0
  35. data/spec/internal/tmp/cache/assets/sprockets/v3.0/4h/4hd8RzwlWb2IEeLLZN0s-3_sdJXtw6nu2k5baLb9vNs.cache +0 -0
  36. data/spec/internal/tmp/cache/assets/sprockets/v3.0/5X/5xFJleOz2sGyE9gbs8KPkToDiv3s9bwFzroBRcjPELY.cache +0 -0
  37. data/spec/internal/tmp/cache/assets/sprockets/v3.0/6Y/6y1tV_fKJP9YIQn-dF847aZ9kza1O7iyTEUht42D7nc.cache +0 -0
  38. data/spec/internal/tmp/cache/assets/sprockets/v3.0/6d/6dfYZY_DkQe892FZVDUbBbrINslzVUkLZePdnVxO3Ps.cache +1 -0
  39. data/spec/internal/tmp/cache/assets/sprockets/v3.0/6w/6WcYsWQCgw0z_URAWGhOsbiKXcqVxZ--ImazY5S-2Gk.cache +2 -0
  40. data/spec/internal/tmp/cache/assets/sprockets/v3.0/77/77EJjFGVCRzLbhJy6KZZUYe5w0LxsqZQcmFcHAbxKeQ.cache +1 -0
  41. data/spec/internal/tmp/cache/assets/sprockets/v3.0/7f/7fvhJnfiJknq6sA-MPtumXlL5qB-rfH__Heye13NyHc.cache +1 -0
  42. data/spec/internal/tmp/cache/assets/sprockets/v3.0/8W/8W6AwDwFqo6egmWyt6Cs0vf_XJbT2YxPs2sqbo0Q9kk.cache +2 -0
  43. data/spec/internal/tmp/cache/assets/sprockets/v3.0/8c/8cQ8uBhUhrouKwor0Z87dDCxyPbqbLvK8KEFEgjHxqM.cache +0 -0
  44. data/spec/internal/tmp/cache/assets/sprockets/v3.0/9L/9LJo1U9wQdfWrrn3HkNZTgIZc6jeHvWbGk8tJ4m_Qec.cache +1 -0
  45. data/spec/internal/tmp/cache/assets/sprockets/v3.0/9o/9oXJXZnA6F49i4EflydD0Ivx6dhSxGGDD69G-N5NSCg.cache +0 -0
  46. data/spec/internal/tmp/cache/assets/sprockets/v3.0/A1/a1jgtYtDHIb04Og07H6_XNmhXppaAnFiO88kgq80edQ.cache +1 -0
  47. data/spec/internal/tmp/cache/assets/sprockets/v3.0/AC/ACV6t4unw39Kpn2DnbBtHeJYLoAHyyBN1DTRXs6a2ik.cache +1 -0
  48. data/spec/internal/tmp/cache/assets/sprockets/v3.0/BO/BoVO8e1GTTGHfnJTOByDxMlvVi9fNGyOdSubqCbBITI.cache +2 -0
  49. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ba/babjk3aW-jBoEw_ERhmT5ZQprEqilJCWmImrvVskWk8.cache +0 -0
  50. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Cg/cgb1vvOogMD0V1lqQ5k_mny7Z38rbqBdIumlGh5sZ_E.cache +0 -0
  51. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Cw/CwjNk_RYiC93RW8vRs7fWsHcwKTg7uE9OLifRm3Y6WA.cache +2 -0
  52. data/spec/internal/tmp/cache/assets/sprockets/v3.0/DY/Dy1qsY0W-eyFR6RVKSCCli-XsitpaXD4DwTjXL86t2M.cache +1 -0
  53. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Dk/DkGOwkJNeDdljv4b8QbwtPVrsghwYuA6EOxx1goEQg0.cache +1 -0
  54. data/spec/internal/tmp/cache/assets/sprockets/v3.0/FG/fGmVSU-v7aZV9-CLG5U2OmteGgWTuAotlFcwFyx4Eqs.cache +1 -0
  55. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Fd/fDidWZjSZsPN4uAEyVYABV2WFCSR7AZE0l8U-9XOw7U.cache +0 -0
  56. data/spec/internal/tmp/cache/assets/sprockets/v3.0/G1/G1RRwpldS5MGQ5x-WHyPWzXJWDOd2qyWMMFumuU4-Ms.cache +1 -0
  57. data/spec/internal/tmp/cache/assets/sprockets/v3.0/GG/ggGfy_gZryUPmYwgenN3A4jv0q-buxyjCGdLB6wfHxQ.cache +1 -0
  58. data/spec/internal/tmp/cache/assets/sprockets/v3.0/GY/gYwYoJrifknCG-a0FXlM1NU6tUj1JXxm27s-a0uP_IE.cache +1 -0
  59. data/spec/internal/tmp/cache/assets/sprockets/v3.0/I6/i64Ysik0cyoTrYF0-O63B7sN3AdIgeoJ7zLh9pMC2u4.cache +0 -0
  60. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ic/ICKeOd4yOff3JGsfU1XliLgXfJtTPKSbXsqNVZAb1-Y.cache +1 -0
  61. data/spec/internal/tmp/cache/assets/sprockets/v3.0/J7/J75M1l--IMcCn-Wy7uWv17SWaj0DFaGiiwac63pENPQ.cache +1 -0
  62. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Jh/JHPqsKZsrkvQg23ukphinYoViiIw3askwCMP8VrHTMk.cache +1 -0
  63. data/spec/internal/tmp/cache/assets/sprockets/v3.0/K9/k9tOCRdX5tsxa5LImq7MZk0WzC692t8tx5LzLln0l4Q.cache +0 -0
  64. data/spec/internal/tmp/cache/assets/sprockets/v3.0/LY/ly4TNAIbW9ghgXz8mxfmskR_6AkuiMiG-RIFGhewgQ0.cache +1 -0
  65. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Lq/LQ9fP0wIqVc5s-AtP3ESWJr0qpkDe-VpTxpgYl-9FfU.cache +1 -0
  66. data/spec/internal/tmp/cache/assets/sprockets/v3.0/MO/MOmnpcaRW98Ke-zTOOCSZ0ODnnQntKhQr0vFc_un1_A.cache +1 -0
  67. data/spec/internal/tmp/cache/assets/sprockets/v3.0/OX/OxOBsUA5EpScoZgEt_UhsHzhu-GGmxKnHpCwnhbTwiM.cache +1 -0
  68. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ot/oTVAc3-iuSlg7XAM-YIAhw3cdc5yhgL2-tK3N7sfOfU.cache +0 -0
  69. data/spec/internal/tmp/cache/assets/sprockets/v3.0/PK/pKNcBOgAbCyIwsWIvnlmiPiFxrw6nUo_nTz7wWFDr80.cache +1 -0
  70. data/spec/internal/tmp/cache/assets/sprockets/v3.0/QB/QBMvSW7SYbYcm5lSjybgO7fhHDFIQjJWOvefH0MQC-A.cache +0 -0
  71. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Qs/QSbtm1y8JKPV0MQkpiC0hEisaSjKZ3tp2AWHSrhO30Y.cache +1 -0
  72. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Sp/SpyGDguFy3tp0sim1miZOehEDpE97oueO7wl3oUFYcE.cache +1 -0
  73. data/spec/internal/tmp/cache/assets/sprockets/v3.0/TW/TwtJPRSE9lmwTuSP0lezWSRSBp2u43zuF196FQcHY-c.cache +1 -0
  74. data/spec/internal/tmp/cache/assets/sprockets/v3.0/VX/Vxn9zv60MCKUBfRhrjefo-MEzFej81PPEutxTPQ4VLQ.cache +0 -0
  75. data/spec/internal/tmp/cache/assets/sprockets/v3.0/Vr/vrqPEzlsuORocHY0EbtGdFomRmrcoAa6wWSDMx642-Q.cache +2 -0
  76. data/spec/internal/tmp/cache/assets/sprockets/v3.0/WH/WHVQ0GBe51hbYqv2g7YYo7EIw9PSzt9-RqU7hKP2dc4.cache +1 -0
  77. data/spec/internal/tmp/cache/assets/sprockets/v3.0/_B/_B796ezRHfk7H8YKj7zr3-gRy6Mw2IVn2NbHu-k20ug.cache +1 -0
  78. data/spec/internal/tmp/cache/assets/sprockets/v3.0/_W/_Wh-7b1t-Xm19wg3KPtkXq7DOpohaL5OhnLggzJLpj4.cache +0 -0
  79. data/spec/internal/tmp/cache/assets/sprockets/v3.0/b2/B2y-2qTbQYKRm6_sCQ6qfUeVfl9rKXUvotTDm56w4bs.cache +1 -0
  80. data/spec/internal/tmp/cache/assets/sprockets/v3.0/bw/bwFR2MLpvJvPSAPJzSLWk6TUDCw5TlBFUUuq7z_Y9vg.cache +1 -0
  81. data/spec/internal/tmp/cache/assets/sprockets/v3.0/c7/c7ubvrHhbhAYh-K4srvM9EqwWdbWTLrsLMgjG5XQDbY.cache +1 -0
  82. data/spec/internal/tmp/cache/assets/sprockets/v3.0/cX/CXpMzZYfJy6HIOVXN0IyYilvy6J4CDgFZIwqKm8OQEU.cache +1 -0
  83. data/spec/internal/tmp/cache/assets/sprockets/v3.0/eN/EN0enu5dkKEnIz-DVCpbhkfeph7wImeXnlqb7SXMrjE.cache +1 -0
  84. data/spec/internal/tmp/cache/assets/sprockets/v3.0/fu/fuP9zP6C6rj650HLkypoTfYN2KD1ecB9HdtlbhbA2cg.cache +1 -0
  85. data/spec/internal/tmp/cache/assets/sprockets/v3.0/gr/gRPXI3EsVPwysy9YKW_6yDxaqRRr4Idxtexf7zCHECw.cache +1 -0
  86. data/spec/internal/tmp/cache/assets/sprockets/v3.0/h0/h0P63ZZdlSbtztDOe0V9r7jtCoy0L2bAf_iDNKLJ0nk.cache +1 -0
  87. data/spec/internal/tmp/cache/assets/sprockets/v3.0/i-/i-Or0Xuxbbm3-HdE_xGIf6sAx2vhUa3eVMpbT37lyEo.cache +1 -0
  88. data/spec/internal/tmp/cache/assets/sprockets/v3.0/iF/iFP67If98izMEAAMKnAFi2dWAb8TNlHNayZKNjXdAMs.cache +1 -0
  89. data/spec/internal/tmp/cache/assets/sprockets/v3.0/iH/Ih2svq5ul-xibfRUfd1fxigouli6U19Rf80FrTSoMak.cache +1 -0
  90. data/spec/internal/tmp/cache/assets/sprockets/v3.0/ka/Ka_YEbZNQxpS8XAA7xZturgPr2vLYQq60KK1uwou4Lo.cache +1 -0
  91. data/spec/internal/tmp/cache/assets/sprockets/v3.0/kq/KqkIGfAdJjTcr53lFl1aDAMUeqhhKdXGyTlHVlCz0R4.cache +1 -0
  92. data/spec/internal/tmp/cache/assets/sprockets/v3.0/mR/mRDPkwomGSfjpIWEKtPPBSx5cBHssvH8v0gCSI33P3Y.cache +1 -0
  93. data/spec/internal/tmp/cache/assets/sprockets/v3.0/n4/n4qaNjjNvKB0VAbVJlP_BjFlcLf70TsBzcIMc7VO9dw.cache +2 -0
  94. data/spec/internal/tmp/cache/assets/sprockets/v3.0/nY/nykt5oy2ExUYa8g1phLCDRqwb55BuUot5ZBbRdNuCCw.cache +2 -0
  95. data/spec/internal/tmp/cache/assets/sprockets/v3.0/nv/nvmgm4bOtxCbD6EA14ZIwDcYO8fxXOoEk_s7V-uRMMM.cache +1 -0
  96. data/spec/internal/tmp/cache/assets/sprockets/v3.0/oG/og5ypFjbFAX_nH7oxK6Bn5Ejh81BMDBSMxbGcL5ZbQs.cache +1 -0
  97. data/spec/internal/tmp/cache/assets/sprockets/v3.0/oO/oO4iBwOm5E7uLH39zeR8zun4eBM-WxZKvEMpIYKx6SU.cache +1 -0
  98. data/spec/internal/tmp/cache/assets/sprockets/v3.0/pN/PnQ-dEclV6jTDE4kkqw4G9dBpHArAgUnATOpRrQAsGc.cache +1 -0
  99. data/spec/internal/tmp/cache/assets/sprockets/v3.0/pe/pet4fFbc2Cm2SD_ZBO_s83Gey29EXE26u-7lwn2O8gM.cache +1 -0
  100. data/spec/internal/tmp/cache/assets/sprockets/v3.0/qo/Qoqb-JjTe1BiY4rICKHm5e6bsPt-DHXZc4ADXESjw2I.cache +1 -0
  101. data/spec/internal/tmp/cache/assets/sprockets/v3.0/qx/QXICLj9xx1EI9rBeXLXpKOeHGll_LBWHRWlpb1DK424.cache +1 -0
  102. data/spec/internal/tmp/cache/assets/sprockets/v3.0/rM/rMF4Y2UGkmBABLlC1eSSqb6y6g_Z3uUCLBtFvz_LoyI.cache +1 -0
  103. data/spec/internal/tmp/cache/assets/sprockets/v3.0/ty/ty1qAnpL07anYdhIJoiPYLcsWKejuzy6JaxU9mI7egw.cache +1 -0
  104. data/spec/internal/tmp/cache/assets/sprockets/v3.0/uH/UHs9nE45XS7v4QlMjSjhwHbqYIKC06FsEjMSMIfKanU.cache +1 -0
  105. data/spec/internal/tmp/cache/assets/sprockets/v3.0/v8/v8VXJ3AQom-JqxBYAB7tOjV-tt4IdDb6YyFEzlsWV8c.cache +1 -0
  106. data/spec/internal/tmp/cache/assets/sprockets/v3.0/vD/VDI2CxkTg7-DuMcLmofLvch0yukSl88oI_AjGgN-hQ8.cache +1 -0
  107. data/spec/internal/tmp/cache/assets/sprockets/v3.0/wq/wqhk46aZc1Bbb8gTCOZKxTvwTV0ANLSz8VdQYACo03E.cache +1 -0
  108. data/spec/internal/tmp/cache/assets/sprockets/v3.0/xy/Xy8Yk--iYZNupHMjUtYX1AQ0BppsvThCh_ZAizblCb0.cache +1 -0
  109. data/spec/internal/tmp/cache/assets/sprockets/v3.0/zu/zUCfHRTHprn06F5WxH6wp_BLs9-yhs-foc0j0Y7BYbg.cache +1 -0
  110. data/spec/internal/tmp/cache/assets/sprockets/v3.0/zx/ZX2IY3eKQjBy93tlH7_Xg7zGZKYuaQ-E8YPvtPT_4vM.cache +1 -0
  111. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-35.705.html +1 -0
  112. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-35.705.png +0 -0
  113. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.005.html +1 -0
  114. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.005.png +0 -0
  115. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.276.html +1 -0
  116. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.276.png +0 -0
  117. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.556.html +1 -0
  118. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.556.png +0 -0
  119. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.818.html +1 -0
  120. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.818.png +0 -0
  121. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.083.html +1 -0
  122. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.083.png +0 -0
  123. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.350.html +1 -0
  124. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.350.png +0 -0
  125. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.620.html +1 -0
  126. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.620.png +0 -0
  127. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.885.html +1 -0
  128. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.885.png +0 -0
  129. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-38.152.html +1 -0
  130. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-38.152.png +0 -0
  131. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-28-14.063.html +207 -0
  132. data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-28-14.063.png +0 -0
  133. data/spec/quby/answers/entities/score_spec.rb +4 -0
  134. data/spec/quby/answers/services/answer_validations_spec.rb +8 -8
  135. data/spec/quby/answers/services/score_calculator_spec.rb +4 -14
  136. data/spec/quby/questionnaires/deserializer/questionnaire_spec.rb +237 -0
  137. data/spec/quby/questionnaires/dsl_spec.rb +0 -9
  138. data/spec/quby/questionnaires/entities/fields_spec.rb +3 -3
  139. data/spec/quby/questionnaires/entities/question_spec.rb +0 -8
  140. data/spec/quby/questionnaires/entities/questionnaire_spec.rb +2 -26
  141. data/spec/quby/table_backend/range_tree_spec.rb +46 -13
  142. data/spec/spec_helper.rb +1 -1
  143. metadata +230 -53
  144. data/lib/quby/lookup_table.rb +0 -29
  145. data/lib/quby/lookup_table_repo.rb +0 -24
  146. data/lib/quby/questionnaires/dsl/base.rb +0 -20
  147. data/lib/quby/questionnaires/dsl/calls_custom_methods.rb +0 -29
  148. data/lib/quby/questionnaires/dsl/charting/bar_chart_builder.rb +0 -18
  149. data/lib/quby/questionnaires/dsl/charting/chart_builder.rb +0 -91
  150. data/lib/quby/questionnaires/dsl/charting/line_chart_builder.rb +0 -57
  151. data/lib/quby/questionnaires/dsl/charting/overview_chart_builder.rb +0 -31
  152. data/lib/quby/questionnaires/dsl/charting/radar_chart_builder.rb +0 -18
  153. data/lib/quby/questionnaires/dsl/helpers.rb +0 -51
  154. data/lib/quby/questionnaires/dsl/panel_builder.rb +0 -80
  155. data/lib/quby/questionnaires/dsl/question_builder.rb +0 -40
  156. data/lib/quby/questionnaires/dsl/questionnaire_builder.rb +0 -260
  157. data/lib/quby/questionnaires/dsl/questions/base.rb +0 -179
  158. data/lib/quby/questionnaires/dsl/questions/checkbox_question_builder.rb +0 -20
  159. data/lib/quby/questionnaires/dsl/questions/date_question_builder.rb +0 -18
  160. data/lib/quby/questionnaires/dsl/questions/deprecated_question_builder.rb +0 -18
  161. data/lib/quby/questionnaires/dsl/questions/float_question_builder.rb +0 -21
  162. data/lib/quby/questionnaires/dsl/questions/integer_question_builder.rb +0 -21
  163. data/lib/quby/questionnaires/dsl/questions/radio_question_builder.rb +0 -20
  164. data/lib/quby/questionnaires/dsl/questions/select_question_builder.rb +0 -18
  165. data/lib/quby/questionnaires/dsl/questions/string_question_builder.rb +0 -20
  166. data/lib/quby/questionnaires/dsl/questions/text_question_builder.rb +0 -22
  167. data/lib/quby/questionnaires/dsl/score_builder.rb +0 -22
  168. data/lib/quby/questionnaires/dsl/standardized_panel_generators.rb +0 -33
  169. data/lib/quby/questionnaires/dsl/table_builder.rb +0 -48
  170. data/lib/quby/questionnaires/services/definition_validator.rb +0 -298
  171. data/spec/benchmarks/load_normscore_csv.rb +0 -18
  172. data/spec/quby/lookup_table_repo_spec.rb +0 -20
  173. data/spec/quby/lookup_table_spec.rb +0 -38
  174. data/spec/quby/questionnaires/dsl/calls_custom_methods_spec.rb +0 -38
  175. data/spec/quby/questionnaires/dsl/charting/bar_chart_builder_spec.rb +0 -41
  176. data/spec/quby/questionnaires/dsl/charting/chart_builder_spec.rb +0 -127
  177. data/spec/quby/questionnaires/dsl/charting/line_chart_builder_spec.rb +0 -66
  178. data/spec/quby/questionnaires/dsl/charting/radar_chart_builder_spec.rb +0 -41
  179. data/spec/quby/questionnaires/dsl/helpers_spec.rb +0 -80
  180. data/spec/quby/questionnaires/dsl/questionnaire_builder_spec.rb +0 -480
  181. data/spec/quby/questionnaires/services/definition_validator_spec.rb +0 -793
  182. data/spec/support/examples_for_chart_builders.rb +0 -59
@@ -22,6 +22,10 @@ module Quby::Answers::Entities
22
22
  # it works with indifferent access
23
23
  subject { answer.score_objects['test'] }
24
24
 
25
+ it 'has working completion' do
26
+ expect(answer.outcome.completion).to eq("value" => 1.0)
27
+ end
28
+
25
29
  it 'exposes score schema fields' do
26
30
  expect(subject.key).to eq(:test)
27
31
  expect(subject.label).to eq('Testscore')
@@ -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
@@ -485,26 +485,16 @@ module Quby::Answers::Services
485
485
  let(:calculator) { ScoreCalculator.new(questionnaire: questionnaire, values: {}, timestamp: timestamp) }
486
486
  let(:table_double) { double.as_null_object }
487
487
 
488
- before do
489
- allow(Quby::LookupTable).to receive(:new).and_return(table_double)
490
- end
491
-
492
- it 'instantiates a new Quby::Answers::Entities::LookupTable if the table_hash cache does not know the key' do
488
+ it 'raises an error if lookup table cannot be found' do
493
489
  expect(questionnaire.lookup_tables).to be_empty
494
- calculator.table_lookup :test_table, score: 1
495
- expect(questionnaire.lookup_tables[:test_table]).to be(table_double)
496
- end
497
-
498
- it 'uses the memoized lookuptable if there is a cache hit' do
499
- calculator.table_lookup :test_table, score: 1
500
- expect(table_double).to receive(:lookup)
501
- calculator.table_lookup :test_table, score: 1
490
+ expect { calculator.table_lookup :test_table, score: 1 }.to raise_error(KeyError)
502
491
  end
503
492
 
504
493
  it 'looks up the given parameters on the given table' do
494
+ questionnaire.lookup_tables[:test_table] = table_double
505
495
  parameters = {score: 1}
506
- expect(table_double).to receive(:lookup).with parameters
507
496
  calculator.table_lookup :test_table, parameters
497
+ expect(table_double).to have_received(:lookup).with parameters
508
498
  end
509
499
 
510
500
  context 'with add_lookup_tree inside dsl' do
@@ -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
@@ -8,15 +8,6 @@ module Quby::Questionnaires
8
8
  definition = repo.find('simple')
9
9
  expect(described_class.build_from_definition(definition)).to be_instance_of(Entities::Questionnaire)
10
10
  end
11
-
12
- it 'uses a path on instance eval, so we get correct stack traces' do
13
- definition = Quby::Questionnaires::Entities::Definition.new(key: 'test',
14
- sourcecode: 'raise("problem")',
15
- path: 'spec/fixtures/raising.rb')
16
- expected_backtrace = include(end_with("spec/fixtures/raising.rb:1:in `block in build_from_definition'"))
17
- expect { described_class.build_from_definition(definition) }.to \
18
- raise_exception(having_attributes(backtrace: expected_backtrace))
19
- end
20
11
  end
21
12
  end
22
13
  end
@@ -82,8 +82,8 @@ module Quby::Questionnaires::Entities
82
82
  end
83
83
 
84
84
  describe '#description_for_variable' do
85
- let(:definition) do
86
- %q~
85
+ let(:questionnaire) do
86
+ Quby::Questionnaires::DSL.build("test") do
87
87
  flag key: :flagtest, description_true: 'it true', description_false: 'it false', description: 'it described'
88
88
  textvar key: :textvartest, description: 'tv description'
89
89
  question :v_1, type: :radio, title: 'select a few'
@@ -105,7 +105,7 @@ module Quby::Questionnaires::Entities
105
105
  score_schema :tot, 'Total', [{key: :value, export_key: 'tot', label: 'Score'},
106
106
  {key: :interpretation, export_key: 'tot_i', label: 'Interpretation'}]
107
107
 
108
- ~
108
+ end
109
109
  end
110
110
 
111
111
  it 'returns question context free titles if the variable is a question' do
@@ -42,14 +42,6 @@ module Quby::Questionnaires::Entities
42
42
  let(:valid_question_options) { {type: :string} }
43
43
  subject(:question) { Question.new(:v_1, valid_question_options) }
44
44
 
45
- it 'validates the key to be a symbol' do
46
- questionnaire = Quby::Questionnaires::DSL.build("test2") do
47
- question "key", type: :radio
48
- end
49
- expect(questionnaire.questions.first.valid?).to eq false
50
- expect(questionnaire.questions.first.errors.full_messages).to eq ["Key Is not of type Symbol"]
51
- end
52
-
53
45
  describe 'sbg_key' do
54
46
  it 'can be set by options hash' do
55
47
  expect(questionnaire.question_hash[:date].sbg_key).to eq 'foo'
@@ -432,30 +432,6 @@ module Quby::Questionnaires::Entities
432
432
  end
433
433
  end
434
434
 
435
- describe '#ensure_scores_have_schemas' do
436
- let(:score_missing_schema_quest) do
437
- Quby::Questionnaires::DSL.build("test") do
438
- question :v_1, type: :date, title: 'vraag'
439
-
440
- score(:key, label: 'score') { {value: 'oh no'} }
441
- score(:key2, label: 'score2', schema: [{key: :value, label: 'Score', export_key: :key2}]) { {value: 'oh'} }
442
- score(:key3, label: 'score3') { {value: 'oh no'} }
443
- end
444
- end
445
-
446
- it 'does not validate presense of score schemas by default' do
447
- expect(score_missing_schema_quest.errors.full_messages).to be_blank
448
- end
449
-
450
- describe 'if quby settings require_score_schemas is true' do
451
- before { Quby::Settings.require_score_schemas = true }
452
- it 'validates every score has a score schema' do
453
- expect(score_missing_schema_quest.errors.full_messages).to eq(["Score key is missing a score schema",
454
- "Score key3 is missing a score schema"])
455
- end
456
- end
457
- end
458
-
459
435
  describe '#add_outcome_table' do
460
436
  let(:questionnaire) do
461
437
  Quby::Questionnaires::DSL.build("test") do
@@ -488,8 +464,8 @@ module Quby::Questionnaires::Entities
488
464
  {"fieldKey" => :v_2, "type" => :requires_answer, "explanation" => nil},
489
465
  # a float type automatically adds a validation that the data entered must be parseable as a float
490
466
  {"fieldKey" => :v_2, "type" => :valid_float, "explanation" => nil},
491
- {"fieldKey" => :v_2, "type" => :minimum, "subtype" => :number, "value" => 5},
492
- {"fieldKey" => :v_2, "type" => :maximum, "subtype" => :number, "value" => 10}
467
+ {"fieldKey" => :v_2, "type" => :minimum, "subtype" => :number, "value" => 5, "explanation" => nil},
468
+ {"fieldKey" => :v_2, "type" => :maximum, "subtype" => :number, "value" => 10, "explanation" => nil}
493
469
  ])
494
470
  end
495
471
 
@@ -1,17 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Quby::TableBackend::RangeTree do
4
- let(:csv_key) { 'test' }
5
- let(:data) { Quby.lookup_table_repo.retrieve(csv_key) }
6
- let(:tree) { described_class.from_csv(levels: data.shift, compare: data.shift, data: data) }
7
-
8
- describe '#from_csv' do
9
- context 'invalid csv data' do
10
- let(:csv_key) { 'bad_range' }
11
- it 'fails when csv data contains a range between two equal values' do
12
- expect { tree }.to raise_error(RuntimeError, 'Cannot create range between two equal values')
13
- end
14
- end
4
+ let(:tree) do
5
+ described_class.new(
6
+ levels: ["scale", "gender", "age", "raw", "norm"],
7
+ tree: {
8
+ "Inhibitie" => {
9
+ "male" => {
10
+ (10.0...11.0) => {
11
+ (-Float::INFINITY...10.0) => 39.0,
12
+ (10.0...20.0) => 42.0,
13
+ (20.0...30.0) => 71.0,
14
+ (30.0...Float::INFINITY) => 75.0
15
+ }
16
+ }
17
+ }
18
+ }
19
+ )
15
20
  end
16
21
 
17
22
  describe '#lookup' do
@@ -68,7 +73,23 @@ describe Quby::TableBackend::RangeTree do
68
73
  end
69
74
 
70
75
  describe 'definition containing range with float values' do
71
- let(:csv_key) { 'float_test' }
76
+ let(:tree) do
77
+ described_class.new(
78
+ levels: ["scale", "gender", "age", "raw", "norm"],
79
+ tree: {
80
+ "Inhibitie" => {
81
+ "male" => {
82
+ (10.0...11.0) => {
83
+ (-Float::INFINITY...10.5) => 39.0,
84
+ (10.5...20.1) => 42.0,
85
+ (20.1...30.7) => 71.0,
86
+ (30.7...Float::INFINITY) => 75.0
87
+ }
88
+ }
89
+ }
90
+ }
91
+ )
92
+ end
72
93
 
73
94
  it 'returns the correct scores' do
74
95
  params = {age: 10, raw: 15.8, scale: 'Inhibitie', gender: 'male'}
@@ -80,7 +101,12 @@ describe Quby::TableBackend::RangeTree do
80
101
  end
81
102
 
82
103
  describe 'definition containing float values' do
83
- let(:csv_key) { 'test2' }
104
+ let(:tree) do
105
+ described_class.new(
106
+ levels: ["scale", "raw", "norm"],
107
+ tree: {"Inhibitie" => {15.0=>39.0, 16.0=>42.0, 17.0=>71.0, 18.0=>75.0}}
108
+ )
109
+ end
84
110
 
85
111
  it 'returns the correct scores when using integers in lookup path' do
86
112
  params = {scale: 'Inhibitie', raw: 17}
@@ -101,6 +127,13 @@ describe Quby::TableBackend::RangeTree do
101
127
  end
102
128
  end
103
129
 
130
+ describe 'array leaves' do
131
+ it 'returns the leaf fully' do
132
+ tree = described_class.new levels: ['key', 'leaf'], tree: {a: [1, 2, 3], b: [9, 8, 7]}
133
+ expect(tree.lookup(key: :a)).to eq([1, 2, 3])
134
+ end
135
+ end
136
+
104
137
  describe 'parameter validation' do
105
138
  it 'raises when parameter keys do not match header keys' do
106
139
  params = {foo: :bar}