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 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.0.18
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: spec_equipment
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
@@ -1,5 +1,5 @@
1
1
  module NcsNavigator
2
2
  module Mdes
3
- VERSION = "0.4.2"
3
+ VERSION = '0.5.0'
4
4
  end
5
5
  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
- version: 0.4.2
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
- date: 2011-09-09 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
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
- requirement: &2152825220 !ruby/object:Gem::Requirement
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
- version: '1.4'
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 1
32
+ - 4
33
+ version: "1.4"
22
34
  type: :runtime
23
- prerelease: false
24
- version_requirements: *2152825220
25
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
26
37
  name: rspec
27
- requirement: &2152824560 !ruby/object:Gem::Requirement
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
- version: '2.6'
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
- prerelease: false
35
- version_requirements: *2152824560
36
- - !ruby/object:Gem::Dependency
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
37
53
  name: rake
38
- requirement: &2152823680 !ruby/object:Gem::Requirement
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
- prerelease: false
46
- version_requirements: *2152823680
47
- - !ruby/object:Gem::Dependency
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
48
69
  name: yard
49
- requirement: &2152822920 !ruby/object:Gem::Requirement
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
- prerelease: false
57
- version_requirements: *2152822920
58
- - !ruby/object:Gem::Dependency
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
59
85
  name: ci_reporter
60
- requirement: &2152822260 !ruby/object:Gem::Requirement
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
- version: '1.6'
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 1
95
+ - 6
96
+ version: "1.6"
66
97
  type: :development
67
- prerelease: false
68
- version_requirements: *2152822260
69
- description: ! '
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
- National Children''s Study''s Master Data Element Specification.
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
- files:
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
- homepage: ''
144
+ has_rdoc: true
145
+ homepage: ""
115
146
  licenses: []
147
+
116
148
  post_install_message:
117
149
  rdoc_options: []
118
- require_paths:
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
- version: '0'
126
- segments:
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ hash: 3
159
+ segments:
127
160
  - 0
128
- hash: 1899662951154371602
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
- version: '0'
135
- segments:
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ hash: 3
168
+ segments:
136
169
  - 0
137
- hash: 1899662951154371602
170
+ version: "0"
138
171
  requirements: []
172
+
139
173
  rubyforge_project:
140
- rubygems_version: 1.8.6
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