1
0
Fork 0
zmodemjs/tests/zsession.js
Daniel Baumann 4d3e0bf859
Adding upstream version 0.1.10+dfsg.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-04-22 16:48:36 +02:00

312 lines
7.6 KiB
JavaScript
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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',
);
} );
} );