[Pkg-javascript-devel] Bug#1108872: unblock: node-tar-fs/3.0.9+~cs2.0.4-1
Yadd
yadd at debian.org
Sun Jul 6 16:23:19 BST 2025
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: node-tar-fs at packages.debian.org, carnil at debian.org, yadd at debian.org
Control: affects -1 + src:node-tar-fs
User: release.debian.org at packages.debian.org
Usertags: unblock
[ Reason ]
node-tar-fs is vulnerable to CVE-2025-48387: it may extarct files
outside the specified directory.
[ Impact ]
Medium security issue
[ Tests ]
Tests OK
[ Risks ]
Low risk, patch is trivial
[ Checklist ]
[X] all changes are documented in the d/changelog
[X] I reviewed all changes and I approve them
[X] attach debdiff against the package in testing
[ Other info ]
In this release, upstream choose another test framework not available in
Debian. Then I added a patch to use "tape" which is available. This permits
to drop useless test modules previously embedded.
That's why I added 2 debdiff here:
- the global debdiff
- a debdiff that shows only changes related to installed files
Best regards,
Xavier
unblock node-tar-fs/3.0.9+~cs2.0.4-1
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index b01fb20..a93913e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+node-tar-fs (3.0.9+~cs2.0.4-1) unstable; urgency=medium
+
+ * Team upload
+ * Keep previous test from 2.1.1 with tape
+ * New upstream version (Closes: CVE-2025-48387)
+
+ -- Yadd <yadd at debian.org> Tue, 03 Jun 2025 17:33:46 +0200
+
node-tar-fs (3.0.8+~cs2.0.4-1) unstable; urgency=medium
* Team upload
diff --git a/debian/patches/fix-test.patch b/debian/patches/fix-test.patch
deleted file mode 100644
index d70b080..0000000
--- a/debian/patches/fix-test.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-Description: Fix test when .gitignore doesn't exist
-Author: Yadd <yadd at debian.org>
-Forwarded: not-needed
-Last-Update: 2025-03-30
-
---- a/test/index.js
-+++ b/test/index.js
-@@ -60,11 +60,11 @@
- })
-
- test('symlink', function (t) {
-- if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
-+ //if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
- t.plan(1)
- t.ok(true)
- return
-- }
-+ //}
-
- t.plan(5)
-
-@@ -93,11 +93,11 @@
- })
-
- test('follow symlinks', function (t) {
-- if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
-+ //if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
- t.plan(1)
- t.ok(true)
- return
-- }
-+ //}
-
- t.plan(5)
-
diff --git a/debian/patches/keep-test-with-tape.patch b/debian/patches/keep-test-with-tape.patch
new file mode 100644
index 0000000..d9c1daf
--- /dev/null
+++ b/debian/patches/keep-test-with-tape.patch
@@ -0,0 +1,265 @@
+Description: keep test with tape
+Author: Yadd <yadd at debian.org>
+Forwarded: not-needed
+Last-Update: 2025-03-31
+
+--- a/test/index.js
++++ b/test/index.js
+@@ -1,4 +1,4 @@
+-const test = require('brittle')
++const test = require('tape')
+ const rimraf = require('rimraf')
+ const tar = require('../index')
+ const tarStream = require('tar-stream')
+@@ -23,13 +23,13 @@
+ .pipe(tar.extract(b))
+ .on('finish', function () {
+ const files = fs.readdirSync(b)
+- t.is(files.length, 1)
+- t.is(files[0], 'hello.txt')
++ t.same(files.length, 1)
++ t.same(files[0], 'hello.txt')
+ const fileB = path.join(b, files[0])
+ const fileA = path.join(a, files[0])
+- t.alike(fs.readFileSync(fileB, 'utf-8'), fs.readFileSync(fileA, 'utf-8'))
+- t.alike(fs.statSync(fileB).mode, fs.statSync(fileA).mode)
+- t.alike(mtime(fs.statSync(fileB)), mtime(fs.statSync(fileA)))
++ t.same(fs.readFileSync(fileB, 'utf-8'), fs.readFileSync(fileA, 'utf-8'))
++ t.same(fs.statSync(fileB).mode, fs.statSync(fileA).mode)
++ t.same(mtime(fs.statSync(fileB)), mtime(fs.statSync(fileA)))
+ })
+ })
+
+@@ -44,18 +44,18 @@
+ .pipe(tar.extract(b))
+ .on('finish', function () {
+ const files = fs.readdirSync(b)
+- t.is(files.length, 1)
+- t.is(files[0], 'a')
++ t.same(files.length, 1)
++ t.same(files[0], 'a')
+ const dirB = path.join(b, files[0])
+ const dirA = path.join(a, files[0])
+- t.alike(fs.statSync(dirB).mode, fs.statSync(dirA).mode)
+- t.alike(mtime(fs.statSync(dirB)), mtime(fs.statSync(dirA)))
++ t.same(fs.statSync(dirB).mode, fs.statSync(dirA).mode)
++ t.same(mtime(fs.statSync(dirB)), mtime(fs.statSync(dirA)))
+ t.ok(fs.statSync(dirB).isDirectory())
+ const fileB = path.join(dirB, 'test.txt')
+ const fileA = path.join(dirA, 'test.txt')
+- t.alike(fs.readFileSync(fileB, 'utf-8'), fs.readFileSync(fileA, 'utf-8'))
+- t.alike(fs.statSync(fileB).mode, fs.statSync(fileA).mode)
+- t.alike(mtime(fs.statSync(fileB)), mtime(fs.statSync(fileA)))
++ t.same(fs.readFileSync(fileB, 'utf-8'), fs.readFileSync(fileA, 'utf-8'))
++ t.same(fs.statSync(fileB).mode, fs.statSync(fileA).mode)
++ t.same(mtime(fs.statSync(fileB)), mtime(fs.statSync(fileA)))
+ })
+ })
+
+@@ -80,15 +80,15 @@
+ .pipe(tar.extract(b))
+ .on('finish', function () {
+ const files = fs.readdirSync(b).sort()
+- t.is(files.length, 2)
+- t.is(files[0], '.gitignore')
+- t.is(files[1], 'link')
++ t.same(files.length, 2)
++ t.same(files[0], '.gitignore')
++ t.same(files[1], 'link')
+
+ const linkA = path.join(a, 'link')
+ const linkB = path.join(b, 'link')
+
+- t.alike(mtime(fs.lstatSync(linkB)), mtime(fs.lstatSync(linkA)))
+- t.alike(fs.readlinkSync(linkB), fs.readlinkSync(linkA))
++ t.same(mtime(fs.lstatSync(linkB)), mtime(fs.lstatSync(linkA)))
++ t.same(fs.readlinkSync(linkB), fs.readlinkSync(linkA))
+ })
+ })
+
+@@ -113,15 +113,15 @@
+ .pipe(tar.extract(b))
+ .on('finish', function () {
+ const files = fs.readdirSync(b).sort()
+- t.is(files.length, 2)
+- t.is(files[0], '.gitignore')
+- t.is(files[1], 'link')
++ t.same(files.length, 2)
++ t.same(files[0], '.gitignore')
++ t.same(files[1], 'link')
+
+ const file1 = path.join(b, '.gitignore')
+ const file2 = path.join(b, 'link')
+
+- t.alike(mtime(fs.lstatSync(file1)), mtime(fs.lstatSync(file2)))
+- t.alike(fs.readFileSync(file1), fs.readFileSync(file2))
++ t.same(mtime(fs.lstatSync(file1)), mtime(fs.lstatSync(file2)))
++ t.same(fs.readFileSync(file1), fs.readFileSync(file2))
+ })
+ })
+
+@@ -137,8 +137,8 @@
+ .pipe(tar.extract(b, { strip: 1 }))
+ .on('finish', function () {
+ const files = fs.readdirSync(b).sort()
+- t.is(files.length, 1)
+- t.is(files[0], 'test.txt')
++ t.same(files.length, 1)
++ t.same(files[0], 'test.txt')
+ })
+ })
+
+@@ -159,8 +159,8 @@
+ .pipe(tar.extract(b, { strip: 1, map: uppercase }))
+ .on('finish', function () {
+ const files = fs.readdirSync(b).sort()
+- t.is(files.length, 1)
+- t.is(files[0], 'TEST.TXT')
++ t.same(files.length, 1)
++ t.same(files[0], 'TEST.TXT')
+ })
+ })
+
+@@ -184,9 +184,9 @@
+ .on('finish', function () {
+ const files = fs.readdirSync(b).sort()
+ const stat = fs.statSync(path.join(b, 'a'))
+- t.is(files.length, 1)
++ t.same(files.length, 1)
+ if (!win32) {
+- t.is(stat.mode & parseInt(777, 8), parseInt(700, 8))
++ t.same(stat.mode & parseInt(777, 8), parseInt(700, 8))
+ }
+ })
+ })
+@@ -200,18 +200,18 @@
+ const entries = ['file1', 'sub-files/file3', 'sub-dir']
+
+ rimraf.sync(b)
+- tar.pack(a, { entries })
++ tar.pack(a, { entries: entries })
+ .pipe(tar.extract(b))
+ .on('finish', function () {
+ const files = fs.readdirSync(b)
+- t.is(files.length, 3)
+- t.not(files.indexOf('file1'), -1)
+- t.not(files.indexOf('sub-files'), -1)
+- t.not(files.indexOf('sub-dir'), -1)
++ t.same(files.length, 3)
++ t.notSame(files.indexOf('file1'), -1)
++ t.notSame(files.indexOf('sub-files'), -1)
++ t.notSame(files.indexOf('sub-dir'), -1)
+ const subFiles = fs.readdirSync(path.join(b, 'sub-files'))
+- t.alike(subFiles, ['file3'])
++ t.same(subFiles, ['file3'])
+ const subDir = fs.readdirSync(path.join(b, 'sub-dir'))
+- t.alike(subDir, ['file5'])
++ t.same(subDir, ['file5'])
+ })
+ })
+
+@@ -221,7 +221,7 @@
+ const e = path.join(__dirname, 'fixtures', 'e')
+
+ const checkHeaderType = function (header) {
+- if (header.name.indexOf('.') === -1) t.is(header.type, header.name)
++ if (header.name.indexOf('.') === -1) t.same(header.type, header.name)
+ }
+
+ tar.pack(e, { map: checkHeaderType })
+@@ -235,20 +235,21 @@
+
+ rimraf.sync(b)
+
+- let packEntries = 0
+- let extractEntries = 0
++ var packEntries = 0
++ var extractEntries = 0
+
+ const countPackEntry = function (header) { packEntries++ }
+ const countExtractEntry = function (header) { extractEntries++ }
+
++ var pack
+ const onPackFinish = function (passedPack) {
+- t.is(packEntries, 2, 'All entries have been packed') // 2 entries - the file and base directory
+- t.is(passedPack, pack, 'The finish hook passes the pack')
++ t.equal(packEntries, 2, 'All entries have been packed') // 2 entries - the file and base directory
++ t.equal(passedPack, pack, 'The finish hook passes the pack')
+ }
+
+- const onExtractFinish = function () { t.is(extractEntries, 2) }
++ const onExtractFinish = function () { t.equal(extractEntries, 2) }
+
+- const pack = tar.pack(a, { map: countPackEntry, finish: onPackFinish })
++ pack = tar.pack(a, { map: countPackEntry, finish: onPackFinish })
+
+ pack.pipe(tar.extract(b, { map: countExtractEntry, finish: onExtractFinish }))
+ .on('finish', function () {
+@@ -280,28 +281,20 @@
+ })
+
+ function packB (pack) {
+- tar.pack(b, { pack, map: prefixer('b-files') })
++ tar.pack(b, { pack: pack, map: prefixer('b-files') })
+ .pipe(tar.extract(out))
+ .on('finish', assertResults)
+ }
+
+ function assertResults () {
+ const containers = fs.readdirSync(out)
+- t.alike(containers, ['a-files', 'b-files'])
++ t.deepEqual(containers, ['a-files', 'b-files'])
+ const aFiles = fs.readdirSync(path.join(out, 'a-files'))
+- t.alike(aFiles, ['hello.txt'])
++ t.deepEqual(aFiles, ['hello.txt'])
+ }
+ })
+
+ test('do not extract invalid tar', function (t) {
+- if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
+- t.plan(1)
+- t.ok(true)
+- return
+- }
+-
+- t.plan(2)
+-
+ const a = path.join(__dirname, 'fixtures', 'invalid.tar')
+
+ const out = path.join(__dirname, 'fixtures', 'invalid')
+@@ -314,22 +307,12 @@
+ t.ok(/is not a valid symlink/i.test(err.message))
+ fs.stat(path.join(out, '../bar'), function (err) {
+ t.ok(err)
++ t.end()
+ })
+ })
+- .on('finish', function () {
+- t.fail('should not finish')
+- })
+ })
+
+ test('no abs hardlink targets', function (t) {
+- if (win32) { // no symlink support on win32 currently. TODO: test if this can be enabled somehow
+- t.plan(1)
+- t.ok(true)
+- return
+- }
+-
+- t.plan(3)
+-
+ const out = path.join(__dirname, 'fixtures', 'invalid')
+ const outside = path.join(__dirname, 'fixtures', 'outside')
+
+@@ -355,8 +338,9 @@
+ .on('error', function (err) {
+ t.ok(err, 'had error')
+ fs.readFile(outside, 'utf-8', function (err, str) {
+- t.absent(err, 'no error')
+- t.is(str, 'something')
++ t.error(err, 'no error')
++ t.same(str, 'something')
++ t.end()
+ })
+ })
+ })
diff --git a/debian/patches/series b/debian/patches/series
index a22cf9d..a9a0458 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1 @@
-fix-test.patch
+keep-test-with-tape.patch
diff --git a/debian/tests/test_modules/b4a/LICENSE b/debian/tests/test_modules/b4a/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/debian/tests/test_modules/b4a/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/debian/tests/test_modules/b4a/README.md b/debian/tests/test_modules/b4a/README.md
deleted file mode 100644
index 6acf9ae..0000000
--- a/debian/tests/test_modules/b4a/README.md
+++ /dev/null
@@ -1,145 +0,0 @@
-# Buffer for Array
-
-Buffer for Array (B4A) provides a set of functions for bridging the gap between the Node.js `Buffer` class and the `Uint8Array` class. A browser compatibility layer is also included, making it possible to use B4A in both Node.js and browsers without having to worry about whether you're dealing with buffers or typed arrays.
-
-## Installation
-
-```sh
-npm install b4a
-```
-
-## API
-
-#### `b4a.isBuffer(value)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferisbufferobj
-
-This will also return `true` when passed a `Uint8Array`.
-
-#### `b4a.isEncoding(encoding)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferisencodingencoding
-
-#### `b4a.alloc(size[, fill[, encoding]])`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferallocsize-fill-encoding
-
-#### `b4a.allocUnsafe(size)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferallocunsafesize
-
-#### `b4a.allocUnsafeSlow(size)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferallocunsafeslowsize
-
-#### `b4a.byteLength(string)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferbytelengthstring-encoding
-
-#### `b4a.compare(buf1, buf2)`
-
-See https://nodejs.org/api/buffer.html#static-method-buffercomparebuf1-buf2
-
-#### `b4a.concat(buffers[, totalLength])`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferconcatlist-totallength
-
-#### `b4a.copy(source, target[, targetStart[, sourceStart[, sourceEnd]]])`
-
-See https://nodejs.org/api/buffer.html#bufcopytarget-targetstart-sourcestart-sourceend
-
-#### `b4a.equals(buf1, buf2)`
-
-See https://nodejs.org/api/buffer.html#bufequalsotherbuffer
-
-#### `b4a.fill(buffer, value[, offset[, end]][, encoding])`
-
-See https://nodejs.org/api/buffer.html#buffillvalue-offset-end-encoding
-
-#### `b4a.from(array)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferfromarray
-
-#### `b4a.from(arrayBuffer[, byteOffset[, length]])`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferfromarraybuffer-byteoffset-length
-
-#### `b4a.from(buffer)`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferfrombuffer
-
-#### `b4a.from(string[, encoding])`
-
-See https://nodejs.org/api/buffer.html#static-method-bufferfromstring-encoding
-
-#### `b4a.includes(buffer, value[, byteOffset][, encoding])`
-
-See https://nodejs.org/api/buffer.html#bufincludesvalue-byteoffset-encoding
-
-#### `b4a.indexOf(buffer, value[, byteOffset][, encoding])`
-
-See https://nodejs.org/api/buffer.html#bufindexofvalue-byteoffset-encoding
-
-#### `b4a.lastIndexOf(buffer, value[, byteOffset][, encoding])`
-
-See https://nodejs.org/api/buffer.html#buflastindexofvalue-byteoffset-encoding
-
-#### `b4a.swap16(buffer)`
-
-See https://nodejs.org/api/buffer.html#bufswap16
-
-#### `b4a.swap32(buffer)`
-
-See https://nodejs.org/api/buffer.html#bufswap32
-
-#### `b4a.swap64(buffer)`
-
-See https://nodejs.org/api/buffer.html#bufswap64
-
-#### `b4a.toBuffer(buffer)`
-
-Convert a buffer to its canonical representation. In Node.js, the canonical representation is a `Buffer`. In the browser, the canonical representation is a `Uint8Array`.
-
-#### `b4a.toString(buffer, [encoding[, start[, end]]])`
-
-See https://nodejs.org/api/buffer.html#buftostringencoding-start-end
-
-#### `b4a.write(buffer, string[, offset[, length]][, encoding])`
-
-See https://nodejs.org/api/buffer.html#bufwritestring-offset-length-encoding
-
-#### `b4a.writeDoubleLE(buffer, value[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufwritedoublelevalue-offset
-
-#### `b4a.writeFloatLE(buffer, value[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufwritefloatlevalue-offset
-
-#### `b4a.writeUInt32LE(buffer, value[, offset])`
-
-https://nodejs.org/api/buffer.html#bufwriteuint32levalue-offset
-
-#### `b4a.writeInt32LE(buffer, value[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufwriteint32levalue-offset
-
-#### `b4a.readDoubleLE(buffer[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufreaddoubleleoffset
-
-#### `b4a.readFloatLE(buffer[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufreadfloatleoffset
-
-#### `b4a.readUInt32LE(buffer[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufreaduint32leoffset
-
-#### `b4a.readInt32LE(buffer[, offset])`
-
-See https://nodejs.org/api/buffer.html#bufreadint32leoffset
-
-## License
-
-Apache 2.0
diff --git a/debian/tests/test_modules/b4a/browser.js b/debian/tests/test_modules/b4a/browser.js
deleted file mode 100644
index 798a32f..0000000
--- a/debian/tests/test_modules/b4a/browser.js
+++ /dev/null
@@ -1,576 +0,0 @@
-const ascii = require('./lib/ascii')
-const base64 = require('./lib/base64')
-const hex = require('./lib/hex')
-const utf8 = require('./lib/utf8')
-const utf16le = require('./lib/utf16le')
-
-const LE = new Uint8Array(Uint16Array.of(0xff).buffer)[0] === 0xff
-
-function codecFor (encoding) {
- switch (encoding) {
- case 'ascii':
- return ascii
- case 'base64':
- return base64
- case 'hex':
- return hex
- case 'utf8':
- case 'utf-8':
- case undefined:
- case null:
- return utf8
- case 'ucs2':
- case 'ucs-2':
- case 'utf16le':
- case 'utf-16le':
- return utf16le
- default:
- throw new Error(`Unknown encoding: ${encoding}`)
- }
-}
-
-function isBuffer (value) {
- return value instanceof Uint8Array
-}
-
-function isEncoding (encoding) {
- try {
- codecFor(encoding)
- return true
- } catch {
- return false
- }
-}
-
-function alloc (size, fill, encoding) {
- const buffer = new Uint8Array(size)
- if (fill !== undefined) exports.fill(buffer, fill, 0, buffer.byteLength, encoding)
- return buffer
-}
-
-function allocUnsafe (size) {
- return new Uint8Array(size)
-}
-
-function allocUnsafeSlow (size) {
- return new Uint8Array(size)
-}
-
-function byteLength (string, encoding) {
- return codecFor(encoding).byteLength(string)
-}
-
-function compare (a, b) {
- if (a === b) return 0
-
- const len = Math.min(a.byteLength, b.byteLength)
-
- a = new DataView(a.buffer, a.byteOffset, a.byteLength)
- b = new DataView(b.buffer, b.byteOffset, b.byteLength)
-
- let i = 0
-
- for (let n = len - (len % 4); i < n; i += 4) {
- const x = a.getUint32(i, LE)
- const y = b.getUint32(i, LE)
- if (x !== y) break
- }
-
- for (; i < len; i++) {
- const x = a.getUint8(i)
- const y = b.getUint8(i)
- if (x < y) return -1
- if (x > y) return 1
- }
-
- return a.byteLength > b.byteLength ? 1 : a.byteLength < b.byteLength ? -1 : 0
-}
-
-function concat (buffers, totalLength) {
- if (totalLength === undefined) {
- totalLength = buffers.reduce((len, buffer) => len + buffer.byteLength, 0)
- }
-
- const result = new Uint8Array(totalLength)
-
- let offset = 0
- for (const buffer of buffers) {
- if (offset + buffer.byteLength > result.byteLength) {
- const sub = buffer.subarray(0, result.byteLength - offset)
- result.set(sub, offset)
- return result
- }
- result.set(buffer, offset)
- offset += buffer.byteLength
- }
-
- return result
-}
-
-function copy (source, target, targetStart = 0, start = 0, end = source.byteLength) {
- if (end > 0 && end < start) return 0
- if (end === start) return 0
- if (source.byteLength === 0 || target.byteLength === 0) return 0
-
- if (targetStart < 0) throw new RangeError('targetStart is out of range')
- if (start < 0 || start >= source.byteLength) throw new RangeError('sourceStart is out of range')
- if (end < 0) throw new RangeError('sourceEnd is out of range')
-
- if (targetStart >= target.byteLength) targetStart = target.byteLength
- if (end > source.byteLength) end = source.byteLength
- if (target.byteLength - targetStart < end - start) {
- end = target.length - targetStart + start
- }
-
- const len = end - start
-
- if (source === target) {
- target.copyWithin(targetStart, start, end)
- } else {
- target.set(source.subarray(start, end), targetStart)
- }
-
- return len
-}
-
-function equals (a, b) {
- if (a === b) return true
- if (a.byteLength !== b.byteLength) return false
-
- const len = a.byteLength
-
- a = new DataView(a.buffer, a.byteOffset, a.byteLength)
- b = new DataView(b.buffer, b.byteOffset, b.byteLength)
-
- let i = 0
-
- for (let n = len - (len % 4); i < n; i += 4) {
- if (a.getUint32(i, LE) !== b.getUint32(i, LE)) return false
- }
-
- for (; i < len; i++) {
- if (a.getUint8(i) !== b.getUint8(i)) return false
- }
-
- return true
-}
-
-function fill (buffer, value, offset, end, encoding) {
- if (typeof value === 'string') {
- // fill(buffer, string, encoding)
- if (typeof offset === 'string') {
- encoding = offset
- offset = 0
- end = buffer.byteLength
-
- // fill(buffer, string, offset, encoding)
- } else if (typeof end === 'string') {
- encoding = end
- end = buffer.byteLength
- }
- } else if (typeof value === 'number') {
- value = value & 0xff
- } else if (typeof value === 'boolean') {
- value = +value
- }
-
- if (offset < 0 || buffer.byteLength < offset || buffer.byteLength < end) {
- throw new RangeError('Out of range index')
- }
-
- if (offset === undefined) offset = 0
- if (end === undefined) end = buffer.byteLength
-
- if (end <= offset) return buffer
-
- if (!value) value = 0
-
- if (typeof value === 'number') {
- for (let i = offset; i < end; ++i) {
- buffer[i] = value
- }
- } else {
- value = isBuffer(value) ? value : from(value, encoding)
-
- const len = value.byteLength
-
- for (let i = 0; i < end - offset; ++i) {
- buffer[i + offset] = value[i % len]
- }
- }
-
- return buffer
-}
-
-function from (value, encodingOrOffset, length) {
- // from(string, encoding)
- if (typeof value === 'string') return fromString(value, encodingOrOffset)
-
- // from(array)
- if (Array.isArray(value)) return fromArray(value)
-
- // from(buffer)
- if (ArrayBuffer.isView(value)) return fromBuffer(value)
-
- // from(arrayBuffer[, byteOffset[, length]])
- return fromArrayBuffer(value, encodingOrOffset, length)
-}
-
-function fromString (string, encoding) {
- const codec = codecFor(encoding)
- const buffer = new Uint8Array(codec.byteLength(string))
- codec.write(buffer, string, 0, buffer.byteLength)
- return buffer
-}
-
-function fromArray (array) {
- const buffer = new Uint8Array(array.length)
- buffer.set(array)
- return buffer
-}
-
-function fromBuffer (buffer) {
- const copy = new Uint8Array(buffer.byteLength)
- copy.set(buffer)
- return copy
-}
-
-function fromArrayBuffer (arrayBuffer, byteOffset, length) {
- return new Uint8Array(arrayBuffer, byteOffset, length)
-}
-
-function includes (buffer, value, byteOffset, encoding) {
- return indexOf(buffer, value, byteOffset, encoding) !== -1
-}
-
-function bidirectionalIndexOf (buffer, value, byteOffset, encoding, first) {
- if (buffer.byteLength === 0) return -1
-
- if (typeof byteOffset === 'string') {
- encoding = byteOffset
- byteOffset = 0
- } else if (byteOffset === undefined) {
- byteOffset = first ? 0 : (buffer.length - 1)
- } else if (byteOffset < 0) {
- byteOffset += buffer.byteLength
- }
-
- if (byteOffset >= buffer.byteLength) {
- if (first) return -1
- else byteOffset = buffer.byteLength - 1
- } else if (byteOffset < 0) {
- if (first) byteOffset = 0
- else return -1
- }
-
- if (typeof value === 'string') {
- value = from(value, encoding)
- } else if (typeof value === 'number') {
- value = value & 0xff
-
- if (first) {
- return buffer.indexOf(value, byteOffset)
- } else {
- return buffer.lastIndexOf(value, byteOffset)
- }
- }
-
- if (value.byteLength === 0) return -1
-
- if (first) {
- let foundIndex = -1
-
- for (let i = byteOffset; i < buffer.byteLength; i++) {
- if (buffer[i] === value[foundIndex === -1 ? 0 : i - foundIndex]) {
- if (foundIndex === -1) foundIndex = i
- if (i - foundIndex + 1 === value.byteLength) return foundIndex
- } else {
- if (foundIndex !== -1) i -= i - foundIndex
- foundIndex = -1
- }
- }
- } else {
- if (byteOffset + value.byteLength > buffer.byteLength) {
- byteOffset = buffer.byteLength - value.byteLength
- }
-
- for (let i = byteOffset; i >= 0; i--) {
- let found = true
-
- for (let j = 0; j < value.byteLength; j++) {
- if (buffer[i + j] !== value[j]) {
- found = false
- break
- }
- }
-
- if (found) return i
- }
- }
-
- return -1
-}
-
-function indexOf (buffer, value, byteOffset, encoding) {
- return bidirectionalIndexOf(buffer, value, byteOffset, encoding, true /* first */)
-}
-
-function lastIndexOf (buffer, value, byteOffset, encoding) {
- return bidirectionalIndexOf(buffer, value, byteOffset, encoding, false /* last */)
-}
-
-function swap (buffer, n, m) {
- const i = buffer[n]
- buffer[n] = buffer[m]
- buffer[m] = i
-}
-
-function swap16 (buffer) {
- const len = buffer.byteLength
-
- if (len % 2 !== 0) throw new RangeError('Buffer size must be a multiple of 16-bits')
-
- for (let i = 0; i < len; i += 2) swap(buffer, i, i + 1)
-
- return buffer
-}
-
-function swap32 (buffer) {
- const len = buffer.byteLength
-
- if (len % 4 !== 0) throw new RangeError('Buffer size must be a multiple of 32-bits')
-
- for (let i = 0; i < len; i += 4) {
- swap(buffer, i, i + 3)
- swap(buffer, i + 1, i + 2)
- }
-
- return buffer
-}
-
-function swap64 (buffer) {
- const len = buffer.byteLength
-
- if (len % 8 !== 0) throw new RangeError('Buffer size must be a multiple of 64-bits')
-
- for (let i = 0; i < len; i += 8) {
- swap(buffer, i, i + 7)
- swap(buffer, i + 1, i + 6)
- swap(buffer, i + 2, i + 5)
- swap(buffer, i + 3, i + 4)
- }
-
- return buffer
-}
-
-function toBuffer (buffer) {
- return buffer
-}
-
-function toString (buffer, encoding, start = 0, end = buffer.byteLength) {
- const len = buffer.byteLength
-
- if (start >= len) return ''
- if (end <= start) return ''
- if (start < 0) start = 0
- if (end > len) end = len
-
- if (start !== 0 || end < len) buffer = buffer.subarray(start, end)
-
- return codecFor(encoding).toString(buffer)
-}
-
-function write (buffer, string, offset, length, encoding) {
- // write(buffer, string)
- if (offset === undefined) {
- encoding = 'utf8'
-
- // write(buffer, string, encoding)
- } else if (length === undefined && typeof offset === 'string') {
- encoding = offset
- offset = undefined
-
- // write(buffer, string, offset, encoding)
- } else if (encoding === undefined && typeof length === 'string') {
- encoding = length
- length = undefined
- }
-
- return codecFor(encoding).write(buffer, string, offset, length)
-}
-
-function writeDoubleLE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setFloat64(offset, value, true)
-
- return offset + 8
-}
-
-function writeFloatLE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setFloat32(offset, value, true)
-
- return offset + 4
-}
-
-function writeUInt32LE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setUint32(offset, value, true)
-
- return offset + 4
-}
-
-function writeInt32LE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setInt32(offset, value, true)
-
- return offset + 4
-}
-
-function readDoubleLE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getFloat64(offset, true)
-}
-
-function readFloatLE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getFloat32(offset, true)
-}
-
-function readUInt32LE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getUint32(offset, true)
-}
-
-function readInt32LE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getInt32(offset, true)
-}
-
-function writeDoubleBE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setFloat64(offset, value, false)
-
- return offset + 8
-}
-
-function writeFloatBE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setFloat32(offset, value, false)
-
- return offset + 4
-}
-
-function writeUInt32BE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setUint32(offset, value, false)
-
- return offset + 4
-}
-
-function writeInt32BE (buffer, value, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
- view.setInt32(offset, value, false)
-
- return offset + 4
-}
-
-function readDoubleBE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getFloat64(offset, false)
-}
-
-function readFloatBE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getFloat32(offset, false)
-}
-
-function readUInt32BE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getUint32(offset, false)
-}
-
-function readInt32BE (buffer, offset) {
- if (offset === undefined) offset = 0
-
- const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-
- return view.getInt32(offset, false)
-}
-
-module.exports = exports = {
- isBuffer,
- isEncoding,
- alloc,
- allocUnsafe,
- allocUnsafeSlow,
- byteLength,
- compare,
- concat,
- copy,
- equals,
- fill,
- from,
- includes,
- indexOf,
- lastIndexOf,
- swap16,
- swap32,
- swap64,
- toBuffer,
- toString,
- write,
- writeDoubleLE,
- writeFloatLE,
- writeUInt32LE,
- writeInt32LE,
- readDoubleLE,
- readFloatLE,
- readUInt32LE,
- readInt32LE,
- writeDoubleBE,
- writeFloatBE,
- writeUInt32BE,
- writeInt32BE,
- readDoubleBE,
- readFloatBE,
- readUInt32BE,
- readInt32BE
-}
diff --git a/debian/tests/test_modules/b4a/index.js b/debian/tests/test_modules/b4a/index.js
deleted file mode 100644
index 5c807d8..0000000
--- a/debian/tests/test_modules/b4a/index.js
+++ /dev/null
@@ -1,189 +0,0 @@
-function isBuffer (value) {
- return Buffer.isBuffer(value) || value instanceof Uint8Array
-}
-
-function isEncoding (encoding) {
- return Buffer.isEncoding(encoding)
-}
-
-function alloc (size, fill, encoding) {
- return Buffer.alloc(size, fill, encoding)
-}
-
-function allocUnsafe (size) {
- return Buffer.allocUnsafe(size)
-}
-
-function allocUnsafeSlow (size) {
- return Buffer.allocUnsafeSlow(size)
-}
-
-function byteLength (string, encoding) {
- return Buffer.byteLength(string, encoding)
-}
-
-function compare (a, b) {
- return Buffer.compare(a, b)
-}
-
-function concat (buffers, totalLength) {
- return Buffer.concat(buffers, totalLength)
-}
-
-function copy (source, target, targetStart, start, end) {
- return toBuffer(source).copy(target, targetStart, start, end)
-}
-
-function equals (a, b) {
- return toBuffer(a).equals(b)
-}
-
-function fill (buffer, value, offset, end, encoding) {
- return toBuffer(buffer).fill(value, offset, end, encoding)
-}
-
-function from (value, encodingOrOffset, length) {
- return Buffer.from(value, encodingOrOffset, length)
-}
-
-function includes (buffer, value, byteOffset, encoding) {
- return toBuffer(buffer).includes(value, byteOffset, encoding)
-}
-
-function indexOf (buffer, value, byfeOffset, encoding) {
- return toBuffer(buffer).indexOf(value, byfeOffset, encoding)
-}
-
-function lastIndexOf (buffer, value, byteOffset, encoding) {
- return toBuffer(buffer).lastIndexOf(value, byteOffset, encoding)
-}
-
-function swap16 (buffer) {
- return toBuffer(buffer).swap16()
-}
-
-function swap32 (buffer) {
- return toBuffer(buffer).swap32()
-}
-
-function swap64 (buffer) {
- return toBuffer(buffer).swap64()
-}
-
-function toBuffer (buffer) {
- if (Buffer.isBuffer(buffer)) return buffer
- return Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength)
-}
-
-function toString (buffer, encoding, start, end) {
- return toBuffer(buffer).toString(encoding, start, end)
-}
-
-function write (buffer, string, offset, length, encoding) {
- return toBuffer(buffer).write(string, offset, length, encoding)
-}
-
-function writeDoubleLE (buffer, value, offset) {
- return toBuffer(buffer).writeDoubleLE(value, offset)
-}
-
-function writeFloatLE (buffer, value, offset) {
- return toBuffer(buffer).writeFloatLE(value, offset)
-}
-
-function writeUInt32LE (buffer, value, offset) {
- return toBuffer(buffer).writeUInt32LE(value, offset)
-}
-
-function writeInt32LE (buffer, value, offset) {
- return toBuffer(buffer).writeInt32LE(value, offset)
-}
-
-function readDoubleLE (buffer, offset) {
- return toBuffer(buffer).readDoubleLE(offset)
-}
-
-function readFloatLE (buffer, offset) {
- return toBuffer(buffer).readFloatLE(offset)
-}
-
-function readUInt32LE (buffer, offset) {
- return toBuffer(buffer).readUInt32LE(offset)
-}
-
-function readInt32LE (buffer, offset) {
- return toBuffer(buffer).readInt32LE(offset)
-}
-
-function writeDoubleBE (buffer, value, offset) {
- return toBuffer(buffer).writeDoubleBE(value, offset)
-}
-
-function writeFloatBE (buffer, value, offset) {
- return toBuffer(buffer).writeFloatBE(value, offset)
-}
-
-function writeUInt32BE (buffer, value, offset) {
- return toBuffer(buffer).writeUInt32BE(value, offset)
-}
-
-function writeInt32BE (buffer, value, offset) {
- return toBuffer(buffer).writeInt32BE(value, offset)
-}
-
-function readDoubleBE (buffer, offset) {
- return toBuffer(buffer).readDoubleBE(offset)
-}
-
-function readFloatBE (buffer, offset) {
- return toBuffer(buffer).readFloatBE(offset)
-}
-
-function readUInt32BE (buffer, offset) {
- return toBuffer(buffer).readUInt32BE(offset)
-}
-
-function readInt32BE (buffer, offset) {
- return toBuffer(buffer).readInt32BE(offset)
-}
-
-module.exports = {
- isBuffer,
- isEncoding,
- alloc,
- allocUnsafe,
- allocUnsafeSlow,
- byteLength,
- compare,
- concat,
- copy,
- equals,
- fill,
- from,
- includes,
- indexOf,
- lastIndexOf,
- swap16,
- swap32,
- swap64,
- toBuffer,
- toString,
- write,
- writeDoubleLE,
- writeFloatLE,
- writeUInt32LE,
- writeInt32LE,
- readDoubleLE,
- readFloatLE,
- readUInt32LE,
- readInt32LE,
- writeDoubleBE,
- writeFloatBE,
- writeUInt32BE,
- writeInt32BE,
- readDoubleBE,
- readFloatBE,
- readUInt32BE,
- readInt32BE
-
-}
diff --git a/debian/tests/test_modules/b4a/lib/ascii.js b/debian/tests/test_modules/b4a/lib/ascii.js
deleted file mode 100644
index 3a2e3b2..0000000
--- a/debian/tests/test_modules/b4a/lib/ascii.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function byteLength (string) {
- return string.length
-}
-
-function toString (buffer) {
- const len = buffer.byteLength
-
- let result = ''
-
- for (let i = 0; i < len; i++) {
- result += String.fromCharCode(buffer[i])
- }
-
- return result
-}
-
-function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
-
- for (let i = 0; i < len; i++) {
- buffer[offset + i] = string.charCodeAt(i)
- }
-
- return len
-}
-
-module.exports = {
- byteLength,
- toString,
- write
-}
diff --git a/debian/tests/test_modules/b4a/lib/base64.js b/debian/tests/test_modules/b4a/lib/base64.js
deleted file mode 100644
index d4731e3..0000000
--- a/debian/tests/test_modules/b4a/lib/base64.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-
-const codes = new Uint8Array(256)
-
-for (let i = 0; i < alphabet.length; i++) {
- codes[alphabet.charCodeAt(i)] = i
-}
-
-codes[/* - */ 0x2d] = 62
-codes[/* _ */ 0x5f] = 63
-
-function byteLength (string) {
- let len = string.length
-
- if (string.charCodeAt(len - 1) === 0x3d) len--
- if (len > 1 && string.charCodeAt(len - 1) === 0x3d) len--
-
- return (len * 3) >>> 2
-}
-
-function toString (buffer) {
- const len = buffer.byteLength
-
- let result = ''
-
- for (let i = 0; i < len; i += 3) {
- result += (
- alphabet[buffer[i] >> 2] +
- alphabet[((buffer[i] & 3) << 4) | (buffer[i + 1] >> 4)] +
- alphabet[((buffer[i + 1] & 15) << 2) | (buffer[i + 2] >> 6)] +
- alphabet[buffer[i + 2] & 63]
- )
- }
-
- if (len % 3 === 2) {
- result = result.substring(0, result.length - 1) + '='
- } else if (len % 3 === 1) {
- result = result.substring(0, result.length - 2) + '=='
- }
-
- return result
-};
-
-function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
-
- for (let i = 0, j = 0; j < len; i += 4) {
- const a = codes[string.charCodeAt(i)]
- const b = codes[string.charCodeAt(i + 1)]
- const c = codes[string.charCodeAt(i + 2)]
- const d = codes[string.charCodeAt(i + 3)]
-
- buffer[j++] = (a << 2) | (b >> 4)
- buffer[j++] = ((b & 15) << 4) | (c >> 2)
- buffer[j++] = ((c & 3) << 6) | (d & 63)
- }
-
- return len
-};
-
-module.exports = {
- byteLength,
- toString,
- write
-}
diff --git a/debian/tests/test_modules/b4a/lib/hex.js b/debian/tests/test_modules/b4a/lib/hex.js
deleted file mode 100644
index d63c88a..0000000
--- a/debian/tests/test_modules/b4a/lib/hex.js
+++ /dev/null
@@ -1,51 +0,0 @@
-function byteLength (string) {
- return string.length >>> 1
-}
-
-function toString (buffer) {
- const len = buffer.byteLength
-
- buffer = new DataView(buffer.buffer, buffer.byteOffset, len)
-
- let result = ''
- let i = 0
-
- for (let n = len - (len % 4); i < n; i += 4) {
- result += buffer.getUint32(i).toString(16).padStart(8, '0')
- }
-
- for (; i < len; i++) {
- result += buffer.getUint8(i).toString(16).padStart(2, '0')
- }
-
- return result
-}
-
-function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
-
- for (let i = 0; i < len; i++) {
- const a = hexValue(string.charCodeAt(i * 2))
- const b = hexValue(string.charCodeAt(i * 2 + 1))
-
- if (a === undefined || b === undefined) {
- return buffer.subarray(0, i)
- }
-
- buffer[offset + i] = (a << 4) | b
- }
-
- return len
-}
-
-module.exports = {
- byteLength,
- toString,
- write
-}
-
-function hexValue (char) {
- if (char >= 0x30 && char <= 0x39) return char - 0x30
- if (char >= 0x41 && char <= 0x46) return char - 0x41 + 10
- if (char >= 0x61 && char <= 0x66) return char - 0x61 + 10
-}
diff --git a/debian/tests/test_modules/b4a/lib/utf16le.js b/debian/tests/test_modules/b4a/lib/utf16le.js
deleted file mode 100644
index 87d7ed4..0000000
--- a/debian/tests/test_modules/b4a/lib/utf16le.js
+++ /dev/null
@@ -1,40 +0,0 @@
-function byteLength (string) {
- return string.length * 2
-}
-
-function toString (buffer) {
- const len = buffer.byteLength
-
- let result = ''
-
- for (let i = 0; i < len - 1; i += 2) {
- result += String.fromCharCode(buffer[i] + (buffer[i + 1] * 256))
- }
-
- return result
-}
-
-function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
-
- let units = len
-
- for (let i = 0; i < string.length; ++i) {
- if ((units -= 2) < 0) break
-
- const c = string.charCodeAt(i)
- const hi = c >> 8
- const lo = c % 256
-
- buffer[offset + i * 2] = lo
- buffer[offset + i * 2 + 1] = hi
- }
-
- return len
-}
-
-module.exports = {
- byteLength,
- toString,
- write
-}
diff --git a/debian/tests/test_modules/b4a/lib/utf8.js b/debian/tests/test_modules/b4a/lib/utf8.js
deleted file mode 100644
index b36d072..0000000
--- a/debian/tests/test_modules/b4a/lib/utf8.js
+++ /dev/null
@@ -1,145 +0,0 @@
-function byteLength (string) {
- let length = 0
-
- for (let i = 0, n = string.length; i < n; i++) {
- const code = string.charCodeAt(i)
-
- if (code >= 0xd800 && code <= 0xdbff && i + 1 < n) {
- const code = string.charCodeAt(i + 1)
-
- if (code >= 0xdc00 && code <= 0xdfff) {
- length += 4
- i++
- continue
- }
- }
-
- if (code <= 0x7f) length += 1
- else if (code <= 0x7ff) length += 2
- else length += 3
- }
-
- return length
-}
-
-let toString
-
-if (typeof TextDecoder !== 'undefined') {
- const decoder = new TextDecoder()
-
- toString = function toString (buffer) {
- return decoder.decode(buffer)
- }
-} else {
- toString = function toString (buffer) {
- const len = buffer.byteLength
-
- let output = ''
- let i = 0
-
- while (i < len) {
- let byte = buffer[i]
-
- if (byte <= 0x7f) {
- output += String.fromCharCode(byte)
- i++
- continue
- }
-
- let bytesNeeded = 0
- let codePoint = 0
-
- if (byte <= 0xdf) {
- bytesNeeded = 1
- codePoint = byte & 0x1f
- } else if (byte <= 0xef) {
- bytesNeeded = 2
- codePoint = byte & 0x0f
- } else if (byte <= 0xf4) {
- bytesNeeded = 3
- codePoint = byte & 0x07
- }
-
- if (len - i - bytesNeeded > 0) {
- let k = 0
-
- while (k < bytesNeeded) {
- byte = buffer[i + k + 1]
- codePoint = (codePoint << 6) | (byte & 0x3f)
- k += 1
- }
- } else {
- codePoint = 0xfffd
- bytesNeeded = len - i
- }
-
- output += String.fromCodePoint(codePoint)
- i += bytesNeeded + 1
- }
-
- return output
- }
-}
-
-let write
-
-if (typeof TextEncoder !== 'undefined') {
- const encoder = new TextEncoder()
-
- write = function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
- encoder.encodeInto(string, buffer.subarray(offset, offset + len))
- return len
- }
-} else {
- write = function write (buffer, string, offset = 0, length = byteLength(string)) {
- const len = Math.min(length, buffer.byteLength - offset)
-
- buffer = buffer.subarray(offset, offset + len)
-
- let i = 0
- let j = 0
-
- while (i < string.length) {
- const code = string.codePointAt(i)
-
- if (code <= 0x7f) {
- buffer[j++] = code
- i++
- continue
- }
-
- let count = 0
- let bits = 0
-
- if (code <= 0x7ff) {
- count = 6
- bits = 0xc0
- } else if (code <= 0xffff) {
- count = 12
- bits = 0xe0
- } else if (code <= 0x1fffff) {
- count = 18
- bits = 0xf0
- }
-
- buffer[j++] = bits | (code >> count)
- count -= 6
-
- while (count >= 0) {
- buffer[j++] = 0x80 | ((code >> count) & 0x3f)
- count -= 6
- }
-
- i += code >= 0x10000 ? 2 : 1
- }
-
- return len
- }
-}
-
-module.exports = {
- byteLength,
- toString,
- write
-}
diff --git a/debian/tests/test_modules/b4a/package.json b/debian/tests/test_modules/b4a/package.json
deleted file mode 100644
index 7b30afd..0000000
--- a/debian/tests/test_modules/b4a/package.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "name": "b4a",
- "version": "1.6.7",
- "description": "Bridging the gap between buffers and typed arrays",
- "main": "index.js",
- "files": [
- "browser.js",
- "index.js",
- "lib"
- ],
- "browser": {
- "./index.js": "./browser.js"
- },
- "scripts": {
- "test": "standard && brittle test/*.mjs"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/holepunchto/b4a.git"
- },
- "author": "Holepunch",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/holepunchto/b4a/issues"
- },
- "homepage": "https://github.com/holepunchto/b4a#readme",
- "devDependencies": {
- "brittle": "^3.5.2",
- "nanobench": "^3.0.0",
- "standard": "^17.1.0"
- }
-}
diff --git a/debian/tests/test_modules/brittle/LICENSE b/debian/tests/test_modules/brittle/LICENSE
deleted file mode 100644
index 261eeb9..0000000
--- a/debian/tests/test_modules/brittle/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/debian/tests/test_modules/brittle/README.md b/debian/tests/test_modules/brittle/README.md
deleted file mode 100644
index a3454dc..0000000
--- a/debian/tests/test_modules/brittle/README.md
+++ /dev/null
@@ -1,665 +0,0 @@
-# brittle
-
-> tap ? la mode
-
-A TAP test runner built for modern times.
-
-<img width=300 height=200 src=brittle.png>
-
-## Usage
-
-First install brittle from npm
-
-```
-npm i brittle
-```
-
-Then start writing tests
-
-```javascript
-import test from 'brittle'
-
-test('basic', function (t) {
- t.is(typeof Date.now(), 'number')
- t.not(typeof Date.now(), 'string')
-
- t.ok(Date.now() > 0)
- t.absent(null)
-
- t.comment('text')
-
- t.alike({ a: 1 }, { a: 1 })
- t.unlike({ a: 2 }, { a: 3 })
-
- t.pass()
- t.fail()
-})
-
-test('asynchronous', async function (t) {
- await new Promise(r => setTimeout(r, 250))
- t.pass()
-})
-
-test('plans', function (t) {
- t.plan(2)
- t.pass()
- setTimeout(() => t.pass(), 250)
-})
-
-test('classic subtest', function (t) {
- t.test('subtest', function (sub) {
- sub.plan(1)
- sub.pass()
- })
-})
-
-test('inverted subtest', function (t) {
- const sub = t.test('subtest')
- sub.plan(1)
- sub.pass()
-})
-
-test('executions', async function (t) {
- t.execution(() => 'should not throw')
- await t.execution(async () => 'should not reject')
-})
-
-test('exceptions', async function (t) {
- t.exception(() => { throw Error('expected to throw') })
- await t.exception(async () => { throw Error('expected to reject') })
-})
-
-const a = test('inverted test without plan needs end()')
-a.pass()
-a.end()
-
-const b = test('inverted test with plan')
-b.plan(1)
-b.pass()
-
-const c = test('inverted tests can be awaited')
-c.plan(1)
-setTimeout(() => c.pass(), 250)
-await c
-```
-
-Every assertion can have a message, i.e. `t.pass('msg')`, `t.ok(false, 'should be true')`, etc.\
-There are also utilities like `t.timeout(ms)`, `t.teardown(fn)`, etc.\
-Check the API but also all the [assertions here](#assertions) and [utilities here](#utilities).
-
-## API
-
-```js
-import { test, solo, skip, hook, todo, configure } from 'brittle'
-```
-
-#### `test([name], [options], callback)`
-
-Create a classic test with an optional `name`.
-
-#### Available `options` for any test creation:
- * `timeout` (`30000`) - milliseconds to wait before ending a stalling test.
- * `solo` (`false`) - Skip all other tests except the `solo()` ones.
- * `hook` (`false`) - setup and teardown resources.
- * `skip` (`false`) - skip this test, alternatively use the `skip()` function.
- * `todo` (`false`) - mark this test as todo and skip it, alternatively use the `todo()` function.
- * `stealth` (`false`) - only print test summary.
-
-The `callback` function (can be async) receives an object called `assert`.\
-`assert` (or `t`) provides the assertions and utilities interface.
-
-```js
-import test from 'brittle'
-
-test('basic', function (t) {
- t.pass()
-})
-```
-
-Test files can be executed directly with `node`, as they're normal Node.js programs.
-
-The `test` method is conveniently both the default export and named exported method:
-
-```js
-import { test } from 'brittle'
-```
-
-Classic tests will run sequentially, buffering pending tests until any prior test catches up.
-
-Any test function returns a promise so you can optionally await for its result:
-
-```js
-const isOk = await test('basic', function (t) {
- t.pass()
-})
-```
-
-#### `test([name], [options]) => assert`
-
-Create an inverted test with an optional `name`.
-
-All `options` for inverted tests are [listed here](#available-options-for-any-test-creation).
-
-An object called `assert` (or `t`) is returned, the same as the classic test.
-
-This time it's also a promise, it can be awaited and it resolves at test completion.
-
-```js
-import test from 'brittle'
-
-const t = test('basic')
-
-t.plan(1)
-
-setTimeout(() => {
- t.pass()
-}, 1000)
-
-await t // Won't proceed past here until plan is fulfilled
-```
-
-For inverted tests without a plan, the `end` method must be called:
-
-```js
-const t = test('basic')
-
-setTimeout(() => {
- t.pass()
- t.end()
-}, 1000)
-
-await t
-```
-
-The `end()` method can be called inline, for inverted tests without a plan:
-
-```js
-const t = test('basic')
-t.pass()
-t.end()
-```
-
-Control flow of inverted is entirely dependent on where its `assert` is awaited.\
-The following executes one test after another:
-
-```js
-const a = test('first test')
-const b = test('second test')
-a.plan(1)
-b.plan(1)
-a.pass()
-await a
-b.pass()
-await b
-```
-
-Awaiting the promise gives you its result:
-
-```js
-const t = test('first test')
-t.plan(1)
-t.pass()
-const isOk = await t
-```
-
-#### `stealth([name], [options], callback)`
-#### `stealth([name], [options]) => assert`
-
-Create a stealth test.\
-This will provide a new sub-assert object that only prints the test summary without assertions and ends the current test upon a failed assertion.
-
-All `options` are the same as `test` which are [listed here](#available-options-for-any-test-creation).
-
-#### `t.test([name], [options], callback)`
-#### `t.test([name], [options]) => assert`
-
-A subtest can be created by calling `test` on an `assert` (or `t`) object.\
-This will provide a new sub-assert object.
-
-All `options` for subtests are [listed here](#available-options-for-any-test-creation).
-
-Using this in inverted style can be very useful for flow control within a test:
-
-```js
-test('basic', async function (t) {
- const a = t.test('sub test')
- const b = t.test('other sub test')
-
- a.plan(1)
- b.plan(1)
-
- setTimeout(() => a.ok(true), Math.random() * 1000)
- setTimeout(() => b.ok(true), Math.random() * 1000)
-
- // Won't proceed past here until both a and b plans are fulfilled
- await a
- await b
-
- t.pass()
-})
-```
-
-Subtest test options can be set by passing an object to the `test` function:
-
-```js
-test('parent', { timeout: 1000 }, function (t) {
- t.test('basic using parent config', async function (t) {
- await new Promise(r => setTimeout(r, 500))
- t.pass()
- })
-
- t.test('another basic using parent config', function (t) {
- t.pass()
- })
-})
-```
-
-You can also await for its result as well:
-
-```js
-test('basic', async function (t) {
- t.plan(1)
- t.pass()
- const isOk = await t
- console.log(isOk)
-})
-```
-
-#### `t.stealth([name], [options], callback)`
-#### `t.stealth([name], [options]) => assert`
-
-Create a stealth sub-test.\
-This will provide a new sub-assert object that only prints the test summary without assertions and ends the current test upon a failed assertion.
-
-All `options` are the same as `test` which are [listed here](#available-options-for-any-test-creation).
-
-#### `solo([name], [options], callback)`
-#### `solo([name], [options]) => assert`
-
-Filter out other tests by using the `solo` method:
-
-```js
-import { test, solo } from 'brittle'
-
-test('this test is skipped', function (t) {
- t.pass()
-})
-
-solo('some test', function (t) {
- t.pass()
-})
-```
-
-If a `solo` function is used, `test` functions will not execute.\
-
-If `solo` is used in a future tick (for example, in a `setTimeout` callback),\
-after `test` has already been used those tests won't be filtered.
-
-A few ways to enable `solo` functions:
-- Use `configure({ solo: true })` before any tests.
-- You can call `solo()` without callback underneath the imports.
-- Using the `--solo` flag with the `brittle` test runner.
-
-It can also be used as an inverted test:
-
-```js
-const t = test.solo('inverted some test')
-t.pass()
-t.end()
-```
-
-#### `skip([name], [options], callback)`
-
-Skip a test:
-
-```js
-import { test, skip } from 'brittle'
-
-skip('this test is skipped', function (t) {
- t.pass()
-})
-
-test('middle test', function (t) {
- t.pass()
-})
-
-test.skip('another skipped test', function (t) {
- t.pass()
-})
-```
-
-Only the `middle test` will be executed.
-
-#### `hook([name], [options], callback)`
-
-Use before tests for setting up and after tests for tearing down. Runs the same way as `test` except always executes regardless of `solo` usage.
-
-```js
-import { test, solo, hook } from 'brittle'
-
-hook('setup hook', function (t) {
- // setup resources
-})
-
-solo('solo test', function (t) {
- t.pass()
-})
-
-test('middle test', function (t) {
- t.pass()
-})
-
-hook('teardown hook', function (t) {
- // teardown resources
-})
-```
-
-The `setup hook`, `solo test` and `teardown hook` will be executed.
-
-#### `configure([options])`
-
-The `configure` function can be used to set options for all tests (including child tests).\
-It must be executed before any tests.
-
-#### Options
-
- * `timeout` (`30000`) - milliseconds to wait before ending a stalling test
- * `bail` (`false`) - exit the process on first test failure
- * `solo` (`false`) - skip all other tests except the `solo()` ones
- * `source` (`true`) - shows error `source` information
- * `unstealth` (`false`) - show assertions even if `stealth` is used
-
-```js
-import { configure } from 'brittle'
-
-configure({ timeout: 15000 }) // All tests will have a 15 seconds timeout
-```
-
-### Assertions
-
-#### `t.is(actual, expected, [message])`
-
-Compare `actual` to `expected` with `===`
-
-#### `t.not(actual, expected, [message])`
-
-Compare `actual` to `expected` with `!==`
-
-#### `t.alike(actual, expected, [message])`
-
-Object comparison, comparing all primitives on the
-`actual` object to those on the `expected` object
-using `===`.
-
-#### `t.unlike(actual, expected, [message])`
-
-Object comparison, comparing all primitives on the
-`actual` object to those on the `expected` object
-using `!==`.
-
-#### `t.ok(value, [message])`
-
-Checks that `value` is truthy: `!!value === true`
-
-#### `t.absent(value, [message])`
-
-Checks that `value` is falsy: `!!value === false`
-
-#### `t.pass([message])`
-
-Asserts success. Useful for explicitly confirming
-that a function was called, or that behavior is
-as expected.
-
-#### `t.fail([message])`
-
-Asserts failure. Useful for explicitly checking
-that a function should not be called.
-
-#### `t.exception(Promise|function|async function, [error], [message])`
-
-Verify that a function throws, or a promise rejects.
-
-```js
-t.exception(() => { throw Error('an err') }, /an err/)
-await t.exception(async () => { throw Error('an err') }, /an err/)
-await t.exception(Promise.reject(Error('an err')), /an err/)
-```
-
-If the error is an instance of any of the following native error constructors,
-then this will still result in failure since native errors often tend to be unintentational.
-
-* `SyntaxError`
-* `ReferenceError`
-* `TypeError`
-* `EvalError`
-* `RangeError`
-
-If a `t.exception` is async, then you're supposed to await it.
-
-#### `t.exception.all(Promise|function|async function, [error], [message])`
-
-Verify that a function throws, or a promise rejects, including native errors.
-
-```js
-t.exception.all(() => { throw Error('an err') }, /an err/)
-await t.exception.all(async () => { throw Error('an err') }, /an err/)
-await t.exception.all(Promise.reject(new SyntaxError('native error')), /native error/)
-```
-
-The `t.exception.all` method is an escape-hatch so it can be used with the
-normally filtered native errors.
-
-If a `t.exception.all` is async, then you're supposed to await it.
-
-#### `t.execution(Promise|function|async function, [message])`
-
-Assert that a function executes instead of throwing or that a promise resolves instead of rejecting. Resolves to the execution time, in milliseconds, of the function or promise.
-
-```js
-t.execution(() => {})
-await t.execution(async () => {})
-await t.execution(Promise.resolve('cool'))
-```
-
-If a `t.execution` is async, then you're supposed to await it
-
-#### `t.is.coercively(actual, expected, [message])`
-
-Compare `actual` to `expected` with `==`.
-
-#### `t.not.coercively(actual, expected, [message])`
-
-Compare `actual` to `expected` with `!=`.
-
-#### `t.alike.coercively(actual, expected, [message])`
-
-Object comparison, comparing all primitives on the
-`actual` object to those on the `expected` object
-using `==`.
-
-#### `t.unlike.coercively(actual, expected, [message])`
-
-Object comparison, comparing all primitives on the
-`actual` object to those on the `expected` object
-using `!=`.
-
-
-### Utilities
-
-#### `t.plan(n)`
-
-Constrain a test to an explicit amount of assertions.
-
-#### `t.tmp() -> <Promise<String>>`
-
-Creates a temporary folder and returns a promise that resolves its path. Once a test either succeeds or fails, the temporary folder is removed.
-
-#### `t.teardown(function|async function, [options])`
-
-**Options:**
-
- * `order` (`0`) - set the ascending position priority for a teardown to be executed.
- * `force` (`false`) - run the teardown on failure as well as success
-
-The function passed to `teardown` is called right after a test ends:
-
-```js
-test('basic', function (t) {
- const timeoutId = setTimeout(() => {}, 1000)
-
- t.teardown(async function () {
- clearTimeout(timeoutId)
- await doMoreCleanUp()
- })
-
- t.ok('cool')
-})
-```
-
-If `teardown` is called multiple times in a test, every function passed will be called after the test ends:
-
-```js
-test('basic', function (t) {
- t.teardown(doSomeCleanUp)
-
- const timeoutId = setTimeout(() => {}, 1000)
- t.teardown(() => clearTimeout(timeoutId))
-
- t.ok('again, cool')
-})
-```
-
-Set `order: -Infinity` to always be in first place, and vice versa with `order: Infinity`.\
-If two teardowns have the same `order` they are ordered per time of invocation within that order group.
-
-```js
-test('teardown order', function (t) {
- t.teardown(async function () {
- await new Promise(r => setTimeout(r, 200))
- console.log('teardown B')
- })
-
- t.teardown(async function () {
- await new Promise(r => setTimeout(r, 200))
- console.log('teardown A')
- }, { order: -1 })
-
- t.teardown(async function () {
- await new Promise(r => setTimeout(r, 200))
- console.log('teardown C')
- }, { order: 1 })
-
- t.pass()
-})
-```
-
-The `A` teardown is executed first, then `B`, and finally `C` due to the `order` option.
-
-#### `t.timeout(ms)`
-
-Fail the test after a given timeout.
-
-#### `t.comment(message)`
-
-Inject a TAP comment into the output.
-
-#### `t.end()`
-
-Force end a test.\
-`end` is determined by `assert` resolution or when a containing async function completes.\
-In case of inverted tests, they're required to be explicitly called.
-
-
-### Readable Properties
-
-#### `t.name`
-The name of the test.
-
-#### `t.passes`
-The number of assertions that passed within the test.
-
-#### `t.fails`
-The number of assertions that failed within the test.
-
-#### `t.assertions`
-The number of assertions that were executed within the test.
-
-## Runner
-
-### Default timeout
-
-The default timeout is 30 seconds.
-
-### Example of `package.json` with `test` script
-
-The following would run all `.js` files in the test folder:
-
-```json
-{
- "name": "my-app",
- "version": "1.0.0",
- "scripts": {
- "test": "brittle test/*.js"
- },
- "devDependencies": {
- "brittle": "^3.0.0-alpha.3"
- }
-}
-```
-
-## CLI
-
-```sh
-npm install -g brittle
-```
-
-```shell
-brittle [flags] <files>
-
-Flags:
- --solo, -s Engage solo mode
- --bail, -b Bail out on first assert failure
- --coverage, -cov, -c Turn on coverage
- --cov-dir <dir> Configure coverage output directory (default: ./coverage)
- --trace Trace all active promises and print them if the test fails
- --timeout, -t <timeout> Set the test timeout in milliseconds (default: 30000)
- --runner, -r <runner> Generates an out file that contains all target tests
- --mine, -m <miners> Keep running the tests in <miners> processes until they fail.
- --unstealth, -u Show assertions even if stealth is used
- --help|-h Show help
-```
-
-Note globbing is supported:
-```sh
-brittle --coverage path/to/test/*.js
-```
-
-Auto generate a single file containing "all tests":
-```shell
-brittle -r test/all.js test/*.js
-
-node test/all.js
-```
-
-You can use an environment variable to also set flags:
-```shell
-BRITTLE="--coverage --bail" brittle test.js
-```
-
-Force disable coverage with an environment variable:
-```shell
-BRITTLE_COVERAGE=false brittle test.js
-```
-### Coverage
-If the `--coverage` flag is set, brittle will output the coverage summary as a table at the end of execution and generate a json coverage report in the coverage output directory (configurable using `--cov-dir`).
-
-The coverage output directory will contain a `coverage-final.json` file which contains an istanbul json coverage report and a `v8-coverage.json` file which contains the raw v8 coverage data.
-
-Istanbul can be used to convert the istanbul json report into other formats. e.g.:
-```
-npx istanbul report html
-```
-
-## License
-Apache-2.0
diff --git a/debian/tests/test_modules/brittle/cmd.js b/debian/tests/test_modules/brittle/cmd.js
deleted file mode 100755
index 315d7e7..0000000
--- a/debian/tests/test_modules/brittle/cmd.js
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/env node
-
-const path = require('path')
-const { command, flag, rest } = require('paparam')
-const Globbie = require('globbie')
-const { spawn } = require('child_process')
-const TracingPromise = require('./lib/tracing-promise')
-
-const args = process.argv.slice(2).concat((process.env.BRITTLE || '').split(/\s|,/g).map(s => s.trim()).filter(s => s))
-const cmd = command('brittle',
- flag('--solo, -s', 'Engage solo mode'),
- flag('--bail, -b', 'Bail out on first assert failure'),
- flag('--coverage, -cov, -c', 'Turn on coverage'),
- flag('--cov-dir <dir>', 'Configure coverage output directory (default: ./coverage)'),
- flag('--trace', 'Trace all active promises and print them if the test fails'),
- flag('--timeout, -t <timeout>', 'Set the test timeout in milliseconds (default: 30000)'),
- flag('--runner, -r <runner>', 'Generates an out file that contains all target tests'),
- flag('--mine, -m <miners>', 'Keep running the tests in <miners> processes until they fail.'),
- flag('--unstealth, -u', 'Print out assertions even if stealth is used'),
- rest('<files>')
-).parse(args)
-if (!cmd) process.exit(0)
-
-const argv = cmd.flags
-
-const files = []
-for (const g of cmd.rest || []) {
- const glob = new Globbie(g, { sync: true })
- const matches = glob.match()
-
- if (matches.length === 0) {
- if (g[0] === '-') continue
- console.error(`Error: no files found when resolving ${g}`)
- process.exit(1)
- }
-
- files.push(...matches)
-}
-
-if (files.length === 0) {
- console.error('Error: No test files were specified')
- process.exit(1)
-}
-
-const { solo, bail, timeout, cov, mine, trace, unstealth } = argv
-
-process.title = 'brittle'
-
-if (trace && !mine) {
- TracingPromise.enable()
- process.on('exit', function (code) {
- if (!code) return
- console.error()
- console.error('Printing tracing info since the tests failed:')
- console.error()
- TracingPromise.print()
- })
-}
-
-if (argv.runner) {
- const fs = require('fs')
-
- if (argv.runner === true) {
- console.error('--runner must be a path to the generated test runner')
- process.exit(2)
- }
-
- const out = path.resolve(argv.runner)
- const dir = path.dirname(out)
-
- let s = ''
-
- s += 'runTests()\n\nasync function runTests () {\n const test = (await import(\'brittle\')).default\n\n'
-
- if (bail || solo || unstealth || timeout) {
- s += ` test.configure({ bail: ${!!bail}, solo: ${!!solo}, unstealth: ${!!unstealth}, timeout: ${timeout} })\n`
- }
-
- s += ' test.pause()\n\n'
-
- for (const f of files) {
- const t = path.resolve(f)
- if (t === out) continue
-
- let r = path.relative(dir, t)
- if (r[0] !== '.') r = '.' + path.sep + r
- s += ' await import(\'' + r + '\')\n'
- }
-
- s = s.trimRight()
-
- s += '\n\n test.resume()\n}\n'
- s = '// This runner is auto-generated by Brittle\n\n' + s
-
- try {
- fs.mkdirSync(dir)
- } catch {}
-
- fs.writeFileSync(out, s)
- process.exit(0)
-}
-
-if (cov && process.env.BRITTLE_COVERAGE !== 'false') require('bare-cov')({ dir: argv['cov-dir'] })
-
-if (mine) startMining().catch()
-else start().catch(onerror)
-
-function onerror (err) {
- console.error(err.stack)
- process.exit(1)
-}
-
-async function start () {
- const brittle = require('./')
-
- if (bail || solo || unstealth || timeout) {
- brittle.configure({ bail, solo, unstealth, timeout: timeout ? Number(timeout) : undefined })
- }
-
- brittle.pause()
-
- for (const f of files) {
- await import('file://' + path.resolve(f))
- }
-
- brittle.resume()
-}
-
-async function startMining () {
- const args = [__filename]
- .concat(solo ? ['--solo'] : [])
- .concat(bail ? ['--bail'] : [])
- .concat(unstealth ? ['--unstealth'] : [])
- .concat(trace ? ['--trace'] : [])
- .concat(timeout ? ['--timeout', timeout + ''] : [])
- .concat(files)
-
- const running = new Set()
- const max = Number(argv.mine) || 1
-
- let runs = 0
- let bailed = false
- let newline = false
-
- const interval = setInterval(function () {
- console.log('Still mining... Total runs: ' + runs)
- newline = true
- }, 1000)
-
- bump()
-
- process.once('SIGINT', bail)
- process.once('SIGTERM', bail)
-
- function bail () {
- bailed = true
- clearInterval(interval)
- for (const r of running) r.kill()
- }
-
- async function bump () {
- if (running.size >= max || bailed) return
-
- const r = run()
- running.add(r)
-
- const { exitCode, output } = await r.promise
- running.delete(r)
- runs++
-
- if (bailed) return
-
- if (!exitCode) {
- bump()
- bump()
- return
- }
-
- bailed = true
-
- clearInterval(interval)
-
- if (newline) console.log()
- console.log('Runner failed with exit code ' + exitCode + '!')
- console.log('Shutting down the rest and printing output...')
-
- for (const r of running) {
- r.kill()
- await r.promise
- }
-
- console.log('Done! The tests took ' + runs + ' runs to fail.')
- console.log()
-
- for (const { stdout, data } of output) {
- if (stdout) process.stdout.write(data)
- else process.stderr.write(data)
- }
-
- process.exit(exitCode)
- }
-
- function run () {
- const p = spawn(process.execPath, args)
-
- const output = []
-
- p.stdout.on('data', (data) => output.push({ stdout: true, data }))
- p.stderr.on('data', (data) => output.push({ stdout: false, data }))
-
- const promise = new Promise((resolve) => {
- p.on('close', (exitCode) => {
- resolve({
- exitCode,
- output
- })
- })
- })
-
- return {
- promise,
- kill: () => p.kill()
- }
- }
-}
diff --git a/debian/tests/test_modules/brittle/index.js b/debian/tests/test_modules/brittle/index.js
deleted file mode 100644
index 4800df8..0000000
--- a/debian/tests/test_modules/brittle/index.js
+++ /dev/null
@@ -1,883 +0,0 @@
-const sameObject = require('same-object')
-const tmp = require('test-tmp')
-const b4a = require('b4a')
-const { getSnapshot, createTypedArray } = require('./lib/snapshot')
-const { INDENT, RUNNER, IS_NODE, IS_BARE, DEFAULT_TIMEOUT } = require('./lib/constants')
-const AssertionError = require('./lib/assertion-error')
-const TracingPromise = require('./lib/tracing-promise')
-const Promise = TracingPromise.Untraced // never trace internal onces
-
-const highDefTimer = IS_NODE ? highDefTimerNode : highDefTimerFallback
-
-// loaded on demand since it's error flow and we want ultra fast positive test runs
-const lazy = {
- _errors: null,
- _tmatch: null,
- get errors () {
- if (!lazy._errors) lazy._errors = require('./lib/errors.js')
- return lazy._errors
- },
- get tmatch () {
- if (!lazy._tmatch) lazy._tmatch = require('tmatch')
- return lazy._tmatch
- }
-}
-
-class Runner {
- constructor () {
- this.tests = { count: 0, pass: 0 }
- this.assertions = { count: 0, pass: 0 }
-
- this.next = null
- this.solos = new Set()
- this.padded = true
- this.started = false
- this.defaultTimeout = DEFAULT_TIMEOUT
- this.bail = false
- this.unstealth = false
- this.skipAll = false
- this.explicitSolo = false
- this.source = true
-
- this._timer = highDefTimer()
- this._log = console.log.bind(console)
- this._paused = null
- this._resume = null
-
- const target = IS_NODE ? process : global.Bare
- const ondeadlock = () => {
- if (this.next && this.next._checkDeadlock === false) return
- target.off('beforeExit', ondeadlock)
- this.end()
- }
-
- target.on('beforeExit', ondeadlock)
- }
-
- resume () {
- if (!this._paused) return
- this._resume()
- this._resume = this._paused = null
- }
-
- pause () {
- if (this._paused) return
- this._paused = new Promise((resolve) => { this._resume = resolve })
- }
-
- async _wait () {
- await wait()
- await this._paused
- }
-
- async queue (test) {
- this.start()
-
- if (test._isSolo) {
- this.solos.add(test)
- }
-
- await this._wait()
-
- if (this.explicitSolo && !test._isSolo) {
- return false
- }
-
- if (this._shouldTest(test)) {
- while (this.next !== null) {
- const next = this.next
- await next
- if (next === this.next) this.next = null
- }
-
- if (test._isSkip) {
- this._skip('SKIP', test)
- return false
- }
-
- if (test._isTodo) {
- this._skip('TODO', test)
- return false
- }
-
- if (!this._shouldTest(test)) {
- return false
- }
-
- this.next = test
- test._header()
-
- if (!IS_NODE && !IS_BARE) this._autoExit(test)
-
- return true
- }
-
- return false
- }
-
- _skip (reason, test) {
- if (this._shouldTest(test)) {
- test._header()
- this.tests.pass++
- this.tests.count++
- this.assert(false, true, this.tests.count, '- ' + test.name + ' # ' + reason, null)
- }
- }
-
- _shouldTest (test) {
- return test._isHook || (!this.skipAll && (this.solos.size === 0 || this.solos.has(test)))
- }
-
- async _autoExit (test) {
- try {
- await test
- await wait(10) // wait 10 ticks...
- if (this.next === test) {
- this.end()
- }
- } catch {}
- }
-
- log (...message) {
- this._log(...message)
- this.padded = false
- }
-
- padding () {
- if (this.padded) return
- this.padded = true
- this.log()
- }
-
- start () {
- if (this.started) return
- this.started = true
- this.log('TAP version 13')
- }
-
- comment (...message) {
- this.log('#', ...message)
- }
-
- end () {
- if (this.next) {
- if (!this.next._isEnded && !(this.next._hasPlan && this.next._planned === 0)) {
- this.next._onend(prematureEnd(this.next, 'Test did not end (' + this.next.name + ')'))
- return
- }
-
- if (!this.next._isResolved) {
- if (this.next._isDone) {
- this.next._onend(new Error('Teardown did not end (unresolved promise)'))
- return
- }
- this.next._onend(new Error('Test appears deadlocked (unresolved promise)'))
- return
- }
- }
-
- if (this.bail && this.skipAll) {
- this.log('Bail out!')
- }
-
- this.padding()
- this.log('1..' + this.tests.count)
- this.log('# tests = ' + this.tests.pass + '/' + this.tests.count + ' pass')
- this.log('# asserts = ' + this.assertions.pass + '/' + this.assertions.count + ' pass')
- this.log('# time = ' + this._timer() + 'ms')
- this.log()
-
- if (this.tests.count === this.tests.pass && this.assertions.count === this.assertions.pass) this.log('# ok')
- else this.log('# not ok')
- }
-
- assert (indent, ok, number, message, explanation, stealth) {
- const ind = indent ? INDENT : ''
-
- if (ok) {
- if (!stealth || this.unstealth) this.log(ind + 'ok ' + number, message)
- } else {
- if (IS_NODE) process.exitCode = 1
- if (IS_BARE) global.Bare.exitCode = 1
- this.log(ind + 'not ok ' + number, message)
- if (explanation) this.log(lazy.errors.stringify(explanation))
- if (this.bail && !this.skipAll) this.skipAll = true
- if (!this.unstealth && stealth) throw new AssertionError({ message: 'Stealth assertion failed' })
- }
- }
-}
-
-class Test {
- constructor (name, parent, opts = {}) {
- this._resolve = null
- this._reject = null
-
- this._promise = new Promise((resolve, reject) => {
- this._resolve = resolve
- this._reject = reject
- })
-
- this._parents = []
- this._main = parent ? parent._main : this
- this._runner = getRunner()
- this.name = name
- this.passes = 0
- this.fails = 0
- this.assertions = 0
-
- this._isEnded = false
- this._isDone = false
- this._isHook = opts?.hook || false
- this._isSolo = opts?.solo || false
- this._isSkip = opts?.skip || false
- this._isTodo = opts?.todo || false
- this._isResolved = false
- this._isQueued = false
- this._isMain = this._main === this
- this._isStealth = opts?.stealth || parent?._isStealth || false
- this._checkDeadlock = opts?.deadlock !== false
-
- // allow destructuring by binding the functions
- this.comment = this._comment.bind(this)
- this.timeout = this._timeout.bind(this)
- this.teardown = this._teardown.bind(this)
- this.test = this._test.bind(this)
- this.plan = this._plan.bind(this)
-
- this.pass = this._pass.bind(this)
- this.fail = this._fail.bind(this)
-
- this.ok = this._ok.bind(this)
- this.absent = this._absent.bind(this)
-
- this.is = this._is.bind(this, true)
- this.is.coercively = this._is.bind(this, false)
-
- this.not = this._not.bind(this, true)
- this.not.coercively = this._not.bind(this, false)
-
- this.alike = this._alike.bind(this, true)
- this.alike.coercively = this._alike.bind(this, false)
-
- this.unlike = this._unlike.bind(this, true)
- this.unlike.coercively = this._unlike.bind(this, false)
-
- this.exception = this._exception.bind(this, false)
- this.exception.all = this._exception.bind(this, true)
-
- this.execution = this._execution.bind(this)
-
- this.stealth = this._stealth.bind(this)
-
- this.snapshot = this._snapshot.bind(this)
-
- this.end = this._end.bind(this)
-
- this._parent = parent
- this._first = true
- this._wait = false
- this._planned = 0
- this._hasPlan = false
- this._active = 0
- this._timer = null
-
- this._headerLogged = false
- this._to = null
- this._teardowns = []
- this._tickers = new Map()
-
- while (parent) {
- this._parents.push(parent)
- parent = parent._parent
- }
- }
-
- then (...args) {
- return this._promise.then(...args)
- }
-
- catch (...args) {
- return this._promise.catch(...args)
- }
-
- finally (...args) {
- return this._promise.finally(...args)
- }
-
- _header () {
- if (this._headerLogged) return
- this._headerLogged = true
- this._runner.start()
- this._runner.padding()
- this._runner.comment(this.name || 'test')
- }
-
- tmp () { return tmp(this) }
-
- _planDoneOrEnd () {
- return this._isEnded || (this._hasPlan && this._planned === 0)
- }
-
- _timeout (ms) {
- if (!ms) {
- if (this._to) clearTimeout(this._to)
- this._to = null
- return
- }
-
- const ontimeout = () => {
- this._to = null
- this._onend(new Error('Test timed out after ' + ms + ' ms'))
- }
-
- if (this._to) clearTimeout(this._to)
- this._to = setTimeout(ontimeout, ms)
- if (this._to.unref) this._to.unref()
- }
-
- _plan (n) {
- if (typeof n !== 'number' || n < 0) {
- throw new Error('Plan takes a positive whole number only')
- }
-
- this._hasPlan = true
- this._planned = n
- }
-
- _comment (...m) {
- if (this._isResolved) throw new Error('Can\'t comment after end')
- this._runner.log(INDENT + '#', ...m)
- }
-
- _message (message) {
- let m = '- '
-
- if (!this._isMain) {
- for (let i = this._parents.length - 2; i >= 0; i--) {
- const p = this._parents[i]
- if (!p.name) continue
- m += '(' + p.name + ') - '
- }
- if (this.name) {
- m += '(' + this.name + ') - '
- }
- }
-
- if (message) {
- m += message
- }
-
- return m
- }
-
- _tick (ok) {
- if (ok) this.passes++
- else this.fails++
- this.assertions++
- }
-
- _track (topLevel, ok) {
- if (topLevel) {
- this._runner.tests.count++
- if (ok) this._runner.tests.pass++
- return this._runner.tests.count
- }
-
- if (this._hasPlan) this._planned--
- this._tick(ok)
-
- if (!this._isMain) this._main._tick(ok)
-
- this._runner.assertions.count++
- if (ok) this._runner.assertions.pass++
-
- return this._main.assertions
- }
-
- _assertion (ok, message, explanation, caller, top, isStealth = this._isStealth) {
- this._runner.assert(!this._main._isResolved, ok, this._track(false, ok), this._message(message), explanation, isStealth)
-
- if (this._isEnded || this._isDone) {
- throw new AssertionError({ message: 'Assertion after end' })
- }
-
- if (this._hasPlan && this._planned < 0) {
- throw new AssertionError({ message: 'Too many assertions' })
- }
-
- if (this._hasPlan && this._planned === 0) {
- this._checkEnd()
- }
- }
-
- _fail (message = 'failed') {
- const explanation = explain(false, message, 'fail', this._fail)
- this._assertion(false, message, explanation, this._fail, undefined)
- }
-
- _pass (message = 'passed') {
- this._assertion(true, message, null, this._pass, undefined)
- }
-
- _ok (assertion, message = 'expected truthy value') {
- const ok = assertion
- const explanation = explain(ok, message, 'ok', this._ok)
- this._assertion(ok, message, explanation, this._ok, undefined)
- }
-
- _absent (assertion, message = 'expected falsy value') {
- const ok = !assertion
- const explanation = explain(ok, message, 'absent', this._absent)
- this._assertion(ok, message, explanation, this._absent, undefined)
- }
-
- _is (strict, actual, expected, message = 'should be equal') {
- const ok = strict ? actual === expected : actual == expected // eslint-disable-line
- const explanation = explain(ok, message, 'is', this._is, actual, expected)
- this._assertion(ok, message, explanation, this._is, undefined)
- }
-
- _not (strict, actual, expected, message = 'should not be equal') {
- const ok = strict ? actual !== expected : actual != expected // eslint-disable-line
- const explanation = explain(ok, message, 'not', this._not, actual, expected)
- this._assertion(ok, message, explanation, this._not, undefined)
- }
-
- _alike (strict, actual, expected, message = 'should deep equal') {
- const ok = sameObject(actual, expected, { strict })
- const explanation = explain(ok, message, 'alike', this._alike, actual, expected)
- this._assertion(ok, message, explanation, this._alike, undefined)
- }
-
- _unlike (strict, actual, expected, message = 'should not deep equal') {
- const ok = sameObject(actual, expected, { strict }) === false
- const explanation = explain(ok, message, 'unlike', this._unlike, actual, expected)
- this._assertion(ok, message, explanation, this._unlike, undefined)
- }
-
- _teardown (fn, opts = {}) {
- if (this._isDone) throw new Error('Can\'t add teardown after end')
- this._teardowns.push([opts.order || 0, !!opts.force, fn])
- }
-
- async _exception (natives, functionOrPromise, expectedError, message) {
- if (typeof expectedError === 'string') {
- message = expectedError
- expectedError = undefined
- }
-
- const top = originFrame(this._exception)
- const pristineMessage = message === undefined
-
- let ok = null
- let actual = false
-
- if (pristineMessage) message = 'should throw'
-
- this._active++
- try {
- if (typeof functionOrPromise === 'function') functionOrPromise = functionOrPromise()
- if (isPromise(functionOrPromise)) {
- if (pristineMessage) message = 'should reject'
- await functionOrPromise
- }
- ok = false
- } catch (err) {
- const native = natives === false && isUncaught(err)
- if (native) throw err
-
- if (!expectedError) {
- ok = true
- } else {
- ok = lazy.tmatch(err, expectedError)
- }
-
- actual = err
- } finally {
- this._active--
- }
-
- const explanation = explain(ok, message, 'exception', this._exception, actual, expectedError, top)
- this._assertion(ok, message, explanation, this._execution, top)
- this._checkEnd()
- }
-
- async _execution (functionOrPromise, message) {
- const top = originFrame(this._execution)
- const pristineMessage = message === undefined
-
- let ok = false
- let error = null
-
- if (pristineMessage) message = 'should return'
-
- const time = highDefTimer()
-
- this._active++
- try {
- if (typeof functionOrPromise === 'function') functionOrPromise = functionOrPromise()
- if (isPromise(functionOrPromise)) {
- if (pristineMessage) message = 'should resolve'
- await functionOrPromise
- }
- ok = true
- } catch (err) {
- error = err
- } finally {
- this._active--
- }
-
- const elapsed = time()
-
- const explanation = explain(ok, message, 'execution', this._execution, error, null, top)
- this._assertion(ok, message, explanation, this._execution, top)
- this._checkEnd()
-
- return elapsed
- }
-
- _stealth (name, opts, fn) {
- if (typeof name === 'function') return this.stealth(null, null, name)
- if (typeof opts === 'function') return this.stealth(name, null, opts)
-
- return this.test(name, { ...opts, stealth: true }, fn)
- }
-
- _snapshot (actual, message = 'should match snapshot') {
- const top = originFrame(this._snapshot)
-
- if (!top) {
- this._assertion(true, message, null, this._snapshot, undefined)
- return
- }
-
- if (b4a.isBuffer(actual)) {
- actual = new Uint8Array(actual.buffer, actual.byteOffset, actual.byteLength)
- }
-
- const filename = top.getFileName()
- const key = (this.name || '') + ' ' + this._message(message)
- const expected = getSnapshot(filename, key + ' - ' + this._getTick(key), actual)
-
- const ok = sameObject(actual, expected, { strict: true })
- const explanation = explain(ok, message, 'snapshot', this._snapshot, actual, expected)
-
- this._assertion(ok, message, explanation, this._snapshot, undefined)
- }
-
- _getTick (key) {
- const tick = this._tickers.get(key) || 0
- this._tickers.set(key, 1 + tick)
- return tick
- }
-
- _test (name, opts, fn) {
- if (typeof name === 'function') return this.test(null, null, name)
- if (typeof opts === 'function') return this.test(name, null, opts)
-
- const t = new Test(name, this, opts)
-
- if (this._hasPlan) this._planned--
- this._active++
-
- return fn ? t._run(fn, opts || {}) : t
- }
-
- async _run (fn, opts) {
- this._isQueued = true
-
- if (!this._parent) {
- if (!(await this._runner.queue(this))) return
- }
-
- this._onstart(opts)
- this._wait = true
-
- try {
- await fn(this)
- } catch (err) {
- if (!(err instanceof AssertionError && err.message === 'ERR_ASSERTION: Stealth assertion failed')) {
- this._wait = false
- await this._runTeardown(err)
- throw err
- }
- }
-
- if (!this._hasPlan) this.end()
-
- this._wait = false
- this._checkEnd()
-
- await this
- }
-
- _end () {
- this._isEnded = true
-
- if (this._hasPlan && this._planned > 0) {
- throw prematureEnd(this, 'Too few assertions')
- }
-
- this._checkEnd()
- }
-
- _checkEnd () {
- if (this._active || this._wait) return
- if (this._isEnded || (this._hasPlan && this._planned === 0)) this._done()
- }
-
- _done () {
- if (this._isDone) return
- this._isDone = true
-
- if (this._teardowns.length) {
- this._teardowns.sort(cmp)
- this._runTeardown(null)
- } else {
- this._onend(null)
- }
-
- if (this._parent) {
- const p = this._parent
-
- this._parent._active--
- this._parent = null
-
- p._checkEnd()
- }
- }
-
- async _runTeardown (error) {
- const forced = !!error
-
- let fired = false
-
- const t = setTimeout(() => {
- fired = true
- this.comment('...teardown still running after 250ms')
- }, 250)
-
- if (t.unref) t.unref()
-
- const time = highDefTimer()
-
- for (const [, force, teardown] of this._teardowns) {
- try {
- if (force || !forced) await teardown()
- } catch (err) {
- if (!error) error = err
- }
- }
-
- clearTimeout(t)
- if (fired) this.comment('...teardown time ' + time() + 'ms')
- this._onend(error)
- }
-
- _onstart (opts) {
- const to = this._isMain
- ? (opts && opts.timeout !== undefined) ? opts.timeout : this._runner.defaultTimeout // main tests need a default timeout, unless opt-out
- : opts && opts.timeout // non main ones do not
-
- if (this._isMain) {
- if (!this._isQueued) {
- if (this._runner.next) throw new Error('Only run test can be running at the same time')
- this._runner.next = this
- }
- this._header()
- this._timer = highDefTimer()
- }
-
- if (to) this._timeout(to)
- }
-
- _onend (err) {
- if (this._isResolved) return
-
- this._timeout(0) // just to be sure incase someone ran this during teardown...
-
- const ok = (this.fails === 0)
-
- if (this._isMain && !err) {
- const time = this._timer ? ' # time = ' + this._timer() + 'ms' : ''
- this._runner.assert(false, ok, this._track(true, ok), '- ' + (this.name || '') + time, null)
- }
-
- this._isResolved = true
- this._isDone = true
-
- if (this._isMain && this._runner.next === this) {
- this._runner.next = null
- }
-
- if (err) this._reject(err)
- else this._resolve(ok)
-
- // if test is running without deadlock detection, trigger "io" to rerun it in case idle now
- if (this._checkDeadlock === false) setImmediate(() => {})
- }
-}
-
-exports = module.exports = test
-
-exports.Test = Test
-exports.test = test
-exports.hook = hook
-exports.solo = solo
-exports.skip = skip
-exports.todo = todo
-exports.configure = configure
-exports.pause = pause
-exports.resume = resume
-exports.stealth = stealth
-
-// Used by snapshots
-exports.createTypedArray = createTypedArray
-
-function configure ({ timeout = DEFAULT_TIMEOUT, bail = false, solo = false, unstealth = false, source = true } = {}) {
- const runner = getRunner()
-
- if (runner.tests.count > 0 || runner.assertions.count > 0) {
- throw new Error('Configuration must happen prior to registering any tests')
- }
-
- runner.defaultTimeout = timeout
- runner.bail = bail
- runner.explicitSolo = solo
- runner.unstealth = unstealth
- runner.source = source
-}
-
-function highDefTimerNode () {
- const then = process.hrtime.bigint()
- return function () {
- const now = process.hrtime.bigint()
- return Number(now - then) / 1e6
- }
-}
-
-function highDefTimerFallback () {
- const then = Date.now()
- return function () {
- const now = Date.now()
- return now - then
- }
-}
-
-function cmp (a, b) {
- return a[0] - b[0]
-}
-
-function test (name, opts, fn, overrides) {
- if (typeof name === 'function') return test(null, null, name, overrides)
- if (typeof opts === 'function') return test(name, null, opts, overrides)
-
- opts = { ...opts, ...overrides }
-
- const t = new Test(name, null, opts)
-
- if (fn) return t._run(fn, opts)
- if (t._isTodo) return t._run(() => {}, opts)
-
- if (t._isSkip) {
- throw new Error('An inverted test cannot be skipped')
- }
- if (t._isSolo) {
- t._runner.solo = t
- }
-
- t._onstart(opts)
-
- return t
-}
-
-function hook (name, opts, fn) {
- return test(name, opts, fn, { hook: true })
-}
-
-function solo (name, opts, fn) {
- if (!name && !opts && !fn) return test.configure({ solo: true })
- return test(name, opts, fn, { solo: true })
-}
-
-function skip (name, opts, fn) {
- return test(name, opts, fn, { skip: true })
-}
-
-function todo (name, opts, fn) {
- return test(name, opts, fn, { todo: true })
-}
-
-function pause () {
- getRunner().pause()
-}
-
-function resume () {
- getRunner().resume()
-}
-
-function wait (ticks = 1) {
- return new Promise(resolve => {
- tickish(function loop () {
- if (--ticks <= 0) return resolve()
- tickish(loop)
- })
- })
-}
-
-function tickish (fn) {
- if (IS_NODE) { // do both types of tick in node to flush both queues
- process.nextTick(queueMicrotask, fn)
- } else {
- queueMicrotask(fn)
- }
-}
-
-function explain (ok, message, assert, stackStartFunction, actual, expected, top = !ok && originFrame(stackStartFunction), extra) {
- const runner = getRunner()
- return ok ? null : lazy.errors.explain(ok, message, assert, stackStartFunction, actual, expected, runner.source ? top : null, extra)
-}
-
-function originFrame (stackStartFunction) {
- if (!Error.captureStackTrace) return undefined
- const { prepareStackTrace } = Error
- Error.prepareStackTrace = (_, stack) => {
- if (stack[0].getFunctionName() === '[brittle.error]') return null
- if (stack[0].getMethodName() === 'coercively') return stack[1]
- return stack[0]
- }
- const err = {}
- Error.captureStackTrace(err, stackStartFunction)
- const { stack: top } = err
- Error.prepareStackTrace = prepareStackTrace
- return top
-}
-
-function isPromise (p) {
- return !!(p && typeof p.then === 'function')
-}
-
-function isUncaught (err) {
- return err instanceof SyntaxError ||
- err instanceof ReferenceError ||
- err instanceof TypeError ||
- err instanceof EvalError ||
- err instanceof RangeError
-}
-
-function getRunner () {
- if (!global[RUNNER]) global[RUNNER] = new Runner()
- return global[RUNNER]
-}
-
-function prematureEnd (t, message) {
- const details = t._hasPlan
- ? ' [assertion count (' + t.assertions + ') did not reach plan (' + (t.assertions + t._planned) + ')]'
- : ''
-
- return new Error(message + details)
-}
-
-function stealth (name, opts, fn) {
- return test(name, opts, fn, { stealth: true })
-}
diff --git a/debian/tests/test_modules/brittle/lib/assertion-error.js b/debian/tests/test_modules/brittle/lib/assertion-error.js
deleted file mode 100644
index 2d0320e..0000000
--- a/debian/tests/test_modules/brittle/lib/assertion-error.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const CODE = 'ERR_ASSERTION'
-
-module.exports = class AssertionError extends Error {
- constructor ({ message }) {
- super(`${CODE}: ${message}`)
- this.code = CODE
-
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, AssertionError)
- }
- }
-}
diff --git a/debian/tests/test_modules/brittle/lib/constants.js b/debian/tests/test_modules/brittle/lib/constants.js
deleted file mode 100644
index 50e8333..0000000
--- a/debian/tests/test_modules/brittle/lib/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
-exports.INDENT = ' '
-exports.RUNNER = Symbol.for('brittle-runner')
-exports.IS_NODE = !!(typeof process === 'object' && process && process.versions && (typeof (process.versions.node || process.versions.pear || process.versions.bare) === 'string') && !process.browser)
-exports.IS_BARE = typeof Bare !== 'undefined'
-exports.DEFAULT_TIMEOUT = 30000
diff --git a/debian/tests/test_modules/brittle/lib/errors.js b/debian/tests/test_modules/brittle/lib/errors.js
deleted file mode 100644
index 980ef19..0000000
--- a/debian/tests/test_modules/brittle/lib/errors.js
+++ /dev/null
@@ -1,132 +0,0 @@
-const StackParser = require('error-stack-parser')
-const { INDENT, IS_NODE } = require('./constants')
-const url = requireIfNode('url')
-const fs = requireIfNode('fs')
-const assert = requireIfNode('assert')
-
-const AssertionError = assert ? assert.AssertionError : Error
-const parseStack = StackParser.parse.bind(StackParser)
-
-const IGNORE = typeof __filename === 'string' ? [__filename, __filename.replace(/errors\.js$/, 'index.js')] : []
-
-exports.stringify = stringify
-exports.explain = explain
-
-function explain (ok, message, assert, stackStartFunction, actual, expected, top, extra) {
- if (ok) return null
-
- const cwd = getCWD()
- const err = new AssertionError({ stackStartFunction, message, operator: assert, actual, expected })
- stackScrub(err)
- if (top) {
- const line = top.getLineNumber()
- const column = top.getColumnNumber()
- let file = top.getFileName()?.replace(/\?cacheBust=\d+/g, '')
-
- try {
- try {
- if (url) file = url.fileURLToPath(new URL(file, 'file:'))
- } catch {}
-
- if (file.startsWith(cwd)) {
- file = file.replace(cwd, '.')
- }
-
- if (fs) {
- const code = fs.readFileSync(file, { encoding: 'utf-8' })
- const split = code.split(/[\n\r]/g)
- const point = Array.from({ length: column - 1 }).map(() => '-').join('') + '^'
- const source = [...split.slice(line - 2, line), point, ...split.slice(line, line + 2)]
- err.source = source.join('\n')
- } else {
- err.source = ''
- }
- } /* c8 ignore next */ catch {}
- }
- const { code, generatedMessage, ...info } = err
- err.code = code
- err.generatedMessage = generatedMessage
- Object.defineProperty(info, 'err', { value: err })
-
- if (err.stack) {
- info.stack = err.stack.split('\n').slice(1).map((line) => {
- let match = false
-
- line = line.slice(7).replace(cwd, () => {
- match = true
- return '.'
- })
-
- if (match) line = line.replace(/file:\/?\/?\/?/, '')
- return line
- }).join('\n').trim()
- }
-
- if (!info.stack || code === 'ERR_TIMEOUT' || code === 'ERR_PREMATURE_END' || actual?.code === 'ERR_TIMEOUT' || actual?.code === 'ERR_PREMATURE_END') delete info.stack
-
- if (actual === undefined && expected === undefined) {
- delete info.actual
- delete info.expected
- }
- return info
-}
-
-function stackScrub (err) {
- if (err && err.stack) {
- const scrubbed = parseStack(err).filter(({ fileName }) => !IGNORE.includes(fileName))
- if (scrubbed.length > 0) {
- err.stack = `${Error.prototype.toString.call(err)}\n at ${scrubbed.join('\n at ').replace(/\?cacheBust=\d+/g, '')}`
- }
- }
- return err
-}
-
-function indent (src) {
- return src.split('\n').map(s => INDENT + ' ' + s).join('\n')
-}
-
-function stringify (o) {
- return indent('---\n' + toYAML(o)).trimRight() + '\n' + INDENT + ' ...'
-}
-
-function getCWD () {
- return IS_NODE ? process.cwd() : '/no/cwd/exists'
-}
-
-function requireIfNode (name) {
- try {
- return IS_NODE ? require(name) : null
- } catch {
- return null
- }
-}
-
-// for the life of me can't find a module that does this, that also works in the browser...
-function toYAML (o, maxDepth = 5, indent = '', prev = null) {
- if (maxDepth < 0) return indent + '...'
-
- if (typeof o === 'string') {
- if (o.indexOf('\n') === -1) return o + '\n'
- return '|\n' + o.split('\n').map(s => indent + s).join('\n').trimRight() + '\n'
- }
-
- if (Array.isArray(o) || o instanceof Set) {
- let s = prev ? '\n' : ''
- for (const i of o) {
- s += indent + '- ' + toYAML(i, maxDepth - 1, indent + ' ', 'array')
- }
- return s.trimRight() + '\n'
- }
-
- if (o && typeof o === 'object') {
- const p = prev && prev !== 'array'
- let s = p ? '\n' : ''
- for (const k of Object.keys(o)) {
- const v = o[k]
- s += indent + k + ': ' + toYAML(v, maxDepth - 1, indent + ' ', 'object')
- }
- return (p ? s.trimRight() : s.trim()) + '\n'
- }
-
- return '' + o + '\n'
-}
diff --git a/debian/tests/test_modules/brittle/lib/snapshot.js b/debian/tests/test_modules/brittle/lib/snapshot.js
deleted file mode 100644
index 53ec34d..0000000
--- a/debian/tests/test_modules/brittle/lib/snapshot.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const { IS_NODE } = require('./constants')
-const b4a = require('b4a')
-
-exports.createTypedArray = function (TypedArray, src) {
- const b = b4a.from(src, 'base64')
- return new TypedArray(b.buffer, b.byteOffset, b.byteLength / TypedArray.BYTES_PER_ELEMENT)
-}
-
-exports.getSnapshot = function (filename, key, actual) {
- let snap = {}
-
- const p = split(filename)
- if (!p) return actual
-
- try {
- snap = require(p.filename)
- } catch {}
-
- if (snap[key] !== undefined) return snap[key]
-
- snap[key] = actual
-
- const fs = requireMaybe('fs')
- if (!fs) return actual
-
- try {
- fs.mkdirSync(p.dirname)
- } catch {}
-
- let brittle = false
- let s = ''
-
- for (const k of Object.keys(snap)) {
- s += 'exports[' + toString(k) + '] = '
-
- const v = snap[k]
-
- if (isTypedArray(v)) {
- if (!brittle) {
- brittle = true
- s = 'const { createTypedArray } = require(\'brittle\')\n\n' + s
- }
- const b = b4a.from(v.buffer, v.byteOffset, v.byteLength)
- s += 'createTypedArray(' + v.constructor.name + ', ' + toString(b4a.toString(b, 'base64')) + ')\n\n'
- } else {
- s += toString(v) + '\n\n'
- }
- }
- s = '/* eslint-disable */\n\n' + s + '/* eslint-enable */\n'
-
- fs.writeFileSync(p.filename, s)
- return actual
-}
-
-function isTypedArray (v) {
- return !!(v && v.BYTES_PER_ELEMENT)
-}
-
-function toString (s) {
- if (typeof s === 'string' && s.indexOf('\n') > 0 && s.indexOf('`') === -1) return '`' + s + '`'
- if (typeof s === 'string' && s.indexOf('"') === -1) return '\'' + s + '\''
- return JSON.stringify(s, null, 2)
-}
-
-function split (filename) {
- if (filename.startsWith('file://')) filename = filename.slice(7)
-
- const a = filename.lastIndexOf('/')
- const b = filename.lastIndexOf('\\')
- const sep = a > b ? '/' : '\\'
- const i = a > b ? a : b
-
- if (i === -1) return null
-
- const dirname = filename.slice(0, i) + sep + 'fixtures'
-
- return {
- dirname,
- filename: dirname + sep + filename.slice(i + 1).replace(/\.[^.]+$/, '') + '.snapshot.cjs'
- }
-}
-
-function requireMaybe (name) {
- if (!IS_NODE) return null
-
- try {
- return require(name)
- } catch {
- return null
- }
-}
diff --git a/debian/tests/test_modules/brittle/lib/tracing-promise.js b/debian/tests/test_modules/brittle/lib/tracing-promise.js
deleted file mode 100644
index 21b6711..0000000
--- a/debian/tests/test_modules/brittle/lib/tracing-promise.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const activePromises = new Map()
-
-class TracingPromise extends Promise {
- constructor (fn) {
- const stack = (new Error()).stack
- let deleted = false
-
- addStack(stack)
-
- super((resolve, reject) => {
- const innerResolve = (value) => {
- if (!deleted) {
- deleted = true
- deleteStack(stack)
- }
- resolve(value)
- }
- const innerReject = (err) => {
- if (!deleted) {
- deleted = true
- deleteStack(stack)
- }
- reject(err)
- }
-
- return fn(innerResolve, innerReject)
- })
- }
-
- static Untraced = Promise
-
- static enable () {
- global.Promise = TracingPromise
- }
-
- static print () {
- if (activePromises.size === 0) {
- console.error('(All promises are resolved)')
- return
- }
- for (const [stack, count] of activePromises) {
- const lines = stack.split('\n')
- lines.shift()
- lines.shift()
-
- const trace = lines.map((line) => {
- line = line.slice(7)
- if (/\(node:[^(]*\)$/.test(line)) return null
- if (line.startsWith('TracingPromise.then ')) return null
- return ' at ' + line
- }).filter(x => x).join('\n')
-
- if (!trace) continue
-
- console.error(count + ' promise' + (count === 1 ? '' : 's') + ' unresolved')
- console.error(trace)
- console.error()
- }
- }
-}
-
-module.exports = TracingPromise
-
-function addStack (s) {
- activePromises.set(s, (activePromises.get(s) || 0) + 1)
-}
-
-function deleteStack (s) {
- const n = activePromises.get(s)
- if (n === 1) activePromises.delete(s)
- else activePromises.set(s, n - 1)
-}
diff --git a/debian/tests/test_modules/brittle/package.json b/debian/tests/test_modules/brittle/package.json
deleted file mode 100644
index 24ff526..0000000
--- a/debian/tests/test_modules/brittle/package.json
+++ /dev/null
@@ -1,49 +0,0 @@
-{
- "name": "brittle",
- "version": "3.13.1",
- "description": "A TAP test runner built for modern times",
- "main": "index.js",
- "bin": {
- "brittle": "./cmd.js"
- },
- "author": "David Mark Clements (@davidmarkclem)",
- "license": "Apache-2.0",
- "scripts": {
- "test": "standard && node test/all.mjs",
- "test-bare": "bare test/bare-test.mjs"
- },
- "files": [
- "index.js",
- "cmd.js",
- "lib/**.js"
- ],
- "dependencies": {
- "b4a": "^1.6.0",
- "bare-cov": "^1.0.1",
- "bare-subprocess": "^5.0.0",
- "error-stack-parser": "^2.1.4",
- "globbie": "^1.0.0",
- "paparam": "^1.6.2",
- "same-object": "^1.0.2",
- "test-tmp": "^1.4.0",
- "tmatch": "^5.0.0"
- },
- "devDependencies": {
- "chalk": "^4.1.2",
- "safety-catch": "^1.0.2",
- "standard": "^17.0.0"
- },
- "imports": {
- "child_process": {
- "bare": "bare-subprocess"
- }
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/holepunchto/brittle.git"
- },
- "bugs": {
- "url": "https://github.com/holepunchto/brittle/issues"
- },
- "homepage": "https://github.com/holepunchto/brittle#readme"
-}
diff --git a/debian/tests/test_modules/same-object/LICENSE b/debian/tests/test_modules/same-object/LICENSE
deleted file mode 100644
index a8ea6f2..0000000
--- a/debian/tests/test_modules/same-object/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2023 Contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/debian/tests/test_modules/same-object/README.md b/debian/tests/test_modules/same-object/README.md
deleted file mode 100644
index eb75c0b..0000000
--- a/debian/tests/test_modules/same-object/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# same-object
-
-Determine if two objects are deeply equal
-
-```
-npm install same-object
-```
-
-Supports circular references, Maps, Symbols, etc.
-
-Aims for ~99% compatibility with `deep-equal` or `assert.deepEqual` without requiring native dependencies.\
-Useful for JavaScript runtimes without native Node modules like `util`, etc.
-
-## Usage
-``` js
-const sameObject = require('same-object')
-
-console.log(sameObject(1, '1')) // true
-console.log(sameObject(1, '1', { strict: true })) // false
-
-console.log(sameObject({ a: 1 }, { a: 1 })) // true
-console.log(sameObject({ a: 1 }, { a: 1, b: 2 })) // false
-
-console.log(sameObject(
- new Set(['a', 1, 'b', 2]),
- new Set(['b', 2, 'a', 1])
-)) // true
-```
-
-## API
-
-#### `const bool = sameObject(a, b, [options])`
-
-Compares `a` and `b`, returning whether they are equal or not.
-
-Available `options`:
-```js
-{
- strict: false
-}
-```
-
-Loosely comparison (`==`) by default.\
-Use `{ strict: true }` for a stronger equality check (`===`).
-
-## References
-The source code is based on:\
-[node/comparisons.js](https://github.com/nodejs/node/blob/2adea16e394448c4c87b0639514f8babbeb7a080/lib/internal/util/comparisons.js)\
-[inspect-js/node-deep-equal](https://github.com/inspect-js/node-deep-equal)\
-[chaijs/deep-eql](https://github.com/chaijs/deep-eql)
-
-## License
-MIT
diff --git a/debian/tests/test_modules/same-object/index.js b/debian/tests/test_modules/same-object/index.js
deleted file mode 100644
index 5ec328a..0000000
--- a/debian/tests/test_modules/same-object/index.js
+++ /dev/null
@@ -1,116 +0,0 @@
-module.exports = same
-
-const isPrimitive = require('./lib/is-primitive.js')
-const sameKeys = require('./lib/same-keys.js')
-const sameKeyValues = require('./lib/same-key-values.js')
-const sameIterable = require('./lib/same-iterable.js')
-const sameSet = require('./lib/same-set.js')
-const sameMap = require('./lib/same-map.js')
-const sameArray = require('./lib/same-array.js')
-const sameRegExp = require('./lib/same-regexp.js')
-
-function same (a, b, opts, memos) {
- // Short path optimization
- if (a === b) {
- if (a !== 0) return true
- return opts && opts.strict ? Object.is(a, b) : true
- }
-
- const aIsPrimitive = isPrimitive(a)
- const bIsPrimitive = isPrimitive(b)
-
- if (aIsPrimitive && bIsPrimitive) {
- if (opts && opts.strict) {
- return typeof a === 'number' ? (Number.isNaN(a) && Number.isNaN(b)) : a === b
- }
- return a == b || (Number.isNaN(a) && Number.isNaN(b)) // eslint-disable-line eqeqeq
- }
-
- if (aIsPrimitive !== bIsPrimitive) return false
-
- if (opts && opts.strict) {
- if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false
- }
-
- const aType = getType(a)
- const bType = getType(b)
-
- if (aType !== bType) return false
-
- if (!sameKeys(a, b, opts, memos)) return false
-
- switch (aType) {
- case 'String':
- case 'Number':
- case 'Boolean':
- case 'Date':
- return same(a.valueOf(), b.valueOf(), opts, memos)
- }
-
- if (aType === 'Error') {
- return sameKeyValues(a, b, opts, memos, ['name', 'message'])
- }
-
- switch (aType) {
- case 'Int8Array':
- case 'Uint8Array':
- case 'Uint8ClampedArray':
- case 'Int16Array':
- case 'Uint16Array':
- case 'Int32Array':
- case 'Uint32Array':
- case 'Float32Array':
- case 'Float64Array':
- return sameIterable(a, b, opts, memos)
- case 'DataView':
- return sameIterable(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength), opts, memos)
- case 'ArrayBuffer':
- return sameIterable(new Uint8Array(a), new Uint8Array(b), opts, memos)
- }
-
- if (aType === 'RegExp') return sameRegExp(a, b)
-
- if (!memos) {
- memos = { a: new Map(), b: new Map(), position: 0 }
- } else {
- const memoA = memos.a.get(a)
- if (memoA !== undefined) {
- const memoB = memos.b.get(b)
- if (memoB !== undefined) return memoA === memoB
- }
- memos.position++
- }
-
- memos.a.set(a, memos.position)
- memos.b.set(b, memos.position)
-
- const equals = sameObject(a, b, opts, memos, aType)
-
- memos.a.delete(a)
- memos.b.delete(b)
-
- return equals
-}
-
-function sameObject (a, b, opts, memos, aType) {
- if (aType === 'Array' || aType === 'Arguments') {
- if (!sameArray(a, b, opts, memos)) return false
- }
-
- if (aType === 'Set') {
- if (!sameSet(a, b, opts, memos)) return false
- }
-
- if (aType === 'Map') {
- if (!sameMap(a, b, opts, memos)) return false
- }
-
- if (!sameKeyValues(a, b, opts, memos)) return false
-
- return true
-}
-
-function getType (o) {
- // Note: it returns 'Null' for null prototypes
- return Object.prototype.toString.call(o).slice(8, -1)
-}
diff --git a/debian/tests/test_modules/same-object/lib/find-loose-matching-primitives.js b/debian/tests/test_modules/same-object/lib/find-loose-matching-primitives.js
deleted file mode 100644
index 3489e0f..0000000
--- a/debian/tests/test_modules/same-object/lib/find-loose-matching-primitives.js
+++ /dev/null
@@ -1,18 +0,0 @@
-module.exports = function findLooseMatchingPrimitives (primitive) {
- switch (typeof primitive) {
- case 'undefined':
- return null
- case 'object':
- return undefined
- case 'symbol':
- return false
- case 'string':
- primitive = +primitive
- // Falls through
- case 'number':
- if (Number.isNaN(primitive)) {
- return false
- }
- }
- return true
-}
diff --git a/debian/tests/test_modules/same-object/lib/is-primitive.js b/debian/tests/test_modules/same-object/lib/is-primitive.js
deleted file mode 100644
index 91134cb..0000000
--- a/debian/tests/test_modules/same-object/lib/is-primitive.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = function isPrimitive (value) {
- return value === null || typeof value !== 'object'
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-array.js b/debian/tests/test_modules/same-object/lib/same-array.js
deleted file mode 100644
index d9614e2..0000000
--- a/debian/tests/test_modules/same-object/lib/same-array.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const same = require('../index.js')
-
-module.exports = function sameArray (a, b, opts, memos) {
- if (a.length !== b.length) return false
-
- for (let i = 0; i < a.length; i++) {
- const aHasProperty = Object.prototype.hasOwnProperty.call(a, i)
- const bHasProperty = Object.prototype.hasOwnProperty.call(b, i)
-
- if (aHasProperty) {
- if (!bHasProperty || !same(a[i], b[i], opts, memos)) {
- return false
- }
- } else if (bHasProperty) {
- return false
- } else {
- // Array is sparse
- const aKeys = Object.keys(a)
-
- for (; i < aKeys.length; i++) {
- const key = aKeys[i]
- if (!Object.prototype.hasOwnProperty.call(b, key) ||
- !same(a[key], b[key], opts, memos)) {
- return false
- }
- }
-
- if (aKeys.length !== Object.keys(b).length) return false
-
- return true
- }
- }
-
- return true
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-iterable.js b/debian/tests/test_modules/same-object/lib/same-iterable.js
deleted file mode 100644
index d505f84..0000000
--- a/debian/tests/test_modules/same-object/lib/same-iterable.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const same = require('../index.js')
-
-module.exports = function sameIterable (a, b, opts, memos) {
- if (a.length !== b.length) return false
-
- for (let i = 0; i < a.length; i++) {
- if (!same(a[i], b[i], opts, memos)) {
- return false
- }
- }
-
- return true
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-key-values.js b/debian/tests/test_modules/same-object/lib/same-key-values.js
deleted file mode 100644
index 60f254a..0000000
--- a/debian/tests/test_modules/same-object/lib/same-key-values.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const same = require('../index.js')
-
-module.exports = function sameKeyValues (a, b, opts, memos, keys = null) {
- if (keys === null) keys = Object.keys(a)
-
- for (const key of keys) {
- if (!same(a[key], b[key], opts, memos)) return false
- }
-
- return true
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-keys.js b/debian/tests/test_modules/same-object/lib/same-keys.js
deleted file mode 100644
index 078c1cb..0000000
--- a/debian/tests/test_modules/same-object/lib/same-keys.js
+++ /dev/null
@@ -1,13 +0,0 @@
-module.exports = function sameKeys (a, b, opts, memos) {
- const aKeys = Object.keys(a)
- const bKeys = Object.keys(b)
- if (aKeys.length !== bKeys.length) return false
-
- for (let i = 0; i < aKeys.length; i++) {
- if (!Object.prototype.propertyIsEnumerable.call(b, aKeys[i])) return false
- }
-
- // + if strict, then check symbol properties: https://github.com/nodejs/node/blob/2adea16e394448c4c87b0639514f8babbeb7a080/lib/internal/util/comparisons.js#L290
-
- return true
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-map.js b/debian/tests/test_modules/same-object/lib/same-map.js
deleted file mode 100644
index 8426cf8..0000000
--- a/debian/tests/test_modules/same-object/lib/same-map.js
+++ /dev/null
@@ -1,70 +0,0 @@
-const same = require('../index.js')
-const isPrimitive = require('./is-primitive.js')
-const findLooseMatchingPrimitives = require('./find-loose-matching-primitives.js')
-
-module.exports = function sameMap (a, b, opts, memos) {
- if (a.size !== b.size) return false
-
- const set = new Set()
-
- for (const [key, item1] of a) {
- if (!isPrimitive(key)) {
- set.add(key)
- } else {
- const item2 = b.get(key)
- if (((item2 === undefined && !b.has(key)) || !same(item1, item2, opts, memos))) {
- if (opts && opts.strict) return false
-
- // Discard string, symbol, undefined, and null keys
- if (!mapMightHaveLoosePrim(a, b, key, item1, memos)) return false
-
- set.add(key)
- }
- }
- }
-
- if (set.size > 0) {
- for (const [key, item] of b) {
- if (!isPrimitive(key)) {
- if (!mapHasEqualEntry(set, a, key, item, opts, memos)) {
- return false
- }
- continue
- }
-
- if (opts && opts.strict) continue
-
- if (a.has(key) && same(a.get(key), item, { strict: false }, memos)) continue
-
- if (mapHasEqualEntry(set, a, key, item, { strict: false }, memos)) continue
-
- return false
- }
-
- return set.size === 0
- }
-
- return true
-}
-
-function mapHasEqualEntry (set, a, key, bValue, opts, memos) {
- for (const key2 of set) {
- if (same(key, key2, opts, memos) && same(bValue, a.get(key2), opts, memos)) {
- set.delete(key2)
- return true
- }
- }
-
- return false
-}
-
-function mapMightHaveLoosePrim (a, b, primitive, item, memos) {
- const altValue = findLooseMatchingPrimitives(primitive)
- if (altValue != null) return altValue
-
- const bValue = b.get(altValue)
- if (bValue === undefined && !b.has(altValue)) return false
- if (!same(item, bValue, { strict: false }, memos)) return false
-
- return !a.has(altValue) && same(item, bValue, { strict: false }, memos)
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-regexp.js b/debian/tests/test_modules/same-object/lib/same-regexp.js
deleted file mode 100644
index aa4b588..0000000
--- a/debian/tests/test_modules/same-object/lib/same-regexp.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = function sameRegExp (a, b) {
- return a.source === b.source && a.flags === b.flags
-}
diff --git a/debian/tests/test_modules/same-object/lib/same-set.js b/debian/tests/test_modules/same-object/lib/same-set.js
deleted file mode 100644
index 4c15df0..0000000
--- a/debian/tests/test_modules/same-object/lib/same-set.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const same = require('../index.js')
-const isPrimitive = require('./is-primitive.js')
-const findLooseMatchingPrimitives = require('./find-loose-matching-primitives.js')
-
-module.exports = function sameSet (a, b, opts, memos) {
- if (a.size !== b.size) return false
-
- const set = new Set()
-
- for (const aValue of a) {
- if (!isPrimitive(aValue)) {
- // Non-null object (non strict only: a not matching primitive)
- set.add(aValue)
- } else if (!b.has(aValue)) {
- if (opts && opts.strict) return false
-
- // Discard string, symbol, undefined, and null values
- if (!setMightHaveLoosePrim(a, b, aValue)) return false
-
- set.add(aValue)
- }
- }
-
- if (set.size > 0) {
- for (const bValue of b) {
- if (!isPrimitive(bValue)) {
- if (!setHasEqualElement(set, bValue, opts, memos)) {
- return false
- }
- continue
- }
-
- if (opts && opts.strict) continue
-
- if (a.has(bValue)) continue
-
- if (setHasEqualElement(set, bValue, opts, memos)) continue
-
- return false
- }
-
- return set.size === 0
- }
-
- return true
-}
-
-function setMightHaveLoosePrim (a, b, primitive) {
- const altValue = findLooseMatchingPrimitives(primitive)
- if (altValue != null) return altValue
-
- return b.has(altValue) && !a.has(altValue)
-}
-
-function setHasEqualElement (set, val1, opts, memos) {
- for (const val2 of set) {
- if (same(val1, val2, opts, memos)) {
- set.delete(val2)
- return true
- }
- }
-
- return false
-}
diff --git a/debian/tests/test_modules/same-object/package.json b/debian/tests/test_modules/same-object/package.json
deleted file mode 100644
index 7b0af43..0000000
--- a/debian/tests/test_modules/same-object/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "same-object",
- "version": "1.0.2",
- "description": "Determine if two objects are deeply equal",
- "main": "index.js",
- "scripts": {
- "test": "standard && brittle test.js --coverage"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/holepunchto/same-object.git"
- },
- "author": "Lucas Barrena (LuKks)",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/holepunchto/same-object/issues"
- },
- "homepage": "https://github.com/holepunchto/same-object",
- "devDependencies": {
- "brittle": "^3.1.1",
- "deep-equal": "^2.2.0",
- "standard": "^17.0.0"
- }
-}
diff --git a/debian/tests/test_modules/same-object/test.js b/debian/tests/test_modules/same-object/test.js
deleted file mode 100644
index 9af358e..0000000
--- a/debian/tests/test_modules/same-object/test.js
+++ /dev/null
@@ -1,1399 +0,0 @@
-const test = require('brittle')
-const sameObject = require('./')
-const deepEqual = require('deep-equal')
-
-test.configure({ bail: true })
-
-// NOTE: most tests were copied and adapted from deep-equal library
-
-const safeBuffer = typeof Buffer === 'function' ? Buffer.from : null
-const buffersAreTypedArrays = typeof Buffer === 'function' && safeBuffer('') instanceof Uint8Array
-
-test('basic', function (t) {
- t.ok(sameObject(1, '1'))
- t.absent(sameObject(1, '1', { strict: true }))
-})
-
-test('basic helper', function (t) {
- unlike(t, 1, '1')
- alikeLoosely(t, 1, '1')
-})
-
-test('equal', function (t) {
- alike(t,
- { a: [2, 3], b: [4] },
- { a: [2, 3], b: [4] },
- 'two equal objects'
- )
-
- alikeLoosely(t,
- { a: 2, b: '4' },
- { a: 2, b: 4 },
- 'two loosely equal, strictly inequal objects'
- )
-
- unlikeLoosely(t,
- { a: 2, b: 4 },
- { a: 2, B: 4 },
- 'two inequal objects'
- )
-
- alikeLoosely(t,
- '-000',
- false,
- '`false` and `"-000"`'
- )
-})
-
-test('Maps', function (t) {
- alike(t,
- new Map([['a', 1], ['b', 2]]),
- new Map([['b', 2], ['a', 1]]),
- 'two equal Maps'
- )
-
- unlikeLoosely(t,
- new Map([['a', [1, 2]]]),
- new Map([['a', [2, 1]]]),
- 'two Maps with inequal values on the same key'
- )
-
- unlikeLoosely(t,
- new Map([['a', 1]]),
- new Map([['b', 1]]),
- 'two inequal Maps'
- )
-
- alike(t,
- new Map([[{}, 3], [{}, 2], [{}, 1]]),
- new Map([[{}, 1], [{}, 2], [{}, 3]]),
- 'two equal Maps in different orders with object keys'
- )
-
- alikeLoosely(t,
- new Map([[undefined, undefined]]),
- new Map([[undefined, null]]),
- 'undefined keys, nullish values, loosely equal, strictly inequal'
- )
-
- alike(t,
- new Map([[{}, null], [true, 2], [{}, 1], [undefined, {}]]),
- new Map([[{}, 1], [true, 2], [{}, null], [undefined, {}]]),
- 'two equal Maps in different orders with primitive keys'
- )
-
- alike(t,
- new Map([[false, 3], [{}, 2], [{}, 1]]),
- new Map([[{}, 1], [{}, 2], [false, 3]]),
- 'two equal Maps in different orders with a mix of keys'
- )
-
- alikeLoosely(t,
- new Map([[null, undefined]]),
- new Map([[null, null]]),
- 'null keys, nullish values, loosely equal, strictly inequal'
- )
-
- alikeLoosely(t,
- new Map([[undefined, 3]]),
- new Map([[null, 3]]),
- 'nullish keys, loosely equal, strictly inequal'
- )
-
- alike(t,
- new Map([[{}, null], [true, 2], [{}, 1], [undefined, {}]]),
- new Map([[{}, 1], [true, 2], [{}, null], [undefined, {}]]),
- 'two equal Maps in different orders with primitive keys'
- )
-
- alike(t,
- new Map([[false, 3], [{}, 2], [{}, 1]]),
- new Map([[{}, 1], [{}, 2], [false, 3]]),
- 'two equal Maps in different orders with a mix of keys'
- )
-
- unlikeLoosely(t,
- new Map(),
- new Map([[{}, 1]]),
- 'two inequal Maps'
- )
-
- unlikeLoosely(t,
- new Map([[{}, null], [false, 3]]),
- new Map([[{}, null], [true, 2]]),
- 'two inequal maps, same size, primitive key, start with object key'
- )
-
- unlikeLoosely(t,
- new Map([[false, 3], [{}, null]]),
- new Map([[true, 2], [{}, null]]),
- 'two inequal maps, same size, primitive key, start with primitive key'
- )
-
- alikeLoosely(t,
- new Map([[undefined, null], ['+000', 2]]),
- new Map([[null, undefined], [false, '2']]),
- 'primitive comparisons'
- )
-})
-
-// +
-test('WeakMaps', function (t) {
- alike(t,
- new WeakMap([[Object, null], [Function, true]]),
- new WeakMap([[Function, true], [Object, null]]),
- 'two equal WeakMaps'
- )
-
- alike(t,
- new WeakMap([[Object, null]]),
- new WeakMap([[Object, true]]),
- 'two WeakMaps with inequal values on the same key'
- )
-
- alike(t,
- new WeakMap([[Object, null], [Function, true]]),
- new WeakMap([[Object, null]]),
- 'two inequal WeakMaps'
- )
-})
-
-test('Sets', function (t) {
- alike(t,
- new Set(['a', 1, 'b', 2]),
- new Set(['b', 2, 'a', 1]),
- 'two equal Sets'
- )
-
- unlikeLoosely(t,
- new Set(['a', 1]),
- new Set(['b', 1]),
- 'two inequal Sets'
- )
-
- alike(t,
- new Set([{}, 1, {}, {}, 2]),
- new Set([{}, 1, {}, 2, {}]),
- 'two equal Sets in different orders'
- )
-
- unlikeLoosely(t,
- new Set(),
- new Set([1]),
- 'two inequally sized Sets'
- )
-
- alikeLoosely(t,
- new Set([{ a: 1 }, 2]),
- new Set(['2', { a: '1' }]),
- 'two loosely equal, strictly inequal Sets'
- )
-
- unlikeLoosely(t,
- new Set([{ a: 1 }, 2]),
- new Set(['2', { a: 2 }]),
- 'two inequal Sets'
- )
-
- alikeLoosely(t,
- new Set([null, '', 1, 5, 2, false]),
- new Set([undefined, 0, '5', true, '2', '-000']),
- 'more primitive comparisons'
- )
-
- alike(t,
- new Set([1, 2]),
- new Set([2, 1]),
- 'primitives in different keys'
- )
-
- alike(t,
- new Set([{ a: 1 }, { b: 2 }]),
- new Set([{ b: 2 }, { a: 1 }]),
- 'object values in different keys'
- )
-
- alike(t,
- new Set([new Set([1, 2]), new Set([3, 4])]),
- new Set([new Set([4, 3]), new Set([2, 1])]),
- 'Set of Sets, all in different keys'
- )
-
- unlikeLoosely(t,
- new Set([{ a: 1 }, 1]),
- new Set([{ a: 1 }, 2]),
- 'non primitive first, and non alike primitive later'
- )
-
- alikeLoosely(t,
- new Set([{ a: 1 }, Infinity]),
- new Set([{ a: 1 }, Infinity]),
- 'primitive that is not loose'
- )
-
- unlikeLoosely(t,
- new Set([Symbol.for('hi')]),
- new Set([Symbol.for('hi2')]),
- 'different symbols in a Set'
- )
-})
-
-test('Set and Map', function (t) {
- unlikeLoosely(t,
- new Set(),
- new Map(),
- 'Map and Set'
- )
-
- // +
- /* const maplikeSet = new Set()
- Object.defineProperty(maplikeSet, 'constructor', { enumerable: false, value: Map })
- maplikeSet.__proto__ = Map.prototype // eslint-disable-line no-proto
- unlikeLoosely(t,
- maplikeSet,
- new Map(),
- 'Map-like Set, and Map'
- ) */
-})
-
-// +
-test('WeakSets', function (t) {
- alike(t,
- new WeakSet([Object, Function]),
- new WeakSet([Function, Object]),
- 'two equal WeakSets'
- )
-
- alike(t,
- new WeakSet([Object, Function]),
- new WeakSet([Object]),
- 'two inequal WeakSets'
- )
-})
-
-test('not equal', function (t) {
- unlikeLoosely(t,
- { x: 5, y: [6] },
- { x: 5, y: 6 },
- 'two inequal objects are'
- )
-})
-
-test('nested nulls', function (t) {
- alike(t,
- [null, null, null],
- [null, null, null],
- 'same-length arrays of nulls'
- )
-})
-
-test('objects with strings vs numbers', function (t) {
- alikeLoosely(t,
- [{ a: 3 }, { b: 4 }],
- [{ a: '3' }, { b: '4' }],
- 'objects with equivalent string/number values'
- )
-})
-
-test('non-objects', function (t) {
- alike(t, 3, 3, 'same numbers', true, true, true)
- alike(t, 'beep', 'beep', 'same strings', true, true, true)
- alikeLoosely(t, '3', 3, 'numeric string and number', true, false)
- unlikeLoosely(t, '3', [3], 'numeric string and array containing number', false, false)
- unlikeLoosely(t, 3, [3], 'number and array containing number', false, false)
-})
-
-test('infinities', function (t) {
- alike(t, Infinity, Infinity, '? and ?', true, true, true)
- alike(t, -Infinity, -Infinity, '-? and -?', true, true, true)
- unlikeLoosely(t, Infinity, -Infinity, '? and -?', false, false)
-})
-
-test('arguments class', function (t) {
- function getArgs () {
- return arguments
- }
-
- alike(t,
- getArgs(1, 2, 3),
- getArgs(1, 2, 3),
- 'equivalent arguments objects are equal'
- )
-
- unlikeLoosely(t,
- getArgs(1, 2, 3),
- [1, 2, 3],
- 'array and arguments with same contents'
- )
-
- const args = getArgs()
- const notArgs = tag({ length: 0 }, 'Arguments')
- unlikeLoosely(t,
- args,
- notArgs,
- 'args and similar arraylike object'
- )
-})
-
-test('Dates', function (t) {
- const d0 = new Date(1387585278000)
- const d1 = new Date('Fri Dec 20 2013 16:21:18 GMT-0800 (PST)')
-
- alike(t, d0, d1, 'two Dates with the same timestamp', true, true)
-
- d1.a = true
-
- unlikeLoosely(t, d0, d1, 'two Dates with the same timestamp but different own properties', false, false)
-
- t.test('overriding `getTime`', function (st) {
- const a = new Date('2000')
- const b = new Date('2000')
- Object.defineProperty(a, 'getTime', { value: function () { return 5 } })
- alike(st, a, b, 'two Dates with the same timestamp but one has overridden `getTime`', true, true)
- })
-
- // +
- /* t.test('fake Date', { skip: !hasDunderProto }, function (st) {
- const a = new Date(2000)
- const b = tag(Object.create(
- a.__proto__, // eslint-disable-line no-proto
- Object.getOwnPropertyDescriptors(a)
- ), 'Date')
-
- unlikeLoosely(st,
- a,
- b,
- 'Date, and fake Date'
- )
- }) */
-
- const a = new Date('2000')
- const b = new Date('2000')
- b.foo = true
- unlikeLoosely(t,
- a,
- b,
- 'two identical Dates, one with an extra property'
- )
-
- unlikeLoosely(t,
- new Date('2000'),
- new Date('2001'),
- 'two inequal Dates'
- )
-})
-
-test('buffers', { skip: typeof Buffer !== 'function' }, function (t) {
- alike(t,
- safeBuffer('xyz'),
- safeBuffer('xyz'),
- 'buffers with same contents are equal'
- )
-
- unlikeLoosely(t,
- safeBuffer('xyz'),
- safeBuffer('xyy'),
- 'buffers with same length and different contents are inequal'
- )
-
- unlikeLoosely(t,
- safeBuffer('xyz'),
- safeBuffer('xy'),
- 'buffers with different length are inequal'
- )
-
- unlikeLoosely(t,
- safeBuffer('abc'),
- safeBuffer('xyz'),
- 'buffers with different contents'
- )
-
- const emptyBuffer = safeBuffer('')
-
- unlikeLoosely(t,
- emptyBuffer,
- [],
- 'empty buffer and empty array'
- )
-
- t.test('bufferlikes', function (st) {
- const fakeBuffer = {
- 0: 'a',
- length: 1,
- __proto__: emptyBuffer.__proto__, // eslint-disable-line no-proto
- copy: emptyBuffer.copy,
- slice: emptyBuffer.slice
- }
- Object.defineProperty(fakeBuffer, '0', { enumerable: false })
- Object.defineProperty(fakeBuffer, 'length', { enumerable: false })
- Object.defineProperty(fakeBuffer, 'copy', { enumerable: false })
- Object.defineProperty(fakeBuffer, 'slice', { enumerable: false })
-
- unlikeLoosely(st,
- safeBuffer('a'),
- fakeBuffer,
- 'real buffer, and mildly fake buffer'
- )
-
- st.test('bufferlike', function (s2t) {
- const bufferlike = buffersAreTypedArrays ? new Uint8Array() : {}
- Object.defineProperty(bufferlike, 'length', {
- enumerable: false,
- value: bufferlike.length || 0
- })
- Object.defineProperty(bufferlike, 'copy', {
- enumerable: false,
- value: emptyBuffer.copy
- })
- bufferlike.__proto__ = emptyBuffer.__proto__ // eslint-disable-line no-proto
-
- alike(s2t,
- emptyBuffer,
- bufferlike,
- 'empty buffer and empty bufferlike'
- )
- s2t.end()
- })
-
- st.end()
- })
-
- t.end()
-})
-
-test('DataView', function (t) {
- const view1 = new DataView(new ArrayBuffer(10))
- const view2 = new DataView(new ArrayBuffer(10))
-
- alike(t,
- view1,
- view2,
- 'two equals DataViews'
- )
-
- view1[3] = 7
-
- unlike(t,
- view1,
- view2,
- 'two inequal DataViews'
- )
-})
-
-test('Arrays', function (t) {
- const a = []
- const b = []
- b.foo = true
-
- unlikeLoosely(t,
- a,
- b,
- 'two identical arrays, one with an extra property'
- )
-
- const c = [undefined, 'test']
- const d = []
- d[1] = 'test'
- unlikeLoosely(t, c, d, 'sparse array')
-
- const e = [undefined, 'test', undefined, undefined, 'test2', undefined]
- const f = []
- e[1] = 'test'
- e[4] = 'test2'
- unlikeLoosely(t, e, f, 'sparse array')
-
- const g = new Array(10)
- const h = new Array(10)
- g[2] = 'test'
- g[5] = 'test2'
- g[8] = 'test3'
- h[2] = 'test'
- h[5] = 'test2'
- h[8] = 'test3'
- alike(t, g, h, 'sparse array')
-
- t.end()
-})
-
-test('booleans', function (t) {
- alike(t,
- true,
- true,
- 'trues'
- )
-
- alike(t,
- false,
- false,
- 'falses'
- )
-
- unlikeLoosely(t,
- true,
- false,
- 'true and false'
- )
-
- t.end()
-})
-
-test('booleans and arrays', function (t) {
- unlikeLoosely(t,
- true,
- [],
- 'true and an empty array',
- false,
- false
- )
- unlikeLoosely(t,
- false,
- [],
- 'false and an empty array'
- )
- t.end()
-})
-
-test('arrays initiated', function (t) {
- const a0 = [
- undefined,
- null,
- -1,
- 0,
- 1,
- false,
- true,
- undefined,
- '',
- 'abc',
- null,
- undefined
- ]
- const a1 = [
- undefined,
- null,
- -1,
- 0,
- 1,
- false,
- true,
- undefined,
- '',
- 'abc',
- null,
- undefined
- ]
-
- alike(t,
- a0,
- a1,
- 'arrays with equal contents are equal'
- )
- t.end()
-})
-
-test('arrays assigned', function (t) {
- const a0 = [
- undefined,
- null,
- -1,
- 0,
- 1,
- false,
- true,
- undefined,
- '',
- 'abc',
- null,
- undefined
- ]
- const a1 = []
-
- a1[0] = undefined
- a1[1] = null
- a1[2] = -1
- a1[3] = 0
- a1[4] = 1
- a1[5] = false
- a1[6] = true
- a1[7] = undefined
- a1[8] = ''
- a1[9] = 'abc'
- a1[10] = null
- a1[11] = undefined
- a1.length = 12
-
- alike(t, a0, a1, 'a literal array and an assigned array', true, true)
- t.end()
-})
-
-test('arrays push', function (t) {
- const a0 = [
- undefined,
- null,
- -1,
- 0,
- 1,
- false,
- true,
- undefined,
- '',
- 'abc',
- null,
- undefined
- ]
- const a1 = []
-
- a1.push(undefined)
- a1.push(null)
- a1.push(-1)
- a1.push(0)
- a1.push(1)
- a1.push(false)
- a1.push(true)
- a1.push(undefined)
- a1.push('')
- a1.push('abc')
- a1.push(null)
- a1.push(undefined)
- a1.length = 12
-
- alike(t, a0, a1, 'a literal array and a pushed array', true, true)
- t.end()
-})
-
-test('null == undefined', function (t) {
- alikeLoosely(t, null, undefined, 'null and undefined', true, false)
- alikeLoosely(t, [null], [undefined], '[null] and [undefined]', true, false)
-
- t.end()
-})
-
-// node 14 changed `deepEqual` to make two NaNs loosely equal
-test('NaNs', function (t) {
- alike(t,
- NaN,
- NaN,
- 'two NaNs'
- )
-
- alike(t,
- { a: NaN },
- { a: NaN },
- 'two equiv objects with a NaN value'
- )
-
- unlikeLoosely(t, NaN, 1, 'NaN and 1', false, false)
-
- t.end()
-})
-
-test('zeroes', function (t) {
- alikeLoosely(t, 0, -0, '0 and -0', true, false)
- unlike(t, 0, -0, '0 and -0', true, false)
-
- alikeLoosely(t, { a: 0 }, { a: -0 }, 'two objects with a same-keyed 0/-0 value', true, false)
- unlike(t, { a: 0 }, { a: -0 }, 'two objects with a same-keyed 0/-0 value', true, false)
-
- t.end()
-})
-
-test('Object.create', function (t) {
- const a = { a: 'A' }
- const b = Object.create(a)
- b.b = 'B'
- const c = Object.create(a)
- c.b = 'C'
-
- unlikeLoosely(t,
- b,
- c,
- 'two objects with the same [[Prototype]] but a different own property'
- )
-
- t.end()
-})
-
-test('Object.create(null)', function (t) {
- alike(t,
- Object.create(null),
- Object.create(null),
- 'two empty null objects'
- )
-
- alike(t,
- Object.create(null, { a: { value: 'b' } }),
- Object.create(null, { a: { value: 'b' } }),
- 'two null objects with the same property pair'
- )
-
- t.end()
-})
-
-test('regexes vs dates', function (t) {
- const d = new Date(1387585278000)
- const r = /abc/
-
- unlikeLoosely(t, d, r, 'Date and RegExp', false, false)
-
- t.end()
-})
-
-test('regexp', function (t) {
- unlikeLoosely(t, /abc/, /xyz/, 'two different regexes', false, false)
- alike(t, /abc/, /abc/, 'two abc regexes', true, true, false)
- alike(t, /xyz/, /xyz/, 'two xyz regexes', true, true, false)
- unlike(t, /abc/i, /def/g, 'two xyz regexes')
-
- // +
- /* t.test('fake RegExp', function (st) {
- const a = /abc/g
- const b = tag(Object.create(
- a.__proto__, // eslint-disable-line no-proto
- Object.getOwnPropertyDescriptors(a)
- ), 'RegExp')
-
- unlikeLoosely(st,a, b, 'regex and fake regex', false, false)
-
- st.end()
- }) */
-
- const a = /abc/gi
- const b = /abc/gi
- b.foo = true
- unlikeLoosely(t,
- a,
- b,
- 'two identical regexes, one with an extra property'
- )
-
- const c = /abc/g
- const d = /abc/i
- unlikeLoosely(t,
- c,
- d,
- 'two regexes with the same source but different flags'
- )
-
- t.end()
-})
-
-test('object literals', function (t) {
- alikeLoosely(t,
- { prototype: 2 },
- { prototype: '2' },
- 'two loosely equal, strictly inequal prototype properties'
- )
-
- t.end()
-})
-
-test('arrays and objects', function (t) {
- unlikeLoosely(t, [], {}, 'empty array and empty object', false, false)
- unlikeLoosely(t, [], { length: 0 }, 'empty array and empty arraylike object', false, false)
- unlikeLoosely(t, [1], { 0: 1 }, 'array and similar object', false, false)
-
- t.end()
-})
-
-test('functions', function (t) {
- function f () {}
-
- alike(t, f, f, 'a function and itself', true, true, true)
- alike(t, [f], [f], 'a function and itself in an array', true, true, true)
-
- unlikeLoosely(t, function () {}, function () {}, 'two distinct functions', false, false, true)
- unlikeLoosely(t, [function () {}], [function () {}], 'two distinct functions in an array', false, false, true)
-
- unlikeLoosely(t, f, {}, 'function and object', false, false, true)
- unlikeLoosely(t, [f], [{}], 'function and object in an array', false, false, true)
-
- t.end()
-})
-
-test('Errors', function (t) {
- alike(t, new Error('xyz'), new Error('xyz'), 'two errors of the same type with the same message', true, true, false)
- unlikeLoosely(t, new Error('xyz'), new TypeError('xyz'), 'two errors of different types with the same message', false, false)
- unlikeLoosely(t, new Error('xyz'), new Error('zyx'), 'two errors of the same type with a different message', false, false)
-
- // +
- /* t.test('errorlike', { skip: !Object.defineProperty }, function (st) {
- const err = new Error('foo')
- // TODO: add `__proto__` when brand check is available
- const errorlike = tag({ message: err.message, stack: err.stack, name: err.name, constructor: err.constructor }, 'Error')
- Object.defineProperty(errorlike, 'message', { enumerable: false })
- Object.defineProperty(errorlike, 'stack', { enumerable: false })
- Object.defineProperty(errorlike, 'name', { enumerable: false })
- Object.defineProperty(errorlike, 'constructor', { enumerable: false })
- st.absent(errorlike instanceof Error)
- st.ok(err instanceof Error)
- unlikeLoosely(st,
- err,
- errorlike,
- 'error, and errorlike object'
- )
-
- st.end()
- }) */
-
- // +
- unlikeLoosely(t,
- new Error('a'),
- Object.assign(new Error('a'), { code: 10 }),
- 'two otherwise equal errors with different own properties'
- )
-
- // +
- /* t.test('fake error', { skip: !process.env.ASSERT || !hasDunderProto }, function (st) {
- const a = tag({
- __proto__: null
- }, 'Error')
- const b = new RangeError('abc')
- b.__proto__ = null // eslint-disable-line no-proto
-
- unlikeLoosely(st,
- a,
- b,
- 'null object faking as an Error, RangeError with null proto'
- )
- st.end()
- }) */
-
- t.end()
-})
-
-test('object and null', function (t) {
- unlikeLoosely(t,
- {},
- null,
- 'null and an object'
- )
-
- t.end()
-})
-
-test('error = Object', function (t) {
- unlikeLoosely(t,
- new Error('a'),
- { message: 'a' }
- )
-
- t.end()
-})
-
-test('[[Prototypes]]', function (t) {
- function C () {}
- const instance = new C()
- delete instance.constructor
-
- alikeLoosely(t, {}, instance, 'two identical objects with different [[Prototypes]]', true, false)
-
- t.test('Dates with different prototypes', function (st) {
- const d1 = new Date(0)
- const d2 = new Date(0)
-
- alike(st, d1, d2, 'two dates with the same timestamp', true, true)
-
- const newProto = {
- __proto__: Date.prototype
- }
- d2.__proto__ = newProto // eslint-disable-line no-proto
- st.ok(d2 instanceof Date, 'd2 is still a Date instance after tweaking [[Prototype]]')
-
- alikeLoosely(st, d1, d2, 'two dates with the same timestamp and different [[Prototype]]', true, false)
-
- st.end()
- })
-
- t.end()
-})
-
-test('toStringTag', function (t) {
- const o1 = {}
- t.is(Object.prototype.toString.call(o1), '[object Object]', 'o1: Symbol.toStringTag works')
-
- const o2 = {}
- t.is(Object.prototype.toString.call(o2), '[object Object]', 'o2: original Symbol.toStringTag works')
-
- alike(t, o1, o2, 'two normal empty objects', true, true)
-
- o2[Symbol.toStringTag] = 'jifasnif'
- t.is(Object.prototype.toString.call(o2), '[object jifasnif]', 'o2: modified Symbol.toStringTag works')
-
- unlikeLoosely(t, o1, o2, 'two normal empty objects with different toStringTags', false, false)
-
- t.end()
-})
-
-test('boxed primitives', function (t) {
- unlikeLoosely(t, Object(false), false, 'boxed and primitive `false`', false, false)
- unlikeLoosely(t, Object(true), true, 'boxed and primitive `true`', false, false)
- unlikeLoosely(t, Object(3), 3, 'boxed and primitive `3`', false, false)
- unlikeLoosely(t, Object(NaN), NaN, 'boxed and primitive `NaN`', false, false)
- unlikeLoosely(t, Object(''), '', 'boxed and primitive `""`', false, false)
- unlikeLoosely(t, Object('str'), 'str', 'boxed and primitive `"str"`', false, false)
-
- t.test('symbol', function (st) {
- const s = Symbol('')
- unlikeLoosely(st, Object(s), s, 'boxed and primitive `Symbol()`', false, false)
- st.end()
- })
-
- t.test('bigint', function (st) {
- const hhgtg = BigInt(42)
- unlikeLoosely(st, Object(hhgtg), hhgtg, 'boxed and primitive `BigInt(42)`', false, false)
- st.end()
- })
-
- // +
- /* t.test('`valueOf` is called for boxed primitives', function (st) {
- const a = Object(5)
- a.valueOf = function () { throw new Error('failed') }
- const b = Object(5)
- b.valueOf = function () { throw new Error('failed') }
-
- unlikeLoosely(st, a, b, 'two boxed numbers with a thrower valueOf', false, false)
-
- st.end()
- }) */
-
- t.end()
-})
-
-test('getters', function (t) {
- const a = {}
- Object.defineProperty(a, 'a', { enumerable: true, get: function () { return 5 } })
- const b = {}
- Object.defineProperty(b, 'a', { enumerable: true, get: function () { return 6 } })
-
- unlikeLoosely(t, a, b, 'two objects with the same getter but producing different values', false, false)
-
- t.end()
-})
-
-test('fake arrays: extra keys will be tested', function (t) {
- const a = tag({
- __proto__: Array.prototype,
- 0: 1,
- 1: 1,
- 2: 'broken',
- length: 2
- }, 'Array')
-
- if (Object.defineProperty) {
- Object.defineProperty(a, 'length', {
- enumerable: false
- })
- }
-
- unlikeLoosely(t, a, [1, 1], 'fake and real array with same contents and [[Prototype]]', false, false)
-
- const b = tag(/abc/, 'Array')
- b.__proto__ = Array.prototype // eslint-disable-line no-proto
- b.length = 3
- if (Object.defineProperty) {
- Object.defineProperty(b, 'length', {
- enumerable: false
- })
- }
- unlikeLoosely(t, b, ['a', 'b', 'c'], 'regex faking as array, and array', false, false)
-
- t.end()
-})
-
-test('circular references', function (t) {
- const b = {}
- b.b = b
-
- const c = {}
- c.b = c
-
- alike(t,
- b,
- c,
- 'two self-referencing objects'
- )
-
- const d = {}
- d.a = 1
- d.b = d
-
- const e = {}
- e.a = 1
- e.b = e.a
-
- unlikeLoosely(t,
- d,
- e,
- 'two deeply self-referencing objects'
- )
-
- t.end()
-})
-
-test('TypedArrays', function (t) {
- // +
- /* t.test('Buffer faked as Uint8Array', function (st) {
- const a = safeBuffer('test')
- const b = tag(Object.create(
- a.__proto__, // eslint-disable-line no-proto
- Object.assign(Object.getOwnPropertyDescriptors(a), {
- length: {
- enumerable: false,
- value: 4
- }
- })
- ), 'Uint8Array')
-
- unlikeLoosely(st,
- a,
- b,
- 'Buffer and Uint8Array'
- )
-
- st.end()
- }) */
-
- // +
- /* t.test('one TypedArray faking as another', { skip: !hasDunderProto }, function (st) {
- const a = new Uint8Array(10)
- const b = tag(new Int8Array(10), 'Uint8Array')
- b.__proto__ = Uint8Array.prototype // eslint-disable-line no-proto
-
- unlikeLoosely(st,
- a,
- b,
- 'Uint8Array, and Int8Array pretending to be a Uint8Array'
- )
-
- st.end()
- }) */
-
- t.test('ArrayBuffers', { skip: typeof ArrayBuffer !== 'function' }, function (st) {
- const buffer1 = new ArrayBuffer(8) // initial value of 0's
- const buffer2 = new ArrayBuffer(8) // initial value of 0's
-
- const view1 = new Int8Array(buffer1)
- const view2 = new Int8Array(buffer2)
-
- alike(st,
- view1,
- view2,
- 'Int8Arrays of similar ArrayBuffers'
- )
-
- alike(st,
- buffer1,
- buffer2,
- 'similar ArrayBuffers'
- )
-
- for (let i = 0; i < view1.byteLength; i += 1) {
- view1[i] = 9 // change all values to 9's
- }
-
- unlikeLoosely(st,
- view1,
- view2,
- 'Int8Arrays of different ArrayBuffers'
- )
-
- unlikeLoosely(st,
- buffer1,
- buffer2,
- 'different ArrayBuffers'
- )
-
- // node < 0.11 has a nonconfigurable own byteLength property
- t.test('lies about byteLength', { skip: !('byteLength' in ArrayBuffer.prototype) }, function (s2t) {
- const empty4 = new ArrayBuffer(4)
- const empty6 = new ArrayBuffer(6)
- Object.defineProperty(empty6, 'byteLength', { value: 4 })
-
- unlikeLoosely(s2t,
- empty4,
- empty6,
- 'different-length ArrayBuffers, one lying'
- )
- s2t.end()
- })
-
- st.end()
- })
-
- t.test('SharedArrayBuffers', { skip: typeof SharedArrayBuffer !== 'function' }, function (st) {
- const buffer1 = new SharedArrayBuffer(8) // initial value of 0's
- const buffer2 = new SharedArrayBuffer(8) // initial value of 0's
-
- const view1 = new Int8Array(buffer1)
- const view2 = new Int8Array(buffer2)
-
- alike(st,
- view1,
- view2,
- 'Int8Arrays of similar SharedArrayBuffers'
- )
-
- alike(st,
- buffer1,
- buffer2,
- 'similar SharedArrayBuffers'
- )
-
- for (let i = 0; i < view1.byteLength; i += 1) {
- view1[i] = 9 // change all values to 9's
- }
-
- unlikeLoosely(st,
- view1,
- view2,
- 'Int8Arrays of different SharedArrayBuffers'
- )
-
- // +
- /* unlikeLoosely(st,
- buffer1,
- buffer2,
- 'different SharedArrayBuffers'
- ) */
-
- // +
- /* t.test('lies about byteLength', { skip: !('byteLength' in SharedArrayBuffer.prototype) }, function (s2t) {
- const empty4 = new SharedArrayBuffer(4)
- const empty6 = new SharedArrayBuffer(6)
- Object.defineProperty(empty6, 'byteLength', { value: 4 })
-
- unlikeLoosely(s2t,
- empty4,
- empty6,
- 'different-length SharedArrayBuffers, one lying'
- )
- s2t.end()
- }) */
-
- st.end()
- })
-
- t.end()
-})
-
-test('String object', function (t) {
- alike(t,
- new String('hi'), // eslint-disable-line no-new-wrappers
- new String('hi'), // eslint-disable-line no-new-wrappers
- 'two same String objects'
- )
-
- unlike(t,
- new String('hi'), // eslint-disable-line no-new-wrappers
- new String('hi2'), // eslint-disable-line no-new-wrappers
- 'two different String objects'
- )
-})
-
-test('Number object', function (t) {
- alike(t,
- new Number(1), // eslint-disable-line no-new-wrappers
- new Number(1), // eslint-disable-line no-new-wrappers
- 'two same Number objects'
- )
-
- t.absent(sameObject(
- new Number(1), // eslint-disable-line no-new-wrappers
- new Number(2) // eslint-disable-line no-new-wrappers
- ), 'two different Number objects')
-})
-
-test('Boolean object', function (t) {
- alike(t,
- new Boolean(true), // eslint-disable-line no-new-wrappers
- new Boolean(true), // eslint-disable-line no-new-wrappers
- 'two same Boolean objects'
- )
-
- t.absent(sameObject(
- new Boolean(true), // eslint-disable-line no-new-wrappers
- new Boolean(false) // eslint-disable-line no-new-wrappers
- ), 'two different Boolean objects')
-})
-
-test('objects', function (t) {
- t.is(sameObject({ foo: 1 }, { foo: 1 }), true)
- t.is(sameObject({ foo: 1 }, { foo: 1, bar: true }), false)
- t.is(sameObject({ foo: 1, nested: { a: 1 } }, { foo: 1, nested: { a: 1 } }), true)
- t.is(sameObject([{ a: 1 }, { b: 1 }], [{ a: 1 }, { b: 1 }]), true)
-})
-
-test('typed arrays', function (t) {
- t.is(sameObject(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])), true)
- t.is(sameObject(new Uint8Array([1, 2, 1]), new Uint8Array([1, 2, 3])), false)
-})
-
-test('symbols', function (t) {
- alike(t, Symbol.for('hello'), Symbol.for('hello'), 'same symbol', true, true)
- unlike(t, Symbol.for('hello'), Symbol.for('holas'), 'diff symbol', false, true)
-
- alike(t, [Symbol.for('hello')], [Symbol.for('hello')], 'symbol inside object', true, true)
- alike(t, { sym: Symbol.for('hello') }, { sym: Symbol.for('hello') }, 'symbol inside object', true, true)
-
- unlike(t, { sym: Symbol.for('hello') }, { sym: Symbol.for('holas') }, 'diff symbol inside object', false, true)
-})
-
-test('numbers', function (t) {
- alike(t, BigInt('9007199254740991'), BigInt('9007199254740991'), 'BigInt', true, true)
- alike(t, Infinity, Infinity, 'Infinity', true, true)
-
- // Note: deep-equal library fails, but Node's assert version passes, so we follow Node standard
- t.ok(sameObject(NaN, NaN, { strict: true }), 'NaN (alike)')
- t.ok(sameObject(NaN, NaN, { strict: false }), 'NaN (alike loosely)')
-})
-
-// +
-test.skip('symbol as key', function (t) {
- alike(t, { a: true, [Symbol.for('aa')]: true }, { a: true, [Symbol.for('aa')]: true })
- unlike(t, { a: true, [Symbol.for('aa')]: true }, { a: true, [Symbol.for('cc')]: true })
-})
-
-test('promises', function (t) {
- const promise = new Promise(noop)
- alike(t, promise, promise, 'two promises with same reference')
-
- // +
- /* alike(t,
- new Promise(noop),
- new Promise(noop),
- 'two promises'
- )
-
- alike(t,
- Promise.resolve('hi'),
- Promise.resolve('hi'),
- 'resolve with same primitive'
- )
-
- unlike(t,
- Promise.resolve('hi1'),
- Promise.resolve('hi2'),
- 'resolve with different primitive'
- )
-
- alike(t,
- Promise.resolve({ a: 1 }),
- Promise.resolve({ a: 1 }),
- 'resolve with same objects'
- )
-
- unlike(t,
- Promise.resolve({ a: 1 }),
- Promise.resolve({ a: 2 }),
- 'resolve with different objects'
- ) */
-
- function noop (resolve, reject) {}
-})
-
-test('functions', function (t) {
- unlike(t, function () {}, function () {}, 'two different functions', true, true)
-
- const fn = function () {}
- alike(t, fn, fn, 'two same functions', true, true)
-})
-
-// + merge this case with the other one
-test('circular references x2', function (t) {
- const obj = { root: null }
- obj.root = obj
- const obj2 = { root: null }
- obj2.root = obj2
- alike(t, obj, obj2)
-
- const obj3 = [{ root: null }]
- obj3.root = obj3
- const obj4 = [{ root: null }]
- obj4.root = obj4
- alike(t, obj3, obj4)
-
- const obj5 = { sub: { root: null, sub2: { obj2, obj3 } } }
- obj5.sub.root = obj5
- const obj6 = { sub: { root: null, sub2: { obj2, obj3 } } }
- obj6.sub.root = obj6
- alike(t, obj5, obj6)
-
- const obj7 = [{ root: null }]
- obj7[0].root = obj7
- const obj8 = [{ root: null }]
- obj8[0].root = obj8
- alike(t, obj7, obj8)
-
- const o = {}
- const obj9 = { a: o, b: o }
- const o2 = {}
- const obj10 = { a: o2, b: o2 }
- alike(t, obj9, obj10)
-
- const obj11 = [o, o]
- const obj12 = [o, o]
- alike(t, obj11, obj12)
-
- const obj13 = [o, obj, o]
- obj13.obj = obj
- const obj14 = [o, obj, o]
- obj14.obj = obj
- alike(t, obj13, obj14)
-})
-
-function alike (t, a, b, comment = '') {
- try {
- t.ok(deepEqual(a, b, { strict: true }), '[deep-equal normal] ' + comment)
- t.ok(deepEqual(b, a, { strict: true }), '[deep-equal reversed] ' + comment)
- } catch (error) {
- if (error.message === 'Cannot convert a Symbol value to a string') t.comment('alike => ' + error.message + ' [deep-equal] ' + comment)
- else throw error
- }
-
- t.ok(sameObject(a, b, { strict: true }), '[same-object normal] ' + comment)
- t.ok(sameObject(b, a, { strict: true }), '[same-object reversed] ' + comment)
-}
-
-function alikeLoosely (t, a, b, comment = '') { // eslint-disable-line no-unused-vars
- try {
- t.ok(deepEqual(a, b, { strict: false }), '[deep-equal normal] ' + comment)
- t.ok(deepEqual(b, a, { strict: false }), '[deep-equal reversed] ' + comment)
- } catch (error) {
- if (error.message === 'Cannot convert a Symbol value to a string') t.comment('alike loosely => ' + error.message + ' [deep-equal] ' + comment)
- else throw error
- }
-
- t.ok(sameObject(a, b, { strict: false }), '[same-object normal] ' + comment)
- t.ok(sameObject(b, a, { strict: false }), '[same-object reversed] ' + comment)
-}
-
-function unlike (t, a, b, comment = '') {
- try {
- t.absent(deepEqual(a, b, { strict: true }), '[deep-equal normal] ' + comment)
- t.absent(deepEqual(b, a, { strict: true }), '[deep-equal reversed] ' + comment)
- } catch (error) {
- if (error.message === 'Cannot convert a Symbol value to a string') t.comment('unlike => ' + error.message + ' [deep-equal] ' + comment)
- else throw error
- }
-
- t.absent(sameObject(a, b, { strict: true }), '[same-object normal] ' + comment)
- t.absent(sameObject(b, a, { strict: true }), '[same-object reversed] ' + comment)
-}
-
-function unlikeLoosely (t, a, b, comment = '') { // eslint-disable-line no-unused-vars
- try {
- t.absent(deepEqual(a, b, { strict: false }), '[deep-equal normal] ' + comment)
- t.absent(deepEqual(b, a, { strict: false }), '[deep-equal reversed] ' + comment)
- } catch (error) {
- if (error.message === 'Cannot convert a Symbol value to a string') t.comment('unlike loosely => ' + error.message + ' [deep-equal] ' + comment)
- else throw error
- }
-
- t.absent(sameObject(a, b, { strict: false }), '[same-object normal] ' + comment)
- t.absent(sameObject(b, a, { strict: false }), '[same-object reversed] ' + comment)
-}
-
-function tag (obj, value) {
- Object.defineProperty(obj, Symbol.toStringTag, { value })
- return obj
-}
diff --git a/debian/tests/test_modules/test-tmp/LICENSE b/debian/tests/test_modules/test-tmp/LICENSE
deleted file mode 100644
index 2b42dab..0000000
--- a/debian/tests/test_modules/test-tmp/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2023 Mathias Buus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/debian/tests/test_modules/test-tmp/README.md b/debian/tests/test_modules/test-tmp/README.md
deleted file mode 100644
index 766e569..0000000
--- a/debian/tests/test_modules/test-tmp/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# test-tmp
-
-Get a fresh tmpdir for tests
-
-```
-npm install test-tmp
-```
-
-## Usage
-
-``` js
-const test = require('brittle')
-const tmp = require('test-tmp')
-
-test('my test', async function (t) {
- const dir = await tmp(t)
- console.log('fresh dir for this test', dir)
-})
-```
-
-## License
-
-MIT
diff --git a/debian/tests/test_modules/test-tmp/index.js b/debian/tests/test_modules/test-tmp/index.js
deleted file mode 100644
index 7a015c8..0000000
--- a/debian/tests/test_modules/test-tmp/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const os = require('os')
-const path = require('path')
-const fs = require('fs')
-
-module.exports = tmp
-
-async function tmp (t, { dir = null, name = null, order = Infinity, force = true } = {}) {
- if (!valid(name)) name = Math.random().toString(16).slice(2)
-
- if (dir) {
- await fs.promises.mkdir(dir, { recursive: true })
- }
-
- const tmpdir = path.join(await fs.promises.realpath(dir || os.tmpdir()), 'tmp-test-' + name)
-
- try {
- await gc(tmpdir)
- } catch {}
-
- await fs.promises.mkdir(tmpdir, { recursive: true })
-
- if (t) t.teardown(gc, { order, force })
- return tmpdir
-
- async function gc () {
- await fs.promises.rm(tmpdir, { recursive: true })
- }
-
- function valid (name) {
- if (typeof name !== 'string') return false
-
- const chars = /[<>:/\\|?*]/
- const max = 64
-
- return !chars.test(name) && name.length <= max
- }
-}
diff --git a/debian/tests/test_modules/test-tmp/package.json b/debian/tests/test_modules/test-tmp/package.json
deleted file mode 100644
index 0654573..0000000
--- a/debian/tests/test_modules/test-tmp/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "test-tmp",
- "version": "1.4.0",
- "description": "Get a fresh tmpdir for tests",
- "main": "index.js",
- "imports": {
- "os": {
- "bare": "bare-os",
- "default": "os"
- },
- "path": {
- "bare": "bare-path",
- "default": "path"
- },
- "fs": {
- "bare": "bare-fs",
- "default": "fs"
- }
- },
- "scripts": {
- "test": "standard && brittle test.js"
- },
- "devDependencies": {
- "brittle": "^3.3.2",
- "standard": "^17.1.0"
- },
- "repository": {
- "type": "git",
- "url": "https://github.com/mafintosh/test-tmp.git"
- },
- "author": "Mathias Buus (@mafintosh)",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/mafintosh/test-tmp/issues"
- },
- "homepage": "https://github.com/mafintosh/test-tmp",
- "dependencies": {
- "bare-fs": "^4.0.1",
- "bare-os": "^3.3.0",
- "bare-path": "^3.0.0"
- }
-}
diff --git a/debian/tests/test_modules/test-tmp/test.js b/debian/tests/test_modules/test-tmp/test.js
deleted file mode 100644
index 0e768a1..0000000
--- a/debian/tests/test_modules/test-tmp/test.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const test = require('brittle')
-const tmp = require('./')
-const fs = require('fs')
-const os = require('os')
-const path = require('path')
-
-test('basic', async function (t) {
- const dir = await tmp(t)
-
- t.alike(await fs.promises.readdir(dir), [])
-})
-
-test('specified name', async function (t) {
- const name = 'testdir'
- const dir = await tmp(t, { name })
- t.ok(dir.includes(name), 'directory contains specified name')
- t.alike(await fs.promises.readdir(dir), [])
-})
-
-test('invalid directory name', async function (t) {
- const name = '<>:/\\|?*'
- try {
- await tmp(t, { name })
- t.pass('should default to a random name when an invalid input is provided')
- } catch (error) {
- t.fail('expected to handle an invalid directory name')
- }
-})
-
-test('reuse directory', async function (t) {
- const name = 'existing-dir'
- const existing = path.join(await fs.promises.realpath(os.tmpdir()), 'tmp-test-' + name)
-
- await fs.promises.mkdir(existing, { recursive: true })
-
- const dir = await tmp(t, { name })
- t.is(dir, existing, 'uses the existing directory when it already exists')
-})
-
-test('specify root directory', async function (t) {
- const dir = await tmp(t, { dir: './tmp-storage' })
-
- const children = await fs.promises.readdir('./tmp-storage')
- t.is(children.length, 1)
-
- t.alike(await fs.promises.readdir(dir), [])
-})
diff --git a/index.js b/index.js
index f1e1a6a..5df3665 100644
--- a/index.js
+++ b/index.js
@@ -164,23 +164,23 @@ exports.extract = function extract (cwd, opts) {
return next()
}
- if (header.type === 'directory') {
- stack.push([name, header.mtime])
- return mkdirfix(name, {
- fs: xfs,
- own,
- uid: header.uid,
- gid: header.gid,
- mode: header.mode
- }, stat)
- }
-
- const dir = path.dirname(name)
+ const dir = path.join(name, '.') === path.join(cwd, '.') ? cwd : path.dirname(name)
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) {
if (err) return next(err)
if (!valid) return next(new Error(dir + ' is not a valid path'))
+ if (header.type === 'directory') {
+ stack.push([name, header.mtime])
+ return mkdirfix(name, {
+ fs: xfs,
+ own,
+ uid: header.uid,
+ gid: header.gid,
+ mode: header.mode
+ }, stat)
+ }
+
mkdirfix(dir, {
fs: xfs,
own,
@@ -228,15 +228,19 @@ exports.extract = function extract (cwd, opts) {
function onlink () {
if (win32) return next() // skip links on win for now before it can be tested
xfs.unlink(name, function () {
- const dst = path.join(cwd, path.join('/', header.linkname))
+ const link = path.join(cwd, path.join('/', header.linkname))
- xfs.link(dst, name, function (err) {
- if (err && err.code === 'EPERM' && opts.hardlinkAsFilesFallback) {
- stream = xfs.createReadStream(dst)
- return onfile()
- }
+ fs.realpath(link, function (err, dst) {
+ if (err || !inCwd(dst)) return next(new Error(name + ' is not a valid hardlink'))
- stat(err)
+ xfs.link(dst, name, function (err) {
+ if (err && err.code === 'EPERM' && opts.hardlinkAsFilesFallback) {
+ stream = xfs.createReadStream(dst)
+ return onfile()
+ }
+
+ stat(err)
+ })
})
})
}
@@ -317,10 +321,11 @@ exports.extract = function extract (cwd, opts) {
function validate (fs, name, root, cb) {
if (name === root) return cb(null, true)
+
fs.lstat(name, function (err, st) {
- if (err && err.code === 'ENOENT') return validate(fs, path.join(name, '..'), root, cb)
- else if (err) return cb(err)
- cb(null, st.isDirectory())
+ if (err && err.code !== 'ENOENT' && err.code !== 'EPERM') return cb(err)
+ if (err || st.isDirectory()) return validate(fs, path.join(name, '..'), root, cb)
+ cb(null, false)
})
}
diff --git a/package.json b/package.json
index 6668d68..16c8a0c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tar-fs",
- "version": "3.0.8",
+ "version": "3.0.9",
"description": "filesystem bindings for tar-stream",
"dependencies": {
"pump": "^3.0.0",
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index b01fb20..a93913e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+node-tar-fs (3.0.9+~cs2.0.4-1) unstable; urgency=medium
+
+ * Team upload
+ * Keep previous test from 2.1.1 with tape
+ * New upstream version (Closes: CVE-2025-48387)
+
+ -- Yadd <yadd at debian.org> Tue, 03 Jun 2025 17:33:46 +0200
+
node-tar-fs (3.0.8+~cs2.0.4-1) unstable; urgency=medium
diff --git a/index.js b/index.js
index f1e1a6a..5df3665 100644
--- a/index.js
+++ b/index.js
@@ -164,23 +164,23 @@ exports.extract = function extract (cwd, opts) {
return next()
}
- if (header.type === 'directory') {
- stack.push([name, header.mtime])
- return mkdirfix(name, {
- fs: xfs,
- own,
- uid: header.uid,
- gid: header.gid,
- mode: header.mode
- }, stat)
- }
-
- const dir = path.dirname(name)
+ const dir = path.join(name, '.') === path.join(cwd, '.') ? cwd : path.dirname(name)
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) {
if (err) return next(err)
if (!valid) return next(new Error(dir + ' is not a valid path'))
+ if (header.type === 'directory') {
+ stack.push([name, header.mtime])
+ return mkdirfix(name, {
+ fs: xfs,
+ own,
+ uid: header.uid,
+ gid: header.gid,
+ mode: header.mode
+ }, stat)
+ }
+
mkdirfix(dir, {
fs: xfs,
own,
@@ -228,15 +228,19 @@ exports.extract = function extract (cwd, opts) {
function onlink () {
if (win32) return next() // skip links on win for now before it can be tested
xfs.unlink(name, function () {
- const dst = path.join(cwd, path.join('/', header.linkname))
+ const link = path.join(cwd, path.join('/', header.linkname))
- xfs.link(dst, name, function (err) {
- if (err && err.code === 'EPERM' && opts.hardlinkAsFilesFallback) {
- stream = xfs.createReadStream(dst)
- return onfile()
- }
+ fs.realpath(link, function (err, dst) {
+ if (err || !inCwd(dst)) return next(new Error(name + ' is not a valid hardlink'))
- stat(err)
+ xfs.link(dst, name, function (err) {
+ if (err && err.code === 'EPERM' && opts.hardlinkAsFilesFallback) {
+ stream = xfs.createReadStream(dst)
+ return onfile()
+ }
+
+ stat(err)
+ })
})
})
}
@@ -317,10 +321,11 @@ exports.extract = function extract (cwd, opts) {
function validate (fs, name, root, cb) {
if (name === root) return cb(null, true)
+
fs.lstat(name, function (err, st) {
- if (err && err.code === 'ENOENT') return validate(fs, path.join(name, '..'), root, cb)
- else if (err) return cb(err)
- cb(null, st.isDirectory())
+ if (err && err.code !== 'ENOENT' && err.code !== 'EPERM') return cb(err)
+ if (err || st.isDirectory()) return validate(fs, path.join(name, '..'), root, cb)
+ cb(null, false)
})
}
diff --git a/package.json b/package.json
index 6668d68..16c8a0c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "tar-fs",
- "version": "3.0.8",
+ "version": "3.0.9",
"description": "filesystem bindings for tar-stream",
"dependencies": {
"pump": "^3.0.0",
More information about the Pkg-javascript-devel
mailing list