Class: Crucible::Tests::ResourceGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/resource_generator.rb

Direct Known Subclasses

DAFResourceGenerator

Class Method Summary collapse

Class Method Details

.apply_invariants!(resource) ⇒ Object



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/resource_generator.rb', line 273

def self.apply_invariants!(resource)
  case resource.class
  when FHIR::Appointment
    resource.reason = minimal_codeableconcept('http://snomed.info/sct','219006') # drinker of alcohol
    resource.participant.each{|p| p.fhirType=[ minimal_codeableconcept('http://hl7.org/fhir/participant-type','emergency') ] }
  when FHIR::AppointmentResponse
    resource.participantType = [ minimal_codeableconcept('http://hl7.org/fhir/participant-type','emergency') ]
  when FHIR::AuditEvent
    resource.object.each do |o|
      o.query=nil
      o.name = "name #{SecureRandom.base64}" if o.name.nil?
    end
  when FHIR::Bundle
    resource.total = nil if !['searchset','history'].include?(resource.fhirType)
    resource.entry.each {|e|e.search=nil} if resource.fhirType!='searchset'
    resource.entry.each {|e|e.request=nil} if !['batch','transaction','history'].include?(resource.fhirType)
    resource.entry.each {|e|e.response=nil} if !['batch-response','transaction-response'].include?(resource.fhirType)
    head = resource.entry.first
    if !head.nil?
      if head.request.nil? && head.response.nil? && head.resource.nil?
        if resource.fhirType == 'document'
          head.resource = generate(FHIR::Composition,3)
        elsif resource.fhirType == 'message'
          head.resource = generate(FHIR::MessageHeader,3)  
        else
          head.resource = generate(FHIR::Basic,3)                              
        end
      end
      if head.resource.nil?
        head.fullUrl = nil
      else
        rid = SecureRandom.random_number(100) + 1
        head.fullUrl = "http://projectcrucible.org/fhir/#{rid}"
        head.resource.xmlId = "#{rid}"
      end
    end
  when FHIR::CarePlan
    resource.activity.each {|a| a.reference = nil if a.detail }
  when FHIR::Claim
    resource.item.each do |item|
      item.fhirType = minimal_coding('http://hl7.org/fhir/v3/ActCode','OHSINV')
      item.detail.each do |detail|
        detail.fhirType = minimal_coding('http://hl7.org/fhir/v3/ActCode','OHSINV')
        detail.subDetail.each do |sub|
          sub.fhirType = minimal_coding('http://hl7.org/fhir/v3/ActCode','OHSINV')
          sub.service = minimal_coding('http://hl7.org/fhir/ex-USCLS','1205')
        end
      end
    end
    resource.missingTeeth.each do |mt|
      mt.tooth = minimal_coding('http://hl7.org/fhir/ex-fdi','42')
    end
  when FHIR::ClaimResponse
    resource.item.each do |item|
      item.adjudication.each{|a|a.code = minimal_coding('http://hl7.org/fhir/adjudication','benefit')}
      item.detail.each do |detail|
        detail.adjudication.each{|a|a.code = minimal_coding('http://hl7.org/fhir/adjudication','benefit')}
        detail.subDetail.each do |sub|
          sub.adjudication.each{|a|a.code = minimal_coding('http://hl7.org/fhir/adjudication','benefit')}
        end
      end
    end
    resource.addItem.each do |addItem|
      addItem.adjudication.each{|a|a.code = minimal_coding('http://hl7.org/fhir/adjudication','benefit')}
      addItem.detail.each do |detail|
        detail.adjudication.each{|a|a.code = minimal_coding('http://hl7.org/fhir/adjudication','benefit')}
      end
    end
  when FHIR::Communication
    resource.payload = nil
  when FHIR::CommunicationRequest
    resource.payload = nil
  when FHIR::Composition
    resource.attester.each {|a| a.mode = ['professional']}
    resource.section.each do |section|
      section.emptyReason = nil
      section.section.each do |sub|
        sub.emptyReason = nil
        sub.section = nil
      end
    end
  when FHIR::ConceptMap
    if(resource.sourceUri.nil? && resource.sourceReference.nil?)
      resource.sourceReference = textonly_reference('ValueSet') 
    end
    if(resource.targetUri.nil? && resource.targetReference.nil?)
      resource.targetReference = textonly_reference('ValueSet') 
    end
  when FHIR::Conformance
    resource.fhirVersion = 'DSTU2'
    resource.format = ['xml','json']
    if resource.kind == 'capability'
      resource.implementation = nil
    elsif resource.kind == 'requirements'
      resource.implementation = nil
      resource.software = nil
    end
    resource.messaging.each{|m| m.endpoint = nil} if resource.kind != 'instance'
  when FHIR::Contract
    resource.actor.each do |actor|
      actor.entity = textonly_reference('Patient')
    end
    resource.term.each do |term|
      term.actor.each do |actor|
        actor.entity = textonly_reference('Organization')
      end
      term.group.each do |group|
        group.actor.each do |actor|
          actor.entity = textonly_reference('Organization')
        end
      end
    end
    resource.friendly.each do |f|
      f.contentAttachment = nil
      f.contentReference = textonly_reference('DocumentReference')
    end
    resource.legal.each do |f|
      f.contentAttachment = nil
      f.contentReference = textonly_reference('DocumentReference')
    end
    resource.rule.each do |f|
      f.contentAttachment = nil
      f.contentReference = textonly_reference('DocumentReference')
    end
  when FHIR::DataElement
    resource.mapping.each do |m|
      m.fhirIdentity = SecureRandom.base64 if m.fhirIdentity.nil?
      m.fhirIdentity.gsub!(/[^0-9A-Za-z]/, '')
    end
  when FHIR::DeviceMetric
    resource.measurementPeriod = nil
  when FHIR::DiagnosticReport
    date = DateTime.now
    resource.effectiveDateTime = date.strftime("%Y-%m-%dT%T.%LZ")
    resource.effectivePeriod = nil
  when FHIR::DocumentManifest
    resource.content.each do |c|
      c.pAttachment = nil
      c.pReference = textonly_reference('Any')
    end
  when FHIR::DocumentReference
    resource.docStatus = minimal_codeableconcept('http://hl7.org/fhir/composition-status','preliminary')
  when FHIR::ElementDefinition
    keys = []
    resource.constraint.each do |constraint|
      constraint.key = SecureRandom.base64 if constraint.key.nil?
      constraint.key.gsub!(/[^0-9A-Za-z]/, '')
      keys << constraint.key
      constraint.xpath = "/"
    end
    resource.condition = keys
    resource.mapping.each do |m|
      m.fhirIdentity = SecureRandom.base64 if m.fhirIdentity.nil?
      m.fhirIdentity.gsub!(/[^0-9A-Za-z]/, '')
    end
    resource.max = "#{resource.min+1}"
    # TODO remove bindings for things that can't be code, Coding, CodeableConcept
    is_codeable = false
    resource.fhirType.each do |f|
      is_codeable = (['code','Coding','CodeableConcept'].include?(f.code))
    end
    resource.binding = nil unless is_codeable
  when FHIR::Goal
    resource.outcome.each do |outcome|
      outcome.resultCodeableConcept = nil
      outcome.resultReference = textonly_reference('Observation')
    end
  when FHIR::Group
    resource.member = [] if resource.actual==false
    resource.characteristic.each do |c|
      c.valueCodeableConcept = nil
      c.valueBoolean = true
      c.valueQuantity = nil
      c.valueRange = nil
    end
  when FHIR::ImagingObjectSelection
    resource.uid = random_oid
    index = SecureRandom.random_number(FHIR::ImagingObjectSelection::VALID_CODES[:title].length)
    code = FHIR::ImagingObjectSelection::VALID_CODES[:title][index]
    resource.title = minimal_codeableconcept('http://nema.org/dicom/dicm',code)
    resource.study.each do |study|
      study.uid = random_oid
      study.series.each do |series|
        series.uid = random_oid
        series.instance.each do |instance|
          instance.sopClass = random_oid
          instance.uid = random_oid
        end
      end
    end
  when FHIR::ImagingStudy
    resource.uid = random_oid
    resource.series.each do |series|
      series.uid=random_oid
      series.instance.each do |instance|
        instance.uid = random_oid
        instance.sopClass = random_oid
      end
    end
  when FHIR::Immunization
    if resource.wasNotGiven
      resource.explanation.reasonNotGiven = [ textonly_codeableconcept("reasonNotGiven #{SecureRandom.base64}") ]
      resource.explanation.reason = nil
      resource.reaction = nil
    else
      resource.explanation.reasonNotGiven = nil
      resource.explanation.reason = [ textonly_codeableconcept("reason #{SecureRandom.base64}") ]
    end
  when FHIR::ImplementationGuide
    resource.fhirVersion = "DSTU2"
    resource.package.each do |package|
      package.resource.each do |r|
        r.sourceUri = nil
        r.sourceReference = textonly_reference('Any')
      end
    end
  when FHIR::List
    resource.emptyReason = nil
    resource.entry.each do |entry|
      resource.mode = 'changes' if !entry.fhirDeleted.nil?
    end
  when FHIR::Media
    if resource.fhirType == 'video'
      resource.frames = nil
    elsif resource.fhirType == 'photo'
      resource.duration = nil
    elsif resource.fhirType == 'audio'
      resource.height = nil
      resource.width = nil
      resource.frames = nil            
    else
      resource.height = nil
      resource.width = nil
      resource.frames = nil
    end
  when FHIR::Medication
    if resource.product.try(:ingredient)
      resource.product.ingredient.each {|i|i.amount = nil}
    end
  when FHIR::MedicationAdministration
    date = DateTime.now
    resource.effectiveTimeDateTime = date.strftime("%Y-%m-%dT%T.%LZ")
    resource.effectiveTimePeriod = nil
    if resource.wasNotGiven
      resource.reasonGiven = nil
    else
      resource.reasonNotGiven = nil
    end
    resource.medicationReference = textonly_reference('Medication')
    resource.medicationCodeableConcept = nil
  when FHIR::MedicationDispense
    resource.medicationReference = textonly_reference('Medication')
    resource.medicationCodeableConcept = nil
    resource.dosageInstruction.each {|d|d.timing = nil }
  when FHIR::MedicationOrder
    resource.medicationReference = textonly_reference('Medication')
    resource.medicationCodeableConcept = nil
    resource.dosageInstruction.each {|d|d.timing = nil }
  when FHIR::MedicationStatement
    resource.reasonNotTaken = nil if resource.wasNotTaken != true
    resource.medicationReference = textonly_reference('Medication')
    resource.medicationCodeableConcept = nil
    resource.dosage.each{|d|d.timing=nil}
  when FHIR::MessageHeader
    resource.response.identifier.gsub!(/[^0-9A-Za-z]/, '') if resource.try(:response).try(:identifier)
  when FHIR::NamingSystem
    resource.replacedBy = nil if resource.status!='retired'
    if resource.kind == 'root'
      resource.uniqueId.each do |uid|
        uid.fhirType='other' if ['uuid','oid'].include?(uid.fhirType)
      end
    end
    resource.uniqueId.each do |uid|
      uid.preferred = nil
    end
  when FHIR::NutritionOrder
    resource.oralDiet.schedule = nil if resource.oralDiet
    resource.supplement.each{|s|s.schedule=nil}
    resource.enteralFormula.administration = nil if resource.enteralFormula
  when FHIR::OperationDefinition
    resource.parameter.each do |p|
      p.binding = nil
      p.part = nil
    end
  when FHIR::Order
    resource.when.schedule = nil
  when FHIR::Patient
    resource.maritalStatus = minimal_codeableconcept('http://hl7.org/fhir/v3/MaritalStatus','S')
  when FHIR::Procedure
    resource.reasonNotPerformed = nil if resource.notPerformed != true
    resource.focalDevice.each do |fd|
      fd.action = minimal_codeableconcept('http://hl7.org/fhir/ValueSet/device-action','implanted')
    end
  when FHIR::Provenance
    resource.entity.each do |e|
      e.agent.relatedAgent = nil if e.agent
    end
  when FHIR::RelatedPerson
    resource.relationship = minimal_codeableconcept('http://hl7.org/fhir/patient-contact-relationship','family')
  when FHIR::Questionnaire
    resource.group.required = true
    resource.group.group = nil
    resource.group.question.each {|q|q.options = nil }
  when FHIR::QuestionnaireResponse
    resource.group.group = nil
    resource.group.question.each {|q|q.answer = nil }
  when FHIR::Subscription
    resource.status = 'requested' if resource.xmlId.nil?
    resource.channel.payload = 'applicaton/json+fhir'
    resource.end = nil
  when FHIR::SupplyDelivery
    resource.fhirType = minimal_codeableconcept('http://hl7.org/fhir/supply-item-type','medication')
  when FHIR::SupplyRequest
    resource.kind = minimal_codeableconcept('http://hl7.org/fhir/supply-kind','central')
    if resource.when 
      resource.when.schedule = nil
      resource.when.code = minimal_codeableconcept('http://snomed.info/sct','20050000') #biweekly
    end
  when FHIR::StructureDefinition
    resource.fhirVersion = 'DSTU2'
    resource.snapshot.element.first.path = resource.constrainedType if resource.snapshot && resource.snapshot.element
    resource.mapping.each do |m|
      m.fhirIdentity.gsub!(/[^0-9A-Za-z]/, '') if m.fhirIdentity
    end
  when FHIR::TestScript
    resource.variable.each do |v|
      v.sourceId.gsub!(/[^0-9A-Za-z]/, '') if v.sourceId
      v.path = nil if v.headerField
    end
    if resource.setup
      resource.setup. = nil 
      resource.setup.action.each do |a|
        a.assert = nil if a.operation
        apply_invariants!(a.operation) if a.operation
        apply_invariants!(a.assert) if a.assert
      end
    end
    resource.test.each do |test|
      test. = nil
      test.action.each do |a|
        a.assert = nil if a.operation
        apply_invariants!(a.operation) if a.operation
        apply_invariants!(a.assert) if a.assert
      end            
    end
    if resource.teardown
      resource.teardown.action.each do |a|
        apply_invariants!(a.operation) if a.operation
      end
    end
  when FHIR::TestScript::TestScriptSetupActionAssertComponent
    # an assertion can only contain one of these...
    keys = ['contentType','headerField','minimumId','navigationLinks','path','resource','responseCode','response','validateProfileId']
    has_keys = []
    keys.each do |key|
      has_keys << key if resource.try(key.to_sym)
    end
    # remove all assertions except the first
    has_keys[1..-1].each do |key|
      resource.send("#{key}=",nil)
    end
    resource.sourceId.gsub!(/[^0-9A-Za-z]/, '') if resource.sourceId
    resource.validateProfileId.gsub!(/[^0-9A-Za-z]/, '') if resource.validateProfileId
  when FHIR::TestScript::TestScriptSetupActionOperationComponent
    resource.responseId.gsub!(/[^0-9A-Za-z]/, '') if resource.responseId
    resource.sourceId.gsub!(/[^0-9A-Za-z]/, '') if resource.sourceId
    resource.targetId.gsub!(/[^0-9A-Za-z]/, '') if resource.targetId
  when FHIR::ValueSet
    if resource.compose
      resource.compose.include.each do |inc|
        inc.filter = nil if inc.concept
      end
      resource.compose.exclude.each do |exc|
        exc.filter = nil if exc.concept
      end
    end
  else
    # default
  end
