2021-08-19 15:29:37 -04:00
# include "tests.h"
2024-01-02 15:25:11 -05:00
# include "bip39.h"
2023-12-13 18:59:11 -05:00
# include "http.h"
2023-03-07 12:50:17 -05:00
# include "log.h"
2022-06-04 13:04:51 -04:00
# include "mem.h"
2021-09-06 14:23:22 -04:00
# include "ssb.tests.h"
2024-01-02 15:25:11 -05:00
# include "util.js.h"
2021-08-19 15:29:37 -04:00
# include <assert.h>
2021-09-06 14:23:22 -04:00
# include <stdbool.h>
2021-08-19 15:29:37 -04:00
# include <stdlib.h>
# include <stdio.h>
2021-09-06 14:23:22 -04:00
# include <string.h>
2021-08-19 15:29:37 -04:00
# include <unistd.h>
2023-12-13 18:59:11 -05:00
# include <uv.h>
2022-05-16 18:30:14 -04:00
# if defined(_WIN32)
# define WIFEXITED(x) 1
# define WEXITSTATUS(x) (x)
# endif
2023-11-07 22:36:08 -05:00
# if defined(__OpenBSD__)
# include <sys/wait.h>
# endif
2023-10-11 20:29:17 -04:00
# if defined(__APPLE__)
# include <TargetConditionals.h>
# endif
# if !TARGET_OS_IPHONE
2024-01-07 16:08:20 -05:00
static void _write_file ( const char * path , const char * contents )
2021-08-19 15:29:37 -04:00
{
FILE * file = fopen ( " out/test.js " , " w " ) ;
2024-01-07 16:08:20 -05:00
if ( ! file )
{
printf ( " Unable to write %s: %s. \n " , path , strerror ( errno ) ) ;
fflush ( stdout ) ;
abort ( ) ;
}
fputs ( contents , file ) ;
2021-08-19 15:29:37 -04:00
fclose ( file ) ;
2024-01-07 16:08:20 -05:00
}
static void _test_nop ( const tf_test_options_t * options )
{
_write_file ( " out/test.js " , " print('hi'); " ) ;
2021-08-19 15:29:37 -04:00
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 15:29:37 -04:00
int result = system ( command ) ;
2021-08-22 13:38:20 -04:00
( void ) result ;
2021-08-19 15:29:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_child ( const tf_test_options_t * options )
2021-08-19 15:29:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 15:29:37 -04:00
" var task = new Task(); \n "
" task.onExit = function() { \n "
" print('child exited'); \n "
" }; \n "
" task.activate(); \n "
2021-10-10 18:45:24 -04:00
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(function() { \n "
" print('child started'); \n "
" }); \n "
2021-08-19 15:29:37 -04:00
" }); " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2021-08-19 15:29:37 -04:00
" print('I am the child process.'); \n "
" exit(0); \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 15:29:37 -04:00
int result = system ( command ) ;
2021-08-22 13:38:20 -04:00
( void ) result ;
2021-08-19 15:29:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_promise ( const tf_test_options_t * options )
2021-08-19 15:29:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file ( " out/test.js " ,
2021-08-19 15:29:37 -04:00
" var task = new Task(); \n "
" task.activate(); \n "
2021-10-10 18:45:24 -04:00
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(function() { \n "
" task.getExports().then(function(exports) { \n "
" return exports.add(1, 1); \n "
" }).then(function(sum) { \n "
" if (sum == 2) { \n "
" exit(0); \n "
" } else { \n "
" exit(1); \n "
" } \n "
" }); \n "
2021-08-19 15:29:37 -04:00
" }); \n "
" }); \n " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2021-08-19 15:29:37 -04:00
" exports = { \n "
" add: function(left, right) { \n "
" return left + right; \n "
" } \n "
" } \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 15:29:37 -04:00
int result = system ( command ) ;
2021-08-22 13:38:20 -04:00
( void ) result ;
2021-08-19 15:29:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_promise_remote_throw ( const tf_test_options_t * options )
2021-08-19 15:29:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 15:29:37 -04:00
" var task = new Task(); \n "
" task.activate(); \n "
2021-10-10 18:45:24 -04:00
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(function() { \n "
" task.getExports().then(function(exp) { \n "
" return exp.add(1, 1); \n "
" }).then(function(sum) { \n "
" exit(1); \n "
" }).catch(function(error) { \n "
" print('Caught: ' + error.message); \n "
" if (error.stack) { \n "
" print('stack: ' + error.stack); \n "
" } \n "
" exit(0); \n "
" }); \n "
" }).catch(function(e) { \n "
" print('caught', e.message); \n "
2021-08-19 15:29:37 -04:00
" }); \n "
" }); \n " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2021-08-19 15:29:37 -04:00
" exports = { \n "
" add: function(left, right) { \n "
" throw new Error('fail'); \n "
" } \n "
" } \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 15:29:37 -04:00
int result = system ( command ) ;
2021-08-22 13:38:20 -04:00
( void ) result ;
2021-08-19 15:29:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_promise_remote_reject ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" var task = new Task(); \n "
" task.activate(); \n "
2021-10-10 18:45:24 -04:00
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(function() { \n "
" task.getExports().then(function(exp) { \n "
" return exp.add(1, 1); \n "
" }).then(function(sum) { \n "
" exit(1); \n "
" }).catch(function(error) { \n "
" print('Caught: ' + error.message); \n "
" if (error.stack) { \n "
" print('stack: ' + error.stack); \n "
" } \n "
" exit(0); \n "
" }); \n "
" }).catch(function(e) { \n "
" print('caught', e.message); \n "
2021-08-19 16:10:37 -04:00
" }); \n "
" }); \n " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2021-08-19 16:10:37 -04:00
" exports = { \n "
" add: function(left, right) { \n "
" return new Promise(function(resolve, reject) { \n "
" reject(new Error('oops')); \n "
" }); \n "
" } \n "
" } \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2021-08-22 13:38:20 -04:00
( void ) result ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_database ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" var db = new Database('testdb'); \n "
" if (db.get('a')) { \n "
" exit(1); \n "
" } \n "
" db.set('a', 1); \n "
" if (db.get('a') != 1) { \n "
" exit(2); \n "
" } \n "
" db.set('b', 2); \n "
" db.set('c', 3); \n "
" \n "
" var expected = ['a', 'b', 'c']; \n "
" var have = db.getAll(); \n "
" for (var i = 0; i < have.length; i++) { \n "
" var item = have[i]; \n "
" if (expected.indexOf(item) == -1) { \n "
" print('Did not find ' + item + ' in db.'); \n "
" exit(3); \n "
" } else { \n "
" expected.splice(expected.indexOf(item), 1); \n "
" } \n "
" } \n "
" if (expected.length) { \n "
" print('Expected but did not find: ' + JSON.stringify(expected)); \n "
" exit(4); \n "
" } \n " ) ;
char command [ 256 ] ;
2023-08-04 19:44:48 -04:00
unlink ( " out/test_db0.sqlite " ) ;
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=out/test_db0.sqlite -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
2023-08-04 19:44:48 -04:00
unlink ( " out/test_db0.sqlite " ) ;
2021-08-19 16:10:37 -04:00
}
2021-09-06 14:23:22 -04:00
static void _test_this ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" var task = new Task(); \n "
" task.activate.bind(null).apply(); \n "
" exit(0); \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_await ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" print('hi'); \n "
" function foobar() { \n "
2021-10-10 18:45:24 -04:00
" return new Promise(function(resolve, reject) { \n "
2021-08-19 16:10:37 -04:00
" resolve(10); \n "
" }); \n "
" } \n "
" \n "
" async function huh() { \n "
" let v = await foobar(); \n "
" print('v => ' + v); \n "
" if (v != 10) { \n "
" throw new Error('nope'); \n "
" } \n "
" } \n "
" \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2022-06-18 13:50:22 -04:00
static void _test_import ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2022-06-18 13:50:22 -04:00
" import * as req from './required.js'; \n "
" if (req.foo() != 12345) { \n "
2021-08-19 16:10:37 -04:00
" exit(1); \n "
2022-06-18 13:50:22 -04:00
" } \n " ) ;
2021-08-19 16:10:37 -04:00
2024-01-07 16:08:20 -05:00
_write_file (
" out/required.js " ,
2022-06-18 13:50:22 -04:00
" export function foo() { \n "
2021-08-19 16:10:37 -04:00
" return 12345; \n "
2022-06-18 13:50:22 -04:00
" } \n " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/bad.js " ,
2022-06-18 13:50:22 -04:00
" import * as req from './missing.js'; \n "
" if (req.foo() != 12345) { \n "
" exit(1); \n "
" } \n " ) ;
2021-08-19 16:10:37 -04:00
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/bad.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2022-06-18 13:50:22 -04:00
result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2022-06-18 13:50:22 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
2021-08-19 16:10:37 -04:00
unlink ( " out/test.js " ) ;
unlink ( " out/required.js " ) ;
2022-06-18 13:50:22 -04:00
unlink ( " out/missing.js " ) ;
2021-08-19 16:10:37 -04:00
}
2021-09-06 14:23:22 -04:00
static void _test_exit ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file ( " out/test.js " , " import * as blah from './blah.js'; \n " ) ;
_write_file ( " out/blah.js " , " \n " ) ;
2021-08-19 16:10:37 -04:00
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/blah.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_icu ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" print('Hi'); \n "
" print(parseInt('3').toLocaleString()); \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_uint8array ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" var task = new Task(); \n "
" task.onExit = function() { \n "
" print('child exited'); \n "
" }; \n "
" task.activate(); \n "
2021-10-10 18:45:24 -04:00
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(async function() { \n "
" print('child started'); \n "
" var input = new Uint8Array(10); \n "
" for (var i = 0; i < 10; i++) { \n "
" input[i] = i; \n "
2021-08-19 16:10:37 -04:00
" } \n "
2021-10-10 18:45:24 -04:00
" var test = (await task.getExports()).test; \n "
" var output = new Uint8Array(await test(input)); \n "
" print('input', input, input.length, input.byteLength); \n "
" print('output', output, output.length, output.byteLength); \n "
" for (var i = 0; i < 10; i++) { \n "
" print(output[i]); \n "
" if (output[i] != i) { \n "
" print('output[' + i + '] == ' + output[i]); \n "
" exit(1); \n "
" } \n "
" } \n "
" exit(0); \n "
" }) \n "
" }) \n " ) ;
2021-08-19 16:10:37 -04:00
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2021-08-19 16:10:37 -04:00
" exports = { \n "
" test: function(data) { \n "
" return data; \n "
" } \n "
" } \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2023-09-16 20:13:31 -04:00
static void _test_float ( const tf_test_options_t * options )
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2023-09-16 20:13:31 -04:00
" var task = new Task(); \n "
" task.onExit = function() { \n "
" print('child exited'); \n "
" }; \n "
" task.activate(); \n "
" File.readFile('out/child.js').then(function(data) { \n "
" task.execute({name: 'child.js', source: utf8Decode(data)}).then(async function() { \n "
" print('get exports'); \n "
" let test = (await task.getExports()).test; \n "
" print('calling export'); \n "
" let result = await test(1.2); \n "
" print(result); \n "
" exit(result == 1.2 ? 0 : 1); \n "
" }); \n "
" }); " ) ;
2024-01-07 16:08:20 -05:00
_write_file (
" out/child.js " ,
2023-09-16 20:13:31 -04:00
" print( \" child \" ); \n "
" exports = { \n "
" test: function(value) { \n "
" print(value); \n "
" return value; \n "
" } \n "
" }; \n "
" print( \" child ready \" ); \n "
) ;
char command [ 256 ] ;
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
tf_printf ( " %s \n " , command ) ;
int result = system ( command ) ;
( void ) result ;
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
unlink ( " out/child.js " ) ;
}
2021-09-06 14:23:22 -04:00
static void _test_socket ( const tf_test_options_t * options )
2021-08-19 16:10:37 -04:00
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-08-19 16:10:37 -04:00
" 'use strict'; \n "
" \n "
" var s = new Socket(); \n "
" print('connecting'); \n "
" print('before connect', s.isConnected); \n "
" s.onError(function(e) { \n "
" print(e); \n "
" }); \n "
" print('noDelay', s.noDelay); \n "
" s.noDelay = true; \n "
" s.connect('www.unprompted.com', 80).then(function() { \n "
2022-10-14 08:27:34 -04:00
" print('connected', 'www.unprompted.com', 80, s.isConnected); \n "
2021-08-19 16:10:37 -04:00
" print(s.peerName); \n "
" s.read(function(data) { \n "
2021-09-06 13:50:38 -04:00
" print('read', data ? data.length : null); \n "
2021-08-19 16:10:37 -04:00
" }); \n "
" s.write('GET / HTTP/1.0 \\ r \\ n \\ r \\ n'); \n "
2022-10-14 08:27:34 -04:00
" }).then(function(e) { \n "
" print('closed 1'); \n "
2021-08-19 16:10:37 -04:00
" }); \n "
" \n "
" var s2 = new Socket(); \n "
" print('connecting'); \n "
" print('before connect', s2.isConnected); \n "
" s2.onError(function(e) { \n "
" print('error'); \n "
" print(e); \n "
" }); \n "
" print('noDelay', s2.noDelay); \n "
" s2.noDelay = true; \n "
" s2.connect('www.unprompted.com', 443).then(function() { \n "
2022-10-14 08:27:34 -04:00
" print('connected', 'www.unprompted.com', 443); \n "
2021-08-19 16:10:37 -04:00
" s2.read(function(data) { \n "
2021-09-06 13:50:38 -04:00
" print('read', data ? data.length : null); \n "
2021-08-19 16:10:37 -04:00
" }); \n "
" return s2.startTls(); \n "
" }).then(function() { \n "
" print('ready'); \n "
" print(s2.peerName); \n "
" s2.write('GET / HTTP/1.0 \\ r \\ nConnection: close \\ r \\ n \\ r \\ n').then(function() { \n "
" s2.shutdown(); \n "
" }); \n "
" }).catch(function(e) { \n "
2022-07-09 10:14:48 -04:00
" print('caught'); \n "
" print(e); \n "
" }); \n "
" var s3 = new Socket(); \n "
" print('connecting s3'); \n "
" print('before connect', s3.isConnected); \n "
" s3.onError(function(e) { \n "
" print('error'); \n "
" print(e); \n "
" }); \n "
" print('noDelay', s3.noDelay); \n "
" s3.noDelay = true; \n "
" s3.connect('0.0.0.0', 443).then(function() { \n "
2022-10-14 08:27:34 -04:00
" print('connected', '0.0.0.0', 443); \n "
2022-07-09 10:14:48 -04:00
" s3.read(function(data) { \n "
" print('read', data ? data.length : null); \n "
" }); \n "
" return s3.startTls(); \n "
" }).then(function() { \n "
" print('ready'); \n "
" print(s3.peerName); \n "
" s3.write('GET / HTTP/1.0 \\ r \\ nConnection: close \\ r \\ n \\ r \\ n').then(function() { \n "
" s3.shutdown(); \n "
" }); \n "
" }).catch(function(e) { \n "
" print('caught'); \n "
2021-08-19 16:10:37 -04:00
" print(e); \n "
" }); \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-08-19 16:10:37 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-08-19 16:10:37 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2021-10-05 21:25:33 -04:00
static void _test_file ( const tf_test_options_t * options )
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2021-10-05 21:25:33 -04:00
" 'use strict'; \n "
" File.readFile('out/test.js').then(function(data) { \n "
" }).catch(function(error) { \n "
" print('ERROR', error); \n "
" exit(1); \n "
" }); \n "
" File.readFile('out/missing.txt').then(function(data) { \n "
" print('READ', utf8Decode(data)); \n "
" exit(1); \n "
" }).catch(function(error) { \n "
" print('expected error', error); \n "
" }); \n " ) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2021-10-05 21:25:33 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2021-10-05 21:25:33 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2022-09-28 19:52:44 -04:00
static void _test_sign ( const tf_test_options_t * options )
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2022-09-28 19:52:44 -04:00
" 'use strict'; \n "
" let id = ssb.createIdentity('test'); \n "
" print(id); \n "
" let sig = ssb.hmacsha256sign('hello', 'test', id); \n "
" print(sig); \n "
" if (!ssb.hmacsha256verify(id, 'hello', sig)) { \n "
" exit(1); \n "
" } \n "
" if (ssb.hmacsha256verify(id, 'world', sig)) { \n "
" exit(1); \n "
" } \n "
" if (ssb.hmacsha256verify(id, 'hello1', sig)) { \n "
" exit(1); \n "
" } \n "
) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2022-09-28 19:52:44 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2022-09-28 19:52:44 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
static void _test_b64 ( const tf_test_options_t * options )
{
2024-01-07 16:08:20 -05:00
_write_file (
" out/test.js " ,
2022-09-28 19:52:44 -04:00
" 'use strict'; \n "
" print(base64Encode('hello')); \n "
2024-01-03 12:25:34 -05:00
" let x = utf8Decode(base64Decode(base64Encode('hello'))); \n "
2023-02-13 22:15:24 -05:00
" if (x !== 'hello') { \n "
" print(x); \n "
2022-09-28 19:52:44 -04:00
" exit(1); \n "
" } \n "
) ;
char command [ 256 ] ;
2022-10-14 08:27:34 -04:00
snprintf ( command , sizeof ( command ) , " %s run --ssb-port=0 --db-path=:memory: -s out/test.js " , options - > exe_path ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " %s \n " , command ) ;
2022-09-28 19:52:44 -04:00
int result = system ( command ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " returned %d \n " , WEXITSTATUS ( result ) ) ;
2022-09-28 19:52:44 -04:00
assert ( WIFEXITED ( result ) ) ;
assert ( WEXITSTATUS ( result ) = = 0 ) ;
unlink ( " out/test.js " ) ;
}
2024-01-02 15:25:11 -05:00
static const char * k_bip39_test_key_base64 = " GO0Lv5BvcuuJJdHrokHoo0PmCDC/XjO/SZ6H+ddq4UvWd/VPW1RJrjd1aCUIfPIojFXrWMb8R54vVerU2TwjdQ==.ed25519 " ;
static const char * k_bip32_test_key_words = " body hair useful camp warm into cause riot two bamboo kick educate dinosaur advice seed type crisp where guilt avocado output rely lunch goddess " ;
static void _test_bip39 ( const tf_test_options_t * options )
{
uint8_t bytes [ 64 ] = { 0 } ;
tf_base64_decode ( k_bip39_test_key_base64 , strlen ( k_bip39_test_key_base64 ) - strlen ( " .ed25519 " ) , bytes , sizeof ( bytes ) ) ;
char words [ 4096 ] = " " ;
bool result = tf_bip39_bytes_to_words ( bytes , sizeof ( bytes ) / 2 , words , sizeof ( words ) ) ;
tf_printf ( " %d: %s \n " , result , words ) ;
assert ( result ) ;
assert ( strcmp ( words , k_bip32_test_key_words ) = = 0 ) ;
uint8_t test_bytes [ 32 ] = { 0 } ;
result = tf_bip39_words_to_bytes ( k_bip32_test_key_words , test_bytes , sizeof ( test_bytes ) ) ;
assert ( result ) ;
assert ( memcmp ( bytes , test_bytes , sizeof ( test_bytes ) ) = = 0 ) ;
}
2023-12-18 12:51:15 -05:00
typedef struct _test_http_t
{
uv_loop_t * loop ;
uv_async_t async ;
bool done ;
} test_http_t ;
static void _test_http_async ( uv_async_t * async )
{
}
2023-12-13 18:59:11 -05:00
static void _test_http_thread ( void * data )
{
2023-12-18 12:51:15 -05:00
test_http_t * test = data ;
2023-12-20 18:58:28 -05:00
int r = system ( " curl -v http://localhost:23456/404 " ) ;
assert ( WEXITSTATUS ( r ) = = 0 ) ;
tf_printf ( " curl returned %d \n " , WEXITSTATUS ( r ) ) ;
r = system ( " curl -v http://localhost:23456/hello " ) ;
assert ( WEXITSTATUS ( r ) = = 0 ) ;
tf_printf ( " curl returned %d \n " , WEXITSTATUS ( r ) ) ;
r = system ( " curl -v --data 'hello world' http://localhost:23456/post " ) ;
2023-12-13 18:59:11 -05:00
assert ( WEXITSTATUS ( r ) = = 0 ) ;
2023-12-17 12:44:54 -05:00
tf_printf ( " curl returned %d \n " , WEXITSTATUS ( r ) ) ;
2023-12-18 12:51:15 -05:00
2023-12-20 19:13:03 -05:00
r = system ( " curl -v http://localhost:23456/hello http://localhost:23456/hello http://localhost:23456/hello " ) ;
assert ( WEXITSTATUS ( r ) = = 0 ) ;
tf_printf ( " curl returned %d \n " , WEXITSTATUS ( r ) ) ;
2023-12-18 12:51:15 -05:00
test - > done = true ;
/* All to wake up the loop. */
uv_async_send ( & test - > async ) ;
2023-12-13 18:59:11 -05:00
}
static void _test_http_handler ( tf_http_request_t * request )
{
2023-12-17 12:44:54 -05:00
const char * headers [ ] =
{
2023-12-20 19:13:03 -05:00
" User-Agent " , " TildeFriends/1.0 " ,
2023-12-17 12:44:54 -05:00
} ;
2023-12-18 12:51:15 -05:00
const char * k_payload = " Hello, world! \n " ;
tf_http_respond ( request , 200 , headers , 1 , k_payload , strlen ( k_payload ) ) ;
2023-12-13 18:59:11 -05:00
}
2023-12-20 18:58:28 -05:00
static void _test_http_handler_post ( tf_http_request_t * request )
{
const void * body = NULL ;
size_t size = tf_http_get_body ( request , & body ) ;
tf_printf ( " size = %zd body=%.*s \n " , size , ( int ) size , ( const char * ) body ) ;
const char * headers [ ] =
{
" Connection " , " close " ,
} ;
const char * k_payload = " Hello, world! \n " ;
tf_http_respond ( request , 200 , headers , 1 , k_payload , strlen ( k_payload ) ) ;
}
2023-12-13 18:59:11 -05:00
static void _test_http ( const tf_test_options_t * options )
{
2023-12-20 18:58:28 -05:00
tf_printf ( " Starting http. \n " ) ;
2023-12-13 18:59:11 -05:00
uv_loop_t loop = { 0 } ;
uv_loop_init ( & loop ) ;
tf_http_t * http = tf_http_create ( & loop ) ;
2023-12-30 11:29:16 -05:00
tf_http_add_handler ( http , " /hello " , _test_http_handler , NULL ) ;
tf_http_add_handler ( http , " /post " , _test_http_handler_post , NULL ) ;
2023-12-30 13:59:02 -05:00
tf_http_listen ( http , 23456 , NULL ) ;
2023-12-13 18:59:11 -05:00
2023-12-18 12:51:15 -05:00
test_http_t test = { . loop = & loop } ;
uv_async_init ( & loop , & test . async , _test_http_async ) ;
2023-12-13 18:59:11 -05:00
uv_thread_t thread = { 0 } ;
2023-12-18 12:51:15 -05:00
uv_thread_create ( & thread , _test_http_thread , & test ) ;
while ( ! test . done )
2023-12-17 12:44:54 -05:00
{
uv_run ( & loop , UV_RUN_ONCE ) ;
}
2023-12-18 12:51:15 -05:00
uv_close ( ( uv_handle_t * ) & test . async , NULL ) ;
2023-12-17 12:44:54 -05:00
tf_printf ( " Done running. \n " ) ;
2023-12-13 18:59:11 -05:00
tf_http_destroy ( http ) ;
2023-12-18 12:51:15 -05:00
uv_run ( & loop , UV_RUN_DEFAULT ) ;
2023-12-13 18:59:11 -05:00
uv_loop_close ( & loop ) ;
uv_thread_join ( & thread ) ;
}
2023-09-21 19:38:55 -04:00
static void _tf_test_run ( const tf_test_options_t * options , const char * name , void ( * test ) ( const tf_test_options_t * options ) , bool opt_in )
2021-08-19 15:29:37 -04:00
{
2021-09-06 14:23:22 -04:00
bool specified = false ;
2021-10-10 17:51:38 -04:00
if ( options - > tests )
{
2022-06-04 13:04:51 -04:00
char * dup = tf_strdup ( options - > tests ) ;
2021-09-06 14:23:22 -04:00
char * state = NULL ;
const char * t = NULL ;
2021-10-10 17:51:38 -04:00
while ( ( t = strtok_r ( t ? NULL : dup , " , " , & state ) ) ! = NULL )
{
if ( strcmp ( t , name ) = = 0 )
{
2021-09-06 14:23:22 -04:00
specified = true ;
break ;
}
}
2022-06-04 13:04:51 -04:00
tf_free ( dup ) ;
2021-09-06 14:23:22 -04:00
}
2023-09-21 19:38:55 -04:00
if ( ( ! opt_in & & ! options - > tests ) | | specified )
2021-10-10 17:51:38 -04:00
{
2022-07-09 10:38:00 -04:00
# define GREEN "\e[1;32m"
2022-07-09 10:33:38 -04:00
# define MAGENTA "\e[1;35m"
# define CYAN "\e[1;36m"
# define RESET "\e[0m"
2023-03-07 12:50:17 -05:00
tf_printf ( CYAN " == running test " MAGENTA " %s " CYAN " == \n " RESET , name ) ;
2021-09-06 14:23:22 -04:00
test ( options ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " [ " GREEN " pass " RESET " ] %s \n " , name ) ;
2022-07-09 10:38:00 -04:00
# undef GREEN
# undef MAGENTA
# undef CYAN
# undef RESET
2021-09-06 14:23:22 -04:00
}
}
2023-10-11 20:29:17 -04:00
# endif
2021-09-06 14:23:22 -04:00
void tf_tests ( const tf_test_options_t * options )
{
2023-10-11 20:29:17 -04:00
# if !TARGET_OS_IPHONE
2024-01-02 15:25:11 -05:00
_tf_test_run ( options , " bip39 " , _test_bip39 , false ) ;
2023-12-13 18:59:11 -05:00
_tf_test_run ( options , " http " , _test_http , false ) ;
2023-09-21 19:38:55 -04:00
_tf_test_run ( options , " ssb " , tf_ssb_test_ssb , false ) ;
_tf_test_run ( options , " ssb_id " , tf_ssb_test_id_conversion , false ) ;
_tf_test_run ( options , " ssb_following " , tf_ssb_test_following , false ) ;
_tf_test_run ( options , " nop " , _test_nop , false ) ;
_tf_test_run ( options , " child " , _test_child , false ) ;
_tf_test_run ( options , " promise " , _test_promise , false ) ;
_tf_test_run ( options , " promise_remote_throw " , _test_promise_remote_throw , false ) ;
_tf_test_run ( options , " promise_remote_reject " , _test_promise_remote_reject , false ) ;
_tf_test_run ( options , " database " , _test_database , false ) ;
_tf_test_run ( options , " this " , _test_this , false ) ;
_tf_test_run ( options , " await " , _test_await , false ) ;
_tf_test_run ( options , " import " , _test_import , false ) ;
_tf_test_run ( options , " exit " , _test_exit , false ) ;
_tf_test_run ( options , " icu " , _test_icu , false ) ;
_tf_test_run ( options , " uint8array " , _test_uint8array , false ) ;
_tf_test_run ( options , " float " , _test_float , false ) ;
_tf_test_run ( options , " socket " , _test_socket , false ) ;
_tf_test_run ( options , " file " , _test_file , false ) ;
_tf_test_run ( options , " sign " , _test_sign , false ) ;
_tf_test_run ( options , " b64 " , _test_b64 , false ) ;
_tf_test_run ( options , " rooms " , tf_ssb_test_rooms , false ) ;
_tf_test_run ( options , " bench " , tf_ssb_test_bench , false ) ;
_tf_test_run ( options , " go-ssb-room " , tf_ssb_test_go_ssb_room , true ) ;
2023-03-07 12:50:17 -05:00
tf_printf ( " Tests completed. \n " ) ;
2023-10-11 20:29:17 -04:00
# endif
2021-08-19 15:29:37 -04:00
}