quby 4.0.4 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +0 -1
- data/lib/quby.rb +2 -10
- data/lib/quby/answers/entities/answer.rb +4 -2
- data/lib/quby/answers/services/score_calculator.rb +1 -3
- data/lib/quby/engine.rb +0 -1
- data/lib/quby/questionnaires.rb +1 -0
- data/lib/quby/questionnaires/api.rb +5 -1
- data/lib/quby/questionnaires/deserializer.rb +441 -0
- data/lib/quby/questionnaires/dsl.rb +12 -15
- data/lib/quby/questionnaires/entities.rb +1 -0
- data/lib/quby/questionnaires/entities/charting/line_chart.rb +23 -0
- data/lib/quby/questionnaires/entities/charting/overview_chart.rb +3 -1
- data/lib/quby/questionnaires/entities/definition.rb +3 -5
- data/lib/quby/questionnaires/entities/fields.rb +0 -15
- data/lib/quby/questionnaires/entities/question.rb +9 -32
- data/lib/quby/questionnaires/entities/questionnaire.rb +4 -15
- data/lib/quby/questionnaires/entities/questions/checkbox_question.rb +0 -24
- data/lib/quby/questionnaires/entities/questions/date_question.rb +0 -8
- data/lib/quby/questionnaires/entities/score_calculation.rb +40 -3
- data/lib/quby/questionnaires/repos.rb +1 -0
- data/lib/quby/questionnaires/repos/bundle_disk_repo.rb +51 -0
- data/lib/quby/table_backend/range_tree.rb +0 -51
- data/lib/quby/version.rb +1 -1
- data/spec/features/tables_spec.rb +40 -0
- data/spec/fixtures/score_test.rb +4 -0
- data/spec/internal/log/test-events.log +183 -0
- data/spec/internal/log/test.log +5522 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/00/00nglkSepN01iGiDa7URmJtWQP-xSWffZb9wJgBqUr4.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/1V/1VQnRlqKBL0MybpMmC3EVtA2s6-ZX-GSGs2Cza3g3kI.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/1_/1_J_3havMjJDCz3iAQXAXXBh6tBQRJ3OpdWm3W46ss8.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/4G/4gcYvPHmPX3fZw9xr6plMl5Hfbo2xTWwcD7T7lIlD4Y.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/4_/4_FK6PMcF1eyIQx7RtVQ5t8c6X7smPQmJWNN5YTImVc.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/4d/4Dd15Upcg8_kiEsx_5wpQNrjM1sCk0tGTtWGhtmCKpg.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/4h/4hd8RzwlWb2IEeLLZN0s-3_sdJXtw6nu2k5baLb9vNs.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/5X/5xFJleOz2sGyE9gbs8KPkToDiv3s9bwFzroBRcjPELY.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/6Y/6y1tV_fKJP9YIQn-dF847aZ9kza1O7iyTEUht42D7nc.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/6d/6dfYZY_DkQe892FZVDUbBbrINslzVUkLZePdnVxO3Ps.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/6w/6WcYsWQCgw0z_URAWGhOsbiKXcqVxZ--ImazY5S-2Gk.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/77/77EJjFGVCRzLbhJy6KZZUYe5w0LxsqZQcmFcHAbxKeQ.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/7f/7fvhJnfiJknq6sA-MPtumXlL5qB-rfH__Heye13NyHc.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/8W/8W6AwDwFqo6egmWyt6Cs0vf_XJbT2YxPs2sqbo0Q9kk.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/8c/8cQ8uBhUhrouKwor0Z87dDCxyPbqbLvK8KEFEgjHxqM.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/9L/9LJo1U9wQdfWrrn3HkNZTgIZc6jeHvWbGk8tJ4m_Qec.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/9o/9oXJXZnA6F49i4EflydD0Ivx6dhSxGGDD69G-N5NSCg.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/A1/a1jgtYtDHIb04Og07H6_XNmhXppaAnFiO88kgq80edQ.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/AC/ACV6t4unw39Kpn2DnbBtHeJYLoAHyyBN1DTRXs6a2ik.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/BO/BoVO8e1GTTGHfnJTOByDxMlvVi9fNGyOdSubqCbBITI.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ba/babjk3aW-jBoEw_ERhmT5ZQprEqilJCWmImrvVskWk8.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Cg/cgb1vvOogMD0V1lqQ5k_mny7Z38rbqBdIumlGh5sZ_E.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Cw/CwjNk_RYiC93RW8vRs7fWsHcwKTg7uE9OLifRm3Y6WA.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/DY/Dy1qsY0W-eyFR6RVKSCCli-XsitpaXD4DwTjXL86t2M.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Dk/DkGOwkJNeDdljv4b8QbwtPVrsghwYuA6EOxx1goEQg0.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/FG/fGmVSU-v7aZV9-CLG5U2OmteGgWTuAotlFcwFyx4Eqs.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Fd/fDidWZjSZsPN4uAEyVYABV2WFCSR7AZE0l8U-9XOw7U.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/G1/G1RRwpldS5MGQ5x-WHyPWzXJWDOd2qyWMMFumuU4-Ms.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/GG/ggGfy_gZryUPmYwgenN3A4jv0q-buxyjCGdLB6wfHxQ.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/GY/gYwYoJrifknCG-a0FXlM1NU6tUj1JXxm27s-a0uP_IE.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/I6/i64Ysik0cyoTrYF0-O63B7sN3AdIgeoJ7zLh9pMC2u4.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ic/ICKeOd4yOff3JGsfU1XliLgXfJtTPKSbXsqNVZAb1-Y.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/J7/J75M1l--IMcCn-Wy7uWv17SWaj0DFaGiiwac63pENPQ.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Jh/JHPqsKZsrkvQg23ukphinYoViiIw3askwCMP8VrHTMk.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/K9/k9tOCRdX5tsxa5LImq7MZk0WzC692t8tx5LzLln0l4Q.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/LY/ly4TNAIbW9ghgXz8mxfmskR_6AkuiMiG-RIFGhewgQ0.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Lq/LQ9fP0wIqVc5s-AtP3ESWJr0qpkDe-VpTxpgYl-9FfU.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/MO/MOmnpcaRW98Ke-zTOOCSZ0ODnnQntKhQr0vFc_un1_A.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/OX/OxOBsUA5EpScoZgEt_UhsHzhu-GGmxKnHpCwnhbTwiM.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Ot/oTVAc3-iuSlg7XAM-YIAhw3cdc5yhgL2-tK3N7sfOfU.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/PK/pKNcBOgAbCyIwsWIvnlmiPiFxrw6nUo_nTz7wWFDr80.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/QB/QBMvSW7SYbYcm5lSjybgO7fhHDFIQjJWOvefH0MQC-A.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Qs/QSbtm1y8JKPV0MQkpiC0hEisaSjKZ3tp2AWHSrhO30Y.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Sp/SpyGDguFy3tp0sim1miZOehEDpE97oueO7wl3oUFYcE.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/TW/TwtJPRSE9lmwTuSP0lezWSRSBp2u43zuF196FQcHY-c.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/VX/Vxn9zv60MCKUBfRhrjefo-MEzFej81PPEutxTPQ4VLQ.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/Vr/vrqPEzlsuORocHY0EbtGdFomRmrcoAa6wWSDMx642-Q.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/WH/WHVQ0GBe51hbYqv2g7YYo7EIw9PSzt9-RqU7hKP2dc4.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/_B/_B796ezRHfk7H8YKj7zr3-gRy6Mw2IVn2NbHu-k20ug.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/_W/_Wh-7b1t-Xm19wg3KPtkXq7DOpohaL5OhnLggzJLpj4.cache +0 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/b2/B2y-2qTbQYKRm6_sCQ6qfUeVfl9rKXUvotTDm56w4bs.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/bw/bwFR2MLpvJvPSAPJzSLWk6TUDCw5TlBFUUuq7z_Y9vg.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/c7/c7ubvrHhbhAYh-K4srvM9EqwWdbWTLrsLMgjG5XQDbY.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/cX/CXpMzZYfJy6HIOVXN0IyYilvy6J4CDgFZIwqKm8OQEU.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/eN/EN0enu5dkKEnIz-DVCpbhkfeph7wImeXnlqb7SXMrjE.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/fu/fuP9zP6C6rj650HLkypoTfYN2KD1ecB9HdtlbhbA2cg.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/gr/gRPXI3EsVPwysy9YKW_6yDxaqRRr4Idxtexf7zCHECw.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/h0/h0P63ZZdlSbtztDOe0V9r7jtCoy0L2bAf_iDNKLJ0nk.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/i-/i-Or0Xuxbbm3-HdE_xGIf6sAx2vhUa3eVMpbT37lyEo.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/iF/iFP67If98izMEAAMKnAFi2dWAb8TNlHNayZKNjXdAMs.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/iH/Ih2svq5ul-xibfRUfd1fxigouli6U19Rf80FrTSoMak.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/ka/Ka_YEbZNQxpS8XAA7xZturgPr2vLYQq60KK1uwou4Lo.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/kq/KqkIGfAdJjTcr53lFl1aDAMUeqhhKdXGyTlHVlCz0R4.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/mR/mRDPkwomGSfjpIWEKtPPBSx5cBHssvH8v0gCSI33P3Y.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/n4/n4qaNjjNvKB0VAbVJlP_BjFlcLf70TsBzcIMc7VO9dw.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/nY/nykt5oy2ExUYa8g1phLCDRqwb55BuUot5ZBbRdNuCCw.cache +2 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/nv/nvmgm4bOtxCbD6EA14ZIwDcYO8fxXOoEk_s7V-uRMMM.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/oG/og5ypFjbFAX_nH7oxK6Bn5Ejh81BMDBSMxbGcL5ZbQs.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/oO/oO4iBwOm5E7uLH39zeR8zun4eBM-WxZKvEMpIYKx6SU.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/pN/PnQ-dEclV6jTDE4kkqw4G9dBpHArAgUnATOpRrQAsGc.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/pe/pet4fFbc2Cm2SD_ZBO_s83Gey29EXE26u-7lwn2O8gM.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/qo/Qoqb-JjTe1BiY4rICKHm5e6bsPt-DHXZc4ADXESjw2I.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/qx/QXICLj9xx1EI9rBeXLXpKOeHGll_LBWHRWlpb1DK424.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/rM/rMF4Y2UGkmBABLlC1eSSqb6y6g_Z3uUCLBtFvz_LoyI.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/ty/ty1qAnpL07anYdhIJoiPYLcsWKejuzy6JaxU9mI7egw.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/uH/UHs9nE45XS7v4QlMjSjhwHbqYIKC06FsEjMSMIfKanU.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/v8/v8VXJ3AQom-JqxBYAB7tOjV-tt4IdDb6YyFEzlsWV8c.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/vD/VDI2CxkTg7-DuMcLmofLvch0yukSl88oI_AjGgN-hQ8.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/wq/wqhk46aZc1Bbb8gTCOZKxTvwTV0ANLSz8VdQYACo03E.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/xy/Xy8Yk--iYZNupHMjUtYX1AQ0BppsvThCh_ZAizblCb0.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/zu/zUCfHRTHprn06F5WxH6wp_BLs9-yhs-foc0j0Y7BYbg.cache +1 -0
- data/spec/internal/tmp/cache/assets/sprockets/v3.0/zx/ZX2IY3eKQjBy93tlH7_Xg7zGZKYuaQ-E8YPvtPT_4vM.cache +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-35.705.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-35.705.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.005.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.005.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.276.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.276.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.556.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.556.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.818.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-36.818.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.083.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.083.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.350.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.350.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.620.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.620.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.885.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-37.885.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-38.152.html +1 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-27-38.152.png +0 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-28-14.063.html +207 -0
- data/spec/internal/tmp/capybara/screenshot_2020-11-17-14-28-14.063.png +0 -0
- data/spec/quby/answers/entities/score_spec.rb +4 -0
- data/spec/quby/answers/services/answer_validations_spec.rb +8 -8
- data/spec/quby/answers/services/score_calculator_spec.rb +4 -14
- data/spec/quby/questionnaires/deserializer/questionnaire_spec.rb +237 -0
- data/spec/quby/questionnaires/dsl_spec.rb +0 -9
- data/spec/quby/questionnaires/entities/fields_spec.rb +3 -3
- data/spec/quby/questionnaires/entities/question_spec.rb +0 -8
- data/spec/quby/questionnaires/entities/questionnaire_spec.rb +2 -26
- data/spec/quby/table_backend/range_tree_spec.rb +46 -13
- data/spec/spec_helper.rb +1 -1
- metadata +230 -53
- data/lib/quby/lookup_table.rb +0 -29
- data/lib/quby/lookup_table_repo.rb +0 -24
- data/lib/quby/questionnaires/dsl/base.rb +0 -20
- data/lib/quby/questionnaires/dsl/calls_custom_methods.rb +0 -29
- data/lib/quby/questionnaires/dsl/charting/bar_chart_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/charting/chart_builder.rb +0 -91
- data/lib/quby/questionnaires/dsl/charting/line_chart_builder.rb +0 -57
- data/lib/quby/questionnaires/dsl/charting/overview_chart_builder.rb +0 -31
- data/lib/quby/questionnaires/dsl/charting/radar_chart_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/helpers.rb +0 -51
- data/lib/quby/questionnaires/dsl/panel_builder.rb +0 -80
- data/lib/quby/questionnaires/dsl/question_builder.rb +0 -40
- data/lib/quby/questionnaires/dsl/questionnaire_builder.rb +0 -260
- data/lib/quby/questionnaires/dsl/questions/base.rb +0 -179
- data/lib/quby/questionnaires/dsl/questions/checkbox_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/date_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/deprecated_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/float_question_builder.rb +0 -21
- data/lib/quby/questionnaires/dsl/questions/integer_question_builder.rb +0 -21
- data/lib/quby/questionnaires/dsl/questions/radio_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/select_question_builder.rb +0 -18
- data/lib/quby/questionnaires/dsl/questions/string_question_builder.rb +0 -20
- data/lib/quby/questionnaires/dsl/questions/text_question_builder.rb +0 -22
- data/lib/quby/questionnaires/dsl/score_builder.rb +0 -22
- data/lib/quby/questionnaires/dsl/standardized_panel_generators.rb +0 -33
- data/lib/quby/questionnaires/dsl/table_builder.rb +0 -48
- data/lib/quby/questionnaires/services/definition_validator.rb +0 -298
- data/spec/benchmarks/load_normscore_csv.rb +0 -18
- data/spec/quby/lookup_table_repo_spec.rb +0 -20
- data/spec/quby/lookup_table_spec.rb +0 -38
- data/spec/quby/questionnaires/dsl/calls_custom_methods_spec.rb +0 -38
- data/spec/quby/questionnaires/dsl/charting/bar_chart_builder_spec.rb +0 -41
- data/spec/quby/questionnaires/dsl/charting/chart_builder_spec.rb +0 -127
- data/spec/quby/questionnaires/dsl/charting/line_chart_builder_spec.rb +0 -66
- data/spec/quby/questionnaires/dsl/charting/radar_chart_builder_spec.rb +0 -41
- data/spec/quby/questionnaires/dsl/helpers_spec.rb +0 -80
- data/spec/quby/questionnaires/dsl/questionnaire_builder_spec.rb +0 -480
- data/spec/quby/questionnaires/services/definition_validator_spec.rb +0 -793
- data/spec/support/examples_for_chart_builders.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a0b61b70b821b00c262a58f7f7fb7ec04a33d4b26df7719be157d8f4015f823
|
4
|
+
data.tar.gz: 6b897f4f1e7867999c9dda5b0bbd39f6b5493945715edce8194d45beab809926
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2595b285e0c4fd37dd708577bafbffc3c830194097d79ebb1c7784c6918f0a40cf4e4695e68cf0755cc7a09fb95a43beee4caebad495c141c61ac377fd90b637
|
7
|
+
data.tar.gz: b575e091c90af8581c044e6866cf5cb328bc513d0f24ba3453efffa212741012f31650bcd07f6fe1d1649fe80e85bd0ff6ebb3e5c03a8e753e7c656bead146be
|
data/README.markdown
CHANGED
@@ -27,7 +27,6 @@ and where it can store its answers.
|
|
27
27
|
```ruby
|
28
28
|
Quby.questionnaire_repo = Quby::Questionnaires::Repos::DiskRepo.new(Rails.root.join("db/questionnaires/definitions"))
|
29
29
|
Quby.answer_repo = Quby::Answers::Repos::MongoidRepo.new
|
30
|
-
Quby.lookup_table_repo = Quby::LookupTableRepo::Disk.new(Rails.root.join("db/questionnaires/lookup_tables"))
|
31
30
|
Quby::Settings.shared_secret = ENV["QUBY_SHARED_SECRET"]
|
32
31
|
```
|
33
32
|
|
data/lib/quby.rb
CHANGED
@@ -38,14 +38,6 @@ module Quby
|
|
38
38
|
@questionnaires_api = nil
|
39
39
|
end
|
40
40
|
|
41
|
-
def lookup_table_repo=(repo)
|
42
|
-
@lookup_table_repo = repo
|
43
|
-
end
|
44
|
-
|
45
|
-
def lookup_table_repo
|
46
|
-
@lookup_table_repo || fail("Quby does not have its lookup table repo (Quby.lookup_table_repo) configured.")
|
47
|
-
end
|
48
|
-
|
49
41
|
def fixtures_path
|
50
42
|
File.expand_path File.join('..', '..', 'spec', 'fixtures'), __FILE__
|
51
43
|
end
|
@@ -79,7 +71,7 @@ module Quby
|
|
79
71
|
end
|
80
72
|
|
81
73
|
require 'quby/settings'
|
74
|
+
require 'quby/table_backend/range_tree'
|
82
75
|
require 'quby/questionnaires'
|
83
76
|
require 'quby/answers'
|
84
|
-
require 'quby/engine'
|
85
|
-
require 'quby/lookup_table_repo'
|
77
|
+
require 'quby/engine'
|
@@ -82,7 +82,7 @@ module Quby
|
|
82
82
|
attr_accessor :extra_question_values
|
83
83
|
attr_accessor :extra_failed_validations
|
84
84
|
|
85
|
-
def initialize(_id: nil, questionnaire_id: nil, questionnaire_key: nil,
|
85
|
+
def initialize(_id: nil, questionnaire_id: nil, questionnaire_key: nil, questionnaire: nil,
|
86
86
|
raw_params: nil, value: nil, patient_id: nil, patient: nil,
|
87
87
|
token: nil, active: true, test: false, created_at: nil, updated_at: nil,
|
88
88
|
started_at: nil, completed_at: nil, outcome: nil, outcome_generated_at: nil,
|
@@ -111,6 +111,8 @@ module Quby
|
|
111
111
|
self.import_notes = import_notes || {}
|
112
112
|
self.flags = flags
|
113
113
|
self.textvars = textvars
|
114
|
+
|
115
|
+
@questionnaire = questionnaire
|
114
116
|
end
|
115
117
|
|
116
118
|
def id
|
@@ -162,7 +164,7 @@ module Quby
|
|
162
164
|
|
163
165
|
# Faux belongs_to :questionnaire
|
164
166
|
def questionnaire
|
165
|
-
Quby.questionnaires.find(questionnaire_key)
|
167
|
+
@questionnaire ||= Quby.questionnaires.find(questionnaire_key)
|
166
168
|
end
|
167
169
|
|
168
170
|
def mark_completed(start_time)
|
@@ -231,9 +231,7 @@ module Quby
|
|
231
231
|
end
|
232
232
|
|
233
233
|
def table_lookup(table_key, parameters)
|
234
|
-
@questionnaire.lookup_tables
|
235
|
-
@questionnaire.lookup_tables[table_key] \
|
236
|
-
.lookup(parameters)
|
234
|
+
@questionnaire.lookup_tables.fetch(table_key).lookup(parameters)
|
237
235
|
end
|
238
236
|
|
239
237
|
# Public: Ensure given question_keys have answers. Strings with nothing but whitespace are
|
data/lib/quby/engine.rb
CHANGED
data/lib/quby/questionnaires.rb
CHANGED
@@ -39,7 +39,11 @@ module Quby
|
|
39
39
|
|
40
40
|
def build_from_definition(definition)
|
41
41
|
ActiveSupport::Notifications.instrument('quby.questionaire.build') do
|
42
|
-
|
42
|
+
if definition.json
|
43
|
+
DSL.from_json(definition.json)
|
44
|
+
else
|
45
|
+
DSL.build_from_definition(definition)
|
46
|
+
end
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -0,0 +1,441 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Quby
|
4
|
+
module Questionnaires
|
5
|
+
module Deserializer
|
6
|
+
# This symbolizes various things. Do not run on arbitrary JSON.
|
7
|
+
def self.from_json(json)
|
8
|
+
# TODO: last_update
|
9
|
+
Entities::Questionnaire.new(json.fetch("key"), json).tap do |questionnaire|
|
10
|
+
questionnaire.title = json.fetch("title")
|
11
|
+
questionnaire.description = json.fetch("description")
|
12
|
+
questionnaire.outcome_description = json.fetch("outcome_description")
|
13
|
+
questionnaire.short_description = json.fetch("short_description")
|
14
|
+
questionnaire.abortable = json.fetch("abortable")
|
15
|
+
questionnaire.enable_previous_questionnaire_button = json.fetch("enable_previous_questionnaire_button")
|
16
|
+
questionnaire.default_answer_value = json.fetch("default_answer_value")
|
17
|
+
questionnaire.leave_page_alert = json.fetch("leave_page_alert")
|
18
|
+
questionnaire.allow_hotkeys = json.fetch("allow_hotkeys")
|
19
|
+
questionnaire.license = json.fetch("license")&.to_sym
|
20
|
+
questionnaire.licensor = json.fetch("licensor")
|
21
|
+
questionnaire.language = json.fetch("language").try(:to_sym)
|
22
|
+
questionnaire.renderer_version = json.fetch("renderer_version")
|
23
|
+
questionnaire.last_update = Time.zone.parse(json.fetch("last_update"))
|
24
|
+
questionnaire.last_author = json.fetch("last_author")
|
25
|
+
questionnaire.extra_css = json.fetch("extra_css")
|
26
|
+
questionnaire.allow_switch_to_bulk = json.fetch("allow_switch_to_bulk")
|
27
|
+
|
28
|
+
questionnaire.flags = json.fetch("flags").with_indifferent_access.transform_values do |attrs|
|
29
|
+
build_flag(attrs)
|
30
|
+
end
|
31
|
+
|
32
|
+
questionnaire.textvars = json.fetch("textvars").with_indifferent_access.transform_values do |attrs|
|
33
|
+
build_textvar(attrs)
|
34
|
+
end
|
35
|
+
|
36
|
+
questionnaire.lookup_tables = YAML.load(json.fetch("lookup_tables")).transform_values do |attrs|
|
37
|
+
Quby::TableBackend::RangeTree.new(levels: attrs[:levels], tree: attrs[:tree])
|
38
|
+
end
|
39
|
+
|
40
|
+
questionnaire.score_calculations = json.fetch("score_calculations").with_indifferent_access.transform_values do |attrs|
|
41
|
+
build_score_calculation(attrs)
|
42
|
+
end
|
43
|
+
|
44
|
+
questionnaire.score_schemas = json.fetch("score_schemas").with_indifferent_access.transform_values do |schema|
|
45
|
+
build_score_schema(schema)
|
46
|
+
end
|
47
|
+
|
48
|
+
json.fetch("panels").each do |panel_json|
|
49
|
+
load_panel(questionnaire, panel_json)
|
50
|
+
end
|
51
|
+
|
52
|
+
# roqua domain
|
53
|
+
questionnaire.roqua_keys = json.fetch("roqua_keys")
|
54
|
+
questionnaire.sbg_key = json.fetch("sbg_key")
|
55
|
+
questionnaire.sbg_domains = json.fetch("sbg_domains").map(&:symbolize_keys)
|
56
|
+
questionnaire.outcome_regeneration_requested_at = json.fetch("outcome_regeneration_requested_at")&.yield_self { |str| Time.zone.parse(str) }
|
57
|
+
questionnaire.deactivate_answers_requested_at = json.fetch("deactivate_answers_requested_at").try { |str| Time.zone.parse(str) }
|
58
|
+
questionnaire.respondent_types = json.fetch("respondent_types").map(&:to_sym)
|
59
|
+
questionnaire.tags = json.fetch("tags")
|
60
|
+
|
61
|
+
json.fetch("charts").fetch("overview")&.tap do |overview_json|
|
62
|
+
questionnaire.charts.overview = Quby::Questionnaires::Entities::Charting::OverviewChart.new(
|
63
|
+
subscore: overview_json.fetch("subscore").to_sym,
|
64
|
+
y_max: overview_json.fetch("y_max"),
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
json.fetch("charts").fetch("others").each do |chart_json|
|
69
|
+
questionnaire.add_chart(build_chart(questionnaire, chart_json))
|
70
|
+
end
|
71
|
+
|
72
|
+
questionnaire.outcome_tables = json.fetch("outcome_tables").map do |attributes|
|
73
|
+
build_outcome_table(questionnaire, attributes)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.load_panel(questionnaire, panel_json)
|
79
|
+
panel = Entities::Panel.new(
|
80
|
+
questionnaire: questionnaire,
|
81
|
+
key: panel_json.fetch("key"),
|
82
|
+
title: panel_json.fetch("title"),
|
83
|
+
items: []
|
84
|
+
)
|
85
|
+
|
86
|
+
panel_json.fetch("items").each do |item_json|
|
87
|
+
load_item(questionnaire, item_json, panel: panel)
|
88
|
+
end
|
89
|
+
|
90
|
+
questionnaire.add_panel(panel)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.load_item(questionnaire, item_json, panel: nil)
|
94
|
+
case item_json.fetch("type")
|
95
|
+
when "text"
|
96
|
+
panel.items << build_text(item_json)
|
97
|
+
when "question"
|
98
|
+
question = build_question(questionnaire, item_json)
|
99
|
+
questionnaire.register_question(question)
|
100
|
+
panel.items << question
|
101
|
+
when "table"
|
102
|
+
table = Entities::Table.new(
|
103
|
+
title: item_json.fetch("title"),
|
104
|
+
description: item_json.fetch("description"),
|
105
|
+
columns: item_json.fetch("columns"),
|
106
|
+
show_option_desc: item_json.fetch("show_option_desc"),
|
107
|
+
)
|
108
|
+
panel.items << table
|
109
|
+
|
110
|
+
item_json.fetch("items").each do |table_item_json|
|
111
|
+
case table_item_json.fetch("type")
|
112
|
+
when "text"
|
113
|
+
table.items << build_text(table_item_json)
|
114
|
+
when "question"
|
115
|
+
question = build_question(questionnaire, table_item_json, table: table)
|
116
|
+
questionnaire.register_question(question)
|
117
|
+
table.items << question
|
118
|
+
panel.items << question
|
119
|
+
else
|
120
|
+
raise "Unknown table item: #{table_item_json}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
else
|
124
|
+
raise "Unknown item: #{item_json}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.build_text(item_json)
|
129
|
+
Entities::Text.new(item_json.fetch("str"), {
|
130
|
+
html_content: item_json.fetch("html_content"),
|
131
|
+
display_in: item_json.fetch("display_in").map(&:to_sym),
|
132
|
+
col_span: item_json.fetch("col_span"),
|
133
|
+
row_span: item_json.fetch("row_span"),
|
134
|
+
raw_content: item_json.fetch("raw_content"),
|
135
|
+
switch_cycle: item_json.fetch("switch_cycle")
|
136
|
+
})
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.build_question(questionnaire, item_json, parent: nil, table: nil)
|
140
|
+
key = item_json.fetch("key").to_sym
|
141
|
+
attributes = {
|
142
|
+
questionnaire: questionnaire,
|
143
|
+
parent: parent,
|
144
|
+
type: item_json.fetch("question_type").to_sym,
|
145
|
+
title: item_json.fetch("title"),
|
146
|
+
context_free_title: item_json.fetch("context_free_title"),
|
147
|
+
description: item_json.fetch("description"),
|
148
|
+
presentation: item_json.fetch("presentation").to_sym,
|
149
|
+
hidden: item_json.fetch("hidden"),
|
150
|
+
depends_on: item_json.fetch("depends_on")&.map(&:to_sym),
|
151
|
+
default_position: item_json.fetch("default_position"),
|
152
|
+
validations: item_json.fetch("validations").map {|attrs| build_question_validation(attrs)},
|
153
|
+
table: table,
|
154
|
+
col_span: item_json.fetch("col_span"),
|
155
|
+
row_span: item_json.fetch("row_span"),
|
156
|
+
|
157
|
+
# only selectable via options passed in DSL, not via DSL methods
|
158
|
+
# many apply only to certain types of questions
|
159
|
+
sbg_key: item_json.fetch("sbg_key"),
|
160
|
+
allow_duplicate_option_values: item_json.fetch("allow_duplicate_option_values"),
|
161
|
+
allow_blank_titles: item_json.fetch("allow_blank_titles"),
|
162
|
+
as: item_json.fetch("as")&.to_sym,
|
163
|
+
display_modes: item_json.fetch("display_modes")&.map(&:to_sym),
|
164
|
+
autocomplete: item_json.fetch("autocomplete"),
|
165
|
+
show_values: item_json.fetch("show_values").to_sym,
|
166
|
+
deselectable: item_json.fetch("deselectable"),
|
167
|
+
disallow_bulk: item_json.fetch("disallow_bulk"),
|
168
|
+
score_header: item_json.fetch("score_header").to_sym,
|
169
|
+
sets_textvar: item_json.fetch("sets_textvar"),
|
170
|
+
default_invisible: item_json.fetch("default_invisible"),
|
171
|
+
question_group: item_json.fetch("question_group"), # sometimes string, sometimes a symbol in the DSL. Just have to hope this works
|
172
|
+
group_minimum_answered: item_json.fetch("group_minimum_answered"),
|
173
|
+
group_maximum_answered: item_json.fetch("group_maximum_answered"),
|
174
|
+
value_tooltip: item_json.fetch("value_tooltip"),
|
175
|
+
|
176
|
+
# might be able to deduce from tree structure
|
177
|
+
parent_option_key: item_json.fetch("parent_option_key")&.to_sym
|
178
|
+
}
|
179
|
+
|
180
|
+
case item_json.fetch("question_type")
|
181
|
+
when "check_box"
|
182
|
+
Entities::Questions::CheckboxQuestion.new(key, attributes.merge(
|
183
|
+
check_all_option: item_json.fetch("check_all_option")&.to_sym,
|
184
|
+
uncheck_all_option: item_json.fetch("uncheck_all_option")&.to_sym,
|
185
|
+
maximum_checked_allowed: item_json.fetch("maximum_checked_allowed"),
|
186
|
+
minimum_checked_required: item_json.fetch("minimum_checked_required"),
|
187
|
+
)).tap do |question|
|
188
|
+
item_json.fetch("options").each do |option_json|
|
189
|
+
question.options << build_option(questionnaire, question, option_json)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
when "date"
|
193
|
+
Entities::Questions::DateQuestion.new(key, attributes.merge(
|
194
|
+
components: item_json.fetch("components").map(&:to_sym),
|
195
|
+
required_components: item_json.fetch("required_components").map(&:to_sym),
|
196
|
+
year_key: item_json.fetch("year_key")&.to_sym,
|
197
|
+
month_key: item_json.fetch("month_key")&.to_sym,
|
198
|
+
day_key: item_json.fetch("day_key")&.to_sym,
|
199
|
+
hour_key: item_json.fetch("hour_key")&.to_sym,
|
200
|
+
minute_key: item_json.fetch("minute_key")&.to_sym,
|
201
|
+
))
|
202
|
+
when "deprecated", "hidden"
|
203
|
+
Entities::Questions::DeprecatedQuestion.new(key, attributes).tap do |question|
|
204
|
+
item_json.fetch("options").each do |option_json|
|
205
|
+
question.options << build_option(questionnaire, question, option_json)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
when "float"
|
209
|
+
Entities::Questions::FloatQuestion.new(key, attributes.merge(
|
210
|
+
labels: item_json.fetch("labels"),
|
211
|
+
unit: item_json.fetch("unit"),
|
212
|
+
size: item_json.fetch("size"),
|
213
|
+
))
|
214
|
+
when "integer"
|
215
|
+
Entities::Questions::IntegerQuestion.new(key, attributes.merge(
|
216
|
+
labels: item_json.fetch("labels"),
|
217
|
+
unit: item_json.fetch("unit"),
|
218
|
+
size: item_json.fetch("size"),
|
219
|
+
))
|
220
|
+
when "radio", "scale"
|
221
|
+
Entities::Questions::RadioQuestion.new(key, attributes).tap do |question|
|
222
|
+
item_json.fetch("options").each do |option_json|
|
223
|
+
question.options << build_option(questionnaire, question, option_json)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
when "select"
|
227
|
+
Entities::Questions::SelectQuestion.new(key, attributes).tap do |question|
|
228
|
+
item_json.fetch("options").each do |option_json|
|
229
|
+
question.options << build_option(questionnaire, question, option_json)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
when "string"
|
233
|
+
Entities::Questions::StringQuestion.new(key, attributes.merge(
|
234
|
+
unit: item_json.fetch("unit"),
|
235
|
+
size: item_json.fetch("size"),
|
236
|
+
))
|
237
|
+
when "textarea"
|
238
|
+
Entities::Questions::TextQuestion.new(key, attributes.merge(
|
239
|
+
lines: item_json.fetch("lines"),
|
240
|
+
))
|
241
|
+
else
|
242
|
+
raise "Unknown question type: #{item_json}"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.build_option(questionnaire, question, option_json)
|
247
|
+
option = Entities::QuestionOption.new(option_json.fetch("key")&.to_sym, question,
|
248
|
+
value: option_json.fetch("value"),
|
249
|
+
description: option_json.fetch("description"),
|
250
|
+
context_free_description: option_json.fetch("context_free_description"),
|
251
|
+
inner_title: option_json.fetch("inner_title"),
|
252
|
+
hides_questions: option_json.fetch("hides_questions").map(&:to_sym),
|
253
|
+
shows_questions: option_json.fetch("shows_questions").map(&:to_sym),
|
254
|
+
hidden: option_json.fetch("hidden"),
|
255
|
+
placeholder: option_json.fetch("placeholder"),
|
256
|
+
)
|
257
|
+
|
258
|
+
option_json.fetch("questions").each do |question_json|
|
259
|
+
subquestion = build_question(questionnaire, question_json, parent: question)
|
260
|
+
questionnaire.register_question(subquestion)
|
261
|
+
option.questions << subquestion
|
262
|
+
end
|
263
|
+
|
264
|
+
option
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.build_question_validation(attrs)
|
268
|
+
base_validation = {
|
269
|
+
type: attrs.fetch("type").to_sym,
|
270
|
+
explanation: attrs["explanation"] # not always specified for min/max validation
|
271
|
+
}
|
272
|
+
|
273
|
+
case attrs.fetch("type")
|
274
|
+
when "requires_answer"
|
275
|
+
base_validation
|
276
|
+
when "answer_group_minimum", "answer_group_maximum"
|
277
|
+
base_validation.merge(
|
278
|
+
group: attrs.fetch("group"), # TODO: sometimes a symbol, sometimes a string in the original, but I hope it doesn't matter
|
279
|
+
value: attrs.fetch("value")
|
280
|
+
)
|
281
|
+
when "valid_integer", "valid_float"
|
282
|
+
base_validation
|
283
|
+
when "valid_date"
|
284
|
+
base_validation.merge(
|
285
|
+
subtype: attrs.fetch("subtype").to_sym
|
286
|
+
)
|
287
|
+
when "minimum", "maximum"
|
288
|
+
value = case attrs.fetch("value_type")
|
289
|
+
when "Date"
|
290
|
+
Date.parse(attrs.fetch("value"))
|
291
|
+
when "DateTime"
|
292
|
+
DateTime.parse(attrs.fetch("value"))
|
293
|
+
when "Time", "ActiveSuport::TimeWithZone"
|
294
|
+
Time.zone.parse(attrs.fetch("value"))
|
295
|
+
else
|
296
|
+
attrs.fetch("value")
|
297
|
+
end
|
298
|
+
|
299
|
+
base_validation.merge(
|
300
|
+
value: value,
|
301
|
+
subtype: attrs.fetch("subtype").to_sym,
|
302
|
+
)
|
303
|
+
when "too_many_checked"
|
304
|
+
base_validation.merge(
|
305
|
+
uncheck_all_key: attrs.fetch("uncheck_all_key").to_sym
|
306
|
+
)
|
307
|
+
when "minimum_checked_required"
|
308
|
+
base_validation.merge(
|
309
|
+
minimum_checked_value: attrs.fetch("minimum_checked_value")
|
310
|
+
)
|
311
|
+
when "maximum_checked_allowed"
|
312
|
+
base_validation.merge(
|
313
|
+
maximum_checked_value: attrs.fetch("maximum_checked_value")
|
314
|
+
)
|
315
|
+
when "regexp"
|
316
|
+
base_validation.merge(
|
317
|
+
matcher: Regexp.new(attrs.fetch("matcher"))
|
318
|
+
)
|
319
|
+
when "not_all_checked"
|
320
|
+
base_validation.merge(
|
321
|
+
check_all_key: attrs.fetch("check_all_key").to_sym
|
322
|
+
)
|
323
|
+
else
|
324
|
+
raise "Unknown validation type: #{attrs.inspect}"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def self.build_score_calculation(attrs)
|
329
|
+
Entities::ScoreCalculation.new(attrs.fetch("key").to_sym,
|
330
|
+
label: attrs.fetch("label"),
|
331
|
+
sbg_key: attrs.fetch("sbg_key"),
|
332
|
+
options: attrs.fetch("options").symbolize_keys,
|
333
|
+
sourcecode: attrs.fetch("sourcecode"),
|
334
|
+
)
|
335
|
+
end
|
336
|
+
|
337
|
+
def self.build_flag(attrs)
|
338
|
+
Entities::Flag.new(
|
339
|
+
key: attrs.fetch("key").to_sym,
|
340
|
+
description_true: attrs.fetch("description_true"),
|
341
|
+
description_false: attrs.fetch("description_false"),
|
342
|
+
description: attrs.fetch("description"),
|
343
|
+
internal: attrs.fetch("internal"),
|
344
|
+
trigger_on: attrs.fetch("trigger_on"),
|
345
|
+
shows_questions: attrs.fetch("shows_questions").map(&:to_sym),
|
346
|
+
hides_questions: attrs.fetch("hides_questions").map(&:to_sym),
|
347
|
+
depends_on: attrs.fetch("depends_on"), # TODO: emperically determined to be a string in DSL, is that right?
|
348
|
+
default_in_interface: attrs.fetch("default_in_interface"),
|
349
|
+
)
|
350
|
+
end
|
351
|
+
|
352
|
+
def self.build_textvar(attrs)
|
353
|
+
Entities::Textvar.new(
|
354
|
+
key: attrs.fetch("key").to_sym,
|
355
|
+
description: attrs.fetch("description"),
|
356
|
+
default: attrs.fetch("default"),
|
357
|
+
depends_on_flag: attrs.fetch("depends_on_flag")&.to_sym
|
358
|
+
)
|
359
|
+
end
|
360
|
+
|
361
|
+
def self.build_chart(questionnaire, chart_json)
|
362
|
+
base_args = {
|
363
|
+
title: chart_json.fetch("title"),
|
364
|
+
plottables: chart_json.fetch("plottables").map do |plottable_json|
|
365
|
+
Quby::Questionnaires::Entities::Charting::Plottable.new(
|
366
|
+
plottable_json.fetch("key").to_sym,
|
367
|
+
label: plottable_json.fetch("label"),
|
368
|
+
plotted_key: plottable_json.fetch("plotted_key").to_sym,
|
369
|
+
global: plottable_json.fetch("global"),
|
370
|
+
questionnaire_key: plottable_json.fetch("questionnaire_key")
|
371
|
+
)
|
372
|
+
end,
|
373
|
+
y_categories: chart_json.fetch("y_categories"),
|
374
|
+
y_range_categories: chart_json.fetch("y_range_categories"),
|
375
|
+
chart_type: chart_json.fetch("chart_type"),
|
376
|
+
y_range: deserialize_range(chart_json.fetch("y_range")),
|
377
|
+
tick_interval: chart_json.fetch("tick_interval"),
|
378
|
+
plotbands: chart_json.fetch("plotbands").map do |plotband_json|
|
379
|
+
{
|
380
|
+
color: plotband_json.fetch("color").to_sym,
|
381
|
+
from: plotband_json.fetch("from"),
|
382
|
+
to: plotband_json.fetch("to")
|
383
|
+
}
|
384
|
+
end,
|
385
|
+
}
|
386
|
+
|
387
|
+
case chart_json.fetch("type")
|
388
|
+
when "bar_chart"
|
389
|
+
Quby::Questionnaires::Entities::Charting::BarChart.new(chart_json.fetch("key").to_sym,
|
390
|
+
plotlines: chart_json.fetch("plotlines"),
|
391
|
+
**base_args
|
392
|
+
)
|
393
|
+
when "line_chart"
|
394
|
+
Quby::Questionnaires::Entities::Charting::LineChart.new(chart_json.fetch("key").to_sym,
|
395
|
+
y_label: chart_json.fetch("y_label"),
|
396
|
+
tonality: chart_json.fetch("tonality").to_sym,
|
397
|
+
baseline: YAML.load(chart_json.fetch("baseline")),
|
398
|
+
clinically_relevant_change: chart_json.fetch("clinically_relevant_change"),
|
399
|
+
**base_args
|
400
|
+
)
|
401
|
+
when "radar_chart"
|
402
|
+
Quby::Questionnaires::Entities::Charting::BarChart.new(chart_json.fetch("key").to_sym,
|
403
|
+
plotlines: chart_json.fetch("plotlines"),
|
404
|
+
**base_args
|
405
|
+
)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def self.build_score_schema(attributes)
|
410
|
+
Entities::ScoreSchema.new(
|
411
|
+
key: attributes.fetch("key").to_sym,
|
412
|
+
label: attributes.fetch("label"),
|
413
|
+
subscore_schemas: attributes.fetch("subscore_schemas").map do |subschema|
|
414
|
+
{
|
415
|
+
key: subschema.fetch("key").to_sym,
|
416
|
+
label: subschema.fetch("label"),
|
417
|
+
export_key: subschema.fetch("export_key").to_sym,
|
418
|
+
only_for_export: subschema.fetch("only_for_export")
|
419
|
+
}
|
420
|
+
end
|
421
|
+
)
|
422
|
+
end
|
423
|
+
|
424
|
+
def self.build_outcome_table(questionnaire, attributes)
|
425
|
+
Entities::OutcomeTable.new(
|
426
|
+
questionnaire: questionnaire,
|
427
|
+
key: attributes.fetch("key").to_sym,
|
428
|
+
score_keys: attributes.fetch("score_keys").map(&:to_sym),
|
429
|
+
subscore_keys: attributes.fetch("subscore_keys").map(&:to_sym),
|
430
|
+
name: attributes.fetch("name"),
|
431
|
+
default_collapsed: attributes.fetch("default_collapsed"),
|
432
|
+
)
|
433
|
+
end
|
434
|
+
|
435
|
+
def self.deserialize_range(range_attributes)
|
436
|
+
return unless range_attributes
|
437
|
+
Range.new(range_attributes.fetch("begin"), range_attributes.fetch("end"), range_attributes.fetch("exclude_end"))
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|