end

.generate(klass, embedded = 0) ⇒ Object

Generate a FHIR resource for the given class klass If embedded is greater than zero, all embedded children will also be generated.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/resource_generator.rb', line 10

def self.generate(klass,embedded=0)
  resource = klass.new
  Time.zone = 'UTC'
  set_fields!(resource)
  if(embedded > 0)
    generate_children!(resource,embedded)
  end
  resource.xmlId=nil if resource.respond_to?(:xmlId=)
  resource.versionId=nil if resource.respond_to?(:versionId=)
  resource.version=nil if resource.respond_to?(:version=)
  resource.text=nil if [FHIR::Bundle,FHIR::Binary,FHIR::Parameters].include?(klass)
  apply_invariants!(resource)
  resource
end

.generate_children!(resource, embedded = 0) ⇒ Object

Generate children for this resource.



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/resource_generator.rb', line 110

def self.generate_children!(resource,embedded=0)
  # For now, we'll skip fields that can have multiple datatypes, such as attribute[x]
  multiples = []
  if resource.class.constants.include? :MULTIPLE_TYPES
    multiples = resource.class::MULTIPLE_TYPES.map{|k,v| v}.flatten
  end

  children = resource.embedded_relations
  children.each do |key,value|
    # TODO: Determine if we can generate references or meta information
    next if ['meta'].include? key
    next if multiples.include? key
    
    klass = resource.get_fhir_class_from_resource_type(value[:class_name])
    case klass
    when FHIR::Reference
      child = FHIR::Reference.new
      child.display = "#{key} #{SecureRandom.base64}"
    when FHIR::CodeableConcept
      child = FHIR::CodeableConcept.new
      child.text = "#{key} #{SecureRandom.base64}"
    when FHIR::Coding
      child = FHIR::Coding.new
      child.display = "#{key} #{SecureRandom.base64}"
    when FHIR::Quantity
      child = FHIR::Quantity.new
      child.value = SecureRandom.random_number
      while child.value.to_s.match(/e/) # according to FHIR spec: decimals may not contain exponents
        child.value = SecureRandom.random_number
      end
      child.unit = SecureRandom.base64
    else
      child = generate(klass,(embedded-1)) if(!['FHIR::Extension','FHIR::PrimitiveExtension','FHIR::Signature'].include?(value[:class_name]))
    end

    case klass
    when FHIR::Identifier
      child.system = nil
    when FHIR::Attachment
      child.url = nil
    end

    if value[:relation] == Mongoid::Relations::Embedded::Many
      child = ([] << child) if child
    end
    resource[key] = child if child
  end
  resource
