All files / node-activedirectory/lib/client rangeretrievalspecifierattribute.js

22.73% Statements 10/44
0% Branches 0/26
0% Functions 0/9
23.26% Lines 10/43

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 1401x       1x                                                     1x                                               1x                                       1x                     1x                           1x                                     1x                         1x           1x  
var _ = require('underscore');
 
// [attribute];range=[low]-[high]
// matching: 1 = name, 2 = low, 3 = high
var pattern = '^([^;]+);range=(\\d+)-(.+)?$'; 
 
/**
 * Parses the range retrieval specifier into an object.
 * 
 * @private
 * @param {String} range The range retrieval specifier to parse.
 * @returns {RangeRetrievalSpecifier}
 */
function parseRangeRetrievalSpecifierAttribute(attribute) {
  var re = new RegExp(pattern, 'i');
  var match = re.exec(attribute);
  return({
    attributeName: match[1],
    low: parseInt(match[2]),
    high: parseInt(match[3]) || null
  });
};
 
/**
 * Multi-valued attribute range retreival specifier.
 *
 * @private
 * @constructor
 * @param {String|Object} attribute The actual attribute name. May also contain a full range retrieval specifier for parsing. (i.e. [attribute];range=[low]-[high]). Optionally an object can be specified.
 * @returns {RangeRetrievalSpecifierAttribute}
 */
var RangeRetrievalSpecifierAttribute = function(attribute) {
  if (this instanceof RangeRetrievalSpecifierAttribute) {
    if (! attribute) throw new Error('No attribute provided to create a range retrieval specifier.');
    if (typeof(attribute) === 'string') {
      attribute = parseRangeRetrievalSpecifierAttribute(attribute);
    }
 
    for(var property in attribute) {
      if (Array.prototype.hasOwnProperty.call(attribute, property)) {
        this[property] = attribute[property];
      }
    }
  }
  else {
    return(new RangeRetrievalSpecifierAttribute(attribute));
  }
}
 
/** 
 * Gets the next range retrieval specifier for a query.
 *
 * @private
 * @returns {String}
 */
RangeRetrievalSpecifierAttribute.prototype.next = function next() {
  var self = this;
 
  if ((self.high != null) && (self.high != self.low)) {
    var low = self.low;
    var high = self.high;
 
    self.low = high + 1;
    self.high = high + (high - low) + 1;
    return(this);
  }
  return(null);
}
 
/** 
 * Checks to see if the range specifier has been exhausted or completed.
 *
 * @private
 * @returns {Boolean}
 */
RangeRetrievalSpecifierAttribute.prototype.isComplete = function isComplete() {
  var self = this;
  return((self.high == null) || (typeof(self.high) === 'undefined'));
}
 
/** 
 * Gets the string representation of the range retrieval specifier.
 *
 * @private
 * @returns {String}
 */
RangeRetrievalSpecifierAttribute.prototype.toString = function toString() {
  var self = this;
 
  return(self.attributeName + ';range=' + self.low + '-' + (self.high ? self.high : '*'));
}
 
/**
 * Retrieves all of the attributes which have range attributes specified.
 * 
 * @private
 * @static
 * @param {Object} item The value to extract the range retrieval attributes from.
 * @returns {Array[RangeRetrievalSpecifierAttribute]}
 */
RangeRetrievalSpecifierAttribute.prototype.getRangeAttributes = function getRangeAttributes(item) {
  var attributes = [];
  for(var attribute in (item || {})) {
    if (RangeRetrievalSpecifierAttribute.prototype.isRangeAttribute(attribute)) {
      var range = new RangeRetrievalSpecifierAttribute(attribute);
      attributes.push(range);
    }
  }
  return(attributes.length > 0 ? attributes : null);
};
 
/**
 * Checks to see if the specified attribute is a range retrieval attribute.
 * 
 * @private
 * @static
 * @param {String} attribute The attribute to inspect.
 * @returns {Boolean}
 */
RangeRetrievalSpecifierAttribute.prototype.isRangeAttribute = function isRangeAttribute(attribute) {
  var re = new RegExp(pattern, 'i');
  return(re.test(attribute));
};
 
/**
 * Checks to see if the specified object has any range retrieval attributes.
 * 
 * @private
 * @static
 * @param {Object} item The value to check for range retrieval specifiers.
 * @returns {Boolean}
 */
RangeRetrievalSpecifierAttribute.prototype.hasRangeAttributes = function hasRangeAttributes(item) {
  return(_.any(_.keys(item || {}), function(attribute) {
    return(RangeRetrievalSpecifierAttribute.prototype.isRangeAttribute(attribute));
  }));
};
 
module.exports = RangeRetrievalSpecifierAttribute;