1
0
Fork 0
zmodemjs/tests/zsession.js

313 lines
7.6 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
"use strict";
const test = require('tape');
const helper = require('./lib/testhelp');
global.Zmodem = require('./lib/zmodem');
var ZSession = Zmodem.Session;
var receiver, sender, sender_promise, received_file;
var offer;
function wait(seconds) {
return new Promise( resolve => setTimeout(_ => resolve("theValue"), 1000 * seconds) );
}
function _init(async) {
sender = null;
receiver = new Zmodem.Session.Receive();
/*
receiver.on("receive", function(hdr) {
console.log("Receiver input", hdr);
} );
receiver.on("offer", function(my_offer) {
//console.log("RECEIVED OFFER (window.offer)", my_offer);
offer = my_offer;
});
*/
var resolver;
sender_promise = new Promise( (res, rej) => { resolver = res; } );
function receiver_sender(bytes_arr) {
//console.log("receiver sending", String.fromCharCode.apply(String, bytes_arr), bytes_arr);
if (sender) {
var consumer = () => {
sender.consume(bytes_arr);
};
if (async) {
wait(0.5).then(consumer);
}
else consumer();
}
else {
var hdr = Zmodem.Header.parse(bytes_arr)[0];
sender = new Zmodem.Session.Send(hdr);
resolver(sender);
sender.set_sender( function(bytes_arr) {
var consumer = () => {
receiver.consume(bytes_arr);
};
if (async) {
wait(0.5).then(consumer);
}
else consumer();
} );
/*
sender.on("receive", function(hdr) {
console.log("Sender input", hdr);
} );
*/
}
}
receiver.set_sender(receiver_sender);
}
test('Sender receives extra ZRPOS', (t) => {
_init();
var zrinit = Zmodem.Header.build("ZRINIT", ["CANFDX", "CANOVIO", "ESCCTL"]);
var mysender = new Zmodem.Session.Send(zrinit);
var zrpos = Zmodem.Header.build("ZRPOS", 12345);
var err;
try {
mysender.consume(zrpos.to_hex());
}
catch(e) {
err = e;
}
t.match(err.toString(), /header/, "error as expected");
t.match(err.toString(), /ZRPOS/, "error as expected");
return Promise.resolve();
} );
test('Offer events', (t) => {
_init();
var inputs = [];
var completed = false;
var r_pms = receiver.start().then( (offer) => {
t.deepEquals(
offer.get_details(),
{
name: "my file",
size: 32,
mode: null,
mtime: null,
serial: null,
files_remaining: null,
bytes_remaining: null,
},
'get_details() returns expected values'
);
offer.on("input", (payload) => {
inputs.push(
{
offset: offer.get_offset(),
payload: payload,
}
);
} );
offer.on("complete", () => { completed = true });
return offer.accept();
} );
var s_pms = sender.send_offer(
{ name: "my file", size: 32 }
).then( (sender_xfer) => {
sender_xfer.send( [1, 2, 3] );
sender_xfer.send( [4, 5, 6, 7] );
sender_xfer.end( [8, 9] ).then( () => {
return sender.close();
} );
} );
return Promise.all( [ r_pms, s_pms ] ).then( () => {
t.deepEquals(
inputs,
[
{
payload: [1, 2, 3],
offset: 3,
},
{
payload: [4, 5, 6, 7],
offset: 7,
},
{
payload: [8, 9],
offset: 9,
},
],
'Offer “input” events',
);
t.ok( completed, 'Offer “complete” event' );
} );
} );
test('receive one, promises', (t) => {
_init();
var r_pms = receiver.start().then( (offer) => {
t.deepEquals(
offer.get_details(),
{
name: "my file",
size: 32,
mode: null,
mtime: null,
serial: null,
files_remaining: null,
bytes_remaining: null,
},
'get_details() returns expected values'
);
return offer.accept();
} );
//r_pms.then( () => { console.log("RECEIVER DONE") } );
var s_pms = sender.send_offer(
{ name: "my file", size: 32 }
).then( (sender_xfer) => {
sender_xfer.end( [12, 23, 34] ).then( () => {
return sender.close();
} );
} );
return Promise.all( [ r_pms, s_pms ] );
} );
test('receive one, events', (t) => {
_init();
var content = [ 1,2,3,4,5,6,7,8,9,2,3,5,1,5,33,2,23,7 ];
var now_epoch = Math.floor(Date.now() / 1000);
receiver.on("offer", (offer) => {
t.deepEquals(
offer.get_details(),
{
name: "my file",
size: content.length,
mode: parseInt("100644", 8),
mtime: new Date( now_epoch * 1000 ),
serial: null,
files_remaining: null,
bytes_remaining: null,
},
'get_details() returns expected values'
);
offer.accept();
} );
receiver.start();
return sender.send_offer( {
name: "my file",
size: content.length,
mtime: now_epoch,
mode: parseInt("0644", 8),
} ).then(
(sender_xfer) => {
sender_xfer.end(content).then( sender.close.bind(sender) );
}
);
} );
test('skip one, receive the next', (t) => {
_init();
var r_pms = receiver.start().then( (offer) => {
//console.log("first offer", offer);
t.equals( offer.get_details().name, "my file", "first files name" );
var next_pms = offer.skip();
//console.log("next", next_pms);
return next_pms;
} ).then( (offer) => {
t.equals( offer.get_details().name, "file 2", "second files name" );
return offer.skip();
} );
var s_pms = sender.send_offer(
{ name: "my file" }
).then(
(sender_xfer) => {
t.ok( !sender_xfer, "skip() -> sender sees no transfer object" );
return sender.send_offer( { name: "file 2" } );
}
).then(
(xfer) => {
t.ok( !xfer, "2nd skip() -> sender sees no transfer object" );
return sender.close();
}
);
return Promise.all( [ r_pms, s_pms ] );
} );
test('abort mid-download', (t) => {
_init();
var transferred_bytes = [];
var aborted;
var r_pms = receiver.start().then( (offer) => {
offer.on("input", (payload) => {
[].push.apply(transferred_bytes, payload);
if (aborted) throw "already aborted!";
aborted = true;
receiver.abort();
});
return offer.accept();
} );
var s_pms = sender.send_offer(
{ name: "my file" }
).then(
(xfer) => {
xfer.send( [1, 2, 3] );
xfer.end( [99, 99, 99] ); //should never get here
}
);
return Promise.all( [r_pms, s_pms] ).catch(
(err) => {
t.ok( err.message.match('abort'), 'error message is about abort' );
}
).then( () => {
t.deepEquals(
transferred_bytes,
[1, 2, 3],
'abort() stopped us from sending more',
);
} );
} );