end

.minimal_animalObject



265
266
267
268
269
270
271
# File 'lib/resource_generator.rb', line 265

def self.minimal_animal
  animal = FHIR::Patient::AnimalComponent.new
  animal.species = minimal_codeableconcept('http://hl7.org/fhir/animal-species','canislf') # dog
  animal.breed = minimal_codeableconcept('http://hl7.org/fhir/animal-breed','gret') # golden retriever
  animal.genderStatus = minimal_codeableconcept('http://hl7.org/fhir/animal-genderstatus','intact') # intact
  animal
end

.minimal_codeableconcept(system = 'http://loinc.org', code = '8302-2') ⇒ Object

Common systems:

SNOMED  http://snomed.info/sct
LOINC   http://loinc.org
ICD-10  http://hl7.org/fhir/sid/icd-10


240
241
242
243
244
# File 'lib/resource_generator.rb', line 240

def self.minimal_codeableconcept(system='http://loinc.org',code='8302-2')
  concept = FHIR::CodeableConcept.new
  concept.coding = [ minimal_coding(system,code) ]
  concept
end

.minimal_coding(system = 'http://loinc.org', code = '8302-2') ⇒ Object

Common systems:

SNOMED  http://snomed.info/sct
LOINC   http://loinc.org
ICD-10  http://hl7.org/fhir/sid/icd-10


