ncs_mdes 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +9 -0
- data/Rakefile +33 -0
- data/ci-exec.sh +3 -3
- data/documents/2.0/heuristic_overrides.yml +3 -1
- data/lib/ncs_navigator/mdes/transmission_table.rb +61 -0
- data/lib/ncs_navigator/mdes/version.rb +1 -1
- data/ncs_mdes.gemspec +1 -1
- data/spec/ncs_navigator/mdes/specification_spec.rb +6 -0
- data/spec/ncs_navigator/mdes/transmission_table_spec.rb +94 -0
- metadata +100 -66
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
NCS Navigator MDES Module history
|
2
2
|
=================================
|
3
3
|
|
4
|
+
0.5.0
|
5
|
+
-----
|
6
|
+
|
7
|
+
- Add `instrument_table?` and `operational_table?` to heuristically
|
8
|
+
flag tables as one or the other.
|
9
|
+
- Fix reference definition for `spec_blood.equip_id`. According to the
|
10
|
+
corresponding instrument, it is not a reference to `spec_equipment`,
|
11
|
+
but rather a manually-filled field.
|
12
|
+
|
4
13
|
0.4.2
|
5
14
|
-----
|
6
15
|
|
data/Rakefile
CHANGED
@@ -13,3 +13,36 @@ namespace :ci do
|
|
13
13
|
desc "Run specs for CI"
|
14
14
|
task :spec => ['ci:setup:rspec', 'rake:spec']
|
15
15
|
end
|
16
|
+
|
17
|
+
task :library do
|
18
|
+
$LOAD_PATH << File.expand_path('../lib', __FILE__)
|
19
|
+
require 'ncs_navigator/mdes'
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Generate a dot-formatted graph of the FK relationships in an MDE spec'
|
23
|
+
task :fk_dot => :library do
|
24
|
+
fail 'Please specify the MDES version with MDES="X.Y"' unless ENV['MDES']
|
25
|
+
spec = NcsNavigator::Mdes(ENV['MDES'])
|
26
|
+
|
27
|
+
filename = "foreign_keys-MDES_#{spec.specification_version}.dot"
|
28
|
+
$stdout.write "Writing DOT graph to #{filename}..."
|
29
|
+
|
30
|
+
File.open(filename, 'w') do |f|
|
31
|
+
f.puts "digraph mdes_fks {"
|
32
|
+
spec.transmission_tables.each do |t1|
|
33
|
+
shape = if t1.primary_instrument_table?
|
34
|
+
'diamond'
|
35
|
+
elsif t1.instrument_table?
|
36
|
+
'rect'
|
37
|
+
else
|
38
|
+
'oval'
|
39
|
+
end
|
40
|
+
f.puts " #{t1.name} [shape=#{shape}];"
|
41
|
+
t1.variables.collect(&:table_reference).compact.each do |t2|
|
42
|
+
f.puts " #{t1.name} -> #{t2.name};"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
f.puts "}"
|
46
|
+
end
|
47
|
+
$stdout.puts "done."
|
48
|
+
end
|
data/ci-exec.sh
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/bin/bash -xe
|
2
2
|
|
3
|
-
BUNDLER_VERSION=1.
|
3
|
+
BUNDLER_VERSION=1.1.rc
|
4
4
|
GEMSET=ncs_mdes
|
5
5
|
|
6
6
|
if [ -z $CI_RUBY ]; then
|
@@ -38,6 +38,6 @@ if [ $? -ne 0 ]; then
|
|
38
38
|
fi
|
39
39
|
set -e
|
40
40
|
|
41
|
-
bundle update
|
41
|
+
bundle _${BUNDLER_VERSION}_ update
|
42
42
|
|
43
|
-
bundle exec rake ci:spec --trace
|
43
|
+
bundle _${BUNDLER_VERSION}_ exec rake ci:spec --trace
|
@@ -338,7 +338,9 @@ foreign_keys:
|
|
338
338
|
six_mth_saq_id: six_mth_saq_2
|
339
339
|
|
340
340
|
spec_blood:
|
341
|
-
equip_id
|
341
|
+
# According to the corresponding instrument, equip_id is manually entered and
|
342
|
+
# not a reference to another table.
|
343
|
+
equip_id: false
|
342
344
|
|
343
345
|
spec_receipt:
|
344
346
|
# Insufficient info to determine what this is supposed to link to
|
@@ -49,5 +49,66 @@ module NcsNavigator::Mdes
|
|
49
49
|
def inspect
|
50
50
|
"\#<#{self.class} name=#{name.inspect}>"
|
51
51
|
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Is this a primary instrument table (i.e., is this the table for
|
55
|
+
# an instrument that stores all single-valued responses for one
|
56
|
+
# execution of that instrument and to which all other instrument
|
57
|
+
# tables for that instrument refer [directly or indirectly])?
|
58
|
+
#
|
59
|
+
# @return [true,false]
|
60
|
+
def primary_instrument_table?
|
61
|
+
self.name != 'instrument' && variables.any? { |v| v.name == 'instrument_version' }
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Is this an instrument table (i.e., a table for storing results
|
66
|
+
# from an instrument)? Every table is either an instrument table
|
67
|
+
# or an operational table (never both).
|
68
|
+
#
|
69
|
+
# This is not explicitly derivable from the MDES, so this method
|
70
|
+
# (and the related methods {#operational_table?} and
|
71
|
+
# {#primary_instrument_table?}) use this heuristic:
|
72
|
+
#
|
73
|
+
# * If this table contains a variable named `instrument_version`
|
74
|
+
# and is not the `instrument` table itself, it is a primary
|
75
|
+
# instrument table (and so is an instrument table).
|
76
|
+
# * If this table is not a primary instrument table, but one of
|
77
|
+
# its {#variables} {Variable#table_reference references} a table
|
78
|
+
# that is a primary instrument table, then this is an instrument
|
79
|
+
# table.
|
80
|
+
# * Similarly, if one of this table's variables references a table
|
81
|
+
# which is an instrument table according to the second
|
82
|
+
# definition, then this table is an instrument table as
|
83
|
+
# well. This continues for any depth of reference.
|
84
|
+
#
|
85
|
+
# If none of these conditions are met, then this table is an
|
86
|
+
# operational table.
|
87
|
+
#
|
88
|
+
# @return [true,false]
|
89
|
+
def instrument_table?
|
90
|
+
instrument_table_predicate_with_stack([])
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# @private # exposed for recursion in siblings
|
95
|
+
def instrument_table_predicate_with_stack(stack)
|
96
|
+
return false if stack.include?(self)
|
97
|
+
primary_instrument_table? || variables.any? { |v|
|
98
|
+
v.table_reference && v.table_reference.instrument_table_predicate_with_stack(stack + [self])
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Is this an operational table (i.e., a table for storing
|
104
|
+
# operational data about a participant, household, staff member,
|
105
|
+
# or other study management concept)? Every table is either an
|
106
|
+
# operational table or an instrument table (never both).
|
107
|
+
#
|
108
|
+
# @see #instrument_table?
|
109
|
+
# @return [true,false]
|
110
|
+
def operational_table?
|
111
|
+
!instrument_table?
|
112
|
+
end
|
52
113
|
end
|
53
114
|
end
|
data/ncs_mdes.gemspec
CHANGED
@@ -21,7 +21,7 @@ National Children's Study's Master Data Element Specification.
|
|
21
21
|
|
22
22
|
s.add_dependency 'nokogiri', '~> 1.4'
|
23
23
|
|
24
|
-
s.add_development_dependency 'rspec', '~> 2.6'
|
24
|
+
s.add_development_dependency 'rspec', '~> 2.6.0' # Can't use 2.7.0 due to #477
|
25
25
|
s.add_development_dependency 'rake', '~> 0.9.2'
|
26
26
|
s.add_development_dependency 'yard', '~> 0.7.2'
|
27
27
|
s.add_development_dependency 'ci_reporter', '~> 1.6'
|
@@ -41,6 +41,12 @@ module NcsNavigator::Mdes
|
|
41
41
|
table.variables.collect { |v| v.type }.select { |t| t.reference? }
|
42
42
|
}.flatten.collect { |t| t.name }.select { |n| n =~ /^ncs:/ }.should == []
|
43
43
|
end
|
44
|
+
|
45
|
+
it 'can determine if each table is instrument or operational' do
|
46
|
+
tables.each do |table|
|
47
|
+
lambda { table.instrument_table? }.should_not raise_error
|
48
|
+
end
|
49
|
+
end
|
44
50
|
end
|
45
51
|
|
46
52
|
context 'in version 1.2' do
|
@@ -85,5 +85,99 @@ XSD
|
|
85
85
|
subject['quux'].should be_nil
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
describe 'instrument table detection' do
|
90
|
+
def table_with_variables(table_name, *variables)
|
91
|
+
TransmissionTable.new(table_name).tap { |t|
|
92
|
+
t.variables = variables.collect { |vn| Variable.new(vn) }
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
let(:event) { table_with_variables('event', 'event_id') }
|
97
|
+
let(:instrument) { table_with_variables('instrument', 'instrument_id', 'instrument_version') }
|
98
|
+
|
99
|
+
let(:spec_blood) {
|
100
|
+
table_with_variables('spec_blood', 'spec_blood_id',
|
101
|
+
'instrument_id', 'instrument_type', 'instrument_version')
|
102
|
+
}
|
103
|
+
let(:spec_blood_tube) {
|
104
|
+
table_with_variables('spec_blood_tube', 'spec_blood_tube_id', 'spec_blood_id').tap do |t|
|
105
|
+
t.variables.detect { |v| v.name == 'spec_blood_id' }.table_reference = spec_blood
|
106
|
+
end
|
107
|
+
}
|
108
|
+
let(:spec_blood_tube_comments) {
|
109
|
+
table_with_variables(
|
110
|
+
'spec_blood_tube_comments',
|
111
|
+
'spec_blood_tube_comments_id', 'spec_blood_tube_id'
|
112
|
+
).tap do |t|
|
113
|
+
t.variables.detect { |v| v.name == 'spec_blood_tube_id' }.
|
114
|
+
table_reference = spec_blood_tube
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
describe '#instrument_table?' do
|
119
|
+
it 'does not consider tables without instrument_version to be instrument tables' do
|
120
|
+
event.should_not be_instrument_table
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'does not consider the instrument operational table to be an instrument table' do
|
124
|
+
instrument.should_not be_instrument_table
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'considers primary instrument tables to be instrument tables' do
|
128
|
+
spec_blood.should be_instrument_table
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'considers secondary instrument tables to be instrument tables' do
|
132
|
+
spec_blood_tube.should be_instrument_table
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'considers tertiary instrument tables to be instrument tables' do
|
136
|
+
spec_blood_tube_comments.should be_instrument_table
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'does not consider circularly referring tables to be instrument tables' do
|
140
|
+
person = table_with_variables('person', 'new_address_id')
|
141
|
+
address = table_with_variables('address', 'person_id')
|
142
|
+
address.variables.first.table_reference = person
|
143
|
+
person.variables.first.table_reference = address
|
144
|
+
|
145
|
+
address.should_not be_instrument_table
|
146
|
+
person.should_not be_instrument_table
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#primary_instrument_table?' do
|
151
|
+
it 'does not consider tables without instrument_version to be a primary instrument table' do
|
152
|
+
event.should_not be_primary_instrument_table
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'does not consider the instrument operational table to be a primary instrument table' do
|
156
|
+
instrument.should_not be_primary_instrument_table
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'considers primary instrument tables to be primary instrument tables' do
|
160
|
+
spec_blood.should be_primary_instrument_table
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'does not consider secondary instrument tables to be primary instrument tables' do
|
164
|
+
spec_blood_tube.should_not be_primary_instrument_table
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'does not consider tertiary instrument tables to be primary instrument tables' do
|
168
|
+
spec_blood_tube_comments.should_not be_primary_instrument_table
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#operational_table?' do
|
173
|
+
it 'is the opposite of instrument_table?' do
|
174
|
+
[
|
175
|
+
event, instrument, spec_blood, spec_blood_tube, spec_blood_tube_comments
|
176
|
+
].each do |table|
|
177
|
+
table.instrument_table?.should == !table.operational_table?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
88
182
|
end
|
89
183
|
end
|
metadata
CHANGED
@@ -1,85 +1,115 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ncs_mdes
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 11
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Rhett Sutphin
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2011-11-29 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
15
22
|
name: nokogiri
|
16
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
25
|
none: false
|
18
|
-
requirements:
|
26
|
+
requirements:
|
19
27
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 4
|
33
|
+
version: "1.4"
|
22
34
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
26
37
|
name: rspec
|
27
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
40
|
none: false
|
29
|
-
requirements:
|
41
|
+
requirements:
|
30
42
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 23
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 6
|
48
|
+
- 0
|
49
|
+
version: 2.6.0
|
33
50
|
type: :development
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
37
53
|
name: rake
|
38
|
-
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
56
|
none: false
|
40
|
-
requirements:
|
57
|
+
requirements:
|
41
58
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 63
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
- 9
|
64
|
+
- 2
|
43
65
|
version: 0.9.2
|
44
66
|
type: :development
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
48
69
|
name: yard
|
49
|
-
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
72
|
none: false
|
51
|
-
requirements:
|
73
|
+
requirements:
|
52
74
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 7
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
- 7
|
80
|
+
- 2
|
54
81
|
version: 0.7.2
|
55
82
|
type: :development
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
59
85
|
name: ci_reporter
|
60
|
-
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
88
|
none: false
|
62
|
-
requirements:
|
89
|
+
requirements:
|
63
90
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 1
|
95
|
+
- 6
|
96
|
+
version: "1.6"
|
66
97
|
type: :development
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
98
|
+
version_requirements: *id005
|
99
|
+
description: |
|
100
|
+
|
71
101
|
Provides a consistent ruby interface to the project metainformation in the
|
102
|
+
National Children's Study's Master Data Element Specification.
|
72
103
|
|
73
|
-
|
74
|
-
|
75
|
-
'
|
76
|
-
email:
|
104
|
+
email:
|
77
105
|
- r-sutphin@northwestern.edu
|
78
|
-
executables:
|
106
|
+
executables:
|
79
107
|
- mdes-console
|
80
108
|
extensions: []
|
109
|
+
|
81
110
|
extra_rdoc_files: []
|
82
|
-
|
111
|
+
|
112
|
+
files:
|
83
113
|
- .gitignore
|
84
114
|
- .rvmrc
|
85
115
|
- .yardopts
|
@@ -111,37 +141,41 @@ files:
|
|
111
141
|
- spec/ncs_navigator/mdes/version_spec.rb
|
112
142
|
- spec/ncs_navigator/mdes_spec.rb
|
113
143
|
- spec/spec_helper.rb
|
114
|
-
|
144
|
+
has_rdoc: true
|
145
|
+
homepage: ""
|
115
146
|
licenses: []
|
147
|
+
|
116
148
|
post_install_message:
|
117
149
|
rdoc_options: []
|
118
|
-
|
150
|
+
|
151
|
+
require_paths:
|
119
152
|
- lib
|
120
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
154
|
none: false
|
122
|
-
requirements:
|
123
|
-
- -
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
|
126
|
-
segments:
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
hash: 3
|
159
|
+
segments:
|
127
160
|
- 0
|
128
|
-
|
129
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
version: "0"
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
163
|
none: false
|
131
|
-
requirements:
|
132
|
-
- -
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
|
135
|
-
segments:
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
hash: 3
|
168
|
+
segments:
|
136
169
|
- 0
|
137
|
-
|
170
|
+
version: "0"
|
138
171
|
requirements: []
|
172
|
+
|
139
173
|
rubyforge_project:
|
140
|
-
rubygems_version: 1.
|
174
|
+
rubygems_version: 1.3.7
|
141
175
|
signing_key:
|
142
176
|
specification_version: 3
|
143
177
|
summary: A ruby API for various versions of the NCS MDES.
|
144
|
-
test_files:
|
178
|
+
test_files:
|
145
179
|
- spec/ncs_navigator/mdes/source_documents_spec.rb
|
146
180
|
- spec/ncs_navigator/mdes/specification_spec.rb
|
147
181
|
- spec/ncs_navigator/mdes/transmission_table_spec.rb
|