Comparing version 0.8.6 to 0.8.7
@@ -10,2 +10,3 @@ var tls = require('tls'), | ||
var Parser = require('./Parser').Parser, | ||
parseExpr = require('./Parser').parseExpr, | ||
parseHeader = require('./Parser').parseHeader; | ||
@@ -168,8 +169,15 @@ | ||
var idx = toget.indexOf('BODY[' + info.which + ']'); | ||
if (idx > -1) { | ||
toget.splice(idx, 1); | ||
msg.msgEmitter.emit('body', stream, info); | ||
} else | ||
stream.resume(); // a body we didn't ask for? | ||
// here we compare the parsed version of the expression inside BODY[] | ||
// because 'HEADER.FIELDS (TO FROM)' really is equivalent to | ||
// 'HEADER.FIELDS ("TO" "FROM")' and some servers will actually send the | ||
// quoted form even if the client did not use quotes | ||
var thisbody = parseExpr(info.which); | ||
for (var i = 0, len = toget.length; i < len; ++i) { | ||
if (_deepEqual(thisbody, toget[i])) { | ||
toget.splice(i, 1); | ||
msg.msgEmitter.emit('body', stream, info); | ||
return; | ||
} | ||
} | ||
stream.resume(); // a body we didn't ask for? | ||
}); | ||
@@ -734,3 +742,3 @@ parser.on('continue', function(info) { | ||
for (i = 0, len = bodies.length; i < len; ++i) { | ||
fetching.push('BODY[' + bodies[i] + ']'); | ||
fetching.push(parseExpr(bodies[i])); | ||
cmd += ' BODY' + prefix + '[' + bodies[i] + ']'; | ||
@@ -1866,1 +1874,96 @@ } | ||
} | ||
// Pulled from assert.deepEqual: | ||
var pSlice = Array.prototype.slice; | ||
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 If the expected value is a RegExp object, the actual value is | ||
// equivalent if it is also a RegExp object with the same source and | ||
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). | ||
} else if (actual instanceof RegExp && expected instanceof RegExp) { | ||
return actual.source === expected.source && | ||
actual.global === expected.global && | ||
actual.multiline === expected.multiline && | ||
actual.lastIndex === expected.lastIndex && | ||
actual.ignoreCase === expected.ignoreCase; | ||
// 7.4. 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.5 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) { | ||
var ka, kb, key, i; | ||
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 { | ||
ka = Object.keys(a); | ||
kb = Object.keys(b); | ||
} 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; | ||
} |
{ "name": "imap", | ||
"version": "0.8.6", | ||
"version": "0.8.7", | ||
"author": "Brian White <mscdex@mscdex.net>", | ||
@@ -8,3 +8,3 @@ "description": "An IMAP module for node.js that makes communicating with IMAP servers easy", | ||
"utf7": "1.0.0", | ||
"readable-stream": "1.1.9" | ||
"readable-stream": "1.1.x" | ||
}, | ||
@@ -11,0 +11,0 @@ "scripts": { |
781662
7886
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@0.0.1(transitive)
+ Addedreadable-stream@1.1.14(transitive)
+ Addedstring_decoder@0.10.31(transitive)
- Removeddebuglog@0.0.2(transitive)
- Removedreadable-stream@1.1.9(transitive)
Updatedreadable-stream@1.1.x