@taprsvp/types
Version:
TypeScript types and interfaces for the Transaction Authorization Protocol (TAP)
618 lines • 30.2 kB
JavaScript
"use strict";
/**
* @fileoverview Tests for TAIP-12 Name Hashing Implementation
*
* These tests verify the name normalization and hashing functions comply with
* the TAIP-12 specification and produce the correct hash values for interoperability
* with VerifyVASP and GTR networks.
*
* Enhanced with fast-check property-based testing and IVMS101 integration tests.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const fc = __importStar(require("fast-check"));
const ivms101_1 = require("ivms101");
const nameHash_1 = require("./nameHash");
(0, vitest_1.describe)('normalizeForHashing', () => {
(0, vitest_1.it)('should remove all whitespace and convert to uppercase', () => {
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('Alice Lee')).toBe('ALICELEE');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('Bob Smith')).toBe('BOBSMITH');
});
(0, vitest_1.it)('should handle multiple spaces and different whitespace types', () => {
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)(' Alice Lee ')).toBe('ALICELEE');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('Bob\tSmith')).toBe('BOBSMITH');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('John\nDoe')).toBe('JOHNDOE');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('Jane\r\nSmith')).toBe('JANESMITH');
});
(0, vitest_1.it)('should preserve non-ASCII characters', () => {
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('José María')).toBe('JOSÉMARÍA');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('François Müller')).toBe('FRANÇOISMÜLLER');
});
(0, vitest_1.it)('should handle non-Western scripts correctly', () => {
// Arabic names
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('محمد علي')).toBe('محمدعلي');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)(' أحمد محمد ')).toBe('أحمدمحمد');
// Chinese names
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('李 小明')).toBe('李小明');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('王小华')).toBe('王小华');
// Korean names
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('김 철수')).toBe('김철수');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('박지민')).toBe('박지민');
// Japanese names
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('田中 太郎')).toBe('田中太郎');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('佐藤花子')).toBe('佐藤花子');
});
(0, vitest_1.it)('should handle edge cases', () => {
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('')).toBe('');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)(' ')).toBe('');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('A')).toBe('A');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('a')).toBe('A');
});
(0, vitest_1.it)('should handle names with middle names and initials', () => {
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('Mary Jane Watson')).toBe('MARYJANEWATSON');
(0, vitest_1.expect)((0, nameHash_1.normalizeForHashing)('John F. Kennedy')).toBe('JOHNF.KENNEDY');
});
});
(0, vitest_1.describe)('generateNameHash', () => {
(0, vitest_1.it)('should generate correct hash for TAIP-12 test vector "Alice Lee"', async () => {
const hash = await (0, nameHash_1.generateNameHash)('Alice Lee');
(0, vitest_1.expect)(hash).toBe('b117f44426c9670da91b563db728cd0bc8bafa7d1a6bb5e764d1aad2ca25032e');
});
(0, vitest_1.it)('should generate correct hash for TAIP-12 test vector "Bob Smith"', async () => {
const hash = await (0, nameHash_1.generateNameHash)('Bob Smith');
(0, vitest_1.expect)(hash).toBe('5432e86b4d4a3a2b4be57b713b12c5c576c88459fe1cfdd760fd6c99a0e06686');
});
(0, vitest_1.it)('should return consistent hashes for the same input', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)('Alice Lee');
const hash2 = await (0, nameHash_1.generateNameHash)('Alice Lee');
(0, vitest_1.expect)(hash1).toBe(hash2);
});
(0, vitest_1.it)('should produce different hashes for different names', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)('Alice Lee');
const hash2 = await (0, nameHash_1.generateNameHash)('Bob Smith');
(0, vitest_1.expect)(hash1).not.toBe(hash2);
});
(0, vitest_1.it)('should handle whitespace variations consistently', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)('Alice Lee');
const hash2 = await (0, nameHash_1.generateNameHash)(' Alice Lee ');
const hash3 = await (0, nameHash_1.generateNameHash)('Alice\tLee');
(0, vitest_1.expect)(hash1).toBe(hash2);
(0, vitest_1.expect)(hash1).toBe(hash3);
});
(0, vitest_1.it)('should handle case variations consistently', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)('Alice Lee');
const hash2 = await (0, nameHash_1.generateNameHash)('alice lee');
const hash3 = await (0, nameHash_1.generateNameHash)('ALICE LEE');
(0, vitest_1.expect)(hash1).toBe(hash2);
(0, vitest_1.expect)(hash1).toBe(hash3);
});
(0, vitest_1.it)('should always return 64-character hex string', async () => {
const testNames = [
'A',
'Alice Lee',
'Very Long Name With Multiple Words',
'José María García-González'
];
for (const name of testNames) {
const hash = await (0, nameHash_1.generateNameHash)(name);
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
}
});
(0, vitest_1.it)('should handle empty string', async () => {
const hash = await (0, nameHash_1.generateNameHash)('');
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
});
(0, vitest_1.it)('should handle non-ASCII characters', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)('José María');
const hash2 = await (0, nameHash_1.generateNameHash)('François Müller');
(0, vitest_1.expect)(hash1).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash2).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash1).not.toBe(hash2);
});
(0, vitest_1.it)('should handle non-Western names correctly', async () => {
const testCases = [
{ name: 'محمد علي', description: 'Arabic name' },
{ name: '李小明', description: 'Chinese name' },
{ name: '김철수', description: 'Korean name' },
{ name: '田中太郎', description: 'Japanese name' },
{ name: 'أحمد محمد', description: 'Another Arabic name' },
{ name: '王小华', description: 'Another Chinese name' },
{ name: '박지민', description: 'Another Korean name' },
{ name: '佐藤花子', description: 'Another Japanese name' }
];
const hashes = new Set();
for (const { name, description } of testCases) {
const hash = await (0, nameHash_1.generateNameHash)(name);
// Verify hash format
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
// Verify uniqueness (no collisions in our test set)
(0, vitest_1.expect)(hashes.has(hash)).toBe(false);
hashes.add(hash);
// Test that normalization works consistently
const hashWithSpaces = await (0, nameHash_1.generateNameHash)(` ${name} `);
const hashLowerCase = await (0, nameHash_1.generateNameHash)(name.toLowerCase());
(0, vitest_1.expect)(hash).toBe(hashWithSpaces);
// Note: toLowerCase() behavior varies for non-Latin scripts,
// but our normalization uses toUpperCase() so we test that
const hashUpperCase = await (0, nameHash_1.generateNameHash)(name.toUpperCase());
(0, vitest_1.expect)(hash).toBe(hashUpperCase);
}
});
(0, vitest_1.it)('should handle special characters and punctuation', async () => {
const hash1 = await (0, nameHash_1.generateNameHash)("O'Connor");
const hash2 = await (0, nameHash_1.generateNameHash)('Smith-Jones');
const hash3 = await (0, nameHash_1.generateNameHash)('Dr. Watson');
(0, vitest_1.expect)(hash1).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash2).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash3).toMatch(/^[0-9a-f]{64}$/);
});
});
(0, vitest_1.describe)('TAIP-12 compliance', () => {
(0, vitest_1.it)('should produce hashes compatible with VerifyVASP specification', async () => {
// These test vectors should match the exact hashing algorithm used by VerifyVASP
const testCases = [
{ name: 'Alice Lee', expected: 'b117f44426c9670da91b563db728cd0bc8bafa7d1a6bb5e764d1aad2ca25032e' },
{ name: 'Bob Smith', expected: '5432e86b4d4a3a2b4be57b713b12c5c576c88459fe1cfdd760fd6c99a0e06686' }
];
for (const { name, expected } of testCases) {
const hash = await (0, nameHash_1.generateNameHash)(name);
(0, vitest_1.expect)(hash).toBe(expected);
}
});
(0, vitest_1.it)('should handle normalization exactly as specified in TAIP-12', async () => {
// Test the specific normalization requirements from TAIP-12
const variations = [
'Alice Lee',
' Alice Lee ',
' Alice Lee ',
'alice lee',
'ALICE LEE'
];
const expectedHash = 'b117f44426c9670da91b563db728cd0bc8bafa7d1a6bb5e764d1aad2ca25032e';
for (const variation of variations) {
const hash = await (0, nameHash_1.generateNameHash)(variation);
(0, vitest_1.expect)(hash).toBe(expectedHash);
}
});
});
(0, vitest_1.describe)('IVMS101 Integration', () => {
(0, vitest_1.describe)('generateNameHash with IVMS101 2020 originators', () => {
(0, vitest_1.it)('should handle natural person originators', async () => {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "Lee",
secondaryIdentifier: "Alice",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)("Alice Lee");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should handle legal person originators', async () => {
const originator = {
originatorPerson: [
{
legalPerson: {
name: {
nameIdentifier: [
{
legalPersonName: "Acme Corporation",
legalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)("Acme Corporation");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should handle multiple persons in originator', async () => {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "Smith",
secondaryIdentifier: "John",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
},
{
legalPerson: {
name: {
nameIdentifier: [
{
legalPersonName: "Tech Corp",
legalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)("John Smith Tech Corp");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should prefer legal names over other name types', async () => {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "Doe",
secondaryIdentifier: "Johnny",
naturalPersonNameIdentifierType: "ALIA"
},
{
primaryIdentifier: "Doe",
secondaryIdentifier: "John",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)("John Doe");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
});
(0, vitest_1.describe)('generateNameHash with IVMS101 2020 beneficiaries', () => {
(0, vitest_1.it)('should handle natural person beneficiaries', async () => {
const beneficiary = {
beneficiaryPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "Smith",
secondaryIdentifier: "Bob",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
const expectedHash = await (0, nameHash_1.generateNameHash)("Bob Smith");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should handle legal person beneficiaries', async () => {
const beneficiary = {
beneficiaryPerson: [
{
legalPerson: {
name: {
nameIdentifier: [
{
legalPersonName: "Global Bank Ltd",
legalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
const expectedHash = await (0, nameHash_1.generateNameHash)("Global Bank Ltd");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
});
(0, vitest_1.describe)('generateNameHash with IVMS101 2023 structures', () => {
(0, vitest_1.it)('should handle 2023 originator format', async () => {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "Williams",
secondaryIdentifier: "Sarah",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)("Sarah Williams");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should handle 2023 beneficiary format', async () => {
const beneficiary = {
beneficiaryPerson: [
{
legalPerson: {
name: {
nameIdentifier: [
{
legalPersonName: "Future Finance Inc",
legalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
const expectedHash = await (0, nameHash_1.generateNameHash)("Future Finance Inc");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
});
(0, vitest_1.describe)('edge cases', () => {
(0, vitest_1.it)('should handle empty name arrays', async () => {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: []
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
const expectedHash = await (0, nameHash_1.generateNameHash)(""); // Empty string hash
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should handle missing name identifiers', async () => {
const beneficiary = {
beneficiaryPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: "OnlyPrimary",
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
const expectedHash = await (0, nameHash_1.generateNameHash)("OnlyPrimary");
(0, vitest_1.expect)(hash).toBe(expectedHash);
});
(0, vitest_1.it)('should throw error for invalid input types', async () => {
await (0, vitest_1.expect)((0, nameHash_1.generateNameHash)({})).rejects.toThrow('Invalid input type. Expected string, IVMS101 Originator, or IVMS101 Beneficiary');
});
});
});
(0, vitest_1.describe)('Property-Based Testing with IVMS101', () => {
(0, vitest_1.it)('should always produce 64-character hex strings for generated originators', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.originator2023(), async (originator) => {
const hash = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
}));
});
(0, vitest_1.it)('should always produce 64-character hex strings for generated beneficiaries', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.beneficiary2023(), async (beneficiary) => {
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
}));
});
(0, vitest_1.it)('should always produce 64-character hex strings for IVMS101 2023 originators', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.originator2023(), async (originator) => {
const hash = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
}));
});
(0, vitest_1.it)('should always produce 64-character hex strings for IVMS101 2023 beneficiaries', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.beneficiary2023(), async (beneficiary) => {
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
}));
});
(0, vitest_1.it)('should produce consistent hashes for equivalent name strings', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.naturalPersonNameId2023(), async (nameId) => {
// Build name string manually
const parts = [];
if (nameId.secondaryIdentifier) {
parts.push(nameId.secondaryIdentifier);
}
parts.push(nameId.primaryIdentifier);
const nameString = parts.join(' ');
// Create IVMS101 structure with same name
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [nameId]
}
}
}
]
};
const stringHash = await (0, nameHash_1.generateNameHash)(nameString);
const structureHash = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(stringHash).toBe(structureHash);
}));
});
(0, vitest_1.it)('should handle all natural person name types correctly', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.naturalPerson2023(), async (naturalPerson) => {
const originator = {
originatorPerson: [{ naturalPerson }]
};
const hash = await (0, nameHash_1.generateNameHash)(originator);
// Should always be a valid hash
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
// Should be deterministic
const hash2 = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(hash).toBe(hash2);
}));
});
(0, vitest_1.it)('should handle all legal person name types correctly', () => {
fc.assert(fc.asyncProperty(ivms101_1.arbitraries.legalPerson2023(), async (legalPerson) => {
const beneficiary = {
beneficiaryPerson: [{ legalPerson }]
};
const hash = await (0, nameHash_1.generateNameHash)(beneficiary);
// Should always be a valid hash
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(hash.length).toBe(64);
// Should be deterministic
const hash2 = await (0, nameHash_1.generateNameHash)(beneficiary);
(0, vitest_1.expect)(hash).toBe(hash2);
}));
});
(0, vitest_1.it)('should normalize names consistently across input types', () => {
fc.assert(fc.asyncProperty(fc.string({ minLength: 1, maxLength: 50 }).filter(s => s.trim().length > 0), async (nameString) => {
// Create an IVMS101 structure with the same name
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: nameString,
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const stringHash = await (0, nameHash_1.generateNameHash)(nameString);
const structureHash = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(stringHash).toBe(structureHash);
}));
});
});
(0, vitest_1.describe)('Performance and Edge Cases', () => {
(0, vitest_1.it)('should handle large numbers of persons efficiently', async () => {
// Create an originator with many persons
const manyPersons = Array.from({ length: 100 }, (_, i) => ({
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: `Person${i}`,
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}));
const originator = {
originatorPerson: manyPersons
};
const start = Date.now();
const hash = await (0, nameHash_1.generateNameHash)(originator);
const duration = Date.now() - start;
(0, vitest_1.expect)(hash).toMatch(/^[0-9a-f]{64}$/);
(0, vitest_1.expect)(duration).toBeLessThan(1000); // Should complete within 1 second
});
(0, vitest_1.it)('should handle Unicode names correctly', async () => {
const unicodeNames = [
"李小明", // Chinese
"محمد علي", // Arabic
"José María", // Spanish
"Владимир", // Russian
"田中太郎" // Japanese
];
for (const name of unicodeNames) {
const originator = {
originatorPerson: [
{
naturalPerson: {
name: {
nameIdentifier: [
{
primaryIdentifier: name,
naturalPersonNameIdentifierType: "LEGL"
}
]
}
}
}
]
};
const stringHash = await (0, nameHash_1.generateNameHash)(name);
const structureHash = await (0, nameHash_1.generateNameHash)(originator);
(0, vitest_1.expect)(stringHash).toBe(structureHash);
(0, vitest_1.expect)(stringHash).toMatch(/^[0-9a-f]{64}$/);
}
});
});
//# sourceMappingURL=nameHash.test.js.map