merged libraries into one
This commit is contained in:
406
packages/lib/src/eve/models/unit.test.ts
Normal file
406
packages/lib/src/eve/models/unit.test.ts
Normal file
@@ -0,0 +1,406 @@
|
||||
import { test, it, expect, mock, beforeEach } from 'bun:test';
|
||||
import { getUnit, renderUnit, isUnitInversePercentage, type Unit } from './unit';
|
||||
|
||||
test('unit.ts', () => {
|
||||
test('getUnit', () => {
|
||||
it('should return unit when found', async () => {
|
||||
const mockUnit: Unit = {
|
||||
unit_id: 123,
|
||||
display_name: 'Test Unit',
|
||||
description: { en: 'Test description' },
|
||||
name: { en: 'Test Name' },
|
||||
};
|
||||
|
||||
mock.module('@star-kitten/util/json-query.js', () => ({
|
||||
queryJsonObject: () => Promise.resolve(mockUnit),
|
||||
}));
|
||||
|
||||
const result = await getUnit(123);
|
||||
|
||||
expect(result).toEqual(mockUnit);
|
||||
});
|
||||
|
||||
it('should throw error when unit not found', async () => {
|
||||
mock.module('@star-kitten/util/json-query.js', () => ({
|
||||
queryJsonObject: () => Promise.resolve(null),
|
||||
}));
|
||||
|
||||
await expect(getUnit(999)).rejects.toThrow('Unit ID 999 not found in reference data');
|
||||
});
|
||||
});
|
||||
|
||||
test('renderUnit', () => {
|
||||
const mockUnit: Unit = {
|
||||
unit_id: 0,
|
||||
display_name: 'Test Unit',
|
||||
description: { en: 'Test description' },
|
||||
name: { en: 'Test Name' },
|
||||
};
|
||||
|
||||
test('inverse percentage units', () => {
|
||||
it('should render unit 108 as inverse percentage', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 108 };
|
||||
const result = await renderUnit(unit, 0.75);
|
||||
expect(result).toBe('0.25 Test Unit');
|
||||
});
|
||||
|
||||
it('should render unit 111 as inverse percentage', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 111 };
|
||||
const result = await renderUnit(unit, 0.3);
|
||||
expect(result).toBe('0.70 Test Unit');
|
||||
});
|
||||
|
||||
it('should handle missing display_name for inverse percentage', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 108, display_name: '' };
|
||||
const result = await renderUnit(unit, 0.5);
|
||||
expect(result).toBe('0.50 ');
|
||||
});
|
||||
});
|
||||
|
||||
test('time units', () => {
|
||||
it('should render unit 3 (seconds) using convertSecondsToTimeString', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 3 };
|
||||
mock.module('@star-kitten/util/text.js', () => ({
|
||||
convertSecondsToTimeString: (seconds: number) => {
|
||||
if (seconds === 330) return '5m 30s';
|
||||
return '0s';
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 330);
|
||||
|
||||
expect(result).toBe('5m 30s');
|
||||
});
|
||||
|
||||
it('should render unit 101 (milliseconds) using convertMillisecondsToTimeString', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 101 };
|
||||
mock.module('@star-kitten/util/text.js', () => ({
|
||||
convertMillisecondsToTimeString: (milliseconds: number) => {
|
||||
if (milliseconds === 2500) return '2.5s';
|
||||
return '0s';
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 2500);
|
||||
|
||||
expect(result).toBe('2.5s');
|
||||
});
|
||||
});
|
||||
|
||||
test('size class unit (117)', () => {
|
||||
it('should render size class 1 as Small', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 117 };
|
||||
const result = await renderUnit(unit, 1);
|
||||
expect(result).toBe('Small');
|
||||
});
|
||||
|
||||
it('should render size class 2 as Medium', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 117 };
|
||||
const result = await renderUnit(unit, 2);
|
||||
expect(result).toBe('Medium');
|
||||
});
|
||||
|
||||
it('should render size class 3 as Large', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 117 };
|
||||
const result = await renderUnit(unit, 3);
|
||||
expect(result).toBe('Large');
|
||||
});
|
||||
|
||||
it('should render size class 4 as X-Large', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 117 };
|
||||
const result = await renderUnit(unit, 4);
|
||||
expect(result).toBe('X-Large');
|
||||
});
|
||||
|
||||
it('should render unknown size class as Unknown', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 117 };
|
||||
const result = await renderUnit(unit, 99);
|
||||
expect(result).toBe('Unknown');
|
||||
});
|
||||
});
|
||||
|
||||
test('specialized units', () => {
|
||||
it('should render unit 141 (hardpoints) as string', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 141 };
|
||||
const result = await renderUnit(unit, 8);
|
||||
expect(result).toBe('8');
|
||||
});
|
||||
|
||||
it('should render unit 120 (calibration) with pts suffix', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 120 };
|
||||
const result = await renderUnit(unit, 400);
|
||||
expect(result).toBe('400 pts');
|
||||
});
|
||||
|
||||
it('should render unit 116 (typeID) using type lookup', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 116 };
|
||||
const mockType = {
|
||||
type_id: 12345,
|
||||
name: { en: 'Test Type' },
|
||||
description: { en: 'Test description' },
|
||||
published: true,
|
||||
};
|
||||
|
||||
mock.module('./type', () => ({
|
||||
getType: (type_id: number) => {
|
||||
if (type_id === 12345) return Promise.resolve(mockType);
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
renderTypeEveRefLink: (type: any, lang: string) => {
|
||||
if (type.type_id === 12345 && lang === 'en') return 'Type Link';
|
||||
return null;
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 12345, 'en');
|
||||
|
||||
expect(result).toBe('Type Link');
|
||||
});
|
||||
|
||||
it('should render unit 116 (typeID) as Unknown when link is null', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 116 };
|
||||
const mockType = {
|
||||
type_id: 12345,
|
||||
name: { en: 'Test Type' },
|
||||
description: { en: 'Test description' },
|
||||
published: true,
|
||||
};
|
||||
|
||||
mock.module('./type', () => ({
|
||||
getType: (type_id: number) => {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
renderTypeEveRefLink: (type: any, lang: string) => {
|
||||
return null;
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 12345);
|
||||
|
||||
expect(result).toBe('Unknown');
|
||||
});
|
||||
|
||||
it('should render unit 115 (groupID) using group lookup', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 115 };
|
||||
const mockGroup = {
|
||||
group_id: 67890,
|
||||
name: { en: 'Test Group' },
|
||||
category_id: 1,
|
||||
published: true,
|
||||
anchorable: false,
|
||||
anchored: false,
|
||||
fittable_non_singleton: false,
|
||||
use_base_price: false,
|
||||
};
|
||||
|
||||
mock.module('./group', () => ({
|
||||
getGroup: () => Promise.resolve(mockGroup),
|
||||
renderGroupEveRefLink: (group: any, lang: string) => {
|
||||
if (group.group_id === 67890 && lang === 'fr') return 'Group Link';
|
||||
return null;
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 67890, 'fr');
|
||||
|
||||
expect(result).toBe('Group Link');
|
||||
});
|
||||
|
||||
it('should render unit 115 (groupID) as Unknown when link is null', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 115 };
|
||||
const mockGroup = {
|
||||
group_id: 67890,
|
||||
name: { en: 'Test Group' },
|
||||
category_id: 1,
|
||||
published: true,
|
||||
anchorable: false,
|
||||
anchored: false,
|
||||
fittable_non_singleton: false,
|
||||
use_base_price: false,
|
||||
};
|
||||
|
||||
mock.module('./group', () => ({
|
||||
getGroup: (group_id: number) => {
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
renderGroupEveRefLink: (group: any, lang: string) => {
|
||||
return null;
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 67890);
|
||||
|
||||
expect(result).toBe('Unknown');
|
||||
});
|
||||
});
|
||||
|
||||
test('physical units', () => {
|
||||
it('should render unit 10 (m/s)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 10 };
|
||||
const result = await renderUnit(unit, 150);
|
||||
expect(result).toBe('150 m/s');
|
||||
});
|
||||
|
||||
it('should render unit 11 (m/s²)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 11 };
|
||||
const result = await renderUnit(unit, 9.8);
|
||||
expect(result).toBe('9.8 m/s²');
|
||||
});
|
||||
|
||||
it('should render unit 9 (m³)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 9 };
|
||||
const result = await renderUnit(unit, 1000);
|
||||
expect(result).toBe('1000 m³');
|
||||
});
|
||||
|
||||
it('should render unit 8 (m²)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 8 };
|
||||
const result = await renderUnit(unit, 50);
|
||||
expect(result).toBe('50 m²');
|
||||
});
|
||||
|
||||
it('should render unit 12 (m⁻¹)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 12 };
|
||||
const result = await renderUnit(unit, 0.1);
|
||||
expect(result).toBe('0.1 m⁻¹');
|
||||
});
|
||||
|
||||
it('should render unit 128 (Mbps)', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 128 };
|
||||
const result = await renderUnit(unit, 100);
|
||||
expect(result).toBe('100 Mbps');
|
||||
});
|
||||
});
|
||||
|
||||
test('default case', () => {
|
||||
it('should render unknown unit with value and display_name', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 999, display_name: 'Custom Unit' };
|
||||
const result = await renderUnit(unit, 42);
|
||||
expect(result).toBe('42 Custom Unit');
|
||||
});
|
||||
|
||||
it('should render unknown unit with empty display_name', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 999, display_name: '' };
|
||||
const result = await renderUnit(unit, 42);
|
||||
expect(result).toBe('42 ');
|
||||
});
|
||||
|
||||
it('should handle undefined display_name', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 999, display_name: undefined as any };
|
||||
const result = await renderUnit(unit, 42);
|
||||
expect(result).toBe('42 ');
|
||||
});
|
||||
});
|
||||
|
||||
test('edge cases', () => {
|
||||
it('should handle zero values', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 10 };
|
||||
const result = await renderUnit(unit, 0);
|
||||
expect(result).toBe('0 m/s');
|
||||
});
|
||||
|
||||
it('should handle negative values', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 120 };
|
||||
const result = await renderUnit(unit, -50);
|
||||
expect(result).toBe('-50 pts');
|
||||
});
|
||||
|
||||
it('should handle very large values', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 9 };
|
||||
const result = await renderUnit(unit, 1e10);
|
||||
expect(result).toBe('10000000000 m³');
|
||||
});
|
||||
|
||||
it('should handle decimal values for inverse percentage', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 108 };
|
||||
const result = await renderUnit(unit, 0.12345);
|
||||
expect(result).toBe('0.88 Test Unit');
|
||||
});
|
||||
|
||||
it('should default to "en" locale when not specified', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 116 };
|
||||
const mockType = {
|
||||
type_id: 12345,
|
||||
name: { en: 'Test Type' },
|
||||
description: { en: 'Test description' },
|
||||
published: true,
|
||||
};
|
||||
|
||||
mock.module('./type', () => ({
|
||||
getType: (type_id: number) => {
|
||||
if (type_id === 12345) return Promise.resolve(mockType);
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
renderTypeEveRefLink: (type: any, lang: string) => {
|
||||
if (type.type_id === 12345 && lang === 'en') return 'Type Link';
|
||||
return null;
|
||||
},
|
||||
}));
|
||||
|
||||
const result = await renderUnit(unit, 12345);
|
||||
expect(result).toBe('Type Link');
|
||||
});
|
||||
});
|
||||
|
||||
test('error handling', () => {
|
||||
it('should handle getType errors gracefully', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 116 };
|
||||
mock.module('./type', () => ({
|
||||
getType: (type_id: number) => {
|
||||
throw new Error('Type not found');
|
||||
},
|
||||
}));
|
||||
|
||||
await expect(renderUnit(unit, 12345)).rejects.toThrow('Type not found');
|
||||
});
|
||||
|
||||
it('should handle getGroup errors gracefully', async () => {
|
||||
const unit = { ...mockUnit, unit_id: 115 };
|
||||
mock.module('./group', () => ({
|
||||
getGroup: (group_id: number) => {
|
||||
throw new Error('Group not found');
|
||||
},
|
||||
}));
|
||||
|
||||
await expect(renderUnit(unit, 67890)).rejects.toThrow('Group not found');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('isUnitInversePercentage', () => {
|
||||
const mockUnit: Unit = {
|
||||
unit_id: 0,
|
||||
display_name: 'Test Unit',
|
||||
description: { en: 'Test description' },
|
||||
name: { en: 'Test Name' },
|
||||
};
|
||||
|
||||
it('should return true for unit_id 108', () => {
|
||||
const unit = { ...mockUnit, unit_id: 108 };
|
||||
expect(isUnitInversePercentage(unit)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true for unit_id 111', () => {
|
||||
const unit = { ...mockUnit, unit_id: 111 };
|
||||
expect(isUnitInversePercentage(unit)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for other unit_ids', () => {
|
||||
const testCases = [0, 1, 3, 8, 9, 10, 11, 12, 101, 107, 109, 115, 116, 117, 120, 128, 141, 999];
|
||||
|
||||
testCases.forEach((unit_id) => {
|
||||
const unit = { ...mockUnit, unit_id };
|
||||
expect(isUnitInversePercentage(unit)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should use loose equality (==) not strict equality (===)', () => {
|
||||
// Test that the function uses == comparison by verifying it works with string unit_ids
|
||||
const unit108 = { ...mockUnit, unit_id: 108 as any };
|
||||
const unit111 = { ...mockUnit, unit_id: 111 as any };
|
||||
|
||||
expect(isUnitInversePercentage(unit108)).toBe(true);
|
||||
expect(isUnitInversePercentage(unit111)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user