ncs_mdes 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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