initial commit
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import {BtihV2Hasher} from '../lib/file-id/BtihV2Hasher';
|
||||
import {CID_ALGORITHM_NAMES, HashComputerWorker} from "../lib";
|
||||
import {readFile} from 'fs/promises';
|
||||
import {createHash} from 'crypto';
|
||||
import * as process from "process";
|
||||
|
||||
process.env.WORKER_URL = "./dist/worker.js";
|
||||
|
||||
/**
|
||||
* BitTorrent v2 Info Hash Tests (BEP 52)
|
||||
*
|
||||
* Tests verify:
|
||||
* - 16KB block hashing
|
||||
* - Merkle tree construction
|
||||
* - Info hash computation
|
||||
* - CID encoding format
|
||||
* - Edge cases (empty files, partial blocks)
|
||||
*/
|
||||
describe('BitTorrent v2 Info Hash (BEP 52)', () => {
|
||||
it('should compute info hash for small file', async () => {
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('test.txt');
|
||||
|
||||
// Read test file and feed to hasher
|
||||
const testData = await readFile('./src/tests/test.txt');
|
||||
hasher.update(testData);
|
||||
|
||||
// Get info hash
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
// Verify hash format
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32); // SHA-256 produces 32 bytes
|
||||
|
||||
// Verify it's non-zero
|
||||
const isNonZero = infoHash.some(byte => byte !== 0);
|
||||
expect(isNonZero).toBe(true);
|
||||
|
||||
console.log('Info hash (hex):', infoHash.toString('hex'));
|
||||
});
|
||||
|
||||
it('should handle empty file', () => {
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('empty.txt');
|
||||
|
||||
// Don't update with any data (empty file)
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
// Verify hash format
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32);
|
||||
|
||||
// Should produce valid hash even for empty file
|
||||
const isNonZero = infoHash.some(byte => byte !== 0);
|
||||
expect(isNonZero).toBe(true);
|
||||
|
||||
console.log('Empty file info hash (hex):', infoHash.toString('hex'));
|
||||
});
|
||||
|
||||
it('should handle file exactly one block (16KB)', () => {
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('exactly-16kb.bin');
|
||||
|
||||
// Create exactly 16KB of data
|
||||
const oneBlock = Buffer.alloc(16 * 1024);
|
||||
for (let i = 0; i < oneBlock.length; i++) {
|
||||
oneBlock[i] = i % 256;
|
||||
}
|
||||
|
||||
hasher.update(oneBlock);
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32);
|
||||
|
||||
console.log('16KB file info hash (hex):', infoHash.toString('hex'));
|
||||
});
|
||||
|
||||
it('should handle streaming updates (partial blocks)', () => {
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('streamed.bin');
|
||||
|
||||
// Simulate streaming: feed data in small chunks
|
||||
const chunkSize = 1024; // 1KB chunks
|
||||
const totalSize = 50 * 1024; // 50KB total
|
||||
const data = Buffer.alloc(totalSize);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
data[i] = i % 256;
|
||||
}
|
||||
|
||||
// Stream in chunks
|
||||
for (let offset = 0; offset < data.length; offset += chunkSize) {
|
||||
const end = Math.min(offset + chunkSize, data.length);
|
||||
hasher.update(data.subarray(offset, end));
|
||||
}
|
||||
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32);
|
||||
|
||||
console.log('Streamed 50KB info hash (hex):', infoHash.toString('hex'));
|
||||
});
|
||||
|
||||
it('should compute consistent hash for same data', () => {
|
||||
const testData = Buffer.from('Hello BitTorrent v2!');
|
||||
|
||||
// Compute hash twice
|
||||
const hasher1 = new BtihV2Hasher();
|
||||
hasher1.setFileName('hello.txt');
|
||||
hasher1.update(testData);
|
||||
const hash1 = hasher1.digest();
|
||||
|
||||
const hasher2 = new BtihV2Hasher();
|
||||
hasher2.setFileName('hello.txt');
|
||||
hasher2.update(testData);
|
||||
const hash2 = hasher2.digest();
|
||||
|
||||
// Should produce identical hashes
|
||||
expect(hash1.equals(hash2)).toBe(true);
|
||||
});
|
||||
|
||||
it('should produce different hashes for different data', () => {
|
||||
const data1 = Buffer.from('File A content');
|
||||
const data2 = Buffer.from('File B content');
|
||||
|
||||
const hasher1 = new BtihV2Hasher();
|
||||
hasher1.setFileName('fileA.txt');
|
||||
hasher1.update(data1);
|
||||
const hash1 = hasher1.digest();
|
||||
|
||||
const hasher2 = new BtihV2Hasher();
|
||||
hasher2.setFileName('fileB.txt');
|
||||
hasher2.update(data2);
|
||||
const hash2 = hasher2.digest();
|
||||
|
||||
// Should produce different hashes
|
||||
expect(hash1.equals(hash2)).toBe(false);
|
||||
});
|
||||
|
||||
it('should produce different hashes for different filenames', () => {
|
||||
const data = Buffer.from('Same content');
|
||||
|
||||
const hasher1 = new BtihV2Hasher();
|
||||
hasher1.setFileName('nameA.txt');
|
||||
hasher1.update(data);
|
||||
const hash1 = hasher1.digest();
|
||||
|
||||
const hasher2 = new BtihV2Hasher();
|
||||
hasher2.setFileName('nameB.txt');
|
||||
hasher2.update(data);
|
||||
const hash2 = hasher2.digest();
|
||||
|
||||
// Different filenames should produce different info hashes
|
||||
expect(hash1.equals(hash2)).toBe(false);
|
||||
});
|
||||
|
||||
it('should integrate with HashComputerWorker', async () => {
|
||||
const hashComputer = new HashComputerWorker([
|
||||
CID_ALGORITHM_NAMES.btih_v2,
|
||||
CID_ALGORITHM_NAMES.sha256
|
||||
]);
|
||||
|
||||
const metadata: any = {};
|
||||
await hashComputer.computeMissingHash('./src/tests/test.txt', metadata);
|
||||
|
||||
console.log('Computed metadata:', metadata);
|
||||
|
||||
// Verify btih_v2 CID was computed
|
||||
expect(metadata).toHaveProperty('cid_btih_v2');
|
||||
expect(typeof metadata.cid_btih_v2).toBe('string');
|
||||
expect(metadata.cid_btih_v2.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify CID format (should start with 'b' for base32 CIDv1)
|
||||
expect(metadata.cid_btih_v2.startsWith('b')).toBe(true);
|
||||
|
||||
// Should also have SHA-256 for comparison
|
||||
expect(metadata).toHaveProperty('cid_sha2-256');
|
||||
});
|
||||
|
||||
it('should compute piece length correctly', () => {
|
||||
// Test piece length formula: 16KB * 2^n where pieces < 2048
|
||||
const testCases = [
|
||||
{fileSize: 0, expectedMin: 16 * 1024, expectedMax: 16 * 1024}, // Empty file
|
||||
{fileSize: 1024, expectedMin: 16 * 1024, expectedMax: 16 * 1024}, // 1KB
|
||||
{fileSize: 16 * 1024, expectedMin: 16 * 1024, expectedMax: 16 * 1024}, // 16KB
|
||||
{fileSize: 1024 * 1024, expectedMin: 16 * 1024, expectedMax: 16 * 1024}, // 1MB
|
||||
{fileSize: 100 * 1024 * 1024, expectedMin: 64 * 1024, expectedMax: 128 * 1024}, // 100MB
|
||||
];
|
||||
|
||||
for (const {fileSize, expectedMin, expectedMax} of testCases) {
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('size-test.bin');
|
||||
|
||||
// Feed dummy data of specified size
|
||||
const chunkSize = 16 * 1024;
|
||||
let remaining = fileSize;
|
||||
while (remaining > 0) {
|
||||
const toWrite = Math.min(chunkSize, remaining);
|
||||
hasher.update(Buffer.alloc(toWrite));
|
||||
remaining -= toWrite;
|
||||
}
|
||||
|
||||
// Digest triggers piece length computation
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
// We can't directly access piece length from outside,
|
||||
// but we can verify the hash was computed successfully
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32);
|
||||
}
|
||||
});
|
||||
|
||||
it('should produce valid CID format with codec 0x10B7', async () => {
|
||||
const hashComputer = new HashComputerWorker([
|
||||
CID_ALGORITHM_NAMES.btih_v2
|
||||
]);
|
||||
|
||||
const metadata: any = {};
|
||||
await hashComputer.computeMissingHash('./src/tests/test.txt', metadata);
|
||||
|
||||
const cid = metadata.cid_btih_v2;
|
||||
console.log('BitTorrent v2 CID:', cid);
|
||||
|
||||
// Verify CID format
|
||||
expect(cid).toBeDefined();
|
||||
expect(typeof cid).toBe('string');
|
||||
|
||||
// CIDv1 base32 starts with 'b'
|
||||
expect(cid.startsWith('b')).toBe(true);
|
||||
|
||||
// Should be longer than minimum CID length
|
||||
expect(cid.length).toBeGreaterThan(10);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,175 @@
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import {BtihV2Hasher, MagnetLinkGenerator} from '../lib';
|
||||
import {readFile, stat} from 'fs/promises';
|
||||
|
||||
/**
|
||||
* End-to-End Magnet Link Generation Tests
|
||||
*
|
||||
* Tests the complete workflow:
|
||||
* 1. Compute BitTorrent v2 info hash from file
|
||||
* 2. Generate magnet link
|
||||
* 3. Parse and validate magnet link
|
||||
*/
|
||||
describe('Magnet Link Generation (End-to-End)', () => {
|
||||
it('should generate valid magnet link from file', async () => {
|
||||
const filePath = './src/tests/test.txt';
|
||||
const fileName = 'test.txt';
|
||||
|
||||
// Step 1: Read file and compute info hash
|
||||
const fileData = await readFile(filePath);
|
||||
const fileStats = await stat(filePath);
|
||||
const fileSize = fileStats.size;
|
||||
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName(fileName);
|
||||
hasher.update(fileData);
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
// Verify info hash computed
|
||||
expect(infoHash).toBeInstanceOf(Buffer);
|
||||
expect(infoHash.length).toBe(32);
|
||||
|
||||
console.log('File:', fileName);
|
||||
console.log('Size:', fileSize, 'bytes');
|
||||
console.log('Info hash (hex):', infoHash.toString('hex'));
|
||||
|
||||
// Note: We can't test magnet link generation end-to-end without
|
||||
// the CID encoding working properly through HashComputerWorker.
|
||||
// This would require the worker integration to be fixed.
|
||||
});
|
||||
|
||||
it('should generate magnet link from mock CID', () => {
|
||||
// Mock CID format (this is a valid CIDv1 with our custom codec 0x10B7)
|
||||
// In real usage, this would come from HashComputerWorker
|
||||
const fileName = 'test-video.mp4';
|
||||
const fileSize = 1024 * 1024 * 100; // 100MB
|
||||
|
||||
// Create a mock info hash (32 bytes of test data)
|
||||
const mockInfoHash = Buffer.from(
|
||||
'b04c198dd3148719db3e32fecc54ec41ec355d7f866a1c3f71bf980c3cde01bf',
|
||||
'hex'
|
||||
);
|
||||
|
||||
// For this test, we'll construct the magnet link manually
|
||||
// since we can't get a real CID without the worker
|
||||
const infoHashHex = mockInfoHash.toString('hex');
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHashHex}&dn=${encodeURIComponent(fileName)}&xl=${fileSize}`;
|
||||
|
||||
console.log('\nGenerated magnet link:');
|
||||
console.log(magnetLink);
|
||||
|
||||
// Verify magnet link format
|
||||
expect(magnetLink.startsWith('magnet:?')).toBe(true);
|
||||
expect(magnetLink.includes('xt=urn:btmh:1220')).toBe(true);
|
||||
expect(magnetLink.includes(infoHashHex)).toBe(true);
|
||||
expect(magnetLink.includes(`dn=${encodeURIComponent(fileName)}`)).toBe(true);
|
||||
expect(magnetLink.includes(`xl=${fileSize}`)).toBe(true);
|
||||
});
|
||||
|
||||
it('should validate magnet link format', () => {
|
||||
const validLink = 'magnet:?xt=urn:btmh:1220' + 'a'.repeat(64) + '&dn=file.mp4&xl=1024';
|
||||
const invalidLink1 = 'http://example.com';
|
||||
const invalidLink2 = 'magnet:?xt=urn:btih:' + 'a'.repeat(40); // v1 format (SHA-1)
|
||||
const invalidLink3 = 'magnet:?xt=urn:btmh:1220' + 'a'.repeat(32); // Too short
|
||||
|
||||
expect(MagnetLinkGenerator.isValid(validLink)).toBe(true);
|
||||
expect(MagnetLinkGenerator.isValid(invalidLink1)).toBe(false);
|
||||
expect(MagnetLinkGenerator.isValid(invalidLink2)).toBe(false);
|
||||
expect(MagnetLinkGenerator.isValid(invalidLink3)).toBe(false);
|
||||
});
|
||||
|
||||
it('should extract info hash from magnet link', () => {
|
||||
const infoHash = 'b04c198dd3148719db3e32fecc54ec41ec355d7f866a1c3f71bf980c3cde01bf';
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash}&dn=file.mp4&xl=1024`;
|
||||
|
||||
const extracted = MagnetLinkGenerator.extractInfoHash(magnetLink);
|
||||
expect(extracted).toBe(infoHash);
|
||||
});
|
||||
|
||||
it('should extract filename from magnet link', () => {
|
||||
const fileName = 'Big Buck Bunny.mp4';
|
||||
const infoHash = 'a'.repeat(64);
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash}&dn=${encodeURIComponent(fileName)}&xl=1024`;
|
||||
|
||||
const extracted = MagnetLinkGenerator.extractFileName(magnetLink);
|
||||
expect(extracted).toBe(fileName);
|
||||
});
|
||||
|
||||
it('should extract file size from magnet link', () => {
|
||||
const fileSize = 1024000;
|
||||
const infoHash = 'a'.repeat(64);
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash}&dn=file.mp4&xl=${fileSize}`;
|
||||
|
||||
const extracted = MagnetLinkGenerator.extractFileSize(magnetLink);
|
||||
expect(extracted).toBe(fileSize);
|
||||
});
|
||||
|
||||
it('should parse complete magnet link', () => {
|
||||
const infoHash = 'b04c198dd3148719db3e32fecc54ec41ec355d7f866a1c3f71bf980c3cde01bf';
|
||||
const fileName = 'test-video.mp4';
|
||||
const fileSize = 1024000;
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash}&dn=${encodeURIComponent(fileName)}&xl=${fileSize}`;
|
||||
|
||||
const parsed = MagnetLinkGenerator.parse(magnetLink);
|
||||
|
||||
expect(parsed).not.toBeNull();
|
||||
expect(parsed!.infoHash).toBe(infoHash);
|
||||
expect(parsed!.fileName).toBe(fileName);
|
||||
expect(parsed!.fileSize).toBe(fileSize);
|
||||
});
|
||||
|
||||
it('should handle special characters in filename', () => {
|
||||
const fileName = 'My Video [1080p] (2024).mp4';
|
||||
const infoHash = 'a'.repeat(64);
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash}&dn=${encodeURIComponent(fileName)}&xl=1024`;
|
||||
|
||||
const extracted = MagnetLinkGenerator.extractFileName(magnetLink);
|
||||
expect(extracted).toBe(fileName);
|
||||
|
||||
// Verify round-trip
|
||||
const parsed = MagnetLinkGenerator.parse(magnetLink);
|
||||
expect(parsed?.fileName).toBe(fileName);
|
||||
});
|
||||
|
||||
it('should demonstrate complete workflow (conceptual)', async () => {
|
||||
// This test demonstrates the intended workflow once worker integration is fixed
|
||||
const filePath = './src/tests/test.txt';
|
||||
const fileStats = await stat(filePath);
|
||||
|
||||
console.log('\n=== Complete Workflow Demo ===');
|
||||
console.log('1. File:', filePath);
|
||||
console.log('2. Size:', fileStats.size, 'bytes');
|
||||
|
||||
// Step 1: Compute info hash
|
||||
const fileData = await readFile(filePath);
|
||||
const hasher = new BtihV2Hasher();
|
||||
hasher.setFileName('test.txt');
|
||||
hasher.update(fileData);
|
||||
const infoHash = hasher.digest();
|
||||
|
||||
console.log('3. Info hash:', infoHash.toString('hex'));
|
||||
|
||||
// Step 2: In production, this would be the CID from metadata
|
||||
// const cid = metadata.cid_btih_v2;
|
||||
// const magnetLink = MagnetLinkGenerator.generate(metadata, 'test.txt', fileStats.size);
|
||||
|
||||
// Step 3: For demo, construct magnet link manually
|
||||
const magnetLink = `magnet:?xt=urn:btmh:1220${infoHash.toString('hex')}&dn=test.txt&xl=${fileStats.size}`;
|
||||
console.log('4. Magnet link:', magnetLink);
|
||||
|
||||
// Step 4: Verify it's valid
|
||||
const isValid = MagnetLinkGenerator.isValid(magnetLink);
|
||||
console.log('5. Valid:', isValid);
|
||||
|
||||
expect(isValid).toBe(true);
|
||||
|
||||
// Step 5: Parse it back
|
||||
const parsed = MagnetLinkGenerator.parse(magnetLink);
|
||||
console.log('6. Parsed:', parsed);
|
||||
|
||||
expect(parsed).not.toBeNull();
|
||||
expect(parsed!.infoHash).toBe(infoHash.toString('hex'));
|
||||
expect(parsed!.fileName).toBe('test.txt');
|
||||
expect(parsed!.fileSize).toBe(fileStats.size);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
import {CID_ALGORITHM_NAMES, HashComputerIndexCache, HashComputerWorker} from "../lib";
|
||||
|
||||
import {describe, expect, it} from 'vitest';
|
||||
import * as process from "process";
|
||||
import { mkdir, rm, rmdir } from "fs/promises";
|
||||
|
||||
process.env.WORKER_URL = "./dist/worker.js";
|
||||
|
||||
/**
|
||||
* /!\ WARNING /!\
|
||||
* Remember to build the worker each time you change the worker code.
|
||||
*/
|
||||
|
||||
describe('add', () => {
|
||||
it('meta data compute', async () => {
|
||||
let hashComputer = new HashComputerWorker([
|
||||
CID_ALGORITHM_NAMES.sha1,
|
||||
CID_ALGORITHM_NAMES.sha256,
|
||||
CID_ALGORITHM_NAMES.md5,
|
||||
CID_ALGORITHM_NAMES.sha3_256,
|
||||
CID_ALGORITHM_NAMES.crc32,
|
||||
CID_ALGORITHM_NAMES.sha3_384
|
||||
]);
|
||||
let metadata = {};
|
||||
await hashComputer.computeMissingHash('./src/tests/test.txt', metadata);
|
||||
console.log(metadata);
|
||||
/**
|
||||
* test.txt CF20B62A (CRC32)
|
||||
* 26f1157f4349a6fb5d207ac5f5995140 *test.txt (MD5)
|
||||
* bb242b7b821074f4b9eb9a94d439ab668705aac4 ?SHA1*test.txt
|
||||
* 2aa7a80d2fd1eb96d31afc7cdda9211a97524202c63f04151d6163fba35061a0 ?SHA256*test.txt
|
||||
* 865a1ea4977b25e04b8ea84af93b21f1a031cb48359f3805089cdae1d89842b9a3faf87654989dcae418144a8bbb378c ?SHA3-384*test.txt
|
||||
*/
|
||||
expect(metadata).toEqual({
|
||||
"cid_crc32": "bagzafmqcathsbnrk",
|
||||
"cid_sha1": 'baeircff3eqvxxaqqot2lt242stkdtk3gq4c2vra',
|
||||
"cid_sha2-256": 'baejbeibku6ua2l6r5olnggx4pto2sii2s5jeeawgh4cbkhlbmp52gudbua',
|
||||
"cid_md5": 'bahkqdvibcatpcfl7ine2n625eb5ml5mzkfaa',
|
||||
"cid_sha3-256": 'baelbmidner7x3dd7t2kldh6wiq4w6lsye7qrwo6uoqot2t52zkhqk56fnq',
|
||||
"cid_sha3-384": 'baekrkmeglipkjf33exqexdvijl4twipruay4wsbvt44akce43lq5rgccxgr7v6dwksmj3sxedakevc53g6ga'
|
||||
});
|
||||
});
|
||||
it('meta data compute with index', async () => {
|
||||
await rm("./tmp",{recursive:true});
|
||||
await mkdir("./tmp",{recursive:true});
|
||||
let hashComputer = new HashComputerIndexCache("./tmp/index.csv",[
|
||||
CID_ALGORITHM_NAMES.sha1,
|
||||
CID_ALGORITHM_NAMES.sha256,
|
||||
CID_ALGORITHM_NAMES.md5,
|
||||
CID_ALGORITHM_NAMES.sha3_256,
|
||||
CID_ALGORITHM_NAMES.crc32,
|
||||
CID_ALGORITHM_NAMES.sha3_384
|
||||
]);
|
||||
let metadata = {};
|
||||
await hashComputer.computeMissingHash('./src/tests/test.txt', metadata);
|
||||
console.log(metadata);
|
||||
/**
|
||||
* test.txt CF20B62A (CRC32)
|
||||
* 26f1157f4349a6fb5d207ac5f5995140 *test.txt (MD5)
|
||||
* bb242b7b821074f4b9eb9a94d439ab668705aac4 ?SHA1*test.txt
|
||||
* 2aa7a80d2fd1eb96d31afc7cdda9211a97524202c63f04151d6163fba35061a0 ?SHA256*test.txt
|
||||
* 865a1ea4977b25e04b8ea84af93b21f1a031cb48359f3805089cdae1d89842b9a3faf87654989dcae418144a8bbb378c ?SHA3-384*test.txt
|
||||
*/
|
||||
expect(metadata).toEqual({
|
||||
"cid_crc32": "bagzafmqcathsbnrk",
|
||||
"cid_sha1": 'baeircff3eqvxxaqqot2lt242stkdtk3gq4c2vra',
|
||||
"cid_sha2-256": 'baejbeibku6ua2l6r5olnggx4pto2sii2s5jeeawgh4cbkhlbmp52gudbua',
|
||||
"cid_md5": 'bahkqdvibcatpcfl7ine2n625eb5ml5mzkfaa',
|
||||
"cid_sha3-256": 'baelbmidner7x3dd7t2kldh6wiq4w6lsye7qrwo6uoqot2t52zkhqk56fnq',
|
||||
"cid_sha3-384": 'baekrkmeglipkjf33exqexdvijl4twipruay4wsbvt44akce43lq5rgccxgr7v6dwksmj3sxedakevc53g6ga'
|
||||
});
|
||||
await (await hashComputer.getHashIndexManager()).saveCacheToFile();
|
||||
});
|
||||
it('cache', async () => {
|
||||
await mkdir("./tmp",{recursive:true});
|
||||
let hashComputer = new HashComputerIndexCache("./tmp/index.csv",[
|
||||
CID_ALGORITHM_NAMES.sha1,
|
||||
CID_ALGORITHM_NAMES.sha256,
|
||||
CID_ALGORITHM_NAMES.md5,
|
||||
CID_ALGORITHM_NAMES.sha3_256,
|
||||
CID_ALGORITHM_NAMES.crc32,
|
||||
CID_ALGORITHM_NAMES.sha3_384
|
||||
]);
|
||||
let indexLine = await (await hashComputer.getHashIndexManager()).getCidForFileAsync('./src/tests/test.txt');
|
||||
delete indexLine['mtime'];
|
||||
expect(indexLine).toEqual({
|
||||
"cid_sha1": 'baeircff3eqvxxaqqot2lt242stkdtk3gq4c2vra',
|
||||
"cid_sha2-256": 'baejbeibku6ua2l6r5olnggx4pto2sii2s5jeeawgh4cbkhlbmp52gudbua',
|
||||
"cid_md5": 'bahkqdvibcatpcfl7ine2n625eb5ml5mzkfaa',
|
||||
"cid_sha3-256": 'baelbmidner7x3dd7t2kldh6wiq4w6lsye7qrwo6uoqot2t52zkhqk56fnq',
|
||||
"cid_crc32": "bagzafmqcathsbnrk",
|
||||
"cid_sha3-384": 'baekrkmeglipkjf33exqexdvijl4twipruay4wsbvt44akce43lq5rgccxgr7v6dwksmj3sxedakevc53g6ga',
|
||||
"path": "test.txt",
|
||||
"size": "499",
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
this is a file that is just some data to be hashed
|
||||
|
||||
loreum ipsum dolor sit amet
|
||||
consectetur adipiscing elit
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
|
||||
ut enim ad minim veniam
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat
|
||||
duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur
|
||||
excepteur sint occaecat cupidatat non proident
|
||||
sunt in culpa qui officia deserunt mollit anim id est laborum
|
||||
Reference in New Issue
Block a user