250
251
252
253
254
255
# File 'lib/resource_generator.rb', line 250

def self.minimal_coding(system='http://loinc.org',code='8302-2')
  coding = FHIR::Coding.new
  coding.system = system
  coding.code = code
  coding
end

.minimal_condition(system = 'http://snomed.info/sct', code = '414915002', patientId = nil) ⇒ Object

Default system/code are for SNOMED “Obese (finding)”



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/resource_generator.rb', line 194

def self.minimal_condition(system='http://snomed.info/sct',code='414915002',patientId=nil)
  resource = FHIR::Condition.new
  resource.patient = FHIR::Reference.new
  if patientId
    resource.patient.reference = "Patient/#{patientId}"
  else
    resource.patient.display = 'Patient'
  end
  resource.code = minimal_codeableconcept(system,code)
  resource.verificationStatus = 'confirmed'
  resource
end

.minimal_humanname(name = 'Name') ⇒ Object



215
216
217
218
219
220
221
222
# File 'lib/resource_generator.rb', line 215

def self.minimal_humanname(name='Name')
  hn = FHIR::HumanName.new
  hn.use = 'official'
  hn.family = [ 'Crucible' ]
  hn.given = [ name ]
  hn.text = "#{hn.given[0]} #{hn.family[0]}"
  hn
