fix(tests): Standardize test syntax and update testing dependencies
This commit is contained in:
parent
283703ec78
commit
45951d2610
@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-05-12 - 1.1.8 - fix(tests)
|
||||||
|
Standardize test syntax and update testing dependencies
|
||||||
|
|
||||||
|
- Added @git.zone/tsrun dependency to package.json for improved test runner support
|
||||||
|
- Refactored test export in test/test.articlesearch.ts to use default export instead of tap.start()
|
||||||
|
- Updated readme.plan.md to describe testing improvements and syntax standardization
|
||||||
|
|
||||||
## 2025-05-12 - 1.1.7 - fix(build)
|
## 2025-05-12 - 1.1.7 - fix(build)
|
||||||
Fix import paths, update CI workflows and upgrade dependencies for ESM compliance
|
Fix import paths, update CI workflows and upgrade dependencies for ESM compliance
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^2.1.27",
|
"@git.zone/tsbuild": "^2.1.27",
|
||||||
|
"@git.zone/tsrun": "^1.3.3",
|
||||||
"@git.zone/tstest": "^1.0.57",
|
"@git.zone/tstest": "^1.0.57",
|
||||||
"@push.rocks/tapbundle": "^6.0.3",
|
"@push.rocks/tapbundle": "^6.0.3",
|
||||||
"@types/node": "^22.15.17"
|
"@types/node": "^22.15.17"
|
||||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -24,6 +24,9 @@ importers:
|
|||||||
'@git.zone/tsbuild':
|
'@git.zone/tsbuild':
|
||||||
specifier: ^2.1.27
|
specifier: ^2.1.27
|
||||||
version: 2.3.2
|
version: 2.3.2
|
||||||
|
'@git.zone/tsrun':
|
||||||
|
specifier: ^1.3.3
|
||||||
|
version: 1.3.3
|
||||||
'@git.zone/tstest':
|
'@git.zone/tstest':
|
||||||
specifier: ^1.0.57
|
specifier: ^1.0.57
|
||||||
version: 1.0.96(@aws-sdk/credential-providers@3.806.0)(socks@2.8.4)(typescript@5.8.3)
|
version: 1.0.96(@aws-sdk/credential-providers@3.806.0)(socks@2.8.4)(typescript@5.8.3)
|
||||||
|
@ -3,28 +3,22 @@
|
|||||||
## Current Status
|
## Current Status
|
||||||
- ESM imports/exports fixed with .js extensions
|
- ESM imports/exports fixed with .js extensions
|
||||||
- Basic fuzzy matching functionality works
|
- Basic fuzzy matching functionality works
|
||||||
- Tests run individually with tsx but fail with pnpm test
|
- Testing infrastructure fixed with @git.zone/tsrun dependency
|
||||||
|
- Test syntax needs standardization (converting from chai-style to SmartExpect syntax)
|
||||||
- Using older versions of dependencies
|
- Using older versions of dependencies
|
||||||
|
|
||||||
## Improvement Plan
|
## Improvement Plan
|
||||||
|
|
||||||
### 1. Fix Testing Infrastructure
|
### 1. Testing Improvements
|
||||||
|
|
||||||
#### 1.1 Fix Test Runner Configuration
|
#### 1.1 Update Test Syntax and Standards
|
||||||
- [ ] Investigate why `pnpm test` fails while individual tests run with `tsx` succeed
|
|
||||||
- [ ] Check if `tsrun` command is properly installed and available (current error shows "tsrun: command not found")
|
|
||||||
- [ ] Examine the `tstest` configuration in package.json and update if needed
|
|
||||||
- [ ] Verify that `@git.zone/tstest` dependency is properly installed and configured
|
|
||||||
- [ ] Consider updating the test script to use `tsx` directly if `tstest` continues to be problematic
|
|
||||||
|
|
||||||
#### 1.2 Update Test Syntax and Standards
|
|
||||||
- [ ] Convert all tests from chai-style syntax (`expect().to.be`) to SmartExpect syntax (`expect().toBeInstanceOf()`)
|
- [ ] Convert all tests from chai-style syntax (`expect().to.be`) to SmartExpect syntax (`expect().toBeInstanceOf()`)
|
||||||
- [ ] Implement consistent test structure across all test files
|
- [ ] Implement consistent test structure across all test files
|
||||||
- [ ] Add proper setup and teardown patterns where needed
|
- [ ] Add proper setup and teardown patterns where needed
|
||||||
- [ ] Replace console.log statements with proper assertions to validate results
|
- [ ] Replace console.log statements with proper assertions to validate results
|
||||||
- [ ] Add descriptive error messages to assertions to improve test debugging
|
- [ ] Add descriptive error messages to assertions to improve test debugging
|
||||||
|
|
||||||
#### 1.3 Expand Test Coverage
|
#### 1.2 Expand Test Coverage
|
||||||
- [ ] Add tests for empty dictionaries and edge cases
|
- [ ] Add tests for empty dictionaries and edge cases
|
||||||
- [ ] Test with extremely large dictionaries to verify performance
|
- [ ] Test with extremely large dictionaries to verify performance
|
||||||
- [ ] Add tests for unicode/special character handling
|
- [ ] Add tests for unicode/special character handling
|
||||||
@ -32,13 +26,6 @@
|
|||||||
- [ ] Add tests for error conditions and input validation
|
- [ ] Add tests for error conditions and input validation
|
||||||
- [ ] Implement tests for all public APIs and features
|
- [ ] Implement tests for all public APIs and features
|
||||||
|
|
||||||
#### 1.4 Test Automation and CI
|
|
||||||
- [ ] Add test coverage reporting
|
|
||||||
- [ ] Set up continuous integration for automated testing
|
|
||||||
- [ ] Add performance regression tests
|
|
||||||
- [ ] Create test fixtures for consistent test data
|
|
||||||
- [ ] Add browser-based tests for web compatibility
|
|
||||||
|
|
||||||
### 2. Code Quality Improvements
|
### 2. Code Quality Improvements
|
||||||
- [ ] Add proper TypeScript documentation comments to all public methods
|
- [ ] Add proper TypeScript documentation comments to all public methods
|
||||||
- [ ] Implement consistent error handling
|
- [ ] Implement consistent error handling
|
||||||
|
@ -31,4 +31,4 @@ tap.test('should sort objects', async () => {
|
|||||||
console.log(result[0].matches);
|
console.log(result[0].matches);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
export default tap.start();
|
||||||
|
@ -1,19 +1,81 @@
|
|||||||
import { expect, tap } from '@push.rocks/tapbundle';
|
import { expect, tap } from '@push.rocks/tapbundle';
|
||||||
import * as smartfuzzy from '../ts/index.js';
|
import * as smartfuzzy from '../ts/index.js';
|
||||||
|
|
||||||
tap.test('should sort objects', async () => {
|
class Car {
|
||||||
class Car {
|
constructor(public brand: string, public model?: string, public year?: number) {}
|
||||||
constructor(public brand: string) {}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const testObjectSorter = new smartfuzzy.ObjectSorter<Car>([
|
const testCars = [
|
||||||
new Car('BMW'),
|
new Car('BMW', 'X5', 2022),
|
||||||
new Car('Mercedes Benz'),
|
new Car('Mercedes Benz', 'S-Class', 2021),
|
||||||
new Car('Volvo'),
|
new Car('Volvo', 'XC90', 2023),
|
||||||
]);
|
new Car('Volkswagen', 'Golf', 2020),
|
||||||
|
new Car('Audi', 'A4', 2022),
|
||||||
|
];
|
||||||
|
|
||||||
const result = testObjectSorter.sort('Volvo', ['brand']);
|
let objectSorter: smartfuzzy.ObjectSorter<Car>;
|
||||||
console.log(result);
|
|
||||||
|
tap.test('should create an instance of ObjectSorter', async () => {
|
||||||
|
objectSorter = new smartfuzzy.ObjectSorter<Car>(testCars);
|
||||||
|
expect(objectSorter).toBeInstanceOf(smartfuzzy.ObjectSorter);
|
||||||
|
expect(objectSorter.objectDictionary).toEqual(testCars);
|
||||||
|
|
||||||
|
// Test empty constructor
|
||||||
|
const emptyObjectSorter = new smartfuzzy.ObjectSorter<Car>();
|
||||||
|
expect(emptyObjectSorter.objectDictionary).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
tap.test('should sort objects by exact brand match', async () => {
|
||||||
|
const result = objectSorter.sort('Volvo', ['brand']);
|
||||||
|
|
||||||
|
// Should return an array of results
|
||||||
|
expect(result).toBeArray();
|
||||||
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
// First result should be the Volvo
|
||||||
|
expect(result[0].item.brand).toEqual('Volvo');
|
||||||
|
|
||||||
|
// Should have expected result structure
|
||||||
|
expect(result[0]).toHaveProperty('item');
|
||||||
|
expect(result[0]).toHaveProperty('refIndex');
|
||||||
|
expect(result[0].refIndex).toBeTypeofNumber();
|
||||||
|
|
||||||
|
// Reference index should match the original array position
|
||||||
|
expect(result[0].refIndex).toEqual(2); // Volvo is at index 2
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should sort objects by fuzzy brand match', async () => {
|
||||||
|
// "Wolvo" should fuzzy match to "Volvo"
|
||||||
|
const result = objectSorter.sort('Wolvo', ['brand']);
|
||||||
|
|
||||||
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
expect(result[0].item.brand).toEqual('Volvo');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should sort objects by multiple field search', async () => {
|
||||||
|
// Add a car with similar model name but different brand
|
||||||
|
objectSorter = new smartfuzzy.ObjectSorter<Car>([
|
||||||
|
...testCars,
|
||||||
|
new Car('Toyota', 'X5 Replica', 2020),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Search across both brand and model
|
||||||
|
const result = objectSorter.sort('BMW X5', ['brand', 'model']);
|
||||||
|
|
||||||
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
// BMW X5 should be first result
|
||||||
|
expect(result[0].item.brand).toEqual('BMW');
|
||||||
|
expect(result[0].item.model).toEqual('X5');
|
||||||
|
|
||||||
|
// Toyota X5 Replica should also be in results but lower ranked
|
||||||
|
const toyotaResult = result.find(r => r.item.brand === 'Toyota');
|
||||||
|
expect(toyotaResult).toBeDefined();
|
||||||
|
|
||||||
|
// Toyota should be ranked lower than BMW
|
||||||
|
const bmwIndex = result.findIndex(r => r.item.brand === 'BMW');
|
||||||
|
const toyotaIndex = result.findIndex(r => r.item.brand === 'Toyota');
|
||||||
|
expect(bmwIndex).toBeLessThan(toyotaIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default tap.start();
|
||||||
|
@ -2,25 +2,66 @@ import { expect, tap } from '@push.rocks/tapbundle';
|
|||||||
import * as smartfuzzy from '../ts/index.js';
|
import * as smartfuzzy from '../ts/index.js';
|
||||||
|
|
||||||
let testSmartfuzzy: smartfuzzy.Smartfuzzy;
|
let testSmartfuzzy: smartfuzzy.Smartfuzzy;
|
||||||
|
const testDictionary = [
|
||||||
tap.test('should create an instance of Smartfuzzy', async () => {
|
|
||||||
testSmartfuzzy = new smartfuzzy.Smartfuzzy([
|
|
||||||
'Sony',
|
'Sony',
|
||||||
'Deutsche Bahn',
|
'Deutsche Bahn',
|
||||||
'Apple Inc.',
|
'Apple Inc.',
|
||||||
"Trader Joe's",
|
"Trader Joe's",
|
||||||
]);
|
];
|
||||||
|
|
||||||
|
tap.test('should create an instance of Smartfuzzy', async () => {
|
||||||
|
testSmartfuzzy = new smartfuzzy.Smartfuzzy(testDictionary);
|
||||||
expect(testSmartfuzzy).toBeInstanceOf(smartfuzzy.Smartfuzzy);
|
expect(testSmartfuzzy).toBeInstanceOf(smartfuzzy.Smartfuzzy);
|
||||||
|
expect(testSmartfuzzy.dictionary).toEqual(testDictionary);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should compute a score', async () => {
|
tap.test('should compute a score for a string against the dictionary', async () => {
|
||||||
const result = testSmartfuzzy.getChangeScoreForString('Apple');
|
const result = testSmartfuzzy.getChangeScoreForString('Apple');
|
||||||
console.log(result);
|
|
||||||
|
// Check that we got a dictionary map back
|
||||||
|
expect(result).toBeTypeOf('object');
|
||||||
|
|
||||||
|
// Check that every dictionary entry has a score
|
||||||
|
for (const word of testDictionary) {
|
||||||
|
expect(result).toHaveProperty(word);
|
||||||
|
expect(result[word]).toBeTypeofNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that 'Apple Inc.' has a lower score (better match) than other entries
|
||||||
|
expect(result['Apple Inc.']).toBeLessThan(result['Sony']);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should get closest match', async () => {
|
tap.test('should get closest match for a string', async () => {
|
||||||
const result = testSmartfuzzy.getClosestMatchForString('Apple');
|
const result = testSmartfuzzy.getClosestMatchForString('Apple');
|
||||||
console.log(result);
|
|
||||||
|
// Should return closest match as string
|
||||||
|
expect(result).toBeTypeofString();
|
||||||
|
|
||||||
|
// Should match the expected closest entry
|
||||||
|
expect(result).toEqual('Apple Inc.');
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
tap.test('should add words to dictionary', async () => {
|
||||||
|
const initialLength = testSmartfuzzy.dictionary.length;
|
||||||
|
|
||||||
|
// Add a single word
|
||||||
|
testSmartfuzzy.addToDictionary('Microsoft');
|
||||||
|
expect(testSmartfuzzy.dictionary.length).toEqual(initialLength + 1);
|
||||||
|
expect(testSmartfuzzy.dictionary).toContain('Microsoft');
|
||||||
|
|
||||||
|
// Add multiple words
|
||||||
|
const additionalWords = ['Google', 'Amazon', 'Facebook'];
|
||||||
|
testSmartfuzzy.addToDictionary(additionalWords);
|
||||||
|
expect(testSmartfuzzy.dictionary.length).toEqual(initialLength + 4);
|
||||||
|
for (const word of additionalWords) {
|
||||||
|
expect(testSmartfuzzy.dictionary).toContain(word);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should handle empty query string', async () => {
|
||||||
|
const result = testSmartfuzzy.getClosestMatchForString('');
|
||||||
|
// For empty strings, behavior should be defined (either null or a specific result)
|
||||||
|
expect(result).toBeNullOrUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
export default tap.start();
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartfuzzy',
|
name: '@push.rocks/smartfuzzy',
|
||||||
version: '1.1.7',
|
version: '1.1.8',
|
||||||
description: 'A library for fuzzy matching strings against word dictionaries or arrays, with support for object and article searching.'
|
description: 'A library for fuzzy matching strings against word dictionaries or arrays, with support for object and article searching.'
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user