315 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			315 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// UTILITY
 | 
						|
var util = require('util');
 | 
						|
var Buffer = require("buffer").Buffer;
 | 
						|
var pSlice = Array.prototype.slice;
 | 
						|
 | 
						|
function objectKeys(object) {
 | 
						|
  if (Object.keys) return Object.keys(object);
 | 
						|
  var result = [];
 | 
						|
  for (var name in object) {
 | 
						|
    if (Object.prototype.hasOwnProperty.call(object, name)) {
 | 
						|
      result.push(name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
// 1. The assert module provides functions that throw
 | 
						|
// AssertionError's when particular conditions are not met. The
 | 
						|
// assert module must conform to the following interface.
 | 
						|
 | 
						|
var assert = module.exports = ok;
 | 
						|
 | 
						|
// 2. The AssertionError is defined in assert.
 | 
						|
// new assert.AssertionError({ message: message,
 | 
						|
//                             actual: actual,
 | 
						|
//                             expected: expected })
 | 
						|
 | 
						|
assert.AssertionError = function AssertionError(options) {
 | 
						|
  this.name = 'AssertionError';
 | 
						|
  this.message = options.message;
 | 
						|
  this.actual = options.actual;
 | 
						|
  this.expected = options.expected;
 | 
						|
  this.operator = options.operator;
 | 
						|
  var stackStartFunction = options.stackStartFunction || fail;
 | 
						|
 | 
						|
  if (Error.captureStackTrace) {
 | 
						|
    Error.captureStackTrace(this, stackStartFunction);
 | 
						|
  }
 | 
						|
};
 | 
						|
util.inherits(assert.AssertionError, Error);
 | 
						|
 | 
						|
function replacer(key, value) {
 | 
						|
  if (value === undefined) {
 | 
						|
    return '' + value;
 | 
						|
  }
 | 
						|
  if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) {
 | 
						|
    return value.toString();
 | 
						|
  }
 | 
						|
  if (typeof value === 'function' || value instanceof RegExp) {
 | 
						|
    return value.toString();
 | 
						|
  }
 | 
						|
  return value;
 | 
						|
}
 | 
						|
 | 
						|
function truncate(s, n) {
 | 
						|
  if (typeof s == 'string') {
 | 
						|
    return s.length < n ? s : s.slice(0, n);
 | 
						|
  } else {
 | 
						|
    return s;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
assert.AssertionError.prototype.toString = function() {
 | 
						|
  if (this.message) {
 | 
						|
    return [this.name + ':', this.message].join(' ');
 | 
						|
  } else {
 | 
						|
    return [
 | 
						|
      this.name + ':',
 | 
						|
      truncate(JSON.stringify(this.actual, replacer), 128),
 | 
						|
      this.operator,
 | 
						|
      truncate(JSON.stringify(this.expected, replacer), 128)
 | 
						|
    ].join(' ');
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// assert.AssertionError instanceof Error
 | 
						|
 | 
						|
assert.AssertionError.__proto__ = Error.prototype;
 | 
						|
 | 
						|
// At present only the three keys mentioned above are used and
 | 
						|
// understood by the spec. Implementations or sub modules can pass
 | 
						|
// other keys to the AssertionError's constructor - they will be
 | 
						|
// ignored.
 | 
						|
 | 
						|
// 3. All of the following functions must throw an AssertionError
 | 
						|
// when a corresponding condition is not met, with a message that
 | 
						|
// may be undefined if not provided.  All assertion methods provide
 | 
						|
// both the actual and expected values to the assertion error for
 | 
						|
// display purposes.
 | 
						|
 | 
						|
function fail(actual, expected, message, operator, stackStartFunction) {
 | 
						|
  throw new assert.AssertionError({
 | 
						|
    message: message,
 | 
						|
    actual: actual,
 | 
						|
    expected: expected,
 | 
						|
    operator: operator,
 | 
						|
    stackStartFunction: stackStartFunction
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
// EXTENSION! allows for well behaved errors defined elsewhere.
 | 
						|
assert.fail = fail;
 | 
						|
 | 
						|
// 4. Pure assertion tests whether a value is truthy, as determined
 | 
						|
// by !!guard.
 | 
						|
// assert.ok(guard, message_opt);
 | 
						|
// This statement is equivalent to assert.equal(true, guard,
 | 
						|
// message_opt);. To test strictly for the value true, use
 | 
						|
// assert.strictEqual(true, guard, message_opt);.
 | 
						|
 | 
						|
function ok(value, message) {
 | 
						|
  if (!!!value) fail(value, true, message, '==', assert.ok);
 | 
						|
}
 | 
						|
assert.ok = ok;
 | 
						|
 | 
						|
// 5. The equality assertion tests shallow, coercive equality with
 | 
						|
// ==.
 | 
						|
// assert.equal(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.equal = function equal(actual, expected, message) {
 | 
						|
  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
 | 
						|
};
 | 
						|
 | 
						|
// 6. The non-equality assertion tests for whether two objects are not equal
 | 
						|
// with != assert.notEqual(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.notEqual = function notEqual(actual, expected, message) {
 | 
						|
  if (actual == expected) {
 | 
						|
    fail(actual, expected, message, '!=', assert.notEqual);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// 7. The equivalence assertion tests a deep equality relation.
 | 
						|
// assert.deepEqual(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.deepEqual = function deepEqual(actual, expected, message) {
 | 
						|
  if (!_deepEqual(actual, expected)) {
 | 
						|
    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
function _deepEqual(actual, expected) {
 | 
						|
  // 7.1. All identical values are equivalent, as determined by ===.
 | 
						|
  if (actual === expected) {
 | 
						|
    return true;
 | 
						|
 | 
						|
  } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
 | 
						|
    if (actual.length != expected.length) return false;
 | 
						|
 | 
						|
    for (var i = 0; i < actual.length; i++) {
 | 
						|
      if (actual[i] !== expected[i]) return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
 | 
						|
  // 7.2. If the expected value is a Date object, the actual value is
 | 
						|
  // equivalent if it is also a Date object that refers to the same time.
 | 
						|
  } else if (actual instanceof Date && expected instanceof Date) {
 | 
						|
    return actual.getTime() === expected.getTime();
 | 
						|
 | 
						|
  // 7.3. Other pairs that do not both pass typeof value == 'object',
 | 
						|
  // equivalence is determined by ==.
 | 
						|
  } else if (typeof actual != 'object' && typeof expected != 'object') {
 | 
						|
    return actual == expected;
 | 
						|
 | 
						|
  // 7.4. For all other Object pairs, including Array objects, equivalence is
 | 
						|
  // determined by having the same number of owned properties (as verified
 | 
						|
  // with Object.prototype.hasOwnProperty.call), the same set of keys
 | 
						|
  // (although not necessarily the same order), equivalent values for every
 | 
						|
  // corresponding key, and an identical 'prototype' property. Note: this
 | 
						|
  // accounts for both named and indexed properties on Arrays.
 | 
						|
  } else {
 | 
						|
    return objEquiv(actual, expected);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function isUndefinedOrNull(value) {
 | 
						|
  return value === null || value === undefined;
 | 
						|
}
 | 
						|
 | 
						|
function isArguments(object) {
 | 
						|
  return Object.prototype.toString.call(object) == '[object Arguments]';
 | 
						|
}
 | 
						|
 | 
						|
function objEquiv(a, b) {
 | 
						|
  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
 | 
						|
    return false;
 | 
						|
  // an identical 'prototype' property.
 | 
						|
  if (a.prototype !== b.prototype) return false;
 | 
						|
  //~~~I've managed to break Object.keys through screwy arguments passing.
 | 
						|
  //   Converting to array solves the problem.
 | 
						|
  if (isArguments(a)) {
 | 
						|
    if (!isArguments(b)) {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    a = pSlice.call(a);
 | 
						|
    b = pSlice.call(b);
 | 
						|
    return _deepEqual(a, b);
 | 
						|
  }
 | 
						|
  try {
 | 
						|
    var ka = objectKeys(a),
 | 
						|
        kb = objectKeys(b),
 | 
						|
        key, i;
 | 
						|
  } catch (e) {//happens when one is a string literal and the other isn't
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
  // having the same number of owned properties (keys incorporates
 | 
						|
  // hasOwnProperty)
 | 
						|
  if (ka.length != kb.length)
 | 
						|
    return false;
 | 
						|
  //the same set of keys (although not necessarily the same order),
 | 
						|
  ka.sort();
 | 
						|
  kb.sort();
 | 
						|
  //~~~cheap key test
 | 
						|
  for (i = ka.length - 1; i >= 0; i--) {
 | 
						|
    if (ka[i] != kb[i])
 | 
						|
      return false;
 | 
						|
  }
 | 
						|
  //equivalent values for every corresponding key, and
 | 
						|
  //~~~possibly expensive deep test
 | 
						|
  for (i = ka.length - 1; i >= 0; i--) {
 | 
						|
    key = ka[i];
 | 
						|
    if (!_deepEqual(a[key], b[key])) return false;
 | 
						|
  }
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
// 8. The non-equivalence assertion tests for any deep inequality.
 | 
						|
// assert.notDeepEqual(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
 | 
						|
  if (_deepEqual(actual, expected)) {
 | 
						|
    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// 9. The strict equality assertion tests strict equality, as determined by ===.
 | 
						|
// assert.strictEqual(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.strictEqual = function strictEqual(actual, expected, message) {
 | 
						|
  if (actual !== expected) {
 | 
						|
    fail(actual, expected, message, '===', assert.strictEqual);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// 10. The strict non-equality assertion tests for strict inequality, as
 | 
						|
// determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
 | 
						|
 | 
						|
assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
 | 
						|
  if (actual === expected) {
 | 
						|
    fail(actual, expected, message, '!==', assert.notStrictEqual);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
function expectedException(actual, expected) {
 | 
						|
  if (!actual || !expected) {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  if (expected instanceof RegExp) {
 | 
						|
    return expected.test(actual);
 | 
						|
  } else if (actual instanceof expected) {
 | 
						|
    return true;
 | 
						|
  } else if (expected.call({}, actual) === true) {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
function _throws(shouldThrow, block, expected, message) {
 | 
						|
  var actual;
 | 
						|
 | 
						|
  if (typeof expected === 'string') {
 | 
						|
    message = expected;
 | 
						|
    expected = null;
 | 
						|
  }
 | 
						|
 | 
						|
  try {
 | 
						|
    block();
 | 
						|
  } catch (e) {
 | 
						|
    actual = e;
 | 
						|
  }
 | 
						|
 | 
						|
  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
 | 
						|
            (message ? ' ' + message : '.');
 | 
						|
 | 
						|
  if (shouldThrow && !actual) {
 | 
						|
    fail('Missing expected exception' + message);
 | 
						|
  }
 | 
						|
 | 
						|
  if (!shouldThrow && expectedException(actual, expected)) {
 | 
						|
    fail('Got unwanted exception' + message);
 | 
						|
  }
 | 
						|
 | 
						|
  if ((shouldThrow && actual && expected &&
 | 
						|
      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
 | 
						|
    throw actual;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// 11. Expected to throw an error:
 | 
						|
// assert.throws(block, Error_opt, message_opt);
 | 
						|
 | 
						|
assert.throws = function(block, /*optional*/error, /*optional*/message) {
 | 
						|
  _throws.apply(this, [true].concat(pSlice.call(arguments)));
 | 
						|
};
 | 
						|
 | 
						|
// EXTENSION! This is annoying to write outside this module.
 | 
						|
assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
 | 
						|
  _throws.apply(this, [false].concat(pSlice.call(arguments)));
 | 
						|
};
 | 
						|
 | 
						|
assert.ifError = function(err) { if (err) {throw err;}};
 |