end

.minimal_identifier(identifier = '0') ⇒ Object



207
208
209
210
211
212
213
# File 'lib/resource_generator.rb', line 207

def self.minimal_identifier(identifier='0')
  mid = FHIR::Identifier.new
  mid.use = 'official'
  mid.system = 'http://projectcrucible.org'
  mid.value = identifier
  mid
end

.minimal_observation(system = 'http://loinc.org', code = '8302-2', value = 170, units = 'cm', patientId = nil) ⇒ Object

Common systems:

SNOMED  http://snomed.info/sct
LOINC   http://loinc.org
ICD-10  http://hl7.org/fhir/sid/icd-10

units: must be UCOM



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/resource_generator.rb', line 180

def self.minimal_observation(system='http://loinc.org',code='8302-2',value=170,units='cm',patientId=nil)
  resource = FHIR::Observation.new
  resource.status = 'final'
  resource.code = minimal_codeableconcept(system,code)
  if patientId
    ref = FHIR::Reference.new
    ref.reference = "Patient/#{patientId}"
    resource.subject = ref
  end
  resource.valueQuantity = minimal_quantity(value,units)
  resource
end

.minimal_patient(identifier = '0', name = 'Name') ⇒ Object



168
169
170
171
172
173
# File 'lib/resource_generator.rb', line 168

