21 changed files with 2674 additions and 28 deletions
@ -1,4 +1,4 @@ |
|||
{ |
|||
"extends": "@joepie91/eslint-config", |
|||
"ignorePatterns": "test/**" |
|||
"ignorePatterns": "test-old/**" |
|||
} |
|||
|
@ -0,0 +1,45 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const pEvent = require("p-event"); |
|||
const pStream = require("p-stream"); |
|||
|
|||
module.exports = function fetch(client, args, options = {}) { |
|||
return new Promise((resolve, reject) => { |
|||
let attributeResults = []; |
|||
let bodyInfoResults = []; |
|||
let bodyPromises = []; |
|||
|
|||
let fetchOp = client.seq.fetch(... args); |
|||
|
|||
fetchOp.on("end", () => { |
|||
resolve(Promise.try(() => { |
|||
if (options.onEnd != null) { |
|||
return options.onEnd(); |
|||
} |
|||
}).then(() => { |
|||
return Promise.all(bodyPromises); |
|||
}).then((bodies) => { |
|||
return { |
|||
attributeResults, |
|||
bodyInfoResults, |
|||
bodies |
|||
}; |
|||
})); |
|||
}); |
|||
|
|||
fetchOp.on("message", (message) => { |
|||
message.on("attributes", (attributes) => { |
|||
attributeResults.push(attributes); |
|||
}); |
|||
|
|||
message.on("body", (bodyStream, info) => { |
|||
bodyInfoResults.push(info); |
|||
|
|||
bodyPromises.push(pStream(bodyStream)); |
|||
}); |
|||
}); |
|||
|
|||
pEvent(fetchOp, "error").then(reject); |
|||
}); |
|||
}; |
@ -0,0 +1,9 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function concatenateLines(lines, includeTrailingNewline = true) { |
|||
let allLines = (includeTrailingNewline) |
|||
? lines.concat([ "" ]) |
|||
: lines; |
|||
|
|||
return allLines.filter((line) => line != null).join("\r\n"); |
|||
}; |
@ -0,0 +1,66 @@ |
|||
"use strict"; |
|||
|
|||
const net = require("net"); |
|||
const Promise = require("bluebird"); |
|||
const chalk = require("chalk"); |
|||
|
|||
const CRLF = "\r\n"; |
|||
|
|||
module.exports = function createMockServer({ steps, test, handle = ()=>{} }) { |
|||
let counter = 0; |
|||
|
|||
const server = net.createServer((socket) => { |
|||
let buffer = ""; |
|||
|
|||
socket.write("* OK asdf\r\n"); |
|||
|
|||
socket.on("data", (data) => { |
|||
buffer += data.toString("utf8"); |
|||
|
|||
if (buffer.includes(CRLF)) { |
|||
let lines = buffer.split(CRLF); |
|||
buffer = lines.pop(); |
|||
|
|||
Promise.map(lines, (line) => { |
|||
return Promise.try(() => { |
|||
console.log(chalk.gray(line)); |
|||
|
|||
return handle(line); |
|||
}).then((result) => { |
|||
if (result == null) { |
|||
let step = steps[counter]; |
|||
counter += 1; |
|||
|
|||
if (step.expected != null) { |
|||
test.same(line, step.expected); |
|||
} |
|||
|
|||
return (typeof step.response === "function") |
|||
? step.response() |
|||
: step.response; |
|||
} else { |
|||
return result; |
|||
} |
|||
}).then((response) => { |
|||
socket.write(response); |
|||
}); |
|||
}, { concurrency: 1 }); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
return new Promise((resolve, reject) => { |
|||
server.listen(0, "127.0.0.1", () => { |
|||
// FIXME: Error condition?
|
|||
resolve({ |
|||
server: server, |
|||
port: server.address().port, |
|||
finalize: function () { |
|||
if (counter < steps.length) { |
|||
test.ok(false, `Mock server expected ${steps.length} steps but only saw ${counter}`); |
|||
} |
|||
} |
|||
}); |
|||
}); |
|||
}); |
|||
}; |
@ -0,0 +1,150 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const tap = require("tap"); |
|||
const pEvent = require("p-event"); |
|||
const IMAP = require("../.."); |
|||
|
|||
const lines = require("../lines"); |
|||
const createMockServer = require("../mock-server"); |
|||
const fetch = require("../fetch"); |
|||
|
|||
tap.test("fetch-with-uid", (test) => { |
|||
return testFetch(test, true, false); |
|||
}); |
|||
|
|||
tap.test("fetch-without-uid", (test) => { |
|||
return testFetch(test, false, false); |
|||
}); |
|||
|
|||
tap.test("fetch-with-body", (test) => { |
|||
return testFetch(test, true, true); |
|||
}); |
|||
|
|||
function testFetch(test, withUID, withBody) { |
|||
let steps = [{ |
|||
expected: 'A0 CAPABILITY', |
|||
response: lines([ |
|||
'* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN', |
|||
'A0 OK Thats all she wrote!', |
|||
]), |
|||
}, { |
|||
expected: 'A1 LOGIN "foo" "bar"', |
|||
response: lines([ |
|||
'* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN UIDPLUS MOVE', |
|||
'A1 OK authenticated (Success)', |
|||
]), |
|||
}, { |
|||
expected: 'A2 NAMESPACE', |
|||
response: lines([ |
|||
'* NAMESPACE (("" "/")) NIL NIL', |
|||
'A2 OK Success', |
|||
]), |
|||
}, { |
|||
expected: 'A3 LIST "" ""', |
|||
response: lines([ |
|||
'* LIST (\\Noselect) "/" "/"', |
|||
'A3 OK Success', |
|||
]), |
|||
}, { |
|||
expected: 'A4 EXAMINE "INBOX"', |
|||
response: lines([ |
|||
'* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)', |
|||
'* OK [PERMANENTFLAGS ()] Flags permitted.', |
|||
'* OK [UIDVALIDITY 2] UIDs valid.', |
|||
'* 685 EXISTS', |
|||
'* 0 RECENT', |
|||
'* OK [UIDNEXT 4422] Predicted next UID.', |
|||
'A4 OK [READ-ONLY] INBOX selected. (Success)', |
|||
]), |
|||
}, { |
|||
expected: (withBody) |
|||
? 'A5 FETCH 1 (UID FLAGS INTERNALDATE BODY.PEEK[TEXT])' |
|||
: 'A5 FETCH 1 (UID FLAGS INTERNALDATE)', |
|||
response: lines([ |
|||
'* 1 FETCH (UID 1)', |
|||
`* 1 FETCH (INTERNALDATE "05-Sep-2004 00:38:03 +0000"${(withUID) ? " UID 1000" : ""})`, |
|||
(withBody) |
|||
? '* 1 FETCH (BODY[TEXT] "IMAP is terrible")' |
|||
: null, |
|||
'* 1 FETCH (FLAGS (\\Seen))', |
|||
'A5 OK Success', |
|||
]), |
|||
}, { |
|||
expected: "A6 LOGOUT", |
|||
response: lines([ |
|||
'* BYE LOGOUT Requested', |
|||
'A6 OK good day (Success)', |
|||
]), |
|||
}]; |
|||
|
|||
return Promise.try(() => { |
|||
let continuationWasSent; |
|||
|
|||
return createMockServer({ |
|||
steps: steps, |
|||
test: test, |
|||
// NOTE: Anything handled here is not matched against steps, nor is the counter incremented
|
|||
handle: function (line) { |
|||
if (line === "IDLE IDLE") { |
|||
continuationWasSent = true; |
|||
|
|||
return Promise.delay(100).then(() => { |
|||
return lines([ "+ idling" ]); |
|||
}); |
|||
} else if (line === "DONE") { |
|||
test.ok(continuationWasSent, "DONE seen before continuation sent"); |
|||
continuationWasSent = false; |
|||
return lines([ "IDLE ok" ]); |
|||
} |
|||
} |
|||
}); |
|||
}).then(({ server, port, finalize }) => { |
|||
const client = new IMAP({ |
|||
user: "foo", |
|||
password: "bar", |
|||
host: "127.0.0.1", |
|||
port: port, |
|||
keepalive: false |
|||
}); |
|||
|
|||
Promise.promisifyAll(client, { multiArgs: true }); |
|||
client.connect(); |
|||
|
|||
return Promise.try(() => { |
|||
return pEvent(client, "ready"); |
|||
}).then(() => { |
|||
server.close(); // Stop listening for new clients
|
|||
|
|||
return client.openBoxAsync("INBOX", true); |
|||
}).then(() => { |
|||
return fetch( client, |
|||
(withBody) |
|||
? [ 1, { bodies: [ "TEXT" ] } ] |
|||
: [ 1 ] |
|||
); |
|||
}).tap(() => { |
|||
client.end(); |
|||
|
|||
return pEvent(client, "end"); |
|||
}).then(({ attributeResults, bodyInfoResults, bodies }) => { |
|||
finalize(); |
|||
|
|||
test.same(attributeResults, [{ |
|||
uid: 1, |
|||
date: new Date('05-Sep-2004 00:38:03 +0000'), |
|||
flags: [ '\\Seen' ] |
|||
}]); |
|||
|
|||
if (withBody) { |
|||
test.same(bodies, [ Buffer.from('IMAP is terrible') ]); |
|||
|
|||
test.same(bodyInfoResults, [{ |
|||
seqno: 1, |
|||
which: 'TEXT', |
|||
size: 16 |
|||
}]); |
|||
} |
|||
}); |
|||
}); |
|||
} |
@ -0,0 +1,154 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const tap = require("tap"); |
|||
const pEvent = require("p-event"); |
|||
const IMAP = require("../.."); |
|||
|
|||
const lines = require("../lines"); |
|||
const createMockServer = require("../mock-server"); |
|||
const fetch = require("../fetch"); |
|||
|
|||
tap.test("idle-with-delay", (test) => { |
|||
return testIdle(test, true); |
|||
}); |
|||
|
|||
tap.test("idle-without-delay", (test) => { |
|||
return testIdle(test, false); |
|||
}); |
|||
|
|||
function testIdle(test, withDelay) { |
|||
let steps = [{ |
|||
expected: 'A0 CAPABILITY', |
|||
response: lines([ |
|||
'* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN', |
|||
'A0 OK Thats all she wrote!', |
|||
]), |
|||
}, { |
|||
expected: 'A1 LOGIN "foo" "bar"', |
|||
response: lines([ |
|||
'* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA CHILDREN UIDPLUS MOVE', |
|||
'A1 OK authenticated (Success)', |
|||
]), |
|||
}, { |
|||
expected: 'A2 NAMESPACE', |
|||
response: lines([ |
|||
'* NAMESPACE (("" "/")) NIL NIL', |
|||
'A2 OK Success', |
|||
]), |
|||
}, { |
|||
expected: 'A3 LIST "" ""', |
|||
response: lines([ |
|||
'* LIST (\\Noselect) "/" "/"', |
|||
'A3 OK Success', |
|||
]), |
|||
}, { |
|||
expected: 'A4 EXAMINE "INBOX"', |
|||
response: lines([ |
|||
'* FLAGS (\\Answered \\Flagged \\Draft \\Deleted \\Seen)', |
|||
'* OK [PERMANENTFLAGS ()] Flags permitted.', |
|||
'* OK [UIDVALIDITY 2] UIDs valid.', |
|||
'* 685 EXISTS', |
|||
'* 0 RECENT', |
|||
'* OK [UIDNEXT 4422] Predicted next UID.', |
|||
'A4 OK [READ-ONLY] INBOX selected. (Success)' |
|||
]), |
|||
}, { |
|||
expected: 'A5 FETCH 1 (UID FLAGS INTERNALDATE BODY.PEEK[TEXT])', |
|||
response: lines([ |
|||
'* 1 FETCH (UID 1)', |
|||
'* 1 FETCH (INTERNALDATE "05-Sep-2004 00:38:03 +0000" UID 1000)', |
|||
'* 1 FETCH (BODY[TEXT] "IMAP is terrible")', |
|||
'* 1 FETCH (FLAGS (\\Seen))', |
|||
'A5 OK Success', |
|||
]), |
|||
}, { |
|||
expected: 'A6 STATUS "test" (MESSAGES RECENT UNSEEN UIDVALIDITY UIDNEXT)', |
|||
response: lines([ |
|||
'* STATUS test (MESSAGES 231 RECENT 0 UNSEEN 0 UIDVALIDITY 123 UIDNEXT 442)', |
|||
'A6 OK STATUS completed', |
|||
]), |
|||
}, { |
|||
expected: 'A7 LOGOUT', |
|||
response: lines([ |
|||
'* BYE LOGOUT Requested', |
|||
'A7 OK good day (Success)', |
|||
]), |
|||
}]; |
|||
|
|||
return Promise.try(() => { |
|||
let continuationWasSent; |
|||
|
|||
return createMockServer({ |
|||
steps: steps, |
|||
test: test, |
|||
// NOTE: Anything handled here is not matched against steps, nor is the counter incremented
|
|||
handle: function (line) { |
|||
if (line === "IDLE IDLE") { |
|||
continuationWasSent = true; |
|||
|
|||
return Promise.delay(100).then(() => { |
|||
return lines([ "+ idling" ]); |
|||
}); |
|||
} else if (line === "DONE") { |
|||
test.ok(continuationWasSent, "DONE seen before continuation sent"); |
|||
continuationWasSent = false; |
|||
return lines([ "IDLE ok" ]); |
|||
} |
|||
} |
|||
}); |
|||
}).then(({ server, port, finalize }) => { |
|||
const client = new IMAP({ |
|||
user: "foo", |
|||
password: "bar", |
|||
host: "127.0.0.1", |
|||
port: port, |
|||
keepalive: true // NOTE: Different in other tests!
|
|||
}); |
|||
|
|||
Promise.promisifyAll(client, { multiArgs: true }); |
|||
client.connect(); |
|||
|
|||
return Promise.try(() => { |
|||
return pEvent(client, "ready"); |
|||
}).then(() => { |
|||
server.close(); // Stop listening for new clients
|
|||
|
|||
return client.openBoxAsync("INBOX", true); |
|||
}).then(() => { |
|||
return fetch( client, |
|||
[ 1, { bodies: [ "TEXT" ] } ] |
|||
); |
|||
}).tap(() => { |
|||
return Promise.try(() => { |
|||
if (withDelay) { |
|||
return Promise.delay(500); |
|||
} |
|||
}).then(() => { |
|||
return Promise.try(() => { |
|||
return client.statusAsync("test"); |
|||
}).then((_status) => { |
|||
client.end(); |
|||
|
|||
return pEvent(client, "end"); |
|||
}).timeout(500, "Timed out waiting for STATUS"); |
|||
}); |
|||
}).then(({ attributeResults, bodyInfoResults, bodies }) => { |
|||
finalize(); |
|||
|
|||
test.same(attributeResults, [{ |
|||
uid: 1, |
|||
date: new Date('05-Sep-2004 00:38:03 +0000'), |
|||
flags: [ '\\Seen' ] |
|||
}]); |
|||
|
|||
test.same(bodies, [ Buffer.from('IMAP is terrible') ]); |
|||
|
|||
test.same(bodyInfoResults, [{ |
|||
seqno: 1, |
|||
which: 'TEXT', |
|||
size: 16 |
|||
}]); |
|||
}); |
|||
}); |
|||
} |
@ -0,0 +1,245 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const pEvent = require("p-event"); |
|||
const tap = require("tap"); |
|||
const BL = require("bl"); |
|||
const { Parser } = require("../../lib/Parser"); |
|||
|
|||
tap.test("parse-session", (test) => { |
|||
let session = ` |
|||
Server: * PREAUTH [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE ACL RIGHTS=texk] Logged in as m.markov at domain.com |
|||
Client: 1 LIST "" "*" |
|||
Server: * LIST (\\HasNoChildren) "/" confirmed-spam |
|||
Server: * LIST (\\HasNoChildren \\Trash) "/" Trash |
|||
Server: * LIST (\\HasNoChildren) "/" SpamLikely |
|||
Server: * LIST (\\HasNoChildren) "/" Spam |
|||
Server: * LIST (\\HasNoChildren) "/" "Sent Items" |
|||
Server: * LIST (\\HasNoChildren) "/" Archive |
|||
Server: * LIST (\\HasNoChildren \\Drafts) "/" Drafts |
|||
Server: * LIST (\\HasNoChildren) "/" Notes |
|||
Server: * LIST (\\HasNoChildren) "/" TeamViewer |
|||
Server: * LIST (\\HasNoChildren \\Sent) "/" "Sent Messages" |
|||
Server: * LIST (\\HasNoChildren) "/" confirmed-ham |
|||
Server: * LIST (\\Noselect \\HasChildren) "/" Public |
|||
Server: * LIST (\\HasNoChildren) "/" Public/office3 |
|||
Server: * LIST (\\HasNoChildren) "/" Public/office4 |
|||
Server: * LIST (\\HasNoChildren) "/" Public/support |
|||
Server: * LIST (\\HasNoChildren) "/" Public/root |
|||
Server: * LIST (\\HasNoChildren) "/" Public/updates |
|||
Server: * LIST (\\HasNoChildren) "/" Public/postmaster |
|||
Server: * LIST (\\Noselect \\HasChildren) "/" Shared |
|||
Server: * LIST (\\Noselect \\HasChildren) "/" Shared/d.marteva |
|||
Server: * LIST (\\HasNoChildren) "/" Shared/d.marteva/INBOX |
|||
Server: * LIST (\\HasNoChildren) "/" INBOX |
|||
Server: 1 OK List completed. |
|||
Client: 2 LOGOUT |
|||
`.replace(/\n/g, "\r\n").replace(/^\t+/gm, "");
|
|||
|
|||
let serverSession = session |
|||
.split("\n") |
|||
.filter((line) => line.startsWith("Server:")) |
|||
.map((line) => line.replace(/^Server: /, "")) |
|||
.join("\n"); |
|||
|
|||
let serverBuffer = new BL([ Buffer.from(serverSession) ]); |
|||
|
|||
let expectedResults = [{ |
|||
"type": "preauth", |
|||
"textCode": { |
|||
"key": "CAPABILITY", |
|||
"val": ["IMAP4rev1", "LITERAL+", "SASL-IR", "LOGIN-REFERRALS", "ID", "ENABLE", "IDLE", "SORT", "SORT=DISPLAY", "THREAD=REFERENCES", "THREAD=REFS", "THREAD=ORDEREDSUBJECT", "MULTIAPPEND", "URL-PARTIAL", "CATENATE", "UNSELECT", "CHILDREN", "NAMESPACE", "UIDPLUS", "LIST-EXTENDED", "I18NLEVEL=1", "CONDSTORE", "QRESYNC", "ESEARCH", "ESORT", "SEARCHRES", "WITHIN", "CONTEXT=SEARCH", "LIST-STATUS", "SPECIAL-USE", "BINARY", "MOVE", "ACL", "RIGHTS=texk"] |
|||
}, |
|||
"text": "Logged in as m.markov at domain.com" |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "confirmed-spam" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren", "\\Trash"], |
|||
"delimiter": "/", |
|||
"name": "Trash" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "SpamLikely" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Spam" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Sent Items" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Archive" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren", "\\Drafts"], |
|||
"delimiter": "/", |
|||
"name": "Drafts" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Notes" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "TeamViewer" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren", "\\Sent"], |
|||
"delimiter": "/", |
|||
"name": "Sent Messages" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "confirmed-ham" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\Noselect", "\\HasChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/office3" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/office4" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/support" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/root" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/updates" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Public/postmaster" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\Noselect", "\\HasChildren"], |
|||
"delimiter": "/", |
|||
"name": "Shared" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\Noselect", "\\HasChildren"], |
|||
"delimiter": "/", |
|||
"name": "Shared/d.marteva" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "Shared/d.marteva/INBOX" |
|||
} |
|||
}, { |
|||
"type": "list", |
|||
"text": { |
|||
"flags": ["\\HasNoChildren"], |
|||
"delimiter": "/", |
|||
"name": "INBOX" |
|||
} |
|||
}]; |
|||
|
|||
let stream = new BL.BufferListStream(serverBuffer); |
|||
let parser = new Parser(stream); |
|||
let results = []; |
|||
|
|||
parser.on("tagged", (item) => { |
|||
// console.log("tagged", item);
|
|||
results.push(item); |
|||
}); |
|||
|
|||
parser.on("untagged", (item) => { |
|||
// console.log("untagged", item);
|
|||
results.push(item); |
|||
}); |
|||
|
|||
parser.on("continue", (... args) => { |
|||
// console.log("continue", args);
|
|||
}); |
|||
|
|||
parser.on("other", (... args) => { |
|||
// console.log("other", args);
|
|||
}); |
|||
|
|||
parser.on("body", (... args) => { |
|||
// console.log("body", args);
|
|||
}); |
|||
|
|||
return Promise.try(() => { |
|||
// NOTE: Parser does not expose an 'end' event
|
|||
return pEvent(stream, "end"); |
|||
}).then(() => { |
|||
// Hack for clearing out `undefined` properties
|
|||
let normalizedResults = JSON.parse(JSON.stringify(results)); |
|||
|
|||
test.same(normalizedResults, expectedResults); |
|||
}); |
|||
}); |
File diff suppressed because it is too large
Loading…
Reference in new issue