surveyor 0.17.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +210 -0
- data/README.md +30 -238
- data/Rakefile +7 -12
- data/VERSION +1 -1
- data/features/redcap.feature +19 -0
- data/features/step_definitions/surveyor_steps.rb +5 -1
- data/features/support/REDCapDemoDatabase_DataDictionary.csv +127 -0
- data/generators/surveyor/templates/surveys/kitchen_sink_survey.rb +1 -1
- data/lib/surveyor/redcap_parser.rb +233 -0
- data/lib/tasks/surveyor_tasks.rake +9 -0
- data/spec/lib/redcap_parser_spec.rb +48 -0
- data/surveyor.gemspec +8 -5
- metadata +10 -7
- data/generators/test_surveyor/templates/TESTING_SURVEYOR +0 -0
- data/generators/test_surveyor/templates/environments/cucumber.rb +0 -21
- data/generators/test_surveyor/test_surveyor_generator.rb +0 -15
data/CHANGELOG
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
0.18.0
|
2
|
+
|
3
|
+
* finalizing redcap feature. parse dependencies. closes #93
|
4
|
+
* finished decomposing redcap branching logic rules
|
5
|
+
* working on redcap parser spec, question/answer reference lookup table
|
6
|
+
* skipping calcuated answers for now
|
7
|
+
* validations
|
8
|
+
* more progress on redcap parser
|
9
|
+
* working on redcap parser
|
10
|
+
|
11
|
+
0.17.0
|
12
|
+
|
13
|
+
* cucumber tests now work
|
14
|
+
* correction to post install notes in rakefile
|
15
|
+
* fix to rakefile instructions
|
16
|
+
* un-dryed the gemfile to try to fix a gem location problem
|
17
|
+
* added test boot file for test app usage, modified the rake task to copy in this file as well
|
18
|
+
* removed unparser from specs, it was breakin a bunch of them. deferred investigation
|
19
|
+
* got specs running and passing by adding internal rails app
|
20
|
+
* added rvmrc to create default gemset and added bundler
|
21
|
+
* Plugin installation is no longer supported
|
22
|
+
* wrong information in readme
|
23
|
+
* Merge branch 'master' into issue87
|
24
|
+
* Add count operator example to kitchen sink survey
|
25
|
+
* Generalize count operator to handle < <= >= !=
|
26
|
+
* Parse/unparse surveys w/ count> DC operator
|
27
|
+
* Add custom validation to handle count operator
|
28
|
+
* Remove count> "operator."
|
29
|
+
|
30
|
+
0.16.1
|
31
|
+
|
32
|
+
* fixed surveyor.sections translation line
|
33
|
+
* changed map resources order to access results survey success
|
34
|
+
* add translations for Sections title
|
35
|
+
* Add I18n to Sections title
|
36
|
+
* updated date on license
|
37
|
+
* updating results views and controller for new paths
|
38
|
+
* new results routes
|
39
|
+
|
40
|
+
0.16.0
|
41
|
+
|
42
|
+
* minor fixes to unparsing
|
43
|
+
* refining unparser. added rake task to unparse survey. closes #79
|
44
|
+
* unparsing for groups, dependencies, validations
|
45
|
+
* starting work on unparser for basic survey, section and question.
|
46
|
+
|
47
|
+
0.15.0
|
48
|
+
|
49
|
+
* prevent duplicate survey titles by appending incrementing numbers
|
50
|
+
* rake task to remove a survey. closes #64
|
51
|
+
* cleanup of old parsing strategy
|
52
|
+
* features and specs and new parser. closes #62
|
53
|
+
* first test driven work on parser
|
54
|
+
* moving parser and common specs so they run automatically. fixing some spec errors
|
55
|
+
* first shot a surveyor parser. some parts untested, but coded to determine style. references #62
|
56
|
+
* refactoring counters
|
57
|
+
* fixing failing specs. fixes acts\_as\_response issues
|
58
|
+
|
59
|
+
0.14.5
|
60
|
+
|
61
|
+
* use modules to include model methods. re-closes #77
|
62
|
+
* rails init. destroy dependent models
|
63
|
+
|
64
|
+
0.14.4
|
65
|
+
|
66
|
+
* explicitly require surveyor models and helper. update sweeper syntax. closes #77
|
67
|
+
* cleanup and requires
|
68
|
+
* fixing instructions for extending surveyor. closes #76
|
69
|
+
|
70
|
+
0.14.3
|
71
|
+
|
72
|
+
* remove manual numbering until it works. refactoring to use common methods.
|
73
|
+
|
74
|
+
0.14.2
|
75
|
+
|
76
|
+
* lowercase localization. feature instead of story in cucumber feature
|
77
|
+
* add results section
|
78
|
+
* add simple admin section for displaying survey result set
|
79
|
+
* Added manual numbering to labels as well
|
80
|
+
|
81
|
+
0.14.1
|
82
|
+
|
83
|
+
* typo in repeaters - use survey\_section\_id instead of section\_id
|
84
|
+
|
85
|
+
0.14.0
|
86
|
+
|
87
|
+
* view my survey specs fixed, fragment caching for surveyor#edit, localization. thanks bnadav
|
88
|
+
|
89
|
+
0.13.0
|
90
|
+
|
91
|
+
* simpler customization of surveyor.
|
92
|
+
* spec plugins task
|
93
|
+
* Feature instead of Story for cucumber. http://wiki.github.com/aslakhellesoy/cucumber/upgrading
|
94
|
+
|
95
|
+
0.12.0
|
96
|
+
|
97
|
+
* fix parser error in ruby 1.9, where instance_variables are symbols. closes #61
|
98
|
+
* added fastercsv as dependency. closes #59
|
99
|
+
* typo fix and test
|
100
|
+
* fixed broken spec for survey urls, made pending surveyor_controller specs pass
|
101
|
+
* Added explicit dependencycondition and validationcondition to DSL
|
102
|
+
* have authentication work with authlogic
|
103
|
+
* added "correct_answer" to parser, so you can specify one correct answer per question
|
104
|
+
|
105
|
+
0.11.0
|
106
|
+
|
107
|
+
* basic csv export. closes #21
|
108
|
+
* add unique indicies. closes #45
|
109
|
+
* add one_integer renderer. closes #51
|
110
|
+
* constrain surveys to have unique access_codes. closes #45. closes #42
|
111
|
+
* covering the extremely unlikely case that response_sets may have a non-unique access_code. closes #46. thanks jakewendt.
|
112
|
+
* current user id not needed in the view, set in SurveyorController. closes #48. thanks jakewendt
|
113
|
+
|
114
|
+
0.10.0
|
115
|
+
|
116
|
+
* surveyor config['extend'] is now an array. custom modules (e.g. SurveyExtensions are now included from within surveyor models, allowing
|
117
|
+
the customizations to work on every request in development. closes #39. thanks to mgurley and jakewendt for the suggestions.
|
118
|
+
* remove comment from surveyor_includes
|
119
|
+
* css tweak
|
120
|
+
* automatically add backslashes and eliminate multiple backslashes in relative root for routes
|
121
|
+
* readme spelling and line breaks
|
122
|
+
* fixing a failing spec with factory instead of mock parent model
|
123
|
+
* upgrading cucumber to 0.6
|
124
|
+
|
125
|
+
0.9.11
|
126
|
+
|
127
|
+
* adding rails init.rb to make gem loading work. thanks mike gurley. closes #52.
|
128
|
+
* Repeater changed to only have +1, not +3 as previous
|
129
|
+
* added locking and transaction to surveyor update action. Prevents bug that caused duplicated answers
|
130
|
+
* some light re-factoring and code readability changes
|
131
|
+
* some code formatting changes
|
132
|
+
* added require statement to specs so the factory_girl test dependency was more clear
|
133
|
+
* spiced up the readme... may have some typos
|
134
|
+
* readme update
|
135
|
+
|
136
|
+
0.9.10
|
137
|
+
|
138
|
+
* styles, adding labels for dates, correcting labels for radio buttons
|
139
|
+
|
140
|
+
0.9.9
|
141
|
+
|
142
|
+
* count label and image questions complete when mandatory. closes #38
|
143
|
+
* validate by other responses. closes #35
|
144
|
+
|
145
|
+
0.9.8
|
146
|
+
|
147
|
+
* @current\_user.id if @current\_user isn't nil. Closes #37
|
148
|
+
|
149
|
+
0.9.7
|
150
|
+
|
151
|
+
* fixing typos
|
152
|
+
* remove surveyor controller from load\_once\_paths. fixes issue with dependencies and unloading in development. closes #36
|
153
|
+
|
154
|
+
0.9.6
|
155
|
+
|
156
|
+
* response set reports progress and mandatory questions completeness. closes #33
|
157
|
+
* adding correctness to response sets
|
158
|
+
* adding correctness to responses
|
159
|
+
|
160
|
+
0.9.5
|
161
|
+
|
162
|
+
* allow append for survey parser. closes #32
|
163
|
+
|
164
|
+
0.9.4
|
165
|
+
|
166
|
+
* making tinycode compatible with ruby 1.8.6
|
167
|
+
|
168
|
+
0.9.3
|
169
|
+
|
170
|
+
* fix for survey parser require
|
171
|
+
|
172
|
+
0.9.2
|
173
|
+
|
174
|
+
* fixing specs for namespacing and move of tinycode
|
175
|
+
* namespacing SurveyParser models to avoid conflict with model extensions
|
176
|
+
|
177
|
+
0.9.1
|
178
|
+
|
179
|
+
* fix for tinycode, more descriptive missing method
|
180
|
+
|
181
|
+
0.9.0
|
182
|
+
|
183
|
+
* validations in dsl and surveyor models
|
184
|
+
* preserve underscores in reference identifiers
|
185
|
+
* dsl specs, refactoring into base class
|
186
|
+
* adding display order to surveys
|
187
|
+
* moving columnizer and tiny column functionality to surveyor module
|
188
|
+
* columnizer (and tiny code) refactoring, columnizer spec extracted from answer spec
|
189
|
+
* cleanup of scopes with joins
|
190
|
+
* refactoring dependency
|
191
|
+
|
192
|
+
0.8.0
|
193
|
+
|
194
|
+
* question group dependencies
|
195
|
+
* expanded examples in kitchen sink survey
|
196
|
+
* specs
|
197
|
+
|
198
|
+
0.7.1
|
199
|
+
|
200
|
+
* custom index page
|
201
|
+
* custom classes and renderers
|
202
|
+
* fixing typo in kitchen sink survey
|
203
|
+
|
204
|
+
0.7.0
|
205
|
+
|
206
|
+
* new kitchen sink survey with better documentation of DSL
|
207
|
+
* migration misspelling
|
208
|
+
* fixing ordering, dependency conditions evaluation, and changing named scopes for now
|
209
|
+
* DRYing up surveyor DSL models
|
210
|
+
* working on adding dependencies for question groups
|
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# Surveys On Rails
|
2
2
|
|
3
|
-
Surveyor is a
|
3
|
+
Surveyor is a ruby gem and developer tool that brings surveys into Rails applications. Surveys are written in the Surveyor DSL (Domain Specific Language). Before Rails 2.3, it was implemented as a Rails Engine. It also existed previously as a plugin. Today it is a gem only.
|
4
4
|
|
5
5
|
## Why you might want to use Surveyor
|
6
6
|
|
7
|
-
If
|
7
|
+
If your Rails app needs to asks users questions as part of a survey, quiz, or questionnaire then you should consider using Surveyor. This gem was designed to deliver clinical research surveys to large populations, but it can be used for any type of survey.
|
8
8
|
|
9
|
-
|
9
|
+
The Surveyor DSL defines questions, answers, question groups, survey sections, dependencies (e.g. if response to question 4 is A, then show question 5), and validations. Answers are the options available for each question - user input is called "responses" and are grouped into "response sets". A DSL makes it significantly easier to import long surveys (no more click/copy/paste). It also enables non-programmers to write out, edit, re-edit... any number of surveys.
|
10
10
|
|
11
11
|
## DSL example
|
12
12
|
|
13
|
-
|
13
|
+
The Surveyor DSL supports a wide range of question types (too many to list here) and complex dependency logic. Here are the first few questions of the "kitchen sink" survey which should give you and idea of how it works. The full example with all the types of questions available if you follow the installation instructions below.
|
14
14
|
|
15
|
-
survey "
|
15
|
+
survey "Kitchen Sink survey" do
|
16
16
|
|
17
17
|
section "Basic questions" do
|
18
18
|
# A label is a question that accepts no answers
|
@@ -46,268 +46,60 @@ Our DSL supports a wide range of question types (too many to list here) and vary
|
|
46
46
|
condition_C :q_2, "==", :a_3
|
47
47
|
condition_D :q_2, "==", :a_4
|
48
48
|
|
49
|
-
# ... other question, sections and such. See kitchen_sink_survey.rb for more.
|
49
|
+
# ... other question, sections and such. See surveys/kitchen_sink_survey.rb for more.
|
50
50
|
end
|
51
51
|
|
52
52
|
end
|
53
53
|
|
54
|
-
The
|
54
|
+
The first question is "pick one" (radio buttons) with "other". The second question is "pick any" (checkboxes) with the option to "omit". It also features a dependency with a follow up question. Notice the dependency rule is defined as a string. We support complex dependency such as "A and (B or C) and D" or "A or ((B and C) or D)". The conditions are evaluated separately using the operators "==","!=","<>", ">=","<" the substituted by letter into to the dependency rule and evaluated.
|
55
55
|
|
56
56
|
# Installation
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
# in environment.rb
|
61
|
-
config.gem "surveyor", :source => 'http://gemcutter.org'
|
62
|
-
|
63
|
-
rake gems:install
|
58
|
+
1. Add it to your bundler Gemfile:
|
64
59
|
|
65
|
-
|
60
|
+
gem "surveyor"
|
66
61
|
|
67
|
-
|
68
|
-
gem "surveyor"
|
62
|
+
`bundle install`
|
69
63
|
|
70
|
-
|
71
|
-
|
72
|
-
Generate assets, run migrations:
|
64
|
+
2. Generate assets, run migrations:
|
73
65
|
|
74
|
-
|
75
|
-
|
66
|
+
`script/generate surveyor`
|
67
|
+
`rake db:migrate`
|
76
68
|
|
77
|
-
Try out the "kitchen sink" survey
|
69
|
+
3. Try out the "kitchen sink" survey. The rake task above generates surveys from our custom survey DSL (a good format for end users and stakeholders).
|
78
70
|
|
79
|
-
|
71
|
+
`rake surveyor FILE=surveys/kitchen_sink_survey.rb`
|
80
72
|
|
81
|
-
|
82
|
-
After you have run them start up your app and go to:
|
73
|
+
4. Start up your app and visit:
|
83
74
|
|
84
|
-
|
75
|
+
http://localhost:3000/surveys
|
85
76
|
|
86
|
-
Try taking the survey and compare it to the contents of the DSL file kitchen\_sink\_survey.rb. See how
|
77
|
+
Try taking the survey and compare it to the contents of the DSL file kitchen\_sink\_survey.rb. See how the DSL maps to what you see.
|
87
78
|
|
88
79
|
There are two other useful rake tasks for removing (only surveys without responses) and un-parsing (from db to DSL file) surveys:
|
89
80
|
|
90
|
-
|
91
|
-
|
81
|
+
`rake surveyor:remove`
|
82
|
+
`rake surveyor:unparse`
|
92
83
|
|
93
84
|
# Customizing surveyor
|
94
85
|
|
95
86
|
Surveyor's controller, models, and views may be customized via classes in your app/models, app/helpers and app/controllers directories. To generate a sample custom controller and layout, run:
|
96
87
|
|
97
|
-
|
98
|
-
|
99
|
-
and check out surveys/EXTENDING\_SURVEYOR
|
100
|
-
|
101
|
-
# Dependencices
|
102
|
-
|
103
|
-
Surveyor depends on Ruby (1.8.7 - 1.9.1), Rails 2.3 and the SASS style sheet language, part of HAML (http://haml.hamptoncatlin.com/download). It also depends on fastercsv for csv exports. For running the test suite you will need rspec and have the rspec plugin installed in your application.
|
104
|
-
|
105
|
-
# Test Suite and Development
|
106
|
-
|
107
|
-
To work on the plugin code (for enhancements, and bug fixes, etc...) fork this github project. Then clone the project under the vendor/plugins directory in a Rails app used only for development:
|
108
|
-
|
109
|
-
# Changes
|
110
|
-
|
111
|
-
0.17.0
|
112
|
-
|
113
|
-
* cucumber tests now work
|
114
|
-
* correction to post install notes in rakefile
|
115
|
-
* fix to rakefile instructions
|
116
|
-
* un-dryed the gemfile to try to fix a gem location problem
|
117
|
-
* added test boot file for test app usage, modified the rake task to copy in this file as well
|
118
|
-
* removed unparser from specs, it was breakin a bunch of them. deferred investigation
|
119
|
-
* got specs running and passing by adding internal rails app
|
120
|
-
* added rvmrc to create default gemset and added bundler
|
121
|
-
* Plugin installation is no longer supported
|
122
|
-
* wrong information in readme
|
123
|
-
* Merge branch 'master' into issue87
|
124
|
-
* Add count operator example to kitchen sink survey
|
125
|
-
* Generalize count operator to handle < <= >= !=
|
126
|
-
* Parse/unparse surveys w/ count> DC operator
|
127
|
-
* Add custom validation to handle count operator
|
128
|
-
* Remove count> "operator."
|
129
|
-
|
130
|
-
0.16.1
|
131
|
-
|
132
|
-
* fixed surveyor.sections translation line
|
133
|
-
* changed map resources order to access results survey success
|
134
|
-
* add translations for Sections title
|
135
|
-
* Add I18n to Sections title
|
136
|
-
* updated date on license
|
137
|
-
* updating results views and controller for new paths
|
138
|
-
* new results routes
|
139
|
-
|
140
|
-
0.16.0
|
141
|
-
|
142
|
-
* minor fixes to unparsing
|
143
|
-
* refining unparser. added rake task to unparse survey. closes #79
|
144
|
-
* unparsing for groups, dependencies, validations
|
145
|
-
* starting work on unparser for basic survey, section and question.
|
146
|
-
|
147
|
-
0.15.0
|
148
|
-
|
149
|
-
* prevent duplicate survey titles by appending incrementing numbers
|
150
|
-
* rake task to remove a survey. closes #64
|
151
|
-
* cleanup of old parsing strategy
|
152
|
-
* features and specs and new parser. closes #62
|
153
|
-
* first test driven work on parser
|
154
|
-
* moving parser and common specs so they run automatically. fixing some spec errors
|
155
|
-
* first shot a surveyor parser. some parts untested, but coded to determine style. references #62
|
156
|
-
* refactoring counters
|
157
|
-
* fixing failing specs. fixes acts\_as\_response issues
|
158
|
-
|
159
|
-
0.14.5
|
160
|
-
|
161
|
-
* use modules to include model methods. re-closes #77
|
162
|
-
* rails init. destroy dependent models
|
163
|
-
|
164
|
-
0.14.4
|
165
|
-
|
166
|
-
* explicitly require surveyor models and helper. update sweeper syntax. closes #77
|
167
|
-
* cleanup and requires
|
168
|
-
* fixing instructions for extending surveyor. closes #76
|
169
|
-
|
170
|
-
0.14.3
|
171
|
-
|
172
|
-
* remove manual numbering until it works. refactoring to use common methods.
|
173
|
-
|
174
|
-
0.14.2
|
175
|
-
|
176
|
-
* lowercase localization. feature instead of story in cucumber feature
|
177
|
-
* add results section
|
178
|
-
* add simple admin section for displaying survey result set
|
179
|
-
* Added manual numbering to labels as well
|
180
|
-
|
181
|
-
0.14.1
|
182
|
-
|
183
|
-
* typo in repeaters - use survey\_section\_id instead of section\_id
|
184
|
-
|
185
|
-
0.14.0
|
186
|
-
|
187
|
-
* view my survey specs fixed, fragment caching for surveyor#edit, localization. thanks bnadav
|
188
|
-
|
189
|
-
0.13.0
|
190
|
-
|
191
|
-
* simpler customization of surveyor.
|
192
|
-
* spec plugins task
|
193
|
-
* Feature instead of Story for cucumber. http://wiki.github.com/aslakhellesoy/cucumber/upgrading
|
194
|
-
|
195
|
-
0.12.0
|
196
|
-
|
197
|
-
* fix parser error in ruby 1.9, where instance_variables are symbols. closes #61
|
198
|
-
* added fastercsv as dependency. closes #59
|
199
|
-
* typo fix and test
|
200
|
-
* fixed broken spec for survey urls, made pending surveyor_controller specs pass
|
201
|
-
* Added explicit dependencycondition and validationcondition to DSL
|
202
|
-
* have authentication work with authlogic
|
203
|
-
* added "correct_answer" to parser, so you can specify one correct answer per question
|
204
|
-
|
205
|
-
0.11.0
|
206
|
-
|
207
|
-
* basic csv export. closes #21
|
208
|
-
* add unique indicies. closes #45
|
209
|
-
* add one_integer renderer. closes #51
|
210
|
-
* constrain surveys to have unique access_codes. closes #45. closes #42
|
211
|
-
* covering the extremely unlikely case that response_sets may have a non-unique access_code. closes #46. thanks jakewendt.
|
212
|
-
* current user id not needed in the view, set in SurveyorController. closes #48. thanks jakewendt
|
213
|
-
|
214
|
-
0.10.0
|
215
|
-
|
216
|
-
* surveyor config['extend'] is now an array. custom modules (e.g. SurveyExtensions are now included from within surveyor models, allowing
|
217
|
-
the customizations to work on every request in development. closes #39. thanks to mgurley and jakewendt for the suggestions.
|
218
|
-
* remove comment from surveyor_includes
|
219
|
-
* css tweak
|
220
|
-
* automatically add backslashes and eliminate multiple backslashes in relative root for routes
|
221
|
-
* readme spelling and line breaks
|
222
|
-
* fixing a failing spec with factory instead of mock parent model
|
223
|
-
* upgrading cucumber to 0.6
|
224
|
-
|
225
|
-
0.9.11
|
226
|
-
|
227
|
-
* adding rails init.rb to make gem loading work. thanks mike gurley. closes #52.
|
228
|
-
* Repeater changed to only have +1, not +3 as previous
|
229
|
-
* added locking and transaction to surveyor update action. Prevents bug that caused duplicated answers
|
230
|
-
* some light re-factoring and code readability changes
|
231
|
-
* some code formatting changes
|
232
|
-
* added require statement to specs so the factory_girl test dependency was more clear
|
233
|
-
* spiced up the readme... may have some typos
|
234
|
-
* readme update
|
235
|
-
|
236
|
-
0.9.10
|
237
|
-
|
238
|
-
* styles, adding labels for dates, correcting labels for radio buttons
|
239
|
-
|
240
|
-
0.9.9
|
241
|
-
|
242
|
-
* count label and image questions complete when mandatory. closes #38
|
243
|
-
* validate by other responses. closes #35
|
244
|
-
|
245
|
-
0.9.8
|
246
|
-
|
247
|
-
* @current\_user.id if @current\_user isn't nil. Closes #37
|
248
|
-
|
249
|
-
0.9.7
|
250
|
-
|
251
|
-
* fixing typos
|
252
|
-
* remove surveyor controller from load\_once\_paths. fixes issue with dependencies and unloading in development. closes #36
|
253
|
-
|
254
|
-
0.9.6
|
255
|
-
|
256
|
-
* response set reports progress and mandatory questions completeness. closes #33
|
257
|
-
* adding correctness to response sets
|
258
|
-
* adding correctness to responses
|
259
|
-
|
260
|
-
0.9.5
|
261
|
-
|
262
|
-
* allow append for survey parser. closes #32
|
263
|
-
|
264
|
-
0.9.4
|
265
|
-
|
266
|
-
* making tinycode compatible with ruby 1.8.6
|
267
|
-
|
268
|
-
0.9.3
|
269
|
-
|
270
|
-
* fix for survey parser require
|
271
|
-
|
272
|
-
0.9.2
|
273
|
-
|
274
|
-
* fixing specs for namespacing and move of tinycode
|
275
|
-
* namespacing SurveyParser models to avoid conflict with model extensions
|
276
|
-
|
277
|
-
0.9.1
|
278
|
-
|
279
|
-
* fix for tinycode, more descriptive missing method
|
280
|
-
|
281
|
-
0.9.0
|
282
|
-
|
283
|
-
* validations in dsl and surveyor models
|
284
|
-
* preserve underscores in reference identifiers
|
285
|
-
* dsl specs, refactoring into base class
|
286
|
-
* adding display order to surveys
|
287
|
-
* moving columnizer and tiny column functionality to surveyor module
|
288
|
-
* columnizer (and tiny code) refactoring, columnizer spec extracted from answer spec
|
289
|
-
* cleanup of scopes with joins
|
290
|
-
* refactoring dependency
|
88
|
+
`script/generate extend_surveyor`
|
291
89
|
|
292
|
-
|
90
|
+
and read surveys/EXTENDING\_SURVEYOR
|
293
91
|
|
294
|
-
|
295
|
-
* expanded examples in kitchen sink survey
|
296
|
-
* specs
|
92
|
+
# Requirements
|
297
93
|
|
298
|
-
|
94
|
+
Surveyor depends on Ruby (1.8.7 - 1.9.1), Rails 2.3 and HAML/SASS http://haml.hamptoncatlin.com/. It also depends on fastercsv for csv exports.
|
299
95
|
|
300
|
-
|
301
|
-
* custom classes and renderers
|
302
|
-
* fixing typo in kitchen sink survey
|
96
|
+
# Contributing, testing
|
303
97
|
|
304
|
-
|
98
|
+
To work on the code fork this github project. Run:
|
305
99
|
|
306
|
-
|
307
|
-
|
308
|
-
* fixing ordering, dependency conditions evaluation, and changing named scopes for now
|
309
|
-
* DRYing up surveyor DSL models
|
310
|
-
* working on adding dependencies for question groups
|
100
|
+
`bundler install`
|
101
|
+
`rake testbed`
|
311
102
|
|
103
|
+
and start writing tests!
|
312
104
|
|
313
|
-
Copyright (c) 2008-
|
105
|
+
Copyright (c) 2008-2010 Brian Chamberlain and Mark Yoon, released under the MIT license
|
data/Rakefile
CHANGED
@@ -30,12 +30,13 @@ rescue LoadError
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
desc "Set up a rails app for testing in the spec dir"
|
34
|
+
task :testbed => [:"testbed:build_app", :"testbed:copy_files", :"testbed:install_surveyor"]
|
33
35
|
|
34
36
|
namespace "testbed" do
|
35
|
-
|
36
37
|
RAPPNAME = "test_app" #This is also hardcoded in the spec/spec_helper.rb and gitignore file. Change it there too...
|
37
|
-
|
38
|
-
|
38
|
+
|
39
|
+
"Generate rails app in spec dir"
|
39
40
|
task :build_app do
|
40
41
|
directory "spec"
|
41
42
|
chdir("spec") do
|
@@ -60,7 +61,7 @@ namespace "testbed" do
|
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
|
-
desc "Install surveyor in
|
64
|
+
desc "Install surveyor in test app, run migrations, prep test db"
|
64
65
|
task :install_surveyor do
|
65
66
|
sh "gem install surveyor"
|
66
67
|
chdir("spec/#{RAPPNAME}") do
|
@@ -73,17 +74,11 @@ namespace "testbed" do
|
|
73
74
|
puts "NOTE: We installed the surveyor gem using 'gem install surveyor' to fix a problem where RVM (or bundler or both) don't let Rails see generators in a gem. ('script/generate surveyor' for example). To remove the gem run `gem uninstall surveyor` to remove the gem version of surveyor leaving the dev version" # Getting around a bug/problem in bundler. see: http://bit.ly/9NZOEz
|
74
75
|
end
|
75
76
|
|
76
|
-
desc "Remove rails
|
77
|
-
task :
|
77
|
+
desc "Remove rails test app from spec dir"
|
78
|
+
task :remove do
|
78
79
|
puts "Removing the test_app in the spec folder"
|
79
80
|
sh "rm -rf spec/#{RAPPNAME}"
|
80
81
|
end
|
81
|
-
|
82
|
-
desc "Setup for the test app (create)"
|
83
|
-
task :setup => [:build_app, :copy_files, :install_surveyor]
|
84
|
-
desc "Teardown for the test app (remove)"
|
85
|
-
task :teardown => [:remove_app]
|
86
|
-
|
87
82
|
end # namespace
|
88
83
|
|
89
84
|
require 'spec/rake/spectask'
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.18.0
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: Survey creation
|
2
|
+
As a
|
3
|
+
I want to write out the survey in the DSL
|
4
|
+
So that I can give it to survey participants
|
5
|
+
|
6
|
+
Scenario: Basic questions
|
7
|
+
Given I parse redcap file "REDCapDemoDatabase_DataDictionary.csv"
|
8
|
+
Then there should be 1 survey with:
|
9
|
+
||
|
10
|
+
And there should be 143 questions with:
|
11
|
+
||
|
12
|
+
And there should be 161 answers with:
|
13
|
+
||
|
14
|
+
And there should be 3 resolved dependency_conditions with:
|
15
|
+
||
|
16
|
+
And there should be 2 dependencies with:
|
17
|
+
| rule |
|
18
|
+
| A |
|
19
|
+
| A and B |
|
@@ -2,6 +2,10 @@ Given /^I parse$/ do |string|
|
|
2
2
|
Surveyor::Parser.parse(string)
|
3
3
|
end
|
4
4
|
|
5
|
+
Given /^I parse redcap file "([^"]*)"$/ do |name|
|
6
|
+
Surveyor::RedcapParser.parse File.read(File.join(RAILS_ROOT, '..', '..', 'features', 'support', name)), name
|
7
|
+
end
|
8
|
+
|
5
9
|
Then /^there should be (\d+) survey(?:s?) with:$/ do |x, table|
|
6
10
|
Survey.count.should == x.to_i
|
7
11
|
table.hashes.each do |hash|
|
@@ -33,7 +37,7 @@ Then /^there should be (\d+) answer(?:s?) with:$/ do |x, table|
|
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
Then /^there should be (\d+)
|
40
|
+
Then /^there should be (\d+) dependenc(?:y|ies) with:$/ do |x, table|
|
37
41
|
Dependency.count.should == x.to_i
|
38
42
|
table.hashes.each do |hash|
|
39
43
|
Dependency.find(:first, :conditions => hash).should_not be_nil
|
@@ -0,0 +1,127 @@
|
|
1
|
+
"Variable / Field Name","Form Name","Field Units","Section Header","Field Type","Field Label","Choices OR Calculations","Field Note","Text Validation Type","Text Validation Min","Text Validation Max",Identifier?,"Branching Logic (Show field only if...)","Required Field?"
|
2
|
+
study_id,demographics,,,text,"Study ID",,,,,,,,
|
3
|
+
date_enrolled,demographics,,"Demographic Characteristics",text,"Date subject signed consent",,YYYY-MM-DD,date,,,,,
|
4
|
+
first_name,demographics,,,text,"First Name",,,,,,y,,
|
5
|
+
last_name,demographics,,,text,"Last Name",,,,,,y,,
|
6
|
+
address,demographics,,"Contact Information",notes,"Street, City, State, ZIP",,,,,,y,,
|
7
|
+
telephone_1,demographics,,,text,"Phone number",,"Include Area Code",phone,,,y,,
|
8
|
+
telephone_2,demographics,,,text,"Second phone number",,"Include Area Code",phone,,,y,,
|
9
|
+
email,demographics,,,text,E-mail,,,email,,,y,,
|
10
|
+
sex,demographics,,,dropdown,Gender,"0, Female | 1, Male",,,,,,,y
|
11
|
+
given_birth,demographics,,,dropdown,"Has the subject given birth before?","0, No | 1, Yes",,,,,,"[sex] = ""0""",
|
12
|
+
num_children,demographics,,,text,"How many times has the subject given birth?",,,integer,0,,,"[sex] = ""0"" and [given_birth] = ""1""",
|
13
|
+
ethnicity,demographics,,,radio,Ethnicity,"0, Hispanic or Latino | 1, NOT Hispanic or Latino | 2, Unknown / Not Reported",,,,,,,
|
14
|
+
race,demographics,,,radio,Race,"0, American Indian/Alaska Native | 1, Asian | 2, Native Hawaiian or Other Pacific Islander | 3, Black or African American | 4, White | 5, More Than One Race | 6, Unknown / Not Reported",,,,,,,
|
15
|
+
dob,demographics,,,text,"Date of birth",,,date,,,y,,
|
16
|
+
age,demographics,,,calc,"Age (years)","round(datediff([dob],'today','y'),1)",,,,,,,
|
17
|
+
height,demographics,cm,,text,"Height (cm)",,,number,130,215,,,
|
18
|
+
weight,demographics,kilograms,,text,"Weight (kilograms)",,,integer,35,200,,,
|
19
|
+
bmi,demographics,kilograms,,calc,BMI,"round(([weight]*10000)/(([height])^(2)),1)",,,,,,,
|
20
|
+
patient_document,demographics,,,file,"Patient document",,,,,,,,
|
21
|
+
meds,demographics,,,checkbox,"Is patient taking any of the following medications? (check all that apply)","1, Lexapro | 2, Celexa | 3, Prozac | 4, Paxil | 5, Zoloft",,,,,,,
|
22
|
+
diabetes,demographics,,,dropdown,"Patient has a diagnosis of diabetes mellitus?","0, No | 1, Yes",,,,,,,
|
23
|
+
diabetes_type,demographics,,,dropdown,"Type of Diabetes Mellitus","0, Type 1 insulin-dependent | 1, Type 2 insulin-dependent | 2, Type 2 non insulin-dependent",,,,,,,
|
24
|
+
dialysis_initiation,demographics,,"Dialysis Information",text,"Date of first outpatient dialysis treatment",,,date,,,,,
|
25
|
+
access_type,demographics,,,dropdown,"Type of vascular access","0, Graft | 1, Fistula | 2, Catheter with maturing graft | 3, Catheter with maturing fistula",,,,,,,
|
26
|
+
access_location,demographics,,,dropdown,"Location of currently used vascular access","0, Forearm | 1, Upper arm | 2, Internal jugular vein | 3, Subclavian vein | 4, Other",,,,,,,
|
27
|
+
dialysis_unit_name,demographics,,,text,"Name of dialysis unit",,,,,,,,
|
28
|
+
dialysis_unit_phone,demographics,,,text,"Phone number",,"Include Area Code",phone,,,,,
|
29
|
+
dialysis_schedule_days,demographics,,,radio,"Days of the week patient is dialyzed","0, Monday-Wednesday-Friday | 1, Tuesday-Thursday-Saturday | 2, Other",,,,,,,
|
30
|
+
dialysis_schedule_time,demographics,,,dropdown,"Shift patient is dialyzed","0, First shift | 1, Second shift | 2, Third shift | 3, Fourth shift",,,,,,,
|
31
|
+
etiology_esrd,demographics,,,dropdown,"Etiology of ESRD","0, Diabetes | 1, Hypertension | 2, Glomerulonephritis | 3, Polycystic Kidney Disease | 4, Interstitial Nephritis | 5, Hereditary Nephritis | 6, Other",,,,,,,
|
32
|
+
subject_comments,demographics,,"General Comments",notes,Comments,,,,,,,,
|
33
|
+
date_visit_b,baseline_data,,"Baseline Measurements",text,"Date of baseline visit",,,date,,,,,
|
34
|
+
date_blood_b,baseline_data,,,text,"Date blood was drawn",,,date,,,,,
|
35
|
+
alb_b,baseline_data,g/dL,,text,"Serum Albumin (g/dL)",,,integer,3,5,,,
|
36
|
+
prealb_b,baseline_data,mg/dL,,text,"Serum Prealbumin (mg/dL)",,,number,10,40,,,
|
37
|
+
creat_b,baseline_data,mg/dL,,text,"Creatinine (mg/dL)",,,number,0.5,20,,,
|
38
|
+
npcr_b,baseline_data,g/kg/d,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,0.5,2,,,
|
39
|
+
chol_b,baseline_data,mg/dL,,text,"Cholesterol (mg/dL)",,,number,100,300,,,
|
40
|
+
transferrin_b,baseline_data,mg/dL,,text,"Transferrin (mg/dL)",,,number,100,300,,,
|
41
|
+
kt_v_b,baseline_data,,,text,Kt/V,,,number,0.9,3,,,
|
42
|
+
drywt_b,baseline_data,kilograms,,text,"Dry weight (kilograms)",,,number,35,200,,,
|
43
|
+
plasma1_b,baseline_data,,,dropdown,"Collected Plasma 1?","0, No | 1, Yes",,,,,,,
|
44
|
+
plasma2_b,baseline_data,,,dropdown,"Collected Plasma 2?","0, No | 1, Yes",,,,,,,
|
45
|
+
plasma3_b,baseline_data,,,dropdown,"Collected Plasma 3?","0, No | 1, Yes",,,,,,,
|
46
|
+
serum1_b,baseline_data,,,dropdown,"Collected Serum 1?","0, No | 1, Yes",,,,,,,
|
47
|
+
serum2_b,baseline_data,,,dropdown,"Collected Serum 2?","0, No | 1, Yes",,,,,,,
|
48
|
+
serum3_b,baseline_data,,,dropdown,"Collected Serum 3?","0, No | 1, Yes",,,,,,,
|
49
|
+
sga_b,baseline_data,,,text,"Subject Global Assessment (score = 1-7)",,,number,0.9,7.1,,,
|
50
|
+
date_supplement_dispensed,baseline_data,,,text,"Date patient begins supplement",,,date,,,,,
|
51
|
+
date_visit_1,month_1_data,,"Month 1",text,"Date of Month 1 visit",,,date,,,,,
|
52
|
+
alb_1,month_1_data,g/dL,,text,"Serum Albumin (g/dL)",,,number,3,5,,,
|
53
|
+
prealb_1,month_1_data,mg/dL,,text,"Serum Prealbumin (mg/dL)",,,number,10,40,,,
|
54
|
+
creat_1,month_1_data,mg/dL,,text,"Creatinine (mg/dL)",,,number,0.5,20,,,
|
55
|
+
npcr_1,month_1_data,g/kg/d,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,0.5,2,,,
|
56
|
+
chol_1,month_1_data,mg/dL,,text,"Cholesterol (mg/dL)",,,number,100,300,,,
|
57
|
+
transferrin_1,month_1_data,mg/dL,,text,"Transferrin (mg/dL)",,,number,100,300,,,
|
58
|
+
kt_v_1,month_1_data,,,text,Kt/V,,,number,0.9,3,,,
|
59
|
+
drywt_1,month_1_data,kilograms,,text,"Dry weight (kilograms)",,,number,35,200,,,
|
60
|
+
no_show_1,month_1_data,,,text,"Number of treatments missed",,,number,0,7,,,
|
61
|
+
compliance_1,month_1_data,,,dropdown,"How compliant was the patient in drinking the supplement?","0, 100 percent | 1, 99-75 percent | 2, 74-50 percent | 3, 49-25 percent | 4, 0-24 percent",,,,,,,
|
62
|
+
hospit_1,month_1_data,,"Hospitalization Data",dropdown,"Was patient hospitalized since last visit?","0, No | 1, Yes",,,,,,,
|
63
|
+
cause_hosp_1,month_1_data,,,dropdown,"What was the cause of hospitalization?","1, Vascular access related events | 2, CVD events | 3, Other",,,,,,,
|
64
|
+
admission_date_1,month_1_data,,,text,"Date of hospital admission",,,date,,,,,
|
65
|
+
discharge_date_1,month_1_data,,,text,"Date of hospital discharge",,,date,,,,,
|
66
|
+
discharge_summary_1,month_1_data,,,dropdown,"Discharge summary in patients binder?","0, No | 1, Yes",,,,,,,
|
67
|
+
death_1,month_1_data,,"Mortality Data",dropdown,"Has patient died since last visit?","0, No | 1, Yes",,,,,,,
|
68
|
+
date_death_1,month_1_data,,,text,"Date of death",,,date,,,,,
|
69
|
+
cause_death_1,month_1_data,,,dropdown,"What was the cause of death?","1, All-cause | 2, Cardiovascular",,,,,,,
|
70
|
+
date_visit_2,month_2_data,,"Month 2",text,"Date of Month 2 visit",,,date,,,,,
|
71
|
+
alb_2,month_2_data,g/dL,,text,"Serum Albumin (g/dL)",,,number,3,5,,,
|
72
|
+
prealb_2,month_2_data,mg/dL,,text,"Serum Prealbumin (mg/dL)",,,number,10,40,,,
|
73
|
+
creat_2,month_2_data,mg/dL,,text,"Creatinine (mg/dL)",,,number,0.5,20,,,
|
74
|
+
npcr_2,month_2_data,g/kg/d,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,0.5,2,,,
|
75
|
+
chol_2,month_2_data,mg/dL,,text,"Cholesterol (mg/dL)",,,number,100,300,,,
|
76
|
+
transferrin_2,month_2_data,mg/dL,,text,"Transferrin (mg/dL)",,,number,100,300,,,
|
77
|
+
kt_v_2,month_2_data,,,text,Kt/V,,,number,0.9,3,,,
|
78
|
+
drywt_2,month_2_data,kilograms,,text,"Dry weight (kilograms)",,,number,35,200,,,
|
79
|
+
no_show_2,month_2_data,,,text,"Number of treatments missed",,,number,0,7,,,
|
80
|
+
compliance_2,month_2_data,,,dropdown,"How compliant was the patient in drinking the supplement?","0, 100 percent | 1, 99-75 percent | 2, 74-50 percent | 3, 49-25 percent | 4, 0-24 percent",,,,,,,
|
81
|
+
hospit_2,month_2_data,,"Hospitalization Data",dropdown,"Was patient hospitalized since last visit?","0, No | 1, Yes",,,,,,,
|
82
|
+
cause_hosp_2,month_2_data,,,dropdown,"What was the cause of hospitalization?","1, Vascular access related events | 2, CVD events | 3, Other",,,,,,,
|
83
|
+
admission_date_2,month_2_data,,,text,"Date of hospital admission",,,date,,,,,
|
84
|
+
discharge_date_2,month_2_data,,,text,"Date of hospital discharge",,,date,,,,,
|
85
|
+
discharge_summary_2,month_2_data,,,dropdown,"Discharge summary in patients binder?","0, No | 1, Yes",,,,,,,
|
86
|
+
death_2,month_2_data,,"Mortality Data",dropdown,"Has patient died since last visit?","0, No | 1, Yes",,,,,,,
|
87
|
+
date_death_2,month_2_data,,,text,"Date of death",,,date,,,,,
|
88
|
+
cause_death_2,month_2_data,,,dropdown,"What was the cause of death?","1, All-cause | 2, Cardiovascular",,,,,,,
|
89
|
+
date_visit_3,month_3_data,,"Month 3",text,"Date of Month 3 visit",,,date,,,,,
|
90
|
+
date_blood_3,month_3_data,,,text,"Date blood was drawn",,,date,,,,,
|
91
|
+
alb_3,month_3_data,g/dL,,text,"Serum Albumin (g/dL)",,,number,3,5,,,
|
92
|
+
prealb_3,month_3_data,mg/dL,,text,"Serum Prealbumin (mg/dL)",,,number,10,40,,,
|
93
|
+
creat_3,month_3_data,mg/dL,,text,"Creatinine (mg/dL)",,,number,0.5,20,,,
|
94
|
+
npcr_3,month_3_data,g/kg/d,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,0.5,2,,,
|
95
|
+
chol_3,month_3_data,mg/dL,,text,"Cholesterol (mg/dL)",,,number,100,300,,,
|
96
|
+
transferrin_3,month_3_data,mg/dL,,text,"Transferrin (mg/dL)",,,number,100,300,,,
|
97
|
+
kt_v_3,month_3_data,,,text,Kt/V,,,number,0.9,3,,,
|
98
|
+
drywt_3,month_3_data,kilograms,,text,"Dry weight (kilograms)",,,number,35,200,,,
|
99
|
+
plasma1_3,month_3_data,,,dropdown,"Collected Plasma 1?","0, No | 1, Yes",,,,,,,
|
100
|
+
plasma2_3,month_3_data,,,dropdown,"Collected Plasma 2?","0, No | 1, Yes",,,,,,,
|
101
|
+
plasma3_3,month_3_data,,,dropdown,"Collected Plasma 3?","0, No | 1, Yes",,,,,,,
|
102
|
+
serum1_3,month_3_data,,,dropdown,"Collected Serum 1?","0, No | 1, Yes",,,,,,,
|
103
|
+
serum2_3,month_3_data,,,dropdown,"Collected Serum 2?","0, No | 1, Yes",,,,,,,
|
104
|
+
serum3_3,month_3_data,,,dropdown,"Collected Serum 3?","0, No | 1, Yes",,,,,,,
|
105
|
+
sga_3,month_3_data,,,text,"Subject Global Assessment (score = 1-7)",,,number,0.9,7.1,,,
|
106
|
+
no_show_3,month_3_data,,,text,"Number of treatments missed",,,number,0,7,,,
|
107
|
+
compliance_3,month_3_data,,,dropdown,"How compliant was the patient in drinking the supplement?","0, 100 percent | 1, 99-75 percent | 2, 74-50 percent | 3, 49-25 percent | 4, 0-24 percent",,,,,,,
|
108
|
+
hospit_3,month_3_data,,"Hospitalization Data",dropdown,"Was patient hospitalized since last visit?","0, No | 1, Yes",,,,,,,
|
109
|
+
cause_hosp_3,month_3_data,,,dropdown,"What was the cause of hospitalization?","1, Vascular access related events | 2, CVD events | 3, Other",,,,,,,
|
110
|
+
admission_date_3,month_3_data,,,text,"Date of hospital admission",,,date,,,,,
|
111
|
+
discharge_date_3,month_3_data,,,text,"Date of hospital discharge",,,date,,,,,
|
112
|
+
discharge_summary_3,month_3_data,,,dropdown,"Discharge summary in patients binder?","0, No | 1, Yes",,,,,,,
|
113
|
+
death_3,month_3_data,,"Mortality Data",dropdown,"Has patient died since last visit?","0, No | 1, Yes",,,,,,,
|
114
|
+
date_death_3,month_3_data,,,text,"Date of death",,,date,,,,,
|
115
|
+
cause_death_3,month_3_data,,,dropdown,"What was the cause of death?","1, All-cause | 2, Cardiovascular",,,,,,,
|
116
|
+
complete_study,completion_data,,"Study Completion Information",dropdown,"Has patient completed study?","0, No | 1, Yes",,,,,,,
|
117
|
+
withdraw_date,completion_data,,,text,"Put a date if patient withdrew study",,,date,,,,,
|
118
|
+
withdraw_reason,completion_data,,,dropdown,"Reason patient withdrew from study","0, Non-compliance | 1, Did not wish to continue in study | 2, Could not tolerate the supplement | 3, Hospitalization | 4, Other",,,,,,,
|
119
|
+
complete_study_date,completion_data,,,text,"Date of study completion",,,date,,,,,
|
120
|
+
study_comments,completion_data,,"General Comments",notes,Comments,,,,,,,,
|
121
|
+
fatexp20_0d31d8,promis_fatigue__short_form_7a,,"Please respond to each item by marking one answer per question.<br><br>In the past 7 days...",radio,"How often did you feel tired?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
122
|
+
fatexp5_d80a4c,promis_fatigue__short_form_7a,,,radio,"How often did you experience extreme exhaustion?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
123
|
+
fatexp18_396fe5,promis_fatigue__short_form_7a,,,radio,"How often did you run out of energy?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
124
|
+
fatimp33_a9e236,promis_fatigue__short_form_7a,,,radio,"How often did your fatigue limit you at work (include work at home)?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
125
|
+
fatimp30_5f4d82,promis_fatigue__short_form_7a,,,radio,"How often were you too tired to think clearly?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
126
|
+
fatimp21_de19f3,promis_fatigue__short_form_7a,,,radio,"How often were you too tired to take a bath or shower?...","1, 1 Never | 2, 2 Rarely | 3, 3 Sometimes | 4, 4 Often | 5, 5 Always",,,,,,,
|
127
|
+
fatimp40_f7e5db,promis_fatigue__short_form_7a,,,radio,"How often did you have enough energy to exercise strenuously?...","5, 5 Never | 4, 4 Rarely | 3, 3 Sometimes | 2, 2 Often | 1, 1 Always",,,,,,,
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'fastercsv'
|
2
|
+
require 'active_support' # for humanize
|
3
|
+
module Surveyor
|
4
|
+
class RedcapParser
|
5
|
+
# Attributes
|
6
|
+
attr_accessor :context
|
7
|
+
|
8
|
+
# Class methods
|
9
|
+
def self.parse(str, filename)
|
10
|
+
puts
|
11
|
+
Surveyor::RedcapParser.new.parse(str, filename)
|
12
|
+
puts
|
13
|
+
puts
|
14
|
+
end
|
15
|
+
|
16
|
+
# Instance methods
|
17
|
+
def initialize
|
18
|
+
self.context = {}
|
19
|
+
end
|
20
|
+
def parse(str, filename)
|
21
|
+
begin
|
22
|
+
FasterCSV.parse(str, :headers => :first_row, :return_headers => true, :header_converters => :symbol) do |r|
|
23
|
+
if r.header_row? # header row
|
24
|
+
return puts "Missing headers: #{missing_columns(r).inspect}\n\n" unless missing_columns(r).blank?
|
25
|
+
context[:survey] = Survey.new(:title => filename)
|
26
|
+
print "survey_#{context[:survey].access_code} "
|
27
|
+
else # non-header rows
|
28
|
+
SurveySection.build_or_set(context, r)
|
29
|
+
Question.build_and_set(context, r)
|
30
|
+
Answer.build_and_set(context, r)
|
31
|
+
Validation.build_and_set(context, r)
|
32
|
+
Dependency.build_and_set(context, r)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
print context[:survey].save ? "saved. " : " not saved! #{context[:survey].errors.each_full{|x| x }.join(", ")} "
|
36
|
+
# print context[:survey].sections.map(&:questions).flatten.map(&:answers).flatten.map{|x| x.errors.each_full{|y| y}.join}.join
|
37
|
+
rescue FasterCSV::MalformedCSVError
|
38
|
+
puts = "Oops. Not a valid CSV file."
|
39
|
+
# ensure
|
40
|
+
end
|
41
|
+
end
|
42
|
+
def missing_columns(r)
|
43
|
+
required_columns - r.headers.map(&:to_s)
|
44
|
+
end
|
45
|
+
def required_columns
|
46
|
+
%w(variable__field_name form_name field_units section_header field_type field_label choices_or_calculations field_note text_validation_type text_validation_min text_validation_max identifier branching_logic_show_field_only_if required_field)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Surveyor models with extra parsing methods
|
52
|
+
class Survey < ActiveRecord::Base
|
53
|
+
include Surveyor::Models::SurveyMethods
|
54
|
+
end
|
55
|
+
class SurveySection < ActiveRecord::Base
|
56
|
+
include Surveyor::Models::SurveySectionMethods
|
57
|
+
def self.build_or_set(context, r)
|
58
|
+
unless context[:survey_section] && context[:survey_section].reference_identifier == r[:form_name]
|
59
|
+
if match = context[:survey].sections.detect{|ss| ss.reference_identifier == r[:form_name]}
|
60
|
+
context[:current_survey_section] = match
|
61
|
+
else
|
62
|
+
context[:survey_section] = context[:survey].sections.build({:title => r[:form_name].to_s.humanize, :reference_identifier => r[:form_name]})
|
63
|
+
print "survey_section_#{context[:survey_section].reference_identifier} "
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
class QuestionGroup < ActiveRecord::Base
|
69
|
+
include Surveyor::Models::QuestionGroupMethods
|
70
|
+
end
|
71
|
+
class Question < ActiveRecord::Base
|
72
|
+
include Surveyor::Models::QuestionMethods
|
73
|
+
def self.build_and_set(context, r)
|
74
|
+
if !r[:section_header].blank?
|
75
|
+
context[:survey_section].questions.build({:display_type => "label", :text => r[:section_header]})
|
76
|
+
print "label_ "
|
77
|
+
end
|
78
|
+
context[:question] = context[:survey_section].questions.build({
|
79
|
+
:reference_identifier => r[:variable__field_name],
|
80
|
+
:text => r[:field_label],
|
81
|
+
:help_text => r[:field_note],
|
82
|
+
:is_mandatory => (/^y/i.match r[:required_field]) ? true : false,
|
83
|
+
:pick => pick_from_field_type(r[:field_type]),
|
84
|
+
:display_type => display_type_from_field_type(r[:field_type])
|
85
|
+
})
|
86
|
+
print "question_#{context[:question].reference_identifier} "
|
87
|
+
end
|
88
|
+
def self.pick_from_field_type(ft)
|
89
|
+
{"checkbox" => :any, "radio" => :one}[ft] || :none
|
90
|
+
end
|
91
|
+
def self.display_type_from_field_type(ft)
|
92
|
+
{"text" => :string, "dropdown" => :dropdown, "notes" => :text}[ft]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
class Dependency < ActiveRecord::Base
|
96
|
+
include Surveyor::Models::DependencyMethods
|
97
|
+
def self.build_and_set(context, r)
|
98
|
+
unless (bl = r[:branching_logic_show_field_only_if]).blank?
|
99
|
+
# TODO: forgot to tie rule key to component, counting on the sequence of components
|
100
|
+
letters = ('A'..'Z').to_a
|
101
|
+
hash = decompose_rule(bl)
|
102
|
+
context[:dependency] = context[:question].build_dependency(:rule => hash[:rule])
|
103
|
+
hash[:components].each do |component|
|
104
|
+
context[:dependency].dependency_conditions.build(decompose_component(component).merge(:lookup_reference => context[:lookup], :rule_key => letters.shift))
|
105
|
+
end
|
106
|
+
print "dependency(#{hash[:rule]}) "
|
107
|
+
end
|
108
|
+
end
|
109
|
+
def self.decompose_component(str)
|
110
|
+
# [initial_52] = "1"
|
111
|
+
if match = str.match(/^\[(\w+)\] ?([!=><]+) ?"(\w+)"$/)
|
112
|
+
{:question_reference => match[1], :operator => match[2].gsub(/^=$/, "=="), :answer_reference => match[3]}
|
113
|
+
# [initial_119(2)] = "1"
|
114
|
+
elsif match = str.match(/^\[(\w+)\((\w+)\)\] ?([!=><]+) ?"1"$/)
|
115
|
+
{:question_reference => match[1], :operator => match[3].gsub(/^=$/, "=="), :answer_reference => match[2]}
|
116
|
+
# [f1_q15] >= 21
|
117
|
+
elsif match = str.match(/^\[(\w+)\] ?([!=><]+) ?(\d+)$/)
|
118
|
+
{:question_reference => match[1], :operator => match[2].gsub(/^=$/, "=="), :integer_value => match[3]}
|
119
|
+
# uhoh
|
120
|
+
else
|
121
|
+
puts "\n!!! skipping dependency_condition #{str}"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
def self.decompose_rule(str)
|
125
|
+
# see spec/lib/redcap_parser_spec.rb for examples
|
126
|
+
letters = ('A'..'Z').to_a
|
127
|
+
rule = str
|
128
|
+
components = str.split(/\band\b|\bor\b|\((?!\d)|\)(?!\(|\])/).reject(&:blank?).map(&:strip)
|
129
|
+
components.each_with_index do |part, i|
|
130
|
+
# internal commas on the right side of the operator e.g. '[initial_189] = "1, 2, 3"'
|
131
|
+
if match = part.match(/^(\[[^\]]+\][^\"]+)"([0-9 ]+,[0-9 ,]+)"$/)
|
132
|
+
nums = match[2].split(",").map(&:strip)
|
133
|
+
components[i] = nums.map{|x| "#{match[1]}\"#{x}\""}
|
134
|
+
# sub in rule key
|
135
|
+
rule = rule.gsub(part, "(#{nums.map{letters.shift}.join(' and ')})")
|
136
|
+
# multiple internal parenthesis on the left e.g. '[initial_119(1)(2)(3)(4)(6)] = "1"'
|
137
|
+
elsif match = part.match(/^\[(\w+)(\(\d+\)\([\d\(\)]+)\]([^\"]+"\d+")$/)
|
138
|
+
nums = match[2].split(/\(|\)/).reject(&:blank?).map(&:strip)
|
139
|
+
components[i] = nums.map{|x| "[#{match[1]}(#{x})]#{match[3]}"}
|
140
|
+
# sub in rule key
|
141
|
+
rule = rule.gsub(part, "(#{nums.map{letters.shift}.join(' and ')})")
|
142
|
+
else
|
143
|
+
# 'or' on the right of the operator
|
144
|
+
components[i] = components[i-1].gsub(/"(\d+)"/, part) if part.match(/^"(\d+)"$/) && i != 0
|
145
|
+
# sub in rule key
|
146
|
+
rule = rule.gsub(part){letters.shift}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
{:rule => rule, :components => components.flatten}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
class DependencyCondition < ActiveRecord::Base
|
153
|
+
include Surveyor::Models::DependencyConditionMethods
|
154
|
+
attr_accessor :question_reference, :answer_reference, :lookup_reference
|
155
|
+
before_save :resolve_references
|
156
|
+
def resolve_references
|
157
|
+
print "resolve(#{question_reference},#{answer_reference})"
|
158
|
+
if row = lookup_reference.find{|r| r[0] == question_reference and r[1] == answer_reference}
|
159
|
+
print "...found "
|
160
|
+
self.answer = row[2]
|
161
|
+
self.question = self.answer.question
|
162
|
+
else
|
163
|
+
puts "\n!!! failed lookup for dependency_condition q: #{question_reference} a: #{question_reference}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
class Answer < ActiveRecord::Base
|
168
|
+
include Surveyor::Models::AnswerMethods
|
169
|
+
def self.build_and_set(context, r)
|
170
|
+
r[:choices_or_calculations].to_s.split("|").each do |pair|
|
171
|
+
aref, atext = pair.strip.split(", ")
|
172
|
+
if aref.blank? or atext.blank?
|
173
|
+
puts "\n!!! skipping answer #{pair}"
|
174
|
+
else
|
175
|
+
context[:answer] = context[:question].answers.build(:reference_identifier => aref, :text => atext)
|
176
|
+
unless context[:question].reference_identifier.blank? or aref.blank? or !context[:answer].valid?
|
177
|
+
context[:lookup] ||= []
|
178
|
+
context[:lookup] << [context[:question].reference_identifier, aref, context[:answer]]
|
179
|
+
end
|
180
|
+
puts "#{context[:answer].errors.full_messages}, #{context[:answer].inspect}" unless context[:answer].valid?
|
181
|
+
print "answer_#{context[:answer].reference_identifier} "
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
class Validation < ActiveRecord::Base
|
187
|
+
include Surveyor::Models::ValidationMethods
|
188
|
+
def self.build_and_set(context, r)
|
189
|
+
# text_validation_type text_validation_min text_validation_max
|
190
|
+
min = r[:text_validation_min].to_s.blank? ? nil : r[:text_validation_min].to_s
|
191
|
+
max = r[:text_validation_max].to_s.blank? ? nil : r[:text_validation_max].to_s
|
192
|
+
type = r[:text_validation_type].to_s.blank? ? nil : r[:text_validation_type].to_s
|
193
|
+
if min or max
|
194
|
+
context[:question].answers.each do |a|
|
195
|
+
context[:validation] = a.validations.build(:rule => min ? max ? "A and B" : "A" : "B")
|
196
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => ">=", :integer_value => min) if min
|
197
|
+
context[:validation].validation_conditions.build(:rule_key => "B", :operator => "<=", :integer_value => max) if max
|
198
|
+
end
|
199
|
+
elsif type
|
200
|
+
# date email integer number phone
|
201
|
+
case r[:text_validation_type]
|
202
|
+
when "date"
|
203
|
+
context[:question].display_type = :date if context[:question].display_type == :string
|
204
|
+
when "email"
|
205
|
+
context[:question].answers.each do |a|
|
206
|
+
context[:validation] = a.validations.build(:rule => "A")
|
207
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp_value => "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$")
|
208
|
+
end
|
209
|
+
when "integer"
|
210
|
+
context[:question].display_type = :integer if context[:question].display_type == :string
|
211
|
+
context[:question].answers.each do |a|
|
212
|
+
context[:validation] = a.validations.build(:rule => "A")
|
213
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp_value => "\d+")
|
214
|
+
end
|
215
|
+
when "number"
|
216
|
+
context[:question].display_type = :float if context[:question].display_type == :string
|
217
|
+
context[:question].answers.each do |a|
|
218
|
+
context[:validation] = a.validations.build(:rule => "A")
|
219
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp_value => "^\d*(,\d{3})*(\.\d*)?$")
|
220
|
+
end
|
221
|
+
when "phone"
|
222
|
+
context[:question].answers.each do |a|
|
223
|
+
context[:validation] = a.validations.build(:rule => "A")
|
224
|
+
context[:validation].validation_conditions.build(:rule_key => "A", :operator => "=~", :regexp_value => "\d{3}.*\d{4}")
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
class ValidationCondition < ActiveRecord::Base
|
232
|
+
include Surveyor::Models::ValidationConditionMethods
|
233
|
+
end
|
@@ -10,6 +10,15 @@ namespace :surveyor do
|
|
10
10
|
Surveyor::Parser.parse File.read(file)
|
11
11
|
puts "--- Done #{file} ---"
|
12
12
|
end
|
13
|
+
desc "generate and load survey from REDCap Data Dictionary (specify FILE=surveys/redcap.csv)"
|
14
|
+
task :redcap => :environment do
|
15
|
+
raise "USAGE: file name required e.g. 'FILE=surveys/redcap_demo_survey.csv'" if ENV["FILE"].blank?
|
16
|
+
file = File.join(RAILS_ROOT, ENV["FILE"])
|
17
|
+
raise "File does not exist: #{file}" unless FileTest.exists?(file)
|
18
|
+
puts "--- Parsing #{file} ---"
|
19
|
+
Surveyor::RedcapParser.parse File.read(file), File.basename(file, ".csv")
|
20
|
+
puts "--- Done #{file} ---"
|
21
|
+
end
|
13
22
|
desc "generate a surveyor DSL file from a survey"
|
14
23
|
task :unparse => :environment do
|
15
24
|
surveys = Survey.all
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Surveyor::RedcapParser do
|
4
|
+
before(:each) do
|
5
|
+
# @parser = Surveyor::Parser.new
|
6
|
+
end
|
7
|
+
it "should decompose dependency rules" do
|
8
|
+
# basic
|
9
|
+
Dependency.decompose_rule('[f1_q12]="1"').should == {:rule => "A", :components => ['[f1_q12]="1"']}
|
10
|
+
# spacing
|
11
|
+
Dependency.decompose_rule('[f1_q9] = "1"').should == {:rule => "A", :components => ['[f1_q9] = "1"']}
|
12
|
+
# and
|
13
|
+
Dependency.decompose_rule('[pre_q88]="1" and [pre_q90]="1"').should == {:rule => "A and B", :components => ['[pre_q88]="1"', '[pre_q90]="1"']}
|
14
|
+
# or
|
15
|
+
Dependency.decompose_rule('[second_q111]="1" or [second_q111]="3"').should == {:rule => "A or B", :components => ['[second_q111]="1"', '[second_q111]="3"']}
|
16
|
+
# or and
|
17
|
+
Dependency.decompose_rule('[second_q100]="1" or [second_q100]="3" and [second_q101]="1"').should == {:rule => "A or B and C", :components => ['[second_q100]="1"', '[second_q100]="3"', '[second_q101]="1"']}
|
18
|
+
# and or
|
19
|
+
Dependency.decompose_rule('[second_q4]="1" and [second_q11]="1" or [second_q11]="98"').should == {:rule => "A and B or C", :components => ['[second_q4]="1"', '[second_q11]="1"', '[second_q11]="98"']}
|
20
|
+
# or or or
|
21
|
+
Dependency.decompose_rule('[pre_q74]="1" or [pre_q74]="2" or [pre_q74]="4" or [pre_q74]="5"').should == {:rule => "A or B or C or D", :components => ['[pre_q74]="1"', '[pre_q74]="2"', '[pre_q74]="4"', '[pre_q74]="5"']}
|
22
|
+
# and with different operator
|
23
|
+
Dependency.decompose_rule('[f1_q15] >= 21 and [f1_q28] ="1"').should == {:rule => "A and B", :components => ['[f1_q15] >= 21', '[f1_q28] ="1"']}
|
24
|
+
end
|
25
|
+
it "should decompose nested dependency rules" do
|
26
|
+
# external parenthesis
|
27
|
+
Dependency.decompose_rule('([pre_q74]="1" or [pre_q74]="2" or [pre_q74]="4" or [pre_q74]="5") and [pre_q76]="2"').should == {:rule => "(A or B or C or D) and E", :components => ['[pre_q74]="1"', '[pre_q74]="2"', '[pre_q74]="4"', '[pre_q74]="5"', '[pre_q76]="2"']}
|
28
|
+
# internal parenthesis
|
29
|
+
Dependency.decompose_rule('[f1_q10(4)]="1"').should == {:rule => "A", :components => ['[f1_q10(4)]="1"']}
|
30
|
+
# internal and external parenthesis
|
31
|
+
Dependency.decompose_rule('([f1_q7(11)] = "1" or [initial_52] = "1") and [pre_q76]="2"').should == {:rule => "(A or B) and C", :components => ['[f1_q7(11)] = "1"', '[initial_52] = "1"', '[pre_q76]="2"']}
|
32
|
+
end
|
33
|
+
it "should decompose shortcut dependency rules" do
|
34
|
+
# 'or' on the right of the operator
|
35
|
+
Dependency.decompose_rule('[initial_108] = "1" or "2"').should == {:rule => "A or B", :components => ['[initial_108] = "1"', '[initial_108] = "2"']}
|
36
|
+
# multiple 'or' on the right
|
37
|
+
Dependency.decompose_rule('[initial_52] = "1" or "2" or "3"').should == {:rule => "A or B or C", :components => ['[initial_52] = "1"', '[initial_52] = "2"', '[initial_52] = "3"']}
|
38
|
+
# commas on the right
|
39
|
+
Dependency.decompose_rule('[initial_189] = "1, 2, 3"').should == {:rule => "(A and B and C)", :components => ['[initial_189] = "1"', '[initial_189] = "2"', '[initial_189] = "3"']}
|
40
|
+
# multiple internal parenthesis on the left
|
41
|
+
Dependency.decompose_rule('[initial_119(1)(2)(3)(4)(5)] = "1"').should == {:rule => "(A and B and C and D and E)", :components => ['[initial_119(1)] = "1"', '[initial_119(2)] = "1"', '[initial_119(3)] = "1"', '[initial_119(4)] = "1"', '[initial_119(5)] = "1"']}
|
42
|
+
end
|
43
|
+
it "should decompose components" do
|
44
|
+
Dependency.decompose_component('[initial_52] = "1"').should == {:question_reference => 'initial_52', :operator => '==', :answer_reference => '1'}
|
45
|
+
Dependency.decompose_component('[initial_119(2)] = "1"').should == {:question_reference => 'initial_119', :operator => '==', :answer_reference => '2'}
|
46
|
+
Dependency.decompose_component('[f1_q15] >= 21').should == {:question_reference => 'f1_q15', :operator => '>=', :integer_value => '21'}
|
47
|
+
end
|
48
|
+
end
|
data/surveyor.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{surveyor}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.18.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Brian Chamberlain", "Mark Yoon"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-01}
|
13
13
|
s.email = %q{yoon@northwestern.edu}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.files = [
|
18
18
|
".gitignore",
|
19
19
|
".rvmrc",
|
20
|
+
"CHANGELOG",
|
20
21
|
"Gemfile",
|
21
22
|
"Gemfile.lock",
|
22
23
|
"MIT-LICENSE",
|
@@ -52,8 +53,10 @@ Gem::Specification.new do |s|
|
|
52
53
|
"app/views/surveyor/new.html.haml",
|
53
54
|
"app/views/surveyor/show.html.haml",
|
54
55
|
"config/routes.rb",
|
56
|
+
"features/redcap.feature",
|
55
57
|
"features/step_definitions/surveyor_steps.rb",
|
56
58
|
"features/step_definitions/web_steps.rb",
|
59
|
+
"features/support/REDCapDemoDatabase_DataDictionary.csv",
|
57
60
|
"features/support/env.rb",
|
58
61
|
"features/support/paths.rb",
|
59
62
|
"features/surveyor.feature",
|
@@ -137,9 +140,6 @@ Gem::Specification.new do |s|
|
|
137
140
|
"generators/surveyor/templates/migrate/create_validations.rb",
|
138
141
|
"generators/surveyor/templates/surveys/kitchen_sink_survey.rb",
|
139
142
|
"generators/surveyor/templates/tasks/surveyor.rb",
|
140
|
-
"generators/test_surveyor/templates/TESTING_SURVEYOR",
|
141
|
-
"generators/test_surveyor/templates/environments/cucumber.rb",
|
142
|
-
"generators/test_surveyor/test_surveyor_generator.rb",
|
143
143
|
"init.rb",
|
144
144
|
"install.rb",
|
145
145
|
"lib/surveyor.rb",
|
@@ -157,6 +157,7 @@ Gem::Specification.new do |s|
|
|
157
157
|
"lib/surveyor/models/validation_condition_methods.rb",
|
158
158
|
"lib/surveyor/models/validation_methods.rb",
|
159
159
|
"lib/surveyor/parser.rb",
|
160
|
+
"lib/surveyor/redcap_parser.rb",
|
160
161
|
"lib/surveyor/surveyor_controller_methods.rb",
|
161
162
|
"lib/surveyor/unparser.rb",
|
162
163
|
"lib/tasks/surveyor_tasks.rake",
|
@@ -165,6 +166,7 @@ Gem::Specification.new do |s|
|
|
165
166
|
"spec/factories.rb",
|
166
167
|
"spec/lib/common_spec.rb",
|
167
168
|
"spec/lib/parser_spec.rb",
|
169
|
+
"spec/lib/redcap_parser_spec.rb",
|
168
170
|
"spec/lib/unparser_spec.rb",
|
169
171
|
"spec/models/answer_spec.rb",
|
170
172
|
"spec/models/dependency_condition_spec.rb",
|
@@ -197,6 +199,7 @@ Gem::Specification.new do |s|
|
|
197
199
|
"spec/factories.rb",
|
198
200
|
"spec/lib/common_spec.rb",
|
199
201
|
"spec/lib/parser_spec.rb",
|
202
|
+
"spec/lib/redcap_parser_spec.rb",
|
200
203
|
"spec/lib/unparser_spec.rb",
|
201
204
|
"spec/models/answer_spec.rb",
|
202
205
|
"spec/models/dependency_condition_spec.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surveyor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 87
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 18
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.18.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brian Chamberlain
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-12-01 00:00:00 -06:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -58,6 +58,7 @@ extra_rdoc_files:
|
|
58
58
|
files:
|
59
59
|
- .gitignore
|
60
60
|
- .rvmrc
|
61
|
+
- CHANGELOG
|
61
62
|
- Gemfile
|
62
63
|
- Gemfile.lock
|
63
64
|
- MIT-LICENSE
|
@@ -93,8 +94,10 @@ files:
|
|
93
94
|
- app/views/surveyor/new.html.haml
|
94
95
|
- app/views/surveyor/show.html.haml
|
95
96
|
- config/routes.rb
|
97
|
+
- features/redcap.feature
|
96
98
|
- features/step_definitions/surveyor_steps.rb
|
97
99
|
- features/step_definitions/web_steps.rb
|
100
|
+
- features/support/REDCapDemoDatabase_DataDictionary.csv
|
98
101
|
- features/support/env.rb
|
99
102
|
- features/support/paths.rb
|
100
103
|
- features/surveyor.feature
|
@@ -178,9 +181,6 @@ files:
|
|
178
181
|
- generators/surveyor/templates/migrate/create_validations.rb
|
179
182
|
- generators/surveyor/templates/surveys/kitchen_sink_survey.rb
|
180
183
|
- generators/surveyor/templates/tasks/surveyor.rb
|
181
|
-
- generators/test_surveyor/templates/TESTING_SURVEYOR
|
182
|
-
- generators/test_surveyor/templates/environments/cucumber.rb
|
183
|
-
- generators/test_surveyor/test_surveyor_generator.rb
|
184
184
|
- init.rb
|
185
185
|
- install.rb
|
186
186
|
- lib/surveyor.rb
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- lib/surveyor/models/validation_condition_methods.rb
|
199
199
|
- lib/surveyor/models/validation_methods.rb
|
200
200
|
- lib/surveyor/parser.rb
|
201
|
+
- lib/surveyor/redcap_parser.rb
|
201
202
|
- lib/surveyor/surveyor_controller_methods.rb
|
202
203
|
- lib/surveyor/unparser.rb
|
203
204
|
- lib/tasks/surveyor_tasks.rake
|
@@ -206,6 +207,7 @@ files:
|
|
206
207
|
- spec/factories.rb
|
207
208
|
- spec/lib/common_spec.rb
|
208
209
|
- spec/lib/parser_spec.rb
|
210
|
+
- spec/lib/redcap_parser_spec.rb
|
209
211
|
- spec/lib/unparser_spec.rb
|
210
212
|
- spec/models/answer_spec.rb
|
211
213
|
- spec/models/dependency_condition_spec.rb
|
@@ -309,6 +311,7 @@ test_files:
|
|
309
311
|
- spec/factories.rb
|
310
312
|
- spec/lib/common_spec.rb
|
311
313
|
- spec/lib/parser_spec.rb
|
314
|
+
- spec/lib/redcap_parser_spec.rb
|
312
315
|
- spec/lib/unparser_spec.rb
|
313
316
|
- spec/models/answer_spec.rb
|
314
317
|
- spec/models/dependency_condition_spec.rb
|
File without changes
|
@@ -1,21 +0,0 @@
|
|
1
|
-
config.cache_classes = true # This must be true for Cucumber to operate correctly!
|
2
|
-
|
3
|
-
# Log error messages when you accidentally call methods on nil.
|
4
|
-
config.whiny_nils = true
|
5
|
-
|
6
|
-
# Show full error reports and disable caching
|
7
|
-
config.action_controller.consider_all_requests_local = true
|
8
|
-
config.action_controller.perform_caching = false
|
9
|
-
|
10
|
-
# Disable request forgery protection in test environment
|
11
|
-
config.action_controller.allow_forgery_protection = false
|
12
|
-
|
13
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
14
|
-
# The :test delivery method accumulates sent emails in the
|
15
|
-
# ActionMailer::Base.deliveries array.
|
16
|
-
config.action_mailer.delivery_method = :test
|
17
|
-
|
18
|
-
config.gem "cucumber", :lib => false, :version => ">=0.3.11" unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber'))
|
19
|
-
config.gem "webrat", :lib => false, :version => ">=0.4.4" unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
|
20
|
-
config.gem "rspec", :lib => false, :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
|
21
|
-
config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
|
@@ -1,15 +0,0 @@
|
|
1
|
-
class TestSurveyorGenerator < Rails::Generator::Base
|
2
|
-
def manifest
|
3
|
-
record do |m|
|
4
|
-
|
5
|
-
m.directory "surveys"
|
6
|
-
|
7
|
-
# Copy README to your app
|
8
|
-
m.file "TESTING_SURVEYOR", "surveys/TESTING_SURVEYOR"
|
9
|
-
|
10
|
-
m.file "environments/cucumber.rb", "config/environments/cucumber.rb"
|
11
|
-
m.readme "TESTING_SURVEYOR"
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|