def self.minimal_patient(identifier='0',name='Name')
  resource = FHIR::Patient.new
  resource.identifier = [ minimal_identifier(identifier) ]
  resource.name = [ minimal_humanname(name) ]
  resource
end

.minimal_quantity(value = 170, units = 'cm') ⇒ Object



257
258
259
260
261
262
263
# File 'lib/resource_generator.rb', line 257

def self.minimal_quantity(value=170,units='cm')
  quantity = FHIR::Quantity.new
  quantity.value = value
  quantity.unit = units
  quantity.system = 'http://unitsofmeasure.org'
  quantity
end

.random_oidObject



160
161
162
163
164
165
166
# File 'lib/resource_generator.rb', line 160

def self.random_oid
  oid = "urn:oid:2"
  SecureRandom.random_number(12).times do |i|
    oid = "#{oid}.#{SecureRandom.random_number(500)}"
  end
  oid
end

.set_fields!(resource) ⇒ Object

Set the fields of this resource to have some random values.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/resource_generator.rb', line 28

def self.set_fields!(resource)
  # Organize some of the validators
  validators = {}
  resource.class.validators.collect{|v| v if v.class==Mongoid::Validatable::FormatValidator}.compact.each do |v|
    v.attributes.each{|a| validators[a] = v.options[:with]}
  end

  # For now, we'll skip fields that can have multiple datatypes, such as attribute[x]
  multiples = []
  if resource.class.constants.include? :MULTIPLE_TYPES
    multiples = resource.class::MULTIPLE_TYPES.map{|k,v| v}.flatten
  end

  # Get valid codes
  valid_codes = {}
  if resource.class.constants.include? :VALID_CODES
    valid_codes = resource.class::VALID_CODES
  end

  # Get special codes
  special_codes = {}
  if resource.class.constants.include? :SPECIAL_CODES
    special_codes = resource.class::SPECIAL_CODES
  end

  fields = resource.fields
  fields.each do |key,value|
    type = value.options[:type]
  next if ['id','xmlId','version','versionId','implicitRules'].include? key
    next if multiples.include? key
    gen = nil
    if type == String
      gen = SecureRandom.base64
      if valid_codes[key.to_sym]
        valid_values = valid_codes[key.to_sym]
        if !valid_values.nil?
          gen = valid_values[ SecureRandom.random_number( valid_values.length ) ]
        end
      elsif validators[key.to_sym]
        date = DateTime.now
        regex = validators[key.to_sym]
        if date.strftime("%Y-%m-%dT%T.%LZ").match(regex)
          gen = date.strftime("%Y-%m-%dT%T.%LZ")
        elsif date.strftime("%Y-%m-%d").match(regex)
          gen = date.strftime("%Y-%m-%d")
        elsif date.strftime("%T").match(regex)
          gen = date.strftime("%T")
        end
      elsif special_codes[key.to_sym]
        if special_codes[key.to_sym]=='MimeType'
          gen = 'text/plain'
        elsif special_codes[key.to_sym]=='Language'
          gen = 'en-US'
        end
      end
    elsif type == Integer
      gen = (SecureRandom.random_number(100) + 1) # add one in case this is a "positiveInt" which must be > 0
    elsif type == Float
      gen = SecureRandom.random_number
      while gen.to_s.match(/e/) # according to FHIR spec: decimals may not contain exponents
        gen = SecureRandom.random_number
      end
    elsif type == Mongoid::Boolean
      gen = (SecureRandom.random_number(100) % 2 == 0)
    elsif type == BSON::Binary
      # gen = SecureRandom.random_bytes
      gen = SecureRandom.base64
    elsif type == BSON::ObjectId or type == Array or type == Object or type == FHIR::AnyType
      gen = nil # ignore
    # else
    #   puts "Unable to generate field #{key} for #{resource.class} -- unrecognized type: #{type}"
    end
    gen='en-US' if(key=='language' && type==String)
    resource[key] = gen if !gen.nil?
  end
  resource
end

.textonly_codeableconcept(text = 'text') ⇒ Object



224
225
226
227
228
# File 'lib/resource_generator.rb', line 224

def self.textonly_codeableconcept(text='text')
  concept = FHIR::CodeableConcept.new
  concept.text = text
  concept
end

.textonly_reference(text = 'Reference') ⇒ Object



230
231
232
233
234
# File 'lib/resource_generator.rb', line 230

def self.textonly_reference(text='Reference')
  ref = FHIR::Reference.new
  ref.display = "#{text} #{SecureRandom.base64}"
  ref
end