diff --git a/node-print/APKBUILD b/node-print/APKBUILD index 5975a5e..c88696c 100644 --- a/node-print/APKBUILD +++ b/node-print/APKBUILD @@ -1,39 +1,26 @@ # Contributor: Patrycja Rosa # Maintainer: Patrycja Rosa pkgname=node-print -pkgver=11 +pkgver=12 pkgrel=0 pkgdesc="another terrible javascript engine wrapper" url="https://git.ddd.rip/ptrcnull/ptrcports" arch="noarch !armhf !armv7" # hangs on tests license="BSD-2-Clause" depends="nodejs-current" -source="np index.js" +source=" + np + index.js + test.js + " builddir="$srcdir" -_assert() { - [ "$1" == "$2" ] || { echo "'$1' != '$2'"; return 1; } -} - check() { - local out - out="$(echo test | node -r . -p "stdin().substring(2).replace('t', 'rc').replace('s', 'pt')")" - _assert "$out" "ptrc" - - out="$(echo '{"test":"property"}' | node -r . -p "stdin().test")" - _assert "$out" "property" - - out="$(echo '["item"]' | node -r . -p "stdin()[0]")" - _assert "$out" "item" - - out="$(echo crtp | node -r . -p "stdin().lines()[0].reverse()")" - _assert "$out" "ptrc" - - out="$(node -r . -p "exec('echo', ['1']).stdout.toString()")" - _assert "$out" "1" - - out="$(node -r . -p "exec('echo', ['[]']).stdout.length")" - _assert "$out" "0" + node --experimental-test-coverage --test > output.txt + + # ensure coverage + local cov_lines="$(grep -F index.js output.txt | cut -d' ' -f4 | cut -d. -f1)" + [ "$cov_lines" -gt 90 ] } package() { @@ -43,5 +30,6 @@ package() { sha512sums=" b3dfdeb49637be33d2e2718c5abcf35a87dd55023918c99341273c3b38bd6685189d1f786451a742c47c5f3bc3b58555decb58e2a3a018c9b9ee92043f8fac03 np -3355f0f044726a75111f7a2788c5eb6150e44c7f9b4789973a6dda9ac980bc6133677067007e9c40f4c576ad2f8365922f98eda422e690a12775025eb788b584 index.js +b8e3205c58bba706e9013616d804d596a2e69c909614cda801e3a0f45ae31e7fad2bff00c2a2e44e2bcb83cb2063bab0bcbbb5d6044e343b515d22b25a977ca5 index.js +2948d361c0ffa3777c528ce2d5a312ff45682aa1cf3d0df73d2d1fa40b0b8d8675cc7a0e05ef11f63094e120ce4cd5a83f9d21585c768dd2d78c00d58da7857a test.js " diff --git a/node-print/index.js b/node-print/index.js index 2dc25ed..9975642 100644 --- a/node-print/index.js +++ b/node-print/index.js @@ -75,20 +75,24 @@ global.execnc = (command, args, options) => { /* wow it's almost like it's my own package and i can include whatever garbage i want :) */ /* not writing a test for that tho */ -global.apkindex = () => stdin() - .split("\n\n") - .filter(str => str.length) - .map(x => Object.fromEntries(x.lines().map(e => [e.at(0), e.slice(2)]))) - .map(pkg => ({ - ...pkg, - S: Number(pkg.S), - I: Number(pkg.I), - t: new Date(Number(pkg.t) * 1000), - i: pkg.i?.split(' '), - D: pkg.D?.split(' '), - p: pkg.p?.split(' ') - })) - .map(Object.prune) +global.apkindex = input => { + if (!input) input = stdin() + + return input + .split("\n\n") + .filter(str => str.length) + .map(x => Object.fromEntries(x.lines().map(e => [e.at(0), e.slice(2)]))) + .map(pkg => ({ + ...pkg, + S: Number(pkg.S), + I: Number(pkg.I), + t: new Date(Number(pkg.t) * 1000), + i: pkg.i?.split(' '), + D: pkg.D?.split(' '), + p: pkg.p?.split(' ') + })) + .map(Object.prune) +} Array.prototype.sum = function(def = 0) { return this.reduce((a, b) => a + b, def) @@ -126,6 +130,14 @@ Array.prototype.transpose = function() { return new Array(this[0].length).fill().map((_, i) => this.map(x => x[i])) } +Array.prototype.shuffle = function() { + // borrowed from https://stackoverflow.com/a/12646864 + for (let i = this.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [this[i], this[j]] = [this[j], this[i]]; + } +} + Set.prototype.union = function(other) { if (!other || !(other instanceof Set)) throw new TypeError('other must be a Set') return new Set([...this, ...other]) diff --git a/node-print/output.txt b/node-print/output.txt new file mode 100644 index 0000000..62c4726 --- /dev/null +++ b/node-print/output.txt @@ -0,0 +1,152 @@ +TAP version 13 +# test output +# Subtest: Object.prototype.map +ok 1 - Object.prototype.map + --- + duration_ms: 1.898781 + ... +# Subtest: Object.prototype.apply +ok 2 - Object.prototype.apply + --- + duration_ms: 0.1012 + ... +# Subtest: String.prototype.lines +ok 3 - String.prototype.lines + --- + duration_ms: 0.668277 + ... +# Subtest: String.prototype.reverse +ok 4 - String.prototype.reverse + --- + duration_ms: 0.097609 + ... +# Subtest: String.prototype.includesAny +ok 5 - String.prototype.includesAny + --- + duration_ms: 0.157079 + ... +# Subtest: String.prototype.tryParseJSON +ok 6 - String.prototype.tryParseJSON + --- + duration_ms: 0.171079 + ... +# Subtest: Buffer.prototype.tryParseJSON +ok 7 - Buffer.prototype.tryParseJSON + --- + duration_ms: 0.15631 + ... +# Subtest: exec +ok 8 - exec + --- + duration_ms: 2.373978 + ... +# Subtest: exec.orFail +ok 9 - exec.orFail + --- + duration_ms: 1.752591 + ... +# Subtest: execnc +ok 10 - execnc + --- + duration_ms: 1.517843 + ... +# Subtest: apkindex +ok 11 - apkindex + --- + duration_ms: 218.94233 + ... +# Subtest: Array.prototype.sum +ok 12 - Array.prototype.sum + --- + duration_ms: 0.167829 + ... +# Subtest: Array.prototype.product +ok 13 - Array.prototype.product + --- + duration_ms: 0.092419 + ... +# Subtest: Array.prototype.sortNum +ok 14 - Array.prototype.sortNum + --- + duration_ms: 0.166239 + ... +# Subtest: Array.prototype.partition +ok 15 - Array.prototype.partition + --- + duration_ms: 0.223309 + ... +# Subtest: Array.prototype.chunks - size 2, length 2n +ok 16 - Array.prototype.chunks - size 2, length 2n + --- + duration_ms: 0.176819 + ... +# Subtest: Array.prototype.chunks - size 2, length 2n+1 +ok 17 - Array.prototype.chunks - size 2, length 2n+1 + --- + duration_ms: 0.12053 + ... +# Subtest: Array.prototype.transpose +ok 18 - Array.prototype.transpose + --- + duration_ms: 0.180939 + ... +# Subtest: Array.prototype.shuffle +ok 19 - Array.prototype.shuffle + --- + duration_ms: 0.189319 + ... +# Subtest: Set.prototype.union +ok 20 - Set.prototype.union + --- + duration_ms: 0.321928 + ... +# Subtest: Set.prototype.intersection +ok 21 - Set.prototype.intersection + --- + duration_ms: 0.191079 + ... +# Subtest: Set.prototype.at - single element +ok 22 - Set.prototype.at - single element + --- + duration_ms: 0.12324 + ... +# Subtest: Set.prototype.at - multiple elements +ok 23 - Set.prototype.at - multiple elements + --- + duration_ms: 0.152549 + ... +# Subtest: matrix - seed with value +ok 24 - matrix - seed with value + --- + duration_ms: 0.267349 + ... +# Subtest: matrix - seed with function +ok 25 - matrix - seed with function + --- + duration_ms: 0.167019 + ... +# Subtest: Number.prototype.toXY +ok 26 - Number.prototype.toXY + --- + duration_ms: 0.177589 + ... +# Subtest: Object.prune +ok 27 - Object.prune + --- + duration_ms: 0.153959 + ... +1..27 +# tests 27 +# suites 0 +# pass 27 +# fail 0 +# cancelled 0 +# skipped 0 +# todo 0 +# duration_ms 313.645715 +# start of coverage report +# file | line % | branch % | funcs % | uncovered lines +# index.js | 96.20 | 86.96 | 95.12 | 5, 6, 7, 171, 172, 173, 174 +# test.js | 98.82 | 96.97 | 100.00 | 107, 108, 109 +# all files | 97.72 | 90.20 | 97.22 | +# end of coverage report diff --git a/node-print/test.js b/node-print/test.js new file mode 100644 index 0000000..5f04c53 --- /dev/null +++ b/node-print/test.js @@ -0,0 +1,254 @@ +require('.') + +const assert = require('node:assert/strict') +const test = require('node:test') +const fs = require('fs/promises') + +const testObject = { + property: "value", + anotherProperty: 1234, + boolean: true, + notBoolean: null +} +const testObjectStr = JSON.stringify(testObject) + +test('Object.prototype.map', t => { + assert.equal( + testObject.map(JSON.stringify), + testObjectStr + ) +}) + +test('Object.prototype.apply', t => { + assert.equal( + testObject.apply(JSON.stringify), + testObjectStr + ) +}) + +test('String.prototype.lines', t => { + const str = 'one\ntwo\nthree\n' + assert.deepEqual( + ['one', 'two', 'three'], + str.lines() + ) + assert.deepEqual( + ['one', 'two', 'three'], + str.lines() + ) +}) + +test('String.prototype.reverse', t => { + assert.equal( + 'tac', + 'cat'.reverse() + ) +}) + +test('String.prototype.includesAny', t => { + const str = 'longer test string' + assert(str.includesAny(['test'])) + assert(str.includesAny(['not', 'test'])) + assert(!str.includesAny(['missing'])) +}) + +test('String.prototype.tryParseJSON', t => { + assert.deepEqual( + testObject, + testObjectStr.tryParseJSON() + ) + assert.deepEqual( + testObject, + `\n\n${testObjectStr}\n\n`.tryParseJSON() + ) + assert.deepEqual( + 'definitely not json', + 'definitely not json'.tryParseJSON() + ) + assert.deepEqual( + '{maybe json?}', + '{maybe json?}'.tryParseJSON() + ) +}) + +test('Buffer.prototype.tryParseJSON', t => { + assert.deepEqual( + testObject, + Buffer.from(testObjectStr).tryParseJSON(), + ) + assert.deepEqual( + Buffer.from('meow'), + Buffer.from('meow').tryParseJSON(), + ) +}) + +test('exec', t => { + assert.equal( + '1\n', + exec('echo', ['1']).stdout.toString() + ) +}) + +test('exec.orFail', t => { + assert.throws(_ => exec('false').orFail()) +}) + +test('execnc', t => { + assert.equal( + undefined, + execnc('echo', ['test output']).stdout + ) +}) + +test('apkindex', async t => { + try { + await fs.access('/lib/apk/db/installed', fs.constants.R_OK) + } catch (err) { + t.skip('not running on alpine') + return + } + + const content = await fs.readFile('/lib/apk/db/installed', 'utf-8') + const index = apkindex(content) + + assert.equal('object', typeof index) + assert(index instanceof Array) + + const musl = index.find(pkg => pkg.P === 'musl') + assert(musl) + assert.equal('musl', musl.o) + assert.equal('number', typeof musl.S) +}) + +test('Array.prototype.sum', t => { + assert.equal( + 10, + [5, 3, 2].sum() + ) +}) + +test('Array.prototype.product', t => { + assert.equal( + 30, + [5, 3, 2].product() + ) +}) + +test('Array.prototype.sortNum', t => { + assert.deepEqual( + [2, 3, 5], + [5, 3, 2].sortNum() + ) +}) + +test('Array.prototype.partition', t => { + assert.deepEqual( + [[1, 3], [2, 4]], + [1, 2, 3, 4].partition(a => a % 2) + ) +}) + +test('Array.prototype.chunks - size 2, length 2n', t => { + assert.deepEqual( + [[1, 2], [3, 4], [5, 6]], + [1, 2, 3, 4, 5, 6].chunks(2) + ) +}) + +test('Array.prototype.chunks - size 2, length 2n+1', t => { + assert.deepEqual( + [[1, 2], [3, 4], [5, 6], [7]], + [1, 2, 3, 4, 5, 6, 7].chunks(2) + ) +}) + +test('Array.prototype.transpose', t => { + assert.deepEqual( + [[1, 3], [2, 4]], + [[1, 2], [3, 4]].transpose() + ) +}) + + +test('Array.prototype.shuffle', t => { + const arr = [1, 2, 3, 4, 5, 6, 7, 8] + assert.notDeepEqual( + arr, + arr.shuffle() + ) +}) + +test('Set.prototype.union', t => { + const left = new Set([1, 3]) + const right = new Set([2, 4]) + assert.deepEqual( + new Set([1, 2, 3, 4]), + left.union(right) + ) +}) + +test('Set.prototype.intersection', t => { + const left = new Set([1, 2, 3]) + const right = new Set([2, 4]) + assert.deepEqual( + new Set([2]), + left.intersection(right) + ) +}) + +test('Set.prototype.at - single element', t => { + assert.equal( + 2, + new Set([2]).at(0) + ) +}) + +test('Set.prototype.at - multiple elements', t => { + assert.equal( + 2, + new Set([1, 2, 3]).at(1) + ) +}) + +test('matrix - seed with value', t => { + const reference = [ + [ 0, 0 ], + [ 0, 0 ] + ] + assert.deepEqual(reference, matrix(2, 2, 0)) +}) + +test('matrix - seed with function', t => { + const reference = [ + [ 0, 1, 2 ], + [ 0, 1, 2 ] + ] + assert.deepEqual(reference, matrix(3, 2, i => i)) +}) + +test('Number.prototype.toXY', t => { + assert.deepEqual( + [ 1, 3 ], + (16).toXY(5) + ) +}) + +test('Object.prune', t => { + assert.deepEqual( + { + emptyProperty: null, + actualProperty: 2 + }, + Object.prune({ + emptyProperty: null, + actualProperty: 2, + anotherEmptyProperty: undefined + }) + ) +}) + +// test('String.prototype.reverse', t => { +// assert.equal( + +// ) +// })