All files / src/elm clinical.coffee

93.41% Statements 85/91
65.52% Branches 19/29
100% Functions 30/30
93.33% Lines 84/90

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 105 106 107 108 109 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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 17979x 1x 1x   1x   115x 115x 115x 115x       31x 31x     1x   379x 379x       28x   28x     1x   72x 72x 72x     4x       4x 4x 3x 1x   1x   254x 254x 254x           16x     16x     16x   1x   73x 73x 73x 73x         1x   137x 137x 137x 137x 137x     26x     1x   311x 311x 311x     14x     1x   5x 5x 5x 5x 5x       1x         1x     1x   124x 124x 124x 124x     22x     1x   307x 307x         1x   5x 5x 5x       1x         1x 1x     2x     1x   30x 30x     5x 5x 5x     1x   80x 80x     35x         35x        
{ Expression } = require './expression'
dt = require '../datatypes/datatypes'
{ build } = require './builder'
 
module.exports.ValueSetDef = class ValueSetDef extends Expression
  constructor: (json) ->
    super
    @name = json.name
    @id = json.id
    @version = json.version
    #todo: code systems and versions
 
  exec: (ctx) ->
    valueset = ctx.codeService.findValueSet(@id, @version) ? new dt.ValueSet(@id, @version)
    ctx.rootContext().set @name, valueset
    valueset
 
module.exports.ValueSetRef = class ValueSetRef extends Expression
  constructor: (json) ->
    super
    @name = json.name
 
  exec: (ctx) ->
    # TODO: This calls the code service every time-- should be optimized
    valueset = ctx.getValueSet(@name)
    if valueset instanceof Expression
      valueset = valueset.execute(ctx)
    valueset
 
module.exports.AnyInValueSet = class AnyInValueSet extends Expression
  constructor: (json) ->
    super
    @codes = build json.codes
    @valueset = new ValueSetRef json.valueset
 
  exec: (ctx) ->
    valueset = @valueset.execute(ctx)
    # If the value set reference cannot be resolved, a run-time error is thrown.
    throw new Error("ValueSet must be provided to InValueSet function") unless valueset? and valueset.isValueSet
 
    codes = @codes.exec(ctx)
    for code in codes
      return true if valueset.hasMatch(code)
    return false
 
module.exports.InValueSet = class InValueSet extends Expression
  constructor: (json) ->
    super
    @code = build json.code
    @valueset = new ValueSetRef json.valueset
 
  exec: (ctx) ->
    # If the code argument is null, the result is false
    return false unless @code?
    throw new Error("ValueSet must be provided to InValueSet function") unless @valueset?
    code = @code.execute(ctx)
    # spec indicates to return false if code is null, throw error if value set cannot be resolved
    return false unless code?
    valueset = @valueset.execute(ctx)
    throw new Error("ValueSet must be provided to InValueSet function") unless valueset? and valueset.isValueSet
    # If there is a code and valueset return whether or not the valueset has the code
    return valueset.hasMatch code
 
module.exports.CodeSystemDef = class CodeSystemDef extends Expression
  constructor: (json) ->
    super
    @name = json.name
    @id = json.id
    @version = json.version
 
  exec: (ctx) ->
    new dt.CodeSystem(@id, @version)
 
module.exports.CodeDef = class CodeDef extends Expression
  constructor: (json) ->
    super
    @name = json.name
    @id = json.id
    @systemName = json.codeSystem.name
    @display = json.display
 
  exec: (ctx) ->
    system = ctx.getCodeSystem(@systemName)?.execute(ctx)
    new dt.Code(@id, system.id, system.version, @display)
 
module.exports.CodeRef = class CodeRef extends Expression
  constructor: (json) ->
    super
    @name = json.name
    @library = json.libraryName
 
  exec: (ctx) ->
    ctx = if @library then ctx.getLibraryContext(@library) else ctx
    ctx.getCode(@name)?.execute(ctx)
 
module.exports.Code = class Code extends Expression
  constructor: (json) ->
    super
    @code = json.code
    @systemName = json.system.name
    @version = json.version
    @display = json.display
 
  # Define a simple getter to allow type-checking of this class without instanceof
  # and in a way that survives minification (as opposed to checking constructor.name)
  Object.defineProperties @prototype,
    isCode:
      get: -> true
 
  exec: (ctx) ->
    system = ctx.getCodeSystem(@systemName)?.id
    new dt.Code(@code, system, @version, @display)
 
module.exports.ConceptDef = class ConceptDef extends Expression
  constructor: (json) ->
    super
    @name = json.name
    @display = json.display
    @codes = json.code
 
  exec: (ctx) ->
    codes = (ctx.getCode(code.name)?.execute(ctx) for code in @codes)
    new dt.Concept(codes, @display)
 
module.exports.ConceptRef = class ConceptRef extends Expression
  constructor: (json) ->
    super
    @name = json.name
 
  exec: (ctx) ->
    ctx.getConcept(@name)?.execute(ctx)
 
module.exports.Concept = class Concept extends Expression
  constructor: (json) ->
    super
    @codes = json.code
    @display = json.display
 
  # Define a simple getter to allow type-checking of this class without instanceof
  # and in a way that survives minification (as opposed to checking constructor.name)
  Object.defineProperties @prototype,
    isConcept:
      get: -> true
 
  toCode: (ctx, code) ->
    system = ctx.getCodeSystem(code.system.name)?.id
    return new dt.Code(code.code, system, code.version, code.display)
 
  exec: (ctx) ->
    codes = (@toCode(ctx, code) for code in @codes)
    new dt.Concept(codes, @display)
 
module.exports.CalculateAge = class CalculateAge extends Expression
  constructor: (json) ->
    super
    @precision = json.precision
 
  exec: (ctx) ->
    date1 = @execArgs(ctx)
    date2 = dt.DateTime.fromJSDate(ctx.getExecutionDateTime())
    result = date1?.durationBetween(date2, @precision.toLowerCase())
    if result? && result.isPoint() then result.low else result
 
module.exports.CalculateAgeAt = class CalculateAgeAt extends Expression
  constructor: (json) ->
    super
    @precision = json.precision
 
  exec: (ctx) ->
    [date1, date2] = @execArgs(ctx)
    if date1? && date2?
      # date1 is the birthdate, convert it to date if date2 is a date (to support ignoring time)
      if date2.isDate and date1.isDateTime
        date1 = date1.getDate()
      result = date1.durationBetween(date2, @precision.toLowerCase())
      if result? && result.isPoint() then result.low else result
    else
      null