quality-measure-engine 0.1.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.
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "Result",
3
+ "properties": {
4
+ "initialPopulation": {
5
+ "type": "integer",
6
+ "description": "Individuals for whom the measure is intended."
7
+ },
8
+ "denominator": {
9
+ "type": "integer",
10
+ "description": "Individuals who should meet the measure. Sometimes equivalent to the initial population."
11
+ },
12
+ "numerator": {
13
+ "type": "array",
14
+ "description": "Individuals who do meet the measure.",
15
+ "items": {
16
+ "type": "integer"
17
+ }
18
+ },
19
+ "exclusions": {
20
+ "type": "array",
21
+ "description": "Individuals that should be in the denominator but have characteristics that make them inappropriate for the measure.",
22
+ "optional": true,
23
+ "items": {
24
+ "type": "integer"
25
+ }
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,143 @@
1
+ {"description":"This is the JSON Schema for JSON Schemas.",
2
+ "type":["object","array"],
3
+ "items":{
4
+ "type":"object",
5
+ "properties":{"$ref":"$.properties"},
6
+ "description":"When the schema is an array, it indicates that it is enforcing tuple typing. Each item in the instance array must correspond to the item in the schema array"},
7
+ "properties":{
8
+ "type":{
9
+ "type":["string","array"],
10
+ "items":{"$ref":"$.properties.type"},
11
+ "description":"This is a type definition value. This can be a simple type, or a union type",
12
+ "enum":["string","object","array","boolean","number","integer","null","any"],
13
+ "unconstrained":true,
14
+ "optional":true,
15
+ "default":"any"},
16
+ "optional":{
17
+ "type":"boolean",
18
+ "description":"This indicates that the instance property in the instance object is not required.",
19
+ "optional":true,
20
+ "default":false},
21
+ "properties":{
22
+ "type":"object",
23
+ "additionalProperties":{"$ref":"$"},
24
+ "description":"This is a definition for the properties of an object value",
25
+ "optional":true,
26
+ "default":{}
27
+ },
28
+ "items":{
29
+ "type":"object",
30
+ "properties":{"$ref":"$.properties"},
31
+ "description":"When the value is an array, this indicates the schema to use to validate each item in an array",
32
+ "optional":true,
33
+ "default":{}},
34
+ "additionalProperties":{
35
+ "type":["boolean","object"],
36
+ "properties":{"$ref":"$.properties"},
37
+ "description":"This provides a default property definition for all properties that are not explicitly defined in an object type definition.",
38
+ "optional":true,
39
+ "default":{}},
40
+ "specificity":{
41
+ "type":"number",
42
+ "description":"This indicates an order of specificity of properties. If an instance defines another property with a higher specificity than this one, than this instance property is required.",
43
+ "optional":true,
44
+ "default":false},
45
+ "unique":{
46
+ "type":"boolean",
47
+ "description":"This indicates that the instance property should have unique values. No other property with the same name in the instance object tree should have the same value.",
48
+ "optional":true,
49
+ "default":false},
50
+ "minimum":{
51
+ "type":"number",
52
+ "optional":true,
53
+ "description":"This indicates the minimum value for the instance property when the type of the instance value is a number, or it indicates the minimum number of values in an array when an array is the instance value."},
54
+ "maximum":{
55
+ "type":"number",
56
+ "optional":true,
57
+ "description":"This indicates the maximum value for the instance property when the type of the instance value is a number, or it indicates the maximum number of values in an array when an array is the instance value."},
58
+ "pattern":{
59
+ "type":"string",
60
+ "format":"regex",
61
+ "description":"When the instance value is a string, this provides a regular expression that a instance string value should match in order to be valid.",
62
+ "optional":true,
63
+ "default":".*"},
64
+ "maxLength" :{
65
+ "type":"number",
66
+ "optional":true,
67
+ "description":"When the instance value is a string, this indicates maximum length of the string."},
68
+ "minLength" :{
69
+ "type":"number",
70
+ "optional":true,
71
+ "description":"When the instance value is a string, this indicates minimum length of the string."},
72
+ "maxItems" :{
73
+ "type":"number",
74
+ "optional":true,
75
+ "description":"When the instance value is an array, this indicates maximum number of items."},
76
+ "minItems" :{
77
+ "type":"number",
78
+ "optional":true,
79
+ "description":"When the instance value is an array, this indicates minimum number of items."},
80
+ "enum" : {
81
+ "type":"array",
82
+ "optional":true,
83
+ "description":"This provides an enumeration of possible values that are valid for the instance property."},
84
+ "options" : {
85
+ "type":"array",
86
+ "items":{
87
+ "properties":{
88
+ "label":{
89
+ "type":"string",
90
+ "description":"This is the label for this option",
91
+ "optional":true
92
+ },
93
+ "value":{
94
+ "description":"This is the value for this option"
95
+ }
96
+ },
97
+ "description":"This is an option for list of possible values"
98
+ },
99
+ "optional":true,
100
+ "description":"This provides a list of suggested options for the instance property."},
101
+ "readonly":{
102
+ "type":"boolean",
103
+ "description":"This indicates that the instance property should not be changed (this is only for interaction, it has no effect for standalone validation).",
104
+ "optional":true,
105
+ "default":false},
106
+ "description":{
107
+ "type":"string",
108
+ "optional":true,
109
+ "description":"This provides a description of the purpose the instance property. The value can be a string or it can be an object with properties corresponding to various different instance languages (with an optional default property indicating the default description)."},
110
+ "format":{
111
+ "type":"string",
112
+ "optional":true,
113
+ "description":"This indicates what format the data is among some predefined formats which may include:\n\ndate - a string following the ISO format \naddress \nschema - a schema definition object \nperson \npage \nhtml - a string representing HTML"},
114
+ "default":{
115
+ "type":"any",
116
+ "optional":true,
117
+ "description":"This indicates the default for the instance property."},
118
+ "transient":{
119
+ "type":"boolean",
120
+ "optional":true,
121
+ "description":"This indicates that the property will be used for transient/volatile values that should not be persisted.",
122
+ "default":false},
123
+ "maxDecimal":{
124
+ "type":"integer",
125
+ "optional":true,
126
+ "description":"This indicates the maximum number of decimal places in a floating point number."},
127
+ "hidden":{
128
+ "type":"boolean",
129
+ "optional":true,
130
+ "description":"This indicates whether the property should be hidden in user interfaces."},
131
+ "extends":{
132
+ "type":"object",
133
+ "properties":{"$ref":"$.properties"},
134
+ "description":"This indicates the schema extends the given schema. All instances of this schema must be valid to by the extended schema also.",
135
+ "optional":true,
136
+ "default":{}},
137
+ "id":{
138
+ "type":["string","number"],
139
+ "optional":true,
140
+ "format":"url",
141
+ "unique":true}
142
+ }
143
+ }
@@ -0,0 +1,64 @@
1
+ MAP_FUNCTION = <<END_OF_MAP_FN
2
+ function () {
3
+ var value = {i: 0, d: 0, n: 0, e: 0};
4
+ if (this.birthdate<=-764985600) {
5
+ value.i++;
6
+ if (this.measures["0043"].encounter>=1253318400) {
7
+ value.d++;
8
+ if (this.measures["0043"].vaccination==true) {
9
+ value.n++;
10
+ } else if (false) {
11
+ value.e++;
12
+ value.d--;
13
+ }
14
+ }
15
+ }
16
+ emit(null, value);
17
+ };
18
+ END_OF_MAP_FN
19
+
20
+ describe QME::MapReduce::Builder do
21
+
22
+ before do
23
+ raw_measure_json = File.read('measures/0043/0043_NQF_PneumoniaVaccinationStatusForOlderAdults.json')
24
+ @measure_json = JSON.parse(raw_measure_json)
25
+ raw_measure_json = File.read('fixtures/complex_measure.json')
26
+ @complex_measure_json = JSON.parse(raw_measure_json)
27
+ end
28
+
29
+ it 'should extract the measure metadata' do
30
+ measure = QME::MapReduce::Builder.new(@measure_json, :effective_date=>Time.gm(2010, 9, 19).to_i)
31
+ measure.id.should eql('0043')
32
+ end
33
+ it 'should extract three parameters for measure 0043 (one provided, two calculated)' do
34
+ time = Time.gm(2010, 9, 19).to_i
35
+
36
+ measure = QME::MapReduce::Builder.new(@measure_json, :effective_date=>time)
37
+ measure.parameters.size.should eql(3)
38
+ measure.parameters.should have_key(:effective_date)
39
+ measure.parameters[:effective_date].should eql(time)
40
+ end
41
+ it 'should raise a RuntimeError if not passed all the parameters' do
42
+ lambda { QME::MapReduce::Builder.new(@measure_json) }.should
43
+ raise_error(RuntimeError, 'No value supplied for measure parameter: effective_date')
44
+ end
45
+ it 'should calculate the calculated dates correctly' do
46
+ date = Time.gm(2010, 9, 19).to_i
47
+ measure = QME::MapReduce::Builder.new(@measure_json, :effective_date=>date)
48
+ measure.parameters[:earliest_encounter].should eql(date-QME::MapReduce::Builder::YEAR_IN_SECONDS)
49
+ end
50
+ it 'should produce valid JavaScript expressions for the query components' do
51
+ date = Time.gm(2010, 9, 19).to_i
52
+ builder = QME::MapReduce::Builder.new(@measure_json, :effective_date=>date)
53
+ builder.numerator.should eql('(this.measures["0043"].vaccination==true)')
54
+ builder.denominator.should eql('(this.measures["0043"].encounter>='+builder.parameters[:earliest_encounter].to_s+')')
55
+ builder.population.should eql('(this.birthdate<='+builder.parameters[:earliest_birthdate].to_s+')')
56
+ builder.exception.should eql('(false)')
57
+ builder.map_function.should eql(MAP_FUNCTION)
58
+ builder.reduce_function.should eql(QME::MapReduce::Builder::REDUCE_FUNCTION)
59
+ end
60
+ it 'should handle logical combinations' do
61
+ builder = QME::MapReduce::Builder.new(@complex_measure_json, {})
62
+ builder.population.should eql('((this.measures["0043"].age>17)&&(this.measures["0043"].age<75)&&((this.measures["0043"].sex=="male")||(this.measures["0043"].sex=="female")))')
63
+ end
64
+ end
@@ -0,0 +1,50 @@
1
+ describe QME::MapReduce::Executor do
2
+
3
+ before do
4
+ db_host = nil
5
+ if ENV['TEST_DB_HOST']
6
+ db_host = ENV['TEST_DB_HOST']
7
+ else
8
+ db_host = 'localhost'
9
+ end
10
+ @db = Mongo::Connection.new(db_host, 27017).db('test')
11
+ @measures = Dir.glob('measures/*')
12
+ end
13
+
14
+ it 'should produce the expected results for each measure' do
15
+ print "\n"
16
+ @measures.each do |dir|
17
+ # load db with measure and sample patient records
18
+ files = Dir.glob(File.join(dir,'*.json'))
19
+ files.size.should eql(1)
20
+ measure_file = files[0]
21
+ patient_files = Dir.glob(File.join(dir, 'patients', '*.json'))
22
+ measure = JSON.parse(File.read(measure_file))
23
+ measure_id = measure['id']
24
+ print "Validating measure #{measure_id}"
25
+ @db.drop_collection('measures')
26
+ @db.drop_collection('records')
27
+ measure_collection = @db.create_collection('measures')
28
+ record_collection = @db.create_collection('records')
29
+ measure_collection.save(measure)
30
+ patient_files.each do |patient_file|
31
+ patient = JSON.parse(File.read(patient_file))
32
+ record_collection.save(patient)
33
+ end
34
+
35
+ # load expected results
36
+ result_file = File.join(dir, 'result', 'result.json')
37
+ expected = JSON.parse(File.read(result_file))
38
+
39
+ # evaulate measure using Map/Reduce and validate results
40
+ executor = QME::MapReduce::Executor.new(@db)
41
+ result = executor.measure_result(measure_id, :effective_date=>Time.gm(2010, 9, 19).to_i)
42
+ result[:population].should eql(expected['initialPopulation'])
43
+ result[:numerator].should eql(expected['numerator'])
44
+ result[:denominator].should eql(expected['denominator'])
45
+ result[:exceptions].should eql(expected['exclusions'])
46
+ print " - done\n"
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,56 @@
1
+ describe QME::Query::JSONDocumentBuilder do
2
+
3
+ before do
4
+ raw_measure_json = File.read('measures/0043/0043_NQF_PneumoniaVaccinationStatusForOlderAdults.json')
5
+ @measure_json = JSON.parse(raw_measure_json)
6
+ raw_measure_json = File.read('fixtures/complex_measure.json')
7
+ @complex_measure_json = JSON.parse(raw_measure_json)
8
+ end
9
+
10
+ it 'should calculate dates for a measure' do
11
+ jdb = QME::Query::JSONDocumentBuilder.new(@measure_json)
12
+ jdb.parameters = {:effective_date => 1287685441}
13
+ jdb.calculate_dates
14
+ jdb.calculated_dates['earliest_birthdate'].should == -762154559
15
+ end
16
+
17
+ it 'should create a query for a simple measure' do
18
+ jdb = QME::Query::JSONDocumentBuilder.new(@measure_json, {:effective_date => 1287685441})
19
+ query_hash = jdb.create_query(@measure_json['denominator'])
20
+ query_hash.size.should be 1
21
+ query_hash['measures.0043.encounter'].should_not be_nil
22
+ query_hash['measures.0043.encounter']['$gte'].should == 1256149441
23
+ end
24
+
25
+ it 'should properly transform a property name' do
26
+ jdb = QME::Query::JSONDocumentBuilder.new(@measure_json, {:effective_date => 1287685441})
27
+ jdb.transform_query_property('birthdate').should == 'birthdate'
28
+ jdb.transform_query_property('foo').should == 'measures.0043.foo'
29
+ end
30
+
31
+ it 'should properly process a query leaf when it is an expression' do
32
+ jdb = QME::Query::JSONDocumentBuilder.new(@measure_json, {:effective_date => 1287685441})
33
+ args = {}
34
+ jdb.process_query({"encounter" => {"_gte" => "@earliest_encounter"}}, args)
35
+ args.size.should be 1
36
+ args['measures.0043.encounter'].should_not be_nil
37
+ args['measures.0043.encounter']['$gte'].should == 1256149441
38
+ end
39
+
40
+ it 'should properly process a query leaf when it is a value' do
41
+ jdb = QME::Query::JSONDocumentBuilder.new(@measure_json, {:effective_date => 1287685441})
42
+ args = {}
43
+ jdb.process_query({"encounter" => 'splat'}, args)
44
+ args.size.should be 1
45
+ args['measures.0043.encounter'].should_not be_nil
46
+ args['measures.0043.encounter'].should == 'splat'
47
+ end
48
+
49
+ it 'should create a query for a complex measure' do
50
+ jdb = QME::Query::JSONDocumentBuilder.new(@complex_measure_json)
51
+ query_hash = jdb.create_query(@complex_measure_json['population'])
52
+ query_hash['measures.0043.age']['$gt'].should == 17
53
+ query_hash['measures.0043.age']['$lt'].should == 75
54
+ query_hash['$or'].should have(2).items
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ require 'json'
2
+
3
+ describe JSON, 'All JSON Schemas' do
4
+ it 'should conform to JSON Schema' do
5
+ schema = File.open('schema/schema.json', 'rb'){|f| JSON.parse(f.read)}
6
+ Dir.glob('schema/*.json').each do |schema_file|
7
+ if schema_file != 'schema/schema.json' # Don't check the schema itself
8
+ data = File.open(schema_file, 'rb'){|f| JSON.parse(f.read)}
9
+ JSON::Schema.validate(data, schema)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ describe JSON, 'Result Example' do
16
+ it 'should conform to the schema defined' do
17
+ schema = File.open('schema/result.json', 'rb'){|f| JSON.parse(f.read)}
18
+ data = File.open('fixtures/result_example.json', 'rb'){|f| JSON.parse(f.read)}
19
+ JSON::Schema.validate(data, schema)
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ begin
2
+ # Try to require the preresolved locked set of gems.
3
+ require File.expand_path('../.bundle/environment', __FILE__)
4
+ rescue LoadError
5
+ # Fall back on doing an unlocked resolve at runtime.
6
+ require "rubygems"
7
+ require "bundler"
8
+ Bundler.setup
9
+ end
10
+
11
+ Bundler.require(:default, :test)
12
+
13
+ PROJECT_ROOT = File.dirname(__FILE__) + '/../'
14
+
15
+ require PROJECT_ROOT + 'lib/quality_measure_engine'
@@ -0,0 +1,21 @@
1
+ # Validate the measure specifications and patient samples
2
+
3
+ require 'json'
4
+
5
+ describe JSON, 'All measure specifications' do
6
+ it 'should be valid JSON' do
7
+ Dir.glob('measures/*/*.json').each do |measure_file|
8
+ measure = File.read(measure_file)
9
+ json = JSON.parse(measure)
10
+ end
11
+ end
12
+ end
13
+
14
+ describe JSON, 'All patient samples' do
15
+ it 'should be valid JSON' do
16
+ Dir.glob('measures/*/patients/*.json').each do |measure_file|
17
+ measure = File.read(measure_file)
18
+ json = JSON.parse(measure)
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quality-measure-engine
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Marc Hadley
13
+ - Andy Gregorowicz
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-28 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mongo
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 1
31
+ - 1
32
+ version: "1.1"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mongomatic
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 5
46
+ - 8
47
+ version: 0.5.8
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: therubyracer
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ - 7
61
+ - 5
62
+ version: 0.7.5
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: bson_ext
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 1
75
+ - 1
76
+ - 1
77
+ version: 1.1.1
78
+ type: :runtime
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: jsonschema
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 2
90
+ - 0
91
+ - 0
92
+ version: 2.0.0
93
+ type: :development
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: rspec
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ segments:
104
+ - 2
105
+ - 0
106
+ - 0
107
+ version: 2.0.0
108
+ type: :development
109
+ version_requirements: *id006
110
+ - !ruby/object:Gem::Dependency
111
+ name: awesome_print
112
+ prerelease: false
113
+ requirement: &id007 !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ segments:
119
+ - 0
120
+ - 2
121
+ - 1
122
+ version: 0.2.1
123
+ type: :development
124
+ version_requirements: *id007
125
+ - !ruby/object:Gem::Dependency
126
+ name: jeweler
127
+ prerelease: false
128
+ requirement: &id008 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ segments:
134
+ - 1
135
+ - 4
136
+ - 0
137
+ version: 1.4.0
138
+ type: :development
139
+ version_requirements: *id008
140
+ description: A library for extracting quality measure information from HITSP C32's and ASTM CCR's
141
+ email: talk@projectpophealth.org
142
+ executables: []
143
+
144
+ extensions: []
145
+
146
+ extra_rdoc_files:
147
+ - README.md
148
+ files:
149
+ - .gitignore
150
+ - Gemfile
151
+ - Gemfile.lock
152
+ - README.md
153
+ - Rakefile
154
+ - VERSION
155
+ - fixtures/complex_measure.json
156
+ - fixtures/result_example.json
157
+ - lib/patches/v8.rb
158
+ - lib/qme/map/map_reduce_builder.rb
159
+ - lib/qme/map/map_reduce_executor.rb
160
+ - lib/qme/query/json_document_builder.rb
161
+ - lib/quality_measure_engine.rb
162
+ - measures/0032/0032_NQF_Cervical_Cancer_Screening.json
163
+ - measures/0032/patients/denominator1.json
164
+ - measures/0032/patients/denominator2.json
165
+ - measures/0032/patients/numerator1.json
166
+ - measures/0032/patients/population1.json
167
+ - measures/0032/patients/population2.json
168
+ - measures/0032/result/result.json
169
+ - measures/0043/0043_NQF_PneumoniaVaccinationStatusForOlderAdults.json
170
+ - measures/0043/patients/denominator.json
171
+ - measures/0043/patients/numerator.json
172
+ - measures/0043/patients/population.json
173
+ - measures/0043/result/result.json
174
+ - quality-measure-engine.gemspec
175
+ - schema/result.json
176
+ - schema/schema.json
177
+ - spec/qme/map/map_reduce_builder_spec.rb
178
+ - spec/qme/measures_spec.rb
179
+ - spec/qme/query/json_document_builder_spec.rb
180
+ - spec/schema_spec.rb
181
+ - spec/spec_helper.rb
182
+ - spec/validate_measures_spec.rb
183
+ has_rdoc: true
184
+ homepage: http://github.com/pophealth/quality-measure-engine
185
+ licenses: []
186
+
187
+ post_install_message:
188
+ rdoc_options:
189
+ - --charset=UTF-8
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ">="
196
+ - !ruby/object:Gem::Version
197
+ segments:
198
+ - 0
199
+ version: "0"
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ segments:
206
+ - 0
207
+ version: "0"
208
+ requirements: []
209
+
210
+ rubyforge_project:
211
+ rubygems_version: 1.3.7
212
+ signing_key:
213
+ specification_version: 3
214
+ summary: A library for extracting quality measure information from HITSP C32's and ASTM CCR's
215
+ test_files:
216
+ - spec/qme/map/map_reduce_builder_spec.rb
217
+ - spec/qme/measures_spec.rb
218
+ - spec/qme/query/json_document_builder_spec.rb
219
+ - spec/schema_spec.rb
220
+ - spec/spec_helper.rb
221
+ - spec/validate_measures_spec.rb