All files / src/datatypes uncertainty.coffee

82.76% Statements 24/29
100% Branches 21/21
92.86% Functions 13/14
81.48% Lines 22/27

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 671x     1x     3805x 3805x       3x   3805x   1027x 6x 1x                             162x   1x   162x             169x       1028x 1x   1028x 1028x 1028x 707x     500x       233x       249x    
{ ThreeValuedLogic } = require './logic'
 
module.exports.Uncertainty = class Uncertainty
  @from: (obj) ->
    if obj instanceof Uncertainty then obj else new Uncertainty(obj)
 
  constructor: (@low = null, @high) ->
    gt = (a, b) -> 
      if typeof a != typeof b
        # TODO: This should probably throw rather than return false.
        # Uncertainties with different types probably shouldn't be supported.
        return false
      if typeof a.after is 'function' then a.after b else a > b
    isNonEnumerable = (val) ->
      val? and (val.isCode or val.isConcept or val.isValueSet)
    if typeof @high is 'undefined' then @high = @low
    if isNonEnumerable(@low) || isNonEnumerable(@high) then @low = @high = null 
    if @low? and @high? and gt(@low, @high) then [@low, @high] = [@high, @low]
 
   copy: ->
    newLow = @low
    newHigh = @high
    if typeof @low.copy == 'function'
      newLow = @low.copy()
    if typeof @high.copy == 'function'
      newHigh = @high.copy();
 
    new Uncertainty(newLow, newHigh)
 
  isPoint: () ->
    # Note: Can't use normal equality, as that fails for Javascript dates
    # TODO: Fix after we don't need to support Javascript date uncertainties anymore
    lte = (a, b) -> 
      if typeof a != typeof b
        return false
      if typeof a.sameOrBefore is 'function' then a.sameOrBefore b else a <= b
    gte = (a, b) -> 
      if typeof a != typeof b
        return false
      if typeof a.sameOrBefore is 'function' then a.sameOrAfter b else a >= b
    @low? and @high? and lte(@low, @high) and gte(@low, @high)
 
  equals: (other) ->
    other = Uncertainty.from other
    ThreeValuedLogic.not ThreeValuedLogic.or(@lessThan(other), @greaterThan(other))
 
  lessThan: (other) ->
    lt = (a, b) -> 
      if typeof a != typeof b then return false
      if typeof a.before is 'function' then a.before b else a < b
    other = Uncertainty.from other
    bestCase = not @low? or not other.high? or lt(@low, other.high)
    worstCase = @high? and other.low? and lt(@high, other.low)
    if bestCase is worstCase then return bestCase else return null
 
  greaterThan: (other) ->
    other = Uncertainty.from other
    other.lessThan @
 
  lessThanOrEquals: (other) ->
    other = Uncertainty.from other
    ThreeValuedLogic.not @greaterThan(other)
 
  greaterThanOrEquals: (other) ->
    other = Uncertainty.from other
    ThreeValuedLogic.not @lessThan(other)